summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--JavaScriptCore/API/JSBase.cpp2
-rw-r--r--JavaScriptCore/API/JSBasePrivate.h2
-rw-r--r--JavaScriptCore/API/JSCallbackObjectFunctions.h68
-rw-r--r--JavaScriptCore/API/JSContextRef.h10
-rw-r--r--JavaScriptCore/API/JSObjectRef.cpp2
-rw-r--r--JavaScriptCore/API/JSObjectRef.h8
-rw-r--r--JavaScriptCore/API/WebKitAvailability.h85
-rw-r--r--JavaScriptCore/API/tests/testapi.c213
-rw-r--r--JavaScriptCore/API/tests/testapi.js67
-rw-r--r--JavaScriptCore/Android.mk6
-rw-r--r--JavaScriptCore/ChangeLog2649
-rw-r--r--JavaScriptCore/Configurations/Base.xcconfig16
-rw-r--r--JavaScriptCore/Configurations/DebugRelease.xcconfig9
-rw-r--r--JavaScriptCore/Configurations/JavaScriptCore.xcconfig10
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig4
-rw-r--r--JavaScriptCore/GNUmakefile.am10
-rw-r--r--JavaScriptCore/JavaScriptCore.exp7
-rw-r--r--JavaScriptCore/JavaScriptCore.pri29
-rw-r--r--JavaScriptCore/JavaScriptCore.scons2
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj20
-rwxr-xr-xJavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh2
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj8
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj6
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj6
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj46
-rw-r--r--JavaScriptCore/JavaScriptCorePrefix.h9
-rw-r--r--JavaScriptCore/JavaScriptCoreSources.bkl2
-rw-r--r--JavaScriptCore/assembler/AbstractMacroAssembler.h841
-rw-r--r--JavaScriptCore/assembler/MacroAssembler.h1887
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerX86.h126
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerX86Common.h583
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerX86_64.h398
-rw-r--r--JavaScriptCore/assembler/X86Assembler.h200
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.h48
-rw-r--r--JavaScriptCore/bytecode/Instruction.h25
-rw-r--r--JavaScriptCore/bytecode/JumpTable.h13
-rw-r--r--JavaScriptCore/bytecode/StructureStubInfo.h16
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.cpp5
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h15
-rw-r--r--JavaScriptCore/interpreter/CallFrame.h1
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp419
-rw-r--r--JavaScriptCore/interpreter/Interpreter.h235
-rw-r--r--JavaScriptCore/interpreter/Register.h3
-rw-r--r--JavaScriptCore/interpreter/RegisterFile.h139
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.h24
-rw-r--r--JavaScriptCore/jit/JIT.cpp1070
-rw-r--r--JavaScriptCore/jit/JIT.h147
-rw-r--r--JavaScriptCore/jit/JITArithmetic.cpp367
-rw-r--r--JavaScriptCore/jit/JITCall.cpp108
-rw-r--r--JavaScriptCore/jit/JITCode.h97
-rw-r--r--JavaScriptCore/jit/JITInlineMethods.h59
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess.cpp373
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp2196
-rw-r--r--JavaScriptCore/jit/JITStubs.h226
-rw-r--r--JavaScriptCore/jsc.cpp75
-rw-r--r--JavaScriptCore/jscore.bkl2
-rw-r--r--JavaScriptCore/parser/Lexer.cpp11
-rw-r--r--JavaScriptCore/parser/Lexer.h11
-rw-r--r--JavaScriptCore/parser/Nodes.cpp63
-rw-r--r--JavaScriptCore/parser/Nodes.h9
-rw-r--r--JavaScriptCore/pcre/pcre_exec.cpp7
-rw-r--r--JavaScriptCore/pcre/pcre_internal.h36
-rw-r--r--JavaScriptCore/profiler/Profiler.cpp2
-rw-r--r--JavaScriptCore/runtime/Arguments.cpp7
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp23
-rw-r--r--JavaScriptCore/runtime/Collector.cpp3
-rw-r--r--JavaScriptCore/runtime/Completion.cpp2
-rw-r--r--JavaScriptCore/runtime/DateMath.cpp8
-rw-r--r--JavaScriptCore/runtime/DatePrototype.cpp25
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp2
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp9
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp64
-rw-r--r--JavaScriptCore/runtime/JSArray.h2
-rw-r--r--JavaScriptCore/runtime/JSByteArray.h11
-rw-r--r--JavaScriptCore/runtime/JSCell.h4
-rw-r--r--JavaScriptCore/runtime/JSFunction.h3
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp67
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h83
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp19
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h4
-rw-r--r--JavaScriptCore/runtime/JSImmediate.cpp8
-rw-r--r--JavaScriptCore/runtime/JSString.h4
-rw-r--r--JavaScriptCore/runtime/NumberConstructor.cpp10
-rw-r--r--JavaScriptCore/runtime/Operations.cpp66
-rw-r--r--JavaScriptCore/runtime/Operations.h153
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp1
-rw-r--r--JavaScriptCore/runtime/Structure.cpp6
-rw-r--r--JavaScriptCore/runtime/TimeoutChecker.cpp154
-rw-r--r--JavaScriptCore/runtime/TimeoutChecker.h (renamed from WebCore/storage/SQLStatementCallback.idl)48
-rw-r--r--JavaScriptCore/runtime/UString.cpp2
-rw-r--r--JavaScriptCore/wrec/WREC.cpp7
-rw-r--r--JavaScriptCore/wrec/WRECGenerator.cpp94
-rw-r--r--JavaScriptCore/wrec/WRECGenerator.h22
-rw-r--r--JavaScriptCore/wtf/Assertions.h2
-rw-r--r--JavaScriptCore/wtf/ByteArray.h3
-rw-r--r--JavaScriptCore/wtf/CrossThreadRefCounted.h165
-rw-r--r--JavaScriptCore/wtf/CurrentTime.cpp74
-rw-r--r--JavaScriptCore/wtf/Deque.h121
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp223
-rw-r--r--JavaScriptCore/wtf/HashTraits.h43
-rw-r--r--JavaScriptCore/wtf/MainThread.cpp73
-rw-r--r--JavaScriptCore/wtf/MainThread.h4
-rw-r--r--JavaScriptCore/wtf/MessageQueue.h40
-rw-r--r--JavaScriptCore/wtf/OwnPtr.h11
-rw-r--r--JavaScriptCore/wtf/Platform.h56
-rw-r--r--JavaScriptCore/wtf/RefCounted.h12
-rw-r--r--JavaScriptCore/wtf/RetainPtr.h11
-rw-r--r--JavaScriptCore/wtf/TCPageMap.h33
-rw-r--r--JavaScriptCore/wtf/TCSystemAlloc.cpp44
-rw-r--r--JavaScriptCore/wtf/TCSystemAlloc.h8
-rw-r--r--JavaScriptCore/wtf/ThreadSpecific.h16
-rw-r--r--JavaScriptCore/wtf/ThreadSpecificWin.cpp17
-rw-r--r--JavaScriptCore/wtf/Threading.cpp22
-rw-r--r--JavaScriptCore/wtf/Threading.h64
-rw-r--r--JavaScriptCore/wtf/ThreadingGtk.cpp4
-rw-r--r--JavaScriptCore/wtf/ThreadingNone.cpp1
-rw-r--r--JavaScriptCore/wtf/ThreadingPthreads.cpp49
-rw-r--r--JavaScriptCore/wtf/ThreadingQt.cpp16
-rw-r--r--JavaScriptCore/wtf/ThreadingWin.cpp24
-rw-r--r--JavaScriptCore/wtf/TypeTraits.cpp120
-rw-r--r--JavaScriptCore/wtf/TypeTraits.h133
-rw-r--r--JavaScriptCore/wtf/Vector.h17
-rw-r--r--JavaScriptCore/wtf/VectorTraits.h19
-rw-r--r--JavaScriptCore/wtf/android/MainThreadAndroid.cpp4
-rw-r--r--JavaScriptCore/wtf/chromium/ChromiumThreading.h45
-rw-r--r--JavaScriptCore/wtf/chromium/MainThreadChromium.cpp49
-rw-r--r--JavaScriptCore/wtf/dtoa.cpp24
-rw-r--r--JavaScriptCore/wtf/gtk/MainThreadGtk.cpp7
-rw-r--r--JavaScriptCore/wtf/mac/MainThreadMac.mm14
-rw-r--r--JavaScriptCore/wtf/qt/MainThreadQt.cpp5
-rw-r--r--JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h5
-rw-r--r--JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h6
-rw-r--r--JavaScriptCore/wtf/win/MainThreadWin.cpp6
-rw-r--r--JavaScriptCore/wtf/wx/MainThreadWx.cpp6
-rw-r--r--WEBKIT_MERGE_REVISION1
-rw-r--r--WebCore/Android.derived.mk12
-rw-r--r--WebCore/Android.mk42
-rw-r--r--WebCore/ChangeLog22533
-rw-r--r--WebCore/Configurations/Base.xcconfig5
-rw-r--r--WebCore/Configurations/DebugRelease.xcconfig9
-rw-r--r--WebCore/Configurations/Version.xcconfig4
-rw-r--r--WebCore/Configurations/WebCore.xcconfig18
-rw-r--r--WebCore/DerivedSources.cpp5
-rw-r--r--WebCore/DerivedSources.make24
-rw-r--r--WebCore/English.lproj/localizedStrings.jsbin15490 -> 18296 bytes
-rw-r--r--WebCore/ForwardingHeaders/wtf/TypeTraits.h1
-rw-r--r--WebCore/GNUmakefile.am170
-rw-r--r--WebCore/WebCore.LP64.exp5
-rw-r--r--WebCore/WebCore.NPAPI.exp2
-rw-r--r--WebCore/WebCore.VideoProxy.exp4
-rw-r--r--WebCore/WebCore.base.exp67
-rw-r--r--WebCore/WebCore.order1
-rw-r--r--WebCore/WebCore.pro91
-rw-r--r--WebCore/WebCore.scons58
-rw-r--r--WebCore/WebCore.vcproj/MigrateIDLAndScripts5
-rw-r--r--WebCore/WebCore.vcproj/QTMovieWin.vcproj18
-rw-r--r--WebCore/WebCore.vcproj/WebCore.vcproj968
-rw-r--r--WebCore/WebCore.xcodeproj/project.pbxproj664
-rw-r--r--WebCore/WebCorePrefix.h10
-rw-r--r--WebCore/WebCoreSources.bkl48
-rw-r--r--WebCore/bindings/js/JSAudioConstructor.cpp12
-rw-r--r--WebCore/bindings/js/JSAudioConstructor.h4
-rw-r--r--WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSCustomPositionCallback.cpp8
-rw-r--r--WebCore/bindings/js/JSCustomPositionErrorCallback.cpp8
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementCallback.cpp6
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp6
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp7
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp6
-rw-r--r--WebCore/bindings/js/JSCustomVoidCallback.cpp7
-rw-r--r--WebCore/bindings/js/JSCustomXPathNSResolver.cpp8
-rw-r--r--WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp43
-rw-r--r--WebCore/bindings/js/JSDOMGlobalObject.cpp56
-rw-r--r--WebCore/bindings/js/JSDOMGlobalObject.h30
-rw-r--r--WebCore/bindings/js/JSDOMWindowBase.cpp48
-rw-r--r--WebCore/bindings/js/JSDOMWindowBase.h4
-rw-r--r--WebCore/bindings/js/JSDOMWindowCustom.cpp12
-rw-r--r--WebCore/bindings/js/JSDOMWindowCustom.h12
-rw-r--r--WebCore/bindings/js/JSDOMWindowShell.cpp14
-rw-r--r--WebCore/bindings/js/JSDocumentCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSEventListener.cpp165
-rw-r--r--WebCore/bindings/js/JSEventListener.h77
-rw-r--r--WebCore/bindings/js/JSEventTarget.cpp53
-rw-r--r--WebCore/bindings/js/JSEventTarget.h1
-rw-r--r--WebCore/bindings/js/JSEventTargetNodeCustom.cpp71
-rw-r--r--WebCore/bindings/js/JSGeolocationCustom.cpp9
-rw-r--r--WebCore/bindings/js/JSHTMLDocumentCustom.cpp45
-rw-r--r--WebCore/bindings/js/JSHTMLInputElementCustom.cpp48
-rw-r--r--WebCore/bindings/js/JSImageConstructor.cpp16
-rw-r--r--WebCore/bindings/js/JSImageConstructor.h4
-rw-r--r--WebCore/bindings/js/JSInspectedObjectWrapper.cpp4
-rw-r--r--WebCore/bindings/js/JSInspectorCallbackWrapper.cpp2
-rw-r--r--WebCore/bindings/js/JSInspectorControllerCustom.cpp333
-rw-r--r--WebCore/bindings/js/JSLazyEventListener.cpp131
-rw-r--r--WebCore/bindings/js/JSLazyEventListener.h63
-rw-r--r--WebCore/bindings/js/JSMessageChannelConstructor.cpp20
-rw-r--r--WebCore/bindings/js/JSMessageChannelConstructor.h5
-rw-r--r--WebCore/bindings/js/JSMessagePortCustom.cpp19
-rw-r--r--WebCore/bindings/js/JSNamedNodesCollection.cpp2
-rw-r--r--WebCore/bindings/js/JSNavigatorCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSNodeCustom.cpp29
-rw-r--r--WebCore/bindings/js/JSNodeFilterCondition.cpp2
-rw-r--r--WebCore/bindings/js/JSOptionConstructor.cpp25
-rw-r--r--WebCore/bindings/js/JSOptionConstructor.h4
-rw-r--r--WebCore/bindings/js/JSPluginElementFunctions.cpp4
-rw-r--r--WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp9
-rw-r--r--WebCore/bindings/js/JSRGBColor.cpp2
-rw-r--r--WebCore/bindings/js/JSSVGElementInstanceCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSSVGPODTypeWrapper.h1
-rw-r--r--WebCore/bindings/js/JSStyleSheetCustom.cpp1
-rw-r--r--WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp4
-rw-r--r--WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h2
-rw-r--r--WebCore/bindings/js/JSWebKitPointConstructor.cpp68
-rw-r--r--WebCore/bindings/js/JSWebKitPointConstructor.h46
-rw-r--r--WebCore/bindings/js/JSWorkerConstructor.cpp1
-rw-r--r--WebCore/bindings/js/JSWorkerContextBase.cpp36
-rw-r--r--WebCore/bindings/js/JSWorkerContextBase.h2
-rw-r--r--WebCore/bindings/js/JSWorkerContextCustom.cpp76
-rw-r--r--WebCore/bindings/js/JSWorkerCustom.cpp19
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp19
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestConstructor.h5
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestCustom.cpp35
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp31
-rw-r--r--WebCore/bindings/js/JSXSLTProcessorConstructor.cpp2
-rw-r--r--WebCore/bindings/js/ScheduledAction.cpp7
-rw-r--r--WebCore/bindings/js/ScriptController.cpp53
-rw-r--r--WebCore/bindings/js/ScriptController.h2
-rw-r--r--WebCore/bindings/js/ScriptControllerMac.mm6
-rw-r--r--WebCore/bindings/js/ScriptControllerQt.cpp6
-rw-r--r--WebCore/bindings/js/ScriptFunctionCall.cpp138
-rw-r--r--WebCore/bindings/js/ScriptFunctionCall.h68
-rw-r--r--WebCore/bindings/js/ScriptObject.cpp43
-rw-r--r--WebCore/bindings/js/ScriptObject.h50
-rw-r--r--WebCore/bindings/js/ScriptObjectQuarantine.cpp85
-rw-r--r--WebCore/bindings/js/ScriptObjectQuarantine.h51
-rw-r--r--WebCore/bindings/js/ScriptValue.cpp12
-rw-r--r--WebCore/bindings/js/ScriptValue.h6
-rw-r--r--WebCore/bindings/js/WorkerScriptController.cpp40
-rw-r--r--WebCore/bindings/js/WorkerScriptController.h4
-rw-r--r--WebCore/bindings/objc/DOM.mm26
-rw-r--r--WebCore/bindings/objc/DOMAbstractView.mm6
-rw-r--r--WebCore/bindings/objc/DOMPrivate.h2
-rw-r--r--WebCore/bindings/objc/WebScriptObject.mm8
-rw-r--r--WebCore/bindings/scripts/CodeGenerator.pm6
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorCOM.pm11
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm96
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorObjC.pm20
-rw-r--r--WebCore/bindings/v8/ScheduledAction.cpp114
-rw-r--r--WebCore/bindings/v8/ScheduledAction.h65
-rw-r--r--WebCore/bindings/v8/ScriptCachedFrameData.h52
-rw-r--r--WebCore/bindings/v8/ScriptCallFrame.cpp62
-rw-r--r--WebCore/bindings/v8/ScriptCallFrame.h73
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.cpp58
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.h63
-rw-r--r--WebCore/bindings/v8/ScriptInstance.cpp83
-rw-r--r--WebCore/bindings/v8/ScriptInstance.h64
-rw-r--r--WebCore/bindings/v8/ScriptSourceCode.h72
-rw-r--r--WebCore/bindings/v8/ScriptState.h51
-rw-r--r--WebCore/bindings/v8/ScriptString.h66
-rw-r--r--WebCore/bindings/v8/ScriptValue.cpp55
-rw-r--r--WebCore/bindings/v8/ScriptValue.h141
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.cpp165
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.h98
-rw-r--r--WebCore/bindings/v8/V8Binding.h81
-rw-r--r--WebCore/bindings/v8/V8Collection.h193
-rw-r--r--WebCore/bindings/v8/V8Index.h38
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.cpp197
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.h80
-rw-r--r--WebCore/bindings/v8/V8NodeFilterCondition.cpp89
-rw-r--r--WebCore/bindings/v8/V8NodeFilterCondition.h57
-rw-r--r--WebCore/bindings/v8/V8ObjectEventListener.cpp75
-rw-r--r--WebCore/bindings/v8/V8ObjectEventListener.h57
-rw-r--r--WebCore/bindings/v8/V8Proxy.h85
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.cpp113
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.h69
-rw-r--r--WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp76
-rw-r--r--WebCore/bindings/v8/V8XMLHttpRequestUtilities.h45
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.cpp359
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.h106
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.cpp93
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.h72
-rw-r--r--WebCore/bindings/v8/custom/V8AttrCustom.cpp58
-rw-r--r--WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp192
-rw-r--r--WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp95
-rw-r--r--WebCore/bindings/v8/custom/V8ClipboardCustom.cpp141
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.cpp59
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.h49
-rw-r--r--WebCore/bindings/v8/custom/V8CustomEventListener.cpp89
-rw-r--r--WebCore/bindings/v8/custom/V8CustomEventListener.h68
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp72
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h62
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp76
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h64
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp75
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h62
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp75
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h63
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp97
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.h66
-rw-r--r--WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp (renamed from WebCore/svg/graphics/skia/SVGResourceMaskerSkia.cpp)22
-rw-r--r--WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp62
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCustom.cpp93
-rw-r--r--WebCore/bindings/v8/custom/V8DocumentCustom.cpp99
-rw-r--r--WebCore/bindings/v8/custom/V8ElementCustom.cpp168
-rw-r--r--WebCore/bindings/v8/custom/V8EventCustom.cpp82
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp52
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp140
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp112
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp70
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp62
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp62
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp51
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp109
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp116
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp111
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp63
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h45
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp75
-rw-r--r--WebCore/bindings/v8/custom/V8LocationCustom.cpp385
-rw-r--r--WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp77
-rw-r--r--WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp74
-rw-r--r--WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp55
-rw-r--r--WebCore/bindings/v8/custom/V8NamedNodesCollection.h55
-rw-r--r--WebCore/bindings/v8/custom/V8NavigatorCustom.cpp48
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp86
-rw-r--r--WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp48
-rw-r--r--WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp81
-rw-r--r--WebCore/bindings/v8/custom/V8NodeListCustom.cpp59
-rw-r--r--WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp90
-rw-r--r--WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp114
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp87
-rw-r--r--WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp65
-rw-r--r--WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp86
-rw-r--r--WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp56
-rw-r--r--WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp127
-rw-r--r--WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp66
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp61
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp444
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp291
-rw-r--r--WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp (renamed from WebCore/dom/WorkerRunLoop.cpp)42
-rw-r--r--WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp45
-rw-r--r--WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp153
-rw-r--r--WebCore/bridge/IdentifierRep.cpp111
-rw-r--r--WebCore/bridge/IdentifierRep.h74
-rw-r--r--WebCore/bridge/NP_jsobject.cpp70
-rw-r--r--WebCore/bridge/c/c_instance.cpp11
-rw-r--r--WebCore/bridge/c/c_utility.cpp2
-rw-r--r--WebCore/bridge/c/c_utility.h18
-rw-r--r--WebCore/bridge/jni/jni_jsobject.mm8
-rw-r--r--WebCore/bridge/npapi.h33
-rw-r--r--WebCore/bridge/npruntime.cpp97
-rw-r--r--WebCore/bridge/npruntime_internal.h1
-rw-r--r--WebCore/bridge/qt/qt_instance.cpp21
-rw-r--r--WebCore/bridge/qt/qt_instance.h10
-rw-r--r--WebCore/bridge/qt/qt_runtime.cpp39
-rw-r--r--WebCore/bridge/testbindings.mm2
-rw-r--r--WebCore/config.h8
-rw-r--r--WebCore/css/CSSComputedStyleDeclaration.cpp179
-rw-r--r--WebCore/css/CSSFontSelector.cpp14
-rw-r--r--WebCore/css/CSSGrammar.y2
-rw-r--r--WebCore/css/CSSMutableStyleDeclaration.cpp13
-rw-r--r--WebCore/css/CSSMutableStyleDeclaration.h2
-rw-r--r--WebCore/css/CSSParser.cpp211
-rw-r--r--WebCore/css/CSSParser.h10
-rw-r--r--WebCore/css/CSSPrimitiveValue.cpp4
-rw-r--r--WebCore/css/CSSPrimitiveValue.h2
-rw-r--r--WebCore/css/CSSPrimitiveValueMappings.h16
-rw-r--r--WebCore/css/CSSPropertyNames.in15
-rw-r--r--WebCore/css/CSSSelectorList.cpp31
-rw-r--r--WebCore/css/CSSStyleDeclaration.cpp2
-rw-r--r--WebCore/css/CSSStyleSelector.cpp530
-rw-r--r--WebCore/css/CSSStyleSelector.h15
-rw-r--r--WebCore/css/CSSStyleSheet.cpp6
-rw-r--r--WebCore/css/CSSValueKeywords.in12
-rw-r--r--WebCore/css/MediaQueryEvaluator.cpp15
-rw-r--r--WebCore/css/SVGCSSComputedStyleDeclaration.cpp1
-rw-r--r--WebCore/css/SVGCSSStyleSelector.cpp121
-rw-r--r--WebCore/css/WebKitCSSMatrix.cpp78
-rw-r--r--WebCore/css/WebKitCSSMatrix.h105
-rw-r--r--WebCore/css/WebKitCSSMatrix.idl62
-rw-r--r--WebCore/css/WebKitCSSTransformValue.cpp30
-rw-r--r--WebCore/css/WebKitCSSTransformValue.h12
-rw-r--r--WebCore/css/WebKitCSSTransformValue.idl10
-rw-r--r--WebCore/css/html4.css4
-rw-r--r--WebCore/css/themeChromiumWin.css39
-rw-r--r--WebCore/css/themeWin.css18
-rw-r--r--WebCore/css/themeWinQuirks.css2
-rw-r--r--WebCore/dom/Attr.idl2
-rw-r--r--WebCore/dom/CharacterData.cpp6
-rw-r--r--WebCore/dom/CharacterData.h4
-rw-r--r--WebCore/dom/CharacterData.idl2
-rw-r--r--WebCore/dom/ClientRect.cpp (renamed from WebCore/dom/WorkerTask.cpp)16
-rw-r--r--WebCore/dom/ClientRect.h59
-rw-r--r--WebCore/dom/ClientRect.idl40
-rw-r--r--WebCore/dom/ClientRectList.cpp66
-rw-r--r--WebCore/dom/ClientRectList.h57
-rw-r--r--WebCore/dom/ClientRectList.idl38
-rw-r--r--WebCore/dom/Clipboard.cpp1
-rw-r--r--WebCore/dom/ContainerNode.cpp159
-rw-r--r--WebCore/dom/ContainerNode.h17
-rw-r--r--WebCore/dom/DOMImplementation.cpp3
-rw-r--r--WebCore/dom/Document.cpp317
-rw-r--r--WebCore/dom/Document.h88
-rw-r--r--WebCore/dom/Document.idl20
-rw-r--r--WebCore/dom/DocumentFragment.idl7
-rw-r--r--WebCore/dom/Element.cpp144
-rw-r--r--WebCore/dom/Element.h15
-rw-r--r--WebCore/dom/Element.idl16
-rw-r--r--WebCore/dom/EventException.idl3
-rw-r--r--WebCore/dom/EventListener.h19
-rw-r--r--WebCore/dom/EventListener.idl1
-rw-r--r--WebCore/dom/EventNames.h8
-rw-r--r--WebCore/dom/EventTarget.cpp2
-rw-r--r--WebCore/dom/EventTarget.h4
-rw-r--r--WebCore/dom/EventTarget.idl6
-rw-r--r--WebCore/dom/EventTargetNode.cpp1241
-rw-r--r--WebCore/dom/EventTargetNode.h219
-rw-r--r--WebCore/dom/EventTargetNode.idl90
-rw-r--r--WebCore/dom/ExceptionCode.cpp3
-rw-r--r--WebCore/dom/FormControlElement.h4
-rw-r--r--WebCore/dom/GenericWorkerTask.h109
-rw-r--r--WebCore/dom/InputElement.cpp4
-rw-r--r--WebCore/dom/InputElement.h4
-rw-r--r--WebCore/dom/MessagePort.cpp1
-rw-r--r--WebCore/dom/MouseEvent.cpp8
-rw-r--r--WebCore/dom/MouseEvent.h11
-rw-r--r--WebCore/dom/MouseRelatedEvent.cpp21
-rw-r--r--WebCore/dom/MouseRelatedEvent.h11
-rw-r--r--WebCore/dom/NamedAttrMap.cpp26
-rw-r--r--WebCore/dom/NamedAttrMap.h55
-rw-r--r--WebCore/dom/NamedMappedAttrMap.cpp4
-rw-r--r--WebCore/dom/NamedMappedAttrMap.h21
-rw-r--r--WebCore/dom/NamedNodeMap.h5
-rw-r--r--WebCore/dom/Node.cpp1258
-rw-r--r--WebCore/dom/Node.h193
-rw-r--r--WebCore/dom/Node.idl73
-rw-r--r--WebCore/dom/Position.cpp161
-rw-r--r--WebCore/dom/Position.h71
-rw-r--r--WebCore/dom/PositionIterator.cpp22
-rw-r--r--WebCore/dom/PositionIterator.h4
-rw-r--r--WebCore/dom/QualifiedName.cpp35
-rw-r--r--WebCore/dom/QualifiedName.h33
-rw-r--r--WebCore/dom/Range.cpp56
-rw-r--r--WebCore/dom/RangeBoundaryPoint.h48
-rw-r--r--WebCore/dom/ScriptExecutionContext.cpp16
-rw-r--r--WebCore/dom/ScriptExecutionContext.h12
-rw-r--r--WebCore/dom/Text.cpp7
-rw-r--r--WebCore/dom/Tokenizer.h2
-rw-r--r--WebCore/dom/WheelEvent.cpp11
-rw-r--r--WebCore/dom/WheelEvent.h6
-rw-r--r--WebCore/dom/XMLTokenizer.cpp43
-rw-r--r--WebCore/dom/XMLTokenizer.h2
-rw-r--r--WebCore/dom/XMLTokenizerLibxml2.cpp12
-rw-r--r--WebCore/dom/XMLTokenizerQt.cpp9
-rwxr-xr-xWebCore/dom/make_names.pl174
-rw-r--r--WebCore/editing/ApplyStyleCommand.cpp127
-rw-r--r--WebCore/editing/BreakBlockquoteCommand.cpp18
-rw-r--r--WebCore/editing/CompositeEditCommand.cpp69
-rw-r--r--WebCore/editing/CompositeEditCommand.h2
-rw-r--r--WebCore/editing/CreateLinkCommand.cpp2
-rw-r--r--WebCore/editing/DeleteButtonController.cpp32
-rw-r--r--WebCore/editing/DeleteButtonController.h4
-rw-r--r--WebCore/editing/DeleteSelectionCommand.cpp61
-rw-r--r--WebCore/editing/DeleteSelectionCommand.h6
-rw-r--r--WebCore/editing/EditCommand.cpp12
-rw-r--r--WebCore/editing/EditCommand.h14
-rw-r--r--WebCore/editing/Editor.cpp486
-rw-r--r--WebCore/editing/Editor.h18
-rw-r--r--WebCore/editing/EditorCommand.cpp84
-rw-r--r--WebCore/editing/FormatBlockCommand.cpp4
-rw-r--r--WebCore/editing/IndentOutdentCommand.cpp18
-rw-r--r--WebCore/editing/InsertLineBreakCommand.cpp29
-rw-r--r--WebCore/editing/InsertListCommand.cpp18
-rw-r--r--WebCore/editing/InsertListCommand.h7
-rw-r--r--WebCore/editing/InsertParagraphSeparatorCommand.cpp103
-rw-r--r--WebCore/editing/InsertTextCommand.cpp16
-rw-r--r--WebCore/editing/ModifySelectionListLevel.cpp18
-rw-r--r--WebCore/editing/MoveSelectionCommand.cpp14
-rw-r--r--WebCore/editing/RemoveFormatCommand.cpp4
-rw-r--r--WebCore/editing/ReplaceSelectionCommand.cpp84
-rw-r--r--WebCore/editing/SelectionController.cpp67
-rw-r--r--WebCore/editing/SelectionController.h12
-rw-r--r--WebCore/editing/SmartReplaceCF.cpp1
-rw-r--r--WebCore/editing/SplitElementCommand.cpp2
-rw-r--r--WebCore/editing/TextIterator.cpp95
-rw-r--r--WebCore/editing/TextIterator.h19
-rw-r--r--WebCore/editing/TypingCommand.cpp124
-rw-r--r--WebCore/editing/TypingCommand.h3
-rw-r--r--WebCore/editing/VisiblePosition.cpp60
-rw-r--r--WebCore/editing/VisibleSelection.cpp (renamed from WebCore/editing/Selection.cpp)152
-rw-r--r--WebCore/editing/VisibleSelection.h (renamed from WebCore/editing/Selection.h)75
-rw-r--r--WebCore/editing/htmlediting.cpp107
-rw-r--r--WebCore/editing/htmlediting.h8
-rw-r--r--WebCore/editing/mac/SelectionControllerMac.mm49
-rw-r--r--WebCore/editing/markup.cpp117
-rw-r--r--WebCore/editing/qt/EditorQt.cpp2
-rw-r--r--WebCore/editing/visible_units.cpp207
-rw-r--r--WebCore/history/BackForwardListChromium.cpp4
-rw-r--r--WebCore/history/CachedFrame.cpp35
-rw-r--r--WebCore/history/CachedFrame.h23
-rw-r--r--WebCore/history/CachedPage.cpp9
-rw-r--r--WebCore/history/CachedPage.h16
-rw-r--r--WebCore/history/HistoryItem.cpp11
-rw-r--r--WebCore/history/HistoryItem.h7
-rw-r--r--WebCore/html/CanvasGradient.cpp5
-rw-r--r--WebCore/html/CanvasGradient.h5
-rw-r--r--WebCore/html/CanvasRenderingContext2D.cpp26
-rw-r--r--WebCore/html/CanvasRenderingContext2D.h3
-rw-r--r--WebCore/html/CanvasStyle.cpp19
-rw-r--r--WebCore/html/HTMLAnchorElement.cpp21
-rw-r--r--WebCore/html/HTMLAppletElement.cpp13
-rw-r--r--WebCore/html/HTMLAreaElement.cpp31
-rw-r--r--WebCore/html/HTMLAreaElement.h27
-rw-r--r--WebCore/html/HTMLCanvasElement.cpp2
-rw-r--r--WebCore/html/HTMLCanvasElement.idl2
-rw-r--r--WebCore/html/HTMLDocument.cpp8
-rw-r--r--WebCore/html/HTMLDocument.h1
-rw-r--r--WebCore/html/HTMLElement.cpp31
-rw-r--r--WebCore/html/HTMLElement.h2
-rw-r--r--WebCore/html/HTMLElementFactory.cpp510
-rw-r--r--WebCore/html/HTMLElementFactory.h47
-rw-r--r--WebCore/html/HTMLEmbedElement.cpp4
-rw-r--r--WebCore/html/HTMLFormControlElement.cpp7
-rw-r--r--WebCore/html/HTMLFormControlElement.h2
-rw-r--r--WebCore/html/HTMLFormElement.cpp22
-rw-r--r--WebCore/html/HTMLImageElement.cpp4
-rw-r--r--WebCore/html/HTMLImageLoader.cpp5
-rw-r--r--WebCore/html/HTMLInputElement.cpp103
-rw-r--r--WebCore/html/HTMLInputElement.h9
-rw-r--r--WebCore/html/HTMLInputElement.idl8
-rw-r--r--WebCore/html/HTMLLegendElement.cpp9
-rw-r--r--WebCore/html/HTMLLegendElement.h1
-rw-r--r--WebCore/html/HTMLMediaElement.cpp1282
-rw-r--r--WebCore/html/HTMLMediaElement.h184
-rw-r--r--WebCore/html/HTMLMediaElement.idl44
-rw-r--r--WebCore/html/HTMLObjectElement.cpp11
-rw-r--r--WebCore/html/HTMLOptGroupElement.cpp10
-rw-r--r--WebCore/html/HTMLOptionElement.cpp11
-rw-r--r--WebCore/html/HTMLOptionElement.h2
-rw-r--r--WebCore/html/HTMLParser.cpp374
-rw-r--r--WebCore/html/HTMLParser.h23
-rw-r--r--WebCore/html/HTMLQuoteElement.cpp8
-rw-r--r--WebCore/html/HTMLQuoteElement.h2
-rw-r--r--WebCore/html/HTMLSelectElement.cpp109
-rw-r--r--WebCore/html/HTMLSelectElement.h5
-rw-r--r--WebCore/html/HTMLSourceElement.cpp2
-rw-r--r--WebCore/html/HTMLTagNames.in2
-rw-r--r--WebCore/html/HTMLTextAreaElement.cpp31
-rw-r--r--WebCore/html/HTMLTextAreaElement.h4
-rw-r--r--WebCore/html/HTMLTokenizer.cpp30
-rw-r--r--WebCore/html/HTMLTokenizer.h2
-rw-r--r--WebCore/html/HTMLVideoElement.cpp22
-rw-r--r--WebCore/html/HTMLVideoElement.h3
-rw-r--r--WebCore/html/HTMLViewSourceDocument.cpp14
-rw-r--r--WebCore/html/MediaError.h2
-rw-r--r--WebCore/html/MediaError.idl1
-rw-r--r--WebCore/html/PreloadScanner.cpp7
-rw-r--r--WebCore/icu/unicode/ucsdet.h350
-rw-r--r--WebCore/inspector/ConsoleMessage.cpp138
-rw-r--r--WebCore/inspector/ConsoleMessage.h (renamed from WebCore/storage/SQLTransactionErrorCallback.idl)44
-rw-r--r--WebCore/inspector/InspectorClient.h2
-rw-r--r--WebCore/inspector/InspectorController.cpp1335
-rw-r--r--WebCore/inspector/InspectorController.h40
-rw-r--r--WebCore/inspector/InspectorController.idl91
-rw-r--r--WebCore/inspector/InspectorDOMStorageResource.cpp95
-rw-r--r--WebCore/inspector/InspectorDOMStorageResource.h76
-rw-r--r--WebCore/inspector/InspectorDatabaseResource.cpp89
-rw-r--r--WebCore/inspector/InspectorDatabaseResource.h70
-rw-r--r--WebCore/inspector/InspectorResource.cpp181
-rw-r--r--WebCore/inspector/InspectorResource.h109
-rw-r--r--WebCore/inspector/JavaScriptDebugServer.cpp11
-rw-r--r--WebCore/inspector/front-end/Console.js186
-rw-r--r--WebCore/inspector/front-end/DOMStorage.js (renamed from WebCore/storage/SQLTransactionCallback.idl)49
-rw-r--r--WebCore/inspector/front-end/DOMStorageDataGrid.js103
-rw-r--r--WebCore/inspector/front-end/DOMStorageItemsView.js108
-rw-r--r--WebCore/inspector/front-end/DatabaseQueryView.js2
-rw-r--r--WebCore/inspector/front-end/DatabaseTableView.js20
-rw-r--r--WebCore/inspector/front-end/DatabasesPanel.js199
-rw-r--r--WebCore/inspector/front-end/Images/domStorage.pngbin0 -> 442 bytes
-rw-r--r--WebCore/inspector/front-end/Images/userInputResultIcon.pngbin0 -> 259 bytes
-rw-r--r--WebCore/inspector/front-end/ScriptsPanel.js22
-rw-r--r--WebCore/inspector/front-end/SourceFrame.js2
-rw-r--r--WebCore/inspector/front-end/WebKit.qrc4
-rw-r--r--WebCore/inspector/front-end/inspector.css135
-rw-r--r--WebCore/inspector/front-end/inspector.html3
-rw-r--r--WebCore/inspector/front-end/inspector.js9
-rw-r--r--WebCore/inspector/front-end/utilities.js37
-rw-r--r--WebCore/loader/Cache.cpp7
-rw-r--r--WebCore/loader/CachedCSSStyleSheet.cpp9
-rw-r--r--WebCore/loader/CachedFont.cpp11
-rw-r--r--WebCore/loader/CachedResource.cpp16
-rw-r--r--WebCore/loader/CachedScript.cpp14
-rw-r--r--WebCore/loader/CachedScript.h4
-rw-r--r--WebCore/loader/CrossOriginAccessControl.cpp116
-rw-r--r--WebCore/loader/CrossOriginAccessControl.h41
-rw-r--r--WebCore/loader/CrossOriginPreflightResultCache.cpp173
-rw-r--r--WebCore/loader/CrossOriginPreflightResultCache.h78
-rw-r--r--WebCore/loader/DocLoader.cpp9
-rw-r--r--WebCore/loader/DocLoader.h6
-rw-r--r--WebCore/loader/DocumentLoader.cpp22
-rw-r--r--WebCore/loader/DocumentLoader.h21
-rw-r--r--WebCore/loader/DocumentThreadableLoader.cpp47
-rw-r--r--WebCore/loader/DocumentThreadableLoader.h5
-rw-r--r--WebCore/loader/EmptyClients.h29
-rw-r--r--WebCore/loader/FTPDirectoryDocument.cpp33
-rw-r--r--WebCore/loader/FrameLoader.cpp693
-rw-r--r--WebCore/loader/FrameLoader.h72
-rw-r--r--WebCore/loader/FrameLoaderClient.cpp92
-rw-r--r--WebCore/loader/FrameLoaderClient.h34
-rw-r--r--WebCore/loader/ImageDocument.cpp9
-rw-r--r--WebCore/loader/ImageLoader.cpp136
-rw-r--r--WebCore/loader/ImageLoader.h31
-rw-r--r--WebCore/loader/MainResourceLoader.cpp43
-rw-r--r--WebCore/loader/MainResourceLoader.h21
-rw-r--r--WebCore/loader/MediaDocument.cpp18
-rw-r--r--WebCore/loader/NetscapePlugInStreamLoader.cpp5
-rw-r--r--WebCore/loader/PluginDocument.cpp13
-rw-r--r--WebCore/loader/ResourceLoader.h3
-rw-r--r--WebCore/loader/SubresourceLoader.h2
-rw-r--r--WebCore/loader/SubresourceLoaderClient.h2
-rw-r--r--WebCore/loader/TextDocument.cpp27
-rw-r--r--WebCore/loader/TextResourceDecoder.cpp152
-rw-r--r--WebCore/loader/TextResourceDecoder.h36
-rw-r--r--WebCore/loader/ThreadableLoader.cpp34
-rw-r--r--WebCore/loader/ThreadableLoader.h6
-rw-r--r--WebCore/loader/ThreadableLoaderClient.h9
-rw-r--r--WebCore/loader/ThreadableLoaderClientWrapper.h117
-rw-r--r--WebCore/loader/WorkerThreadableLoader.cpp261
-rw-r--r--WebCore/loader/WorkerThreadableLoader.h147
-rw-r--r--WebCore/loader/appcache/ApplicationCache.cpp6
-rw-r--r--WebCore/loader/appcache/ApplicationCacheGroup.cpp136
-rw-r--r--WebCore/loader/appcache/ApplicationCacheGroup.h8
-rw-r--r--WebCore/loader/appcache/ApplicationCacheResource.cpp4
-rw-r--r--WebCore/loader/appcache/ApplicationCacheResource.h2
-rw-r--r--WebCore/loader/appcache/DOMApplicationCache.cpp2
-rw-r--r--WebCore/loader/appcache/ManifestParser.cpp9
-rw-r--r--WebCore/loader/archive/cf/LegacyWebArchive.cpp128
-rw-r--r--WebCore/loader/archive/cf/LegacyWebArchive.h27
-rw-r--r--WebCore/loader/archive/cf/LegacyWebArchiveMac.mm20
-rw-r--r--WebCore/loader/cf/ResourceLoaderCFNet.cpp44
-rw-r--r--WebCore/loader/icon/IconDatabase.cpp2
-rw-r--r--WebCore/loader/icon/IconDatabaseNone.cpp47
-rw-r--r--WebCore/loader/icon/IconFetcher.cpp2
-rw-r--r--WebCore/loader/icon/IconLoader.cpp9
-rw-r--r--WebCore/loader/loader.cpp13
-rw-r--r--WebCore/loader/mac/ResourceLoaderMac.mm2
-rwxr-xr-xWebCore/make-generated-sources.sh2
-rw-r--r--WebCore/manual-tests/gtk/floatingdiv.html149
-rw-r--r--WebCore/manual-tests/gtk/plugin-resize-scroll.html28
-rw-r--r--WebCore/manual-tests/inspector/console-dir.html31
-rw-r--r--WebCore/manual-tests/inspector/debugger-step-on-do-while-statements.html29
-rw-r--r--WebCore/manual-tests/inspector/debugger-step-on-for-in-statements.html35
-rw-r--r--WebCore/manual-tests/inspector/debugger-step-on-for-statements.html28
-rw-r--r--WebCore/manual-tests/inspector/debugger-step-on-while-statements.html29
-rw-r--r--WebCore/manual-tests/inspector/highlight-nodes.html23
-rw-r--r--WebCore/manual-tests/inspector/resources/loop-statements.js22
-rw-r--r--WebCore/manual-tests/media-controls-when-javascript-disabled.html26
-rw-r--r--WebCore/manual-tests/resources/simple_image.pngbin0 -> 10585 bytes
-rw-r--r--WebCore/manual-tests/simple-image-compositing.html76
-rw-r--r--WebCore/page/AXObjectCache.cpp51
-rw-r--r--WebCore/page/AXObjectCache.h7
-rw-r--r--WebCore/page/AccessibilityImageMapLink.cpp2
-rw-r--r--WebCore/page/AccessibilityList.cpp12
-rw-r--r--WebCore/page/AccessibilityListBox.cpp10
-rw-r--r--WebCore/page/AccessibilityListBoxOption.cpp4
-rw-r--r--WebCore/page/AccessibilityObject.cpp27
-rw-r--r--WebCore/page/AccessibilityObject.h6
-rw-r--r--WebCore/page/AccessibilityRenderObject.cpp328
-rw-r--r--WebCore/page/AccessibilityRenderObject.h6
-rw-r--r--WebCore/page/AccessibilityTable.cpp26
-rw-r--r--WebCore/page/AccessibilityTableCell.cpp6
-rw-r--r--WebCore/page/AccessibilityTableColumn.cpp4
-rw-r--r--WebCore/page/AccessibilityTableRow.cpp4
-rw-r--r--WebCore/page/Chrome.cpp25
-rw-r--r--WebCore/page/Chrome.h5
-rw-r--r--WebCore/page/ChromeClient.h21
-rw-r--r--WebCore/page/Console.cpp46
-rw-r--r--WebCore/page/Console.h2
-rw-r--r--WebCore/page/ContextMenuController.cpp17
-rw-r--r--WebCore/page/Coordinates.cpp38
-rw-r--r--WebCore/page/Coordinates.h74
-rw-r--r--WebCore/page/Coordinates.idl41
-rw-r--r--WebCore/page/DOMSelection.cpp103
-rw-r--r--WebCore/page/DOMSelection.h8
-rw-r--r--WebCore/page/DOMSelection.idl38
-rw-r--r--WebCore/page/DOMTimer.cpp22
-rw-r--r--WebCore/page/DOMTimer.h7
-rw-r--r--WebCore/page/DOMWindow.cpp86
-rw-r--r--WebCore/page/DOMWindow.h5
-rw-r--r--WebCore/page/DOMWindow.idl60
-rw-r--r--WebCore/page/DragController.cpp28
-rw-r--r--WebCore/page/EditorClient.h12
-rw-r--r--WebCore/page/EventHandler.cpp264
-rw-r--r--WebCore/page/EventHandler.h14
-rw-r--r--WebCore/page/FocusController.cpp20
-rw-r--r--WebCore/page/Frame.cpp369
-rw-r--r--WebCore/page/Frame.h50
-rw-r--r--WebCore/page/FrameTree.cpp4
-rw-r--r--WebCore/page/FrameTree.h1
-rw-r--r--WebCore/page/FrameView.cpp346
-rw-r--r--WebCore/page/FrameView.h34
-rw-r--r--WebCore/page/Geolocation.cpp44
-rw-r--r--WebCore/page/Geolocation.h25
-rw-r--r--WebCore/page/Geoposition.cpp4
-rw-r--r--WebCore/page/Geoposition.h31
-rw-r--r--WebCore/page/Geoposition.idl8
-rw-r--r--WebCore/page/History.idl9
-rw-r--r--WebCore/page/Location.cpp5
-rw-r--r--WebCore/page/Location.idl16
-rw-r--r--WebCore/page/Navigator.cpp14
-rw-r--r--WebCore/page/NavigatorBase.cpp4
-rw-r--r--WebCore/page/Page.cpp43
-rw-r--r--WebCore/page/Page.h10
-rw-r--r--WebCore/page/PositionOptions.h8
-rw-r--r--WebCore/page/PrintContext.cpp2
-rw-r--r--WebCore/page/SecurityOrigin.cpp21
-rw-r--r--WebCore/page/SecurityOrigin.h6
-rw-r--r--WebCore/page/Settings.cpp42
-rw-r--r--WebCore/page/Settings.h30
-rw-r--r--WebCore/page/WebKitPoint.h63
-rw-r--r--WebCore/page/WebKitPoint.idl33
-rw-r--r--WebCore/page/android/InspectorControllerAndroid.cpp2
-rw-r--r--WebCore/page/animation/AnimationBase.cpp183
-rw-r--r--WebCore/page/animation/AnimationBase.h30
-rw-r--r--WebCore/page/animation/AnimationController.cpp243
-rw-r--r--WebCore/page/animation/AnimationController.h19
-rw-r--r--WebCore/page/animation/AnimationControllerPrivate.h135
-rw-r--r--WebCore/page/animation/CompositeAnimation.cpp139
-rw-r--r--WebCore/page/animation/CompositeAnimation.h22
-rw-r--r--WebCore/page/animation/ImplicitAnimation.cpp77
-rw-r--r--WebCore/page/animation/ImplicitAnimation.h9
-rw-r--r--WebCore/page/animation/KeyframeAnimation.cpp180
-rw-r--r--WebCore/page/animation/KeyframeAnimation.h13
-rw-r--r--WebCore/page/chromium/AccessibilityObjectWrapper.h6
-rw-r--r--WebCore/page/chromium/EventHandlerChromium.cpp6
-rw-r--r--WebCore/page/chromium/FrameChromium.cpp2
-rw-r--r--WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp4
-rw-r--r--WebCore/page/mac/AXObjectCacheMac.mm6
-rw-r--r--WebCore/page/mac/AccessibilityObjectWrapper.h9
-rw-r--r--WebCore/page/mac/AccessibilityObjectWrapper.mm97
-rw-r--r--WebCore/page/mac/EventHandlerMac.mm6
-rw-r--r--WebCore/page/mac/FrameMac.mm9
-rw-r--r--WebCore/page/win/FrameWin.cpp2
-rw-r--r--WebCore/platform/ContentType.cpp73
-rw-r--r--WebCore/platform/ContentType.h47
-rw-r--r--WebCore/platform/ContextMenu.cpp14
-rw-r--r--WebCore/platform/CrossThreadCopier.cpp62
-rw-r--r--WebCore/platform/CrossThreadCopier.h109
-rw-r--r--WebCore/platform/FileSystem.h6
-rw-r--r--WebCore/platform/GeolocationService.cpp4
-rw-r--r--WebCore/platform/GeolocationService.h12
-rw-r--r--WebCore/platform/KURL.cpp37
-rw-r--r--WebCore/platform/KURL.h24
-rw-r--r--WebCore/platform/KURLGoogle.cpp944
-rw-r--r--WebCore/platform/KURLGooglePrivate.h115
-rw-r--r--WebCore/platform/MIMETypeRegistry.h1
-rw-r--r--WebCore/platform/PlatformWheelEvent.h35
-rw-r--r--WebCore/platform/PopupMenuStyle.h10
-rw-r--r--WebCore/platform/RunLoopTimer.h (renamed from WebCore/storage/SQLStatementErrorCallback.idl)56
-rw-r--r--WebCore/platform/ScrollView.cpp12
-rw-r--r--WebCore/platform/Scrollbar.h3
-rw-r--r--WebCore/platform/SharedTimer.h43
-rw-r--r--WebCore/platform/ThreadCheck.h14
-rw-r--r--WebCore/platform/ThreadGlobalData.cpp3
-rw-r--r--WebCore/platform/ThreadGlobalData.h3
-rw-r--r--WebCore/platform/ThreadTimers.cpp158
-rw-r--r--WebCore/platform/ThreadTimers.h69
-rw-r--r--WebCore/platform/Timer.cpp165
-rw-r--r--WebCore/platform/Timer.h17
-rw-r--r--WebCore/platform/Widget.h3
-rw-r--r--WebCore/platform/android/RenderThemeAndroid.cpp18
-rw-r--r--WebCore/platform/animation/Animation.cpp39
-rw-r--r--WebCore/platform/animation/Animation.h25
-rw-r--r--WebCore/platform/cf/RunLoopTimerCF.cpp84
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h18
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.cpp2
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.h1
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.cpp12
-rw-r--r--WebCore/platform/chromium/ClipboardChromium.h6
-rw-r--r--WebCore/platform/chromium/ClipboardChromiumLinux.cpp (renamed from WebCore/svg/graphics/cg/SVGResourceMaskerCg.cpp)17
-rw-r--r--WebCore/platform/chromium/ClipboardChromiumMac.cpp (renamed from WebCore/dom/WorkerTask.h)33
-rw-r--r--WebCore/platform/chromium/ClipboardChromiumWin.cpp56
-rw-r--r--WebCore/platform/chromium/MimeTypeRegistryChromium.cpp9
-rw-r--r--WebCore/platform/chromium/PasteboardChromium.cpp19
-rw-r--r--WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp4
-rw-r--r--WebCore/platform/chromium/PlatformWidget.h4
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.cpp156
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.h50
-rw-r--r--WebCore/platform/chromium/ScrollbarThemeChromium.cpp14
-rw-r--r--WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp154
-rw-r--r--WebCore/platform/chromium/TemporaryLinkStubs.cpp8
-rw-r--r--WebCore/platform/graphics/BitmapImage.cpp1
-rw-r--r--WebCore/platform/graphics/BitmapImage.h14
-rw-r--r--WebCore/platform/graphics/Color.cpp39
-rw-r--r--WebCore/platform/graphics/Color.h7
-rw-r--r--WebCore/platform/graphics/FloatPoint.cpp2
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.cpp2
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.h4
-rw-r--r--WebCore/platform/graphics/FontCache.cpp26
-rw-r--r--WebCore/platform/graphics/GlyphBuffer.h2
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.cpp1
-rw-r--r--WebCore/platform/graphics/GlyphWidthMap.cpp37
-rw-r--r--WebCore/platform/graphics/GlyphWidthMap.h43
-rw-r--r--WebCore/platform/graphics/Gradient.cpp8
-rw-r--r--WebCore/platform/graphics/Gradient.h10
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp40
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h39
-rw-r--r--WebCore/platform/graphics/GraphicsContextPrivate.h13
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.cpp545
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h407
-rw-r--r--WebCore/platform/graphics/GraphicsLayerClient.h69
-rw-r--r--WebCore/platform/graphics/GraphicsTypes.h8
-rw-r--r--WebCore/platform/graphics/Image.cpp4
-rw-r--r--WebCore/platform/graphics/Image.h10
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp254
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h88
-rw-r--r--WebCore/platform/graphics/MediaPlayerPrivate.h94
-rw-r--r--WebCore/platform/graphics/Pattern.h6
-rw-r--r--WebCore/platform/graphics/SimpleFontData.cpp14
-rw-r--r--WebCore/platform/graphics/SimpleFontData.h17
-rw-r--r--WebCore/platform/graphics/android/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp7
-rw-r--r--WebCore/platform/graphics/android/GraphicsContextAndroid.cpp18
-rw-r--r--WebCore/platform/graphics/android/TransformationMatrixAndroid.cpp260
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp53
-rw-r--r--WebCore/platform/graphics/cairo/GradientCairo.cpp16
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp24
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h2
-rw-r--r--WebCore/platform/graphics/cairo/ImageBufferCairo.cpp32
-rw-r--r--WebCore/platform/graphics/cairo/ImageCairo.cpp27
-rw-r--r--WebCore/platform/graphics/cairo/ImageSourceCairo.cpp2
-rw-r--r--WebCore/platform/graphics/cairo/PatternCairo.cpp13
-rw-r--r--WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp248
-rw-r--r--WebCore/platform/graphics/cg/ColorCG.cpp6
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp8
-rw-r--r--WebCore/platform/graphics/cg/ImageCG.cpp2
-rw-r--r--WebCore/platform/graphics/cg/ImageSourceCG.cpp2
-rw-r--r--WebCore/platform/graphics/cg/PatternCG.cpp7
-rw-r--r--WebCore/platform/graphics/cg/TransformationMatrixCG.cpp184
-rw-r--r--WebCore/platform/graphics/chromium/ColorChromium.cpp30
-rw-r--r--WebCore/platform/graphics/chromium/ColorChromiumMac.mm132
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp47
-rw-r--r--WebCore/platform/graphics/chromium/FontCacheLinux.cpp10
-rw-r--r--WebCore/platform/graphics/chromium/FontChromiumWin.cpp427
-rw-r--r--WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp6
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp42
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp15
-rw-r--r--WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h17
-rw-r--r--WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.cpp104
-rw-r--r--WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.h98
-rw-r--r--WebCore/platform/graphics/chromium/TransparencyWin.cpp480
-rw-r--r--WebCore/platform/graphics/chromium/TransparencyWin.h252
-rw-r--r--WebCore/platform/graphics/chromium/UniscribeHelper.cpp83
-rw-r--r--WebCore/platform/graphics/chromium/UniscribeHelper.h16
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp54
-rw-r--r--WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp59
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp113
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h48
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp27
-rw-r--r--WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp25
-rw-r--r--WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp25
-rw-r--r--WebCore/platform/graphics/mac/ColorMac.mm3
-rw-r--r--WebCore/platform/graphics/mac/FontCacheMac.mm13
-rw-r--r--WebCore/platform/graphics/mac/FontCustomPlatformData.cpp17
-rw-r--r--WebCore/platform/graphics/mac/FontCustomPlatformData.h1
-rw-r--r--WebCore/platform/graphics/mac/FontMac.mm1
-rw-r--r--WebCore/platform/graphics/mac/FontMacATSUI.mm1
-rw-r--r--WebCore/platform/graphics/mac/FontPlatformData.h18
-rw-r--r--WebCore/platform/graphics/mac/FontPlatformDataMac.mm23
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm5
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h138
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm1540
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h58
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm253
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerProxy.h118
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm1
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.h57
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.mm219
-rw-r--r--WebCore/platform/graphics/mac/WebTiledLayer.h45
-rw-r--r--WebCore/platform/graphics/mac/WebTiledLayer.mm111
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp (renamed from WebCore/platform/graphics/win/OpenTypeUtilities.cpp)25
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.h (renamed from WebCore/platform/graphics/win/OpenTypeUtilities.h)2
-rw-r--r--WebCore/platform/graphics/qt/FontPlatformDataQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp81
-rw-r--r--WebCore/platform/graphics/qt/GradientQt.cpp17
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp138
-rw-r--r--WebCore/platform/graphics/qt/ImageBufferQt.cpp107
-rw-r--r--WebCore/platform/graphics/qt/ImageQt.cpp58
-rw-r--r--WebCore/platform/graphics/qt/ImageSourceQt.cpp2
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp58
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h43
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp80
-rw-r--r--WebCore/platform/graphics/qt/PatternQt.cpp5
-rw-r--r--WebCore/platform/graphics/qt/TransformationMatrixQt.cpp167
-rw-r--r--WebCore/platform/graphics/skia/GradientSkia.cpp20
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp53
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp23
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp8
-rw-r--r--WebCore/platform/graphics/skia/ImageSourceSkia.cpp14
-rw-r--r--WebCore/platform/graphics/skia/PathSkia.cpp2
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp165
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h47
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.cpp155
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.h35
-rw-r--r--WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp189
-rw-r--r--WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp56
-rw-r--r--WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h72
-rw-r--r--WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp4
-rw-r--r--WebCore/platform/graphics/transforms/MatrixTransformOperation.h19
-rw-r--r--WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp58
-rw-r--r--WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h71
-rw-r--r--WebCore/platform/graphics/transforms/RotateTransformOperation.cpp61
-rw-r--r--WebCore/platform/graphics/transforms/RotateTransformOperation.h29
-rw-r--r--WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp9
-rw-r--r--WebCore/platform/graphics/transforms/ScaleTransformOperation.h23
-rw-r--r--WebCore/platform/graphics/transforms/TransformOperation.h26
-rw-r--r--WebCore/platform/graphics/transforms/TransformOperations.h10
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.cpp1051
-rw-r--r--WebCore/platform/graphics/transforms/TransformationMatrix.h285
-rw-r--r--WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp7
-rw-r--r--WebCore/platform/graphics/transforms/TranslateTransformOperation.h25
-rw-r--r--WebCore/platform/graphics/win/FontCGWin.cpp55
-rw-r--r--WebCore/platform/graphics/win/FontCacheWin.cpp19
-rw-r--r--WebCore/platform/graphics/win/FontCustomPlatformData.cpp14
-rw-r--r--WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp14
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp2
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextWin.cpp12
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp147
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h27
-rw-r--r--WebCore/platform/graphics/win/QTMovieWin.cpp6
-rw-r--r--WebCore/platform/graphics/win/QTMovieWinTimer.cpp26
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformData.h64
-rw-r--r--WebCore/platform/graphics/wx/FontPlatformDataWx.cpp30
-rw-r--r--WebCore/platform/graphics/wx/ImageSourceWx.cpp2
-rw-r--r--WebCore/platform/graphics/wx/ImageWx.cpp2
-rw-r--r--WebCore/platform/graphics/wx/SimpleFontDataWx.cpp24
-rw-r--r--WebCore/platform/graphics/wx/TransformationMatrixWx.cpp231
-rw-r--r--WebCore/platform/gtk/ContextMenuGtk.cpp5
-rw-r--r--WebCore/platform/gtk/ContextMenuItemGtk.cpp5
-rw-r--r--WebCore/platform/gtk/FileSystemGtk.cpp2
-rw-r--r--WebCore/platform/gtk/GeolocationServiceGtk.cpp162
-rw-r--r--WebCore/platform/gtk/GeolocationServiceGtk.h30
-rw-r--r--WebCore/platform/gtk/LoggingGtk.cpp86
-rw-r--r--WebCore/platform/gtk/PopupMenuGtk.cpp5
-rw-r--r--WebCore/platform/gtk/ScrollViewGtk.cpp4
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.cpp76
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.h4
-rw-r--r--WebCore/platform/gtk/WheelEventGtk.cpp17
-rw-r--r--WebCore/platform/gtk/WidgetGtk.cpp61
-rw-r--r--WebCore/platform/image-decoders/ImageDecoder.h9
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp48
-rw-r--r--WebCore/platform/image-decoders/skia/ImageDecoder.h7
-rw-r--r--WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp172
-rw-r--r--WebCore/platform/image-encoders/skia/PNGImageEncoder.h55
-rw-r--r--WebCore/platform/mac/FoundationExtras.h3
-rw-r--r--WebCore/platform/mac/GeolocationServiceMac.h75
-rw-r--r--WebCore/platform/mac/GeolocationServiceMac.mm209
-rw-r--r--WebCore/platform/mac/LocalCurrentGraphicsContext.h4
-rw-r--r--WebCore/platform/mac/PasteboardMac.mm12
-rw-r--r--WebCore/platform/mac/PlatformScreenMac.mm6
-rw-r--r--WebCore/platform/mac/SharedBufferMac.mm10
-rw-r--r--WebCore/platform/mac/ThreadCheck.mm62
-rw-r--r--WebCore/platform/mac/WebCoreSystemInterface.h9
-rw-r--r--WebCore/platform/mac/WebCoreSystemInterface.mm1
-rw-r--r--WebCore/platform/mac/WebCoreTextRenderer.h9
-rw-r--r--WebCore/platform/mac/WebCoreTextRenderer.mm1
-rw-r--r--WebCore/platform/mac/WebFontCache.h3
-rw-r--r--WebCore/platform/mac/WebFontCache.mm2
-rw-r--r--WebCore/platform/mac/WheelEventMac.mm14
-rw-r--r--WebCore/platform/network/FormData.cpp6
-rw-r--r--WebCore/platform/network/FormData.h8
-rw-r--r--WebCore/platform/network/HTTPHeaderMap.cpp2
-rw-r--r--WebCore/platform/network/HTTPParsers.cpp9
-rw-r--r--WebCore/platform/network/ResourceErrorBase.cpp17
-rw-r--r--WebCore/platform/network/ResourceErrorBase.h7
-rw-r--r--WebCore/platform/network/ResourceHandle.h12
-rw-r--r--WebCore/platform/network/ResourceHandleClient.h6
-rw-r--r--WebCore/platform/network/ResourceHandleInternal.h13
-rw-r--r--WebCore/platform/network/ResourceRequestBase.cpp23
-rw-r--r--WebCore/platform/network/ResourceRequestBase.h12
-rw-r--r--WebCore/platform/network/ResourceResponseBase.cpp4
-rw-r--r--WebCore/platform/network/ResourceResponseBase.h9
-rw-r--r--WebCore/platform/network/cf/FormDataStreamCFNet.cpp88
-rw-r--r--WebCore/platform/network/cf/ResourceHandleCFNet.cpp93
-rw-r--r--WebCore/platform/network/cf/ResourceRequestCFNet.h2
-rw-r--r--WebCore/platform/network/cf/ResourceResponse.h12
-rw-r--r--WebCore/platform/network/chromium/ResourceRequest.h53
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp4
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.mm2
-rw-r--r--WebCore/platform/network/mac/ResourceErrorMac.mm7
-rw-r--r--WebCore/platform/network/mac/ResourceRequestMac.mm4
-rw-r--r--WebCore/platform/network/mac/ResourceResponse.h12
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp4
-rw-r--r--WebCore/platform/network/soup/CookieJarSoup.cpp33
-rw-r--r--WebCore/platform/network/soup/CookieJarSoup.h3
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp497
-rw-r--r--WebCore/platform/network/win/CookieJarCFNetWin.cpp24
-rw-r--r--WebCore/platform/qt/CookieJarQt.cpp2
-rw-r--r--WebCore/platform/qt/FileSystemQt.cpp28
-rw-r--r--WebCore/platform/qt/KURLQt.cpp3
-rw-r--r--WebCore/platform/qt/PlatformKeyboardEventQt.cpp49
-rw-r--r--WebCore/platform/qt/QWebPopup.cpp14
-rw-r--r--WebCore/platform/qt/RenderThemeQt.cpp4
-rw-r--r--WebCore/platform/qt/RenderThemeQt.h2
-rw-r--r--WebCore/platform/qt/WheelEventQt.cpp16
-rw-r--r--WebCore/platform/text/AtomicString.cpp2
-rw-r--r--WebCore/platform/text/Base64.cpp6
-rw-r--r--WebCore/platform/text/BidiResolver.h19
-rw-r--r--WebCore/platform/text/CString.cpp25
-rw-r--r--WebCore/platform/text/CString.h17
-rw-r--r--WebCore/platform/text/PlatformString.h12
-rw-r--r--WebCore/platform/text/String.cpp9
-rw-r--r--WebCore/platform/text/StringImpl.cpp87
-rw-r--r--WebCore/platform/text/StringImpl.h40
-rw-r--r--WebCore/platform/text/TextBreakIterator.h12
-rw-r--r--WebCore/platform/text/TextBreakIteratorICU.cpp116
-rw-r--r--WebCore/platform/text/TextCodecICU.cpp2
-rw-r--r--WebCore/platform/text/TextDecoder.cpp129
-rw-r--r--WebCore/platform/text/TextDecoder.h64
-rw-r--r--WebCore/platform/text/TextEncoding.cpp26
-rw-r--r--WebCore/platform/text/TextEncoding.h11
-rw-r--r--WebCore/platform/text/TextEncodingDetector.h48
-rw-r--r--WebCore/platform/text/TextEncodingDetectorICU.cpp129
-rw-r--r--WebCore/platform/text/TextEncodingDetectorNone.cpp51
-rw-r--r--WebCore/platform/text/TextEncodingRegistry.h7
-rw-r--r--WebCore/platform/text/cf/StringImplCF.cpp131
-rw-r--r--WebCore/platform/text/mac/ShapeArabic.c2
-rw-r--r--WebCore/platform/text/mac/StringImplMac.mm8
-rw-r--r--WebCore/platform/text/mac/StringMac.mm1
-rw-r--r--WebCore/platform/text/qt/TextBreakIteratorQt.cpp10
-rw-r--r--WebCore/platform/win/FileSystemWin.cpp6
-rw-r--r--WebCore/platform/win/PopupMenuWin.cpp5
-rw-r--r--WebCore/platform/win/WheelEventWin.cpp55
-rw-r--r--WebCore/platform/wx/MouseWheelEventWx.cpp7
-rw-r--r--WebCore/platform/wx/wxcode/fontprops.h3
-rw-r--r--WebCore/platform/wx/wxcode/gtk/fontprops.cpp71
-rw-r--r--WebCore/platform/wx/wxcode/gtk/non-kerned-drawing.cpp185
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp11
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp7
-rw-r--r--WebCore/platform/wx/wxcode/non-kerned-drawing.h21
-rw-r--r--WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp4
-rw-r--r--WebCore/plugins/PluginDataNone.cpp (renamed from WebCore/plugins/wx/PluginDataWx.cpp)0
-rw-r--r--WebCore/plugins/PluginPackage.cpp3
-rw-r--r--WebCore/plugins/PluginPackageNone.cpp (renamed from WebCore/plugins/wx/PluginPackageWx.cpp)6
-rw-r--r--WebCore/plugins/PluginView.cpp7
-rw-r--r--WebCore/plugins/PluginView.h12
-rw-r--r--WebCore/plugins/PluginViewNone.cpp (renamed from WebCore/plugins/wx/PluginViewWx.cpp)18
-rw-r--r--WebCore/plugins/gtk/PluginPackageGtk.cpp2
-rw-r--r--WebCore/plugins/gtk/PluginViewGtk.cpp117
-rw-r--r--WebCore/plugins/mac/PluginViewMac.cpp15
-rw-r--r--WebCore/plugins/npfunctions.h7
-rw-r--r--WebCore/plugins/qt/PluginViewQt.cpp7
-rw-r--r--WebCore/plugins/win/PluginPackageWin.cpp5
-rw-r--r--WebCore/rendering/EllipsisBox.cpp17
-rw-r--r--WebCore/rendering/EllipsisBox.h11
-rw-r--r--WebCore/rendering/HitTestRequest.h34
-rw-r--r--WebCore/rendering/InlineBox.cpp53
-rw-r--r--WebCore/rendering/InlineBox.h72
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp464
-rw-r--r--WebCore/rendering/InlineFlowBox.h56
-rw-r--r--WebCore/rendering/InlineTextBox.cpp213
-rw-r--r--WebCore/rendering/InlineTextBox.h10
-rw-r--r--WebCore/rendering/LayoutState.cpp7
-rw-r--r--WebCore/rendering/ListMarkerBox.cpp2
-rw-r--r--WebCore/rendering/MediaControlElements.cpp87
-rw-r--r--WebCore/rendering/MediaControlElements.h10
-rw-r--r--WebCore/rendering/PointerEventsHitRules.h2
-rw-r--r--WebCore/rendering/RenderBR.cpp15
-rw-r--r--WebCore/rendering/RenderBR.h8
-rw-r--r--WebCore/rendering/RenderBlock.cpp1315
-rw-r--r--WebCore/rendering/RenderBlock.h176
-rw-r--r--WebCore/rendering/RenderBox.cpp1207
-rw-r--r--WebCore/rendering/RenderBox.h157
-rw-r--r--WebCore/rendering/RenderBoxModelObject.cpp1111
-rw-r--r--WebCore/rendering/RenderBoxModelObject.h133
-rw-r--r--WebCore/rendering/RenderButton.cpp27
-rw-r--r--WebCore/rendering/RenderButton.h22
-rw-r--r--WebCore/rendering/RenderContainer.cpp726
-rw-r--r--WebCore/rendering/RenderContainer.h82
-rw-r--r--WebCore/rendering/RenderCounter.cpp15
-rw-r--r--WebCore/rendering/RenderCounter.h1
-rw-r--r--WebCore/rendering/RenderFieldset.cpp18
-rw-r--r--WebCore/rendering/RenderFieldset.h2
-rw-r--r--WebCore/rendering/RenderFileUploadControl.cpp7
-rw-r--r--WebCore/rendering/RenderFileUploadControl.h2
-rw-r--r--WebCore/rendering/RenderFlexibleBox.cpp74
-rw-r--r--WebCore/rendering/RenderFlow.cpp744
-rw-r--r--WebCore/rendering/RenderFlow.h145
-rw-r--r--WebCore/rendering/RenderForeignObject.cpp24
-rw-r--r--WebCore/rendering/RenderForeignObject.h2
-rw-r--r--WebCore/rendering/RenderFrame.h2
-rw-r--r--WebCore/rendering/RenderFrameSet.cpp23
-rw-r--r--WebCore/rendering/RenderFrameSet.h12
-rw-r--r--WebCore/rendering/RenderHTMLCanvas.cpp1
-rw-r--r--WebCore/rendering/RenderImage.cpp57
-rw-r--r--WebCore/rendering/RenderImage.h16
-rw-r--r--WebCore/rendering/RenderImageGeneratedContent.h14
-rw-r--r--WebCore/rendering/RenderInline.cpp772
-rw-r--r--WebCore/rendering/RenderInline.h108
-rw-r--r--WebCore/rendering/RenderLayer.cpp1214
-rw-r--r--WebCore/rendering/RenderLayer.h212
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp1067
-rw-r--r--WebCore/rendering/RenderLayerBacking.h178
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp803
-rw-r--r--WebCore/rendering/RenderLayerCompositor.h140
-rw-r--r--WebCore/rendering/RenderLegend.cpp36
-rw-r--r--WebCore/rendering/RenderLegend.h42
-rw-r--r--WebCore/rendering/RenderLineBoxList.cpp333
-rw-r--r--WebCore/rendering/RenderLineBoxList.h86
-rw-r--r--WebCore/rendering/RenderListBox.cpp31
-rw-r--r--WebCore/rendering/RenderListBox.h4
-rw-r--r--WebCore/rendering/RenderListItem.cpp14
-rw-r--r--WebCore/rendering/RenderListItem.h2
-rw-r--r--WebCore/rendering/RenderListMarker.cpp31
-rw-r--r--WebCore/rendering/RenderListMarker.h10
-rw-r--r--WebCore/rendering/RenderMarquee.cpp29
-rw-r--r--WebCore/rendering/RenderMarquee.h3
-rw-r--r--WebCore/rendering/RenderMedia.cpp62
-rw-r--r--WebCore/rendering/RenderMedia.h13
-rw-r--r--WebCore/rendering/RenderMenuList.cpp30
-rw-r--r--WebCore/rendering/RenderMenuList.h2
-rw-r--r--WebCore/rendering/RenderObject.cpp1810
-rw-r--r--WebCore/rendering/RenderObject.h505
-rw-r--r--WebCore/rendering/RenderObjectChildList.cpp426
-rw-r--r--WebCore/rendering/RenderObjectChildList.h67
-rw-r--r--WebCore/rendering/RenderPart.cpp33
-rw-r--r--WebCore/rendering/RenderPart.h6
-rw-r--r--WebCore/rendering/RenderPartObject.cpp59
-rw-r--r--WebCore/rendering/RenderPartObject.h2
-rw-r--r--WebCore/rendering/RenderPath.cpp28
-rw-r--r--WebCore/rendering/RenderPath.h4
-rw-r--r--WebCore/rendering/RenderReplaced.cpp114
-rw-r--r--WebCore/rendering/RenderReplaced.h16
-rw-r--r--WebCore/rendering/RenderReplica.cpp8
-rw-r--r--WebCore/rendering/RenderSVGContainer.cpp157
-rw-r--r--WebCore/rendering/RenderSVGContainer.h30
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.cpp4
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.h9
-rw-r--r--WebCore/rendering/RenderSVGHiddenContainer.cpp2
-rw-r--r--WebCore/rendering/RenderSVGHiddenContainer.h2
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp21
-rw-r--r--WebCore/rendering/RenderSVGImage.h2
-rw-r--r--WebCore/rendering/RenderSVGInline.cpp23
-rw-r--r--WebCore/rendering/RenderSVGInline.h14
-rw-r--r--WebCore/rendering/RenderSVGInlineText.cpp58
-rw-r--r--WebCore/rendering/RenderSVGInlineText.h10
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp83
-rw-r--r--WebCore/rendering/RenderSVGRoot.h14
-rw-r--r--WebCore/rendering/RenderSVGTSpan.cpp12
-rw-r--r--WebCore/rendering/RenderSVGText.cpp48
-rw-r--r--WebCore/rendering/RenderSVGText.h6
-rw-r--r--WebCore/rendering/RenderSVGTextPath.cpp20
-rw-r--r--WebCore/rendering/RenderSVGTransformableContainer.cpp2
-rw-r--r--WebCore/rendering/RenderSVGViewportContainer.cpp30
-rw-r--r--WebCore/rendering/RenderScrollbar.cpp14
-rw-r--r--WebCore/rendering/RenderScrollbar.h5
-rw-r--r--WebCore/rendering/RenderScrollbarPart.cpp6
-rw-r--r--WebCore/rendering/RenderScrollbarPart.h4
-rw-r--r--WebCore/rendering/RenderSelectionInfo.h104
-rw-r--r--WebCore/rendering/RenderSlider.cpp397
-rw-r--r--WebCore/rendering/RenderSlider.h41
-rw-r--r--WebCore/rendering/RenderTable.cpp145
-rw-r--r--WebCore/rendering/RenderTable.h39
-rw-r--r--WebCore/rendering/RenderTableCell.cpp102
-rw-r--r--WebCore/rendering/RenderTableCell.h13
-rw-r--r--WebCore/rendering/RenderTableCol.cpp12
-rw-r--r--WebCore/rendering/RenderTableCol.h12
-rw-r--r--WebCore/rendering/RenderTableRow.cpp35
-rw-r--r--WebCore/rendering/RenderTableRow.h17
-rw-r--r--WebCore/rendering/RenderTableSection.cpp128
-rw-r--r--WebCore/rendering/RenderTableSection.h19
-rw-r--r--WebCore/rendering/RenderText.cpp253
-rw-r--r--WebCore/rendering/RenderText.h34
-rw-r--r--WebCore/rendering/RenderTextControl.cpp109
-rw-r--r--WebCore/rendering/RenderTextControl.h38
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.cpp52
-rw-r--r--WebCore/rendering/RenderTextControlMultiLine.h1
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp120
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h20
-rw-r--r--WebCore/rendering/RenderTextFragment.cpp4
-rw-r--r--WebCore/rendering/RenderTheme.cpp52
-rw-r--r--WebCore/rendering/RenderTheme.h12
-rw-r--r--WebCore/rendering/RenderThemeChromiumGtk.cpp532
-rw-r--r--WebCore/rendering/RenderThemeChromiumLinux.cpp421
-rw-r--r--WebCore/rendering/RenderThemeChromiumLinux.h (renamed from WebCore/rendering/RenderThemeChromiumGtk.h)30
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.h3
-rw-r--r--WebCore/rendering/RenderThemeChromiumMac.mm17
-rw-r--r--WebCore/rendering/RenderThemeChromiumWin.cpp197
-rw-r--r--WebCore/rendering/RenderThemeChromiumWin.h12
-rw-r--r--WebCore/rendering/RenderThemeMac.h2
-rw-r--r--WebCore/rendering/RenderThemeMac.mm32
-rw-r--r--WebCore/rendering/RenderThemeSafari.cpp9
-rw-r--r--WebCore/rendering/RenderThemeWin.cpp33
-rw-r--r--WebCore/rendering/RenderThemeWin.h8
-rw-r--r--WebCore/rendering/RenderTreeAsText.cpp66
-rw-r--r--WebCore/rendering/RenderVideo.cpp5
-rw-r--r--WebCore/rendering/RenderView.cpp220
-rw-r--r--WebCore/rendering/RenderView.h72
-rw-r--r--WebCore/rendering/RenderWidget.cpp67
-rw-r--r--WebCore/rendering/RenderWidget.h4
-rw-r--r--WebCore/rendering/RootInlineBox.cpp110
-rw-r--r--WebCore/rendering/RootInlineBox.h33
-rw-r--r--WebCore/rendering/SVGCharacterLayoutInfo.cpp4
-rw-r--r--WebCore/rendering/SVGInlineFlowBox.h7
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp75
-rw-r--r--WebCore/rendering/SVGInlineTextBox.h5
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp6
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp22
-rw-r--r--WebCore/rendering/SVGRootInlineBox.cpp109
-rw-r--r--WebCore/rendering/SVGRootInlineBox.h5
-rw-r--r--WebCore/rendering/ScrollBehavior.cpp55
-rw-r--r--WebCore/rendering/ScrollBehavior.h78
-rw-r--r--WebCore/rendering/TextControlInnerElements.cpp37
-rw-r--r--WebCore/rendering/TransformState.cpp162
-rw-r--r--WebCore/rendering/TransformState.h132
-rw-r--r--WebCore/rendering/bidi.cpp272
-rw-r--r--WebCore/rendering/style/ContentData.cpp58
-rw-r--r--WebCore/rendering/style/ContentData.h50
-rw-r--r--WebCore/rendering/style/CounterContent.h8
-rw-r--r--WebCore/rendering/style/RenderStyle.cpp225
-rw-r--r--WebCore/rendering/style/RenderStyle.h85
-rw-r--r--WebCore/rendering/style/RenderStyleConstants.h53
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp2
-rw-r--r--WebCore/rendering/style/StyleInheritedData.cpp2
-rw-r--r--WebCore/rendering/style/StyleRareInheritedData.cpp2
-rw-r--r--WebCore/rendering/style/StyleRareNonInheritedData.cpp50
-rw-r--r--WebCore/rendering/style/StyleRareNonInheritedData.h13
-rw-r--r--WebCore/rendering/style/StyleTransformData.cpp4
-rw-r--r--WebCore/rendering/style/StyleTransformData.h1
-rw-r--r--WebCore/storage/Database.cpp11
-rw-r--r--WebCore/storage/DatabaseThread.cpp2
-rw-r--r--WebCore/storage/LocalStorageArea.cpp5
-rw-r--r--WebCore/storage/LocalStorageThread.cpp2
-rw-r--r--WebCore/storage/SQLError.idl2
-rw-r--r--WebCore/storage/SQLResultSet.idl4
-rw-r--r--WebCore/storage/SessionStorageArea.cpp5
-rw-r--r--WebCore/svg/SVGAnimateMotionElement.cpp4
-rw-r--r--WebCore/svg/SVGElementInstance.h2
-rw-r--r--WebCore/svg/SVGFont.cpp8
-rw-r--r--WebCore/svg/SVGImageLoader.cpp16
-rw-r--r--WebCore/svg/SVGLength.cpp2
-rw-r--r--WebCore/svg/SVGLinearGradientElement.cpp2
-rw-r--r--WebCore/svg/SVGPathSegList.idl14
-rw-r--r--WebCore/svg/SVGPointList.idl14
-rw-r--r--WebCore/svg/SVGPreserveAspectRatio.cpp6
-rw-r--r--WebCore/svg/SVGRadialGradientElement.cpp2
-rw-r--r--WebCore/svg/SVGSVGElement.cpp8
-rw-r--r--WebCore/svg/SVGStyledElement.cpp2
-rw-r--r--WebCore/svg/SVGTextContentElement.cpp8
-rw-r--r--WebCore/svg/SVGTransform.cpp12
-rw-r--r--WebCore/svg/SVGTransformDistance.cpp4
-rw-r--r--WebCore/svg/SVGTransformList.idl14
-rw-r--r--WebCore/svg/SVGUseElement.cpp8
-rw-r--r--WebCore/svg/graphics/SVGImage.cpp10
-rw-r--r--WebCore/svg/graphics/SVGPaintServer.cpp18
-rw-r--r--WebCore/svg/graphics/SVGPaintServerGradient.cpp71
-rw-r--r--WebCore/svg/graphics/SVGPaintServerGradient.h4
-rw-r--r--WebCore/svg/graphics/SVGPaintServerPattern.cpp7
-rw-r--r--WebCore/svg/graphics/SVGResourceClipper.cpp2
-rw-r--r--WebCore/svg/graphics/SVGResourceMarker.cpp6
-rw-r--r--WebCore/svg/graphics/SVGResourceMasker.cpp47
-rw-r--r--WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp48
-rw-r--r--WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm128
-rw-r--r--WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm2
-rw-r--r--WebCore/svg/graphics/qt/SVGResourceMaskerQt.cpp38
-rw-r--r--WebCore/webcore-base.bkl6
-rw-r--r--WebCore/webcore-wx.bkl8
-rw-r--r--WebCore/wml/WMLAElement.cpp15
-rw-r--r--WebCore/wml/WMLFormControlElement.cpp20
-rw-r--r--WebCore/wml/WMLFormControlElement.h5
-rw-r--r--WebCore/wml/WMLGoElement.cpp2
-rw-r--r--WebCore/wml/WMLImageElement.cpp4
-rw-r--r--WebCore/wml/WMLImageLoader.cpp4
-rw-r--r--WebCore/wml/WMLInputElement.cpp225
-rw-r--r--WebCore/wml/WMLInputElement.h11
-rw-r--r--WebCore/wml/WMLInsertedLegendElement.cpp7
-rw-r--r--WebCore/wml/WMLInsertedLegendElement.h2
-rw-r--r--WebCore/wml/WMLOptGroupElement.cpp1
-rw-r--r--WebCore/wml/WMLOptionElement.cpp1
-rw-r--r--WebCore/wml/WMLTableElement.cpp2
-rw-r--r--WebCore/workers/GenericWorkerTask.h415
-rw-r--r--WebCore/workers/Worker.cpp (renamed from WebCore/dom/Worker.cpp)63
-rw-r--r--WebCore/workers/Worker.h (renamed from WebCore/dom/Worker.h)16
-rw-r--r--WebCore/workers/Worker.idl (renamed from WebCore/dom/Worker.idl)0
-rw-r--r--WebCore/workers/WorkerContext.cpp (renamed from WebCore/dom/WorkerContext.cpp)122
-rw-r--r--WebCore/workers/WorkerContext.h (renamed from WebCore/dom/WorkerContext.h)12
-rw-r--r--WebCore/workers/WorkerContext.idl (renamed from WebCore/dom/WorkerContext.idl)10
-rw-r--r--WebCore/workers/WorkerContextProxy.h (renamed from WebCore/dom/WorkerRunLoop.h)46
-rw-r--r--WebCore/workers/WorkerImportScriptsClient.cpp96
-rw-r--r--WebCore/workers/WorkerImportScriptsClient.h77
-rw-r--r--WebCore/workers/WorkerLocation.cpp (renamed from WebCore/dom/WorkerLocation.cpp)4
-rw-r--r--WebCore/workers/WorkerLocation.h (renamed from WebCore/dom/WorkerLocation.h)0
-rw-r--r--WebCore/workers/WorkerLocation.idl (renamed from WebCore/dom/WorkerLocation.idl)0
-rw-r--r--WebCore/workers/WorkerMessagingProxy.cpp (renamed from WebCore/dom/WorkerMessagingProxy.cpp)111
-rw-r--r--WebCore/workers/WorkerMessagingProxy.h (renamed from WebCore/dom/WorkerMessagingProxy.h)52
-rw-r--r--WebCore/workers/WorkerObjectProxy.h64
-rw-r--r--WebCore/workers/WorkerRunLoop.cpp210
-rw-r--r--WebCore/workers/WorkerRunLoop.h82
-rw-r--r--WebCore/workers/WorkerThread.cpp (renamed from WebCore/dom/WorkerThread.cpp)17
-rw-r--r--WebCore/workers/WorkerThread.h (renamed from WebCore/dom/WorkerThread.h)14
-rw-r--r--WebCore/xml/XMLHttpRequest.cpp395
-rw-r--r--WebCore/xml/XMLHttpRequest.h23
-rw-r--r--WebCore/xml/XMLHttpRequest.idl3
-rw-r--r--WebCore/xml/XMLHttpRequestException.idl3
-rw-r--r--WebCore/xml/XMLHttpRequestProgressEvent.idl3
-rw-r--r--WebCore/xml/XMLHttpRequestUpload.cpp6
-rw-r--r--WebCore/xml/XMLHttpRequestUpload.h2
-rw-r--r--WebCore/xml/XMLHttpRequestUpload.idl3
-rw-r--r--WebCore/xml/XPathExpression.cpp4
-rw-r--r--WebCore/xml/XPathFunctions.cpp16
-rw-r--r--WebCore/xml/XPathNodeSet.cpp2
-rw-r--r--WebCore/xml/XPathResult.cpp4
-rw-r--r--WebCore/xml/XPathResult.h8
-rw-r--r--WebCore/xml/XPathStep.cpp8
-rw-r--r--WebKit/android/RenderSkinCombo.cpp8
-rw-r--r--WebKit/android/RenderSkinRadio.cpp17
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp16
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h7
-rw-r--r--WebKit/android/WebCoreSupport/InspectorClientAndroid.h1
-rw-r--r--WebKit/android/jni/JavaBridge.cpp7
-rw-r--r--WebKit/android/jni/WebHistory.cpp1
-rw-r--r--WebKit/android/jni/WebSettings.cpp4
-rw-r--r--WebKit/android/jni/WebViewCore.cpp8
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp147
-rw-r--r--WebKit/android/nav/CacheBuilder.h4
1329 files changed, 87765 insertions, 30005 deletions
diff --git a/Android.mk b/Android.mk
index cebfb23..c6f98fe 100644
--- a/Android.mk
+++ b/Android.mk
@@ -136,6 +136,7 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/WebCore/rendering \
$(LOCAL_PATH)/WebCore/rendering/style \
$(LOCAL_PATH)/WebCore/storage \
+ $(LOCAL_PATH)/WebCore/workers \
$(LOCAL_PATH)/WebCore/xml \
$(LOCAL_PATH)/WebKit/android \
$(LOCAL_PATH)/WebKit/android/WebCoreSupport \
diff --git a/JavaScriptCore/API/JSBase.cpp b/JavaScriptCore/API/JSBase.cpp
index 2ffe345..422b296 100644
--- a/JavaScriptCore/API/JSBase.cpp
+++ b/JavaScriptCore/API/JSBase.cpp
@@ -58,7 +58,7 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
*exception = toRef(completion.value());
return 0;
}
-
+
if (completion.value())
return toRef(completion.value());
diff --git a/JavaScriptCore/API/JSBasePrivate.h b/JavaScriptCore/API/JSBasePrivate.h
index 6beacda..befa316 100644
--- a/JavaScriptCore/API/JSBasePrivate.h
+++ b/JavaScriptCore/API/JSBasePrivate.h
@@ -43,7 +43,7 @@ owns a large non-GC memory region. Calling this function will encourage the
garbage collector to collect soon, hoping to reclaim that large non-GC memory
region.
*/
-JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_IN_WEBKIT_VERSION_4_0;
#ifdef __cplusplus
}
diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h
index 23f941d..d6ae9bd 100644
--- a/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -99,7 +99,7 @@ template <class Base>
UString JSCallbackObject<Base>::className() const
{
UString thisClassName = classRef()->className();
- if (!thisClassName.isNull())
+ if (!thisClassName.isEmpty())
return thisClassName;
return Base::className();
@@ -126,10 +126,17 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
- if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) {
+ JSValueRef exception = 0;
+ JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+ exec->setException(toJS(exception));
+ if (value) {
slot.setValue(toJS(value));
return true;
}
+ if (exception) {
+ slot.setValue(jsUndefined());
+ return true;
+ }
}
if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) {
@@ -169,7 +176,10 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
- if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
+ JSValueRef exception = 0;
+ bool result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ exec->setException(toJS(exception));
+ if (result || exception)
return;
}
@@ -181,7 +191,10 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
- if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
+ JSValueRef exception = 0;
+ bool result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+ exec->setException(toJS(exception));
+ if (result || exception)
return;
} else
throwError(exec, ReferenceError, "Attempt to set a property that is not settable.");
@@ -213,7 +226,10 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
- if (deleteProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
+ JSValueRef exception = 0;
+ bool result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+ exec->setException(toJS(exception));
+ if (result || exception)
return true;
}
@@ -268,7 +284,10 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct
for (int i = 0; i < argumentCount; i++)
arguments[i] = toRef(args.at(exec, i));
JSLock::DropAllLocks dropAllLocks(exec);
- return toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+ JSValueRef exception = 0;
+ JSObject* result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
+ exec->setException(toJS(exception));
+ return result;
}
}
@@ -285,7 +304,10 @@ bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValuePtr value, JSVa
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
JSLock::DropAllLocks dropAllLocks(exec);
- return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot()));
+ JSValueRef exception = 0;
+ bool result = hasInstance(execRef, thisRef, toRef(value), &exception);
+ exec->setException(toJS(exception));
+ return result;
}
}
return false;
@@ -317,7 +339,10 @@ JSValuePtr JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObjec
for (int i = 0; i < argumentCount; i++)
arguments[i] = toRef(args.at(exec, i));
JSLock::DropAllLocks dropAllLocks(exec);
- return toJS(callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+ JSValueRef exception = 0;
+ JSValuePtr result = toJS(callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
+ exec->setException(toJS(exception));
+ return result;
}
}
@@ -377,7 +402,11 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
JSLock::DropAllLocks dropAllLocks(exec);
- if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot()))) {
+
+ JSValueRef exception = 0;
+ JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, &exception);
+ exec->setException(toJS(exception));
+ if (value) {
double dValue;
return toJS(value).getNumber(dValue) ? dValue : NaN;
}
@@ -395,12 +424,16 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const
for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
JSValueRef value;
+ JSValueRef exception = 0;
{
JSLock::DropAllLocks dropAllLocks(exec);
- value = convertToType(ctx, thisRef, kJSTypeString, toRef(exec->exceptionSlot()));
+ value = convertToType(ctx, thisRef, kJSTypeString, &exception);
+ exec->setException(toJS(exception));
}
if (value)
return toJS(value).getString();
+ if (exception)
+ return "";
}
return Base::toString(exec);
@@ -443,8 +476,13 @@ JSValuePtr JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Iden
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
- if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
+ JSValueRef exception = 0;
+ JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+ exec->setException(toJS(exception));
+ if (value)
return toJS(value);
+ if (exception)
+ return jsUndefined();
}
return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback.");
@@ -488,8 +526,14 @@ JSValuePtr JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identif
if (!propertyNameRef)
propertyNameRef = OpaqueJSString::create(propertyName.ustring());
JSLock::DropAllLocks dropAllLocks(exec);
- if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
+
+ JSValueRef exception = 0;
+ JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+ exec->setException(toJS(exception));
+ if (value)
return toJS(value);
+ if (exception)
+ return jsUndefined();
}
return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist.");
diff --git a/JavaScriptCore/API/JSContextRef.h b/JavaScriptCore/API/JSContextRef.h
index bc89511..c5c8a71 100644
--- a/JavaScriptCore/API/JSContextRef.h
+++ b/JavaScriptCore/API/JSContextRef.h
@@ -48,7 +48,7 @@ extern "C" {
synchronization is required.
@result The created JSContextGroup.
*/
-JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@@ -56,14 +56,14 @@ JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_AFTER_WEBKIT_VERSIO
@param group The JSContextGroup to retain.
@result A JSContextGroup that is the same as group.
*/
-JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@abstract Releases a JavaScript context group.
@param group The JSContextGroup to release.
*/
-JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@@ -92,7 +92,7 @@ JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
@result A JSGlobalContext with a global object of class globalObjectClass and a context
group equal to group.
*/
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@@ -123,7 +123,7 @@ JS_EXPORT JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);
@param ctx The JSContext whose group you want to get.
@result ctx's group.
*/
-JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) AVAILABLE_IN_WEBKIT_VERSION_4_0;
#ifdef __cplusplus
}
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
index 67bb2a5..e81e512 100644
--- a/JavaScriptCore/API/JSObjectRef.cpp
+++ b/JavaScriptCore/API/JSObjectRef.cpp
@@ -467,7 +467,7 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o
jsObject->getPropertyNames(exec, array);
size_t size = array.size();
- propertyNames->array.reserveCapacity(size);
+ propertyNames->array.reserveInitialCapacity(size);
for (size_t i = 0; i < size; ++i)
propertyNames->array.append(JSRetainPtr<JSStringRef>(Adopt, OpaqueJSString::create(array[i].ustring()).releaseRef()));
diff --git a/JavaScriptCore/API/JSObjectRef.h b/JavaScriptCore/API/JSObjectRef.h
index 461764c..3e8b0eb 100644
--- a/JavaScriptCore/API/JSObjectRef.h
+++ b/JavaScriptCore/API/JSObjectRef.h
@@ -441,7 +441,7 @@ JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsCla
@discussion The behavior of this function does not exactly match the behavior of the built-in Array constructor. Specifically, if one argument
is supplied, this function returns an array with one element.
*/
-JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@@ -452,7 +452,7 @@ JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount,
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
@result A JSObject that is a Date.
*/
-JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@@ -463,7 +463,7 @@ JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, c
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
@result A JSObject that is a Error.
*/
-JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
@@ -474,7 +474,7 @@ JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount,
@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
@result A JSObject that is a RegExp.
*/
-JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
/*!
@function
diff --git a/JavaScriptCore/API/WebKitAvailability.h b/JavaScriptCore/API/WebKitAvailability.h
index 1273360..8402528 100644
--- a/JavaScriptCore/API/WebKitAvailability.h
+++ b/JavaScriptCore/API/WebKitAvailability.h
@@ -38,6 +38,7 @@
#define WEBKIT_VERSION_2_0 0x0200
#define WEBKIT_VERSION_3_0 0x0300
#define WEBKIT_VERSION_3_1 0x0310
+#define WEBKIT_VERSION_4_0 0x0400
#define WEBKIT_VERSION_LATEST 0x9999
#ifdef __APPLE__
@@ -640,123 +641,123 @@
/*
- * AVAILABLE_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_IN_WEBKIT_VERSION_4_0
*
- * Used on declarations introduced after WebKit 3.1
+ * Used on declarations introduced in WebKit 4.0
*/
#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST
- #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1 UNAVAILABLE_ATTRIBUTE
+ #define AVAILABLE_IN_WEBKIT_VERSION_4_0 UNAVAILABLE_ATTRIBUTE
#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST
- #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1 WEAK_IMPORT_ATTRIBUTE
+ #define AVAILABLE_IN_WEBKIT_VERSION_4_0 WEAK_IMPORT_ATTRIBUTE
#else
- #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1
+ #define AVAILABLE_IN_WEBKIT_VERSION_4_0
#endif
/*
- * AVAILABLE_AFTER_WEBKIT_VERSION_3_1_BUT_DEPRECATED
+ * AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED
*
- * Used on declarations introduced after WebKit 3.1,
- * and deprecated after WebKit 3.1
+ * Used on declarations introduced in WebKit 4.0,
+ * and deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1_BUT_DEPRECATED AVAILABLE_AFTER_WEBKIT_VERSION_3_1
+ #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED AVAILABLE_IN_WEBKIT_VERSION_4_0
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 1.0,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 1.1,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 1.2,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 1.3,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 2.0,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 3.0,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
#endif
/*
- * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
*
* Used on declarations introduced in WebKit 3.1,
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1 AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
+ #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0 AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
#endif
/*
- * DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * DEPRECATED_IN_WEBKIT_VERSION_4_0
*
- * Used on types deprecated after WebKit 3.1
+ * Used on types deprecated in WebKit 4.0
*/
#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
- #define DEPRECATED_AFTER_WEBKIT_VERSION_3_1 DEPRECATED_ATTRIBUTE
+ #define DEPRECATED_IN_WEBKIT_VERSION_4_0 DEPRECATED_ATTRIBUTE
#else
- #define DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ #define DEPRECATED_IN_WEBKIT_VERSION_4_0
#endif
diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c
index 48c8583..bbcf1e7 100644
--- a/JavaScriptCore/API/tests/testapi.c
+++ b/JavaScriptCore/API/tests/testapi.c
@@ -26,6 +26,7 @@
#include "JavaScriptCore.h"
#include "JSBasePrivate.h"
#include <math.h>
+#define ASSERT_DISABLED 0
#include <wtf/Assertions.h>
#include <wtf/UnusedParam.h>
@@ -41,11 +42,13 @@ static double nan(const char*)
#endif
static JSGlobalContextRef context = 0;
-
+static int failed = 0;
static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
{
- if (JSValueToBoolean(context, value) != expectedValue)
+ if (JSValueToBoolean(context, value) != expectedValue) {
fprintf(stderr, "assertEqualsAsBoolean failed: %p, %d\n", value, expectedValue);
+ failed = 1;
+ }
}
static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
@@ -55,8 +58,10 @@ static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
// FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
// causing a build break with -Wshorten-64-to-32 enabled. The issue is known by the appropriate team.
// After that's resolved, we can remove these casts
- if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue)))
+ if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue))) {
fprintf(stderr, "assertEqualsAsNumber failed: %p, %lf\n", value, expectedValue);
+ failed = 1;
+ }
}
static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
@@ -68,12 +73,17 @@ static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue
JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize);
unsigned i;
- for (i = 0; jsBuffer[i]; i++)
- if (jsBuffer[i] != expectedValue[i])
+ for (i = 0; jsBuffer[i]; i++) {
+ if (jsBuffer[i] != expectedValue[i]) {
fprintf(stderr, "assertEqualsAsUTF8String failed at character %d: %c(%d) != %c(%d)\n", i, jsBuffer[i], jsBuffer[i], expectedValue[i], expectedValue[i]);
-
- if (jsSize < strlen(jsBuffer) + 1)
+ failed = 1;
+ }
+ }
+
+ if (jsSize < strlen(jsBuffer) + 1) {
fprintf(stderr, "assertEqualsAsUTF8String failed: jsSize was too small\n");
+ failed = 1;
+ }
free(jsBuffer);
JSStringRelease(valueAsString);
@@ -94,12 +104,16 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa
CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
CFRelease(expectedValueAsCFString);
- if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0)
+ if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0) {
fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n");
+ failed = 1;
+ }
- if (jsLength != (size_t)cfLength)
+ if (jsLength != (size_t)cfLength) {
fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength);
-
+ failed = 1;
+ }
+
free(cfBuffer);
JSStringRelease(valueAsString);
}
@@ -115,6 +129,7 @@ static bool MyObject_hasProperty(JSContextRef context, JSObjectRef object, JSStr
if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")
|| JSStringIsEqualToUTF8CString(propertyName, "cantFind")
+ || JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")
|| JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")
|| JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")
|| JSStringIsEqualToUTF8CString(propertyName, "0")) {
@@ -140,7 +155,11 @@ static JSValueRef MyObject_getProperty(JSContextRef context, JSObjectRef object,
if (JSStringIsEqualToUTF8CString(propertyName, "cantFind")) {
return JSValueMakeUndefined(context);
}
-
+
+ if (JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")) {
+ return JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ }
+
if (JSStringIsEqualToUTF8CString(propertyName, "0")) {
*exception = JSValueMakeNumber(context, 1);
return JSValueMakeNumber(context, 1);
@@ -159,6 +178,10 @@ static bool MyObject_setProperty(JSContextRef context, JSObjectRef object, JSStr
if (JSStringIsEqualToUTF8CString(propertyName, "cantSet"))
return true; // pretend we set the property in order to swallow it
+ if (JSStringIsEqualToUTF8CString(propertyName, "throwOnSet")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ }
+
return false;
}
@@ -171,7 +194,7 @@ static bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JS
return true;
if (JSStringIsEqualToUTF8CString(propertyName, "throwOnDelete")) {
- *exception = JSValueMakeNumber(context, 2);
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
return false;
}
@@ -201,6 +224,11 @@ static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef obje
UNUSED_PARAM(thisObject);
UNUSED_PARAM(exception);
+ if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnCall")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return JSValueMakeUndefined(context);
+ }
+
if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
return JSValueMakeNumber(context, 1);
@@ -212,6 +240,11 @@ static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef
UNUSED_PARAM(context);
UNUSED_PARAM(object);
+ if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnConstruct")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return object;
+ }
+
if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
return JSValueToObject(context, JSValueMakeNumber(context, 1), exception);
@@ -223,6 +256,11 @@ static bool MyObject_hasInstance(JSContextRef context, JSObjectRef constructor,
UNUSED_PARAM(context);
UNUSED_PARAM(constructor);
+ if (JSValueIsString(context, possibleValue) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, possibleValue, 0), "throwOnHasInstance")) {
+ JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), constructor, JSStringCreateWithUTF8CString("test script"), 1, exception);
+ return false;
+ }
+
JSStringRef numberString = JSStringCreateWithUTF8CString("Number");
JSObjectRef numberConstructor = JSValueToObject(context, JSObjectGetProperty(context, JSContextGetGlobalObject(context), numberString, exception), exception);
JSStringRelease(numberString);
@@ -297,6 +335,118 @@ static JSClassRef MyObject_class(JSContextRef context)
return jsClass;
}
+static bool EvilExceptionObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
+{
+ UNUSED_PARAM(context);
+ UNUSED_PARAM(constructor);
+
+ JSStringRef hasInstanceName = JSStringCreateWithUTF8CString("hasInstance");
+ JSValueRef hasInstance = JSObjectGetProperty(context, constructor, hasInstanceName, exception);
+ JSStringRelease(hasInstanceName);
+ if (!hasInstance)
+ return false;
+ JSObjectRef function = JSValueToObject(context, hasInstance, exception);
+ JSValueRef result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
+ return result && JSValueToBoolean(context, result);
+}
+
+static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
+{
+ UNUSED_PARAM(object);
+ UNUSED_PARAM(exception);
+ JSStringRef funcName;
+ switch (type) {
+ case kJSTypeNumber:
+ funcName = JSStringCreateWithUTF8CString("toNumber");
+ break;
+ case kJSTypeString:
+ funcName = JSStringCreateWithUTF8CString("toStringExplicit");
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
+ JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
+ JSStringRelease(funcName);
+ JSObjectRef function = JSValueToObject(context, func, exception);
+ if (!function)
+ return NULL;
+ JSValueRef value = JSObjectCallAsFunction(context, function, object, 0, NULL, exception);
+ if (!value)
+ return (JSValueRef)JSStringCreateWithUTF8CString("convertToType failed");
+ return value;
+}
+
+JSClassDefinition EvilExceptionObject_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ "EvilExceptionObject",
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ EvilExceptionObject_hasInstance,
+ EvilExceptionObject_convertToType,
+};
+
+static JSClassRef EvilExceptionObject_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass)
+ jsClass = JSClassCreate(&EvilExceptionObject_definition);
+
+ return jsClass;
+}
+
+JSClassDefinition EmptyObject_definition = {
+ 0,
+ kJSClassAttributeNone,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static JSClassRef EmptyObject_class(JSContextRef context)
+{
+ UNUSED_PARAM(context);
+
+ static JSClassRef jsClass;
+ if (!jsClass)
+ jsClass = JSClassCreate(&EmptyObject_definition);
+
+ return jsClass;
+}
+
+
static JSValueRef Base_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
{
UNUSED_PARAM(object);
@@ -656,6 +806,16 @@ int main(int argc, char* argv[])
JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
JSStringRelease(myObjectIString);
+ JSObjectRef EvilExceptionObject = JSObjectMake(context, EvilExceptionObject_class(context), NULL);
+ JSStringRef EvilExceptionObjectIString = JSStringCreateWithUTF8CString("EvilExceptionObject");
+ JSObjectSetProperty(context, globalObject, EvilExceptionObjectIString, EvilExceptionObject, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(EvilExceptionObjectIString);
+
+ JSObjectRef EmptyObject = JSObjectMake(context, EmptyObject_class(context), NULL);
+ JSStringRef EmptyObjectIString = JSStringCreateWithUTF8CString("EmptyObject");
+ JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(EmptyObjectIString);
+
JSValueRef exception;
// Conversions that throw exceptions
@@ -846,7 +1006,7 @@ int main(int argc, char* argv[])
JSStringRelease(functionBody);
string = JSValueToStringCopy(context, function, NULL);
- assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {return foo;}");
+ assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) { return foo;\n}");
JSStringRelease(string);
JSStringRef print = JSStringCreateWithUTF8CString("print");
@@ -954,9 +1114,10 @@ int main(int argc, char* argv[])
JSStringRelease(script);
char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
- if (!scriptUTF8)
+ if (!scriptUTF8) {
printf("FAIL: Test script could not be loaded.\n");
- else {
+ failed = 1;
+ } else {
script = JSStringCreateWithUTF8CString(scriptUTF8);
result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
if (JSValueIsUndefined(context, result))
@@ -968,6 +1129,7 @@ int main(int argc, char* argv[])
CFShow(exceptionCF);
CFRelease(exceptionCF);
JSStringRelease(exceptionIString);
+ failed = 1;
}
JSStringRelease(script);
free(scriptUTF8);
@@ -991,6 +1153,27 @@ int main(int argc, char* argv[])
JSGlobalContextRelease(context);
JSClassRelease(globalObjectClass);
+ // Test for an infinite prototype chain that used to be created. This test
+ // passes if the call to JSObjectHasProperty() does not hang.
+
+ JSClassDefinition prototypeLoopClassDefinition = kJSClassDefinitionEmpty;
+ prototypeLoopClassDefinition.staticFunctions = globalObject_staticFunctions;
+ JSClassRef prototypeLoopClass = JSClassCreate(&prototypeLoopClassDefinition);
+ JSGlobalContextRef prototypeLoopContext = JSGlobalContextCreateInGroup(NULL, prototypeLoopClass);
+
+ JSStringRef nameProperty = JSStringCreateWithUTF8CString("name");
+ JSObjectHasProperty(prototypeLoopContext, JSContextGetGlobalObject(prototypeLoopContext), nameProperty);
+
+ JSGlobalContextRelease(prototypeLoopContext);
+ JSClassRelease(prototypeLoopClass);
+
+ printf("PASS: Infinite prototype chain does not occur.\n");
+
+ if (failed) {
+ printf("FAIL: Some tests failed.\n");
+ return 1;
+ }
+
printf("PASS: Program exited normally.\n");
return 0;
}
diff --git a/JavaScriptCore/API/tests/testapi.js b/JavaScriptCore/API/tests/testapi.js
index 9c8ca9e..6a1fab3 100644
--- a/JavaScriptCore/API/tests/testapi.js
+++ b/JavaScriptCore/API/tests/testapi.js
@@ -22,6 +22,17 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+var failed = false;
+function pass(msg)
+{
+ print("PASS: " + msg, "green");
+}
+
+function fail(msg)
+{
+ print("FAIL: " + msg, "red");
+ failed = true;
+}
function shouldBe(a, b)
{
@@ -33,23 +44,22 @@ function shouldBe(a, b)
}
if (evalA == b || isNaN(evalA) && typeof evalA == 'number' && isNaN(b) && typeof b == 'number')
- print("PASS: " + a + " should be " + b + " and is.", "green");
+ pass(a + " should be " + b + " and is.");
else
- print("__FAIL__: " + a + " should be " + b + " but instead is " + evalA + ".", "red");
+ fail(a + " should be " + b + " but instead is " + evalA + ".");
}
function shouldThrow(a)
{
- var result = "__FAIL__: " + a + " did not throw an exception.";
-
var evalA;
try {
eval(a);
} catch(e) {
- result = "PASS: " + a + " threw: " + e;
+ pass(a + " threw: " + e);
+ return;
}
-
- print(result);
+
+ fail(a + " did not throw an exception.");
}
function globalStaticFunction()
@@ -70,9 +80,14 @@ shouldBe("MyObject.alwaysOne", 1);
MyObject.cantDelete = 1;
delete MyObject.cantDelete;
shouldBe("MyObject.cantDelete", 1);
-shouldBe("delete MyObject.throwOnDelete", 2); // deleteProperty -- should throw 2
+shouldBe("delete MyObject.throwOnDelete", "an exception");
MyObject.cantSet = 1;
shouldBe("MyObject.cantSet", undefined);
+shouldBe("MyObject.throwOnGet", "an exception");
+shouldBe("MyObject.throwOnSet = 5", "an exception");
+shouldBe("MyObject('throwOnCall')", "an exception");
+shouldBe("new MyObject('throwOnConstruct')", "an exception");
+shouldBe("'throwOnHasInstance' instanceof MyObject", "an exception");
var foundMyPropertyName = false;
var foundRegularType = false;
@@ -82,12 +97,16 @@ for (var p in MyObject) {
if (p == "regularType")
foundRegularType = true;
}
-print(foundMyPropertyName
- ? "PASS: MyObject.myPropertyName was enumerated"
- : "__FAIL__: MyObject.myPropertyName was not enumerated");
-print(foundRegularType
- ? "PASS: MyObject.regularType was enumerated"
- : "__FAIL__: MyObject.regularType was not enumerated");
+
+if (foundMyPropertyName)
+ pass("MyObject.myPropertyName was enumerated");
+else
+ fail("MyObject.myPropertyName was not enumerated");
+
+if (foundRegularType)
+ pass("MyObject.regularType was enumerated");
+else
+ fail("MyObject.regularType was not enumerated");
myObject = new MyObject();
@@ -100,7 +119,7 @@ shouldBe("MyObject ? 1 : 0", true); // toBoolean
shouldBe("+MyObject", 1); // toNumber
shouldBe("(MyObject.toString())", "[object MyObject]"); // toString
shouldBe("String(MyObject)", "MyObjectAsString"); // type conversion to string
-shouldBe("MyObject - 0", NaN); // toPrimitive
+shouldBe("MyObject - 0", 1); // toNumber
shouldBe("typeof MyConstructor", "object");
constructedObject = new MyConstructor(1);
@@ -130,3 +149,21 @@ shouldBe("derived.baseDup = 0", 2);
shouldBe("derived.baseOnly = 0", 1);
shouldBe("derived.derivedOnly = 0", 2)
shouldBe("derived.protoDup = 0", 2);
+
+shouldBe("undefined instanceof MyObject", false);
+EvilExceptionObject.hasInstance = function f() { return f(); };
+EvilExceptionObject.__proto__ = undefined;
+shouldThrow("undefined instanceof EvilExceptionObject");
+EvilExceptionObject.hasInstance = function () { return true; };
+shouldBe("undefined instanceof EvilExceptionObject", true);
+
+EvilExceptionObject.toNumber = function f() { return f(); }
+shouldThrow("EvilExceptionObject*5");
+EvilExceptionObject.toStringExplicit = function f() { return f(); }
+shouldThrow("String(EvilExceptionObject)");
+
+shouldBe("EmptyObject", "[object CallbackObject]");
+
+if (failed)
+ throw "Some tests failed";
+
diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk
index b04ebaf..fbad0f6 100644
--- a/JavaScriptCore/Android.mk
+++ b/JavaScriptCore/Android.mk
@@ -48,6 +48,10 @@
# /wx/* \
LOCAL_SRC_FILES := \
+ API/JSValueRef.cpp \
+ API/JSCallbackObject.cpp \
+ API/OpaqueJSString.cpp \
+ \
bytecode/CodeBlock.cpp \
bytecode/JumpTable.cpp \
bytecode/Opcode.cpp \
@@ -152,6 +156,7 @@ LOCAL_SRC_FILES := \
runtime/StringPrototype.cpp \
runtime/Structure.cpp \
runtime/StructureChain.cpp \
+ runtime/TimeoutChecker.cpp \
runtime/UString.cpp \
\
wrec/CharacterClass.cpp \
@@ -175,6 +180,7 @@ LOCAL_SRC_FILES := \
\
wtf/android/MainThreadAndroid.cpp \
\
+ wtf/TypeTraits.cpp \
wtf/dtoa.cpp \
\
wtf/unicode/CollatorDefault.cpp \
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 5b9cc4b..2cecfd2 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,52 +1,1663 @@
-2009-02-13 Mark Rowe <mrowe@apple.com>
+2009-03-26 Adam Roben <aroben@apple.com>
- Merge r40975.
+ Copy testapi.js to $WebKitOutputDir on Windows
- 2009-02-12 Darin Adler <darin@apple.com>
+ Part of Bug 24856: run-javascriptcore-tests should run testapi on
+ Windows
+ <https://bugs.webkit.org/show_bug.cgi?id=24856>
- Reviewed by Oliver Hunt and Alexey Proskuryakov.
+ This matches what Mac does, which will help once we enable running
+ testapi from run-javascriptcore-tests on Windows.
- Speed up a couple string functions.
+ Reviewed by Steve Falkenburg.
- * runtime/StringPrototype.cpp:
- (JSC::stringProtoFuncIndexOf): Added a fast path for cases where the second
- argument is either missing or an integer.
- (JSC::stringProtoFuncBig): Use jsNontrivialString since the string is guaranteed
- to be 2 or more characters long.
- (JSC::stringProtoFuncSmall): Ditto.
- (JSC::stringProtoFuncBlink): Ditto.
- (JSC::stringProtoFuncBold): Ditto.
- (JSC::stringProtoFuncItalics): Ditto.
- (JSC::stringProtoFuncStrike): Ditto.
- (JSC::stringProtoFuncSub): Ditto.
- (JSC::stringProtoFuncSup): Ditto.
- (JSC::stringProtoFuncFontcolor): Ditto.
- (JSC::stringProtoFuncFontsize): Make the fast path Sam recently added even faster
- by avoiding all but the minimum memory allocation.
- (JSC::stringProtoFuncAnchor): Use jsNontrivialString.
- (JSC::stringProtoFuncLink): Added a fast path.
+ * JavaScriptCore.vcproj/testapi/testapi.vcproj: Copy testapi.js next
+ to testapi.exe.
+
+2009-03-25 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Fix exception handling for instanceof in the interpreter.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2009-03-25 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fixed <rdar://problem/6724011> Write to freed memory in JSC::Label::deref
+ when reloading http://helpme.att.net/speedtest/
+
+ * bytecompiler/BytecodeGenerator.h: Reversed the declaration order for
+ m_labelScopes and m_labels to reverse their destruction order.
+ m_labelScopes has references to memory within m_labels, so its destructor
+ needs to run first.
+
+2009-03-24 Eli Fidler <eli.fidler@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Correct warnings which in some environments are treated as errors.
+
+ * wtf/dtoa.cpp:
+ (WTF::b2d):
+ (WTF::d2b):
+ (WTF::strtod):
+ (WTF::dtoa):
+
+2009-03-24 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Darin Adler.
+
+ Explicitly define HAVE_LANGINFO_H on Darwin. Fixes the wx build bot jscore
+ test failure.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24780
+ * wtf/Platform.h:
+
+2009-03-23 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix className() for API defined class
+
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::className):
+ * API/tests/testapi.c:
+ (EmptyObject_class):
+ (main):
+ * API/tests/testapi.js:
+
+2009-03-23 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Make testapi assertions run in release builds, so that testapi actually
+ works in a release build.
+
+ Many of the testapi assertions have side effects that are necessary, and
+ given testapi is a testing program, perf impact of an assertion is not
+ important, so it makes sense to apply the assertions in release builds
+ anyway.
+
+ * API/tests/testapi.c:
+ (EvilExceptionObject_hasInstance):
+
+2009-03-23 David Kilzer <ddkilzer@apple.com>
+
+ Provide JavaScript exception information after slow script timeout
+
+ Reviewed by Oliver Hunt.
+
+ * runtime/Completion.cpp:
+ (JSC::evaluate): Set the exception object as the Completion
+ object's value for slow script timeouts. This is used in
+ WebCore when reporting the exception.
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::InterruptedExecutionError::toString): Added. Provides a
+ description message for the exception when it is reported.
+
+2009-03-23 Gustavo Noronha Silva <gns@gnome.org> and Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+
+ Reviewed by Adam Roben.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24674
+ Crashes in !PLATFORM(MAC)'s formatLocaleDate, in very specific situations
+
+ Make sure strftime never returns 2-digits years to avoid ambiguity
+ and a crash. We wrap this new code option in HAVE_LANGINFO_H,
+ since it is apparently not available in all platforms.
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+ * wtf/Platform.h:
+
+2009-03-22 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Fix exception handling in API
+
+ We can't just use the ExecState exception slot for returning exceptions
+ from class introspection functions provided through the API as many JSC
+ functions will explicitly clear the ExecState exception when returning.
+
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::JSCallbackObject<Base>::getOwnPropertySlot):
+ (JSC::JSCallbackObject<Base>::put):
+ (JSC::JSCallbackObject<Base>::deleteProperty):
+ (JSC::JSCallbackObject<Base>::construct):
+ (JSC::JSCallbackObject<Base>::hasInstance):
+ (JSC::JSCallbackObject<Base>::call):
+ (JSC::JSCallbackObject<Base>::toNumber):
+ (JSC::JSCallbackObject<Base>::toString):
+ (JSC::JSCallbackObject<Base>::staticValueGetter):
+ (JSC::JSCallbackObject<Base>::callbackGetter):
+ * API/tests/testapi.c:
+ (MyObject_hasProperty):
+ (MyObject_getProperty):
+ (MyObject_setProperty):
+ (MyObject_deleteProperty):
+ (MyObject_callAsFunction):
+ (MyObject_callAsConstructor):
+ (MyObject_hasInstance):
+ (EvilExceptionObject_hasInstance):
+ (EvilExceptionObject_convertToType):
+ (EvilExceptionObject_class):
+ (main):
+ * API/tests/testapi.js:
+ (EvilExceptionObject.hasInstance):
+ (EvilExceptionObject.toNumber):
+ (EvilExceptionObject.toStringExplicit):
+
+2009-03-21 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 20049: testapi failure: MyObject - 0 should be NaN but instead is 1.
+ <https://bugs.webkit.org/show_bug.cgi?id=20049>
+ <rdar://problem/6079127>
+
+ In this case, the test is wrong. According to the ECMA spec, subtraction
+ uses ToNumber, not ToPrimitive. Change the test to match the spec.
+
+ * API/tests/testapi.js:
+
+2009-03-21 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Ensure that JSObjectMakeFunction doesn't produce incorrect line numbers.
+
+ Also make test api correctly propagate failures.
+
+ * API/tests/testapi.c:
+ (main):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+
+2009-03-21 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Improve testapi by making it report failures in a way we can pick up
+ from our test scripts.
+
+ * API/tests/testapi.c:
+ (assertEqualsAsBoolean):
+ (assertEqualsAsNumber):
+ (assertEqualsAsUTF8String):
+ (assertEqualsAsCharactersPtr):
+ (main):
+ * API/tests/testapi.js:
+ (pass):
+ (fail):
+ (shouldBe):
+ (shouldThrow):
+
+2009-03-20 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24535
+
+ Fixes missing line terminator character (;) after macro call.
+ It is common practice to add the trailing ";" where macros are substituted
+ and not where they are defined with #define.
+ This change is consistent with other macro declarations across webkit,
+ and it also solves compilation failure with symbian compilers.
+
* runtime/UString.cpp:
- (JSC::UString::find): Added a fast path for single-character search strings.
+ * wtf/Assertions.h:
+
+2009-03-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fixed a JavaScriptCore crash on the Windows buildbot.
+
+ * bytecompiler/BytecodeGenerator.h: Reduced the AST recursion limit.
+ Apparently, Windows has small stacks.
+
+2009-03-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ A little cleanup in the RegisterFile code.
+
+ Moved large inline functions out of the class declaration, to make it
+ more readable.
+
+ Switched over to using the roundUpAllocationSize function to avoid
+ duplicate code and subtle bugs.
+
+ Renamed m_maxCommitted to m_commitEnd, to match m_end.
+
+ Renamed allocationSize to commitSize because it's the chunk size for
+ committing memory, not allocating memory.
+
+ SunSpider reports no change.
+
+ * interpreter/RegisterFile.h:
+ (JSC::RegisterFile::RegisterFile):
+ (JSC::RegisterFile::shrink):
+ (JSC::RegisterFile::grow):
+ * jit/ExecutableAllocator.h:
+ (JSC::roundUpAllocationSize):
+
+2009-03-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed <rdar://problem/6033712> -- a little bit of hardening in the Collector.
+
+ SunSpider reports no change. I also verified in the disassembly that
+ we end up with a single compare to constant.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::heapAllocate):
+
+2009-03-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Cameron Zwarich and Oliver Hunt.
+
+ Fixed <rdar://problem/6406045> REGRESSION: Stack overflow on PowerPC on
+ fast/workers/use-machine-stack.html (22531)
+
+ Dialed down the re-entry allowance to 64 (from 128).
+
+ On a 512K stack, this leaves about 64K for other code on the stack while
+ JavaScript is running. Not perfect, but it solves our crash on PPC.
+
+ Different platforms may want to dial this down even more.
+
+ Also, substantially shrunk BytecodeGenerator. Since we allocate one on
+ the stack in order to throw a stack overflow exception -- well, let's
+ just say the old code had an appreciation for irony.
+
+ SunSpider reports no change.
+
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.h:
+ (JSC::):
+
+2009-03-19 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 24350: REGRESSION: Safari 4 breaks SPAW wysiwyg editor multiple instances
+ <https://bugs.webkit.org/show_bug.cgi?id=24350>
+ <rdar://problem/6674182>
+
+ The SPAW editor's JavaScript assumes that toString() on a function
+ constructed with the Function constructor produces a function with
+ a newline after the opening brace.
+
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction): Add a newline after the opening brace of the
+ function's source code.
+
+2009-03-19 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Geoff Garen.
+
+ Bug 23771: REGRESSION (r36016): JSObjectHasProperty freezes on global class without kJSClassAttributeNoAutomaticPrototype
+ <https://bugs.webkit.org/show_bug.cgi?id=23771>
+ <rdar://problem/6561016>
+
+ * API/tests/testapi.c:
+ (main): Add a test for this bug.
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::resetPrototype): Don't set the prototype of the
+ last object in the prototype chain to the object prototype when the
+ object prototype is already the last object in the prototype chain.
+
+2009-03-19 Timothy Hatcher <timothy@apple.com>
+
+ <rdar://problem/6687342> -[WebView scheduleInRunLoop:forMode:] has no affect on timers
+
+ Reviewed by Darin Adler.
+
+ * wtf/Platform.h: Added HAVE_RUNLOOP_TIMER for PLATFORM(MAC).
+
+2009-03-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed <rdar://problem/6279213> Regular expression run-time complexity
+ limit too low for long inputs (21485)
+
+ I raised PCRE's "matchLimit" (limit on backtracking) by an order of
+ magnitude. This fixes all the reported examples of timing out on legitimate
+ regular expression matches.
+
+ In my testing on a Core Duo MacBook Pro, the longest you can get stuck
+ trying to match a string is still under 1s, so this seems like a safe change.
+
+ I can think of a number of better solutions that are more complicated,
+ but this is a good improvement for now.
+
+ * pcre/pcre_exec.cpp:
+
+2009-03-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed <rdar://problem/6603562> REGRESSION (Safari 4): regular expression
+ pattern size limit lower than Safari 3.2, other browsers, breaks SAP (14873)
+
+ Bumped the pattern size limit to 1MB, and standardized it between PCRE
+ and WREC. (Empirical testing says that we can easily compile a 1MB regular
+ expression without risking a hang. Other browsers support bigger regular
+ expressions, but also hang.)
+
+ SunSpider reports no change.
+
+ I started with a patch posted to Bugzilla by Erik Corry (erikcorry@google.com).
+
+ * pcre/pcre_internal.h:
+ (put3ByteValue):
+ (get3ByteValue):
+ (put3ByteValueAndAdvance):
+ (putLinkValueAllowZero):
+ (getLinkValueAllowZero): Made PCRE's "LINK_SIZE" (the number of bytes
+ used to record jumps between bytecodes) 3, to accomodate larger potential
+ jumps. Bumped PCRE's "MAX_PATTERN_SIZE" to 1MB. (Technically, at this
+ LINK_SIZE, we can support even larger patterns, but we risk a hang during
+ compilation, and it's not clear that such large patterns are important
+ on the web.)
+
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp): Match PCRE's maximum pattern size,
+ to avoid quirks between platforms.
+
+2009-03-18 Ada Chan <adachan@apple.com>
+
+ Rolling out r41818 since it broke the windows build.
+ Error: ..\..\runtime\DatePrototype.cpp(30) : fatal error C1083: Cannot open include file: 'langinfo.h': No such file or directory
+
+ * runtime/DatePrototype.cpp:
+ (JSC::formatLocaleDate):
+
+2009-03-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ <rdar://problem/6692138> REGRESSION (Safari 4): Incorrect function return value when using IE "try ... finally" memory leak work-around (24654)
+ <https://bugs.webkit.org/show_bug.cgi?id=24654>
+
+ If the return value for a function is in a local register we need
+ to copy it before executing any finalisers, otherwise it is possible
+ for the finaliser to clobber the result.
+
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::hasFinaliser):
+ * parser/Nodes.cpp:
+ (JSC::ReturnNode::emitBytecode):
+
+2009-03-17 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Mark Rowe.
+
+ Move BUILDING_ON_* defines into Platform.h to make them available to other ports.
+ Also tweak the defines so that they work with the default values set by
+ AvailabilityMacros.h.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24630
+
+ * JavaScriptCorePrefix.h:
+ * wtf/Platform.h:
+
+2009-03-15 Simon Fraser <simon.fraser@apple.com>
+
+ Revert r41718 because it broke DumpRenderTree on Tiger.
+
+ * JavaScriptCorePrefix.h:
+ * wtf/Platform.h:
+
+2009-03-15 Kevin Ollivier <kevino@theolliviers.com>
+
+ Non-Apple Mac ports build fix. Move defines for the BUILDING_ON_ macros into
+ Platform.h so that they're defined for all ports building on Mac, and tweak
+ the definitions of those macros based on Mark Rowe's suggestions to accomodate
+ cases where the values may not be <= to the .0 release for that version.
+
+ * JavaScriptCorePrefix.h:
+ * wtf/Platform.h:
+
+2009-03-13 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Dan Bernstein.
+
+ Take advantage of the ability of recent versions of Xcode to easily switch the active
+ architecture.
+
+ * Configurations/DebugRelease.xcconfig:
+
+2009-03-13 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by David Kilzer.
+
+ Prevent AllInOneFile.cpp and ProfileGenerator.cpp from rebuilding unnecessarily when
+ switching between building in Xcode and via build-webkit.
+
+ build-webkit passes FEATURE_DEFINES to xcodebuild, resulting in it being present in the
+ Derived Sources build settings. When building in Xcode, this setting isn't present so
+ Xcode reruns the script build phases. This results in a new version of TracingDtrace.h
+ being generated, and the files that include it being rebuilt.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Don't regenerate TracingDtrace.h if it is
+ already newer than the input file.
+
+2009-03-13 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Resolved name conflict with globally defined tzname in Symbian.
+ Replaced with different name instead of using namespace qualifier
+ (appeared to be less clumsy).
+
+ * runtime/DateMath.cpp:
+
+2009-03-12 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6548446> TCMalloc_SystemRelease should use madvise rather than re-mmaping span of pages
+
+ * wtf/FastMalloc.cpp:
+ (WTF::mergeDecommittedStates): If either of the spans has been released to the system, release the other
+ span as well so that the flag in the merged span is accurate.
+ * wtf/Platform.h:
+ * wtf/TCSystemAlloc.cpp: Track decommitted spans when using MADV_FREE_REUSABLE / MADV_FREE_REUSE.
+ (TCMalloc_SystemRelease): Use madvise with MADV_FREE_REUSABLE when it is available.
+ (TCMalloc_SystemCommit): Use madvise with MADV_FREE_REUSE when it is available.
+ * wtf/TCSystemAlloc.h:
+
+2009-03-12 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Include string.h for strlen usage.
+
+ * wtf/Threading.cpp:
+
+2009-03-12 David Kilzer <ddkilzer@apple.com>
+
+ Add NO_RETURN attribute to runInteractive() when not using readline
+
+ Reviewed by Darin Adler.
+
+ * jsc.cpp:
+ (runInteractive): If the readline library is not used, this method
+ will never return, thus the NO_RETURN attribute is needed to prevent
+ a gcc warning.
+
+2009-03-12 Adam Roben <aroben@apple.com>
+
+ Adopt setThreadNameInternal on Windows
+
+ Also changed a Windows-only assertion about thread name length to an
+ all-platform log message.
+
+ Reviewed by Adam Treat.
+
+ * wtf/Threading.cpp:
+ (WTF::createThread): Warn if the thread name is longer than 31
+ characters, as Visual Studio will truncate names longer than that
+ length.
+
+ * wtf/ThreadingWin.cpp:
+ (WTF::setThreadNameInternal): Renamed from setThreadName and changed
+ to always operate on the current thread.
+ (WTF::initializeThreading): Changed to use setThreadNameInternal.
+ (WTF::createThreadInternal): Removed call to setThreadName. This is
+ now handled by threadEntryPoint and setThreadNameInternal.
+
+2009-03-11 David Kilzer <ddkilzer@apple.com>
+
+ Clarify comments regarding order of FEATURE_DEFINES
+
+ Rubber-stamped by Mark Rowe.
+
+ * Configurations/JavaScriptCore.xcconfig: Added warning about
+ the consequences when FEATURE_DEFINES are not kept in sync.
+
+2009-03-11 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ - WTF support for fixing <rdar://problem/3919124> Thai text selection
+ in Safari is incorrect
+
+ * wtf/unicode/icu/UnicodeIcu.h:
+ (WTF::Unicode::hasLineBreakingPropertyComplexContext): Added. Returns
+ whether the character has Unicode line breaking property value SA
+ ("Complex Context").
+ * wtf/unicode/qt4/UnicodeQt4.h:
+ (WTF::Unicode::hasLineBreakingPropertyComplexContext): Added an
+ implementation that always returns false.
+
+2009-03-11 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Give threads names on platforms with pthread_setname_np.
+
+ * wtf/Threading.cpp:
+ (WTF::NewThreadContext::NewThreadContext): Initialize thread name.
+ (WTF::threadEntryPoint): Call setThreadNameInternal.
+ (WTF::createThread): Pass thread name.
+
+ * wtf/Threading.h: Added new comments, setThreadNameInternal.
+
+ * wtf/ThreadingGtk.cpp:
+ (WTF::setThreadNameInternal): Added. Empty.
+ * wtf/ThreadingNone.cpp:
+ (WTF::setThreadNameInternal): Added. Empty.
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::setThreadNameInternal): Call pthread_setname_np when available.
+ * wtf/ThreadingQt.cpp:
+ (WTF::setThreadNameInternal): Added. Empty.
+ * wtf/ThreadingWin.cpp:
+ (WTF::setThreadNameInternal): Added. Empty.
+
+2009-03-11 Adam Roben <aroben@apple.com>
+
+ Change the Windows implementation of ThreadSpecific to use functions
+ instead of extern globals
+
+ This will make it easier to export ThreadSpecific from WebKit.
+
+ Reviewed by John Sullivan.
+
+ * API/JSBase.cpp:
+ (JSEvaluateScript):
+ Touched this file to force ThreadSpecific.h to be copied into
+ $WebKitOutputDir.
+
+ * wtf/ThreadSpecific.h: Replaced g_tls_key_count with tlsKeyCount()
+ and g_tls_keys with tlsKeys().
+
+ (WTF::::ThreadSpecific):
+ (WTF::::~ThreadSpecific):
+ (WTF::::get):
+ (WTF::::set):
+ (WTF::::destroy):
+ Updated to use the new functions.
+
+ * wtf/ThreadSpecificWin.cpp:
+ (WTF::tlsKeyCount):
+ (WTF::tlsKeys):
+ Added.
+
+ (WTF::ThreadSpecificThreadExit): Changed to use the new functions.
+
+2009-03-10 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Geoff Garen.
+
+ Bug 24291: REGRESSION (r38635): Single line JavaScript comment prevents HTML button click handler execution
+ <https://bugs.webkit.org/show_bug.cgi?id=24291>
+ <rdar://problem/6663472>
+
+ Add an extra newline to the end of the body of the program text constructed
+ by the Function constructor for parsing. This allows single line comments to
+ be handled correctly by the parser.
+
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+
+2009-03-09 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Bug 24447: REGRESSION (r41508): Google Maps does not complete initialization
+ <rdar://problem/6657774>
+
+ r41508 actually exposed a pre-existing bug where we were not invalidating the result
+ register cache at jump targets. This causes problems when condition loads occur in an
+ expression -- namely through the ?: and || operators. This patch corrects these issues
+ by marking the target of all forward jumps as being a jump target, and then clears the
+ result register cache when ever it starts generating code for a targeted instruction.
+
+ I do not believe it is possible to cause this class of failure outside of a single
+ expression, and expressions only provide forward branches, so this should resolve this
+ entire class of bug. That said i've included a test case that gets as close as possible
+ to hitting this bug with a back branch, to hopefully prevent anyone from introducing the
+ problem in future.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Label::isUsed):
+ (JSC::AbstractMacroAssembler::Label::used):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::JmpDst::JmpDst):
+ (JSC::X86Assembler::JmpDst::isUsed):
+ (JSC::X86Assembler::JmpDst::used):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2009-03-09 David Levin <levin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Bug 23175: String and UString should be able to share a UChar* buffer.
+ <https://bugs.webkit.org/show_bug.cgi?id=23175>
+
+ Add CrossThreadRefCounted.
+
+ * wtf/CrossThreadRefCounted.h: Added.
+ (WTF::CrossThreadRefCounted::create):
+ (WTF::CrossThreadRefCounted::isShared):
+ (WTF::CrossThreadRefCounted::dataAccessMustBeThreadSafe):
+ (WTF::CrossThreadRefCounted::mayBePassedToAnotherThread):
+ (WTF::CrossThreadRefCounted::CrossThreadRefCounted):
+ (WTF::CrossThreadRefCounted::~CrossThreadRefCounted):
+ (WTF::CrossThreadRefCounted::ref):
+ (WTF::CrossThreadRefCounted::deref):
+ (WTF::CrossThreadRefCounted::release):
+ (WTF::CrossThreadRefCounted::copy):
+ (WTF::CrossThreadRefCounted::threadSafeDeref):
+ * wtf/RefCounted.h:
+ * wtf/Threading.h:
+ (WTF::ThreadSafeSharedBase::ThreadSafeSharedBase):
+ (WTF::ThreadSafeSharedBase::derefBase):
+ (WTF::ThreadSafeShared::ThreadSafeShared):
+ (WTF::ThreadSafeShared::deref):
+
+2009-03-09 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24353
+ Allow to overrule default build options for Qt build.
+
+ * JavaScriptCore.pri: Allow to overrule ENABLE_JIT
+
+2009-03-08 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Build fix.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncConcat):
+
+2009-03-01 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Bug 24268: RuntimeArray is not a fully implemented JSArray
+ <https://bugs.webkit.org/show_bug.cgi?id=24268>
+
+ Don't cast a type to JSArray, just because it reportsArray as a supertype
+ in the JS type system. Doesn't appear feasible to create a testcase
+ unfortunately as setting up the failure conditions requires internal access
+ to JSC not present in DRT.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncConcat):
+
+2009-03-06 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ When preforming an op_mov, preserve any existing register mapping.
+
+ ~0.5% progression on v8 tests x86-64.
+
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2009-03-05 Simone Fiorentino <simone.fiorentino@consulenti.fastweb.it>
+
+ Bug 24382: request to add SH4 platform
+
+ <https://bugs.webkit.org/show_bug.cgi?id=24382>
+
+ Reviewed by David Kilzer.
+
+ * wtf/Platform.h: Added support for SH4 platform.
+
+2009-03-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Writes of constant values to SF registers should be made with direct memory
+ writes where possible, rather than moving the value via a hardware register.
+
+ ~3% win on SunSpider tests on x86, ~1.5% win on v8 tests on x86-64.
+
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::storePtr):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::movq_i32m):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2009-03-05 Mark Rowe <mrowe@apple.com>
+
+ Fix the build.
+
+ Sprinkle "static" around NumberConstructor.cpp in order to please the compiler.
+
+ * runtime/NumberConstructor.cpp:
+ (JSC::numberConstructorNaNValue):
+ (JSC::numberConstructorNegInfinity):
+ (JSC::numberConstructorPosInfinity):
+ (JSC::numberConstructorMaxValue):
+ (JSC::numberConstructorMinValue):
+
+2009-03-04 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6354858> FastMallocZone's enumeration code reports fragmented administration space
+
+ The handling of MALLOC_ADMIN_REGION_RANGE_TYPE in FastMalloc's zone was incorrect. It was attempting
+ to record the memory containing and individual span as an administrative region, when all memory
+ allocated via MetaDataAlloc should in fact be recorded. This was causing memory regions allocated
+ via MetaDataAlloc to appear as "VM_ALLOCATE ?" in vmmap output. They are now correctly reported as
+ "MALLOC_OTHER" regions associated with the JavaScriptCore FastMalloc zone.
+
+ Memory is allocated via MetaDataAlloc from two locations: PageHeapAllocator, and TCMalloc_PageMap{2,3}.
+ These two cases are handled differently.
+
+ PageHeapAllocator is extended to keep a linked list of memory regions that it has allocated. The
+ first object in an allocated region contains the link to the previously allocated region. To record
+ the administrative regions of a PageHeapAllocator we can simply walk the linked list and record
+ each allocated region we encounter.
+
+ TCMalloc_PageMaps allocate memory via MetaDataAlloc to store each level of the radix tree. To record
+ the administrative regions of a TCMalloc_PageMap we walk the tree and record the storage used for nodes
+ at each position rather than the nodes themselves.
+
+ A small performance improvement is achieved by coalescing adjacent memory regions inside the PageMapMemoryUsageRecorder
+ so that fewer calls in to the range recorder are necessary. We further reduce the number of calls to the
+ range recorder by aggregating the in-use ranges of a given memory region into a local buffer before recording
+ them with a single call. A similar approach is also used by AdminRegionRecorder.
-2009-02-13 Mark Rowe <mrowe@apple.com>
+ * wtf/FastMalloc.cpp:
+ (WTF::PageHeapAllocator::Init):
+ (WTF::PageHeapAllocator::New):
+ (WTF::PageHeapAllocator::recordAdministrativeRegions):
+ (WTF::TCMallocStats::FreeObjectFinder::isFreeObject):
+ (WTF::TCMallocStats::PageMapMemoryUsageRecorder::~PageMapMemoryUsageRecorder):
+ (WTF::TCMallocStats::PageMapMemoryUsageRecorder::recordPendingRegions):
+ (WTF::TCMallocStats::PageMapMemoryUsageRecorder::visit):
+ (WTF::TCMallocStats::AdminRegionRecorder::AdminRegionRecorder):
+ (WTF::TCMallocStats::AdminRegionRecorder::recordRegion):
+ (WTF::TCMallocStats::AdminRegionRecorder::visit):
+ (WTF::TCMallocStats::AdminRegionRecorder::recordPendingRegions):
+ (WTF::TCMallocStats::AdminRegionRecorder::~AdminRegionRecorder):
+ (WTF::TCMallocStats::FastMallocZone::enumerate):
+ (WTF::TCMallocStats::FastMallocZone::FastMallocZone):
+ (WTF::TCMallocStats::FastMallocZone::init):
+ * wtf/TCPageMap.h:
+ (TCMalloc_PageMap2::visitValues):
+ (TCMalloc_PageMap2::visitAllocations):
+ (TCMalloc_PageMap3::visitValues):
+ (TCMalloc_PageMap3::visitAllocations):
+
+2009-03-04 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24359
+ Repaint throttling mechanism
+
+ Set ENABLE_REPAINT_THROTTLING to 0 by default.
- Merge r40945.
+ * wtf/Platform.h:
+
+2009-03-03 David Kilzer <ddkilzer@apple.com>
+
+ <rdar://problem/6581203> WebCore and WebKit should install the same set of headers during installhdrs phase as build phase
+
+ Reviewed by Mark Rowe.
+
+ * Configurations/Base.xcconfig: Defined REAL_PLATFORM_NAME based
+ on PLATFORM_NAME to work around the missing definition on Tiger.
+ Updated HAVE_DTRACE to use REAL_PLATFORM_NAME.
+
+2009-03-03 Kevin McCullough <kmccullough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6639110> console.profile() doesn't work without a title
+
+ * profiler/Profiler.cpp:
+ (JSC::Profiler::startProfiling): assert if there is not title to ensure
+ we don't start profiling without one.
+
+2009-03-02 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
- 2009-02-12 Sam Weinig <sam@webkit.org>
+ Enable Geolocation (except on Tiger and Leopard).
+
+ * Configurations/JavaScriptCore.xcconfig:
+
+2009-03-01 David Kilzer <ddkilzer@apple.com>
+
+ <rdar://problem/6635688> Move HAVE_DTRACE check to Base.xcconfig
+
+ Reviewed by Mark Rowe.
+
+ * Configurations/Base.xcconfig: Set HAVE_DTRACE Xcode variable
+ based on PLATFORM_NAME and MAC_OS_X_VERSION_MAJOR. Also define
+ it as a preprocessor macro by modifying
+ GCC_PREPROCESSOR_DEFINITIONS.
+ * JavaScriptCore.xcodeproj/project.pbxproj: Changed "Generate
+ DTrace header" script phase to check for HAVE_DTRACE instead of
+ MACOSX_DEPLOYMENT_TARGET.
+ * wtf/Platform.h: Removed definition of HAVE_DTRACE macro since
+ it's defined in Base.xcconfig now.
+
+2009-03-01 Horia Olaru <olaru@adobe.com>
+
+ By looking in grammar.y there are only a few types of statement nodes
+ on which the debugger should stop.
+
+ Removed isBlock and isLoop virtual calls. No need to emit debug hooks in
+ the "statementListEmitCode" method as long as the necessary hooks can be
+ added in each "emitCode".
+
+ https://bugs.webkit.org/show_bug.cgi?id=21073
+
+ Reviewed by Kevin McCullough.
+
+ * parser/Nodes.cpp:
+ (JSC::ConstStatementNode::emitBytecode):
+ (JSC::statementListEmitCode):
+ (JSC::EmptyStatementNode::emitBytecode):
+ (JSC::ExprStatementNode::emitBytecode):
+ (JSC::VarStatementNode::emitBytecode):
+ (JSC::IfNode::emitBytecode):
+ (JSC::IfElseNode::emitBytecode):
+ (JSC::DoWhileNode::emitBytecode):
+ (JSC::WhileNode::emitBytecode):
+ (JSC::ForNode::emitBytecode):
+ (JSC::ForInNode::emitBytecode):
+ (JSC::ContinueNode::emitBytecode):
+ (JSC::BreakNode::emitBytecode):
+ (JSC::ReturnNode::emitBytecode):
+ (JSC::WithNode::emitBytecode):
+ (JSC::SwitchNode::emitBytecode):
+ (JSC::LabelNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+ (JSC::TryNode::emitBytecode):
+ * parser/Nodes.h:
+
+2009-02-26 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Fix bug #23614. Switches on double precision values were incorrectly
+ truncating the scrutinee value. E.g.:
+
+ switch (1.1) { case 1: print("FAIL"); }
+
+ Was resulting in FAIL.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::JITStubs::cti_op_switch_imm):
+
+2009-02-26 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Integer Immediate representation need not be canonical in x86 JIT code.
+ On x86-64 we already have loosened the requirement that the int immediate
+ representation in canonical, we should bring x86 into line.
+
+ This patch is a minor (~0.5%) improvement on sunspider & v8-tests, and
+ should reduce memory footoprint (reduces JIT code size).
+
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::privateCompileSlowCases):
+ * jit/JIT.h:
+ (JSC::JIT::emitJumpIfImmediateNumber):
+ (JSC::JIT::emitJumpIfNotImmediateNumber):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+
+2009-02-26 Carol Szabo <carol.szabo@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24099
+ ARM Compiler Warnings in pcre_exec.cpp
+
+ * pcre/pcre_exec.cpp:
+ (match):
+
+2009-02-25 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Gavin Barraclough.
+
+ Bug 24086: Regression (r40993): WebKit crashes after logging in to lists.zenbe
+ <https://bugs.webkit.org/show_bug.cgi?id=24086>
+ <rdar://problem/6625111>
+
+ The numeric sort optimization in r40993 generated bytecode for a function
+ without generating JIT code. This breaks an assumption in some parts of
+ the JIT's function calling logic that the presence of a CodeBlock implies
+ the existence of JIT code.
+
+ In order to fix this, we simply generate JIT code whenever we check whether
+ a function is a numeric sort function. This only incurs an additional cost
+ in the case when the function is a numeric sort function, in which case it
+ is not expensive to generate JIT code for it.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::isNumericCompareFunction):
+
+2009-02-25 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Fixed <rdar://problem/6611174> REGRESSION (r36701): Unable to select
+ messages on hotmail (24052)
+
+ The bug was that for-in enumeration used a cached prototype chain without
+ validating that it was up-to-date.
+
+ This led me to refactor prototype chain caching so it was easier to work
+ with and harder to get wrong.
+
+ After a bit of inlining, this patch is performance-neutral on SunSpider
+ and the v8 benchmarks.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCachePutByID):
+ (JSC::Interpreter::tryCacheGetByID):
+ * jit/JITStubs.cpp:
+ (JSC::JITStubs::tryCachePutByID):
+ (JSC::JITStubs::tryCacheGetByID):
+ (JSC::JITStubs::cti_op_get_by_id_proto_list): Use the new refactored goodness. See
+ lines beginning with "-" and smile.
+
+ * runtime/JSGlobalObject.h:
+ (JSC::Structure::prototypeForLookup): A shout out to const.
+
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::next): We can use a pointer comparison to
+ see if our cached structure chain is equal to the object's structure chain,
+ since in the case of a cache hit, we share references to the same structure
+ chain.
+
+ * runtime/Operations.h:
+ (JSC::countPrototypeChainEntriesAndCheckForProxies): Use the new refactored
+ goodness.
+
+ * runtime/PropertyNameArray.h:
+ (JSC::PropertyNameArray::PropertyNameArray):
+ (JSC::PropertyNameArray::setShouldCache):
+ (JSC::PropertyNameArray::shouldCache): Renamed "cacheable" to "shouldCache"
+ to communicate that the client is specifying a recommendation, not a
+ capability.
+
+ * runtime/Structure.cpp:
+ (JSC::Structure::Structure): No need to initialize a RefPtr.
+ (JSC::Structure::getEnumerablePropertyNames): Moved some code into helper
+ functions.
+
+ (JSC::Structure::prototypeChain): New centralized accessor for a prototype
+ chain. Revalidates on every access, since the objects in the prototype
+ chain may have mutated.
+
+ (JSC::Structure::isValid): Helper function for revalidating a cached
+ prototype chain.
+
+ (JSC::Structure::getEnumerableNamesFromPropertyTable):
+ (JSC::Structure::getEnumerableNamesFromClassInfoTable): Factored out of
+ getEnumerablePropertyNames.
+
+ * runtime/Structure.h:
+
+ * runtime/StructureChain.cpp:
+ (JSC::StructureChain::StructureChain):
+ * runtime/StructureChain.h:
+ (JSC::StructureChain::create): No need for structureChainsAreEqual, since
+ we use pointer equality now. Refactored StructureChain to make a little
+ more sense and eliminate special cases for null prototypes.
+
+2009-02-25 Steve Falkenburg <sfalken@apple.com>
+
+ Use timeBeginPeriod to enable timing resolution greater than 16ms in command line jsc for Windows.
+ Allows more accurate reporting of benchmark times via command line jsc.exe. Doesn't affect WebKit's use of JavaScriptCore.
+
+ Reviewed by Adam Roben.
+
+ * jsc.cpp:
+ (main):
+
+2009-02-24 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix?
+
+ * GNUmakefile.am:
+
+2009-02-24 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6259220> Rename AVAILABLE_AFTER_WEBKIT_VERSION_3_1 (etc.) to match the other macros
+
+ * API/JSBasePrivate.h:
+ * API/JSContextRef.h:
+ * API/JSObjectRef.h:
+ * API/WebKitAvailability.h:
+
+2009-02-23 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Next step in splitting JIT functionality out of the Interpreter class:
+ Moved vptr storage from Interpreter to JSGlobalData, so it could be shared
+ between Interpreter and JITStubs, and moved the *Trampoline JIT stubs
+ into the JITStubs class. Also added a VPtrSet class to encapsulate vptr
+ hacks during JSGlobalData initialization.
+
+ SunSpider says 0.4% faster. Meh.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ (JSC::JIT::compileCTIMachineTrampolines):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JITStubs.cpp:
+ (JSC::JITStubs::JITStubs):
+ (JSC::JITStubs::tryCacheGetByID):
+ (JSC::JITStubs::cti_vm_dontLazyLinkCall):
+ (JSC::JITStubs::cti_op_get_by_val):
+ (JSC::JITStubs::cti_op_get_by_val_byte_array):
+ (JSC::JITStubs::cti_op_put_by_val):
+ (JSC::JITStubs::cti_op_put_by_val_array):
+ (JSC::JITStubs::cti_op_put_by_val_byte_array):
+ (JSC::JITStubs::cti_op_is_string):
+ * jit/JITStubs.h:
+ (JSC::JITStubs::ctiArrayLengthTrampoline):
+ (JSC::JITStubs::ctiStringLengthTrampoline):
+ (JSC::JITStubs::ctiVirtualCallPreLink):
+ (JSC::JITStubs::ctiVirtualCallLink):
+ (JSC::JITStubs::ctiVirtualCall):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncPop):
+ (JSC::arrayProtoFuncPush):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncApply):
+ * runtime/JSArray.h:
+ (JSC::isJSArray):
+ * runtime/JSByteArray.h:
+ (JSC::asByteArray):
+ (JSC::isJSByteArray):
+ * runtime/JSCell.h:
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::VPtrSet::VPtrSet):
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::create):
+ (JSC::JSGlobalData::sharedInstance):
+ * runtime/JSGlobalData.h:
+ * runtime/JSString.h:
+ (JSC::isJSString):
+ * runtime/Operations.h:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ * wrec/WREC.cpp:
+ (JSC::WREC::Generator::compileRegExp):
+
+2009-02-23 Csaba Osztrogonac <oszi@inf.u-szeged.hu>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 23787: Allow JIT to generate SSE2 code if using GCC
+ <https://bugs.webkit.org/show_bug.cgi?id=23787>
+
+ GCC version of the cpuid check.
+
+ * jit/JITArithmetic.cpp:
+ (JSC::isSSE2Present): previous assembly code fixed.
+
+2009-02-23 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24047: Need to simplify nested if's in WorkerRunLoop::runInMode
+ <https://bugs.webkit.org/show_bug.cgi?id=24047>
+
+ * wtf/MessageQueue.h:
+ (WTF::MessageQueue::infiniteTime):
+ Allows for one to call waitForMessageFilteredWithTimeout and wait forever.
+
+ (WTF::MessageQueue::alwaysTruePredicate):
+ (WTF::MessageQueue::waitForMessage):
+ Made waitForMessage call waitForMessageFilteredWithTimeout, so that there is less
+ duplicate code.
+
+ (WTF::MessageQueue::waitForMessageFilteredWithTimeout):
+
+ * wtf/ThreadingQt.cpp:
+ (WTF::ThreadCondition::timedWait):
+ * wtf/ThreadingWin.cpp:
+ (WTF::ThreadCondition::timedWait):
+ Made these two implementations consistent with the pthread and gtk implementations.
+ Currently, the time calculations would overflow when passed large values.
+
+2009-02-23 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Adam Roben.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24096
+ PLATFORM(MAC)->PLATFORM(CF) since we want to use the CF functions in Chrome on OS X.
+
+ * wtf/CurrentTime.cpp:
+
+2009-02-22 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix?
+
+ * GNUmakefile.am:
+
+2009-02-22 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix.
+
+ * GNUmakefile.am:
+
+2009-02-22 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Next step in splitting JIT functionality out of the Interpreter class:
+ Created a JITStubs class and renamed Interpreter::cti_* to JITStubs::cti_*.
+
+ Also, moved timeout checking into its own class, located in JSGlobalData,
+ so both the Interpreter and the JIT could have access to it.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+ * interpreter/CallFrame.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::Interpreter):
+ (JSC::Interpreter::privateExecute):
+ * interpreter/Interpreter.h:
+ * interpreter/Register.h:
+ * jit/JIT.cpp:
+ (JSC::):
+ (JSC::JIT::emitTimeoutCheck):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArithSlow_op_lshift):
+ (JSC::JIT::compileFastArithSlow_op_rshift):
+ (JSC::JIT::compileFastArithSlow_op_bitand):
+ (JSC::JIT::compileFastArithSlow_op_mod):
+ (JSC::JIT::compileFastArith_op_mod):
+ (JSC::JIT::compileFastArithSlow_op_post_inc):
+ (JSC::JIT::compileFastArithSlow_op_post_dec):
+ (JSC::JIT::compileFastArithSlow_op_pre_inc):
+ (JSC::JIT::compileFastArithSlow_op_pre_dec):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArith_op_sub):
+ (JSC::JIT::compileBinaryArithOpSlowCase):
+ (JSC::JIT::compileFastArithSlow_op_add):
+ (JSC::JIT::compileFastArithSlow_op_mul):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+ * jit/JITStubs.cpp:
+ (JSC::JITStubs::tryCachePutByID):
+ (JSC::JITStubs::tryCacheGetByID):
+ (JSC::JITStubs::cti_op_convert_this):
+ (JSC::JITStubs::cti_op_end):
+ (JSC::JITStubs::cti_op_add):
+ (JSC::JITStubs::cti_op_pre_inc):
+ (JSC::JITStubs::cti_timeout_check):
+ (JSC::JITStubs::cti_register_file_check):
+ (JSC::JITStubs::cti_op_loop_if_less):
+ (JSC::JITStubs::cti_op_loop_if_lesseq):
+ (JSC::JITStubs::cti_op_new_object):
+ (JSC::JITStubs::cti_op_put_by_id_generic):
+ (JSC::JITStubs::cti_op_get_by_id_generic):
+ (JSC::JITStubs::cti_op_put_by_id):
+ (JSC::JITStubs::cti_op_put_by_id_second):
+ (JSC::JITStubs::cti_op_put_by_id_fail):
+ (JSC::JITStubs::cti_op_get_by_id):
+ (JSC::JITStubs::cti_op_get_by_id_second):
+ (JSC::JITStubs::cti_op_get_by_id_self_fail):
+ (JSC::JITStubs::cti_op_get_by_id_proto_list):
+ (JSC::JITStubs::cti_op_get_by_id_proto_list_full):
+ (JSC::JITStubs::cti_op_get_by_id_proto_fail):
+ (JSC::JITStubs::cti_op_get_by_id_array_fail):
+ (JSC::JITStubs::cti_op_get_by_id_string_fail):
+ (JSC::JITStubs::cti_op_instanceof):
+ (JSC::JITStubs::cti_op_del_by_id):
+ (JSC::JITStubs::cti_op_mul):
+ (JSC::JITStubs::cti_op_new_func):
+ (JSC::JITStubs::cti_op_call_JSFunction):
+ (JSC::JITStubs::cti_op_call_arityCheck):
+ (JSC::JITStubs::cti_vm_dontLazyLinkCall):
+ (JSC::JITStubs::cti_vm_lazyLinkCall):
+ (JSC::JITStubs::cti_op_push_activation):
+ (JSC::JITStubs::cti_op_call_NotJSFunction):
+ (JSC::JITStubs::cti_op_create_arguments):
+ (JSC::JITStubs::cti_op_create_arguments_no_params):
+ (JSC::JITStubs::cti_op_tear_off_activation):
+ (JSC::JITStubs::cti_op_tear_off_arguments):
+ (JSC::JITStubs::cti_op_profile_will_call):
+ (JSC::JITStubs::cti_op_profile_did_call):
+ (JSC::JITStubs::cti_op_ret_scopeChain):
+ (JSC::JITStubs::cti_op_new_array):
+ (JSC::JITStubs::cti_op_resolve):
+ (JSC::JITStubs::cti_op_construct_JSConstruct):
+ (JSC::JITStubs::cti_op_construct_NotJSConstruct):
+ (JSC::JITStubs::cti_op_get_by_val):
+ (JSC::JITStubs::cti_op_get_by_val_byte_array):
+ (JSC::JITStubs::cti_op_resolve_func):
+ (JSC::JITStubs::cti_op_sub):
+ (JSC::JITStubs::cti_op_put_by_val):
+ (JSC::JITStubs::cti_op_put_by_val_array):
+ (JSC::JITStubs::cti_op_put_by_val_byte_array):
+ (JSC::JITStubs::cti_op_lesseq):
+ (JSC::JITStubs::cti_op_loop_if_true):
+ (JSC::JITStubs::cti_op_negate):
+ (JSC::JITStubs::cti_op_resolve_base):
+ (JSC::JITStubs::cti_op_resolve_skip):
+ (JSC::JITStubs::cti_op_resolve_global):
+ (JSC::JITStubs::cti_op_div):
+ (JSC::JITStubs::cti_op_pre_dec):
+ (JSC::JITStubs::cti_op_jless):
+ (JSC::JITStubs::cti_op_not):
+ (JSC::JITStubs::cti_op_jtrue):
+ (JSC::JITStubs::cti_op_post_inc):
+ (JSC::JITStubs::cti_op_eq):
+ (JSC::JITStubs::cti_op_lshift):
+ (JSC::JITStubs::cti_op_bitand):
+ (JSC::JITStubs::cti_op_rshift):
+ (JSC::JITStubs::cti_op_bitnot):
+ (JSC::JITStubs::cti_op_resolve_with_base):
+ (JSC::JITStubs::cti_op_new_func_exp):
+ (JSC::JITStubs::cti_op_mod):
+ (JSC::JITStubs::cti_op_less):
+ (JSC::JITStubs::cti_op_neq):
+ (JSC::JITStubs::cti_op_post_dec):
+ (JSC::JITStubs::cti_op_urshift):
+ (JSC::JITStubs::cti_op_bitxor):
+ (JSC::JITStubs::cti_op_new_regexp):
+ (JSC::JITStubs::cti_op_bitor):
+ (JSC::JITStubs::cti_op_call_eval):
+ (JSC::JITStubs::cti_op_throw):
+ (JSC::JITStubs::cti_op_get_pnames):
+ (JSC::JITStubs::cti_op_next_pname):
+ (JSC::JITStubs::cti_op_push_scope):
+ (JSC::JITStubs::cti_op_pop_scope):
+ (JSC::JITStubs::cti_op_typeof):
+ (JSC::JITStubs::cti_op_is_undefined):
+ (JSC::JITStubs::cti_op_is_boolean):
+ (JSC::JITStubs::cti_op_is_number):
+ (JSC::JITStubs::cti_op_is_string):
+ (JSC::JITStubs::cti_op_is_object):
+ (JSC::JITStubs::cti_op_is_function):
+ (JSC::JITStubs::cti_op_stricteq):
+ (JSC::JITStubs::cti_op_nstricteq):
+ (JSC::JITStubs::cti_op_to_jsnumber):
+ (JSC::JITStubs::cti_op_in):
+ (JSC::JITStubs::cti_op_push_new_scope):
+ (JSC::JITStubs::cti_op_jmp_scopes):
+ (JSC::JITStubs::cti_op_put_by_index):
+ (JSC::JITStubs::cti_op_switch_imm):
+ (JSC::JITStubs::cti_op_switch_char):
+ (JSC::JITStubs::cti_op_switch_string):
+ (JSC::JITStubs::cti_op_del_by_val):
+ (JSC::JITStubs::cti_op_put_getter):
+ (JSC::JITStubs::cti_op_put_setter):
+ (JSC::JITStubs::cti_op_new_error):
+ (JSC::JITStubs::cti_op_debug):
+ (JSC::JITStubs::cti_vm_throw):
+ * jit/JITStubs.h:
+ (JSC::):
+ * runtime/JSFunction.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.cpp:
+ * runtime/JSGlobalObject.h:
+ * runtime/TimeoutChecker.cpp: Copied from interpreter/Interpreter.cpp.
+ (JSC::TimeoutChecker::TimeoutChecker):
+ (JSC::TimeoutChecker::reset):
+ (JSC::TimeoutChecker::didTimeOut):
+ * runtime/TimeoutChecker.h: Copied from interpreter/Interpreter.h.
+ (JSC::TimeoutChecker::setTimeoutInterval):
+ (JSC::TimeoutChecker::ticksUntilNextCheck):
+ (JSC::TimeoutChecker::start):
+ (JSC::TimeoutChecker::stop):
+
+2009-02-20 Gustavo Noronha Silva <gns@gnome.org>
+
+ Unreviewed build fix after r41100.
+
+ * GNUmakefile.am:
+
+2009-02-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ <rdar://problem/6606660> 2==null returns true in 64bit jit
+
+ Code for op_eq_null and op_neq_null was incorrectly performing
+ a 32bit compare, which truncated the type tag from an integer
+ immediate, leading to incorrect behaviour.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::setPtr):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::setPtr):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+
+2009-02-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ First step in splitting JIT functionality out of the Interpreter class:
+ Created JITStubs.h/.cpp, and moved Interpreter::cti_* into JITStubs.cpp.
+
+ Functions that the Interpreter and JITStubs share moved to Operations.h/.cpp.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::resolveBase):
+ (JSC::Interpreter::checkTimeout):
+ (JSC::Interpreter::privateExecute):
+ * interpreter/Interpreter.h:
+ * jit/JITStubs.cpp: Copied from interpreter/Interpreter.cpp.
+ (JSC::Interpreter::cti_op_resolve_base):
+ * jit/JITStubs.h: Copied from interpreter/Interpreter.h.
+ * runtime/Operations.cpp:
+ (JSC::jsAddSlowCase):
+ (JSC::jsTypeStringForValue):
+ (JSC::jsIsObjectType):
+ (JSC::jsIsFunctionType):
+ * runtime/Operations.h:
+ (JSC::jsLess):
+ (JSC::jsLessEq):
+ (JSC::jsAdd):
+ (JSC::cachePrototypeChain):
+ (JSC::countPrototypeChainEntriesAndCheckForProxies):
+ (JSC::resolveBase):
+
+2009-02-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix for x86-64. Where the JavaScriptCore text segment lies outside
+ a 2gb range of the heap containing JIT generated code, callbacks
+ from JIT code to the stub functions in Interpreter will be incorrectly
+ linked.
+
+ No performance impact on Sunspider, 1% regression on v8-tests,
+ due to a 3% regression on richards.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Call::Call):
+ (JSC::AbstractMacroAssembler::Jump::link):
+ (JSC::AbstractMacroAssembler::Jump::linkTo):
+ (JSC::AbstractMacroAssembler::CodeLocationJump::relink):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::relink):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToFunction):
+ (JSC::AbstractMacroAssembler::PatchBuffer::link):
+ (JSC::AbstractMacroAssembler::PatchBuffer::linkTailRecursive):
+ (JSC::AbstractMacroAssembler::differenceBetween):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::tailRecursiveCall):
+ (JSC::MacroAssembler::makeTailRecursiveCall):
+ * assembler/MacroAssemblerX86.h:
+ (JSC::MacroAssemblerX86::call):
+ * assembler/MacroAssemblerX86Common.h:
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::call):
+ (JSC::MacroAssemblerX86_64::moveWithPatch):
+ (JSC::MacroAssemblerX86_64::branchPtrWithPatch):
+ (JSC::MacroAssemblerX86_64::storePtrWithPatch):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::jmp_r):
+ (JSC::X86Assembler::linkJump):
+ (JSC::X86Assembler::patchJump):
+ (JSC::X86Assembler::patchCall):
+ (JSC::X86Assembler::linkCall):
+ (JSC::X86Assembler::patchAddress):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCTICachePutByID):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate):
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompilePutByIdReplace):
+
+2009-02-18 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Simplified .call and .apply in preparation for optimizing them. Also,
+ a little cleanup.
+
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncApply):
+ (JSC::functionProtoFuncCall): No need to do any specific conversion on
+ 'this' -- op_convert_this will do it if necessary.
+
+ * runtime/JSImmediate.cpp:
+ (JSC::JSImmediate::toThisObject): Slightly relaxed the rules on
+ toThisObject to allow for 'undefined', which can be passed through
+ .call and .apply.
+
+2009-02-19 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23976: MessageQueue needs a way to wait for a message that satisfies an arbitrary criteria.
+ <https://bugs.webkit.org/show_bug.cgi?id=23976>
+
+ * wtf/Deque.h:
+ (WTF::Deque<T>::findIf):
+ * wtf/MessageQueue.h:
+ (WTF::MessageQueue<T>::waitForMessageFiltered):
+
+2009-02-18 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23974: Deque::Remove would be a useful method.
+ <https://bugs.webkit.org/show_bug.cgi?id=23974>
+
+ Add Deque::remove and DequeIteratorBase<T>::operator=.
+
+ Why was operator= added? Every concrete iterator (DequeIterator..DequeConstReverseIterator)
+ was calling DequeIteratorBase::assign(), which called Base::operator=(). Base::operator=()
+ was not implemented. This went unnoticed because the iterator copy code has been unused.
+
+ * wtf/Deque.h:
+ (WTF::Deque<T>::remove):
+ (WTF::DequeIteratorBase<T>::removeFromIteratorsList):
+ (WTF::DequeIteratorBase<T>::operator=):
+ (WTF::DequeIteratorBase<T>::~DequeIteratorBase):
+
+2009-02-18 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Fix symbols.filter location, and add other missing files to the
+ autotools build, so that make dist works.
+
+ * GNUmakefile.am:
+
+2009-02-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed failure in js1_5/Regress/regress-168347.js, as seen on the Oliver
+ bot.
+
+ Technically, both behaviors are OK, but we might as well keep this test
+ passing.
+
+ * runtime/FunctionPrototype.cpp:
+ (JSC::insertSemicolonIfNeeded): No need to add a trailing semicolon
+ after a trailing '}', since '}' ends a block, indicating the end of a
+ statement.
+
+2009-02-17 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix.
+
+ * runtime/FunctionPrototype.cpp:
+
+2009-02-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Add assertion to guard against oversized pc relative calls.
+
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::link):
+
+2009-02-17 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed <rdar://problem/6595040> REGRESSION: http://www.amnestyusa.org/
+ fails to load.
+
+ amnestyusa.org uses the Optimist JavaScript library, which adds event
+ listeners by concatenating string-ified functions. This is only sure to
+ be syntactically valid if the string-ified functions end in semicolons.
+
+ * parser/Lexer.cpp:
+ (JSC::Lexer::isWhiteSpace):
+ * parser/Lexer.h:
+ (JSC::Lexer::isWhiteSpace):
+ (JSC::Lexer::isLineTerminator): Added some helper functions for examining
+ whitespace.
+
+ * runtime/FunctionPrototype.cpp:
+ (JSC::appendSemicolonIfNeeded):
+ (JSC::functionProtoFuncToString): When string-ifying a function, insert
+ a semicolon in the last non-whitespace position, if one doesn't already exist.
+
+2009-02-16 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Roll out r41022 as it breaks qt and gtk builds
+
+ * jit/JITArithmetic.cpp:
+ (JSC::isSSE2Present):
+
+2009-02-16 Sam Weinig <sam@webkit.org>
Reviewed by Geoffrey Garen.
- Speed up String.prototype.fontsize.
+ Fix for <rdar://problem/6468156>
+ REGRESSION (r36779): Adding link, images, flash in TinyMCE blocks entire page (21382)
- * runtime/StringPrototype.cpp:
- (JSC::stringProtoFuncFontsize): Specialize for defined/commonly used values.
+ No performance regression.
+
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::fillArgList): Add codepath for when the "length" property has been
+ overridden.
+
+2009-02-16 Mark Rowe <mrowe@apple.com>
+
+ Build fix.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMallocStats::):
+ (WTF::TCMallocStats::FastMallocZone::FastMallocZone):
+
+2009-02-16 Csaba Osztrogonac <oszi@inf.u-szeged.hu>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 23787: Allow JIT to generate SSE2 code if using GCC
+ <https://bugs.webkit.org/show_bug.cgi?id=23787>
+
+ GCC version of the cpuid check.
+
+ * jit/JITArithmetic.cpp:
+ (JSC::isSSE2Present): GCC assembly code added.
+ 6.6% progression on x86 Linux with JIT and WREC on SunSpider if using SSE2 capable machine.
-2009-02-13 Mark Rowe <mrowe@apple.com>
+2009-02-13 Adam Treat <adam.treat@torchmobile.com>
- Merge r41000.
+ Reviewed by George Staikos.
- 2009-02-13 Gavin Barraclough <barraclough@apple.com>
+ https://bugs.webkit.org/show_bug.cgi?id=23960
+ Crash Fix.
+
+ Don't depend on 'initializeThreading()' to come before a call to 'isMainThread()'
+ as QtWebKit only calls 'initializeThreading()' during QWebPage construction.
+
+ A client app may well make a call to QWebSettings::iconForUrl() for instance
+ before creating a QWebPage and that call to QWebSettings triggers an
+ ASSERT(isMainThread()) deep within WebCore.
+
+ * wtf/ThreadingQt.cpp:
+ (WTF::isMainThread):
+
+2009-02-13 Gavin Barraclough <barraclough@apple.com>
Reviewed by Darin Adler.
@@ -62,11 +1673,7 @@
* parser/ResultType.h:
(JSC::OperandTypes::OperandTypes):
-2009-02-13 Mark Rowe <mrowe@apple.com>
-
- Merge r40995.
-
- 2009-02-13 Geoffrey Garen <ggaren@apple.com>
+2009-02-13 Geoffrey Garen <ggaren@apple.com>
Build fix for non_JIT platforms.
@@ -74,17 +1681,13 @@
(JSC::CodeBlock::setIsNumericCompareFunction):
(JSC::CodeBlock::isNumericCompareFunction):
-2009-02-13 Mark Rowe <mrowe@apple.com>
-
- Merge r40993.
-
- 2009-02-13 Geoffrey Garen <ggaren@apple.com>
+2009-02-13 Geoffrey Garen <ggaren@apple.com>
Reviewed by Darin Adler.
-
+
Fixed <rdar://problem/6584057> Optimize sort by JS numeric comparison
function not to run the comparison function
-
+
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
* bytecode/CodeBlock.h:
@@ -127,11 +1730,48 @@
* runtime/JSGlobalData.h: Added helper data for computing the
isNumericCompareFunction bit.
-2009-02-13 Mark Rowe <mrowe@apple.com>
+2009-02-13 Darin Adler <darin@apple.com>
+
+ * Configurations/JavaScriptCore.xcconfig: Undo accidental commit of this file.
+
+2009-02-12 Darin Adler <darin@apple.com>
+
+ Reviewed by Oliver Hunt and Alexey Proskuryakov.
+
+ Speed up a couple string functions.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncIndexOf): Added a fast path for cases where the second
+ argument is either missing or an integer.
+ (JSC::stringProtoFuncBig): Use jsNontrivialString since the string is guaranteed
+ to be 2 or more characters long.
+ (JSC::stringProtoFuncSmall): Ditto.
+ (JSC::stringProtoFuncBlink): Ditto.
+ (JSC::stringProtoFuncBold): Ditto.
+ (JSC::stringProtoFuncItalics): Ditto.
+ (JSC::stringProtoFuncStrike): Ditto.
+ (JSC::stringProtoFuncSub): Ditto.
+ (JSC::stringProtoFuncSup): Ditto.
+ (JSC::stringProtoFuncFontcolor): Ditto.
+ (JSC::stringProtoFuncFontsize): Make the fast path Sam recently added even faster
+ by avoiding all but the minimum memory allocation.
+ (JSC::stringProtoFuncAnchor): Use jsNontrivialString.
+ (JSC::stringProtoFuncLink): Added a fast path.
+
+ * runtime/UString.cpp:
+ (JSC::UString::find): Added a fast path for single-character search strings.
+
+2009-02-13 David Levin <levin@chromium.org>
- Merge r40968.
+ Reviewed by Darin Adler.
+
+ Bug 23926: Race condition in callOnMainThreadAndWait
+ <https://bugs.webkit.org/show_bug.cgi?id=23926>
- 2009-02-13 Oliver Hunt <oliver@apple.com>
+ * wtf/MainThread.cpp:
+ Removed callOnMainThreadAndWait since it isn't used.
+
+2009-02-13 Oliver Hunt <oliver@apple.com>
Reviewed by Jon Honeycutt.
@@ -157,50 +1797,135 @@
* wtf/RandomNumberSeed.h:
(WTF::initializeWeakRandomNumberGenerator):
-2009-02-13 Mark Rowe <mrowe@apple.com>
-
- Merge r40967.
-
- 2009-02-12 Mark Rowe <mrowe@apple.com>
+2009-02-12 Mark Rowe <mrowe@apple.com>
Fix the build for other platforms.
* wtf/RandomNumber.cpp:
(WTF::randomNumber):
-2009-02-13 Mark Rowe <mrowe@apple.com>
+2009-02-12 Gavin Barraclough <barraclough@apple.com>
- Merge r40937.
+ Reviewed by Sam Weinig.
- 2009-02-12 Geoffrey Garen <ggaren@apple.com>
+ Remove (/reduce) use of hard-wired register names from the JIT.
+ Currently there is no abstraction of registers used in the JIT,
+ which has a number of negative consequences. Hard-wiring x86
+ register names makes the JIT less portable to other platforms,
+ and prevents us from performing dynamic register allocation to
+ attempt to maintain more temporary values in machine registers.
+ (The latter will be more important on x86-64, where we have more
+ registers to make use of).
- Reviewed by Sam Weinig.
+ Also, remove MacroAssembler::mod32. This was not providing a
+ useful abstraction, and was not in keeping with the rest of the
+ MacroAssembler interface, in having specific register requirements.
+
+ * assembler/MacroAssemblerX86Common.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_lshift):
+ (JSC::JIT::compileFastArithSlow_op_lshift):
+ (JSC::JIT::compileFastArith_op_rshift):
+ (JSC::JIT::compileFastArithSlow_op_rshift):
+ (JSC::JIT::compileFastArith_op_bitand):
+ (JSC::JIT::compileFastArithSlow_op_bitand):
+ (JSC::JIT::compileFastArith_op_mod):
+ (JSC::JIT::compileFastArithSlow_op_mod):
+ (JSC::JIT::compileFastArith_op_post_inc):
+ (JSC::JIT::compileFastArithSlow_op_post_inc):
+ (JSC::JIT::compileFastArith_op_post_dec):
+ (JSC::JIT::compileFastArithSlow_op_post_dec):
+ (JSC::JIT::compileFastArith_op_pre_inc):
+ (JSC::JIT::compileFastArithSlow_op_pre_inc):
+ (JSC::JIT::compileFastArith_op_pre_dec):
+ (JSC::JIT::compileFastArithSlow_op_pre_dec):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ (JSC::JIT::compileFastArith_op_sub):
+ (JSC::JIT::compileBinaryArithOp):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCallInitializeCallFrame):
+ (JSC::JIT::compileOpCallSetupArgs):
+ (JSC::JIT::compileOpCallEvalSetupArgs):
+ (JSC::JIT::compileOpConstructSetupArgs):
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitGetVirtualRegister):
+ (JSC::JIT::emitPutVirtualRegister):
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::restoreArgumentReference):
+ (JSC::JIT::restoreArgumentReferenceForTrampoline):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+
+2009-02-12 Horia Olaru <olaru@adobe.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23400
+
+ When throwing an exception within an eval argument string, the dst parameter was
+ modified in the functions below and the return value for eval was altered. Changed
+ the emitNode call in JSC::ThrowNode::emitBytecode to use a temporary register
+ to store its results instead of dst. The JSC::FunctionCallResolveNode::emitBytecode
+ would load the function within the dst registry, also altering the result returned
+ by eval. Replaced it with another temporary.
+ * parser/Nodes.cpp:
+ (JSC::FunctionCallResolveNode::emitBytecode):
+ (JSC::ThrowNode::emitBytecode):
+
+2009-02-12 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Speed up String.prototype.fontsize.
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncFontsize): Specialize for defined/commonly used values.
+
+2009-02-12 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
Correctness fix.
* wtf/RandomNumber.cpp:
(WTF::randomNumber): Divide by the maximum representable value, which
is different on each platform now, to get values between 0 and 1.
-2009-02-13 Mark Rowe <mrowe@apple.com>
-
- Merge r40935.
-
- 2009-02-12 Geoffrey Garen <ggaren@apple.com>
+2009-02-12 Geoffrey Garen <ggaren@apple.com>
Build fix.
* wtf/RandomNumber.cpp:
(WTF::randomNumber):
-2009-02-13 Mark Rowe <mrowe@apple.com>
-
- Merge r40932.
-
- 2009-02-12 Geoffrey Garen <ggaren@apple.com>
+2009-02-12 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
-
+
Fixed <rdar://problem/6582048>.
* wtf/RandomNumber.cpp:
@@ -209,11 +1934,654 @@
of randomness over and above cryptographically secure randomness is not
clear, and it caused some performance problems.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-02-12 Adam Roben <aroben@apple.com>
+
+ Fix lots of Perl warnings when building JavaScriptCoreGenerated on
+ Windows
+
+ Reviewed by John Sullivan.
- Merge r40522.
+ * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh:
+ Create the docs/ directory so that we can write bytecode.html into it.
+ This matches what JavaScriptCore.xcodeproj does.
+
+2009-02-12 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Rubber-stamped by Lars.
+
+ Re-enable the JIT in the Qt build with -fno-stack-protector on Linux.
+
+ * JavaScriptCore.pri:
- 2009-02-02 Oliver Hunt <oliver@apple.com>
+2009-02-11 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23705
+ Fix the UI freeze caused by Worker generating a flood of messages.
+ Measure time we spend in executing posted work items. If too much time is spent
+ without returning to the run loop, exit and reschedule.
+
+ * wtf/MainThread.h:
+ Added initializeMainThreadPlatform() to initialize low-level mechanism for posting
+ work items from thread to thread. This removes #ifdefs for WIN and CHROMIUM from platform-independent code.
+
+ * wtf/MainThread.cpp:
+ (WTF::initializeMainThread):
+ (WTF::dispatchFunctionsFromMainThread):
+ Instead of dispatching all work items in the queue, dispatch them one by one
+ and measure elapsed time. After a threshold, reschedule and quit.
+
+ (WTF::callOnMainThread):
+ (WTF::callOnMainThreadAndWait):
+ Only schedule dispatch if the queue was empty - to avoid many posted messages in the run loop queue.
+
+ * wtf/mac/MainThreadMac.mm:
+ (WTF::scheduleDispatchFunctionsOnMainThread):
+ Use static instance of the mainThreadCaller instead of allocating and releasing it each time.
+ (WTF::initializeMainThreadPlatform):
+ * wtf/gtk/MainThreadChromium.cpp:
+ (WTF::initializeMainThreadPlatform):
+ * wtf/gtk/MainThreadGtk.cpp:
+ (WTF::initializeMainThreadPlatform):
+ * wtf/qt/MainThreadQt.cpp:
+ (WTF::initializeMainThreadPlatform):
+ * wtf/win/MainThreadWin.cpp:
+ (WTF::initializeMainThreadPlatform):
+ * wtf/wx/MainThreadWx.cpp:
+ (WTF::initializeMainThreadPlatform):
+
+2009-02-11 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Style cleanup.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::CodeLocationCommon::CodeLocationCommon):
+ (JSC::AbstractMacroAssembler::CodeLocationCommon::operator bool):
+ (JSC::AbstractMacroAssembler::CodeLocationCommon::reset):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::addressForSwitch):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::addressForExceptionHandler):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::addressForJSR):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::getJumpDestination):
+ (JSC::AbstractMacroAssembler::CodeLocationJump::relink):
+ (JSC::AbstractMacroAssembler::CodeLocationJump::CodeLocationJump):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::relink):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::calleeReturnAddressValue):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::CodeLocationCall):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabel32::repatch):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabel32::CodeLocationDataLabel32):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabelPtr::repatch):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabelPtr::CodeLocationDataLabelPtr):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::ProcessorReturnAddress):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToFunction):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::operator void*):
+ (JSC::AbstractMacroAssembler::PatchBuffer::link):
+ (JSC::::CodeLocationCommon::labelAtOffset):
+ (JSC::::CodeLocationCommon::jumpAtOffset):
+ (JSC::::CodeLocationCommon::callAtOffset):
+ (JSC::::CodeLocationCommon::dataLabelPtrAtOffset):
+ (JSC::::CodeLocationCommon::dataLabel32AtOffset):
+
+2009-02-11 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ * assembler/AbstractMacroAssembler.h: Fix comments.
+
+2009-02-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Trying to fix wx build.
+
+ * bytecode/JumpTable.h: Include "MacroAssembler.h", not <MacroAssembler.h>.
+ * jscore.bkl: Added assembler directory to search paths.
+
+2009-02-10 Gavin Barraclough <barraclough@apple.com>
+
+ Build
+ fix.
+ (Narrow
+ changelog
+ for
+ dhyatt).
+
+ * bytecode/Instruction.h:
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+
+2009-02-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Reduce use of void* / reinterpret_cast in JIT repatching code,
+ add strong types for Calls and for the various types of pointers
+ we retain into the JIT generated instruction stream.
+
+ No performance impact.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::ImmPtr::ImmPtr):
+ (JSC::AbstractMacroAssembler::ImmPtr::asIntptr):
+ (JSC::AbstractMacroAssembler::Imm32::Imm32):
+ (JSC::AbstractMacroAssembler::Label::Label):
+ (JSC::AbstractMacroAssembler::DataLabelPtr::DataLabelPtr):
+ (JSC::AbstractMacroAssembler::Call::Call):
+ (JSC::AbstractMacroAssembler::Call::link):
+ (JSC::AbstractMacroAssembler::Call::linkTo):
+ (JSC::AbstractMacroAssembler::Jump::Jump):
+ (JSC::AbstractMacroAssembler::Jump::linkTo):
+ (JSC::AbstractMacroAssembler::CodeLocationCommon::CodeLocationCommon):
+ (JSC::AbstractMacroAssembler::CodeLocationCommon::operator bool):
+ (JSC::AbstractMacroAssembler::CodeLocationCommon::reset):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::CodeLocationLabel):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::addressForSwitch):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::addressForExceptionHandler):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::addressForJSR):
+ (JSC::AbstractMacroAssembler::CodeLocationLabel::getJumpDestination):
+ (JSC::AbstractMacroAssembler::CodeLocationJump::CodeLocationJump):
+ (JSC::AbstractMacroAssembler::CodeLocationJump::relink):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::CodeLocationCall):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::relink):
+ (JSC::AbstractMacroAssembler::CodeLocationCall::calleeReturnAddressValue):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabel32::CodeLocationDataLabel32):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabel32::repatch):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabelPtr::CodeLocationDataLabelPtr):
+ (JSC::AbstractMacroAssembler::CodeLocationDataLabelPtr::repatch):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::ProcessorReturnAddress):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToFunction):
+ (JSC::AbstractMacroAssembler::ProcessorReturnAddress::operator void*):
+ (JSC::AbstractMacroAssembler::PatchBuffer::entry):
+ (JSC::AbstractMacroAssembler::PatchBuffer::trampolineAt):
+ (JSC::AbstractMacroAssembler::PatchBuffer::link):
+ (JSC::AbstractMacroAssembler::PatchBuffer::linkTailRecursive):
+ (JSC::AbstractMacroAssembler::PatchBuffer::patch):
+ (JSC::AbstractMacroAssembler::PatchBuffer::locationOf):
+ (JSC::AbstractMacroAssembler::PatchBuffer::returnAddressOffset):
+ (JSC::AbstractMacroAssembler::differenceBetween):
+ (JSC::::CodeLocationCommon::labelAtOffset):
+ (JSC::::CodeLocationCommon::jumpAtOffset):
+ (JSC::::CodeLocationCommon::callAtOffset):
+ (JSC::::CodeLocationCommon::dataLabelPtrAtOffset):
+ (JSC::::CodeLocationCommon::dataLabel32AtOffset):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::call):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::getCallReturnOffset):
+ * bytecode/CodeBlock.h:
+ (JSC::CallLinkInfo::CallLinkInfo):
+ (JSC::getStructureStubInfoReturnLocation):
+ (JSC::getCallLinkInfoReturnLocation):
+ * bytecode/Instruction.h:
+ (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+ (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+ * bytecode/JumpTable.h:
+ (JSC::StringJumpTable::ctiForValue):
+ (JSC::SimpleJumpTable::ctiForValue):
+ * bytecode/StructureStubInfo.h:
+ (JSC::StructureStubInfo::StructureStubInfo):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitCatch):
+ (JSC::prepareJumpTableForStringSwitch):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::cti_op_get_by_id_self_fail):
+ (JSC::getPolymorphicAccessStructureListSlot):
+ (JSC::Interpreter::cti_op_throw):
+ (JSC::Interpreter::cti_op_switch_imm):
+ (JSC::Interpreter::cti_op_switch_char):
+ (JSC::Interpreter::cti_op_switch_string):
+ (JSC::Interpreter::cti_vm_throw):
+ * jit/JIT.cpp:
+ (JSC::ctiSetReturnAddress):
+ (JSC::ctiPatchCallByReturnAddress):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JIT.h:
+ (JSC::CallRecord::CallRecord):
+ (JSC::JIT::compileGetByIdSelf):
+ (JSC::JIT::compileGetByIdProto):
+ (JSC::JIT::compileGetByIdChain):
+ (JSC::JIT::compilePutByIdReplace):
+ (JSC::JIT::compilePutByIdTransition):
+ (JSC::JIT::compilePatchGetArrayLength):
+ (JSC::JIT::emitCTICall):
+ * jit/JITCall.cpp:
+ (JSC::JIT::unlinkCall):
+ (JSC::JIT::linkCall):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitNakedCall):
+ (JSC::JIT::emitCTICall_internal):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdSlowCase):
+ (JSC::JIT::compilePutByIdSlowCase):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::patchGetByIdSelf):
+ (JSC::JIT::patchPutByIdReplace):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdSelf):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ (JSC::JIT::privateCompilePutByIdReplace):
+
+2009-02-10 Adam Roben <aroben@apple.com>
+
+ Windows build fix after r40813
+
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj: Added profiler/ to the include
+ path so that Profiler.h can be found.
+
+2009-02-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Provide a class type for a generated block of JIT code.
+ Also changes the return address -> bytecode index map to
+ track the return addess as an unsigned offset into the code
+ instead of a ptrdiff_t in terms of void**s - the latter is
+ equal to the actual offset / sizeof(void*), making it a
+ potentially lossy representation.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::PatchBuffer::returnAddressOffset):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::getCallReturnOffset):
+ * bytecode/CodeBlock.h:
+ (JSC::CallReturnOffsetToBytecodeIndex::CallReturnOffsetToBytecodeIndex):
+ (JSC::getCallReturnOffset):
+ (JSC::CodeBlock::getBytecodeIndex):
+ (JSC::CodeBlock::jitCode):
+ (JSC::CodeBlock::callReturnIndexVector):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::cti_vm_dontLazyLinkCall):
+ (JSC::Interpreter::cti_vm_lazyLinkCall):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JIT.h:
+ (JSC::):
+ * jit/JITCall.cpp:
+ (JSC::JIT::linkCall):
+ * jit/JITCode.h: Added.
+ (JSC::):
+ (JSC::JITCode::JITCode):
+ (JSC::JITCode::operator bool):
+ (JSC::JITCode::addressForCall):
+ (JSC::JITCode::offsetOf):
+ (JSC::JITCode::execute):
+
+2009-02-09 John Grabowski <jrg@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23856
+ Change the definition of "main thread" for Chromium on OSX.
+ It does not match the DARWIN definition.
+
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::initializeThreading):
+ (WTF::isMainThread):
+
+2009-02-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Minor bugfix, incorrect check meant that subtraction causing integer overflow
+ would be missed on x86-64 JIT.
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOp):
+
+2009-02-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ A more sensible register allocation for x86-64.
+
+ When WREC was ported to x86-64 it stuck with the same register allocation as x86.
+ This requires registers to be reordered on entry into WREC generated code, since
+ argument passing is different on x86-64 and x86 (regparm(3)). This patch switches
+ x86-64 to use a native register allocation, that does not require argument registers
+ to be reordered.
+
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateReturnSuccess):
+ (JSC::WREC::Generator::generateReturnFailure):
+ * wrec/WRECGenerator.h:
+
+2009-02-05 Adam Roben <aroben@apple.com>
+
+ Build fix
+
+ Rubberstamped by Sam Weinig.
+
+ * wtf/TypeTraits.h: Include Platform.h, since this header uses macros
+ defined there.
+
+2009-02-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23747
+ Add Chromium threading-related files.
+
+ * wtf/MainThread.cpp: Added platform guard to initializeMainThread.
+ * wtf/chromium/ChromiumThreading.h: Added.
+ * wtf/chromium/MainThreadChromium.cpp: Added.
+ (WTF::initializeMainThread):
+ (WTF::scheduleDispatchFunctionsOnMainThread):
+
+2009-02-05 David Levin <levin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Bug 23713: COMPILE_ASSERTS should be moved out of TypeTraits.h and into .cpp file
+ <https://bugs.webkit.org/show_bug.cgi?id=23713>
+
+ * GNUmakefile.am:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.scons:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * JavaScriptCoreSources.bkl:
+
+ * wtf/HashTraits.h:
+ Remove unnecessary header file that I missed when moving out the type traits form this file.
+
+ * wtf/TypeTraits.cpp: Added.
+ (WTF::):
+ * wtf/TypeTraits.h:
+ Moved the compile asserts into TypeTraits.cpp file.
+
+2009-02-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver 'the nun' Hunt.
+
+ Add -e switch to jsc to enable evaluation of scripts passed on the command line.
+
+ * jsc.cpp:
+ (Script::Script):
+ (runWithScripts):
+ (printUsageStatement):
+ (parseArguments):
+ (jscmain):
+
+2009-02-04 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Sam 'Big Mac' Weinig.
+
+ * assembler/AbstractMacroAssembler.h: Copied from assembler/MacroAssembler.h.
+ * assembler/MacroAssemblerX86.h: Copied from assembler/MacroAssembler.h.
+ * assembler/MacroAssemblerX86Common.h: Copied from assembler/MacroAssembler.h.
+ * assembler/MacroAssemblerX86_64.h: Copied from assembler/MacroAssembler.h.
+
+2009-02-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ This patch tidies up the MacroAssembler, cleaning up the code and refactoring out the
+ platform-specific parts. The MacroAssembler gets split up like a beef burger, with the
+ platform-agnostic data types being the lower bun (in the form of the class AbstractMacroAssembler),
+ the plaform-specific code generation forming a big meaty patty of methods like 'add32',
+ 'branch32', etc (MacroAssemblerX86), and finally topped off with the bun-lid of the
+ MacroAssembler class itself, providing covenience methods such as the stack peek & poke,
+ and backwards branch methods, all of which can be described in a platform independent
+ way using methods from the base class. The AbstractMacroAssembler is templated on the
+ type of the assembler class that will be used for code generation, and the three layers
+ are held together with the cocktail stick of inheritance.
+
+ The above description is a slight simplification since the MacroAssemblerX86 is actually
+ formed from two layers (in effect giving us a kind on bacon double cheeseburger) - with the
+ bulk of methods that are common between x86 & x86-64 implemented in MacroAssemblerX86Common,
+ which forms a base class for MacroAssemblerX86 and MacroAssemblerX86_64 (which add the methods
+ specific to the given platform).
+
+ I'm landing these changes first without splitting the classes across multiple files,
+ I will follow up with a second patch to split up the file MacroAssembler.h.
+
+ * assembler/MacroAssembler.h:
+ (JSC::AbstractMacroAssembler::):
+ (JSC::AbstractMacroAssembler::DataLabelPtr::DataLabelPtr):
+ (JSC::AbstractMacroAssembler::DataLabelPtr::patch):
+ (JSC::AbstractMacroAssembler::DataLabel32::DataLabel32):
+ (JSC::AbstractMacroAssembler::DataLabel32::patch):
+ (JSC::AbstractMacroAssembler::Label::Label):
+ (JSC::AbstractMacroAssembler::Jump::Jump):
+ (JSC::AbstractMacroAssembler::Jump::link):
+ (JSC::AbstractMacroAssembler::Jump::linkTo):
+ (JSC::AbstractMacroAssembler::Jump::patch):
+ (JSC::AbstractMacroAssembler::JumpList::link):
+ (JSC::AbstractMacroAssembler::JumpList::linkTo):
+ (JSC::AbstractMacroAssembler::PatchBuffer::link):
+ (JSC::AbstractMacroAssembler::PatchBuffer::addressOf):
+ (JSC::AbstractMacroAssembler::PatchBuffer::setPtr):
+ (JSC::AbstractMacroAssembler::size):
+ (JSC::AbstractMacroAssembler::copyCode):
+ (JSC::AbstractMacroAssembler::label):
+ (JSC::AbstractMacroAssembler::align):
+ (JSC::AbstractMacroAssembler::differenceBetween):
+ (JSC::MacroAssemblerX86Common::xor32):
+ (JSC::MacroAssemblerX86Common::load32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerX86Common::store32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerX86Common::move):
+ (JSC::MacroAssemblerX86Common::swap):
+ (JSC::MacroAssemblerX86Common::signExtend32ToPtr):
+ (JSC::MacroAssemblerX86Common::zeroExtend32ToPtr):
+ (JSC::MacroAssemblerX86Common::branch32):
+ (JSC::MacroAssemblerX86Common::jump):
+ (JSC::MacroAssemblerX86_64::add32):
+ (JSC::MacroAssemblerX86_64::sub32):
+ (JSC::MacroAssemblerX86_64::load32):
+ (JSC::MacroAssemblerX86_64::store32):
+ (JSC::MacroAssemblerX86_64::addPtr):
+ (JSC::MacroAssemblerX86_64::andPtr):
+ (JSC::MacroAssemblerX86_64::orPtr):
+ (JSC::MacroAssemblerX86_64::rshiftPtr):
+ (JSC::MacroAssemblerX86_64::subPtr):
+ (JSC::MacroAssemblerX86_64::xorPtr):
+ (JSC::MacroAssemblerX86_64::loadPtr):
+ (JSC::MacroAssemblerX86_64::loadPtrWithAddressOffsetPatch):
+ (JSC::MacroAssemblerX86_64::storePtr):
+ (JSC::MacroAssemblerX86_64::storePtrWithAddressOffsetPatch):
+ (JSC::MacroAssemblerX86_64::branchPtr):
+ (JSC::MacroAssemblerX86_64::branchTestPtr):
+ (JSC::MacroAssemblerX86_64::branchAddPtr):
+ (JSC::MacroAssemblerX86_64::branchSubPtr):
+ (JSC::MacroAssemblerX86_64::branchPtrWithPatch):
+ (JSC::MacroAssemblerX86_64::storePtrWithPatch):
+ (JSC::MacroAssemblerX86::add32):
+ (JSC::MacroAssemblerX86::sub32):
+ (JSC::MacroAssemblerX86::load32):
+ (JSC::MacroAssemblerX86::store32):
+ (JSC::MacroAssemblerX86::branch32):
+ (JSC::MacroAssemblerX86::branchPtrWithPatch):
+ (JSC::MacroAssemblerX86::storePtrWithPatch):
+ (JSC::MacroAssembler::pop):
+ (JSC::MacroAssembler::peek):
+ (JSC::MacroAssembler::poke):
+ (JSC::MacroAssembler::branchPtr):
+ (JSC::MacroAssembler::branch32):
+ (JSC::MacroAssembler::branch16):
+ (JSC::MacroAssembler::branchTestPtr):
+ (JSC::MacroAssembler::addPtr):
+ (JSC::MacroAssembler::andPtr):
+ (JSC::MacroAssembler::orPtr):
+ (JSC::MacroAssembler::rshiftPtr):
+ (JSC::MacroAssembler::subPtr):
+ (JSC::MacroAssembler::xorPtr):
+ (JSC::MacroAssembler::loadPtr):
+ (JSC::MacroAssembler::loadPtrWithAddressOffsetPatch):
+ (JSC::MacroAssembler::storePtr):
+ (JSC::MacroAssembler::storePtrWithAddressOffsetPatch):
+ (JSC::MacroAssembler::branchAddPtr):
+ (JSC::MacroAssembler::branchSubPtr):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileBinaryArithOp):
+
+2009-02-04 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23681
+ Worker tests crash in debug builds if run --singly
+
+ The crash happened because worker threads continued running while debug-only static objects
+ were already being destroyed on main thread.
+
+ * runtime/Structure.cpp: Create static debug-only sets in heap, so that they don't get
+ destroyed.
+
+ * wtf/ThreadingPthreads.cpp: Changed assertions to conventional form.
+
+2009-02-03 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23715
+
+ Simplify MacroAssembler interface, by combining comparison methods.
+ Seprate operations are combined as follows:
+ jz32/jnz32/jzPtr/jnzPtr -> branchTest32/branchTestPtr,
+ j*(Add|Mul|Sub)32/j*(Add|Mul|Sub)Ptr -> branch(Add|Mul|Sub)32/branch(Add|Mul|Sub)Ptr
+ j*32/j*Ptr (all other two op combparisons) -> branch32/brnachPtr
+ set*32 -> set32
+
+ Also, represent the Scale of BaseIndex addresses as a plain enum (0,1,2,3),
+ instead of as multiplicands (1,2,4,8).
+
+ This patch singificantly reduces replication of code, and increases functionality supported
+ by the MacroAssembler. No performance impact.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::):
+ (JSC::MacroAssembler::branchPtr):
+ (JSC::MacroAssembler::branchPtrWithPatch):
+ (JSC::MacroAssembler::branch32):
+ (JSC::MacroAssembler::branch16):
+ (JSC::MacroAssembler::branchTestPtr):
+ (JSC::MacroAssembler::branchTest32):
+ (JSC::MacroAssembler::branchAddPtr):
+ (JSC::MacroAssembler::branchAdd32):
+ (JSC::MacroAssembler::branchMul32):
+ (JSC::MacroAssembler::branchSubPtr):
+ (JSC::MacroAssembler::branchSub32):
+ (JSC::MacroAssembler::set32):
+ (JSC::MacroAssembler::setTest32):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::jccRel32):
+ (JSC::X86Assembler::setccOpcode):
+ (JSC::X86Assembler::cmpq_mr):
+ (JSC::X86Assembler::setcc_r):
+ (JSC::X86Assembler::sete_r):
+ (JSC::X86Assembler::setne_r):
+ (JSC::X86Assembler::jne):
+ (JSC::X86Assembler::je):
+ (JSC::X86Assembler::jl):
+ (JSC::X86Assembler::jb):
+ (JSC::X86Assembler::jle):
+ (JSC::X86Assembler::jbe):
+ (JSC::X86Assembler::jge):
+ (JSC::X86Assembler::jg):
+ (JSC::X86Assembler::ja):
+ (JSC::X86Assembler::jae):
+ (JSC::X86Assembler::jo):
+ (JSC::X86Assembler::jp):
+ (JSC::X86Assembler::js):
+ (JSC::X86Assembler::jcc):
+ (JSC::X86Assembler::X86InstructionFormatter::putModRmSib):
+ * jit/JIT.cpp:
+ (JSC::JIT::compileOpStrictEq):
+ (JSC::JIT::emitSlowScriptCheck):
+ (JSC::JIT::privateCompileMainPass):
+ (JSC::JIT::privateCompileSlowCases):
+ (JSC::JIT::privateCompile):
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::compileFastArith_op_lshift):
+ (JSC::JIT::compileFastArith_op_mod):
+ (JSC::JIT::compileFastArith_op_post_inc):
+ (JSC::JIT::compileFastArith_op_post_dec):
+ (JSC::JIT::compileFastArith_op_pre_inc):
+ (JSC::JIT::compileFastArith_op_pre_dec):
+ (JSC::JIT::compileBinaryArithOp):
+ (JSC::JIT::compileFastArith_op_add):
+ (JSC::JIT::compileFastArith_op_mul):
+ * jit/JITCall.cpp:
+ (JSC::JIT::compileOpCall):
+ (JSC::JIT::compileOpCallSlowCase):
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::checkStructure):
+ (JSC::JIT::emitJumpIfJSCell):
+ (JSC::JIT::emitJumpIfNotJSCell):
+ (JSC::JIT::emitJumpIfImmediateNumber):
+ (JSC::JIT::emitJumpIfNotImmediateNumber):
+ (JSC::JIT::emitJumpIfImmediateInteger):
+ (JSC::JIT::emitJumpIfNotImmediateInteger):
+ (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::compileGetByIdHotPath):
+ (JSC::JIT::compilePutByIdHotPath):
+ (JSC::JIT::privateCompilePutByIdTransition):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match):
+ * wrec/WRECGenerator.cpp:
+ (JSC::WREC::Generator::generateEnter):
+ (JSC::WREC::Generator::generateIncrementIndex):
+ (JSC::WREC::Generator::generateLoadCharacter):
+ (JSC::WREC::Generator::generateJumpIfNotEndOfInput):
+ (JSC::WREC::Generator::generateBackreferenceQuantifier):
+ (JSC::WREC::Generator::generateNonGreedyQuantifier):
+ (JSC::WREC::Generator::generateGreedyQuantifier):
+ (JSC::WREC::Generator::generatePatternCharacterPair):
+ (JSC::WREC::Generator::generatePatternCharacter):
+ (JSC::WREC::Generator::generateCharacterClassInvertedRange):
+ (JSC::WREC::Generator::generateCharacterClassInverted):
+ (JSC::WREC::Generator::generateAssertionBOL):
+ (JSC::WREC::Generator::generateAssertionEOL):
+ (JSC::WREC::Generator::generateAssertionWordBoundary):
+ (JSC::WREC::Generator::generateBackreference):
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Fix a bug in Vector's shrinkCapacity method. It did not properly copy elements into the inline buffer
+ when shrinking down from a size that was greater than the inline capacity.
+
+ Reviewed by Maciej
+
+ * wtf/Vector.h:
+ (WTF::VectorBuffer::VectorBuffer):
+ (WTF::VectorBuffer::allocateBuffer):
+
+2009-02-03 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Added accessor for JSByteArray storage.
+
+ * runtime/JSByteArray.h:
+ (JSC::JSByteArray::storage):
+
+2009-02-03 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23560
+ Implement SharedTimer on WorkerRunLoop
+
+ * JavaScriptCore.exp:
+ Forgot to expose ThreadCondition::timedWait() in one of previous patches.
+
+2009-02-02 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough.
@@ -229,11 +2597,103 @@
* wrec/WRECGenerator.cpp:
(JSC::WREC::Generator::generateCharacterClassInvertedRange):
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-02-02 Darin Adler <darin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Bug 23676: Speed up uses of reserveCapacity on new vectors by adding a new reserveInitialCapacity
+ https://bugs.webkit.org/show_bug.cgi?id=23676
+
+ * API/JSObjectRef.cpp:
+ (JSObjectCopyPropertyNames): Use reserveInitialCapacity.
+ * parser/Lexer.cpp:
+ (JSC::Lexer::Lexer): Ditto.
+ (JSC::Lexer::clear): Ditto.
+
+ * wtf/Vector.h: Added reserveInitialCapacity, a more efficient version of
+ reserveCapacity for use when the vector is brand new (still size 0 with no
+ capacity other than the inline capacity).
+
+2009-01-30 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Oliver Hunt.
+
+ <rdar://problem/6391501> Enable the JIT on Mac OS X x86_64 as it passes all tests.
+
+ * wtf/Platform.h:
+
+2009-01-30 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Mark Rowe and Sam Weinig.
+
+ Finally fix load() to propagate exceptions correctly.
+
+ * jsc.cpp:
+ (functionLoad):
+
+2009-01-30 David Levin <levin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23618
+ Templated worker tasks should be more error proof to use.
+ Fix Chromium build.
- Merge r40397.
+ * wtf/TypeTraits.h:
+ (WTF::IsConvertibleToInteger::IsConvertibleToDouble):
+ Avoid "possible loss of data" warning when using Microsoft's C++ compiler
+ by avoiding an implicit conversion of int types to doubles.
- 2009-01-29 Stephanie Lewis <slewis@apple.com>
+2009-01-30 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Bug 23580: GNU mode RVCT compilation support
+ <https://bugs.webkit.org/show_bug.cgi?id=23580>
+
+ * pcre/pcre_exec.cpp: Use COMPILER(GCC) instead of __GNUC__.
+ * wtf/FastMalloc.cpp: Ditto.
+ (WTF::TCMallocStats::):
+ * wtf/Platform.h: Don't define COMPILER(GCC) with RVCT --gnu.
+
+2009-01-30 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23618: Templated worker tasks should be more error proof to use
+ <https://bugs.webkit.org/show_bug.cgi?id=23618>
+
+ Add the type traits needed for the generic worker tasks
+ and compile asserts for them.
+
+ Add a summary header to the TypeTraits.h file to explain what is in there.
+
+ Add a note to explain IsPod's deficiencies.
+
+ * wtf/TypeTraits.h:
+
+2009-01-30 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23616: Various "template helpers" should be consolidated from isolated files in JavaScriptCore.
+ <https://bugs.webkit.org/show_bug.cgi?id=23616>
+
+ * wtf/TypeTraits.h: Moved RemovePointer, IsPod, IsInteger to this file.
+
+ * wtf/OwnPtr.h: Use RemovePointer from TypeTraits.h.
+ * wtf/RetainPtr.h: Ditto.
+
+ * wtf/HashTraits.h: Use IsInteger from TypeTraits.h.
+
+ * wtf/VectorTraits.h: Use IsPod from TypeTraits.h.
+
+ * GNUmakefile.am:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ Added TypeTraits.h.
+
+2009-01-29 Stephanie Lewis <slewis@apple.com>
RS by Oliver Hunt.
@@ -241,11 +2701,7 @@
* JavaScriptCore.order:
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40396.
-
- 2009-01-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+2009-01-29 Cameron Zwarich <cwzwarich@uwaterloo.ca>
Reviewed by Oliver Hunt.
@@ -266,11 +2722,7 @@
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40345.
-
- 2009-01-28 Sam Weinig <sam@webkit.org>
+2009-01-28 Sam Weinig <sam@webkit.org>
Reviewed by Gavin Barraclough.
@@ -279,11 +2731,7 @@
* JavaScriptCore.exp: Export JSGlobalData::sharedInstance.
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40339.
-
- 2009-01-28 Sam Weinig <sam@webkit.org>
+2009-01-28 Sam Weinig <sam@webkit.org>
Reviewed by Geoff Garen.
@@ -302,11 +2750,7 @@
the array.
(JSC::JSArray::increaseVectorLength): Ditto.
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40332.
-
- 2009-01-28 Sam Weinig <sam@webkit.org>
+2009-01-28 Sam Weinig <sam@webkit.org>
Reviewed by Geoff Garen.
@@ -339,6 +2783,25 @@
* runtime/JSObject.h:
(JSC::JSObject::isActivationObject): Added.
+2009-01-28 David Kilzer <ddkilzer@apple.com>
+
+ Bug 23490: Remove initialRefCount argument from RefCounted class
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23490>
+
+ Reviewed by Darin Adler.
+
+ RefCountedBase now always starts with a ref count of 1, so there
+ is no need to pass the initialRefCount into the class anymore.
+
+ * wtf/ByteArray.h:
+ (WTF::ByteArray::ByteArray): Removed call to RefCounted(1).
+ * wtf/RefCounted.h:
+ (WTF::RefCountedBase::RefCountedBase): Changed to start with a
+ ref count of 1.
+ (WTF::RefCounted::RefCounted): Removed initialRefCount argument
+ and removed call to RefCounted(1).
+
2009-01-26 Adele Peterson <adele@apple.com>
Build fix.
diff --git a/JavaScriptCore/Configurations/Base.xcconfig b/JavaScriptCore/Configurations/Base.xcconfig
index 4154cb8..b639dad 100644
--- a/JavaScriptCore/Configurations/Base.xcconfig
+++ b/JavaScriptCore/Configurations/Base.xcconfig
@@ -12,7 +12,7 @@ GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_MODEL_TUNING = G5;
GCC_OBJC_CALL_CXX_CDTORS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
-GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST $(GCC_PREPROCESSOR_DEFINITIONS);
+GCC_PREPROCESSOR_DEFINITIONS = $(DEBUG_DEFINES) HAVE_DTRACE=$(HAVE_DTRACE) WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST $(GCC_PREPROCESSOR_DEFINITIONS);
GCC_STRICT_ALIASING = YES;
GCC_THREADSAFE_STATICS = NO;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
@@ -34,6 +34,11 @@ WARNING_CFLAGS_x86_64 = $(WARNING_CFLAGS_BASE);
HEADER_SEARCH_PATHS = . icu $(HEADER_SEARCH_PATHS);
+REAL_PLATFORM_NAME = $(REAL_PLATFORM_NAME_$(PLATFORM_NAME));
+REAL_PLATFORM_NAME_ = $(REAL_PLATFORM_NAME_macosx);
+REAL_PLATFORM_NAME_macosx = macosx;
+
+
// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants.
// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant.
DEBUG_DEFINES_debug = ;
@@ -57,6 +62,15 @@ GCC_VERSION = $(GCC_VERSION_$(XCODE_VERSION_ACTUAL));
GCC_VERSION_0310 = 4.2;
+// HAVE_DTRACE is disabled on Leopard due to <rdar://problem/5628149>
+HAVE_DTRACE = $(HAVE_DTRACE_$(REAL_PLATFORM_NAME));
+HAVE_DTRACE_macosx = $(HAVE_DTRACE_macosx_$(MAC_OS_X_VERSION_MAJOR));
+HAVE_DTRACE_macosx_ = $(HAVE_DTRACE_macosx_1040);
+HAVE_DTRACE_macosx_1040 = 0;
+HAVE_DTRACE_macosx_1050 = 0;
+HAVE_DTRACE_macosx_1060 = 1;
+
+
// <rdar://problem/5488678>: Production builds on 10.4 PowerPC need to have debugging symbols disabled to prevent a huge STABS section being generated.
// Xcode on 10.4 does not define MAC_OS_X_VERSION_MAJOR, so the default Mac OS X version is treated as 10.4.
GCC_GENERATE_DEBUGGING_SYMBOLS = $(GCC_GENERATE_DEBUGGING_SYMBOLS_$(CURRENT_ARCH));
diff --git a/JavaScriptCore/Configurations/DebugRelease.xcconfig b/JavaScriptCore/Configurations/DebugRelease.xcconfig
index cbb2933..a9c39aa 100644
--- a/JavaScriptCore/Configurations/DebugRelease.xcconfig
+++ b/JavaScriptCore/Configurations/DebugRelease.xcconfig
@@ -1,5 +1,12 @@
#include "Base.xcconfig"
-ARCHS = $(NATIVE_ARCH);
+
+ARCHS = $(ARCHS_$(MAC_OS_X_VERSION_MAJOR));
+ARCHS_ = $(ARCHS_1040);
+ARCHS_1040 = $(NATIVE_ARCH);
+ARCHS_1050 = $(NATIVE_ARCH);
+ARCHS_1060 = $(ARCHS_STANDARD_32_64_BIT);
+
+ONLY_ACTIVE_ARCH = YES;
MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR));
MACOSX_DEPLOYMENT_TARGET_ = 10.4;
diff --git a/JavaScriptCore/Configurations/JavaScriptCore.xcconfig b/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
index ef199d2..0976c16 100644
--- a/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
+++ b/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
@@ -12,8 +12,14 @@ INFOPLIST_FILE = Info.plist;
INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks;
PRODUCT_NAME = JavaScriptCore;
-// This needs to be kept sorted, and in sync with FEATURE_DEFINES in WebCore.xcconfig, WebKit.xcconfig and the default settings of build-webkit.
-FEATURE_DEFINES = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_WORKERS ENABLE_XPATH ENABLE_XSLT;
+// This needs to be kept sorted, and in sync with FEATURE_DEFINES in WebCore.xcconfig, WebKit.xcconfig and
+// the default settings of build-webkit to prevent needless rebuilding when using both Xcode and build-webkit.
+FEATURE_DEFINES = $(FEATURE_DEFINES_$(MAC_OS_X_VERSION_MAJOR));
+FEATURE_DEFINES_BASE = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_WORKERS ENABLE_XPATH ENABLE_XSLT;
+FEATURE_DEFINES_ = $(FEATURE_DEFINES_1040);
+FEATURE_DEFINES_1040 = $(FEATURE_DEFINES_BASE);
+FEATURE_DEFINES_1050 = $(FEATURE_DEFINES_BASE);
+FEATURE_DEFINES_1060 = $(FEATURE_DEFINES_BASE) ENABLE_GEOLOCATION;
OTHER_CFLAGS = $(OTHER_CFLAGS_$(CONFIGURATION)_$(CURRENT_VARIANT));
OTHER_CFLAGS_Release_normal = $(OTHER_CFLAGS_normal_$(XCODE_VERSION_ACTUAL));
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index 16a349c..ab0aa9b 100644
--- a/JavaScriptCore/Configurations/Version.xcconfig
+++ b/JavaScriptCore/Configurations/Version.xcconfig
@@ -1,5 +1,5 @@
-MAJOR_VERSION = 528;
-MINOR_VERSION = 15;
+MAJOR_VERSION = 530;
+MINOR_VERSION = 5;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 3d90470..b9feada 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -76,12 +76,15 @@ javascriptcore_sources += \
JavaScriptCore/jit/ExecutableAllocator.h \
JavaScriptCore/jit/JIT.cpp \
JavaScriptCore/jit/JITCall.cpp \
+ JavaScriptCore/jit/JITCode.h \
JavaScriptCore/jit/JITPropertyAccess.cpp \
JavaScriptCore/jit/JITArithmetic.cpp \
JavaScriptCore/jit/ExecutableAllocator.cpp \
JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \
JavaScriptCore/jit/JIT.h \
JavaScriptCore/jit/JITInlineMethods.h \
+ JavaScriptCore/jit/JITStubs.cpp \
+ JavaScriptCore/jit/JITStubs.h \
JavaScriptCore/bytecode/StructureStubInfo.cpp \
JavaScriptCore/bytecode/StructureStubInfo.h \
JavaScriptCore/bytecode/CodeBlock.cpp \
@@ -130,8 +133,11 @@ javascriptcore_sources += \
JavaScriptCore/icu/unicode/utypes.h \
JavaScriptCore/icu/unicode/uversion.h \
JavaScriptCore/assembler/X86Assembler.h \
+ JavaScriptCore/assembler/AbstractMacroAssembler.h \
JavaScriptCore/assembler/AssemblerBuffer.h \
JavaScriptCore/assembler/MacroAssembler.h \
+ JavaScriptCore/assembler/MacroAssemblerX86.h \
+ JavaScriptCore/assembler/MacroAssemblerX86Common.h \
JavaScriptCore/os-win32/stdbool.h \
JavaScriptCore/os-win32/stdint.h \
JavaScriptCore/pcre/pcre.h \
@@ -157,6 +163,8 @@ javascriptcore_sources += \
JavaScriptCore/profiler/TreeProfile.h \
JavaScriptCore/interpreter/CallFrame.cpp \
JavaScriptCore/interpreter/CallFrame.h \
+ JavaScriptCore/runtime/TimeoutChecker.cpp \
+ JavaScriptCore/runtime/TimeoutChecker.h \
JavaScriptCore/runtime/InitializeThreading.cpp \
JavaScriptCore/runtime/InitializeThreading.h \
JavaScriptCore/runtime/JSActivation.cpp \
@@ -247,6 +255,8 @@ javascriptcore_sources += \
JavaScriptCore/wtf/Threading.cpp \
JavaScriptCore/wtf/ThreadingGtk.cpp \
JavaScriptCore/wtf/ThreadingPthreads.cpp \
+ JavaScriptCore/wtf/TypeTraits.cpp \
+ JavaScriptCore/wtf/TypeTraits.h \
JavaScriptCore/wtf/UnusedParam.h \
JavaScriptCore/wtf/Vector.h \
JavaScriptCore/wtf/VectorTraits.h \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 5e1bb78..993ebe7 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -111,7 +111,7 @@ __ZN3JSC12DateInstance4infoE
__ZN3JSC12JSGlobalData10ClientDataD2Ev
__ZN3JSC12JSGlobalData12createLeakedEv
__ZN3JSC12JSGlobalData14sharedInstanceEv
-__ZN3JSC12JSGlobalData6createEv
+__ZN3JSC12JSGlobalData6createEb
__ZN3JSC12JSGlobalDataD1Ev
__ZN3JSC12SamplingTool13notifyOfScopeEPNS_9ScopeNodeE
__ZN3JSC12SamplingTool4dumpEPNS_9ExecStateE
@@ -132,15 +132,13 @@ __ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
__ZN3JSC14JSGlobalObject10globalExecEv
__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
-__ZN3JSC14JSGlobalObject14setTimeoutTimeEj
-__ZN3JSC14JSGlobalObject16stopTimeoutCheckEv
__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
-__ZN3JSC14JSGlobalObject17startTimeoutCheckEv
__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
__ZN3JSC14JSGlobalObject4markEv
__ZN3JSC14JSGlobalObjectD2Ev
__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
+__ZN3JSC14TimeoutChecker5resetEv
__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
__ZN3JSC15JSWrapperObject4markEv
__ZN3JSC15toInt32SlowCaseEdRb
@@ -284,6 +282,7 @@ __ZN3WTF13tryFastCallocEmm
__ZN3WTF15ThreadCondition4waitERNS_5MutexE
__ZN3WTF15ThreadCondition6signalEv
__ZN3WTF15ThreadCondition9broadcastEv
+__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
__ZN3WTF15ThreadConditionC1Ev
__ZN3WTF15ThreadConditionD1Ev
__ZN3WTF16callOnMainThreadEPFvPvES0_
diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri
index 6aee0aa..eb4bab3 100644
--- a/JavaScriptCore/JavaScriptCore.pri
+++ b/JavaScriptCore/JavaScriptCore.pri
@@ -14,18 +14,20 @@ win32-* {
}
# Disable the JIT due to numerous observed miscompilations :(
-#CONFIG(release):isEqual(QT_ARCH,i386) {
-# JIT_DEFINES = ENABLE_JIT ENABLE_WREC ENABLE_JIT_OPTIMIZE_CALL ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS ENABLE_JIT_OPTIMIZE_ARITHMETIC
-# # gcc <= 4.1 is known to miscompile, so require >= 4.2, written as major > 3 and minor > 1
-# linux-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,1) {
-# DEFINES += $$JIT_DEFINES
-# SOURCES += wtf/TCSystemAlloc.cpp
-# DEFINES -= USE_SYSTEM_MALLOC
-# }
-# win32-msvc* {
-# DEFINES += $$JIT_DEFINES
-# }
-#}
+!contains(DEFINES, ENABLE_JIT=.) {
+ CONFIG(release):isEqual(QT_ARCH,i386) {
+ JIT_DEFINES = ENABLE_JIT ENABLE_WREC ENABLE_JIT_OPTIMIZE_CALL ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS ENABLE_JIT_OPTIMIZE_ARITHMETIC
+ # Require gcc >= 4.1
+ linux-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) {
+ DEFINES += $$JIT_DEFINES WTF_USE_JIT_STUB_ARGUMENT_VA_LIST
+ QMAKE_CXXFLAGS += -fno-stack-protector
+ QMAKE_CFLAGS += -fno-stack-protector
+ }
+ win32-msvc* {
+ DEFINES += $$JIT_DEFINES WTF_USE_JIT_STUB_ARGUMENT_REGISTER
+ }
+ }
+}
include(pcre/pcre.pri)
@@ -51,6 +53,7 @@ SOURCES += \
wtf/MainThread.cpp \
wtf/RandomNumber.cpp \
wtf/RefCountedLeakCounter.cpp \
+ wtf/TypeTraits.cpp \
wtf/unicode/CollatorDefault.cpp \
wtf/unicode/icu/CollatorICU.cpp \
wtf/unicode/UTF8.cpp \
@@ -71,6 +74,7 @@ SOURCES += \
runtime/JSVariableObject.cpp \
runtime/JSActivation.cpp \
runtime/JSNotAnObject.cpp \
+ runtime/TimeoutChecker.cpp \
bytecode/CodeBlock.cpp \
bytecode/StructureStubInfo.cpp \
bytecode/JumpTable.cpp \
@@ -79,6 +83,7 @@ SOURCES += \
jit/JITArithmetic.cpp \
jit/JITPropertyAccess.cpp \
jit/ExecutableAllocator.cpp \
+ jit/JITStubs.cpp \
bytecompiler/BytecodeGenerator.cpp \
runtime/ExceptionHelpers.cpp \
runtime/JSPropertyNameIterator.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.scons b/JavaScriptCore/JavaScriptCore.scons
index 24e5003..30665cf 100644
--- a/JavaScriptCore/JavaScriptCore.scons
+++ b/JavaScriptCore/JavaScriptCore.scons
@@ -114,6 +114,7 @@ sources['runtime'] = [
'runtime/StringPrototype.cpp',
'runtime/Structure.cpp',
'runtime/StructureChain.cpp',
+ 'runtime/TimeoutChecker.cpp',
'runtime/UString.cpp',
]
sources['bytecode'] = [
@@ -149,6 +150,7 @@ sources['wtf'] = [
'wtf/RandomNumber.cpp',
'wtf/RefCountedLeakCounter.cpp',
'wtf/Threading.cpp',
+ 'wtf/TypeTraits.cpp',
'wtf/dtoa.cpp',
]
sources['wtf/unicode'] = [
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index e28adab..a19b310 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -505,10 +505,6 @@
>
</File>
<File
- RelativePath="..\..\runtime\Interpreter.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\JSActivation.cpp"
>
</File>
@@ -1290,6 +1286,22 @@
>
</File>
<File
+ RelativePath="..\..\runtime\TimeoutChecker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\TimeoutChecker.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\JITStubs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jit\JITStubs.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\JSPropertyNameIterator.cpp"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
index 4f44ddc..6d6b588 100755
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh
@@ -29,7 +29,7 @@ export SDKROOT
export BUILT_PRODUCTS_DIR="$XDSTROOT/obj/JavaScriptCore"
-mkdir -p "${BUILT_PRODUCTS_DIR}/DerivedSources"
+mkdir -p "${BUILT_PRODUCTS_DIR}/DerivedSources/docs"
cd "${BUILT_PRODUCTS_DIR}/DerivedSources"
export JavaScriptCore="${XSRCROOT}"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 3934b15..76c76ff 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -459,6 +459,14 @@
>
</File>
<File
+ RelativePath="..\..\wtf\TypeTraits.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\TypeTraits.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\unicode\Unicode.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
index 0b3a006..5ca2306 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jsc.vcproj
@@ -39,7 +39,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -109,7 +109,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -178,7 +178,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;../../../icu/include;&quot;$(WebKitLibrariesDir)\include&quot;;../../jit/"
PreprocessorDefinitions="__STD_C"
/>
<Tool
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
index d4d9966..d13ed56 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapi.vcproj
@@ -89,7 +89,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\API\tests\testapi.js&quot; &quot;$(OutDir)&quot;"
/>
</Configuration>
<Configuration
@@ -166,7 +166,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\API\tests\testapi.js&quot; &quot;$(OutDir)&quot;"
/>
</Configuration>
<Configuration
@@ -242,7 +242,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\API\tests\testapi.js&quot; &quot;$(OutDir)&quot;"
/>
</Configuration>
</Configurations>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 3c02898..e10ec7b 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -40,6 +40,8 @@
088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 088FA5BA0EF76D4300578E6F /* RandomNumber.h */; settings = {ATTRIBUTES = (Private, ); }; };
08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */ = {isa = PBXBuildFile; fileRef = 08E279E80EF83B10007DB523 /* RandomNumberSeed.h */; };
0B1F921D0F1753500036468E /* PtrAndFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B1F921B0F17502D0036468E /* PtrAndFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B330C260F38C62300692DE3 /* TypeTraits.cpp */; };
+ 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */; };
140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
141211310A48794D00480255 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
@@ -82,11 +84,15 @@
1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; };
1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */; };
+ 14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */; };
+ 14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */; };
+ 14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
14ABDF600A437FEF00ECCA01 /* JSCallbackObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14ABDF5E0A437FEF00ECCA01 /* JSCallbackObject.cpp */; };
14B8EC720A5652090062BE54 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; };
+ 14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A6581A0F4E36F4000150FD /* JITStubs.h */; settings = {ATTRIBUTES = (Private, ); }; };
14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 180B9AF00F16C569009BDBC5 /* CurrentTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */; };
@@ -106,6 +112,10 @@
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 */; };
7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */; };
+ 860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */; };
+ 860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */; };
+ 860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */; };
+ 860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */; };
869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; };
869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; };
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -114,6 +124,7 @@
86CC85A10EE79A4700288682 /* JITInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CC85A00EE79A4700288682 /* JITInlineMethods.h */; };
86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85A20EE79B7400288682 /* JITCall.cpp */; };
86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */; };
+ 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CCEFDD0F413F8900FD7F9E /* JITCode.h */; };
905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */; };
90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */; settings = {ATTRIBUTES = (Private, ); }; };
930754C108B0F68000AB3056 /* pcre_compile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 930754BF08B0F68000AB3056 /* pcre_compile.cpp */; };
@@ -425,6 +436,8 @@
088FA5BA0EF76D4300578E6F /* RandomNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumber.h; sourceTree = "<group>"; };
08E279E80EF83B10007DB523 /* RandomNumberSeed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumberSeed.h; sourceTree = "<group>"; };
0B1F921B0F17502D0036468E /* PtrAndFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PtrAndFlags.h; sourceTree = "<group>"; };
+ 0B330C260F38C62300692DE3 /* TypeTraits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeTraits.cpp; sourceTree = "<group>"; };
+ 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; };
@@ -483,7 +496,11 @@
148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefPtrHashMap.h; sourceTree = "<group>"; };
149559ED0DDCDDF700648087 /* DebuggerCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerCallFrame.cpp; sourceTree = "<group>"; };
149B24FF0D8AF6D1009CB8C7 /* Register.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Register.h; sourceTree = "<group>"; };
+ 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubs.cpp; sourceTree = "<group>"; };
14A396A60CD2933100B5B4FF /* SymbolTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = "<group>"; };
+ 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeoutChecker.cpp; sourceTree = "<group>"; };
+ 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeoutChecker.h; sourceTree = "<group>"; };
+ 14A6581A0F4E36F4000150FD /* JITStubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubs.h; sourceTree = "<group>"; };
14ABB36E099C076400E2A24F /* JSValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSValue.h; sourceTree = "<group>"; };
14ABB454099C2A0F00E2A24F /* JSType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSType.h; sourceTree = "<group>"; };
14ABDF5D0A437FEF00ECCA01 /* JSCallbackObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObject.h; sourceTree = "<group>"; };
@@ -575,6 +592,10 @@
7E4EE7080EBB7963005934AA /* StructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureChain.h; sourceTree = "<group>"; };
7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureChain.cpp; sourceTree = "<group>"; };
7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeInfo.h; sourceTree = "<group>"; };
+ 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractMacroAssembler.h; sourceTree = "<group>"; };
+ 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86.h; sourceTree = "<group>"; };
+ 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86_64.h; sourceTree = "<group>"; };
+ 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86Common.h; sourceTree = "<group>"; };
869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; };
869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; };
869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
@@ -583,6 +604,7 @@
86CC85A00EE79A4700288682 /* JITInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineMethods.h; sourceTree = "<group>"; };
86CC85A20EE79B7400288682 /* JITCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCall.cpp; sourceTree = "<group>"; };
86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess.cpp; sourceTree = "<group>"; };
+ 86CCEFDD0F413F8900FD7F9E /* JITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCode.h; sourceTree = "<group>"; };
905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCountedLeakCounter.cpp; sourceTree = "<group>"; };
90D3469B0E285280009492EE /* RefCountedLeakCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCountedLeakCounter.h; sourceTree = "<group>"; };
9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; };
@@ -960,6 +982,9 @@
1429D92C0ED22D7000B89619 /* jit */ = {
isa = PBXGroup;
children = (
+ 14A6581A0F4E36F4000150FD /* JITStubs.h */,
+ 14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */,
+ 86CCEFDD0F413F8900FD7F9E /* JITCode.h */,
A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */,
A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */,
A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */,
@@ -1082,6 +1107,7 @@
65162EF108E6A21C007556CD /* wtf */ = {
isa = PBXGroup;
children = (
+ 0B330C260F38C62300692DE3 /* TypeTraits.cpp */,
06D358A00DAAD9C4003B174E /* mac */,
E195678D09E7CF1200B89D13 /* unicode */,
938C4F690CA06BC700D9310A /* ASCIICType.h */,
@@ -1142,6 +1168,7 @@
5D6A566A0F05995500266145 /* Threading.cpp */,
E1EE79220D6C95CD00FEA3BA /* Threading.h */,
E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */,
+ 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */,
935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */,
6592C316098B7DE10003D4F6 /* Vector.h */,
6592C317098B7DE10003D4F6 /* VectorTraits.h */,
@@ -1359,6 +1386,8 @@
7E4EE7080EBB7963005934AA /* StructureChain.h */,
BC9041470EB9250900FE26FA /* StructureTransitionTable.h */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
+ 14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */,
+ 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */,
5D53726D0E1C546B0021E549 /* Tracing.d */,
5D53726E0E1C54880021E549 /* Tracing.h */,
6507D2970E871E4A00D7D896 /* TypeInfo.h */,
@@ -1425,6 +1454,10 @@
9688CB120ED12B4E001D649F /* assembler */ = {
isa = PBXGroup;
children = (
+ 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */,
+ 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */,
+ 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */,
+ 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */,
9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */,
9688CB140ED12B4E001D649F /* X86Assembler.h */,
@@ -1492,6 +1525,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ 14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */,
BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
BC18C3E90E16F5CD00B34460 /* ASCIICType.h in Headers */,
BC18C3EB0E16F5CD00B34460 /* AVLTree.h in Headers */,
@@ -1684,6 +1718,7 @@
5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
95CD41B40E1BF6560085358E /* TreeProfile.h in Headers */,
6507D29E0E871E5E00D7D896 /* TypeInfo.h in Headers */,
+ 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */,
BC18C4760E16F5CD00B34460 /* UString.h in Headers */,
BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */,
BC18C4730E16F5CD00B34460 /* Unicode.h in Headers */,
@@ -1707,6 +1742,12 @@
BC18C4720E16F5CD00B34460 /* ucpinternal.h in Headers */,
A7A1F7AD0F252B3C00E184E2 /* ByteArray.h in Headers */,
BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */,
+ 860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
+ 860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */,
+ 860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */,
+ 860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */,
+ 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */,
+ 14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1904,7 +1945,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "TRACING_D=\"$SRCROOT/runtime/Tracing.d\";\nTRACING_H=\"$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h\";\n\nif [[ \"$MACOSX_DEPLOYMENT_TARGET\" > \"10.5\" ]];\nthen\n\tdtrace -h -o \"$TRACING_H\" -s \"$TRACING_D\";\nfi;\n";
+ shellScript = "TRACING_D=\"$SRCROOT/runtime/Tracing.d\";\nTRACING_H=\"$BUILT_PRODUCTS_DIR/DerivedSources/JavaScriptCore/TracingDtrace.h\";\n\nif [[ \"$HAVE_DTRACE\" = \"1\" && \"$TRACING_D\" -nt \"$TRACING_H\" ]];\nthen\n\tdtrace -h -o \"$TRACING_H\" -s \"$TRACING_D\";\nfi;\n";
};
5D5D8ABF0E0D0B0300F9C692 /* Fix Framework Reference */ = {
isa = PBXShellScriptBuildPhase;
@@ -2011,6 +2052,7 @@
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */,
86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */,
86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */,
+ 14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */,
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
1421359B0A677F4F00A8195E /* JSBase.cpp in Sources */,
A791EF290F11E07900AE1F68 /* JSByteArray.cpp in Sources */,
@@ -2059,6 +2101,8 @@
93E26BD408B1514100F85226 /* pcre_xclass.cpp in Sources */,
A7A1F7AC0F252B3C00E184E2 /* ByteArray.cpp in Sources */,
BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */,
+ 0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */,
+ 14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/JavaScriptCorePrefix.h b/JavaScriptCore/JavaScriptCorePrefix.h
index e71c8a8..13b21bb 100644
--- a/JavaScriptCore/JavaScriptCorePrefix.h
+++ b/JavaScriptCore/JavaScriptCorePrefix.h
@@ -25,15 +25,6 @@
#endif
-#if defined(__APPLE__)
-#import <AvailabilityMacros.h>
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
-#define BUILDING_ON_TIGER 1
-#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-#define BUILDING_ON_LEOPARD 1
-#endif
-#endif
-
#ifdef __cplusplus
#define new ("if you use new/delete make sure to include config.h at the top of the file"())
#define delete ("if you use new/delete make sure to include config.h at the top of the file"())
diff --git a/JavaScriptCore/JavaScriptCoreSources.bkl b/JavaScriptCore/JavaScriptCoreSources.bkl
index 7ba3e09..b3a461b 100644
--- a/JavaScriptCore/JavaScriptCoreSources.bkl
+++ b/JavaScriptCore/JavaScriptCoreSources.bkl
@@ -152,6 +152,7 @@ Source files for JSCore.
bytecode/StructureStubInfo.cpp
bytecode/JumpTable.cpp
runtime/ExceptionHelpers.cpp
+ runtime/TimeoutChecker.cpp
interpreter/Interpreter.cpp
bytecode/Opcode.cpp
bytecode/SamplingTool.cpp
@@ -169,6 +170,7 @@ Source files for JSCore.
wtf/TCSystemAlloc.cpp
wtf/Threading.cpp
wtf/ThreadingNone.cpp
+ wtf/TypeTraits.cpp
wtf/wx/MainThreadWx.cpp
wtf/unicode/CollatorDefault.cpp
wtf/unicode/icu/CollatorICU.cpp
diff --git a/JavaScriptCore/assembler/AbstractMacroAssembler.h b/JavaScriptCore/assembler/AbstractMacroAssembler.h
new file mode 100644
index 0000000..851b6d5
--- /dev/null
+++ b/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -0,0 +1,841 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AbstractMacroAssembler_h
+#define AbstractMacroAssembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+namespace JSC {
+
+template <class AssemblerType>
+class AbstractMacroAssembler {
+public:
+ class Jump;
+ class PatchBuffer;
+ class CodeLocationLabel;
+ class CodeLocationJump;
+ class CodeLocationCall;
+ class CodeLocationDataLabel32;
+ class CodeLocationDataLabelPtr;
+
+ typedef typename AssemblerType::RegisterID RegisterID;
+ typedef typename AssemblerType::JmpSrc JmpSrc;
+ typedef typename AssemblerType::JmpDst JmpDst;
+
+
+ // Section 1: MacroAssembler operand types
+ //
+ // The following types are used as operands to MacroAssembler operations,
+ // describing immediate and memory operands to the instructions to be planted.
+
+
+ enum Scale {
+ TimesOne,
+ TimesTwo,
+ TimesFour,
+ TimesEight,
+ };
+
+ // Address:
+ //
+ // Describes a simple base-offset address.
+ struct Address {
+ explicit Address(RegisterID base, int32_t offset = 0)
+ : base(base)
+ , offset(offset)
+ {
+ }
+
+ RegisterID base;
+ int32_t offset;
+ };
+
+ // ImplicitAddress:
+ //
+ // This class is used for explicit 'load' and 'store' operations
+ // (as opposed to situations in which a memory operand is provided
+ // to a generic operation, such as an integer arithmetic instruction).
+ //
+ // In the case of a load (or store) operation we want to permit
+ // addresses to be implicitly constructed, e.g. the two calls:
+ //
+ // load32(Address(addrReg), destReg);
+ // load32(addrReg, destReg);
+ //
+ // Are equivalent, and the explicit wrapping of the Address in the former
+ // is unnecessary.
+ struct ImplicitAddress {
+ ImplicitAddress(RegisterID base)
+ : base(base)
+ , offset(0)
+ {
+ }
+
+ ImplicitAddress(Address address)
+ : base(address.base)
+ , offset(address.offset)
+ {
+ }
+
+ RegisterID base;
+ int32_t offset;
+ };
+
+ // BaseIndex:
+ //
+ // Describes a complex addressing mode.
+ struct BaseIndex {
+ BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
+ : base(base)
+ , index(index)
+ , scale(scale)
+ , offset(offset)
+ {
+ }
+
+ RegisterID base;
+ RegisterID index;
+ Scale scale;
+ int32_t offset;
+ };
+
+ // AbsoluteAddress:
+ //
+ // Describes an memory operand given by a pointer. For regular load & store
+ // operations an unwrapped void* will be used, rather than using this.
+ struct AbsoluteAddress {
+ explicit AbsoluteAddress(void* ptr)
+ : m_ptr(ptr)
+ {
+ }
+
+ void* m_ptr;
+ };
+
+ // ImmPtr:
+ //
+ // A pointer sized immediate operand to an instruction - this is wrapped
+ // in a class requiring explicit construction in order to differentiate
+ // from pointers used as absolute addresses to memory operations
+ struct ImmPtr {
+ explicit ImmPtr(void* value)
+ : m_value(value)
+ {
+ }
+
+ intptr_t asIntptr()
+ {
+ return reinterpret_cast<intptr_t>(m_value);
+ }
+
+ void* m_value;
+ };
+
+ // Imm32:
+ //
+ // A 32bit immediate operand to an instruction - this is wrapped in a
+ // class requiring explicit construction in order to prevent RegisterIDs
+ // (which are implemented as an enum) from accidentally being passed as
+ // immediate values.
+ struct Imm32 {
+ explicit Imm32(int32_t value)
+ : m_value(value)
+ {
+ }
+
+#if !PLATFORM(X86_64)
+ explicit Imm32(ImmPtr ptr)
+ : m_value(ptr.asIntptr())
+ {
+ }
+#endif
+
+ int32_t m_value;
+ };
+
+
+ // Section 2: MacroAssembler code buffer handles
+ //
+ // The following types are used to reference items in the code buffer
+ // during JIT code generation. For example, the type Jump is used to
+ // track the location of a jump instruction so that it may later be
+ // linked to a label marking its destination.
+
+
+ // Label:
+ //
+ // A Label records a point in the generated instruction stream, typically such that
+ // it may be used as a destination for a jump.
+ class Label {
+ friend class Jump;
+ template<class AssemblerType_T>
+ friend class AbstractMacroAssembler;
+ friend class PatchBuffer;
+ public:
+ Label()
+ {
+ }
+
+ Label(AbstractMacroAssembler<AssemblerType>* masm)
+ : m_label(masm->m_assembler.label())
+ {
+ }
+
+ bool isUsed() const { return m_label.isUsed(); }
+ void used() { m_label.used(); }
+ private:
+ JmpDst m_label;
+ };
+
+ // DataLabelPtr:
+ //
+ // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
+ // patched after the code has been generated.
+ class DataLabelPtr {
+ template<class AssemblerType_T>
+ friend class AbstractMacroAssembler;
+ friend class PatchBuffer;
+ public:
+ DataLabelPtr()
+ {
+ }
+
+ DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
+ : m_label(masm->m_assembler.label())
+ {
+ }
+
+ private:
+ JmpDst m_label;
+ };
+
+ // DataLabel32:
+ //
+ // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
+ // patched after the code has been generated.
+ class DataLabel32 {
+ template<class AssemblerType_T>
+ friend class AbstractMacroAssembler;
+ friend class PatchBuffer;
+ public:
+ DataLabel32()
+ {
+ }
+
+ DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
+ : m_label(masm->m_assembler.label())
+ {
+ }
+
+ private:
+ JmpDst m_label;
+ };
+
+ // Call:
+ //
+ // A Call object is a reference to a call instruction that has been planted
+ // into the code buffer - it is typically used to link the call, setting the
+ // relative offset such that when executed it will call to the desired
+ // destination.
+ class Call {
+ friend class PatchBuffer;
+ template<class AssemblerType_T>
+ friend class AbstractMacroAssembler;
+ public:
+ enum Flags {
+ None = 0x0,
+ Linkable = 0x1,
+ Near = 0x2,
+ LinkableNear = 0x3,
+ };
+
+ Call()
+ : m_flags(None)
+ {
+ }
+
+ Call(JmpSrc jmp, Flags flags)
+ : m_jmp(jmp)
+ , m_flags(flags)
+ {
+ }
+
+ bool isFlagSet(Flags flag)
+ {
+ return m_flags & flag;
+ }
+
+ static Call fromTailJump(Jump jump)
+ {
+ return Call(jump.m_jmp, Linkable);
+ }
+
+ private:
+ JmpSrc m_jmp;
+ Flags m_flags;
+ };
+
+ // Jump:
+ //
+ // A jump object is a reference to a jump instruction that has been planted
+ // into the code buffer - it is typically used to link the jump, setting the
+ // relative offset such that when executed it will jump to the desired
+ // destination.
+ class Jump {
+ friend class PatchBuffer;
+ template<class AssemblerType_T>
+ friend class AbstractMacroAssembler;
+ friend class Call;
+ public:
+ Jump()
+ {
+ }
+
+ Jump(JmpSrc jmp)
+ : m_jmp(jmp)
+ {
+ }
+
+ void link(AbstractMacroAssembler<AssemblerType>* masm)
+ {
+ masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
+ }
+
+ void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+ {
+ masm->m_assembler.linkJump(m_jmp, label.m_label);
+ }
+
+ private:
+ JmpSrc m_jmp;
+ };
+
+ // JumpList:
+ //
+ // A JumpList is a set of Jump objects.
+ // All jumps in the set will be linked to the same destination.
+ class JumpList {
+ friend class PatchBuffer;
+
+ public:
+ void link(AbstractMacroAssembler<AssemblerType>* masm)
+ {
+ size_t size = m_jumps.size();
+ for (size_t i = 0; i < size; ++i)
+ m_jumps[i].link(masm);
+ m_jumps.clear();
+ }
+
+ void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+ {
+ size_t size = m_jumps.size();
+ for (size_t i = 0; i < size; ++i)
+ m_jumps[i].linkTo(label, masm);
+ m_jumps.clear();
+ }
+
+ void append(Jump jump)
+ {
+ m_jumps.append(jump);
+ }
+
+ void append(JumpList& other)
+ {
+ m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
+ }
+
+ bool empty()
+ {
+ return !m_jumps.size();
+ }
+
+ private:
+ Vector<Jump, 16> m_jumps;
+ };
+
+
+ // Section 3: MacroAssembler JIT instruction stream handles.
+ //
+ // The MacroAssembler supported facilities to modify a JIT generated
+ // instruction stream after it has been generated (relinking calls and
+ // jumps, and repatching data values). The following types are used
+ // to store handles into the underlying instruction stream, the type
+ // providing semantic information as to what it is that is in the
+ // instruction stream at this point, and thus what operations may be
+ // performed on it.
+
+
+ // CodeLocationCommon:
+ //
+ // Base type for other CodeLocation* types. A postion in the JIT genertaed
+ // instruction stream, without any semantic information.
+ class CodeLocationCommon {
+ public:
+ CodeLocationCommon()
+ : m_location(0)
+ {
+ }
+
+ // In order to avoid the need to store multiple handles into the
+ // instructions stream, where the code generation is deterministic
+ // and the labels will always be a fixed distance apart, these
+ // methods may be used to recover a handle that has nopw been
+ // retained, based on a known fixed relative offset from one that has.
+ CodeLocationLabel labelAtOffset(int offset);
+ CodeLocationJump jumpAtOffset(int offset);
+ CodeLocationCall callAtOffset(int offset);
+ CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
+ CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
+
+ operator bool() { return m_location; }
+ void reset() { m_location = 0; }
+
+ protected:
+ explicit CodeLocationCommon(void* location)
+ : m_location(location)
+ {
+ }
+
+ void* m_location;
+ };
+
+ // CodeLocationLabel:
+ //
+ // A point in the JIT code maked with a label.
+ class CodeLocationLabel : public CodeLocationCommon {
+ friend class CodeLocationCommon;
+ friend class CodeLocationJump;
+ friend class PatchBuffer;
+ public:
+ CodeLocationLabel()
+ {
+ }
+
+ void* addressForSwitch() { return this->m_location; }
+ void* addressForExceptionHandler() { return this->m_location; }
+ void* addressForJSR() { return this->m_location; }
+
+ private:
+ explicit CodeLocationLabel(void* location)
+ : CodeLocationCommon(location)
+ {
+ }
+
+ void* getJumpDestination() { return this->m_location; }
+ };
+
+ // CodeLocationJump:
+ //
+ // A point in the JIT code at which there is a jump instruction.
+ class CodeLocationJump : public CodeLocationCommon {
+ friend class CodeLocationCommon;
+ friend class PatchBuffer;
+ public:
+ CodeLocationJump()
+ {
+ }
+
+ void relink(CodeLocationLabel destination)
+ {
+ AssemblerType::patchJump(reinterpret_cast<intptr_t>(this->m_location), destination.m_location);
+ }
+
+ private:
+ explicit CodeLocationJump(void* location)
+ : CodeLocationCommon(location)
+ {
+ }
+ };
+
+ // CodeLocationCall:
+ //
+ // A point in the JIT code at which there is a call instruction.
+ class CodeLocationCall : public CodeLocationCommon {
+ friend class CodeLocationCommon;
+ friend class PatchBuffer;
+ public:
+ CodeLocationCall()
+ {
+ }
+
+ template<typename FunctionSig>
+ void relink(FunctionSig* function)
+ {
+ AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));
+ }
+
+ // This methods returns the value that will be set as the return address
+ // within a function that has been called from this call instruction.
+ void* calleeReturnAddressValue()
+ {
+ return this->m_location;
+ }
+
+ private:
+ explicit CodeLocationCall(void* location)
+ : CodeLocationCommon(location)
+ {
+ }
+ };
+
+ // CodeLocationNearCall:
+ //
+ // A point in the JIT code at which there is a call instruction with near linkage.
+ class CodeLocationNearCall : public CodeLocationCommon {
+ friend class CodeLocationCommon;
+ friend class PatchBuffer;
+ public:
+ CodeLocationNearCall()
+ {
+ }
+
+ template<typename FunctionSig>
+ void relink(FunctionSig* function)
+ {
+ AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));
+ }
+
+ // This methods returns the value that will be set as the return address
+ // within a function that has been called from this call instruction.
+ void* calleeReturnAddressValue()
+ {
+ return this->m_location;
+ }
+
+ private:
+ explicit CodeLocationNearCall(void* location)
+ : CodeLocationCommon(location)
+ {
+ }
+ };
+
+ // CodeLocationDataLabel32:
+ //
+ // A point in the JIT code at which there is an int32_t immediate that may be repatched.
+ class CodeLocationDataLabel32 : public CodeLocationCommon {
+ friend class CodeLocationCommon;
+ friend class PatchBuffer;
+ public:
+ CodeLocationDataLabel32()
+ {
+ }
+
+ void repatch(int32_t value)
+ {
+ AssemblerType::patchImmediate(reinterpret_cast<intptr_t>(this->m_location), value);
+ }
+
+ private:
+ explicit CodeLocationDataLabel32(void* location)
+ : CodeLocationCommon(location)
+ {
+ }
+ };
+
+ // CodeLocationDataLabelPtr:
+ //
+ // A point in the JIT code at which there is a void* immediate that may be repatched.
+ class CodeLocationDataLabelPtr : public CodeLocationCommon {
+ friend class CodeLocationCommon;
+ friend class PatchBuffer;
+ public:
+ CodeLocationDataLabelPtr()
+ {
+ }
+
+ void repatch(void* value)
+ {
+ AssemblerType::patchPointer(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<intptr_t>(value));
+ }
+
+ private:
+ explicit CodeLocationDataLabelPtr(void* location)
+ : CodeLocationCommon(location)
+ {
+ }
+ };
+
+ // ProcessorReturnAddress:
+ //
+ // This class can be used to relink a call identified by its return address.
+ class ProcessorReturnAddress {
+ public:
+ ProcessorReturnAddress(void* location)
+ : m_location(location)
+ {
+ }
+
+ template<typename FunctionSig>
+ void relinkCallerToFunction(FunctionSig* newCalleeFunction)
+ {
+ AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction));
+ }
+
+ template<typename FunctionSig>
+ void relinkNearCallerToFunction(FunctionSig* newCalleeFunction)
+ {
+ AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction));
+ }
+
+ operator void*()
+ {
+ return m_location;
+ }
+
+ private:
+ void* m_location;
+ };
+
+
+ // Section 4: The patch buffer - utility to finalize code generation.
+
+
+ // PatchBuffer:
+ //
+ // This class assists in linking code generated by the macro assembler, once code generation
+ // has been completed, and the code has been copied to is final location in memory. At this
+ // time pointers to labels within the code may be resolved, and relative offsets to external
+ // addresses may be fixed.
+ //
+ // Specifically:
+ // * Jump objects may be linked to external targets,
+ // * The address of Jump objects may taken, such that it can later be relinked.
+ // * The return address of a Jump object representing a call may be acquired.
+ // * The address of a Label pointing into the code may be resolved.
+ // * The value referenced by a DataLabel may be fixed.
+ //
+ // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return
+ // address of calls, as opposed to a point that can be used to later relink a Jump -
+ // possibly wrap the later up in an object that can do just that).
+ class PatchBuffer {
+ public:
+ PatchBuffer(void* code)
+ : m_code(code)
+ {
+ }
+
+ CodeLocationLabel entry()
+ {
+ return CodeLocationLabel(m_code);
+ }
+
+ void* trampolineAt(Label label)
+ {
+ return AssemblerType::getRelocatedAddress(m_code, label.m_label);
+ }
+
+ // These methods are used to link or set values at code generation time.
+
+ template<typename FunctionSig>
+ void link(Call call, FunctionSig* function)
+ {
+ ASSERT(call.isFlagSet(Call::Linkable));
+#if PLATFORM(X86_64)
+ if (call.isFlagSet(Call::Near)) {
+ AssemblerType::linkCall(m_code, call.m_jmp, reinterpret_cast<void*>(function));
+ } else {
+ intptr_t callLocation = reinterpret_cast<intptr_t>(AssemblerType::getRelocatedAddress(m_code, call.m_jmp));
+ AssemblerType::patchMacroAssemblerCall(callLocation, reinterpret_cast<void*>(function));
+ }
+#else
+ AssemblerType::linkCall(m_code, call.m_jmp, reinterpret_cast<void*>(function));
+#endif
+ }
+
+ template<typename FunctionSig>
+ void linkTailRecursive(Jump jump, FunctionSig* function)
+ {
+ AssemblerType::linkJump(m_code, jump.m_jmp, reinterpret_cast<void*>(function));
+ }
+
+ template<typename FunctionSig>
+ void linkTailRecursive(JumpList list, FunctionSig* function)
+ {
+ for (unsigned i = 0; i < list.m_jumps.size(); ++i) {
+ AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, reinterpret_cast<void*>(function));
+ }
+ }
+
+ void link(Jump jump, CodeLocationLabel label)
+ {
+ AssemblerType::linkJump(m_code, jump.m_jmp, label.m_location);
+ }
+
+ void link(JumpList list, CodeLocationLabel label)
+ {
+ for (unsigned i = 0; i < list.m_jumps.size(); ++i)
+ AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, label.m_location);
+ }
+
+ void patch(DataLabelPtr label, void* value)
+ {
+ AssemblerType::patchAddress(m_code, label.m_label, value);
+ }
+
+ // These methods are used to obtain handles to allow the code to be relinked / repatched later.
+
+ CodeLocationCall locationOf(Call call)
+ {
+ ASSERT(call.isFlagSet(Call::Linkable));
+ ASSERT(!call.isFlagSet(Call::Near));
+ return CodeLocationCall(AssemblerType::getRelocatedAddress(m_code, call.m_jmp));
+ }
+
+ CodeLocationNearCall locationOfNearCall(Call call)
+ {
+ ASSERT(call.isFlagSet(Call::Linkable));
+ ASSERT(call.isFlagSet(Call::Near));
+ return CodeLocationNearCall(AssemblerType::getRelocatedAddress(m_code, call.m_jmp));
+ }
+
+ CodeLocationLabel locationOf(Label label)
+ {
+ return CodeLocationLabel(AssemblerType::getRelocatedAddress(m_code, label.m_label));
+ }
+
+ CodeLocationDataLabelPtr locationOf(DataLabelPtr label)
+ {
+ return CodeLocationDataLabelPtr(AssemblerType::getRelocatedAddress(m_code, label.m_label));
+ }
+
+ CodeLocationDataLabel32 locationOf(DataLabel32 label)
+ {
+ return CodeLocationDataLabel32(AssemblerType::getRelocatedAddress(m_code, label.m_label));
+ }
+
+ // This method obtains the return address of the call, given as an offset from
+ // the start of the code.
+ unsigned returnAddressOffset(Call call)
+ {
+ return AssemblerType::getCallReturnOffset(call.m_jmp);
+ }
+
+ private:
+ void* m_code;
+ };
+
+
+ // Section 5: Misc admin methods
+
+ size_t size()
+ {
+ return m_assembler.size();
+ }
+
+ void* copyCode(ExecutablePool* allocator)
+ {
+ return m_assembler.executableCopy(allocator);
+ }
+
+ Label label()
+ {
+ return Label(this);
+ }
+
+ Label align()
+ {
+ m_assembler.align(16);
+ return Label(this);
+ }
+
+ ptrdiff_t differenceBetween(Label from, Jump to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+ }
+
+ ptrdiff_t differenceBetween(Label from, Call to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+ }
+
+ ptrdiff_t differenceBetween(Label from, Label to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+ }
+
+ ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+ }
+
+ ptrdiff_t differenceBetween(Label from, DataLabel32 to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+ }
+
+ ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+ }
+
+ ptrdiff_t differenceBetween(DataLabelPtr from, Call to)
+ {
+ return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+ }
+
+protected:
+ AssemblerType m_assembler;
+};
+
+
+template <class AssemblerType>
+typename AbstractMacroAssembler<AssemblerType>::CodeLocationLabel AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::labelAtOffset(int offset)
+{
+ return typename AbstractMacroAssembler::CodeLocationLabel(reinterpret_cast<char*>(m_location) + offset);
+}
+
+template <class AssemblerType>
+typename AbstractMacroAssembler<AssemblerType>::CodeLocationJump AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::jumpAtOffset(int offset)
+{
+ return typename AbstractMacroAssembler::CodeLocationJump(reinterpret_cast<char*>(m_location) + offset);
+}
+
+template <class AssemblerType>
+typename AbstractMacroAssembler<AssemblerType>::CodeLocationCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::callAtOffset(int offset)
+{
+ return typename AbstractMacroAssembler::CodeLocationCall(reinterpret_cast<char*>(m_location) + offset);
+}
+
+template <class AssemblerType>
+typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset)
+{
+ return typename AbstractMacroAssembler::CodeLocationDataLabelPtr(reinterpret_cast<char*>(m_location) + offset);
+}
+
+template <class AssemblerType>
+typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabel32 AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabel32AtOffset(int offset)
+{
+ return typename AbstractMacroAssembler::CodeLocationDataLabel32(reinterpret_cast<char*>(m_location) + offset);
+}
+
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // AbstractMacroAssembler_h
diff --git a/JavaScriptCore/assembler/MacroAssembler.h b/JavaScriptCore/assembler/MacroAssembler.h
index 9d24653..71ac1f6 100644
--- a/JavaScriptCore/assembler/MacroAssembler.h
+++ b/JavaScriptCore/assembler/MacroAssembler.h
@@ -30,1986 +30,301 @@
#if ENABLE(ASSEMBLER)
-#include "X86Assembler.h"
-
-namespace JSC {
+#if PLATFORM(X86)
+#include "MacroAssemblerX86.h"
+namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
-class MacroAssembler {
-protected:
- X86Assembler m_assembler;
+#elif PLATFORM(X86_64)
+#include "MacroAssemblerX86_64.h"
+namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; };
-#if PLATFORM(X86_64)
- static const X86::RegisterID scratchRegister = X86::r11;
+#else
+#error "The MacroAssembler is not supported on this platform."
#endif
+
+namespace JSC {
+
+class MacroAssembler : public MacroAssemblerBase {
public:
- typedef X86::RegisterID RegisterID;
-
- // Note: do not rely on values in this enum, these will change (to 0..3).
- enum Scale {
- TimesOne = 1,
- TimesTwo = 2,
- TimesFour = 4,
- TimesEight = 8,
-#if PLATFORM(X86)
- ScalePtr = TimesFour
-#endif
+
+ using MacroAssemblerBase::pop;
+ using MacroAssemblerBase::jump;
+ using MacroAssemblerBase::branch32;
+ using MacroAssemblerBase::branch16;
#if PLATFORM(X86_64)
- ScalePtr = TimesEight
+ using MacroAssemblerBase::branchPtr;
+ using MacroAssemblerBase::branchTestPtr;
#endif
- };
- MacroAssembler()
+
+ // Platform agnostic onvenience functions,
+ // described in terms of other macro assembly methods.
+ void pop()
{
+ addPtr(Imm32(sizeof(void*)), stackPointerRegister);
}
- size_t size() { return m_assembler.size(); }
- void* copyCode(ExecutablePool* allocator)
+ void peek(RegisterID dest, int index = 0)
{
- return m_assembler.executableCopy(allocator);
+ loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest);
}
-
- // Address:
- //
- // Describes a simple base-offset address.
- struct Address {
- explicit Address(RegisterID base, int32_t offset = 0)
- : base(base)
- , offset(offset)
- {
- }
-
- RegisterID base;
- int32_t offset;
- };
-
- // ImplicitAddress:
- //
- // This class is used for explicit 'load' and 'store' operations
- // (as opposed to situations in which a memory operand is provided
- // to a generic operation, such as an integer arithmetic instruction).
- //
- // In the case of a load (or store) operation we want to permit
- // addresses to be implicitly constructed, e.g. the two calls:
- //
- // load32(Address(addrReg), destReg);
- // load32(addrReg, destReg);
- //
- // Are equivalent, and the explicit wrapping of the Address in the former
- // is unnecessary.
- struct ImplicitAddress {
- ImplicitAddress(RegisterID base)
- : base(base)
- , offset(0)
- {
- }
-
- ImplicitAddress(Address address)
- : base(address.base)
- , offset(address.offset)
- {
- }
-
- RegisterID base;
- int32_t offset;
- };
-
- // BaseIndex:
- //
- // Describes a complex addressing mode.
- struct BaseIndex {
- BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
- : base(base)
- , index(index)
- , scale(scale)
- , offset(offset)
- {
- }
-
- RegisterID base;
- RegisterID index;
- Scale scale;
- int32_t offset;
- };
-
- // AbsoluteAddress:
- //
- // Describes an memory operand given by a pointer. For regular load & store
- // operations an unwrapped void* will be used, rather than using this.
- struct AbsoluteAddress {
- explicit AbsoluteAddress(void* ptr)
- : m_ptr(ptr)
- {
- }
-
- void* m_ptr;
- };
-
-
- class Jump;
- class PatchBuffer;
-
- // DataLabelPtr:
- //
- // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
- // patched after the code has been generated.
- class DataLabelPtr {
- friend class MacroAssembler;
- friend class PatchBuffer;
-
- public:
- DataLabelPtr()
- {
- }
-
- DataLabelPtr(MacroAssembler* masm)
- : m_label(masm->m_assembler.label())
- {
- }
-
- static void patch(void* address, void* value)
- {
- X86Assembler::patchPointer(reinterpret_cast<intptr_t>(address), reinterpret_cast<intptr_t>(value));
- }
-
- private:
- X86Assembler::JmpDst m_label;
- };
-
- // DataLabel32:
- //
- // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
- // patched after the code has been generated.
- class DataLabel32 {
- friend class MacroAssembler;
- friend class PatchBuffer;
-
- public:
- DataLabel32()
- {
- }
-
- DataLabel32(MacroAssembler* masm)
- : m_label(masm->m_assembler.label())
- {
- }
-
- static void patch(void* address, int32_t value)
- {
- X86Assembler::patchImmediate(reinterpret_cast<intptr_t>(address), value);
- }
-
- private:
- X86Assembler::JmpDst m_label;
- };
-
- // Label:
- //
- // A Label records a point in the generated instruction stream, typically such that
- // it may be used as a destination for a jump.
- class Label {
- friend class Jump;
- friend class MacroAssembler;
- friend class PatchBuffer;
-
- public:
- Label()
- {
- }
-
- Label(MacroAssembler* masm)
- : m_label(masm->m_assembler.label())
- {
- }
-
- // FIXME: transitionary method, while we replace JmpSrces with Jumps.
- operator X86Assembler::JmpDst()
- {
- return m_label;
- }
-
- private:
- X86Assembler::JmpDst m_label;
- };
-
-
- // Jump:
- //
- // A jump object is a reference to a jump instruction that has been planted
- // into the code buffer - it is typically used to link the jump, setting the
- // relative offset such that when executed it will jump to the desired
- // destination.
- //
- // Jump objects retain a pointer to the assembler for syntactic purposes -
- // to allow the jump object to be able to link itself, e.g.:
- //
- // Jump forwardsBranch = jne32(Imm32(0), reg1);
- // // ...
- // forwardsBranch.link();
- //
- // Jumps may also be linked to a Label.
- class Jump {
- friend class PatchBuffer;
- friend class MacroAssembler;
-
- public:
- Jump()
- {
- }
-
- // FIXME: transitionary method, while we replace JmpSrces with Jumps.
- Jump(X86Assembler::JmpSrc jmp)
- : m_jmp(jmp)
- {
- }
-
- void link(MacroAssembler* masm)
- {
- masm->m_assembler.link(m_jmp, masm->m_assembler.label());
- }
-
- void linkTo(Label label, MacroAssembler* masm)
- {
- masm->m_assembler.link(m_jmp, label.m_label);
- }
-
- // FIXME: transitionary method, while we replace JmpSrces with Jumps.
- operator X86Assembler::JmpSrc()
- {
- return m_jmp;
- }
-
- static void patch(void* address, void* destination)
- {
- X86Assembler::patchBranchOffset(reinterpret_cast<intptr_t>(address), destination);
- }
-
- private:
- X86Assembler::JmpSrc m_jmp;
- };
-
- // JumpList:
- //
- // A JumpList is a set of Jump objects.
- // All jumps in the set will be linked to the same destination.
- class JumpList {
- friend class PatchBuffer;
-
- public:
- void link(MacroAssembler* masm)
- {
- size_t size = m_jumps.size();
- for (size_t i = 0; i < size; ++i)
- m_jumps[i].link(masm);
- m_jumps.clear();
- }
-
- void linkTo(Label label, MacroAssembler* masm)
- {
- size_t size = m_jumps.size();
- for (size_t i = 0; i < size; ++i)
- m_jumps[i].linkTo(label, masm);
- m_jumps.clear();
- }
-
- void append(Jump jump)
- {
- m_jumps.append(jump);
- }
-
- void append(JumpList& other)
- {
- m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
- }
-
- bool empty()
- {
- return !m_jumps.size();
- }
-
- private:
- Vector<Jump, 16> m_jumps;
- };
-
-
- // PatchBuffer:
- //
- // This class assists in linking code generated by the macro assembler, once code generation
- // has been completed, and the code has been copied to is final location in memory. At this
- // time pointers to labels within the code may be resolved, and relative offsets to external
- // addresses may be fixed.
- //
- // Specifically:
- // * Jump objects may be linked to external targets,
- // * The address of Jump objects may taken, such that it can later be relinked.
- // * The return address of a Jump object representing a call may be acquired.
- // * The address of a Label pointing into the code may be resolved.
- // * The value referenced by a DataLabel may be fixed.
- //
- // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return
- // address of calls, as opposed to a point that can be used to later relink a Jump -
- // possibly wrap the later up in an object that can do just that).
- class PatchBuffer {
- public:
- PatchBuffer(void* code)
- : m_code(code)
- {
- }
-
- void link(Jump jump, void* target)
- {
- X86Assembler::link(m_code, jump.m_jmp, target);
- }
-
- void link(JumpList list, void* target)
- {
- for (unsigned i = 0; i < list.m_jumps.size(); ++i)
- X86Assembler::link(m_code, list.m_jumps[i], target);
- }
-
- void* addressOf(Jump jump)
- {
- return X86Assembler::getRelocatedAddress(m_code, jump.m_jmp);
- }
-
- void* addressOf(Label label)
- {
- return X86Assembler::getRelocatedAddress(m_code, label.m_label);
- }
-
- void* addressOf(DataLabelPtr label)
- {
- return X86Assembler::getRelocatedAddress(m_code, label.m_label);
- }
-
- void* addressOf(DataLabel32 label)
- {
- return X86Assembler::getRelocatedAddress(m_code, label.m_label);
- }
-
- void setPtr(DataLabelPtr label, void* value)
- {
- X86Assembler::patchAddress(m_code, label.m_label, value);
- }
-
- private:
- void* m_code;
- };
-
-
- // ImmPtr:
- //
- // A pointer sized immediate operand to an instruction - this is wrapped
- // in a class requiring explicit construction in order to differentiate
- // from pointers used as absolute addresses to memory operations
- struct ImmPtr {
- explicit ImmPtr(void* value)
- : m_value(value)
- {
- }
-
- intptr_t asIntptr()
- {
- return reinterpret_cast<intptr_t>(m_value);
- }
-
- void* m_value;
- };
-
-
- // Imm32:
- //
- // A 32bit immediate operand to an instruction - this is wrapped in a
- // class requiring explicit construction in order to prevent RegisterIDs
- // (which are implemented as an enum) from accidentally being passed as
- // immediate values.
- struct Imm32 {
- explicit Imm32(int32_t value)
- : m_value(value)
- {
- }
-
-#if PLATFORM(X86)
- explicit Imm32(ImmPtr ptr)
- : m_value(ptr.asIntptr())
- {
- }
-#endif
-
- int32_t m_value;
- };
-
- // Integer arithmetic operations:
- //
- // Operations are typically two operand - operation(source, srcDst)
- // For many operations the source may be an Imm32, the srcDst operand
- // may often be a memory location (explictly described using an Address
- // object).
-
- void addPtr(RegisterID src, RegisterID dest)
+ void poke(RegisterID src, int index = 0)
{
-#if PLATFORM(X86_64)
- m_assembler.addq_rr(src, dest);
-#else
- add32(src, dest);
-#endif
+ storePtr(src, Address(stackPointerRegister, (index * sizeof(void*))));
}
- void addPtr(Imm32 imm, RegisterID srcDest)
+ void poke(Imm32 value, int index = 0)
{
-#if PLATFORM(X86_64)
- m_assembler.addq_ir(imm.m_value, srcDest);
-#else
- add32(imm, srcDest);
-#endif
+ store32(value, Address(stackPointerRegister, (index * sizeof(void*))));
}
- void addPtr(ImmPtr imm, RegisterID dest)
+ void poke(ImmPtr imm, int index = 0)
{
-#if PLATFORM(X86_64)
- move(imm, scratchRegister);
- m_assembler.addq_rr(scratchRegister, dest);
-#else
- add32(Imm32(imm), dest);
-#endif
+ storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*))));
}
- void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
+
+ // Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
+ void branchPtr(Condition cond, RegisterID op1, ImmPtr imm, Label target)
{
- m_assembler.leal_mr(imm.m_value, src, dest);
+ branchPtr(cond, op1, imm).linkTo(target, this);
}
- void add32(RegisterID src, RegisterID dest)
+ void branch32(Condition cond, RegisterID op1, RegisterID op2, Label target)
{
- m_assembler.addl_rr(src, dest);
+ branch32(cond, op1, op2).linkTo(target, this);
}
- void add32(Imm32 imm, Address address)
+ void branch32(Condition cond, RegisterID op1, Imm32 imm, Label target)
{
- m_assembler.addl_im(imm.m_value, address.offset, address.base);
+ branch32(cond, op1, imm).linkTo(target, this);
}
- void add32(Imm32 imm, RegisterID dest)
+ void branch32(Condition cond, RegisterID left, Address right, Label target)
{
- m_assembler.addl_ir(imm.m_value, dest);
+ branch32(cond, left, right).linkTo(target, this);
}
-
- void add32(Imm32 imm, AbsoluteAddress address)
- {
-#if PLATFORM(X86_64)
- move(ImmPtr(address.m_ptr), scratchRegister);
- add32(imm, Address(scratchRegister));
-#else
- m_assembler.addl_im(imm.m_value, address.m_ptr);
-#endif
- }
-
- void add32(Address src, RegisterID dest)
+
+ void branch16(Condition cond, BaseIndex left, RegisterID right, Label target)
{
- m_assembler.addl_mr(src.offset, src.base, dest);
+ branch16(cond, left, right).linkTo(target, this);
}
- void andPtr(RegisterID src, RegisterID dest)
+ void branchTestPtr(Condition cond, RegisterID reg, Label target)
{
-#if PLATFORM(X86_64)
- m_assembler.andq_rr(src, dest);
-#else
- and32(src, dest);
-#endif
+ branchTestPtr(cond, reg).linkTo(target, this);
}
- void andPtr(Imm32 imm, RegisterID srcDest)
+ void jump(Label target)
{
-#if PLATFORM(X86_64)
- m_assembler.andq_ir(imm.m_value, srcDest);
-#else
- and32(imm, srcDest);
-#endif
+ jump().linkTo(target, this);
}
- void and32(RegisterID src, RegisterID dest)
- {
- m_assembler.andl_rr(src, dest);
- }
- void and32(Imm32 imm, RegisterID dest)
+ // Ptr methods
+ // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents.
+#if !PLATFORM(X86_64)
+ void addPtr(RegisterID src, RegisterID dest)
{
- m_assembler.andl_ir(imm.m_value, dest);
+ add32(src, dest);
}
- void lshift32(Imm32 imm, RegisterID dest)
- {
- m_assembler.shll_i8r(imm.m_value, dest);
- }
-
- void lshift32(RegisterID shift_amount, RegisterID dest)
+ void addPtr(Imm32 imm, RegisterID srcDest)
{
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86::ecx) {
- swap(shift_amount, X86::ecx);
-
- // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.shll_CLr(X86::ecx);
- // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86::ecx)
- m_assembler.shll_CLr(shift_amount);
- // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
- else
- m_assembler.shll_CLr(dest);
-
- swap(shift_amount, X86::ecx);
- } else
- m_assembler.shll_CLr(dest);
+ add32(imm, srcDest);
}
-
- // Take the value from dividend, divide it by divisor, and put the remainder in remainder.
- // For now, this operation has specific register requirements, and the three register must
- // be unique. It is unfortunate to expose this in the MacroAssembler interface, however
- // given the complexity to fix, the fact that it is not uncommmon for processors to have
- // specific register requirements on this operation (e.g. Mips result in 'hi'), or to not
- // support a hardware divide at all, it may not be
- void mod32(RegisterID divisor, RegisterID dividend, RegisterID remainder)
- {
-#ifdef NDEBUG
-#pragma unused(dividend,remainder)
-#else
- ASSERT((dividend == X86::eax) && (remainder == X86::edx));
- ASSERT((dividend != divisor) && (remainder != divisor));
-#endif
- m_assembler.cdq();
- m_assembler.idivl_r(divisor);
+ void addPtr(ImmPtr imm, RegisterID dest)
+ {
+ add32(Imm32(imm), dest);
}
- void mul32(RegisterID src, RegisterID dest)
+ void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
{
- m_assembler.imull_rr(src, dest);
+ add32(imm, src, dest);
}
-
- void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+
+ void andPtr(RegisterID src, RegisterID dest)
{
- m_assembler.imull_i32r(src, imm.m_value, dest);
+ and32(src, dest);
}
-
- void not32(RegisterID srcDest)
+
+ void andPtr(Imm32 imm, RegisterID srcDest)
{
- m_assembler.notl_r(srcDest);
+ and32(imm, srcDest);
}
-
+
void orPtr(RegisterID src, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.orq_rr(src, dest);
-#else
or32(src, dest);
-#endif
}
void orPtr(ImmPtr imm, RegisterID dest)
{
-#if PLATFORM(X86_64)
- move(imm, scratchRegister);
- m_assembler.orq_rr(scratchRegister, dest);
-#else
or32(Imm32(imm), dest);
-#endif
}
void orPtr(Imm32 imm, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.orq_ir(imm.m_value, dest);
-#else
or32(imm, dest);
-#endif
- }
-
- void or32(RegisterID src, RegisterID dest)
- {
- m_assembler.orl_rr(src, dest);
- }
-
- void or32(Imm32 imm, RegisterID dest)
- {
- m_assembler.orl_ir(imm.m_value, dest);
}
void rshiftPtr(RegisterID shift_amount, RegisterID dest)
{
-#if PLATFORM(X86_64)
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86::ecx) {
- swap(shift_amount, X86::ecx);
-
- // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.sarq_CLr(X86::ecx);
- // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86::ecx)
- m_assembler.sarq_CLr(shift_amount);
- // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
- else
- m_assembler.sarq_CLr(dest);
-
- swap(shift_amount, X86::ecx);
- } else
- m_assembler.sarq_CLr(dest);
-#else
rshift32(shift_amount, dest);
-#endif
}
void rshiftPtr(Imm32 imm, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.sarq_i8r(imm.m_value, dest);
-#else
rshift32(imm, dest);
-#endif
- }
-
- void rshift32(RegisterID shift_amount, RegisterID dest)
- {
- // On x86 we can only shift by ecx; if asked to shift by another register we'll
- // need rejig the shift amount into ecx first, and restore the registers afterwards.
- if (shift_amount != X86::ecx) {
- swap(shift_amount, X86::ecx);
-
- // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
- if (dest == shift_amount)
- m_assembler.sarl_CLr(X86::ecx);
- // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
- else if (dest == X86::ecx)
- m_assembler.sarl_CLr(shift_amount);
- // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
- else
- m_assembler.sarl_CLr(dest);
-
- swap(shift_amount, X86::ecx);
- } else
- m_assembler.sarl_CLr(dest);
- }
-
- void rshift32(Imm32 imm, RegisterID dest)
- {
- m_assembler.sarl_i8r(imm.m_value, dest);
}
void subPtr(RegisterID src, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.subq_rr(src, dest);
-#else
sub32(src, dest);
-#endif
}
void subPtr(Imm32 imm, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.subq_ir(imm.m_value, dest);
-#else
sub32(imm, dest);
-#endif
}
void subPtr(ImmPtr imm, RegisterID dest)
{
-#if PLATFORM(X86_64)
- move(imm, scratchRegister);
- m_assembler.subq_rr(scratchRegister, dest);
-#else
sub32(Imm32(imm), dest);
-#endif
- }
-
- void sub32(RegisterID src, RegisterID dest)
- {
- m_assembler.subl_rr(src, dest);
- }
-
- void sub32(Imm32 imm, RegisterID dest)
- {
- m_assembler.subl_ir(imm.m_value, dest);
- }
-
- void sub32(Imm32 imm, Address address)
- {
- m_assembler.subl_im(imm.m_value, address.offset, address.base);
- }
-
- void sub32(Imm32 imm, AbsoluteAddress address)
- {
-#if PLATFORM(X86_64)
- move(ImmPtr(address.m_ptr), scratchRegister);
- sub32(imm, Address(scratchRegister));
-#else
- m_assembler.subl_im(imm.m_value, address.m_ptr);
-#endif
- }
-
- void sub32(Address src, RegisterID dest)
- {
- m_assembler.subl_mr(src.offset, src.base, dest);
}
void xorPtr(RegisterID src, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.xorq_rr(src, dest);
-#else
xor32(src, dest);
-#endif
}
void xorPtr(Imm32 imm, RegisterID srcDest)
{
-#if PLATFORM(X86_64)
- m_assembler.xorq_ir(imm.m_value, srcDest);
-#else
xor32(imm, srcDest);
-#endif
}
- void xor32(RegisterID src, RegisterID dest)
- {
- m_assembler.xorl_rr(src, dest);
- }
-
- void xor32(Imm32 imm, RegisterID srcDest)
- {
- m_assembler.xorl_ir(imm.m_value, srcDest);
- }
-
-
- // Memory access operations:
- //
- // Loads are of the form load(address, destination) and stores of the form
- // store(source, address). The source for a store may be an Imm32. Address
- // operand objects to loads and store will be implicitly constructed if a
- // register is passed.
void loadPtr(ImplicitAddress address, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.movq_mr(address.offset, address.base, dest);
-#else
load32(address, dest);
-#endif
- }
-
- DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
- {
-#if PLATFORM(X86_64)
- m_assembler.movq_mr_disp32(address.offset, address.base, dest);
- return DataLabel32(this);
-#else
- m_assembler.movl_mr_disp32(address.offset, address.base, dest);
- return DataLabel32(this);
-#endif
}
void loadPtr(BaseIndex address, RegisterID dest)
{
-#if PLATFORM(X86_64)
- m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
-#else
load32(address, dest);
-#endif
}
void loadPtr(void* address, RegisterID dest)
{
-#if PLATFORM(X86_64)
- if (dest == X86::eax)
- m_assembler.movq_mEAX(address);
- else {
- move(X86::eax, dest);
- m_assembler.movq_mEAX(address);
- swap(X86::eax, dest);
- }
-#else
load32(address, dest);
-#endif
- }
-
- void load32(ImplicitAddress address, RegisterID dest)
- {
- m_assembler.movl_mr(address.offset, address.base, dest);
}
- void load32(BaseIndex address, RegisterID dest)
+ DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
{
- m_assembler.movl_mr(address.offset, address.base, address.index, address.scale, dest);
+ return load32WithAddressOffsetPatch(address, dest);
}
- void load32(void* address, RegisterID dest)
+ void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
{
-#if PLATFORM(X86_64)
- if (dest == X86::eax)
- m_assembler.movl_mEAX(address);
- else {
- move(X86::eax, dest);
- m_assembler.movl_mEAX(address);
- swap(X86::eax, dest);
- }
-#else
- m_assembler.movl_mr(address, dest);
-#endif
- }
-
- void load16(BaseIndex address, RegisterID dest)
- {
- m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
+ set32(cond, left, right, dest);
}
void storePtr(RegisterID src, ImplicitAddress address)
{
-#if PLATFORM(X86_64)
- m_assembler.movq_rm(src, address.offset, address.base);
-#else
store32(src, address);
-#endif
- }
-
- DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
- {
-#if PLATFORM(X86_64)
- m_assembler.movq_rm_disp32(src, address.offset, address.base);
- return DataLabel32(this);
-#else
- m_assembler.movl_rm_disp32(src, address.offset, address.base);
- return DataLabel32(this);
-#endif
}
void storePtr(RegisterID src, BaseIndex address)
{
-#if PLATFORM(X86_64)
- m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale);
-#else
store32(src, address);
-#endif
}
void storePtr(ImmPtr imm, ImplicitAddress address)
{
-#if PLATFORM(X86_64)
- move(imm, scratchRegister);
- storePtr(scratchRegister, address);
-#else
- m_assembler.movl_i32m(imm.asIntptr(), address.offset, address.base);
-#endif
+ store32(Imm32(imm), address);
}
-#if !PLATFORM(X86_64)
void storePtr(ImmPtr imm, void* address)
{
store32(Imm32(imm), address);
}
-#endif
-
- DataLabelPtr storePtrWithPatch(Address address)
- {
-#if PLATFORM(X86_64)
- m_assembler.movq_i64r(0, scratchRegister);
- DataLabelPtr label(this);
- storePtr(scratchRegister, address);
- return label;
-#else
- m_assembler.movl_i32m(0, address.offset, address.base);
- return DataLabelPtr(this);
-#endif
- }
-
- void store32(RegisterID src, ImplicitAddress address)
- {
- m_assembler.movl_rm(src, address.offset, address.base);
- }
-
- void store32(RegisterID src, BaseIndex address)
- {
- m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale);
- }
-
- void store32(Imm32 imm, ImplicitAddress address)
- {
- m_assembler.movl_i32m(imm.m_value, address.offset, address.base);
- }
-
- void store32(Imm32 imm, void* address)
- {
-#if PLATFORM(X86_64)
- move(X86::eax, scratchRegister);
- move(imm, X86::eax);
- m_assembler.movl_EAXm(address);
- move(scratchRegister, X86::eax);
-#else
- m_assembler.movl_i32m(imm.m_value, address);
-#endif
- }
-
-
- // Stack manipulation operations:
- //
- // The ABI is assumed to provide a stack abstraction to memory,
- // containing machine word sized units of data. Push and pop
- // operations add and remove a single register sized unit of data
- // to or from the stack. Peek and poke operations read or write
- // values on the stack, without moving the current stack position.
-
- void pop(RegisterID dest)
- {
- m_assembler.pop_r(dest);
- }
-
- void push(RegisterID src)
- {
- m_assembler.push_r(src);
- }
-
- void push(Address address)
- {
- m_assembler.push_m(address.offset, address.base);
- }
-
- void push(Imm32 imm)
- {
- m_assembler.push_i32(imm.m_value);
- }
-
- void pop()
- {
- addPtr(Imm32(sizeof(void*)), X86::esp);
- }
-
- void peek(RegisterID dest, int index = 0)
- {
- loadPtr(Address(X86::esp, (index * sizeof(void *))), dest);
- }
-
- void poke(RegisterID src, int index = 0)
- {
- storePtr(src, Address(X86::esp, (index * sizeof(void *))));
- }
-
- void poke(Imm32 value, int index = 0)
- {
- store32(value, Address(X86::esp, (index * sizeof(void *))));
- }
-
- void poke(ImmPtr imm, int index = 0)
- {
- storePtr(imm, Address(X86::esp, (index * sizeof(void *))));
- }
-
- // Register move operations:
- //
- // Move values in registers.
-
- void move(Imm32 imm, RegisterID dest)
- {
- // Note: on 64-bit the Imm32 value is zero extended into the register, it
- // may be useful to have a separate version that sign extends the value?
- if (!imm.m_value)
- m_assembler.xorl_rr(dest, dest);
- else
- m_assembler.movl_i32r(imm.m_value, dest);
- }
-
- void move(RegisterID src, RegisterID dest)
- {
- // Note: on 64-bit this is is a full register move; perhaps it would be
- // useful to have separate move32 & movePtr, with move32 zero extending?
-#if PLATFORM(X86_64)
- m_assembler.movq_rr(src, dest);
-#else
- m_assembler.movl_rr(src, dest);
-#endif
- }
-
- void move(ImmPtr imm, RegisterID dest)
- {
-#if PLATFORM(X86_64)
- if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr()))
- m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest);
- else
- m_assembler.movq_i64r(imm.asIntptr(), dest);
-#else
- m_assembler.movl_i32r(imm.asIntptr(), dest);
-#endif
- }
-
- void swap(RegisterID reg1, RegisterID reg2)
- {
-#if PLATFORM(X86_64)
- m_assembler.xchgq_rr(reg1, reg2);
-#else
- m_assembler.xchgl_rr(reg1, reg2);
-#endif
- }
-
- void signExtend32ToPtr(RegisterID src, RegisterID dest)
- {
-#if PLATFORM(X86_64)
- m_assembler.movsxd_rr(src, dest);
-#else
- if (src != dest)
- move(src, dest);
-#endif
- }
-
- void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
- {
-#if PLATFORM(X86_64)
- m_assembler.movl_rr(src, dest);
-#else
- if (src != dest)
- move(src, dest);
-#endif
- }
-
-
- // Forwards / external control flow operations:
- //
- // This set of jump and conditional branch operations return a Jump
- // object which may linked at a later point, allow forwards jump,
- // or jumps that will require external linkage (after the code has been
- // relocated).
- //
- // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
- // respecitvely, for unsigned comparisons the names b, a, be, and ae are
- // used (representing the names 'below' and 'above').
- //
- // Operands to the comparision are provided in the expected order, e.g.
- // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
- // treated as a signed 32bit value, is less than or equal to 5.
- //
- // jz and jnz test whether the first operand is equal to zero, and take
- // an optional second operand of a mask under which to perform the test.
-
-private:
- void compareImm32ForBranch(RegisterID left, int32_t right)
- {
- m_assembler.cmpl_ir(right, left);
- }
-
- void compareImm32ForBranchEquality(RegisterID reg, int32_t imm)
- {
- if (!imm)
- m_assembler.testl_rr(reg, reg);
- else
- m_assembler.cmpl_ir(imm, reg);
- }
-
- void compareImm32ForBranchEquality(Address address, int32_t imm)
- {
- m_assembler.cmpl_im(imm, address.offset, address.base);
- }
-
- void testImm32(RegisterID reg, Imm32 mask)
- {
- // if we are only interested in the low seven bits, this can be tested with a testb
- if (mask.m_value == -1)
- m_assembler.testl_rr(reg, reg);
- else if ((mask.m_value & ~0x7f) == 0)
- m_assembler.testb_i8r(mask.m_value, reg);
- else
- m_assembler.testl_i32r(mask.m_value, reg);
- }
-
- void testImm32(Address address, Imm32 mask)
- {
- if (mask.m_value == -1)
- m_assembler.cmpl_im(0, address.offset, address.base);
- else
- m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
- }
-
- void testImm32(BaseIndex address, Imm32 mask)
- {
- if (mask.m_value == -1)
- m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale);
- else
- m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
- }
-
-#if PLATFORM(X86_64)
- void compareImm64ForBranch(RegisterID left, int32_t right)
- {
- m_assembler.cmpq_ir(right, left);
- }
-
- void compareImm64ForBranchEquality(RegisterID reg, int32_t imm)
- {
- if (!imm)
- m_assembler.testq_rr(reg, reg);
- else
- m_assembler.cmpq_ir(imm, reg);
- }
-
- void testImm64(RegisterID reg, Imm32 mask)
- {
- // if we are only interested in the low seven bits, this can be tested with a testb
- if (mask.m_value == -1)
- m_assembler.testq_rr(reg, reg);
- else if ((mask.m_value & ~0x7f) == 0)
- m_assembler.testb_i8r(mask.m_value, reg);
- else
- m_assembler.testq_i32r(mask.m_value, reg);
- }
-
- void testImm64(Address address, Imm32 mask)
- {
- if (mask.m_value == -1)
- m_assembler.cmpq_im(0, address.offset, address.base);
- else
- m_assembler.testq_i32m(mask.m_value, address.offset, address.base);
- }
-
- void testImm64(BaseIndex address, Imm32 mask)
- {
- if (mask.m_value == -1)
- m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
- else
- m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
- }
-#endif
-
-public:
- Jump ja32(RegisterID left, Imm32 right)
- {
- compareImm32ForBranch(left, right.m_value);
- return Jump(m_assembler.ja());
- }
-
- Jump jaePtr(RegisterID left, RegisterID right)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(right, left);
- return Jump(m_assembler.jae());
-#else
- return jae32(left, right);
-#endif
- }
-
- Jump jaePtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranch(reg, imm);
- return Jump(m_assembler.jae());
- } else {
- move(ptr, scratchRegister);
- return jaePtr(reg, scratchRegister);
- }
-#else
- return jae32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jae32(RegisterID left, RegisterID right)
- {
- m_assembler.cmpl_rr(right, left);
- return Jump(m_assembler.jae());
- }
-
- Jump jae32(RegisterID left, Imm32 right)
- {
- compareImm32ForBranch(left, right.m_value);
- return Jump(m_assembler.jae());
- }
-
- Jump jae32(RegisterID left, Address right)
- {
- m_assembler.cmpl_mr(right.offset, right.base, left);
- return Jump(m_assembler.jae());
- }
-
- Jump jae32(Address left, RegisterID right)
- {
- m_assembler.cmpl_rm(right, left.offset, left.base);
- return Jump(m_assembler.jae());
- }
-
- Jump jbPtr(RegisterID left, RegisterID right)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(right, left);
- return Jump(m_assembler.jb());
-#else
- return jb32(left, right);
-#endif
- }
-
- Jump jbPtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranch(reg, imm);
- return Jump(m_assembler.jb());
- } else {
- move(ptr, scratchRegister);
- return jbPtr(reg, scratchRegister);
- }
-#else
- return jb32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jb32(RegisterID left, RegisterID right)
- {
- m_assembler.cmpl_rr(right, left);
- return Jump(m_assembler.jb());
- }
-
- Jump jb32(RegisterID left, Imm32 right)
- {
- compareImm32ForBranch(left, right.m_value);
- return Jump(m_assembler.jb());
- }
-
- Jump jb32(RegisterID left, Address right)
- {
- m_assembler.cmpl_mr(right.offset, right.base, left);
- return Jump(m_assembler.jb());
- }
-
- Jump jePtr(RegisterID op1, RegisterID op2)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(op1, op2);
- return Jump(m_assembler.je());
-#else
- return je32(op1, op2);
-#endif
- }
-
- Jump jePtr(RegisterID reg, Address address)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rm(reg, address.offset, address.base);
-#else
- m_assembler.cmpl_rm(reg, address.offset, address.base);
-#endif
- return Jump(m_assembler.je());
- }
-
- Jump jePtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranchEquality(reg, imm);
- return Jump(m_assembler.je());
- } else {
- move(ptr, scratchRegister);
- return jePtr(scratchRegister, reg);
- }
-#else
- return je32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jePtr(Address address, ImmPtr imm)
- {
-#if PLATFORM(X86_64)
- move(imm, scratchRegister);
- return jePtr(scratchRegister, address);
-#else
- return je32(address, Imm32(imm));
-#endif
- }
-
- Jump je32(RegisterID op1, RegisterID op2)
- {
- m_assembler.cmpl_rr(op1, op2);
- return Jump(m_assembler.je());
- }
-
- Jump je32(Address op1, RegisterID op2)
- {
- m_assembler.cmpl_mr(op1.offset, op1.base, op2);
- return Jump(m_assembler.je());
- }
-
- Jump je32(RegisterID reg, Imm32 imm)
- {
- compareImm32ForBranchEquality(reg, imm.m_value);
- return Jump(m_assembler.je());
- }
-
- Jump je32(Address address, Imm32 imm)
- {
- compareImm32ForBranchEquality(address, imm.m_value);
- return Jump(m_assembler.je());
- }
-
- Jump je16(RegisterID op1, BaseIndex op2)
- {
- m_assembler.cmpw_rm(op1, op2.offset, op2.base, op2.index, op2.scale);
- return Jump(m_assembler.je());
- }
-
- Jump jg32(RegisterID left, RegisterID right)
- {
- m_assembler.cmpl_rr(right, left);
- return Jump(m_assembler.jg());
- }
-
- Jump jg32(RegisterID reg, Address address)
- {
- m_assembler.cmpl_mr(address.offset, address.base, reg);
- return Jump(m_assembler.jg());
- }
-
- Jump jgePtr(RegisterID left, RegisterID right)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(right, left);
- return Jump(m_assembler.jge());
-#else
- return jge32(left, right);
-#endif
- }
-
- Jump jgePtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranch(reg, imm);
- return Jump(m_assembler.jge());
- } else {
- move(ptr, scratchRegister);
- return jgePtr(reg, scratchRegister);
- }
-#else
- return jge32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jge32(RegisterID left, RegisterID right)
- {
- m_assembler.cmpl_rr(right, left);
- return Jump(m_assembler.jge());
- }
-
- Jump jge32(RegisterID left, Imm32 right)
- {
- compareImm32ForBranch(left, right.m_value);
- return Jump(m_assembler.jge());
- }
-
- Jump jlPtr(RegisterID left, RegisterID right)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(right, left);
- return Jump(m_assembler.jl());
-#else
- return jl32(left, right);
-#endif
- }
-
- Jump jlPtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranch(reg, imm);
- return Jump(m_assembler.jl());
- } else {
- move(ptr, scratchRegister);
- return jlPtr(reg, scratchRegister);
- }
-#else
- return jl32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jl32(RegisterID left, RegisterID right)
- {
- m_assembler.cmpl_rr(right, left);
- return Jump(m_assembler.jl());
- }
-
- Jump jl32(RegisterID left, Imm32 right)
- {
- compareImm32ForBranch(left, right.m_value);
- return Jump(m_assembler.jl());
- }
-
- Jump jlePtr(RegisterID left, RegisterID right)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(right, left);
- return Jump(m_assembler.jle());
-#else
- return jle32(left, right);
-#endif
- }
-
- Jump jlePtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranch(reg, imm);
- return Jump(m_assembler.jle());
- } else {
- move(ptr, scratchRegister);
- return jlePtr(reg, scratchRegister);
- }
-#else
- return jle32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jle32(RegisterID left, RegisterID right)
- {
- m_assembler.cmpl_rr(right, left);
- return Jump(m_assembler.jle());
- }
-
- Jump jle32(RegisterID left, Imm32 right)
- {
- compareImm32ForBranch(left, right.m_value);
- return Jump(m_assembler.jle());
- }
-
- Jump jnePtr(RegisterID op1, RegisterID op2)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rr(op1, op2);
- return Jump(m_assembler.jne());
-#else
- return jne32(op1, op2);
-#endif
- }
- Jump jnePtr(RegisterID reg, Address address)
- {
-#if PLATFORM(X86_64)
- m_assembler.cmpq_rm(reg, address.offset, address.base);
-#else
- m_assembler.cmpl_rm(reg, address.offset, address.base);
-#endif
- return Jump(m_assembler.jne());
- }
-
- Jump jnePtr(RegisterID reg, AbsoluteAddress address)
- {
-#if PLATFORM(X86_64)
- move(ImmPtr(address.m_ptr), scratchRegister);
- return jnePtr(reg, Address(scratchRegister));
-#else
- m_assembler.cmpl_rm(reg, address.m_ptr);
- return Jump(m_assembler.jne());
-#endif
- }
-
- Jump jnePtr(RegisterID reg, ImmPtr ptr)
- {
-#if PLATFORM(X86_64)
- intptr_t imm = ptr.asIntptr();
- if (CAN_SIGN_EXTEND_32_64(imm)) {
- compareImm64ForBranchEquality(reg, imm);
- return Jump(m_assembler.jne());
- } else {
- move(ptr, scratchRegister);
- return jnePtr(scratchRegister, reg);
- }
-#else
- return jne32(reg, Imm32(ptr));
-#endif
- }
-
- Jump jnePtr(Address address, ImmPtr imm)
- {
-#if PLATFORM(X86_64)
- move(imm, scratchRegister);
- return jnePtr(scratchRegister, address);
-#else
- return jne32(address, Imm32(imm));
-#endif
- }
-
-#if !PLATFORM(X86_64)
- Jump jnePtr(AbsoluteAddress address, ImmPtr imm)
+ DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
{
- m_assembler.cmpl_im(imm.asIntptr(), address.m_ptr);
- return Jump(m_assembler.jne());
+ return store32WithAddressOffsetPatch(src, address);
}
-#endif
- Jump jnePtrWithPatch(RegisterID reg, DataLabelPtr& dataLabel, ImmPtr initialValue = ImmPtr(0))
- {
-#if PLATFORM(X86_64)
- m_assembler.movq_i64r(initialValue.asIntptr(), scratchRegister);
- dataLabel = DataLabelPtr(this);
- return jnePtr(scratchRegister, reg);
-#else
- m_assembler.cmpl_ir_force32(initialValue.asIntptr(), reg);
- dataLabel = DataLabelPtr(this);
- return Jump(m_assembler.jne());
-#endif
- }
- Jump jnePtrWithPatch(Address address, DataLabelPtr& dataLabel, ImmPtr initialValue = ImmPtr(0))
+ Jump branchPtr(Condition cond, RegisterID left, RegisterID right)
{
-#if PLATFORM(X86_64)
- m_assembler.movq_i64r(initialValue.asIntptr(), scratchRegister);
- dataLabel = DataLabelPtr(this);
- return jnePtr(scratchRegister, address);
-#else
- m_assembler.cmpl_im_force32(initialValue.asIntptr(), address.offset, address.base);
- dataLabel = DataLabelPtr(this);
- return Jump(m_assembler.jne());
-#endif
+ return branch32(cond, left, right);
}
- Jump jne32(RegisterID op1, RegisterID op2)
+ Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
{
- m_assembler.cmpl_rr(op1, op2);
- return Jump(m_assembler.jne());
+ return branch32(cond, left, Imm32(right));
}
- Jump jne32(RegisterID reg, Imm32 imm)
+ Jump branchPtr(Condition cond, RegisterID left, Address right)
{
- compareImm32ForBranchEquality(reg, imm.m_value);
- return Jump(m_assembler.jne());
+ return branch32(cond, left, right);
}
- Jump jne32(Address address, Imm32 imm)
- {
- compareImm32ForBranchEquality(address, imm.m_value);
- return Jump(m_assembler.jne());
- }
-
- Jump jne32(Address address, RegisterID reg)
+ Jump branchPtr(Condition cond, Address left, RegisterID right)
{
- m_assembler.cmpl_rm(reg, address.offset, address.base);
- return Jump(m_assembler.jne());
- }
-
- Jump jnzPtr(RegisterID reg, RegisterID mask)
- {
-#if PLATFORM(X86_64)
- m_assembler.testq_rr(reg, mask);
- return Jump(m_assembler.jne());
-#else
- return jnz32(reg, mask);
-#endif
+ return branch32(cond, left, right);
}
- Jump jnzPtr(RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
{
-#if PLATFORM(X86_64)
- testImm64(reg, mask);
- return Jump(m_assembler.jne());
-#else
- return jnz32(reg, mask);
-#endif
+ return branch32(cond, left, right);
}
- Jump jnzPtr(RegisterID reg, ImmPtr mask)
+ Jump branchPtr(Condition cond, Address left, ImmPtr right)
{
-#if PLATFORM(X86_64)
- move(mask, scratchRegister);
- m_assembler.testq_rr(scratchRegister, reg);
- return Jump(m_assembler.jne());
-#else
- return jnz32(reg, Imm32(mask));
-#endif
+ return branch32(cond, left, Imm32(right));
}
- Jump jnzPtr(Address address, Imm32 mask = Imm32(-1))
+ Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right)
{
-#if PLATFORM(X86_64)
- testImm64(address, mask);
- return Jump(m_assembler.jne());
-#else
- return jnz32(address, mask);
-#endif
+ return branch32(cond, left, Imm32(right));
}
- Jump jnz32(RegisterID reg, RegisterID mask)
+ Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
{
- m_assembler.testl_rr(reg, mask);
- return Jump(m_assembler.jne());
+ return branchTest32(cond, reg, mask);
}
- Jump jnz32(RegisterID reg, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
{
- testImm32(reg, mask);
- return Jump(m_assembler.jne());
+ return branchTest32(cond, reg, mask);
}
- Jump jnz32(Address address, Imm32 mask = Imm32(-1))
+ Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
{
- testImm32(address, mask);
- return Jump(m_assembler.jne());
+ return branchTest32(cond, address, mask);
}
- Jump jzPtr(RegisterID reg, RegisterID mask)
+ Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
{
-#if PLATFORM(X86_64)
- m_assembler.testq_rr(reg, mask);
- return Jump(m_assembler.je());
-#else
- return jz32(reg, mask);
-#endif
+ return branchTest32(cond, address, mask);
}
- Jump jzPtr(RegisterID reg, Imm32 mask = Imm32(-1))
- {
-#if PLATFORM(X86_64)
- testImm64(reg, mask);
- return Jump(m_assembler.je());
-#else
- return jz32(reg, mask);
-#endif
- }
- Jump jzPtr(RegisterID reg, ImmPtr mask)
+ Jump branchAddPtr(Condition cond, RegisterID src, RegisterID dest)
{
-#if PLATFORM(X86_64)
- move(mask, scratchRegister);
- m_assembler.testq_rr(scratchRegister, reg);
- return Jump(m_assembler.je());
-#else
- return jz32(reg, Imm32(mask));
-#endif
+ return branchAdd32(cond, src, dest);
}
- Jump jzPtr(Address address, Imm32 mask = Imm32(-1))
+ Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
{
-#if PLATFORM(X86_64)
- testImm64(address, mask);
- return Jump(m_assembler.je());
-#else
- return jz32(address, mask);
-#endif
+ return branchSub32(cond, imm, dest);
}
-
- Jump jzPtr(BaseIndex address, Imm32 mask = Imm32(-1))
- {
-#if PLATFORM(X86_64)
- testImm64(address, mask);
- return Jump(m_assembler.je());
-#else
- return jz32(address, mask);
#endif
- }
-
- Jump jz32(RegisterID reg, RegisterID mask)
- {
- m_assembler.testl_rr(reg, mask);
- return Jump(m_assembler.je());
- }
-
- Jump jz32(RegisterID reg, Imm32 mask = Imm32(-1))
- {
- testImm32(reg, mask);
- return Jump(m_assembler.je());
- }
-
- Jump jz32(Address address, Imm32 mask = Imm32(-1))
- {
- testImm32(address, mask);
- return Jump(m_assembler.je());
- }
-
- Jump jz32(BaseIndex address, Imm32 mask = Imm32(-1))
- {
- testImm32(address, mask);
- return Jump(m_assembler.je());
- }
-
- Jump jump()
- {
- return Jump(m_assembler.jmp());
- }
-
-
- // Backwards, local control flow operations:
- //
- // These operations provide a shorter notation for local
- // backwards branches, which may be both more convenient
- // for the user, and for the programmer, and for the
- // assembler (allowing shorter values to be used in
- // relative offsets).
- //
- // The code sequence:
- //
- // Label topOfLoop(this);
- // // ...
- // jne32(reg1, reg2, topOfLoop);
- //
- // Is equivalent to the longer, potentially less efficient form:
- //
- // Label topOfLoop(this);
- // // ...
- // jne32(reg1, reg2).linkTo(topOfLoop);
-
- void jae32(RegisterID left, Address right, Label target)
- {
- jae32(left, right).linkTo(target, this);
- }
-
- void je32(RegisterID op1, Imm32 imm, Label target)
- {
- je32(op1, imm).linkTo(target, this);
- }
-
- void je16(RegisterID op1, BaseIndex op2, Label target)
- {
- je16(op1, op2).linkTo(target, this);
- }
-
- void jl32(RegisterID left, Imm32 right, Label target)
- {
- jl32(left, right).linkTo(target, this);
- }
-
- void jle32(RegisterID left, RegisterID right, Label target)
- {
- jle32(left, right).linkTo(target, this);
- }
-
- void jnePtr(RegisterID op1, ImmPtr imm, Label target)
- {
- jnePtr(op1, imm).linkTo(target, this);
- }
-
- void jne32(RegisterID op1, RegisterID op2, Label target)
- {
- jne32(op1, op2).linkTo(target, this);
- }
-
- void jne32(RegisterID op1, Imm32 imm, Label target)
- {
- jne32(op1, imm).linkTo(target, this);
- }
-
- void jzPtr(RegisterID reg, Label target)
- {
- jzPtr(reg).linkTo(target, this);
- }
-
- void jump(Label target)
- {
- m_assembler.link(m_assembler.jmp(), target.m_label);
- }
-
- void jump(RegisterID target)
- {
- m_assembler.jmp_r(target);
- }
-
- // Address is a memory location containing the address to jump to
- void jump(Address address)
- {
- m_assembler.jmp_m(address.offset, address.base);
- }
-
-
- // Arithmetic control flow operations:
- //
- // This set of conditional branch operations branch based
- // on the result of an arithmetic operation. The operation
- // is performed as normal, storing the result.
- //
- // * jz operations branch if the result is zero.
- // * jo operations branch if the (signed) arithmetic
- // operation caused an overflow to occur.
-
- Jump jnzSubPtr(Imm32 imm, RegisterID dest)
- {
- subPtr(imm, dest);
- return Jump(m_assembler.jne());
- }
-
- Jump jnzSub32(Imm32 imm, RegisterID dest)
- {
- sub32(imm, dest);
- return Jump(m_assembler.jne());
- }
-
- Jump joAddPtr(RegisterID src, RegisterID dest)
- {
- addPtr(src, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump joAdd32(RegisterID src, RegisterID dest)
- {
- add32(src, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump joAdd32(Imm32 imm, RegisterID dest)
- {
- add32(imm, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump joMul32(RegisterID src, RegisterID dest)
- {
- mul32(src, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump joMul32(Imm32 imm, RegisterID src, RegisterID dest)
- {
- mul32(imm, src, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump joSub32(RegisterID src, RegisterID dest)
- {
- sub32(src, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump joSub32(Imm32 imm, RegisterID dest)
- {
- sub32(imm, dest);
- return Jump(m_assembler.jo());
- }
-
- Jump jzSubPtr(Imm32 imm, RegisterID dest)
- {
- subPtr(imm, dest);
- return Jump(m_assembler.je());
- }
-
- Jump jzSub32(Imm32 imm, RegisterID dest)
- {
- sub32(imm, dest);
- return Jump(m_assembler.je());
- }
-
- // Miscellaneous operations:
-
- void breakpoint()
- {
- m_assembler.int3();
- }
-
- Jump call()
- {
- return Jump(m_assembler.call());
- }
-
- // FIXME: why does this return a Jump object? - it can't be linked.
- // This may be to get a reference to the return address of the call.
- //
- // This should probably be handled by a separate label type to a regular
- // jump. Todo: add a CallLabel type, for the regular call - can be linked
- // like a jump (possibly a subclass of jump?, or possibly casts to a Jump).
- // Also add a CallReturnLabel type for this to return (just a more JmpDsty
- // form of label, can get the void* after the code has been linked, but can't
- // try to link it like a Jump object), and let the CallLabel be cast into a
- // CallReturnLabel.
- Jump call(RegisterID target)
- {
- return Jump(m_assembler.call(target));
- }
-
- Label label()
- {
- return Label(this);
- }
-
- Label align()
- {
- m_assembler.align(16);
- return Label(this);
- }
-
- ptrdiff_t differenceBetween(Label from, Jump to)
- {
- return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
- }
-
- ptrdiff_t differenceBetween(Label from, Label to)
- {
- return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
- }
-
- ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
- {
- return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
- }
-
- ptrdiff_t differenceBetween(Label from, DataLabel32 to)
- {
- return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
- }
-
- ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
- {
- return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
- }
-
- void ret()
- {
- m_assembler.ret();
- }
-
- void sete32(RegisterID src, RegisterID srcDest)
- {
- m_assembler.cmpl_rr(srcDest, src);
- m_assembler.sete_r(srcDest);
- m_assembler.movzbl_rr(srcDest, srcDest);
- }
-
- void sete32(Imm32 imm, RegisterID srcDest)
- {
- compareImm32ForBranchEquality(srcDest, imm.m_value);
- m_assembler.sete_r(srcDest);
- m_assembler.movzbl_rr(srcDest, srcDest);
- }
-
- void setne32(RegisterID src, RegisterID srcDest)
- {
- m_assembler.cmpl_rr(srcDest, src);
- m_assembler.setne_r(srcDest);
- m_assembler.movzbl_rr(srcDest, srcDest);
- }
-
- void setne32(Imm32 imm, RegisterID srcDest)
- {
- compareImm32ForBranchEquality(srcDest, imm.m_value);
- m_assembler.setne_r(srcDest);
- m_assembler.movzbl_rr(srcDest, srcDest);
- }
-
- // FIXME:
- // The mask should be optional... paerhaps the argument order should be
- // dest-src, operations always have a dest? ... possibly not true, considering
- // asm ops like test, or pseudo ops like pop().
- void setnz32(Address address, Imm32 mask, RegisterID dest)
- {
- testImm32(address, mask);
- m_assembler.setnz_r(dest);
- m_assembler.movzbl_rr(dest, dest);
- }
-
- void setz32(Address address, Imm32 mask, RegisterID dest)
- {
- testImm32(address, mask);
- m_assembler.setz_r(dest);
- m_assembler.movzbl_rr(dest, dest);
- }
};
} // namespace JSC
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86.h b/JavaScriptCore/assembler/MacroAssemblerX86.h
new file mode 100644
index 0000000..b85b8b2
--- /dev/null
+++ b/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MacroAssemblerX86_h
+#define MacroAssemblerX86_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && PLATFORM(X86)
+
+#include "MacroAssemblerX86Common.h"
+
+namespace JSC {
+
+class MacroAssemblerX86 : public MacroAssemblerX86Common {
+public:
+ static const Scale ScalePtr = TimesFour;
+
+ using MacroAssemblerX86Common::add32;
+ using MacroAssemblerX86Common::sub32;
+ using MacroAssemblerX86Common::load32;
+ using MacroAssemblerX86Common::store32;
+ using MacroAssemblerX86Common::branch32;
+ using MacroAssemblerX86Common::call;
+
+ void add32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.leal_mr(imm.m_value, src, dest);
+ }
+
+ void add32(Imm32 imm, AbsoluteAddress address)
+ {
+ m_assembler.addl_im(imm.m_value, address.m_ptr);
+ }
+
+ void sub32(Imm32 imm, AbsoluteAddress address)
+ {
+ m_assembler.subl_im(imm.m_value, address.m_ptr);
+ }
+
+ void load32(void* address, RegisterID dest)
+ {
+ m_assembler.movl_mr(address, dest);
+ }
+
+ void store32(Imm32 imm, void* address)
+ {
+ m_assembler.movl_i32m(imm.m_value, address);
+ }
+
+ Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
+ {
+ m_assembler.cmpl_rm(right, left.m_ptr);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+ {
+ m_assembler.cmpl_im(right.m_value, left.m_ptr);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Call call()
+ {
+ return Call(m_assembler.call(), Call::Linkable);
+ }
+
+ Call tailRecursiveCall()
+ {
+ return Call::fromTailJump(jump());
+ }
+
+ Call makeTailRecursiveCall(Jump oldJump)
+ {
+ return Call::fromTailJump(oldJump);
+ }
+
+
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ {
+ m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left);
+ dataLabel = DataLabelPtr(this);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ {
+ m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base);
+ dataLabel = DataLabelPtr(this);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ DataLabelPtr storePtrWithPatch(Address address)
+ {
+ m_assembler.movl_i32m(0, address.offset, address.base);
+ return DataLabelPtr(this);
+ }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerX86_h
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/JavaScriptCore/assembler/MacroAssemblerX86Common.h
new file mode 100644
index 0000000..5fcd25d
--- /dev/null
+++ b/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MacroAssemblerX86Common_h
+#define MacroAssemblerX86Common_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include "X86Assembler.h"
+#include "AbstractMacroAssembler.h"
+
+namespace JSC {
+
+class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
+public:
+
+ typedef X86Assembler::Condition Condition;
+ static const Condition Equal = X86Assembler::ConditionE;
+ static const Condition NotEqual = X86Assembler::ConditionNE;
+ static const Condition Above = X86Assembler::ConditionA;
+ static const Condition AboveOrEqual = X86Assembler::ConditionAE;
+ static const Condition Below = X86Assembler::ConditionB;
+ static const Condition BelowOrEqual = X86Assembler::ConditionBE;
+ static const Condition GreaterThan = X86Assembler::ConditionG;
+ static const Condition GreaterThanOrEqual = X86Assembler::ConditionGE;
+ static const Condition LessThan = X86Assembler::ConditionL;
+ static const Condition LessThanOrEqual = X86Assembler::ConditionLE;
+ static const Condition Overflow = X86Assembler::ConditionO;
+ static const Condition Zero = X86Assembler::ConditionE;
+ static const Condition NonZero = X86Assembler::ConditionNE;
+
+ static const RegisterID stackPointerRegister = X86::esp;
+
+ // Integer arithmetic operations:
+ //
+ // Operations are typically two operand - operation(source, srcDst)
+ // For many operations the source may be an Imm32, the srcDst operand
+ // may often be a memory location (explictly described using an Address
+ // object).
+
+ void add32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.addl_rr(src, dest);
+ }
+
+ void add32(Imm32 imm, Address address)
+ {
+ m_assembler.addl_im(imm.m_value, address.offset, address.base);
+ }
+
+ void add32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.addl_ir(imm.m_value, dest);
+ }
+
+ void add32(Address src, RegisterID dest)
+ {
+ m_assembler.addl_mr(src.offset, src.base, dest);
+ }
+
+ void and32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.andl_rr(src, dest);
+ }
+
+ void and32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.andl_ir(imm.m_value, dest);
+ }
+
+ void lshift32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.shll_i8r(imm.m_value, dest);
+ }
+
+ void lshift32(RegisterID shift_amount, RegisterID dest)
+ {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ if (shift_amount != X86::ecx) {
+ swap(shift_amount, X86::ecx);
+
+ // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+ if (dest == shift_amount)
+ m_assembler.shll_CLr(X86::ecx);
+ // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+ else if (dest == X86::ecx)
+ m_assembler.shll_CLr(shift_amount);
+ // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+ else
+ m_assembler.shll_CLr(dest);
+
+ swap(shift_amount, X86::ecx);
+ } else
+ m_assembler.shll_CLr(dest);
+ }
+
+ void mul32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.imull_rr(src, dest);
+ }
+
+ void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.imull_i32r(src, imm.m_value, dest);
+ }
+
+ void not32(RegisterID srcDest)
+ {
+ m_assembler.notl_r(srcDest);
+ }
+
+ void or32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.orl_rr(src, dest);
+ }
+
+ void or32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.orl_ir(imm.m_value, dest);
+ }
+
+ void rshift32(RegisterID shift_amount, RegisterID dest)
+ {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ if (shift_amount != X86::ecx) {
+ swap(shift_amount, X86::ecx);
+
+ // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+ if (dest == shift_amount)
+ m_assembler.sarl_CLr(X86::ecx);
+ // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+ else if (dest == X86::ecx)
+ m_assembler.sarl_CLr(shift_amount);
+ // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+ else
+ m_assembler.sarl_CLr(dest);
+
+ swap(shift_amount, X86::ecx);
+ } else
+ m_assembler.sarl_CLr(dest);
+ }
+
+ void rshift32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.sarl_i8r(imm.m_value, dest);
+ }
+
+ void sub32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.subl_rr(src, dest);
+ }
+
+ void sub32(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.subl_ir(imm.m_value, dest);
+ }
+
+ void sub32(Imm32 imm, Address address)
+ {
+ m_assembler.subl_im(imm.m_value, address.offset, address.base);
+ }
+
+ void sub32(Address src, RegisterID dest)
+ {
+ m_assembler.subl_mr(src.offset, src.base, dest);
+ }
+
+ void xor32(RegisterID src, RegisterID dest)
+ {
+ m_assembler.xorl_rr(src, dest);
+ }
+
+ void xor32(Imm32 imm, RegisterID srcDest)
+ {
+ m_assembler.xorl_ir(imm.m_value, srcDest);
+ }
+
+
+ // Memory access operations:
+ //
+ // Loads are of the form load(address, destination) and stores of the form
+ // store(source, address). The source for a store may be an Imm32. Address
+ // operand objects to loads and store will be implicitly constructed if a
+ // register is passed.
+
+ void load32(ImplicitAddress address, RegisterID dest)
+ {
+ m_assembler.movl_mr(address.offset, address.base, dest);
+ }
+
+ void load32(BaseIndex address, RegisterID dest)
+ {
+ m_assembler.movl_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
+
+ DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
+ {
+ m_assembler.movl_mr_disp32(address.offset, address.base, dest);
+ return DataLabel32(this);
+ }
+
+ void load16(BaseIndex address, RegisterID dest)
+ {
+ m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
+
+ DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
+ {
+ m_assembler.movl_rm_disp32(src, address.offset, address.base);
+ return DataLabel32(this);
+ }
+
+ void store32(RegisterID src, ImplicitAddress address)
+ {
+ m_assembler.movl_rm(src, address.offset, address.base);
+ }
+
+ void store32(RegisterID src, BaseIndex address)
+ {
+ m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale);
+ }
+
+ void store32(Imm32 imm, ImplicitAddress address)
+ {
+ m_assembler.movl_i32m(imm.m_value, address.offset, address.base);
+ }
+
+
+ // Stack manipulation operations:
+ //
+ // The ABI is assumed to provide a stack abstraction to memory,
+ // containing machine word sized units of data. Push and pop
+ // operations add and remove a single register sized unit of data
+ // to or from the stack. Peek and poke operations read or write
+ // values on the stack, without moving the current stack position.
+
+ void pop(RegisterID dest)
+ {
+ m_assembler.pop_r(dest);
+ }
+
+ void push(RegisterID src)
+ {
+ m_assembler.push_r(src);
+ }
+
+ void push(Address address)
+ {
+ m_assembler.push_m(address.offset, address.base);
+ }
+
+ void push(Imm32 imm)
+ {
+ m_assembler.push_i32(imm.m_value);
+ }
+
+ // Register move operations:
+ //
+ // Move values in registers.
+
+ void move(Imm32 imm, RegisterID dest)
+ {
+ // Note: on 64-bit the Imm32 value is zero extended into the register, it
+ // may be useful to have a separate version that sign extends the value?
+ if (!imm.m_value)
+ m_assembler.xorl_rr(dest, dest);
+ else
+ m_assembler.movl_i32r(imm.m_value, dest);
+ }
+
+#if PLATFORM(X86_64)
+ void move(RegisterID src, RegisterID dest)
+ {
+ // Note: on 64-bit this is is a full register move; perhaps it would be
+ // useful to have separate move32 & movePtr, with move32 zero extending?
+ m_assembler.movq_rr(src, dest);
+ }
+
+ void move(ImmPtr imm, RegisterID dest)
+ {
+ if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr()))
+ m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest);
+ else
+ m_assembler.movq_i64r(imm.asIntptr(), dest);
+ }
+
+ void swap(RegisterID reg1, RegisterID reg2)
+ {
+ m_assembler.xchgq_rr(reg1, reg2);
+ }
+
+ void signExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.movsxd_rr(src, dest);
+ }
+
+ void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.movl_rr(src, dest);
+ }
+#else
+ void move(RegisterID src, RegisterID dest)
+ {
+ m_assembler.movl_rr(src, dest);
+ }
+
+ void move(ImmPtr imm, RegisterID dest)
+ {
+ m_assembler.movl_i32r(imm.asIntptr(), dest);
+ }
+
+ void swap(RegisterID reg1, RegisterID reg2)
+ {
+ m_assembler.xchgl_rr(reg1, reg2);
+ }
+
+ void signExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ }
+
+ void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ }
+#endif
+
+
+ // Forwards / external control flow operations:
+ //
+ // This set of jump and conditional branch operations return a Jump
+ // object which may linked at a later point, allow forwards jump,
+ // or jumps that will require external linkage (after the code has been
+ // relocated).
+ //
+ // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
+ // respecitvely, for unsigned comparisons the names b, a, be, and ae are
+ // used (representing the names 'below' and 'above').
+ //
+ // Operands to the comparision are provided in the expected order, e.g.
+ // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+ // treated as a signed 32bit value, is less than or equal to 5.
+ //
+ // jz and jnz test whether the first operand is equal to zero, and take
+ // an optional second operand of a mask under which to perform the test.
+
+public:
+ Jump branch32(Condition cond, RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpl_rr(right, left);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branch32(Condition cond, RegisterID left, Imm32 right)
+ {
+ if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+ m_assembler.testl_rr(left, left);
+ else
+ m_assembler.cmpl_ir(right.m_value, left);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branch32(Condition cond, RegisterID left, Address right)
+ {
+ m_assembler.cmpl_mr(right.offset, right.base, left);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branch32(Condition cond, Address left, RegisterID right)
+ {
+ m_assembler.cmpl_rm(right, left.offset, left.base);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branch32(Condition cond, Address left, Imm32 right)
+ {
+ m_assembler.cmpl_im(right.m_value, left.offset, left.base);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branch16(Condition cond, BaseIndex left, RegisterID right)
+ {
+ m_assembler.cmpw_rm(right, left.offset, left.base, left.index, left.scale);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
+ {
+ ASSERT((cond == Zero) || (cond == NonZero));
+ m_assembler.testl_rr(reg, mask);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ {
+ ASSERT((cond == Zero) || (cond == NonZero));
+ // if we are only interested in the low seven bits, this can be tested with a testb
+ if (mask.m_value == -1)
+ m_assembler.testl_rr(reg, reg);
+ else if ((mask.m_value & ~0x7f) == 0)
+ m_assembler.testb_i8r(mask.m_value, reg);
+ else
+ m_assembler.testl_i32r(mask.m_value, reg);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ {
+ ASSERT((cond == Zero) || (cond == NonZero));
+ if (mask.m_value == -1)
+ m_assembler.cmpl_im(0, address.offset, address.base);
+ else
+ m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ {
+ ASSERT((cond == Zero) || (cond == NonZero));
+ if (mask.m_value == -1)
+ m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale);
+ else
+ m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump jump()
+ {
+ return Jump(m_assembler.jmp());
+ }
+
+ void jump(RegisterID target)
+ {
+ m_assembler.jmp_r(target);
+ }
+
+ // Address is a memory location containing the address to jump to
+ void jump(Address address)
+ {
+ m_assembler.jmp_m(address.offset, address.base);
+ }
+
+
+ // Arithmetic control flow operations:
+ //
+ // This set of conditional branch operations branch based
+ // on the result of an arithmetic operation. The operation
+ // is performed as normal, storing the result.
+ //
+ // * jz operations branch if the result is zero.
+ // * jo operations branch if the (signed) arithmetic
+ // operation caused an overflow to occur.
+
+ Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ add32(src, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ add32(imm, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ mul32(src, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ mul32(imm, src, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ sub32(src, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ sub32(imm, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+
+ // Miscellaneous operations:
+
+ void breakpoint()
+ {
+ m_assembler.int3();
+ }
+
+ Call nearCall()
+ {
+ return Call(m_assembler.call(), Call::LinkableNear);
+ }
+
+ Call call(RegisterID target)
+ {
+ return Call(m_assembler.call(target), Call::None);
+ }
+
+ void ret()
+ {
+ m_assembler.ret();
+ }
+
+ void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+ {
+ m_assembler.cmpl_rr(right, left);
+ m_assembler.setCC_r(cond, dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+
+ void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ {
+ if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+ m_assembler.testl_rr(left, left);
+ else
+ m_assembler.cmpl_ir(right.m_value, left);
+ m_assembler.setCC_r(cond, dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+
+ // FIXME:
+ // The mask should be optional... paerhaps the argument order should be
+ // dest-src, operations always have a dest? ... possibly not true, considering
+ // asm ops like test, or pseudo ops like pop().
+ void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpl_im(0, address.offset, address.base);
+ else
+ m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+ m_assembler.setCC_r(cond, dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerX86Common_h
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/JavaScriptCore/assembler/MacroAssemblerX86_64.h
new file mode 100644
index 0000000..971787b
--- /dev/null
+++ b/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MacroAssemblerX86_64_h
+#define MacroAssemblerX86_64_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && PLATFORM(X86_64)
+
+#include "MacroAssemblerX86Common.h"
+
+namespace JSC {
+
+class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
+protected:
+ static const X86::RegisterID scratchRegister = X86::r11;
+
+public:
+ static const Scale ScalePtr = TimesEight;
+
+ using MacroAssemblerX86Common::add32;
+ using MacroAssemblerX86Common::sub32;
+ using MacroAssemblerX86Common::load32;
+ using MacroAssemblerX86Common::store32;
+ using MacroAssemblerX86Common::call;
+
+ void add32(Imm32 imm, AbsoluteAddress address)
+ {
+ move(ImmPtr(address.m_ptr), scratchRegister);
+ add32(imm, Address(scratchRegister));
+ }
+
+ void sub32(Imm32 imm, AbsoluteAddress address)
+ {
+ move(ImmPtr(address.m_ptr), scratchRegister);
+ sub32(imm, Address(scratchRegister));
+ }
+
+ void load32(void* address, RegisterID dest)
+ {
+ if (dest == X86::eax)
+ m_assembler.movl_mEAX(address);
+ else {
+ move(X86::eax, dest);
+ m_assembler.movl_mEAX(address);
+ swap(X86::eax, dest);
+ }
+ }
+
+ void store32(Imm32 imm, void* address)
+ {
+ move(X86::eax, scratchRegister);
+ move(imm, X86::eax);
+ m_assembler.movl_EAXm(address);
+ move(scratchRegister, X86::eax);
+ }
+
+ Call call()
+ {
+ DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ Call result = Call(m_assembler.call(scratchRegister), Call::Linkable);
+ ASSERT(differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11);
+ return result;
+ }
+
+ Call tailRecursiveCall()
+ {
+ DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
+ ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
+ return Call::fromTailJump(newJump);
+ }
+
+ Call makeTailRecursiveCall(Jump oldJump)
+ {
+ oldJump.link(this);
+ DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
+ ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
+ return Call::fromTailJump(newJump);
+ }
+
+
+ void addPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.addq_rr(src, dest);
+ }
+
+ void addPtr(Imm32 imm, RegisterID srcDest)
+ {
+ m_assembler.addq_ir(imm.m_value, srcDest);
+ }
+
+ void addPtr(ImmPtr imm, RegisterID dest)
+ {
+ move(imm, scratchRegister);
+ m_assembler.addq_rr(scratchRegister, dest);
+ }
+
+ void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.leal_mr(imm.m_value, src, dest);
+ }
+
+ void andPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.andq_rr(src, dest);
+ }
+
+ void andPtr(Imm32 imm, RegisterID srcDest)
+ {
+ m_assembler.andq_ir(imm.m_value, srcDest);
+ }
+
+ void orPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.orq_rr(src, dest);
+ }
+
+ void orPtr(ImmPtr imm, RegisterID dest)
+ {
+ move(imm, scratchRegister);
+ m_assembler.orq_rr(scratchRegister, dest);
+ }
+
+ void orPtr(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.orq_ir(imm.m_value, dest);
+ }
+
+ void rshiftPtr(RegisterID shift_amount, RegisterID dest)
+ {
+ // On x86 we can only shift by ecx; if asked to shift by another register we'll
+ // need rejig the shift amount into ecx first, and restore the registers afterwards.
+ if (shift_amount != X86::ecx) {
+ swap(shift_amount, X86::ecx);
+
+ // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+ if (dest == shift_amount)
+ m_assembler.sarq_CLr(X86::ecx);
+ // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+ else if (dest == X86::ecx)
+ m_assembler.sarq_CLr(shift_amount);
+ // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+ else
+ m_assembler.sarq_CLr(dest);
+
+ swap(shift_amount, X86::ecx);
+ } else
+ m_assembler.sarq_CLr(dest);
+ }
+
+ void rshiftPtr(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.sarq_i8r(imm.m_value, dest);
+ }
+
+ void subPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.subq_rr(src, dest);
+ }
+
+ void subPtr(Imm32 imm, RegisterID dest)
+ {
+ m_assembler.subq_ir(imm.m_value, dest);
+ }
+
+ void subPtr(ImmPtr imm, RegisterID dest)
+ {
+ move(imm, scratchRegister);
+ m_assembler.subq_rr(scratchRegister, dest);
+ }
+
+ void xorPtr(RegisterID src, RegisterID dest)
+ {
+ m_assembler.xorq_rr(src, dest);
+ }
+
+ void xorPtr(Imm32 imm, RegisterID srcDest)
+ {
+ m_assembler.xorq_ir(imm.m_value, srcDest);
+ }
+
+
+ void loadPtr(ImplicitAddress address, RegisterID dest)
+ {
+ m_assembler.movq_mr(address.offset, address.base, dest);
+ }
+
+ void loadPtr(BaseIndex address, RegisterID dest)
+ {
+ m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
+ }
+
+ void loadPtr(void* address, RegisterID dest)
+ {
+ if (dest == X86::eax)
+ m_assembler.movq_mEAX(address);
+ else {
+ move(X86::eax, dest);
+ m_assembler.movq_mEAX(address);
+ swap(X86::eax, dest);
+ }
+ }
+
+ DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
+ {
+ m_assembler.movq_mr_disp32(address.offset, address.base, dest);
+ return DataLabel32(this);
+ }
+
+ void storePtr(RegisterID src, ImplicitAddress address)
+ {
+ m_assembler.movq_rm(src, address.offset, address.base);
+ }
+
+ void storePtr(RegisterID src, BaseIndex address)
+ {
+ m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale);
+ }
+
+ void storePtr(ImmPtr imm, ImplicitAddress address)
+ {
+ intptr_t ptr = imm.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(ptr))
+ m_assembler.movq_i32m(static_cast<int>(ptr), address.offset, address.base);
+ else {
+ move(imm, scratchRegister);
+ storePtr(scratchRegister, address);
+ }
+ }
+
+ DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
+ {
+ m_assembler.movq_rm_disp32(src, address.offset, address.base);
+ return DataLabel32(this);
+ }
+
+ void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+ {
+ if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+ m_assembler.testq_rr(left, left);
+ else
+ m_assembler.cmpq_ir(right.m_value, left);
+ m_assembler.setCC_r(cond, dest);
+ m_assembler.movzbl_rr(dest, dest);
+ }
+
+ Jump branchPtr(Condition cond, RegisterID left, RegisterID right)
+ {
+ m_assembler.cmpq_rr(right, left);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
+ {
+ intptr_t imm = right.asIntptr();
+ if (CAN_SIGN_EXTEND_32_64(imm)) {
+ if (!imm)
+ m_assembler.testq_rr(left, left);
+ else
+ m_assembler.cmpq_ir(imm, left);
+ return Jump(m_assembler.jCC(cond));
+ } else {
+ move(right, scratchRegister);
+ return branchPtr(cond, left, scratchRegister);
+ }
+ }
+
+ Jump branchPtr(Condition cond, RegisterID left, Address right)
+ {
+ m_assembler.cmpq_mr(right.offset, right.base, left);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
+ {
+ move(ImmPtr(left.m_ptr), scratchRegister);
+ return branchPtr(cond, Address(scratchRegister), right);
+ }
+
+ Jump branchPtr(Condition cond, Address left, RegisterID right)
+ {
+ m_assembler.cmpq_rm(right, left.offset, left.base);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchPtr(Condition cond, Address left, ImmPtr right)
+ {
+ move(right, scratchRegister);
+ return branchPtr(cond, left, scratchRegister);
+ }
+
+ Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
+ {
+ m_assembler.testq_rr(reg, mask);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+ {
+ // if we are only interested in the low seven bits, this can be tested with a testb
+ if (mask.m_value == -1)
+ m_assembler.testq_rr(reg, reg);
+ else if ((mask.m_value & ~0x7f) == 0)
+ m_assembler.testb_i8r(mask.m_value, reg);
+ else
+ m_assembler.testq_i32r(mask.m_value, reg);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpq_im(0, address.offset, address.base);
+ else
+ m_assembler.testq_i32m(mask.m_value, address.offset, address.base);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+ {
+ if (mask.m_value == -1)
+ m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
+ else
+ m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+
+ Jump branchAddPtr(Condition cond, RegisterID src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ addPtr(src, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+ subPtr(imm, dest);
+ return Jump(m_assembler.jCC(cond));
+ }
+
+ DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+ {
+ m_assembler.movq_i64r(initialValue.asIntptr(), dest);
+ return DataLabelPtr(this);
+ }
+
+ Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ {
+ dataLabel = moveWithPatch(initialRightValue, scratchRegister);
+ return branchPtr(cond, left, scratchRegister);
+ }
+
+ Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+ {
+ dataLabel = moveWithPatch(initialRightValue, scratchRegister);
+ return branchPtr(cond, left, scratchRegister);
+ }
+
+ DataLabelPtr storePtrWithPatch(Address address)
+ {
+ DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+ storePtr(scratchRegister, address);
+ return label;
+ }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerX86_64_h
diff --git a/JavaScriptCore/assembler/X86Assembler.h b/JavaScriptCore/assembler/X86Assembler.h
index de23e45..bcafda1 100644
--- a/JavaScriptCore/assembler/X86Assembler.h
+++ b/JavaScriptCore/assembler/X86Assembler.h
@@ -41,6 +41,8 @@ inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(sign
#if PLATFORM(X86_64)
inline bool CAN_SIGN_EXTEND_32_64(intptr_t value) { return value == (intptr_t)(int32_t)value; }
inline bool CAN_SIGN_EXTEND_U32_64(intptr_t value) { return value == (intptr_t)(uint32_t)value; }
+
+#define REPTACH_OFFSET_CALL_R11 3
#endif
namespace X86 {
@@ -84,6 +86,29 @@ public:
typedef X86::XMMRegisterID XMMRegisterID;
typedef enum {
+ ConditionO,
+ ConditionNO,
+ ConditionB,
+ ConditionAE,
+ ConditionE,
+ ConditionNE,
+ ConditionBE,
+ ConditionA,
+ ConditionS,
+ ConditionNS,
+ ConditionP,
+ ConditionNP,
+ ConditionL,
+ ConditionGE,
+ ConditionLE,
+ ConditionG,
+
+ ConditionC = ConditionB,
+ ConditionNC = ConditionAE,
+ } Condition;
+
+private:
+ typedef enum {
OP_ADD_EvGv = 0x01,
OP_ADD_GvEv = 0x03,
OP_OR_EvGv = 0x09,
@@ -147,27 +172,24 @@ public:
OP2_SUBSD_VsdWsd = 0x5C,
OP2_MOVD_VdEd = 0x6E,
OP2_MOVD_EdVd = 0x7E,
- OP2_JO_rel32 = 0x80,
- OP2_JB_rel32 = 0x82,
- OP2_JAE_rel32 = 0x83,
- OP2_JE_rel32 = 0x84,
- OP2_JNE_rel32 = 0x85,
- OP2_JBE_rel32 = 0x86,
- OP2_JA_rel32 = 0x87,
- OP2_JS_rel32 = 0x88,
- OP2_JP_rel32 = 0x8A,
- OP2_JL_rel32 = 0x8C,
- OP2_JGE_rel32 = 0x8D,
- OP2_JLE_rel32 = 0x8E,
- OP2_JG_rel32 = 0x8F,
- OP_SETE = 0x94,
- OP_SETNE = 0x95,
+ OP2_JCC_rel32 = 0x80,
+ OP_SETCC = 0x90,
OP2_IMUL_GvEv = 0xAF,
OP2_MOVZX_GvEb = 0xB6,
OP2_MOVZX_GvEw = 0xB7,
OP2_PEXTRW_GdUdIb = 0xC5,
} TwoByteOpcodeID;
+ TwoByteOpcodeID jccRel32(Condition cond)
+ {
+ return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
+ }
+
+ TwoByteOpcodeID setccOpcode(Condition cond)
+ {
+ return (TwoByteOpcodeID)(OP_SETCC + cond);
+ }
+
typedef enum {
GROUP1_OP_ADD = 0,
GROUP1_OP_OR = 1,
@@ -192,9 +214,6 @@ public:
GROUP11_MOV = 0,
} GroupOpcodeID;
- // Opaque label types
-
-private:
class X86InstructionFormatter;
public:
@@ -222,16 +241,22 @@ public:
public:
JmpDst()
: m_offset(-1)
+ , m_used(false)
{
}
+ bool isUsed() const { return m_used; }
+ void used() { m_used = true; }
private:
JmpDst(int offset)
: m_offset(offset)
+ , m_used(false)
{
+ ASSERT(m_offset == offset);
}
- int m_offset;
+ int m_offset : 31;
+ bool m_used : 1;
};
X86Assembler()
@@ -640,6 +665,11 @@ public:
m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
}
+ void cmpq_mr(int offset, RegisterID base, RegisterID src)
+ {
+ m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
+ }
+
void cmpq_ir(int imm, RegisterID dst)
{
if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -750,9 +780,14 @@ public:
m_formatter.immediate8(imm);
}
+ void setCC_r(Condition cond, RegisterID dst)
+ {
+ m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
+ }
+
void sete_r(RegisterID dst)
{
- m_formatter.twoByteOp8(OP_SETE, (GroupOpcodeID)0, dst);
+ m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
}
void setz_r(RegisterID dst)
@@ -762,7 +797,7 @@ public:
void setne_r(RegisterID dst)
{
- m_formatter.twoByteOp8(OP_SETNE, (GroupOpcodeID)0, dst);
+ m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
}
void setnz_r(RegisterID dst)
@@ -898,6 +933,12 @@ public:
m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
}
+ void movq_i32m(int imm, int offset, RegisterID base)
+ {
+ m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
+ m_formatter.immediate32(imm);
+ }
+
void movq_i64r(int64_t imm, RegisterID dst)
{
m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
@@ -969,9 +1010,13 @@ public:
return m_formatter.immediateRel32();
}
- void jmp_r(RegisterID dst)
+ // Return a JmpSrc so we have a label to the jump, so we can use this
+ // To make a tail recursive call on x86-64. The MacroAssembler
+ // really shouldn't wrap this as a Jump, since it can't be linked. :-/
+ JmpSrc jmp_r(RegisterID dst)
{
m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
+ return JmpSrc(m_formatter.size());
}
void jmp_m(int offset, RegisterID base)
@@ -981,7 +1026,7 @@ public:
JmpSrc jne()
{
- m_formatter.twoByteOp(OP2_JNE_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionNE));
return m_formatter.immediateRel32();
}
@@ -992,73 +1037,79 @@ public:
JmpSrc je()
{
- m_formatter.twoByteOp(OP2_JE_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionE));
return m_formatter.immediateRel32();
}
JmpSrc jl()
{
- m_formatter.twoByteOp(OP2_JL_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionL));
return m_formatter.immediateRel32();
}
JmpSrc jb()
{
- m_formatter.twoByteOp(OP2_JB_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionB));
return m_formatter.immediateRel32();
}
JmpSrc jle()
{
- m_formatter.twoByteOp(OP2_JLE_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionLE));
return m_formatter.immediateRel32();
}
JmpSrc jbe()
{
- m_formatter.twoByteOp(OP2_JBE_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionBE));
return m_formatter.immediateRel32();
}
JmpSrc jge()
{
- m_formatter.twoByteOp(OP2_JGE_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionGE));
return m_formatter.immediateRel32();
}
JmpSrc jg()
{
- m_formatter.twoByteOp(OP2_JG_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionG));
return m_formatter.immediateRel32();
}
JmpSrc ja()
{
- m_formatter.twoByteOp(OP2_JA_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionA));
return m_formatter.immediateRel32();
}
JmpSrc jae()
{
- m_formatter.twoByteOp(OP2_JAE_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionAE));
return m_formatter.immediateRel32();
}
JmpSrc jo()
{
- m_formatter.twoByteOp(OP2_JO_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionO));
return m_formatter.immediateRel32();
}
JmpSrc jp()
{
- m_formatter.twoByteOp(OP2_JP_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionP));
return m_formatter.immediateRel32();
}
JmpSrc js()
{
- m_formatter.twoByteOp(OP2_JS_rel32);
+ m_formatter.twoByteOp(jccRel32(ConditionS));
+ return m_formatter.immediateRel32();
+ }
+
+ JmpSrc jCC(Condition cond)
+ {
+ m_formatter.twoByteOp(jccRel32(cond));
return m_formatter.immediateRel32();
}
@@ -1191,7 +1242,7 @@ public:
// Linking & patching:
- void link(JmpSrc from, JmpDst to)
+ void linkJump(JmpSrc from, JmpDst to)
{
ASSERT(to.m_offset != -1);
ASSERT(from.m_offset != -1);
@@ -1199,20 +1250,73 @@ public:
reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
}
- static void patchAddress(void* code, JmpDst position, void* value)
+ static void linkJump(void* code, JmpSrc from, void* to)
{
- ASSERT(position.m_offset != -1);
+ ASSERT(from.m_offset != -1);
+ ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
+ ASSERT(linkOffset == static_cast<int>(linkOffset));
+ reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset;
+ }
+
+ static void patchJump(intptr_t where, void* destination)
+ {
+ intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
+ ASSERT(offset == static_cast<int32_t>(offset));
+ reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
+ }
+
+#if PLATFORM(X86_64)
+ // FIXME: transition these functions out of here - the assembler
+ // shouldn't know that that this is mov/call pair using r11. :-/
+ static void patchMacroAssemblerCall(intptr_t where, void* destination)
+ {
+ patchAddress(reinterpret_cast<void*>(where - REPTACH_OFFSET_CALL_R11), JmpDst(0), destination);
+ }
+#else
+ static void patchMacroAssemblerCall(intptr_t where, void* destination)
+ {
+ intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
+ ASSERT(offset == static_cast<int32_t>(offset));
+ reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
+ }
+#endif
+
+ void linkCall(JmpSrc from, JmpDst to)
+ {
+ ASSERT(to.m_offset != -1);
+ ASSERT(from.m_offset != -1);
- reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value;
+ reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
}
- static void link(void* code, JmpSrc from, void* to)
+ static void linkCall(void* code, JmpSrc from, void* to)
{
ASSERT(from.m_offset != -1);
+ ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
+ ASSERT(linkOffset == static_cast<int>(linkOffset));
+ reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset;
+ }
+
+ static void patchCall(intptr_t where, void* destination)
+ {
+ intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
+ ASSERT(offset == static_cast<int32_t>(offset));
+ reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
+ }
+
+ static void patchAddress(void* code, JmpDst position, void* value)
+ {
+ ASSERT(position.m_offset != -1);
- reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
+ reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value;
}
+ static unsigned getCallReturnOffset(JmpSrc call)
+ {
+ ASSERT(call.m_offset >= 0);
+ return call.m_offset;
+ }
+
static void* getRelocatedAddress(void* code, JmpSrc jump)
{
return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
@@ -1250,13 +1354,6 @@ public:
reinterpret_cast<intptr_t*>(where)[-1] = value;
}
- static void patchBranchOffset(intptr_t where, void* destination)
- {
- intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
- ASSERT(offset == static_cast<int32_t>(offset));
- reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
- }
-
void* executableCopy(ExecutablePool* allocator)
{
void* copy = m_formatter.executableCopy(allocator);
@@ -1601,13 +1698,8 @@ private:
{
ASSERT(mode != ModRmRegister);
- // Encode sacle of (1,2,4,8) -> (0,1,2,3)
- int shift = 0;
- while (scale >>= 1)
- shift++;
-
putModRm(mode, reg, hasSib);
- m_buffer.putByteUnchecked((shift << 6) | ((index & 7) << 3) | (base & 7));
+ m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
}
void registerModRM(int reg, RegisterID rm)
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h
index e5d78d3..9bd4090 100644
--- a/JavaScriptCore/bytecode/CodeBlock.h
+++ b/JavaScriptCore/bytecode/CodeBlock.h
@@ -32,6 +32,7 @@
#include "EvalCodeCache.h"
#include "Instruction.h"
+#include "JITCode.h"
#include "JSGlobalObject.h"
#include "JumpTable.h"
#include "Nodes.h"
@@ -58,14 +59,14 @@ namespace JSC {
uint32_t target;
uint32_t scopeDepth;
#if ENABLE(JIT)
- void* nativeCode;
+ MacroAssembler::CodeLocationLabel nativeCode;
#endif
};
#if ENABLE(JIT)
// The code, and the associated pool from which it was allocated.
struct JITCodeRef {
- void* code;
+ JITCode code;
#ifndef NDEBUG
unsigned codeSize;
#endif
@@ -117,19 +118,15 @@ namespace JSC {
#if ENABLE(JIT)
struct CallLinkInfo {
CallLinkInfo()
- : callReturnLocation(0)
- , hotPathBegin(0)
- , hotPathOther(0)
- , coldPathOther(0)
- , callee(0)
+ : callee(0)
{
}
unsigned bytecodeIndex;
- void* callReturnLocation;
- void* hotPathBegin;
- void* hotPathOther;
- void* coldPathOther;
+ MacroAssembler::CodeLocationNearCall callReturnLocation;
+ MacroAssembler::CodeLocationDataLabelPtr hotPathBegin;
+ MacroAssembler::CodeLocationNearCall hotPathOther;
+ MacroAssembler::CodeLocationLabel coldPathOther;
CodeBlock* callee;
unsigned position;
@@ -161,14 +158,18 @@ namespace JSC {
unsigned bytecodeOffset;
};
- struct PC {
- PC(ptrdiff_t nativePCOffset, unsigned bytecodeIndex)
- : nativePCOffset(nativePCOffset)
+ // This structure is used to map from a call return location
+ // (given as an offset in bytes into the JIT code) back to
+ // the bytecode index of the corresponding bytecode operation.
+ // This is then used to look up the corresponding handler.
+ struct CallReturnOffsetToBytecodeIndex {
+ CallReturnOffsetToBytecodeIndex(unsigned callReturnOffset, unsigned bytecodeIndex)
+ : callReturnOffset(callReturnOffset)
, bytecodeIndex(bytecodeIndex)
{
}
- ptrdiff_t nativePCOffset;
+ unsigned callReturnOffset;
unsigned bytecodeIndex;
};
@@ -176,17 +177,17 @@ namespace JSC {
inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
{
- return structureStubInfo->callReturnLocation;
+ return structureStubInfo->callReturnLocation.calleeReturnAddressValue();
}
inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
{
- return callLinkInfo->callReturnLocation;
+ return callLinkInfo->callReturnLocation.calleeReturnAddressValue();
}
- inline ptrdiff_t getNativePCOffset(PC* pc)
+ inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeIndex* pc)
{
- return pc->nativePCOffset;
+ return pc->callReturnOffset;
}
// Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
@@ -311,8 +312,7 @@ namespace JSC {
unsigned getBytecodeIndex(CallFrame* callFrame, void* nativePC)
{
reparseForExceptionInfoIfNecessary(callFrame);
- ptrdiff_t nativePCOffset = reinterpret_cast<void**>(nativePC) - reinterpret_cast<void**>(m_jitCode.code);
- return binaryChop<PC, ptrdiff_t, getNativePCOffset>(m_exceptionInfo->m_pcVector.begin(), m_exceptionInfo->m_pcVector.size(), nativePCOffset)->bytecodeIndex;
+ return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), m_jitCode.code.offsetOf(nativePC))->bytecodeIndex;
}
bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
@@ -328,7 +328,7 @@ namespace JSC {
#if ENABLE(JIT)
void setJITCode(JITCodeRef& jitCode);
- void* jitCode() { return m_jitCode.code; }
+ JITCode jitCode() { return m_jitCode.code; }
ExecutablePool* executablePool() { return m_jitCode.executablePool.get(); }
#endif
@@ -393,7 +393,7 @@ namespace JSC {
LineInfo& lastLineInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.last(); }
#if ENABLE(JIT)
- Vector<PC>& pcVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_pcVector; }
+ Vector<CallReturnOffsetToBytecodeIndex>& callReturnIndexVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_callReturnIndexVector; }
#endif
// Constant Pool
@@ -514,7 +514,7 @@ namespace JSC {
Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
#if ENABLE(JIT)
- Vector<PC> m_pcVector;
+ Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector;
#endif
};
OwnPtr<ExceptionInfo> m_exceptionInfo;
diff --git a/JavaScriptCore/bytecode/Instruction.h b/JavaScriptCore/bytecode/Instruction.h
index 1fab106..314fda4 100644
--- a/JavaScriptCore/bytecode/Instruction.h
+++ b/JavaScriptCore/bytecode/Instruction.h
@@ -29,6 +29,7 @@
#ifndef Instruction_h
#define Instruction_h
+#include "MacroAssembler.h"
#include "Opcode.h"
#include "Structure.h"
#include <wtf/VectorTraits.h>
@@ -37,6 +38,16 @@
namespace JSC {
+ // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type MacroAssembler::CodeLocationLabel),
+ // If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't
+ // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best
+ // solution for now - will need to something smarter if/when we actually want mixed-mode operation.
+#if ENABLE(JIT)
+ typedef MacroAssembler::CodeLocationLabel PolymorphicAccessStructureListStubRoutineType;
+#else
+ typedef void* PolymorphicAccessStructureListStubRoutineType;
+#endif
+
class JSCell;
class Structure;
class StructureChain;
@@ -45,14 +56,14 @@ namespace JSC {
struct PolymorphicAccessStructureList {
struct PolymorphicStubInfo {
bool isChain;
- void* stubRoutine;
+ PolymorphicAccessStructureListStubRoutineType stubRoutine;
Structure* base;
union {
Structure* proto;
StructureChain* chain;
} u;
- void set(void* _stubRoutine, Structure* _base)
+ void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base)
{
stubRoutine = _stubRoutine;
base = _base;
@@ -60,7 +71,7 @@ namespace JSC {
isChain = false;
}
- void set(void* _stubRoutine, Structure* _base, Structure* _proto)
+ void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto)
{
stubRoutine = _stubRoutine;
base = _base;
@@ -68,7 +79,7 @@ namespace JSC {
isChain = false;
}
- void set(void* _stubRoutine, Structure* _base, StructureChain* _chain)
+ void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
{
stubRoutine = _stubRoutine;
base = _base;
@@ -77,17 +88,17 @@ namespace JSC {
}
} list[POLYMORPHIC_LIST_CACHE_SIZE];
- PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase)
+ PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase)
{
list[0].set(stubRoutine, firstBase);
}
- PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, Structure* firstProto)
+ PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto)
{
list[0].set(stubRoutine, firstBase, firstProto);
}
- PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, StructureChain* firstChain)
+ PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
{
list[0].set(stubRoutine, firstBase, firstChain);
}
diff --git a/JavaScriptCore/bytecode/JumpTable.h b/JavaScriptCore/bytecode/JumpTable.h
index 44e224d..eee773c 100644
--- a/JavaScriptCore/bytecode/JumpTable.h
+++ b/JavaScriptCore/bytecode/JumpTable.h
@@ -30,6 +30,7 @@
#ifndef JumpTable_h
#define JumpTable_h
+#include "MacroAssembler.h"
#include "UString.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
@@ -39,7 +40,7 @@ namespace JSC {
struct OffsetLocation {
int32_t branchOffset;
#if ENABLE(JIT)
- void* ctiOffset;
+ MacroAssembler::CodeLocationLabel ctiOffset;
#endif
};
@@ -47,7 +48,7 @@ namespace JSC {
typedef HashMap<RefPtr<UString::Rep>, OffsetLocation> StringOffsetTable;
StringOffsetTable offsetTable;
#if ENABLE(JIT)
- void* ctiDefault; // FIXME: it should not be necessary to store this.
+ MacroAssembler::CodeLocationLabel ctiDefault; // FIXME: it should not be necessary to store this.
#endif
inline int32_t offsetForValue(UString::Rep* value, int32_t defaultOffset)
@@ -60,7 +61,7 @@ namespace JSC {
}
#if ENABLE(JIT)
- inline void* ctiForValue(UString::Rep* value)
+ inline MacroAssembler::CodeLocationLabel ctiForValue(UString::Rep* value)
{
StringOffsetTable::const_iterator end = offsetTable.end();
StringOffsetTable::const_iterator loc = offsetTable.find(value);
@@ -76,8 +77,8 @@ namespace JSC {
Vector<int32_t> branchOffsets;
int32_t min;
#if ENABLE(JIT)
- Vector<void*> ctiOffsets;
- void* ctiDefault;
+ Vector<MacroAssembler::CodeLocationLabel> ctiOffsets;
+ MacroAssembler::CodeLocationLabel ctiDefault;
#endif
int32_t offsetForValue(int32_t value, int32_t defaultOffset);
@@ -88,7 +89,7 @@ namespace JSC {
}
#if ENABLE(JIT)
- inline void* ctiForValue(int32_t value)
+ inline MacroAssembler::CodeLocationLabel ctiForValue(int32_t value)
{
if (value >= min && static_cast<uint32_t>(value - min) < ctiOffsets.size())
return ctiOffsets[value - min];
diff --git a/JavaScriptCore/bytecode/StructureStubInfo.h b/JavaScriptCore/bytecode/StructureStubInfo.h
index a9e0678..24fcb7d 100644
--- a/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -26,19 +26,18 @@
#ifndef StructureStubInfo_h
#define StructureStubInfo_h
+#if ENABLE(JIT)
+
#include "Instruction.h"
+#include "MacroAssembler.h"
#include "Opcode.h"
#include "Structure.h"
namespace JSC {
-#if ENABLE(JIT)
struct StructureStubInfo {
StructureStubInfo(OpcodeID opcodeID)
: opcodeID(opcodeID)
- , stubRoutine(0)
- , callReturnLocation(0)
- , hotPathBegin(0)
{
}
@@ -145,12 +144,13 @@ namespace JSC {
} putByIdReplace;
} u;
- void* stubRoutine;
- void* callReturnLocation;
- void* hotPathBegin;
+ MacroAssembler::CodeLocationLabel stubRoutine;
+ MacroAssembler::CodeLocationCall callReturnLocation;
+ MacroAssembler::CodeLocationLabel hotPathBegin;
};
-#endif
} // namespace JSC
+#endif
+
#endif // StructureStubInfo_h
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index cd89c1e..c83cdc7 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -1611,7 +1611,7 @@ RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID*
RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
{
#if ENABLE(JIT)
- HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, 0 };
+ HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, MacroAssembler::CodeLocationLabel() };
#else
HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
#endif
@@ -1744,9 +1744,6 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t
UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
OffsetLocation location;
location.branchOffset = labels[i]->offsetFrom(switchAddress);
-#if ENABLE(JIT)
- location.ctiOffset = 0;
-#endif
jumpTable.offsetTable.add(clause, location);
}
}
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index ceb5881..a6f245d 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -317,6 +317,7 @@ namespace JSC {
void emitDebugHook(DebugHookID, int firstLine, int lastLine);
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
+ bool hasFinaliser() { return m_finallyDepth != 0; }
void pushFinallyContext(Label* target, RegisterID* returnAddrDst);
void popFinallyContext();
@@ -432,16 +433,18 @@ namespace JSC {
ScopeNode* m_scopeNode;
CodeBlock* m_codeBlock;
+ // Some of these objects keep pointers to one another. They are arranged
+ // to ensure a sane destruction order that avoids references to freed memory.
HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions;
RegisterID m_ignoredResultRegister;
RegisterID m_thisRegister;
RegisterID m_argumentsRegister;
int m_activationRegisterIndex;
- SegmentedVector<RegisterID, 512> m_calleeRegisters;
- SegmentedVector<RegisterID, 512> m_parameters;
- SegmentedVector<RegisterID, 512> m_globals;
- SegmentedVector<LabelScope, 256> m_labelScopes;
- SegmentedVector<Label, 256> m_labels;
+ SegmentedVector<RegisterID, 32> m_calleeRegisters;
+ SegmentedVector<RegisterID, 32> m_parameters;
+ SegmentedVector<RegisterID, 32> m_globals;
+ SegmentedVector<Label, 32> m_labels;
+ SegmentedVector<LabelScope, 8> m_labelScopes;
RefPtr<RegisterID> m_lastConstant;
int m_finallyDepth;
int m_dynamicScopeDepth;
@@ -472,7 +475,7 @@ namespace JSC {
bool m_regeneratingForExceptionInfo;
CodeBlock* m_codeBlockBeingRegeneratedFrom;
- static const unsigned s_maxEmitNodeDepth = 10000;
+ static const unsigned s_maxEmitNodeDepth = 5000;
};
}
diff --git a/JavaScriptCore/interpreter/CallFrame.h b/JavaScriptCore/interpreter/CallFrame.h
index d6b9b79..10d0b99 100644
--- a/JavaScriptCore/interpreter/CallFrame.h
+++ b/JavaScriptCore/interpreter/CallFrame.h
@@ -97,6 +97,7 @@ namespace JSC {
friend class JSActivation;
friend class JSGlobalObject;
friend class Interpreter;
+ friend class JITStubs;
static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
Register* registers() { return this; }
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index 135c42f..8178d15 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -66,29 +66,10 @@
#include "AssemblerBuffer.h"
#endif
-#if PLATFORM(DARWIN)
-#include <mach/mach.h>
-#endif
-
-#if HAVE(SYS_TIME_H)
-#include <sys/time.h>
-#endif
-
-#if PLATFORM(WIN_OS)
-#include <windows.h>
-#endif
-
-#if PLATFORM(QT)
-#include <QDateTime>
-#endif
-
using namespace std;
namespace JSC {
-// Preferred number of milliseconds between each timeout check
-static const int preferredScriptCheckTimeInterval = 1000;
-
static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, void* pc)
{
#if ENABLE(JIT)
@@ -107,162 +88,6 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
return sc.localDepth();
}
-static inline bool jsLess(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
- if (JSValuePtr::areBothInt32Fast(v1, v2))
- return v1.getInt32Fast() < v2.getInt32Fast();
-
- double n1;
- double n2;
- if (v1.getNumber(n1) && v2.getNumber(n2))
- return n1 < n2;
-
- Interpreter* interpreter = callFrame->interpreter();
- if (interpreter->isJSString(v1) && interpreter->isJSString(v2))
- return asString(v1)->value() < asString(v2)->value();
-
- JSValuePtr p1;
- JSValuePtr p2;
- bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
- bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
-
- if (wasNotString1 | wasNotString2)
- return n1 < n2;
-
- return asString(p1)->value() < asString(p2)->value();
-}
-
-static inline bool jsLessEq(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
- if (JSValuePtr::areBothInt32Fast(v1, v2))
- return v1.getInt32Fast() <= v2.getInt32Fast();
-
- double n1;
- double n2;
- if (v1.getNumber(n1) && v2.getNumber(n2))
- return n1 <= n2;
-
- Interpreter* interpreter = callFrame->interpreter();
- if (interpreter->isJSString(v1) && interpreter->isJSString(v2))
- return !(asString(v2)->value() < asString(v1)->value());
-
- JSValuePtr p1;
- JSValuePtr p2;
- bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
- bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
-
- if (wasNotString1 | wasNotString2)
- return n1 <= n2;
-
- return !(asString(p2)->value() < asString(p1)->value());
-}
-
-static NEVER_INLINE JSValuePtr jsAddSlowCase(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
- // exception for the Date exception in defaultValue()
- JSValuePtr p1 = v1.toPrimitive(callFrame);
- JSValuePtr p2 = v2.toPrimitive(callFrame);
-
- if (p1.isString() || p2.isString()) {
- RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
- }
-
- return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
-}
-
-// Fast-path choices here are based on frequency data from SunSpider:
-// <times> Add case: <t1> <t2>
-// ---------------------------
-// 5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
-// 247412 Add case: 5 5
-// 20900 Add case: 5 6
-// 13962 Add case: 5 3
-// 4000 Add case: 3 5
-
-static ALWAYS_INLINE JSValuePtr jsAdd(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
- double left;
- double right = 0.0;
-
- bool rightIsNumber = v2.getNumber(right);
- if (rightIsNumber && v1.getNumber(left))
- return jsNumber(callFrame, left + right);
-
- bool leftIsString = v1.isString();
- if (leftIsString && v2.isString()) {
- RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
- }
-
- if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = v2.isInt32Fast() ?
- concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
- concatenate(asString(v1)->value().rep(), right);
-
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
- }
-
- // All other cases are pretty uncommon
- return jsAddSlowCase(callFrame, v1, v2);
-}
-
-static JSValuePtr jsTypeStringForValue(CallFrame* callFrame, JSValuePtr v)
-{
- if (v.isUndefined())
- return jsNontrivialString(callFrame, "undefined");
- if (v.isBoolean())
- return jsNontrivialString(callFrame, "boolean");
- if (v.isNumber())
- return jsNontrivialString(callFrame, "number");
- if (v.isString())
- return jsNontrivialString(callFrame, "string");
- if (v.isObject()) {
- // Return "undefined" for objects that should be treated
- // as null when doing comparisons.
- if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
- return jsNontrivialString(callFrame, "undefined");
- CallData callData;
- if (asObject(v)->getCallData(callData) != CallTypeNone)
- return jsNontrivialString(callFrame, "function");
- }
- return jsNontrivialString(callFrame, "object");
-}
-
-static bool jsIsObjectType(JSValuePtr v)
-{
- if (!v.isCell())
- return v.isNull();
-
- JSType type = asCell(v)->structure()->typeInfo().type();
- if (type == NumberType || type == StringType)
- return false;
- if (type == ObjectType) {
- if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
- return false;
- CallData callData;
- if (asObject(v)->getCallData(callData) != CallTypeNone)
- return false;
- }
- return true;
-}
-
-static bool jsIsFunctionType(JSValuePtr v)
-{
- if (v.isObject()) {
- CallData callData;
- if (asObject(v)->getCallData(callData) != CallTypeNone)
- return true;
- }
- return false;
-}
-
NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
{
int dst = (vPC + 1)->u.operand;
@@ -364,34 +189,11 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
return false;
}
-static ALWAYS_INLINE JSValuePtr inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
-{
- ScopeChainIterator iter = scopeChain->begin();
- ScopeChainIterator next = iter;
- ++next;
- ScopeChainIterator end = scopeChain->end();
- ASSERT(iter != end);
-
- PropertySlot slot;
- JSObject* base;
- while (true) {
- base = *iter;
- if (next == end || base->getPropertySlot(callFrame, property, slot))
- return base;
-
- iter = next;
- ++next;
- }
-
- ASSERT_NOT_REACHED();
- return noValue();
-}
-
NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
{
int dst = (vPC + 1)->u.operand;
int property = (vPC + 2)->u.operand;
- callFrame[dst] = JSValuePtr(inlineResolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
+ callFrame[dst] = JSValuePtr(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
}
NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
@@ -545,56 +347,9 @@ NEVER_INLINE JSValuePtr Interpreter::callEval(CallFrame* callFrame, RegisterFile
Interpreter::Interpreter()
: m_sampler(0)
-#if ENABLE(JIT)
- , m_ctiArrayLengthTrampoline(0)
- , m_ctiStringLengthTrampoline(0)
- , m_ctiVirtualCallPreLink(0)
- , m_ctiVirtualCallLink(0)
- , m_ctiVirtualCall(0)
-#endif
, m_reentryDepth(0)
- , m_timeoutTime(0)
- , m_timeAtLastCheckTimeout(0)
- , m_timeExecuting(0)
- , m_timeoutCheckCount(0)
- , m_ticksUntilNextTimeoutCheck(initialTickCountThreshold)
{
- initTimeout();
privateExecute(InitializeAndReturn, 0, 0, 0);
-
- // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
- void* storage = fastMalloc(sizeof(CollectorBlock));
-
- JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
- m_jsArrayVptr = jsArray->vptr();
- jsArray->~JSCell();
-
- JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
- m_jsByteArrayVptr = jsByteArray->vptr();
- jsByteArray->~JSCell();
-
- JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
- m_jsStringVptr = jsString->vptr();
- jsString->~JSCell();
-
- JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
- m_jsFunctionVptr = jsFunction->vptr();
- jsFunction->~JSCell();
-
- fastFree(storage);
-}
-
-void Interpreter::initialize(JSGlobalData* globalData)
-{
-#if ENABLE(JIT)
- JIT::compileCTIMachineTrampolines(globalData);
-#else
- UNUSED_PARAM(globalData);
-#endif
-}
-
-Interpreter::~Interpreter()
-{
}
#ifndef NDEBUG
@@ -865,7 +620,7 @@ JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame,
#if ENABLE(JIT)
if (!codeBlock->jitCode())
JIT::compile(scopeChain->globalData, codeBlock);
- result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = codeBlock->jitCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -931,7 +686,7 @@ JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* c
#if ENABLE(JIT)
if (!codeBlock->jitCode())
JIT::compile(scopeChain->globalData, codeBlock);
- result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = codeBlock->jitCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -1023,7 +778,7 @@ JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObje
#if ENABLE(JIT)
if (!codeBlock->jitCode())
JIT::compile(scopeChain->globalData, codeBlock);
- result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = codeBlock->jitCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#else
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
#endif
@@ -1065,93 +820,6 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
}
}
-void Interpreter::resetTimeoutCheck()
-{
- m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
- m_timeAtLastCheckTimeout = 0;
- m_timeExecuting = 0;
-}
-
-// Returns the time the current thread has spent executing, in milliseconds.
-static inline unsigned getCPUTime()
-{
-#if PLATFORM(DARWIN)
- mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
- thread_basic_info_data_t info;
-
- // Get thread information
- mach_port_t threadPort = mach_thread_self();
- thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
- mach_port_deallocate(mach_task_self(), threadPort);
-
- unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
- time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
-
- return time;
-#elif HAVE(SYS_TIME_H)
- // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag.
- struct timeval tv;
- gettimeofday(&tv, 0);
- return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#elif PLATFORM(QT)
- QDateTime t = QDateTime::currentDateTime();
- return t.toTime_t() * 1000 + t.time().msec();
-#elif PLATFORM(WIN_OS)
- union {
- FILETIME fileTime;
- unsigned long long fileTimeAsLong;
- } userTime, kernelTime;
-
- // GetThreadTimes won't accept NULL arguments so we pass these even though
- // they're not used.
- FILETIME creationTime, exitTime;
-
- GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
-
- return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
-#else
-#error Platform does not have getCurrentTime function
-#endif
-}
-
-// We have to return a JSValue here, gcc seems to produce worse code if
-// we attempt to return a bool
-ALWAYS_INLINE bool Interpreter::checkTimeout(JSGlobalObject* globalObject)
-{
- unsigned currentTime = getCPUTime();
-
- if (!m_timeAtLastCheckTimeout) {
- // Suspicious amount of looping in a script -- start timing it
- m_timeAtLastCheckTimeout = currentTime;
- return false;
- }
-
- unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
-
- if (timeDiff == 0)
- timeDiff = 1;
-
- m_timeExecuting += timeDiff;
- m_timeAtLastCheckTimeout = currentTime;
-
- // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in
- // preferredScriptCheckTimeInterval
- m_ticksUntilNextTimeoutCheck = static_cast<unsigned>((static_cast<float>(preferredScriptCheckTimeInterval) / timeDiff) * m_ticksUntilNextTimeoutCheck);
- // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
- // preferred script check time interval.
- if (m_ticksUntilNextTimeoutCheck == 0)
- m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
-
- if (m_timeoutTime && m_timeExecuting > m_timeoutTime) {
- if (globalObject->shouldInterruptScript())
- return true;
-
- resetTimeoutCheck();
- }
-
- return false;
-}
-
NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
{
int dst = (++vPC)->u.operand;
@@ -1251,37 +919,6 @@ NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock* codeBlock, Instruction*
vPC[4] = 0;
}
-static size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValuePtr baseValue, const PropertySlot& slot)
-{
- JSCell* cell = asCell(baseValue);
- size_t count = 0;
-
- while (slot.slotBase() != cell) {
- JSValuePtr v = cell->structure()->prototypeForLookup(callFrame);
-
- // If we didn't find slotBase in baseValue's prototype chain, then baseValue
- // must be a proxy for another object.
-
- if (v.isNull())
- return 0;
-
- cell = asCell(v);
-
- // Since we're accessing a prototype in a loop, it's a good bet that it
- // should not be treated as a dictionary.
- if (cell->structure()->isDictionary()) {
- RefPtr<Structure> transition = Structure::fromDictionaryTransition(cell->structure());
- asObject(cell)->setStructure(transition.release());
- cell->structure()->setCachedPrototypeChain(0);
- }
-
- ++count;
- }
-
- ASSERT(count);
- return count;
-}
-
NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
{
// Recursive invocation may already have specialized this instruction.
@@ -1294,12 +931,13 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
return;
}
- if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
+ JSGlobalData* globalData = &callFrame->globalData();
+ if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
vPC[0] = getOpcode(op_get_array_length);
return;
}
- if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
+ if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
vPC[0] = getOpcode(op_get_string_length);
return;
}
@@ -1417,7 +1055,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
Instruction* vPC = callFrame->codeBlock()->instructions().begin();
Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
- unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
+ unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();
#define CHECK_FOR_EXCEPTION() \
do { \
@@ -1433,19 +1071,17 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
#define CHECK_FOR_TIMEOUT() \
if (!--tickCount) { \
- if (checkTimeout(callFrame->dynamicGlobalObject())) { \
+ if (globalData->timeoutChecker.didTimeOut(callFrame)) { \
exceptionValue = jsNull(); \
goto vm_throw; \
} \
- tickCount = m_ticksUntilNextTimeoutCheck; \
+ tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \
}
#if ENABLE(OPCODE_SAMPLING)
#define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
- #define CTI_SAMPLER ARG_globalData->interpreter->sampler()
#else
#define SAMPLE(codeBlock, vPC)
- #define CTI_SAMPLER 0
#endif
#if HAVE(COMPUTED_GOTO)
@@ -2123,7 +1759,12 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
goto vm_throw;
JSObject* baseObj = asObject(baseVal);
- callFrame[dst] = jsBoolean(baseObj->structure()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
+ if (baseObj->structure()->typeInfo().implementsHasInstance()) {
+ bool result = baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame));
+ CHECK_FOR_EXCEPTION();
+ callFrame[dst] = jsBoolean(result);
+ } else
+ callFrame[dst] = jsBoolean(false);
vPC += 5;
NEXT_INSTRUCTION();
@@ -2607,7 +2248,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
int base = vPC[2].u.operand;
JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(isJSArray(baseValue))) {
+ if (LIKELY(isJSArray(globalData, baseValue))) {
int dst = vPC[1].u.operand;
callFrame[dst] = JSValuePtr(jsNumber(callFrame, asArray(baseValue)->length()));
vPC += 8;
@@ -2627,7 +2268,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
int base = vPC[2].u.operand;
JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
- if (LIKELY(isJSString(baseValue))) {
+ if (LIKELY(isJSString(globalData, baseValue))) {
int dst = vPC[1].u.operand;
callFrame[dst] = JSValuePtr(jsNumber(callFrame, asString(baseValue)->value().size()));
vPC += 8;
@@ -2809,15 +2450,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
if (LIKELY(subscript.isUInt32Fast())) {
uint32_t i = subscript.getUInt32Fast();
- if (isJSArray(baseValue)) {
+ if (isJSArray(globalData, baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canGetIndex(i))
result = jsArray->getIndex(i);
else
result = jsArray->JSArray::get(callFrame, i);
- } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
+ } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
- else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
+ else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i))
result = asByteArray(baseValue)->getIndex(callFrame, i);
else
result = baseValue.get(callFrame, i);
@@ -2851,13 +2492,13 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
if (LIKELY(subscript.isUInt32Fast())) {
uint32_t i = subscript.getUInt32Fast();
- if (isJSArray(baseValue)) {
+ if (isJSArray(globalData, baseValue)) {
JSArray* jsArray = asArray(baseValue);
if (jsArray->canSetIndex(i))
jsArray->setIndex(i, callFrame[value].jsValue(callFrame));
else
jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue(callFrame));
- } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
JSByteArray* jsByteArray = asByteArray(baseValue);
double dValue = 0;
JSValuePtr jsValue = callFrame[value].jsValue(callFrame);
@@ -3144,9 +2785,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
if (scrutinee.isInt32Fast())
vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.getInt32Fast(), defaultOffset);
else {
- int32_t value;
- if (scrutinee.numberToInt32(value))
- vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(value, defaultOffset);
+ double value;
+ int32_t intValue;
+ if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value))
+ vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(intValue, defaultOffset);
else
vPC += defaultOffset;
}
@@ -3591,7 +3233,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
the object in register override to register dst.
*/
- int dst = vPC[1].u.operand;;
+ int dst = vPC[1].u.operand;
if (LIKELY(callFrame[dst].jsValue(callFrame).isObject())) {
vPC += 3;
NEXT_INSTRUCTION();
@@ -3711,7 +3353,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
DEFINE_OPCODE(op_catch) {
/* catch ex(r)
- Retrieves the VMs current exception and puts it in register
+ Retrieves the VM's current exception and puts it in register
ex. This is only valid after an exception has been raised,
and usually forms the beginning of an exception handler.
*/
@@ -4004,6 +3646,7 @@ CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, InternalFunc
return 0;
}
+#ifdef MANUAL_MERGE_REQUIRED
#if ENABLE(JIT)
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
@@ -6137,4 +5780,6 @@ JSValueEncodedAsPointer* Interpreter::cti_vm_throw(STUB_ARGS)
#endif // ENABLE(JIT)
+#else // MANUAL_MERGE_REQUIRED
+#endif // MANUAL_MERGE_REQUIRED
} // namespace JSC
diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h
index 18c2185..7d97962 100644
--- a/JavaScriptCore/interpreter/Interpreter.h
+++ b/JavaScriptCore/interpreter/Interpreter.h
@@ -32,6 +32,7 @@
#include "ArgList.h"
#include "JSCell.h"
#include "JSValue.h"
+#include "JSObject.h"
#include "Opcode.h"
#include "RegisterFile.h"
#include <wtf/HashMap.h>
@@ -56,52 +57,6 @@ namespace JSC {
class SamplingTool;
struct HandlerInfo;
-#if ENABLE(JIT)
-
-#if USE(JIT_STUB_ARGUMENT_VA_LIST)
- #define STUB_ARGS void* args, ...
- #define ARGS (reinterpret_cast<void**>(vl_args) - 1)
-#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
- #define STUB_ARGS void** args
- #define ARGS (args)
-#endif
-
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
- #if PLATFORM(X86_64)
- #define JIT_STUB
- #elif COMPILER(MSVC)
- #define JIT_STUB __fastcall
- #elif COMPILER(GCC)
- #define JIT_STUB __attribute__ ((fastcall))
- #else
- #error Need to support register calling convention in this compiler
- #endif
-#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
- #if COMPILER(MSVC)
- #define JIT_STUB __cdecl
- #else
- #define JIT_STUB
- #endif
-#endif
-
-// The Mac compilers are fine with this,
-#if PLATFORM(MAC)
- struct VoidPtrPair {
- void* first;
- void* second;
- };
-#define RETURN_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
-#else
- typedef uint64_t VoidPtrPair;
- union VoidPtrPairValue {
- struct { void* first; void* second; } s;
- VoidPtrPair i;
- };
-#define RETURN_PAIR(a,b) VoidPtrPairValue pair = {{ a, b }}; return pair.i
-#endif
-
-#endif // ENABLE(JIT)
-
enum DebugHookID {
WillExecuteProgram,
DidExecuteProgram,
@@ -111,16 +66,15 @@ namespace JSC {
WillExecuteStatement
};
- enum { MaxReentryDepth = 128 };
+ enum { MaxReentryDepth = 64 };
class Interpreter {
friend class JIT;
+ friend class JITStubs;
+
public:
Interpreter();
- ~Interpreter();
- void initialize(JSGlobalData*);
-
RegisterFile& registerFile() { return m_registerFile; }
Opcode getOpcode(OpcodeID id)
@@ -153,161 +107,9 @@ namespace JSC {
void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const;
void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
- void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
-
- void startTimeoutCheck()
- {
- if (!m_timeoutCheckCount)
- resetTimeoutCheck();
-#ifdef ANDROID_INSTRUMENT
- if (!m_timeoutCheckCount)
- android::TimeCounter::start(android::TimeCounter::JavaScriptTimeCounter);
-#endif
-
- ++m_timeoutCheckCount;
- }
-
- void stopTimeoutCheck()
- {
- ASSERT(m_timeoutCheckCount);
- --m_timeoutCheckCount;
-#ifdef ANDROID_INSTRUMENT
- if (!m_timeoutCheckCount)
- android::TimeCounter::record(android::TimeCounter::JavaScriptTimeCounter, __FUNCTION__);
-#endif
- }
-
- inline void initTimeout()
- {
- ASSERT(!m_timeoutCheckCount);
- resetTimeoutCheck();
- m_timeoutTime = 0;
- m_timeoutCheckCount = 0;
- }
-
void setSampler(SamplingTool* sampler) { m_sampler = sampler; }
SamplingTool* sampler() { return m_sampler; }
-#if ENABLE(JIT)
-
- static int JIT_STUB cti_timeout_check(STUB_ARGS);
- static void JIT_STUB cti_register_file_check(STUB_ARGS);
-
- static JSObject* JIT_STUB cti_op_convert_this(STUB_ARGS);
- static void JIT_STUB cti_op_end(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_add(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_inc(STUB_ARGS);
- static int JIT_STUB cti_op_loop_if_less(STUB_ARGS);
- static int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_object(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id_second(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_second(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_generic(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_id(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_instanceof(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_mul(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_func(STUB_ARGS);
- static void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS);
- static void JIT_STUB cti_op_create_arguments(STUB_ARGS);
- static void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS);
- static void JIT_STUB cti_op_tear_off_activation(STUB_ARGS);
- static void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS);
- static void JIT_STUB cti_op_profile_will_call(STUB_ARGS);
- static void JIT_STUB cti_op_profile_did_call(STUB_ARGS);
- static void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_array(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_global(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_resolve_func(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_sub(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_val(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_val_array(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_lesseq(STUB_ARGS);
- static int JIT_STUB cti_op_loop_if_true(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_base(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_negate(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_skip(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_div(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_dec(STUB_ARGS);
- static int JIT_STUB cti_op_jless(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_not(STUB_ARGS);
- static int JIT_STUB cti_op_jtrue(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_post_inc(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_eq(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_lshift(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitand(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_rshift(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitnot(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_resolve_with_base(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_mod(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_less(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_neq(STUB_ARGS);
- static VoidPtrPair JIT_STUB cti_op_post_dec(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_urshift(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitxor(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_bitor(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_call_eval(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_throw(STUB_ARGS);
- static JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_next_pname(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS);
- static void JIT_STUB cti_op_pop_scope(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_typeof(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_undefined(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_boolean(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_number(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_string(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_object(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_is_function(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_stricteq(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_nstricteq(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_to_jsnumber(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_in(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS);
- static void JIT_STUB cti_op_jmp_scopes(STUB_ARGS);
- static void JIT_STUB cti_op_put_by_index(STUB_ARGS);
- static void* JIT_STUB cti_op_switch_imm(STUB_ARGS);
- static void* JIT_STUB cti_op_switch_char(STUB_ARGS);
- static void* JIT_STUB cti_op_switch_string(STUB_ARGS);
- static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_val(STUB_ARGS);
- static void JIT_STUB cti_op_put_getter(STUB_ARGS);
- static void JIT_STUB cti_op_put_setter(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_new_error(STUB_ARGS);
- static void JIT_STUB cti_op_debug(STUB_ARGS);
-
- static JSValueEncodedAsPointer* JIT_STUB cti_vm_throw(STUB_ARGS);
- static void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS);
- static void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS);
- static JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS);
-
-#endif // ENABLE(JIT)
-
- // Default number of ticks before a timeout check should be done.
- static const int initialTickCountThreshold = 1024;
-
- bool isJSArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsArrayVptr; }
- bool isJSString(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsStringVptr; }
- bool isJSByteArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsByteArrayVptr; }
-
private:
enum ExecutionFlag { Normal, InitializeAndReturn };
@@ -336,9 +138,6 @@ namespace JSC {
void dumpCallFrame(CallFrame*);
void dumpRegisters(CallFrame*);
- bool checkTimeout(JSGlobalObject*);
- void resetTimeoutCheck();
-
void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
void uncacheGetByID(CodeBlock*, Instruction* vPC);
void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const PutPropertySlot&);
@@ -346,38 +145,12 @@ namespace JSC {
bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
-#if ENABLE(JIT)
- static void throwStackOverflowPreviousFrame(CallFrame**, JSGlobalData*, void*& returnAddress);
-
- void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
- void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot&);
-#endif
-
SamplingTool* m_sampler;
-#if ENABLE(JIT)
- RefPtr<ExecutablePool> m_executablePool;
- void* m_ctiArrayLengthTrampoline;
- void* m_ctiStringLengthTrampoline;
- void* m_ctiVirtualCallPreLink;
- void* m_ctiVirtualCallLink;
- void* m_ctiVirtualCall;
-#endif
-
int m_reentryDepth;
- unsigned m_timeoutTime;
- unsigned m_timeAtLastCheckTimeout;
- unsigned m_timeExecuting;
- unsigned m_timeoutCheckCount;
- unsigned m_ticksUntilNextTimeoutCheck;
RegisterFile m_registerFile;
- void* m_jsArrayVptr;
- void* m_jsByteArrayVptr;
- void* m_jsStringVptr;
- void* m_jsFunctionVptr;
-
#if HAVE(COMPUTED_GOTO)
Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
diff --git a/JavaScriptCore/interpreter/Register.h b/JavaScriptCore/interpreter/Register.h
index ff36bbc..5277a0f 100644
--- a/JavaScriptCore/interpreter/Register.h
+++ b/JavaScriptCore/interpreter/Register.h
@@ -60,8 +60,9 @@ namespace JSC {
private:
friend class ExecState;
friend class Interpreter;
+ friend class JITStubs;
- // Only CallFrame and Interpreter should use these functions.
+ // Only CallFrame, Interpreter, and JITStubs should use these functions.
Register(intptr_t);
diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h
index ec190d6..c320f04 100644
--- a/JavaScriptCore/interpreter/RegisterFile.h
+++ b/JavaScriptCore/interpreter/RegisterFile.h
@@ -29,6 +29,7 @@
#ifndef RegisterFile_h
#define RegisterFile_h
+#include "ExecutableAllocator.h"
#include "Register.h"
#include "Collector.h"
#include <wtf/Noncopyable.h>
@@ -111,48 +112,9 @@ namespace JSC {
static const size_t defaultCapacity = 524288;
static const size_t defaultMaxGlobals = 8192;
- static const size_t allocationSize = 1 << 14;
- static const size_t allocationSizeMask = allocationSize - 1;
-
- RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals)
- : m_numGlobals(0)
- , m_maxGlobals(maxGlobals)
- , m_start(0)
- , m_end(0)
- , m_max(0)
- , m_buffer(0)
- , m_globalObject(0)
- {
- size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
-#if HAVE(MMAP)
- m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0));
- if (m_buffer == MAP_FAILED) {
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
- CRASH();
- }
-#elif HAVE(VIRTUALALLOC)
- // Ensure bufferLength is a multiple of allocation size
- bufferLength = (bufferLength + allocationSizeMask) & ~allocationSizeMask;
- m_buffer = static_cast<Register*>(VirtualAlloc(0, bufferLength, MEM_RESERVE, PAGE_READWRITE));
- if (!m_buffer) {
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
- CRASH();
- }
- int initialAllocation = (maxGlobals * sizeof(Register) + allocationSizeMask) & ~allocationSizeMask;
- void* commitCheck = VirtualAlloc(m_buffer, initialAllocation, MEM_COMMIT, PAGE_READWRITE);
- if (commitCheck != m_buffer) {
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
- CRASH();
- }
- m_maxCommitted = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + initialAllocation);
-#else
- #error "Don't know how to reserve virtual memory on this platform."
-#endif
- m_start = m_buffer + maxGlobals;
- m_end = m_start;
- m_max = m_start + capacity;
- }
+ static const size_t commitSize = 1 << 14;
+ RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
~RegisterFile();
Register* start() const { return m_start; }
@@ -162,31 +124,8 @@ namespace JSC {
void setGlobalObject(JSGlobalObject* globalObject) { m_globalObject = globalObject; }
JSGlobalObject* globalObject() { return m_globalObject; }
- void shrink(Register* newEnd)
- {
- if (newEnd < m_end)
- m_end = newEnd;
- }
-
- bool grow(Register* newEnd)
- {
- if (newEnd > m_end) {
- if (newEnd > m_max)
- return false;
-#if !HAVE(MMAP) && HAVE(VIRTUALALLOC)
- if (newEnd > m_maxCommitted) {
- ptrdiff_t additionalAllocation = ((reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_maxCommitted)) + allocationSizeMask) & ~allocationSizeMask;
- if (!VirtualAlloc(m_maxCommitted, additionalAllocation, MEM_COMMIT, PAGE_READWRITE)) {
- fprintf(stderr, "Could not allocate register file: %d\n", errno);
- CRASH();
- }
- m_maxCommitted = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_maxCommitted) + additionalAllocation);
- }
-#endif
- m_end = newEnd;
- }
- return true;
- }
+ bool grow(Register* newEnd);
+ void shrink(Register* newEnd);
void setNumGlobals(size_t numGlobals) { m_numGlobals = numGlobals; }
int numGlobals() const { return m_numGlobals; }
@@ -205,12 +144,78 @@ namespace JSC {
Register* m_max;
Register* m_buffer;
#if HAVE(VIRTUALALLOC)
- Register* m_maxCommitted;
+ Register* m_commitEnd;
#endif
JSGlobalObject* m_globalObject; // The global object whose vars are currently stored in the register file.
};
+ inline RegisterFile::RegisterFile(size_t capacity, size_t maxGlobals)
+ : m_numGlobals(0)
+ , m_maxGlobals(maxGlobals)
+ , m_start(0)
+ , m_end(0)
+ , m_max(0)
+ , m_buffer(0)
+ , m_globalObject(0)
+ {
+ size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
+ #if HAVE(MMAP)
+ m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0));
+ if (m_buffer == MAP_FAILED) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ #elif HAVE(VIRTUALALLOC)
+ m_buffer = static_cast<Register*>(VirtualAlloc(0, roundUpAllocationSize(bufferLength, commitSize), MEM_RESERVE, PAGE_READWRITE));
+ if (!m_buffer) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize);
+ void* commitCheck = VirtualAlloc(m_buffer, committedSize, MEM_COMMIT, PAGE_READWRITE);
+ if (commitCheck != m_buffer) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + committedSize);
+ #else
+ #error "Don't know how to reserve virtual memory on this platform."
+ #endif
+ m_start = m_buffer + maxGlobals;
+ m_end = m_start;
+ m_max = m_start + capacity;
+ }
+
+ inline void RegisterFile::shrink(Register* newEnd)
+ {
+ if (newEnd < m_end)
+ m_end = newEnd;
+ }
+
+ inline bool RegisterFile::grow(Register* newEnd)
+ {
+ if (newEnd < m_end)
+ return true;
+
+ if (newEnd > m_max)
+ return false;
+
+#if !HAVE(MMAP) && HAVE(VIRTUALALLOC)
+ if (newEnd > m_commitEnd) {
+ size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize);
+ if (!VirtualAlloc(m_commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) {
+ fprintf(stderr, "Could not allocate register file: %d\n", errno);
+ CRASH();
+ }
+ m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_commitEnd) + size);
+ }
+#endif
+
+ m_end = newEnd;
+ return true;
+ }
+
} // namespace JSC
#endif // RegisterFile_h
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index 1541256..0cb78ad 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -40,6 +40,18 @@
namespace JSC {
+inline size_t roundUpAllocationSize(size_t request, size_t granularity)
+{
+ if ((std::numeric_limits<size_t>::max() - granularity) <= request)
+ CRASH(); // Allocation is too large
+
+ // Round up to next page boundary
+ size_t size = request + (granularity - 1);
+ size = size & ~(granularity - 1);
+ ASSERT(size >= request);
+ return size;
+}
+
class ExecutablePool : public RefCounted<ExecutablePool> {
private:
struct Allocation {
@@ -86,18 +98,6 @@ private:
static Allocation systemAlloc(size_t n);
static void systemRelease(const Allocation& alloc);
- inline size_t roundUpAllocationSize(size_t request, size_t granularity)
- {
- if ((std::numeric_limits<size_t>::max() - granularity) <= request)
- CRASH(); // Allocation is too large
-
- // Round up to next page boundary
- size_t size = request + (granularity - 1);
- size = size & ~(granularity - 1);
- ASSERT(size >= request);
- return size;
- }
-
ExecutablePool(size_t n);
void* poolAllocate(size_t n);
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index 5640c8a..e6113fc 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -79,14 +79,14 @@ asm(
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if USE(JIT_STUB_ARGUMENT_VA_LIST)
- "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPvz) "\n"
+ "call " SYMBOL_STRING(_ZN3JSC8JITStubs12cti_vm_throwEPvz) "\n"
#else
#if USE(JIT_STUB_ARGUMENT_REGISTER)
"movl %esp, %ecx" "\n"
#else // JIT_STUB_ARGUMENT_STACK
"movl %esp, 0(%esp)" "\n"
#endif
- "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
+ "call " SYMBOL_STRING(_ZN3JSC8JITStubs12cti_vm_throwEPPv) "\n"
#endif
"addl $0x1c, %esp" "\n"
"popl %ebx" "\n"
@@ -138,7 +138,7 @@ asm(
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if USE(JIT_STUB_ARGUMENT_REGISTER)
"movq %rsp, %rdi" "\n"
- "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
+ "call " SYMBOL_STRING(_ZN3JSC8JITStubs12cti_vm_throwEPPv) "\n"
#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
#error "JIT_STUB_ARGUMENT configuration not supported."
#endif
@@ -186,7 +186,7 @@ extern "C" {
#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
#error "JIT_STUB_ARGUMENT configuration not supported."
#endif
- call JSC::Interpreter::cti_vm_throw;
+ call JSC::JITStubs::cti_vm_throw;
add esp, 0x1c;
pop ebx;
pop edi;
@@ -200,14 +200,19 @@ extern "C" {
#endif
-void ctiSetReturnAddress(void** where, void* what)
+void ctiSetReturnAddress(void** addressOfReturnAddress, void* newDestinationToReturnTo)
{
- *where = what;
+ *addressOfReturnAddress = newDestinationToReturnTo;
}
-void ctiPatchCallByReturnAddress(void* where, void* what)
+void ctiPatchCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction)
{
- MacroAssembler::Jump::patch(where, what);
+ returnAddress.relinkCallerToFunction(newCalleeFunction);
+}
+
+void ctiPatchNearCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction)
+{
+ returnAddress.relinkNearCallerToFunction(newCalleeFunction);
}
JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
@@ -228,62 +233,28 @@ void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqTy
unsigned src1 = currentInstruction[2].u.operand;
unsigned src2 = currentInstruction[3].u.operand;
- emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
+ emitGetVirtualRegisters(src1, regT0, src2, regT1);
-#if USE(ALTERNATE_JSIMMEDIATE)
// Jump to a slow case if either operand is a number, or if both are JSCell*s.
- move(X86::eax, X86::ecx);
- orPtr(X86::edx, X86::ecx);
- addSlowCase(emitJumpIfJSCell(X86::ecx));
- addSlowCase(emitJumpIfImmediateNumber(X86::ecx));
+ move(regT0, regT2);
+ orPtr(regT1, regT2);
+ addSlowCase(emitJumpIfJSCell(regT2));
+ addSlowCase(emitJumpIfImmediateNumber(regT2));
if (type == OpStrictEq)
- sete32(X86::edx, X86::eax);
+ set32(Equal, regT1, regT0, regT0);
else
- setne32(X86::edx, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
-#else
- bool negated = (type == OpNStrictEq);
-
- // Check that both are immediates, if so check if they're equal
- Jump firstNotImmediate = emitJumpIfJSCell(X86::eax);
- Jump secondNotImmediate = emitJumpIfJSCell(X86::edx);
- Jump bothWereImmediatesButNotEqual = jnePtr(X86::edx, X86::eax);
-
- // They are equal - set the result to true. (Or false, if negated).
- move(ImmPtr(JSValuePtr::encode(jsBoolean(!negated))), X86::eax);
- Jump bothWereImmediatesAndEqual = jump();
-
- // eax was not an immediate, we haven't yet checked edx.
- // If edx is also a JSCell, or is 0, then jump to a slow case,
- // otherwise these values are not equal.
- firstNotImmediate.link(this);
- emitJumpSlowCaseIfJSCell(X86::edx);
- addSlowCase(jePtr(X86::edx, ImmPtr(JSValuePtr::encode(js0()))));
- Jump firstWasNotImmediate = jump();
-
- // eax was an immediate, but edx wasn't.
- // If eax is 0 jump to a slow case, otherwise these values are not equal.
- secondNotImmediate.link(this);
- addSlowCase(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0()))));
-
- // We get here if the two values are different immediates, or one is 0 and the other is a JSCell.
- // Vaelues are not equal, set the result to false.
- bothWereImmediatesButNotEqual.link(this);
- firstWasNotImmediate.link(this);
- move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), X86::eax);
-
- bothWereImmediatesAndEqual.link(this);
-#endif
+ set32(NotEqual, regT1, regT0, regT0);
+ emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
}
-void JIT::emitSlowScriptCheck()
+void JIT::emitTimeoutCheck()
{
- Jump skipTimeout = jnzSub32(Imm32(1), timeoutCheckRegister);
- emitCTICall(Interpreter::cti_timeout_check);
- move(X86::eax, timeoutCheckRegister);
+ Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);
+ emitCTICall(JITStubs::cti_timeout_check);
+ move(regT0, timeoutCheckRegister);
skipTimeout.link(this);
killLastResultRegister();
@@ -296,21 +267,24 @@ void JIT::emitSlowScriptCheck()
#define CTI_COMPILE_BINARY_OP(name) \
case name: { \
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx); \
- emitCTICall(Interpreter::cti_##name); \
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2); \
+ emitCTICall(JITStubs::cti_##name); \
emitPutVirtualRegister(currentInstruction[1].u.operand); \
NEXT_OPCODE(name); \
}
#define CTI_COMPILE_UNARY_OP(name) \
case name: { \
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
- emitCTICall(Interpreter::cti_##name); \
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \
+ emitCTICall(JITStubs::cti_##name); \
emitPutVirtualRegister(currentInstruction[1].u.operand); \
NEXT_OPCODE(name); \
}
+#define RECORD_JUMP_TARGET(targetOffset) \
+ do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false)
+
void JIT::privateCompileMainPass()
{
Instruction* instructionsBegin = m_codeBlock->instructions().begin();
@@ -328,13 +302,31 @@ void JIT::privateCompileMainPass()
sampleInstruction(currentInstruction);
#endif
+ if (m_labels[m_bytecodeIndex].isUsed())
+ killLastResultRegister();
+
m_labels[m_bytecodeIndex] = label();
OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode);
switch (opcodeID) {
case op_mov: {
- emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
- emitPutVirtualRegister(currentInstruction[1].u.operand);
+ int src = currentInstruction[2].u.operand;
+ int dst = currentInstruction[1].u.operand;
+
+ if (m_codeBlock->isConstantRegisterIndex(src)) {
+ storePtr(ImmPtr(JSValuePtr::encode(getConstantOperand(src))), Address(callFrameRegister, dst * sizeof(Register)));
+ if (dst == m_lastResultBytecodeRegister)
+ killLastResultRegister();
+ } else if ((src == m_lastResultBytecodeRegister) || (dst == m_lastResultBytecodeRegister)) {
+ // If either the src or dst is the cached register go though
+ // get/put registers to make sure we track this correctly.
+ emitGetVirtualRegister(src, regT0);
+ emitPutVirtualRegister(dst);
+ } else {
+ // Perform the copy via regT1; do not disturb any mapping in regT0.
+ loadPtr(Address(callFrameRegister, src * sizeof(Register)), regT1);
+ storePtr(regT1, Address(callFrameRegister, dst * sizeof(Register)));
+ }
NEXT_OPCODE(op_mov);
}
case op_add: {
@@ -343,8 +335,9 @@ void JIT::privateCompileMainPass()
}
case op_end: {
if (m_codeBlock->needsFullScopeChain())
- emitCTICall(Interpreter::cti_op_end);
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitCTICall(JITStubs::cti_op_end);
+ ASSERT(returnValueRegister != callFrameRegister);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
push(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
ret();
NEXT_OPCODE(op_end);
@@ -352,6 +345,7 @@ void JIT::privateCompileMainPass()
case op_jmp: {
unsigned target = currentInstruction[1].u.operand;
addJump(jump(), target + 1);
+ RECORD_JUMP_TARGET(target + 1);
NEXT_OPCODE(op_jmp);
}
case op_pre_inc: {
@@ -359,60 +353,60 @@ void JIT::privateCompileMainPass()
NEXT_OPCODE(op_pre_inc);
}
case op_loop: {
- emitSlowScriptCheck();
+ emitTimeoutCheck();
unsigned target = currentInstruction[1].u.operand;
addJump(jump(), target + 1);
NEXT_OPCODE(op_end);
}
case op_loop_if_less: {
- emitSlowScriptCheck();
+ emitTimeoutCheck();
unsigned op1 = currentInstruction[1].u.operand;
unsigned op2 = currentInstruction[2].u.operand;
unsigned target = currentInstruction[3].u.operand;
if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(op1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
int32_t op2imm = getConstantOperandImmediateInt(op2);
#else
int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
#endif
- addJump(jl32(X86::eax, Imm32(op2imm)), target + 3);
+ addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3);
} else {
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
- addJump(jl32(X86::eax, X86::edx), target + 3);
+ emitGetVirtualRegisters(op1, regT0, op2, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
+ addJump(branch32(LessThan, regT0, regT1), target + 3);
}
NEXT_OPCODE(op_loop_if_less);
}
case op_loop_if_lesseq: {
- emitSlowScriptCheck();
+ emitTimeoutCheck();
unsigned op1 = currentInstruction[1].u.operand;
unsigned op2 = currentInstruction[2].u.operand;
unsigned target = currentInstruction[3].u.operand;
if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(op1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
int32_t op2imm = getConstantOperandImmediateInt(op2);
#else
int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
#endif
- addJump(jle32(X86::eax, Imm32(op2imm)), target + 3);
+ addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3);
} else {
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
- addJump(jle32(X86::eax, X86::edx), target + 3);
+ emitGetVirtualRegisters(op1, regT0, op2, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
+ addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3);
}
NEXT_OPCODE(op_loop_if_less);
}
case op_new_object: {
- emitCTICall(Interpreter::cti_op_new_object);
+ emitCTICall(JITStubs::cti_op_new_object);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_new_object);
}
@@ -425,49 +419,49 @@ void JIT::privateCompileMainPass()
NEXT_OPCODE(op_get_by_id);
}
case op_instanceof: {
- emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax); // value
- emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx); // baseVal
- emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // proto
+ emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); // value
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT2); // baseVal
+ emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); // proto
// check if any are immediates
- move(X86::eax, X86::ebx);
- orPtr(X86::ecx, X86::ebx);
- orPtr(X86::edx, X86::ebx);
- emitJumpSlowCaseIfNotJSCell(X86::ebx);
+ move(regT0, regT3);
+ orPtr(regT2, regT3);
+ orPtr(regT1, regT3);
+ emitJumpSlowCaseIfNotJSCell(regT3);
// check that all are object type - this is a bit of a bithack to avoid excess branching;
// we check that the sum of the three type codes from Structures is exactly 3 * ObjectType,
// this works because NumberType and StringType are smaller
- move(Imm32(3 * ObjectType), X86::ebx);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::eax);
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- loadPtr(Address(X86::edx, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
- sub32(Address(X86::eax, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
- sub32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
- addSlowCase(jne32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx));
+ move(Imm32(3 * ObjectType), regT3);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT0);
+ loadPtr(Address(regT2, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ loadPtr(Address(regT1, FIELD_OFFSET(JSCell, m_structure)), regT1);
+ sub32(Address(regT0, FIELD_OFFSET(Structure, m_typeInfo.m_type)), regT3);
+ sub32(Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_type)), regT3);
+ addSlowCase(branch32(NotEqual, Address(regT1, FIELD_OFFSET(Structure, m_typeInfo.m_type)), regT3));
// check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
- load32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), X86::ecx);
- and32(Imm32(ImplementsHasInstance | OverridesHasInstance), X86::ecx);
- addSlowCase(jne32(X86::ecx, Imm32(ImplementsHasInstance)));
+ load32(Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), regT2);
+ and32(Imm32(ImplementsHasInstance | OverridesHasInstance), regT2);
+ addSlowCase(branch32(NotEqual, regT2, Imm32(ImplementsHasInstance)));
- emitGetVirtualRegister(currentInstruction[2].u.operand, X86::ecx); // reload value
- emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // reload proto
+ emitGetVirtualRegister(currentInstruction[2].u.operand, regT2); // reload value
+ emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); // reload proto
// optimistically load true result
- move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), X86::eax);
+ move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), regT0);
Label loop(this);
// load value's prototype
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+ loadPtr(Address(regT2, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ loadPtr(Address(regT2, FIELD_OFFSET(Structure, m_prototype)), regT2);
- Jump exit = jePtr(X86::ecx, X86::edx);
+ Jump exit = branchPtr(Equal, regT2, regT1);
- jnePtr(X86::ecx, ImmPtr(JSValuePtr::encode(jsNull())), loop);
+ branchPtr(NotEqual, regT2, ImmPtr(JSValuePtr::encode(jsNull())), loop);
- move(ImmPtr(JSValuePtr::encode(jsBoolean(false))), X86::eax);
+ move(ImmPtr(JSValuePtr::encode(jsBoolean(false))), regT0);
exit.link(this);
@@ -476,10 +470,10 @@ void JIT::privateCompileMainPass()
NEXT_OPCODE(op_instanceof);
}
case op_del_by_id: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
emitPutJITStubArgConstant(ident, 2);
- emitCTICall(Interpreter::cti_op_del_by_id);
+ emitCTICall(JITStubs::cti_op_del_by_id);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_del_by_id);
}
@@ -490,7 +484,7 @@ void JIT::privateCompileMainPass()
case op_new_func: {
FuncDeclNode* func = m_codeBlock->function(currentInstruction[2].u.operand);
emitPutJITStubArgConstant(func, 1);
- emitCTICall(Interpreter::cti_op_new_func);
+ emitCTICall(JITStubs::cti_op_new_func);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_new_func);
}
@@ -508,67 +502,71 @@ void JIT::privateCompileMainPass()
}
case op_get_global_var: {
JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[2].u.jsCell);
- move(ImmPtr(globalObject), X86::eax);
- emitGetVariableObjectRegister(X86::eax, currentInstruction[3].u.operand, X86::eax);
+ move(ImmPtr(globalObject), regT0);
+ emitGetVariableObjectRegister(regT0, currentInstruction[3].u.operand, regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_get_global_var);
}
case op_put_global_var: {
- emitGetVirtualRegister(currentInstruction[3].u.operand, X86::edx);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT1);
JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[1].u.jsCell);
- move(ImmPtr(globalObject), X86::eax);
- emitPutVariableObjectRegister(X86::edx, X86::eax, currentInstruction[2].u.operand);
+ move(ImmPtr(globalObject), regT0);
+ emitPutVariableObjectRegister(regT1, regT0, currentInstruction[2].u.operand);
NEXT_OPCODE(op_put_global_var);
}
case op_get_scoped_var: {
int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain();
- emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::eax);
+ emitGetFromCallFrameHeader(RegisterFile::ScopeChain, regT0);
while (skip--)
- loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, next)), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(ScopeChainNode, next)), regT0);
- loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, object)), X86::eax);
- emitGetVariableObjectRegister(X86::eax, currentInstruction[2].u.operand, X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(ScopeChainNode, object)), regT0);
+ emitGetVariableObjectRegister(regT0, currentInstruction[2].u.operand, regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_get_scoped_var);
}
case op_put_scoped_var: {
int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain();
- emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::edx);
- emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
+ emitGetFromCallFrameHeader(RegisterFile::ScopeChain, regT1);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
while (skip--)
- loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, next)), X86::edx);
+ loadPtr(Address(regT1, FIELD_OFFSET(ScopeChainNode, next)), regT1);
- loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, object)), X86::edx);
- emitPutVariableObjectRegister(X86::eax, X86::edx, currentInstruction[1].u.operand);
+ loadPtr(Address(regT1, FIELD_OFFSET(ScopeChainNode, object)), regT1);
+ emitPutVariableObjectRegister(regT0, regT1, currentInstruction[1].u.operand);
NEXT_OPCODE(op_put_scoped_var);
}
case op_tear_off_activation: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
- emitCTICall(Interpreter::cti_op_tear_off_activation);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
+ emitCTICall(JITStubs::cti_op_tear_off_activation);
NEXT_OPCODE(op_tear_off_activation);
}
case op_tear_off_arguments: {
- emitCTICall(Interpreter::cti_op_tear_off_arguments);
+ emitCTICall(JITStubs::cti_op_tear_off_arguments);
NEXT_OPCODE(op_tear_off_arguments);
}
case op_ret: {
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
if (m_codeBlock->needsFullScopeChain())
- emitCTICall(Interpreter::cti_op_ret_scopeChain);
+ emitCTICall(JITStubs::cti_op_ret_scopeChain);
+
+ ASSERT(callFrameRegister != regT1);
+ ASSERT(regT1 != returnValueRegister);
+ ASSERT(returnValueRegister != callFrameRegister);
// Return the result in %eax.
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
// Grab the return address.
- emitGetFromCallFrameHeader(RegisterFile::ReturnPC, X86::edx);
+ emitGetFromCallFrameHeader(RegisterFile::ReturnPC, regT1);
// Restore our caller's "r".
emitGetFromCallFrameHeader(RegisterFile::CallerFrame, callFrameRegister);
// Return.
- push(X86::edx);
+ push(regT1);
ret();
NEXT_OPCODE(op_ret);
@@ -576,29 +574,29 @@ void JIT::privateCompileMainPass()
case op_new_array: {
emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);
emitPutJITStubArgConstant(currentInstruction[3].u.operand, 2);
- emitCTICall(Interpreter::cti_op_new_array);
+ emitCTICall(JITStubs::cti_op_new_array);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_new_array);
}
case op_resolve: {
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
emitPutJITStubArgConstant(ident, 1);
- emitCTICall(Interpreter::cti_op_resolve);
+ emitCTICall(JITStubs::cti_op_resolve);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_resolve);
}
case op_construct_verify: {
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- emitJumpSlowCaseIfNotJSCell(X86::eax);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- addSlowCase(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+ emitJumpSlowCaseIfNotJSCell(regT0);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ addSlowCase(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
NEXT_OPCODE(op_construct_verify);
}
case op_get_by_val: {
- emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
#if USE(ALTERNATE_JSIMMEDIATE)
// This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter.
// We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if
@@ -606,27 +604,27 @@ void JIT::privateCompileMainPass()
// size is always less than 4Gb). As such zero extending wil have been correct (and extending the value
// to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign
// extending since it makes it easier to re-tag the value in the slow case.
- zeroExtend32ToPtr(X86::edx, X86::edx);
+ zeroExtend32ToPtr(regT1, regT1);
#else
- emitFastArithImmToInt(X86::edx);
+ emitFastArithImmToInt(regT1);
#endif
- emitJumpSlowCaseIfNotJSCell(X86::eax);
- addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
+ emitJumpSlowCaseIfNotJSCell(regT0);
+ addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
// This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
- addSlowCase(jae32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));
+ loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);
+ addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));
// Get the value from the vector
- loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::eax);
+ loadPtr(BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_get_by_val);
}
case op_resolve_func: {
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
emitPutJITStubArgConstant(ident, 1);
- emitCTICall(Interpreter::cti_op_resolve_func);
- emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
+ emitCTICall(JITStubs::cti_op_resolve_func);
+ emitPutVirtualRegister(currentInstruction[2].u.operand, regT1);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_resolve_func);
}
@@ -635,45 +633,45 @@ void JIT::privateCompileMainPass()
NEXT_OPCODE(op_sub);
}
case op_put_by_val: {
- emitGetVirtualRegisters(currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+ emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
#if USE(ALTERNATE_JSIMMEDIATE)
// See comment in op_get_by_val.
- zeroExtend32ToPtr(X86::edx, X86::edx);
+ zeroExtend32ToPtr(regT1, regT1);
#else
- emitFastArithImmToInt(X86::edx);
+ emitFastArithImmToInt(regT1);
#endif
- emitJumpSlowCaseIfNotJSCell(X86::eax);
- addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
+ emitJumpSlowCaseIfNotJSCell(regT0);
+ addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
// This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
- Jump inFastVector = jb32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
+ loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);
+ Jump inFastVector = branch32(Below, regT1, Address(regT0, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
// No; oh well, check if the access if within the vector - if so, we may still be okay.
- addSlowCase(jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength))));
+ addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, FIELD_OFFSET(ArrayStorage, m_vectorLength))));
// This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
// FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff.
- addSlowCase(jzPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));
+ addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));
// All good - put the value into the array.
inFastVector.link(this);
- emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
- storePtr(X86::eax, BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+ storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
NEXT_OPCODE(op_put_by_val);
}
CTI_COMPILE_BINARY_OP(op_lesseq)
case op_loop_if_true: {
- emitSlowScriptCheck();
+ emitTimeoutCheck();
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0())));
- addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
+ Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0())));
+ addJump(emitJumpIfImmediateInteger(regT0), target + 2);
- addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
- addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
+ addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
isZero.link(this);
NEXT_OPCODE(op_loop_if_true);
@@ -681,13 +679,13 @@ void JIT::privateCompileMainPass()
case op_resolve_base: {
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
emitPutJITStubArgConstant(ident, 1);
- emitCTICall(Interpreter::cti_op_resolve_base);
+ emitCTICall(JITStubs::cti_op_resolve_base);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_resolve_base);
}
case op_negate: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
- emitCTICall(Interpreter::cti_op_negate);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
+ emitCTICall(JITStubs::cti_op_negate);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_negate);
}
@@ -695,7 +693,7 @@ void JIT::privateCompileMainPass()
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
emitPutJITStubArgConstant(ident, 1);
emitPutJITStubArgConstant(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain(), 2);
- emitCTICall(Interpreter::cti_op_resolve_skip);
+ emitCTICall(JITStubs::cti_op_resolve_skip);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_resolve_skip);
}
@@ -709,14 +707,14 @@ void JIT::privateCompileMainPass()
void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
// Check Structure of global object
- move(ImmPtr(globalObject), X86::eax);
- loadPtr(structureAddress, X86::edx);
- Jump noMatch = jnePtr(X86::edx, Address(X86::eax, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
+ move(ImmPtr(globalObject), regT0);
+ loadPtr(structureAddress, regT1);
+ Jump noMatch = branchPtr(NotEqual, regT1, Address(regT0, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
// Load cached property
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), X86::eax);
- load32(offsetAddr, X86::edx);
- loadPtr(BaseIndex(X86::eax, X86::edx, ScalePtr), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), regT0);
+ load32(offsetAddr, regT1);
+ loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
Jump end = jump();
@@ -725,7 +723,7 @@ void JIT::privateCompileMainPass()
emitPutJITStubArgConstant(globalObject, 1);
emitPutJITStubArgConstant(ident, 2);
emitPutJITStubArgConstant(currentIndex, 3);
- emitCTICall(Interpreter::cti_op_resolve_global);
+ emitCTICall(JITStubs::cti_op_resolve_global);
emitPutVirtualRegister(currentInstruction[1].u.operand);
end.link(this);
NEXT_OPCODE(op_resolve_global);
@@ -740,81 +738,85 @@ void JIT::privateCompileMainPass()
unsigned op2 = currentInstruction[2].u.operand;
unsigned target = currentInstruction[3].u.operand;
if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(op1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
int32_t op2imm = getConstantOperandImmediateInt(op2);
#else
int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
#endif
- addJump(jge32(X86::eax, Imm32(op2imm)), target + 3);
+ addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);
} else {
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
- addJump(jge32(X86::eax, X86::edx), target + 3);
+ emitGetVirtualRegisters(op1, regT0, op2, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT1);
+ addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);
}
+ RECORD_JUMP_TARGET(target + 3);
NEXT_OPCODE(op_jnless);
}
case op_not: {
- emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
- xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
- addSlowCase(jnzPtr(X86::eax, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
- xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), X86::eax);
+ emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+ xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+ addSlowCase(branchTestPtr(NonZero, regT0, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
+ xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_not);
}
case op_jfalse: {
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0()))), target + 2);
- Jump isNonZero = emitJumpIfImmediateInteger(X86::eax);
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0()))), target + 2);
+ Jump isNonZero = emitJumpIfImmediateInteger(regT0);
- addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
- addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
+ addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));
isNonZero.link(this);
+ RECORD_JUMP_TARGET(target + 2);
NEXT_OPCODE(op_jfalse);
};
case op_jeq_null: {
unsigned src = currentInstruction[1].u.operand;
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(src, X86::eax);
- Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+ emitGetVirtualRegister(src, regT0);
+ Jump isImmediate = emitJumpIfNotJSCell(regT0);
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- addJump(jnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ addJump(branchTest32(NonZero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
- addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);
wasNotImmediate.link(this);
+ RECORD_JUMP_TARGET(target + 2);
NEXT_OPCODE(op_jeq_null);
};
case op_jneq_null: {
unsigned src = currentInstruction[1].u.operand;
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(src, X86::eax);
- Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+ emitGetVirtualRegister(src, regT0);
+ Jump isImmediate = emitJumpIfNotJSCell(regT0);
// First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- addJump(jz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ addJump(branchTest32(Zero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
Jump wasNotImmediate = jump();
// Now handle the immediate cases - undefined & null
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
- addJump(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);
wasNotImmediate.link(this);
+ RECORD_JUMP_TARGET(target + 2);
NEXT_OPCODE(op_jneq_null);
}
case op_post_inc: {
@@ -823,7 +825,7 @@ void JIT::privateCompileMainPass()
}
case op_unexpected_load: {
JSValuePtr v = m_codeBlock->unexpectedConstant(currentInstruction[2].u.operand);
- move(ImmPtr(JSValuePtr::encode(v)), X86::eax);
+ move(ImmPtr(JSValuePtr::encode(v)), regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_unexpected_load);
}
@@ -833,17 +835,20 @@ void JIT::privateCompileMainPass()
DataLabelPtr storeLocation = storePtrWithPatch(Address(callFrameRegister, sizeof(Register) * retAddrDst));
addJump(jump(), target + 2);
m_jsrSites.append(JSRInfo(storeLocation, label()));
+ killLastResultRegister();
+ RECORD_JUMP_TARGET(target + 2);
NEXT_OPCODE(op_jsr);
}
case op_sret: {
jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand));
+ killLastResultRegister();
NEXT_OPCODE(op_sret);
}
case op_eq: {
- emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
- sete32(X86::edx, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+ emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+ set32(Equal, regT1, regT0, regT0);
+ emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_eq);
}
@@ -860,13 +865,13 @@ void JIT::privateCompileMainPass()
NEXT_OPCODE(op_rshift);
}
case op_bitnot: {
- emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
- not32(X86::eax);
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ not32(regT0);
+ emitFastArithIntToImmNoCheck(regT0, regT0);
#else
- xorPtr(Imm32(~JSImmediate::TagTypeNumber), X86::eax);
+ xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0);
#endif
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_bitnot);
@@ -874,15 +879,15 @@ void JIT::privateCompileMainPass()
case op_resolve_with_base: {
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
emitPutJITStubArgConstant(ident, 1);
- emitCTICall(Interpreter::cti_op_resolve_with_base);
- emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
+ emitCTICall(JITStubs::cti_op_resolve_with_base);
+ emitPutVirtualRegister(currentInstruction[2].u.operand, regT1);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_resolve_with_base);
}
case op_new_func_exp: {
FuncExprNode* func = m_codeBlock->functionExpression(currentInstruction[2].u.operand);
emitPutJITStubArgConstant(func, 1);
- emitCTICall(Interpreter::cti_op_new_func_exp);
+ emitCTICall(JITStubs::cti_op_new_func_exp);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_new_func_exp);
}
@@ -892,23 +897,24 @@ void JIT::privateCompileMainPass()
}
case op_jtrue: {
unsigned target = currentInstruction[2].u.operand;
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0())));
- addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
+ Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0())));
+ addJump(emitJumpIfImmediateInteger(regT0), target + 2);
- addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
- addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
+ addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
+ addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
isZero.link(this);
+ RECORD_JUMP_TARGET(target + 2);
NEXT_OPCODE(op_jtrue);
}
CTI_COMPILE_BINARY_OP(op_less)
case op_neq: {
- emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
- setne32(X86::edx, X86::eax);
- emitTagAsBoolImmediate(X86::eax);
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+ emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+ set32(NotEqual, regT1, regT0, regT0);
+ emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
@@ -920,30 +926,31 @@ void JIT::privateCompileMainPass()
}
CTI_COMPILE_BINARY_OP(op_urshift)
case op_bitxor: {
- emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
- xorPtr(X86::edx, X86::eax);
- emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+ emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+ xorPtr(regT1, regT0);
+ emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_bitxor);
}
case op_new_regexp: {
RegExp* regExp = m_codeBlock->regexp(currentInstruction[2].u.operand);
emitPutJITStubArgConstant(regExp, 1);
- emitCTICall(Interpreter::cti_op_new_regexp);
+ emitCTICall(JITStubs::cti_op_new_regexp);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_new_regexp);
}
case op_bitor: {
- emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
- emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
- orPtr(X86::edx, X86::eax);
+ emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+ emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+ orPtr(regT1, regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_bitor);
}
case op_throw: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
- emitCTICall(Interpreter::cti_op_throw);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
+ emitCTICall(JITStubs::cti_op_throw);
+ ASSERT(regT0 == returnValueRegister);
#if PLATFORM(X86_64)
addPtr(Imm32(0x48), X86::esp);
pop(X86::ebx);
@@ -964,29 +971,29 @@ void JIT::privateCompileMainPass()
NEXT_OPCODE(op_throw);
}
case op_get_pnames: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
- emitCTICall(Interpreter::cti_op_get_pnames);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
+ emitCTICall(JITStubs::cti_op_get_pnames);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_get_pnames);
}
case op_next_pname: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
unsigned target = currentInstruction[3].u.operand;
- emitCTICall(Interpreter::cti_op_next_pname);
- Jump endOfIter = jzPtr(X86::eax);
+ emitCTICall(JITStubs::cti_op_next_pname);
+ Jump endOfIter = branchTestPtr(Zero, regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
addJump(jump(), target + 3);
endOfIter.link(this);
NEXT_OPCODE(op_next_pname);
}
case op_push_scope: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
- emitCTICall(Interpreter::cti_op_push_scope);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
+ emitCTICall(JITStubs::cti_op_push_scope);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_push_scope);
}
case op_pop_scope: {
- emitCTICall(Interpreter::cti_op_pop_scope);
+ emitCTICall(JITStubs::cti_op_pop_scope);
NEXT_OPCODE(op_pop_scope);
}
CTI_COMPILE_UNARY_OP(op_typeof)
@@ -1006,13 +1013,13 @@ void JIT::privateCompileMainPass()
}
case op_to_jsnumber: {
int srcVReg = currentInstruction[2].u.operand;
- emitGetVirtualRegister(srcVReg, X86::eax);
+ emitGetVirtualRegister(srcVReg, regT0);
- Jump wasImmediate = emitJumpIfImmediateInteger(X86::eax);
+ Jump wasImmediate = emitJumpIfImmediateInteger(regT0);
- emitJumpSlowCaseIfNotJSCell(X86::eax, srcVReg);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- addSlowCase(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
+ emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ addSlowCase(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
wasImmediate.link(this);
@@ -1023,8 +1030,8 @@ void JIT::privateCompileMainPass()
case op_push_new_scope: {
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
emitPutJITStubArgConstant(ident, 1);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_push_new_scope);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);
+ emitCTICall(JITStubs::cti_op_push_new_scope);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_push_new_scope);
}
@@ -1036,16 +1043,17 @@ void JIT::privateCompileMainPass()
case op_jmp_scopes: {
unsigned count = currentInstruction[1].u.operand;
emitPutJITStubArgConstant(count, 1);
- emitCTICall(Interpreter::cti_op_jmp_scopes);
+ emitCTICall(JITStubs::cti_op_jmp_scopes);
unsigned target = currentInstruction[2].u.operand;
addJump(jump(), target + 2);
+ RECORD_JUMP_TARGET(target + 2);
NEXT_OPCODE(op_jmp_scopes);
}
case op_put_by_index: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
- emitCTICall(Interpreter::cti_op_put_by_index);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);
+ emitCTICall(JITStubs::cti_op_put_by_index);
NEXT_OPCODE(op_put_by_index);
}
case op_switch_imm: {
@@ -1058,10 +1066,10 @@ void JIT::privateCompileMainPass()
m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate));
jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
- emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);
emitPutJITStubArgConstant(tableIndex, 2);
- emitCTICall(Interpreter::cti_op_switch_imm);
- jump(X86::eax);
+ emitCTICall(JITStubs::cti_op_switch_imm);
+ jump(regT0);
NEXT_OPCODE(op_switch_imm);
}
case op_switch_char: {
@@ -1074,10 +1082,10 @@ void JIT::privateCompileMainPass()
m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character));
jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
- emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);
emitPutJITStubArgConstant(tableIndex, 2);
- emitCTICall(Interpreter::cti_op_switch_char);
- jump(X86::eax);
+ emitCTICall(JITStubs::cti_op_switch_char);
+ jump(regT0);
NEXT_OPCODE(op_switch_char);
}
case op_switch_string: {
@@ -1089,33 +1097,33 @@ void JIT::privateCompileMainPass()
StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
- emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);
emitPutJITStubArgConstant(tableIndex, 2);
- emitCTICall(Interpreter::cti_op_switch_string);
- jump(X86::eax);
+ emitCTICall(JITStubs::cti_op_switch_string);
+ jump(regT0);
NEXT_OPCODE(op_switch_string);
}
case op_del_by_val: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_del_by_val);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);
+ emitCTICall(JITStubs::cti_op_del_by_val);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_del_by_val);
}
case op_put_getter: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
emitPutJITStubArgConstant(ident, 2);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
- emitCTICall(Interpreter::cti_op_put_getter);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);
+ emitCTICall(JITStubs::cti_op_put_getter);
NEXT_OPCODE(op_put_getter);
}
case op_put_setter: {
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
emitPutJITStubArgConstant(ident, 2);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
- emitCTICall(Interpreter::cti_op_put_setter);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);
+ emitCTICall(JITStubs::cti_op_put_setter);
NEXT_OPCODE(op_put_setter);
}
case op_new_error: {
@@ -1123,7 +1131,7 @@ void JIT::privateCompileMainPass()
emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);
emitPutJITStubArgConstant(JSValuePtr::encode(message), 2);
emitPutJITStubArgConstant(m_bytecodeIndex, 3);
- emitCTICall(Interpreter::cti_op_new_error);
+ emitCTICall(JITStubs::cti_op_new_error);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_new_error);
}
@@ -1131,29 +1139,29 @@ void JIT::privateCompileMainPass()
emitPutJITStubArgConstant(currentInstruction[1].u.operand, 1);
emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
emitPutJITStubArgConstant(currentInstruction[3].u.operand, 3);
- emitCTICall(Interpreter::cti_op_debug);
+ emitCTICall(JITStubs::cti_op_debug);
NEXT_OPCODE(op_debug);
}
case op_eq_null: {
unsigned dst = currentInstruction[1].u.operand;
unsigned src1 = currentInstruction[2].u.operand;
- emitGetVirtualRegister(src1, X86::eax);
- Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+ emitGetVirtualRegister(src1, regT0);
+ Jump isImmediate = emitJumpIfNotJSCell(regT0);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- setnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ setTest32(NonZero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
Jump wasNotImmediate = jump();
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
- sete32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ setPtr(Equal, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
wasNotImmediate.link(this);
- emitTagAsBoolImmediate(X86::eax);
+ emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
NEXT_OPCODE(op_eq_null);
@@ -1162,22 +1170,22 @@ void JIT::privateCompileMainPass()
unsigned dst = currentInstruction[1].u.operand;
unsigned src1 = currentInstruction[2].u.operand;
- emitGetVirtualRegister(src1, X86::eax);
- Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
+ emitGetVirtualRegister(src1, regT0);
+ Jump isImmediate = emitJumpIfNotJSCell(regT0);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- setz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ setTest32(Zero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
Jump wasNotImmediate = jump();
isImmediate.link(this);
- andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
- setne32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
+ andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+ setPtr(NotEqual, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
wasNotImmediate.link(this);
- emitTagAsBoolImmediate(X86::eax);
+ emitTagAsBoolImmediate(regT0);
emitPutVirtualRegister(dst);
NEXT_OPCODE(op_neq_null);
@@ -1200,41 +1208,41 @@ void JIT::privateCompileMainPass()
for (size_t j = 0; j < count; ++j)
emitInitRegister(j);
- emitCTICall(Interpreter::cti_op_push_activation);
+ emitCTICall(JITStubs::cti_op_push_activation);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_enter_with_activation);
}
case op_create_arguments: {
if (m_codeBlock->m_numParameters == 1)
- emitCTICall(Interpreter::cti_op_create_arguments_no_params);
+ emitCTICall(JITStubs::cti_op_create_arguments_no_params);
else
- emitCTICall(Interpreter::cti_op_create_arguments);
+ emitCTICall(JITStubs::cti_op_create_arguments);
NEXT_OPCODE(op_create_arguments);
}
case op_convert_this: {
- emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
- emitJumpSlowCaseIfNotJSCell(X86::eax);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
- addSlowCase(jnz32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ emitJumpSlowCaseIfNotJSCell(regT0);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT1);
+ addSlowCase(branchTest32(NonZero, Address(regT1, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
NEXT_OPCODE(op_convert_this);
}
case op_profile_will_call: {
- emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
- Jump noProfiler = jzPtr(Address(X86::eax));
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
- emitCTICall(Interpreter::cti_op_profile_will_call);
+ emitGetCTIParam(STUB_ARGS_profilerReference, regT0);
+ Jump noProfiler = branchTestPtr(Zero, Address(regT0));
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT0);
+ emitCTICall(JITStubs::cti_op_profile_will_call);
noProfiler.link(this);
NEXT_OPCODE(op_profile_will_call);
}
case op_profile_did_call: {
- emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
- Jump noProfiler = jzPtr(Address(X86::eax));
- emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
- emitCTICall(Interpreter::cti_op_profile_did_call);
+ emitGetCTIParam(STUB_ARGS_profilerReference, regT0);
+ Jump noProfiler = branchTestPtr(Zero, Address(regT0));
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT0);
+ emitCTICall(JITStubs::cti_op_profile_did_call);
noProfiler.link(this);
NEXT_OPCODE(op_profile_did_call);
@@ -1292,8 +1300,8 @@ void JIT::privateCompileSlowCases()
case op_convert_this: {
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_convert_this);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_convert_this);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_convert_this);
}
@@ -1304,7 +1312,7 @@ void JIT::privateCompileSlowCases()
case op_construct_verify: {
linkSlowCase(iter);
linkSlowCase(iter);
- emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
+ emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_construct_verify);
@@ -1316,25 +1324,25 @@ void JIT::privateCompileSlowCases()
Jump notImm = getSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
- emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+ emitFastArithIntToImmNoCheck(regT1, regT1);
notImm.link(this);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_get_by_val);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_get_by_val);
emitPutVirtualRegister(currentInstruction[1].u.operand);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
// This is slow case that handles accesses to arrays above the fast cut-off.
// First, check if this is an access to the vector
linkSlowCase(iter);
- jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow);
+ branch32(AboveOrEqual, regT1, Address(regT2, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow);
// okay, missed the fast region, but it is still in the vector. Get the value.
- loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::ecx);
+ loadPtr(BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), regT2);
// Check whether the value loaded is zero; if so we need to return undefined.
- jzPtr(X86::ecx, beginGetByValSlow);
- move(X86::ecx, X86::eax);
- emitPutVirtualRegister(currentInstruction[1].u.operand, X86::eax);
+ branchTestPtr(Zero, regT2, beginGetByValSlow);
+ move(regT2, regT0);
+ emitPutVirtualRegister(currentInstruction[1].u.operand, regT0);
NEXT_OPCODE(op_get_by_val);
}
@@ -1355,17 +1363,17 @@ void JIT::privateCompileSlowCases()
unsigned target = currentInstruction[3].u.operand;
if (isOperandConstantImmediateInt(op2)) {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_loop_if_less);
- emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
+ emitCTICall(JITStubs::cti_op_loop_if_less);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
} else {
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_loop_if_less);
- emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_loop_if_less);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
}
NEXT_OPCODE(op_loop_if_less);
}
@@ -1382,17 +1390,17 @@ void JIT::privateCompileSlowCases()
unsigned target = currentInstruction[3].u.operand;
if (isOperandConstantImmediateInt(op2)) {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_loop_if_lesseq);
- emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, regT2);
+ emitCTICall(JITStubs::cti_op_loop_if_lesseq);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
} else {
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_loop_if_lesseq);
- emitJumpSlowToHot(jnz32(X86::eax), target + 3);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_loop_if_lesseq);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
}
NEXT_OPCODE(op_loop_if_lesseq);
}
@@ -1405,32 +1413,32 @@ void JIT::privateCompileSlowCases()
Jump notImm = getSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
- emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+ emitFastArithIntToImmNoCheck(regT1, regT1);
notImm.link(this);
- emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitPutJITStubArg(X86::ecx, 3);
- emitCTICall(Interpreter::cti_op_put_by_val);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT2);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitPutJITStubArg(regT2, 3);
+ emitCTICall(JITStubs::cti_op_put_by_val);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val));
// slow cases for immediate int accesses to arrays
linkSlowCase(iter);
linkSlowCase(iter);
- emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitPutJITStubArg(X86::ecx, 3);
- emitCTICall(Interpreter::cti_op_put_by_val_array);
+ emitGetVirtualRegister(currentInstruction[3].u.operand, regT2);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitPutJITStubArg(regT2, 3);
+ emitCTICall(JITStubs::cti_op_put_by_val_array);
NEXT_OPCODE(op_put_by_val);
}
case op_loop_if_true: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_jtrue);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_jtrue);
unsigned target = currentInstruction[2].u.operand;
- emitJumpSlowToHot(jnz32(X86::eax), target + 2);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
NEXT_OPCODE(op_loop_if_true);
}
case op_pre_dec: {
@@ -1442,34 +1450,34 @@ void JIT::privateCompileSlowCases()
unsigned target = currentInstruction[3].u.operand;
if (isOperandConstantImmediateInt(op2)) {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_jless);
- emitJumpSlowToHot(jz32(X86::eax), target + 3);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, regT2);
+ emitCTICall(JITStubs::cti_op_jless);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
} else {
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_jless);
- emitJumpSlowToHot(jz32(X86::eax), target + 3);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_jless);
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
}
NEXT_OPCODE(op_jnless);
}
case op_not: {
linkSlowCase(iter);
- xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_not);
+ xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_not);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_not);
}
case op_jfalse: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_jtrue);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_jtrue);
unsigned target = currentInstruction[2].u.operand;
- emitJumpSlowToHot(jz32(X86::eax), target + 2); // inverted!
+ emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // inverted!
NEXT_OPCODE(op_jfalse);
}
case op_post_inc: {
@@ -1478,8 +1486,8 @@ void JIT::privateCompileSlowCases()
}
case op_bitnot: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_bitnot);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_bitnot);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_bitnot);
}
@@ -1489,10 +1497,10 @@ void JIT::privateCompileSlowCases()
}
case op_jtrue: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_jtrue);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_jtrue);
unsigned target = currentInstruction[2].u.operand;
- emitJumpSlowToHot(jnz32(X86::eax), target + 2);
+ emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
NEXT_OPCODE(op_jtrue);
}
case op_post_dec: {
@@ -1501,57 +1509,51 @@ void JIT::privateCompileSlowCases()
}
case op_bitxor: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_bitxor);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_bitxor);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_bitxor);
}
case op_bitor: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_bitor);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_bitor);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_bitor);
}
case op_eq: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_eq);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_eq);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_eq);
}
case op_neq: {
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_neq);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_neq);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_neq);
}
case op_stricteq: {
linkSlowCase(iter);
linkSlowCase(iter);
-#if !USE(ALTERNATE_JSIMMEDIATE)
- linkSlowCase(iter);
-#endif
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_stricteq);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_stricteq);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_stricteq);
}
case op_nstricteq: {
linkSlowCase(iter);
linkSlowCase(iter);
-#if !USE(ALTERNATE_JSIMMEDIATE)
- linkSlowCase(iter);
-#endif
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 2);
- emitCTICall(Interpreter::cti_op_nstricteq);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 2);
+ emitCTICall(JITStubs::cti_op_nstricteq);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_nstricteq);
}
@@ -1559,10 +1561,10 @@ void JIT::privateCompileSlowCases()
linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
- emitPutJITStubArgFromVirtualRegister(currentInstruction[4].u.operand, 3, X86::ecx);
- emitCTICall(Interpreter::cti_op_instanceof);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);
+ emitPutJITStubArgFromVirtualRegister(currentInstruction[4].u.operand, 3, regT2);
+ emitCTICall(JITStubs::cti_op_instanceof);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_instanceof);
}
@@ -1591,8 +1593,8 @@ void JIT::privateCompileSlowCases()
linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_to_jsnumber);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_to_jsnumber);
emitPutVirtualRegister(currentInstruction[1].u.operand);
NEXT_OPCODE(op_to_jsnumber);
@@ -1627,8 +1629,8 @@ void JIT::privateCompile()
#endif
// Could use a pop_m, but would need to offset the following instruction if so.
- pop(X86::ecx);
- emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
+ pop(regT2);
+ emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
Jump slowRegisterFileCheck;
Label afterRegisterFileCheck;
@@ -1636,10 +1638,10 @@ void JIT::privateCompile()
// In the case of a fast linked call, we do not set this up in the caller.
emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
- emitGetCTIParam(STUB_ARGS_registerFile, X86::eax);
- addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, X86::edx);
+ emitGetCTIParam(STUB_ARGS_registerFile, regT0);
+ addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
- slowRegisterFileCheck = jg32(X86::edx, Address(X86::eax, FIELD_OFFSET(RegisterFile, m_end)));
+ slowRegisterFileCheck = branch32(GreaterThan, regT1, Address(regT0, FIELD_OFFSET(RegisterFile, m_end)));
afterRegisterFileCheck = label();
}
@@ -1650,7 +1652,7 @@ void JIT::privateCompile()
if (m_codeBlock->codeType() == FunctionCode) {
slowRegisterFileCheck.link(this);
m_bytecodeIndex = 0; // emitCTICall will add to the map, but doesn't actually need this...
- emitCTICall(Interpreter::cti_register_file_check);
+ emitCTICall(JITStubs::cti_register_file_check);
#ifndef NDEBUG
// reset this, in order to guard it's use with asserts
m_bytecodeIndex = (unsigned)-1;
@@ -1660,7 +1662,7 @@ void JIT::privateCompile()
ASSERT(m_jmpTable.isEmpty());
- RefPtr<ExecutablePool> allocator = m_globalData->poolForSize(m_assembler.size());
+ RefPtr<ExecutablePool> allocator = m_globalData->executableAllocator.poolForSize(m_assembler.size());
void* code = m_assembler.executableCopy(allocator.get());
JITCodeRef codeRef(code, allocator);
#ifndef NDEBUG
@@ -1678,28 +1680,28 @@ void JIT::privateCompile()
ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character);
ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size());
- record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+ record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) {
unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j];
- record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
+ record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
}
} else {
ASSERT(record.type == SwitchRecord::String);
- record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+ record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end();
for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) {
unsigned offset = it->second.branchOffset;
- it->second.ctiOffset = offset ? patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
+ it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
}
}
}
for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
- handler.nativeCode = patchBuffer.addressOf(m_labels[handler.target]);
+ handler.nativeCode = patchBuffer.locationOf(m_labels[handler.target]);
}
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
@@ -1708,61 +1710,53 @@ void JIT::privateCompile()
}
if (m_codeBlock->hasExceptionInfo()) {
- m_codeBlock->pcVector().reserveCapacity(m_calls.size());
+ m_codeBlock->callReturnIndexVector().reserveCapacity(m_calls.size());
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter)
- m_codeBlock->pcVector().append(PC(reinterpret_cast<void**>(patchBuffer.addressOf(iter->from)) - reinterpret_cast<void**>(code), iter->bytecodeIndex));
+ m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeIndex(patchBuffer.returnAddressOffset(iter->from), iter->bytecodeIndex));
}
// Link absolute addresses for jsr
for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
- patchBuffer.setPtr(iter->storeLocation, patchBuffer.addressOf(iter->target));
+ patchBuffer.patch(iter->storeLocation, patchBuffer.locationOf(iter->target).addressForJSR());
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
for (unsigned i = 0; i < m_codeBlock->numberOfStructureStubInfos(); ++i) {
StructureStubInfo& info = m_codeBlock->structureStubInfo(i);
-#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
- info.callReturnLocation = patchBuffer.addressOf(m_propertyAccessCompilationInfo[i].callReturnLocation);
- info.hotPathBegin = patchBuffer.addressOf(m_propertyAccessCompilationInfo[i].hotPathBegin);
-#else
- info.callReturnLocation = 0;
- info.hotPathBegin = 0;
-#endif
+ info.callReturnLocation = patchBuffer.locationOf(m_propertyAccessCompilationInfo[i].callReturnLocation);
+ info.hotPathBegin = patchBuffer.locationOf(m_propertyAccessCompilationInfo[i].hotPathBegin);
}
+#endif
+#if ENABLE(JIT_OPTIMIZE_CALL)
for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) {
CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
-#if ENABLE(JIT_OPTIMIZE_CALL)
- info.callReturnLocation = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].callReturnLocation);
- info.hotPathBegin = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
- info.hotPathOther = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].hotPathOther);
- info.coldPathOther = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].coldPathOther);
-#else
- info.callReturnLocation = 0;
- info.hotPathBegin = 0;
- info.hotPathOther = 0;
- info.coldPathOther = 0;
-#endif
+ info.callReturnLocation = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation);
+ info.hotPathBegin = patchBuffer.locationOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
+ info.hotPathOther = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].hotPathOther);
+ info.coldPathOther = patchBuffer.locationOf(m_callStructureStubCompilationInfo[i].coldPathOther);
}
+#endif
m_codeBlock->setJITCode(codeRef);
}
-void JIT::privateCompileCTIMachineTrampolines()
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall)
{
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
// (1) The first function provides fast property access for array length
Label arrayLengthBegin = align();
// Check eax is an array
- Jump array_failureCases1 = emitJumpIfNotJSCell(X86::eax);
- Jump array_failureCases2 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
+ Jump array_failureCases1 = emitJumpIfNotJSCell(regT0);
+ Jump array_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
// Checks out okay! - get the length from the storage
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::eax);
- load32(Address(X86::eax, FIELD_OFFSET(ArrayStorage, m_length)), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT0);
+ load32(Address(regT0, FIELD_OFFSET(ArrayStorage, m_length)), regT0);
- Jump array_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
+ Jump array_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
- // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
+ emitFastArithIntToImmNoCheck(regT0, regT0);
ret();
@@ -1770,159 +1764,175 @@ void JIT::privateCompileCTIMachineTrampolines()
Label stringLengthBegin = align();
// Check eax is a string
- Jump string_failureCases1 = emitJumpIfNotJSCell(X86::eax);
- Jump string_failureCases2 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsStringVptr));
+ Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
+ Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
// Checks out okay! - get the length from the Ustring.
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep)), X86::eax);
- load32(Address(X86::eax, FIELD_OFFSET(UString::Rep, len)), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep)), regT0);
+ load32(Address(regT0, FIELD_OFFSET(UString::Rep, len)), regT0);
- Jump string_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
+ Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
- // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
+ emitFastArithIntToImmNoCheck(regT0, regT0);
ret();
#endif
+#if !(PLATFORM(X86) || PLATFORM(X86_64))
+#error "This code is less portable than it looks this code assumes that regT3 is callee preserved, which happens to be true on x86/x86-64."
+#endif
+
// (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
Label virtualCallPreLinkBegin = align();
// Load the callee CodeBlock* into eax
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
- loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
- Jump hasCodeBlock1 = jnzPtr(X86::eax);
- pop(X86::ebx);
+ loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT0);
+ loadPtr(Address(regT0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);
+ Jump hasCodeBlock1 = branchTestPtr(NonZero, regT0);
+ pop(regT3);
restoreArgumentReference();
- Jump callJSFunction1 = call();
- emitGetJITStubArg(1, X86::ecx);
- emitGetJITStubArg(3, X86::edx);
- push(X86::ebx);
+ Call callJSFunction1 = call();
+ emitGetJITStubArg(1, regT2);
+ emitGetJITStubArg(3, regT1);
+ push(regT3);
hasCodeBlock1.link(this);
// Check argCount matches callee arity.
- Jump arityCheckOkay1 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
- pop(X86::ebx);
- emitPutJITStubArg(X86::ebx, 2);
- emitPutJITStubArg(X86::eax, 4);
+ Jump arityCheckOkay1 = branch32(Equal, Address(regT0, FIELD_OFFSET(CodeBlock, m_numParameters)), regT1);
+ pop(regT3);
+ emitPutJITStubArg(regT3, 2);
+ emitPutJITStubArg(regT0, 4);
restoreArgumentReference();
- Jump callArityCheck1 = call();
- move(X86::edx, callFrameRegister);
- emitGetJITStubArg(1, X86::ecx);
- emitGetJITStubArg(3, X86::edx);
- push(X86::ebx);
+ Call callArityCheck1 = call();
+ move(regT1, callFrameRegister);
+ emitGetJITStubArg(1, regT2);
+ emitGetJITStubArg(3, regT1);
+ push(regT3);
arityCheckOkay1.link(this);
compileOpCallInitializeCallFrame();
- pop(X86::ebx);
- emitPutJITStubArg(X86::ebx, 2);
+ pop(regT3);
+ emitPutJITStubArg(regT3, 2);
restoreArgumentReference();
- Jump callDontLazyLinkCall = call();
- push(X86::ebx);
+ Call callDontLazyLinkCall = call();
+ push(regT3);
- jump(X86::eax);
+ jump(regT0);
Label virtualCallLinkBegin = align();
// Load the callee CodeBlock* into eax
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
- loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
- Jump hasCodeBlock2 = jnzPtr(X86::eax);
- pop(X86::ebx);
+ loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT0);
+ loadPtr(Address(regT0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);
+ Jump hasCodeBlock2 = branchTestPtr(NonZero, regT0);
+ pop(regT3);
restoreArgumentReference();
- Jump callJSFunction2 = call();
- emitGetJITStubArg(1, X86::ecx);
- emitGetJITStubArg(3, X86::edx);
- push(X86::ebx);
+ Call callJSFunction2 = call();
+ emitGetJITStubArg(1, regT2);
+ emitGetJITStubArg(3, regT1);
+ push(regT3);
hasCodeBlock2.link(this);
// Check argCount matches callee arity.
- Jump arityCheckOkay2 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
- pop(X86::ebx);
- emitPutJITStubArg(X86::ebx, 2);
- emitPutJITStubArg(X86::eax, 4);
+ Jump arityCheckOkay2 = branch32(Equal, Address(regT0, FIELD_OFFSET(CodeBlock, m_numParameters)), regT1);
+ pop(regT3);
+ emitPutJITStubArg(regT3, 2);
+ emitPutJITStubArg(regT0, 4);
restoreArgumentReference();
- Jump callArityCheck2 = call();
- move(X86::edx, callFrameRegister);
- emitGetJITStubArg(1, X86::ecx);
- emitGetJITStubArg(3, X86::edx);
- push(X86::ebx);
+ Call callArityCheck2 = call();
+ move(regT1, callFrameRegister);
+ emitGetJITStubArg(1, regT2);
+ emitGetJITStubArg(3, regT1);
+ push(regT3);
arityCheckOkay2.link(this);
compileOpCallInitializeCallFrame();
- pop(X86::ebx);
- emitPutJITStubArg(X86::ebx, 2);
+ pop(regT3);
+ emitPutJITStubArg(regT3, 2);
restoreArgumentReference();
- Jump callLazyLinkCall = call();
- push(X86::ebx);
+ Call callLazyLinkCall = call();
+ push(regT3);
- jump(X86::eax);
+ jump(regT0);
Label virtualCallBegin = align();
// Load the callee CodeBlock* into eax
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
- loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
- Jump hasCodeBlock3 = jnzPtr(X86::eax);
- pop(X86::ebx);
+ loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT0);
+ loadPtr(Address(regT0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);
+ Jump hasCodeBlock3 = branchTestPtr(NonZero, regT0);
+ pop(regT3);
restoreArgumentReference();
- Jump callJSFunction3 = call();
- emitGetJITStubArg(1, X86::ecx);
- emitGetJITStubArg(3, X86::edx);
- push(X86::ebx);
+ Call callJSFunction3 = call();
+ emitGetJITStubArg(1, regT2);
+ emitGetJITStubArg(3, regT1);
+ push(regT3);
hasCodeBlock3.link(this);
// Check argCount matches callee arity.
- Jump arityCheckOkay3 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
- pop(X86::ebx);
- emitPutJITStubArg(X86::ebx, 2);
- emitPutJITStubArg(X86::eax, 4);
+ Jump arityCheckOkay3 = branch32(Equal, Address(regT0, FIELD_OFFSET(CodeBlock, m_numParameters)), regT1);
+ pop(regT3);
+ emitPutJITStubArg(regT3, 2);
+ emitPutJITStubArg(regT0, 4);
restoreArgumentReference();
- Jump callArityCheck3 = call();
- move(X86::edx, callFrameRegister);
- emitGetJITStubArg(1, X86::ecx);
- emitGetJITStubArg(3, X86::edx);
- push(X86::ebx);
+ Call callArityCheck3 = call();
+ move(regT1, callFrameRegister);
+ emitGetJITStubArg(1, regT2);
+ emitGetJITStubArg(3, regT1);
+ push(regT3);
arityCheckOkay3.link(this);
compileOpCallInitializeCallFrame();
// load ctiCode from the new codeBlock.
- loadPtr(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_jitCode)), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(CodeBlock, m_jitCode)), regT0);
- jump(X86::eax);
+ jump(regT0);
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+ Call array_failureCases1Call = makeTailRecursiveCall(array_failureCases1);
+ Call array_failureCases2Call = makeTailRecursiveCall(array_failureCases2);
+ Call array_failureCases3Call = makeTailRecursiveCall(array_failureCases3);
+ Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1);
+ Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2);
+ Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3);
+#endif
// All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
- m_interpreter->m_executablePool = m_globalData->poolForSize(m_assembler.size());
- void* code = m_assembler.executableCopy(m_interpreter->m_executablePool.get());
- PatchBuffer patchBuffer(code);
+ *executablePool = m_globalData->executableAllocator.poolForSize(m_assembler.size());
+ void* code = m_assembler.executableCopy((*executablePool).get());
+ PatchBuffer patchBuffer(code);
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
- patchBuffer.link(array_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
- patchBuffer.link(array_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
- patchBuffer.link(array_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
- patchBuffer.link(string_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
- patchBuffer.link(string_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
- patchBuffer.link(string_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
-
- m_interpreter->m_ctiArrayLengthTrampoline = patchBuffer.addressOf(arrayLengthBegin);
- m_interpreter->m_ctiStringLengthTrampoline = patchBuffer.addressOf(stringLengthBegin);
+ patchBuffer.link(array_failureCases1Call, JITStubs::cti_op_get_by_id_array_fail);
+ patchBuffer.link(array_failureCases2Call, JITStubs::cti_op_get_by_id_array_fail);
+ patchBuffer.link(array_failureCases3Call, JITStubs::cti_op_get_by_id_array_fail);
+ patchBuffer.link(string_failureCases1Call, JITStubs::cti_op_get_by_id_string_fail);
+ patchBuffer.link(string_failureCases2Call, JITStubs::cti_op_get_by_id_string_fail);
+ patchBuffer.link(string_failureCases3Call, JITStubs::cti_op_get_by_id_string_fail);
+
+ *ctiArrayLengthTrampoline = patchBuffer.trampolineAt(arrayLengthBegin);
+ *ctiStringLengthTrampoline = patchBuffer.trampolineAt(stringLengthBegin);
+#else
+ UNUSED_PARAM(ctiArrayLengthTrampoline);
+ UNUSED_PARAM(ctiStringLengthTrampoline);
#endif
- patchBuffer.link(callArityCheck1, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
- patchBuffer.link(callArityCheck2, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
- patchBuffer.link(callArityCheck3, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
- patchBuffer.link(callJSFunction1, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
- patchBuffer.link(callJSFunction2, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
- patchBuffer.link(callJSFunction3, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
- patchBuffer.link(callDontLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_dontLazyLinkCall));
- patchBuffer.link(callLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_lazyLinkCall));
-
- m_interpreter->m_ctiVirtualCallPreLink = patchBuffer.addressOf(virtualCallPreLinkBegin);
- m_interpreter->m_ctiVirtualCallLink = patchBuffer.addressOf(virtualCallLinkBegin);
- m_interpreter->m_ctiVirtualCall = patchBuffer.addressOf(virtualCallBegin);
+ patchBuffer.link(callArityCheck1, JITStubs::cti_op_call_arityCheck);
+ patchBuffer.link(callArityCheck2, JITStubs::cti_op_call_arityCheck);
+ patchBuffer.link(callArityCheck3, JITStubs::cti_op_call_arityCheck);
+ patchBuffer.link(callJSFunction1, JITStubs::cti_op_call_JSFunction);
+ patchBuffer.link(callJSFunction2, JITStubs::cti_op_call_JSFunction);
+ patchBuffer.link(callJSFunction3, JITStubs::cti_op_call_JSFunction);
+ patchBuffer.link(callDontLazyLinkCall, JITStubs::cti_vm_dontLazyLinkCall);
+ patchBuffer.link(callLazyLinkCall, JITStubs::cti_vm_lazyLinkCall);
+
+ *ctiVirtualCallPreLink = patchBuffer.trampolineAt(virtualCallPreLinkBegin);
+ *ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin);
+ *ctiVirtualCall = patchBuffer.trampolineAt(virtualCallBegin);
}
void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index d13fbb5..25c7825 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -27,17 +27,19 @@
#define JIT_h
#include <wtf/Platform.h>
-#include <bytecode/SamplingTool.h>
#if ENABLE(JIT)
#define WTF_USE_CTI_REPATCH_PIC 1
#include "Interpreter.h"
+#include "JITCode.h"
+#include "JITStubs.h"
#include "Opcode.h"
#include "RegisterFile.h"
#include "MacroAssembler.h"
#include "Profiler.h"
+#include <bytecode/SamplingTool.h>
#include <wtf/AlwaysInline.h>
#include <wtf/Vector.h>
@@ -113,7 +115,7 @@ namespace JSC {
typedef VoidPtrPair (JIT_STUB *CTIHelper_2)(STUB_ARGS);
struct CallRecord {
- MacroAssembler::Jump from;
+ MacroAssembler::Call from;
unsigned bytecodeIndex;
void* to;
@@ -121,7 +123,7 @@ namespace JSC {
{
}
- CallRecord(MacroAssembler::Jump from, unsigned bytecodeIndex, void* to = 0)
+ CallRecord(MacroAssembler::Call from, unsigned bytecodeIndex, void* to = 0)
: from(from)
, bytecodeIndex(bytecodeIndex)
, to(to)
@@ -188,44 +190,73 @@ namespace JSC {
};
struct PropertyStubCompilationInfo {
- MacroAssembler::Jump callReturnLocation;
+ MacroAssembler::Call callReturnLocation;
MacroAssembler::Label hotPathBegin;
};
struct StructureStubCompilationInfo {
MacroAssembler::DataLabelPtr hotPathBegin;
- MacroAssembler::Jump hotPathOther;
- MacroAssembler::Jump callReturnLocation;
+ MacroAssembler::Call hotPathOther;
+ MacroAssembler::Call callReturnLocation;
MacroAssembler::Label coldPathOther;
};
extern "C" {
- JSValueEncodedAsPointer* ctiTrampoline(
-#if PLATFORM(X86_64)
- // FIXME: (bug #22910) this will force all arguments onto the stack (regparm(0) does not appear to have any effect).
- // We can allow register passing here, and move the writes of these values into the trampoline.
- void*, void*, void*, void*, void*, void*,
-#endif
- void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*);
void ctiVMThrowTrampoline();
};
- void ctiSetReturnAddress(void** where, void* what);
- void ctiPatchCallByReturnAddress(void* where, void* what);
+ void ctiSetReturnAddress(void** addressOfReturnAddress, void* newDestinationToReturnTo);
+ void ctiPatchCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction);
+ void ctiPatchNearCallByReturnAddress(MacroAssembler::ProcessorReturnAddress returnAddress, void* newCalleeFunction);
class JIT : private MacroAssembler {
using MacroAssembler::Jump;
using MacroAssembler::JumpList;
using MacroAssembler::Label;
+ // NOTES:
+ //
+ // regT0 has two special meanings. The return value from a stub
+ // call will always be in regT0, and by default (unless
+ // a register is specified) emitPutVirtualRegister() will store
+ // the value from regT0.
+ //
+ // tempRegister2 is has no such dependencies. It is important that
+ // on x86/x86-64 it is ecx for performance reasons, since the
+ // MacroAssembler will need to plant register swaps if it is not -
+ // however the code will still function correctly.
#if PLATFORM(X86_64)
+ static const RegisterID returnValueRegister = X86::eax;
+ static const RegisterID cachedResultRegister = X86::eax;
+ static const RegisterID firstArgumentRegister = X86::edi;
+
static const RegisterID timeoutCheckRegister = X86::r12;
static const RegisterID callFrameRegister = X86::r13;
static const RegisterID tagTypeNumberRegister = X86::r14;
static const RegisterID tagMaskRegister = X86::r15;
-#else
+
+ static const RegisterID regT0 = X86::eax;
+ static const RegisterID regT1 = X86::edx;
+ static const RegisterID regT2 = X86::ecx;
+ // NOTE: privateCompileCTIMachineTrampolines() relies on this being callee preserved; this should be considered non-interface.
+ static const RegisterID regT3 = X86::ebx;
+#elif PLATFORM(X86)
+ static const RegisterID returnValueRegister = X86::eax;
+ static const RegisterID cachedResultRegister = X86::eax;
+ // On x86 we always use fastcall conventions = but on
+ // OS X if might make more sense to just use regparm.
+ static const RegisterID firstArgumentRegister = X86::ecx;
+
static const RegisterID timeoutCheckRegister = X86::esi;
static const RegisterID callFrameRegister = X86::edi;
+
+ static const RegisterID regT0 = X86::eax;
+ static const RegisterID regT1 = X86::edx;
+ static const RegisterID regT2 = X86::ecx;
+ // NOTE: privateCompileCTIMachineTrampolines() relies on this being callee preserved; this should be considered non-interface.
+ static const RegisterID regT3 = X86::ebx;
+#else
+ #error "JIT not supported on this platform."
#endif
static const int patchGetByIdDefaultStructure = -1;
@@ -255,9 +286,9 @@ namespace JSC {
static const int patchOffsetGetByIdPropertyMapOffset = 31;
static const int patchOffsetGetByIdPutResult = 31;
#if ENABLE(OPCODE_SAMPLING)
- static const int patchOffsetGetByIdSlowCaseCall = 53 + ctiArgumentInitSize;
+ static const int patchOffsetGetByIdSlowCaseCall = 61 + ctiArgumentInitSize;
#else
- static const int patchOffsetGetByIdSlowCaseCall = 30 + ctiArgumentInitSize;
+ static const int patchOffsetGetByIdSlowCaseCall = 38 + ctiArgumentInitSize;
#endif
static const int patchOffsetOpCallCompareToJump = 9;
#else
@@ -284,13 +315,13 @@ namespace JSC {
jit.privateCompile();
}
- static void compileGetByIdSelf(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+ static void compileGetByIdSelf(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
JIT jit(globalData, codeBlock);
jit.privateCompileGetByIdSelf(stubInfo, structure, cachedOffset, returnAddress);
}
- static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress)
+ static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
JIT jit(globalData, codeBlock);
jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, cachedOffset, returnAddress, callFrame);
@@ -314,51 +345,43 @@ namespace JSC {
}
#endif
- static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress)
+ static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
JIT jit(globalData, codeBlock);
jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, cachedOffset, returnAddress, callFrame);
}
- static void compilePutByIdReplace(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+ static void compilePutByIdReplace(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
JIT jit(globalData, codeBlock);
jit.privateCompilePutByIdReplace(stubInfo, structure, cachedOffset, returnAddress);
}
- static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void* returnAddress)
+ static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ProcessorReturnAddress returnAddress)
{
JIT jit(globalData, codeBlock);
jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress);
}
- static void compileCTIMachineTrampolines(JSGlobalData* globalData)
+ static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall)
+
{
JIT jit(globalData);
- jit.privateCompileCTIMachineTrampolines();
+ jit.privateCompileCTIMachineTrampolines(executablePool, ctiArrayLengthTrampoline, ctiStringLengthTrampoline, ctiVirtualCallPreLink, ctiVirtualCallLink, ctiVirtualCall);
}
- static void patchGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
- static void patchPutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
+ static void patchGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, ProcessorReturnAddress returnAddress);
+ static void patchPutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, ProcessorReturnAddress returnAddress);
- static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, void* returnAddress)
+ static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ProcessorReturnAddress returnAddress)
{
JIT jit(globalData, codeBlock);
return jit.privateCompilePatchGetArrayLength(returnAddress);
}
- static void linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount);
+ static void linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, JITCode ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount);
static void unlinkCall(CallLinkInfo*);
- inline static JSValuePtr execute(void* code, RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValuePtr* exception)
- {
- return JSValuePtr::decode(ctiTrampoline(
-#if PLATFORM(X86_64)
- 0, 0, 0, 0, 0, 0,
-#endif
- code, registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData));
- }
-
private:
JIT(JSGlobalData*, CodeBlock* = 0);
@@ -366,19 +389,19 @@ namespace JSC {
void privateCompileLinkPass();
void privateCompileSlowCases();
void privateCompile();
- void privateCompileGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
- void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress, CallFrame* callFrame);
+ void privateCompileGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, ProcessorReturnAddress returnAddress);
+ void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame);
#if USE(CTI_REPATCH_PIC)
void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, size_t cachedOffset);
void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame);
void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame);
#endif
- void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame);
- void privateCompilePutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
- void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, void* returnAddress);
+ void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame);
+ void privateCompilePutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, ProcessorReturnAddress returnAddress);
+ void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ProcessorReturnAddress returnAddress);
- void privateCompileCTIMachineTrampolines();
- void privateCompilePatchGetArrayLength(void* returnAddress);
+ void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, void** ctiArrayLengthTrampoline, void** ctiStringLengthTrampoline, void** ctiVirtualCallPreLink, void** ctiVirtualCallLink, void** ctiVirtualCall);
+ void privateCompilePatchGetArrayLength(ProcessorReturnAddress returnAddress);
void addSlowCase(Jump);
void addJump(Jump, int);
@@ -396,7 +419,6 @@ namespace JSC {
void compileOpConstructSetupArgs(Instruction*);
enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type);
- void putDoubleResultToJSNumberCellOrJSImmediate(X86Assembler::XMMRegisterID xmmSource, RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86Assembler::XMMRegisterID tempXmm, RegisterID tempReg1, RegisterID tempReg2);
void compileFastArith_op_add(Instruction*);
void compileFastArith_op_sub(Instruction*);
@@ -427,7 +449,7 @@ namespace JSC {
void emitGetVirtualRegister(int src, RegisterID dst);
void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2);
- void emitPutVirtualRegister(unsigned dst, RegisterID from = X86::eax);
+ void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0);
void emitPutJITStubArg(RegisterID src, unsigned argumentNumber);
void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch);
@@ -458,6 +480,16 @@ namespace JSC {
#if USE(ALTERNATE_JSIMMEDIATE)
JIT::Jump emitJumpIfImmediateNumber(RegisterID);
JIT::Jump emitJumpIfNotImmediateNumber(RegisterID);
+#else
+ JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
+ {
+ return emitJumpIfImmediateInteger(reg);
+ }
+
+ JIT::Jump emitJumpIfNotImmediateNumber(RegisterID reg)
+ {
+ return emitJumpIfNotImmediateInteger(reg);
+ }
#endif
Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
@@ -492,21 +524,20 @@ namespace JSC {
void restoreArgumentReference();
void restoreArgumentReferenceForTrampoline();
- Jump emitNakedCall(RegisterID);
- Jump emitNakedCall(void* function);
- Jump emitCTICall_internal(void*);
- Jump emitCTICall(CTIHelper_j helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
- Jump emitCTICall(CTIHelper_o helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
- Jump emitCTICall(CTIHelper_p helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
- Jump emitCTICall(CTIHelper_v helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
- Jump emitCTICall(CTIHelper_s helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
- Jump emitCTICall(CTIHelper_b helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
- Jump emitCTICall(CTIHelper_2 helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitNakedCall(void* function);
+ Call emitCTICall_internal(void*);
+ Call emitCTICall(CTIHelper_j helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitCTICall(CTIHelper_o helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitCTICall(CTIHelper_p helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitCTICall(CTIHelper_v helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitCTICall(CTIHelper_s helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitCTICall(CTIHelper_b helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+ Call emitCTICall(CTIHelper_2 helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
void emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst);
void emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index);
- void emitSlowScriptCheck();
+ void emitTimeoutCheck();
#ifndef NDEBUG
void printBytecodeOperandTypes(unsigned src1, unsigned src2);
#endif
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index 0a3e9ab..8fe245e 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -48,23 +48,23 @@ namespace JSC {
void JIT::compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2)
{
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+ emitGetVirtualRegisters(op1, regT0, op2, regT2);
// FIXME: would we be better using 'emitJumpSlowCaseIfNotImmediateIntegers'? - we *probably* ought to be consistent.
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
- emitFastArithImmToInt(X86::eax);
- emitFastArithImmToInt(X86::ecx);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT2);
+ emitFastArithImmToInt(regT0);
+ emitFastArithImmToInt(regT2);
#if !PLATFORM(X86)
// Mask with 0x1f as per ecma-262 11.7.2 step 7.
// On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
- and32(Imm32(0x1f), X86::ecx);
+ and32(Imm32(0x1f), regT2);
#endif
- lshift32(X86::ecx, X86::eax);
+ lshift32(regT2, regT0);
#if !USE(ALTERNATE_JSIMMEDIATE)
- addSlowCase(joAdd32(X86::eax, X86::eax));
- signExtend32ToPtr(X86::eax, X86::eax);
+ addSlowCase(branchAdd32(Overflow, regT0, regT0));
+ signExtend32ToPtr(regT0, regT0);
#endif
- emitFastArithReTagImmediate(X86::eax, X86::eax);
+ emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(result);
}
void JIT::compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
@@ -79,47 +79,47 @@ void JIT::compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned
Jump notImm1 = getSlowCase(iter);
Jump notImm2 = getSlowCase(iter);
linkSlowCase(iter);
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+ emitGetVirtualRegisters(op1, regT0, op2, regT2);
notImm1.link(this);
notImm2.link(this);
#endif
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::ecx, 2);
- emitCTICall(Interpreter::cti_op_lshift);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT2, 2);
+ emitCTICall(JITStubs::cti_op_lshift);
emitPutVirtualRegister(result);
}
void JIT::compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2)
{
if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(op1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
// Mask with 0x1f as per ecma-262 11.7.2 step 7.
#if USE(ALTERNATE_JSIMMEDIATE)
- rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), X86::eax);
+ rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
#else
- rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), X86::eax);
+ rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
#endif
} else {
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
- emitFastArithImmToInt(X86::ecx);
+ emitGetVirtualRegisters(op1, regT0, op2, regT2);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT2);
+ emitFastArithImmToInt(regT2);
#if !PLATFORM(X86)
// Mask with 0x1f as per ecma-262 11.7.2 step 7.
// On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
- and32(Imm32(0x1f), X86::ecx);
+ and32(Imm32(0x1f), regT2);
#endif
#if USE(ALTERNATE_JSIMMEDIATE)
- rshift32(X86::ecx, X86::eax);
+ rshift32(regT2, regT0);
#else
- rshiftPtr(X86::ecx, X86::eax);
+ rshiftPtr(regT2, regT0);
#endif
}
#if USE(ALTERNATE_JSIMMEDIATE)
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ emitFastArithIntToImmNoCheck(regT0, regT0);
#else
- orPtr(Imm32(JSImmediate::TagTypeNumber), X86::eax);
+ orPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
#endif
emitPutVirtualRegister(result);
}
@@ -127,45 +127,45 @@ void JIT::compileFastArithSlow_op_rshift(unsigned result, unsigned, unsigned op2
{
linkSlowCase(iter);
if (isOperandConstantImmediateInt(op2))
- emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
else {
linkSlowCase(iter);
- emitPutJITStubArg(X86::ecx, 2);
+ emitPutJITStubArg(regT2, 2);
}
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_rshift);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_rshift);
emitPutVirtualRegister(result);
}
void JIT::compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2)
{
if (isOperandConstantImmediateInt(op1)) {
- emitGetVirtualRegister(op2, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(op2, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
int32_t imm = getConstantOperandImmediateInt(op1);
- andPtr(Imm32(imm), X86::eax);
+ andPtr(Imm32(imm), regT0);
if (imm >= 0)
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ emitFastArithIntToImmNoCheck(regT0, regT0);
#else
- andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), X86::eax);
+ andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), regT0);
#endif
} else if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(op1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
int32_t imm = getConstantOperandImmediateInt(op2);
- andPtr(Imm32(imm), X86::eax);
+ andPtr(Imm32(imm), regT0);
if (imm >= 0)
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ emitFastArithIntToImmNoCheck(regT0, regT0);
#else
- andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), X86::eax);
+ andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), regT0);
#endif
} else {
- emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
- andPtr(X86::edx, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegisters(op1, regT0, op2, regT1);
+ andPtr(regT1, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
}
emitPutVirtualRegister(result);
}
@@ -173,31 +173,34 @@ void JIT::compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned
{
linkSlowCase(iter);
if (isOperandConstantImmediateInt(op1)) {
- emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
- emitPutJITStubArg(X86::eax, 2);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
+ emitPutJITStubArg(regT0, 2);
} else if (isOperandConstantImmediateInt(op2)) {
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
} else {
- emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
- emitPutJITStubArg(X86::edx, 2);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
+ emitPutJITStubArg(regT1, 2);
}
- emitCTICall(Interpreter::cti_op_bitand);
+ emitCTICall(JITStubs::cti_op_bitand);
emitPutVirtualRegister(result);
}
+#if PLATFORM(X86) || PLATFORM(X86_64)
void JIT::compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2)
{
emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
#if USE(ALTERNATE_JSIMMEDIATE)
- addSlowCase(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(js0()))));
- mod32(X86::ecx, X86::eax, X86::edx);
+ addSlowCase(branchPtr(Equal, X86::ecx, ImmPtr(JSValuePtr::encode(js0()))));
+ m_assembler.cdq();
+ m_assembler.idivl_r(X86::ecx);
#else
emitFastArithDeTagImmediate(X86::eax);
addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx));
- mod32(X86::ecx, X86::eax, X86::edx);
+ m_assembler.cdq();
+ m_assembler.idivl_r(X86::ecx);
signExtend32ToPtr(X86::edx, X86::edx);
#endif
emitFastArithReTagImmediate(X86::edx, X86::eax);
@@ -220,70 +223,83 @@ void JIT::compileFastArithSlow_op_mod(unsigned result, unsigned, unsigned, Vecto
#endif
emitPutJITStubArg(X86::eax, 1);
emitPutJITStubArg(X86::ecx, 2);
- emitCTICall(Interpreter::cti_op_mod);
+ emitCTICall(JITStubs::cti_op_mod);
+ emitPutVirtualRegister(result);
+}
+#else
+void JIT::compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2)
+{
+ emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
+ emitCTICall(JITStubs::cti_op_mod);
emitPutVirtualRegister(result);
}
+void JIT::compileFastArithSlow_op_mod(unsigned, unsigned, unsigned, Vector<SlowCaseEntry>::iterator&)
+{
+ ASSERT_NOT_REACHED();
+}
+#endif
void JIT::compileFastArith_op_post_inc(unsigned result, unsigned srcDst)
{
- emitGetVirtualRegister(srcDst, X86::eax);
- move(X86::eax, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(srcDst, regT0);
+ move(regT0, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
- addSlowCase(joAdd32(Imm32(1), X86::edx));
- emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+ addSlowCase(branchAdd32(Overflow, Imm32(1), regT1));
+ emitFastArithIntToImmNoCheck(regT1, regT1);
#else
- addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
- signExtend32ToPtr(X86::edx, X86::edx);
+ addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
+ signExtend32ToPtr(regT1, regT1);
#endif
- emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
void JIT::compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_post_inc);
- emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_post_inc);
+ emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
void JIT::compileFastArith_op_post_dec(unsigned result, unsigned srcDst)
{
- emitGetVirtualRegister(srcDst, X86::eax);
- move(X86::eax, X86::edx);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(srcDst, regT0);
+ move(regT0, regT1);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
- addSlowCase(joSub32(Imm32(1), X86::edx));
- emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+ addSlowCase(branchSub32(Zero, Imm32(1), regT1));
+ emitFastArithIntToImmNoCheck(regT1, regT1);
#else
- addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
- signExtend32ToPtr(X86::edx, X86::edx);
+ addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
+ signExtend32ToPtr(regT1, regT1);
#endif
- emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
void JIT::compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
linkSlowCase(iter);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_post_dec);
- emitPutVirtualRegister(srcDst, X86::edx);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_post_dec);
+ emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
void JIT::compileFastArith_op_pre_inc(unsigned srcDst)
{
- emitGetVirtualRegister(srcDst, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(srcDst, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
- addSlowCase(joAdd32(Imm32(1), X86::eax));
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+ emitFastArithIntToImmNoCheck(regT0, regT0);
#else
- addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
- signExtend32ToPtr(X86::eax, X86::eax);
+ addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
+ signExtend32ToPtr(regT0, regT0);
#endif
emitPutVirtualRegister(srcDst);
}
@@ -291,23 +307,23 @@ void JIT::compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>
{
Jump notImm = getSlowCase(iter);
linkSlowCase(iter);
- emitGetVirtualRegister(srcDst, X86::eax);
+ emitGetVirtualRegister(srcDst, regT0);
notImm.link(this);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_pre_inc);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_pre_inc);
emitPutVirtualRegister(srcDst);
}
void JIT::compileFastArith_op_pre_dec(unsigned srcDst)
{
- emitGetVirtualRegister(srcDst, X86::eax);
- emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+ emitGetVirtualRegister(srcDst, regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
#if USE(ALTERNATE_JSIMMEDIATE)
- addSlowCase(joSub32(Imm32(1), X86::eax));
- emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+ addSlowCase(branchSub32(Zero, Imm32(1), regT0));
+ emitFastArithIntToImmNoCheck(regT0, regT0);
#else
- addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
- signExtend32ToPtr(X86::eax, X86::eax);
+ addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
+ signExtend32ToPtr(regT0, regT0);
#endif
emitPutVirtualRegister(srcDst);
}
@@ -315,10 +331,10 @@ void JIT::compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>
{
Jump notImm = getSlowCase(iter);
linkSlowCase(iter);
- emitGetVirtualRegister(srcDst, X86::eax);
+ emitGetVirtualRegister(srcDst, regT0);
notImm.link(this);
- emitPutJITStubArg(X86::eax, 1);
- emitCTICall(Interpreter::cti_op_pre_dec);
+ emitPutJITStubArg(regT0, 1);
+ emitCTICall(JITStubs::cti_op_pre_dec);
emitPutVirtualRegister(srcDst);
}
@@ -331,9 +347,9 @@ void JIT::compileFastArith_op_add(Instruction* currentInstruction)
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
- emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
- emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_add);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
+ emitCTICall(JITStubs::cti_op_add);
emitPutVirtualRegister(result);
}
void JIT::compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&)
@@ -347,9 +363,9 @@ void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
- emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
- emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_mul);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
+ emitCTICall(JITStubs::cti_op_mul);
emitPutVirtualRegister(result);
}
void JIT::compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&)
@@ -363,9 +379,9 @@ void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
- emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
- emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_sub);
+ emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
+ emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
+ emitCTICall(JITStubs::cti_op_sub);
emitPutVirtualRegister(result);
}
void JIT::compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&)
@@ -381,13 +397,13 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsign
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
if (opcodeID == op_add)
- addSlowCase(joAdd32(X86::edx, X86::eax));
+ addSlowCase(branchAdd32(Overflow, X86::edx, X86::eax));
else if (opcodeID == op_sub)
- addSlowCase(joSub32(X86::edx, X86::eax));
+ addSlowCase(branchSub32(Overflow, X86::edx, X86::eax));
else {
ASSERT(opcodeID == op_mul);
- addSlowCase(joMul32(X86::edx, X86::eax));
- addSlowCase(jz32(X86::eax));
+ addSlowCase(branchMul32(Overflow, X86::edx, X86::eax));
+ addSlowCase(branchTest32(Zero, X86::eax));
}
emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
}
@@ -409,12 +425,12 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
emitPutJITStubArg(X86::eax, 1);
emitPutJITStubArg(X86::edx, 2);
if (opcodeID == op_add)
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
else if (opcodeID == op_sub)
- emitCTICall(Interpreter::cti_op_sub);
+ emitCTICall(JITStubs::cti_op_sub);
else {
ASSERT(opcodeID == op_mul);
- emitCTICall(Interpreter::cti_op_mul);
+ emitCTICall(JITStubs::cti_op_mul);
}
Jump end = jump();
@@ -464,7 +480,7 @@ void JIT::compileFastArith_op_add(Instruction* currentInstruction)
if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
emitPutVirtualRegister(result);
return;
}
@@ -472,12 +488,12 @@ void JIT::compileFastArith_op_add(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
+ addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
} else if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
+ addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
} else
compileBinaryArithOp(op_add, result, op1, op2, types);
@@ -496,13 +512,13 @@ void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<Sl
linkSlowCase(iter);
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
} else if (isOperandConstantImmediateInt(op2)) {
linkSlowCase(iter);
linkSlowCase(iter);
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
} else
compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
@@ -521,12 +537,12 @@ void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
emitGetVirtualRegister(op2, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ addSlowCase(branchMul32(Overflow, Imm32(value), X86::eax, X86::eax));
emitFastArithReTagImmediate(X86::eax, X86::eax);
} else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
emitGetVirtualRegister(op1, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ addSlowCase(branchMul32(Overflow, Imm32(value), X86::eax, X86::eax));
emitFastArithReTagImmediate(X86::eax, X86::eax);
} else
compileBinaryArithOp(op_mul, result, op1, op2, types);
@@ -547,7 +563,7 @@ void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<Sl
// There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_mul);
+ emitCTICall(JITStubs::cti_op_mul);
} else
compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types);
@@ -605,9 +621,19 @@ static bool isSSE2Present()
cpuid;
mov flags, edx;
}
+#elif COMPILER(GCC)
+ asm (
+ "movl $0x1, %%eax;"
+ "pushl %%ebx;"
+ "cpuid;"
+ "popl %%ebx;"
+ "movl %%edx, %0;"
+ : "=g" (flags)
+ :
+ : "%eax", "%ecx", "%edx"
+ );
#else
flags = 0;
- // FIXME: Add GCC code to do above asm
#endif
present = (flags & SSE2FeatureBit) != 0;
}
@@ -619,53 +645,11 @@ static bool isSSE2Present()
#endif
-/*
- This is required since number representation is canonical - values representable as a JSImmediate should not be stored in a JSNumberCell.
-
- In the common case, the double value from 'xmmSource' is written to the reusable JSNumberCell pointed to by 'jsNumberCell', then 'jsNumberCell'
- is written to the output SF Register 'dst', and then a jump is planted (stored into *wroteJSNumberCell).
-
- However if the value from xmmSource is representable as a JSImmediate, then the JSImmediate value will be written to the output, and flow
- control will fall through from the code planted.
-*/
-void JIT::putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, JmpSrc* wroteJSNumberCell, X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2)
-{
- // convert (double -> JSImmediate -> double), and check if the value is unchanged - in which case the value is representable as a JSImmediate.
- __ cvttsd2si_rr(xmmSource, tempReg1);
- __ addl_rr(tempReg1, tempReg1);
- __ sarl_i8r(1, tempReg1);
- __ cvtsi2sd_rr(tempReg1, tempXmm);
- // Compare & branch if immediate.
- __ ucomisd_rr(tempXmm, xmmSource);
- JmpSrc resultIsImm = __ je();
- JmpDst resultLookedLikeImmButActuallyIsnt = __ label();
-
- // Store the result to the JSNumberCell and jump.
- __ movsd_rm(xmmSource, FIELD_OFFSET(JSNumberCell, m_value), jsNumberCell);
- if (jsNumberCell != X86::eax)
- __ movl_rr(jsNumberCell, X86::eax);
- emitPutVirtualRegister(dst);
- *wroteJSNumberCell = __ jmp();
-
- __ link(resultIsImm, __ label());
- // value == (double)(JSImmediate)value... or at least, it looks that way...
- // ucomi will report that (0 == -0), and will report true if either input in NaN (result is unordered).
- __ link(__ jp(), resultLookedLikeImmButActuallyIsnt); // Actually was a NaN
- __ pextrw_irr(3, xmmSource, tempReg2);
- __ cmpl_ir(0x8000, tempReg2);
- __ link(__ je(), resultLookedLikeImmButActuallyIsnt); // Actually was -0
- // Yes it really really really is representable as a JSImmediate.
- emitFastArithIntToImmNoCheck(tempReg1, X86::eax);
- emitPutVirtualRegister(dst);
-}
-
void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
{
Structure* numberStructure = m_globalData->numberStructure.get();
JmpSrc wasJSNumberCell1;
- JmpSrc wasJSNumberCell1b;
JmpSrc wasJSNumberCell2;
- JmpSrc wasJSNumberCell2b;
emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
@@ -695,11 +679,11 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
__ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
JmpSrc loadedDouble = __ jmp();
// (1b) if we get here, src1 is an immediate
- __ link(op1imm, __ label());
+ __ linkJump(op1imm, __ label());
emitFastArithImmToInt(X86::eax);
__ cvtsi2sd_rr(X86::eax, X86::xmm0);
// (1c)
- __ link(loadedDouble, __ label());
+ __ linkJump(loadedDouble, __ label());
if (opcodeID == op_add)
__ addsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
else if (opcodeID == op_sub)
@@ -709,12 +693,15 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
__ mulsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
}
- putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::edx, dst, &wasJSNumberCell2, X86::xmm1, X86::ecx, X86::eax);
- wasJSNumberCell2b = __ jmp();
+ // Store the result to the JSNumberCell and jump.
+ __ movsd_rm(X86::xmm0, FIELD_OFFSET(JSNumberCell, m_value), X86::edx);
+ __ movl_rr(X86::edx, X86::eax);
+ emitPutVirtualRegister(dst);
+ wasJSNumberCell2 = __ jmp();
// (2) This handles cases where src2 is an immediate number.
// Two slow cases - either src1 isn't an immediate, or the subtract overflows.
- __ link(op2imm, __ label());
+ __ linkJump(op2imm, __ label());
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
} else if (types.first().isReusable() && isSSE2Present()) {
ASSERT(types.first().mightBeNumber());
@@ -742,11 +729,11 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
__ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm1);
JmpSrc loadedDouble = __ jmp();
// (1b) if we get here, src2 is an immediate
- __ link(op2imm, __ label());
+ __ linkJump(op2imm, __ label());
emitFastArithImmToInt(X86::edx);
__ cvtsi2sd_rr(X86::edx, X86::xmm1);
// (1c)
- __ link(loadedDouble, __ label());
+ __ linkJump(loadedDouble, __ label());
__ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
if (opcodeID == op_add)
__ addsd_rr(X86::xmm1, X86::xmm0);
@@ -759,12 +746,14 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
__ movsd_rm(X86::xmm0, FIELD_OFFSET(JSNumberCell, m_value), X86::eax);
emitPutVirtualRegister(dst);
- putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, dst, &wasJSNumberCell1, X86::xmm1, X86::ecx, X86::edx);
- wasJSNumberCell1b = __ jmp();
+ // Store the result to the JSNumberCell and jump.
+ __ movsd_rm(X86::xmm0, FIELD_OFFSET(JSNumberCell, m_value), X86::eax);
+ emitPutVirtualRegister(dst);
+ wasJSNumberCell1 = __ jmp();
// (2) This handles cases where src1 is an immediate number.
// Two slow cases - either src2 isn't an immediate, or the subtract overflows.
- __ link(op1imm, __ label());
+ __ linkJump(op1imm, __ label());
emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
} else
emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
@@ -782,17 +771,17 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
ASSERT(opcodeID == op_mul);
// convert eax & edx from JSImmediates to ints, and check if either are zero
emitFastArithImmToInt(X86::edx);
- JmpSrc op1Zero = emitFastArithDeTagImmediateJumpIfZero(X86::eax);
+ Jump op1Zero = emitFastArithDeTagImmediateJumpIfZero(X86::eax);
__ testl_rr(X86::edx, X86::edx);
JmpSrc op2NonZero = __ jne();
- __ link(op1Zero, __ label());
+ op1Zero.link(this);
// if either input is zero, add the two together, and check if the result is < 0.
// If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
__ movl_rr(X86::eax, X86::ecx);
__ addl_rr(X86::edx, X86::ecx);
addSlowCase(__ js());
// Skip the above check if neither input is zero
- __ link(op2NonZero, __ label());
+ __ linkJump(op2NonZero, __ label());
__ imull_rr(X86::edx, X86::eax);
addSlowCase(__ jo());
signExtend32ToPtr(X86::eax, X86::eax);
@@ -801,12 +790,10 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
emitPutVirtualRegister(dst);
if (types.second().isReusable() && isSSE2Present()) {
- __ link(wasJSNumberCell2, __ label());
- __ link(wasJSNumberCell2b, __ label());
+ __ linkJump(wasJSNumberCell2, __ label());
}
else if (types.first().isReusable() && isSSE2Present()) {
- __ link(wasJSNumberCell1, __ label());
- __ link(wasJSNumberCell1b, __ label());
+ __ linkJump(wasJSNumberCell1, __ label());
}
}
@@ -841,12 +828,12 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx);
if (opcodeID == op_add)
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
else if (opcodeID == op_sub)
- emitCTICall(Interpreter::cti_op_sub);
+ emitCTICall(JITStubs::cti_op_sub);
else {
ASSERT(opcodeID == op_mul);
- emitCTICall(Interpreter::cti_op_mul);
+ emitCTICall(JITStubs::cti_op_mul);
}
emitPutVirtualRegister(dst);
}
@@ -860,13 +847,13 @@ void JIT::compileFastArith_op_add(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
+ addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
signExtend32ToPtr(X86::eax, X86::eax);
emitPutVirtualRegister(result);
} else if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
- addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
+ addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
signExtend32ToPtr(X86::eax, X86::eax);
emitPutVirtualRegister(result);
} else {
@@ -876,7 +863,7 @@ void JIT::compileFastArith_op_add(Instruction* currentInstruction)
else {
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
emitPutVirtualRegister(result);
}
}
@@ -894,7 +881,7 @@ void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<Sl
notImm.link(this);
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArg(X86::eax, 2);
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
emitPutVirtualRegister(result);
} else if (isOperandConstantImmediateInt(op2)) {
Jump notImm = getSlowCase(iter);
@@ -903,7 +890,7 @@ void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<Sl
notImm.link(this);
emitPutJITStubArg(X86::eax, 1);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_add);
+ emitCTICall(JITStubs::cti_op_add);
emitPutVirtualRegister(result);
} else {
OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
@@ -924,7 +911,7 @@ void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
emitGetVirtualRegister(op2, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
emitFastArithDeTagImmediate(X86::eax);
- addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ addSlowCase(branchMul32(Overflow, Imm32(value), X86::eax, X86::eax));
signExtend32ToPtr(X86::eax, X86::eax);
emitFastArithReTagImmediate(X86::eax, X86::eax);
emitPutVirtualRegister(result);
@@ -932,7 +919,7 @@ void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
emitGetVirtualRegister(op1, X86::eax);
emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
emitFastArithDeTagImmediate(X86::eax);
- addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
+ addSlowCase(branchMul32(Overflow, Imm32(value), X86::eax, X86::eax));
signExtend32ToPtr(X86::eax, X86::eax);
emitFastArithReTagImmediate(X86::eax, X86::eax);
emitPutVirtualRegister(result);
@@ -952,7 +939,7 @@ void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<Sl
// There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
- emitCTICall(Interpreter::cti_op_mul);
+ emitCTICall(JITStubs::cti_op_mul);
emitPutVirtualRegister(result);
} else
compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
diff --git a/JavaScriptCore/jit/JITCall.cpp b/JavaScriptCore/jit/JITCall.cpp
index af26712..62c7149 100644
--- a/JavaScriptCore/jit/JITCall.cpp
+++ b/JavaScriptCore/jit/JITCall.cpp
@@ -49,10 +49,11 @@ void JIT::unlinkCall(CallLinkInfo* callLinkInfo)
// When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
// (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
// match). Reset the check so it no longer matches.
- DataLabelPtr::patch(callLinkInfo->hotPathBegin, JSValuePtr::encode(jsImpossibleValue()));
+ callLinkInfo->hotPathBegin.repatch(JSValuePtr::encode(jsImpossibleValue()));
}
-void JIT::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount)
+//void JIT::linkCall(JSFunction* , CodeBlock* , JITCode , CallLinkInfo* callLinkInfo, int )
+void JIT::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, JITCode ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount)
{
// Currently we only link calls with the exact number of arguments.
if (callerArgCount == calleeCodeBlock->m_numParameters) {
@@ -60,24 +61,23 @@ void JIT::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode
calleeCodeBlock->addCaller(callLinkInfo);
- DataLabelPtr::patch(callLinkInfo->hotPathBegin, callee);
- Jump::patch(callLinkInfo->hotPathOther, ctiCode);
+ callLinkInfo->hotPathBegin.repatch(callee);
+ callLinkInfo->hotPathOther.relink(ctiCode.addressForCall());
}
// patch the instruction that jumps out to the cold path, so that we only try to link once.
- void* patchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + patchOffsetOpCallCompareToJump);
- Jump::patch(patchCheck, callLinkInfo->coldPathOther);
+ callLinkInfo->hotPathBegin.jumpAtOffset(patchOffsetOpCallCompareToJump).relink(callLinkInfo->coldPathOther);
}
void JIT::compileOpCallInitializeCallFrame()
{
- store32(X86::edx, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
+ store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain
+ loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), regT1); // newScopeChain
storePtr(ImmPtr(JSValuePtr::encode(noValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register))));
- storePtr(X86::ecx, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
- storePtr(X86::edx, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
+ storePtr(regT2, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
+ storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
}
void JIT::compileOpCallSetupArgs(Instruction* instruction)
@@ -86,7 +86,7 @@ void JIT::compileOpCallSetupArgs(Instruction* instruction)
int registerOffset = instruction[4].u.operand;
// ecx holds func
- emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArg(regT2, 1);
emitPutJITStubArgConstant(registerOffset, 2);
emitPutJITStubArgConstant(argCount, 3);
}
@@ -97,7 +97,7 @@ void JIT::compileOpCallEvalSetupArgs(Instruction* instruction)
int registerOffset = instruction[4].u.operand;
// ecx holds func
- emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArg(regT2, 1);
emitPutJITStubArgConstant(registerOffset, 2);
emitPutJITStubArgConstant(argCount, 3);
}
@@ -110,10 +110,10 @@ void JIT::compileOpConstructSetupArgs(Instruction* instruction)
int thisRegister = instruction[6].u.operand;
// ecx holds func
- emitPutJITStubArg(X86::ecx, 1);
+ emitPutJITStubArg(regT2, 1);
emitPutJITStubArgConstant(registerOffset, 2);
emitPutJITStubArgConstant(argCount, 3);
- emitPutJITStubArgFromVirtualRegister(proto, 4, X86::eax);
+ emitPutJITStubArgFromVirtualRegister(proto, 4, regT0);
emitPutJITStubArgConstant(thisRegister, 5);
}
@@ -129,14 +129,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
// Handle eval
Jump wasEval;
if (opcodeID == op_call_eval) {
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
compileOpCallEvalSetupArgs(instruction);
- emitCTICall(Interpreter::cti_op_call_eval);
- wasEval = jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+ emitCTICall(JITStubs::cti_op_call_eval);
+ wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
}
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
// The arguments have been set up on the hot path for op_call_eval
if (opcodeID == op_call)
compileOpCallSetupArgs(instruction);
@@ -144,22 +144,22 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
compileOpConstructSetupArgs(instruction);
// Check for JSFunctions.
- emitJumpSlowCaseIfNotJSCell(X86::ecx);
- addSlowCase(jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr)));
+ emitJumpSlowCaseIfNotJSCell(regT2);
+ addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
// First, in the case of a construct, allocate the new object.
if (opcodeID == op_construct) {
- emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitCTICall(JITStubs::cti_op_construct_JSConstruct);
emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
}
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
- move(Imm32(argCount), X86::edx);
+ move(Imm32(argCount), regT1);
- emitNakedCall(m_interpreter->m_ctiVirtualCall);
+ emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
if (opcodeID == op_call_eval)
wasEval.link(this);
@@ -178,7 +178,7 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
linkSlowCase(iter);
// This handles host functions
- emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction));
+ emitCTICall(((opcodeID == op_construct) ? JITStubs::cti_op_construct_NotJSConstruct : JITStubs::cti_op_call_NotJSFunction));
// Put the return value in dst. In the interpreter, op_ret does this.
emitPutVirtualRegister(dst);
@@ -187,12 +187,6 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
#else
-static NO_RETURN void unreachable()
-{
- ASSERT_NOT_REACHED();
- exit(1);
-}
-
void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
{
int dst = instruction[1].u.operand;
@@ -203,18 +197,18 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
// Handle eval
Jump wasEval;
if (opcodeID == op_call_eval) {
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
compileOpCallEvalSetupArgs(instruction);
- emitCTICall(Interpreter::cti_op_call_eval);
- wasEval = jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+ emitCTICall(JITStubs::cti_op_call_eval);
+ wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
}
// This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
// This deliberately leaves the callee in ecx, used when setting up the stack frame below
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
DataLabelPtr addressOfLinkedFunctionCheck;
- Jump jumpToSlow = jnePtrWithPatch(X86::ecx, addressOfLinkedFunctionCheck, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+ Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT2, addressOfLinkedFunctionCheck, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
addSlowCase(jumpToSlow);
ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump);
m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
@@ -226,25 +220,25 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
int proto = instruction[5].u.operand;
int thisRegister = instruction[6].u.operand;
- emitPutJITStubArg(X86::ecx, 1);
- emitPutJITStubArgFromVirtualRegister(proto, 4, X86::eax);
- emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitPutJITStubArg(regT2, 1);
+ emitPutJITStubArgFromVirtualRegister(proto, 4, regT0);
+ emitCTICall(JITStubs::cti_op_construct_JSConstruct);
emitPutVirtualRegister(thisRegister);
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
}
// Fast version of stack frame initialization, directly relative to edi.
// Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
storePtr(ImmPtr(JSValuePtr::encode(noValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register))));
- storePtr(X86::ecx, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain
+ storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
+ loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), regT1); // newScopeChain
store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
- storePtr(X86::edx, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
+ storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister);
// Call to the callee
- m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(reinterpret_cast<void*>(unreachable));
+ m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(reinterpret_cast<void*>(0));
if (opcodeID == op_call_eval)
wasEval.link(this);
@@ -271,24 +265,24 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
compileOpConstructSetupArgs(instruction);
// Fast check for JS function.
- Jump callLinkFailNotObject = emitJumpIfNotJSCell(X86::ecx);
- Jump callLinkFailNotJSFunction = jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr));
+ Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT2);
+ Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr));
// First, in the case of a construct, allocate the new object.
if (opcodeID == op_construct) {
- emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitCTICall(JITStubs::cti_op_construct_JSConstruct);
emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
}
- move(Imm32(argCount), X86::edx);
+ move(Imm32(argCount), regT1);
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation =
- emitNakedCall(m_interpreter->m_ctiVirtualCallPreLink);
+ emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink());
Jump storeResultForFirstRun = jump();
@@ -303,14 +297,14 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
compileOpConstructSetupArgs(instruction);
// Check for JSFunctions.
- Jump isNotObject = emitJumpIfNotJSCell(X86::ecx);
- Jump isJSFunction = jePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr));
+ Jump isNotObject = emitJumpIfNotJSCell(regT2);
+ Jump isJSFunction = branchPtr(Equal, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr));
// This handles host functions
isNotObject.link(this);
callLinkFailNotObject.link(this);
callLinkFailNotJSFunction.link(this);
- emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction));
+ emitCTICall(((opcodeID == op_construct) ? JITStubs::cti_op_construct_NotJSConstruct : JITStubs::cti_op_call_NotJSFunction));
Jump wasNotJSFunction = jump();
// Next, handle JSFunctions...
@@ -318,17 +312,17 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
// First, in the case of a construct, allocate the new object.
if (opcodeID == op_construct) {
- emitCTICall(Interpreter::cti_op_construct_JSConstruct);
+ emitCTICall(JITStubs::cti_op_construct_JSConstruct);
emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
- emitGetVirtualRegister(callee, X86::ecx);
+ emitGetVirtualRegister(callee, regT2);
}
// Speculatively roll the callframe, assuming argCount will match the arity.
storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
- move(Imm32(argCount), X86::edx);
+ move(Imm32(argCount), regT1);
- emitNakedCall(m_interpreter->m_ctiVirtualCall);
+ emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
// Put the return value in dst. In the interpreter, op_ret does this.
wasNotJSFunction.link(this);
diff --git a/JavaScriptCore/jit/JITCode.h b/JavaScriptCore/jit/JITCode.h
new file mode 100644
index 0000000..0490d0e
--- /dev/null
+++ b/JavaScriptCore/jit/JITCode.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITCode_h
+#define JITCode_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+#include "CallFrame.h"
+#include "JSValue.h"
+#include "Profiler.h"
+
+namespace JSC {
+
+ class JSGlobalData;
+ class RegisterFile;
+
+ extern "C" {
+ JSValueEncodedAsPointer* ctiTrampoline(
+#if PLATFORM(X86_64)
+ // FIXME: (bug #22910) this will force all arguments onto the stack (regparm(0) does not appear to have any effect).
+ // We can allow register passing here, and move the writes of these values into the trampoline.
+ void*, void*, void*, void*, void*, void*,
+#endif
+ void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*);
+ };
+
+ class JITCode {
+ public:
+ JITCode(void* code)
+ : code(code)
+ {
+ }
+
+ operator bool()
+ {
+ return code != 0;
+ }
+
+ void* addressForCall()
+ {
+ return code;
+ }
+
+ // This function returns the offset in bytes of 'pointerIntoCode' into
+ // this block of code. The pointer provided must be a pointer into this
+ // block of code. It is ASSERTed that no codeblock >4gb in size.
+ unsigned offsetOf(void* pointerIntoCode)
+ {
+ intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - reinterpret_cast<intptr_t>(code);
+ ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result);
+ return static_cast<unsigned>(result);
+ }
+
+ // Execute the code!
+ inline JSValuePtr execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValuePtr* exception)
+ {
+ return JSValuePtr::decode(ctiTrampoline(
+#if PLATFORM(X86_64)
+ 0, 0, 0, 0, 0, 0,
+#endif
+ code, registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData));
+ }
+
+ private:
+ void* code;
+ };
+
+};
+
+#endif
+
+#endif
diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h
index 7a97cd8..684c404 100644
--- a/JavaScriptCore/jit/JITInlineMethods.h
+++ b/JavaScriptCore/jit/JITInlineMethods.h
@@ -69,8 +69,8 @@ ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
if (!atJumpTarget) {
// The argument we want is already stored in eax
- if (dst != X86::eax)
- move(X86::eax, dst);
+ if (dst != cachedResultRegister)
+ move(cachedResultRegister, dst);
killLastResultRegister();
return;
}
@@ -177,7 +177,7 @@ ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeader
ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from)
{
storePtr(from, Address(callFrameRegister, dst * sizeof(Register)));
- m_lastResultBytecodeRegister = (from == X86::eax) ? dst : std::numeric_limits<int>::max();
+ m_lastResultBytecodeRegister = (from == cachedResultRegister) ? dst : std::numeric_limits<int>::max();
// FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
}
@@ -187,20 +187,11 @@ ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
// FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
}
-ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(X86::RegisterID r)
+ALWAYS_INLINE JIT::Call JIT::emitNakedCall(void* function)
{
ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
- Jump nakedCall = call(r);
- m_calls.append(CallRecord(nakedCall, m_bytecodeIndex));
- return nakedCall;
-}
-
-ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(void* function)
-{
- ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
-
- Jump nakedCall = call();
+ Call nakedCall = nearCall();
m_calls.append(CallRecord(nakedCall, m_bytecodeIndex, function));
return nakedCall;
}
@@ -208,25 +199,21 @@ ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(void* function)
#if USE(JIT_STUB_ARGUMENT_REGISTER)
ALWAYS_INLINE void JIT::restoreArgumentReference()
{
-#if PLATFORM(X86_64)
- move(X86::esp, X86::edi);
-#else
- move(X86::esp, X86::ecx);
-#endif
+ move(stackPointerRegister, firstArgumentRegister);
emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
}
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
{
// In the trampoline on x86-64, the first argument register is not overwritten.
#if !PLATFORM(X86_64)
- move(X86::esp, X86::ecx);
- addPtr(Imm32(sizeof(void*)), X86::ecx);
+ move(stackPointerRegister, firstArgumentRegister);
+ addPtr(Imm32(sizeof(void*)), firstArgumentRegister);
#endif
}
#elif USE(JIT_STUB_ARGUMENT_STACK)
ALWAYS_INLINE void JIT::restoreArgumentReference()
{
- storePtr(X86::esp, X86::esp);
+ poke(stackPointerRegister);
emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
}
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
@@ -238,7 +225,7 @@ ALWAYS_INLINE void JIT::restoreArgumentReference()
ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
#endif
-ALWAYS_INLINE JIT::Jump JIT::emitCTICall_internal(void* helper)
+ALWAYS_INLINE JIT::Call JIT::emitCTICall_internal(void* helper)
{
ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
@@ -246,7 +233,7 @@ ALWAYS_INLINE JIT::Jump JIT::emitCTICall_internal(void* helper)
sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, true);
#endif
restoreArgumentReference();
- Jump ctiCall = call();
+ Call ctiCall = call();
m_calls.append(CallRecord(ctiCall, m_bytecodeIndex, helper));
#if ENABLE(OPCODE_SAMPLING)
sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, false);
@@ -258,15 +245,15 @@ ALWAYS_INLINE JIT::Jump JIT::emitCTICall_internal(void* helper)
ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
{
- return jnePtr(Address(reg, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(structure));
+ return branchPtr(NotEqual, Address(reg, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(structure));
}
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
{
#if USE(ALTERNATE_JSIMMEDIATE)
- return jzPtr(reg, tagMaskRegister);
+ return branchTestPtr(Zero, reg, tagMaskRegister);
#else
- return jz32(reg, Imm32(JSImmediate::TagMask));
+ return branchTest32(Zero, reg, Imm32(JSImmediate::TagMask));
#endif
}
@@ -285,9 +272,9 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfJSCell(RegisterID reg)
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg)
{
#if USE(ALTERNATE_JSIMMEDIATE)
- return jnzPtr(reg, tagMaskRegister);
+ return branchTestPtr(NonZero, reg, tagMaskRegister);
#else
- return jnz32(reg, Imm32(JSImmediate::TagMask));
+ return branchTest32(NonZero, reg, Imm32(JSImmediate::TagMask));
#endif
}
@@ -311,29 +298,29 @@ ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&
#if USE(ALTERNATE_JSIMMEDIATE)
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateNumber(RegisterID reg)
{
- return jnzPtr(reg, tagTypeNumberRegister);
+ return branchTestPtr(NonZero, reg, tagTypeNumberRegister);
}
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg)
{
- return jzPtr(reg, tagTypeNumberRegister);
+ return branchTestPtr(Zero, reg, tagTypeNumberRegister);
}
#endif
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
{
#if USE(ALTERNATE_JSIMMEDIATE)
- return jaePtr(reg, tagTypeNumberRegister);
+ return branchPtr(AboveOrEqual, reg, tagTypeNumberRegister);
#else
- return jnz32(reg, Imm32(JSImmediate::TagTypeNumber));
+ return branchTest32(NonZero, reg, Imm32(JSImmediate::TagTypeNumber));
#endif
}
ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg)
{
#if USE(ALTERNATE_JSIMMEDIATE)
- return jbPtr(reg, tagTypeNumberRegister);
+ return branchPtr(Below, reg, tagTypeNumberRegister);
#else
- return jz32(reg, Imm32(JSImmediate::TagTypeNumber));
+ return branchTest32(Zero, reg, Imm32(JSImmediate::TagTypeNumber));
#endif
}
@@ -362,7 +349,7 @@ ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID reg)
{
- return jzSubPtr(Imm32(JSImmediate::TagTypeNumber), reg);
+ return branchSubPtr(Zero, Imm32(JSImmediate::TagTypeNumber), reg);
}
#endif
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp
index 6740bec..ce90ee4 100644
--- a/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -53,11 +53,11 @@ void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident,
// to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
// to jump back to if one of these trampolies finds a match.
- emitGetVirtualRegister(baseVReg, X86::eax);
+ emitGetVirtualRegister(baseVReg, regT0);
- emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(regT0, 1);
emitPutJITStubArgConstant(ident, 2);
- emitCTICall(Interpreter::cti_op_get_by_id_generic);
+ emitCTICall(JITStubs::cti_op_get_by_id_generic);
emitPutVirtualRegister(resultVReg);
}
@@ -73,12 +73,12 @@ void JIT::compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg,
// to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
// such that the Structure & offset are always at the same distance from this.
- emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx);
+ emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1);
emitPutJITStubArgConstant(ident, 2);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 3);
- emitCTICall(Interpreter::cti_op_put_by_id_generic);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 3);
+ emitCTICall(JITStubs::cti_op_put_by_id_generic);
}
void JIT::compilePutByIdSlowCase(int, Identifier*, int, Vector<SlowCaseEntry>::iterator&, unsigned)
@@ -95,21 +95,21 @@ void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier*, unsig
// to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
// to jump back to if one of these trampolies finds a match.
- emitGetVirtualRegister(baseVReg, X86::eax);
+ emitGetVirtualRegister(baseVReg, regT0);
- emitJumpSlowCaseIfNotJSCell(X86::eax, baseVReg);
+ emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
Label hotPathBegin(this);
m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
DataLabelPtr structureToCompare;
- Jump structureCheck = jnePtrWithPatch(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+ Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
addSlowCase(structureCheck);
ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure);
ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
- DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(X86::eax, patchGetByIdDefaultOffset), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);
+ DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0);
ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset);
Label putResult(this);
@@ -132,9 +132,9 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident
#ifndef NDEBUG
Label coldPathBegin(this);
#endif
- emitPutJITStubArg(X86::eax, 1);
+ emitPutJITStubArg(regT0, 1);
emitPutJITStubArgConstant(ident, 2);
- Jump call = emitCTICall(Interpreter::cti_op_get_by_id);
+ Call call = emitCTICall(JITStubs::cti_op_get_by_id);
emitPutVirtualRegister(resultVReg);
ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall);
@@ -149,22 +149,22 @@ void JIT::compilePutByIdHotPath(int baseVReg, Identifier*, int valueVReg, unsign
// to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
// such that the Structure & offset are always at the same distance from this.
- emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx);
+ emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1);
// Jump to a slow case if either the base object is an immediate, or if the Structure does not match.
- emitJumpSlowCaseIfNotJSCell(X86::eax, baseVReg);
+ emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
Label hotPathBegin(this);
m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
// It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
DataLabelPtr structureToCompare;
- addSlowCase(jnePtrWithPatch(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
+ addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure);
// Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
- DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(X86::edx, Address(X86::eax, patchGetByIdDefaultOffset));
+ loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);
+ DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset));
ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset);
}
@@ -174,9 +174,9 @@ void JIT::compilePutByIdSlowCase(int baseVReg, Identifier* ident, int, Vector<Sl
linkSlowCase(iter);
emitPutJITStubArgConstant(ident, 2);
- emitPutJITStubArg(X86::eax, 1);
- emitPutJITStubArg(X86::edx, 3);
- Jump call = emitCTICall(Interpreter::cti_op_put_by_id);
+ emitPutJITStubArg(regT0, 1);
+ emitPutJITStubArg(regT1, 3);
+ Call call = emitCTICall(JITStubs::cti_op_put_by_id);
// Track the location of the call; this will be used to recover patch information.
m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
@@ -193,54 +193,55 @@ static inline bool transitionWillNeedStorageRealloc(Structure* oldStructure, Str
return oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
}
-void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void* returnAddress)
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ProcessorReturnAddress returnAddress)
{
JumpList failureCases;
// Check eax is an object of the right Structure.
- failureCases.append(emitJumpIfNotJSCell(X86::eax));
- failureCases.append(jnePtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(oldStructure)));
+ failureCases.append(emitJumpIfNotJSCell(regT0));
+ failureCases.append(branchPtr(NotEqual, Address(regT0, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(oldStructure)));
JumpList successCases;
// ecx = baseObject
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
// proto(ecx) = baseObject->structure()->prototype()
- failureCases.append(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+ failureCases.append(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
- loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+ loadPtr(Address(regT2, FIELD_OFFSET(Structure, m_prototype)), regT2);
// ecx = baseObject->m_structure
for (RefPtr<Structure>* it = chain->head(); *it; ++it) {
// null check the prototype
- successCases.append(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(jsNull()))));
+ successCases.append(branchPtr(Equal, regT2, ImmPtr(JSValuePtr::encode(jsNull()))));
// Check the structure id
- failureCases.append(jnePtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(it->get())));
+ failureCases.append(branchPtr(NotEqual, Address(regT2, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(it->get())));
- loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
- failureCases.append(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
- loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+ loadPtr(Address(regT2, FIELD_OFFSET(JSCell, m_structure)), regT2);
+ failureCases.append(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+ loadPtr(Address(regT2, FIELD_OFFSET(Structure, m_prototype)), regT2);
}
successCases.link(this);
- Jump callTarget;
+ Call callTarget;
// emit a call only if storage realloc is needed
- if (transitionWillNeedStorageRealloc(oldStructure, newStructure)) {
+ bool willNeedStorageRealloc = transitionWillNeedStorageRealloc(oldStructure, newStructure);
+ if (willNeedStorageRealloc) {
pop(X86::ebx);
#if PLATFORM(X86_64)
- move(Imm32(newStructure->propertyStorageCapacity()), X86::edx);
+ move(Imm32(newStructure->propertyStorageCapacity()), regT1);
move(Imm32(oldStructure->propertyStorageCapacity()), X86::esi);
- move(X86::eax, X86::edi);
+ move(regT0, X86::edi);
callTarget = call();
#else
push(Imm32(newStructure->propertyStorageCapacity()));
push(Imm32(oldStructure->propertyStorageCapacity()));
- push(X86::eax);
+ push(regT0);
callTarget = call();
addPtr(Imm32(3 * sizeof(void*)), X86::esp);
#endif
- emitGetJITStubArg(3, X86::edx);
+ emitGetJITStubArg(3, regT1);
push(X86::ebx);
}
@@ -248,150 +249,144 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
// codeblock should ensure oldStructure->m_refCount > 0
sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
- storePtr(ImmPtr(newStructure), Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)));
+ storePtr(ImmPtr(newStructure), Address(regT0, FIELD_OFFSET(JSCell, m_structure)));
// write the value
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
- storePtr(X86::edx, Address(X86::eax, cachedOffset * sizeof(JSValuePtr)));
+ loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);
+ storePtr(regT1, Address(regT0, cachedOffset * sizeof(JSValuePtr)));
ret();
- Jump failureJump;
- bool plantedFailureJump = false;
- if (!failureCases.empty()) {
- failureCases.link(this);
- restoreArgumentReferenceForTrampoline();
- failureJump = jump();
- plantedFailureJump = true;
- }
+ ASSERT(!failureCases.empty());
+ failureCases.link(this);
+ restoreArgumentReferenceForTrampoline();
+ Call failureCall = tailRecursiveCall();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
- if (plantedFailureJump)
- patchBuffer.link(failureJump, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+ patchBuffer.link(failureCall, JITStubs::cti_op_put_by_id_fail);
- if (transitionWillNeedStorageRealloc(oldStructure, newStructure))
- patchBuffer.link(callTarget, reinterpret_cast<void*>(resizePropertyStorage));
-
- stubInfo->stubRoutine = code;
+ if (willNeedStorageRealloc)
+ patchBuffer.link(callTarget, resizePropertyStorage);
- Jump::patch(returnAddress, code);
+ stubInfo->stubRoutine = patchBuffer.entry();
+
+ returnAddress.relinkCallerToFunction(code);
}
-void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
// We don't want to patch more than once - in future go to cti_op_get_by_id_generic.
- // Should probably go to Interpreter::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
- Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
+ // Should probably go to JITStubs::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
+ returnAddress.relinkCallerToFunction(JITStubs::cti_op_get_by_id_self_fail);
// Patch the offset into the propoerty map to load from, then patch the Structure to look for.
- void* structureAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdStructure);
- void* displacementAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPropertyMapOffset);
- DataLabelPtr::patch(structureAddress, structure);
- DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr));
+ stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure).repatch(structure);
+ stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset).repatch(cachedOffset * sizeof(JSValuePtr));
}
-void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
// We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
- // Should probably go to Interpreter::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
- Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_generic));
+ // Should probably go to JITStubs::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
+ returnAddress.relinkCallerToFunction(JITStubs::cti_op_put_by_id_generic);
// Patch the offset into the propoerty map to load from, then patch the Structure to look for.
- void* structureAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdStructure;
- void* displacementAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdPropertyMapOffset;
- DataLabelPtr::patch(structureAddress, structure);
- DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr));
+ stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure).repatch(structure);
+ stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset).repatch(cachedOffset * sizeof(JSValuePtr));
}
-void JIT::privateCompilePatchGetArrayLength(void* returnAddress)
+void JIT::privateCompilePatchGetArrayLength(ProcessorReturnAddress returnAddress)
{
StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
// We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
- Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
+ returnAddress.relinkCallerToFunction(JITStubs::cti_op_get_by_id_array_fail);
// Check eax is an array
- Jump failureCases1 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
+ Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
// Checks out okay! - get the length from the storage
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
- load32(Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_length)), X86::ecx);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);
+ load32(Address(regT2, FIELD_OFFSET(ArrayStorage, m_length)), regT2);
- Jump failureCases2 = ja32(X86::ecx, Imm32(JSImmediate::maxImmediateInt));
+ Jump failureCases2 = branch32(Above, regT2, Imm32(JSImmediate::maxImmediateInt));
- emitFastArithIntToImmNoCheck(X86::ecx, X86::eax);
+ emitFastArithIntToImmNoCheck(regT2, regT0);
Jump success = jump();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
// Use the patch information to link the failure cases back to the original slow case routine.
- void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+ CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
patchBuffer.link(failureCases1, slowCaseBegin);
patchBuffer.link(failureCases2, slowCaseBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
- void* hotPathPutResult = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
- patchBuffer.link(success, hotPathPutResult);
+ patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = code;
+ CodeLocationLabel entryLabel = patchBuffer.entry();
+ stubInfo->stubRoutine = entryLabel;
- // Finally patch the jump to sow case back in the hot path to jump here instead.
- void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
- Jump::patch(jumpLocation, code);
+ // Finally patch the jump to slow case back in the hot path to jump here instead.
+ CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+ jumpLocation.relink(entryLabel);
}
-void JIT::privateCompileGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+void JIT::privateCompileGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
// Check eax is an object of the right Structure.
- Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
- Jump failureCases2 = checkStructure(X86::eax, structure);
+ Jump failureCases1 = emitJumpIfNotJSCell(regT0);
+ Jump failureCases2 = checkStructure(regT0, structure);
// Checks out okay! - getDirectOffset
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
- loadPtr(Address(X86::eax, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);
+ loadPtr(Address(regT0, cachedOffset * sizeof(JSValuePtr)), regT0);
ret();
+ Call failureCases1Call = makeTailRecursiveCall(failureCases1);
+ Call failureCases2Call = makeTailRecursiveCall(failureCases2);
+
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
- patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
- patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
+ patchBuffer.link(failureCases1Call, JITStubs::cti_op_get_by_id_self_fail);
+ patchBuffer.link(failureCases2Call, JITStubs::cti_op_get_by_id_self_fail);
- stubInfo->stubRoutine = code;
+ stubInfo->stubRoutine = patchBuffer.entry();
- Jump::patch(returnAddress, code);
+ returnAddress.relinkCallerToFunction(code);
}
-void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame)
{
#if USE(CTI_REPATCH_PIC)
// We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
- Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));
+ returnAddress.relinkCallerToFunction(JITStubs::cti_op_get_by_id_proto_list);
// The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
// referencing the prototype object - let's speculatively load it's table nice and early!)
JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- loadPtr(static_cast<void*>(protoPropertyStorage), X86::edx);
+ loadPtr(static_cast<void*>(protoPropertyStorage), regT1);
// Check eax is an object of the right Structure.
- Jump failureCases1 = checkStructure(X86::eax, structure);
+ Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
#if PLATFORM(X86_64)
- move(ImmPtr(prototypeStructure), X86::ebx);
- Jump failureCases2 = jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress));
+ move(ImmPtr(prototypeStructure), regT3);
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
- Jump failureCases2 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
#endif
// Checks out okay! - getDirectOffset
- loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);
Jump success = jump();
@@ -399,59 +394,59 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
PatchBuffer patchBuffer(code);
// Use the patch information to link the failure cases back to the original slow case routine.
- void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+ CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
patchBuffer.link(failureCases1, slowCaseBegin);
patchBuffer.link(failureCases2, slowCaseBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
- patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+ patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = code;
+ CodeLocationLabel entryLabel = patchBuffer.entry();
+ stubInfo->stubRoutine = entryLabel;
// Finally patch the jump to slow case back in the hot path to jump here instead.
- void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
- Jump::patch(jumpLocation, code);
+ CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+ jumpLocation.relink(entryLabel);
#else
// The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
// referencing the prototype object - let's speculatively load it's table nice and early!)
JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- loadPtr(protoPropertyStorage, X86::edx);
+ loadPtr(protoPropertyStorage, regT1);
// Check eax is an object of the right Structure.
- Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
- Jump failureCases2 = checkStructure(X86::eax, structure);
+ Jump failureCases1 = emitJumpIfNotJSCell(regT0);
+ Jump failureCases2 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
- Jump failureCases3 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases3 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
// Checks out okay! - getDirectOffset
- loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);
ret();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
- patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
- patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
- patchBuffer.link(failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
+ patchBuffer.link(failureCases1, JITStubs::cti_op_get_by_id_proto_fail);
+ patchBuffer.link(failureCases2, JITStubs::cti_op_get_by_id_proto_fail);
+ patchBuffer.link(failureCases3, JITStubs::cti_op_get_by_id_proto_fail);
- stubInfo->stubRoutine = code;
+ stubInfo->stubRoutine = patchBuffer.entry();
- Jump::patch(returnAddress, code);
+ returnAddress.relinkCallerToFunction(code);
#endif
}
#if USE(CTI_REPATCH_PIC)
void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
{
- Jump failureCase = checkStructure(X86::eax, structure);
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
- loadPtr(Address(X86::eax, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ Jump failureCase = checkStructure(regT0, structure);
+ loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);
+ loadPtr(Address(regT0, cachedOffset * sizeof(JSValuePtr)), regT0);
Jump success = jump();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
@@ -459,22 +454,23 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
PatchBuffer patchBuffer(code);
// Use the patch information to link the failure cases back to the original slow case routine.
- void* lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;
+ CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;
if (!lastProtoBegin)
- lastProtoBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+ lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
patchBuffer.link(failureCase, lastProtoBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
- patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+ patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+ CodeLocationLabel entryLabel = patchBuffer.entry();
structure->ref();
- polymorphicStructures->list[currentIndex].set(code, structure);
+ polymorphicStructures->list[currentIndex].set(entryLabel, structure);
// Finally patch the jump to slow case back in the hot path to jump here instead.
- void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
- Jump::patch(jumpLocation, code);
+ CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+ jumpLocation.relink(entryLabel);
}
void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame)
@@ -483,22 +479,22 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
// referencing the prototype object - let's speculatively load it's table nice and early!)
JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- loadPtr(protoPropertyStorage, X86::edx);
+ loadPtr(protoPropertyStorage, regT1);
// Check eax is an object of the right Structure.
- Jump failureCases1 = checkStructure(X86::eax, structure);
+ Jump failureCases1 = checkStructure(regT0, structure);
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
#if PLATFORM(X86_64)
- move(ImmPtr(prototypeStructure), X86::ebx);
- Jump failureCases2 = jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress));
+ move(ImmPtr(prototypeStructure), regT3);
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
#else
- Jump failureCases2 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+ Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
#endif
// Checks out okay! - getDirectOffset
- loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);
Jump success = jump();
@@ -506,21 +502,22 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
PatchBuffer patchBuffer(code);
// Use the patch information to link the failure cases back to the original slow case routine.
- void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+ CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
patchBuffer.link(failureCases1, lastProtoBegin);
patchBuffer.link(failureCases2, lastProtoBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
- patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+ patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+ CodeLocationLabel entryLabel = patchBuffer.entry();
structure->ref();
prototypeStructure->ref();
- prototypeStructures->list[currentIndex].set(code, structure, prototypeStructure);
+ prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure);
// Finally patch the jump to slow case back in the hot path to jump here instead.
- void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
- Jump::patch(jumpLocation, code);
+ CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+ jumpLocation.relink(entryLabel);
}
void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame)
@@ -530,7 +527,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
JumpList bucketsOfFail;
// Check eax is an object of the right Structure.
- Jump baseObjectCheck = checkStructure(X86::eax, structure);
+ Jump baseObjectCheck = checkStructure(regT0, structure);
bucketsOfFail.append(baseObjectCheck);
Structure* currStructure = structure;
@@ -543,54 +540,55 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
#if PLATFORM(X86_64)
- move(ImmPtr(currStructure), X86::ebx);
- bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+ move(ImmPtr(currStructure), regT3);
+ bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
#else
- bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+ bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
#endif
}
ASSERT(protoObject);
PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- loadPtr(protoPropertyStorage, X86::edx);
- loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(protoPropertyStorage, regT1);
+ loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);
Jump success = jump();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
// Use the patch information to link the failure cases back to the original slow case routine.
- void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+ CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
patchBuffer.link(bucketsOfFail, lastProtoBegin);
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
- patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+ patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+ CodeLocationLabel entryLabel = patchBuffer.entry();
// Track the stub we have created so that it will be deleted later.
structure->ref();
chain->ref();
- prototypeStructures->list[currentIndex].set(code, structure, chain);
+ prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
// Finally patch the jump to slow case back in the hot path to jump here instead.
- void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
- Jump::patch(jumpLocation, code);
+ CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+ jumpLocation.relink(entryLabel);
}
#endif
-void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ProcessorReturnAddress returnAddress, CallFrame* callFrame)
{
#if USE(CTI_REPATCH_PIC)
// We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
- Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));
+ returnAddress.relinkCallerToFunction(JITStubs::cti_op_get_by_id_proto_list);
ASSERT(count);
JumpList bucketsOfFail;
// Check eax is an object of the right Structure.
- bucketsOfFail.append(checkStructure(X86::eax, structure));
+ bucketsOfFail.append(checkStructure(regT0, structure));
Structure* currStructure = structure;
RefPtr<Structure>* chainEntries = chain->head();
@@ -602,45 +600,43 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
#if PLATFORM(X86_64)
- move(ImmPtr(currStructure), X86::ebx);
- bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+ move(ImmPtr(currStructure), regT3);
+ bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
#else
- bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+ bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
#endif
}
ASSERT(protoObject);
PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- loadPtr(protoPropertyStorage, X86::edx);
- loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(protoPropertyStorage, regT1);
+ loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);
Jump success = jump();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
// Use the patch information to link the failure cases back to the original slow case routine.
- void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
-
- patchBuffer.link(bucketsOfFail, slowCaseBegin);
+ patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall));
// On success return back to the hot patch code, at a point it will perform the store to dest for us.
- intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
- patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+ patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
// Track the stub we have created so that it will be deleted later.
- stubInfo->stubRoutine = code;
+ CodeLocationLabel entryLabel = patchBuffer.entry();
+ stubInfo->stubRoutine = entryLabel;
// Finally patch the jump to slow case back in the hot path to jump here instead.
- void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
- Jump::patch(jumpLocation, code);
+ CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+ jumpLocation.relink(entryLabel);
#else
ASSERT(count);
JumpList bucketsOfFail;
// Check eax is an object of the right Structure.
- bucketsOfFail.append(emitJumpIfNotJSCell(X86::eax));
- bucketsOfFail.append(checkStructure(X86::eax, structure));
+ bucketsOfFail.append(emitJumpIfNotJSCell(regT0));
+ bucketsOfFail.append(checkStructure(regT0, structure));
Structure* currStructure = structure;
RefPtr<Structure>* chainEntries = chain->head();
@@ -652,49 +648,52 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
// Check the prototype object's Structure had not changed.
Structure** prototypeStructureAddress = &(protoObject->m_structure);
#if PLATFORM(X86_64)
- move(ImmPtr(currStructure), X86::ebx);
- bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+ move(ImmPtr(currStructure), regT3);
+ bucketsOfFail.append(branchPtr(NotEqual, regT3, AbsoluteAddress(prototypeStructureAddress)));
#else
- bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+ bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
#endif
}
ASSERT(protoObject);
PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
- loadPtr(protoPropertyStorage, X86::edx);
- loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+ loadPtr(protoPropertyStorage, regT1);
+ loadPtr(Address(regT1, cachedOffset * sizeof(JSValuePtr)), regT0);
ret();
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
- patchBuffer.link(bucketsOfFail, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
+ patchBuffer.link(bucketsOfFail, JITStubs::cti_op_get_by_id_proto_fail);
- stubInfo->stubRoutine = code;
+ stubInfo->stubRoutine = patchBuffer.entry();
- Jump::patch(returnAddress, code);
+ returnAddress.relinkCallerToFunction(code);
#endif
}
-void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ProcessorReturnAddress returnAddress)
{
// Check eax is an object of the right Structure.
- Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
- Jump failureCases2 = checkStructure(X86::eax, structure);
+ Jump failureCases1 = emitJumpIfNotJSCell(regT0);
+ Jump failureCases2 = checkStructure(regT0, structure);
// checks out okay! - putDirectOffset
- loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
- storePtr(X86::edx, Address(X86::eax, cachedOffset * sizeof(JSValuePtr)));
+ loadPtr(Address(regT0, FIELD_OFFSET(JSObject, m_propertyStorage)), regT0);
+ storePtr(regT1, Address(regT0, cachedOffset * sizeof(JSValuePtr)));
ret();
+ Call failureCases1Call = makeTailRecursiveCall(failureCases1);
+ Call failureCases2Call = makeTailRecursiveCall(failureCases2);
+
void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
PatchBuffer patchBuffer(code);
- patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
- patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+ patchBuffer.link(failureCases1Call, JITStubs::cti_op_put_by_id_fail);
+ patchBuffer.link(failureCases2Call, JITStubs::cti_op_put_by_id_fail);
- stubInfo->stubRoutine = code;
+ stubInfo->stubRoutine = patchBuffer.entry();
- Jump::patch(returnAddress, code);
+ returnAddress.relinkCallerToFunction(code);
}
#endif
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
new file mode 100644
index 0000000..de528a5
--- /dev/null
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -0,0 +1,2196 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JITStubs.h"
+
+#if ENABLE(JIT)
+
+#include "Arguments.h"
+#include "CallFrame.h"
+#include "CodeBlock.h"
+#include "Collector.h"
+#include "Debugger.h"
+#include "ExceptionHelpers.h"
+#include "GlobalEvalFunction.h"
+#include "JIT.h"
+#include "JSActivation.h"
+#include "JSArray.h"
+#include "JSByteArray.h"
+#include "JSFunction.h"
+#include "JSNotAnObject.h"
+#include "JSPropertyNameIterator.h"
+#include "JSStaticScopeObject.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "Operations.h"
+#include "Parser.h"
+#include "Profiler.h"
+#include "RegExpObject.h"
+#include "RegExpPrototype.h"
+#include "Register.h"
+#include "SamplingTool.h"
+#include <stdio.h>
+
+using namespace std;
+
+namespace JSC {
+
+#if ENABLE(OPCODE_SAMPLING)
+ #define CTI_SAMPLER ARG_globalData->interpreter->sampler()
+#else
+ #define CTI_SAMPLER 0
+#endif
+
+JITStubs::JITStubs(JSGlobalData* globalData)
+ : m_ctiArrayLengthTrampoline(0)
+ , m_ctiStringLengthTrampoline(0)
+ , m_ctiVirtualCallPreLink(0)
+ , m_ctiVirtualCallLink(0)
+ , m_ctiVirtualCall(0)
+{
+ JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiArrayLengthTrampoline, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall);
+}
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+NEVER_INLINE void JITStubs::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot& slot)
+{
+ // The interpreter checks for recursion here; I do not believe this can occur in CTI.
+
+ if (!baseValue.isCell())
+ return;
+
+ // Uncacheable: give up.
+ if (!slot.isCacheable()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(JITStubs::cti_op_put_by_id_generic));
+ return;
+ }
+
+ JSCell* baseCell = asCell(baseValue);
+ Structure* structure = baseCell->structure();
+
+ if (structure->isDictionary()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(JITStubs::cti_op_put_by_id_generic));
+ return;
+ }
+
+ // If baseCell != base, then baseCell must be a proxy for another object.
+ if (baseCell != slot.base()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(JITStubs::cti_op_put_by_id_generic));
+ return;
+ }
+
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
+
+ // Cache hit: Specialize instruction and ref Structures.
+
+ // Structure transition, cache transition info
+ if (slot.type() == PutPropertySlot::NewProperty) {
+ StructureChain* prototypeChain = structure->prototypeChain(callFrame);
+ stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
+ JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress);
+ return;
+ }
+
+ stubInfo->initPutByIdReplace(structure);
+
+#if USE(CTI_REPATCH_PIC)
+ JIT::patchPutByIdReplace(stubInfo, structure, slot.cachedOffset(), returnAddress);
+#else
+ JIT::compilePutByIdReplace(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
+#endif
+}
+
+NEVER_INLINE void JITStubs::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
+{
+ // FIXME: Write a test that proves we need to check for recursion here just
+ // like the interpreter does, then add a check for recursion.
+
+ // FIXME: Cache property access for immediates.
+ if (!baseValue.isCell()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(JITStubs::cti_op_get_by_id_generic));
+ return;
+ }
+
+ JSGlobalData* globalData = &callFrame->globalData();
+
+ if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+#if USE(CTI_REPATCH_PIC)
+ JIT::compilePatchGetArrayLength(callFrame->scopeChain()->globalData, codeBlock, returnAddress);
+#else
+ ctiPatchCallByReturnAddress(returnAddress, globalData->jitStubs.ctiArrayLengthTrampoline());
+#endif
+ return;
+ }
+
+ if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+ // The tradeoff of compiling an patched inline string length access routine does not seem
+ // to pay off, so we currently only do this for arrays.
+ ctiPatchCallByReturnAddress(returnAddress, globalData->jitStubs.ctiStringLengthTrampoline());
+ return;
+ }
+
+ // Uncacheable: give up.
+ if (!slot.isCacheable()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(JITStubs::cti_op_get_by_id_generic));
+ return;
+ }
+
+ JSCell* baseCell = asCell(baseValue);
+ Structure* structure = baseCell->structure();
+
+ if (structure->isDictionary()) {
+ ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(JITStubs::cti_op_get_by_id_generic));
+ return;
+ }
+
+ // In the interpreter the last structure is trapped here; in CTI we use the
+ // *_second method to achieve a similar (but not quite the same) effect.
+
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
+
+ // Cache hit: Specialize instruction and ref Structures.
+
+ if (slot.slotBase() == baseValue) {
+ // set this up, so derefStructures can do it's job.
+ stubInfo->initGetByIdSelf(structure);
+
+#if USE(CTI_REPATCH_PIC)
+ JIT::patchGetByIdSelf(stubInfo, structure, slot.cachedOffset(), returnAddress);
+#else
+ JIT::compileGetByIdSelf(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
+#endif
+ return;
+ }
+
+ if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
+ ASSERT(slot.slotBase().isObject());
+
+ JSObject* slotBaseObject = asObject(slot.slotBase());
+
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (slotBaseObject->structure()->isDictionary())
+ slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
+
+ stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
+
+ JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
+ return;
+ }
+
+ size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
+ if (!count) {
+ stubInfo->opcodeID = op_get_by_id_generic;
+ return;
+ }
+
+ StructureChain* prototypeChain = structure->prototypeChain(callFrame);
+ stubInfo->initGetByIdChain(structure, prototypeChain);
+ JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress);
+}
+
+#endif
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#define SETUP_VA_LISTL_ARGS va_list vl_args; va_start(vl_args, args)
+#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
+#define SETUP_VA_LISTL_ARGS
+#endif
+
+#ifndef NDEBUG
+
+extern "C" {
+
+static void jscGeneratedNativeCode()
+{
+ // When executing a CTI function (which might do an allocation), we hack the return address
+ // to pretend to be executing this function, to keep stack logging tools from blowing out
+ // memory.
+}
+
+}
+
+struct StackHack {
+ ALWAYS_INLINE StackHack(void** location)
+ {
+ returnAddressLocation = location;
+ savedReturnAddress = *returnAddressLocation;
+ ctiSetReturnAddress(returnAddressLocation, reinterpret_cast<void*>(jscGeneratedNativeCode));
+ }
+ ALWAYS_INLINE ~StackHack()
+ {
+ ctiSetReturnAddress(returnAddressLocation, savedReturnAddress);
+ }
+
+ void** returnAddressLocation;
+ void* savedReturnAddress;
+};
+
+#define BEGIN_STUB_FUNCTION() SETUP_VA_LISTL_ARGS; StackHack stackHack(&STUB_RETURN_ADDRESS_SLOT)
+#define STUB_SET_RETURN_ADDRESS(address) stackHack.savedReturnAddress = address
+#define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
+
+#else
+
+#define BEGIN_STUB_FUNCTION() SETUP_VA_LISTL_ARGS
+#define STUB_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&STUB_RETURN_ADDRESS_SLOT, address);
+#define STUB_RETURN_ADDRESS STUB_RETURN_ADDRESS_SLOT
+
+#endif
+
+// The reason this is not inlined is to avoid having to do a PIC branch
+// to get the address of the ctiVMThrowTrampoline function. It's also
+// good to keep the code size down by leaving as much of the exception
+// handling code out of line as possible.
+static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
+{
+ ASSERT(globalData->exception);
+ globalData->exceptionLocation = exceptionLocation;
+ ctiSetReturnAddress(&returnAddressSlot, reinterpret_cast<void*>(ctiVMThrowTrampoline));
+}
+
+static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
+{
+ globalData->exception = createStackOverflowError(callFrame);
+ returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
+}
+
+#define VM_THROW_EXCEPTION() \
+ do { \
+ VM_THROW_EXCEPTION_AT_END(); \
+ return 0; \
+ } while (0)
+#define VM_THROW_EXCEPTION_2() \
+ do { \
+ VM_THROW_EXCEPTION_AT_END(); \
+ RETURN_PAIR(0, 0); \
+ } while (0)
+#define VM_THROW_EXCEPTION_AT_END() \
+ returnToThrowTrampoline(ARG_globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS)
+
+#define CHECK_FOR_EXCEPTION() \
+ do { \
+ if (UNLIKELY(ARG_globalData->exception != noValue())) \
+ VM_THROW_EXCEPTION(); \
+ } while (0)
+#define CHECK_FOR_EXCEPTION_AT_END() \
+ do { \
+ if (UNLIKELY(ARG_globalData->exception != noValue())) \
+ VM_THROW_EXCEPTION_AT_END(); \
+ } while (0)
+#define CHECK_FOR_EXCEPTION_VOID() \
+ do { \
+ if (UNLIKELY(ARG_globalData->exception != noValue())) { \
+ VM_THROW_EXCEPTION_AT_END(); \
+ return; \
+ } \
+ } while (0)
+
+JSObject* JITStubs::cti_op_convert_this(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v1 = ARG_src1;
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSObject* result = v1.toThisObject(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+}
+
+void JITStubs::cti_op_end(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ScopeChainNode* scopeChain = ARG_callFrame->scopeChain();
+ ASSERT(scopeChain->refCount > 1);
+ scopeChain->deref();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_add(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v1 = ARG_src1;
+ JSValuePtr v2 = ARG_src2;
+
+ double left;
+ double right = 0.0;
+
+ bool rightIsNumber = v2.getNumber(right);
+ if (rightIsNumber && v1.getNumber(left))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left + right));
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ bool leftIsString = v1.isString();
+ if (leftIsString && v2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
+ if (UNLIKELY(!value)) {
+ throwOutOfMemoryError(callFrame);
+ VM_THROW_EXCEPTION();
+ }
+
+ return JSValuePtr::encode(jsString(ARG_globalData, value.release()));
+ }
+
+ if (rightIsNumber & leftIsString) {
+ RefPtr<UString::Rep> value = v2.isInt32Fast() ?
+ concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
+ concatenate(asString(v1)->value().rep(), right);
+
+ if (UNLIKELY(!value)) {
+ throwOutOfMemoryError(callFrame);
+ VM_THROW_EXCEPTION();
+ }
+ return JSValuePtr::encode(jsString(ARG_globalData, value.release()));
+ }
+
+ // All other cases are pretty uncommon
+ JSValuePtr result = jsAddSlowCase(callFrame, v1, v2);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_pre_inc(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, v.toNumber(callFrame) + 1);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+int JITStubs::cti_timeout_check(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSGlobalData* globalData = ARG_globalData;
+ TimeoutChecker& timeoutChecker = globalData->timeoutChecker;
+
+ if (timeoutChecker.didTimeOut(ARG_callFrame)) {
+ globalData->exception = createInterruptedExecutionException(globalData);
+ VM_THROW_EXCEPTION_AT_END();
+ }
+
+ return timeoutChecker.ticksUntilNextCheck();
+}
+
+void JITStubs::cti_register_file_check(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->m_numCalleeRegisters)))
+ return;
+
+ // Rewind to the previous call frame because op_call already optimistically
+ // moved the call frame forward.
+ CallFrame* oldCallFrame = ARG_callFrame->callerFrame();
+ ARG_setCallFrame(oldCallFrame);
+ throwStackOverflowError(oldCallFrame, ARG_globalData, oldCallFrame->returnPC(), STUB_RETURN_ADDRESS);
+}
+
+int JITStubs::cti_op_loop_if_less(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+ CallFrame* callFrame = ARG_callFrame;
+
+ bool result = jsLess(callFrame, src1, src2);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+}
+
+int JITStubs::cti_op_loop_if_lesseq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+ CallFrame* callFrame = ARG_callFrame;
+
+ bool result = jsLessEq(callFrame, src1, src2);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+}
+
+JSObject* JITStubs::cti_op_new_object(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return constructEmptyObject(ARG_callFrame);
+}
+
+void JITStubs::cti_op_put_by_id_generic(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ PutPropertySlot slot;
+ ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_generic(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+void JITStubs::cti_op_put_by_id(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
+
+ PutPropertySlot slot;
+ ARG_src1.put(callFrame, ident, ARG_src3, slot);
+
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_id_second));
+
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+void JITStubs::cti_op_put_by_id_second(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ PutPropertySlot slot;
+ ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
+ tryCachePutByID(ARG_callFrame, ARG_callFrame->codeBlock(), STUB_RETURN_ADDRESS, ARG_src1, slot);
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+void JITStubs::cti_op_put_by_id_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
+
+ PutPropertySlot slot;
+ ARG_src1.put(callFrame, ident, ARG_src3, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
+
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_second));
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_second(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
+
+ tryCacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_self_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ Identifier& ident = *ARG_id2;
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(callFrame, ident, slot);
+
+ CHECK_FOR_EXCEPTION();
+
+ if (baseValue.isCell()
+ && slot.isCacheable()
+ && !asCell(baseValue)->structure()->isDictionary()
+ && slot.slotBase() == baseValue) {
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+ ASSERT(slot.slotBase().isObject());
+
+ PolymorphicAccessStructureList* polymorphicStructureList;
+ int listIndex = 1;
+
+ if (stubInfo->opcodeID == op_get_by_id_self) {
+ ASSERT(!stubInfo->stubRoutine);
+ polymorphicStructureList = new PolymorphicAccessStructureList(MacroAssembler::CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
+ stubInfo->initGetByIdSelfList(polymorphicStructureList, 2);
+ } else {
+ polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
+ listIndex = stubInfo->u.getByIdSelfList.listSize;
+ stubInfo->u.getByIdSelfList.listSize++;
+ }
+
+ JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
+
+ if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ } else {
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
+ }
+ return JSValuePtr::encode(result);
+}
+
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
+{
+ PolymorphicAccessStructureList* prototypeStructureList = 0;
+ listIndex = 1;
+
+ switch (stubInfo->opcodeID) {
+ case op_get_by_id_proto:
+ prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
+ stubInfo->stubRoutine.reset();
+ stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+ break;
+ case op_get_by_id_chain:
+ prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
+ stubInfo->stubRoutine.reset();
+ stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+ break;
+ case op_get_by_id_proto_list:
+ prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
+ listIndex = stubInfo->u.getByIdProtoList.listSize;
+ stubInfo->u.getByIdProtoList.listSize++;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
+ return prototypeStructureList;
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_proto_list(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION();
+
+ if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
+ return JSValuePtr::encode(result);
+ }
+
+ Structure* structure = asCell(baseValue)->structure();
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+ ASSERT(slot.slotBase().isObject());
+ JSObject* slotBaseObject = asObject(slot.slotBase());
+
+ if (slot.slotBase() == baseValue)
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
+ else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) {
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (slotBaseObject->structure()->isDictionary())
+ slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure()));
+
+ int listIndex;
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+
+ JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset());
+
+ if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full));
+ } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) {
+ int listIndex;
+ PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+ JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, structure->prototypeChain(callFrame), count, slot.cachedOffset());
+
+ if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full));
+ } else
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
+
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_proto_list_full(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_proto_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_array_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_id_string_fail(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr baseValue = ARG_src1;
+ PropertySlot slot(baseValue);
+ JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+#endif
+
+JSValueEncodedAsPointer* JITStubs::cti_op_instanceof(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr value = ARG_src1;
+ JSValuePtr baseVal = ARG_src2;
+ JSValuePtr proto = ARG_src3;
+
+ // at least one of these checks must have failed to get to the slow case
+ ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
+ || !value.isObject() || !baseVal.isObject() || !proto.isObject()
+ || (asObject(baseVal)->structure()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance);
+
+ if (!baseVal.isObject()) {
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION();
+ }
+
+ JSObject* baseObj = asObject(baseVal);
+ TypeInfo typeInfo = baseObj->structure()->typeInfo();
+ if (!typeInfo.implementsHasInstance())
+ return JSValuePtr::encode(jsBoolean(false));
+
+ if (!typeInfo.overridesHasInstance()) {
+ if (!proto.isObject()) {
+ throwError(callFrame, TypeError, "instanceof called on an object with an invalid prototype property.");
+ VM_THROW_EXCEPTION();
+ }
+
+ if (!value.isObject())
+ return JSValuePtr::encode(jsBoolean(false));
+ }
+
+ JSValuePtr result = jsBoolean(baseObj->hasInstance(callFrame, value, proto));
+ CHECK_FOR_EXCEPTION_AT_END();
+
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_del_by_id(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSObject* baseObj = ARG_src1.toObject(callFrame);
+
+ JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, *ARG_id2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_mul(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ double left;
+ double right;
+ if (src1.getNumber(left) && src2.getNumber(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left * right));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) * src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSObject* JITStubs::cti_op_new_func(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return ARG_func1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());
+}
+
+void* JITStubs::cti_op_call_JSFunction(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+#ifndef NDEBUG
+ CallData callData;
+ ASSERT(ARG_src1.getCallData(callData) == CallTypeJS);
+#endif
+
+ ScopeChainNode* callDataScopeChain = asFunction(ARG_src1)->scope().node();
+ CodeBlock* newCodeBlock = &asFunction(ARG_src1)->body()->bytecode(callDataScopeChain);
+
+ if (!newCodeBlock->jitCode())
+ JIT::compile(ARG_globalData, newCodeBlock);
+
+ return newCodeBlock;
+}
+
+VoidPtrPair JITStubs::cti_op_call_arityCheck(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* newCodeBlock = ARG_codeBlock4;
+ int argCount = ARG_int3;
+
+ ASSERT(argCount != newCodeBlock->m_numParameters);
+
+ CallFrame* oldCallFrame = callFrame->callerFrame();
+
+ if (argCount > newCodeBlock->m_numParameters) {
+ size_t numParameters = newCodeBlock->m_numParameters;
+ Register* r = callFrame->registers() + numParameters;
+
+ Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
+ for (size_t i = 0; i < numParameters; ++i)
+ argv[i + argCount] = argv[i];
+
+ callFrame = CallFrame::create(r);
+ callFrame->setCallerFrame(oldCallFrame);
+ } else {
+ size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
+ Register* r = callFrame->registers() + omittedArgCount;
+ Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
+ if (!ARG_registerFile->grow(newEnd)) {
+ // Rewind to the previous call frame because op_call already optimistically
+ // moved the call frame forward.
+ ARG_setCallFrame(oldCallFrame);
+ throwStackOverflowError(oldCallFrame, ARG_globalData, ARG_returnAddress2, STUB_RETURN_ADDRESS);
+ RETURN_PAIR(0, 0);
+ }
+
+ Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
+ for (size_t i = 0; i < omittedArgCount; ++i)
+ argv[i] = jsUndefined();
+
+ callFrame = CallFrame::create(r);
+ callFrame->setCallerFrame(oldCallFrame);
+ }
+
+ RETURN_PAIR(newCodeBlock, callFrame);
+}
+
+void* JITStubs::cti_vm_dontLazyLinkCall(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSGlobalData* globalData = ARG_globalData;
+ JSFunction* callee = asFunction(ARG_src1);
+ CodeBlock* codeBlock = &callee->body()->bytecode(callee->scope().node());
+ if (!codeBlock->jitCode())
+ JIT::compile(globalData, codeBlock);
+
+ ctiPatchNearCallByReturnAddress(ARG_returnAddress2, globalData->jitStubs.ctiVirtualCallLink());
+
+ return codeBlock->jitCode().addressForCall();
+}
+
+void* JITStubs::cti_vm_lazyLinkCall(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSFunction* callee = asFunction(ARG_src1);
+ CodeBlock* codeBlock = &callee->body()->bytecode(callee->scope().node());
+ if (!codeBlock->jitCode())
+ JIT::compile(ARG_globalData, codeBlock);
+
+ CallLinkInfo* callLinkInfo = &ARG_callFrame->callerFrame()->codeBlock()->getCallLinkInfo(ARG_returnAddress2);
+ JIT::linkCall(callee, codeBlock, codeBlock->jitCode(), callLinkInfo, ARG_int3);
+
+ return codeBlock->jitCode().addressForCall();
+}
+
+JSObject* JITStubs::cti_op_push_activation(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSActivation* activation = new (ARG_globalData) JSActivation(ARG_callFrame, static_cast<FunctionBodyNode*>(ARG_callFrame->codeBlock()->ownerNode()));
+ ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->copy()->push(activation));
+ return activation;
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_call_NotJSFunction(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr funcVal = ARG_src1;
+
+ CallData callData;
+ CallType callType = funcVal.getCallData(callData);
+
+ ASSERT(callType != CallTypeJS);
+
+ if (callType == CallTypeHost) {
+ int registerOffset = ARG_int2;
+ int argCount = ARG_int3;
+ CallFrame* previousCallFrame = ARG_callFrame;
+ CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
+
+ callFrame->init(0, static_cast<Instruction*>(STUB_RETURN_ADDRESS), previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0);
+ ARG_setCallFrame(callFrame);
+
+ Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
+ ArgList argList(argv + 1, argCount - 1);
+
+ JSValuePtr returnValue;
+ {
+ SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
+
+ // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
+ JSValuePtr thisValue = argv[0].jsValue(callFrame);
+ if (thisValue == jsNull())
+ thisValue = callFrame->globalThisValue();
+
+ returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList);
+ }
+ ARG_setCallFrame(previousCallFrame);
+ CHECK_FOR_EXCEPTION();
+
+ return JSValuePtr::encode(returnValue);
+ }
+
+ ASSERT(callType == CallTypeNone);
+
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createNotAFunctionError(ARG_callFrame, funcVal, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION();
+}
+
+void JITStubs::cti_op_create_arguments(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame);
+ ARG_callFrame->setCalleeArguments(arguments);
+ ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;
+}
+
+void JITStubs::cti_op_create_arguments_no_params(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame, Arguments::NoParameters);
+ ARG_callFrame->setCalleeArguments(arguments);
+ ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;
+}
+
+void JITStubs::cti_op_tear_off_activation(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain());
+ asActivation(ARG_src1)->copyRegisters(ARG_callFrame->optionalCalleeArguments());
+}
+
+void JITStubs::cti_op_tear_off_arguments(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ASSERT(ARG_callFrame->codeBlock()->usesArguments() && !ARG_callFrame->codeBlock()->needsFullScopeChain());
+ ARG_callFrame->optionalCalleeArguments()->copyRegisters();
+}
+
+void JITStubs::cti_op_profile_will_call(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ASSERT(*ARG_profilerReference);
+ (*ARG_profilerReference)->willExecute(ARG_callFrame, ARG_src1);
+}
+
+void JITStubs::cti_op_profile_did_call(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ASSERT(*ARG_profilerReference);
+ (*ARG_profilerReference)->didExecute(ARG_callFrame, ARG_src1);
+}
+
+void JITStubs::cti_op_ret_scopeChain(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain());
+ ARG_callFrame->scopeChain()->deref();
+}
+
+JSObject* JITStubs::cti_op_new_array(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ArgList argList(&ARG_callFrame->registers()[ARG_int1], ARG_int2);
+ return constructArray(ARG_callFrame, argList);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_resolve(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+ ScopeChainIterator iter = scopeChain->begin();
+ ScopeChainIterator end = scopeChain->end();
+ ASSERT(iter != end);
+
+ Identifier& ident = *ARG_id1;
+ do {
+ JSObject* o = *iter;
+ PropertySlot slot(o);
+ if (o->getPropertySlot(callFrame, ident, slot)) {
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+ }
+ } while (++iter != end);
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION();
+}
+
+JSObject* JITStubs::cti_op_construct_JSConstruct(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+#ifndef NDEBUG
+ ConstructData constructData;
+ ASSERT(asFunction(ARG_src1)->getConstructData(constructData) == ConstructTypeJS);
+#endif
+
+ Structure* structure;
+ if (ARG_src4.isObject())
+ structure = asObject(ARG_src4)->inheritorID();
+ else
+ structure = asFunction(ARG_src1)->scope().node()->globalObject()->emptyObjectStructure();
+ return new (ARG_globalData) JSObject(structure);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_construct_NotJSConstruct(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr constrVal = ARG_src1;
+ int argCount = ARG_int3;
+ int thisRegister = ARG_int5;
+
+ ConstructData constructData;
+ ConstructType constructType = constrVal.getConstructData(constructData);
+
+ if (constructType == ConstructTypeHost) {
+ ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1);
+
+ JSValuePtr returnValue;
+ {
+ SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
+ returnValue = constructData.native.function(callFrame, asObject(constrVal), argList);
+ }
+ CHECK_FOR_EXCEPTION();
+
+ return JSValuePtr::encode(returnValue);
+ }
+
+ ASSERT(constructType == ConstructTypeNone);
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_val(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSGlobalData* globalData = ARG_globalData;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+
+ JSValuePtr result;
+
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (isJSArray(globalData, baseValue)) {
+ JSArray* jsArray = asArray(baseValue);
+ if (jsArray->canGetIndex(i))
+ result = jsArray->getIndex(i);
+ else
+ result = jsArray->JSArray::get(callFrame, i);
+ } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
+ result = asString(baseValue)->getIndex(ARG_globalData, i);
+ else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val_byte_array));
+ return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i));
+ } else
+ result = baseValue.get(callFrame, i);
+ } else {
+ Identifier property(callFrame, subscript.toString(callFrame));
+ result = baseValue.get(callFrame, property);
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_get_by_val_byte_array(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSGlobalData* globalData = ARG_globalData;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+
+ JSValuePtr result;
+
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i));
+ }
+
+ result = baseValue.get(callFrame, i);
+ if (!isJSByteArray(globalData, baseValue))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val));
+ } else {
+ Identifier property(callFrame, subscript.toString(callFrame));
+ result = baseValue.get(callFrame, property);
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+VoidPtrPair JITStubs::cti_op_resolve_func(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+ ScopeChainIterator iter = scopeChain->begin();
+ ScopeChainIterator end = scopeChain->end();
+
+ // FIXME: add scopeDepthIsZero optimization
+
+ ASSERT(iter != end);
+
+ Identifier& ident = *ARG_id1;
+ JSObject* base;
+ do {
+ base = *iter;
+ PropertySlot slot(base);
+ if (base->getPropertySlot(callFrame, ident, slot)) {
+ // ECMA 11.2.3 says that if we hit an activation the this value should be null.
+ // However, section 10.2.3 says that in the case where the value provided
+ // by the caller is null, the global object should be used. It also says
+ // that the section does not apply to internal functions, but for simplicity
+ // of implementation we use the global object anyway here. This guarantees
+ // that in host objects you always get a valid object for this.
+ // We also handle wrapper substitution for the global object at the same time.
+ JSObject* thisObj = base->toThisObject(callFrame);
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
+
+ RETURN_PAIR(thisObj, JSValuePtr::encode(result));
+ }
+ ++iter;
+ } while (iter != end);
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION_2();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_sub(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ double left;
+ double right;
+ if (src1.getNumber(left) && src2.getNumber(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left - right));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) - src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+void JITStubs::cti_op_put_by_val(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSGlobalData* globalData = ARG_globalData;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+ JSValuePtr value = ARG_src3;
+
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (isJSArray(globalData, baseValue)) {
+ JSArray* jsArray = asArray(baseValue);
+ if (jsArray->canSetIndex(i))
+ jsArray->setIndex(i, value);
+ else
+ jsArray->JSArray::put(callFrame, i, value);
+ } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ JSByteArray* jsByteArray = asByteArray(baseValue);
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_val_byte_array));
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ if (value.isInt32Fast()) {
+ jsByteArray->setIndex(i, value.getInt32Fast());
+ return;
+ } else {
+ double dValue = 0;
+ if (value.getNumber(dValue)) {
+ jsByteArray->setIndex(i, dValue);
+ return;
+ }
+ }
+
+ baseValue.put(callFrame, i, value);
+ } else
+ baseValue.put(callFrame, i, value);
+ } else {
+ Identifier property(callFrame, subscript.toString(callFrame));
+ if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
+ PutPropertySlot slot;
+ baseValue.put(callFrame, property, value, slot);
+ }
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+void JITStubs::cti_op_put_by_val_array(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr baseValue = ARG_src1;
+ int i = ARG_int2;
+ JSValuePtr value = ARG_src3;
+
+ ASSERT(isJSArray(ARG_globalData, baseValue));
+
+ if (LIKELY(i >= 0))
+ asArray(baseValue)->JSArray::put(callFrame, i, value);
+ else {
+ // This should work since we're re-boxing an immediate unboxed in JIT code.
+ ASSERT(JSValuePtr::makeInt32Fast(i));
+ Identifier property(callFrame, JSValuePtr::makeInt32Fast(i).toString(callFrame));
+ // FIXME: can toString throw an exception here?
+ if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
+ PutPropertySlot slot;
+ baseValue.put(callFrame, property, value, slot);
+ }
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+void JITStubs::cti_op_put_by_val_byte_array(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSGlobalData* globalData = ARG_globalData;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSValuePtr subscript = ARG_src2;
+ JSValuePtr value = ARG_src3;
+
+ if (LIKELY(subscript.isUInt32Fast())) {
+ uint32_t i = subscript.getUInt32Fast();
+ if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+ JSByteArray* jsByteArray = asByteArray(baseValue);
+
+ // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+ if (value.isInt32Fast()) {
+ jsByteArray->setIndex(i, value.getInt32Fast());
+ return;
+ } else {
+ double dValue = 0;
+ if (value.getNumber(dValue)) {
+ jsByteArray->setIndex(i, dValue);
+ return;
+ }
+ }
+ }
+
+ if (!isJSByteArray(globalData, baseValue))
+ ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_val));
+ baseValue.put(callFrame, i, value);
+ } else {
+ Identifier property(callFrame, subscript.toString(callFrame));
+ if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
+ PutPropertySlot slot;
+ baseValue.put(callFrame, property, value, slot);
+ }
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_lesseq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsBoolean(jsLessEq(callFrame, ARG_src1, ARG_src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+int JITStubs::cti_op_loop_if_true(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ bool result = src1.toBoolean(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_negate(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src = ARG_src1;
+
+ double v;
+ if (src.getNumber(v))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, -v));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, -src.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_resolve_base(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(JSC::resolveBase(ARG_callFrame, *ARG_id1, ARG_callFrame->scopeChain()));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_resolve_skip(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+ int skip = ARG_int2;
+
+ ScopeChainIterator iter = scopeChain->begin();
+ ScopeChainIterator end = scopeChain->end();
+ ASSERT(iter != end);
+ while (skip--) {
+ ++iter;
+ ASSERT(iter != end);
+ }
+ Identifier& ident = *ARG_id1;
+ do {
+ JSObject* o = *iter;
+ PropertySlot slot(o);
+ if (o->getPropertySlot(callFrame, ident, slot)) {
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+ }
+ } while (++iter != end);
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_resolve_global(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSGlobalObject* globalObject = asGlobalObject(ARG_src1);
+ Identifier& ident = *ARG_id2;
+ unsigned globalResolveInfoIndex = ARG_int3;
+ ASSERT(globalObject->isGlobalObject());
+
+ PropertySlot slot(globalObject);
+ if (globalObject->getPropertySlot(callFrame, ident, slot)) {
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ if (slot.isCacheable() && !globalObject->structure()->isDictionary()) {
+ GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
+ if (globalResolveInfo.structure)
+ globalResolveInfo.structure->deref();
+ globalObject->structure()->ref();
+ globalResolveInfo.structure = globalObject->structure();
+ globalResolveInfo.offset = slot.cachedOffset();
+ return JSValuePtr::encode(result);
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+ }
+
+ unsigned vPCIndex = callFrame->codeBlock()->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, callFrame->codeBlock());
+ VM_THROW_EXCEPTION();
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_div(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ double left;
+ double right;
+ if (src1.getNumber(left) && src2.getNumber(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left / right));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) / src2.toNumber(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_pre_dec(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, v.toNumber(callFrame) - 1);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+int JITStubs::cti_op_jless(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+ CallFrame* callFrame = ARG_callFrame;
+
+ bool result = jsLess(callFrame, src1, src2);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_not(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr result = jsBoolean(!src.toBoolean(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+int JITStubs::cti_op_jtrue(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ bool result = src1.toBoolean(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return result;
+}
+
+VoidPtrPair JITStubs::cti_op_post_inc(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr number = v.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+
+ RETURN_PAIR(JSValuePtr::encode(number), JSValuePtr::encode(jsNumber(ARG_globalData, number.uncheckedGetNumber() + 1)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_eq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ ASSERT(!JSValuePtr::areBothInt32Fast(src1, src2));
+ JSValuePtr result = jsBoolean(JSValuePtr::equalSlowCaseInline(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_lshift(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr val = ARG_src1;
+ JSValuePtr shift = ARG_src2;
+
+ int32_t left;
+ uint32_t right;
+ if (JSValuePtr::areBothInt32Fast(val, shift))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f)));
+ if (val.numberToInt32(left) && shift.numberToUInt32(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left << (right & 0x1f)));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_bitand(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ int32_t left;
+ int32_t right;
+ if (src1.numberToInt32(left) && src2.numberToInt32(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left & right));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) & src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_rshift(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr val = ARG_src1;
+ JSValuePtr shift = ARG_src2;
+
+ int32_t left;
+ uint32_t right;
+ if (JSFastMath::canDoFastRshift(val, shift))
+ return JSValuePtr::encode(JSFastMath::rightShiftImmediateNumbers(val, shift));
+ if (val.numberToInt32(left) && shift.numberToUInt32(right))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, left >> (right & 0x1f)));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_bitnot(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src = ARG_src1;
+
+ int value;
+ if (src.numberToInt32(value))
+ return JSValuePtr::encode(jsNumber(ARG_globalData, ~value));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsNumber(ARG_globalData, ~src.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+VoidPtrPair JITStubs::cti_op_resolve_with_base(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+ ScopeChainIterator iter = scopeChain->begin();
+ ScopeChainIterator end = scopeChain->end();
+
+ // FIXME: add scopeDepthIsZero optimization
+
+ ASSERT(iter != end);
+
+ Identifier& ident = *ARG_id1;
+ JSObject* base;
+ do {
+ base = *iter;
+ PropertySlot slot(base);
+ if (base->getPropertySlot(callFrame, ident, slot)) {
+ JSValuePtr result = slot.getValue(callFrame, ident);
+ CHECK_FOR_EXCEPTION_AT_END();
+
+ RETURN_PAIR(base, JSValuePtr::encode(result));
+ }
+ ++iter;
+ } while (iter != end);
+
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION_2();
+}
+
+JSObject* JITStubs::cti_op_new_func_exp(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return ARG_funcexp1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_mod(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr dividendValue = ARG_src1;
+ JSValuePtr divisorValue = ARG_src2;
+
+ CallFrame* callFrame = ARG_callFrame;
+ double d = dividendValue.toNumber(callFrame);
+ JSValuePtr result = jsNumber(ARG_globalData, fmod(d, divisorValue.toNumber(callFrame)));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_less(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsBoolean(jsLess(callFrame, ARG_src1, ARG_src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_neq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ ASSERT(!JSValuePtr::areBothInt32Fast(src1, src2));
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr result = jsBoolean(!JSValuePtr::equalSlowCaseInline(callFrame, src1, src2));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+VoidPtrPair JITStubs::cti_op_post_dec(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v = ARG_src1;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr number = v.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+
+ RETURN_PAIR(JSValuePtr::encode(number), JSValuePtr::encode(jsNumber(ARG_globalData, number.uncheckedGetNumber() - 1)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_urshift(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr val = ARG_src1;
+ JSValuePtr shift = ARG_src2;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ if (JSFastMath::canDoFastUrshift(val, shift))
+ return JSValuePtr::encode(JSFastMath::rightShiftImmediateNumbers(val, shift));
+ else {
+ JSValuePtr result = jsNumber(ARG_globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+ }
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_bitxor(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSObject* JITStubs::cti_op_new_regexp(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return new (ARG_globalData) RegExpObject(ARG_callFrame->lexicalGlobalObject()->regExpStructure(), ARG_regexp1);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_bitor(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) | src2.toInt32(callFrame));
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_call_eval(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ RegisterFile* registerFile = ARG_registerFile;
+
+ Interpreter* interpreter = ARG_globalData->interpreter;
+
+ JSValuePtr funcVal = ARG_src1;
+ int registerOffset = ARG_int2;
+ int argCount = ARG_int3;
+
+ Register* newCallFrame = callFrame->registers() + registerOffset;
+ Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
+ JSValuePtr thisValue = argv[0].jsValue(callFrame);
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+
+ if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
+ JSValuePtr exceptionValue = noValue();
+ JSValuePtr result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
+ if (UNLIKELY(exceptionValue != noValue())) {
+ ARG_globalData->exception = exceptionValue;
+ VM_THROW_EXCEPTION_AT_END();
+ }
+ return JSValuePtr::encode(result);
+ }
+
+ return JSValuePtr::encode(jsImpossibleValue());
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_throw(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+
+ JSValuePtr exceptionValue = ARG_src1;
+ ASSERT(exceptionValue);
+
+ HandlerInfo* handler = ARG_globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, true);
+
+ if (!handler) {
+ *ARG_exception = exceptionValue;
+ return JSValuePtr::encode(jsNull());
+ }
+
+ ARG_setCallFrame(callFrame);
+ void* catchRoutine = handler->nativeCode.addressForExceptionHandler();
+ ASSERT(catchRoutine);
+ STUB_SET_RETURN_ADDRESS(catchRoutine);
+ return JSValuePtr::encode(exceptionValue);
+}
+
+JSPropertyNameIterator* JITStubs::cti_op_get_pnames(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSPropertyNameIterator::create(ARG_callFrame, ARG_src1);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_next_pname(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSPropertyNameIterator* it = ARG_pni1;
+ JSValuePtr temp = it->next(ARG_callFrame);
+ if (!temp)
+ it->invalidate();
+ return JSValuePtr::encode(temp);
+}
+
+JSObject* JITStubs::cti_op_push_scope(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSObject* o = ARG_src1.toObject(ARG_callFrame);
+ CHECK_FOR_EXCEPTION();
+ ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->push(o));
+ return o;
+}
+
+void JITStubs::cti_op_pop_scope(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->pop());
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_typeof(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(jsTypeStringForValue(ARG_callFrame, ARG_src1));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_is_undefined(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr v = ARG_src1;
+ return JSValuePtr::encode(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_is_boolean(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(jsBoolean(ARG_src1.isBoolean()));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_is_number(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(jsBoolean(ARG_src1.isNumber()));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_is_string(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(jsBoolean(isJSString(ARG_globalData, ARG_src1)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_is_object(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(jsBoolean(jsIsObjectType(ARG_src1)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_is_function(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ return JSValuePtr::encode(jsBoolean(jsIsFunctionType(ARG_src1)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_stricteq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ return JSValuePtr::encode(jsBoolean(JSValuePtr::strictEqual(src1, src2)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_nstricteq(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src1 = ARG_src1;
+ JSValuePtr src2 = ARG_src2;
+
+ return JSValuePtr::encode(jsBoolean(!JSValuePtr::strictEqual(src1, src2)));
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_to_jsnumber(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr src = ARG_src1;
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr result = src.toJSNumber(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_in(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ JSValuePtr baseVal = ARG_src2;
+
+ if (!baseVal.isObject()) {
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+ ARG_globalData->exception = createInvalidParamError(callFrame, "in", baseVal, vPCIndex, codeBlock);
+ VM_THROW_EXCEPTION();
+ }
+
+ JSValuePtr propName = ARG_src1;
+ JSObject* baseObj = asObject(baseVal);
+
+ uint32_t i;
+ if (propName.getUInt32(i))
+ return JSValuePtr::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
+
+ Identifier property(callFrame, propName.toString(callFrame));
+ CHECK_FOR_EXCEPTION();
+ return JSValuePtr::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
+}
+
+JSObject* JITStubs::cti_op_push_new_scope(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSObject* scope = new (ARG_globalData) JSStaticScopeObject(ARG_callFrame, *ARG_id1, ARG_src2, DontDelete);
+
+ CallFrame* callFrame = ARG_callFrame;
+ callFrame->setScopeChain(callFrame->scopeChain()->push(scope));
+ return scope;
+}
+
+void JITStubs::cti_op_jmp_scopes(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ unsigned count = ARG_int1;
+ CallFrame* callFrame = ARG_callFrame;
+
+ ScopeChainNode* tmp = callFrame->scopeChain();
+ while (count--)
+ tmp = tmp->pop();
+ callFrame->setScopeChain(tmp);
+}
+
+void JITStubs::cti_op_put_by_index(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ unsigned property = ARG_int2;
+
+ ARG_src1.put(callFrame, property, ARG_src3);
+}
+
+void* JITStubs::cti_op_switch_imm(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr scrutinee = ARG_src1;
+ unsigned tableIndex = ARG_int2;
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+
+ if (scrutinee.isInt32Fast())
+ return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.getInt32Fast()).addressForSwitch();
+ else {
+ double value;
+ int32_t intValue;
+ if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value))
+ return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(intValue).addressForSwitch();
+ else
+ return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.addressForSwitch();
+ }
+}
+
+void* JITStubs::cti_op_switch_char(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr scrutinee = ARG_src1;
+ unsigned tableIndex = ARG_int2;
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+
+ void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.addressForSwitch();
+
+ if (scrutinee.isString()) {
+ UString::Rep* value = asString(scrutinee)->value().rep();
+ if (value->size() == 1)
+ result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).addressForSwitch();
+ }
+
+ return result;
+}
+
+void* JITStubs::cti_op_switch_string(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ JSValuePtr scrutinee = ARG_src1;
+ unsigned tableIndex = ARG_int2;
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+
+ void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.addressForSwitch();
+
+ if (scrutinee.isString()) {
+ UString::Rep* value = asString(scrutinee)->value().rep();
+ result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).addressForSwitch();
+ }
+
+ return result;
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_op_del_by_val(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ JSValuePtr baseValue = ARG_src1;
+ JSObject* baseObj = baseValue.toObject(callFrame); // may throw
+
+ JSValuePtr subscript = ARG_src2;
+ JSValuePtr result;
+ uint32_t i;
+ if (subscript.getUInt32(i))
+ result = jsBoolean(baseObj->deleteProperty(callFrame, i));
+ else {
+ CHECK_FOR_EXCEPTION();
+ Identifier property(callFrame, subscript.toString(callFrame));
+ CHECK_FOR_EXCEPTION();
+ result = jsBoolean(baseObj->deleteProperty(callFrame, property));
+ }
+
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValuePtr::encode(result);
+}
+
+void JITStubs::cti_op_put_getter(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ ASSERT(ARG_src1.isObject());
+ JSObject* baseObj = asObject(ARG_src1);
+ ASSERT(ARG_src3.isObject());
+ baseObj->defineGetter(callFrame, *ARG_id2, asObject(ARG_src3));
+}
+
+void JITStubs::cti_op_put_setter(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ ASSERT(ARG_src1.isObject());
+ JSObject* baseObj = asObject(ARG_src1);
+ ASSERT(ARG_src3.isObject());
+ baseObj->defineSetter(callFrame, *ARG_id2, asObject(ARG_src3));
+}
+
+JSObject* JITStubs::cti_op_new_error(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ unsigned type = ARG_int1;
+ JSValuePtr message = ARG_src2;
+ unsigned bytecodeOffset = ARG_int3;
+
+ unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
+ return Error::create(callFrame, static_cast<ErrorType>(type), message.toString(callFrame), lineNumber, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+}
+
+void JITStubs::cti_op_debug(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+
+ int debugHookID = ARG_int1;
+ int firstLine = ARG_int2;
+ int lastLine = ARG_int3;
+
+ ARG_globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
+}
+
+JSValueEncodedAsPointer* JITStubs::cti_vm_throw(STUB_ARGS)
+{
+ BEGIN_STUB_FUNCTION();
+
+ CallFrame* callFrame = ARG_callFrame;
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ JSGlobalData* globalData = ARG_globalData;
+
+ unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, globalData->exceptionLocation);
+
+ JSValuePtr exceptionValue = globalData->exception;
+ ASSERT(exceptionValue);
+ globalData->exception = noValue();
+
+ HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, false);
+
+ if (!handler) {
+ *ARG_exception = exceptionValue;
+ return JSValuePtr::encode(jsNull());
+ }
+
+ ARG_setCallFrame(callFrame);
+ void* catchRoutine = handler->nativeCode.addressForExceptionHandler();
+ ASSERT(catchRoutine);
+ STUB_SET_RETURN_ADDRESS(catchRoutine);
+ return JSValuePtr::encode(exceptionValue);
+}
+
+#undef STUB_RETURN_ADDRESS
+#undef STUB_SET_RETURN_ADDRESS
+#undef BEGIN_STUB_FUNCTION
+#undef CHECK_FOR_EXCEPTION
+#undef CHECK_FOR_EXCEPTION_AT_END
+#undef CHECK_FOR_EXCEPTION_VOID
+#undef VM_THROW_EXCEPTION
+#undef VM_THROW_EXCEPTION_2
+#undef VM_THROW_EXCEPTION_AT_END
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
new file mode 100644
index 0000000..b7b8f35
--- /dev/null
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITStubs_h
+#define JITStubs_h
+
+#include "Register.h"
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+ class ExecutablePool;
+ class JSGlobalData;
+ class JSObject;
+ class JSPropertyNameIterator;
+ class JSValueEncodedAsPointer;
+ class CodeBlock;
+ class JSValuePtr;
+ class Identifier;
+ class PropertySlot;
+ class PutPropertySlot;
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+ #define STUB_ARGS void* args, ...
+ #define ARGS (reinterpret_cast<void**>(vl_args) - 1)
+#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
+ #define STUB_ARGS void** args
+ #define ARGS (args)
+#endif
+
+#if USE(JIT_STUB_ARGUMENT_REGISTER)
+ #if PLATFORM(X86_64)
+ #define JIT_STUB
+ #elif COMPILER(MSVC)
+ #define JIT_STUB __fastcall
+ #elif COMPILER(GCC)
+ #define JIT_STUB __attribute__ ((fastcall))
+ #else
+ #error Need to support register calling convention in this compiler
+ #endif
+#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
+ #if COMPILER(MSVC)
+ #define JIT_STUB __cdecl
+ #else
+ #define JIT_STUB
+ #endif
+#endif
+
+// The Mac compilers are fine with this,
+#if PLATFORM(MAC)
+ struct VoidPtrPair {
+ void* first;
+ void* second;
+ };
+#define RETURN_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
+#else
+ typedef uint64_t VoidPtrPair;
+ union VoidPtrPairValue {
+ struct { void* first; void* second; } s;
+ VoidPtrPair i;
+ };
+#define RETURN_PAIR(a,b) VoidPtrPairValue pair = {{ a, b }}; return pair.i
+#endif
+
+ class JITStubs {
+ public:
+ JITStubs(JSGlobalData*);
+
+ static JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_convert_this(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_array(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_error(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_func(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_object(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS);
+ static JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS);
+ static JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_add(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitand(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitnot(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitor(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_bitxor(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_call_eval(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_id(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_val(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_div(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_eq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_generic(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_second(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_in(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_instanceof(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_boolean(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_function(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_number(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_object(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_string(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_is_undefined(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_less(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_lesseq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_lshift(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_mod(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_mul(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_negate(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_neq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_next_pname(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_not(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_nstricteq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_dec(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_inc(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_base(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_global(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_skip(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_rshift(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_stricteq(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_sub(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_throw(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_to_jsnumber(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_typeof(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_op_urshift(STUB_ARGS);
+ static JSValueEncodedAsPointer* JIT_STUB cti_vm_throw(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_post_dec(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_post_inc(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_resolve_func(STUB_ARGS);
+ static VoidPtrPair JIT_STUB cti_op_resolve_with_base(STUB_ARGS);
+ static int JIT_STUB cti_op_jless(STUB_ARGS);
+ static int JIT_STUB cti_op_jtrue(STUB_ARGS);
+ static int JIT_STUB cti_op_loop_if_less(STUB_ARGS);
+ static int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS);
+ static int JIT_STUB cti_op_loop_if_true(STUB_ARGS);
+ static int JIT_STUB cti_timeout_check(STUB_ARGS);
+ static void JIT_STUB cti_op_create_arguments(STUB_ARGS);
+ static void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS);
+ static void JIT_STUB cti_op_debug(STUB_ARGS);
+ static void JIT_STUB cti_op_end(STUB_ARGS);
+ static void JIT_STUB cti_op_jmp_scopes(STUB_ARGS);
+ static void JIT_STUB cti_op_pop_scope(STUB_ARGS);
+ static void JIT_STUB cti_op_profile_did_call(STUB_ARGS);
+ static void JIT_STUB cti_op_profile_will_call(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_id_second(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_index(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_val(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_val_array(STUB_ARGS);
+ static void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS);
+ static void JIT_STUB cti_op_put_getter(STUB_ARGS);
+ static void JIT_STUB cti_op_put_setter(STUB_ARGS);
+ static void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS);
+ static void JIT_STUB cti_op_tear_off_activation(STUB_ARGS);
+ static void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS);
+ static void JIT_STUB cti_register_file_check(STUB_ARGS);
+ static void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS);
+ static void* JIT_STUB cti_op_switch_char(STUB_ARGS);
+ static void* JIT_STUB cti_op_switch_imm(STUB_ARGS);
+ static void* JIT_STUB cti_op_switch_string(STUB_ARGS);
+ static void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS);
+ static void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS);
+
+ static void tryCacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
+ static void tryCachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot&);
+
+ void* ctiArrayLengthTrampoline() { return m_ctiArrayLengthTrampoline; }
+ void* ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; }
+ void* ctiVirtualCallPreLink() { return m_ctiVirtualCallPreLink; }
+ void* ctiVirtualCallLink() { return m_ctiVirtualCallLink; }
+ void* ctiVirtualCall() { return m_ctiVirtualCall; }
+
+ private:
+ RefPtr<ExecutablePool> m_executablePool;
+
+ void* m_ctiArrayLengthTrampoline;
+ void* m_ctiStringLengthTrampoline;
+ void* m_ctiVirtualCallPreLink;
+ void* m_ctiVirtualCallLink;
+ void* m_ctiVirtualCall;
+ };
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITStubs_h
diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp
index 666bd58..746868b 100644
--- a/JavaScriptCore/jsc.cpp
+++ b/JavaScriptCore/jsc.cpp
@@ -54,6 +54,7 @@
#if COMPILER(MSVC) && !PLATFORM(WIN_CE)
#include <crtdbg.h>
#include <windows.h>
+#include <mmsystem.h>
#endif
#if PLATFORM(QT)
@@ -76,6 +77,17 @@ static JSValuePtr functionLoad(ExecState*, JSObject*, JSValuePtr, const ArgList&
static JSValuePtr functionReadline(ExecState*, JSObject*, JSValuePtr, const ArgList&);
static NO_RETURN JSValuePtr functionQuit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+struct Script {
+ bool isFile;
+ char *argument;
+
+ Script(bool isFile, char *argument)
+ : isFile(isFile)
+ , argument(argument)
+ {
+ }
+};
+
struct Options {
Options()
: interactive(false)
@@ -85,7 +97,7 @@ struct Options {
bool interactive;
bool dump;
- Vector<UString> fileNames;
+ Vector<Script> scripts;
Vector<UString> arguments;
};
@@ -233,9 +245,10 @@ JSValuePtr functionLoad(ExecState* exec, JSObject*, JSValuePtr, const ArgList& a
return throwError(exec, GeneralError, "Could not open file.");
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
- evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
-
- return jsUndefined();
+ Completion result = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+ if (result.complType() == Throw)
+ exec->setException(result.value());
+ return result.value();
}
JSValuePtr functionReadline(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
@@ -284,6 +297,10 @@ int main(int argc, char** argv)
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
#endif
+#if COMPILER(MSVC) && !PLATFORM(WIN_CE)
+ timeBeginPeriod(1);
+#endif
+
#if PLATFORM(QT)
QCoreApplication app(argc, argv);
#endif
@@ -310,9 +327,11 @@ static void cleanupGlobalData(JSGlobalData* globalData)
globalData->deref();
}
-static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fileNames, bool dump)
+static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump)
{
- Vector<char> script;
+ UString script;
+ UString fileName;
+ Vector<char> scriptBuffer;
if (dump)
BytecodeGenerator::setDumpsGeneratedCode(true);
@@ -323,16 +342,21 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fi
#endif
bool success = true;
- for (size_t i = 0; i < fileNames.size(); i++) {
- UString fileName = fileNames[i];
-
- if (!fillBufferWithContentsOfFile(fileName, script))
- return false; // fail early so we can catch missing files
+ for (size_t i = 0; i < scripts.size(); i++) {
+ if (scripts[i].isFile) {
+ fileName = scripts[i].argument;
+ if (!fillBufferWithContentsOfFile(fileName, scriptBuffer))
+ return false; // fail early so we can catch missing files
+ script = scriptBuffer.data();
+ } else {
+ script = scripts[i].argument;
+ fileName = "[Command Line]";
+ }
#if ENABLE(OPCODE_SAMPLING)
interpreter->sampler()->start();
#endif
- Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+ Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script, fileName));
success = success && completion.complType() != Throw;
if (dump) {
if (completion.complType() == Throw)
@@ -355,7 +379,11 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fi
return success;
}
-static void runInteractive(GlobalObject* globalObject)
+static
+#if !HAVE(READLINE)
+NO_RETURN
+#endif
+void runInteractive(GlobalObject* globalObject)
{
while (true) {
#if HAVE(READLINE)
@@ -389,15 +417,16 @@ static void runInteractive(GlobalObject* globalObject)
printf("\n");
}
-static NO_RETURN void printUsageStatement()
+static NO_RETURN void printUsageStatement(bool help = false)
{
fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
fprintf(stderr, " -d Dumps bytecode (debug builds only)\n");
+ fprintf(stderr, " -e Evaluate argument as script code\n");
fprintf(stderr, " -f Specifies a source file (deprecated)\n");
fprintf(stderr, " -h|--help Prints this help message\n");
fprintf(stderr, " -i Enables interactive mode (default if no files are specified)\n");
fprintf(stderr, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
- exit(EXIT_FAILURE);
+ exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
}
static void parseArguments(int argc, char** argv, Options& options)
@@ -408,11 +437,17 @@ static void parseArguments(int argc, char** argv, Options& options)
if (strcmp(arg, "-f") == 0) {
if (++i == argc)
printUsageStatement();
- options.fileNames.append(argv[i]);
+ options.scripts.append(Script(true, argv[i]));
+ continue;
+ }
+ if (strcmp(arg, "-e") == 0) {
+ if (++i == argc)
+ printUsageStatement();
+ options.scripts.append(Script(false, argv[i]));
continue;
}
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
- printUsageStatement();
+ printUsageStatement(true);
}
if (strcmp(arg, "-i") == 0) {
options.interactive = true;
@@ -435,10 +470,10 @@ static void parseArguments(int argc, char** argv, Options& options)
++i;
break;
}
- options.fileNames.append(argv[i]);
+ options.scripts.append(Script(true, argv[i]));
}
- if (options.fileNames.isEmpty())
+ if (options.scripts.isEmpty())
options.interactive = true;
for (; i < argc; ++i)
@@ -453,7 +488,7 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData)
parseArguments(argc, argv, options);
GlobalObject* globalObject = new (globalData) GlobalObject(options.arguments);
- bool success = runWithScripts(globalObject, options.fileNames, options.dump);
+ bool success = runWithScripts(globalObject, options.scripts, options.dump);
if (options.interactive && success)
runInteractive(globalObject);
diff --git a/JavaScriptCore/jscore.bkl b/JavaScriptCore/jscore.bkl
index 262c883..e88b9f0 100644
--- a/JavaScriptCore/jscore.bkl
+++ b/JavaScriptCore/jscore.bkl
@@ -55,6 +55,7 @@ JavaScriptCore Bakefile project file.
<include>$(SRCDIR)</include>
<include>$(SRCDIR)/..</include>
<include>$(SRCDIR)/API</include>
+ <include>$(SRCDIR)/assembler</include>
<include>$(SRCDIR)/bytecompiler</include>
<include>$(SRCDIR)/DerivedSources/JavaScriptCore</include>
<include>$(SRCDIR)/ForwardingHeaders</include>
@@ -95,6 +96,7 @@ JavaScriptCore Bakefile project file.
<depends>jscore</depends>
<include>$(SRCDIR)</include>
<include>$(WK_ROOT)/JavaScriptCore</include>
+ <include>$(WK_ROOT)/JavaScriptCore/assembler</include>
<include>$(WK_ROOT)/JavaScriptCore/bytecompiler</include>
<include>$(WK_ROOT)/JavaScriptCore/debugger</include>
<include>$(WK_ROOT)/JavaScriptCore/parser</include>
diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp
index 22de4a0..6f65096 100644
--- a/JavaScriptCore/parser/Lexer.cpp
+++ b/JavaScriptCore/parser/Lexer.cpp
@@ -33,7 +33,6 @@
#include <string.h>
#include <wtf/ASCIICType.h>
#include <wtf/Assertions.h>
-#include <wtf/unicode/Unicode.h>
using namespace WTF;
using namespace Unicode;
@@ -80,8 +79,8 @@ Lexer::Lexer(JSGlobalData* globalData)
, m_globalData(globalData)
, m_mainTable(JSC::mainTable)
{
- m_buffer8.reserveCapacity(initialReadBufferCapacity);
- m_buffer16.reserveCapacity(initialReadBufferCapacity);
+ m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
+ m_buffer16.reserveInitialCapacity(initialReadBufferCapacity);
}
Lexer::~Lexer()
@@ -589,7 +588,7 @@ int Lexer::lex(void* p1, void* p2)
bool Lexer::isWhiteSpace() const
{
- return m_current == '\t' || m_current == 0x0b || m_current == 0x0c || isSeparatorSpace(m_current);
+ return isWhiteSpace(m_current);
}
bool Lexer::isLineTerminator()
@@ -884,11 +883,11 @@ void Lexer::clear()
m_identifiers.clear();
Vector<char> newBuffer8;
- newBuffer8.reserveCapacity(initialReadBufferCapacity);
+ newBuffer8.reserveInitialCapacity(initialReadBufferCapacity);
m_buffer8.swap(newBuffer8);
Vector<UChar> newBuffer16;
- newBuffer16.reserveCapacity(initialReadBufferCapacity);
+ newBuffer16.reserveInitialCapacity(initialReadBufferCapacity);
m_buffer16.swap(newBuffer16);
m_isReparsing = false;
diff --git a/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h
index 63d3892..63c2da9 100644
--- a/JavaScriptCore/parser/Lexer.h
+++ b/JavaScriptCore/parser/Lexer.h
@@ -27,6 +27,7 @@
#include "SegmentedVector.h"
#include "SourceCode.h"
#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
namespace JSC {
@@ -90,6 +91,16 @@ namespace JSC {
void clear();
SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine); }
+ static inline bool isWhiteSpace(int ch)
+ {
+ return ch == '\t' || ch == 0x0b || ch == 0x0c || WTF::Unicode::isSeparatorSpace(ch);
+ }
+
+ static inline bool isLineTerminator(int ch)
+ {
+ return ch == '\r' || ch == '\n' || ch == 0x2028 || ch == 0x2029;
+ }
+
private:
friend class JSGlobalData;
Lexer(JSGlobalData*);
diff --git a/JavaScriptCore/parser/Nodes.cpp b/JavaScriptCore/parser/Nodes.cpp
index 96fe50b..f7fa739 100644
--- a/JavaScriptCore/parser/Nodes.cpp
+++ b/JavaScriptCore/parser/Nodes.cpp
@@ -640,7 +640,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
}
- RefPtr<RegisterID> func = generator.tempDestination(dst);
+ RefPtr<RegisterID> func = generator.newTemporary();
RefPtr<RegisterID> thisRegister = generator.newTemporary();
int identifierStart = divot() - startOffset();
generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
@@ -1579,6 +1579,7 @@ void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
return generator.emitNode(m_next.get());
}
@@ -1589,8 +1590,6 @@ static inline RegisterID* statementListEmitCode(const StatementVector& statement
StatementVector::const_iterator end = statements.end();
for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
StatementNode* n = it->get();
- if (!n->isLoop())
- generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
generator.emitNode(dst, n);
}
return 0;
@@ -1624,8 +1623,9 @@ RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
// ------------------------------ EmptyStatementNode ---------------------------
-RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
+RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
return dst;
}
@@ -1642,6 +1642,7 @@ RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, Re
RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
ASSERT(m_expr);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
return generator.emitNode(dst, m_expr.get());
}
@@ -1660,6 +1661,7 @@ void VarStatementNode::releaseNodes(NodeReleaser& releaser)
RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
{
ASSERT(m_expr);
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
return generator.emitNode(m_expr.get());
}
@@ -1678,14 +1680,13 @@ void IfNode::releaseNodes(NodeReleaser& releaser)
RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
RefPtr<Label> afterThen = generator.newLabel();
RegisterID* cond = generator.emitNode(m_condition.get());
generator.emitJumpIfFalse(cond, afterThen.get());
- if (!m_ifBlock->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
-
generator.emitNode(dst, m_ifBlock.get());
generator.emitLabel(afterThen.get());
@@ -1708,23 +1709,19 @@ void IfElseNode::releaseNodes(NodeReleaser& releaser)
RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
RefPtr<Label> beforeElse = generator.newLabel();
RefPtr<Label> afterElse = generator.newLabel();
RegisterID* cond = generator.emitNode(m_condition.get());
generator.emitJumpIfFalse(cond, beforeElse.get());
- if (!m_ifBlock->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
-
generator.emitNode(dst, m_ifBlock.get());
generator.emitJump(afterElse.get());
generator.emitLabel(beforeElse.get());
- if (!m_elseBlock->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
-
generator.emitNode(dst, m_elseBlock.get());
generator.emitLabel(afterElse.get());
@@ -1754,10 +1751,7 @@ RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
generator.emitLabel(topOfLoop.get());
generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
-
- if (!m_statement->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-
+
RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
generator.emitLabel(scope->continueTarget());
@@ -1790,10 +1784,7 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
-
- if (!m_statement->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-
+
generator.emitNode(dst, m_statement.get());
generator.emitLabel(scope->continueTarget());
@@ -1840,11 +1831,10 @@ RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
RefPtr<Label> topOfLoop = generator.newLabel();
generator.emitLabel(topOfLoop.get());
- if (!m_statement->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
generator.emitLabel(scope->continueTarget());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (m_expr3)
generator.emitNode(generator.ignoredResult(), m_expr3.get());
@@ -1953,12 +1943,11 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
generator.emitPutByVal(base.get(), subscript, propertyName);
}
- if (!m_statement->isBlock())
- generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
generator.emitNode(dst, m_statement.get());
generator.emitLabel(scope->continueTarget());
generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
generator.emitLabel(scope->breakTarget());
return dst;
}
@@ -1968,6 +1957,8 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
// ECMA 12.7
RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
LabelScope* scope = generator.continueTarget(m_ident);
if (!scope)
@@ -1984,6 +1975,8 @@ RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
// ECMA 12.8
RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
LabelScope* scope = generator.breakTarget(m_ident);
if (!scope)
@@ -2009,14 +2002,20 @@ void ReturnNode::releaseNodes(NodeReleaser& releaser)
RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
if (generator.codeType() != FunctionCode)
return emitThrowError(generator, SyntaxError, "Invalid return statement.");
if (dst == generator.ignoredResult())
dst = 0;
RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
+ RefPtr<RegisterID> returnRegister;
if (generator.scopeDepth()) {
RefPtr<Label> l0 = generator.newLabel();
+ if (generator.hasFinaliser() && !r0->isTemporary()) {
+ returnRegister = generator.emitMove(generator.newTemporary(), r0);
+ r0 = returnRegister.get();
+ }
generator.emitJumpScopes(l0.get(), 0);
generator.emitLabel(l0.get());
}
@@ -2039,6 +2038,8 @@ void WithNode::releaseNodes(NodeReleaser& releaser)
RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
RefPtr<RegisterID> scope = generator.newTemporary();
generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
@@ -2244,6 +2245,8 @@ void SwitchNode::releaseNodes(NodeReleaser& releaser)
RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
@@ -2267,6 +2270,8 @@ void LabelNode::releaseNodes(NodeReleaser& releaser)
RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
if (generator.breakTarget(m_name))
return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
@@ -2291,12 +2296,14 @@ void ThrowNode::releaseNodes(NodeReleaser& releaser)
RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
if (dst == generator.ignoredResult())
dst = 0;
- RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
+ RefPtr<RegisterID> expr = generator.emitNode(m_expr.get());
generator.emitExpressionInfo(divot(), startOffset(), endOffset());
generator.emitThrow(expr.get());
- return dst;
+ return 0;
}
// ------------------------------ TryNode --------------------------------------
@@ -2315,6 +2322,8 @@ void TryNode::releaseNodes(NodeReleaser& releaser)
RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
+ generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
RefPtr<Label> tryStartLabel = generator.newLabel();
RefPtr<Label> tryEndLabel = generator.newLabel();
RefPtr<Label> finallyStart;
diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h
index baa9984..f209133 100644
--- a/JavaScriptCore/parser/Nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -205,7 +205,6 @@ namespace JSC {
virtual bool isExprStatement() const JSC_FAST_CALL { return false; }
virtual bool isBlock() const JSC_FAST_CALL { return false; }
- virtual bool isLoop() const JSC_FAST_CALL { return false; }
private:
int m_lastLine;
@@ -1831,8 +1830,6 @@ namespace JSC {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
-
private:
RefPtr<StatementNode> m_statement;
RefPtr<ExpressionNode> m_expr;
@@ -1852,8 +1849,6 @@ namespace JSC {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
-
private:
RefPtr<ExpressionNode> m_expr;
RefPtr<StatementNode> m_statement;
@@ -1877,8 +1872,6 @@ namespace JSC {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
-
private:
RefPtr<ExpressionNode> m_expr1;
RefPtr<ExpressionNode> m_expr2;
@@ -1897,8 +1890,6 @@ namespace JSC {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
- virtual bool isLoop() const JSC_FAST_CALL { return true; }
-
private:
Identifier m_ident;
RefPtr<ExpressionNode> m_init;
diff --git a/JavaScriptCore/pcre/pcre_exec.cpp b/JavaScriptCore/pcre/pcre_exec.cpp
index 34e2786..80a092a 100644
--- a/JavaScriptCore/pcre/pcre_exec.cpp
+++ b/JavaScriptCore/pcre/pcre_exec.cpp
@@ -56,7 +56,7 @@ the JavaScript specification. There are also some supporting functions. */
using namespace WTF;
-#ifdef __GNUC__
+#if COMPILER(GCC)
#define USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
//#define USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
#endif
@@ -175,7 +175,7 @@ reqByte match. */
/* The below limit restricts the number of "recursive" match calls in order to
avoid spending exponential time on complex regular expressions. */
-static const unsigned matchLimit = 100000;
+static const unsigned matchLimit = 1000000;
#ifdef DEBUG
/*************************************************
@@ -447,6 +447,7 @@ static int match(const UChar* subjectPtr, const unsigned char* instructionPtr, i
int min;
bool minimize = false; /* Initialization not really needed, but some compilers think so. */
unsigned remainingMatchCount = matchLimit;
+ int othercase; /* Declare here to avoid errors during jumps */
MatchStack stack;
@@ -1186,7 +1187,7 @@ RECURSE:
stack.currentFrame->args.instructionPtr += stack.currentFrame->locals.length;
if (stack.currentFrame->locals.fc <= 0xFFFF) {
- int othercase = md.ignoreCase ? jsc_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1;
+ othercase = md.ignoreCase ? jsc_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1;
for (int i = 1; i <= min; i++) {
if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc && *stack.currentFrame->args.subjectPtr != othercase)
diff --git a/JavaScriptCore/pcre/pcre_internal.h b/JavaScriptCore/pcre/pcre_internal.h
index 2916765..0016bb5 100644
--- a/JavaScriptCore/pcre/pcre_internal.h
+++ b/JavaScriptCore/pcre/pcre_internal.h
@@ -85,7 +85,7 @@ total length. */
offsets within the compiled regex. The default is 2, which allows for compiled
patterns up to 64K long. */
-#define LINK_SIZE 2
+#define LINK_SIZE 3
/* Define DEBUG to get debugging output on stdout. */
@@ -124,28 +124,60 @@ static inline void put2ByteValue(unsigned char* opcodePtr, int value)
opcodePtr[1] = value;
}
+static inline void put3ByteValue(unsigned char* opcodePtr, int value)
+{
+ ASSERT(value >= 0 && value <= 0xFFFFFF);
+ opcodePtr[0] = value >> 16;
+ opcodePtr[1] = value >> 8;
+ opcodePtr[2] = value;
+}
+
static inline int get2ByteValue(const unsigned char* opcodePtr)
{
return (opcodePtr[0] << 8) | opcodePtr[1];
}
+static inline int get3ByteValue(const unsigned char* opcodePtr)
+{
+ return (opcodePtr[0] << 16) | (opcodePtr[1] << 8) | opcodePtr[2];
+}
+
static inline void put2ByteValueAndAdvance(unsigned char*& opcodePtr, int value)
{
put2ByteValue(opcodePtr, value);
opcodePtr += 2;
}
+static inline void put3ByteValueAndAdvance(unsigned char*& opcodePtr, int value)
+{
+ put3ByteValue(opcodePtr, value);
+ opcodePtr += 3;
+}
+
static inline void putLinkValueAllowZero(unsigned char* opcodePtr, int value)
{
+#if LINK_SIZE == 3
+ put3ByteValue(opcodePtr, value);
+#elif LINK_SIZE == 2
put2ByteValue(opcodePtr, value);
+#else
+# error LINK_SIZE not supported.
+#endif
}
static inline int getLinkValueAllowZero(const unsigned char* opcodePtr)
{
+#if LINK_SIZE == 3
+ return get3ByteValue(opcodePtr);
+#elif LINK_SIZE == 2
return get2ByteValue(opcodePtr);
+#else
+# error LINK_SIZE not supported.
+#endif
}
-#define MAX_PATTERN_SIZE (1 << 16)
+#define MAX_PATTERN_SIZE 1024 * 1024 // Derived by empirical testing of compile time in PCRE and WREC.
+COMPILE_ASSERT(MAX_PATTERN_SIZE < (1 << (8 * LINK_SIZE)), pcre_max_pattern_fits_in_bytecode);
static inline void putLinkValue(unsigned char* opcodePtr, int value)
{
diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp
index 2de8f84..ace0a33 100644
--- a/JavaScriptCore/profiler/Profiler.cpp
+++ b/JavaScriptCore/profiler/Profiler.cpp
@@ -58,6 +58,8 @@ Profiler* Profiler::profiler()
void Profiler::startProfiling(ExecState* exec, const UString& title)
{
+ ASSERT_ARG(title, !title.isNull());
+
// Check if we currently have a Profile for this global ExecState and title.
// If so return early and don't create a new Profile.
ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0;
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
index b0429a9..ea4b4f0 100644
--- a/JavaScriptCore/runtime/Arguments.cpp
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -71,6 +71,13 @@ void Arguments::mark()
void Arguments::fillArgList(ExecState* exec, ArgList& args)
{
+ if (UNLIKELY(d->overrodeLength)) {
+ unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
+ for (unsigned i = 0; i < length; i++)
+ args.append(get(exec, i));
+ return;
+ }
+
if (LIKELY(!d->deletedArguments)) {
if (LIKELY(!d->numParameters)) {
args.initialize(d->extraArguments, d->numArguments);
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 4cd229a..654386b 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -26,6 +26,7 @@
#include "CodeBlock.h"
#include "Interpreter.h"
+#include "JIT.h"
#include "ObjectPrototype.h"
#include "Lookup.h"
#include "Operations.h"
@@ -67,8 +68,16 @@ static inline bool isNumericCompareFunction(CallType callType, const CallData& c
{
if (callType != CallTypeJS)
return false;
-
- return callData.js.functionBody->bytecode(callData.js.scopeChain).isNumericCompareFunction();
+
+ CodeBlock& codeBlock = callData.js.functionBody->bytecode(callData.js.scopeChain);
+#if ENABLE(JIT)
+ // If the JIT is enabled then we need to preserve the invariant that every
+ // function with a CodeBlock also has JIT code.
+ if (!codeBlock.jitCode())
+ JIT::compile(callData.js.scopeChain->globalData, &codeBlock);
+#endif
+
+ return codeBlock.isNumericCompareFunction();
}
// ------------------------------ ArrayPrototype ----------------------------
@@ -278,10 +287,10 @@ JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue
ArgList::const_iterator end = args.end();
while (1) {
if (curArg.isObject(&JSArray::info)) {
- JSArray* curArray = asArray(curArg);
- unsigned length = curArray->length();
+ unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
+ JSObject* curObject = curArg.toObject(exec);
for (unsigned k = 0; k < length; ++k) {
- if (JSValuePtr v = getProperty(exec, curArray, k))
+ if (JSValuePtr v = getProperty(exec, curObject, k))
arr->put(exec, n, v);
n++;
}
@@ -300,7 +309,7 @@ JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue
JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
- if (exec->interpreter()->isJSArray(thisValue))
+ if (isJSArray(&exec->globalData(), thisValue))
return asArray(thisValue)->pop();
JSObject* thisObj = thisValue.toThisObject(exec);
@@ -319,7 +328,7 @@ JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, c
JSValuePtr arrayProtoFuncPush(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
- if (exec->interpreter()->isJSArray(thisValue) && args.size() == 1) {
+ if (isJSArray(&exec->globalData(), thisValue) && args.size() == 1) {
JSArray* array = asArray(thisValue);
array->push(exec, args.begin()->jsValue(exec));
return jsNumber(exec, array->length());
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 13e7f51..a4fea7d 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -349,6 +349,9 @@ collect:
// didn't find a block, and GC didn't reclaim anything, need to allocate a new block
size_t numBlocks = heap.numBlocks;
if (usedBlocks == numBlocks) {
+ static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR;
+ if (numBlocks > maxNumBlocks)
+ CRASH();
numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
heap.numBlocks = numBlocks;
heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*)));
diff --git a/JavaScriptCore/runtime/Completion.cpp b/JavaScriptCore/runtime/Completion.cpp
index 0231a15..5655fa5 100644
--- a/JavaScriptCore/runtime/Completion.cpp
+++ b/JavaScriptCore/runtime/Completion.cpp
@@ -68,7 +68,7 @@ Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& s
if (exception) {
if (exception.isObject() && asObject(exception)->isWatchdogException())
- return Completion(Interrupted, result);
+ return Completion(Interrupted, exception);
return Completion(Throw, exception);
}
return Completion(Normal, result);
diff --git a/JavaScriptCore/runtime/DateMath.cpp b/JavaScriptCore/runtime/DateMath.cpp
index b452963..356d7a1 100644
--- a/JavaScriptCore/runtime/DateMath.cpp
+++ b/JavaScriptCore/runtime/DateMath.cpp
@@ -919,14 +919,14 @@ UString formatTime(const GregorianDateTime &t, bool utc)
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
} else {
int offset = abs(gmtoffset(t));
- char tzname[70];
+ char timeZoneName[70];
struct tm gtm = t;
- strftime(tzname, sizeof(tzname), "%Z", &gtm);
+ strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
- if (tzname[0]) {
+ if (timeZoneName[0]) {
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
t.hour, t.minute, t.second,
- gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, tzname);
+ gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
} else {
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
t.hour, t.minute, t.second,
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index b325070..fad1d55 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -27,6 +27,11 @@
#include "ObjectPrototype.h"
#include "DateInstance.h"
#include <float.h>
+
+#if !PLATFORM(MAC) && HAVE(LANGINFO_H)
+#include <langinfo.h>
+#endif
+
#include <limits.h>
#include <locale.h>
#include <math.h>
@@ -181,7 +186,11 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil
static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, LocaleDateTimeFormat format)
{
+#if HAVE(LANGINFO_H)
+ static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT };
+#else
static const char* const formatStrings[] = { "%#c", "%#x", "%X" };
+#endif
// Offset year if needed
struct tm localTM = gdt;
@@ -190,10 +199,26 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L
if (yearNeedsOffset)
localTM.tm_year = equivalentYearForDST(year) - 1900;
+#if HAVE(LANGINFO_H)
+ // We do not allow strftime to generate dates with 2-digits years,
+ // both to avoid ambiguity, and a crash in strncpy, for years that
+ // need offset.
+ char* formatString = strdup(nl_langinfo(formats[format]));
+ char* yPos = strchr(formatString, 'y');
+ if (yPos)
+ *yPos = 'Y';
+#endif
+
// Do the formatting
const int bufsize = 128;
char timebuffer[bufsize];
+
+#if HAVE(LANGINFO_H)
+ size_t ret = strftime(timebuffer, bufsize, formatString, &localTM);
+ free(formatString);
+#else
size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM);
+#endif
if (ret == 0)
return jsEmptyString(exec);
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index d1b5aac..30f1503 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -47,6 +47,8 @@ public:
}
virtual bool isWatchdogException() const { return true; }
+
+ virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; }
};
JSValuePtr createInterruptedExecutionException(JSGlobalData* globalData)
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index d58334a..ff77b9d 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -93,16 +93,19 @@ FunctionBodyNode* extractFunctionBody(ProgramNode* program)
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
+ // Functions need to have a space following the opening { due to for web compatibility
+ // see https://bugs.webkit.org/show_bug.cgi?id=24350
+ // We also need \n before the closing } to handle // comments at the end of the last line
UString program;
if (args.isEmpty())
- program = "(function(){})";
+ program = "(function() { \n})";
else if (args.size() == 1)
- program = "(function(){" + args.at(exec, 0).toString(exec) + "})";
+ program = "(function() { " + args.at(exec, 0).toString(exec) + "\n})";
else {
program = "(function(" + args.at(exec, 0).toString(exec);
for (size_t i = 1; i < args.size() - 1; i++)
program += "," + args.at(exec, i).toString(exec);
- program += "){" + args.at(exec, args.size() - 1).toString(exec) + "})";
+ program += ") { " + args.at(exec, args.size() - 1).toString(exec) + "\n})";
}
int errLine;
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index 7be2685..01fc57c 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -26,6 +26,7 @@
#include "JSFunction.h"
#include "JSString.h"
#include "Interpreter.h"
+#include "Lexer.h"
#include "PrototypeFunction.h"
namespace JSC {
@@ -63,11 +64,29 @@ CallType FunctionPrototype::getCallData(CallData& callData)
// Functions
+// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.)
+static inline void insertSemicolonIfNeeded(UString& functionBody)
+{
+ ASSERT(functionBody[0] == '{');
+ ASSERT(functionBody[functionBody.size() - 1] == '}');
+
+ for (size_t i = functionBody.size() - 2; i > 0; --i) {
+ UChar ch = functionBody[i];
+ if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
+ if (ch != ';' && ch != '}')
+ functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
+ return;
+ }
+ }
+}
+
JSValuePtr functionProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
{
if (thisValue.isObject(&JSFunction::info)) {
JSFunction* function = asFunction(thisValue);
- return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + function->body()->toSourceString());
+ UString functionBody = function->body()->toSourceString();
+ insertSemicolonIfNeeded(functionBody);
+ return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + functionBody);
}
if (thisValue.isObject(&InternalFunction::info)) {
@@ -85,32 +104,25 @@ JSValuePtr functionProtoFuncApply(ExecState* exec, JSObject*, JSValuePtr thisVal
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSValuePtr thisArg = args.at(exec, 0);
- JSValuePtr argArray = args.at(exec, 1);
-
- JSValuePtr applyThis;
- if (thisArg.isUndefinedOrNull())
- applyThis = exec->globalThisValue();
- else
- applyThis = thisArg.toObject(exec);
+ JSValuePtr array = args.at(exec, 1);
ArgList applyArgs;
- if (!argArray.isUndefinedOrNull()) {
- if (!argArray.isObject())
+ if (!array.isUndefinedOrNull()) {
+ if (!array.isObject())
return throwError(exec, TypeError);
- if (asObject(argArray)->classInfo() == &Arguments::info)
- asArguments(argArray)->fillArgList(exec, applyArgs);
- else if (exec->interpreter()->isJSArray(argArray))
- asArray(argArray)->fillArgList(exec, applyArgs);
- else if (asObject(argArray)->inherits(&JSArray::info)) {
- unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length).toUInt32(exec);
+ if (asObject(array)->classInfo() == &Arguments::info)
+ asArguments(array)->fillArgList(exec, applyArgs);
+ else if (isJSArray(&exec->globalData(), array))
+ asArray(array)->fillArgList(exec, applyArgs);
+ else if (asObject(array)->inherits(&JSArray::info)) {
+ unsigned length = asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned i = 0; i < length; ++i)
- applyArgs.append(asArray(argArray)->get(exec, i));
+ applyArgs.append(asArray(array)->get(exec, i));
} else
return throwError(exec, TypeError);
}
- return call(exec, thisValue, callType, callData, applyThis, applyArgs);
+ return call(exec, thisValue, callType, callData, args.at(exec, 0), applyArgs);
}
JSValuePtr functionProtoFuncCall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
@@ -120,17 +132,9 @@ JSValuePtr functionProtoFuncCall(ExecState* exec, JSObject*, JSValuePtr thisValu
if (callType == CallTypeNone)
return throwError(exec, TypeError);
- JSValuePtr thisArg = args.at(exec, 0);
-
- JSObject* callThis;
- if (thisArg.isUndefinedOrNull())
- callThis = exec->globalThisValue();
- else
- callThis = thisArg.toObject(exec);
-
- ArgList argsTail;
- args.getSlice(1, argsTail);
- return call(exec, thisValue, callType, callData, callThis, argsTail);
+ ArgList callArgs;
+ args.getSlice(1, callArgs);
+ return call(exec, thisValue, callType, callData, args.at(exec, 0), callArgs);
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index 7eecf33..f873f13 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -122,6 +122,8 @@ namespace JSC {
return static_cast<JSArray*>(asObject(value));
}
+ inline bool isJSArray(JSGlobalData* globalData, JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; }
+
} // namespace JSC
#endif // JSArray_h
diff --git a/JavaScriptCore/runtime/JSByteArray.h b/JavaScriptCore/runtime/JSByteArray.h
index 19c8f0e..eb8e0ac 100644
--- a/JavaScriptCore/runtime/JSByteArray.h
+++ b/JavaScriptCore/runtime/JSByteArray.h
@@ -33,7 +33,7 @@
namespace JSC {
class JSByteArray : public JSObject {
- friend class Interpreter;
+ friend class VPtrSet;
public:
bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
JSValuePtr getIndex(ExecState* exec, unsigned i)
@@ -88,6 +88,8 @@ namespace JSC {
size_t length() const { return m_storage->length(); }
+ WTF::ByteArray* storage() const { return m_storage.get(); }
+
private:
enum VPtrStealingHackType { VPtrStealingHack };
JSByteArray(VPtrStealingHackType)
@@ -105,6 +107,9 @@ namespace JSC {
{
return static_cast<JSByteArray*>(asCell(value));
}
-}
-#endif
+ inline bool isJSByteArray(JSGlobalData* globalData, JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == globalData->jsByteArrayVPtr; }
+
+} // namespace JSC
+
+#endif // JSByteArray_h
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index 43d81a5..1973c54 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -32,15 +32,15 @@
namespace JSC {
class JSCell : Noncopyable {
- friend class JIT;
friend class GetterSetter;
friend class Heap;
+ friend class JIT;
friend class JSNumberCell;
friend class JSObject;
friend class JSPropertyNameIterator;
friend class JSString;
friend class JSValuePtr;
- friend class Interpreter;
+ friend class VPtrSet;
private:
explicit JSCell(Structure*);
diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h
index 6a43737..87ca2a2 100644
--- a/JavaScriptCore/runtime/JSFunction.h
+++ b/JavaScriptCore/runtime/JSFunction.h
@@ -39,7 +39,8 @@ namespace JSC {
class JSFunction : public InternalFunction {
friend class JIT;
- friend class Interpreter;
+ friend class JITStubs;
+ friend class VPtrSet;
typedef InternalFunction Base;
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 10b584d..3a2f7c0 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -35,6 +35,8 @@
#include "FunctionConstructor.h"
#include "Interpreter.h"
#include "JSActivation.h"
+#include "JSArray.h"
+#include "JSByteArray.h"
#include "JSClassRef.h"
#include "JSLock.h"
#include "JSNotAnObject.h"
@@ -64,10 +66,42 @@ extern const HashTable regExpTable;
extern const HashTable regExpConstructorTable;
extern const HashTable stringTable;
-JSGlobalData::JSGlobalData(bool isShared)
- : initializingLazyNumericCompareFunction(false)
- , interpreter(new Interpreter)
- , exception(noValue())
+struct VPtrSet {
+ VPtrSet();
+
+ void* jsArrayVPtr;
+ void* jsByteArrayVPtr;
+ void* jsStringVPtr;
+ void* jsFunctionVPtr;
+};
+
+VPtrSet::VPtrSet()
+{
+ // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
+ void* storage = fastMalloc(sizeof(CollectorBlock));
+
+ JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
+ jsArrayVPtr = jsArray->vptr();
+ jsArray->~JSCell();
+
+ JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
+ jsByteArrayVPtr = jsByteArray->vptr();
+ jsByteArray->~JSCell();
+
+ JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
+ jsStringVPtr = jsString->vptr();
+ jsString->~JSCell();
+
+ JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
+ jsFunctionVPtr = jsFunction->vptr();
+ jsFunction->~JSCell();
+
+ fastFree(storage);
+}
+
+JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
+ : isSharedInstance(isShared)
+ , clientData(0)
, arrayTable(new HashTable(JSC::arrayTable))
, dateTable(new HashTable(JSC::dateTable))
, mathTable(new HashTable(JSC::mathTable))
@@ -84,24 +118,31 @@ JSGlobalData::JSGlobalData(bool isShared)
#if !USE(ALTERNATE_JSIMMEDIATE)
, numberStructure(JSNumberCell::createStructure(jsNull()))
#endif
+ , jsArrayVPtr(vptrSet.jsArrayVPtr)
+ , jsByteArrayVPtr(vptrSet.jsByteArrayVPtr)
+ , jsStringVPtr(vptrSet.jsStringVPtr)
+ , jsFunctionVPtr(vptrSet.jsFunctionVPtr)
, identifierTable(createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new ArgList)
- , newParserObjects(0)
- , parserObjectExtraRefCounts(0)
, lexer(new Lexer(this))
, parser(new Parser)
+ , interpreter(new Interpreter)
+#if ENABLE(JIT)
+ , jitStubs(this)
+#endif
+ , heap(this)
+ , exception(noValue())
+ , initializingLazyNumericCompareFunction(false)
+ , newParserObjects(0)
+ , parserObjectExtraRefCounts(0)
, head(0)
, dynamicGlobalObject(0)
- , isSharedInstance(isShared)
- , clientData(0)
, scopeNodeBeingReparsed(0)
- , heap(this)
{
#if PLATFORM(MAC)
startProfilerServerIfNeeded();
#endif
- interpreter->initialize(this);
}
JSGlobalData::~JSGlobalData()
@@ -145,9 +186,9 @@ JSGlobalData::~JSGlobalData()
delete clientData;
}
-PassRefPtr<JSGlobalData> JSGlobalData::create()
+PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared)
{
- return adoptRef(new JSGlobalData);
+ return adoptRef(new JSGlobalData(isShared, VPtrSet()));
}
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
@@ -171,7 +212,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
if (!instance) {
- instance = new JSGlobalData(true);
+ instance = create(true).releaseRef();
#if ENABLE(JSC_MULTIPLE_THREADS)
instance->makeUsableFromMultipleThreads();
#endif
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 4223191..1936f1f 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -29,13 +29,15 @@
#ifndef JSGlobalData_h
#define JSGlobalData_h
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/RefCounted.h>
#include "Collector.h"
#include "ExecutableAllocator.h"
-#include "SmallStrings.h"
+#include "JITStubs.h"
#include "JSValue.h"
+#include "SmallStrings.h"
+#include "TimeoutChecker.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
struct OpaqueJSClass;
struct OpaqueJSClassContextData;
@@ -57,13 +59,18 @@ namespace JSC {
class Structure;
class UString;
struct HashTable;
+ struct VPtrSet;
class JSGlobalData : public RefCounted<JSGlobalData> {
public:
+ struct ClientData {
+ virtual ~ClientData() = 0;
+ };
+
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
- static PassRefPtr<JSGlobalData> create();
+ static PassRefPtr<JSGlobalData> create(bool isShared = false);
static PassRefPtr<JSGlobalData> createLeaked();
~JSGlobalData();
@@ -72,16 +79,8 @@ namespace JSC {
void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
#endif
- const Vector<Instruction>& numericCompareFunction(ExecState*);
- Vector<Instruction> lazyNumericCompareFunction;
- bool initializingLazyNumericCompareFunction;
-
- Interpreter* interpreter;
-
- JSValuePtr exception;
-#if ENABLE(JIT)
- void* exceptionLocation;
-#endif
+ bool isSharedInstance;
+ ClientData* clientData;
const HashTable* arrayTable;
const HashTable* dateTable;
@@ -101,48 +100,54 @@ namespace JSC {
RefPtr<Structure> numberStructure;
#endif
+ void* jsArrayVPtr;
+ void* jsByteArrayVPtr;
+ void* jsStringVPtr;
+ void* jsFunctionVPtr;
+
IdentifierTable* identifierTable;
CommonIdentifiers* propertyNames;
const ArgList* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
-
SmallStrings smallStrings;
-
- HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- HashSet<ParserRefCounted*>* newParserObjects;
- HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
+#if ENABLE(ASSEMBLER)
+ ExecutableAllocator executableAllocator;
+#endif
Lexer* lexer;
Parser* parser;
+ Interpreter* interpreter;
+#if ENABLE(JIT)
+ JITStubs jitStubs;
+#endif
+ TimeoutChecker timeoutChecker;
+ Heap heap;
- JSGlobalObject* head;
- JSGlobalObject* dynamicGlobalObject;
+ JSValuePtr exception;
+#if ENABLE(JIT)
+ void* exceptionLocation;
+#endif
- bool isSharedInstance;
+ const Vector<Instruction>& numericCompareFunction(ExecState*);
+ Vector<Instruction> lazyNumericCompareFunction;
+ bool initializingLazyNumericCompareFunction;
- struct ClientData {
- virtual ~ClientData() = 0;
- };
+ HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- ClientData* clientData;
+ HashSet<ParserRefCounted*>* newParserObjects;
+ HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
+
+ JSGlobalObject* head;
+ JSGlobalObject* dynamicGlobalObject;
HashSet<JSObject*> arrayVisitedElements;
ScopeNode* scopeNodeBeingReparsed;
- Heap heap;
-#if ENABLE(ASSEMBLER)
- PassRefPtr<ExecutablePool> poolForSize(size_t n) { return m_executableAllocator.poolForSize(n); }
-#endif
private:
- JSGlobalData(bool isShared = false);
-#if ENABLE(ASSEMBLER)
- ExecutableAllocator m_executableAllocator;
-#endif
-
+ JSGlobalData(bool isShared, const VPtrSet&);
static JSGlobalData*& sharedInstanceInternal();
};
+} // namespace JSC
-}
-
-#endif
+#endif // JSGlobalData_h
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index eb2b349..d6ad295 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -341,22 +341,11 @@ void JSGlobalObject::reset(JSValuePtr prototype)
void JSGlobalObject::resetPrototype(JSValuePtr prototype)
{
setPrototype(prototype);
- lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
-}
-
-void JSGlobalObject::setTimeoutTime(unsigned timeoutTime)
-{
- globalData()->interpreter->setTimeoutTime(timeoutTime);
-}
-void JSGlobalObject::startTimeoutCheck()
-{
- globalData()->interpreter->startTimeoutCheck();
-}
-
-void JSGlobalObject::stopTimeoutCheck()
-{
- globalData()->interpreter->stopTimeoutCheck();
+ JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
+ JSObject* objectPrototype = d()->objectPrototype;
+ if (oldLastInPrototypeChain != objectPrototype)
+ oldLastInPrototypeChain->setPrototype(objectPrototype);
}
void JSGlobalObject::mark()
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index 4a10f64..da8b7bf 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -214,10 +214,6 @@ namespace JSC {
void setProfileGroup(unsigned value) { d()->profileGroup = value; }
unsigned profileGroup() const { return d()->profileGroup; }
- void setTimeoutTime(unsigned timeoutTime);
- void startTimeoutCheck();
- void stopTimeoutCheck();
-
Debugger* debugger() const { return d()->debugger; }
void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
diff --git a/JavaScriptCore/runtime/JSImmediate.cpp b/JavaScriptCore/runtime/JSImmediate.cpp
index c6cca80..a407ec3 100644
--- a/JavaScriptCore/runtime/JSImmediate.cpp
+++ b/JavaScriptCore/runtime/JSImmediate.cpp
@@ -39,12 +39,8 @@ JSObject* JSImmediate::toThisObject(JSValuePtr v, ExecState* exec)
return constructNumber(exec, v);
if (isBoolean(v))
return constructBooleanFromImmediateBoolean(exec, v);
- if (v.isNull())
- return exec->globalThisValue();
-
- JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
- exec->setException(exception);
- return new (exec) JSNotAnObject(exec, exception);
+ ASSERT(v.isUndefinedOrNull());
+ return exec->globalThisValue();
}
JSObject* JSImmediate::toObject(JSValuePtr v, ExecState* exec)
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index e4baa73..7398d50 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -60,7 +60,7 @@ namespace JSC {
class JSString : public JSCell {
friend class JIT;
- friend class Interpreter;
+ friend class VPtrSet;
public:
JSString(JSGlobalData* globalData, const UString& value)
@@ -202,6 +202,8 @@ namespace JSC {
return false;
}
+ inline bool isJSString(JSGlobalData* globalData, JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == globalData->jsStringVPtr; }
+
// --- JSValue inlines ----------------------------
inline JSString* JSValuePtr::toThisJSString(ExecState* exec)
diff --git a/JavaScriptCore/runtime/NumberConstructor.cpp b/JavaScriptCore/runtime/NumberConstructor.cpp
index caa4a70..8bd424d 100644
--- a/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -68,27 +68,27 @@ bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
}
-JSValuePtr numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValuePtr numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNaN(exec);
}
-JSValuePtr numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValuePtr numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNumber(exec, -Inf);
}
-JSValuePtr numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValuePtr numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNumber(exec, Inf);
}
-JSValuePtr numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValuePtr numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNumber(exec, 1.7976931348623157E+308);
}
-JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
{
return jsNumber(exec, 5E-324);
}
diff --git a/JavaScriptCore/runtime/Operations.cpp b/JavaScriptCore/runtime/Operations.cpp
index 550d3f6..fe516fe 100644
--- a/JavaScriptCore/runtime/Operations.cpp
+++ b/JavaScriptCore/runtime/Operations.cpp
@@ -52,4 +52,70 @@ NEVER_INLINE JSValuePtr throwOutOfMemoryError(ExecState* exec)
return error;
}
+NEVER_INLINE JSValuePtr jsAddSlowCase(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
+{
+ // exception for the Date exception in defaultValue()
+ JSValuePtr p1 = v1.toPrimitive(callFrame);
+ JSValuePtr p2 = v2.toPrimitive(callFrame);
+
+ if (p1.isString() || p2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
+ }
+
+ return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
+}
+
+JSValuePtr jsTypeStringForValue(CallFrame* callFrame, JSValuePtr v)
+{
+ if (v.isUndefined())
+ return jsNontrivialString(callFrame, "undefined");
+ if (v.isBoolean())
+ return jsNontrivialString(callFrame, "boolean");
+ if (v.isNumber())
+ return jsNontrivialString(callFrame, "number");
+ if (v.isString())
+ return jsNontrivialString(callFrame, "string");
+ if (v.isObject()) {
+ // Return "undefined" for objects that should be treated
+ // as null when doing comparisons.
+ if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+ return jsNontrivialString(callFrame, "undefined");
+ CallData callData;
+ if (asObject(v)->getCallData(callData) != CallTypeNone)
+ return jsNontrivialString(callFrame, "function");
+ }
+ return jsNontrivialString(callFrame, "object");
+}
+
+bool jsIsObjectType(JSValuePtr v)
+{
+ if (!v.isCell())
+ return v.isNull();
+
+ JSType type = asCell(v)->structure()->typeInfo().type();
+ if (type == NumberType || type == StringType)
+ return false;
+ if (type == ObjectType) {
+ if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+ return false;
+ CallData callData;
+ if (asObject(v)->getCallData(callData) != CallTypeNone)
+ return false;
+ }
+ return true;
+}
+
+bool jsIsFunctionType(JSValuePtr v)
+{
+ if (v.isObject()) {
+ CallData callData;
+ if (asObject(v)->getCallData(callData) != CallTypeNone)
+ return true;
+ }
+ return false;
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index c6a7e7a..85dee99 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -22,12 +22,19 @@
#ifndef Operations_h
#define Operations_h
+#include "Interpreter.h"
#include "JSImmediate.h"
#include "JSNumberCell.h"
#include "JSString.h"
namespace JSC {
+ NEVER_INLINE JSValuePtr throwOutOfMemoryError(ExecState*);
+ NEVER_INLINE JSValuePtr jsAddSlowCase(CallFrame*, JSValuePtr, JSValuePtr);
+ JSValuePtr jsTypeStringForValue(CallFrame*, JSValuePtr);
+ bool jsIsObjectType(JSValuePtr);
+ bool jsIsFunctionType(JSValuePtr);
+
// ECMA 11.9.3
inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
{
@@ -129,7 +136,147 @@ namespace JSC {
return v1 == v2;
}
- JSValuePtr throwOutOfMemoryError(ExecState*);
+ inline bool jsLess(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
+ {
+ if (JSValuePtr::areBothInt32Fast(v1, v2))
+ return v1.getInt32Fast() < v2.getInt32Fast();
+
+ double n1;
+ double n2;
+ if (v1.getNumber(n1) && v2.getNumber(n2))
+ return n1 < n2;
+
+ JSGlobalData* globalData = &callFrame->globalData();
+ if (isJSString(globalData, v1) && isJSString(globalData, v2))
+ return asString(v1)->value() < asString(v2)->value();
+
+ JSValuePtr p1;
+ JSValuePtr p2;
+ bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+
+ if (wasNotString1 | wasNotString2)
+ return n1 < n2;
+
+ return asString(p1)->value() < asString(p2)->value();
+ }
+
+ inline bool jsLessEq(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
+ {
+ if (JSValuePtr::areBothInt32Fast(v1, v2))
+ return v1.getInt32Fast() <= v2.getInt32Fast();
+
+ double n1;
+ double n2;
+ if (v1.getNumber(n1) && v2.getNumber(n2))
+ return n1 <= n2;
+
+ JSGlobalData* globalData = &callFrame->globalData();
+ if (isJSString(globalData, v1) && isJSString(globalData, v2))
+ return !(asString(v2)->value() < asString(v1)->value());
+
+ JSValuePtr p1;
+ JSValuePtr p2;
+ bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+ bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+
+ if (wasNotString1 | wasNotString2)
+ return n1 <= n2;
+
+ return !(asString(p2)->value() < asString(p1)->value());
+ }
+
+ // Fast-path choices here are based on frequency data from SunSpider:
+ // <times> Add case: <t1> <t2>
+ // ---------------------------
+ // 5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
+ // 247412 Add case: 5 5
+ // 20900 Add case: 5 6
+ // 13962 Add case: 5 3
+ // 4000 Add case: 3 5
+
+ ALWAYS_INLINE JSValuePtr jsAdd(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
+ {
+ double left;
+ double right = 0.0;
+
+ bool rightIsNumber = v2.getNumber(right);
+ if (rightIsNumber && v1.getNumber(left))
+ return jsNumber(callFrame, left + right);
+
+ bool leftIsString = v1.isString();
+ if (leftIsString && v2.isString()) {
+ RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
+ }
+
+ if (rightIsNumber & leftIsString) {
+ RefPtr<UString::Rep> value = v2.isInt32Fast() ?
+ concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
+ concatenate(asString(v1)->value().rep(), right);
+
+ if (!value)
+ return throwOutOfMemoryError(callFrame);
+ return jsString(callFrame, value.release());
+ }
+
+ // All other cases are pretty uncommon
+ return jsAddSlowCase(callFrame, v1, v2);
+ }
+
+ inline size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValuePtr baseValue, const PropertySlot& slot)
+ {
+ JSCell* cell = asCell(baseValue);
+ size_t count = 0;
+
+ while (slot.slotBase() != cell) {
+ JSValuePtr v = cell->structure()->prototypeForLookup(callFrame);
+
+ // If we didn't find slotBase in baseValue's prototype chain, then baseValue
+ // must be a proxy for another object.
+
+ if (v.isNull())
+ return 0;
+
+ cell = asCell(v);
+
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (cell->structure()->isDictionary())
+ asObject(cell)->setStructure(Structure::fromDictionaryTransition(cell->structure()));
+
+ ++count;
+ }
+
+ ASSERT(count);
+ return count;
+ }
+
+ ALWAYS_INLINE JSValuePtr resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+ {
+ ScopeChainIterator iter = scopeChain->begin();
+ ScopeChainIterator next = iter;
+ ++next;
+ ScopeChainIterator end = scopeChain->end();
+ ASSERT(iter != end);
+
+ PropertySlot slot;
+ JSObject* base;
+ while (true) {
+ base = *iter;
+ if (next == end || base->getPropertySlot(callFrame, property, slot))
+ return base;
+
+ iter = next;
+ ++next;
+ }
+
+ ASSERT_NOT_REACHED();
+ return noValue();
+ }
+
+} // namespace JSC
-}
-#endif
+#endif // Operations_h
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index b8251d2..5d05f11 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -123,6 +123,7 @@ int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
if (m_wrecFunction) {
int offsetVectorSize = (m_numSubpatterns + 1) * 2;
int* offsetVector = new int [offsetVectorSize];
+ ASSERT(offsetVector);
for (int j = 0; j < offsetVectorSize; ++j)
offsetVector[j] = -1;
diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp
index 86ee76c..f702221 100644
--- a/JavaScriptCore/runtime/Structure.cpp
+++ b/JavaScriptCore/runtime/Structure.cpp
@@ -65,15 +65,15 @@ static const unsigned newTableSize = 16;
static WTF::RefCountedLeakCounter structureCounter("Structure");
#if ENABLE(JSC_MULTIPLE_THREADS)
-static Mutex ignoreSetMutex;
+static Mutex& ignoreSetMutex = *(new Mutex);
#endif
static bool shouldIgnoreLeaks;
-static HashSet<Structure*> ignoreSet;
+static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>);
#endif
#if DUMP_STRUCTURE_ID_STATISTICS
-static HashSet<Structure*> liveStructureSet;
+static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
#endif
void Structure::dumpStatistics()
diff --git a/JavaScriptCore/runtime/TimeoutChecker.cpp b/JavaScriptCore/runtime/TimeoutChecker.cpp
new file mode 100644
index 0000000..30ba6e9
--- /dev/null
+++ b/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TimeoutChecker.h"
+
+#include "CallFrame.h"
+#include "JSGlobalObject.h"
+
+#if PLATFORM(DARWIN)
+#include <mach/mach.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if PLATFORM(WIN_OS)
+#include <windows.h>
+#endif
+
+#if PLATFORM(QT)
+#include <QDateTime>
+#endif
+
+using namespace std;
+
+namespace JSC {
+
+// Number of ticks before the first timeout check is done.
+static const int ticksUntilFirstCheck = 1024;
+
+// Number of milliseconds between each timeout check.
+static const int intervalBetweenChecks = 1000;
+
+// Returns the time the current thread has spent executing, in milliseconds.
+static inline unsigned getCPUTime()
+{
+#if PLATFORM(DARWIN)
+ mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
+ thread_basic_info_data_t info;
+
+ // Get thread information
+ mach_port_t threadPort = mach_thread_self();
+ thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
+ mach_port_deallocate(mach_task_self(), threadPort);
+
+ unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
+ time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
+
+ return time;
+#elif HAVE(SYS_TIME_H)
+ // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag.
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#elif PLATFORM(QT)
+ QDateTime t = QDateTime::currentDateTime();
+ return t.toTime_t() * 1000 + t.time().msec();
+#elif PLATFORM(WIN_OS)
+ union {
+ FILETIME fileTime;
+ unsigned long long fileTimeAsLong;
+ } userTime, kernelTime;
+
+ // GetThreadTimes won't accept NULL arguments so we pass these even though
+ // they're not used.
+ FILETIME creationTime, exitTime;
+
+ GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
+
+ return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
+#else
+#error Platform does not have getCurrentTime function
+#endif
+}
+
+TimeoutChecker::TimeoutChecker()
+ : m_timeoutInterval(0)
+ , m_startCount(0)
+{
+ reset();
+}
+
+void TimeoutChecker::reset()
+{
+ m_ticksUntilNextCheck = ticksUntilFirstCheck;
+ m_timeAtLastCheck = 0;
+ m_timeExecuting = 0;
+}
+
+bool TimeoutChecker::didTimeOut(ExecState* exec)
+{
+ unsigned currentTime = getCPUTime();
+
+ if (!m_timeAtLastCheck) {
+ // Suspicious amount of looping in a script -- start timing it
+ m_timeAtLastCheck = currentTime;
+ return false;
+ }
+
+ unsigned timeDiff = currentTime - m_timeAtLastCheck;
+
+ if (timeDiff == 0)
+ timeDiff = 1;
+
+ m_timeExecuting += timeDiff;
+ m_timeAtLastCheck = currentTime;
+
+ // Adjust the tick threshold so we get the next checkTimeout call in the
+ // interval specified in intervalBetweenChecks.
+ m_ticksUntilNextCheck = static_cast<unsigned>((static_cast<float>(intervalBetweenChecks) / timeDiff) * m_ticksUntilNextCheck);
+ // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
+ // preferred script check time interval.
+ if (m_ticksUntilNextCheck == 0)
+ m_ticksUntilNextCheck = ticksUntilFirstCheck;
+
+ if (m_timeoutInterval && m_timeExecuting > m_timeoutInterval) {
+ if (exec->dynamicGlobalObject()->shouldInterruptScript())
+ return true;
+
+ reset();
+ }
+
+ return false;
+}
+
+} // namespace JSC
diff --git a/WebCore/storage/SQLStatementCallback.idl b/JavaScriptCore/runtime/TimeoutChecker.h
index 783e8c4..7bfa6d0 100644
--- a/WebCore/storage/SQLStatementCallback.idl
+++ b/JavaScriptCore/runtime/TimeoutChecker.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,10 +26,48 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-module storage {
+#ifndef TimeoutChecker_h
+#define TimeoutChecker_h
- interface SQLStatementCallback {
- void handleEvent(in SQLTransaction transaction, in SQLResultSet resultSet);
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+ class ExecState;
+
+ class TimeoutChecker {
+ public:
+ TimeoutChecker();
+
+ void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; }
+
+ unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; }
+
+ void start()
+ {
+ if (!m_startCount)
+ reset();
+ ++m_startCount;
+ }
+
+ void stop()
+ {
+ ASSERT(m_startCount);
+ --m_startCount;
+ }
+
+ void reset();
+
+ bool didTimeOut(ExecState*);
+
+ private:
+ unsigned m_timeoutInterval;
+ unsigned m_timeAtLastCheck;
+ unsigned m_timeExecuting;
+ unsigned m_startCount;
+ unsigned m_ticksUntilNextCheck;
};
-}
+} // namespace JSC
+
+#endif // TimeoutChecker_h
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index 8cb12cf..024d6a1 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -93,7 +93,7 @@ static inline void copyChars(UChar* destination, const UChar* source, unsigned n
memcpy(destination, source, numCharacters * sizeof(UChar));
}
-COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes)
+COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes);
CString::CString(const char* c)
: m_length(strlen(c))
diff --git a/JavaScriptCore/wrec/WREC.cpp b/JavaScriptCore/wrec/WREC.cpp
index 099931b..145a1ce 100644
--- a/JavaScriptCore/wrec/WREC.cpp
+++ b/JavaScriptCore/wrec/WREC.cpp
@@ -40,12 +40,9 @@ using namespace WTF;
namespace JSC { namespace WREC {
-// Patterns longer than this can hang the compiler.
-static const int MaxPatternSize = (1 << 13);
-
CompiledRegExp Generator::compileRegExp(JSGlobalData* globalData, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, RefPtr<ExecutablePool>& pool, bool ignoreCase, bool multiline)
{
- if (pattern.size() > MaxPatternSize) {
+ if (pattern.size() > MAX_PATTERN_SIZE) {
*error_ptr = "regular expression too large";
return 0;
}
@@ -80,7 +77,7 @@ CompiledRegExp Generator::compileRegExp(JSGlobalData* globalData, const UString&
}
*numSubpatterns_ptr = parser.numSubpatterns();
- pool = globalData->poolForSize(generator.size());
+ pool = globalData->executableAllocator.poolForSize(generator.size());
return reinterpret_cast<CompiledRegExp>(generator.copyCode(pool.get()));
}
diff --git a/JavaScriptCore/wrec/WRECGenerator.cpp b/JavaScriptCore/wrec/WRECGenerator.cpp
index 4b5f3d4..e2e8aba 100644
--- a/JavaScriptCore/wrec/WRECGenerator.cpp
+++ b/JavaScriptCore/wrec/WRECGenerator.cpp
@@ -40,16 +40,7 @@ namespace JSC { namespace WREC {
void Generator::generateEnter()
{
-#if PLATFORM(X86_64)
- // On x86-64 edi and esi are caller preserved, so nothing to do here.
- // The four arguments have been passed in the registers %rdi, %rsi,
- // %rdx, %rcx - shuffle these into the expected locations.
- move(X86::edi, input); // (arg 1) edi -> eax
- move(X86::ecx, output); // (arg 4) ecx -> edi
- move(X86::edx, length); // (arg 3) edx -> ecx
- move(X86::esi, index); // (arg 2) esi -> edx
-
-#else
+#if PLATFORM(X86)
// On x86 edi & esi are callee preserved registers.
push(X86::edi);
push(X86::esi);
@@ -67,24 +58,20 @@ void Generator::generateEnter()
peek(output, 3);
#endif
#endif
-
-#ifndef NDEBUG
- // ASSERT that the output register is not null.
- Jump outputNotNull = jnzPtr(output);
- breakpoint();
- outputNotNull.link(this);
-#endif
}
void Generator::generateReturnSuccess()
{
+ ASSERT(returnRegister != index);
+ ASSERT(returnRegister != output);
+
// Set return value.
- pop(X86::eax); // match begin
- store32(X86::eax, output);
+ pop(returnRegister); // match begin
+ store32(returnRegister, output);
store32(index, Address(output, 4)); // match end
// Restore callee save registers.
-#if !PLATFORM(X86_64)
+#if PLATFORM(X86)
pop(X86::esi);
pop(X86::edi);
#endif
@@ -100,14 +87,14 @@ void Generator::generateIncrementIndex(Jump* failure)
{
peek(index);
if (failure)
- *failure = je32(length, index);
+ *failure = branch32(Equal, length, index);
add32(Imm32(1), index);
poke(index);
}
void Generator::generateLoadCharacter(JumpList& failures)
{
- failures.append(je32(length, index));
+ failures.append(branch32(Equal, length, index));
load16(BaseIndex(input, index, TimesTwo), character);
}
@@ -115,14 +102,15 @@ void Generator::generateLoadCharacter(JumpList& failures)
// were part of the input string.
void Generator::generateJumpIfNotEndOfInput(Label target)
{
- jle32(index, length, target);
+ branch32(LessThanOrEqual, index, length, target);
}
void Generator::generateReturnFailure()
{
pop();
- move(Imm32(-1), X86::eax);
-#if !PLATFORM(X86_64)
+ move(Imm32(-1), returnRegister);
+
+#if PLATFORM(X86)
pop(X86::esi);
pop(X86::edi);
#endif
@@ -145,7 +133,7 @@ void Generator::generateBackreferenceQuantifier(JumpList& failures, Quantifier::
GenerateBackreferenceFunctor functor(subpatternId);
load32(Address(output, (2 * subpatternId) * sizeof(int)), character);
- Jump skipIfEmpty = je32(Address(output, ((2 * subpatternId) + 1) * sizeof(int)), character);
+ Jump skipIfEmpty = branch32(Equal, Address(output, ((2 * subpatternId) + 1) * sizeof(int)), character);
ASSERT(quantifierType == Quantifier::Greedy || quantifierType == Quantifier::NonGreedy);
if (quantifierType == Quantifier::Greedy)
@@ -175,7 +163,7 @@ void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunc
Label alternativeFailed(this);
pop(index);
if (max != Quantifier::Infinity)
- je32(repeatCount, Imm32(max), quantifierFailed);
+ branch32(Equal, repeatCount, Imm32(max), quantifierFailed);
// (1) Read an atom.
if (min)
@@ -187,7 +175,7 @@ void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunc
// (2) Keep reading if we're under the minimum.
if (min > 1)
- jl32(repeatCount, Imm32(min), readAtom);
+ branch32(LessThan, repeatCount, Imm32(min), readAtom);
// (3) Test the rest of the alternative.
if (!min)
@@ -221,7 +209,7 @@ void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor
else if (max == 1)
doneReadingAtomsList.append(jump());
else {
- jne32(repeatCount, Imm32(max), readAtom);
+ branch32(NotEqual, repeatCount, Imm32(max), readAtom);
doneReadingAtomsList.append(jump());
}
@@ -238,7 +226,7 @@ void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor
// (2) Verify that we have enough atoms.
doneReadingAtomsList.link(this);
- jl32(repeatCount, Imm32(min), quantifierFailed);
+ branch32(LessThan, repeatCount, Imm32(min), quantifierFailed);
// (3) Test the rest of the alternative.
push(index);
@@ -277,7 +265,7 @@ bool Generator::generatePatternCharacterPair(JumpList& failures, int ch1, int ch
// Optimistically consume 2 characters.
add32(Imm32(2), index);
- failures.append(jg32(index, length));
+ failures.append(branch32(GreaterThan, index, length));
// Load the characters we just consumed, offset -2 characters from index.
load32(BaseIndex(input, index, TimesTwo, -2 * 2), character);
@@ -306,7 +294,7 @@ bool Generator::generatePatternCharacterPair(JumpList& failures, int ch1, int ch
}
int pair = ch1 | (ch2 << 16);
- failures.append(jne32(character, Imm32(pair)));
+ failures.append(branch32(NotEqual, character, Imm32(pair)));
return true;
}
@@ -328,14 +316,14 @@ void Generator::generatePatternCharacter(JumpList& failures, int ch)
ch |= 32;
} else if (!isASCII(ch) && ((lower = Unicode::toLower(ch)) != (upper = Unicode::toUpper(ch)))) {
// handle unicode case sentitive characters - branch to success on upper
- isUpper = je32(character, Imm32(upper));
+ isUpper = branch32(Equal, character, Imm32(upper));
hasUpper = true;
ch = lower;
}
}
// checks for ch, or lower case version of ch, if insensitive
- failures.append(jne32(character, Imm32((unsigned short)ch)));
+ failures.append(branch32(NotEqual, character, Imm32((unsigned short)ch)));
if (m_parser.ignoreCase() && hasUpper) {
// for unicode case insensitive matches, branch here if upper matches.
@@ -357,33 +345,33 @@ void Generator::generateCharacterClassInvertedRange(JumpList& failures, JumpList
// check if there are any ranges or matches below lo. If not, just jl to failure -
// if there is anything else to check, check that first, if it falls through jmp to failure.
if ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
- Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));
+ Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));
// generate code for all ranges before this one
if (which)
generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
- matchDest.append(je32(character, Imm32((unsigned short)matches[*matchIndex])));
+ matchDest.append(branch32(Equal, character, Imm32((unsigned short)matches[*matchIndex])));
++*matchIndex;
}
failures.append(jump());
loOrAbove.link(this);
} else if (which) {
- Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));
+ Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));
generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
failures.append(jump());
loOrAbove.link(this);
} else
- failures.append(jl32(character, Imm32((unsigned short)lo)));
+ failures.append(branch32(LessThan, character, Imm32((unsigned short)lo)));
while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))
++*matchIndex;
- matchDest.append(jle32(character, Imm32((unsigned short)hi)));
+ matchDest.append(branch32(LessThanOrEqual, character, Imm32((unsigned short)hi)));
// fall through to here, the value is above hi.
// shuffle along & loop around if there are any more matches to handle.
@@ -397,12 +385,12 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
{
Jump unicodeFail;
if (charClass.numMatchesUnicode || charClass.numRangesUnicode) {
- Jump isAscii = jle32(character, Imm32(0x7f));
+ Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));
if (charClass.numMatchesUnicode) {
for (unsigned i = 0; i < charClass.numMatchesUnicode; ++i) {
UChar ch = charClass.matchesUnicode[i];
- matchDest.append(je32(character, Imm32(ch)));
+ matchDest.append(branch32(Equal, character, Imm32(ch)));
}
}
@@ -411,8 +399,8 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
UChar lo = charClass.rangesUnicode[i].begin;
UChar hi = charClass.rangesUnicode[i].end;
- Jump below = jl32(character, Imm32(lo));
- matchDest.append(jle32(character, Imm32(hi)));
+ Jump below = branch32(LessThan, character, Imm32(lo));
+ matchDest.append(branch32(LessThanOrEqual, character, Imm32(hi)));
below.link(this);
}
}
@@ -426,7 +414,7 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
JumpList failures;
generateCharacterClassInvertedRange(failures, matchDest, charClass.ranges, charClass.numRanges, &matchIndex, charClass.matches, charClass.numMatches);
while (matchIndex < charClass.numMatches)
- matchDest.append(je32(character, Imm32((unsigned short)charClass.matches[matchIndex++])));
+ matchDest.append(branch32(Equal, character, Imm32((unsigned short)charClass.matches[matchIndex++])));
failures.link(this);
} else if (charClass.numMatches) {
@@ -443,13 +431,13 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
if (isASCIIUpper(ch))
continue;
}
- matchDest.append(je32(character, Imm32((unsigned short)ch)));
+ matchDest.append(branch32(Equal, character, Imm32((unsigned short)ch)));
}
if (unsigned countAZaz = matchesAZaz.size()) {
or32(Imm32(32), character);
for (unsigned i = 0; i < countAZaz; ++i)
- matchDest.append(je32(character, Imm32(matchesAZaz[i])));
+ matchDest.append(branch32(Equal, character, Imm32(matchesAZaz[i])));
}
}
@@ -533,7 +521,7 @@ void Generator::generateAssertionBOL(JumpList& failures)
JumpList previousIsNewline;
// begin of input == success
- previousIsNewline.append(je32(index, Imm32(0)));
+ previousIsNewline.append(branch32(Equal, index, Imm32(0)));
// now check prev char against newline characters.
load16(BaseIndex(input, index, TimesTwo, -2), character);
@@ -543,7 +531,7 @@ void Generator::generateAssertionBOL(JumpList& failures)
previousIsNewline.link(this);
} else
- failures.append(jne32(index, Imm32(0)));
+ failures.append(branch32(NotEqual, index, Imm32(0)));
}
void Generator::generateAssertionEOL(JumpList& failures)
@@ -556,7 +544,7 @@ void Generator::generateAssertionEOL(JumpList& failures)
failures.append(jump());
nextIsNewline.link(this);
} else {
- failures.append(jne32(length, index));
+ failures.append(branch32(NotEqual, length, index));
}
}
@@ -568,7 +556,7 @@ void Generator::generateAssertionWordBoundary(JumpList& failures, bool invert)
// (1) Check if the previous value was a word char
// (1.1) check for begin of input
- Jump atBegin = je32(index, Imm32(0));
+ Jump atBegin = branch32(Equal, index, Imm32(0));
// (1.2) load the last char, and chck if is word character
load16(BaseIndex(input, index, TimesTwo, -2), character);
JumpList previousIsWord;
@@ -625,14 +613,14 @@ void Generator::generateBackreference(JumpList& failures, unsigned subpatternId)
skipIncrement.link(this);
// check if we're at the end of backref (if we are, success!)
- Jump endOfBackRef = je32(Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);
+ Jump endOfBackRef = branch32(Equal, Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);
load16(BaseIndex(input, repeatCount, MacroAssembler::TimesTwo), character);
// check if we've run out of input (this would be a can o'fail)
- Jump endOfInput = je32(length, index);
+ Jump endOfInput = branch32(Equal, length, index);
- je16(character, BaseIndex(input, index, TimesTwo), topOfLoop);
+ branch16(Equal, BaseIndex(input, index, TimesTwo), character, topOfLoop);
endOfInput.link(this);
diff --git a/JavaScriptCore/wrec/WRECGenerator.h b/JavaScriptCore/wrec/WRECGenerator.h
index af4101a..8562cac 100644
--- a/JavaScriptCore/wrec/WRECGenerator.h
+++ b/JavaScriptCore/wrec/WRECGenerator.h
@@ -62,13 +62,29 @@ namespace JSC {
{
}
+#if PLATFORM(X86)
static const RegisterID input = X86::eax;
- static const RegisterID length = X86::ecx;
static const RegisterID index = X86::edx;
- static const RegisterID character = X86::esi;
+ static const RegisterID length = X86::ecx;
static const RegisterID output = X86::edi;
+
+ static const RegisterID character = X86::esi;
static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match.
-
+
+ static const RegisterID returnRegister = X86::eax;
+#endif
+#if PLATFORM(X86_64)
+ static const RegisterID input = X86::edi;
+ static const RegisterID index = X86::esi;
+ static const RegisterID length = X86::edx;
+ static const RegisterID output = X86::ecx;
+
+ static const RegisterID character = X86::eax;
+ static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match.
+
+ static const RegisterID returnRegister = X86::eax;
+#endif
+
void generateEnter();
void generateSaveIndex();
void generateIncrementIndex(Jump* failure = 0);
diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h
index c17e501..9643517 100644
--- a/JavaScriptCore/wtf/Assertions.h
+++ b/JavaScriptCore/wtf/Assertions.h
@@ -194,7 +194,7 @@ while (0)
/* COMPILE_ASSERT */
#ifndef COMPILE_ASSERT
-#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
+#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
#endif
/* FATAL */
diff --git a/JavaScriptCore/wtf/ByteArray.h b/JavaScriptCore/wtf/ByteArray.h
index 865c30e..33f0877 100644
--- a/JavaScriptCore/wtf/ByteArray.h
+++ b/JavaScriptCore/wtf/ByteArray.h
@@ -69,8 +69,7 @@ namespace WTF {
private:
ByteArray(size_t size)
- : RefCountedBase(1)
- , m_size(size)
+ : m_size(size)
{
}
size_t m_size;
diff --git a/JavaScriptCore/wtf/CrossThreadRefCounted.h b/JavaScriptCore/wtf/CrossThreadRefCounted.h
new file mode 100644
index 0000000..82f1ba1
--- /dev/null
+++ b/JavaScriptCore/wtf/CrossThreadRefCounted.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CrossThreadRefCounted_h
+#define CrossThreadRefCounted_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Threading.h>
+#include <wtf/TypeTraits.h>
+
+namespace WTF {
+
+ // Used to allowing sharing data across classes and threads (like ThreadedSafeShared).
+ //
+ // Why not just use ThreadSafeShared?
+ // ThreadSafeShared can have a significant perf impact when used in low level classes
+ // (like UString) that get ref/deref'ed a lot. This class has the benefit of doing fast ref
+ // counts like RefPtr whenever possible, but it has the downside that you need to copy it
+ // to use it on another thread.
+ //
+ // Is this class threadsafe?
+ // While each instance of the class is not threadsafe, the copied instance is threadsafe
+ // with respect to the original and any other copies. The underlying m_data is jointly
+ // owned by the original instance and all copies.
+ template<class T>
+ class CrossThreadRefCounted : Noncopyable {
+ public:
+ static PassRefPtr<CrossThreadRefCounted<T> > create(T* data)
+ {
+ return adoptRef(new CrossThreadRefCounted<T>(data, 0));
+ }
+
+ // Used to make an instance that can be used on another thread.
+ PassRefPtr<CrossThreadRefCounted<T> > crossThreadCopy();
+
+ void ref();
+ void deref();
+ T* release();
+
+#ifndef NDEBUG
+ bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); }
+#endif
+
+ private:
+ CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
+ : m_threadSafeRefCounter(threadedCounter)
+ , m_data(data)
+#ifndef NDEBUG
+ , m_threadId(0)
+#endif
+ {
+ }
+
+ ~CrossThreadRefCounted()
+ {
+ if (!m_threadSafeRefCounter)
+ delete m_data;
+ }
+
+ void threadSafeDeref();
+
+ RefCountedBase m_refCounter;
+ ThreadSafeSharedBase* m_threadSafeRefCounter;
+ T* m_data;
+#ifndef NDEBUG
+ ThreadIdentifier m_threadId;
+#endif
+ };
+
+ template<class T>
+ void CrossThreadRefCounted<T>::ref()
+ {
+ ASSERT(!m_threadId || m_threadId == currentThread());
+ m_refCounter.ref();
+#ifndef NDEBUG
+ // Store the threadId as soon as the ref count gets to 2.
+ // The class gets created with a ref count of 1 and then passed
+ // to another thread where to ref count get increased. This
+ // is a heuristic but it seems to always work and has helped
+ // find some bugs.
+ if (!m_threadId && m_refCounter.refCount() == 2)
+ m_threadId = currentThread();
+#endif
+ }
+
+ template<class T>
+ void CrossThreadRefCounted<T>::deref()
+ {
+ ASSERT(!m_threadId || m_threadId == currentThread());
+ if (m_refCounter.derefBase()) {
+ threadSafeDeref();
+ delete this;
+ } else {
+#ifndef NDEBUG
+ // Clear the threadId when the ref goes to 1 because it
+ // is safe to be passed to another thread at this point.
+ if (m_threadId && m_refCounter.refCount() == 1)
+ m_threadId = 0;
+#endif
+ }
+ }
+
+ template<class T>
+ T* CrossThreadRefCounted<T>::release()
+ {
+ ASSERT(!isShared());
+
+ T* data = m_data;
+ m_data = 0;
+ return data;
+ }
+
+ template<class T>
+ PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy()
+ {
+ if (m_threadSafeRefCounter)
+ m_threadSafeRefCounter->ref();
+ else
+ m_threadSafeRefCounter = new ThreadSafeSharedBase(2);
+ return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter));
+ }
+
+
+ template<class T>
+ void CrossThreadRefCounted<T>::threadSafeDeref()
+ {
+ if (m_threadSafeRefCounter && m_threadSafeRefCounter->derefBase()) {
+ delete m_threadSafeRefCounter;
+ m_threadSafeRefCounter = 0;
+ }
+ }
+} // namespace WTF
+
+using WTF::CrossThreadRefCounted;
+
+#endif // CrossThreadRefCounted_h
diff --git a/JavaScriptCore/wtf/CurrentTime.cpp b/JavaScriptCore/wtf/CurrentTime.cpp
index d9ea448..74984c1 100644
--- a/JavaScriptCore/wtf/CurrentTime.cpp
+++ b/JavaScriptCore/wtf/CurrentTime.cpp
@@ -32,13 +32,9 @@
#include "config.h"
#include "CurrentTime.h"
-#if PLATFORM(MAC)
-#include <CoreFoundation/CFDate.h>
-#elif PLATFORM(GTK)
-#include <glib.h>
-#elif PLATFORM(WX)
-#include <wx/datetime.h>
-#elif PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS)
+// Windows is first since we want to use hires timers, despite PLATFORM(CF)
+// being defined.
// If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod.
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -47,6 +43,12 @@
#include <sys/timeb.h>
#include <sys/types.h>
#include <time.h>
+#elif PLATFORM(CF)
+#include <CoreFoundation/CFDate.h>
+#elif PLATFORM(GTK)
+#include <glib.h>
+#elif PLATFORM(WX)
+#include <wx/datetime.h>
#else // Posix systems relying on the gettimeofday()
#include <sys/time.h>
#endif
@@ -55,35 +57,7 @@ namespace WTF {
const double msPerSecond = 1000.0;
-#if PLATFORM(MAC)
-
-double currentTime()
-{
- return CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
-}
-
-#elif PLATFORM(GTK)
-
-// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
-// better accuracy compared with Windows implementation of g_get_current_time:
-// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time).
-// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function.
-double currentTime()
-{
- GTimeVal now;
- g_get_current_time(&now);
- return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0);
-}
-
-#elif PLATFORM(WX)
-
-double currentTime()
-{
- wxDateTime now = wxDateTime::UNow();
- return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
-}
-
-#elif PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS)
static LARGE_INTEGER qpcFrequency;
static bool syncedTime;
@@ -210,6 +184,34 @@ double currentTime()
return utc / 1000.0;
}
+#elif PLATFORM(CF)
+
+double currentTime()
+{
+ return CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
+}
+
+#elif PLATFORM(GTK)
+
+// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
+// better accuracy compared with Windows implementation of g_get_current_time:
+// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time).
+// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function.
+double currentTime()
+{
+ GTimeVal now;
+ g_get_current_time(&now);
+ return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0);
+}
+
+#elif PLATFORM(WX)
+
+double currentTime()
+{
+ wxDateTime now = wxDateTime::UNow();
+ return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
+}
+
#else // Other Posix systems rely on the gettimeofday().
double currentTime()
diff --git a/JavaScriptCore/wtf/Deque.h b/JavaScriptCore/wtf/Deque.h
index 70c546b..c371d38 100644
--- a/JavaScriptCore/wtf/Deque.h
+++ b/JavaScriptCore/wtf/Deque.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -75,9 +76,14 @@ namespace WTF {
template<typename U> void append(const U&);
template<typename U> void prepend(const U&);
void removeFirst();
+ void remove(iterator&);
+ void remove(const_iterator&);
void clear();
+ template<typename Predicate>
+ iterator findIf(Predicate&);
+
private:
friend class DequeIteratorBase<T>;
@@ -85,6 +91,7 @@ namespace WTF {
typedef VectorTypeOperations<T> TypeOperations;
typedef DequeIteratorBase<T> IteratorBase;
+ void remove(size_t position);
void invalidateIterators();
void destroyAll();
void checkValidity() const;
@@ -124,6 +131,7 @@ namespace WTF {
private:
void addToIteratorsList();
+ void removeFromIteratorsList();
void checkValidity() const;
void checkValidity(const Base&) const;
@@ -348,7 +356,7 @@ namespace WTF {
destroyAll();
}
- template <typename T>
+ template<typename T>
inline void Deque<T>::swap(Deque<T>& other)
{
checkValidity();
@@ -361,7 +369,7 @@ namespace WTF {
other.checkValidity();
}
- template <typename T>
+ template<typename T>
inline void Deque<T>::clear()
{
checkValidity();
@@ -373,6 +381,18 @@ namespace WTF {
}
template<typename T>
+ template<typename Predicate>
+ inline DequeIterator<T> Deque<T>::findIf(Predicate& predicate)
+ {
+ iterator end_iterator = end();
+ for (iterator it = begin(); it != end_iterator; ++it) {
+ if (predicate(*it))
+ return it;
+ }
+ return end_iterator;
+ }
+
+ template<typename T>
inline void Deque<T>::expandCapacityIfNeeded()
{
if (m_start) {
@@ -447,10 +467,48 @@ namespace WTF {
checkValidity();
}
+ template<typename T>
+ inline void Deque<T>::remove(iterator& it)
+ {
+ it.checkValidity();
+ remove(it.m_index);
+ }
+
+ template<typename T>
+ inline void Deque<T>::remove(const_iterator& it)
+ {
+ it.checkValidity();
+ remove(it.m_index);
+ }
+
+ template<typename T>
+ inline void Deque<T>::remove(size_t position)
+ {
+ if (position == m_end)
+ return;
+
+ checkValidity();
+ invalidateIterators();
+
+ T* buffer = m_buffer.buffer();
+ TypeOperations::destruct(&buffer[position], &buffer[position + 1]);
+
+ // Find which segment of the circular buffer contained the remove element, and only move elements in that part.
+ if (position >= m_start) {
+ TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1);
+ m_start = (m_start + 1) % m_buffer.capacity();
+ } else {
+ TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position);
+ m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity();
+ }
+ checkValidity();
+ }
+
#ifdef NDEBUG
template<typename T> inline void DequeIteratorBase<T>::checkValidity() const { }
template<typename T> inline void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase<T>&) const { }
template<typename T> inline void DequeIteratorBase<T>::addToIteratorsList() { }
+ template<typename T> inline void DequeIteratorBase<T>::removeFromIteratorsList() { }
#else
template<typename T>
void DequeIteratorBase<T>::checkValidity() const
@@ -480,6 +538,30 @@ namespace WTF {
}
m_previous = 0;
}
+
+ template<typename T>
+ void DequeIteratorBase<T>::removeFromIteratorsList()
+ {
+ if (!m_deque) {
+ ASSERT(!m_next);
+ ASSERT(!m_previous);
+ } else {
+ if (m_next) {
+ ASSERT(m_next->m_previous == this);
+ m_next->m_previous = m_previous;
+ }
+ if (m_previous) {
+ ASSERT(m_deque->m_iterators != this);
+ ASSERT(m_previous->m_next == this);
+ m_previous->m_next = m_next;
+ } else {
+ ASSERT(m_deque->m_iterators == this);
+ m_deque->m_iterators = m_next;
+ }
+ }
+ m_next = 0;
+ m_previous = 0;
+ }
#endif
template<typename T>
@@ -507,30 +589,25 @@ namespace WTF {
}
template<typename T>
+ inline DequeIteratorBase<T>& DequeIteratorBase<T>::operator=(const Base& other)
+ {
+ checkValidity();
+ other.checkValidity();
+ removeFromIteratorsList();
+
+ m_deque = other.m_deque;
+ m_index = other.m_index;
+ addToIteratorsList();
+ checkValidity();
+ return *this;
+ }
+
+ template<typename T>
inline DequeIteratorBase<T>::~DequeIteratorBase()
{
#ifndef NDEBUG
- // Delete iterator from doubly-linked list of iterators.
- if (!m_deque) {
- ASSERT(!m_next);
- ASSERT(!m_previous);
- } else {
- if (m_next) {
- ASSERT(m_next->m_previous == this);
- m_next->m_previous = m_previous;
- }
- if (m_previous) {
- ASSERT(m_deque->m_iterators != this);
- ASSERT(m_previous->m_next == this);
- m_previous->m_next = m_next;
- } else {
- ASSERT(m_deque->m_iterators == this);
- m_deque->m_iterators = m_next;
- }
- }
+ removeFromIteratorsList();
m_deque = 0;
- m_next = 0;
- m_previous = 0;
#endif
}
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index 88c10ca..bcac242 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -94,7 +94,7 @@
#define FORCE_SYSTEM_MALLOC 1
#endif
-#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC))
+#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC) || HAVE(MADV_FREE_REUSE))
#ifndef NDEBUG
namespace WTF {
@@ -321,9 +321,11 @@ namespace WTF {
#define CHECK_CONDITION ASSERT
#if PLATFORM(DARWIN)
+class Span;
+class TCMalloc_Central_FreeListPadded;
class TCMalloc_PageHeap;
class TCMalloc_ThreadCache;
-class TCMalloc_Central_FreeListPadded;
+template <typename T> class PageHeapAllocator;
class FastMallocZone {
public:
@@ -339,7 +341,7 @@ public:
static void statistics(malloc_zone_t*, malloc_statistics_t* stats) { memset(stats, 0, sizeof(malloc_statistics_t)); }
private:
- FastMallocZone(TCMalloc_PageHeap*, TCMalloc_ThreadCache**, TCMalloc_Central_FreeListPadded*);
+ FastMallocZone(TCMalloc_PageHeap*, TCMalloc_ThreadCache**, TCMalloc_Central_FreeListPadded*, PageHeapAllocator<Span>*, PageHeapAllocator<TCMalloc_ThreadCache>*);
static size_t size(malloc_zone_t*, const void*);
static void* zoneMalloc(malloc_zone_t*, size_t);
static void* zoneCalloc(malloc_zone_t*, size_t numItems, size_t size);
@@ -352,6 +354,8 @@ private:
TCMalloc_PageHeap* m_pageHeap;
TCMalloc_ThreadCache** m_threadHeaps;
TCMalloc_Central_FreeListPadded* m_centralCaches;
+ PageHeapAllocator<Span>* m_spanAllocator;
+ PageHeapAllocator<TCMalloc_ThreadCache>* m_pageHeapAllocator;
};
#endif
@@ -820,6 +824,9 @@ class PageHeapAllocator {
char* free_area_;
size_t free_avail_;
+ // Linked list of all regions allocated by this allocator
+ void* allocated_regions_;
+
// Free list of already carved objects
void* free_list_;
@@ -830,6 +837,7 @@ class PageHeapAllocator {
void Init() {
ASSERT(kAlignedSize <= kAllocIncrement);
inuse_ = 0;
+ allocated_regions_ = 0;
free_area_ = NULL;
free_avail_ = 0;
free_list_ = NULL;
@@ -844,9 +852,14 @@ class PageHeapAllocator {
} else {
if (free_avail_ < kAlignedSize) {
// Need more room
- free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
- if (free_area_ == NULL) CRASH();
- free_avail_ = kAllocIncrement;
+ char* new_allocation = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
+ if (!new_allocation)
+ CRASH();
+
+ *(void**)new_allocation = allocated_regions_;
+ allocated_regions_ = new_allocation;
+ free_area_ = new_allocation + kAlignedSize;
+ free_avail_ = kAllocIncrement - kAlignedSize;
}
result = free_area_;
free_area_ += kAlignedSize;
@@ -863,6 +876,18 @@ class PageHeapAllocator {
}
int inuse() const { return inuse_; }
+
+#if defined(WTF_CHANGES) && PLATFORM(DARWIN)
+ template <class Recorder>
+ void recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader)
+ {
+ vm_address_t adminAllocation = reinterpret_cast<vm_address_t>(allocated_regions_);
+ while (adminAllocation) {
+ recorder.recordRegion(adminAllocation, kAllocIncrement);
+ adminAllocation = *reader(reinterpret_cast<vm_address_t*>(adminAllocation));
+ }
+ }
+#endif
};
// -------------------------------------------------------------------------
@@ -1378,8 +1403,14 @@ static ALWAYS_INLINE void mergeDecommittedStates(Span*, Span*) { }
#else
static ALWAYS_INLINE void mergeDecommittedStates(Span* destination, Span* other)
{
- if (other->decommitted)
+ if (destination->decommitted && !other->decommitted) {
+ TCMalloc_SystemRelease(reinterpret_cast<void*>(other->start << kPageShift),
+ static_cast<size_t>(other->length << kPageShift));
+ } else if (other->decommitted && !destination->decommitted) {
+ TCMalloc_SystemRelease(reinterpret_cast<void*>(destination->start << kPageShift),
+ static_cast<size_t>(destination->length << kPageShift));
destination->decommitted = true;
+ }
}
#endif
@@ -3571,7 +3602,7 @@ extern "C" struct mallinfo mallinfo(void) {
#if defined(__GLIBC__)
extern "C" {
-# if defined(__GNUC__) && !defined(__MACH__) && defined(HAVE___ATTRIBUTE__)
+#if COMPILER(GCC) && !defined(__MACH__) && defined(HAVE___ATTRIBUTE__)
// Potentially faster variants that use the gcc alias extension.
// Mach-O (Darwin) does not support weak aliases, hence the __MACH__ check.
# define ALIAS(x) __attribute__ ((weak, alias (x)))
@@ -3630,6 +3661,7 @@ public:
void visit(void* ptr) { m_freeObjects.add(ptr); }
bool isFreeObject(void* ptr) const { return m_freeObjects.contains(ptr); }
+ bool isFreeObject(vm_address_t ptr) const { return isFreeObject(reinterpret_cast<void*>(ptr)); }
size_t freeObjectCount() const { return m_freeObjects.size(); }
void findFreeObjects(TCMalloc_ThreadCache* threadCache)
@@ -3680,7 +3712,9 @@ class PageMapMemoryUsageRecorder {
vm_range_recorder_t* m_recorder;
const RemoteMemoryReader& m_reader;
const FreeObjectFinder& m_freeObjectFinder;
- mutable HashSet<void*> m_seenPointers;
+
+ HashSet<void*> m_seenPointers;
+ Vector<Span*> m_coalescedSpans;
public:
PageMapMemoryUsageRecorder(task_t task, void* context, unsigned typeMask, vm_range_recorder_t* recorder, const RemoteMemoryReader& reader, const FreeObjectFinder& freeObjectFinder)
@@ -3692,51 +3726,133 @@ public:
, m_freeObjectFinder(freeObjectFinder)
{ }
- int visit(void* ptr) const
+ ~PageMapMemoryUsageRecorder()
+ {
+ ASSERT(!m_coalescedSpans.size());
+ }
+
+ void recordPendingRegions()
+ {
+ Span* lastSpan = m_coalescedSpans[m_coalescedSpans.size() - 1];
+ vm_range_t ptrRange = { m_coalescedSpans[0]->start << kPageShift, 0 };
+ ptrRange.size = (lastSpan->start << kPageShift) - ptrRange.address + (lastSpan->length * kPageSize);
+
+ // Mark the memory region the spans represent as a candidate for containing pointers
+ if (m_typeMask & MALLOC_PTR_REGION_RANGE_TYPE)
+ (*m_recorder)(m_task, m_context, MALLOC_PTR_REGION_RANGE_TYPE, &ptrRange, 1);
+
+ if (!(m_typeMask & MALLOC_PTR_IN_USE_RANGE_TYPE)) {
+ m_coalescedSpans.clear();
+ return;
+ }
+
+ Vector<vm_range_t, 1024> allocatedPointers;
+ for (size_t i = 0; i < m_coalescedSpans.size(); ++i) {
+ Span *theSpan = m_coalescedSpans[i];
+ if (theSpan->free)
+ continue;
+
+ vm_address_t spanStartAddress = theSpan->start << kPageShift;
+ vm_size_t spanSizeInBytes = theSpan->length * kPageSize;
+
+ if (!theSpan->sizeclass) {
+ // If it's an allocated large object span, mark it as in use
+ if (!m_freeObjectFinder.isFreeObject(spanStartAddress))
+ allocatedPointers.append((vm_range_t){spanStartAddress, spanSizeInBytes});
+ } else {
+ const size_t objectSize = ByteSizeForClass(theSpan->sizeclass);
+
+ // Mark each allocated small object within the span as in use
+ const vm_address_t endOfSpan = spanStartAddress + spanSizeInBytes;
+ for (vm_address_t object = spanStartAddress; object + objectSize <= endOfSpan; object += objectSize) {
+ if (!m_freeObjectFinder.isFreeObject(object))
+ allocatedPointers.append((vm_range_t){object, objectSize});
+ }
+ }
+ }
+
+ (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, allocatedPointers.data(), allocatedPointers.size());
+
+ m_coalescedSpans.clear();
+ }
+
+ int visit(void* ptr)
{
if (!ptr)
return 1;
Span* span = m_reader(reinterpret_cast<Span*>(ptr));
+ if (!span->start)
+ return 1;
+
if (m_seenPointers.contains(ptr))
return span->length;
m_seenPointers.add(ptr);
- // Mark the memory used for the Span itself as an administrative region
- vm_range_t ptrRange = { reinterpret_cast<vm_address_t>(ptr), sizeof(Span) };
- if (m_typeMask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE))
- (*m_recorder)(m_task, m_context, MALLOC_ADMIN_REGION_RANGE_TYPE, &ptrRange, 1);
+ if (!m_coalescedSpans.size()) {
+ m_coalescedSpans.append(span);
+ return span->length;
+ }
- ptrRange.address = span->start << kPageShift;
- ptrRange.size = span->length * kPageSize;
+ Span* previousSpan = m_coalescedSpans[m_coalescedSpans.size() - 1];
+ vm_address_t previousSpanStartAddress = previousSpan->start << kPageShift;
+ vm_size_t previousSpanSizeInBytes = previousSpan->length * kPageSize;
- // Mark the memory region the span represents as candidates for containing pointers
- if (m_typeMask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE))
- (*m_recorder)(m_task, m_context, MALLOC_PTR_REGION_RANGE_TYPE, &ptrRange, 1);
+ // If the new span is adjacent to the previous span, do nothing for now.
+ vm_address_t spanStartAddress = span->start << kPageShift;
+ if (spanStartAddress == previousSpanStartAddress + previousSpanSizeInBytes) {
+ m_coalescedSpans.append(span);
+ return span->length;
+ }
- if (!span->free && (m_typeMask & MALLOC_PTR_IN_USE_RANGE_TYPE)) {
- // If it's an allocated large object span, mark it as in use
- if (span->sizeclass == 0 && !m_freeObjectFinder.isFreeObject(reinterpret_cast<void*>(ptrRange.address)))
- (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, &ptrRange, 1);
- else if (span->sizeclass) {
- const size_t byteSize = ByteSizeForClass(span->sizeclass);
- unsigned totalObjects = (span->length << kPageShift) / byteSize;
- ASSERT(span->refcount <= totalObjects);
- char* ptr = reinterpret_cast<char*>(span->start << kPageShift);
+ // New span is not adjacent to previous span, so record the spans coalesced so far.
+ recordPendingRegions();
+ m_coalescedSpans.append(span);
- // Mark each allocated small object within the span as in use
- for (unsigned i = 0; i < totalObjects; i++) {
- char* thisObject = ptr + (i * byteSize);
- if (m_freeObjectFinder.isFreeObject(thisObject))
- continue;
+ return span->length;
+ }
+};
- vm_range_t objectRange = { reinterpret_cast<vm_address_t>(thisObject), byteSize };
- (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, &objectRange, 1);
- }
- }
+class AdminRegionRecorder {
+ task_t m_task;
+ void* m_context;
+ unsigned m_typeMask;
+ vm_range_recorder_t* m_recorder;
+ const RemoteMemoryReader& m_reader;
+
+ Vector<vm_range_t, 1024> m_pendingRegions;
+
+public:
+ AdminRegionRecorder(task_t task, void* context, unsigned typeMask, vm_range_recorder_t* recorder, const RemoteMemoryReader& reader)
+ : m_task(task)
+ , m_context(context)
+ , m_typeMask(typeMask)
+ , m_recorder(recorder)
+ , m_reader(reader)
+ { }
+
+ void recordRegion(vm_address_t ptr, size_t size)
+ {
+ if (m_typeMask & MALLOC_ADMIN_REGION_RANGE_TYPE)
+ m_pendingRegions.append((vm_range_t){ ptr, size });
+ }
+
+ void visit(void *ptr, size_t size)
+ {
+ recordRegion(reinterpret_cast<vm_address_t>(ptr), size);
+ }
+
+ void recordPendingRegions()
+ {
+ if (m_pendingRegions.size()) {
+ (*m_recorder)(m_task, m_context, MALLOC_ADMIN_REGION_RANGE_TYPE, m_pendingRegions.data(), m_pendingRegions.size());
+ m_pendingRegions.clear();
}
+ }
- return span->length;
+ ~AdminRegionRecorder()
+ {
+ ASSERT(!m_pendingRegions.size());
}
};
@@ -3759,10 +3875,22 @@ kern_return_t FastMallocZone::enumerate(task_t task, void* context, unsigned typ
TCMalloc_PageHeap::PageMap* pageMap = &pageHeap->pagemap_;
PageMapFreeObjectFinder pageMapFinder(memoryReader, finder);
- pageMap->visit(pageMapFinder, memoryReader);
+ pageMap->visitValues(pageMapFinder, memoryReader);
PageMapMemoryUsageRecorder usageRecorder(task, context, typeMask, recorder, memoryReader, finder);
- pageMap->visit(usageRecorder, memoryReader);
+ pageMap->visitValues(usageRecorder, memoryReader);
+ usageRecorder.recordPendingRegions();
+
+ AdminRegionRecorder adminRegionRecorder(task, context, typeMask, recorder, memoryReader);
+ pageMap->visitAllocations(adminRegionRecorder, memoryReader);
+
+ PageHeapAllocator<Span>* spanAllocator = memoryReader(mzone->m_spanAllocator);
+ PageHeapAllocator<TCMalloc_ThreadCache>* pageHeapAllocator = memoryReader(mzone->m_pageHeapAllocator);
+
+ spanAllocator->recordAdministrativeRegions(adminRegionRecorder, memoryReader);
+ pageHeapAllocator->recordAdministrativeRegions(adminRegionRecorder, memoryReader);
+
+ adminRegionRecorder.recordPendingRegions();
return 0;
}
@@ -3803,15 +3931,24 @@ void* FastMallocZone::zoneRealloc(malloc_zone_t*, void*, size_t)
extern "C" {
malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print,
- &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics };
+ &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics
+
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher.
+#endif
+
+ };
}
-FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache** threadHeaps, TCMalloc_Central_FreeListPadded* centralCaches)
+FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache** threadHeaps, TCMalloc_Central_FreeListPadded* centralCaches, PageHeapAllocator<Span>* spanAllocator, PageHeapAllocator<TCMalloc_ThreadCache>* pageHeapAllocator)
: m_pageHeap(pageHeap)
, m_threadHeaps(threadHeaps)
, m_centralCaches(centralCaches)
+ , m_spanAllocator(spanAllocator)
+ , m_pageHeapAllocator(pageHeapAllocator)
{
memset(&m_zone, 0, sizeof(m_zone));
+ m_zone.version = 4;
m_zone.zone_name = "JavaScriptCore FastMalloc";
m_zone.size = &FastMallocZone::size;
m_zone.malloc = &FastMallocZone::zoneMalloc;
@@ -3827,7 +3964,7 @@ FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache
void FastMallocZone::init()
{
- static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache));
+ static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator);
}
#endif
diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h
index b3c0b7a..c8d40f7 100644
--- a/JavaScriptCore/wtf/HashTraits.h
+++ b/JavaScriptCore/wtf/HashTraits.h
@@ -21,8 +21,8 @@
#ifndef WTF_HashTraits_h
#define WTF_HashTraits_h
-#include "Assertions.h"
#include "HashFunctions.h"
+#include "TypeTraits.h"
#include <utility>
#include <limits>
@@ -31,47 +31,6 @@ namespace WTF {
using std::pair;
using std::make_pair;
- template<typename T> struct IsInteger { static const bool value = false; };
- template<> struct IsInteger<bool> { static const bool value = true; };
- template<> struct IsInteger<char> { static const bool value = true; };
- template<> struct IsInteger<signed char> { static const bool value = true; };
- template<> struct IsInteger<unsigned char> { static const bool value = true; };
- template<> struct IsInteger<short> { static const bool value = true; };
- template<> struct IsInteger<unsigned short> { static const bool value = true; };
- template<> struct IsInteger<int> { static const bool value = true; };
- template<> struct IsInteger<unsigned int> { static const bool value = true; };
- template<> struct IsInteger<long> { static const bool value = true; };
- template<> struct IsInteger<unsigned long> { static const bool value = true; };
- template<> struct IsInteger<long long> { static const bool value = true; };
- template<> struct IsInteger<unsigned long long> { static const bool value = true; };
-
-#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
- template<> struct IsInteger<wchar_t> { static const bool value = true; };
-#endif
-
- COMPILE_ASSERT(IsInteger<bool>::value, WTF_IsInteger_bool_true);
- COMPILE_ASSERT(IsInteger<char>::value, WTF_IsInteger_char_true);
- COMPILE_ASSERT(IsInteger<signed char>::value, WTF_IsInteger_signed_char_true);
- COMPILE_ASSERT(IsInteger<unsigned char>::value, WTF_IsInteger_unsigned_char_true);
- COMPILE_ASSERT(IsInteger<short>::value, WTF_IsInteger_short_true);
- COMPILE_ASSERT(IsInteger<unsigned short>::value, WTF_IsInteger_unsigned_short_true);
- COMPILE_ASSERT(IsInteger<int>::value, WTF_IsInteger_int_true);
- COMPILE_ASSERT(IsInteger<unsigned int>::value, WTF_IsInteger_unsigned_int_true);
- COMPILE_ASSERT(IsInteger<long>::value, WTF_IsInteger_long_true);
- COMPILE_ASSERT(IsInteger<unsigned long>::value, WTF_IsInteger_unsigned_long_true);
- COMPILE_ASSERT(IsInteger<long long>::value, WTF_IsInteger_long_long_true);
- COMPILE_ASSERT(IsInteger<unsigned long long>::value, WTF_IsInteger_unsigned_long_long_true);
-
-#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
- COMPILE_ASSERT(IsInteger<wchar_t>::value, WTF_IsInteger_wchar_t_true);
-#endif
-
- COMPILE_ASSERT(!IsInteger<char*>::value, WTF_IsInteger_char_pointer_false);
- COMPILE_ASSERT(!IsInteger<const char* >::value, WTF_IsInteger_const_char_pointer_false);
- COMPILE_ASSERT(!IsInteger<volatile char* >::value, WTF_IsInteger_volatile_char_pointer__false);
- COMPILE_ASSERT(!IsInteger<double>::value, WTF_IsInteger_double_false);
- COMPILE_ASSERT(!IsInteger<float>::value, WTF_IsInteger_float_false);
-
template<typename T> struct HashTraits;
template<bool isInteger, typename T> struct GenericHashTraitsBase;
diff --git a/JavaScriptCore/wtf/MainThread.cpp b/JavaScriptCore/wtf/MainThread.cpp
index c7a6caa..3c19b7a 100644
--- a/JavaScriptCore/wtf/MainThread.cpp
+++ b/JavaScriptCore/wtf/MainThread.cpp
@@ -29,26 +29,25 @@
#include "config.h"
#include "MainThread.h"
+#include "CurrentTime.h"
+#include "Deque.h"
#include "StdLibExtras.h"
#include "Threading.h"
-#include "Vector.h"
namespace WTF {
struct FunctionWithContext {
MainThreadFunction* function;
void* context;
- ThreadCondition* syncFlag;
- FunctionWithContext(MainThreadFunction* function = 0, void* context = 0, ThreadCondition* syncFlag = 0)
+ FunctionWithContext(MainThreadFunction* function = 0, void* context = 0)
: function(function)
, context(context)
- , syncFlag(syncFlag)
{
}
};
-typedef Vector<FunctionWithContext> FunctionQueue;
+typedef Deque<FunctionWithContext> FunctionQueue;
static bool callbacksPaused; // This global variable is only accessed from main thread.
@@ -64,12 +63,14 @@ static FunctionQueue& functionQueue()
return staticFunctionQueue;
}
-#if !PLATFORM(WIN)
void initializeMainThread()
{
mainThreadFunctionQueueMutex();
+ initializeMainThreadPlatform();
}
-#endif
+
+// 0.1 sec delays in UI is approximate threshold when they become noticeable. Have a limit that's half of that.
+static const double maxRunLoopSuspensionTime = 0.05;
void dispatchFunctionsFromMainThread()
{
@@ -78,52 +79,42 @@ void dispatchFunctionsFromMainThread()
if (callbacksPaused)
return;
- FunctionQueue queueCopy;
- {
- MutexLocker locker(mainThreadFunctionQueueMutex());
- queueCopy.swap(functionQueue());
- }
+ double startTime = currentTime();
+
+ FunctionWithContext invocation;
+ while (true) {
+ {
+ MutexLocker locker(mainThreadFunctionQueueMutex());
+ if (!functionQueue().size())
+ break;
+ invocation = functionQueue().first();
+ functionQueue().removeFirst();
+ }
- for (unsigned i = 0; i < queueCopy.size(); ++i) {
- FunctionWithContext& invocation = queueCopy[i];
invocation.function(invocation.context);
- if (invocation.syncFlag)
- invocation.syncFlag->signal();
+
+ // If we are running accumulated functions for too long so UI may become unresponsive, we need to
+ // yield so the user input can be processed. Otherwise user may not be able to even close the window.
+ // This code has effect only in case the scheduleDispatchFunctionsOnMainThread() is implemented in a way that
+ // allows input events to be processed before we are back here.
+ if (currentTime() - startTime > maxRunLoopSuspensionTime) {
+ scheduleDispatchFunctionsOnMainThread();
+ break;
+ }
}
}
void callOnMainThread(MainThreadFunction* function, void* context)
{
ASSERT(function);
-
+ bool needToSchedule = false;
{
MutexLocker locker(mainThreadFunctionQueueMutex());
+ needToSchedule = functionQueue().size() == 0;
functionQueue().append(FunctionWithContext(function, context));
}
-
- scheduleDispatchFunctionsOnMainThread();
-}
-
-void callOnMainThreadAndWait(MainThreadFunction* function, void* context)
-{
- ASSERT(function);
-
- if (isMainThread()) {
- function(context);
- return;
- }
-
- ThreadCondition syncFlag;
- Mutex conditionMutex;
-
- {
- MutexLocker locker(mainThreadFunctionQueueMutex());
- functionQueue().append(FunctionWithContext(function, context, &syncFlag));
- conditionMutex.lock();
- }
-
- scheduleDispatchFunctionsOnMainThread();
- syncFlag.wait(conditionMutex);
+ if (needToSchedule)
+ scheduleDispatchFunctionsOnMainThread();
}
void setMainThreadCallbacksPaused(bool paused)
diff --git a/JavaScriptCore/wtf/MainThread.h b/JavaScriptCore/wtf/MainThread.h
index 953b986..01ce804 100644
--- a/JavaScriptCore/wtf/MainThread.h
+++ b/JavaScriptCore/wtf/MainThread.h
@@ -37,7 +37,6 @@ class Mutex;
typedef void MainThreadFunction(void*);
void callOnMainThread(MainThreadFunction*, void* context);
-void callOnMainThreadAndWait(MainThreadFunction*, void* context);
void setMainThreadCallbacksPaused(bool paused);
@@ -45,9 +44,10 @@ void setMainThreadCallbacksPaused(bool paused);
void initializeMainThread();
// These functions are internal to the callOnMainThread implementation.
-void dispatchFunctionsFromMainThread();
+void initializeMainThreadPlatform();
void scheduleDispatchFunctionsOnMainThread();
Mutex& mainThreadFunctionQueueMutex();
+void dispatchFunctionsFromMainThread();
} // namespace WTF
diff --git a/JavaScriptCore/wtf/MessageQueue.h b/JavaScriptCore/wtf/MessageQueue.h
index 19c5c10..9549f37 100644
--- a/JavaScriptCore/wtf/MessageQueue.h
+++ b/JavaScriptCore/wtf/MessageQueue.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,6 +30,7 @@
#ifndef MessageQueue_h
#define MessageQueue_h
+#include <limits>
#include <wtf/Assertions.h>
#include <wtf/Deque.h>
#include <wtf/Noncopyable.h>
@@ -50,7 +52,8 @@ namespace WTF {
void append(const DataType&);
void prepend(const DataType&);
bool waitForMessage(DataType&);
- MessageQueueWaitResult waitForMessageTimed(DataType&, double absoluteTime);
+ template<typename Predicate>
+ MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Predicate&, double absoluteTime);
void kill();
bool tryGetMessage(DataType&);
@@ -59,7 +62,11 @@ namespace WTF {
// The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time.
bool isEmpty();
+ static double infiniteTime() { return std::numeric_limits<double>::max(); }
+
private:
+ static bool alwaysTruePredicate(DataType&) { return true; }
+
mutable Mutex m_mutex;
ThreadCondition m_condition;
Deque<DataType> m_queue;
@@ -85,38 +92,33 @@ namespace WTF {
template<typename DataType>
inline bool MessageQueue<DataType>::waitForMessage(DataType& result)
{
- MutexLocker lock(m_mutex);
-
- while (!m_killed && m_queue.isEmpty())
- m_condition.wait(m_mutex);
-
- if (m_killed)
- return false;
-
- ASSERT(!m_queue.isEmpty());
- result = m_queue.first();
- m_queue.removeFirst();
- return true;
+ MessageQueueWaitResult exitReason = waitForMessageFilteredWithTimeout(result, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime());
+ ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived);
+ return exitReason == MessageQueueMessageReceived;
}
template<typename DataType>
- inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageTimed(DataType& result, double absoluteTime)
+ template<typename Predicate>
+ inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageFilteredWithTimeout(DataType& result, Predicate& predicate, double absoluteTime)
{
MutexLocker lock(m_mutex);
bool timedOut = false;
- while (!m_killed && !timedOut && m_queue.isEmpty())
+ DequeConstIterator<DataType> found = m_queue.end();
+ while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end())
timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
+ ASSERT(!timedOut || absoluteTime != infiniteTime());
+
if (m_killed)
return MessageQueueTerminated;
if (timedOut)
return MessageQueueTimeout;
- ASSERT(!m_queue.isEmpty());
- result = m_queue.first();
- m_queue.removeFirst();
+ ASSERT(found != m_queue.end());
+ result = *found;
+ m_queue.remove(found);
return MessageQueueMessageReceived;
}
@@ -157,7 +159,7 @@ namespace WTF {
MutexLocker lock(m_mutex);
return m_killed;
}
-}
+} // namespace WTF
using WTF::MessageQueue;
// MessageQueueWaitResult enum and all its values.
diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h
index 256b55c..af939e7 100644
--- a/JavaScriptCore/wtf/OwnPtr.h
+++ b/JavaScriptCore/wtf/OwnPtr.h
@@ -21,10 +21,11 @@
#ifndef WTF_OwnPtr_h
#define WTF_OwnPtr_h
+#include "Assertions.h"
+#include "Noncopyable.h"
+#include "TypeTraits.h"
#include <algorithm>
#include <memory>
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
#if PLATFORM(WIN)
@@ -41,10 +42,6 @@ namespace WTF {
// Unlike most of our smart pointers, OwnPtr can take either the pointer type or the pointed-to type.
- // FIXME: Share a single RemovePointer class template with RetainPtr.
- template <typename T> struct OwnPtrRemovePointer { typedef T type; };
- template <typename T> struct OwnPtrRemovePointer<T*> { typedef T type; };
-
template <typename T> inline void deleteOwnedPtr(T* ptr)
{
typedef char known[sizeof(T) ? 1 : -1];
@@ -63,7 +60,7 @@ namespace WTF {
template <typename T> class OwnPtr : Noncopyable {
public:
- typedef typename OwnPtrRemovePointer<T>::type ValueType;
+ typedef typename RemovePointer<T>::Type ValueType;
typedef ValueType* PtrType;
explicit OwnPtr(PtrType ptr = 0) : m_ptr(ptr) { }
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index fea00c4..1813114 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -40,6 +40,12 @@
/* be used regardless of operating environment */
#ifdef __APPLE__
#define WTF_PLATFORM_DARWIN 1
+#include <AvailabilityMacros.h>
+#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+#define BUILDING_ON_TIGER 1
+#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+#define BUILDING_ON_LEOPARD 1
+#endif
#endif
/* PLATFORM(WIN_OS) */
@@ -238,6 +244,11 @@
#define WTF_PLATFORM_X86_64 1
#endif
+/* PLATFORM(SH4) */
+#if defined(__SH4__)
+#define WTF_PLATFORM_SH4 1
+#endif
+
/* PLATFORM(SPARC64) */
#if defined(__sparc64__)
#define WTF_PLATFORM_SPARC64 1
@@ -268,8 +279,14 @@
#endif
#endif
+/* COMPILER(RVCT) */
+#if defined(__CC_ARM) || defined(__ARMCC__)
+#define WTF_COMPILER_RVCT 1
+#endif
+
/* COMPILER(GCC) */
-#if defined(__GNUC__)
+/* --gnu option of the RVCT compiler also defines __GNUC__ */
+#if defined(__GNUC__) && !COMPILER(RVCT)
#define WTF_COMPILER_GCC 1
#endif
@@ -290,11 +307,6 @@
#define WTF_COMPILER_CYGWIN 1
#endif
-/* COMPILER(RVCT) */
-#if defined(__CC_ARM) || defined(__ARMCC__)
-#define WTF_COMPILER_RVCT 1
-#endif
-
/* COMPILER(WINSCW) */
#if defined(__WINSCW__)
#define WTF_COMPILER_WINSCW 1
@@ -325,9 +337,7 @@
#define ENABLE_DASHBOARD_SUPPORT 1
#endif
#define HAVE_READLINE 1
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
-#define HAVE_DTRACE 1
-#endif
+#define HAVE_RUNLOOP_TIMER 1
#endif
#if PLATFORM(CHROMIUM) && PLATFORM(DARWIN)
@@ -363,6 +373,7 @@
#if PLATFORM(DARWIN)
#define HAVE_ERRNO_H 1
+#define HAVE_LANGINFO_H 1
#define HAVE_MMAP 1
#define HAVE_MERGESORT 1
#define HAVE_SBRK 1
@@ -371,6 +382,10 @@
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMEB_H 1
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#define HAVE_MADV_FREE_REUSE 1
+#endif
+
#elif PLATFORM(WIN_OS)
#define HAVE_FLOAT_H 1
@@ -394,11 +409,22 @@
#define HAVE_SYS_PARAM_H 1
#endif
+#elif PLATFORM(ANDROID)
+
+#define HAVE_ERRNO_H 1
+#define HAVE_LANGINFO_H 0
+#define HAVE_MMAP 1
+#define HAVE_SBRK 1
+#define HAVE_STRINGS_H 1
+#define HAVE_SYS_PARAM_H 1
+#define HAVE_SYS_TIME_H 1
+
#else
/* FIXME: is this actually used or do other platforms generate their own config.h? */
#define HAVE_ERRNO_H 1
+#define HAVE_LANGINFO_H 1
#define HAVE_MMAP 1
#define HAVE_SBRK 1
#define HAVE_STRINGS_H 1
@@ -466,14 +492,22 @@
#define ENABLE_ARCHIVE 1
#endif
+#if !defined(ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL)
+#define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0
+#endif
+
#if !defined(WTF_USE_ALTERNATE_JSIMMEDIATE) && PLATFORM(X86_64) && PLATFORM(MAC)
#define WTF_USE_ALTERNATE_JSIMMEDIATE 1
#endif
+#if !defined(ENABLE_REPAINT_THROTTLING)
+#define ENABLE_REPAINT_THROTTLING 0
+#endif
+
#if !defined(ENABLE_JIT)
-/* x86-64 support is under development. */
+/* The JIT is tested & working on x86_64 Mac */
#if PLATFORM(X86_64) && PLATFORM(MAC)
- #define ENABLE_JIT 0
+ #define ENABLE_JIT 1
#define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
/* The JIT is tested & working on x86 Mac */
#elif PLATFORM(X86) && PLATFORM(MAC)
diff --git a/JavaScriptCore/wtf/RefCounted.h b/JavaScriptCore/wtf/RefCounted.h
index ac8e167..93ee0da 100644
--- a/JavaScriptCore/wtf/RefCounted.h
+++ b/JavaScriptCore/wtf/RefCounted.h
@@ -49,8 +49,8 @@ public:
}
protected:
- RefCountedBase(int initialRefCount)
- : m_refCount(initialRefCount)
+ RefCountedBase()
+ : m_refCount(1)
#ifndef NDEBUG
, m_deletionHasBegun(false)
#endif
@@ -76,6 +76,9 @@ protected:
}
protected:
+ template<class T>
+ friend class CrossThreadRefCounted;
+
int m_refCount;
#ifndef NDEBUG
bool m_deletionHasBegun;
@@ -85,11 +88,6 @@ protected:
template<class T> class RefCounted : public RefCountedBase {
public:
- RefCounted(int initialRefCount = 1)
- : RefCountedBase(initialRefCount)
- {
- }
-
void deref()
{
if (derefBase())
diff --git a/JavaScriptCore/wtf/RetainPtr.h b/JavaScriptCore/wtf/RetainPtr.h
index a66a127..77f25e0 100644
--- a/JavaScriptCore/wtf/RetainPtr.h
+++ b/JavaScriptCore/wtf/RetainPtr.h
@@ -21,6 +21,7 @@
#ifndef RetainPtr_h
#define RetainPtr_h
+#include "TypeTraits.h"
#include <algorithm>
#include <CoreFoundation/CoreFoundation.h>
@@ -30,14 +31,6 @@
namespace WTF {
- template <typename T> struct RemovePointer {
- typedef T type;
- };
-
- template <typename T> struct RemovePointer<T*> {
- typedef T type;
- };
-
// Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
// so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
@@ -56,7 +49,7 @@ namespace WTF {
template <typename T> class RetainPtr {
public:
- typedef typename RemovePointer<T>::type ValueType;
+ typedef typename RemovePointer<T>::Type ValueType;
typedef ValueType* PtrType;
RetainPtr() : m_ptr(0) {}
diff --git a/JavaScriptCore/wtf/TCPageMap.h b/JavaScriptCore/wtf/TCPageMap.h
index 3e6b80e..9ffd77b 100644
--- a/JavaScriptCore/wtf/TCPageMap.h
+++ b/JavaScriptCore/wtf/TCPageMap.h
@@ -54,7 +54,6 @@
#endif
#include <string.h>
-
#include "Assertions.h"
// Single-level array
@@ -164,7 +163,7 @@ class TCMalloc_PageMap2 {
#ifdef WTF_CHANGES
template<class Visitor, class MemoryReader>
- void visit(const Visitor& visitor, const MemoryReader& reader)
+ void visitValues(Visitor& visitor, const MemoryReader& reader)
{
for (int i = 0; i < ROOT_LENGTH; i++) {
if (!root_[i])
@@ -175,6 +174,14 @@ class TCMalloc_PageMap2 {
;
}
}
+
+ template<class Visitor, class MemoryReader>
+ void visitAllocations(Visitor& visitor, const MemoryReader&) {
+ for (int i = 0; i < ROOT_LENGTH; i++) {
+ if (root_[i])
+ visitor.visit(root_[i], sizeof(Leaf));
+ }
+ }
#endif
};
@@ -266,7 +273,7 @@ class TCMalloc_PageMap3 {
#ifdef WTF_CHANGES
template<class Visitor, class MemoryReader>
- void visit(const Visitor& visitor, const MemoryReader& reader) {
+ void visitValues(Visitor& visitor, const MemoryReader& reader) {
Node* root = reader(root_);
for (int i = 0; i < INTERIOR_LENGTH; i++) {
if (!root->ptrs[i])
@@ -283,6 +290,26 @@ class TCMalloc_PageMap3 {
}
}
}
+
+ template<class Visitor, class MemoryReader>
+ void visitAllocations(Visitor& visitor, const MemoryReader& reader) {
+ visitor.visit(root_, sizeof(Node));
+
+ Node* root = reader(root_);
+ for (int i = 0; i < INTERIOR_LENGTH; i++) {
+ if (!root->ptrs[i])
+ continue;
+
+ visitor.visit(root->ptrs[i], sizeof(Node));
+ Node* n = reader(root->ptrs[i]);
+ for (int j = 0; j < INTERIOR_LENGTH; j++) {
+ if (!n->ptrs[j])
+ continue;
+
+ visitor.visit(n->ptrs[j], sizeof(Leaf));
+ }
+ }
+ }
#endif
};
diff --git a/JavaScriptCore/wtf/TCSystemAlloc.cpp b/JavaScriptCore/wtf/TCSystemAlloc.cpp
index 3a8908d..bf2dcb1 100644
--- a/JavaScriptCore/wtf/TCSystemAlloc.cpp
+++ b/JavaScriptCore/wtf/TCSystemAlloc.cpp
@@ -381,9 +381,17 @@ void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, size_t alignment) {
return NULL;
}
+#if HAVE(MADV_FREE_REUSE)
+
+void TCMalloc_SystemRelease(void* start, size_t length)
+{
+ while (madvise(start, length, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+}
+
+#elif HAVE(MADV_DONTNEED)
+
void TCMalloc_SystemRelease(void* start, size_t length)
{
-#if HAVE(MADV_DONTNEED)
if (FLAGS_malloc_devmem_start) {
// It's not safe to use MADV_DONTNEED if we've been mapping
// /dev/mem for heap memory
@@ -414,25 +422,41 @@ void TCMalloc_SystemRelease(void* start, size_t length)
errno == EAGAIN) {
// NOP
}
- return;
}
-#endif
+}
-#if HAVE(MMAP)
+#elif HAVE(MMAP)
+
+void TCMalloc_SystemRelease(void* start, size_t length)
+{
void* newAddress = mmap(start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
// If the mmap failed then that's ok, we just won't return the memory to the system.
ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED));
- return;
-#endif
+}
+
+#else
+
+// Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease
+// declared in TCSystemAlloc.h
-#if !HAVE(MADV_DONTNEED) && !HAVE(MMAP)
- UNUSED_PARAM(start);
- UNUSED_PARAM(length);
#endif
+
+#if HAVE(MADV_FREE_REUSE)
+
+void TCMalloc_SystemCommit(void* start, size_t length)
+{
+ while (madvise(start, length, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
}
-#if HAVE(VIRTUALALLOC)
+#elif HAVE(VIRTUALALLOC)
+
void TCMalloc_SystemCommit(void*, size_t)
{
}
+
+#else
+
+// Platforms that don't need to explicitly commit memory use an empty inline version of TCMalloc_SystemCommit
+// declared in TCSystemAlloc.h
+
#endif
diff --git a/JavaScriptCore/wtf/TCSystemAlloc.h b/JavaScriptCore/wtf/TCSystemAlloc.h
index d82e860..f2c915e 100644
--- a/JavaScriptCore/wtf/TCSystemAlloc.h
+++ b/JavaScriptCore/wtf/TCSystemAlloc.h
@@ -62,9 +62,13 @@ extern void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes,
// be released, partial pages will not.)
extern void TCMalloc_SystemRelease(void* start, size_t length);
-#if HAVE(VIRTUALALLOC)
extern void TCMalloc_SystemCommit(void* start, size_t length);
-#else
+
+#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP)
+inline void TCMalloc_SystemRelease(void*, size_t) { }
+#endif
+
+#if !HAVE(VIRTUALALLOC) && !HAVE(MADV_FREE_REUSE)
inline void TCMalloc_SystemCommit(void*, size_t) { }
#endif
diff --git a/JavaScriptCore/wtf/ThreadSpecific.h b/JavaScriptCore/wtf/ThreadSpecific.h
index 7603802..8aaaf5f 100644
--- a/JavaScriptCore/wtf/ThreadSpecific.h
+++ b/JavaScriptCore/wtf/ThreadSpecific.h
@@ -129,8 +129,8 @@ inline void ThreadSpecific<T>::set(T* ptr)
// 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
const int kMaxTlsKeySize = 256;
-extern long g_tls_key_count;
-extern DWORD g_tls_keys[kMaxTlsKeySize];
+long& tlsKeyCount();
+DWORD* tlsKeys();
template<typename T>
inline ThreadSpecific<T>::ThreadSpecific()
@@ -140,23 +140,23 @@ inline ThreadSpecific<T>::ThreadSpecific()
if (tls_key == TLS_OUT_OF_INDEXES)
CRASH();
- m_index = InterlockedIncrement(&g_tls_key_count) - 1;
+ m_index = InterlockedIncrement(&tlsKeyCount()) - 1;
if (m_index >= kMaxTlsKeySize)
CRASH();
- g_tls_keys[m_index] = tls_key;
+ tlsKeys()[m_index] = tls_key;
}
template<typename T>
inline ThreadSpecific<T>::~ThreadSpecific()
{
// Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached.
- TlsFree(g_tls_keys[m_index]);
+ TlsFree(tlsKeys()[m_index]);
}
template<typename T>
inline T* ThreadSpecific<T>::get()
{
- Data* data = static_cast<Data*>(TlsGetValue(g_tls_keys[m_index]));
+ Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index]));
return data ? data->value : 0;
}
@@ -166,7 +166,7 @@ inline void ThreadSpecific<T>::set(T* ptr)
ASSERT(!get());
Data* data = new Data(ptr, this);
data->destructor = &ThreadSpecific<T>::destroy;
- TlsSetValue(g_tls_keys[m_index], data);
+ TlsSetValue(tlsKeys()[m_index], data);
}
#else
@@ -190,7 +190,7 @@ inline void ThreadSpecific<T>::destroy(void* ptr)
#if USE(PTHREADS)
pthread_setspecific(data->owner->m_key, 0);
#elif PLATFORM(WIN_OS)
- TlsSetValue(g_tls_keys[data->owner->m_index], 0);
+ TlsSetValue(tlsKeys()[data->owner->m_index], 0);
#else
#error ThreadSpecific is not implemented for this platform.
#endif
diff --git a/JavaScriptCore/wtf/ThreadSpecificWin.cpp b/JavaScriptCore/wtf/ThreadSpecificWin.cpp
index 1a3febb..f2c0cad 100644
--- a/JavaScriptCore/wtf/ThreadSpecificWin.cpp
+++ b/JavaScriptCore/wtf/ThreadSpecificWin.cpp
@@ -29,14 +29,23 @@
namespace WTF {
-long g_tls_key_count = 0;
-DWORD g_tls_keys[kMaxTlsKeySize];
+long& tlsKeyCount()
+{
+ static long count;
+ return count;
+}
+
+DWORD* tlsKeys()
+{
+ static DWORD keys[kMaxTlsKeySize];
+ return keys;
+}
void ThreadSpecificThreadExit()
{
- for (long i = 0; i < g_tls_key_count; i++) {
+ for (long i = 0; i < tlsKeyCount(); i++) {
// The layout of ThreadSpecific<T>::Data does not depend on T. So we are safe to do the static cast to ThreadSpecific<int> in order to access its data member.
- ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(g_tls_keys[i]));
+ ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(tlsKeys()[i]));
if (data)
data->destructor(data);
}
diff --git a/JavaScriptCore/wtf/Threading.cpp b/JavaScriptCore/wtf/Threading.cpp
index 41c9135..bd25ee7 100644
--- a/JavaScriptCore/wtf/Threading.cpp
+++ b/JavaScriptCore/wtf/Threading.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,16 +26,21 @@
#include "config.h"
#include "Threading.h"
+#include <string.h>
+
namespace WTF {
struct NewThreadContext {
- NewThreadContext(ThreadFunction entryPoint, void* data)
+ NewThreadContext(ThreadFunction entryPoint, void* data, const char* name)
: entryPoint(entryPoint)
, data(data)
- { }
+ , name(name)
+ {
+ }
ThreadFunction entryPoint;
void* data;
+ const char* name;
Mutex creationMutex;
};
@@ -44,6 +49,8 @@ static void* threadEntryPoint(void* contextData)
{
NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
+ setThreadNameInternal(context->name);
+
// Block until our creating thread has completed any extra setup work
{
MutexLocker locker(context->creationMutex);
@@ -59,7 +66,14 @@ static void* threadEntryPoint(void* contextData)
ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
{
- NewThreadContext* context = new NewThreadContext(entryPoint, data);
+ // Visual Studio has a 31-character limit on thread names. Longer names will
+ // be truncated silently, but we'd like callers to know about the limit.
+#if !LOG_DISABLED
+ if (strlen(name) > 31)
+ LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name);
+#endif
+
+ NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
// Prevent the thread body from executing until we've established the thread identifier
MutexLocker locker(context->creationMutex);
diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h
index 1c0dab1..e562f35 100644
--- a/JavaScriptCore/wtf/Threading.h
+++ b/JavaScriptCore/wtf/Threading.h
@@ -110,10 +110,17 @@ namespace WTF {
typedef uint32_t ThreadIdentifier;
typedef void* (*ThreadFunction)(void* argument);
-// Returns 0 if thread creation failed
+// Returns 0 if thread creation failed.
+// The thread name must be a literal since on some platforms it's passed in to the thread.
ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
+
+// Internal platform-specific createThread implementation.
ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
+// Called in the thread during initialization.
+// Helpful for platforms where the thread name must be set from within the thread.
+void setThreadNameInternal(const char* threadName);
+
ThreadIdentifier currentThread();
bool isMainThread();
int waitForThreadCompletion(ThreadIdentifier, void**);
@@ -212,9 +219,9 @@ inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_
#endif
-template<class T> class ThreadSafeShared : Noncopyable {
+class ThreadSafeSharedBase : Noncopyable {
public:
- ThreadSafeShared(int initialRefCount = 1)
+ ThreadSafeSharedBase(int initialRefCount = 1)
: m_refCount(initialRefCount)
{
}
@@ -229,20 +236,6 @@ public:
#endif
}
- void deref()
- {
-#if USE(LOCKFREE_THREADSAFESHARED)
- if (atomicDecrement(&m_refCount) <= 0)
-#else
- {
- MutexLocker locker(m_mutex);
- --m_refCount;
- }
- if (m_refCount <= 0)
-#endif
- delete static_cast<T*>(this);
- }
-
bool hasOneRef()
{
return refCount() == 1;
@@ -256,13 +249,50 @@ public:
return static_cast<int const volatile &>(m_refCount);
}
+protected:
+ // Returns whether the pointer should be freed or not.
+ bool derefBase()
+ {
+#if USE(LOCKFREE_THREADSAFESHARED)
+ if (atomicDecrement(&m_refCount) <= 0)
+ return true;
+#else
+ int refCount;
+ {
+ MutexLocker locker(m_mutex);
+ --m_refCount;
+ refCount = m_refCount;
+ }
+ if (refCount <= 0)
+ return true;
+#endif
+ return false;
+ }
+
private:
+ template<class T>
+ friend class CrossThreadRefCounted;
+
int m_refCount;
#if !USE(LOCKFREE_THREADSAFESHARED)
mutable Mutex m_mutex;
#endif
};
+template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {
+public:
+ ThreadSafeShared(int initialRefCount = 1)
+ : ThreadSafeSharedBase(initialRefCount)
+ {
+ }
+
+ void deref()
+ {
+ if (derefBase())
+ delete static_cast<T*>(this);
+ }
+};
+
// This function must be called from the main thread. It is safe to call it repeatedly.
// Darwin is an exception to this rule: it is OK to call it from any thread, the only requirement is that the calls are not reentrant.
void initializeThreading();
diff --git a/JavaScriptCore/wtf/ThreadingGtk.cpp b/JavaScriptCore/wtf/ThreadingGtk.cpp
index 24c34ca..b4f4de1 100644
--- a/JavaScriptCore/wtf/ThreadingGtk.cpp
+++ b/JavaScriptCore/wtf/ThreadingGtk.cpp
@@ -138,6 +138,10 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
return threadID;
}
+void setThreadNameInternal(const char*)
+{
+}
+
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID);
diff --git a/JavaScriptCore/wtf/ThreadingNone.cpp b/JavaScriptCore/wtf/ThreadingNone.cpp
index 0be2a4b..24431fc 100644
--- a/JavaScriptCore/wtf/ThreadingNone.cpp
+++ b/JavaScriptCore/wtf/ThreadingNone.cpp
@@ -34,6 +34,7 @@ namespace WTF {
void initializeThreading() { }
ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return 0; }
+void setThreadNameInternal(const char*) { }
int waitForThreadCompletion(ThreadIdentifier, void**) { return 0; }
void detachThread(ThreadIdentifier) { }
ThreadIdentifier currentThread() { return 0; }
diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp
index 105e42a..42133bc 100644
--- a/JavaScriptCore/wtf/ThreadingPthreads.cpp
+++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
*
* Redistribution and use in source and binary forms, with or without
@@ -26,18 +26,18 @@
* (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 "Threading.h"
-#include "StdLibExtras.h"
-
#if USE(PTHREADS)
#include "CurrentTime.h"
#include "HashMap.h"
#include "MainThread.h"
#include "RandomNumberSeed.h"
-
+#include "StdLibExtras.h"
+#include "UnusedParam.h"
#include <errno.h>
#include <limits.h>
#include <sys/time.h>
@@ -48,7 +48,7 @@ typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
static Mutex* atomicallyInitializedStaticMutex;
-#if !PLATFORM(DARWIN)
+#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM)
static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread.
#endif
@@ -64,7 +64,7 @@ void initializeThreading()
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
initializeRandomNumberGenerator();
-#if !PLATFORM(DARWIN)
+#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM)
mainThreadIdentifier = currentThread();
#endif
initializeMainThread();
@@ -133,7 +133,7 @@ static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
{
pthread_t threadHandle;
- if (pthread_create(&threadHandle, NULL, entryPoint, data)) {
+ if (pthread_create(&threadHandle, 0, entryPoint, data)) {
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
return 0;
}
@@ -141,6 +141,15 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
return establishIdentifierForPthreadHandle(threadHandle);
}
+void setThreadNameInternal(const char* threadName)
+{
+#if PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ pthread_setname_np(threadName);
+#else
+ UNUSED_PARAM(threadName);
+#endif
+}
+
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID);
@@ -176,7 +185,7 @@ ThreadIdentifier currentThread()
bool isMainThread()
{
-#if PLATFORM(DARWIN)
+#if PLATFORM(DARWIN) && !PLATFORM(CHROMIUM)
return pthread_main_np();
#else
return currentThread() == mainThreadIdentifier;
@@ -195,8 +204,8 @@ Mutex::~Mutex()
void Mutex::lock()
{
- if (pthread_mutex_lock(&m_mutex) != 0)
- ASSERT(false);
+ int result = pthread_mutex_lock(&m_mutex);
+ ASSERT_UNUSED(result, !result);
}
bool Mutex::tryLock()
@@ -205,17 +214,17 @@ bool Mutex::tryLock()
if (result == 0)
return true;
- else if (result == EBUSY)
+ if (result == EBUSY)
return false;
- ASSERT(false);
+ ASSERT_NOT_REACHED();
return false;
}
void Mutex::unlock()
{
- if (pthread_mutex_unlock(&m_mutex) != 0)
- ASSERT(false);
+ int result = pthread_mutex_unlock(&m_mutex);
+ ASSERT_UNUSED(result, !result);
}
ThreadCondition::ThreadCondition()
@@ -230,8 +239,8 @@ ThreadCondition::~ThreadCondition()
void ThreadCondition::wait(Mutex& mutex)
{
- if (pthread_cond_wait(&m_condition, &mutex.impl()) != 0)
- ASSERT(false);
+ int result = pthread_cond_wait(&m_condition, &mutex.impl());
+ ASSERT_UNUSED(result, !result);
}
bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
@@ -256,14 +265,14 @@ bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
void ThreadCondition::signal()
{
- if (pthread_cond_signal(&m_condition) != 0)
- ASSERT(false);
+ int result = pthread_cond_signal(&m_condition);
+ ASSERT_UNUSED(result, !result);
}
void ThreadCondition::broadcast()
{
- if (pthread_cond_broadcast(&m_condition) != 0)
- ASSERT(false);
+ int result = pthread_cond_broadcast(&m_condition);
+ ASSERT_UNUSED(result, !result);
}
} // namespace WTF
diff --git a/JavaScriptCore/wtf/ThreadingQt.cpp b/JavaScriptCore/wtf/ThreadingQt.cpp
index 55a479b..1fdd2bb 100644
--- a/JavaScriptCore/wtf/ThreadingQt.cpp
+++ b/JavaScriptCore/wtf/ThreadingQt.cpp
@@ -162,6 +162,10 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
return establishIdentifierForThread(threadRef);
}
+void setThreadNameInternal(const char*)
+{
+}
+
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID);
@@ -191,7 +195,7 @@ ThreadIdentifier currentThread()
bool isMainThread()
{
- return currentThread() == mainThreadIdentifier;
+ return QThread::currentThread() == QCoreApplication::instance()->thread();
}
Mutex::Mutex()
@@ -242,11 +246,13 @@ bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
if (absoluteTime < currentTime)
return false;
- double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
- // Qt defines wait for up to ULONG_MAX milliseconds.
- if (intervalMilliseconds >= ULONG_MAX)
- intervalMilliseconds = ULONG_MAX;
+ // Time is too far in the future (and would overflow unsigned long) - wait forever.
+ if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) {
+ wait(mutex);
+ return true;
+ }
+ double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
return m_condition->wait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
}
diff --git a/JavaScriptCore/wtf/ThreadingWin.cpp b/JavaScriptCore/wtf/ThreadingWin.cpp
index 399fb38..415ba53 100644
--- a/JavaScriptCore/wtf/ThreadingWin.cpp
+++ b/JavaScriptCore/wtf/ThreadingWin.cpp
@@ -98,7 +98,7 @@
namespace WTF {
-// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadName all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
+// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
static const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
@@ -110,16 +110,12 @@ typedef struct tagTHREADNAME_INFO {
} THREADNAME_INFO;
#pragma pack(pop)
-static void setThreadName(DWORD dwThreadID, LPCSTR szThreadName)
+void setThreadNameInternal(const char* szThreadName)
{
- // Visual Studio has a 31-character limit on thread names. Longer names will
- // be truncated silently, but we'd like callers to know about the limit.
- ASSERT_ARG(szThreadName, strlen(szThreadName) <= 31);
-
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = szThreadName;
- info.dwThreadID = dwThreadID;
+ info.dwThreadID = GetCurrentThreadId();
info.dwFlags = 0;
__try {
@@ -157,7 +153,7 @@ void initializeThreading()
initializeRandomNumberGenerator();
initializeMainThread();
mainThreadIdentifier = currentThread();
- setThreadName(mainThreadIdentifier, "Main Thread");
+ setThreadNameInternal("Main Thread");
}
}
@@ -220,9 +216,6 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
return 0;
}
- if (threadName)
- setThreadName(threadIdentifier, threadName);
-
threadID = static_cast<ThreadIdentifier>(threadIdentifier);
storeThreadHandleByIdentifier(threadIdentifier, threadHandle);
@@ -457,10 +450,13 @@ bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
if (absoluteTime < currentTime)
return false;
- double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
- if (intervalMilliseconds >= INT_MAX)
- intervalMilliseconds = INT_MAX;
+ // Time is too far in the future (and would overflow unsigned long) - wait forever.
+ if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) {
+ wait(mutex);
+ return true;
+ }
+ double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
return m_condition.timedWait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
}
diff --git a/JavaScriptCore/wtf/TypeTraits.cpp b/JavaScriptCore/wtf/TypeTraits.cpp
new file mode 100644
index 0000000..36fc6c6
--- /dev/null
+++ b/JavaScriptCore/wtf/TypeTraits.cpp
@@ -0,0 +1,120 @@
+ /*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "TypeTraits.h"
+
+#include "Assertions.h"
+
+namespace WTF {
+
+COMPILE_ASSERT(IsInteger<bool>::value, WTF_IsInteger_bool_true);
+COMPILE_ASSERT(IsInteger<char>::value, WTF_IsInteger_char_true);
+COMPILE_ASSERT(IsInteger<signed char>::value, WTF_IsInteger_signed_char_true);
+COMPILE_ASSERT(IsInteger<unsigned char>::value, WTF_IsInteger_unsigned_char_true);
+COMPILE_ASSERT(IsInteger<short>::value, WTF_IsInteger_short_true);
+COMPILE_ASSERT(IsInteger<unsigned short>::value, WTF_IsInteger_unsigned_short_true);
+COMPILE_ASSERT(IsInteger<int>::value, WTF_IsInteger_int_true);
+COMPILE_ASSERT(IsInteger<unsigned int>::value, WTF_IsInteger_unsigned_int_true);
+COMPILE_ASSERT(IsInteger<long>::value, WTF_IsInteger_long_true);
+COMPILE_ASSERT(IsInteger<unsigned long>::value, WTF_IsInteger_unsigned_long_true);
+COMPILE_ASSERT(IsInteger<long long>::value, WTF_IsInteger_long_long_true);
+COMPILE_ASSERT(IsInteger<unsigned long long>::value, WTF_IsInteger_unsigned_long_long_true);
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+COMPILE_ASSERT(IsInteger<wchar_t>::value, WTF_IsInteger_wchar_t_true);
+#endif
+COMPILE_ASSERT(!IsInteger<char*>::value, WTF_IsInteger_char_pointer_false);
+COMPILE_ASSERT(!IsInteger<const char*>::value, WTF_IsInteger_const_char_pointer_false);
+COMPILE_ASSERT(!IsInteger<volatile char*>::value, WTF_IsInteger_volatile_char_pointer_false);
+COMPILE_ASSERT(!IsInteger<double>::value, WTF_IsInteger_double_false);
+COMPILE_ASSERT(!IsInteger<float>::value, WTF_IsInteger_float_false);
+
+COMPILE_ASSERT(IsPod<bool>::value, WTF_IsPod_bool_true);
+COMPILE_ASSERT(IsPod<char>::value, WTF_IsPod_char_true);
+COMPILE_ASSERT(IsPod<signed char>::value, WTF_IsPod_signed_char_true);
+COMPILE_ASSERT(IsPod<unsigned char>::value, WTF_IsPod_unsigned_char_true);
+COMPILE_ASSERT(IsPod<short>::value, WTF_IsPod_short_true);
+COMPILE_ASSERT(IsPod<unsigned short>::value, WTF_IsPod_unsigned_short_true);
+COMPILE_ASSERT(IsPod<int>::value, WTF_IsPod_int_true);
+COMPILE_ASSERT(IsPod<unsigned int>::value, WTF_IsPod_unsigned_int_true);
+COMPILE_ASSERT(IsPod<long>::value, WTF_IsPod_long_true);
+COMPILE_ASSERT(IsPod<unsigned long>::value, WTF_IsPod_unsigned_long_true);
+COMPILE_ASSERT(IsPod<long long>::value, WTF_IsPod_long_long_true);
+COMPILE_ASSERT(IsPod<unsigned long long>::value, WTF_IsPod_unsigned_long_long_true);
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+COMPILE_ASSERT(IsPod<wchar_t>::value, WTF_IsPod_wchar_t_true);
+#endif
+COMPILE_ASSERT(IsPod<char*>::value, WTF_IsPod_char_pointer_true);
+COMPILE_ASSERT(IsPod<const char*>::value, WTF_IsPod_const_char_pointer_true);
+COMPILE_ASSERT(IsPod<volatile char*>::value, WTF_IsPod_volatile_char_pointer_true);
+COMPILE_ASSERT(IsPod<double>::value, WTF_IsPod_double_true);
+COMPILE_ASSERT(IsPod<long double>::value, WTF_IsPod_long_double_true);
+COMPILE_ASSERT(IsPod<float>::value, WTF_IsPod_float_true);
+COMPILE_ASSERT(!IsPod<IsPod<bool> >::value, WTF_IsPod_struct_false);
+
+enum IsConvertibleToIntegerCheck { };
+COMPILE_ASSERT(IsConvertibleToInteger<IsConvertibleToIntegerCheck>::value, WTF_IsConvertibleToInteger_enum_true);
+COMPILE_ASSERT(IsConvertibleToInteger<bool>::value, WTF_IsConvertibleToInteger_bool_true);
+COMPILE_ASSERT(IsConvertibleToInteger<char>::value, WTF_IsConvertibleToInteger_char_true);
+COMPILE_ASSERT(IsConvertibleToInteger<signed char>::value, WTF_IsConvertibleToInteger_signed_char_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned char>::value, WTF_IsConvertibleToInteger_unsigned_char_true);
+COMPILE_ASSERT(IsConvertibleToInteger<short>::value, WTF_IsConvertibleToInteger_short_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned short>::value, WTF_IsConvertibleToInteger_unsigned_short_true);
+COMPILE_ASSERT(IsConvertibleToInteger<int>::value, WTF_IsConvertibleToInteger_int_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned int>::value, WTF_IsConvertibleToInteger_unsigned_int_true);
+COMPILE_ASSERT(IsConvertibleToInteger<long>::value, WTF_IsConvertibleToInteger_long_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned long>::value, WTF_IsConvertibleToInteger_unsigned_long_true);
+COMPILE_ASSERT(IsConvertibleToInteger<long long>::value, WTF_IsConvertibleToInteger_long_long_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned long long>::value, WTF_IsConvertibleToInteger_unsigned_long_long_true);
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+COMPILE_ASSERT(IsConvertibleToInteger<wchar_t>::value, WTF_IsConvertibleToInteger_wchar_t_true);
+#endif
+COMPILE_ASSERT(IsConvertibleToInteger<double>::value, WTF_IsConvertibleToInteger_double_true);
+COMPILE_ASSERT(IsConvertibleToInteger<long double>::value, WTF_IsConvertibleToInteger_long_double_true);
+COMPILE_ASSERT(IsConvertibleToInteger<float>::value, WTF_IsConvertibleToInteger_float_true);
+COMPILE_ASSERT(!IsConvertibleToInteger<char*>::value, WTF_IsConvertibleToInteger_char_pointer_false);
+COMPILE_ASSERT(!IsConvertibleToInteger<const char*>::value, WTF_IsConvertibleToInteger_const_char_pointer_false);
+COMPILE_ASSERT(!IsConvertibleToInteger<volatile char*>::value, WTF_IsConvertibleToInteger_volatile_char_pointer_false);
+COMPILE_ASSERT(!IsConvertibleToInteger<IsConvertibleToInteger<bool> >::value, WTF_IsConvertibleToInteger_struct_false);
+
+COMPILE_ASSERT((IsSameType<bool, bool>::value), WTF_IsSameType_bool_true);
+COMPILE_ASSERT((IsSameType<int*, int*>::value), WTF_IsSameType_int_pointer_true);
+COMPILE_ASSERT((!IsSameType<int, int*>::value), WTF_IsSameType_int_int_pointer_false);
+COMPILE_ASSERT((!IsSameType<bool, const bool>::value), WTF_IsSameType_const_change_false);
+COMPILE_ASSERT((!IsSameType<bool, volatile bool>::value), WTF_IsSameType_volatile_change_false);
+
+COMPILE_ASSERT((IsSameType<bool, RemoveConst<const bool>::Type>::value), WTF_test_RemoveConst_const_bool);
+COMPILE_ASSERT((!IsSameType<bool, RemoveConst<volatile bool>::Type>::value), WTF_test_RemoveConst_volatile_bool);
+
+COMPILE_ASSERT((IsSameType<bool, RemoveVolatile<bool>::Type>::value), WTF_test_RemoveVolatile_bool);
+COMPILE_ASSERT((!IsSameType<bool, RemoveVolatile<const bool>::Type>::value), WTF_test_RemoveVolatile_const_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveVolatile<volatile bool>::Type>::value), WTF_test_RemoveVolatile_volatile_bool);
+
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<bool>::Type>::value), WTF_test_RemoveConstVolatile_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<const bool>::Type>::value), WTF_test_RemoveConstVolatile_const_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<volatile bool>::Type>::value), WTF_test_RemoveConstVolatile_volatile_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<const volatile bool>::Type>::value), WTF_test_RemoveConstVolatile_const_volatile_bool);
+
+COMPILE_ASSERT((IsSameType<int, RemovePointer<int>::Type>::value), WTF_Test_RemovePointer_int);
+COMPILE_ASSERT((IsSameType<int, RemovePointer<int*>::Type>::value), WTF_Test_RemovePointer_int_pointer);
+COMPILE_ASSERT((!IsSameType<int, RemovePointer<int**>::Type>::value), WTF_Test_RemovePointer_int_pointer_pointer);
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/TypeTraits.h b/JavaScriptCore/wtf/TypeTraits.h
new file mode 100644
index 0000000..2aeabcf
--- /dev/null
+++ b/JavaScriptCore/wtf/TypeTraits.h
@@ -0,0 +1,133 @@
+ /*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TypeTraits_h
+#define TypeTraits_h
+
+#include "Platform.h"
+
+namespace WTF {
+
+ // The following are provided in this file:
+ //
+ // IsInteger<T>::value
+ // IsPod<T>::value, see the definition for a note about its limitations
+ // IsConvertibleToInteger<T>::value
+ //
+ // IsSameType<T, U>::value
+ //
+ // RemovePointer<T>::Type
+ // RemoveConst<T>::Type
+ // RemoveVolatile<T>::Type
+ // RemoveConstVolatile<T>::Type
+ //
+ // COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
+
+ template<typename T> struct IsInteger { static const bool value = false; };
+ template<> struct IsInteger<bool> { static const bool value = true; };
+ template<> struct IsInteger<char> { static const bool value = true; };
+ template<> struct IsInteger<signed char> { static const bool value = true; };
+ template<> struct IsInteger<unsigned char> { static const bool value = true; };
+ template<> struct IsInteger<short> { static const bool value = true; };
+ template<> struct IsInteger<unsigned short> { static const bool value = true; };
+ template<> struct IsInteger<int> { static const bool value = true; };
+ template<> struct IsInteger<unsigned int> { static const bool value = true; };
+ template<> struct IsInteger<long> { static const bool value = true; };
+ template<> struct IsInteger<unsigned long> { static const bool value = true; };
+ template<> struct IsInteger<long long> { static const bool value = true; };
+ template<> struct IsInteger<unsigned long long> { static const bool value = true; };
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+ template<> struct IsInteger<wchar_t> { static const bool value = true; };
+#endif
+
+ // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
+ // Specifically, it doesn't allow for enums or for structs.
+ template <typename T> struct IsPod { static const bool value = IsInteger<T>::value; };
+ template <> struct IsPod<float> { static const bool value = true; };
+ template <> struct IsPod<double> { static const bool value = true; };
+ template <> struct IsPod<long double> { static const bool value = true; };
+ template <typename P> struct IsPod<P*> { static const bool value = true; };
+
+ template<typename T> class IsConvertibleToInteger {
+ // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
+ // by not converting int's to doubles.
+ template<bool performCheck, typename U> class IsConvertibleToDouble;
+ template<typename U> class IsConvertibleToDouble<false, U> {
+ public:
+ static const bool value = false;
+ };
+
+ template<typename U> class IsConvertibleToDouble<true, U> {
+ typedef char YesType;
+ struct NoType {
+ char padding[8];
+ };
+
+ static YesType floatCheck(long double);
+ static NoType floatCheck(...);
+ static T& t;
+ public:
+ static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
+ };
+
+ public:
+ static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
+ };
+
+ template <typename T, typename U> struct IsSameType {
+ static const bool value = false;
+ };
+
+ template <typename T> struct IsSameType<T, T> {
+ static const bool value = true;
+ };
+
+ template <typename T> struct RemoveConst {
+ typedef T Type;
+ };
+
+ template <typename T> struct RemoveConst<const T> {
+ typedef T Type;
+ };
+
+ template <typename T> struct RemoveVolatile {
+ typedef T Type;
+ };
+
+ template <typename T> struct RemoveVolatile<volatile T> {
+ typedef T Type;
+ };
+
+ template <typename T> struct RemoveConstVolatile {
+ typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
+ };
+
+ template <typename T> struct RemovePointer {
+ typedef T Type;
+ };
+
+ template <typename T> struct RemovePointer<T*> {
+ typedef T Type;
+ };
+
+} // namespace WTF
+
+#endif // TypeTraits_h
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index 880b45d..190226d 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -377,7 +377,8 @@ namespace WTF {
VectorBuffer(size_t capacity)
: Base(inlineBuffer(), inlineCapacity)
{
- allocateBuffer(capacity);
+ if (capacity > inlineCapacity)
+ Base::allocateBuffer(capacity);
}
~VectorBuffer()
@@ -389,6 +390,10 @@ namespace WTF {
{
if (newCapacity > inlineCapacity)
Base::allocateBuffer(newCapacity);
+ else {
+ m_buffer = inlineBuffer();
+ m_capacity = inlineCapacity;
+ }
}
void deallocateBuffer(T* bufferToDeallocate)
@@ -503,6 +508,7 @@ namespace WTF {
void grow(size_t size);
void resize(size_t size);
void reserveCapacity(size_t newCapacity);
+ void reserveInitialCapacity(size_t initialCapacity);
void shrinkCapacity(size_t newCapacity);
void shrinkToFit() { shrinkCapacity(size()); }
@@ -733,6 +739,15 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity>
+ inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity)
+ {
+ ASSERT(!m_size);
+ ASSERT(capacity() == inlineCapacity);
+ if (initialCapacity > inlineCapacity)
+ m_buffer.allocateBuffer(initialCapacity);
+ }
+
+ template<typename T, size_t inlineCapacity>
void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity)
{
if (newCapacity >= capacity())
diff --git a/JavaScriptCore/wtf/VectorTraits.h b/JavaScriptCore/wtf/VectorTraits.h
index 6efe36c..7974b9a 100644
--- a/JavaScriptCore/wtf/VectorTraits.h
+++ b/JavaScriptCore/wtf/VectorTraits.h
@@ -22,6 +22,7 @@
#define WTF_VectorTraits_h
#include "RefPtr.h"
+#include "TypeTraits.h"
#include <utility>
#include <memory>
@@ -29,24 +30,6 @@ using std::pair;
namespace WTF {
- template <typename T> struct IsPod { static const bool value = false; };
- template <> struct IsPod<bool> { static const bool value = true; };
- template <> struct IsPod<char> { static const bool value = true; };
- template <> struct IsPod<signed char> { static const bool value = true; };
- template <> struct IsPod<unsigned char> { static const bool value = true; };
- template <> struct IsPod<short> { static const bool value = true; };
- template <> struct IsPod<unsigned short> { static const bool value = true; };
- template <> struct IsPod<int> { static const bool value = true; };
- template <> struct IsPod<unsigned int> { static const bool value = true; };
- template <> struct IsPod<long> { static const bool value = true; };
- template <> struct IsPod<unsigned long> { static const bool value = true; };
- template <> struct IsPod<long long> { static const bool value = true; };
- template <> struct IsPod<unsigned long long> { static const bool value = true; };
- template <> struct IsPod<float> { static const bool value = true; };
- template <> struct IsPod<double> { static const bool value = true; };
- template <> struct IsPod<long double> { static const bool value = true; };
- template <typename P> struct IsPod<P *> { static const bool value = true; };
-
template<bool isPod, typename T>
class VectorTraitsBase;
diff --git a/JavaScriptCore/wtf/android/MainThreadAndroid.cpp b/JavaScriptCore/wtf/android/MainThreadAndroid.cpp
index d00c0ab..ab0d3bf 100644
--- a/JavaScriptCore/wtf/android/MainThreadAndroid.cpp
+++ b/JavaScriptCore/wtf/android/MainThreadAndroid.cpp
@@ -38,6 +38,10 @@ static void timeoutFired(void* )
dispatchFunctionsFromMainThread();
}
+void initializeMainThreadPlatform()
+{
+}
+
void scheduleDispatchFunctionsOnMainThread()
{
JavaSharedClient::EnqueueFunctionPtr(timeoutFired, 0);
diff --git a/JavaScriptCore/wtf/chromium/ChromiumThreading.h b/JavaScriptCore/wtf/chromium/ChromiumThreading.h
new file mode 100644
index 0000000..e9b1f39
--- /dev/null
+++ b/JavaScriptCore/wtf/chromium/ChromiumThreading.h
@@ -0,0 +1,45 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ChromiumThreading_h
+#define ChromiumThreading_h
+
+namespace WTF {
+
+ // An interface to the embedding layer, which provides threading support.
+ class ChromiumThreading {
+ public:
+ static void initializeMainThread();
+ static void scheduleDispatchFunctionsOnMainThread();
+ };
+
+} // namespace WTF
+
+#endif // ChromiumThreading_h
diff --git a/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp b/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp
new file mode 100644
index 0000000..394370f
--- /dev/null
+++ b/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp
@@ -0,0 +1,49 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+#include "MainThread.h"
+
+#include "ChromiumThreading.h"
+
+namespace WTF {
+
+void initializeMainThreadPlatform()
+{
+ ChromiumThreading::initializeMainThread();
+}
+
+void scheduleDispatchFunctionsOnMainThread()
+{
+ ChromiumThreading::scheduleDispatchFunctionsOnMainThread();
+}
+
+} // namespace WTF
+
diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp
index c9e8d30..c104dad 100644
--- a/JavaScriptCore/wtf/dtoa.cpp
+++ b/JavaScriptCore/wtf/dtoa.cpp
@@ -824,16 +824,16 @@ static double b2d(Bigint* a, int* e)
*e = 32 - k;
#ifdef Pack_32
if (k < Ebits) {
- d0 = Exp_1 | y >> Ebits - k;
+ d0 = Exp_1 | (y >> (Ebits - k));
w = xa > xa0 ? *--xa : 0;
- d1 = y << (32 - Ebits) + k | w >> Ebits - k;
+ d1 = (y << (32 - Ebits + k)) | (w >> (Ebits - k));
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
if (k -= Ebits) {
- d0 = Exp_1 | y << k | z >> 32 - k;
+ d0 = Exp_1 | (y << k) | (z >> (32 - k));
y = xa > xa0 ? *--xa : 0;
- d1 = z << k | y >> 32 - k;
+ d1 = (z << k) | (y >> (32 - k));
} else {
d0 = Exp_1 | y;
d1 = z;
@@ -889,7 +889,7 @@ static Bigint* d2b(double d, int* e, int* bits)
#ifdef Pack_32
if ((y = d1)) {
if ((k = lo0bits(&y))) {
- x[0] = y | z << 32 - k;
+ x[0] = y | (z << (32 - k));
z >>= k;
} else
x[0] = y;
@@ -1349,7 +1349,7 @@ ovfl:
if (j >= 53)
word0(rv) = (P + 2) * Exp_msk1;
else
- word0(rv) &= 0xffffffff << j - 32;
+ word0(rv) &= 0xffffffff << (j - 32);
} else
word1(rv) &= 0xffffffff << j;
}
@@ -2011,8 +2011,8 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
/* d is denormalized */
i = bbits + be + (Bias + (P - 1) - 1);
- x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
- : word1(d) << 32 - i;
+ x = (i > 32) ? (word0(d) << (64 - i)) | (word1(d) >> (i - 32))
+ : word1(d) << (32 - i);
dval(d2) = x;
word0(d2) -= 31 * Exp_msk1; /* adjust exponent */
i -= (Bias + (P - 1) - 1) + 1;
@@ -2193,7 +2193,7 @@ fast_failed:
}
if (i == ilim) {
dval(d) += dval(d);
- if (dval(d) > ds || dval(d) == ds && L & 1) {
+ if (dval(d) > ds || (dval(d) == ds && (L & 1))) {
bump_up:
while (*--s == '9')
if (s == s0) {
@@ -2334,7 +2334,7 @@ bump_up:
*s++ = dig;
goto ret;
}
- if (j < 0 || j == 0 && !(word1(d) & 1)) {
+ if (j < 0 || (j == 0 && !(word1(d) & 1))) {
if (!b->x[0] && b->wds <= 1) {
#ifdef SET_INEXACT
inexact = 0;
@@ -2344,7 +2344,7 @@ bump_up:
if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
- if ((j1 > 0 || j1 == 0 && dig & 1) && dig++ == '9')
+ if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9')
goto round_9_up;
}
accept_dig:
@@ -2389,7 +2389,7 @@ round_9_up:
b = lshift(b, 1);
j = cmp(b, S);
- if (j > 0 || j == 0 && dig & 1) {
+ if (j > 0 || (j == 0 && (dig & 1))) {
roundoff:
while (*--s == '9')
if (s == s0) {
diff --git a/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp b/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp
index a6e061f..7624247 100644
--- a/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp
+++ b/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp
@@ -34,6 +34,10 @@
namespace WTF {
+void initializeMainThreadPlatform()
+{
+}
+
static gboolean timeoutFired(gpointer)
{
dispatchFunctionsFromMainThread();
@@ -45,5 +49,4 @@ void scheduleDispatchFunctionsOnMainThread()
g_timeout_add(0, timeoutFired, 0);
}
-
-}
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/mac/MainThreadMac.mm b/JavaScriptCore/wtf/mac/MainThreadMac.mm
index b04ef0e..c79acc1 100644
--- a/JavaScriptCore/wtf/mac/MainThreadMac.mm
+++ b/JavaScriptCore/wtf/mac/MainThreadMac.mm
@@ -30,6 +30,7 @@
#import "MainThread.h"
#import <Foundation/NSThread.h>
+#import <wtf/Assertions.h>
@interface WTFMainThreadCaller : NSObject {
}
@@ -47,11 +48,18 @@
namespace WTF {
+static WTFMainThreadCaller* staticMainThreadCaller = nil;
+
+void initializeMainThreadPlatform()
+{
+ ASSERT(!staticMainThreadCaller);
+ staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
+}
+
void scheduleDispatchFunctionsOnMainThread()
{
- WTFMainThreadCaller *caller = [[WTFMainThreadCaller alloc] init];
- [caller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
- [caller release];
+ ASSERT(staticMainThreadCaller);
+ [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
}
} // namespace WTF
diff --git a/JavaScriptCore/wtf/qt/MainThreadQt.cpp b/JavaScriptCore/wtf/qt/MainThreadQt.cpp
index 1914600..7b2d0f2 100644
--- a/JavaScriptCore/wtf/qt/MainThreadQt.cpp
+++ b/JavaScriptCore/wtf/qt/MainThreadQt.cpp
@@ -58,12 +58,15 @@ void MainThreadInvoker::dispatch()
Q_GLOBAL_STATIC(MainThreadInvoker, webkit_main_thread_invoker)
+void initializeMainThreadPlatform()
+{
+}
void scheduleDispatchFunctionsOnMainThread()
{
QMetaObject::invokeMethod(webkit_main_thread_invoker(), "dispatch", Qt::QueuedConnection);
}
-}
+} // namespace WTF
#include "MainThreadQt.moc"
diff --git a/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h b/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
index 608aea6..de5e082 100644
--- a/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
+++ b/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
@@ -179,6 +179,11 @@ inline bool isPunct(UChar32 c)
return !!u_ispunct(c);
}
+inline bool hasLineBreakingPropertyComplexContext(UChar32 c)
+{
+ return u_getIntPropertyValue(c, UCHAR_LINE_BREAK) == U_LB_COMPLEX_CONTEXT;
+}
+
inline UChar32 mirroredChar(UChar32 c)
{
return u_charMirror(c);
diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index d7d78ce..f65e292 100644
--- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -352,6 +352,12 @@ inline bool isLower(UChar32 c)
return QChar::category(c) == QChar::Letter_Lowercase;
}
+inline bool hasLineBreakingPropertyComplexContext(UChar32)
+{
+ // FIXME: Implement this to return whether the character has line breaking property SA (Complex Context).
+ return false;
+}
+
inline UChar32 mirroredChar(UChar32 c)
{
return QChar::mirroredChar(c);
diff --git a/JavaScriptCore/wtf/win/MainThreadWin.cpp b/JavaScriptCore/wtf/win/MainThreadWin.cpp
index 5f0163c..b828b7d 100644
--- a/JavaScriptCore/wtf/win/MainThreadWin.cpp
+++ b/JavaScriptCore/wtf/win/MainThreadWin.cpp
@@ -50,13 +50,11 @@ LRESULT CALLBACK ThreadingWindowWndProc(HWND hWnd, UINT message, WPARAM wParam,
return 0;
}
-void initializeMainThread()
+void initializeMainThreadPlatform()
{
if (threadingWindowHandle)
return;
- mainThreadFunctionQueueMutex();
-
WNDCLASSEX wcex;
memset(&wcex, 0, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
@@ -75,4 +73,4 @@ void scheduleDispatchFunctionsOnMainThread()
PostMessage(threadingWindowHandle, threadingFiredMessage, 0, 0);
}
-} // namespace WebCore
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/wx/MainThreadWx.cpp b/JavaScriptCore/wtf/wx/MainThreadWx.cpp
index 3166331..bcd5f05 100644
--- a/JavaScriptCore/wtf/wx/MainThreadWx.cpp
+++ b/JavaScriptCore/wtf/wx/MainThreadWx.cpp
@@ -31,8 +31,12 @@
namespace WTF {
-void scheduleDispatchFunctionsOnMainThread()
+void initializeMainThreadPlatform()
{
}
+void scheduleDispatchFunctionsOnMainThread()
+{
}
+
+} // namespace WTF
diff --git a/WEBKIT_MERGE_REVISION b/WEBKIT_MERGE_REVISION
new file mode 100644
index 0000000..335d0ff
--- /dev/null
+++ b/WEBKIT_MERGE_REVISION
@@ -0,0 +1 @@
+http://svn.webkit.org/repository/webkit/trunk@42026
diff --git a/WebCore/Android.derived.mk b/WebCore/Android.derived.mk
index b29cdd2..304014f 100644
--- a/WebCore/Android.derived.mk
+++ b/WebCore/Android.derived.mk
@@ -253,6 +253,8 @@ GEN := \
$(intermediates)/dom/JSAttr.h \
$(intermediates)/dom/JSCDATASection.h \
$(intermediates)/dom/JSCharacterData.h \
+ $(intermediates)/dom/JSClientRect.h \
+ $(intermediates)/dom/JSClientRectList.h \
$(intermediates)/dom/JSClipboard.h \
$(intermediates)/dom/JSComment.h \
$(intermediates)/dom/JSDOMCoreException.h \
@@ -266,7 +268,6 @@ GEN := \
$(intermediates)/dom/JSEntityReference.h \
$(intermediates)/dom/JSEvent.h \
$(intermediates)/dom/JSEventException.h \
- $(intermediates)/dom/JSEventTargetNode.h \
$(intermediates)/dom/JSKeyboardEvent.h \
$(intermediates)/dom/JSMessageChannel.h \
$(intermediates)/dom/JSMessageEvent.h \
@@ -429,6 +430,7 @@ $(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/loader/appcache/%.cpp : $(interme
GEN := \
$(intermediates)/page/JSBarInfo.h \
$(intermediates)/page/JSConsole.h \
+ $(intermediates)/page/JSCoordinates.h \
$(intermediates)/page/JSDOMSelection.h \
$(intermediates)/page/JSDOMWindow.h \
$(intermediates)/page/JSGeolocation.h \
@@ -438,7 +440,8 @@ GEN := \
$(intermediates)/page/JSNavigator.h \
$(intermediates)/page/JSPositionError.h \
$(intermediates)/page/JSPositionErrorCallback.h \
- $(intermediates)/page/JSScreen.h
+ $(intermediates)/page/JSScreen.h \
+ $(intermediates)/page/JSWebKitPoint.h
$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
$(GEN): PRIVATE_CUSTOM_TOOL = perl -I$(PRIVATE_PATH)/bindings/scripts $(PRIVATE_PATH)/bindings/scripts/generate-bindings.pl --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator JS --include dom --include html --outputdir $(dir $@) $<
$(GEN): $(intermediates)/page/JS%.h : $(LOCAL_PATH)/page/%.idl $(js_binding_scripts)
@@ -621,6 +624,7 @@ GEN := \
$(intermediates)/xml/JSXMLHttpRequestUpload.h \
$(intermediates)/xml/JSXMLSerializer.h \
$(intermediates)/xml/JSXPathEvaluator.h \
+ $(intermediates)/xml/JSXPathException.h \
$(intermediates)/xml/JSXPathExpression.h \
$(intermediates)/xml/JSXPathNSResolver.h \
$(intermediates)/xml/JSXPathResult.h \
@@ -638,9 +642,9 @@ $(patsubst %.h,%.cpp,$(GEN)): $(intermediates)/xml/%.cpp : $(intermediates)/xml/
# HTML tag and attribute names
-GEN:= $(intermediates)/HTMLNames.cpp $(intermediates)/JSHTMLElementWrapperFactory.cpp
+GEN:= $(intermediates)/HTMLNames.cpp $(intermediates)/HTMLElementFactory.cpp $(intermediates)/JSHTMLElementWrapperFactory.cpp
$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
-$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(html_tags) --attrs $(html_attrs) --wrapperFactory --output $(dir $@)
+$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(html_tags) --attrs $(html_attrs) --factory --wrapperFactory --output $(dir $@)
$(GEN): html_tags := $(LOCAL_PATH)/html/HTMLTagNames.in
$(GEN): html_attrs := $(LOCAL_PATH)/html/HTMLAttributeNames.in
$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(html_tags) $(html_attrs)
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index 6bead25..9da2c56 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -138,7 +138,6 @@ LOCAL_SRC_FILES := \
bindings/js/JSEventCustom.cpp \
bindings/js/JSEventListener.cpp \
bindings/js/JSEventTarget.cpp \
- bindings/js/JSEventTargetNodeCustom.cpp \
bindings/js/JSGeolocationCustom.cpp \
bindings/js/JSHTMLAllCollection.cpp \
bindings/js/JSHTMLAppletElementCustom.cpp \
@@ -160,6 +159,7 @@ LOCAL_SRC_FILES := \
bindings/js/JSInspectedObjectWrapper.cpp \
bindings/js/JSInspectorCallbackWrapper.cpp \
bindings/js/JSJavaScriptCallFrameCustom.cpp \
+ bindings/js/JSLazyEventListener.cpp \
bindings/js/JSLocationCustom.cpp \
bindings/js/JSMessageChannelConstructor.cpp \
bindings/js/JSMessageChannelCustom.cpp \
@@ -198,6 +198,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
bindings/js/JSTextCustom.cpp \
bindings/js/JSTreeWalkerCustom.cpp \
bindings/js/JSWebKitCSSMatrixConstructor.cpp \
+ bindings/js/JSWebKitPointConstructor.cpp \
bindings/js/JSXMLHttpRequestConstructor.cpp \
bindings/js/JSXMLHttpRequestCustom.cpp \
bindings/js/JSXMLHttpRequestUploadCustom.cpp \
@@ -207,8 +208,11 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
bindings/js/ScriptCallStack.cpp \
bindings/js/ScriptController.cpp \
bindings/js/ScriptControllerAndroid.cpp \
+ bindings/js/ScriptFunctionCall.cpp \
+ bindings/js/ScriptObject.cpp \
bindings/js/ScriptValue.cpp \
\
+ bridge/IdentifierRep.cpp \
bridge/NP_jsobject.cpp \
bridge/c/c_class.cpp \
bridge/c/c_instance.cpp \
@@ -305,6 +309,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
dom/ChildNodeList.cpp \
dom/ClassNames.cpp \
dom/ClassNodeList.cpp \
+ dom/ClientRect.cpp \
+ dom/ClientRectList.cpp \
dom/Clipboard.cpp \
dom/ClipboardEvent.cpp \
dom/Comment.cpp \
@@ -322,7 +328,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
dom/Event.cpp \
dom/EventNames.cpp \
dom/EventTarget.cpp \
- dom/EventTargetNode.cpp \
dom/ExceptionBase.cpp \
dom/ExceptionCode.cpp \
dom/FormControlElement.cpp \
@@ -407,7 +412,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
editing/RemoveNodeCommand.cpp \
editing/RemoveNodePreservingChildrenCommand.cpp \
editing/ReplaceSelectionCommand.cpp \
- editing/Selection.cpp \
editing/SelectionController.cpp \
editing/SetNodeAttributeCommand.cpp \
editing/SplitElementCommand.cpp \
@@ -417,6 +421,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
editing/TypingCommand.cpp \
editing/UnlinkCommand.cpp \
editing/VisiblePosition.cpp \
+ editing/VisibleSelection.cpp \
editing/WrapContentsInDummySpanCommand.cpp \
\
editing/android/EditorAndroid.cpp \
@@ -453,7 +458,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
html/HTMLDivElement.cpp \
html/HTMLDocument.cpp \
html/HTMLElement.cpp \
- html/HTMLElementFactory.cpp \
html/HTMLEmbedElement.cpp \
html/HTMLFieldSetElement.cpp \
html/HTMLFontElement.cpp \
@@ -525,12 +529,13 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
loader/CachedResourceClientWalker.cpp \
loader/CachedResourceHandle.cpp \
loader/CachedScript.cpp \
+ loader/CrossOriginAccessControl.cpp \
+ loader/CrossOriginPreflightResultCache.cpp \
loader/DocLoader.cpp \
loader/DocumentLoader.cpp \
loader/DocumentThreadableLoader.cpp \
loader/FormState.cpp \
loader/FrameLoader.cpp \
- loader/FrameLoaderClient.cpp \
loader/ImageDocument.cpp \
loader/ImageLoader.cpp \
loader/MainResourceLoader.cpp \
@@ -558,6 +563,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
page/Chrome.cpp \
page/Console.cpp \
page/ContextMenuController.cpp \
+ page/Coordinates.cpp \
page/DOMSelection.cpp \
page/DOMTimer.cpp \
page/DOMWindow.cpp \
@@ -593,13 +599,16 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
page/animation/KeyframeAnimation.cpp \
\
platform/Arena.cpp \
+ platform/ContentType.cpp \
platform/ContextMenu.cpp \
+ platform/CrossThreadCopier.cpp \
platform/DeprecatedPtrListImpl.cpp \
platform/DragData.cpp \
platform/DragImage.cpp \
platform/FileChooser.cpp \
platform/GeolocationService.cpp \
platform/KURL.cpp \
+ platform/KURLGoogle.cpp \
platform/Length.cpp \
platform/LinkHash.cpp \
platform/Logging.cpp \
@@ -610,6 +619,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/SharedBuffer.cpp \
platform/Theme.cpp \
platform/ThreadGlobalData.cpp \
+ platform/ThreadTimers.cpp \
platform/Timer.cpp \
platform/Widget.cpp \
\
@@ -639,6 +649,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/BitmapImage.cpp \
platform/graphics/Color.cpp \
platform/graphics/FloatPoint.cpp \
+ platform/graphics/FloatPoint3D.cpp \
platform/graphics/FloatQuad.cpp \
platform/graphics/FloatRect.cpp \
platform/graphics/FloatSize.cpp \
@@ -654,6 +665,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/GlyphWidthMap.cpp \
platform/graphics/Gradient.cpp \
platform/graphics/GraphicsContext.cpp \
+ platform/graphics/GraphicsLayer.cpp \
platform/graphics/GraphicsTypes.cpp \
platform/graphics/Image.cpp \
platform/graphics/IntRect.cpp \
@@ -688,7 +700,9 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
\
platform/graphics/skia/NativeImageSkia.cpp \
\
+ platform/graphics/transforms/Matrix3DTransformOperation.cpp \
platform/graphics/transforms/MatrixTransformOperation.cpp \
+ platform/graphics/transforms/PerspectiveTransformOperation.cpp \
platform/graphics/transforms/RotateTransformOperation.cpp \
platform/graphics/transforms/ScaleTransformOperation.cpp \
platform/graphics/transforms/SkewTransformOperation.cpp \
@@ -696,8 +710,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/transforms/TransformationMatrix.cpp \
platform/graphics/transforms/TranslateTransformOperation.cpp \
\
- platform/image-decoders/skia/GIFImageDecoder.cpp \
- platform/image-decoders/skia/GIFImageReader.cpp \
+ platform/image-decoders/skia/GIFImageDecoder.cpp \
+ platform/image-decoders/skia/GIFImageReader.cpp \
\
platform/network/AuthenticationChallengeBase.cpp \
platform/network/Credential.cpp \
@@ -717,7 +731,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/network/android/NetworkStateNotifierAndroid.cpp \
\
platform/posix/FileSystemPOSIX.cpp \
- \
+ \
platform/sql/SQLValue.cpp \
platform/sql/SQLiteAuthorizer.cpp \
platform/sql/SQLiteDatabase.cpp \
@@ -740,8 +754,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/text/TextCodecLatin1.cpp \
platform/text/TextCodecUTF16.cpp \
platform/text/TextCodecUserDefined.cpp \
- platform/text/TextDecoder.cpp \
platform/text/TextEncoding.cpp \
+ platform/text/TextEncodingDetectorICU.cpp \
platform/text/TextEncodingRegistry.cpp \
platform/text/TextStream.cpp \
platform/text/UnicodeRange.cpp \
@@ -780,13 +794,12 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
rendering/RenderBR.cpp \
rendering/RenderBlock.cpp \
rendering/RenderBox.cpp \
+ rendering/RenderBoxModelObject.cpp \
rendering/RenderButton.cpp \
- rendering/RenderContainer.cpp \
rendering/RenderCounter.cpp \
rendering/RenderFieldset.cpp \
rendering/RenderFileUploadControl.cpp \
rendering/RenderFlexibleBox.cpp \
- rendering/RenderFlow.cpp \
rendering/RenderForeignObject.cpp \
rendering/RenderFrame.cpp \
rendering/RenderFrameSet.cpp \
@@ -795,7 +808,9 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
rendering/RenderImageGeneratedContent.cpp \
rendering/RenderInline.cpp \
rendering/RenderLayer.cpp \
- rendering/RenderLegend.cpp \
+ rendering/RenderLayerBacking.cpp \
+ rendering/RenderLayerCompositor.cpp \
+ rendering/RenderLineBoxList.cpp \
rendering/RenderListBox.cpp \
rendering/RenderListItem.cpp \
rendering/RenderListMarker.cpp \
@@ -803,6 +818,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
rendering/RenderMedia.cpp \
rendering/RenderMenuList.cpp \
rendering/RenderObject.cpp \
+ rendering/RenderObjectChildList.cpp \
rendering/RenderPart.cpp \
rendering/RenderPartObject.cpp \
rendering/RenderPath.cpp \
@@ -860,7 +876,9 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
endif
LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
+ rendering/ScrollBehavior.cpp \
rendering/TextControlInnerElements.cpp \
+ rendering/TransformState.cpp \
rendering/bidi.cpp \
rendering/break_lines.cpp \
\
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b7efdff..164a9fd 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,8 +1,10326 @@
-2009-02-19 Mark Rowe <mrowe@apple.com>
+2009-03-26 Jungshik Shin <jshin@chromium.org>
- Merge r41091.
+ Reviewed by Cameron Zwarich.
+
+ 1. Fix the crash in setHintEncoding
+ 2. Fix build failures on Tiger and Qt.
+ UnusedParam.h was not included by TextEncodingDetector{None,ICU}.cpp
+ in the patch landed in r42023
+ for http://bugs.webkit.org/show_bug.cgi?id=16482
+
+ * loader/TextResourceDecoder.h:
+ (WebCore::TextResourceDecoder::setHintEncoding):
+ * platform/text/TextEncodingDetectorICU.cpp:
+ * platform/text/TextEncodingDetectorNone.cpp:
+
+2009-03-26 Simon Fraser <simon.fraser@apple.com>
+
+ Build fix when ACCELERATED_COMPOSITING is turned on.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::canUseDirectCompositing):
+
+2009-03-26 Eric Seidel <eric@webkit.org>
+
+ No additional review, committing previously reviewed files for build fix only.
+
+ Add files I missed when commiting Jungshik's patch in r42022.
+ https://bugs.webkit.org/show_bug.cgi?id=16482
+
+ * icu/unicode/ucsdet.h: Added.
+ * platform/text/TextEncodingDetector.h: Added.
+ * platform/text/TextEncodingDetectorICU.cpp: Added.
+ (WebCore::detectTextEncoding):
+ * platform/text/TextEncodingDetectorNone.cpp: Added.
+ (WebCore::detectTextEncoding):
+
+2009-03-26 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add an encoding detector 'hook' to TextResourceDecoder.
+ - add |usesEncodingDetector| to Settings. It's off by default.
+ - add a new encoding source type |EncodingFromParent|
+ to distinguish cases when the encoding is inherited from
+ the parent frame from cases when it's actually auto-detected.
+ - add TextEncodingDetector* to platform/text. Currently,
+ the only implementation uses ICU. Stub is added for
+ ports that do not use ICU and a build on Tiger. Mac OS
+ Tiger comes with ICU 3.2 that does not support encoding detector.
+ - add ucsdet.h to icu/unicode for ports using ICU.
+
+ Layout tests will be added once bug 20534 is fixed and a WebPreference
+ can be controlled in test_shell. With UsesEncodingDetector off, there
+ is no change to test.
+
+ http://bugs.webkit.org/show_bug.cgi?id=16482
+
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCore/GNUmakefile.am
+ * WebCore/WebCore.pro
+ * WebCore/WebCore.scons
+ * WebCore/WebCoreSources.bkl
+ * WebCore.base.exp
+ * icu/unicode/ucsdet.h
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::write): turn on/off encoding detector depending on Settings and set hintEncoding of TextResourceDecoder to the parent frame encoding if necessary and the security policy allows refering to the parent frame encoding.
+ * loader/TextResourceDecoder.cpp:
+ (WebCore::TextResourceDecoder::TextResourceDecoder):
+ (WebCore::TextResourceDecoder::checkForCSSCharset): add check for EncodingFromParentFrame
+ (WebCore::TextResourceDecoder::checkForHeadCharset): ditto
+ (WebCore::TextResourceDecoder::shouldAutoDetect):
+ (WebCore::TextResourceDecoder::decode): call encoding detector if shouldAutoDetect returns true.
+ (WebCore::TextResourceDecoder::flush): if encoding is not determined by now, call encoding detector if shouldAutoDetect returns true.
+ * loader/TextResourceDecoder.h:
+ (WebCore::TextResourceDecoder::):
+ (WebCore::TextResourceDecoder::create):
+ (WebCore::TextResourceDecoder::setHintEncoding):
+ (WebCore::TextResourceDecoder::source):
+ * page/Settings.cpp: add m_usesEncodingDetector
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setUsesEncodingDetector):
+ * page/Settings.h:
+ (WebCore::Settings::usesEncodingDetector):
+ * platform/text/TextEncodingDetector.h: Added.
+ * platform/text/TextEncodingDetectorICU.cpp: Added.
+ (WebCore::detectTextEncoding):
+ * platform/text/TextEncodingDetectorNone.cpp: Added.
+ (WebCore::detectTextEncoding):
+
+2009-03-26 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Removed code that casts EventListener down to derived classes
+ without type checking. A crash could happen if you added event
+ listeners with Objective-C and then manipulated the class with
+ JavaScript.
+
+ * bindings/js/JSDOMApplicationCacheCustom.cpp:
+ (WebCore::JSDOMApplicationCache::mark): Removed all the casts
+ and used the markIfNotNull function and mark functions on
+ EventListener instead.
+ * bindings/js/JSMessagePortCustom.cpp:
+ (WebCore::JSMessagePort::mark): Ditto.
+ * bindings/js/JSWorkerContextCustom.cpp:
+ (WebCore::JSWorkerContext::mark): Ditto.
+ * bindings/js/JSWorkerCustom.cpp:
+ (WebCore::JSWorker::mark): Ditto.
+ * bindings/js/JSXMLHttpRequestCustom.cpp:
+ (WebCore::JSXMLHttpRequest::mark): Ditto.
+ * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
+ (WebCore::JSXMLHttpRequestUpload::mark): Ditto.
+
+ * bindings/js/JSEventListener.cpp:
+ (WebCore::JSAbstractEventListener::handleEvent): Used function,
+ the new name for what used to be called listenerObj.
+ (WebCore::JSAbstractEventListener::virtualIsInline): Renamed since
+ this doesn't need to be virtual for callers who have a pointer to
+ this class, not the base class.
+ (WebCore::JSEventListener::function): Renamed from listenerObj.
+ (WebCore::JSProtectedEventListener::function): Ditto.
+
+ * bindings/js/JSEventListener.h: Removed unneeded forward class
+ declarations. Made all virtual functions private since there's no
+ need to call any of them on a particular derived class, only on
+ EventListener. Explicitly declare JSEventListener::mark as virtual
+ since it's now overriding a function in the EventListener base class.
+ Made JSProtectedEventListener::m_globalObject protected so the
+ JSLazyEventListener derived class can use it directly instead of using
+ a virtual function to get the pointer.
+
+ * bindings/js/JSLazyEventListener.cpp:
+ (WebCore::JSLazyEventListener::parseCode): Use m_globalObject instead
+ of globalObject since the latter is a virtual function and there's no
+ need to pay virtual function overhead.
+ (WebCore::JSLazyEventListener::function): Renamed from listenerObj.
+
+ * bindings/js/JSLazyEventListener.h: Moved forward declaration of the
+ Node class here from JSEventListener.h.
+
+ * bindings/scripts/CodeGeneratorJS.pm: Removed now-unneeded cast to
+ JSEventListener when getting the script object from a listener.
+
+ * dom/EventListener.h: Added virtual function and mark functions
+ so we can extract the JavaScript function object or mark a JavaScript
+ event listener in a type safe manner.
+
+2009-03-26 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Adele Peterson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24859
+ Use CSS file instead of code to adjust search field styling.
+
+ * css/themeWin.css:
+ * rendering/RenderThemeWin.cpp:
+ * rendering/RenderThemeWin.h:
+
+2009-03-26 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Split JSLazyEventListener out into its own separate source file.
+ We'll be removing JSAbstractEventListener and JSProtectedEventListener soon,
+ so leave those in the same file with JSEventListener.
+
+ * GNUmakefile.am: Added JSLazyEventListener.
+ * WebCore.pro: Ditto.
+ * WebCore.scons: Ditto.
+ * WebCore.vcproj/WebCore.vcproj: Ditto.
+ * WebCore.xcodeproj/project.pbxproj: Ditto.
+ * WebCoreSources.bkl: Ditto.
+
+ * bindings/js/JSEventListener.cpp: Removed the JSLazyEventListener part.
+ Removed unneeded includes. Removed incorrect ASSERT_CLASS_FITS_IN_CELL, since
+ JSAbstractEventListener is not derived from JSCell.
+
+ * bindings/js/JSEventListener.h: Removed the JSLazyEventListener part
+ and the now-unneeded include of PlatformString.h.
+
+ * bindings/js/JSLazyEventListener.cpp: Copied from bindings/js/JSEventListener.cpp.
+ Kept only the JSLazyEventListener part.
+ (WebCore::eventParameterName): Made this have internal linkage by adding "static".
+ Also moved the default case out of the switch statement so we will get a warning
+ if we omit any cases in the future.
+
+ * bindings/js/JSLazyEventListener.h: Copied from bindings/js/JSEventListener.h.
+ Kept only the JSLazyEventListener part.
+
+ * bindings/js/ScriptController.cpp: Removed unneeded includes and sorted the
+ remanining ones. Include JSLazyEventListener.h instead of JSEventListener.h.
+
+2009-03-26 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Renamed JSUnprotectedEventListener to JSEventListener.
+ And related renames.
+
+ Soon Geoff will make all JavaScript event listeners use mark instead
+ of protect, so there's no need to emphasize "unprotected".
+
+ * bindings/js/JSDOMApplicationCacheCustom.cpp:
+ (WebCore::JSDOMApplicationCache::mark):
+ (WebCore::JSDOMApplicationCache::addEventListener):
+ (WebCore::JSDOMApplicationCache::removeEventListener):
+ * bindings/js/JSDOMGlobalObject.cpp:
+ (WebCore::JSDOMGlobalObject::~JSDOMGlobalObject):
+ (WebCore::JSDOMGlobalObject::findJSEventListener):
+ (WebCore::JSDOMGlobalObject::findOrCreateJSEventListener):
+ (WebCore::JSDOMGlobalObject::jsEventListeners):
+ (WebCore::JSDOMGlobalObject::jsInlineEventListeners):
+ * bindings/js/JSDOMGlobalObject.h:
+ * bindings/js/JSDOMWindowBase.h:
+ * bindings/js/JSEventListener.cpp:
+ (WebCore::JSEventListener::JSEventListener):
+ (WebCore::JSEventListener::~JSEventListener):
+ (WebCore::JSEventListener::listenerObj):
+ (WebCore::JSEventListener::globalObject):
+ (WebCore::JSEventListener::clearGlobalObject):
+ (WebCore::JSEventListener::mark):
+ * bindings/js/JSEventListener.h:
+ (WebCore::JSEventListener::create):
+ * bindings/js/JSMessagePortCustom.cpp:
+ (WebCore::JSMessagePort::mark):
+ (WebCore::JSMessagePort::addEventListener):
+ (WebCore::JSMessagePort::removeEventListener):
+ * bindings/js/JSWorkerContextCustom.cpp:
+ (WebCore::JSWorkerContext::mark):
+ (WebCore::JSWorkerContext::addEventListener):
+ (WebCore::JSWorkerContext::removeEventListener):
+ * bindings/js/JSWorkerCustom.cpp:
+ (WebCore::JSWorker::mark):
+ (WebCore::JSWorker::addEventListener):
+ (WebCore::JSWorker::removeEventListener):
+ * bindings/js/JSXMLHttpRequestCustom.cpp:
+ (WebCore::JSXMLHttpRequest::mark):
+ (WebCore::JSXMLHttpRequest::addEventListener):
+ (WebCore::JSXMLHttpRequest::removeEventListener):
+ * bindings/js/JSXMLHttpRequestUploadCustom.cpp:
+ (WebCore::JSXMLHttpRequestUpload::mark):
+ (WebCore::JSXMLHttpRequestUpload::addEventListener):
+ (WebCore::JSXMLHttpRequestUpload::removeEventListener):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ All just renaming.
+
+2009-03-26 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Renamed JSEventListener to JSProtectedEventListener.
+ And related renames.
+
+ Soon Geoff will make all JavaScript event listeners use mark instead
+ of protect, and so this class will be be obsolete. We will rename
+ JSUnrpotectedEventListener to JSEventListener in the next check-in,
+ since that one will remain.
+
+ * bindings/js/JSDOMGlobalObject.cpp:
+ (WebCore::JSDOMGlobalObject::~JSDOMGlobalObject):
+ (WebCore::JSDOMGlobalObject::findJSProtectedEventListener):
+ (WebCore::JSDOMGlobalObject::findOrCreateJSProtectedEventListener):
+ (WebCore::JSDOMGlobalObject::jsProtectedEventListeners):
+ (WebCore::JSDOMGlobalObject::jsProtectedInlineEventListeners):
+ * bindings/js/JSDOMGlobalObject.h:
+ * bindings/js/JSDOMWindowBase.h:
+ * bindings/js/JSDOMWindowCustom.cpp:
+ (WebCore::JSDOMWindow::addEventListener):
+ (WebCore::JSDOMWindow::removeEventListener):
+ * bindings/js/JSEventListener.cpp:
+ (WebCore::JSProtectedEventListener::JSProtectedEventListener):
+ (WebCore::JSProtectedEventListener::~JSProtectedEventListener):
+ (WebCore::JSProtectedEventListener::listenerObj):
+ (WebCore::JSProtectedEventListener::globalObject):
+ (WebCore::JSProtectedEventListener::clearGlobalObject):
+ (WebCore::JSLazyEventListener::JSLazyEventListener):
+ (WebCore::JSLazyEventListener::parseCode):
+ * bindings/js/JSEventListener.h:
+ (WebCore::JSProtectedEventListener::create):
+ * bindings/js/JSNodeCustom.cpp:
+ (WebCore::JSNode::addEventListener):
+ (WebCore::JSNode::removeEventListener):
+ * bindings/js/JSSVGElementInstanceCustom.cpp:
+ (WebCore::JSSVGElementInstance::addEventListener):
+ (WebCore::JSSVGElementInstance::removeEventListener):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ All just renaming.
+
+2009-03-26 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ - fix <rdar://problem/6725042> BidiResolver::createBidiRunsForLine can
+ create runs extending beyond the end
+
+ No test because Safari does not use this version of
+ createBidiRunsForLine() with the end iterator not pointing to the end
+ of the text run.
+
+ * platform/text/BidiResolver.h:
+ (WebCore::BidiResolver::appendRun): Cap the end of the run at the end
+ of the line and set the reachedEndOfLine flag. This mirrors the logic
+ in the specialized version of appendRun() in bidi.cpp, which is why the
+ problem did not show up in HTML. Also avoid creating empty runs.
+
+2009-03-26 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24864
+
+ Change the terminology from "inner content layer" to "direct compositing"
+ for cases where we can push an image directly over to the compositing system,
+ without having to draw it.
+
+ Clean up much of the code which looks at style to determine if this is possible,
+ and fix some bugs when backgrounds change dynamically.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::hasBorderOutlineOrShadow):
+ (WebCore::hasBoxDecorations):
+ (WebCore::hasBoxDecorationsWithBackgroundImage):
+ (WebCore::RenderLayerBacking::canBeSimpleContainerCompositingLayer):
+ (WebCore::RenderLayerBacking::canUseDirectCompositing):
+ (WebCore::RenderLayerBacking::detectDrawingOptimizations):
+ (WebCore::RenderLayerBacking::rendererContentChanged):
+ (WebCore::RenderLayerBacking::updateImageContents):
+ * rendering/RenderLayerBacking.h:
+
+2009-03-26 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23914
+
+ Tests: compositing/overflow/ancestor-overflow.html
+ compositing/overflow/parent-overflow.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::calculateClipRects):
+ * rendering/RenderLayer.h:
+ (WebCore::ClipRects::infiniteRect):
+ New static method that returns a large rect that is used by the clipping
+ logic.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ Use parentClipRects(), rather than calculateRects(), to compute the overflow
+ rect that we'll use to create a masking layer for composited clipping.
+
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::clippedByAncestor):
+ Use parentClipRects() to see whether there's a layer between us and our
+ compositing ancestor which applies clipping.
+
+ (WebCore::RenderLayerCompositor::clipsCompositingDescendants):
+ A layer which imposes clipping to its children doesn't have to be a stacking
+ context; it might be a normal flow layer; in either case, we can rely on the
+ hasCompositingDescendant() bit.
+
+2009-03-26 Steve Falkenburg <sfalken@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=24837
+ Escape key should dismiss select menu
+
+ Reviewed by Adam Roben.
+
+ * platform/win/PopupMenuWin.cpp:
+ (WebCore::PopupWndProc):
+
+2009-03-26 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Make sure the script uses LF line endings even on Windows.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24805
+
+ * WebCore/make-generated-sources.sh: Change svn:eol-style to LF
+
+2009-03-26 Eli Fidler <eli.fidler@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Remove warnings all over the place by making operator precedence
+ explicit in cases like x && y || z. No functional change.
+
+ * css/CSSFontSelector.cpp:
+ (WebCore::CSSFontSelector::addFontFaceRule):
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ (WebCore::CSSParser::parseShadow):
+ * dom/Document.cpp:
+ (WebCore::Document::shouldScheduleLayout):
+ * dom/Node.cpp:
+ (WebCore::Node::isBlockFlowOrBlockTable):
+ * dom/Node.h:
+ (WebCore::Node::document):
+ * dom/Position.cpp:
+ (WebCore::Position::next):
+ (WebCore::Position::upstream):
+ (WebCore::Position::downstream):
+ (WebCore::Position::getInlineBoxAndOffset):
+ * dom/PositionIterator.cpp:
+ (WebCore::PositionIterator::atStart):
+ * dom/Range.cpp:
+ (WebCore::Range::intersectsNode):
+ * editing/Editor.cpp:
+ (WebCore::Editor::setBaseWritingDirection):
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply):
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::doApply):
+ * editing/TextIterator.cpp:
+ (WebCore::TextIterator::advance):
+ (WebCore::SimplifiedBackwardsTextIterator::advance):
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::leftVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::rightVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::canonicalPosition):
+ * editing/htmlediting.cpp:
+ (WebCore::isMailBlockquote):
+ (WebCore::lineBreakExistsAtPosition):
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::parseMappedAttribute):
+ * loader/FTPDirectoryDocument.cpp:
+ (WebCore::processFileDateString):
+ * loader/ImageLoader.cpp:
+ (WebCore::ImageLoader::updateFromElement):
+ * loader/TextResourceDecoder.cpp:
+ (WebCore::TextResourceDecoder::checkForHeadCharset):
+ * page/AccessibilityObject.cpp:
+ (WebCore::updateAXLineStartForVisiblePosition):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::sendContextMenuEvent):
+ * page/animation/AnimationBase.cpp:
+ (WebCore::PropertyWrapperGetter::equals):
+ (WebCore::PropertyWrapperShadow::equals):
+ * platform/ContextMenu.cpp:
+ (WebCore::ContextMenu::populate):
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::adjustScrollbarsAvoidingResizerCount):
+ * platform/text/Base64.cpp:
+ (WebCore::base64Encode):
+ * platform/text/BidiResolver.h:
+ (WebCore::::raiseExplicitEmbeddingLevel):
+ (WebCore::::createBidiRunsForLine):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::placeEllipsisBox):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::addChild):
+ (WebCore::RenderBlock::repaintOverhangingFloats):
+ (WebCore::RenderBlock::fillInlineSelectionGaps):
+ (WebCore::RenderBlock::positionForPoint):
+ (WebCore::RenderBlock::calcInlinePrefWidths):
+ (WebCore::RenderBlock::hasLineIfEmpty):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::imageChanged):
+ (WebCore::RenderBox::localCaretRect):
+ (WebCore::RenderBox::positionForPoint):
+ (WebCore::RenderBox::shrinkToAvoidFloats):
+ * rendering/RenderObject.h:
+ (WebCore::objectIsRelayoutBoundary):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::clippedOverflowRectForRepaint):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::calcPrefWidths):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::determineStartPosition):
+ (WebCore::textWidth):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::diff):
+ * rendering/style/StyleInheritedData.cpp:
+ (WebCore::cursorDataEquivalent):
+ * rendering/style/StyleRareInheritedData.cpp:
+ (WebCore::StyleRareInheritedData::shadowDataEquivalent):
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::shadowDataEquivalent):
+ (WebCore::StyleRareNonInheritedData::animationDataEquivalent):
+ (WebCore::StyleRareNonInheritedData::transitionDataEquivalent):
+
+2009-03-26 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24804
+ [GTK] 401 responses cause rogue content to be loaded
+
+ Our soup code handles 401 responses itself, so we should not feed
+ the headers and data of those responses to the loader.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::gotHeadersCallback):
+ (WebCore::gotChunkCallback):
+
+2009-03-25 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt and Darin Adler.
+
+ Fixed <rdar://problem/6603167> Crash in WebKit!JSC::JSGlobalObject::resetPrototype
+ during Stress test (#3 & #7 WER crashes for Safari 4 Beta)
+
+ The problem was that allocation of the global object would, for just a
+ moment, leave the global object's prototype unprotected from GC. This
+ bug doesn't apply to non-global DOM objects because their prototypes are
+ cached and marked by the global object.
+
+ No test case because the crashing condition is hard to deterministically
+ produce in a normal build, and in a Windows Release build with
+ COLLECT_ON_EVERY_ALLOCATION set to 1, existing tests crash/hang.
+
+ * bindings/js/JSDOMWindowShell.cpp:
+ (WebCore::JSDOMWindowShell::setWindow):
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::initScript): Protect the global object's
+ prototype from GC during construction, since the global object does not
+ yet point to it, and therefore won't mark it.
+
+2009-03-25 Dean Jackson <dino@apple.com>
+
+ Reviewed by Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=23361
+
+ When using hardware compositing, some images can be directly
+ rendered by the hardware - no need to draw them into a separate
+ context, therefore saving memory.
+ Only images with certain style properties can be directly
+ composited - basically anything that is not a simple image requires
+ the usual rendering path (eg. if the image has borders).
+
+ Test: compositing/direct-image-compositing.html
+
+ * manual-tests/resources/simple_image.png: Added.
+ * manual-tests/simple-image-compositing.html: Added.
+ * platform/graphics/Image.h:
+ (WebCore::Image::startAnimation):
+ - move this to public
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::imageChanged):
+ - poke compositing layer if image has changed
+ (WebCore::RenderImage::notifyFinished):
+ - let the compositing layer know that it can render the image
+ * rendering/RenderImage.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::rendererContentChanged):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::canUseInnerContentLayer):
+ (WebCore::RenderLayerBacking::detectDrawingOptimizations):
+ (WebCore::RenderLayerBacking::rendererContentChanged):
+ * rendering/RenderLayerBacking.h:
+ - code to hook up direct compositing of images where
+ possible
+
+2009-03-25 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Chromium build fix. Fix #include in V8NodeFilterCondition.cpp due to the
+ rename of V8NodeFilter to V8NodeFilterCondition.
+
+ * bindings/v8/V8NodeFilterCondition.cpp:
+
+2009-03-25 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24817
+
+ When the slider range is zero, avoid a divide by zero, which caused the
+ thumb to be positioned off in the weeds, which broke painting.
+
+ Test: media/video-empty-source.html
+
+ * rendering/RenderSlider.cpp:
+ (WebCore::SliderRange::proportionFromValue):
+ (WebCore::SliderRange::valueFromProportion):
+ (WebCore::sliderPosition):
+ (WebCore::RenderSlider::setValueForPosition):
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Remove dead code and style cleanup
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * html/CanvasStyle.cpp:
+ (WebCore::CanvasStyle::CanvasStyle):
+ Coverty was annoyed that we didn't initialize all of our members. I agree, but I didn't
+ want to paste all 8 members each time, so I just cleaned up the existing constructors and left them.
+ * page/FocusController.cpp:
+ (WebCore::FocusController::setFocusedNode):
+ "node" was checked just above and is already known to be non-null
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::insertOnlyThisLayer):
+ We were already using parentLayer w/o a NULL check above, so just add an explicit ASSERT and use it w/o NULL check
+ (WebCore::RenderLayer::resize):
+ element is already ASSERTed above, no need to null check it here
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::addCell):
+ currentCell.cell was just assigned to the value "cell" which is known to be non-null, no need to null check again.
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Move ASSERT(foo) to before where foo-> is used
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * platform/chromium/PasteboardChromium.cpp:
+ (WebCore::Pasteboard::writeImage):
+ Move ASSERTs to the top of the function, code was using "node" before ASSERT(node), once I moved
+ ASSERT(node) to the top of the function it made sense to move the rest of them there too.
+ * rendering/SVGRenderSupport.cpp:
+ (WebCore::prepareToRenderSVGContent):
+ move ASSERT(object) to *before* we use "object" :)
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Make TextTokenizer ASSERT that the buffer was freed
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * loader/TextDocument.cpp:
+ (WebCore::TextTokenizer::TextTokenizer):
+ (WebCore::TextTokenizer::~TextTokenizer):
+ (WebCore::TextTokenizer::finish):
+ Make it clear by adding a ~TextTokenizer that finish() will always be called and the memory never leaked.
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Fix case where lBreak.obj->isBR() when lBreak.obj was NULL
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ I don't have a test case where we were taking the wrong path here
+ However, adding an ASSERT(lBreak.obj) before this usage caused
+ multiple bidi tests to fail, so lBreak.obj can be null here.
+
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::findNextLineBreak):
+ lBreak.obj can be null, so we can't call ->isBR() on it unconditionally.
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Style cleanup and dead code removal in dom, editing
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::getUpperLeftCorner):
+ (WebCore::ContainerNode::getLowerRightCorner):
+ (WebCore::ContainerNode::getRect):
+ Coverty was (rightly) confused as to what the hell "o" was being used for
+ and whether or not it would ever be NULL. I added some ASSERTS so that people (and machines)
+ would be less confused about the logic in getUpperLeftCorner/getLowerRightCorner
+ * dom/Document.cpp:
+ (WebCore::Document::recalcStyle):
+ Remove dead code, this block already checked that change == Force
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::removeInlineStyle):
+ Coverty correctly identified that traversePreviousNodePostOrder can return NULL, thus
+ prev will be null, and we don't really explicitly handle it (like we probably should)
+ It's OK though, because we end up creating a null position object, which may not have
+ been what we intended, but we certainly don't crash.
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply):
+ Remove dead code, insertionPosition.node() is already checked to be non-null above.
+ * editing/markup.cpp:
+ (WebCore::appendStartMarkup):
+ removed dead code, annotate is already known to be true at this point in the file
+ !annotate was checked above, and break; was called.
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ CSS dead code removal and cleanup from Coverty errors
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty):
+ Every other place in the code we check settings() for NULL, so I made these places
+ check too, even though we should never be resolving style against a document which has
+ no frame (which I believe is the only time settings() can be null)
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::styleSheetChanged):
+ Removing dead code, "root" can never be null here.
+ * css/SVGCSSStyleSelector.cpp:
+ (WebCore::colorFromSVGColorCSSValue):
+ (WebCore::CSSStyleSelector::applySVGProperty):
+ Extra returns in the old macros caused dead code. Removing the old macros and use modern
+ ones instead. :)
+ Extra null checks to value were not needed. Added an ASSERT at the top of the function
+ to make it clear that value will never be NULL.
+ Added colorFromSVGColorCSSValue to clean up the code a little.
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Font fallback cleanup and added ASSERT for GlyphPageTreeNode
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * css/CSSFontSelector.cpp:
+ (WebCore::compareFontFaces):
+ Coverty was concerned that it was possible to index off the end of weightFallbackRuleSets
+ I can't read the code well enough to tell, so I tried to make the code clearer
+ and added an ASSERT.
+ * platform/graphics/GlyphPageTreeNode.cpp:
+ (WebCore::GlyphPageTreeNode::initializePage):
+ Coverty believes we can crash here due to j being larger than GlyphPage::size. I think to is already
+ known to be < GlyphPage::size due to the min() statement above, but not being sure I added an ASSERT.
+
+2009-03-24 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Coverty inspired fixes in Animations/Transforms
+ https://bugs.webkit.org/show_bug.cgi?id=24684
+
+ * page/animation/AnimationBase.h:
+ Fix animate() signatures to match so that the virtual methods actually override one another. :)
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::removeFromStartTimeResponseWaitList):
+ Attempt to fix this method, prevAnimation was never set to anything but NULL,
+ as far as I can tell the author originally intended to update it at the end
+ of the loop, which is what I changed this code to do.
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::animate):
+ Make method signature match AnimationBase::animate
+ * page/animation/ImplicitAnimation.h:
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::animate):
+ Make method signature match AnimationBase::animate
+ * page/animation/KeyframeAnimation.h:
+ * platform/graphics/transforms/PerspectiveTransformOperation.cpp:
+ (WebCore::PerspectiveTransformOperation::blend):
+ if (blendToIdentity) already returned above.
+ * platform/graphics/transforms/RotateTransformOperation.cpp:
+ (WebCore::RotateTransformOperation::blend):
+ if (blendToIdentity) already returned above.
+
+2009-03-25 Eli Fidler <eli.fidler@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Fix compiler warnings regarding assignments in if statements.
+
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::createFormData):
+ * plugins/PluginPackage.cpp:
+ (WebCore::PluginPackage::compare):
+
+2009-03-25 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ - fix <rdar://problem/6472150> repro crash in
+ RenderBlock::rightmostPosition(bool, bool) const at mercotte.fr using
+ menus
+
+ Test: fast/inline/continuation-positioned-reparenting.html
+
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::splitFlow): When repurposing the existing
+ container as the "pre" block, clear its positioned objects list, because
+ positioned descendants may end up in a different block after the split.
+
+2009-03-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24784
+
+ Length values in transform operations need to take zoom into account.
+
+ Test: fast/transforms/transforms-with-zoom.html
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::createTransformOperations):
+
+2009-03-25 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24809, background-clip/origin don't use the correct
+ values. Add support for the new values (while preserving the old values for backwards
+ compatibility).
+
+ Changed some existing test cases to use the new values.
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseFillProperty):
+ * css/CSSPrimitiveValueMappings.h:
+ (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
+ (WebCore::CSSPrimitiveValue::operator EFillBox):
+ * css/CSSValueKeywords.in:
+
+2009-03-25 Brett Wilson <brettw@dhcp-172-22-71-191.mtv.corp.google.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ Fix complex text opacity on the Chromium Windows port.
+ https://bugs.webkit.org/show_bug.cgi?id=24757
+
+ Test: fast/text/complex-text-opacity.html
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::TransparencyAwareFontPainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::init):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::initializeForGDI):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::~TransparencyAwareFontPainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::TransparencyAwareGlyphPainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::~TransparencyAwareGlyphPainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::estimateTextBounds):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::drawGlyphs):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::hdc):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::TransparencyAwareUniscribePainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::~TransparencyAwareUniscribePainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::estimateTextBounds):
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+
+2009-03-25 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Fix for bug 23198, border images should not clip to border radii. The border-image should just ignore
+ the border-radius, since the assumption is that any desired rounding will be built into the border-image
+ itself.
+
+ Note that I do not agree with this change, but I am matching the spec.
+
+ Added fast/borders/border-image-border-radius.html
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintNinePieceImage):
+
+2009-03-25 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24750
+ [GTK] requests download instead of displaying page
+
+ Fix the Content-Type headers we get from soup, so that we set a
+ proper media type on the ResourceResponse.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::fillResponseFromMessage):
+
+2009-03-25 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24600
+ [GTK] responses with status code >= 400 should not be given special treatment
+
+ Do not special case requests that have HTTP responses >=
+ 400. Redirects are handled automatically by libsoup, but the rest
+ of the responses should be treated like any other.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::):
+ (WebCore::gotHeadersCallback):
+ (WebCore::gotChunkCallback):
+ (WebCore::finishedCallback):
+
+2009-03-25 Darin Adler <darin@apple.com>
+
+ Reviewed by John Sullivan.
+
+ Tidy up LegacyWebArchive a bit. And don't include favicons in web archives when
+ they are being used only for selections, not an entire document.
+
+ * WebCore.base.exp: Remove exported function that's not used in WebKit.
+
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ (WebCore::LegacyWebArchive::createPropertyListRepresentation): Made a static member
+ function so it can share private things with other member functions. Added some FIXME
+ comments to a branch of code I think is dead. Changed boolean argument into a named
+ one. Renamed to match other similar functions.
+ (WebCore::LegacyWebArchive::createResourceResponseFromPropertyListData): Ditto.
+ (WebCore::LegacyWebArchive::createResource): Ditto.
+ (WebCore::LegacyWebArchive::create): Merged the create and init functions.
+ (WebCore::LegacyWebArchive::rawDataRepresentation): Added some assertions because
+ we should never fail to write (we can fail to read).
+ (WebCore::LegacyWebArchive::createResourceResponseFromMacArchivedData): Made a static
+ member function as above.
+ (WebCore::LegacyWebArchive::createFromSelection): Ditto.
+ (WebCore::LegacyWebArchive::create): Iterate the vector with indices rather than
+ iterators. Only include the favicon if the first node is the document since we don't
+ want to include the favicon when copying and pasting.
+
+ * loader/archive/cf/LegacyWebArchive.h: Made one of the create functions private.
+ Made the Mac-specific functions be static member functions. Made other helpers be
+ static member functions. Removed the nit function.
+
+ * loader/archive/cf/LegacyWebArchiveMac.mm:
+ (WebCore::LegacyWebArchive::createResourceResponseFromMacArchivedData): Updated
+ comment and made this a static member function.
+ (WebCore::LegacyWebArchive::createPropertyListRepresentation): Ditto. Also made
+ it so we only type cast in one place.
+
+2009-03-25 Darin Adler <darin@apple.com>
+
+ Reviewed by David Hyatt.
+
+ Bug 24740: crash in RenderSlider::setPositionFromValue when calling pause() after setting <video> to display: none
+ https://bugs.webkit.org/show_bug.cgi?id=24740
+ rdar://problem/6679873
+
+ Bug 12104: Native Slider: When the thumb's height is specified as a percentage, it is not centered properly
+ https://bugs.webkit.org/show_bug.cgi?id=12104
+
+ Test: media/video-display-none-crash.html
+
+ The problem here was that RenderSlider was trying to position its thumb in a way that
+ requires it to call updateLayout inside rendering code. The right way to position a
+ child renderer is to do layout, so I had to write a layout function. And then fix a few
+ other small problems shown by the same test case.
+
+ * rendering/RenderSlider.cpp: Made defaultTrackLength have internal linkage.
+ Renamed HTMLSliderThumbElement to SliderThumbElement because we only use the HTML
+ prefix for public DOM classes, not elements used as implementation details.
+ Made SliderThumbElement function members private and got rid of unneeded default
+ argument value for shadowParent.
+ (WebCore::SliderRange::SliderRange): Added. Parses precision, max, and min attributes.
+ (WebCore::SliderRange::clampValue): Added. Does standard clamping based on the above.
+ (WebCore::SliderRange::valueFromElement): Added. Reads the value from the element in
+ a way that clamps to the range.
+ (WebCore::sliderPosition): Added. Computes the slider position: a double.
+ (WebCore::SliderThumbElement::SliderThumbElement): Removed unneeded explicit
+ initialization of m_initialClickPoint.
+ (WebCore::SliderThumbElement::defaultEventHandler): Call setValueForPosition instead
+ of calling setCurrentPosition and valueChanged.
+ (WebCore::RenderSlider::RenderSlider): Remove unneeded explicit initialization of m_thumb.
+ (WebCore::RenderSlider::styleDidChange): Remove unneeded second argument to createThumbStyle.
+ (WebCore::RenderSlider::createThumbStyle): Remove unneeded second argument. Get rid of code
+ setting the position to relative and setting the left and top. We now handle positioning
+ in a custom layout function.
+ (WebCore::RenderSlider::layout): Rewrote to handle positioning of the thumb as layout.
+ (WebCore::RenderSlider::updateFromElement): Added code to immediately update the value
+ in the element if it's out of range. This clamping used to be done as a side effect of
+ setPositionFromValue. Also, this has nothing to do with the renderer, so at some point
+ it could be moved into HTMLInputElement. Removed call to setPositionFromValue
+ and instead just rely on the call to setNeedsLayout. Fix the setNeedsLayout call to be
+ a normal setNeedsLayout(true), not a setNeedsLayout(true, false), because we do want
+ this to be propagated to the parent -- it's not called during layout.
+ (WebCore::RenderSlider::setValueForPosition): Refactor to use the new SliderRange
+ class. Also don't call setCurrentPosition; instead just call setNeedsLayout.
+ (WebCore::RenderSlider::currentPosition): Use the actual position of the renderer rather
+ than the style to find the position; that means this needs to be done after layout is done.
+ Also removed unneeded runtime checks and replaced them with assertions, after checking
+ all callers to see they already guarantee this.
+ (WebCore::RenderSlider::trackSize): Removed unneeded runtime checks and replaced them
+ with assertions, after checking all callers to see they already guarantee this.
+ (WebCore::RenderSlider::inDragMode): Added a null check for m_thumb so this won't
+ crash if called early on a brand new RenderSlider.
+
+ * rendering/RenderSlider.h: Made all functions private except for forwardEvent and inDragMode.
+ Renamed HTMLSliderThumbElement to SliderThumbElement because we only use the HTML
+ prefix for public DOM classes, not elements used as implementation details. Made the
+ mouseEventIsInThumb function non-virtual. Removed the return value and argument from
+ setPositionFromValue. Removed valueChanged and setCurrentPosition. Removed the oldStyle
+ argument to createThumbStyle (see above). Made SliderThumbElement a friend so it can use some
+ private member functions.
+
+2009-03-25 Eli Fidler <eli.fidler@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Fix ambiguous else cases by adding braces to nested if()s with elses.
+
+ * loader/MainResourceLoader.cpp:
+ (WebCore::MainResourceLoader::continueAfterContentPolicy):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::updateDragAndDrop):
+ * rendering/RenderListMarker.cpp:
+ (WebCore::toArmenianUnder10000):
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::TextControlInnerTextElement::defaultEventHandler):
+
+2009-03-24 Eli Fidler <eli.fidler@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Move variable into proper platform block to quiet warning.
+
+ * html/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::drawTextInternal):
+
+2009-03-24 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ Fix for <rdar://problem/6719375> Deal with QTKit loadstate changes when playing streaming movies
+
+ * WebCore/html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::setNetworkState): Deal with media engine reviving after having
+ network state of NETWORK_NO_SOURCE.
+
+ * WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::updateStates): Reset m_readyState at each state change since
+ some types of movies currently cause QTKit's load state to bounce around. QTMovieLoadStatePlaythroughOK
+ corresponds to HaveFutureData, not HaveEnoughData.
+
+2009-03-24 Adele Peterson <adele@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=24707
+ <rdar://problem/6593021> Deleting with a caret in a blank, quoted line decreases the quoting, but does not delete the line
+
+ * editing/TypingCommand.cpp: (WebCore::TypingCommand::deleteKeyPressed):
+ After breaking out of an empty mail blockquote, we still want continue with the deletion
+ so actual content will get deleted, and not just the quote style.
+
+2009-03-24 Darin Adler <darin@apple.com>
+
+ Reviewed by Brady Eidson.
+
+ <rdar://problem/6624662> REGRESSION (r39904): can't save certain web pages as web archive (ones without favicons!)
+
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ (WebCore::LegacyWebArchive::create): Added a null check.
+
+2009-03-24 Adam Langley <agl@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24685
+
+ The Skia drawLine function takes subpixel values and attempts to draw
+ a line with subpixel precision. This is complex and slow for drawing
+ scrollbars which use only vertical and horizontal lines.
+
+ This changes the Chromium Linux scrollbar code to use drawIRect.
+
+ * platform/chromium/ScrollbarThemeChromiumLinux.cpp:
+ (WebCore::ScrollbarThemeChromium::invalidateOnMouseEnterExit):
+ (WebCore::drawVertLine):
+ (WebCore::drawHorizLine):
+ (WebCore::drawBox):
+ (WebCore::ScrollbarThemeChromium::paintTrackPiece):
+ (WebCore::ScrollbarThemeChromium::paintThumb):
+
+2009-03-24 David Kilzer <ddkilzer@apple.com>
+
+ Bug 23310: Setting an absolute path (/abs) on an <iframe> with no src doesn't resolve the URL properly
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23310>
+
+ Reviewed by Darin Adler.
+
+ Test: fast/frames/iframe-no-src-set-location.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::completeURL): If m_baseURL is empty or is
+ about:blank and we have a parent document, use the parent
+ document's URL for the base when completing a new URL.
+
+2009-03-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24659
+
+ When hit-testing 3d-transformed layers, it doesn't make sense to project the hitTestRect
+ into the coordinate space of the layer, and doing so can result in pathalogical quads
+ that break hit testing. In that case, simply use the same bounds as used for painting,
+ which are the composited bounds for this layer.
+
+ Test: transforms/3d/hit-testing/rotated-hit-test.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24436
+
+ When compositing is enabled, painting and hit testing end up using different
+ clipping roots, because, for painting, every composited layer is a clipping root,
+ but for hit testing only layers with transforms are. To fix this, we use
+ temporary clip rects for hit testing, if the page is in compositing mode.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayer):
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::parentClipRects):
+ (WebCore::RenderLayer::calculateRects):
+ * rendering/RenderLayer.h:
+
+2009-03-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ https://bugs.webkit.org/show_bug.cgi?id=24782
+
+ Fix regression with CSS clip rects with non-length values, by reverting to
+ the original code, but passing the zoom multiplier through convertToLength().
+
+ Also make stylistic change in createTransformOperations(), renaming 'inStyle'
+ to 'style.
+
+ Tested by existing tests.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::convertToLength):
+ (WebCore::CSSStyleSelector::applyProperty):
+ (WebCore::CSSStyleSelector::createTransformOperations):
+
+2009-03-24 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=21789, overflow:hidden elements should clip their foreground contents
+ to a border-radius.
+
+ This patch makes non-self-painting overflow layers and control clips work with border-radius. RenderLayers
+ that should be clipped by overflow ancestors with border-radius are still broken.
+
+ Added fast/clip/overflow-border-radius-clip.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::pushContentsClip):
+
+2009-03-24 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=21789, overflow:hidden elements should clip their foreground contents.
+
+ This first patch makes overflow:hidden properly clip the foreground contents of overflow:hidden replaced elements. Common
+ replaced elements now default to overflow:hidden in the UA stylesheet (this is what the spec specifically recommends be
+ done).
+
+ Added fast/replaced/border-radius-clip.html
+
+ * css/html4.css:
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::paint):
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::paint):
+
+2009-03-24 Adele Peterson <adele@apple.com>
+
+ RS by Mark Rowe.
+
+ Only build these Mail quirks checks in on the Mac.
+
+ * dom/Document.cpp: (WebCore::disableRangeMutation):
+ * html/HTMLElement.cpp: (WebCore::HTMLElement::inEitherTagList):
+
+2009-03-24 Brent Fulgham <bfulgham@webkit.org>
+
+ Build fix, no review.
+
+ Remove ResourceLoaderCFNet.cpp from build list for Cairo Releas
+ and Debug targets.
+
+ * WebCore.vcproj/WebCore.vcproj:
+
+2009-03-24 Eric Carlson <eric.carlson@apple.com>
+
+ Fix layout tests broken by r41907.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::setReadyState): Don't set "was playing" based on the new ready state
+
+2009-03-24 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24689
+ Fix Chromium compilation errors.
+
+ * bindings/v8/WorkerContextExecutionProxy.cpp:
+ (WebCore::WorkerContextExecutionProxy::FindOrCreateEventListener):
+ (WebCore::WorkerContextExecutionProxy::RemoveEventListener):
+
+2009-03-24 Yury Semikhatsky <yurys@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24759
+ Add missing methods Element.prototype.removeMatchingStyleClasses and
+ Node.prototype.enclosingNodeOrSelfWithNodeNameInArray to SourceFrame content
+ iframe. These methods are called by Element.prototype.removeStyleClass and
+ Node.prototype.enclosingNodeOrSelfWithNodeName.
+
+ * inspector/front-end/SourceFrame.js:
+ (WebInspector.SourceFrame.prototype._loaded):
+
+2009-03-24 Mark Mentovai <mark@chromium.org>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24653
+ WebKit should be buildable without prefix header injection.
+ Adds missing #includes and forward declarations as needed.
+
+ * editing/SmartReplaceCF.cpp:
+ * platform/graphics/mac/ColorMac.mm:
+ * platform/graphics/mac/FontCacheMac.mm:
+ * platform/graphics/mac/FontCustomPlatformData.h:
+ * platform/graphics/mac/FontMac.mm:
+ * platform/graphics/mac/FontMacATSUI.mm:
+ * platform/graphics/mac/FontPlatformData.h:
+ * platform/graphics/mac/FontPlatformDataMac.mm:
+ * platform/graphics/mac/GraphicsContextMac.mm:
+ * platform/graphics/mac/SimpleFontDataMac.mm:
+ * platform/mac/FoundationExtras.h:
+ * platform/mac/LocalCurrentGraphicsContext.h:
+ * platform/mac/WebCoreSystemInterface.h:
+ * platform/mac/WebCoreSystemInterface.mm:
+ * platform/mac/WebCoreTextRenderer.h:
+ * platform/mac/WebCoreTextRenderer.mm:
+ * platform/mac/WebFontCache.h:
+ * platform/mac/WebFontCache.mm:
+ * platform/text/PlatformString.h:
+ * platform/text/mac/ShapeArabic.c:
+ * platform/text/mac/StringMac.mm:
+ * rendering/RenderThemeChromiumMac.h:
+
+2009-03-24 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ - fix <rdar://problem/6107874> by capping the nesting depth of
+ "block-level" elements generated by the parser
+
+ Test: fast/parser/block-nesting-cap.html
+
+ * html/HTMLParser.cpp:
+ (WebCore::HTMLParser::HTMLParser):
+ (WebCore::HTMLParser::insertNode):
+ (WebCore::HTMLParser::pushBlock):
+ (WebCore::HTMLParser::popOneBlockCommon):
+ (WebCore::HTMLParser::freeBlock):
+ * html/HTMLParser.h:
+
+2009-03-23 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by David Kilzer.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24771
+
+ DOMTimeStamps are based upon 1970.
+
+ * platform/mac/GeolocationServiceMac.mm:
+ (-[WebCoreCoreLocationObserver locationManager:didUpdateToLocation:fromLocation:]):
+
+2009-03-23 Eric Seidel <eric@webkit.org>
+
+ Build fix, no review.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::createVisiblePosition): change .container to .isNotNull()
+
+2009-03-23 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Rename Position::container to m_anchorNode and make it private
+ https://bugs.webkit.org/show_bug.cgi?id=24760
+
+ More code cleanup for Position.
+
+ Change all uses of m_container to node()
+ Eventually most uses of node() should change to anchorNode() to designate
+ that it's the node the Position is anchored to, but not necessarily the
+ container of the position (it could be the before/after neighbor).
+
+ Remove any code which sets m_container, and change it to use a new
+ Position::moveToPosition function which takes a node and offset.
+ It never makes sense to change the node and leave the offset.
+
+ * dom/Position.h:
+ (WebCore::Position::Position):
+ (WebCore::Position::clear):
+ (WebCore::Position::anchorNode):
+ (WebCore::Position::node):
+ (WebCore::Position::moveToPosition):
+ (WebCore::Position::moveToOffset):
+ (WebCore::Position::isNull):
+ (WebCore::Position::isNotNull):
+ (WebCore::operator==):
+ * dom/Range.cpp:
+ (WebCore::Range::create):
+ (WebCore::Range::compareBoundaryPoints):
+ * dom/RangeBoundaryPoint.h:
+ (WebCore::RangeBoundaryPoint::container):
+ (WebCore::RangeBoundaryPoint::set):
+ (WebCore::RangeBoundaryPoint::setOffset):
+ (WebCore::RangeBoundaryPoint::setToChild):
+ (WebCore::RangeBoundaryPoint::setToStart):
+ (WebCore::RangeBoundaryPoint::setToEnd):
+
+2009-03-17 Eric Seidel <eric@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ document.write() should be able to make a document strict mode
+ https://bugs.webkit.org/show_bug.cgi?id=24336
+
+ Remove an implicit write of "<html>" on the first document.write call
+ this was added as part of a KDE import http://trac.webkit.org/changeset/798
+ with no layout test or explanation. I can't think of any reason why
+ an implicit <html> write is necessary (or correct), so I'm removing it and
+ adding a test for the correct behavior. The parser will add any necessary
+ HTMLHTMLElements during the write() anyway.
+
+ Our behavior is now tested by fast/dom/Document/document-write-doctype
+ and matches IE, FF fails this new test. Mozilla bug filed:
+ https://bugzilla.mozilla.org/show_bug.cgi?id=483908
+
+ * dom/Document.cpp:
+ (WebCore::Document::write):
+
+2009-03-23 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Dan Bernstein.
+
+ Fix for <rdar://problem/6140966>
+ Empty Caches does not clear the Cross-site XMLHttpRequest preflight cache
+
+ * WebCore.base.exp:
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/CrossOriginPreflightResultCache.cpp:
+ (WebCore::CrossOriginPreflightResultCache::empty):
+ * loader/CrossOriginPreflightResultCache.h:
+
+2009-03-23 Darin Adler <darin@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ Bug 24726: hit testing doesn't work right when the click is on anonymous content
+ https://bugs.webkit.org/show_bug.cgi?id=24726
+ rdar://problem/6696992
+
+ Test: editing/selection/hit-test-anonymous.html
+
+ * rendering/RenderBR.cpp:
+ (WebCore::RenderBR::positionForPoint): Call createVisiblePosition instead of
+ creating a VisiblePosition directly. It will handle finding non-anonymous
+ content nearby if node() is 0.
+ * rendering/RenderBlock.cpp:
+ (WebCore::positionForPointRespectingEditingBoundaries): Ditto.
+ (WebCore::positionForPointWithInlineChildren): Ditto.
+ (WebCore::RenderBlock::positionForPoint): Ditto.
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::positionForPoint): Ditto.
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::positionForPoint): Ditto.
+ (WebCore::RenderObject::createVisiblePosition): Added.
+ * rendering/RenderObject.h: Added createVisiblePosition.
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::positionForPoint): Call createVisiblePosition.
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::positionForPoint): Ditto.
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::positionForPoint): Ditto.
+
+2009-03-23 Adele Peterson <adele@apple.com>
+
+ Reviewed by Darin Adler & Dave Hyatt.
+
+ Fix for <rdar://problem/6621310> REGRESSION(35185): Apple Travel HTML emails missing some style after Safari 4 upgrade
+
+ Leopard Mail doesn't expect <style> to be in the body. This change reverts back to the old behavior of
+ moving <style> to <head> for that version of Mail.
+
+ * html/HTMLElement.cpp: (WebCore::HTMLElement::inEitherTagList):
+
+2009-03-23 Adele Peterson <adele@apple.com>
+
+ Reviewed by Mark Rowe & Dave Hyatt.
+
+ Merge some of the individual Mail quirks into two settings that we can check for future quirks.
+
+ * WebCore.base.exp:
+ * dom/Document.cpp:
+ (WebCore::disableRangeMutation):
+ (WebCore::Document::nodeChildrenChanged):
+ (WebCore::Document::nodeWillBeRemoved):
+ (WebCore::Document::textInserted):
+ (WebCore::Document::textRemoved):
+ (WebCore::Document::textNodesMerged):
+ (WebCore::Document::textNodeSplit):
+ * page/Settings.cpp:
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setNeedsLeopardMailQuirks):
+ (WebCore::Settings::setNeedsTigerMailQuirks):
+ * page/Settings.h:
+ (WebCore::Settings::needsLeopardMailQuirks):
+ (WebCore::Settings::needsTigerMailQuirks):
+
+2009-03-23 Ada Chan <adachan@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=24762
+ Support text-indent in <option> elements on windows platform.
+
+ Reviewed by Adele Peterson.
+
+ * css/themeWin.css:
+ * platform/PopupMenuStyle.h: We don't honor font specified on <option> elements right now. Make this
+ explicit via windows themed default stylesheet.
+ (WebCore::PopupMenuStyle::PopupMenuStyle): Also store text-indent and text-direction.
+ (WebCore::PopupMenuStyle::textIndent):
+ (WebCore::PopupMenuStyle::textDirection):
+ * platform/win/PopupMenuWin.cpp:
+ (WebCore::PopupMenu::paint): Adjust the text's x-coordinate if text-indent is supported for options and
+ text-indent is specified with LTR direction.
+ * rendering/RenderMenuList.cpp:
+ (WebCore::RenderMenuList::updateOptionsWidth): Take text-indent into account if theme supports text-indent for options.
+ (WebCore::RenderMenuList::itemStyle): Use new PopupMenuStyle constructor on windows.
+ (WebCore::RenderMenuList::menuStyle): Ditto.
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::menuStyle): Ditto.
+ * rendering/RenderTheme.h:
+ (WebCore::RenderTheme::popupOptionSupportsTextIndent): Added. Default is false since we are only supporting it in windows for now.
+ * rendering/RenderThemeWin.h:
+ (WebCore::RenderThemeWin::popupOptionSupportsTextIndent): Returns true for windows.
+
+2009-03-23 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Anders Carlsson.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=24699
+ REGRESSION: Java Applets broken
+ <rdar://problem/6707494>
+
+ Fix loading Java applets without a codeBase. Only pass the base (up to the
+ the last path component) of the baseURL to the plug-in.
+
+ * html/HTMLAppletElement.cpp:
+ (WebCore::HTMLAppletElement::createRenderer):
+ * platform/KURL.cpp:
+ (WebCore::KURL::baseAsString):
+ * platform/KURL.h:
+
+2009-03-23 Darin Adler <darin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ * platform/KURL.h: Removed now-incorrect comments.
+ None of the parts include the separator characters any more, now that
+ query doesn't include the "?", so the comments explaining which do and do
+ not are no-longer helpful.
+
+2009-03-23 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24764
+
+ Renamed files V8NodeFilter -> V8NodeFilterCondition to reflect
+ class names. Also fixed some headers that got mangled in search/replace
+ operations.
+
+ No change in behavior, so no test.
+
+ * bindings/v8/V8NodeFilter.h: Removed.
+ * bindings/v8/V8NodeFilterCondition.cpp: Renamed from WebCore/bindings/v8/V8NodeFilter.cpp.
+ * bindings/v8/V8NodeFilterCondition.h: Added.
+ * bindings/v8/custom/V8ClipboardCustom.cpp:
+ * bindings/v8/custom/V8DocumentCustom.cpp:
+ * bindings/v8/custom/V8ElementCustom.cpp:
+ * bindings/v8/custom/V8HTMLCanvasElementCustom.cpp:
+ * bindings/v8/custom/V8NavigatorCustom.cpp:
+
+2009-03-23 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Antti Koivisto.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24741
+
+ Adds a unique across-browser-sessions identifier to FormData, which may
+ be used by ResourceHandle as a secondary cache key to enable cached
+ form submissions.
+
+ At issue: two otherwise identical form submissions may result in
+ completely independent responses, which may each be appropriate to
+ store and reuse from cache.
+
+ * html/HTMLFormElement.cpp: Added call to FormData::setIdentifier so that
+ we only enable cached form submissions for those generated by HTML. This
+ way we do not bother with POSTs generated by XMLHttpRequest.
+ (WebCore::generateFormDataIdentifier):
+ (WebCore::HTMLFormElement::createFormData):
+ * platform/network/FormData.cpp: Initialize m_identifier to 0, which means
+ the unspecified identifier. So by default there is no identifier and
+ nothing changes.
+ (WebCore::FormData::FormData):
+ * platform/network/FormData.h: Added m_identifier with setter and getter.
+ (WebCore::FormData::setIdentifier):
+ (WebCore::FormData::identifier):
+
+2009-03-23 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Antti Koivisto
+
+ https://bugs.webkit.org/show_bug.cgi?id=24733
+
+ Fix media controller with full-page zoom. Previously, the media controller
+ shadow nodes never saw style changes on the RenderMedia, so did not respond
+ to zooming at all. Now, we update the style on the shadow renderers
+ whenever RenderMedia gets a style change. Also fix the video thumb in
+ the theme to be scaled properly.
+
+ Test: media/video-controls-zoomed.html
+
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaControlShadowRootElement::updateStyle):
+ (WebCore::MediaTextDisplayElement::MediaTextDisplayElement):
+ (WebCore::MediaTextDisplayElement::updateStyle):
+ (WebCore::MediaControlInputElement::MediaControlInputElement):
+ (WebCore::MediaControlInputElement::updateStyle):
+ * rendering/MediaControlElements.h:
+ * rendering/RenderMedia.cpp:
+ (WebCore::RenderMedia::styleDidChange):
+ * rendering/RenderMedia.h:
+ * rendering/RenderThemeMac.mm:
+ (WebCore::RenderThemeMac::adjustSliderThumbSize):
+
+2009-03-23 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24739
+
+ Rework StringImpl::create methods to try to allocate a single buffer
+ rather than allocating both the StringImpl class and a separate data
+ buffer.
+
+ * platform/text/StringImpl.cpp:
+ * platform/text/StringImpl.h:
+
+2009-03-23 Darin Adler <darin@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ Based on a patch by Nico Weber <nicolasweber@gmx.de>
+
+ Bug 24755: LayoutTests/http/tests/misc/url-in-utf16le.html regression
+ https://bugs.webkit.org/show_bug.cgi?id=24755
+
+ * platform/text/TextEncoding.cpp:
+ (WebCore::TextEncoding::isUTF7Encoding): Added. Checks if the current encoding
+ is UTF7 without loading extended codecs.
+ (WebCore::TextEncoding::encodingForFormSubmission): Use isUTF7Encoding() instead
+ of comparing with UTF7Encoding(). Eliminate the explicit check of
+ noExtendedTextEncodingNameUsed() because that's now handled by the functions
+ that this function calls instead.
+
+ * platform/text/TextEncoding.h: Added isUTF7Encoding function.
+ Also tweaked formatting a bit.
+
+2009-03-20 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24720
+ RenderThemeChromium should draw something for Slider parts instead of
+ dropping them on the floor.
+
+ * platform/chromium/ChromiumBridge.h:
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::RenderThemeChromiumWin::adjustSliderThumbSize):
+ (WebCore::RenderThemeChromiumWin::paintSliderTrack):
+ (WebCore::RenderThemeChromiumWin::determineSliderThumbState):
+ (WebCore::RenderThemeChromiumWin::getThemeData):
+ * rendering/RenderThemeChromiumWin.h:
+ (WebCore::RenderThemeChromiumWin::paintSliderThumb):
+
+2009-03-23 Glen Murphy <glen@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24657
+
+ Fix Skia drawing of highly scaled bitmaps; the conversion to
+ IntRect produced visible layout test failures in highly scaled
+ coordinate systems.
+
+ Test: svg/custom/image-small-width-height.svg
+
+ * WebCore\platform\graphics\skia\ImageSkia.cpp:
+
+2009-03-23 David Kilzer <ddkilzer@apple.com>
+
+ Provide JavaScript exception information after slow script timeout
+
+ Reviewed by Oliver Hunt.
+
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::evaluate): Changed to report
+ exceptions for the Interrupted completion type as well.
+
+2009-03-23 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24736
+
+ Fix three mostly-unrelated problems with full-page zoom:
+
+ * dom/Document.cpp:
+ (WebCore::Document::elementFromPoint):
+ Document::elementFromPoint() needs to take full-page zoom into account.
+
+ * dom/MouseRelatedEvent.cpp:
+ (WebCore::MouseRelatedEvent::receivedTarget):
+ Take full-page zoom into account when computing offsetX/offsetY.
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::listBoxDefaultEventHandler):
+ Don't use offsetX/offsetY when hit testing list boxes; offsets were broken
+ with full-page zoom, and using pageX/pageY is easier because we don't
+ have to worry about the event target, and we already have a point in
+ absolute coordinates.
+
+ Tests: fast/forms/listbox-hit-test-zoomed.html
+ fast/forms/search-zoomed.html
+ fast/forms/slider-zoomed.html
+
+2009-03-23 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ https://bugs.webkit.org/show_bug.cgi?id=24753
+
+ The rect for CSS 'clip' needs to have zooming applied to it.
+
+ Test: fast/css/clip-zooming.html
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty):
+
+2009-03-23 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Adam Roben.
+
+ <rdar://problem/6704282>
+ https://bugs.webkit.org/show_bug.cgi?id=24719
+ QTMovieWinTimer logic inversion
+
+ Fix logic inversion in the Win32 timer used by QTMovieWin that caused it to always
+ use SetTimer, even when the intervals was below USER_TIMER_MINIMUM. A side effect of
+ this was that a movie timer would sometimes be blocked for significant amounts of time
+ because WM_TIMER messages are not processed when the thread's message queue has any
+ higher priority messages, and WebCore/Win's timer uses PostMessage for low interval
+ timers. Also change SetTimer call to use HWND and custom message instead of
+ timer function since the timer already has an HWND for processing PostMessage.
+
+ Not possible to make a test for this because it is so timing dependant.
+
+ * platform/graphics/win/QTMovieWinTimer.cpp:
+ (TimerWindowWndProc):
+ (setSharedTimerFireDelay):
+
+2009-03-23 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24588
+
+ Update media element implementation to current HTML5 spec
+
+ New tests:
+ media/media-constants.html
+ media/video-seek-no-src-exception.html
+ media/video-source-add-src.html
+ media/video-src-invalid-remove.html
+ media/video-src-plus-source.html
+ media/video-timeupdate-during-playback.html
+
+ * dom/EventNames.h: Remove obsolute events, add new ones.
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize new member vars.
+ (WebCore::HTMLMediaElement::attributeChanged): Trigger load() only when we don't
+ have a source.
+ (WebCore::HTMLMediaElement::removedFromDocument): Deal with state name changes.
+ (WebCore::HTMLMediaElement::scheduleProgressEvent): New, create a progress event and
+ add it to the event queue to be dispatch when the timer fires.
+ (WebCore::HTMLMediaElement::scheduleEvent): New, create a generic event and add
+ it to the event queue to be dispatch when the timer fires.
+ (WebCore::HTMLMediaElement::enqueueEvent): Add an event to the queue and ticke the
+ asynch event timer.
+ (WebCore::HTMLMediaElement::asyncEventTimerFired): Dispatch all pending events.
+ (WebCore::HTMLMediaElement::loadTimerFired): Either trigger the initial load or
+ try to load the next <source> url.
+ (WebCore::HTMLMediaElement::load): Minor style change.
+ (WebCore::HTMLMediaElement::loadInternal): The first part of the spec load algorithm, cleanup
+ the current load (if any) and set up state for a new load.
+ (WebCore::HTMLMediaElement::selectMediaResource): Deal with no 'src' or <source>, post 'loadstart'
+ event, and initiate load from 'src' if present.
+ (WebCore::HTMLMediaElement::loadNextSourceChild): Initiate load from next <source> url, or trigger
+ noneSupported() if no more to consider.
+ (WebCore::HTMLMediaElement::loadResource): Instantiate a new MediaPlayer and ask it to load a url.
+ (WebCore::HTMLMediaElement::startProgressEventTimer): Start the repeating progress event timer.
+ (WebCore::HTMLMediaElement::noneSupported): Post error event and set up state when no valid
+ media url was found.
+ (WebCore::HTMLMediaElement::mediaEngineError): Post error event and set up state when no valid
+ media engine failed with a decode error or a network error.
+ (WebCore::HTMLMediaElement::mediaPlayerNetworkStateChanged):
+ (WebCore::HTMLMediaElement::setNetworkState): Updated for new spec network states.
+ (WebCore::HTMLMediaElement::mediaPlayerReadyStateChanged):
+ (WebCore::HTMLMediaElement::setReadyState): Updated for new spec ready state.
+ (WebCore::HTMLMediaElement::progressEventTimerFired): Bail if the network is not active.
+ (WebCore::HTMLMediaElement::seek): Return INVALID_STATE_ERR exception if state is too low or
+ if player hasn't been set up yet. This is necessary becase load() is async. Clear the flag
+ we use to guard against sending 'ended' more than once.
+ (WebCore::HTMLMediaElement::duration): Don't bother calling media engine before it has metadata.
+ (WebCore::HTMLMediaElement::setDefaultPlaybackRate): Remove exception param, 0 is no longer an
+ invalid rate.
+ (WebCore::HTMLMediaElement::setPlaybackRate): Remove exception param, 0 is no longer an
+ invalid rate. Cache rate being set so we can use it later if media engine isn't ready now.
+ (WebCore::HTMLMediaElement::play): Remove exception param, play() before load() now just
+ starts loading asynchronously.
+ (WebCore::HTMLMediaElement::playInternal): Remove exception param. Fire 'waiting' or 'playing'
+ event depending on current state.
+ (WebCore::HTMLMediaElement::pause): Remove exception param, pause() before load() now just
+ starts loading asynchronously.
+ (WebCore::HTMLMediaElement::pauseInternal): Remove exception param.
+ (WebCore::HTMLMediaElement::setVolume): dispatchEventAsync -> scheduleEvent
+ (WebCore::HTMLMediaElement::setMuted): dispatchEventAsync -> scheduleEvent
+ (WebCore::HTMLMediaElement::togglePlayState): Remove exception param.
+ (WebCore::HTMLMediaElement::beginScrubbing): pause() doesn't take an exception param.
+ (WebCore::HTMLMediaElement::startPlaybackProgressTimer): New, starts timer that fires 4 times per
+ second when the movie is playing to timeupdate so we can post 'timeupdate' events.
+ (WebCore::HTMLMediaElement::playbackProgressTimerFired): Timer proc.
+ (WebCore::HTMLMediaElement::scheduleTimeupdateEvent): Bottleneck around scheduling a 'timeupdate'
+ event because we both fire them them when the spec says we should and when the media engine
+ says that time has jumped, but we don't want to fire more than one at a given movie time. We also
+ use this bottleneck to keep track of the last time one was posted so we won't fire too often
+ during playback.
+ (WebCore::HTMLMediaElement::canPlay): readyState now tracks whether or not we have metadata.
+ (WebCore::HTMLMediaElement::havePotentialSourceChild): New, checks to see if there are a <source>
+ element with a 'src' attribute that we have not tried to load yet.
+ (WebCore::HTMLMediaElement::nextSourceChild): New, returns the url and content type of the next
+ <source> element that we haven't tried to load.
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Schedule 'seeked' event when seeking completes.
+ Set a flag when we post the 'ended' event, clear it when time changed and we aren't at the end since
+ some media engines call this proc more than once when playback reaches the end and stops, but we
+ don't want to post 'ended' more than once.
+ (WebCore::HTMLMediaElement::mediaPlayerDurationChanged): New, added so media engine can inform
+ when the movie duration changes and we can post 'durationchanged' event.
+ (WebCore::HTMLMediaElement::mediaPlayerRateChanged): New, added so media engine can inform when
+ the rate changed and we can updated our cached rate. This is useful because we only want to know
+ post periodic 'timeupdate' events when the movie is actually playing, and because we want to know
+ the actual playback rate when it differs from what we tried to set.
+ (WebCore::HTMLMediaElement::mediaPlayerSizeChanged): New, added so media engine can inform when
+ a movie's intrinsic size changes and we can inform the renderer.
+ (WebCore::HTMLMediaElement::potentiallyPlaying): Renamed from activelyPlaying since the spec now
+ uses "actively playing" for this concept. Update logic for new state names and un-comment calls
+ to stoppedDueToErrors() and pausedForUserInteraction() since the spec says those condiditons
+ are part of the answer.
+ (WebCore::HTMLMediaElement::endedPlayback): Update logic for new state names.
+ (WebCore::HTMLMediaElement::stoppedDueToErrors): New, spec says this logic should be part of
+ the determination of "potentially playing".
+ (WebCore::HTMLMediaElement::pausedForUserInteraction): New, placeholder for when (if) user
+ agent supports this spec concept.
+ (WebCore::HTMLMediaElement::updatePlayState): Stop timer used to fire periodic 'timeupdate'
+ events when we pauses the movie. Set the media engine rate before calling play() in case it
+ wasn't set up when the rate was changed.
+ (WebCore::HTMLMediaElement::stopPeriodicTimers): New, stop the progress event and 'timeupate'
+ event timers.
+ (WebCore::HTMLMediaElement::userCancelledLoad): New, logic pulled out of documentWillBecomeInactive
+ and updated for the current spec.
+ (WebCore::HTMLMediaElement::documentWillBecomeInactive): Moved some logic to userCancelledLoad.
+ (WebCore::HTMLMediaElement::documentDidBecomeActive): Update comments.
+ (WebCore::HTMLMediaElement::initialURL): Update for refactoring of code that determines the
+ initial url.
+ * html/HTMLMediaElement.h: Change ReadyState and NetworkState enums to match names in the spec,
+ update for changes in .cpp.
+ (WebCore::HTMLMediaElement::):
+
+ * html/HTMLMediaElement.idl: Update ready state and network state constants for spec changes.
+ defaultPlaybackRate, playbackRate, play(), and pause() no longer raise exceptions.
+
+ * html/HTMLSourceElement.cpp:
+ (WebCore::HTMLSourceElement::insertedIntoDocument): Update for network state name changes.
+
+ * html/HTMLVideoElement.cpp:
+ (WebCore::HTMLVideoElement::updatePosterImage): Update for ready state name changes.
+
+ * html/MediaError.h:
+ (WebCore::MediaError::): add MEDIA_ERR_NONE_SUPPORTED.
+
+ * html/MediaError.idl: add MEDIA_ERR_NONE_SUPPORTED.
+
+ * loader/MediaDocument.cpp:
+ (WebCore::MediaDocument::defaultEventHandler): play() and pause() don't take an exception.
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::NullMediaPlayerPrivate::readyState): Update for newtork state name changes.
+ (WebCore::MediaPlayer::sizeChanged): New, so engine can report intrinsic size changes.
+ (WebCore::MediaPlayer::rateChanged): New, so engine can report rate changes.
+ (WebCore::MediaPlayer::durationChanged): New, so engine can report duration changes.
+ * platform/graphics/MediaPlayer.h: Update NetworkState and ReadyState enum names to match spec
+ states.
+ (WebCore::MediaPlayerClient::mediaPlayerDurationChanged): New.
+ (WebCore::MediaPlayerClient::mediaPlayerRateChanged): New.
+ (WebCore::MediaPlayerClient::mediaPlayerSizeChanged): New.
+ (WebCore::MediaPlayer::):
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Update for network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::load): Ditto.
+ (WebCore::MediaPlayerPrivate::updateStates): Ditto.
+ (WebCore::MediaPlayerPrivate::loadingFailed): Ditto.
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h: Update for network/ready state name changes.
+ Remove endPointTimer, it is no longer necessary. Add m_enabledTrackCount and m_duration.
+ (WebCore::MediaPlayerPrivate::metaDataAvailable):
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): No more m_endPointTimer or m_endTime. Initialize
+ m_enabledTrackCount and m_duration. Update for network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::load): Update for network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::play): No more m_endPointTimer.
+ (WebCore::MediaPlayerPrivate::pause): Ditto.
+ (WebCore::MediaPlayerPrivate::currentTime): No more m_endTime.
+ (WebCore::MediaPlayerPrivate::seek): Ditto.
+ (WebCore::MediaPlayerPrivate::doSeek): Ditto, plus don't call setRate(0) when the rate is
+ already zero.
+ (WebCore::MediaPlayerPrivate::setEndTime): No more m_endTime.
+ (WebCore::MediaPlayerPrivate::updateStates): Update for network/ready state name changes. Return
+ different errors depending on what causes a failure. Watch for and report duration changes.
+ (WebCore::MediaPlayerPrivate::rateChanged): Report rate changes.
+ (WebCore::MediaPlayerPrivate::sizeChanged): Report size changes.
+ (WebCore::MediaPlayerPrivate::didEnd): No more endpoint timer.
+ (WebCore::MediaPlayerPrivate::setVisible): Update for network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::disableUnsupportedTracks): Don't return number of unsupported
+ tracks, store in m_enabledTrackCount so we can use it to help determine causes of failure.
+
+ * platform/graphics/qt/MediaPlayerPrivatePhonon.cpp:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Update for network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::load): Ditto.
+ (WebCore::MediaPlayerPrivate::duration): Ditto.
+ (WebCore::MediaPlayerPrivate::updateStates): Ditto.
+ (WebCore::MediaPlayerPrivate::naturalSize): Ditto.
+
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): No more m_endPointTimer. Update for
+ network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::load): Update for network/ready state name changes. No more
+ m_endPointTimer.
+ (WebCore::MediaPlayerPrivate::play): No more m_endPointTimer.
+ (WebCore::MediaPlayerPrivate::pause): Ditto.
+ (WebCore::MediaPlayerPrivate::setEndTime): Ditto.
+ (WebCore::MediaPlayerPrivate::updateStates): Update for network/ready state name changes.
+ (WebCore::MediaPlayerPrivate::didEnd): No more m_endPointTimer.
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h:
+
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaControlPlayButtonElement::defaultEventHandler): Update for network/ready state
+ name changes.
+ (WebCore::MediaControlSeekButtonElement::defaultEventHandler): Ditto.
+
+2009-03-22 Kevin Ollivier <kevino@theolliviers.com>
+
+ wxGTK build fix. Add missing header.
+
+ * platform/wx/wxcode/gtk/non-kerned-drawing.cpp:
+
+2009-03-22 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ https://bugs.webkit.org/show_bug.cgi?id=24665
+
+ Image-map code in RenderImage could result in RenderImage::nodeAtPoint()
+ setting HitTestResult::innerNode(), but returning false, which violates
+ hit testing rules. Use a temporary HitTestResult so that we only fill in
+ result when we know we've hit.
+
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::nodeAtPoint):
+
+2009-03-22 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ https://bugs.webkit.org/show_bug.cgi?id=24743
+
+ Fix hit testing regression from r41840. We need to pass the temporary
+ HitTestResult when testing sublayers, then only copy to 'result' when
+ the layer is known to have been hit.
+
+ Test: fast/layers/zindex-hit-test.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-20 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24733
+
+ Fix hit testing on video controls after full page zoom by fixing wider issue
+ with event->pageX(), pageY() with zooming. pageX and pageY are "fixed" to be
+ invariant under zooming (for JavaScript), so we keep an actual page point around
+ in MouseEvent::absoluteLocation() to avoid the need to factor in zooming everywhere.
+
+ * dom/MouseRelatedEvent.cpp:
+ (WebCore::MouseRelatedEvent::initCoordinates):
+ (WebCore::MouseRelatedEvent::computePageLocation):
+ * dom/MouseRelatedEvent.h:
+ (WebCore::MouseRelatedEvent::absoluteLocation):
+ (WebCore::MouseRelatedEvent::setAbsoluteLocation):
+ Member var, and getter and setter for absoluteLocation.
+ New method, computePageLocation(), to compute the actual page point,
+ and call it when creating and initting mouse-related events.
+
+ * dom/Node.cpp:
+ (WebCore::Node::dispatchMouseEvent):
+ (WebCore::Node::dispatchWheelEvent):
+ Keep non-adjusted pageX and pageY around, and call setAbsoluteLocation()
+ on the event to replace a potentially rounded point.
+
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::defaultEventHandler):
+ Clean up slider handling code.
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::listBoxDefaultEventHandler):
+ Add FIXME comment for use of offsetX/offsetY.
+
+ * page/ContextMenuController.cpp:
+ (WebCore::ContextMenuController::handleContextMenuEvent):
+ Use absoluteLocation() when hit testing for context menus.
+
+ * rendering/RenderFrameSet.cpp:
+ (WebCore::RenderFrameSet::userResize):
+ Use absoluteLocation() when resizing frames.
+
+ * rendering/RenderMedia.cpp:
+ (WebCore::RenderMedia::forwardEvent):
+ Use absoluteLocation() when hit testing media controls.
+
+ * rendering/RenderSlider.cpp:
+ (WebCore::HTMLSliderThumbElement::defaultEventHandler):
+ (WebCore::RenderSlider::mouseEventIsInThumb):
+ Use absoluteLocation() when handling slider events.
+
+ (WebCore::RenderSlider::forwardEvent):
+ Factor some code out of HTMLInputElement::defaultEventHandler().
+
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::forwardEvent):
+ Use absoluteLocation() when hit testing search field buttons, which fixees
+ bugs in the search field with zooming.
+
+2009-03-21 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24727
+ Add V8XMLHttpRequest*.
+
+ * bindings/v8/V8XMLHttpRequestUtilities.cpp: Added.
+ * bindings/v8/V8XMLHttpRequestUtilities.h: Added.
+ * bindings/v8/custom/V8XMLHttpRequestConstructor.cpp: Added.
+ * bindings/v8/custom/V8XMLHttpRequestCustom.cpp: Added.
+ * bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp: Added.
+
+2009-03-21 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24725
+ Add V8NodeFilter.
+
+ * bindings/v8/V8NodeFilter.cpp: Added.
+ * bindings/v8/V8NodeFilter.h: Added.
+
+2009-03-21 Dan Bernstein <mitz@apple.com>
+
+ Rubber-stamped by Kevin Decker
+
+ - remove some redundant #include statements
+
+ * bindings/js/JSDOMWindowBase.cpp:
+
+2009-03-20 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ - fix <rdar://problem/6574185> REGRESSION (3.2.2-TOT): hang in text drawing code
+
+ * platform/graphics/win/FontCGWin.cpp:
+ (WebCore::drawGDIGlyphs): Changed glyph stroking to fill and stroke each
+ glyph as a separate path, instead of all glyphs as a single path. This
+ matches what CGContextShowGlyphsWithAdvances() does, and has comparable
+ performance.
+
+2009-03-20 Dean Jackson <dino@apple.com>
+
+ Reviewed by Simon Fraser
+
+ Build fix for ENABLE(3D_RENDERING)
+
+ * rendering/RenderObject.h:
+ (WebCore::makeMatrixRenderable):
+
+2009-03-20 Dave Moore <davemoore@google.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24705
+
+ A bug in the V8 bindings is preventing chromium from setting the href on the
+ location object...any attempt throws a security error, not just for javascript
+ protocol
+
+ * page/Location.idl:
+
+2009-03-20 Craig Schlenter <craig.schlenter@gmail.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24608
+
+ Include stdio.h needed for printf on gcc 4.4.0
+
+ * platform/KURLGoogle.cpp:
+
+2009-03-20 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24577
+
+ Don't let comments at the end of an event handler
+ break the event handler.
+
+ No change in behavior, so no test.
+
+ * bindings/v8/V8LazyEventListener.cpp:
+ (WebCore::V8LazyEventListener::getWrappedListenerFunction):
+
+2009-03-20 Norbert Leser <norbert.leser@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24535
+
+ Fixes missing line terminator character (;) after macro call.
+ It is common practice to add the trailing ";" where macros are substituted
+ and not where they are defined with #define.
+ This change is consistent with other macro declarations across webkit,
+ and it also solves compilation failure with symbian compilers.
+
+ No change in behavior, so no test.
+
+ * bindings/js/JSDOMWindowShell.cpp:
+ * bindings/js/JSEventListener.cpp:
+ * bindings/js/JSImageConstructor.cpp:
+ * bindings/js/JSInspectedObjectWrapper.cpp:
+ * bindings/js/JSInspectorCallbackWrapper.cpp:
+ * bindings/js/JSNamedNodesCollection.cpp:
+ * bindings/js/JSNodeFilterCondition.cpp:
+ * bindings/js/JSOptionConstructor.cpp:
+ * bindings/js/JSQuarantinedObjectWrapper.cpp:
+ * bindings/js/JSRGBColor.cpp:
+ * bindings/js/JSWorkerContextBase.cpp:
+ * bindings/js/JSXMLHttpRequestConstructor.cpp:
+ * bindings/js/JSXSLTProcessorConstructor.cpp:
+ * bindings/scripts/CodeGeneratorJS.pm:
+
+2009-03-20 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Dimitri Glazkov and Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24324
+
+ Make the minimum timer configurable for different platforms.
+
+ * page/DOMTimer.cpp:
+ (WebCore::DOMTimer::DOMTimer):
+ (WebCore::DOMTimer::fired):
+ * page/DOMTimer.h:
+ (WebCore::DOMTimer::minTimerInterval):
+ (WebCore::DOMTimer::setMinTimerInterval):
+
+2009-03-20 Dean McNamee <deanm@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22834
+
+ Make sure to consistently match new/delete and fastMalloc/fastFree.
+
+ * css/CSSSelectorList.cpp:
+ (WebCore::CSSSelectorList::adoptSelectorVector):
+ (WebCore::CSSSelectorList::deleteSelectors):
+
+2009-03-20 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ - fix https://bugs.webkit.org/show_bug.cgi?id=23739
+ <rdar://problem/6556371> REGRESSION (r36513): iframe isn't sized properly upon load
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::percentHeightDescendants): Added this accessor.
+ * rendering/RenderBlock.h:
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::layoutRows): Extended the check for
+ children that flex to include other descendants with percent height
+ which is relative to the cell.
+
+2009-03-20 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24706
+ Remove ScriptExecutionContext::encoding() since Workers do not need it.
+ WorkerContext::encoding() is simply removed, while Document::encoding()
+ made non-virtual and private. Workers use UTF-8 now except when instructed
+ otherwise by http header. Also updated test.
+
+ * dom/Document.h: Made encoding() non-virtual and private.
+ * dom/ScriptExecutionContext.h: removed encoding().
+
+ * workers/Worker.cpp:
+ (WebCore::Worker::Worker):
+ (WebCore::Worker::notifyFinished):
+ * workers/WorkerContext.cpp: removed encoding() implementation.
+ (WebCore::WorkerContext::WorkerContext):
+ (WebCore::WorkerContext::completeURL):
+ * workers/WorkerContext.h: removed encoding()
+ (WebCore::WorkerContext::create):
+ * workers/WorkerContextProxy.h:
+ * workers/WorkerImportScriptsClient.cpp:
+ (WebCore::WorkerImportScriptsClient::didReceiveData):
+ * workers/WorkerMessagingProxy.cpp:
+ (WebCore::WorkerMessagingProxy::startWorkerContext):
+ * workers/WorkerMessagingProxy.h:
+ * workers/WorkerThread.cpp:
+ (WebCore::WorkerThreadStartupData::create):
+ (WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
+ (WebCore::WorkerThread::create):
+ (WebCore::WorkerThread::WorkerThread):
+ (WebCore::WorkerThread::workerThread):
+ * workers/WorkerThread.h:
+ In all these, removed storing encoding and 'inheriting' it from the parent.
+ Instead, they are all using UTF-8 now.
+
+2009-03-20 Timothy Hatcher <timothy@apple.com>
+
+ Change how threading exceptions are checked so they are reported
+ by what round they were added. That way WebKit can decided the
+ behavior per-round based on linked-on-or-after checks.
+
+ <rdar://problem/6626741&6648478&6635474&6674079>
+
+ Reviewed by Darin Adler.
+
+ * WebCore.base.exp: Export the new symbols.
+ * bindings/objc/DOMAbstractView.mm: Use the new WebCoreThreadViolationCheckRoundOne macro.
+ * bindings/scripts/CodeGeneratorObjC.pm: Ditto.
+ * platform/ThreadCheck.h:
+ * platform/mac/ThreadCheck.mm:
+ (WebCore::readThreadViolationBehaviorFromUserDefaults): Refactor how the default is read.
+ (WebCore::setDefaultThreadViolationBehavior): Take a round argument.
+ (WebCore::reportThreadViolation): Ditto.
+ (WebCoreReportThreadViolation): Ditto.
+
+2009-03-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed up an out-of-date comment.
+
+ * bindings/js/JSDOMWindowCustom.h:
+ (WebCore::JSDOMWindow::customPut):
+
+2009-03-20 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=20909 REGRESSION
+ (r35318): A press release at pfizer.com does not display correctly
+ - and corresponding -
+ <rdar://problem/6680073>
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::invalidateContainerPrefWidths):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::markContainingBlocksForLayout):
+
+2009-03-20 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Justin Garcia.
+
+ maxDeepOffset is confusing and should be removed
+ https://bugs.webkit.org/show_bug.cgi?id=24586
+
+ Abstract some hard-to-read (but shared) logic into a new renderedAsNonInlineTableOrHR function.
+ Add first/lastDeepEditingPositionForNode Position creation functions
+ and deploy them to places we used to call maxDeepOffset.
+
+ Rename Position::atStart and atEnd to atStartOfTree atEndOfTree
+ Add a new Position::atFirst/atLastEditingPositionForNode() and use these
+ to replace a few more callers for maxDeepOffset()
+
+ Rename maxDeepOffset to lastEditingOffsetForNode (so that we mere mortals have some clue what it does)
+
+ "Editing positions" are confusing because they have one
+ of two behaviors, depending on if the container node is ignored
+ by editing (if editingIgnoresContent(node) returns true) or not.
+ Positions referring to nodes ignored by editing are
+ neighbor-relative (they are before or after the node) where as
+ positions reffering to other nodes are container-relative
+ (they are between two child nodes of the container, identified
+ by the offset() member). I will be fixing this confusion in
+ future patches. These renames hopefully make the current behavior clearer.
+
+ * dom/Position.cpp:
+ (WebCore::Position::previous):
+ (WebCore::Position::next):
+ (WebCore::Position::atFirstEditingPositionForNode):
+ (WebCore::Position::atLastEditingPositionForNode):
+ (WebCore::Position::atStartOfTree):
+ (WebCore::Position::atEndOfTree):
+ (WebCore::Position::previousCharacterPosition):
+ (WebCore::Position::nextCharacterPosition):
+ (WebCore::Position::upstream):
+ (WebCore::Position::isCandidate):
+ (WebCore::firstDeepEditingPositionForNode):
+ (WebCore::lastDeepEditingPositionForNode):
+ * dom/Position.h:
+ * dom/PositionIterator.cpp:
+ (WebCore::PositionIterator::operator Position):
+ (WebCore::PositionIterator::increment):
+ (WebCore::PositionIterator::decrement):
+ (WebCore::PositionIterator::atEnd):
+ (WebCore::PositionIterator::atEndOfNode):
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::positionAvoidingSpecialElementBoundary):
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::isTableCellEmpty):
+ (WebCore::DeleteSelectionCommand::removeNode):
+ (WebCore::DeleteSelectionCommand::handleGeneralDelete):
+ * editing/Editor.cpp:
+ (WebCore::Editor::advanceToNextMisspelling):
+ * editing/InsertLineBreakCommand.cpp:
+ (WebCore::InsertLineBreakCommand::doApply):
+ * editing/InsertListCommand.cpp:
+ (WebCore::InsertListCommand::doApply):
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::positionAtEndOfInsertedContent):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::previous):
+ (WebCore::VisiblePosition::leftVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::left):
+ (WebCore::VisiblePosition::rightVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::right):
+ * editing/VisibleSelection.cpp:
+ (WebCore::VisibleSelection::selectionFromContentsOfNode):
+ (WebCore::VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries):
+ * editing/htmlediting.cpp:
+ (WebCore::nextVisuallyDistinctCandidate):
+ (WebCore::previousVisuallyDistinctCandidate):
+ (WebCore::firstEditablePositionAfterPositionInRoot):
+ (WebCore::lastEditablePositionBeforePositionInRoot):
+ (WebCore::lastOffsetForEditing):
+ (WebCore::isFirstPositionAfterTable):
+ (WebCore::isLastPositionBeforeTable):
+ (WebCore::positionBeforeNode):
+ (WebCore::positionAfterNode):
+ (WebCore::enclosingEmptyListItem):
+ (WebCore::caretMaxOffset):
+ * editing/htmlediting.h:
+ * editing/visible_units.cpp:
+ (WebCore::renderedAsNonInlineTableOrHR):
+ (WebCore::startOfParagraph):
+ (WebCore::endOfParagraph):
+ (WebCore::startOfEditableContent):
+ (WebCore::endOfEditableContent):
+ * page/AccessibilityObject.cpp:
+ (WebCore::endOfStyleRange):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::visiblePositionRange):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::positionForPoint):
+
+2009-03-20 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24689
+ Add (upstream) V8 bindings for Workers. Mostly style cleaning.
+
+ * bindings/v8/WorkerContextExecutionProxy.cpp: Added.
+ * bindings/v8/WorkerContextExecutionProxy.h: Added.
+ * bindings/v8/WorkerScriptController.cpp: Added.
+ * bindings/v8/WorkerScriptController.h: Added.
+ * bindings/v8/V8Index.h: Added. This is just a wrapper for v8_index.h, like V8Proxy.h
+ * bindings/v8/V8Proxy.h: Added domObjectMap() function that wraps GetDOMObjectMap().
+ * bindings/v8/V8WorkerContextEventListener.cpp:
+ (WebCore::V8WorkerContextEventListener::callListenerFunction): TrackEvent() renamed trackEvent()
+
+2009-03-20 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Fix for LayoutTests/fast/canvas/canvas-text-alignment.html
+ on chromium/skia. The problem was that the gradient matrix
+ for text was being applied twice. Fixed by reverting some of
+ https://bugs.webkit.org/show_bug.cgi?id=23957, so that skiaDrawText
+ is no longer responsible for measuring the text and scaling up
+ the gradient matrix. Instead, the text bounding box is passed
+ in from SVGPaintServerGradient. I didn't make this change for CG,
+ since it uses a different method (the gradient is drawn using the
+ text as a pre-rendered mask).
+ https://bugs.webkit.org/show_bug.cgi?id=24687
+
+ * platform/graphics/skia/SkiaFontWin.cpp:
+ (WebCore::skiaDrawText):
+ * svg/graphics/SVGPaintServerGradient.cpp:
+ (WebCore::SVGPaintServerGradient::setup):
+
+2009-03-20 Xan Lopez <xlopez@igalia.com>
+
+ Rubber-stamped by Holger Freyther.
+
+ There seems to be some rounding error in cairo (or in how we use
+ cairo) with some fonts, like DejaVu Sans Mono, which makes cairo
+ report a height smaller than ascent + descent, which is wrong and
+ confuses WebCore's layout system. Workaround this while we figure
+ out what's going on.
+
+ * platform/graphics/gtk/SimpleFontDataGtk.cpp:
+ (WebCore::SimpleFontData::platformInit):
+ * platform/graphics/gtk/SimpleFontDataPango.cpp:
+ (WebCore::SimpleFontData::platformInit):
+
+2009-03-19 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24122
+ <rdar://problem/6674179>
+ REGRESSION: DOM Range extractContents/deleteContents failures seen on Moxiecode tests
+
+ Test: fast/dom/Range/deleted-range-endpoints.html
+
+ * dom/Range.cpp: (WebCore::Range::processContents): Set the final range in accordance
+ to the specification.
+
+2009-03-19 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ <rdar://problem/6682554> Flash content not being rendered (Shockwave Flash 10.0 r22)
+
+ If calling updateWidget for some reason resulted in another widget being added to m_widgetUpdateSet, then
+ that object would never be updated.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateWidgets):
+ Factor the widget updating code out into this method. Return true if the update set is empty.
+
+ (WebCore::FrameView::performPostLayoutTasks):
+ Loop over the update set multiple times until all widgets have been updated or until we reach the cap.
+
+ * page/FrameView.h:
+
+2009-03-18 Timothy Hatcher <timothy@apple.com>
+
+ Make the defered data loading timer honor the Page's scheduled runloop pairs.
+ Introduces a new RunLoopTimer class that has an API mimicking Timer but
+ allows it to be scheduled with one or more SchedulePairs.
+
+ <rdar://problem/6687342> -[WebView scheduleInRunLoop:forMode:] has no affect on timers
+
+ Reviewed by Darin Adler.
+
+ * WebCore.xcodeproj/project.pbxproj: Adds the new RunLoopTimer.{cpp,h} files.
+ * loader/MainResourceLoader.cpp:
+ (WebCore::MainResourceLoader::handleDataLoadNow): Use the MainResourceLoaderTimer typedef.
+ (WebCore::MainResourceLoader::startDataLoadTimer): Added. Start the timer and on
+ Mac platforms also schedule with the Page's SchedulePairs.
+ (WebCore::MainResourceLoader::handleDataLoadSoon): Call startDataLoadTimer().
+ (WebCore::MainResourceLoader::setDefersLoading): Ditto.
+ * loader/MainResourceLoader.h:
+ * platform/cf/RunLoopTimerCF.cpp: Added.
+ (WebCore::RunLoopTimerBase::~RunLoopTimerBase):
+ (WebCore::timerFired):
+ (WebCore::RunLoopTimerBase::start):
+ (WebCore::RunLoopTimerBase::schedule):
+ (WebCore::RunLoopTimerBase::stop):
+ (WebCore::RunLoopTimerBase::isActive):
+ * platform/RunLoopTimer.h: Added.
+ (WebCore::RunLoopTimerBase::RunLoopTimerBase):
+ (WebCore::RunLoopTimerBase::startRepeating):
+ (WebCore::RunLoopTimerBase::startOneShot):
+ (WebCore::RunLoopTimer::RunLoopTimer):
+ (WebCore::RunLoopTimer::fired):
+
+2009-03-19 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24702
+ Upstream miscellaneous bindings changes.
+
+ * bindings/v8/ScheduledAction.cpp:
+ (WebCore::ScheduledAction::execute): Changed to call lower-case evaluate.
+ * bindings/v8/ScriptCallStack.h: Added an extra include.
+
+2009-03-19 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24686
+
+ When hit testing a RenderLayer whose parent lives in a preserves-3D hierarchy,
+ we need to compare the computed z-offset with the depth-test z-offset before
+ deciding that such a RenderLayer was hit. This fixes an issue, tested by the
+ 3d-point-mapping-overlapping.html test, where the child of a transformed element
+ is found by hit testing, even when some other element with greater Z overlaps
+ them both.
+
+ Improved the code by adding a utility method, isHitCandidate(), which computes and tests
+ z-depth when necessary.
+
+ Tests: transforms/3d/point-mapping/3d-point-mapping-coplanar.html
+ transforms/3d/point-mapping/3d-point-mapping-overlapping.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::isHitCandidate):
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-19 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24456
+ Split ColorChromium.cpp into Mac & Windows variants.
+ Remove Chromium Dependency on platform/graphics/mac/ColorMac.mm since we
+ ultimately need to take a different approach. For now, createCGColor()
+ is copied from ColorMac.mm.
+
+ No observable change in behavior, so no test.
+
+ * platform/graphics/chromium/ColorChromium.cpp:
+ (WebCore::focusRingColor):
+ * platform/graphics/chromium/ColorChromiumMac.mm: Added.
+
+2009-03-19 Pavel Feldman <pfeldman@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24675
+ Unforking frontend: add custom InspectorController methods
+ implementation.
+
+ * bindings/v8/custom/V8InspectorControllerCustom.cpp: Added.
+
+2009-03-19 Jay Campan <jcampan@google.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24625
+ Adding an accessor to the currently selected index in the PopupMenuChromium.
+ This is required for implementing the deletion of an autocomplete entry in Chromium.
+
+ * platform/chromium/PopupMenuChromium.cpp:
+ (WebCore::PopupContainer::selectedIndex):
+ * platform/chromium/PopupMenuChromium.h:
+
+2009-03-19 Evan Stade <estade@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24526
+ Improve windows skia text stroking.
+
+ Test: LayoutTests/svg/custom/struct-use-09-b.svg
+
+ * platform/graphics/skia/SkiaFontWin.cpp: Close the path representing
+ each font glyph polygon, rather than only closing the path once per
+ letter. This fixes stroking for letters with multiple polygons, such
+ as 'A' or 'D'.
+ (WebCore::getPathForGlyph):
+ (WebCore::skiaDrawText):
+
+2009-03-19 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Fixed support for doing calls from JavaScript into NPAPI Plugins for the Qt port on Windows.
+
+ Removed dead code for distinguishing between Widget and PluginView in the Qt port.
+
+ * bindings/js/ScriptControllerQt.cpp:
+ (WebCore::ScriptController::createScriptInstanceForWidget): Removed incorrect isNPAPI check.
+ * plugins/PluginView.cpp:
+ (WebCore::PluginView::PluginView): Removed m_isNPAPIPlugin variable.
+ * plugins/PluginView.h: Removed setter/getter.
+ * plugins/mac/PluginViewMac.cpp:
+ (WebCore::PluginView::init): Removed call to setIsNPAPIPlugin.
+ * plugins/qt/PluginViewQt.cpp:
+ (WebCore::PluginView::init): Ditto.
+
+2009-03-19 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 24596: ASSERT in JSC::PropertySlot::slotBase @ iGoogle homepage
+ <https://bugs.webkit.org/show_bug.cgi?id=24596>
+ <rdar://problem/6686493>
+
+ JSDOMWindow::customGetOwnPropertySlot() does an access check after calling
+ JSGlobalObject::getOwnPropertySlot(). This causes the PropertySlot to be
+ set twice, once to the value that is illegal to access, and then to undefined
+ This causes an assertion failure in property access caching code.
+
+ The fix is to do the access check before calling JSGlobalObject::getOwnPropertySlot().
+
+ * bindings/js/JSDOMWindowCustom.h:
+ (WebCore::JSDOMWindow::customGetOwnPropertySlot):
+
+2009-03-18 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24676
+ Simple cross-origin requests shouldn't dispatch upload progress events
+
+ Test: http/tests/xmlhttprequest/simple-cross-origin-progress-events.html
+
+ * loader/CrossOriginAccessControl.cpp: (WebCore::passesAccessControlCheck): Added a comment
+ explaining the somewhat unexpected behavior of this function.
+
+ * xml/XMLHttpRequestUpload.cpp: (WebCore::XMLHttpRequestUpload::hasListeners):
+ * xml/XMLHttpRequestUpload.h:
+ Report whether there are any event listeners registered.
+
+ * xml/XMLHttpRequest.h: Added m_uploadEventsAllowed.
+
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::createRequest): Set m_uploadEventsAllowed flag.
+ (WebCore::XMLHttpRequest::makeSameOriginRequest): Ditto.
+ (WebCore::XMLHttpRequest::makeCrossOriginAccessRequest): Ditto.
+ (WebCore::XMLHttpRequest::makeSimpleCrossOriginAccessRequest): Set request body - it can be
+ non-empty for POST requests.
+ (WebCore::XMLHttpRequest::makeCrossOriginAccessRequestWithPreflight): Set m_uploadEventsAllowed flag.
+ (WebCore::XMLHttpRequest::handleAsynchronousPreflightResult): Ditto.
+ (WebCore::XMLHttpRequest::abort): Only dispatch upload progress events if allowed.
+ (WebCore::XMLHttpRequest::networkError): Ditto.
+ (WebCore::XMLHttpRequest::abortError): Ditto.
+ (WebCore::XMLHttpRequest::didSendData): Ditto.
+
+2009-03-18 Marc-Antoine Ruel <maruel@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24398
+ Fix a crash when loading a svg file in Chromium's test_shell and
+ then reloading the page.
+
+ * history/BackForwardListChromium.cpp:
+ (WebCore::BackForwardList::BackForwardList):
+ (WebCore::BackForwardList::close):
+
+2009-03-18 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Fix for <rdar://problem/6685235>
+ <video> element poster cannot be set dynamically if not originally set up in HTML
+
+ Allocate the media engine immediately so the plug-in proxy is available for
+ scripting right away.
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::MediaPlayer):
+
+2009-03-18 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Fix for <rdar://problem/6636747> REGRESSION (Safari 4 PB-r41326):
+ Popup menu appears at the wrong location on page at http://
+ www.signonsandiego.com/
+
+ This was a regression from http://trac.webkit.org/changeset/40769,
+ which changed the base class of RenderInline to
+ RenderBoxModelObject rather than RenderBox.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::offsetParent): offsetParent should return a
+ RenderBoxModelObject rather than just a RenderBox, which is more
+ restrictive.
+
+2009-03-18 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6504776>
+ CrashTracer: [USER] 188 crashes in Safari at com.apple.WebCore • WTF::HashTableIterator<WTF::RefPtr<WebCore::ResourceLoader>, ...
+
+ Return early in case calling the client ends up spinning the run loop and completing/cancelling the load.
+
+ * loader/NetscapePlugInStreamLoader.cpp:
+ (WebCore::NetscapePlugInStreamLoader::didCancel):
+
+2009-03-18 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24664
+ Upstreaming v8 collection.h
+
+ No change in behavior, so no test.
+
+ * bindings/v8/V8Collection.h: Added.
+
+2009-03-18 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23966
+ REGRESSION: Custom arrow navigation functionality doesn't work at dropular.net
+ <rdar://problem/6589657>
+
+ Match the CSSOM spec for getClientRects and getBoundingClientRect by
+ returning a 0x0 rect at the correct top/left position for empty inline
+ boxes.
+
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::absoluteRects):
+ (WebCore::RenderInline::absoluteQuads):
+
+2009-03-18 David Levin <levin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Match the changes done for windows in the bug
+ https://bugs.webkit.org/show_bug.cgi?id=24530.
+
+ No change in behavior, so no test.
+
+ * rendering/RenderThemeChromiumLinux.cpp:
+ (WebCore::RenderThemeChromiumLinux::extraDefaultStyleSheet):
+
+2009-03-18 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ Added support for SVG's stroked texts to Qt.
+
+ [Qt] SVGs stroked text support missing
+ https://bugs.webkit.org/show_bug.cgi?id=24262
+
+ * platform/graphics/qt/FontQt.cpp:
+ (WebCore::Font::drawComplexText):
+
+2009-03-18 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fix fast/encoding/char-decoding.html with recent ICU.
+
+ * platform/text/TextCodecICU.cpp:
+ (WebCore::TextCodecICU::decode): Look for gb18030 case-insensitively,
+ as newer versions of ICU use GB18030 as the canonical name.
+
+2009-03-17 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24662
+ Chromium build fixes.
+
+ Bug https://bugs.webkit.org/show_bug.cgi?id=24663 tracks
+ the invalid implementation of ScriptCallStack.
+
+ No change in behavior, so no test.
+
+ * bindings/v8/ScriptCallStack.h:
+ (WebCore::ScriptCallStack::state):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::drawRect):
+
+2009-03-17 David Carson <dacarson@apple.com>
+
+ Reviewed by David Hyatt.
+
+ Add anchor elements to the simple style sheet so that applications that
+ are using WebKit just for simple text and links will also take advantage
+ of the fast path.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::elementCanUseSimpleDefaultStyle):
+
+2009-03-17 Darin Adler <darin@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ <rdar://problem/6687005> Need support for new move-left/right selectors.
+
+ * editing/EditorCommand.cpp:
+ (WebCore::executeMoveToLeftEndOfLine): Added.
+ (WebCore::executeMoveToLeftEndOfLineAndModifySelection): Added.
+ (WebCore::executeMoveToRightEndOfLine): Added.
+ (WebCore::executeMoveToRightEndOfLineAndModifySelection): Added.
+ Added command entries for the functions above.
+
+2009-03-17 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Adele Peterson.
+
+ Put the padding inside scrollbars on textareas.
+ https://bugs.webkit.org/show_bug.cgi?id=24370
+
+ Put the padding inside the scrollbars on textareas. This is done by moving the
+ overflow from the shadowNode to the RenderTextControlMultiline. As a result,
+ all of the scroll handing methods that RenderTextControl overrides can be moved
+ down into RenderTextControlSingleLine since RenderTextControlMultiline can now
+ just use RenderBlock's versions. This also allows RenderTextControlMultiLine to
+ no longer need a custom layout method since the shadowNode can now just size
+ like a regular DIV.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::adjustRenderStyle):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::styleDidChange):
+ (WebCore::RenderTextControl::selection):
+ (WebCore::RenderTextControl::calcHeight):
+ (WebCore::RenderTextControl::hitInnerTextElement):
+ * rendering/RenderTextControl.h:
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::nodeAtPoint):
+ (WebCore::RenderTextControlMultiLine::createInnerTextStyle):
+ * rendering/RenderTextControlMultiLine.h:
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::styleDidChange):
+ (WebCore::RenderTextControlSingleLine::autoscroll):
+ (WebCore::RenderTextControlSingleLine::scrollWidth):
+ (WebCore::RenderTextControlSingleLine::scrollHeight):
+ (WebCore::RenderTextControlSingleLine::scrollLeft):
+ (WebCore::RenderTextControlSingleLine::scrollTop):
+ (WebCore::RenderTextControlSingleLine::setScrollLeft):
+ (WebCore::RenderTextControlSingleLine::setScrollTop):
+ (WebCore::RenderTextControlSingleLine::scroll):
+ * rendering/RenderTextControlSingleLine.h:
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::RenderTextControlInnerBlock::RenderTextControlInnerBlock):
+ (WebCore::RenderTextControlInnerBlock::positionForPoint):
+ (WebCore::TextControlInnerTextElement::createRenderer):
+
+2009-03-17 Darin Adler <darin@apple.com>
+
+ Reviewed by David Hyatt.
+
+ Bug 24517: REGRESSION (r41552): innerHTML does an updateLayout -- unneeded and can be slow
+ https://bugs.webkit.org/show_bug.cgi?id=24517
+
+ * editing/DeleteButtonController.cpp:
+ (WebCore::DeleteButtonController::enable): Added a call to updateRendering, since
+ determining whether to display the delete button involves style and updateRendering
+ also updates style (should probably be named updateStyle, in fact). Not needed to fix
+ this bug, but would have prevented the crash that led to this bug in the first place.
+
+ * editing/EditCommand.cpp:
+ (WebCore::EditCommand::EditCommand): Get rid of unneeded null check. All frames have
+ delete button controllers.
+ * editing/Editor.cpp:
+ (WebCore::Editor::rangeForPoint): Ditto.
+
+ * editing/markup.cpp:
+ (WebCore::appendStartMarkup): Changed a "&" to a "&&" so that generating markup
+ doesn't depend on renderers at all when the convertBlocksToInlines boolean is false.
+ This allows us to omit the call to updateLayoutIgnorePendingStylesheets in the
+ createMarkup function that's called by innerHTML.
+ (WebCore::MarkupAccumulator::appendMarkup): Turned this into a class with a member
+ function. Added a feature where the accumulator will skip a node. Moved arguments
+ that don't change during recursion into an object. This function still is a bit
+ inefficient, since it creates a new HashMap at every level as it recurses, but for now
+ I did not tackle that. Also replaced the onlyIncludeChildren boolean with EChildrenOnly
+ for consistency and clarity.
+ (WebCore::createMarkup): Removed the call to updateLayoutIgnorePendingStylesheets.
+ Instead of calling disable/enable on the delete button controller's container element,
+ pass it in to the markup accumulator as a node to skip.
+
+2009-03-17 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24651
+ Skia does not always render text fill/stroke pattern/gradient/color correctly
+
+ Changes Skia's font rendering to only render gradient/pattern if current
+ color space indicates the gradient/pattern should be used.
+ This is covered by LayoutTests/fast/canvas/canvas-text-alignment.html .
+
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::strokeColorSpace):
+ (WebCore::GraphicsContext::fillColorSpace):
+ * platform/graphics/GraphicsContext.h:
+ (WebCore::):
+ * platform/graphics/GraphicsContextPrivate.h:
+ * platform/graphics/skia/SkiaFontWin.cpp:
+ (WebCore::paintSkiaText):
+
+2009-03-17 Adele Peterson <adele@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=24655
+ <rdar://problem/6633727> Hitting return at the end of a line with an anchor jumps me to the bottom of the message
+
+ Test: editing/inserting/6633727.html
+
+ This changes does a few things:
+ 1) Renames pos to insertionPosition.
+ 2) Eliminates "startNode". It doesn't work well to consider the node separately from the insertionPosition.
+ The insertionPosition gets updated at various times, and it seems likely that startNode can get out of sync.
+ 3) Before building up a list of ancestors to move around when we insert the new block, make sure to use the deepest
+ representation of the insertionPosition, so all ancestor nodes are correctly included.
+
+ * editing/InsertParagraphSeparatorCommand.cpp: (WebCore::InsertParagraphSeparatorCommand::doApply):
+
+2009-03-17 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kevin Ollivier.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24115
+ Introduce platform independent stubs for plugins.
+
+ * plugins/PluginDataNone.cpp: Copied from WebCore/plugins/wx/PluginDataWx.cpp.
+ * plugins/PluginPackageNone.cpp: Copied from WebCore/plugins/wx/PluginPackageWx.cpp.
+ * plugins/PluginViewNone.cpp: Copied from WebCore/plugins/wx/PluginViewWx.cpp.
+ * plugins/wx/PluginDataWx.cpp: Removed.
+ * plugins/wx/PluginPackageWx.cpp: Removed.
+ * plugins/wx/PluginViewWx.cpp: Removed.
+ * webcore-wx.bkl:
+
+2009-03-17 Darin Adler <darin@apple.com>
+
+ Earlier version reviewed by Adele Peterson.
+
+ Bug 24304: REGRESSION (r39864): Hitting the space bar to select an <input type=radio>
+ or push an <input type=button> or <button> causes the page to scroll down.
+
+ Would be best to add a regression test for Windows eventually; tested that this has
+ no effect on the Mac OS X platform.
+
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::defaultEventHandler): Added FIXMEs and tweaked formatting.
+ Use the code that calls the base class's defaultEventHandler early only in the cases
+ where it's needed: keydown and keypress events in text fields. In other cases, do the
+ more typical thing and call the default handler only at the end of the function.
+ This function already had code to make sure the keypress event for space never gets
+ through, but it was running too late since the scrolling code was moved into the
+ base class default event handler.
+
+2009-03-17 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24632
+
+ Fix repaint issues when composited layers come and go (only applies
+ when ACCELERATED_COMPOSITING is turned on).
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::mustOverlayCompositedLayers):
+ (WebCore::RenderLayer::setMustOverlayCompositedLayers):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::RenderLayerBacking):
+ * rendering/RenderLayerBacking.h:
+
+ Move what used to be the 'forceCompositingLayer' flag from RenderLayerBacking
+ to RenderLayer, because we don't want the side-effects of creating RenderLayerBacking
+ when setting this flag.
+
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateLayerCompositingState):
+ When a RenderLayer flips into or out of compositing mode, compute a repaint
+ rect relative to the containerForRepaint, and repaint it.
+
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+ Call layer->setMustOverlayCompositedLayers() rather than setForcedCompositingLayer().
+
+ (WebCore::RenderLayerCompositor::needsToBeComposited):
+ (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+ (WebCore::RenderLayerCompositor::requiresCompositingForTransform):
+ (WebCore::RenderLayerCompositor::requiresCompositingForAnimation):
+ * rendering/RenderLayerCompositor.h:
+
+ Rename requiresCompositingLayerForTransform() to requiresCompositingForTransform()
+ and make it a class static method to match requiresCompositingForAnimation(). Both
+ now take RenderObjects, rathern than RenderLayers.
+
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::hasTransformRelatedProperty):
+ Minor tidyup using convenience methods added in an earlier commit.
+
+2009-03-17 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24396
+
+ * config.h:
+ Add WTF_USE_ACCELERATED_COMPOSITING, defined to 0 for now, and add some
+ comments to make the #ifdefs more readable.
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::computedTransform):
+ Add a comment to mention that we don't flatten the matrix.
+
+ * css/MediaQueryEvaluator.cpp:
+ (WebCore::transform_3dMediaFeatureEval):
+ Have the 'transform-3d' media query evaluate to 'true' if 3d-rendering
+ is supported.
+
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::GraphicsLayerCA::animateTransform):
+ No need for the #ifdef here. If we don't support 3d, we will have already flattened
+ the matrix.
+
+ * platform/graphics/transforms/TransformationMatrix.cpp:
+ (WebCore::TransformationMatrix::makeAffine):
+ * platform/graphics/transforms/TransformationMatrix.h:
+ New method to convert the matrix to an affine matrix by throwing a way the non-affine
+ parts.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateTransform):
+ (WebCore::RenderLayer::currentTransform):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateLayerTransform):
+ If 3d rendering is not supported, convert the matrix to an affine matrix
+ which can be rendered, and used for hit testing.
+
+ * rendering/RenderLayerCompositor.cpp:
+ Change the name of the exported symbol that webkitdirs.pm uses to know if
+ 3d rendering is supported. There is no other 3d-rendering-specific symbol we can sniff.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::transformFromContainer):
+ Only take perspective into account if 3d rendering is supported.
+
+ * rendering/RenderObject.h:
+ (WebCore::makeMatrixRenderable):
+ Utility method that flattens a matrix if 3d rendering is not supported.
+
+2009-03-17 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix. Fix typo after mouse wheel changes.
+
+ * platform/wx/MouseWheelEventWx.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+
+2009-03-17 Darin Adler <darin@apple.com>
+
+ * inspector/ConsoleMessage.cpp:
+ (WebCore::ConsoleMessage::isEqual): Fix build, remove stray parenthesis.
+
+2009-03-17 Darin Adler <darin@apple.com>
+
+ Fix crash seen right away when running run-webkit-tests.
+
+ * inspector/ConsoleMessage.cpp:
+ (WebCore::ConsoleMessage::isEqual): Restore assertion to its behavior pre-refactoring.
+ Also tweaked formatting a bit.
+
+2009-03-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ HTMLSelectElement::add() doesn't look at exception code returned from insertBefore(), so
+ it doesn't need to zero it out before calling.
+
+ * html/HTMLSelectElement.cpp: (WebCore::HTMLSelectElement::add): Removed "ec = 0" line.
+
+2009-03-17 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Adam Roben.
+
+ - WebCore part of adding a mechanism for controlling the caching of
+ responses through WebFrameLoaderClient
+
+ Mac already has such a mechanism, and this adds one for CFNetwork ports.
+
+ * WebCore.vcproj/WebCore.vcproj: Added EmptyClients.h
+ and ResourceLoaderCFNet.cpp.
+
+ * loader/EmptyClients.h:
+ (WebCore::EmptyFrameLoaderClient::shouldCacheResponse): Added an
+ implementation that always returns true.
+
+ * loader/FrameLoaderClient.h: Declared shouldCacheResponse().
+
+ * loader/ResourceLoader.h: Ditto.
+
+ * loader/cf/ResourceLoaderCFNet.cpp: Added.
+ (WebCore::ResourceLoader::shouldCacheResponse): Added. Calls through to
+ FrameLoaderClient::shouldCacheResponse().
+
+ * platform/network/ResourceHandleClient.h:
+ (WebCore::ResourceHandleClient::shouldCacheResponse): Added an
+ implementation that always returns true.
+
+ * platform/network/cf/ResourceHandleCFNet.cpp:
+ (WebCore::willCacheResponse): Added a call to
+ ResourceHandleClient::shouldCacheResponse(). If the client returns
+ false, return 0, which will prevent CFNetwork from caching the response.
+
+2009-03-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=13287
+ Cannot change SELECT to a dynamically created option
+
+ Tests: fast/forms/add-and-remove-option.html
+ fast/forms/add-remove-option-modification-event.html
+ fast/forms/add-selected-option.html
+ fast/forms/select-cache-desynchronization.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::dispatchChildInsertionEvents): Increment DOM tree version. This will happen when
+ dispatching DOMSubtreeModified again, but the version should be incremented for event
+ listeners to have an up to date view of the DOM.
+ (WebCore::dispatchChildRemovalEvents): Ditto.
+
+ * html/HTMLOptionElement.cpp: (WebCore::HTMLOptionElement::insertedIntoTree):
+ Make sure that the select element knows about its new selected option.
+
+ * html/HTMLOptionElement.h: Use insertedIntoTree() instead of insertedIntoDocument(),
+ because DOM also needs to be updated for forms that are not in document yet. Similar
+ problems exist for node removing, but removedFromTree() is called at a wrong time, so
+ those problems cannot be fixed without deeper refactoring.
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::setRecalcListItems): Reset m_activeSelectionAnchorIndex - it
+ doesn't make sense to keep the anchor after programmatically changing the selection, and
+ keeping it was causing a failure in fast/forms/listbox-selection.html.
+
+ * html/HTMLSelectElement.h: Removed overrides for ContainerNode methods that only called
+ base class versions.
+
+2009-03-17 Steve Falkenburg <sfalken@apple.com>
+
+ <rdar://problem/6690324> Accessing FTP sites reads unallocated memory, can result in garbled entries or crashes
+
+ Reviewed by Darin Adler.
+
+ * loader/FTPDirectoryDocument.cpp:
+ (WebCore::FTPDirectoryTokenizer::parseAndAppendOneLine): Assign CString to a local while we hold pointers into it.
+
+2009-03-16 David Hyatt <hyatt@apple.com>
+
+ <rdar://problem/6648411> REGRESSION: Layout of page is wrong at http://www.popcap.com/
+
+ Make sure that the initial shouldPaint check that looks at enclosingLayers properly skips over
+ layers that don't paint themselves. This is done by adding a new enclosingSelfPaintingLayer method
+ so that RenderObjects can walk up the enclosing layer chain and skip any layers that don't paint
+ themselves.
+
+ Reviewed by Darin Adler.
+
+ Added fast/block/float/overlapping-floats-with-overflow-hidden.html
+
+ * WebCore.base.exp:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::addOverhangingFloats):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::enclosingSelfPaintingLayer):
+ * rendering/RenderObject.h:
+
+2009-03-17 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24592
+ [GTK] Crash in FcPatternHash
+
+ Style fixes.
+
+ * platform/graphics/gtk/FontPlatformDataGtk.cpp:
+ (WebCore::FontPlatformData::operator=):
+ * platform/graphics/gtk/FontPlatformDataPango.cpp:
+
+2009-03-17 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24592
+ [GTK] Crash in FcPatternHash
+
+ Sanitize memory management in pango fonts.
+
+ Release memory allocated by FontPlatformDataPango in its own
+ destructor instead of doing it from other classes, and add copy
+ constructor and '=' operator to be able to track referenced
+ objects properly.
+
+ * platform/graphics/gtk/FontPlatformDataPango.cpp:
+ (WebCore::FontPlatformData::~FontPlatformData):
+ (WebCore::FontPlatformData::operator=):
+ (WebCore::FontPlatformData::FontPlatformData):
+ * platform/graphics/gtk/SimpleFontDataPango.cpp:
+
+2009-03-17 Darin Adler <darin@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24624: Crash in imageLoadEventTimerFired after adoptNode used on <img>,
+ seen with inspector, which uses adoptNode
+ https://bugs.webkit.org/show_bug.cgi?id=24624
+ rdar://problem/6422850
+
+ Test: fast/dom/HTMLImageElement/image-load-cross-document.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document): Removed m_imageLoadEventTimer.
+ (WebCore::Document::detach): Removed m_imageLoadEventDispatchSoonList and
+ m_imageLoadEventDispatchingList.
+ (WebCore::Document::implicitClose): Called ImageLoader::dispatchPendingLoadEvents
+ instead of dispatchImageLoadEventsNow.
+
+ * dom/Document.h: Removed ImageLoader, dispatchImageLoadEventSoon,
+ dispatchImageLoadEventsNow, removeImage, m_imageLoadEventDispatchSoonList,
+ m_imageLoadEventDispatchingList, m_imageLoadEventTimer, and imageLoadEventTimerFired.
+
+ * loader/ImageLoader.cpp:
+ (WebCore::loadEventSender): Added. Returns the single global ImageLoadEventSender
+ object used privately as the target of the load event timer.
+ (WebCore::ImageLoader::~ImageLoader): Call ImageLoadEventSender::cancelLoadEvent
+ rather than Document::removeImage.
+ (WebCore::ImageLoader::setImage): Use m_element directly, not element().
+ (WebCore::ImageLoader::updateFromElement): Ditto. Also name the local variable
+ document instead of doc.
+ (WebCore::ImageLoader::notifyFinished): Call ImageLoadEventSender::dispatchLoadEventSoon
+ rather than Document::dispatchImageLoadEventSoon.
+ (WebCore::ImageLoader::dispatchPendingLoadEvent): Added. Handles the common logic
+ about when load events can be dispatched so that dispatchLoadEvent only has to
+ have the specific part for each derived class. This includes a check that the
+ document is attached, which used to be handled by having documents empty out the
+ image load event vectors in the detach function.
+ (WebCore::ImageLoader::dispatchPendingLoadEvents): Added. Calls the appropriate
+ function on the ImageLoadEventSender, which avoids the need to have that class be
+ public in the ImageLoader header.
+ (WebCore::ImageLoadEventSender::ImageLoadEventSender): Added. Has the code that
+ was previously in the Document constructor.
+ (WebCore::ImageLoadEventSender::dispatchLoadEventSoon): Added. Has the code that
+ was previously in Document::dispatchImageLoadEventSoon.
+ (WebCore::ImageLoadEventSender::cancelLoadEvent): Added. Has the code that was
+ previously in Document::removeImage.
+ (WebCore::ImageLoadEventSender::dispatchPendingLoadEvents): Added. Has the code
+ that was previously in Document::dispatchImageLoadEventsNow.
+ (WebCore::ImageLoadEventSender::timerFired): Added. Calls dispatchPendingLoadEvents.
+
+ * loader/ImageLoader.h: Improved comments. Made the virtual functions private
+ or protected rather than public. Added static dispatchPendingLoadEvents function
+ for use by Document and private dispatchPendingLoadEvent function for use by
+ ImageLoadEventSender. Made setLoadingImage private and eliminated
+ setHaveFiredLoadEvent since that can all be done inside the class without any
+ member functions.
+
+ * html/HTMLImageLoader.cpp:
+ (WebCore::HTMLImageLoader::dispatchLoadEvent): Removed logic to check whether a
+ load event already fired and whether image() is 0. These are now both base class
+ responsibilities.
+ * svg/SVGImageLoader.cpp:
+ (WebCore::SVGImageLoader::dispatchLoadEvent): Ditto.
+ * wml/WMLImageLoader.cpp:
+ (WebCore::WMLImageLoader::dispatchLoadEvent): Ditto.
+
+2009-03-17 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24623
+ Refactor ConsoleMessage to use ScriptFuncitonCall and eliminate JSC
+ dependencies.
+
+ * bindings/js/ScriptFunctionCall.cpp:
+ (WebCore::ScriptFunctionCall::appendArgument): Added uint and ScriptString-taking methods.
+ * bindings/js/ScriptFunctionCall.h:
+ * bindings/js/ScriptObjectQuarantine.cpp:
+ (WebCore::quarantineValue): Added generic ScriptValue quarantine helper.
+ * bindings/js/ScriptObjectQuarantine.h:
+ * bindings/js/ScriptValue.cpp:
+ (WebCore::ScriptValue::isEqual): Added.
+ * bindings/js/ScriptValue.h:
+ * inspector/ConsoleMessage.cpp:
+ (WebCore::ConsoleMessage::ConsoleMessage):
+ (WebCore::ConsoleMessage::addToConsole): Added.
+ (WebCore::ConsoleMessage::isEqual): Changed to use ScriptValue::isEqual.
+ * inspector/ConsoleMessage.h:
+ (WebCore::ConsoleMessage::incrementCount): Added.
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::addConsoleMessage): Changed to use ConsoleMessage::addToConsole.
+ (WebCore::InspectorController::populateScriptObjects): Ditto.
+ * inspector/InspectorController.h:
+
+2009-03-17 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Mark Rowe.
+
+ Get BUILDING_ON_* defines from Platform.h.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24630
+
+ * WebCorePrefix.h:
+
+2009-03-16 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24592
+ [GTK] Crash in FcPatternHash
+
+ Sanitize memory management in gtk fonts.
+
+ Release memory allocated by FontPlatformDataGtk in its own
+ destructor instead of doing it from other classes, and add copy
+ constructor and '=' operator to be able to track referenced
+ objects properly.
+
+ * platform/graphics/gtk/FontPlatformData.h:
+ * platform/graphics/gtk/FontPlatformDataGtk.cpp:
+ (WebCore::FontPlatformData::operator=):
+ (WebCore::FontPlatformData::FontPlatformData):
+ (WebCore::FontPlatformData::~FontPlatformData):
+ * platform/graphics/gtk/SimpleFontDataGtk.cpp:
+ (WebCore::SimpleFontData::platformDestroy):
+
+2009-03-17 Ariya Hidayat <ariya.hidayat@nokia.com>
+
+ Build fix for Qt < 4.5.
+
+ As reported by Yael Aharon <yael.aharon@nokia.com>
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::drawLine):
+
+2009-03-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24614
+ Access control checks are different in cached and uncached cases
+
+ Test: http/tests/xmlhttprequest/access-control-basic-non-simple-deny-cached.html
+
+ * loader/CrossOriginAccessControl.cpp:
+ (WebCore::isOnAccessControlSimpleRequestMethodWhitelist): Factored out simple method
+ check for use in both cached and uncached cases. In cached case, an old definition that
+ omitted HEAD was still used.
+ (WebCore::isOnAccessControlSimpleRequestHeaderWhitelist): Check that content type has an
+ allowed value. This is needed in all call sites. Also changed to compare MIME type, not
+ content type.
+ (WebCore::isSimpleCrossOriginAccessRequest): Use the above methods.
+
+ * loader/CrossOriginAccessControl.h: Expose isOnAccessControlSimpleRequestMethodWhitelist.
+
+ * loader/CrossOriginPreflightResultCache.cpp:
+ (WebCore::CrossOriginPreflightResultCacheItem::allowsCrossOriginMethod):
+ (WebCore::CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders):
+ Use the new checks for simple method and header.
+
+2009-03-16 Gustavo Noronha Silva <gns@gnome.org> and Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24638
+ [GTK] HTML5 media tags do not work
+
+ Add a repaint-requested signal to the video sink, and use it to
+ call MediaPlayerPrivate::repaint, so that the video actually
+ plays.
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::mediaPlayerPrivateRepaintCallback):
+ (WebCore::MediaPlayerPrivate::createGSTPlayBin):
+ * platform/graphics/gtk/VideoSinkGStreamer.cpp:
+ (webkit_video_sink_idle_func):
+ (webkit_video_sink_render):
+ (webkit_video_sink_class_init):
+
+2009-03-16 Gustavo Noronha Silva <gns@gnome.org> and Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24638
+ [GTK] HTML5 media tags do not work
+
+ Work-around the fact that gst_element_query_duration returns true even
+ though it is unable to figure out the duration when in stream (push)
+ mode.
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivate::duration):
+
+2009-03-16 Darin Adler <darin@apple.com>
+
+ Reviewed by Kevin Decker.
+
+ <rdar://problem/6642742> Top Sites malfunction when switching text zoom mode
+
+ * page/Frame.cpp:
+ (WebCore::Frame::setNeedsReapplyStyles): Don’t do anything if the frame is
+ currently showing a non-HTML view.
+
+2009-03-16 Darin Adler <darin@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ Bug 24629: moving forward or backward a paragraph fails at edge of document
+ https://bugs.webkit.org/show_bug.cgi?id=24629
+ rdar://problem/6544413
+
+ Test: editing/selection/move-paragraph-document-edges.html
+
+ * editing/visible_units.cpp:
+ (WebCore::previousParagraphPosition): Use the last result from
+ previousLinePosition rather than going all the way back to what was originally
+ passed in when we hit exception cases like null or not moving. This correctly
+ inherits the behavior of previousLinePosition when we are in a paragraph at the
+ edge of a document.
+ (WebCore::nextParagraphPosition): Ditto.
+
+2009-03-16 Darin Adler <darin@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ Bug 24619: RenderObject::selectionStartEnd does not need to be a virtual function
+ https://bugs.webkit.org/show_bug.cgi?id=24619
+
+ * rendering/RenderObject.h: Remove virtual keyword from selectionStartEnd declaration.
+ * rendering/RenderView.h: Ditto.
+
+2009-03-16 Peter Kasting <pkasting@google.com>
+
+ Reviewed by David Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24368
+ DOM scroll events should be based off the actual number of wheel
+ ticks, not off the number of lines scrolled. This matches IE.
+
+ * dom/Node.cpp:
+ (WebCore::Node::dispatchWheelEvent):
+ * dom/WheelEvent.cpp:
+ (WebCore::WheelEvent::WheelEvent):
+ * dom/WheelEvent.h:
+ (WebCore::WheelEvent::create):
+ * platform/PlatformWheelEvent.h:
+ (WebCore::PlatformWheelEvent::wheelTicksX):
+ (WebCore::PlatformWheelEvent::wheelTicksY):
+ * platform/gtk/WheelEventGtk.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/mac/WheelEventMac.mm:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/qt/WheelEventQt.cpp:
+ * platform/win/WheelEventWin.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/wx/MouseWheelEventWx.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+
+2009-03-16 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Clean up a few issues in the Animation code:
+
+ * page/animation/AnimationBase.cpp:
+ (WebCore::AnimationBase::updateStateMachine):
+ Whitespace
+
+ (WebCore::AnimationBase::willNeedService):
+ Don't round to float, use std::max
+
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::startTimeResponse):
+ Fix erroneously copied line to null out m_lastResponseWaiter.
+
+2009-03-12 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ https://bugs.webkit.org/show_bug.cgi?id=13632
+
+ Overflow scrolling needs to account for the bottom/right padding on the object itself as well
+ as for bottom/right margins on children.
+
+ Existing tests cover this.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::lowestPosition):
+ (WebCore::RenderBlock::rightmostPosition):
+
+2009-03-16 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Anders Carlsson.
+
+ Fix for <rdar://problem/6320555>
+ Add an upper limit for setting HTMLSelectElement.length.
+
+ Test: fast/forms/select-max-length.html
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::setOption):
+ (WebCore::HTMLSelectElement::setLength):
+
+2009-03-16 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ <rdar://problem/6686721> Media document crash in 64-bit WebKit
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::createQTMovieView): QTMovieContentViewClass is only used when
+ rendering inline with old versions of QuickTime, so don't look for it when we are in a
+ media document.
+
+2009-03-16 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24590
+ Refactor InspectorDOMStorageResource to use ScriptFunctionCall.
+
+ * bindings/js/ScriptFunctionCall.cpp:
+ (WebCore::ScriptFunctionCall::appendArgument): Added method for bool argument.
+ * bindings/js/ScriptFunctionCall.h: Ditto, also cleaned up.
+ * bindings/js/ScriptObjectQuarantine.cpp:
+ (WebCore::getQuarantinedScriptObject): Added Storage helper.
+ * bindings/js/ScriptObjectQuarantine.h: Ditto.
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::populateScriptObjects): Changed to use bind method.
+ (WebCore::InspectorController::resetScriptObjects): Changed to use unbind method.
+ (WebCore::InspectorController::didUseDOMStorage): Changed to use isSameHostAndType and bind methods.
+ * inspector/InspectorController.h: Removed add/remove methods for DOM storage.
+ * inspector/InspectorDOMStorageResource.cpp:
+ (WebCore::InspectorDOMStorageResource::InspectorDOMStorageResource):
+ (WebCore::InspectorDOMStorageResource::isSameHostAndType): Added.
+ (WebCore::InspectorDOMStorageResource::bind): Added.
+ (WebCore::InspectorDOMStorageResource::unbind): Added.
+ * inspector/InspectorDOMStorageResource.h:
+
+2009-03-16 Mike Belshe <mike@belse.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24580
+ Fix query() to match KURL behavior, this time with the code that
+ compiles.
+
+ * platform/KURLGoogle.cpp:
+ (WebCore::KURL::query): Fix copy/paste mistake.
+
+2009-03-16 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=21752
+ REGRESSION: referencing XHR constructor for a not yet loaded frame permanently breaks it
+
+ Test: fast/dom/Window/window-early-properties-xhr.html
+
+ For some transitions, the Window object is not replaced, but Document is. When this happened,
+ window.document property was updated, but references to Document kept in cached constructors
+ were not.
+
+ * bindings/js/JSAudioConstructor.cpp:
+ (WebCore::JSAudioConstructor::JSAudioConstructor):
+ (WebCore::JSAudioConstructor::document):
+ (WebCore::JSAudioConstructor::mark):
+ * bindings/js/JSAudioConstructor.h:
+ * bindings/js/JSImageConstructor.cpp:
+ (WebCore::JSImageConstructor::JSImageConstructor):
+ (WebCore::JSImageConstructor::document):
+ (WebCore::JSImageConstructor::mark):
+ * bindings/js/JSImageConstructor.h:
+ * bindings/js/JSMessageChannelConstructor.cpp:
+ (WebCore::JSMessageChannelConstructor::JSMessageChannelConstructor):
+ (WebCore::JSMessageChannelConstructor::scriptExecutionContext):
+ (WebCore::JSMessageChannelConstructor::mark):
+ * bindings/js/JSMessageChannelConstructor.h:
+ * bindings/js/JSOptionConstructor.cpp:
+ (WebCore::JSOptionConstructor::JSOptionConstructor):
+ (WebCore::JSOptionConstructor::document):
+ (WebCore::JSOptionConstructor::mark):
+ * bindings/js/JSOptionConstructor.h:
+ * bindings/js/JSXMLHttpRequestConstructor.cpp:
+ (WebCore::JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor):
+ (WebCore::JSXMLHttpRequestConstructor::scriptExecutionContext):
+ (WebCore::JSXMLHttpRequestConstructor::mark):
+ * bindings/js/JSXMLHttpRequestConstructor.h:
+ Changed cached constructors to keep a reference to Window, not Document.
+
+2009-03-15 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24549
+ Impose a limit on Access-Control-Max-Age value
+
+ * loader/CrossOriginPreflightResultCache.cpp:
+ (WebCore::CrossOriginPreflightResultCacheItem::parse):
+
+2009-03-15 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by David Kilzer.
+
+ <rdar://problem/6668875> Normalize Geolocation results
+
+ * platform/mac/GeolocationServiceMac.mm:
+ (-[WebCoreCoreLocationObserver locationManager:didUpdateToLocation:fromLocation:]):
+
+2009-03-15 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by David Kilzer.
+
+ Update ::toString format as suggested by Darin Adler.
+
+ * page/Geoposition.cpp:
+ (WebCore::Geoposition::toString):
+
+2009-03-15 David Kilzer <ddkilzer@apple.com>
+
+ <rdar://problem/6668238> WebCore is registering text encodings needlessly from KURL constructor.
+
+ Reviewed by Darin Adler.
+
+ Yet another case where we would trigger extended encoding loading needlessly.
+
+ * platform/text/TextEncoding.cpp:
+ (WebCore::TextEncoding::encodingForFormSubmission):
+
+2009-03-15 Simon Fraser <simon.fraser@apple.com>
+
+ Build fix: no review.
+
+ * rendering/style/ContentData.h:
+
+2009-03-15 David Kilzer <ddkilzer@apple.com>
+
+ Bug 24542: Improve ContentData encapsulation
+
+ <https://bugs.webkit.org/show_bug.cgi?id=24542>
+
+ Reviewed by Simon Fraser.
+
+ No tests since there is no change in behavior.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::createObject): Used getter methods
+ instead of data members on ContentData class. Used isImage()
+ convenience method.
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent): Ditto.
+
+ * rendering/style/ContentData.cpp:
+ (WebCore::ContentData::clear): Extracted code into
+ deleteContent() method.
+ (WebCore::ContentData::dataEquivalent): Added. Extracted code
+ from StyleRareNonInheritedData::contentDataEquivalent().
+ (WebCore::ContentData::deleteContent): Added. Used by setter
+ methods.
+ * rendering/style/ContentData.h: Made m_type, m_content and
+ m_next private.
+ (WebCore::ContentData::isCounter): Added.
+ (WebCore::ContentData::isImage): Added.
+ (WebCore::ContentData::isNone): Added.
+ (WebCore::ContentData::isText): Added.
+ (WebCore::ContentData::type): Added.
+ (WebCore::ContentData::dataEquivalent): Added.
+ (WebCore::ContentData::image): Added.
+ (WebCore::ContentData::setImage): Added.
+ (WebCore::ContentData::text): Added.
+ (WebCore::ContentData::setText): Added.
+ (WebCore::ContentData::counter): Added.
+ (WebCore::ContentData::setCounter): Added.
+ (WebCore::ContentData::next): Added.
+ (WebCore::ContentData::setNext): Added.
+
+ * rendering/style/CounterContent.h:
+ (WebCore::operator!=): Removed.
+ (WebCore::operator==): Renamed operator!=() and reversed its
+ logic after extracting code from
+ StyleRareNonInheritedData::contentDataEquivalent() to create
+ ContentData::dataEquivalent().
+
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::setContent): Used new getters and setters
+ on ContentData class. Changed first argument from a StringImpl*
+ to a PassRefPtr<StrimgImpl>. Used isText() convenience method.
+ * rendering/style/RenderStyle.h:
+ (WebCore::RenderStyle::setContent): Updated declaration.
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::contentDataEquivalent):
+ Extracted most logic in while() loop into
+ ContentData::dataEquivalent().
+
+2009-03-15 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Anders Carlsson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24602
+ [Gtk] Searching in thepiratebay.org doesn't work with more than 1 word
+
+ Reintroduce the URI into the soup message after having set it in
+ the KURL, on redirects, to make sure it is properly encoded. This
+ fixes bad request problems when servers give bad URIs on their
+ response's Location header.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::restartedCallback):
+
+2009-03-15 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=19737
+ No cursor and paste not enabled right clicking text field/area
+
+ Test: fast/events/right-click-focus.html
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::handleMousePressEventSingleClick):
+ (WebCore::EventHandler::handleMousePressEvent):
+ Take normal code path for right clicks (we were taking it for Ctrl-clicks anyway).
+
+2009-03-15 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Adele Peterson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23949
+ HTMLSelectElement is in inconsistent state when handling mutation events
+
+ Test: fast/forms/mutation-event-recalc.html
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::insertBefore):
+ (WebCore::ContainerNode::appendChild):
+ Call childrenChanged() before dispatching modification events, not after.
+
+ * html/HTMLOptGroupElement.cpp:
+ (WebCore::HTMLOptGroupElement::insertBefore):
+ (WebCore::HTMLOptGroupElement::replaceChild):
+ (WebCore::HTMLOptGroupElement::removeChild):
+ (WebCore::HTMLOptGroupElement::appendChild):
+ (WebCore::HTMLOptGroupElement::removeChildren):
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::add):
+ (WebCore::HTMLSelectElement::remove):
+ (WebCore::HTMLSelectElement::insertBefore):
+ (WebCore::HTMLSelectElement::replaceChild):
+ (WebCore::HTMLSelectElement::removeChild):
+ (WebCore::HTMLSelectElement::appendChild):
+ (WebCore::HTMLSelectElement::removeChildren):
+ Remove calls to recalcSelectOptions(). It is too late to recalc now, after mutation events
+ were already dispatched.
+
+2009-03-14 Greg Bolsinga <bolsinga@apple.com>
+
+ <rdar://problem/6683465>
+
+ Geolocation has to be able to handle NULL Frames.
+
+ Reviewed by Mark Rowe
+
+2009-03-14 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by David Kilzer.
+
+ Geoposition::toString was missing the Coordinates after the update.
+
+ * page/Geoposition.cpp:
+ (WebCore::Geoposition::toString):
+
+2009-03-14 Jan Michael Alonzo <jmalonzo@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ [Gtk] Build fix - pass a Coordinate to Geoposition::create
+ https://bugs.webkit.org/show_bug.cgi?id=24603
+
+ Gtk build fix per r41650
+ https://bugs.webkit.org/show_bug.cgi?id=24506
+ Geolocation in Safari differs from the spec, no Coordinates attribute on Position
+
+ Pass a Coordinate to Geoposition::create.
+
+ * platform/gtk/GeolocationServiceGtk.cpp:
+ (WebCore::GeolocationServiceGtk::updatePosition):
+
+2009-03-14 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24545
+ Make cross-site XHR simple request definition match current spec draft
+
+ Tests: http/tests/xmlhttprequest/access-control-basic-post-fail-non-simple-content-type.html
+ http/tests/xmlhttprequest/access-control-basic-whitelist-request-headers.html
+
+ * loader/CrossOriginAccessControl.cpp:
+ (WebCore::isOnAccessControlSimpleRequestHeaderWhitelist): Added Content-Language.
+ (WebCore::isSimpleCrossOriginAccessRequest): Added HEAD. Restricted content types to those
+ that could be sent via form submission.
+
+2009-03-14 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=15172
+ object fallback - empty string for first argument of setAttributeNS does not work like null
+
+ https://bugs.webkit.org/show_bug.cgi?id=24548
+ createElementNS("", name) should create an element in null namespace
+
+ Tests: fast/dom/createElementNS-empty-namespace.html
+ fast/dom/setAttributeNS-empty-namespace.html
+
+ * dom/QualifiedName.h: (WebCore::QualifiedName::QualifiedNameImpl::QualifiedNameImpl):
+ Convert empty namespaces to null.
+
+2009-03-13 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Dan Bernstein.
+
+ Take advantage of the ability of recent versions of Xcode to easily switch the active
+ architecture.
+
+ * Configurations/DebugRelease.xcconfig:
+
+2009-03-13 John Abd-El-Malek <jam@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24593
+ Added requestorID so we can track the request to its WebView without using frame (which was removed).
+
+ * platform/network/chromium/ResourceRequest.h:
+ (WebCore::ResourceRequest::ResourceRequest):
+ (WebCore::ResourceRequest::requestorID):
+ (WebCore::ResourceRequest::setRequestorID):
+ (WebCore::ResourceRequest::setTargetType):
+ (WebCore::ResourceRequest::policyURL):
+ (WebCore::ResourceRequest::setPolicyURL):
+ (WebCore::ResourceRequest::requestorPid):
+ (WebCore::ResourceRequest::setRequestorPid):
+
+2009-03-13 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24561
+ Add custom V8 bindings for HTMLElementCanvas, Location.
+
+ * bindings/v8/custom/V8HTMLCanvasElementCustom.cpp: Added.
+ * bindings/v8/custom/V8LocationCustom.cpp: Added.
+
+2009-03-13 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24584
+
+ Fix transparent text rendering on Chromium. FontChromiumWin
+ was calling beginTransparencyLayer()/endTransparencyLayer(), with
+ a TransparencyWin inside to do GDI ClearType rendering over an
+ opaque background. TransparencyWin does its special sauce
+ in the destructor, but it was being called too late to be used
+ correctly in the layer. Put the special sauce into a new function,
+ composite(), and call that explicitly instead.
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::~TransparencyAwareFontPainter):
+ * platform/graphics/chromium/TransparencyWin.cpp:
+ (WebCore::TransparencyWin::~TransparencyWin):
+ (WebCore::TransparencyWin::composite):
+ (WebCore::TransparencyWin::init):
+ * platform/graphics/chromium/TransparencyWin.h:
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::):
+
+2009-03-13 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24562
+ Add custom implementation for getCSSCanvasContext to V8 bindings.
+
+ * bindings/v8/custom/V8DocumentCustom.cpp: Added new method.
+
+2009-03-13 Mike Belshe <mike@belse.com>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24580
+ Fix query() to match KURL behavior.
+
+ * platform/KURLGoogle.cpp:
+ (WebCore::KURL::query): remove extra logic around question mark.
+
+2009-03-13 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ Bug 24474: AX: in multi-body tables, asking for a cell at a specific coordinate can return nil
+ https://bugs.webkit.org/show_bug.cgi?id=24474
+
+ Test: platform/mac-snowleopard/accessibility/table-multi-bodies.html
+
+ * page/AccessibilityTable.cpp:
+ (WebCore::AccessibilityTable::cellForColumnAndRow):
+
+2009-03-13 Jian Li <jianli@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24589
+ Upstream changes to V8 event listeners (Chromium r11133) in order to
+ fix worker functionality break in Chromium.
+
+ * bindings/v8/V8AbstractEventListener.cpp:
+ (WebCore::V8AbstractEventListener::invokeEventHandler):
+ (WebCore::V8AbstractEventListener::handleEvent):
+ * bindings/v8/V8AbstractEventListener.h:
+ * bindings/v8/V8WorkerContextEventListener.cpp:
+ (WebCore::V8WorkerContextEventListener::handleEvent):
+
+2009-03-13 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24524
+ Introduce ScriptObject and ScriptFunctionCall abstractions.
+
+ * GNUmakefile.am: Added ScriptObject and ScriptFunctionCall to project.
+ * WebCore.pro: Ditto.
+ * WebCore.vcproj/WebCore.vcproj: Ditto.
+ * WebCore.xcodeproj/project.pbxproj: Ditto.
+ * WebCoreSources.bkl: Ditto.
+ * bindings/js/ScriptFunctionCall.cpp: Added.
+ * bindings/js/ScriptFunctionCall.h: Added.
+ * bindings/js/ScriptObject.cpp: Added.
+ * bindings/js/ScriptObject.h: Added.
+ * bindings/js/ScriptObjectQuarantine.cpp: Added.
+ * bindings/js/ScriptObjectQuarantine.h: Added.
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::populateScriptObjects): Changed to use InspectorDatabaseResource::bind.
+ (WebCore::InspectorController::resetScriptObjects): Changed to use InspectorDatabaseResource::unbind.
+ (WebCore::InspectorController::didOpenDatabase): Changed to use InspectorDatabaseResource::unbind.
+ * inspector/InspectorController.h: Removed addScriptDatabaseResource and
+ removeScriptDatabaseResource declarations.
+ * inspector/InspectorDatabaseResource.cpp:
+ (WebCore::InspectorDatabaseResource::InspectorDatabaseResource):
+ (WebCore::InspectorDatabaseResource::bind): Added.
+ (WebCore::InspectorDatabaseResource::unbind): Added.
+ * inspector/InspectorDatabaseResource.h: Added bind and unbind declarations.
+
+2009-03-13 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24467
+ Make Skia drawRect() and stroke behavior match CG.
+
+ This makes drawRect() ignore the stroke width (like CG does), and
+ adds a warning comment about that to the appropriate header.
+
+ It also eliminates some hacky code in Skia's stroke preparation,
+ which tried to adjust odd-width strokes to fall on pixel boundaries.
+ Not only did this not match CG, it wouldn't necessarily work right,
+ because there could be other transforms (e.g. full-page zoom) that
+ would affect the stroke before it reached the device pixel level.
+
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::drawRect):
+ (WebCore::GraphicsContext::fillRect):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::drawRect):
+ (PlatformContextSkia::setupPaintForStroking):
+
+2009-03-13 Jian Li <jianli@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24583
+ Need to change scope of constructor and destructor of V8ObjectEventListener from private
+ to protected so that they could be used in its derived class V8WorkerContextEventListener.
+
+ * bindings/v8/V8ObjectEventListener.h:
+
+2009-03-13 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24579
+ Many V8*Event* files are misplaced.
+
+ This code is infrastructure for supporting the bindings and thus should
+ be in the bindings/v8 directory.
+
+ * bindings/v8/V8AbstractEventListener.cpp: Renamed from WebCore/bindings/v8/custom/V8AbstractEventListener.cpp.
+ * bindings/v8/V8AbstractEventListener.h: Renamed from WebCore/bindings/v8/custom/V8AbstractEventListener.h.
+ * bindings/v8/V8LazyEventListener.cpp: Renamed from WebCore/bindings/v8/custom/V8LazyEventListener.cpp.
+ * bindings/v8/V8LazyEventListener.h: Renamed from WebCore/bindings/v8/custom/V8LazyEventListener.h.
+ * bindings/v8/V8ObjectEventListener.cpp: Renamed from WebCore/bindings/v8/custom/V8ObjectEventListener.cpp.
+ * bindings/v8/V8ObjectEventListener.h: Renamed from WebCore/bindings/v8/custom/V8ObjectEventListener.h.
+ * bindings/v8/V8WorkerContextEventListener.cpp: Renamed from WebCore/bindings/v8/custom/V8WorkerContextEventListener.cpp.
+ * bindings/v8/V8WorkerContextEventListener.h: Renamed from WebCore/bindings/v8/custom/V8WorkerContextEventListener.h.
+
+2009-03-13 Adele Peterson <adele@apple.com>
+
+ Reviewed by Justin Garcia.
+
+ Fix for <rdar://problem/5089327> Color of quoted content is wrong when pasted inside other quoted content
+
+ Test: editing/pasteboard/5089327.html
+
+ Handle spans being pasted within a quoted region in the same way we handle "paste as quotation" content.
+
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::handleStyleSpansBeforeInsertion):
+ (WebCore::ReplaceSelectionCommand::handleStyleSpans):
+
+2009-03-13 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Update Geolocation perimission dialogs to be asynchronous.
+ https://bugs.webkit.org/show_bug.cgi?id=24505
+
+ Geolocation now requests permission from the Chrome asynchronously.
+ The Chrome is passed the Geolocation object, and the Chrome sets the permission
+ on the Geolocation. Geolocation also tracks if the Chrome should clear its cache
+ of SecurityOrigins with geolocation permission. This is so that the GeolocationService
+ can inform the Chrome of its request, and the Chrome is also free to implement its
+ own policy.
+
+ * WebCore.base.exp:
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/Chrome.cpp:
+ (WebCore::Chrome::requestGeolocationPermissionForFrame):
+ * page/Chrome.h:
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::requestGeolocationPermissionForFrame):
+ * page/Geolocation.cpp:
+ (WebCore::Geolocation::Geolocation):
+ (WebCore::Geolocation::getCurrentPosition):
+ (WebCore::Geolocation::watchPosition):
+ (WebCore::Geolocation::setIsAllowed):
+ (WebCore::Geolocation::displayChallengeIfNecessary):
+ (WebCore::Geolocation::geolocationServicePositionChanged):
+ * page/Geolocation.h:
+ (WebCore::Geolocation::isAllowed):
+ (WebCore::Geolocation::setShouldClearCache):
+ (WebCore::Geolocation::shouldClearCache):
+ (WebCore::Geolocation::):
+
+2009-03-13 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ <rdar://problem/6610666> Revise the Cocoa event model text API
+
+ Add a NPCocoaEventTextInput event type. Remove the text input variables.
+
+ * bridge/npapi.h:
+ (_NPCocoaEvent::):
+
+2009-03-13 Kevin Decker <kdecker@apple.com>
+
+ Reviewed by Anders.
+
+ <rdar://problem/6630340> REGRESSION (39114-39115): Unity Web Player no longer works if Flip4Mac is also installed
+
+ The code assumed if we have a plug-in that supports "application/x-oleobject" we should always prefer the object tag
+ over of an embed tag. That assumption can cause the Mac platform to load the wrong plug-in, as Flip4Mac claims supports
+ for x-oleobject.
+
+ * rendering/RenderPartObject.cpp:
+ (WebCore::shouldUseEmbedDescendant): Made the Mac platform always return true here.
+
+2009-03-13 Jian Li <jianli@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24559
+ Need to port JSC fix (r41565) to V8 in order to fix layout test onload-single-line-comment.html.
+
+ * bindings/v8/custom/V8LazyEventListener.cpp:
+ (WebCore::V8LazyEventListener::getListenerFunction):
+ (WebCore::V8LazyEventListener::getWrappedListenerFunction):
+
+2009-03-13 Jian Li <jianli@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24557
+ This is to support running multiple workers in a single worker process in chromium.
+
+ * bindings/v8/custom/V8WorkerContextEventListener.cpp:
+ (WebCore::V8WorkerContextEventListener::handleEvent):
+ Add locker to v8 event listener of worker context.
+
+2009-03-13 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24575
+ XHR response is incorrect after a network error.
+
+ Tests: http/tests/xmlhttprequest/cross-site-denied-response-sync-2.html
+ http/tests/xmlhttprequest/cross-site-denied-response-sync.html
+ http/tests/xmlhttprequest/cross-site-denied-response.html
+
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::networkError): Call internalAbort() to fully reset the request.
+ (WebCore::XMLHttpRequest::didFailRedirectCheck): No need to call internalAbort() here. Note
+ that since internalAbort() can drop GC protection, it is not safe to use the object after
+ this call.
+ (WebCore::XMLHttpRequest::didReceiveData): Check that the request wasn't aborted, and
+ return early if it was. This can happen during sync requests, as the loader does not know
+ that it was aborted, and just synthesizes all callbacks.
+
+2009-03-13 Adam Bergkvist <adam.bergkvist@ericsson.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=3547
+ XMLHttpRequest.statusText returns always "OK"
+
+ Covered by existing tests (which now pass on all platforms but Mac).
+
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::statusText): Return ResourceResponse status text. It is now up
+ to each platform to correctly set the status text or set it to "OK" to retain current
+ behavior.
+
+2009-03-13 Adam Bergkvist <adam.bergkvist@ericsson.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24349
+ [QT] HTTP status text is never set
+
+ Set HTTP status text to the reason phrase attribute of QNetworkReply.
+
+ * platform/network/qt/QNetworkReplyHandler.cpp:
+ (WebCore::QNetworkReplyHandler::sendResponseIfNeeded):
+
+2009-03-12 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Mark Rowe
+
+ <rdar://problem/6622300>: Reproducible crash on
+ <http://www.editgrid.com/explore/tnc/dave/FusionChart%3A_Candlestick>
+
+ Prevent CSSStyleSheet::checkLoaded() writing to freed memory when it gets
+ deleted from under itself. The sheetLoaded() notification can allow scripts
+ to run via HTMLTokenizer::executeScriptsWaitingForStylesheets(),
+ which can cause the last ref to the CSSStyleSheet to be released.
+
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::checkLoaded):
+
+2009-03-12 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix. Allow make-generated-sources.sh to pass args down to DerivedSources.make
+
+ * make-generated-sources.sh:
+
+2009-03-12 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24498
+ Fix the Qt port to use the same algorithm for drawing dashed and dotted
+ borders as the other ports. This makes the Qt port pixel-for-pixel perfect
+ compared to border drawing with Apple's canonical mac port and much closer
+ to konqueror and firefox behavior.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::drawLine):
+
+2009-02-26 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Justin Garcia.
+
+ Clean up DOMSelection to use some helper functions
+ making the code smaller, and less error-prone.
+ https://bugs.webkit.org/show_bug.cgi?id=19221
+
+ I tried moving DOMSelection off of rangeCompliantEquivalent
+ but failed. VisibleSelection holds positions like (table, 1) to mean
+ "after the table".
+
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::visibleSelection):
+ (WebCore::anchorPosition):
+ (WebCore::focusPosition):
+ (WebCore::basePosition):
+ (WebCore::extentPosition):
+ (WebCore::DOMSelection::anchorNode):
+ (WebCore::DOMSelection::anchorOffset):
+ (WebCore::DOMSelection::focusNode):
+ (WebCore::DOMSelection::focusOffset):
+ (WebCore::DOMSelection::baseNode):
+ (WebCore::DOMSelection::baseOffset):
+ (WebCore::DOMSelection::extentNode):
+ (WebCore::DOMSelection::extentOffset):
+ * page/DOMSelection.h:
+
+2009-03-12 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24563
+ Change ResourceRequest to be a struct rather then a class to match other declarations.
+
+ * platform/network/chromium/ResourceRequest.h:
+
+2009-03-12 David Levin <levin@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Bug 24530: width100percent-searchfield.html should be fixed for chromium.
+ <https://bugs.webkit.org/show_bug.cgi?id=24530>
+
+ Compensate for r39924 in chromium, which broke LayoutTests/fast/replaced/width100percent-searchfield.html
+
+ * css/themeChromiumWin.css: Added.
+ Overrides the changes to start supporting input[type="search"] on Windows (since
+ Chromium doesn't do anything special for this).
+
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::supportsFocus):
+ (WebCore::RenderThemeChromiumWin::extraDefaultStyleSheet):
+ (WebCore::RenderThemeChromiumWin::determineState):
+ (WebCore::RenderThemeChromiumWin::getThemeData):
+
+2009-03-12 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24506
+ Geolocation in Safari differs from the spec, no Coordinates attribute on Position
+
+ Get up to date.
+
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * bindings/js/JSGeolocationCustom.cpp:
+ (WebCore::createPositionOptions):
+ * page/Coordinates.cpp: Added.
+ (WebCore::Coordinates::toString):
+ * page/Coordinates.h: Added.
+ (WebCore::Coordinates::create):
+ (WebCore::Coordinates::latitude):
+ (WebCore::Coordinates::longitude):
+ (WebCore::Coordinates::altitude):
+ (WebCore::Coordinates::accuracy):
+ (WebCore::Coordinates::altitudeAccuracy):
+ (WebCore::Coordinates::heading):
+ (WebCore::Coordinates::speed):
+ (WebCore::Coordinates::Coordinates):
+ * page/Coordinates.idl: Added.
+ * page/Geoposition.cpp:
+ (WebCore::Geoposition::toString):
+ * page/Geoposition.h:
+ (WebCore::Geoposition::create):
+ (WebCore::Geoposition::coords):
+ (WebCore::Geoposition::Geoposition):
+ * page/Geoposition.idl:
+ * page/PositionOptions.h:
+ (WebCore::PositionOptions::create):
+ (WebCore::PositionOptions::maximumAge):
+ (WebCore::PositionOptions::setMaximumAge):
+ (WebCore::PositionOptions::PositionOptions):
+ * platform/mac/GeolocationServiceMac.mm:
+ (-[WebCoreCoreLocationObserver locationManager:didUpdateToLocation:fromLocation:]):
+
+2009-03-12 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24496
+ Fix console logging of non-string values by coercing the argument to
+ a string, for V8 bindings.
+
+ Test: fast/js/console-non-string-values.html
+
+ * bindings/v8/ScriptValue.cpp: Added toString method.
+ (WebCore::ScriptValue::toString):
+ * bindings/v8/ScriptValue.h: Added PlatformString, ScriptState includes
+ and toString declaration.
+
+2009-03-12 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Eliminate ChromiumBridge::uiResourceProtocol
+ https://bugs.webkit.org/show_bug.cgi?id=24558
+
+ * platform/chromium/ChromiumBridge.h:
+
+2009-03-12 Greg Bolsinga <bolsinga@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Missing breaks in switch statement
+ https://bugs.webkit.org/show_bug.cgi?id=24556
+
+ * platform/mac/GeolocationServiceMac.mm:
+ (-[WebCoreCoreLocationObserver locationManager:didFailWithError:]):
+
+2009-03-12 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24554
+ Remove some unused functions from ChromiumBridge.
+
+ * platform/chromium/ChromiumBridge.h:
+
+2009-03-02 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Darin Fisher and Justin Garcia.
+
+ Safari crashes during drag and drop in Google presentations
+ due to mutation event handlers removing DOM content during insertNode
+ https://bugs.webkit.org/show_bug.cgi?id=22634
+
+ Added a bunch of "null" checks to make sure nodes are still
+ in the document before we operate on them. This is an
+ inelegant solution, but it's the best we have for now.
+
+ Test: editing/selection/crash-on-drag-with-mutation-events.html
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::insertNodeAt):
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::doApply):
+
+2009-03-12 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Adam Treat.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24525
+ REGRESSION: Inspector window doesn't close when inspected page is
+ destroyed. This is a revert of r41158, which became unnecessary when
+ InspectorController became ref-counted in r41462.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::inspectedPageDestroyed): Reset m_inspectedPage
+ after calling close().
+ (WebCore::InspectorController::stopUserInitiatedProfiling): Remove
+ m_inspectedPage check guard around profile logic.
+
+2009-03-12 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24502
+ Make horizontal scrolling on Windows always go the correct direction.
+
+ * platform/PlatformWheelEvent.h:
+ * platform/win/WheelEventWin.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+
+2009-03-12 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24496
+ Fix console logging of non-string values by coercing the argument to
+ a string.
+
+ Test: fast/js/console-non-string-values.html
+
+ * bindings/js/ScriptValue.cpp: Removed PlatformString include.
+ * bindings/js/ScriptValue.h: Added toString method.
+ (WebCore::ScriptValue::toString):
+ * page/Console.cpp:
+ (WebCore::getFirstArgumentAsString): Changed firstArgumentAsString method to use
+ ScriptValue::toString.
+ (WebCore::Console::addMessage): added extra ScriptState argument to callsite.
+ (WebCore::Console::count): Ditto.
+
+2009-03-12 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24508
+
+ Fix updating of text field with placeholder text when value is set
+ by ensuring that updatePlaceholderVisibility() is called after
+ the value has been updated, not before.
+
+ Test: fast/forms/placeholder-set-value.html
+
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::setValue):
+
+2009-03-12 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24552
+
+ Hit testing involving normal flow, self-painting layers (e.g. reflections)
+ was broken because it was not null-testing the result of hitTestLayer(),
+ so bailing early with a nil hit layer.
+
+ Test: fast/layers/normal-flow-hit-test.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-12 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Cameron Zwarich.
+
+ Removed zero-sized files, left over from improperly applied patch.
+
+ * platform/graphics/chromium/ThemeHelperChromiumWin.cpp: Removed.
+ * platform/graphics/chromium/ThemeHelperChromiumWin.h: Removed.
+
+2009-03-12 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Do not ignore alpha color in optimization. Hard to believe, but there
+ are websites that fill the entire page with a tiled image consisting of
+ nothing but a 100% transparent 1x1 image. <cough>orbitz.com</cough>
+
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+
+2009-03-12 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Bug 24110: cloneNode should call cloneElement and not the reverse
+
+ - Splitted the code from cloneNode into cloneElementWithChildren and cloneElementWithChildren.
+ Now cloneNode calls one of the 2 previous methods.
+
+ - Renamed cloneElement to cloneElementWithoutChildren as it was the previous behaviour.
+
+ - Moved cloneNode to the Element private section so that WebCore callers cannot use it.
+
+ - Removed Element::cloneNode usage through WebCore.
+
+ * dom/Element.cpp:
+ (WebCore::Element::cloneNode): Moved to Element's private section and it
+ now calls the two next methods.
+ (WebCore::Element::cloneElementWithChildren): Added.
+ (WebCore::Element::cloneElementWithoutChildren): Renamed from cloneElement
+ to avoid ambiguity.
+ * dom/Element.h:
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::addInlineStyleIfNeeded): Changed call to cloneElement
+ to call to cloneElementWithoutChildren.
+ * editing/BreakBlockquoteCommand.cpp:
+ (WebCore::BreakBlockquoteCommand::doApply): Ditto.
+ * editing/IndentOutdentCommand.cpp:
+ (WebCore::IndentOutdentCommand::indentRegion): Ditto.
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply): Ditto.
+ * editing/ModifySelectionListLevel.cpp:
+ (WebCore::IncreaseSelectionListLevelCommand::doApply): Ditto.
+ * editing/SplitElementCommand.cpp:
+ (WebCore::SplitElementCommand::doApply): Ditto.
+ * editing/markup.cpp:
+ (WebCore::createFragmentFromText): Ditto.
+ * svg/SVGUseElement.cpp:
+ (WebCore::SVGUseElement::buildShadowTree): Ditto.
+ (WebCore::SVGUseElement::expandUseElementsInShadowTree): Ditto.
+
+2009-03-12 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed a crash on the 1x1 pixel check for background image in gtk.
+ We need to load the image first and need to be sure that the image
+ is not null before checking the type.
+
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+
+2009-03-12 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24544
+ Rename setUrl to setURL
+
+ Use proper case for setUrl method, rename it to setURL.
+
+ * platform/network/ResourceResponseBase.cpp:
+ (WebCore::ResourceResponseBase::adopt):
+ * platform/network/ResourceResponseBase.h:
+ * platform/network/curl/ResourceHandleManager.cpp:
+ (WebCore::writeCallback):
+ (WebCore::headerCallback):
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::fillResponseFromMessage):
+ (WebCore::queryInfoCallback):
+
+2009-03-12 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24519
+ [GTK] Use two argument KURL ctor in ResourceHandleSoup
+
+ Use two argument KURL ctor, the single argument ctor expects its
+ input to be the output of a previous KURL::parse call, which is
+ not the case here.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::fillResponseFromMessage):
+ (WebCore::queryInfoCallback):
+
+2009-03-11 Jon Honeycutt <jhoneycutt@apple.com>
+
+ Fix for <rdar://6418681>
+ https://bugs.webkit.org/show_bug.cgi?id=22644
+
+ Reviewed by Steve Falkenburg.
+
+ * plugins/win/PluginPackageWin.cpp:
+ (WebCore::PluginPackage::isPluginBlacklisted): Add the Citrix ICA
+ Client plug-in to the blacklist; it requires a Mozilla-based browser.
+
+2009-03-12 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ build fix.
+
+ * html/CanvasRenderingContext2D.h:
+
+2009-03-11 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ <rdar://problem/6673852> Widget "Simple World Clock" does not display with Safari 4
+
+ A number of dashboard widgets rely on canvas failing silently when given invalid
+ colors for gradient stops, but both the spec and firefox throw exceptions here.
+ So we work around this by creating a dashboard quirk that will only suppress the
+ exception in dashboard compatibility mode.
+
+ Test: fast/canvas/canvas-gradient-addStop-error.html
+
+ * html/CanvasGradient.cpp:
+ (WebCore::CanvasGradient::CanvasGradient):
+ (WebCore::CanvasGradient::addColorStop):
+ * html/CanvasGradient.h:
+ (WebCore::CanvasGradient::setDashboardCompatibilityMode):
+ * html/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::prepareGradientForDashboard):
+ (WebCore::CanvasRenderingContext2D::createLinearGradient):
+ (WebCore::CanvasRenderingContext2D::createRadialGradient):
+ * html/CanvasRenderingContext2D.h:
+
+2009-03-11 David Kilzer <ddkilzer@apple.com>
+
+ Clarify comments regarding order of FEATURE_DEFINES
+
+ Rubber-stamped by Mark Rowe.
+
+ * Configurations/WebCore.xcconfig: Added warning about the
+ consequences when FEATURE_DEFINES are not kept in sync.
+
+2009-03-11 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24515
+ [GTK] soup backend should use GMappedFile instead of mmap directly
+
+ Rewrite mmap code used to upload files to use GMappedFile, so that
+ it is platform-independent.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::startHttp):
+
+2009-03-11 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ - WebCore part of fixing <rdar://problem/3919124> Thai text selection
+ in Safari is incorrect
+
+ Test: platform/mac/editing/selection/word-thai.html
+
+ Tested on Mac, but should work on all ICU platforms (or more precisely
+ on all platforms that implement
+ WTF::Unicode::hasLineBreakingPropertyComplexContext() correctly).
+
+ * editing/TextIterator.cpp:
+ (WebCore::BackwardsCharacterIterator::BackwardsCharacterIterator):
+ Added.
+ (WebCore::BackwardsCharacterIterator::range): Added.
+ (WebCore::BackwardsCharacterIterator::advance): Added.
+
+ * editing/TextIterator.h: Added BackwardsCharacterIterator with the
+ minimal functionality required for this patch.
+ (WebCore::BackwardsCharacterIterator::atEnd): Added.
+
+ * editing/visible_units.cpp:
+ (WebCore::firstNonComplexContextLineBreak): Added this helper function
+ that returns the index of the first character in the string whose
+ Unicode line breaking property value is not SA ("Complex Context"), or
+ the length of the string if there is no such character.
+ (WebCore::lastNonComplexContextLineBreak): Added this helper function
+ that returns the index of the last character in the string whose
+ Unicode line breaking property value is not SA ("Complex Context"), or
+ -1 if there is no such character.
+ (WebCore::previousBoundary): Changed the signature of the search
+ function to include an offset parameter. Renamed the 'exception' local
+ variable to 'ec' and changed its type to ExceptionCode. Extend the
+ string forwards until the first character with Unicode line breaking
+ property value other than SA. This gives the boundary search function
+ enough context in the forward direction. Changed to use a
+ BackwardsCharacterIterator for translating the backwards offset into
+ a position.
+ (WebCore::nextBoundary): Changed the signature of the search
+ function to include an offset parameter. Extend the string backwards
+ until the first character with Unicode line breaking property value
+ other than SA. This gives the boundary search function enough context in
+ the backwards direction. Restricted the workaround for <rdar://5192593>
+ only to the line break case, because it was causing an extra character
+ to be selected following a word that ended with a combining mark.
+ (WebCore::startWordBoundary): Added an offset parameter. Check that
+ going backwards from the given offset, there is a character with Unicode
+ line breaking property value other than SA, and otherwise return 0 to
+ request more context.
+ (WebCore::endWordBoundary): Similar, but in reverse.
+ (WebCore::previousWordPositionBoundary): Similar.
+ (WebCore::nextWordPositionBoundary): Similar.
+ (WebCore::startSentenceBoundary): Updated for the new search function
+ signature.
+ (WebCore::endSentenceBoundary): Ditto.
+ (WebCore::previousSentencePositionBoundary): Ditto.
+ (WebCore::nextSentencePositionBoundary): Ditto.
+
+2009-03-11 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Don't use "::" in thread names because it is ugly!
+
+ * loader/icon/IconDatabase.cpp:
+ (WebCore::IconDatabase::open): Use "WebCore: " instead of "WebCore::".
+ * platform/network/cf/ResourceHandleCFNet.cpp:
+ (WebCore::ResourceHandle::loaderRunLoop): Call this "WebCore: CFNetwork Loader" to make
+ it clear this is a WebCore-created thread.
+ * storage/DatabaseThread.cpp:
+ (WebCore::DatabaseThread::start): Use "WebCore: " instead of "WebCore::".
+ * storage/LocalStorageThread.cpp:
+ (WebCore::LocalStorageThread::start): Use "WebCore: " instead of "WebCore::".
+ * workers/WorkerThread.cpp:
+ (WebCore::WorkerThread::start): Use "WebCore: " instead of "WebCore::".
+
+2009-03-11 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Darin Adler.
+
+ <rdar://problem/6653286> WebCore's implementation of screenIsMonochrome is needlessly complex
+
+ * platform/mac/PlatformScreenMac.mm:
+ (WebCore::screenIsMonochrome): Return false.
+
+2009-03-11 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=14749 percentage
+ top value on position:relative child not calculated correctly if
+ parent has percentage height
+ - and corresponding -
+ <rdar://problem/6172925>
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::relativePositionOffsetY):
+
+2009-03-11 Jian Li <jianli@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Implement ScriptValue::hasNoValue for V8.
+ https://bugs.webkit.org/show_bug.cgi?id=24507
+
+ * bindings/v8/ScriptValue.h:
+ (WebCore::ScriptValue::hasNoValue):
+
+2009-03-11 David Levin <levin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ Bug 24459: Add v8 bindings for event.
+ <https://bugs.webkit.org/show_bug.cgi?id=24459>
+
+ Adding custom event bindings.
+
+ * bindings/v8/custom/V8AbstractEventListener.cpp: Added.
+ * bindings/v8/custom/V8AbstractEventListener.h: Added.
+ * bindings/v8/custom/V8AttrCustom.cpp:
+ Fixed messed up copyright header.
+ * bindings/v8/custom/V8CustomEventListener.cpp: Added.
+ * bindings/v8/custom/V8CustomEventListener.h:
+ Replaced forwarding header with the real implementation.
+ * bindings/v8/custom/V8ElementCustom.cpp:
+ * bindings/v8/custom/V8LazyEventListener.cpp: Added.
+ * bindings/v8/custom/V8LazyEventListener.h: Added.
+ * bindings/v8/custom/V8ObjectEventListener.cpp: Added.
+ * bindings/v8/custom/V8ObjectEventListener.h: Added.
+ * bindings/v8/custom/V8WorkerContextEventListener.cpp: Added.
+ * bindings/v8/custom/V8WorkerContextEventListener.h: Added.
+
+2009-03-11 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Dimitri Glazkov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24521
+ Add some missing includes for the non-JSC build.
+
+ * platform/text/PlatformString.h: added OwnPtr.h
+ * xml/XMLHttpRequest.cpp: added SecurityOrigin.h
+
+2009-03-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24531
+
+ Make sure that AnimationControllerPrivate::getAnimatedStyleForRenderer() never
+ returns a null style if it has a valid renderer, which could happen if a
+ CompositeAnimation existed, but wasn't running any animations or transitions.
+
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::getAnimatedStyleForRenderer):
+
+2009-03-11 Simon Fraser <simon.fraser@apple.com>
+
+ Fix Scons build. Patch from Alexander Guy.
+
+ * WebCore.scons:
+
+2009-03-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ https://bugs.webkit.org/show_bug.cgi?id=23093
+
+ When the cancel button in the search field is shown or hidden,
+ we need to explicitly setStyle() on the cancel button's renderer,
+ to ensure that repaint happens. Changing the style without telling
+ the renderer won't work.
+
+ Test: fast/repaint/search-field-cancel.html
+
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::subtreeHasChanged):
+ (WebCore::RenderTextControlSingleLine::updateFromElement):
+ (WebCore::RenderTextControlSingleLine::createCancelButtonStyle):
+ (WebCore::RenderTextControlSingleLine::updateCancelButtonVisibility):
+ (WebCore::RenderTextControlSingleLine::visibilityForCancelButton):
+ * rendering/RenderTextControlSingleLine.h:
+
+2009-03-11 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=15790
+ Ligatures aren't accounted for when manipulating VisiblePositions
+
+ Changed cursorMovementIterator rules to prevent a cursor from moving in the middle of an
+ Indic ligature which uses a virama sign.
+
+ Test: editing/deleting/skip-virama-001.html
+
+ * platform/text/TextBreakIteratorICU.cpp:
+ (WebCore::cursorMovementIterator):
+
+2009-03-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24513
+ REGRESSION: Cursor movement doesn't work on Tiger (ICU 3.2)
+
+ Fixes existing tests on Tiger.
+
+ * platform/text/TextBreakIteratorICU.cpp: (WebCore::cursorMovementIterator):
+ Use characterBreakIterator on Tiger (like we used to do).
+
+2009-03-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/4072827> Downloaded non-ASCII file name becomes garbled
+
+ * platform/network/mac/ResourceRequestMac.mm:
+ (WebCore::ResourceRequest::doUpdatePlatformRequest): Correct selector name
+ in instancesRespondToSelector.
+
+2009-03-11 Jan Michael Alonzo <jmalonzo@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ [GTK]DumpRenderTree doesn't compile for non-X11 GTK ports anymore
+ https://bugs.webkit.org/show_bug.cgi?id=2260
+
+ Add missing stdio.h include to get the build going
+
+ * plugins/gtk/PluginPackageGtk.cpp:
+
+2009-03-10 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Ken Kocienda.
+
+ * dom/Range.cpp:
+ (WebCore::Range::addLineBoxRects): If the range ended at [div, 0], addLineBoxRects
+ would include rects for the divs contents. Set the correct RenderObject to stop at.
+
+2009-03-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ <rdar://problem/6123770> Restrict access to document.cookie when making a cross-site XHR
+
+ * xml/XMLHttpRequest.cpp: (WebCore::XMLHttpRequest::responseXML): Removed an incorrect
+ comment about cookie support. Firefox doesn't expose cookies on responseXML at all, and
+ there are security concerns with exposing them for cross-origin requests, so it's not clear
+ if we want to change anything here.
+
+2009-03-10 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24503
+
+ Fix hit testing of absolutely positioned single line text controls by
+ ensuring that we set result.innerNode() correctly. If the hit node is
+ a descendant of the inner text element or if it is the <input> itself,
+ then we say we hit the innerTextElement.
+
+ Rename hitInnerTextBlock() to hitInnerTextElement() to match the
+ 'innerTextElement' terminology used elsewhere.
+
+ Assert that if renderer()->hitTest() returns false, no-one set
+ result.innerNode().
+
+ Test: fast/forms/search-abs-pos-cancel-button.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestContents):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::hitInnerTextElement):
+ * rendering/RenderTextControl.h:
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::nodeAtPoint):
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::nodeAtPoint):
+
+2009-03-10 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ <rdar://problem/6668238> WebCore is registering text encodings needlessly from KURL constructor.
+
+ Another case where we would trigger extended encoding loading needlessly.
+
+ * platform/text/TextEncoding.cpp:
+ (WebCore::TextEncoding::isNonByteBasedEncoding):
+
+2009-03-10 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fix for <rdar://problem/6624769> REGRESSION (Safari 4 PB): No
+ scroll bar appears for long line of text with NOWRAP set
+
+ This is a regression from http://trac.webkit.org/changeset/32226
+ I talked with Dan about the original change, and we decided that
+ the best fix was to remove his small potential-optimization that
+ only created a separate line box for whitespace under certain
+ circumstances. This new code will always create a separate line
+ box.
+
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren):
+
+2009-03-10 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix for <rdar://problem/6166844>
+ https://bugs.webkit.org/show_bug.cgi?id=24495
+
+ Use same rule for loading java applets as we do for images.
+
+ * html/HTMLAppletElement.cpp:
+ (WebCore::HTMLAppletElement::createRenderer):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::loadItem):
+
+2009-03-10 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by David Kilzer.
+
+ Get rid of revealCaret and use revealSelection instead.
+
+ * WebCore.base.exp:
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::setSelection):
+ * page/Frame.cpp:
+ (WebCore::Frame::revealSelection):
+ * page/Frame.h:
+
+2009-03-10 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Geoff Garen.
+
+ Bug 23736: WebKit Crashes on http://g-conquest.fr/~server2
+ <https://bugs.webkit.org/show_bug.cgi?id=23736>
+ <rdar://problem/6560278>
+
+ Before replacing the document, FrameLoader::executeIfJavaScriptURL()
+ should call stopAllLoaders(), just like continueLoadAfterNavigationPolicy().
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::executeIfJavaScriptURL):
+
+2009-03-10 Darin Adler <darin@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24494: crash when deleting at end of document and merging paragraphs
+ https://bugs.webkit.org/show_bug.cgi?id=24494
+ rdar://problem/6571537
+
+ Test: editing/deleting/merge-at-end-of-document.html
+
+ * dom/Range.cpp:
+ (WebCore::Range::compareBoundaryPoints): Split out assertion. It's better not to
+ use && in assertions since we'd like to know which condition is failing.
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::applyInlineStyleToRange): Added a null check before
+ calling compareBoundaryPoints, since a 0 for the node is ambiguous and so the
+ function doesn't know which value to return.
+
+2009-03-10 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Eric Seidel. Math checked by Oliver Hunt.
+
+ Implement the Cairo version of the checkForSolidColor() method. This halfes the
+ time to draw on 1x1 px background images.
+ I added two new calls to Color for the pixel manipulation on cairo_surface's.
+ They are neede to premultiply/unpremultiply the colors of the surface.
+
+ [CAIRO] Introduce single-pixel image optimizations
+ https://bugs.webkit.org/show_bug.cgi?id=17284
+
+ * platform/graphics/Color.cpp:
+ (WebCore::colorFromPremultipliedARGB):
+ (WebCore::premultipliedARGBFromColor):
+ * platform/graphics/Color.h:
+ * platform/graphics/cairo/ImageBufferCairo.cpp:
+ (WebCore::ImageBuffer::getImageData):
+ (WebCore::ImageBuffer::putImageData):
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+
+2009-03-06 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24437
+
+ Add support for registering noAccess URL schemes:
+ 1- Add FrameLoader::registerURLSchemeAsNoAccess, and have SecurityOrigin check
+ that list upon construction (similar to how isLocal is implemented).
+ 2- Make InspectorController call grantUniversalAccess on its Document's
+ SecurityOrigin at the time when windowScriptObjectAvailable is called.
+
+ This enables content such as the inspector to be loaded from a custom (non-file)
+ URL, which is how Chromium loads the inspector. It also allows other URL schemes
+ to be treated like data: URLs, which Chromium utilizes for its various HTML-based
+ UI panels.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::windowScriptObjectAvailable):
+ * loader/FrameLoader.cpp:
+ (WebCore::localSchemes):
+ (WebCore::noAccessSchemes):
+ (WebCore::FrameLoader::loadItem):
+ * loader/FrameLoader.h:
+ * page/SecurityOrigin.cpp:
+ (WebCore::SecurityOrigin::SecurityOrigin):
+ (WebCore::SecurityOrigin::isLocal):
+
+2009-03-10 Xan Lopez <xlopez@igalia.com>
+
+ Build fix, no review
+
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (textMarkerForVisiblePosition):
+ (visiblePositionForTextMarker):
+
+2009-03-10 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24491
+ Rename posOffset to m_offset, get rid of accessor
+
+ As suggested in dom/Position.h, this patch gets rid of the
+ 'offset()' accessor and renames posOffset to m_offset. I've used
+ m_offset instead of offset to follow the style guide lines, since
+ Position is still a class and not a structure. If the long term
+ plan is still to make it a structure it would be pretty easy to
+ just s/m_offset/offset/ globally when that is achieved.
+
+ * dom/Position.cpp:
+ (WebCore::Position::previous):
+ (WebCore::Position::next):
+ (WebCore::Position::atStart):
+ (WebCore::Position::atEnd):
+ (WebCore::Position::renderedOffset):
+ (WebCore::Position::isCandidate):
+ (WebCore::Position::inRenderedText):
+ (WebCore::Position::isRenderedCharacter):
+ (WebCore::Position::rendersInDifferentPosition):
+ (WebCore::Position::leadingWhitespacePosition):
+ (WebCore::Position::debugPosition):
+ (WebCore::Position::formatForDebugger):
+ * dom/Position.h:
+ (WebCore::Position::Position):
+ * dom/PositionIterator.h:
+ (WebCore::PositionIterator::PositionIterator):
+ * dom/Range.cpp:
+ * dom/RangeBoundaryPoint.h:
+ (WebCore::RangeBoundaryPoint::position):
+ (WebCore::RangeBoundaryPoint::set):
+ (WebCore::RangeBoundaryPoint::setOffset):
+ (WebCore::RangeBoundaryPoint::setToChild):
+ (WebCore::RangeBoundaryPoint::setToStart):
+ (WebCore::RangeBoundaryPoint::setToEnd):
+ (WebCore::RangeBoundaryPoint::childBeforeWillBeRemoved):
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::applyRelativeFontStyleChange):
+ (WebCore::ApplyStyleCommand::applyInlineStyleToRange):
+ (WebCore::ApplyStyleCommand::removeInlineStyle):
+ (WebCore::ApplyStyleCommand::nodeFullySelected):
+ (WebCore::ApplyStyleCommand::nodeFullyUnselected):
+ (WebCore::ApplyStyleCommand::splitTextAtStartIfNeeded):
+ (WebCore::ApplyStyleCommand::splitTextAtEndIfNeeded):
+ (WebCore::ApplyStyleCommand::splitTextElementAtStartIfNeeded):
+ (WebCore::ApplyStyleCommand::splitTextElementAtEndIfNeeded):
+ (WebCore::ApplyStyleCommand::mergeStartWithPreviousIfIdentical):
+ (WebCore::ApplyStyleCommand::mergeEndWithNextIfIdentical):
+ (WebCore::ApplyStyleCommand::joinChildTextNodes):
+ * editing/BreakBlockquoteCommand.cpp:
+ (WebCore::BreakBlockquoteCommand::doApply):
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::insertNodeAt):
+ (WebCore::CompositeEditCommand::positionOutsideTabSpan):
+ (WebCore::CompositeEditCommand::rebalanceWhitespaceAt):
+ (WebCore::CompositeEditCommand::prepareWhitespaceAtPositionForSplit):
+ (WebCore::CompositeEditCommand::deleteInsignificantText):
+ (WebCore::CompositeEditCommand::removePlaceholderAt):
+ (WebCore::CompositeEditCommand::moveParagraphs):
+ (WebCore::CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph):
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::updatePositionForNodeRemoval):
+ (WebCore::updatePositionForTextRemoval):
+ (WebCore::DeleteSelectionCommand::handleGeneralDelete):
+ (WebCore::DeleteSelectionCommand::fixupWhitespace):
+ * editing/Editor.cpp:
+ (WebCore::Editor::setComposition):
+ (WebCore::Editor::advanceToNextMisspelling):
+ (WebCore::Editor::getCompositionSelection):
+ * editing/InsertLineBreakCommand.cpp:
+ (WebCore::InsertLineBreakCommand::doApply):
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply):
+ * editing/InsertTextCommand.cpp:
+ (WebCore::InsertTextCommand::performTrivialReplace):
+ (WebCore::InsertTextCommand::input):
+ (WebCore::InsertTextCommand::insertTab):
+ * editing/MoveSelectionCommand.cpp:
+ (WebCore::MoveSelectionCommand::doApply):
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplaceSelectionCommand::doApply):
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::debugRenderer):
+ * editing/TextIterator.cpp:
+ (WebCore::TextIterator::rangeFromLocationAndLength):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::deleteKeyPressed):
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::characterAfter):
+ (WebCore::VisiblePosition::debugPosition):
+ (WebCore::makeRange):
+ (WebCore::setStart):
+ (WebCore::setEnd):
+ * editing/VisibleSelection.cpp:
+ (WebCore::VisibleSelection::toNormalizedRange):
+ (WebCore::makeSearchRange):
+ (WebCore::VisibleSelection::debugPosition):
+ (WebCore::VisibleSelection::showTreeForThis):
+ * editing/htmlediting.cpp:
+ (WebCore::comparePositions):
+ (WebCore::rangeCompliantEquivalent):
+ (WebCore::isFirstPositionAfterTable):
+ (WebCore::isLastPositionBeforeTable):
+ * editing/visible_units.cpp:
+ (WebCore::previousBoundary):
+ (WebCore::nextBoundary):
+ (WebCore::startPositionForLine):
+ (WebCore::startOfLine):
+ (WebCore::endPositionForLine):
+ (WebCore::nextLinePosition):
+ (WebCore::startOfParagraph):
+ (WebCore::endOfParagraph):
+ * page/AccessibilityObject.cpp:
+ (WebCore::updateAXLineStartForVisiblePosition):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::indexForVisiblePosition):
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::anchorOffset):
+ (WebCore::DOMSelection::baseOffset):
+ (WebCore::DOMSelection::focusOffset):
+ (WebCore::DOMSelection::extentOffset):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::handleMousePressEventSingleClick):
+ * page/Frame.cpp:
+ (WebCore::Frame::selectionLayoutChanged):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::indexForVisiblePosition):
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::writeSelection):
+
+2009-03-10 Darin Adler <darin@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Bug 23564: REGRESSION (r39230-39286): crash loading page that changes <input> display type and then calls innerHTML
+ https://bugs.webkit.org/show_bug.cgi?id=23564
+ rdar://problem/6537238
+
+ Test: fast/dom/HTMLElement/innerHTML-selection-crash.html
+
+ * editing/markup.cpp: (WebCore::createMarkup): Added updateLayoutIgnorePendingStylesheets
+ call to the one of the two overloads of this function that wasn't calling it. This fixes
+ this crash and other possible crashes inside innerHTML.
+
+2009-03-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24285
+ Text resource loading checks for BOM twice
+
+ This removes TextDecoder class, since its only purpose was to check for BOM, which is
+ already done in TextResourceDecoder. Callers that use TextEncoding::decode() won't get
+ BOM checked, but I didn't find any cases where it would significantly change behavior.
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ Remove TextDecoder.{h,cpp}.
+
+ * platform/text/TextDecoder.cpp: Removed.
+ * platform/text/TextDecoder.h: Removed.
+
+ * loader/TextResourceDecoder.h: Instead of a TextDecoder object, keep TextEncoding and
+ TextCodec separately.
+
+ * loader/TextResourceDecoder.cpp:
+ (WebCore::TextResourceDecoder::TextResourceDecoder): Updated for m_encoding being a member.
+ (WebCore::TextResourceDecoder::setEncoding): Ditto.
+ (WebCore::TextResourceDecoder::checkForBOM): Removed a FIXME saying that a BOM could override
+ even a user-chosen encoding - this is how it already worked due to TextDecoder checking for
+ BOM again. Made this function return the detected BOM length.
+ (WebCore::TextResourceDecoder::decode): Skip the BOM if it was found at the beginning of
+ a text resource.
+ (WebCore::TextResourceDecoder::flush): Reset m_checkedForBOM, so that re-decoding the same
+ resource again (as frequently done by CachedResource subclasses) will skip the BOM correctly.
+
+ * platform/text/TextEncoding.cpp: (WebCore::TextEncoding::decode):
+ Use TextCodec directly without a TextDecoder wrapper. This means that this method no longer
+ checks for BOM, which was a counter-intuitive feature.
+
+ * loader/CachedScript.cpp:
+ (WebCore::CachedScript::CachedScript):
+ (WebCore::CachedScript::setEncoding):
+ (WebCore::CachedScript::encoding):
+ (WebCore::CachedScript::script):
+ * loader/CachedScript.h:
+ * loader/appcache/ManifestParser.cpp:
+ (WebCore::parseManifest):
+ Use TextResourceDecoder, as TextEncoding::decode() no longer checks for BOM.
+ A side effect of this is that these resources will now be subject to encoding auto-detection.
+
+ * loader/CachedFont.cpp: (WebCore::CachedFont::ensureSVGFontData):
+ * page/Page.cpp: (WebCore::Page::userStyleSheet):
+ Be sure to flush TextResourceDecoder, pushing any remaining bytes out, and making the decoder
+ re-usable (for repeated decoding of the same resource).
+
+ * platform/text/TextEncodingRegistry.h: Updated comments for newTextCodec().
+
+2009-03-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24488
+ An assertion failure when updating an offline application cache after emptying caches
+
+ Emptying appcache cannot be performed automatically, so no test.
+
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::checkIfLoadIsComplete): Ensure that the cache is in disk
+ storage, even if the application wasn't updated server side.
+
+2009-03-10 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ <rdar://problem/6425807> Implement WorkerUtils.importScripts()
+ <https://bugs.webkit.org/show_bug.cgi?id=22721>
+
+ Implement importScripts, currently uses a series of synchronous loads
+ to fetch the scripts, but this is simpler than a synchronous load of
+ multiple loads in parallel. In future we'll want to switch to parallel
+ loading, but this will do for now.
+
+ Test: http/tests/workers/worker-importScripts.html
+
+ * GNUmakefile.am:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSWorkerContextCustom.cpp:
+ (WebCore::JSWorkerContext::importScripts):
+ * bindings/js/ScriptValue.h:
+ (WebCore::ScriptValue::hasNoValue):
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::evaluate):
+ (WebCore::WorkerScriptController::setException):
+ * bindings/js/WorkerScriptController.h:
+ * dom/Document.cpp:
+ (WebCore::Document::scriptImported):
+ * dom/Document.h:
+ * dom/ScriptExecutionContext.h:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::scriptImported):
+ * inspector/InspectorController.h:
+ * inspector/InspectorResource.cpp:
+ (WebCore::InspectorResource::setScriptProperties):
+ * inspector/InspectorResource.h:
+ * workers/WorkerContext.cpp:
+ (WebCore::WorkerContext::scriptImported):
+ (WebCore::WorkerContext::importScripts):
+ * workers/WorkerContext.h:
+ * workers/WorkerContext.idl:
+ * workers/WorkerImportScriptsClient.cpp: Added.
+ (WebCore::WorkerImportScriptsClient::didReceiveResponse):
+ (WebCore::WorkerImportScriptsClient::didReceiveData):
+ (WebCore::WorkerImportScriptsClient::didFinishLoading):
+ (WebCore::WorkerImportScriptsClient::didFail):
+ (WebCore::WorkerImportScriptsClient::didFailRedirectCheck):
+ (WebCore::WorkerImportScriptsClient::didReceiveAuthenticationCancellation):
+ * workers/WorkerImportScriptsClient.h: Added.
+ (WebCore::WorkerImportScriptsClient::WorkerImportScriptsClient):
+ (WebCore::WorkerImportScriptsClient::script):
+ (WebCore::WorkerImportScriptsClient::failed):
+
+2009-03-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24462
+ Move cross-origin access control code out of XMLHttpRequest
+
+ Step 1: move preflight result cache and access control helper functions.
+
+ No change in behavior, so no test.
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * loader/CrossOriginAccessControl.cpp: Added.
+ (WebCore::isOnAccessControlSimpleRequestHeaderWhitelist):
+ (WebCore::isSimpleCrossOriginAccessRequest):
+ (WebCore::createAllowedCrossOriginResponseHeadersSet):
+ (WebCore::isOnAccessControlResponseHeaderWhitelist):
+ (WebCore::passesAccessControlCheck):
+ * loader/CrossOriginAccessControl.h: Added.
+ * loader/CrossOriginPreflightResultCache.cpp: Added.
+ (WebCore::parseAccessControlMaxAge):
+ (WebCore::addToAccessControlAllowList):
+ (WebCore::parseAccessControlAllowList):
+ (WebCore::CrossOriginPreflightResultCacheItem::parse):
+ (WebCore::CrossOriginPreflightResultCacheItem::allowsCrossOriginMethod):
+ (WebCore::CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders):
+ (WebCore::CrossOriginPreflightResultCacheItem::allowsRequest):
+ (WebCore::CrossOriginPreflightResultCache::shared):
+ (WebCore::CrossOriginPreflightResultCache::appendEntry):
+ (WebCore::CrossOriginPreflightResultCache::canSkipPreflight):
+ * loader/CrossOriginPreflightResultCache.h: Added.
+ (WebCore::CrossOriginPreflightResultCacheItem::CrossOriginPreflightResultCacheItem):
+ (WebCore::CrossOriginPreflightResultCache::CrossOriginPreflightResultCache):
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequestStaticData::XMLHttpRequestStaticData):
+ (WebCore::XMLHttpRequest::createRequest):
+ (WebCore::XMLHttpRequest::makeCrossOriginAccessRequest):
+ (WebCore::XMLHttpRequest::makeSimpleCrossOriginAccessRequest):
+ (WebCore::XMLHttpRequest::makeCrossOriginAccessRequestWithPreflight):
+ (WebCore::XMLHttpRequest::didReceiveResponse):
+ (WebCore::XMLHttpRequest::didReceiveResponsePreflight):
+ * xml/XMLHttpRequest.h:
+
+2009-03-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=19797
+ Bring the list of forbidden headers in sync with XMLHttpRequest spec draft
+
+ Added new checks to http/tests/xmlhttprequest/set-dangerous-headers.html.
+
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequestStaticData::XMLHttpRequestStaticData): Added all headers from
+ XMLHttpRequest 2 draft.
+
+2009-03-10 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ - fix https://bugs.webkit.org/show_bug.cgi?id=23975
+ <rdar://problem/6593610> REGRESSION: Scrollbar arrow not repainted
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::invalidateScrollbarRect): Corrected the vertical
+ scrollbar rect calculation.
+
+2009-03-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein, Oliver Hunt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24475
+
+ When repainting replaced elements, need to union the selection
+ and overflow rects because either may extend outside the other.
+
+ Test: fast/repaint/transform-replaced-shadows.html
+
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::clippedOverflowRectForRepaint):
+
+2009-03-09 Stephanie Lewis <slewis@apple.com>
+
+ Fix build.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::advanceToNextMisspelling):
+ (WebCore::markAllMisspellingsAndBadGrammarInRanges):
+
+2009-03-09 Kim Christensen <kimworking@gmail.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24276
+ Dropdown / select boxes do not consider the windows task bar in Chromium.
+
+ * platform/chromium/PopupMenuChromium.cpp:
+ (WebCore::PopupContainer::showPopup):
+
+2009-03-09 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Adele Peterson and Dave Hyatt.
+
+ - fix <rdar://problem/6654344> REGRESSION (r41041): Zillow.com has
+ misaligned edit fields
+
+ Test: fast/forms/legend-display-none.html
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::adjustRenderStyle): Change the display
+ property of legend elements to 'block' unless it is 'none'.
+ * css/html4.css: Do not force the display property of legend elements to
+ 'block' using CSS, because that prevents style rules from setting it to
+ 'none'.
+
+2009-03-09 Alpha Lam <hclam@chromium.org>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23024
+
+ Fix an incorrect criteria in the if statement that leaves references to
+ deleted floating objects in RenderBlock.
+
+ Test: fast/block/float/crash-on-absolute-positioning.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::markAllDescendantsWithFloatsForLayout):
+
+2009-03-09 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Eric Seidel.
+
+ Unify JSC/V8 idl file.
+ https://bugs.webkit.org/show_bug.cgi?id=24424
+
+ * page/Location.idl:
+
+2009-03-09 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Eric Seidel.
+
+ Unify JSC/V8 for History.idl.
+
+ * page/History.idl:
+
+2009-03-09 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Eric Seidel.
+
+ Unify JSC/V8 implementations of DOMWindow.idl.
+
+ * page/DOMWindow.idl:
+
+2009-03-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24163
+
+ Implement mapping of FloatQuads through 3D transforms.
+
+ Removed the redundant localToContainerQuad() methods, which can now
+ shared code with the old mapLocalToAbsolutePoint(), which was
+ renamed to mapLocalToContainer(). This can now convert a point,
+ and optionally a FloatQuad, which are carried along in the TransformState.
+
+ Optimized TransformState to reduce to simple FloatPoint.move()
+ if there are no transforms, and to heap-allocate a transform only if
+ necessary to accumulate transforms (when using preserve-3d).
+
+ Tested by 3d point mapping tests, and the inspector highlight (which now shows
+ the correct quads for 3d-transformed elements).
+
+ * platform/graphics/transforms/TransformationMatrix.cpp:
+ (WebCore::TransformationMatrix::projectQuad):
+ (WebCore::TransformationMatrix::translateRight):
+ (WebCore::TransformationMatrix::translateRight3d):
+ * platform/graphics/transforms/TransformationMatrix.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::mapLocalToContainer):
+ (WebCore::RenderBox::mapAbsoluteToLocalPoint):
+ * rendering/RenderBox.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::localToAbsolute):
+ (WebCore::RenderObject::absoluteToLocal):
+ (WebCore::RenderObject::mapLocalToContainer):
+ (WebCore::RenderObject::localToContainerQuad):
+ * rendering/RenderObject.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::mapLocalToContainer):
+ * rendering/RenderTableCell.h:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::mapLocalToContainer):
+ * rendering/RenderView.h:
+ * rendering/TransformState.cpp:
+ (WebCore::TransformState::move):
+ (WebCore::TransformState::applyTransform):
+ (WebCore::TransformState::flatten):
+ (WebCore::TransformState::mappedPoint):
+ (WebCore::TransformState::mappedQuad):
+ (WebCore::TransformState::flattenWithTransform):
+ (WebCore::HitTestingTransformState::mappedQuad):
+ * rendering/TransformState.h:
+ (WebCore::TransformState::TransformState):
+ (WebCore::TransformState::move):
+ (WebCore::TransformState::lastPlanarPoint):
+ (WebCore::TransformState::lastPlanarQuad):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::preserves3D):
+
+2009-03-09 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24433
+
+ During hit testing with transforms, if a layer has backface-visibility: hidden,
+ we need to check for it whether or not the layer has a transform, because it
+ might be an ancestor that is transformed.
+
+ Test: transforms/3d/hit-testing/backface-no-transform-hit-test.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-09 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24353
+ Allow to overrule default build options for Qt build.
+
+ * WebCore.pro: Allow to overrule ENABLE_VIDEO and ENABLE_NETSCAPE_PLUGIN_API
+
+2009-03-09 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24463
+ WebCore::qstring is detaching and copying twice for every single
+ WebCore::TextRun that is processed and drawn. This elevates this method
+ to one of the top-ten most expensive methods in all of QtWebKit according
+ to profiling. This changes the method so that QString only detaches
+ when absolutely necessary.
+
+ * platform/graphics/qt/FontQt.cpp:
+ (WebCore::qstring):
+ (WebCore::fixSpacing):
+ (WebCore::Font::drawComplexText):
+ (WebCore::Font::floatWidthForComplexText):
+ (WebCore::Font::offsetForPositionForComplexText):
+ (WebCore::Font::selectionRectForComplexText):
+
+2009-03-08 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Split ScrollAlignment and ScrollBehavior out of RenderLayer.h so that
+ Frame.h no longer needs to include it. This cuts the size of the symbols
+ for a debug build by around 3%.
+
+ * dom/Element.cpp:
+ (WebCore::Element::scrollIntoView):
+ (WebCore::Element::scrollIntoViewIfNeeded):
+ * editing/Editor.cpp:
+ (WebCore::Editor::insertTextWithoutSendingTextEvent):
+ (WebCore::Editor::revealSelectionAfterEditingOperation):
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::setSelection):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::gotoAnchor):
+ * page/ContextMenuController.cpp:
+ (WebCore::ContextMenuController::contextMenuItemSelected):
+ * page/Frame.cpp:
+ (WebCore::Frame::revealSelection):
+ (WebCore::Frame::revealCaret):
+ * page/Frame.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::getRectToExpose):
+ (WebCore::RenderLayer::autoscroll):
+ * rendering/RenderLayer.h:
+ * rendering/ScrollBehavior.cpp: Added.
+ (WebCore::):
+ * rendering/ScrollBehavior.h: Added.
+ (WebCore::):
+ (WebCore::ScrollAlignment::getVisibleBehavior):
+ (WebCore::ScrollAlignment::getPartialBehavior):
+ (WebCore::ScrollAlignment::getHiddenBehavior):
+
+ Add the new files to the build systems:
+ * GNUmakefile.am:
+ * WebCore.base.exp:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+
+ Add includes that were previously pulled in by way of RenderLayer.h from Frame.h:
+ * dom/Clipboard.cpp:
+ * editing/EditorCommand.cpp:
+ * editing/InsertLineBreakCommand.cpp:
+ * editing/TypingCommand.cpp:
+ * html/HTMLFormControlElement.cpp:
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ * loader/icon/IconLoader.cpp:
+ * page/animation/AnimationController.cpp:
+ * rendering/RenderSlider.cpp:
+ * rendering/RenderTextControl.cpp:
+
+
+2009-03-08 Mark Rowe <mrowe@apple.com>
+
+ Reviewed Dan Bernstein.
+
+ Push the include of Frame.h out of RenderView.h and down to those files
+ that need it. This cuts the size of symbols for RenderFoo object files
+ by around 15% in a debug build.
+
+ * bindings/objc/DOM.mm:
+ * rendering/RenderFileUploadControl.cpp:
+ * rendering/RenderInline.cpp:
+ * rendering/RenderObject.cpp:
+ * rendering/RenderReplaced.cpp:
+ * rendering/RenderText.cpp:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::zoomFactor):
+ * rendering/RenderView.h:
+
+2009-03-08 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Dan Bernstein.
+
+ Remove some unnecessary or redundant includes from files related to the JS bindings.
+ This cuts the size of the symbols for a debug build by around 3%.
+
+ * bindings/js/JSCustomPositionCallback.cpp:
+ * bindings/js/JSCustomPositionErrorCallback.cpp:
+ * bindings/js/JSCustomSQLStatementCallback.cpp:
+ * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
+ * bindings/js/JSCustomSQLTransactionCallback.cpp:
+ * bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
+ * bindings/js/JSCustomVoidCallback.cpp:
+ * bindings/js/JSCustomXPathNSResolver.cpp:
+ * bindings/js/JSDocumentCustom.cpp:
+ * bindings/js/JSPluginElementFunctions.cpp:
+ * bindings/js/JSSVGPODTypeWrapper.h:
+
+2009-03-08 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+
+ Reviewed by Oliver Hunt.
+
+ Remove the unused methods previousHistoryItem(), setPreviousHistoryItem()
+ and provisionalHistoryItem() from FrameLoader.
+
+ * WebCore.base.exp:
+ * WebCore.order:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::frameLoadCompleted):
+ (WebCore::FrameLoader::loadItem):
+ * loader/FrameLoader.h:
+
+2009-03-08 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Implement proper logging for the GTK+ port, inspired by the one in
+ Qt. We use the WEBKIT_DEBUG environment variable which was already
+ being used to decide whether to setup a logger for soup or not.
+
+ * platform/gtk/LoggingGtk.cpp:
+ (WebCore::getChannelFromName):
+ (WebCore::InitializeLoggingChannelsIfNecessary):
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ensureSessionIsInitialized):
+
+2009-03-07 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ - WebCore part of removing build-time and run-time support for legacy
+ versions of CFNetwork and Core Graphics
+
+ * platform/graphics/win/FontCGWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/win/FontCustomPlatformData.cpp:
+ (WebCore::FontCustomPlatformData::fontPlatformData):
+ * platform/graphics/win/FontPlatformDataCGWin.cpp:
+ (WebCore::FontPlatformData::platformDataInit):
+ * platform/network/cf/FormDataStreamCFNet.cpp:
+ (WebCore::setHTTPBody):
+ (WebCore::httpBodyFromRequest):
+ * platform/network/cf/ResourceHandleCFNet.cpp:
+ (WebCore::didSendBodyData):
+ (WebCore::shouldUseCredentialStorageCallback):
+ (WebCore::ResourceHandle::start):
+ * platform/network/win/CookieJarCFNetWin.cpp:
+ (WebCore::filterCookies):
+
+2009-03-07 Adele Peterson <adele@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=24444
+ No multiple JS property for <input type="file" multiple />
+
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::multiple):
+ (WebCore::HTMLInputElement::setMultiple):
+ * html/HTMLInputElement.h:
+ * html/HTMLInputElement.idl:
+
+2009-03-07 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24358
+ [GTK] Scrollbars not clipped correctly
+
+ ScrollView scrollbars in subframes are *not* native, so take that
+ into account again.
+
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::getLocationInParentWindow):
+ (ScrollbarGtk::frameRectsChanged):
+ (ScrollbarGtk::paint):
+ * platform/gtk/ScrollbarGtk.h:
+
+2009-03-06 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24405
+ Horizontal scrolling on Windows was reversed from Mac (and intuition).
+
+ * platform/gtk/WheelEventGtk.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/win/WheelEventWin.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+
+2009-03-06 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Sam Weinig.
+
+ Convert some C-style casts to static_cast<>()s.
+
+ * platform/gtk/WheelEventGtk.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/mac/WheelEventMac.mm:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/win/WheelEventWin.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/wx/MouseWheelEventWx.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+
+2009-03-06 Adele Peterson <adele@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix for <rdar://problem/6607524> REGRESSION (Safari 3-4): I can't tab back to the URL field in an empty window (key loop is broken)
+
+ I haven't been able to make a test for this since the problem is not reproducible within an empty iframe.
+
+ * page/EventHandler.cpp: (WebCore::eventTargetNodeForDocument): We used to ensure that every html document had a body element.
+ That is no longer true, so we should return the document element for a truly empty document.
+
+2009-03-06 Jay Campan <jcampan@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24306
+
+ Adding a flag to ResourceRequestBase to indicate whether or not upload
+ progress notifications are needed for a resource. This is useful to
+ avoid sending these notifications when there are no consumers
+ (especially in the Chromium case where IPC is involved).
+
+ * platform/network/ResourceRequestBase.h:
+ (WebCore::ResourceRequestBase::reportUploadProgress):
+ (WebCore::ResourceRequestBase::setReportUploadProgress):
+ (WebCore::ResourceRequestBase::ResourceRequestBase):
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::loadRequestAsynchronously):
+
+2009-03-06 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24150
+ Add virtual ScriptExecutionContext::encoding()
+
+ Test: http/tests/workers/text-encoding.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::encoding):
+ * dom/Document.h:
+ (WebCore::Document::inputEncoding):
+ (WebCore::Document::charset):
+ (WebCore::Document::characterSet):
+ Add new virtual method and route DOM synonym functions on Document through it.
+
+ * dom/ScriptExecutionContext.h:
+ * workers/Worker.cpp:
+ (WebCore::Worker::Worker):
+ (WebCore::Worker::notifyFinished):
+ * workers/WorkerContext.cpp:
+ (WebCore::WorkerContext::WorkerContext):
+ (WebCore::WorkerContext::encoding):
+ (WebCore::WorkerContext::completeURL): Added comment on why this is different from Document::completeURL
+ * workers/WorkerContext.h:
+ (WebCore::WorkerContext::create):
+ * workers/WorkerContextProxy.h:
+ * workers/WorkerMessagingProxy.cpp:
+ (WebCore::WorkerMessagingProxy::startWorkerContext):
+ * workers/WorkerMessagingProxy.h:
+ * workers/WorkerThread.cpp:
+ (WebCore::WorkerThreadStartupData::create):
+ (WebCore::WorkerThreadStartupData::WorkerThreadStartupData):
+ (WebCore::WorkerThread::create):
+ (WebCore::WorkerThread::WorkerThread):
+ (WebCore::WorkerThread::workerThread):
+ * workers/WorkerThread.h:
+ All of the above route the 'encoding' parameter of parent context to the new
+ instance of WorkerContext - from Worker::notifyFinished() via WorkerMessagingProxy
+ through WorkerThread through WorkerThreadStartupData and into constructor of WorkerContext.
+
+2009-03-06 Peter Kasting <pkasting@google.com>
+
+ Build bustage fix.
+
+ * dom/Node.cpp:
+ (WebCore::Node::dispatchWheelEvent):
+
+2009-03-06 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::createQTMovieView): Delay callback while setting up movieview.
+
+2009-03-06 Douglas R. Davidson <ddavidso@apple.com>
+
+ Reviewed by Justin Garcia.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24108
+
+ Update spelling and grammar checking to use the new combined text
+ checking (with automatic language identification) on Snow Leopard.
+ Tested manually in Mail and Safari; automated tests to come later.
+
+ * editing/Editor.cpp:
+ (WebCore::findFirstMisspellingOrBadGrammarInRange):
+ (WebCore::Editor::advanceToNextMisspelling):
+ (WebCore::guessesForMisspelledOrUngrammaticalRange):
+ (WebCore::Editor::guessesForMisspelledOrUngrammaticalSelection):
+ (WebCore::Editor::markMisspellingsAfterTypingToPosition):
+ (WebCore::markAllMisspellingsAndBadGrammarInRanges):
+ (WebCore::Editor::markMisspellingsAndBadGrammar):
+ * editing/Editor.h:
+ * loader/EmptyClients.h:
+ (WebCore::EmptyEditorClient::checkSpellingAndGrammarOfParagraph):
+ * page/EditorClient.h:
+ * page/Frame.cpp:
+ (WebCore::Frame::respondToChangedSelection):
+ * platform/ContextMenu.cpp:
+ (WebCore::ContextMenu::populate):
+
+2009-03-06 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24407
+ Windows scroll amount was too small, and wheel scroll distance
+ conversion code was overly complex.
+
+ * page/EventHandler.cpp:
+ (WebCore::scrollAndAcceptEvent):
+ * platform/PlatformWheelEvent.h:
+ (WebCore::):
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::wheelEvent):
+ * platform/Scrollbar.h:
+ * platform/gtk/WheelEventGtk.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/mac/WheelEventMac.mm:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/qt/WheelEventQt.cpp:
+ * platform/win/WheelEventWin.cpp:
+ (WebCore::horizontalScrollChars):
+ (WebCore::verticalScrollLines):
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+ * platform/wx/MouseWheelEventWx.cpp:
+ (WebCore::PlatformWheelEvent::PlatformWheelEvent):
+
+2009-03-06 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Adam Roben.
+
+ Generate valid bindings with HTML5 database support disabled.
+
+ * inspector/InspectorController.idl: Added feature guard around
+ databaseTableNames definition.
+
+2009-03-04 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24358
+ [GTK] Scrollbars not clipped correctly
+
+ Do not take into account the case of being a ScrollView scrollbar,
+ since those are native in our case.
+
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::frameRectsChanged):
+
+2009-03-04 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24358
+ [GTK] Scrollbars not clipped correctly
+
+ Move Widget::paint to ScrollbarGtk::paint, since it's scrollbar
+ specific and it's our only Widget anyway.
+
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::paint):
+ * platform/gtk/ScrollbarGtk.h:
+ * platform/gtk/WidgetGtk.cpp:
+
+2009-03-04 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24358
+ [GTK] Scrollbars not clipped correctly
+
+ Use correct clip rectangle and apply coordinate translation needed
+ for non-ScrollView scrollbars.
+
+ We were ignoring the clip rectangle passed as parameter, which is
+ wrong in the case of non coalesced expose events. This, in turn,
+ uncovers the fact that we were not applying coordinate translation
+ to our position.
+
+ * platform/gtk/WidgetGtk.cpp:
+ (WebCore::Widget::paint):
+
+2009-03-06 Eric Carlson <eric.carlson@apple.com>
+
+ Build fix, no review
+
+ * platform/graphics/chromium/MediaPlayerPrivateChromium.h: fix setSize declaration
+
+2009-03-06 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22790
+ Bug 22790: [Transforms] MediaPlayer::setRect() makes no sense with transforms
+ Replace media engine setRect with setSize since they don't use about the
+ position anyway.
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::NullMediaPlayerPrivate::setSize): Changed from setRect.
+ (WebCore::MediaPlayer::setSize): Ditto.
+ * platform/graphics/MediaPlayer.h:
+ (WebCore::MediaPlayer::size): Changed from rect().
+
+ * platform/graphics/MediaPlayerPrivate.h: Changed setRect to setSize.
+
+ * platform/graphics/chromium/MediaPlayerPrivateChromium.h: Ditto.
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Initialize m_size instead of m_rect
+ (WebCore::MediaPlayerPrivate::setSize): Changed from setRect
+ (WebCore::MediaPlayerPrivate::paint): update comment
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h: m_rect -> m_size.
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h: m_rect
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): Initialize m_rect.
+ (WebCore::MediaPlayerPrivate::createQTMovieView): setRect-> setSize.
+ (WebCore::MediaPlayerPrivate::setSize): Changed from setRect
+ (WebCore::MediaPlayerPrivate::paint): Call view:setFrame: when in a media document so
+ the movie is drawn in the correct location.
+
+ * platform/graphics/qt/MediaPlayerPrivatePhonon.cpp:
+ (WebCore::MediaPlayerPrivate::setSize): Changed from setRect
+ * platform/graphics/qt/MediaPlayerPrivatePhonon.h:
+
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
+ (WebCore::MediaPlayerPrivate::setSize): Changed from setRect
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h:
+
+ * rendering/RenderVideo.cpp:
+ (WebCore::RenderVideo::updatePlayer): Call setSize instead of setRect.
+
+2009-03-06 Darin Adler <darin@apple.com>
+
+ Reviewed by Darin Fisher.
+
+ Bug 24422: REGRESSION: null-URL crash in FrameLoader setting location.hash on new window
+ https://bugs.webkit.org/show_bug.cgi?id=24422
+ rdar://problem/6402208
+
+ Test: fast/dom/location-new-window-no-crash.html
+
+ The issue here is empty (or null) URLs. I picked the "schedule navigation" bottleneck
+ to add some checks for empty URLs. We could also put the empty URL checks at some
+ other bottleneck level and add more assertions over time. I tried adding a few more
+ assertions to functions like loadURL and hit them while running the regression tests,
+ so it's probably going to be a bit tricky to clean this up throughout the loader.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::ScheduledRedirection::ScheduledRedirection): Explicitly marked this struct
+ immutable by making all its members const. Added assertions about the arguments,
+ including that the URL is not empty. Initialized one uninitialized member in one of
+ the constructors.
+ (WebCore::FrameLoader::scheduleHTTPRedirection): Added an early exit to make this
+ a no-op if passed an empty URL.
+ (WebCore::FrameLoader::scheduleLocationChange): Ditto.
+ (WebCore::FrameLoader::scheduleRefresh): Ditto.
+
+2009-03-06 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24423
+ Use new soup_message_body_set_accumulate API in soup backend
+
+ Disable accumulating chunks for request_body on file uploads,
+ using the new soup API.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::startHttp):
+
+2009-03-06 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Replace use of deprecated SOUP_MESSAGE_OVERWRITE_CHUNKS flag with
+ the new soup_message_body_set_accumulate API in soup.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::gotHeadersCallback):
+ (WebCore::ResourceHandle::startHttp):
+
+2009-03-06 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24051
+ Soup backend needs content sniffing capabilities
+
+ Perform content sniffing when using soup, so that we have a chance
+ of figuring out the Content-Type of the file if it's not sent by
+ the server.
+
+ * platform/network/ResourceHandleInternal.h:
+ (WebCore::ResourceHandleInternal::ResourceHandleInternal):
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::gotHeadersCallback):
+ (WebCore::gotChunkCallback):
+
+2009-03-06 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24342
+ Cannot insert a Thai character after a Thai prepend character when using ICU 4.0
+
+ This change creates a new break iterator "cursorMovementIterator" for
+ moving cursors and use it when moving an input cursor.
+ In "TextBreakIteratorICU.cpp", this break iterator uses custom ruleset
+ based on the one of ICU 3.8.
+ On the other hand, in "TextBreakIteratorQt.cpp", this break iterator
+ just calls the characterBreakIterator() function.
+
+ Test: editing/inserting/insert-thai-characters-001.html
+
+ * platform/text/TextBreakIterator.h: Added a new function cursorMovementIterator().
+ * platform/text/TextBreakIteratorICU.cpp: Implemented the cursorMovementIterator() function for ICU.
+ (WebCore::setUpIteratorWithRules): Ditto.
+ (WebCore::cursorMovementIterator): Ditto.
+ * platform/text/qt/TextBreakIteratorQt.cpp: Implemented the cursorMovementIterator() function for Qt.
+ (WebCore::cursorMovementIterator): Ditto.
+ * rendering/RenderText.cpp: Call the cursorMovementIterator() function when moving an input cursor.
+ (WebCore::RenderText::previousOffset): Ditto.
+ (WebCore::RenderText::nextOffset): Ditto.
+
+2009-03-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6621701> Safari 4 Beta Breaks XMLHttpRequest Response Text With Special
+ Characters (a compatibility issue with widgets).
+
+ Test: http/tests/xmlhttprequest/broken-xml-encoding.html
+
+ Revert part of an Acid 3 fix - now we are no longer strict when decoding XMLHttpRequest XML
+ responses.
+
+ * loader/TextResourceDecoder.cpp:
+ (WebCore::TextResourceDecoder::TextResourceDecoder):
+ (WebCore::TextResourceDecoder::decode):
+ (WebCore::TextResourceDecoder::flush):
+ * loader/TextResourceDecoder.h:
+ (WebCore::TextResourceDecoder::useLenientXMLDecoding):
+ Don't stop on XML decoding errors if useLenientXMLDecoding() was called.
+
+ * xml/XMLHttpRequest.cpp: (WebCore::XMLHttpRequest::didReceiveData): Don't stop on XML
+ decoding errors. This behavior is now limited to other kinds of XML content.
+
+2009-03-05 Simone Fiorentino <simone.fiorentino@consulenti.fastweb.it>
+
+ Bug 24382: request to add SH4 platform
+
+ <https://bugs.webkit.org/show_bug.cgi?id=24382>
+
+ Reviewed by David Kilzer.
+
+ * platform/text/AtomicString.cpp:
+ (WebCore::equal): Aligned memory access on SH4 platform.
+
+2009-03-05 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Simon Fraser.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=24215
+
+ Gears expects an object tag with display:none to instantiate the plugin,
+ so we add a workaround to make this work and fix Gears on WebKit trunk.
+
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::rendererIsNeeded):
+
+2009-03-05 Avi Drissman <avi@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Need to have Chromium Mac match Safari Mac's accesskey handling
+ https://bugs.webkit.org/show_bug.cgi?id=24404
+
+ * page/chromium/EventHandlerChromium.cpp:
+ (WebCore::EventHandler::accessKeyModifiers): Share access key modifiers with Mac Safari when building for the Mac.
+
+2009-03-05 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24412
+
+ Fix crash when hit-testing elements with -webkit-transform-style: preserve-3d
+ but no transform. We need to make localTransformState if we see preserve-3d.
+ Also need to call update3DTransformedDescendantStatus() before we test
+ m_has3DTransformedDescendant.
+
+ Test: transforms/3d/hit-testing/hit-preserves-3d.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-05 Eric Seidel <eric@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Changes to RenderLayer destruction to hopefully help catch an elusive crasher
+ https://bugs.webkit.org/show_bug.cgi?id=24409
+
+ Added a new RenderBoxModelObject::destroyLayer() call which is
+ now the only way which RenderLayers should ever be destroyed.
+ This ensures that the pointer to the layer is cleared in the
+ RenderObject after destruction, allowing us to ASSERT in the
+ RenderBoxModelObject destructor.
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::~RenderBoxModelObject):
+ (WebCore::RenderBoxModelObject::destroyLayer):
+ (WebCore::RenderBoxModelObject::destroy):
+ (WebCore::RenderBoxModelObject::styleDidChange):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::stackingContext):
+ (WebCore::RenderLayer::destroy):
+ (WebCore::RenderLayer::removeOnlyThisLayer):
+ * rendering/RenderLayer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::destroy):
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::destroy):
+
+2009-03-05 Eric Seidel <eric@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Remove old, unused IE 5.5 scrollbar-* CSS properties.
+ Sort the unimplemented getComputedStyle properties so it's
+ easier to see which ones actually need implementation.
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ * css/CSSPropertyNames.in:
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty):
+
+2009-03-05 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Darin Adler.
+
+ WebViewDidChangeSelectionNotifications weren't being sent for commands that change the selection's position
+ within the document without changing its position in the DOM. For example, pressing return in (caret marked by ^):
+ <div contentEditable="true"><div>^Hello</div></div>
+ Undo was being enabled, shouldDeleteDOMRange called, etc. when doing no-op deletes (a delete in an empty document
+ for example).
+
+ Changes to layout tests demonstrate fix.
+
+ * editing/EditCommand.cpp:
+ (WebCore::EditCommand::apply): Don't call applyEditing for a TypingCommand. The TypingCommand knows whether or
+ not it did work that needs to be applied.
+ * editing/Editor.cpp:
+ (WebCore::Editor::appliedEditing): Moved code (but did not alter) to changeSelectionAfterCommand.
+ (WebCore::Editor::unappliedEditing): Ditto.
+ (WebCore::Editor::reappliedEditing): Ditto.
+ (WebCore::Editor::changeSelectionAfterCommand): Moved code from *appliedEditing into here. Also call out to
+ EditorClient::respondToChangedSelection() for commands that changed the selection's position in the document
+ even if they did not change it's position in the DOM. Any TypingCommand that gets this far changed it's position
+ in the document.
+ * editing/Editor.h:
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::TypingCommand): Removed unused m_appliedEditing.
+ (WebCore::TypingCommand::typingAddedToOpenCommand): Always apply editing. We won't get this far if we don't need to.
+ (WebCore::TypingCommand::deleteKeyPressed): Don't do any of the things that only make sense for Range selections, like
+ adding to the killring and responding to a change in selections if the delete was a no-op.
+ (WebCore::TypingCommand::forwardDeleteKeyPressed): Ditto.
+ * editing/TypingCommand.h:
+
+2009-03-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Adam Roben.
+
+ Eliminate a ref-counting leak in InspectorController.
+
+ * inspector/InspectorController.h: Made constructor private, added static create method.
+ * page/Page.cpp:
+ (WebCore::Page::Page): Change initializer to use static create method.
+
+2009-03-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24355
+ Add InspectorController.idl and convert InspectorController.cpp to use
+ JSC bindings.
+
+ * DerivedSources.make: Added InspectorController.idl
+ * WebCore.xcodeproj/project.pbxproj: Added idl, bindings files.
+ * bindings/js/JSInspectorControllerCustom.cpp: Added.
+ * bindings/scripts/CodeGeneratorJS.pm: Added Array to no-header types.
+ * inspector/InspectorController.cpp: Removed hand-rolled bindings.
+ * inspector/InspectorController.h: Added platform and addSourceToFrame methods.
+ * inspector/InspectorController.idl: Added.
+ * page/Page.h: Changed member to RefPtr since InspectorController is now ref-counted.
+
+2009-03-05 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24400
+ Bug 24400: Remove "start", "end", "loopStart", "loopEnd", "currentLoop", and "playCount"
+ media element attributes
+
+ Test: media/video-loop.html
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement):
+ (WebCore::HTMLMediaElement::loadInternal):
+ (WebCore::HTMLMediaElement::setNetworkState):
+ (WebCore::HTMLMediaElement::seek):
+ (WebCore::HTMLMediaElement::playInternal):
+ (WebCore::HTMLMediaElement::loop):
+ (WebCore::HTMLMediaElement::setLoop):
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged):
+ (WebCore::HTMLMediaElement::endedPlayback):
+ (WebCore::HTMLMediaElement::updatePlayState):
+ * html/HTMLMediaElement.h:
+ * html/HTMLMediaElement.idl:
+
+2009-03-05 Steve Falkenburg <sfalken@apple.com>
- 2009-02-19 Anders Carlsson <andersca@apple.com>
+ <rdar://problem/6651112> Safari asks about re-posting a form even when page is cached
+
+ Reviewed by Ada Chan.
+
+ * platform/network/cf/ResourceHandleCFNet.cpp:
+ (WebCore::ResourceHandle::willLoadFromCache): Ported from Mac version.
+
+2009-03-05 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ https://bugs.webkit.org/show_bug.cgi?id=24248
+
+ Make sure painting of overflow controls checks that visibility:visible is set on the block before
+ painting. Pixel tests caught this regression.
+
+ Make sure resizer painting pushes a clip of the corner rect. It was relying on the clip layers happened
+ to do to their bounds (which had nothing to do with overflow).
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paint):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintResizer):
+
+2009-03-05 Yong Li <yong.li@torchmobile.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24386
+ A faster implementation of extractMIMETypeFromMediaType.
+
+ * platform/network/HTTPParsers.cpp:
+ (WebCore::extractMIMETypeFromMediaType):
+
+2009-03-05 Yong Li <yong.li@torchmobile.com>
+
+ Reviewed by Antti Koivisto.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24392
+ Do not get the current time for unless we're doing PRELOAD_DEBUG as this
+ can be unnecessarily expensive.
+
+ * html/PreloadScanner.cpp:
+ (WebCore::PreloadScanner::write):
+
+2009-03-04 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24327
+
+ When mapping points and hit testing through transforms, work
+ correctly when acclerated animations of transforms are running.
+
+ Tested by LayoutTests/animations/animation-hit-test-transform.html,
+ which only failed when ACCELERATED_COMPOSITING was turned on.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::currentTransform):
+ * rendering/RenderLayer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::transformFromContainer):
+
+2009-03-05 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24391
+ Frame.cpp uses JSC specific includes
+
+ * page/Frame.cpp:
+
+2009-03-05 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24389
+ WebKitGTK+ crashes when cancelling plugin loads
+
+ Remove bogus calls to the client's didFinishLoading method from
+ our ResourceHandle::cancel implementation. Calling
+ didFinishLoading here is mostly inoffensive for most loads, but
+ causes crashes when plugin loads are cancelled.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::cancel):
+
+2009-03-05 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+
+ * WebCore.vcproj/QTMovieWin.vcproj:
+
+2009-03-05 Adam Treat <adam.treat@torchmobile.com>
+
+ Build fix for when ENABLE_NETSCAPE_PLUGIN_API = 0. The method
+ ScriptController::jsObjectForPluginElement(HTMLPlugInElement*); is not
+ protected by an #if and uses HTMLPlugInElement so it must be included.
+
+ * bindings/js/ScriptController.cpp:
+
+2009-03-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ GTK Build fix.
+
+ * inspector/ConsoleMessage.h: Use proper header.
+
+2009-03-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24376
+ Split InspectorController.cpp file into separate classes.
+
+ * GNUmakefile.am: Modified to include new files.
+ * WebCore.pro: Ditto.
+ * WebCore.scons: Ditto.
+ * WebCore.vcproj/WebCore.vcproj: Ditto.
+ * WebCore.xcodeproj/project.pbxproj: Ditto.
+ * WebCoreSources.bkl: Ditto.
+ * inspector/ConsoleMessage.cpp: Added.
+ * inspector/ConsoleMessage.h: Added.
+ * inspector/InspectorController.cpp:
+ * inspector/InspectorDOMStorageResource.cpp: Added.
+ * inspector/InspectorDOMStorageResource.h: Added.
+ * inspector/InspectorDatabaseResource.cpp: Added.
+ * inspector/InspectorDatabaseResource.h: Added.
+ * inspector/InspectorResource.cpp: Added.
+ * inspector/InspectorResource.h: Added.
+
+2009-03-05 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24387
+ Remove media element bufferingRate attribute. No test necessary as there
+ were none for this attribute.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Don't initialize m_bufferingRate.
+ (WebCore::HTMLMediaElement::loadInternal): Ditto.
+ (WebCore::HTMLMediaElement::setNetworkState): Ditto.
+ (WebCore::HTMLMediaElement::progressEventTimerFired): Don't calculate m_bufferingRate.
+ * html/HTMLMediaElement.h: Remove m_bufferingRate.
+ * html/HTMLMediaElement.idl: Ditto.
+
+2009-03-05 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24377
+ [GTK] Comply better with coding style guidelines in ResourceHandleSoup
+
+ Use C++ booleans, 0 instead of NULL, prefix boolean variables with
+ 'is', do not use 'else if' if the previous if had a return, delete
+ trailing whitespace, etc.
+
+ * platform/network/ResourceHandleInternal.h:
+ (WebCore::ResourceHandleInternal::ResourceHandleInternal):
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::WebCoreSynchronousLoader::WebCoreSynchronousLoader):
+ (WebCore::fillResponseFromMessage):
+ (WebCore::restartedCallback):
+ (WebCore::finishedCallback):
+ (WebCore::parseDataUrl):
+ (WebCore::ensureSessionIsInitialized):
+ (WebCore::ResourceHandle::startHttp):
+ (WebCore::reportUnknownProtocolError):
+ (WebCore::ResourceHandle::start):
+ (WebCore::cleanupGioOperation):
+ (WebCore::closeCallback):
+ (WebCore::readCallback):
+ (WebCore::openCallback):
+ (WebCore::queryInfoCallback):
+ (WebCore::ResourceHandle::startGio):
+
+2009-03-04 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Eric Seidel
+
+ https://bugs.webkit.org/show_bug.cgi?id=24328
+
+ If an element has backface-visibility: hidden, hit testing should not
+ hit the back sides of elements. Test for that by inverting the accumulated
+ transform and looking at the z vector.
+
+ Tested by transforms/3d/hit-testing/backface-hit-test.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-03-04 Adam Langley <agl@google.com>
+
+ Reviewed by Darin Fisher.
+
+ r41362 mistakenly added functions "RenderThemeWin::" into
+ RenderThemeChromiumGtk.cpp. When correcting this, I somehow changed
+ them to void return types. This patch switches them back to ints.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24360
+
+ * rendering/RenderThemeChromiumLinux.cpp:
+ (WebCore::RenderThemeChromiumLinux::buttonInternalPaddingLeft):
+ (WebCore::RenderThemeChromiumLinux::buttonInternalPaddingRight):
+ (WebCore::RenderThemeChromiumLinux::buttonInternalPaddingTop):
+ (WebCore::RenderThemeChromiumLinux::buttonInternalPaddingBottom):
+
+2009-03-04 Adam Langley <agl@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Chromium Linux: change some metrics to better match Windows after
+ r41416. Aesthetically this may be worse, but web-compat is king.
+
+ Also, the previous code had an off by one error when drawing
+ scrollbars which caused the scrollbar to overflow it's bounds by 1px
+ at the right and bottom edges.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24369
+
+ * rendering/RenderThemeChromiumLinux.cpp:
+ (WebCore::):
+ (WebCore::RenderThemeChromiumLinux::systemFont):
+ * platform/chromium/ScrollbarThemeChromiumLinux.cpp:
+ (WebCore::ScrollbarThemeChromium::paintTrackPiece):
+
+2009-03-04 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Add an ASSERT to better demonstrate the cause of the crash in
+ https://bugs.webkit.org/show_bug.cgi?id=23736
+
+ * loader/DocLoader.cpp:
+ (WebCore::DocLoader::~DocLoader):
+
+2009-03-04 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24337: Assert when doing sync XHR in a worker for a cacheable response.
+ <https://bugs.webkit.org/show_bug.cgi?id=24337>
+
+ Tests: http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache.html
+ http/tests/xmlhttprequest/workers/xmlhttprequest-file-not-found.html
+
+ * loader/mac/ResourceLoaderMac.mm:
+ (WebCore::ResourceLoader::willCacheResponse):
+ An identifier is only asssigned if resource load callbacks are done. So don't send
+ willCacheResponse which uses identifier if resource load callbacks aren't being sent.
+
+2009-03-04 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24330: Sync xhr in workers should send an abort exception when the worker is terminated.
+ <https://bugs.webkit.org/show_bug.cgi?id=24330>
+
+ Test: http/tests/xmlhttprequest/workers/abort-exception-assert.html
+
+ * dom/ExceptionCode.cpp:
+ (WebCore::xmlHttpRequestExceptionNames):
+ Added missing ABORT_ERR whose absence caused an assert.
+
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::cancel):
+ Add more logic to handle the termination case for sync xhr.
+
+2009-03-04 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24364
+ Add support for HTMLMediaElement canPlayType method. Make
+ MediaPlayer::supportsType take a ContentType instead of a
+ separate mime type and codecs parameter.
+
+ Test: media/video-can-play-type.html
+
+ * dom/DOMImplementation.cpp:
+ (WebCore::DOMImplementation::createDocument):
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::canPlayType): Add canPlayType method.
+ (WebCore::HTMLMediaElement::loadInternal): selectMediaURL returns a ContentType.
+ (WebCore::HTMLMediaElement::selectMediaURL): Return a ContentType instead of raw MIME type.
+ (WebCore::HTMLMediaElement::initialURL): selectMediaURL returns a ContentType.
+ * html/HTMLMediaElement.h: Add prototype.
+ * html/HTMLMediaElement.idl: Ditto.
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::load): Take a ContentType instead of raw MIME type.
+ (WebCore::MediaPlayer::supportsType): Ditto.
+ * platform/graphics/MediaPlayer.h:
+
+2009-03-04 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24359
+ Repaint throttling mechanism
+
+ Excessive repainting can slow down page loadind. This implements a timer
+ based throttling mechanism. It is behind ENABLE(REPAINT_THROTTLING) and not
+ enabled by default.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::checkCompleted):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::dispatchDragEvent):
+ (WebCore::EventHandler::dispatchMouseEvent):
+ (WebCore::EventHandler::keyEvent):
+ (WebCore::EventHandler::handleTextInputEvent):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::FrameView):
+ (WebCore::FrameView::reset):
+ (WebCore::FrameView::repaintContentRectangle):
+ (WebCore::FrameView::beginDeferredRepaints):
+ (WebCore::FrameView::endDeferredRepaints):
+ (WebCore::FrameView::checkStopDelayingDeferredRepaints):
+ (WebCore::FrameView::doDeferredRepaints):
+ (WebCore::FrameView::updateDeferredRepaintDelay):
+ (WebCore::FrameView::resetDeferredRepaintDelay):
+ (WebCore::FrameView::adjustedDeferredRepaintDelay):
+ (WebCore::FrameView::deferredRepaintTimerFired):
+ (WebCore::FrameView::paintContents):
+ * page/FrameView.h:
+
+2009-03-04 Sam Weinig <sam@webkit.org>
+
+ Rubber-stamped by Antti Koivisto.
+
+ Remove LOW_BANDWIDTH_DISPLAY as it is not being used by any platforms.
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ * dom/Document.h:
+ (WebCore::Document::haveStylesheetsLoaded):
+ * html/HTMLTokenizer.cpp:
+ (WebCore::HTMLTokenizer::scriptHandler):
+ * loader/Cache.cpp:
+ (WebCore::Cache::requestResource):
+ * loader/CachedCSSStyleSheet.cpp:
+ (WebCore::CachedCSSStyleSheet::checkNotify):
+ * loader/DocLoader.h:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::FrameLoader):
+ (WebCore::FrameLoader::requestFrame):
+ (WebCore::FrameLoader::stopLoading):
+ (WebCore::FrameLoader::begin):
+ (WebCore::FrameLoader::write):
+ (WebCore::FrameLoader::endIfNotLoadingMainResource):
+ (WebCore::FrameLoader::checkCompleted):
+ (WebCore::FrameLoader::requestObject):
+ (WebCore::FrameLoader::loadItem):
+ * loader/FrameLoader.h:
+
+2009-03-02 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24287
+ [GTK] Move auth dialog feature to WebKit/
+
+ Remove WebKitSoupAuthDialog files from build and stop using it.
+
+ * GNUmakefile.am:
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ensureSessionIsInitialized):
+ * platform/network/soup/webkit-soup-auth-dialog.c: Removed.
+ * platform/network/soup/webkit-soup-auth-dialog.h: Removed.
+
+2009-03-04 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24361
+
+ Reinstate code that sets result.innerNode when hitTest() returns true,
+ but never filled in the innerNode. Fixes hit testing of generated content.
+
+ Test: fast/css-generated-content/hit-test-generated-content.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestContents):
+
+2009-03-04 Adam Barth <abath@webkit.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24356
+
+ Fix WebKit style for allowUniversalAccessFromFileURLs.
+
+ * WebCore.base.exp:
+ * dom/Document.cpp:
+ (WebCore::Document::initSecurityContext):
+ * page/Settings.cpp:
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setAllowUniversalAccessFromFileURLs):
+ * page/Settings.h:
+ (WebCore::Settings::allowUniversalAccessFromFileURLs):
+
+2009-03-04 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Darin Adler
+
+ <rdar://problem/6619630> Quick Look of vCards stuck on image of first card opened.
+
+ I narrowed this down to http://trac.webkit.org/changeset/39304 which, among other things,
+ consolidated some of the various decision making pieces of the Cache into the new method
+ FrameLoader::cachePolicy().
+
+ Before 39304, when deciding whether to use an existing CachedResource, we checked if the FrameLoader
+ is reloading. If it is, we'd evict any existing resource then recreate it. Quick looks uses the
+ same URL for this image every time and expects it to be reloaded with each new card.
+
+ The FrameLoader::isReloading() check did one thing - Ask the DocumentLoader if it's cache policy
+ is "ReloadIgnoringCacheData". This check was lost in the consolidation to the new method.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::cachePolicy): Restore the DocumentLoader's cachePolicy check as a possible
+ condition for returning CachePolicyReload.
+
+2009-03-04 Timothy Hatcher <timothy@apple.com>
+
+ * English.lproj/localizedStrings.js: Update strings to include "DATABASES",
+ "LOCAL STORAGE" and "SESSION STORAGE".
+
+2009-03-04 Timothy Hatcher <timothy@apple.com>
+
+ Fix a regression where the Web Inspector console would not animate
+ in or out correctly.
+
+ Reviewed by Anders Carlsson.
+
+ * inspector/front-end/inspector.css: Move a z-index to a child element
+ to get the correct stacking order during the animation.
+
+2009-03-03 David Hyatt <hyatt@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=24201, pathologically bad block layout.
+
+ Make sure to factor clear deltas into y position estimates. Also avoid doing the comparison of
+ the final position against the y position estimate until after the clear has happened. This gets rid
+ of some duplicated cut/pasted code and also ensures a layout delta only has to be put in once.
+
+ Reviewed by Dan Bernstein
+
+ Added fast/block/float/nested-clearance.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::collapseMargins):
+ (WebCore::RenderBlock::clearFloatsIfNeeded):
+ (WebCore::RenderBlock::estimateVerticalPosition):
+ (WebCore::RenderBlock::layoutBlockChildren):
+ (WebCore::RenderBlock::getClearDelta):
+ * rendering/RenderBlock.h:
+
+2009-03-02 Kim Grönholm <kim.gronholm@nomovok.com>
+
+ Reviewed by Simon Hausmann.
+
+ Improvement to 3d transformations rendering in QtWebKit. QTransform is used
+ instead of QMatrix. This allows perspective transformations since QTransform is
+ a true 3x3 matrix.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp: Use QTransform instead of QMatrix everywhere.
+ (WebCore::GraphicsContext::getCTM):
+ (WebCore::GraphicsContext::restorePlatformState):
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ (WebCore::GraphicsContext::fillRect):
+ (WebCore::GraphicsContext::translate):
+ (WebCore::GraphicsContext::rotate):
+ (WebCore::GraphicsContext::scale):
+ (WebCore::GraphicsContext::concatCTM):
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::Image::drawPattern):
+ * platform/graphics/qt/PathQt.cpp:
+ (WebCore::Path::translate):
+ (WebCore::Path::transform):
+ * platform/graphics/qt/PatternQt.cpp:
+ (WebCore::Pattern::createPlatformPattern):
+ * platform/graphics/qt/TransformationMatrixQt.cpp:
+ (WebCore::TransformationMatrix::operator QTransform): Replace the conversion operator
+ to QMatrix with one to QTransform.
+ * platform/graphics/transforms/TransformationMatrix.h:
+ * platform/graphics/qt/FontQt.cpp:
+
+2009-02-24 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24151
+ Fix Qt/S60 build break
+
+ * platform/FileSystem.h: Create a default case for non-win and non-mac Qt builds
+ * platform/qt/FileSystemQt.cpp: Ditto
+ (WebCore::unloadModule):
+
+2009-03-03 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=21939
+ Uninitialized ExceptionCode in DOMWindow::postMessage
+
+ * dom/MessagePort.cpp:
+ (WebCore::MessagePort::postMessage):
+
+2009-03-03 David Kilzer <ddkilzer@apple.com>
+
+ <rdar://problem/6581203> WebCore and WebKit should install the same set of headers during installhdrs phase as build phase
+
+ Reviewed by Mark Rowe.
+
+ The fix is to add INSTALLHDRS_COPY_PHASE = YES and
+ INSTALLHDRS_SCRIPT_PHASE = YES to WebCore.xcconfig, then to make
+ sure various build phase scripts work with the installhdrs build
+ phase.
+
+ * Configurations/Base.xcconfig: Defined REAL_PLATFORM_NAME
+ based on PLATFORM_NAME to work around the missing definition on
+ Tiger.
+ * Configurations/WebCore.xcconfig: Added
+ JAVASCRIPTCORE_PRIVATE_HEADERS_DIR variable to simplify logic in
+ the "Generate Derived Sources" script. Added
+ INSTALLHDRS_COPY_PHASE = YES and INSTALLHDRS_SCRIPT_PHASE = YES.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ - Added shell code to prevent running "Check For Global
+ Initializers", "Check For Exit Time Destructors" and "Check
+ For Weak VTables" scripts during the installhdrs build phase.
+ - Made "Generate Derived Sources" work for the installhdrs build
+ phase. Also simplified setting of CREATE_HASH_TABLE by using
+ JAVASCRIPTCORE_PRIVATE_HEADERS_DIR.
+
+2009-03-02 Adam Langley <agl@google.com>
+
+ Reviewed by Darin Fisher.
+
+ Chromium Linux: Switch to using Skia to render widgets.
+
+ In order to sandbox the Chromium renderer on Linux we need to remove
+ the X connection. GTK cannot render without an X connection so, for
+ now, we render widgets ourselves.
+
+ Previously didn't use anti-alias fonts in order to match Windows font
+ rendering exactly. This was helpful when bootstrapping our layout
+ tests. Now, however, we are ready to enable it.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24244
+
+ * platform/chromium/ScrollbarThemeChromium.cpp:
+ (WebCore::ScrollbarThemeChromium::buttonSize):
+ * platform/chromium/ScrollbarThemeChromiumLinux.cpp:
+ (WebCore::ScrollbarThemeChromium::scrollbarThickness):
+ (WebCore::ScrollbarThemeChromium::paintTrackPiece):
+ (WebCore::ScrollbarThemeChromium::paintButton):
+ (WebCore::ScrollbarThemeChromium::paintThumb):
+ * platform/graphics/chromium/FontPlatformDataLinux.cpp:
+ (WebCore::FontPlatformData::setupPaint):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::PlatformContextSkia):
+ (PlatformContextSkia::~PlatformContextSkia):
+ * platform/graphics/skia/PlatformContextSkia.h:
+ * rendering/RenderThemeChromiumGtk.cpp: Removed.
+ * rendering/RenderThemeChromiumGtk.h: Removed.
+ * rendering/RenderThemeChromiumLinux.cpp: Added.
+ * rendering/RenderThemeChromiumLinux.h: Added.
+
+2009-03-03 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24261
+ Fix return types.
+
+ Test: LayoutTests/dom/svg/level3/xpath/XPathEvaluator_evaluate_TYPE_ERR.svg
+
+ * bindings/v8/V8Binding.h:
+ (WebCore::toInt32): change return type to int
+ (WebCore::toFloat): change return type to float.
+
+2009-03-03 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by John Sullivan.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22884
+ <rdar://problem/6449783>
+ modified layout test crashes Safari
+
+ Null check NPStream before dereferencing it.
+
+ * plugins/PluginView.cpp:
+ (WebCore::PluginView::destroyStream):
+
+2009-03-03 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Fix for <rdar://problem/6641045>
+ Don't call QTKit to get movie properties until movie metadata has been loaded.
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+ (WebCore::MediaPlayerPrivate::metaDataAvailable): defined
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::createQTTime): return default if !metaDataAvailable.
+ (WebCore::MediaPlayerPrivate::play): Ditto.
+ (WebCore::MediaPlayerPrivate::pause): Ditto.
+ (WebCore::MediaPlayerPrivate::duration): Ditto.
+ (WebCore::MediaPlayerPrivate::currentTime): Ditto.
+ (WebCore::MediaPlayerPrivate::seek): Ditto.
+ (WebCore::MediaPlayerPrivate::seekTimerFired): Ditto.
+ (WebCore::MediaPlayerPrivate::paused): Ditto.
+ (WebCore::MediaPlayerPrivate::seeking): Ditto.
+ (WebCore::MediaPlayerPrivate::naturalSize): Ditto.
+ (WebCore::MediaPlayerPrivate::hasVideo): Ditto.
+ (WebCore::MediaPlayerPrivate::setVolume): Ditto.
+ (WebCore::MediaPlayerPrivate::setRate): Ditto.
+ (WebCore::MediaPlayerPrivate::dataRate): Ditto.
+ (WebCore::MediaPlayerPrivate::maxTimeLoaded): Ditto.
+ (WebCore::MediaPlayerPrivate::totalBytes): Ditto.
+
+2009-03-03 Kevin McCullough <kmccullough@apple.com>
+
+ - Spelling fix.
+
+ * page/Console.cpp:
+ (WebCore::Console::profile):
+
+2009-03-03 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23657
+ Remove Database API callback IDLs from the project.
+ They were removed in r40633.
+
+ * WebCore.xcodeproj/project.pbxproj: Removed IDL files from the project.
+
+2009-03-03 Kevin McCullough <kmccullough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6639110> console.profile() doesn't work without a title
+
+ * page/Console.cpp:
+ (WebCore::Console::profile): If there is no title assume this is a user
+ initiated profile and give it the next incremented title name.
+
+2009-03-03 Timothy Hatcher <timothy@apple.com>
+
+ Fix a regression that broke dirxml and caused an ASSERT in debug builds. Also simplified
+ the console code and refactored things to have fewer code paths and duplication.
+
+ rdar://problem/6367127
+ https://bugs.webkit.org/show_bug.cgi?id=24329
+
+ Reviewed by Kevin McCullough.
+
+ Test: manual-tests/inspector/console-dir.html
+
+ * bindings/js/JSInspectedObjectWrapper.cpp:
+ (WebCore::JSInspectedObjectWrapper::wrap): Use the lexicalGlobalObject instead of dynamicGlobalObject
+ to fix an ASSERT about using a wrapper from the wrong ExecState.
+ * bindings/js/JSQuarantinedObjectWrapper.cpp:
+ (WebCore::JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper): Ditto.
+ (WebCore::JSQuarantinedObjectWrapper::allowsUnwrappedAccessFrom): Ditto.
+ * inspector/front-end/Console.js:
+ (WebInspector.Console.prototype._format): Remove the inline argument and add forceObjectFormat.
+ When forceObjectFormat is true, the only formatter used is _formatobject.
+ (WebInspector.Console.prototype._formatvalue): Remove the inline argument.
+ (WebInspector.Console.prototype._formatstring): Ditto.
+ (WebInspector.Console.prototype._formatregexp): Ditto.
+ (WebInspector.Console.prototype._formatarray): Ditto.
+ (WebInspector.Console.prototype._formatnode): Remove the inline argument and make a DOM tree instead of an anchor.
+ (WebInspector.Console.prototype._formatobject): Remove the inline argument and always make a property graph.
+ (WebInspector.Console.prototype._formaterror): Remove the inline argument.
+ (WebInspector.ConsoleMessage): Remove the case for MessageLevel.Node and
+ simplify the case for MessageLevel.Object to use the normal _format code path with the %O formatter.
+ (WebInspector.ConsoleMessage.prototype._format.formatForConsole): Don't pass an additional true argument for inline.
+ (WebInspector.ConsoleMessage.prototype._format.formatAsObjectForConsole): Added. Pass a true argument for forceObjectFormat.
+ (WebInspector.ConsoleMessage.prototype._format): Added support for the %O formatter. Use formatForConsole for all arguments.
+ (WebInspector.ConsoleMessage.prototype.toString): Add the other message levels.
+ * inspector/front-end/inspector.css: Tweak styles to look and work correctly.
+ * inspector/front-end/utilities.js:
+ (Object.type): Return "node" for Node objects.
+ (Object.describe): Handle the "node" type.
+ * page/Console.cpp:
+ (WebCore::printMessageSourceAndLevelPrefix): Fix an assert by adding the other message level types.
+ (WebCore::Console::dirxml): Use the standard log fuction since it prints a DOM tree for nodes by default.
+ * page/Console.h:
+ (WebCore::enum MessageLevel): Removed NodeMessageLevel. Added a FIXME.
+
+2009-03-03 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24325
+ Crash on replacing document contents during drop.
+
+ Makes sure a node is in the document during a move before using it.
+
+ Test: fast/events/crash-on-mutate-during-drop.html
+
+ * editing/MoveSelectionCommand.cpp:
+ (WebCore::MoveSelectionCommand::doApply):
+
+2009-03-03 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23028
+ Enable dynamic web font support to Chromium on Windows.
+ Files that were omitted by mistake in the latest patch
+ that was landed.
+
+ * loader/CachedFont.cpp:
+ (WebCore::CachedFont::~CachedFont):
+ (WebCore::CachedFont::ensureCustomFontData):
+ (WebCore::CachedFont::platformDataFromCustomData):
+ (WebCore::CachedFont::allClientsRemoved):
+ * platform/graphics/chromium/FontCustomPlatformData.cpp:
+ (WebCore::EOTStream::EOTStream):
+ (WebCore::createFontCustomPlatformData):
+ * platform/graphics/win/FontCustomPlatformData.cpp:
+ (WebCore::EOTStream::EOTStream):
+ (WebCore::createFontCustomPlatformData):
+
+2009-03-03 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=16826
+ [Gtk] Implement WebKitDownload
+
+ Make the Soup backend able to handle requests without a frame,
+ since we may have such things now that we support downloads.
+
+ * platform/network/ResourceHandleInternal.h:
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::start):
+
+2009-03-03 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24331
+ Add custom V8 bindings for Element, Attr, HTMLFrame, and HTMLIFrame.
+
+ * bindings/v8/custom/V8AttrCustom.cpp: Added.
+ * bindings/v8/custom/V8CustomBinding.cpp: Added.
+ * bindings/v8/custom/V8CustomBinding.h: Added attribute-checking helpers.
+ * bindings/v8/custom/V8ElementCustom.cpp: Added.
+ * bindings/v8/custom/V8HTMLFrameElementCustom.cpp: Added.
+ * bindings/v8/custom/V8HTMLIFrameElementCustom.cpp: Added.
+
+2009-03-03 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Darin Adler
+
+ <rdar://problem/6616664> - Quick looks of various file types is broken
+
+ In http://trac.webkit.org/changeset/40553 there was an attempt to prevent NSURLRequest churn
+ for non-HTTP loads when the underlying ResourceRequest changed. Unfortunately it was a little
+ overzealous as the mainDocumentURL is relevant for all loads, not only HTTP/HTTPS loads.
+
+ Partially reverted behavior to always set the mainDocumentURL in situations when we would've
+ before that patch.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::addExtraFieldsToRequest):
+
+ * platform/network/ResourceRequestBase.cpp:
+ (WebCore::ResourceRequestBase::setMainDocumentURL):
+
+2009-03-03 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24256
+
+ Added a WebCoreForceSoftwareAnimation flag.
+
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::forceSoftwareAnimation):
+ (WebCore::GraphicsLayerCA::setOpacity):
+ (WebCore::GraphicsLayerCA::animateTransform):
+ (WebCore::GraphicsLayerCA::animateFloat):
+
+2009-03-02 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24257
+
+ Added prototype properties for several classes with constructors that
+ were missing them, including the one mentioned in the bug.
+
+ Test: fast/dom/Window/custom-constructors.html
+
+ * bindings/js/JSAudioConstructor.cpp:
+ (WebCore::JSAudioConstructor::JSAudioConstructor):
+ * bindings/js/JSDOMWindowBase.cpp:
+ (jsDOMWindowBaseWebKitCSSMatrix):
+ * bindings/js/JSImageConstructor.cpp:
+ (WebCore::JSImageConstructor::JSImageConstructor):
+ * bindings/js/JSOptionConstructor.cpp:
+ (WebCore::JSOptionConstructor::JSOptionConstructor):
+ * bindings/js/JSWebKitCSSMatrixConstructor.cpp:
+ (WebCore::JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor):
+ * bindings/js/JSWebKitCSSMatrixConstructor.h:
+ * bindings/js/JSWebKitPointConstructor.cpp:
+ (WebCore::JSWebKitPointConstructor::JSWebKitPointConstructor):
+ * bindings/js/JSWorkerConstructor.cpp:
+ (WebCore::JSWorkerConstructor::JSWorkerConstructor):
+
+2009-03-03 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24321
+ Add V8 bindings headers.
+
+ * bindings/v8/V8Binding.h: Added.
+ * bindings/v8/V8Proxy.h: Added.
+ * bindings/v8/custom/V8CustomBinding.h: Added.
+ * bindings/v8/custom/V8CustomEventListener.h: Added.
+
+2009-03-03 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23803
+ Fix an 'off-by-1' error in ChromiumWin's font fallback.
+
+ * platform/graphics/chromium/FontCacheChromiumWin.cpp:
+ (WebCore::FontCache::getFontDataForCharacters):
+
+2009-03-03 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ http://bugs.webkit.org/show_bug.cgi?id=23028
+ Enable dynamic web font support to Chromium on Windows: Part 1
+ - Move OpenTypeUtilities.{cpp,h} to platform/graphics/opentype
+ from platform/graphics/win because both Windows port and Chromium Windows
+ port will use them.
+ - Adjust WebCore.vcproj accordingly.
+
+ * WebCore.vcproj/WebCore.vcproj:
+ * platform/graphics/opentype: Added.
+ * platform/graphics/opentype/OpenTypeUtilities.cpp: Copied from WebCore/platform/graphics/win/OpenTypeUtilities.cpp.
+ * platform/graphics/opentype/OpenTypeUtilities.h: Copied from WebCore/platform/graphics/win/OpenTypeUtilities.h.
+ * platform/graphics/win/OpenTypeUtilities.cpp: Removed.
+ * platform/graphics/win/OpenTypeUtilities.h: Removed.
+
+2009-03-03 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24312
+
+ Take 3D transforms into account when hit testing:
+
+ 1. Maintain a bit on each RenderLayer that is set when the layer
+ has 3d descendants, so that we know when to fall into the slow
+ hit testing path.
+
+ 2. Make a ref-counted HitTestingTransformState, which is used to store
+ an accumulated transform, and the hit test point, and hitTestRect
+ in the plane of the ancestor non-3d ('flattening') layer.
+
+ It's ref-counted so we can heap allocate it (to avoid stack bloat),
+ and avoid copying when hitTestLayer calls itself after applying the transform.
+
+ 3. Add logic to hitTestLayer to depth-test just direct descendants, if any have
+ 3D transforms, or to do deep depth-testing when traversing a preserves-3d
+ hierarchy. When hit, layers compute a z-offset from the ancestor flattening
+ layer, which allows for correct depth testing.
+
+ The existing early-return codepath is unaffected when there are no 3d transforms
+ and no preserve-3d.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::updateTransform):
+ (WebCore::RenderLayer::dirty3DTransformedDescendantStatus):
+ (WebCore::RenderLayer::update3DTransformedDescendantStatus):
+ (WebCore::RenderLayer::hitTest):
+ (WebCore::computeZOffset):
+ (WebCore::RenderLayer::createLocalTransformState):
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::hitTestContents):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::preserves3D):
+ (WebCore::RenderLayer::has3DTransform):
+ (WebCore::RenderLayer::setHas3DTransformedDescendant):
+ (WebCore::RenderLayer::has3DTransformedDescendant):
+ * rendering/RenderLayerBacking.cpp:
+ * rendering/TransformState.cpp:
+ (WebCore::TransformState::flatten):
+ (WebCore::TransformState::mappedPoint):
+ (WebCore::HitTestingTransformState::move):
+ (WebCore::HitTestingTransformState::applyTransform):
+ (WebCore::HitTestingTransformState::flatten):
+ (WebCore::HitTestingTransformState::mappedPoint):
+ (WebCore::HitTestingTransformState::mappedQuad):
+ * rendering/TransformState.h:
+ (WebCore::TransformState::TransformState):
+ (WebCore::HitTestingTransformState::create):
+ (WebCore::HitTestingTransformState::move):
+ (WebCore::HitTestingTransformState::HitTestingTransformState):
+
+2009-03-03 Brett Wilson <brettw@chromium.org>
+
+ Fix uninitialized memory reads in the Chromium Windows transparency
+ code that were identified by Purify,
+
+ Reviewed by Darin Fisher.
+
+ * platform/graphics/chromium/TransparencyWin.cpp:
+ (WebCore::TransparencyWin::OwnedBuffers::OwnedBuffers):
+ (WebCore::TransparencyWin::initializeNewContext):
+
+2009-03-03 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24312
+
+ Factor the code that compute a transform relative to the container
+ into RenderObject::transformFromContainer().
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::mapLocalToAbsolutePoint):
+ (WebCore::RenderBox::mapAbsoluteToLocalPoint):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::transformFromContainer):
+ * rendering/RenderObject.h:
+
+2009-03-03 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24317
+
+ Always return |true| from RenderTextControlMultiLine::nodeAtPoint() if
+ the superclass found a node, otherwise we set the innerNode of the
+ HitTestResult, but don't actually report that we found a hit.
+
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::nodeAtPoint):
+
+2009-03-03 Onne Gorter <onne.gorter@avinity.net>
+
+ Reviewed by Anders Carlsson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23707
+ resizing plugins does not work, because the plugin never gets informed
+
+ Make gtk plugins resize correctly, by sending them the setwindow event
+ correctly. Also ensure that all plugin eventing is done with correct
+ locking/calling. Mostly copied from mac implementation.
+
+ manual test: manual-tests/gtk/plugin-resize-scroll.html
+
+ * plugins/PluginView.h:
+ * plugins/gtk/PluginViewGtk.cpp:
+ (WebCore::PluginView::dispatchNPEvent):
+ ensure locking/calling for NPEvents
+ (WebCore::PluginView::updatePluginWidget):
+ if something changed, let setNPWindowIfNeeded handle it
+ (WebCore::PluginView::paint):
+ (WebCore::PluginView::handleKeyboardEvent):
+ (WebCore::PluginView::handleMouseEvent):
+ ensure calling conventions
+ (WebCore::PluginView::setNPWindowRect):
+ just pass control to setNPWindowIfNeeded
+ (WebCore::PluginView::setNPWindowIfNeeded):
+ event the plugin correctly of new window
+ (WebCore::PluginView::init):
+ init through the new setup
+
+2009-03-03 Mike Belshe <mike@belshe.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24311
+ Make IDL returning DOMObject use [V8Custom]
+
+ * dom/Document.idl:
+ * html/HTMLCanvasElement.idl:
+
+2009-03-02 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Adele Peterson
+
+ https://bugs.webkit.org/show_bug.cgi?id=24313
+
+ If RenderTextControlSingleLine::nodeAtPoint() pokes a node into the
+ HitTestResult, then it had better well return |true|. And m_innerBlock
+ could never have been set as the hit node by the superclass, because
+ the superclass knows nothing about m_innerBlock.
+
+ Test: fast/forms/input-hit-test-border.html
+
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::nodeAtPoint):
+
+2009-03-02 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Enable Geolocation (except on Tiger and Leopard).
+
+ * Configurations/WebCore.xcconfig:
+
+2009-03-02 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Adele Peterson.
+
+ Fix https://bugs.webkit.org/show_bug.cgi?id=24307
+ Null out m_highlightedNode on hideHighlight().
+ Ran WebCore/manual-tests/inspector/highlight-nodes.html.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::hideHighlight):
+
+2009-03-02 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix for <rdar://problem/6507404> Add Geolocation support.
+
+ This is not yet turned on for any Mac platform.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/Chrome.cpp:
+ (WebCore::Chrome::shouldAllowGeolocationForFrame):
+ * page/Chrome.h:
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::shouldAllowGeolocationForFrame):
+ * page/Geolocation.cpp:
+ (WebCore::Geolocation::Geolocation):
+ (WebCore::Geolocation::disconnectFrame): Remove call to setUsingGeolocation as the document
+ will not be alive at this point.
+ (WebCore::Geolocation::getCurrentPosition): Check if the embedding app allows geolocation and
+ return a PERMISSION_DENIED if not.
+ (WebCore::Geolocation::watchPosition): Ditto.
+ (WebCore::Geolocation::shouldAllowGeolocation): Perform request to embedding layer of whether
+ to allow geolocation and cache the result.
+ * page/Geolocation.h:
+ (WebCore::Geolocation::):
+ * platform/GeolocationService.cpp:
+ * platform/GeolocationService.h:
+ (WebCore::GeolocationService::~GeolocationService):
+ (WebCore::GeolocationService::stopUpdating):
+ * platform/mac/GeolocationServiceMac.h: Added.
+ (WebCore::GeolocationServiceMac::lastPosition):
+ (WebCore::GeolocationServiceMac::lastError):
+ * platform/mac/GeolocationServiceMac.mm: Added.
+ (WebCore::GeolocationService::create):
+ (WebCore::GeolocationServiceMac::GeolocationServiceMac):
+ (WebCore::GeolocationServiceMac::~GeolocationServiceMac):
+ (WebCore::GeolocationServiceMac::startUpdating):
+ (WebCore::GeolocationServiceMac::stopUpdating):
+ (WebCore::GeolocationServiceMac::suspend):
+ (WebCore::GeolocationServiceMac::resume):
+ (WebCore::GeolocationServiceMac::positionChanged):
+ (WebCore::GeolocationServiceMac::errorOccurred):
+ (-[WebCoreCoreLocationObserver initWithCallback:]):
+ (-[WebCoreCoreLocationObserver locationManager:didUpdateToLocation:fromLocation:]):
+ (-[WebCoreCoreLocationObserver locationManager:didFailWithError:]):
+
+2009-03-02 Kevin Ollivier <kevino@theolliviers.com>
+
+ Build fixes for wxWidgets Mac trunk build.
+
+ * platform/wx/wxcode/mac/carbon/fontprops.cpp:
+ (wxFontProperties::wxFontProperties):
+ (GetTextExtent):
+ * webcore-wx.bkl:
+
+2009-03-02 Kevin Ollivier <kevino@theolliviers.com>
+
+ wxGTK missing header build fix.
+
+ * platform/wx/wxcode/gtk/fontprops.cpp:
+
+2009-03-02 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Adam Roben.
+
+ - fix https://bugs.webkit.org/show_bug.cgi?id=21811
+ REGRESSION: Windows Build Not Selecting Proper Font
+
+ * platform/graphics/win/FontCacheWin.cpp:
+ (WebCore::createGDIFont): Added back code to verify that the created
+ HFONT has the requested face name.
+
+2009-03-02 Timothy Hatcher <timothy@apple.com>
+
+ Fixes a regression caused by splitting the input and output of console commands.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24293
+
+ Reviewed by Kevin McCullough.
+
+ * inspector/front-end/Console.js:
+ (WebInspector.Console.prototype.addMessage): Don't treat ConsoleCommandResult as a
+ normal ConsoleMessage when appending. This prevents resetting repeatCounts incorrectly.
+
+2009-03-02 Timothy Hatcher <timothy@apple.com>
+
+ Make exception messages and logged Error objects display consistently.
+
+ https://bugs.webkit.org/show_bug.cgi?id=18983
+
+ Reviewed by Adam Roben.
+
+ * English.lproj/localizedStrings.js: Remove a string for line numbers.
+ * inspector/front-end/Console.js:
+ (WebInspector.Console.prototype._enterKeyPressed): Pass the exception
+ boolean to the ConsoleCommandResult constructor and don't pass level.
+ (WebInspector.Console.prototype._formatnode): Fix a className typo.
+ (WebInspector.Console.prototype._formaterror): Add an error-message
+ classed span around the message to show in red and remove the
+ console-message-url class from the link so it doesn't float right.
+ Instead enclose the link in parentheses and use displayNameForURL
+ to shorten the URL in the link.
+ (WebInspector.ConsoleMessage.prototype.toMessageElement): Simplify
+ how line numbers are shown since link underlining a string with
+ parentheses looks bad.
+ (WebInspector.ConsoleCommandResult): Take an exception boolean flag
+ instead of a level and get line and URL based on that flag.
+ * inspector/front-end/inspector.css: Tweaks to the styles.
+
+2009-03-02 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Adele Peterson.
+
+ Bug 24048: extra windows button padding doesn't apply when there's no appearance
+ <https://bugs.webkit.org/show_bug.cgi?id=24048>
+
+ Replace adjustButtonInnerStyle with buttonInternalPaddingLeft/Right/Top/Bottom.
+
+ No tests added as existing tests already cover this behavior.
+
+ * rendering/RenderButton.cpp:
+ (WebCore::RenderButton::setupInnerStyle):
+ * rendering/RenderTheme.cpp:
+ * rendering/RenderTheme.h:
+ (WebCore::RenderTheme::buttonInternalPaddingLeft):
+ (WebCore::RenderTheme::buttonInternalPaddingRight):
+ (WebCore::RenderTheme::buttonInternalPaddingTop):
+ * rendering/RenderThemeChromiumGtk.cpp:
+ (WebCore::RenderThemeWin::buttonInternalPaddingLeft):
+ (WebCore::RenderThemeWin::buttonInternalPaddingRight):
+ (WebCore::RenderThemeWin::buttonInternalPaddingTop):
+ (WebCore::RenderThemeWin::buttonInternalPaddingBottom):
+ * rendering/RenderThemeChromiumGtk.h:
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::RenderThemeChromiumWin::buttonInternalPaddingLeft):
+ (WebCore::RenderThemeChromiumWin::buttonInternalPaddingRight):
+ (WebCore::RenderThemeChromiumWin::buttonInternalPaddingTop):
+ (WebCore::RenderThemeChromiumWin::buttonInternalPaddingBottom):
+ * rendering/RenderThemeChromiumWin.h:
+ * rendering/RenderThemeWin.cpp:
+ (WebCore::RenderThemeWin::buttonInternalPaddingLeft):
+ (WebCore::RenderThemeWin::buttonInternalPaddingRight):
+ (WebCore::RenderThemeWin::buttonInternalPaddingTop):
+ (WebCore::RenderThemeWin::buttonInternalPaddingBottom):
+ * rendering/RenderThemeWin.h:
+
+2009-03-02 Adam Treat <adam.treat@torchmobile.com>
+
+ Build fix for Qt port. Remove unnecessary assert.
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::putImageData):
+
+2009-03-02 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Adam Roben and previously by Eric Seidel and Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24227
+ Ensure that the checkForSolidColor() optimization is correctly triggered
+ for all cases of drawPattern. Currently, the optimization was not triggered
+ when the check had not been previously performed via a request for the
+ image's NativeImagePtr.
+
+ Implement the Qt version of the checkForSolidColor() method. Combined with
+ the bug fix this reduces the time it takes to draw a repeating background
+ of a 1x1 image from ~50msecs to ~0msecs on my machine.
+
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ * platform/graphics/BitmapImage.h:
+ (WebCore::BitmapImage::mayFillWithSolidColor):
+ * platform/graphics/Image.h:
+ (WebCore::Image::mayFillWithSolidColor):
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/cg/ImageCG.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/wx/ImageWx.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+
+2009-03-02 Gustavo Noronha Silva <gns@gnome.org>
+
+ Unreviewed build fix; adding missing files to EXTRA_DIST, so that
+ they show up in the tarball.
+
+ * GNUmakefile.am:
+
+2009-03-02 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ Added putImageData to Qt. Discussed with Ariya Hidayat.
+
+ [Qt] lacks putImageData support in Canvas
+ https://bugs.webkit.org/show_bug.cgi?id=22186
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::putImageData):
+
+2009-03-02 Timothy Hatcher <timothy@apple.com>
+
+ Show exception messages again when evaluating bad expressions in the
+ Web Inspector's console.
+
+ https://bugs.webkit.org/show_bug.cgi?id=19890
+
+ Reviewed by Oliver Hunt.
+
+ * bindings/js/JSQuarantinedObjectWrapper.cpp:
+ (WebCore::JSQuarantinedObjectWrapper::transferExceptionToExecState):
+ Fix the order in which the exception is set and cleared now that the
+ exception is stored in the shared GlobalData, not per ExecState.
+
+2009-02-28 Timothy Hatcher <timothy@apple.com>
+
+ Make input in the Web Inspector console print before any output
+ that might be added by the called function.
+
+ https://bugs.webkit.org/show_bug.cgi?id=19931
+
+ Reviewed by Oliver Hunt.
+
+ * inspector/front-end/Console.js:
+ (WebInspector.Console.prototype._enterKeyPressed): Add the command
+ message before evaluating the result. Associate the originating
+ command to the result, so if they are adjacent there is no divider.
+ (WebInspector.ConsoleCommand): No longer take a result.
+ (WebInspector.ConsoleCommand.prototype.toMessageElement): Result
+ code removed since it isn't used now.
+ (WebInspector.ConsoleCommandResult): Subclass ConsoleMessage.
+ (WebInspector.ConsoleCommandResult.prototype.toMessageElement):
+ Call the ConsoleMessage toMessageElement and add a style class.
+ * inspector/front-end/inspector.css: Add a new style class for
+ adjacent results to hide the divider. Also tweak the position of
+ the disclosure triangle for objects to not use the left margin.
+
+2009-03-01 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 24282: AX Palindrome error when asking for a specific index of the AXChildren array
+ <https://bugs.webkit.org/show_bug.cgi?id=24282>
+
+ When fetching an array of elements with a range, attachment views need to be returned
+ instead of the actual attachment.
+
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (-[AccessibilityObjectWrapper accessibilityIndexOfChild:]):
+ (-[AccessibilityObjectWrapper accessibilityArrayAttributeValues:index:maxCount:]):
+
+2009-03-01 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Bug 24251: Cleanup: replace positionForCoordinates with positionForPoint
+ <https://bugs.webkit.org/show_bug.cgi?id=24251>
+
+ Make RenderObject::positionForCoordinate non-virtual and
+ RenderObject::positionForPoint virtual in preparation for
+ removing positionFor* from RenderObject/RenderText.
+
+ * page/Frame.cpp:
+ (WebCore::Frame::visiblePositionForPoint):
+ * rendering/RenderBR.cpp:
+ (WebCore::RenderBR::positionForPoint):
+ * rendering/RenderBR.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::positionForPoint):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::positionForPoint):
+ * rendering/RenderBox.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::positionForPoint):
+ * rendering/RenderInline.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::positionForCoordinates):
+ (WebCore::RenderObject::positionForPoint):
+ * rendering/RenderObject.h:
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::positionForPoint):
+ * rendering/RenderReplaced.h:
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::positionForPoint):
+ * rendering/RenderSVGInlineText.h:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::positionForPoint):
+ * rendering/RenderText.h:
+
+2009-03-01 Larry Ewing <lewing@novell.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24080
+ NPN_GetValue casting to the wrong type and writing outside bounds
+
+ Make sure to cast the value to the correct type so that only
+ memory owned by the value is written to.
+
+ * plugins/gtk/PluginViewGtk.cpp (PluginView::getValueStatic):
+ * plugins/qt/PluginViewQt.cpp (PluginView::getValueStatic):
+ * plugins/mac/PluginViewMac.cpp (PluginView::getValueStatic):
+ (PluginView::getValue):
+
+2009-03-01 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24197 and
+ https://bugs.webkit.org/show_bug.cgi?id=23512
+
+ The Windows version of cgColor() is conditionally compiled using
+ !PLATFORM(MAC) change this to PLATFORM(WIN_OS) so that Chrome
+ can use the OS X version instead of the Windows version.
+
+ Also rename cgColor() -> createCGColor()
+
+ No observable change in behavior, so no test.
+
+ * platform/graphics/Color.h:
+ * platform/graphics/cg/ColorCG.cpp:
+ (WebCore::createCGColor):
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ (WebCore::GraphicsContext::setPlatformShadow):
+ * platform/graphics/mac/ColorMac.mm:
+ (WebCore::createCGColor):
+ * platform/graphics/mac/GraphicsContextMac.mm:
+ (WebCore::GraphicsContext::drawFocusRing):
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::setLayerBorderColor):
+ (WebCore::setLayerBackgroundColor):
+ (WebCore::GraphicsLayerCA::setBackgroundColor):
+ * platform/graphics/win/GraphicsContextCGWin.cpp:
+ (WebCore::GraphicsContext::drawFocusRing):
+ * svg/graphics/filters/cg/SVGFEHelpersCg.mm:
+ (WebCore::ciColor):
+
+2009-03-01 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24271: XMLHttpRequest needs js bindings for Workers.
+ <https://bugs.webkit.org/show_bug.cgi?id=24271>
+
+ Tests: http/tests/xmlhttprequest/workers/methods-async.html
+ http/tests/xmlhttprequest/workers/methods.html
+
+ * bindings/js/JSWorkerContextBase.cpp:
+ (WebCore::JSWorkerContextBase::getOwnPropertySlot):
+ (jsWorkerContextBaseXMLHttpRequest):
+ (setJSWorkerContextBaseXMLHttpRequest):
+ Expose XMLHttpRequest to Workers.
+
+ * bindings/js/JSWorkerContextBase.h:
+
+ * bindings/js/JSXMLHttpRequestConstructor.cpp:
+ (WebCore::JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor):
+ (WebCore::constructXMLHttpRequest):
+ (WebCore::JSXMLHttpRequestConstructor::mark):
+ Removed the dependencies on Document.
+
+ * bindings/js/JSXMLHttpRequestConstructor.h:
+ (WebCore::JSXMLHttpRequestConstructor::scriptExecutionContext):
+ * dom/EventException.idl:
+ * dom/EventListener.idl:
+ Change to have the NoStaticTables attribute since they are used from XHR.
+
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::workerContextDidFinishLoading):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFinishLoading):
+ Fixed identifier to be unsigned long.
+
+ * loader/WorkerThreadableLoader.h:
+ * workers/WorkerThread.cpp:
+ (WebCore::WorkerThread::workerThread):
+ Stop active objects when the thread is getting shutdown so that xhr gets properly shutdown.
+
+ * xml/XMLHttpRequestUpload.cpp:
+
+ * xml/XMLHttpRequest.idl:
+ * xml/XMLHttpRequestException.idl:
+ * xml/XMLHttpRequestProgressEvent.idl:
+ * xml/XMLHttpRequestUpload.idl:
+ Change to have the NoStaticTables attribute since they are used from XHR.
+
+2009-03-01 Horia Olaru <olaru@adobe.com>
+
+ Adding manual debugger test cases for bug.
+
+ https://bugs.webkit.org/show_bug.cgi?id=21073
+
+ Reviewed by Kevin McCullough.
+
+ * manual-tests/inspector/debugger-step-on-do-while-statements.html: Added.
+ * manual-tests/inspector/debugger-step-on-for-in-statements.html: Added.
+ * manual-tests/inspector/debugger-step-on-for-statements.html: Added.
+ * manual-tests/inspector/debugger-step-on-while-statements.html: Added.
+ * manual-tests/inspector/resources/loop-statements.js: Added.
+
+2009-03-01 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Darin Adler.
+
+ - fix <rdar://problem/6634768> Reproducible crash in RenderLayer::updateScrollCornerStyle() using full-page zoom at MobileMe Contacts
+
+ Test: fast/events/scroll-during-zoom-change.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::recalcStyle): Pause scheduled events during style
+ reclaculation. Changes to the zoom property result in scroll events
+ being generated during style recalc, and those events need to be
+ deferred until the render tree is consistent.
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layout): Changed to account for a case in which the
+ post-layout tasks trigger a nested layout, which reactivates the
+ post-layout task timer.
+
+2009-03-01 Ross Boucher <rboucher@gmail.com>
+
+ Alphabetically sort scripts in the Script's panel file popup menu.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23395
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/front-end/ScriptsPanel.js:
+ (WebInspector.ScriptsPanel.prototype._addScriptToFilesMenu):
+ * inspector/front-end/utilities.js:
+ (insertionIndexForObjectInListSortedByFunction):
+ (indexOfObjectInListSortedByFunction):
+
+2009-03-01 Yael Aharon <yael.aharon@nokia.com>
+
+ Pass securityOrigin->host() instead of securityOrigin->domain() to WebInspector
+ when creating databases, localStorage or sessionStorage. Changing document.domain
+ should have no affect on databases, localStorage and sessionStorage in Web Inspector.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23844
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::addDOMStorageScriptResource):
+ (WebCore::InspectorController::didUseDOMStorage):
+ * storage/Database.cpp:
+ (WebCore::Database::openDatabase):
+
+2009-03-01 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Avoid leaking errors when reporting GIO errors.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::readCallback):
+ (WebCore::openCallback):
+ (WebCore::queryInfoCallback):
+
+2009-03-01 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Fixes crash when the GIO backend is given the URI for a directory.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::networkErrorForFile):
+
+2009-02-28 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24261
+ Fix V8 custom binding scrubbing error.
+
+ Test: fast/dom/TreeWalker/TreeWalker-currentNode.html
+ Test: traversal/exception-forwarding.html
+ TesT: traversal/stay-within-root.html
+
+ * bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp:
+ * bindings/v8/custom/V8NodeIteratorCustom.cpp:
+ (WebCore::toV8): Replace v8::Undefined() return value with v8::Null().
+ * bindings/v8/custom/V8TreeWalkerCustom.cpp:
+ (WebCore::toV8): Ditto.
+
+2009-02-28 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24261
+ Fix V8 custom binding scrubbing error.
+
+ Test: fast/dom/CSSStyleDeclaration/css-properties-case-sensitive.html
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp:
+ (WebCore::cssPropertyName): Remove dubious checks, left over from
+ incomplete conversion of parameter from pointer to pass-by-ref.
+ (WebCore::NAMED_PROPERTY_GETTER): Initialize parameter.
+ (WebCore::NAMED_PROPERTY_SETTER): Ditto.
+
+2009-02-28 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24263
+ [GTK] ref ResourceHandle until we are finished with it
+
+ Add a ref to the ResourceHandle in startHttp so we can keep it
+ alive untill all callbacks have been executed, and unref it when
+ soup tells us it's done with the SoupMessage (in
+ finishedCallback). Fixes a number of crashes when calling
+ didReceiveData whould crash because of the handle dying.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::finishedCallback):
+ (WebCore::ResourceHandle::startHttp):
+
+2009-02-28 Adam Bergkvist <adam.bergkvist@ericsson.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24226
+ [SOUP] HTTP status text is never set
+
+ Set HTTP status text to SoupMessage reason_phrase.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::fillResponseFromMessage):
+
+2009-02-28 Dan Bernstein <mitz@apple.com>
+
+ - fix malformed project file
+
+ * WebCore.xcodeproj/project.pbxproj:
+
+2009-02-28 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ - fix https://bugs.webkit.org/show_bug.cgi?id=23848
+ <rdar://problem/6573250> REGRESSION: Crash when mouse cursor moves over a link on www.opportuno.de
+
+ Test: fast/layers/inline-dirty-z-order-lists.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::styleWillChange): Moved the code that dirties a
+ layer's and its stacking context's z-order lists when the layer's
+ z-index or visibility change from here...
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::styleWillChange): ...to here, so that
+ it will apply to RenderInline too.
+
+2009-02-27 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Don't include TextResourceDecoder.h in Document.h
+
+ This undoes inlining of Document::displayStringModifiedByEncoding() to avoid world rebuilds
+ when TextResourceDecoder.h is modified. Performance impact is expected to be negligible.
+
+ * dom/Document.cpp:
+ (WebCore::Document::displayStringModifiedByEncoding):
+ (WebCore::Document::displayBufferModifiedByEncoding):
+ * dom/Document.h:
+ * WebCore.base.exp:
+
+2009-02-27 Matt Pennig <pennig@apple.com>
+
+ Reviewed by David Hyatt.
+
+ Resolves: https://bugs.webkit.org/show_bug.cgi?id=24107
+ "Fixed elements have 0 as an offsetLeft property"
+
+ Code also brings offsetLeft/Top in full conformance with the spec.
+ Added two tests, one for fixed-position elements, and one for <html>.
+
+ Tests: fast/dom/Element/fixed-position-offset-parent.html
+ fast/dom/Element/offsetLeft-offsetTop-html.html
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::offsetLeft):
+ (WebCore::RenderBoxModelObject::offsetTop):
+
+2009-02-27 Dean Jackson <dino@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ renderer()->hasTransform() returns true for elements
+ with perspective, but no transform, so test for transform
+ when hit testing. This fixes ASSERT from
+ https://bugs.webkit.org/show_bug.cgi?id=24252
+
+ Test: transforms/no_transform_hit_testing.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+
+2009-02-27 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Fix scrubbing error -- a reversed condition.
+
+ * bindings/v8/ScriptValue.h:
+ (WebCore::ScriptValue::clear): Change early exit for empty value, not the opposite.
+
+2009-02-27 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add confirmMessageFromWorkerObject to WorkerObjectProxy.
+ https://bugs.webkit.org/show_bug.cgi?id=24152
+
+ * workers/WorkerMessagingProxy.cpp:
+ (WebCore::MessageWorkerContextTask::performTask):
+ (WebCore::WorkerMessagingProxy::confirmMessageFromWorkerObject):
+ * workers/WorkerMessagingProxy.h:
+ * workers/WorkerObjectProxy.h:
+
+2009-02-27 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by David Hyatt.
+
+ Revert r41295, the fix for https://bugs.webkit.org/show_bug.cgi?id=24227
+ because it leads to assertion failures in the Mac port.
+
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ * platform/graphics/BitmapImage.h:
+ (WebCore::BitmapImage::mayFillWithSolidColor):
+ * platform/graphics/Image.h:
+ (WebCore::Image::mayFillWithSolidColor):
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ * platform/graphics/cg/ImageCG.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/wx/ImageWx.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+
+2009-02-27 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20249
+
+ Add a preference to allow universal access from local URLs to mitigate
+ some attacks. Some clients still want to allow this access, so we
+ expose this as a preference.
+
+ * WebCore.base.exp:
+ * dom/Document.cpp:
+ (WebCore::Document::initSecurityContext):
+ * page/SecurityOrigin.cpp:
+ (WebCore::SecurityOrigin::SecurityOrigin):
+ * page/Settings.cpp:
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setAllowUniversalAccessFromFileUrls):
+ * page/Settings.h:
+ (WebCore::Settings::allowUniversalAccessFromFileUrls):
+
+2009-02-27 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24229
+ If an image has no alpha channel there is no reason to use SourceOver.
+
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::Image::drawPattern):
+ (WebCore::BitmapImage::draw):
+
+2009-02-27 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Eric Seidel and Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24227
+ Ensure that the checkForSolidColor() optimization is correctly triggered
+ for all cases of drawPattern. Currently, the optimization was not triggered
+ when the check had not been previously performed via a request for the
+ image's NativeImagePtr.
+
+ Implement the Qt version of the checkForSolidColor() method. Combined with
+ the bug fix this reduces the time it takes to draw a repeating background
+ of a 1x1 image from ~50msecs to ~0msecs on my machine.
+
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ * platform/graphics/BitmapImage.h:
+ (WebCore::BitmapImage::mayFillWithSolidColor):
+ * platform/graphics/Image.h:
+ (WebCore::Image::mayFillWithSolidColor):
+ * platform/graphics/cairo/ImageCairo.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ * platform/graphics/cg/ImageCG.cpp:
+ (WebCore::BitmapImage::BitmapImage):
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+ * platform/graphics/wx/ImageWx.cpp:
+ (WebCore::BitmapImage::checkForSolidColor):
+
+2009-02-27 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Zack Rusin.
+
+ Added support for gradients and pattern on Fonts for Qt.
+
+ [Qt] gradients and patterns for FontQt
+ https://bugs.webkit.org/show_bug.cgi?id=24243
+
+ * platform/graphics/qt/FontQt.cpp:
+ (WebCore::Font::drawComplexText):
+
+2009-02-27 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ WorkerContextProxy::create in WorkerMessagingProxy.cpp should only be provided for non-Chromium platform.
+ https://bugs.webkit.org/show_bug.cgi?id=24113
+
+ * workers/WorkerMessagingProxy.cpp:
+
+2009-02-27 Yael Aharon <yael.aharon@nokia.com>
+
+ Added a refresh button to storage views.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24040
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/front-end/DOMStorageItemsView.js:
+ (WebInspector.DOMStorageItemsView):
+ (WebInspector.DOMStorageItemsView.prototype.get statusBarItems):
+ (WebInspector.DOMStorageItemsView.prototype.update):
+ (WebInspector.DOMStorageItemsView.prototype._refreshButtonClicked):
+ * inspector/front-end/DatabaseTableView.js:
+ (WebInspector.DatabaseTableView):
+ (WebInspector.DatabaseTableView.prototype.get statusBarItems):
+ (WebInspector.DatabaseTableView.prototype._refreshButtonClicked):
+ * inspector/front-end/DatabasesPanel.js:
+ (WebInspector.DatabasesPanel):
+ (WebInspector.DatabasesPanel.prototype.get statusBarItems):
+ (WebInspector.DatabasesPanel.prototype.reset):
+ (WebInspector.DatabasesPanel.prototype.showDatabase):
+ (WebInspector.DatabasesPanel.prototype.showDOMStorage):
+ (WebInspector.DatabasesPanel.prototype._updateSidebarWidth):
+ * inspector/front-end/inspector.css:
+
+2009-02-27 Yael Aharon <yael.aharon@nokia.com>
+
+ Added support for editing/deleting localStorage and sessionStorage items
+ directly from Web Inspector.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23866.
+
+ Reviewed by Timothy Hatcher.
+
+ * WebCore.vcproj/WebCore.vcproj:
+ * inspector/front-end/DOMStorageDataGrid.js: Added.
+ (WebInspector.DOMStorageDataGrid):
+ (WebInspector.DOMStorageDataGrid.prototype._ondblclick):
+ (WebInspector.DOMStorageDataGrid.prototype._startEditing):
+ (WebInspector.DOMStorageDataGrid.prototype._editingCommitted):
+ (WebInspector.DOMStorageDataGrid.prototype._editingCancelled):
+ (WebInspector.DOMStorageDataGrid.prototype.deleteSelectedRow):
+ * inspector/front-end/DOMStorageItemsView.js:
+ (WebInspector.DOMStorageItemsView):
+ (WebInspector.DOMStorageItemsView.prototype.get statusBarItems):
+ (WebInspector.DOMStorageItemsView.prototype.hide):
+ (WebInspector.DOMStorageItemsView.prototype.update):
+ (WebInspector.DOMStorageItemsView.prototype._deleteButtonClicked):
+ * inspector/front-end/DatabasesPanel.js:
+ (WebInspector.DatabasesPanel):
+ (WebInspector.DatabasesPanel.prototype.get statusBarItems):
+ (WebInspector.DatabasesPanel.prototype.reset):
+ (WebInspector.DatabasesPanel.prototype.showDOMStorage):
+ (WebInspector.DatabasesPanel.prototype.dataGridForDOMStorage):
+ (WebInspector.DatabasesPanel.prototype._updateSidebarWidth):
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/inspector.css:
+ * inspector/front-end/inspector.html:
+
+2009-02-26 Brett Wilson <brettw@chromium.org>
+
+ Fix Windows transparency for the Chromium port. Implement a helper
+ class for handling transparency on Windows. It allows semitransparent
+ ClearType and semitransparent form controls by making new layers in the
+ background.
+
+ It also replaces the "ThemeHelper" which allows better
+ scaling and transforms on Windows form controls. In addition to the
+ functionality that the ThemeHelper did, but additionally handles the
+ antialiasing properly so that the form controls aren't composited on a
+ white square.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24101
+
+ Reviewed by Eric Seidel.
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::TransparencyAwareFontPainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::initializeForGDI):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::~TransparencyAwareFontPainter):
+ (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::drawGlyphs):
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/chromium/ThemeHelperChromiumWin.cpp:
+ * platform/graphics/chromium/ThemeHelperChromiumWin.h:
+ * platform/graphics/chromium/TransparencyWin.cpp: Added.
+ (WebCore::):
+ (WebCore::TransparencyWin::OwnedBuffers::OwnedBuffers):
+ (WebCore::TransparencyWin::OwnedBuffers::destBitmap):
+ (WebCore::TransparencyWin::OwnedBuffers::referenceBitmap):
+ (WebCore::TransparencyWin::OwnedBuffers::canHandleSize):
+ (WebCore::TransparencyWin::TransparencyWin):
+ (WebCore::TransparencyWin::~TransparencyWin):
+ (WebCore::TransparencyWin::init):
+ (WebCore::TransparencyWin::computeLayerSize):
+ (WebCore::TransparencyWin::setupLayer):
+ (WebCore::TransparencyWin::setupLayerForNoLayer):
+ (WebCore::TransparencyWin::setupLayerForOpaqueCompositeLayer):
+ (WebCore::TransparencyWin::setupLayerForTextComposite):
+ (WebCore::TransparencyWin::setupLayerForWhiteLayer):
+ (WebCore::TransparencyWin::setupTransform):
+ (WebCore::TransparencyWin::setupTransformForKeepTransform):
+ (WebCore::TransparencyWin::setupTransformForUntransform):
+ (WebCore::TransparencyWin::setupTransformForScaleTransform):
+ (WebCore::TransparencyWin::setTextCompositeColor):
+ (WebCore::TransparencyWin::initializeNewContext):
+ (WebCore::TransparencyWin::compositeOpaqueComposite):
+ (WebCore::TransparencyWin::compositeTextComposite):
+ (WebCore::TransparencyWin::makeLayerOpaque):
+ * platform/graphics/chromium/TransparencyWin.h: Added.
+ (WebCore::TransparencyWin::):
+ (WebCore::TransparencyWin::context):
+ (WebCore::TransparencyWin::platformContext):
+ (WebCore::TransparencyWin::drawRect):
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::endTransparencyLayer):
+ * platform/graphics/skia/ImageSkia.cpp:
+ (WebCore::paintSkBitmap):
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::):
+ (WebCore::RenderThemeChromiumWin::paintButton):
+ (WebCore::RenderThemeChromiumWin::paintMenuList):
+ (WebCore::RenderThemeChromiumWin::paintTextFieldInternal):
+
+2009-02-27 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24211
+ Add ScheduledAction for V8.
+
+ * bindings/v8/ScheduledAction.cpp: Added.
+ (WebCore::ScheduledAction::ScheduledAction):
+ (WebCore::ScheduledAction::~ScheduledAction):
+ (WebCore::ScheduledAction::execute):
+ * bindings/v8/ScheduledAction.h: Added.
+ (WebCore::ScheduledAction::ScheduledAction):
+
+2009-02-27 Zack Rusin <zack@kde.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Qt: be more reasonable about scrolled lines
+
+ cMouseWheelPixelsPerLineStep is currently a constant set to 13.3. it doesn't
+ match our metrics meaning that Qt scrolls by ~2 lines by default which is quite
+ irritating. so lets scroll vertically by the Qt set number of lines * Qt default
+ single step scroll
+
+ * platform/qt/WheelEventQt.cpp:
+
+2009-02-27 Xan Lopez <xan@gnome.org>
+
+ Rubber-stamped by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24222
+ [GTK] Remove checks for old glib versions
+
+ libsoup, which is a hard dependency, needs at least glib 2.15.3,
+ so remove all glib checks for versions older than that.
+
+ * platform/gtk/ContextMenuGtk.cpp:
+ (WebCore::ContextMenu::ContextMenu):
+ * platform/gtk/ContextMenuItemGtk.cpp:
+ (WebCore::ContextMenuItem::setSubMenu):
+ * platform/gtk/PopupMenuGtk.cpp:
+ (WebCore::PopupMenu::show):
+ * platform/gtk/WidgetGtk.cpp:
+ (WebCore::Widget::retainPlatformWidget):
+ * platform/network/soup/ResourceHandleSoup.cpp:
+
+2009-02-26 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Added support for Gradients and Patterns on filled or stroked Fonts
+ in Cairo. I also added support for globalAlpha on FontCairo.
+
+ [CAIRO] SVG/Canvas fonts miss gradients/pattern support
+ https://bugs.webkit.org/show_bug.cgi?id=18617
+
+ * html/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::drawTextInternal):
+ * platform/graphics/cairo/FontCairo.cpp:
+ (WebCore::Font::drawGlyphs):
+
+2009-02-26 Stephen White <senorblanco@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23957
+
+ Fix for SVG gradient and pattern text for Chromium/skia.
+ Added accessors for the fill and stroke gradients to
+ GraphicsContext. Changed the paintSkiaText function to take a
+ GraphicsContext, so we can check for gradients/patterns.
+ Changed the skiaDrawText function to set the SkPaint shader
+ correctly, and to scale up the gradient shader matrix to
+ encompass the entire text string. Also offset each glyph
+ separately, rather than transforming the canvas, so that the
+ gradient/pattern stays fixed relative to the text origin.
+
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::getFillGradient):
+ (WebCore::GraphicsContext::getStrokeGradient):
+ (WebCore::GraphicsContext::getFillPattern):
+ (WebCore::GraphicsContext::getStrokePattern):
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/chromium/UniscribeHelper.cpp:
+ (WebCore::UniscribeHelper::draw):
+ * platform/graphics/skia/SkiaFontWin.cpp:
+ (WebCore::windowsCanHandleTextDrawing):
+ (WebCore::skiaDrawText):
+ (WebCore::paintSkiaText):
+ * platform/graphics/skia/SkiaFontWin.h:
+
+2009-02-26 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24208
+ Add custom V8 bindings for Navigator, Clipboard, Document, and Node.
+
+ * bindings/v8/custom/V8ClipboardCustom.cpp: Added.
+ (WebCore::ACCESSOR_GETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8DocumentCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8NavigatorCustom.cpp: Added.
+ (WebCore::ACCESSOR_GETTER):
+ * bindings/v8/custom/V8NodeCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+
+2009-02-26 Gustavo Noronha Silva <gns@gnome.org>
+
+ Unreviewed build fix for building with GNOME Keyring enabled.
+
+ * platform/network/soup/webkit-soup-auth-dialog.c:
+ (show_auth_dialog):
+
+2009-02-26 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=16947
+ [GTK] Missing HTTP Auth challenge
+
+ Add HTTP authentication dialog with optional GNOME Keyring
+ storage.
+
+ * GNUmakefile.am:
+ * platform/network/ResourceHandleInternal.h:
+ (WebCore::ResourceHandleInternal::ResourceHandleInternal):
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::currentToplevelCallback):
+ (WebCore::ResourceHandle::startHttp):
+ (WebCore::ResourceHandle::start):
+ * platform/network/soup/webkit-soup-auth-dialog.c: Added.
+ (webkit_soup_auth_dialog_class_init):
+ (webkit_soup_auth_dialog_init):
+ (webkit_soup_auth_dialog_session_feature_init):
+ (free_authData):
+ (set_password_callback):
+ (response_callback):
+ (show_auth_dialog):
+ (find_password_callback):
+ (session_authenticate):
+ (attach):
+ * platform/network/soup/webkit-soup-auth-dialog.h: Added.
+
+2009-02-25 Ojan Vafai <ojan@chromium.org> and Eric Seidel <eric@webkit.org>
+
+ Reviewed by Dave Hyatt.
+
+ After Ojan's positionForCoordinates fix http://trac.webkit.org/changeset/41191
+ svg/custom/pointer-events-image.svg and svg/custom/pointer-events-text.svg
+ started failing because Ojan's new code was now *correctly* calling through to
+ SVG asking for the closest text offset in the last line box, instead of
+ just returning the offset at the end of the last line box when clicking below a box.
+
+ But! The SVG code was wrong, in that it returned the character offset of the last
+ character when you asked for a character offset after the end of the box, instead
+ it should return the offset *after* the last character. This patch fixes
+ that behavior by reordering the last two clauses in svgCharacterHitsPosition.
+
+ The SVG positionForCoordinates function is still wrong, and I've added some FIXMEs
+ to document what's wrong. I've also cleaned up the code a bit so it's clearer
+ what it is doing (which also makes more obvious what's wrong with it).
+
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::positionForCoordinates):
+ * rendering/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBoxClosestCharacterToPositionWalker::SVGInlineTextBoxClosestCharacterToPositionWalker):
+ (WebCore::SVGInlineTextBoxClosestCharacterToPositionWalker::chunkPortionCallback):
+ (WebCore::SVGInlineTextBoxClosestCharacterToPositionWalker::offsetOfHitCharacter):
+ (WebCore::SVGInlineTextBox::closestCharacterToPosition):
+ (WebCore::SVGInlineTextBox::svgCharacterHitsPosition):
+
+2009-02-26 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Minor cleanup of ChromiumBridge:
+ Removing unused matchesMIMEType method and s/Javascript/JavaScript/
+
+ * platform/chromium/ChromiumBridge.h:
+ * platform/chromium/MimeTypeRegistryChromium.cpp:
+ (WebCore::MIMETypeRegistry::isSupportedImageMIMEType):
+ (WebCore::MIMETypeRegistry::isSupportedJavaScriptMIMEType):
+ (WebCore::MIMETypeRegistry::isSupportedNonImageMIMEType):
+
+2009-02-26 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Sam Weinig
+
+ Fix text-bottom vertical alignment. It was incorrectly aligning the bottom of the descent instead of including
+ the line-height below the descent.
+
+ Added fast/inline/vertical-align-text-bottom.html
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::verticalPosition):
+
+2009-02-26 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Make SVG Masking platform independet with the use of ImageBuffer::getImageData(),
+ ImageBuffer::putImageData() and GraphicsContext::clipToImageBuffer(). Every platform has
+ just to implement this three methods to support SVG Masking now.
+
+ Make SVG Masking platform aware
+ https://bugs.webkit.org/show_bug.cgi?id=19243
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * svg/graphics/SVGResourceMasker.cpp:
+ (WebCore::SVGResourceMasker::applyMask):
+ * svg/graphics/cairo/SVGResourceMaskerCairo.cpp: Removed.
+ * svg/graphics/cg/SVGResourceMaskerCg.cpp: Removed.
+ * svg/graphics/cg/SVGResourceMaskerCg.mm: Removed.
+ * svg/graphics/qt/SVGResourceMaskerQt.cpp: Removed.
+ * svg/graphics/skia/SVGResourceMaskerSkia.cpp: Removed.
+
+2009-02-26 Yong Li <yong.li@torchmobile.com>
+
+ Reviewed by Darin Adler, Antti Koivisto and Alexey Proskuryakov.
+
+ Test: http/tests/misc/slow-preload-cancel.html
+
+ https://bugs.webkit.org/show_bug.cgi?id=24133
+ Clear all pending preloads in the DocLoader object when we decide to
+ cancel its all requests.
+
+ * loader/DocLoader.cpp:
+ (WebCore::DocLoader::clearPendingPreloads):
+ * loader/DocLoader.h:
+ * loader/loader.cpp:
+ (WebCore::Loader::cancelRequests):
+
+2009-02-26 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24182
+ Add NodeFilter, NodeIterator, and TreeWalker custom V8 bindings.
+
+ * bindings/v8/custom/V8NodeFilterCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8NodeIteratorCustom.cpp: Added.
+ (WebCore::toV8):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8TreeWalkerCustom.cpp: Added.
+ (WebCore::toV8):
+ (WebCore::CALLBACK_FUNC_DECL):
+
+2009-02-26 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23500
+ KURL::parse() incorrectly compares its result to original string
+
+ * platform/KURL.cpp: (WebCore::KURL::parse): Take string length into account.
+
+2009-02-26 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Kevin McCullough.
+
+ Manual test for inspector node highlighting.
+
+ * manual-tests/inspector/highlight-nodes.html: Added.
+
+2009-02-16 Anantanarayanan Iyengar <ananta@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23973
+ ScrollView::scrollContents can be invoked during view shutdown. In
+ this scenario the FrameView::hostWindow method can return NULL, which
+ indicates that the frame/page is being destroyed. This causes a crash
+ when we try to dereference a NULL hostWindow pointer. Fix is to add a
+ NULL check for this.
+
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::scrollContents):
+
+2009-02-26 Rahul Kuchhal <kuchhal@chromium.org>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24003
+ Fix a crash caused by unsafe type conversion.
+
+ Test: fast/block/positioning/absolute-in-inline-rtl-4.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::calcAbsoluteHorizontalValues):
+
+2009-02-26 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Adam Roben.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24202
+ Have drawNodeHighlight clip instead of clearing. This makes it work for
+ both Safari and Chromium since Chromium draws the inspector highlighting
+ in the same buffer as the page.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::quadToPath):
+ (WebCore::drawOutlinedQuad):
+ (WebCore::drawOutlinedQuadWithClip):
+ (WebCore::drawHighlightForBox):
+
+2009-02-26 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Dan Bernstein & Darin Adler
+
+ Make sure the border/padding are properly omitted at the start of an inline that is a continuation.
+
+ Added fast/inline/inline-continuation-borders.html
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::determineSpacingForFlowBoxes):
+
+2009-02-26 Simon Fraser <simon.fraser@apple.com>
+
+ Build fix, no review.
+
+ Try to fix the wx build after r41218.
+
+ * WebCoreSources.bkl:
+
+2009-02-26 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=19527
+ ASSERTION FAILED: containerA && containerB
+
+ Test: fast/dom/Range/bug-19527.html
+
+ * dom/Range.cpp:
+ (WebCore::Range::isPointInRange):
+ (WebCore::Range::comparePoint):
+ Bring the behavior in line with current Firefox, making it impossible for these methods
+ to pass a null container to compareBoundaryPoints().
+
+2009-02-26 Jonathon Jongsma <jonathon@quotidian.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20358
+
+ * platform/graphics/gtk/SimpleFontDataGtk.cpp:
+ (WebCore::SimpleFontData::smallCapsFontData): the small-caps font data
+ should set the computed size rather than the specified size, otherwise
+ the caps just get rendered normal size.
+
+2009-02-26 Benjamin Meyer <benjamin.meyer@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24062
+ QNetworkCookieJar expects the url and not the policy url. Sending the
+ policy url will cause QNetworkCookieJar to behave incorrectly. One
+ example would be a cookie that does not have a path or domain.
+ QNetworkCookieJar will use the url it is given to fill in default values.
+ This allows setting cookies on the url of the main frame from an iFrame
+ when the cookie should be set on the url of the iFrame.
+
+ Originally noticed on http://writer.zoho.com/jsp/home.jsp?serviceurl=/index.do
+
+ * platform/qt/CookieJarQt.cpp:
+ (WebCore::setCookies):
+
+2009-02-26 Charles Wei <charles.wei@torchmobile.com.cn>
+
+ Reviewed by George Staikos.
+
+ make WebKit/Qt compile with SVG disabled
+
+ * WebCore.pro:
+ * platform/graphics/qt/FontPlatformDataQt.cpp:
+
+2009-02-25 Gustavo Noronha Silva <gns@gnome.org>
+
+ Unreviewed build fix. Add WebCore/workers to the list of paths
+ searched by the bindings generator perl script.
+
+ * GNUmakefile.am:
+
+2009-02-25 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Add canvas to the list of RenderObjects that can mark a page as
+ visually not empty.
+
+ * rendering/RenderHTMLCanvas.cpp:
+ (WebCore::RenderHTMLCanvas::RenderHTMLCanvas):
+
+2009-02-25 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::nodeAtPoint): Remove assertion fired when child has layer
+ as RenderMedia with controls always has a layer.
+
+2009-02-25 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ - fix https://bugs.webkit.org/show_bug.cgi?id=24130
+ <rdar://problem/6618196> Paint very slow when horizontally resizing
+
+ Test: fast/gradients/background-clipped.html
+
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended): Intersect the
+ destination rectangle passed to drawTiledImage() with the dirty
+ rectangle. This makes it more likely for the destination rect to be
+ contained in a single tile rect, which results in a faster code path
+ being taken down the road (just drawing a single tile instead of
+ tiling).
+
+2009-02-25 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Fix test regressions from positionForCoordinates patch.
+ https://bugs.webkit.org/show_bug.cgi?id=24148
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::positionForPointWithInlineChildren):
+ Remove ASSERT that placeholder text codepath is hitting.
+
+2009-02-25 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ Bug 24143: Crash occurs at WebCore::AccessibilityTable::isTableExposableThroughAccessibility() when applying a link in GMail
+ https://bugs.webkit.org/show_bug.cgi?id=24143
+
+ When an AX object is marked dirty, do not create AX elements while going up the parent chain.
+ Do not allow AXRenderObjects to remove their own IDs from the cache, all the cache to do that work
+ Make sure the AXObjectWrapper's have an object before calling them
+ In AXObjectCache, change get -> getOrCreate. Use get() to only retrieve an element if it exists
+
+ Test: platform/mac-snowleopard/accessibility/table-updating.html
+
+ * WebCore.base.exp:
+ * page/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::~AXObjectCache):
+ (WebCore::AXObjectCache::get):
+ (WebCore::AXObjectCache::getOrCreate):
+ (WebCore::AXObjectCache::removeAXID):
+ (WebCore::AXObjectCache::handleActiveDescendantChanged):
+ (WebCore::AXObjectCache::handleAriaRoleChanged):
+ * page/AXObjectCache.h:
+ * page/AccessibilityImageMapLink.cpp:
+ (WebCore::AccessibilityImageMapLink::parentObject):
+ * page/AccessibilityListBox.cpp:
+ (WebCore::AccessibilityListBox::listBoxOptionAccessibilityObject):
+ (WebCore::AccessibilityListBox::doAccessibilityHitTest):
+ * page/AccessibilityListBoxOption.cpp:
+ (WebCore::AccessibilityListBoxOption::elementRect):
+ (WebCore::AccessibilityListBoxOption::parentObject):
+ * page/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::detach):
+ (WebCore::AccessibilityObject::parentObjectIfExists):
+ (WebCore::replacedNodeNeedsCharacter):
+ (WebCore::AccessibilityObject::accessibilityObjectForPosition):
+ * page/AccessibilityObject.h:
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::firstChild):
+ (WebCore::AccessibilityRenderObject::lastChild):
+ (WebCore::AccessibilityRenderObject::previousSibling):
+ (WebCore::AccessibilityRenderObject::nextSibling):
+ (WebCore::AccessibilityRenderObject::parentObjectIfExists):
+ (WebCore::AccessibilityRenderObject::parentObject):
+ (WebCore::AccessibilityRenderObject::isAttachment):
+ (WebCore::AccessibilityRenderObject::headingLevel):
+ (WebCore::AccessibilityRenderObject::anchorElement):
+ (WebCore::AccessibilityRenderObject::menuForMenuButton):
+ (WebCore::AccessibilityRenderObject::menuButtonForMenu):
+ (WebCore::AccessibilityRenderObject::checkboxOrRadioRect):
+ (WebCore::AccessibilityRenderObject::internalLinkElement):
+ (WebCore::AccessibilityRenderObject::addRadioButtonGroupMembers):
+ (WebCore::AccessibilityRenderObject::titleUIElement):
+ (WebCore::AccessibilityRenderObject::accessibilityIsIgnored):
+ (WebCore::AccessibilityRenderObject::accessibilityParentForImageMap):
+ (WebCore::AccessibilityRenderObject::getDocumentLinks):
+ (WebCore::AccessibilityRenderObject::doAccessibilityHitTest):
+ (WebCore::AccessibilityRenderObject::focusedUIElement):
+ (WebCore::AccessibilityRenderObject::activeDescendant):
+ (WebCore::AccessibilityRenderObject::observableObject):
+ (WebCore::AccessibilityRenderObject::childrenChanged):
+ (WebCore::AccessibilityRenderObject::addChildren):
+ * page/AccessibilityRenderObject.h:
+ (WebCore::AccessibilityRenderObject::setRenderObject):
+ * page/AccessibilityTable.cpp:
+ (WebCore::AccessibilityTable::addChildren):
+ (WebCore::AccessibilityTable::headerContainer):
+ (WebCore::AccessibilityTable::cellForColumnAndRow):
+ * page/AccessibilityTableCell.cpp:
+ (WebCore::AccessibilityTableCell::isTableCell):
+ (WebCore::AccessibilityTableCell::titleUIElement):
+ * page/AccessibilityTableColumn.cpp:
+ (WebCore::AccessibilityTableColumn::headerObjectForSection):
+ * page/AccessibilityTableRow.cpp:
+ (WebCore::AccessibilityTableRow::isTableRow):
+ * page/gtk/AccessibilityObjectWrapperAtk.cpp:
+ * page/mac/AXObjectCacheMac.mm:
+ (WebCore::AXObjectCache::postNotification):
+ (WebCore::AXObjectCache::postNotificationToElement):
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (textMarkerForVisiblePosition):
+ (AXLinkElementForNode):
+ (nsStringForReplacedNode):
+ (-[AccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:]):
+ (-[AccessibilityObjectWrapper accessibilityActionNames]):
+ (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
+ (-[AccessibilityObjectWrapper accessibilityFocusedUIElement]):
+ (-[AccessibilityObjectWrapper accessibilityHitTest:]):
+ (-[AccessibilityObjectWrapper accessibilityIsAttributeSettable:]):
+ (-[AccessibilityObjectWrapper accessibilityIsIgnored]):
+ (-[AccessibilityObjectWrapper accessibilityParameterizedAttributeNames]):
+ (-[AccessibilityObjectWrapper accessibilityPerformPressAction]):
+ (-[AccessibilityObjectWrapper accessibilityPerformAction:]):
+ (-[AccessibilityObjectWrapper accessibilitySetValue:forAttribute:]):
+ (-[AccessibilityObjectWrapper _accessibilityParentForSubview:]):
+ (-[AccessibilityObjectWrapper accessibilityIndexOfChild:]):
+ (-[AccessibilityObjectWrapper accessibilityArrayAttributeCount:]):
+ (-[AccessibilityObjectWrapper accessibilityArrayAttributeValues:index:maxCount:]):
+
+2009-02-25 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Re-working of <rdar://problem/6487249> repro crash in
+ WebCore::CSSParser::parseFillImage copying entire contents of this
+ page
+ -and corresponding: https://bugs.webkit.org/show_bug.cgi?id=24172
+
+ Fixes a bunch of layout test failures I caused!
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ (WebCore::CSSParser::parseContent):
+ (WebCore::CSSParser::parseFillImage):
+ (WebCore::CSSParser::parseFontFaceSrc):
+ (WebCore::CSSParser::parseBorderImage):
+
+2009-02-25 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24174
+ Add more V8 custom bindings.
+
+ * bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp: Added.
+ (WebCore::hasCSSPropertyNamePrefix):
+ (WebCore::cssPropertyName):
+ (WebCore::NAMED_PROPERTY_GETTER):
+ (WebCore::NAMED_PROPERTY_SETTER):
+ * bindings/v8/custom/V8DOMStringListCustom.cpp: Added.
+ (WebCore::INDEXED_PROPERTY_GETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8EventCustom.cpp: Added.
+ (WebCore::ACCESSOR_SETTER):
+ (WebCore::ACCESSOR_GETTER):
+ * bindings/v8/custom/V8HTMLDocumentCustom.cpp: Added.
+ (WebCore::NAMED_PROPERTY_DELETER):
+ (WebCore::NAMED_PROPERTY_SETTER):
+ (WebCore::NAMED_PROPERTY_GETTER):
+ * bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp: Added.
+ (WebCore::NAMED_PROPERTY_GETTER):
+ * bindings/v8/custom/V8NamedNodeMapCustom.cpp: Added.
+ (WebCore::INDEXED_PROPERTY_GETTER):
+ (WebCore::NAMED_PROPERTY_GETTER):
+ * bindings/v8/custom/V8NodeListCustom.cpp: Added.
+ (WebCore::NAMED_PROPERTY_GETTER):
+ * bindings/v8/custom/V8StyleSheetListCustom.cpp: Added.
+ (WebCore::NAMED_PROPERTY_GETTER):
+
+2009-02-25 Scott Violet <sky@google.com>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24171
+ Provides a RenderTheme method for getting the scroll bar size and
+ changes RenderListBox to use it. RenderTheme returns a size of regular,
+ and Mac's override to return small. Changes ScrollbarThemeChromium to
+ use the scrollbarsize of the scrollbar when getting the size
+ instead of passing in no-args.
+
+ * platform/chromium/ScrollbarThemeChromium.cpp:
+ (WebCore::ScrollbarThemeChromium::trackRect):
+ (WebCore::ScrollbarThemeChromium::buttonSize):
+ * rendering/RenderListBox.cpp:
+ (WebCore::RenderListBox::createScrollbar):
+ * rendering/RenderTheme.h:
+ (WebCore::RenderTheme::scrollbarControlSizeForPart):
+ * rendering/RenderThemeChromiumMac.h:
+ (WebCore::RenderThemeChromiumMac::scrollbarControlSizeForPart):
+ * rendering/RenderThemeMac.h:
+ (WebCore::RenderThemeMac::scrollbarControlSizeForPart):
+
+2009-02-25 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fix for <rdar://problem/6487249> repro crash in
+ WebCore::CSSParser::parseFillImage copying entire contents of this
+ page
+ -and corresponding: https://bugs.webkit.org/show_bug.cgi?id=24172
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue): Null-check m_styleSheet
+
+2009-02-25 Adam Treat <adam.treat@torchmobile.com>
+
+ Fix the Qt build.
+
+ * WebCore.pro:
+
+2009-02-25 Jan Michael Alonzo <jmalonzo@webkit.org>
+
+ Gtk build fix. Not reviewed.
+
+ Add files to the build per r41218.
+ Rename WebkitPoint.h to WebKitPoint.h in DOMWindow.cpp
+
+ * GNUmakefile.am:
+ * page/DOMWindow.cpp:
+
+2009-02-25 Zan Dobersek <zandobersek@gmail.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24043
+ When faced with URLs with unsupported protocol on Gtk port,
+ report the error through an idle function and return true, so
+ a proper resource handle is created.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::reportUnknownProtocolError):
+ (WebCore::ResourceHandle::start):
+
+2009-02-25 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+ Use struct to forward declare ResourceRequest.
+
+ * history/HistoryItem.h:
+ * inspector/InspectorController.h:
+ * loader/DocumentThreadableLoader.h:
+ * loader/FrameLoaderClient.h:
+ * loader/MainResourceLoader.h:
+ * loader/SubresourceLoader.h:
+ * loader/SubresourceLoaderClient.h:
+ * loader/ThreadableLoader.h:
+ * loader/WorkerThreadableLoader.h:
+ * platform/CrossThreadCopier.h:
+ * platform/network/ResourceHandle.h:
+ * platform/network/ResourceHandleClient.h:
+ * platform/network/ResourceRequestBase.h:
+ * platform/network/cf/ResourceRequestCFNet.h:
+ * xml/XMLHttpRequest.h:
+
+2009-02-25 Steve Falkenburg <sfalken@apple.com>
+
+ Partial Windows build fix.
+
+ * DerivedSources.cpp:
+ * WebCore.vcproj/WebCore.vcproj:
+
+2009-02-25 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Oliver Hunt.
+
+ Ported arcTo to Qt. Qt has no native support for arcTo. This changes
+ calculate the behavior of arcTo and draws it with lineTo and arc.
+
+ [QT] implement Canvas arcTo
+ https://bugs.webkit.org/show_bug.cgi?id=23873
+
+ * platform/graphics/qt/PathQt.cpp:
+ (WebCore::Path::addArcTo):
+
+2009-02-25 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ Remove idl files from Resources, and sort.
+
+ * WebCore.xcodeproj/project.pbxproj:
+
+2009-02-25 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23943
+
+ Added webkitConvertPointFromNodeToPage and webkitConvertPointFromPageToNode on
+ the window object. Also added WebKitPoint object, which is passed in and out
+ of these functions.
+
+ Test: fast/dom/Window/webkitConvertPoint.html
+
+ * DerivedSources.make:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * bindings/js/JSDOMWindowBase.cpp:
+ (jsDOMWindowBaseWebKitPoint):
+ (setJSDOMWindowBaseWebKitPoint):
+ * bindings/js/JSWebKitPointConstructor.cpp: Added.
+ (WebCore::):
+ (WebCore::JSWebKitPointConstructor::JSWebKitPointConstructor):
+ (WebCore::constructWebKitPoint):
+ (WebCore::JSWebKitPointConstructor::getConstructData):
+ * bindings/js/JSWebKitPointConstructor.h: Added.
+ (WebCore::JSWebKitPointConstructor::classInfo):
+ * dom/Node.cpp:
+ (WebCore::Node::convertToPage):
+ (WebCore::Node::convertFromPage):
+ * dom/Node.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::webkitConvertPointFromNodeToPage):
+ (WebCore::DOMWindow::webkitConvertPointFromPageToNode):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+ * page/WebKitPoint.h: Added.
+ (WebCore::WebKitPoint::create):
+ (WebCore::WebKitPoint::x):
+ (WebCore::WebKitPoint::y):
+ (WebCore::WebKitPoint::setX):
+ (WebCore::WebKitPoint::setY):
+ (WebCore::WebKitPoint::WebKitPoint):
+ * page/WebKitPoint.idl: Added.
+
+2009-02-25 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Remove "#if ENABLE(WORKERS)" wrap from CrossThreadCopier files.
+ https://bugs.webkit.org/show_bug.cgi?id=24145
+
+ * platform/CrossThreadCopier.cpp:
+ * platform/CrossThreadCopier.h:
+
+2009-02-25 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23688: ThreadableLoader needs a sync implementation for Workers.
+ <https://bugs.webkit.org/show_bug.cgi?id=23688>
+
+ No observable change in behavior, so no test.
+
+ * loader/ThreadableLoader.cpp:
+ (WebCore::ThreadableLoader::loadResourceSynchronously):
+ * loader/ThreadableLoaderClientWrapper.h:
+ (WebCore::ThreadableLoaderClientWrapper::clearClient):
+ (WebCore::ThreadableLoaderClientWrapper::done):
+ (WebCore::ThreadableLoaderClientWrapper::didFinishLoading):
+ (WebCore::ThreadableLoaderClientWrapper::didFail):
+ (WebCore::ThreadableLoaderClientWrapper::didFailRedirectCheck):
+ (WebCore::ThreadableLoaderClientWrapper::ThreadableLoaderClientWrapper):
+ Expose whether the loader is done (based on what callbacks were done).
+
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
+ (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
+ Each loader is given its own mode so that only its callbacks get through the run loop.
+
+ The xhr spec says that the readystatechange events are synchronous, so in the case of a
+ nested sync xhr no readystatechange events should be fired for the outer xhr.
+
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
+
+ * loader/WorkerThreadableLoader.h:
+ (WebCore::WorkerThreadableLoader::create):
+ (WebCore::WorkerThreadableLoader::done):
+
+ * workers/WorkerRunLoop.cpp:
+ (WebCore::WorkerRunLoop::WorkerRunLoop):
+ * workers/WorkerRunLoop.h:
+ (WebCore::WorkerRunLoop::createUniqueId):
+ Simple method to create a uniqueId on demand with respect to the run loop.
+
+ * workers/WorkerThread.h:
+
+2009-02-25 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24089: ThreadableLoader::loadResourceSynchronously should do callbacks like the async code.
+ <https://bugs.webkit.org/show_bug.cgi?id=24089>
+
+ Make threadable loader callbacks to happen during the sync load call.
+
+ Changes the behavior of sync xhr for insecure redirects in two ways:
+ + Sends an error event instead of an abort event (which is the same as async xhr's behavior).
+ + Throws a network exception which is what other browsers do and what the spec
+ says to do (http://www.w3.org/TR/XMLHttpRequest/).
+
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::loadResourceSynchronously):
+ * loader/DocumentThreadableLoader.h:
+ * loader/ThreadableLoader.cpp:
+ (WebCore::ThreadableLoader::loadResourceSynchronously):
+ * loader/ThreadableLoader.h:
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::XMLHttpRequest):
+ (WebCore::XMLHttpRequest::loadRequestSynchronously):
+ (WebCore::XMLHttpRequest::loadRequestAsynchronously):
+ (WebCore::XMLHttpRequest::didFail):
+ (WebCore::XMLHttpRequest::didFailRedirectCheck):
+ * xml/XMLHttpRequest.h:
+
+2009-02-24 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by David Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23368
+
+ Added logic to correctly hit test accelerated layers.
+
+ Tests: animations/animation-hit-test-transform.html
+ animations/animation-hit-test.html
+ transitions/transition-hit-test-transform.html
+ transitions/transition-hit-test.html
+
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::animate):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::updateClipRects):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+
+2009-02-25 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24067
+ REGRESSION: Crash in WebCore::Document::initSecurityContext
+
+ The crash started to happen when we removed a check for frame->document() being null.
+ However, the original document shouldn't be null here, because it is needed to alias
+ security origins. So, this patch fixes the crash by correcting security origin behavior.
+
+ Test: http/tests/security/aboutBlank/window-open-self-about-blank.html
+ This tests for not crashing, and for inheriting the domain from the document being replaced.
+ Preserving the aliasing cannot be tested for automatically, because we'd need a non-trivial
+ domain to remove a prefix from.
+
+ * loader/FrameLoader.cpp: (WebCore::FrameLoader::begin): Create a new document before
+ clearing the frame, so that Document::initSecurityContext() could access the old one.
+
+2009-02-25 Jay Campan <jcampan@google.com>
+
+ Reviewed by Darin Fisher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24066
+
+ Items in drop-downs were not painted correctly. Makes sure the
+ PopupListBox invalidates in the coordinates of the window as this is
+ FramelessScrollView::invalidateRect paints to.
+
+ * platform/chromium/PopupMenuChromium.cpp:
+ (WebCore::PopupListBox::invalidateRow):
+
+2009-02-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Anders Carlsson
+
+ https://bugs.webkit.org/show_bug.cgi?id=15081
+
+ Make display:none work for applet, emebed and object elements
+ by calling rendererIsNeeded() on superclasses.
+
+ Tests: fast/replaced/applet-display-none.html
+ fast/replaced/embed-display-none.html
+ fast/replaced/object-display-none.html
+
+ * html/HTMLAppletElement.cpp:
+ (WebCore::HTMLAppletElement::rendererIsNeeded):
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::rendererIsNeeded):
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::rendererIsNeeded):
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::rendererIsNeeded):
+
+2009-02-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=24137
+
+ Fix localToAbsolute() and absoluteToLocal() to map points through 3d transforms,
+ taking perspective and transform-style: preserve-3d into account.
+
+ In order to support transform-style: preserve-3d, which keeps elements in a
+ 3d space, we have to carry along an accumulated matrix in TransformState.
+ We also need to apply the perspective from the parent, if any, with the
+ appropriate origin.
+
+ * GNUmakefile.am:
+ * WebCore.base.exp:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * platform/graphics/transforms/TransformationMatrix.cpp:
+ (WebCore::TransformationMatrix::translate):
+ (WebCore::TransformationMatrix::translate3d):
+ (WebCore::TransformationMatrix::translateRight3d):
+ * platform/graphics/transforms/TransformationMatrix.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::mapLocalToAbsolutePoint):
+ (WebCore::RenderBox::mapAbsoluteToLocalPoint):
+ * rendering/RenderBox.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateTransform):
+ (WebCore::RenderLayer::perspectiveTransform):
+ (WebCore::RenderLayer::perspectiveOrigin):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::requiresCompositingLayerForTransform):
+ (WebCore::RenderLayerCompositor::layerHas3DContent):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::localToAbsolute):
+ (WebCore::RenderObject::absoluteToLocal):
+ (WebCore::RenderObject::mapLocalToAbsolutePoint):
+ (WebCore::RenderObject::mapAbsoluteToLocalPoint):
+ * rendering/RenderObject.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::mapLocalToAbsolutePoint):
+ (WebCore::RenderTableCell::mapAbsoluteToLocalPoint):
+ * rendering/RenderTableCell.h:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::mapLocalToAbsolutePoint):
+ (WebCore::RenderView::mapAbsoluteToLocalPoint):
+ * rendering/RenderView.h:
+ * rendering/TransformState.cpp: Added.
+ (WebCore::TransformState::move):
+ (WebCore::TransformState::applyTransform):
+ (WebCore::TransformState::flatten):
+ * rendering/TransformState.h: Added.
+ (WebCore::TransformState::):
+ (WebCore::TransformState::TransformState):
+ (WebCore::TransformState::move):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::hasPerspective):
+
+2009-02-24 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23990
+ Regression (r40837): JavaScript image popup doesn't work
+
+ Make the getClientRects and getBoundingClientRect methods return rects
+ relative to the viewport.
+
+ Test: fast/dom/getBoundingClientRect-getClientRects-relative-to-viewport.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::getClientRects):
+ (WebCore::Element::getBoundingClientRect):
+
+2009-02-24 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ SVG pages don't have a body or an html element!
+ Don't return early if there is no body.
+
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::canonicalPosition):
+
+2009-02-23 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ https://bugs.webkit.org/show_bug.cgi?id=23740, painting order wrong for normal flow elements with overflow: hidden
+
+ This patch reworks the painting of overflow. There is now the concept of a "self-painting layer." All
+ layers are considered to be self-painting except for overflow layers that are normal flow (and that don't have
+ reflections or masks).
+
+ If an overflow layer is not self-painting, then it ends up painted by its parent just like any other normal flow object.
+ The only difference is that the clip has to be pushed and popped when painting the object's children.
+
+ The lightweight clipping scheme used for controls has been extended to cover overflow now in this simplified case. With
+ the code consolidated into reusable push/pop functions, all of the renderers that use overflow have been patched to
+ use the new functions.
+
+ Hit testing has also been patched to check the overflow clip rect first before recurring into children.
+
+ Scrollbar paint has been moved into RenderBlock for now, since none of the table objects support scrollbars
+ yet, and scrollbar hit testing was already there anyway. Now the two code paths are more symmetrical.
+
+ Masks are now treated like normal flow layers (just like reflections).
+
+ A couple of test cases have been added to fast/overflow to test the stacking order.
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::nodeAtPoint):
+ (WebCore::InlineFlowBox::paint):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::repaintOverhangingFloats):
+ (WebCore::RenderBlock::paint):
+ (WebCore::RenderBlock::paintChildren):
+ (WebCore::RenderBlock::paintObject):
+ (WebCore::RenderBlock::paintFloats):
+ (WebCore::RenderBlock::insertFloatingObject):
+ (WebCore::RenderBlock::floatRect):
+ (WebCore::RenderBlock::lowestPosition):
+ (WebCore::RenderBlock::rightmostPosition):
+ (WebCore::RenderBlock::leftmostPosition):
+ (WebCore::RenderBlock::addOverhangingFloats):
+ (WebCore::RenderBlock::nodeAtPoint):
+ (WebCore::RenderBlock::hitTestContents):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::nodeAtPoint):
+ (WebCore::RenderBox::pushContentsClip):
+ (WebCore::RenderBox::popContentsClip):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::paintObject):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::hasSelfPaintingLayer):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayer):
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::shouldBeNormalFlowOnly):
+ (WebCore::RenderLayer::isSelfPaintingLayer):
+ * rendering/RenderLayer.h:
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::paint):
+ (WebCore::RenderTable::paintObject):
+ (WebCore::RenderTable::nodeAtPoint):
+ * rendering/RenderTable.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::paint):
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::nodeAtPoint):
+ (WebCore::RenderTableRow::paint):
+ * rendering/RenderTableRow.h:
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::paint):
+ (WebCore::RenderTableSection::paintObject):
+ (WebCore::RenderTableSection::nodeAtPoint):
+ * rendering/RenderTableSection.h:
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::write):
+ (WebCore::writeLayers):
+
+2009-02-24 David Levin <levin@chromium.org>
+
+ Reviewed by NOBODY (build fix).
+
+ Attempted build fix for wx-mac.
+
+ * WebCoreSources.bkl:
+
+2009-02-24 David Levin <levin@chromium.org>
+
+ Reviewed by NOBODY (build fix).
+
+ Attempted build fixes for qt-linux and wx-mac.
+
+ * WebCore.pro:
+ * webcore-base.bkl:
+
+2009-02-24 Ojan Vafai <ojan@dhcp-172-31-134-214.sfo.corp.google.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix null pointer error. If the node is the Document, then ownerDocument()
+ returns null, document() does not.
+
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::canonicalPosition):
+
+2009-02-24 Jian Li <jianli@chromium.org>
+
+ Reviewed by NOBODY (attempted build fixes).
+
+ Fix build break for Windows and Linux.
+
+ * GNUmakefile.am:
+ * WebCore.vcproj/WebCore.vcproj:
+
+2009-02-24 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24131
+ Fix-up COM/RefCounted dichotomy in Chromium port.
+
+ * page/chromium/AccessibilityObjectWrapper.h:
+ (WebCore::AccessibilityObjectWrapper::AccessibilityObjectWrapper): Added
+ explicit setting of recount.
+
+2009-02-24 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24141
+ Add clarity to V8 interceptor helper function.
+
+ * bindings/v8/custom/V8HTMLPlugInElementCustom.cpp:
+ (WebCore::NAMED_PROPERTY_GETTER): Renamed to notHandledByInterceptor.
+ (WebCore::NAMED_PROPERTY_SETTER): Ditto.
+ (WebCore::INDEXED_PROPERTY_GETTER): Ditto.
+ (WebCore::INDEXED_PROPERTY_SETTER): Ditto.
+
+2009-02-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Minor numeric cleanup: convert float literals to doubles.
+
+ * platform/graphics/transforms/RotateTransformOperation.cpp:
+ (WebCore::RotateTransformOperation::blend):
+
+2009-02-24 Mark Mentovai <mark@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24139
+ Add missing include.
+
+ * bindings/v8/ScriptInstance.h:
+
+2009-02-24 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Move worker related files from dom directory to worker directory under WebCore.
+ https://bugs.webkit.org/show_bug.cgi?id=24123
+
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/MigrateIDLAndScripts:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/CrossThreadCopier.cpp: Renamed from WebCore/dom/CrossThreadCopier.cpp.
+ * platform/CrossThreadCopier.h: Renamed from WebCore/dom/CrossThreadCopier.h.
+ * workers/GenericWorkerTask.h: Renamed from WebCore/dom/GenericWorkerTask.h.
+ * workers/Worker.cpp: Renamed from WebCore/dom/Worker.cpp.
+ * workers/Worker.h: Renamed from WebCore/dom/Worker.h.
+ * workers/Worker.idl: Renamed from WebCore/dom/Worker.idl.
+ * workers/WorkerContext.cpp: Renamed from WebCore/dom/WorkerContext.cpp.
+ * workers/WorkerContext.h: Renamed from WebCore/dom/WorkerContext.h.
+ * workers/WorkerContext.idl: Renamed from WebCore/dom/WorkerContext.idl.
+ * workers/WorkerContextProxy.h: Renamed from WebCore/dom/WorkerContextProxy.h.
+ * workers/WorkerLocation.cpp: Renamed from WebCore/dom/WorkerLocation.cpp.
+ * workers/WorkerLocation.h: Renamed from WebCore/dom/WorkerLocation.h.
+ * workers/WorkerLocation.idl: Renamed from WebCore/dom/WorkerLocation.idl.
+ * workers/WorkerMessagingProxy.cpp: Renamed from WebCore/dom/WorkerMessagingProxy.cpp.
+ * workers/WorkerMessagingProxy.h: Renamed from WebCore/dom/WorkerMessagingProxy.h.
+ * workers/WorkerObjectProxy.h: Renamed from WebCore/dom/WorkerObjectProxy.h.
+ * workers/WorkerRunLoop.cpp: Renamed from WebCore/dom/WorkerRunLoop.cpp.
+ * workers/WorkerRunLoop.h: Renamed from WebCore/dom/WorkerRunLoop.h.
+ * workers/WorkerThread.cpp: Renamed from WebCore/dom/WorkerThread.cpp.
+ * workers/WorkerThread.h: Renamed from WebCore/dom/WorkerThread.h.
+
+2009-02-05 Ojan Vafai <ojan@chromium.org> and Eric Seidel <eric@webkit.org>
+
+ Reviewed by Dave Hyatt.
+
+ Make cursor positions match IE6/IE7/FF3 when clicking in margins/padding
+ around divs inside editable regions.
+ https://bugs.webkit.org/show_bug.cgi?id=23605
+
+ Fix clicks outside editable regions from focusing the editable region.
+ https://bugs.webkit.org/show_bug.cgi?id=23607
+
+ Removed editing/selection/contenteditable-click-outside.html as it's
+ not as useful as our new tests.
+
+ Clean up RenderBlock::positionForCoordinates to remove dead code,
+ duplicate code, and generally make it more readable.
+
+ Tests: editing/selection/click-in-margins-inside-editable-div.html
+ editing/selection/click-in-padding-with-multiple-line-boxes.html
+ editing/selection/click-outside-editable-div.html
+
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::canonicalPosition):
+ * rendering/RenderBlock.cpp:
+ (WebCore::positionForPointRespectingEditingBoundaries):
+ (WebCore::positionForPointWithInlineChildren):
+ (WebCore::RenderBlock::positionForCoordinates):
+ (WebCore::RenderBlock::updateFirstLetter):
+
+2009-02-24 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Related to <rdar://problem/6590295>
+ Allow disabling javascript: urls.
+
+ * WebCore.base.exp:
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::parseMappedAttribute):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::executeIfJavaScriptURL):
+ * page/Page.cpp:
+ (WebCore::Page::Page):
+ (WebCore::Page::setJavaScriptURLsAreAllowed):
+ (WebCore::Page::javaScriptURLsAreAllowed):
+ * page/Page.h:
+
+2009-02-24 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build when ACCELERATED_COMPOSITING is turned on
+ (overflowList() -> normalFlowList()).
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::hasNonCompositingContent):
+ (WebCore::RenderLayerBacking::paintIntoLayer):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::calculateCompositedBounds):
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+ (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
+ (WebCore::RenderLayerCompositor::recursiveRepaintLayerRect):
+ (WebCore::RenderLayerCompositor::layerHas3DContent):
+
+2009-02-24 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Darin Adler
+
+ https://bugs.webkit.org/show_bug.cgi?id=24135
+
+ Round the FloatPoint returned by absoluteToLocal(), rather than
+ truncating it.
+
+ * dom/MouseRelatedEvent.cpp:
+ (WebCore::MouseRelatedEvent::receivedTarget):
+
+2009-02-24 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=24004 REGRESSION:
+ Ordered list item marker misaligned when line height is not 1.2
+ -and corresponding <rdar://problem/6602506>
+
+ This is a regression from http://trac.webkit.org/changeset/40880
+ where createInlineBox was taken off of RenderObject and moved to
+ RenderBox. The problem was that the RenderBox version still needs
+ to be virtual because there is still an existing implementation in
+ RenderListMarker.
+
+ * rendering/RenderBox.h:
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::createInlineBox):
+ * rendering/RenderListMarker.h:
+
+2009-02-24 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24128
+ Upstream more V8 custom bindings: constructors, XSLTProcessor.
+
+ * bindings/v8/custom/V8DOMParserConstructor.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8MessageChannelConstructor.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8XMLSerializerConstructor.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8XPathEvaluatorConstructor.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8XSLTProcessorCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+
+2009-02-24 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24090: WorkerThreadableLoader needs to be able to post tasks for a mode.
+ <https://bugs.webkit.org/show_bug.cgi?id=24090>
+
+ No observable change in behavior, so no test.
+
+ * dom/WorkerMessagingProxy.cpp:
+ (WebCore::WorkerMessagingProxy::postMessageToWorkerContext):
+ (WebCore::WorkerMessagingProxy::postTaskToWorkerContext):
+ Fixed the bug that m_unconfirmedMessageCount was getting incremented for non-message tasks.
+
+ (WebCore::WorkerMessagingProxy::postTaskForModeToWorkerContext):
+
+ * dom/WorkerMessagingProxy.h:
+ * loader/ThreadableLoader.cpp:
+ (WebCore::ThreadableLoader::create):
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didSendData):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didReceiveResponse):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didReceiveData):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFinishLoading):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFail):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFailRedirectCheck):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didReceiveAuthenticationCancellation):
+ Changed these methods to post task using a mode.
+
+ * loader/WorkerThreadableLoader.h:
+ (WebCore::WorkerThreadableLoader::create):
+
+2009-02-24 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24091
+ <rdar://problem/6468660> Start of redirect chain ends up as master entry in Application Cache
+
+ Test: http/tests/appcache/access-via-redirect.php
+
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::finishedLoadingMainResource): Use the URL we ended up with,
+ not the original one.
+
+2009-02-24 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Change to include WorkerObjectProxy.h instead of WorkerMessagingProxy.h in WorkerContext.cpp and WorkerScriptController.cpp.
+ https://bugs.webkit.org/show_bug.cgi?id=24112
+
+ * bindings/js/WorkerScriptController.cpp:
+ * dom/WorkerContext.cpp:
+
+2009-02-23 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ <rdar://problem/6613796> Extended text codecs registered on webview creation
+
+ Comparing a text encoding with string "GBK" ended up constructing
+ TextEncoding("GBK") which in turn initialized all extended
+ text codecs.
+
+ * platform/text/TextCodecICU.cpp:
+ (WebCore::TextCodecICU::decode):
+
+2009-02-23 Sam Weinig <sam@webkit.org>
+
+ Fix Qt build.
+
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::valueRealType):
+
+2009-02-23 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Bug 23956: Safari crashes when cloneNode fails (cloning a XML element with an invalid nodeName)
+
+ The crash occurred because Document::cloneNode would call Document::createElementNS. Unfortunately
+ element created with createElement could have a wrong nodeName (createElement sets the string as the
+ localName without checking for a prefix).
+
+ The fix is to call Document::createElement(const QualifiedName&, bool) that will not do any checks on the QualifiedName
+ and will always succeed.
+ Also rolled-out the HTMLElement specialisation of clonedNode as it was equivalent to what is done now (added an ASSERT
+ to ensure that).
+
+ Test: fast/dom/cloneNode.html
+
+ * dom/Element.cpp:
+ (WebCore::Element::cloneNode): Call createElement(const QualifiedName&, bool) instead of createElementNS as it will
+ always return an element.
+
+ * html/HTMLElement.cpp:
+ * html/HTMLElement.h: Removed HTMLElement::clonedNode as it is equivalent to what is now done.
+
+2009-02-23 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24109
+ Upstream V8 Script abstractions, all except ScriptController.
+
+ * bindings/v8/ScriptCachedFrameData.h: Added.
+ (WebCore::ScriptCachedFrameData::ScriptCachedFrameData):
+ (WebCore::ScriptCachedFrameData::~ScriptCachedFrameData):
+ (WebCore::ScriptCachedFrameData::restore):
+ (WebCore::ScriptCachedFrameData::clear):
+ (WebCore::ScriptCachedFrameData::domWindow):
+ * bindings/v8/ScriptCallFrame.cpp: Added.
+ (WebCore::ScriptCallFrame::ScriptCallFrame):
+ (WebCore::ScriptCallFrame::~ScriptCallFrame):
+ (WebCore::ScriptCallFrame::argumentAt):
+ * bindings/v8/ScriptCallFrame.h: Added.
+ (WebCore::ScriptCallFrame::functionName):
+ (WebCore::ScriptCallFrame::sourceURL):
+ (WebCore::ScriptCallFrame::lineNumber):
+ (WebCore::ScriptCallFrame::argumentCount):
+ * bindings/v8/ScriptCallStack.cpp: Added.
+ (WebCore::ScriptCallStack::ScriptCallStack):
+ (WebCore::ScriptCallStack::~ScriptCallStack):
+ (WebCore::ScriptCallStack::at):
+ * bindings/v8/ScriptCallStack.h: Added.
+ (WebCore::ScriptCallStack::size):
+ * bindings/v8/ScriptInstance.cpp: Added.
+ (WebCore::V8ScriptInstance::V8ScriptInstance):
+ (WebCore::V8ScriptInstance::~V8ScriptInstance):
+ (WebCore::V8ScriptInstance::instance):
+ (WebCore::V8ScriptInstance::clear):
+ (WebCore::V8ScriptInstance::set):
+ * bindings/v8/ScriptInstance.h: Added.
+ (WebCore::V8ScriptInstance::create):
+ * bindings/v8/ScriptSourceCode.h: Added.
+ (WebCore::ScriptSourceCode::ScriptSourceCode):
+ (WebCore::ScriptSourceCode::isEmpty):
+ (WebCore::ScriptSourceCode::source):
+ (WebCore::ScriptSourceCode::url):
+ (WebCore::ScriptSourceCode::startLine):
+ * bindings/v8/ScriptState.h: Added.
+ (WebCore::ScriptState::hadException):
+ (WebCore::ScriptState::setException):
+ (WebCore::ScriptState::exception):
+ * bindings/v8/ScriptString.h: Added.
+ (WebCore::ScriptString::ScriptString):
+ (WebCore::ScriptString::operator String):
+ (WebCore::ScriptString::isNull):
+ (WebCore::ScriptString::size):
+ (WebCore::ScriptString::operator=):
+ (WebCore::ScriptString::operator+=):
+ * bindings/v8/ScriptValue.cpp: Added.
+ (WebCore::ScriptValue::getString):
+ * bindings/v8/ScriptValue.h: Added.
+ (WebCore::ScriptValue::ScriptValue):
+ (WebCore::ScriptValue::operator=):
+ (WebCore::ScriptValue::operator==):
+ (WebCore::ScriptValue::operator!=):
+ (WebCore::ScriptValue::isNull):
+ (WebCore::ScriptValue::isUndefined):
+ (WebCore::ScriptValue::clear):
+ (WebCore::ScriptValue::~ScriptValue):
+ (WebCore::ScriptValue::v8Value):
+
+2009-02-23 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Timothy Hatcher.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24106
+ The Qt port is crashing on exit because the tear down procedure involves
+ the WebCore::InspectorController trying to access the JS execution context
+ for a page that is being deleted. This patch amends the inspector so
+ that it does not try and access the execution context of the WebCore::Page
+ in the midst of deletion.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::inspectedPageDestroyed):
+ (WebCore::InspectorController::stopUserInitiatedProfiling):
+
+2009-02-23 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24088: ThreadableLoaderClient::didFailWillSendRequestCheck isn't wired up completely for workers and could use a better name.
+ <https://bugs.webkit.org/show_bug.cgi?id=24088>
+
+ No observable change in behavior, so no test.
+
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::create):
+ * loader/ThreadableLoaderClient.h:
+ (WebCore::ThreadableLoaderClient::didFailRedirectCheck):
+ * loader/ThreadableLoaderClientWrapper.h:
+ (WebCore::ThreadableLoaderClientWrapper::didFailRedirectCheck):
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::workerContextDidFailRedirectCheck):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFailRedirectCheck):
+ * loader/WorkerThreadableLoader.h:
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::didFinishLoading):
+ * xml/XMLHttpRequest.h:
+
+2009-02-23 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 24047: Need to simplify nested if's in WorkerRunLoop::runInMode
+ <https://bugs.webkit.org/show_bug.cgi?id=24047>
+
+ Made a nested if inside of WorkerRunLoop::runInMode a lot simpler by
+ using only MessageQueue::waitForMessageFilteredWithTimeout instead
+ of three different MessageQueue methods.
+
+ No observable change in behavior, so no test.
+
+ * dom/WorkerRunLoop.cpp:
+ (WebCore::ModePredicate::operator()):
+ Minor clean-up to able to pass a const ref point for ModePredicate into runInMode.
+ (WebCore::WorkerRunLoop::runInMode):
+ * dom/WorkerRunLoop.h:
+
+2009-02-23 David Hyatt <hyatt@apple.com>
+
+ In preparation for making layers for multicol objects (so that they can properly split child layers
+ into multiple columns), rename all of the "overflowOnly" and "overflowList" members and functions
+ of RenderLayer to use the term "normal flow" instead.
+
+ Reviewed by Cameron Zwarich
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::~RenderLayer):
+ (WebCore::RenderLayer::setHasVisibleContent):
+ (WebCore::RenderLayer::enclosingCompositingLayer):
+ (WebCore::RenderLayer::addChild):
+ (WebCore::RenderLayer::removeChild):
+ (WebCore::RenderLayer::paintLayer):
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::dirtyNormalFlowList):
+ (WebCore::RenderLayer::updateNormalFlowList):
+ (WebCore::RenderLayer::collectLayers):
+ (WebCore::RenderLayer::updateLayerListsIfNeeded):
+ (WebCore::RenderLayer::shouldBeNormalFlowOnly):
+ (WebCore::RenderLayer::styleChanged):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::isNormalFlowOnly):
+ (WebCore::RenderLayer::normalFlowList):
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::writeLayers):
+
+2009-02-23 David Hyatt <hyatt@apple.com>
+
+ Fix the stacking order for column rules in multi-column layout. Column rules should paint as part of the background of an element, just
+ after all other components of the background have been painted. This allows negative z-index children to still paint on top of the
+ column rules (rather than ending up above the background of the box but behind the column rules).
+
+ Reviewed by Eric Seidel
+
+ Added fast/multicol/column-rules-stacking.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintColumnRules):
+ (WebCore::RenderBlock::paintColumnContents):
+ (WebCore::RenderBlock::paintObject):
+ * rendering/RenderBlock.h:
+
+2009-02-23 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by David Hyatt.
+
+ No testcases have been added or modified since this patch should not result in
+ a behavior change for ports that have layout tests enabled.
+
+ Currently, the implementation of GraphicsContext::drawLineForText amongst
+ the various ports differ in that some of them are honoring the context's
+ strokeStyle when drawing a text-decoration and some of them are not.
+ For instance, Apple's Mac port *does not* honor the context's strokeStyle(),
+ but the Cairo implementation does and has an explicit workaround that
+ sets the strokeStyle() temporarily.
+
+ This patch fixes so that all ports are consistent by explicitly making sure
+ to set the GraphicsContext strokeStyle to SolidStroke whenever
+ painting the text-decoration of an InlineFlowBox or InlineTextBox as these
+ should always use a solid stroke.
+
+ This patch addresses these bugs:
+ https://bugs.webkit.org/show_bug.cgi?id=19364
+ https://bugs.webkit.org/show_bug.cgi?id=15659
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::paintTextDecorations):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paintDecoration):
+
+2009-02-23 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24098
+ Bugs in ClipboardChromium
+
+ Fixes the following bugs in ClipboardChromium:
+ * It's possible for the extension to be empty, resulting in a bad file
+ name, for example, 'foo.' or just '.'.
+ * We weren't restricting the size of the file to MAX_PATH.
+ * We weren't removing characters that are invalid for file system names.
+
+ * platform/chromium/ClipboardChromium.cpp:
+ (WebCore::writeImageToDataObject):
+ * platform/chromium/ClipboardChromium.h:
+ * platform/chromium/ClipboardChromiumLinux.cpp: Added.
+ (WebCore::ClipboardChromium::validateFileName):
+ * platform/chromium/ClipboardChromiumMac.cpp: Added.
+ (WebCore::ClipboardChromium::validateFileName):
+ * platform/chromium/ClipboardChromiumWin.cpp: Added.
+ (WebCore::isInvalidFileCharacter):
+ (WebCore::ClipboardChromium::validateFileName):
+
+2009-02-23 Thiago Macieira <thiago.macieira@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix the Copyright notices in a few files
+
+ * platform/qt/RenderThemeQt.h:
+
+2009-02-23 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22624
+ [SOUP][GTK] Need API to get SoupSession from WebKit.
+
+ Allow to retrieve the Soup session and modify the code to take
+ into account users changing features on it.
+
+ * platform/network/ResourceHandle.h:
+ * platform/network/soup/CookieJarSoup.cpp:
+ (WebCore::defaultCookieJar):
+ (WebCore::setDefaultCookieJar):
+ * platform/network/soup/CookieJarSoup.h:
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::createSoupSession):
+ (WebCore::ensureSessionIsInitialized):
+ (WebCore::ResourceHandle::startHttp):
+ (WebCore::ResourceHandle::cancel):
+ (WebCore::ResourceHandle::defaultSession):
+
+2009-02-23 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22624
+ [SOUP][GTK] Need API to get SoupSession from WebKit.
+
+ Remove CURL support.
+
+ * GNUmakefile.am:
+
+2009-02-23 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ Test: fast/dom/empty-hash-and-search.html
+
+ https://bugs.webkit.org/show_bug.cgi?id=21147
+ hash property returns incorrect value for links w/o hash
+
+ Make hash() and search() behavior for empty and missing parts match IE and Firefox.
+
+ * platform/KURL.cpp:
+ (WebCore::KURL::query): Changed to return query without '?', as it is already done for ref().
+ (WebCore::KURL::prettyURL): Append the query with the question mark.
+
+ * page/Location.cpp:
+ (WebCore::Location::search): Return an empty string if query is empty or missing.
+ (WebCore::Location::hash): Return an empty string for empty hashes, not only missing ones.
+
+ * dom/WorkerLocation.cpp:
+ (WebCore::WorkerLocation::search):
+ (WebCore::WorkerLocation::hash):
+ Match document.location fixes above.
+
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::hash):
+ (WebCore::HTMLAnchorElement::search):
+ Return an empty string for empty and missing parts.
+
+2009-02-23 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20184
+ SELECT with no name generates invalid query string
+
+ Test: fast/forms/select-no-name.html
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::appendFormData): Added a check for empty name.
+
+2009-02-23 Alexey Proskuryakov <ap@webkit.org>
+
+ Apply review comments for the previous check-in (forgot to save the file, oops).
+
+ * dom/ContainerNode.cpp: (WebCore::ContainerNode::removeChildren):
+
+2009-02-23 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=15707
+ Crash when manipulating document from within an iframe onload function
+
+ Test: fast/dom/onload-open.html
+
+ * dom/ContainerNode.cpp: (WebCore::ContainerNode::removeChildren): Protect the container and
+ the current node, because anything can happen when dispatching events.
+
+2009-02-23 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=18970
+ Numerically named input fields cause document.forms loop problems
+
+ Test: fast/forms/numeric-input-name.html
+
+ * bindings/scripts/CodeGeneratorJS.pm: Try index getter before name getter, even if the
+ latter overrides properties.
+
+2009-02-23 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24059
+ Tokenizer::write() return value is never used
+
+ * dom/Tokenizer.h:
+ * dom/XMLTokenizer.cpp:
+ (WebCore::XMLTokenizer::write):
+ * dom/XMLTokenizer.h:
+ * html/HTMLTokenizer.cpp:
+ (WebCore::HTMLTokenizer::write):
+ * html/HTMLTokenizer.h:
+ * loader/FTPDirectoryDocument.cpp:
+ (WebCore::FTPDirectoryTokenizer::write):
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageTokenizer::write):
+ * loader/MediaDocument.cpp:
+ (WebCore::MediaTokenizer::write):
+ * loader/PluginDocument.cpp:
+ (WebCore::PluginTokenizer::write):
+ * loader/TextDocument.cpp:
+ (WebCore::TextTokenizer::write):
+ Made write() return void, not bool.
+
+2009-02-20 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Updated for JavaScriptCore changes to timeout checking.
+
+ * bindings/js/JSCustomPositionCallback.cpp:
+ (WebCore::JSCustomPositionCallback::handleEvent):
+ * bindings/js/JSCustomPositionErrorCallback.cpp:
+ (WebCore::JSCustomPositionErrorCallback::handleEvent):
+ * bindings/js/JSCustomSQLStatementCallback.cpp:
+ (WebCore::JSCustomSQLStatementCallback::handleEvent):
+ * bindings/js/JSCustomSQLStatementErrorCallback.cpp:
+ (WebCore::JSCustomSQLStatementErrorCallback::handleEvent):
+ * bindings/js/JSCustomSQLTransactionCallback.cpp:
+ (WebCore::JSCustomSQLTransactionCallback::handleEvent):
+ * bindings/js/JSCustomSQLTransactionErrorCallback.cpp:
+ (WebCore::JSCustomSQLTransactionErrorCallback::handleEvent):
+ * bindings/js/JSCustomVoidCallback.cpp:
+ (WebCore::JSCustomVoidCallback::handleEvent):
+ * bindings/js/JSCustomXPathNSResolver.cpp:
+ (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
+ * bindings/js/JSDOMWindowBase.cpp:
+ (WebCore::JSDOMWindowBase::JSDOMWindowBase):
+ (WebCore::JSDOMWindowBase::commonJSGlobalData):
+ * bindings/js/JSEventListener.cpp:
+ (WebCore::JSAbstractEventListener::handleEvent):
+ * bindings/js/ScheduledAction.cpp:
+ (WebCore::ScheduledAction::executeFunctionInContext):
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::evaluate):
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::evaluate):
+ (WebCore::WorkerScriptController::forbidExecution):
+ * bindings/objc/WebScriptObject.mm:
+ (-[WebScriptObject callWebScriptMethod:withArguments:]):
+ (-[WebScriptObject evaluateWebScript:]):
+ * bridge/NP_jsobject.cpp:
+ (_NPN_InvokeDefault):
+ (_NPN_Invoke):
+ (_NPN_Evaluate):
+ (_NPN_Construct):
+ * bridge/jni/jni_jsobject.mm:
+ (JavaJSObject::call):
+ (JavaJSObject::eval):
+
+2009-02-21 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23786
+ [Chromium] line-break characters in a complex text are treated as zero-width spaces
+
+ This change prevents the UniscribeHelper class from treating the line-break characters
+ as whitespaces.
+
+ Tests: fast/text/international/bidi-linebreak-001.html
+ fast/text/international/bidi-linebreak-002.html
+ fast/text/international/bidi-linebreak-003.html
+
+ * platform/graphics/chromium/UniscribeHelper.cpp:
+ (WebCore::UniscribeHelper::adjustSpaceAdvances):
+ Make the UniscribeHelper::adjustSpaceAdvances() function treat all characters in
+ the treatAsSpace() function (e.g. U+0020, U+000A, U+000D, U+00A0) as whitespaces,
+ so does when Chromium renders a simple text.
+
+2009-02-20 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23940: Use Document::createElement(const QualifiedName&, bool) when creating a known element inside WebCore
+
+ Document::createElement(const QualifiedName&, bool) does not check for the prefix as opposed the the one taking an AtomicString
+ or Document::createElementNS. This is perfectly fine internally because we know the type of element created and the check is
+ unneeded.
+
+ It also removes the use of an ExceptionCode argument which was here only to check that the prefix check was fine. Finally it
+ enables us to use some generated QualifiedName.
+
+ * bindings/js/JSOptionConstructor.cpp:
+ (WebCore::constructHTMLOptionElement):
+ * dom/Document.cpp:
+ (WebCore::Document::setTitle):
+ * dom/XMLTokenizer.cpp:
+ (WebCore::createXHTMLParserErrorHeader):
+ (WebCore::XMLTokenizer::insertErrorMessageBlock):
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::createBlockPlaceholderElement):
+ * editing/htmlediting.cpp:
+ (WebCore::createTabSpanElement):
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::setLength):
+ * loader/FTPDirectoryDocument.cpp:
+ (WebCore::FTPDirectoryTokenizer::appendEntry):
+ (WebCore::FTPDirectoryTokenizer::createTDForFilename):
+ (WebCore::FTPDirectoryTokenizer::loadDocumentTemplate):
+ (WebCore::FTPDirectoryTokenizer::createBasicDocument):
+ * loader/ImageDocument.cpp:
+ (WebCore::ImageDocument::createDocumentStructure):
+ * loader/MediaDocument.cpp:
+ (WebCore::MediaTokenizer::createDocumentStructure):
+ * loader/PluginDocument.cpp:
+ (WebCore::PluginTokenizer::createDocumentStructure):
+ * loader/TextDocument.cpp:
+ (WebCore::TextTokenizer::write):
+ * page/Frame.cpp:
+ (WebCore::Frame::selectionComputedStyle):
+ (WebCore::Frame::styleForSelectionStart):
+ Document::createElement(const AtomicString&, ...) to Document::createElement(const QualifiedName&, ...) switch.
+
+ * xml/XPathFunctions.cpp:
+ (WebCore::XPath::FunLang::evaluate): Re-use langAttr instead of creating a new attribute.
+ * page/DragController.cpp:
+ (WebCore::documentFragmentFromDragData): Use the HTMLAnchorElement directly to get rid of the static cast.
+
+2009-02-19 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24060
+ Fix up to accommodate for CanvasPixelArray return.
+
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::getImageData): Added an extra data() to call.
+ (WebCore::ImageBuffer::putImageData): Ditto.
+
+2009-02-20 Eric Carlson <eric.carlson@apple.com>
+
+ Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=24042
+ Bug 24042: MediaPlayer should cache plug-in proxy
+
+ The changes in https://bugs.webkit.org/show_bug.cgi?id=23917 assume that
+ MediaPlayer will always have created the private media player object before
+ the plug-in is instantiated and calls back with the proxy object. This is not
+ true on all platforms because of threading latency, so MediaPlayer should
+ cache the plug-in proxy so it can pass it to the media engine at a later time.
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::NullMediaPlayerPrivate::setPoster): Null media engine implementation of proxy methods.
+ (WebCore::NullMediaPlayerPrivate::deliverNotification): Ditto.
+ (WebCore::NullMediaPlayerPrivate::setMediaPlayerProxy): Ditto.
+ (WebCore::MediaPlayer::MediaPlayer): Initialize m_playerProxy.
+ (WebCore::MediaPlayer::load): Pass m_playerProxy to newly created engine.
+ (WebCore::MediaPlayer::setMediaPlayerProxy): Cache m_playerProxy.
+ * platform/graphics/MediaPlayer.h: Declare m_playerProxy.
+
+2009-02-20 Eric Carlson <eric.carlson@apple.com>
+
+ Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24063
+ Make it possible for a port to require a user gesture to play/pause an <audio> or <video> element
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Rename m_loadRestrictions to m_Restrictions.
+ Initialize m_internalCall.
+ (WebCore::HTMLMediaElement::loadTimerFired): Increment m_internalCall around call to load().
+ (WebCore::HTMLMediaElement::load): Call loadInternal if restrictions check out.
+ (WebCore::HTMLMediaElement::loadInternal): New, guts of old load()
+ (WebCore::HTMLMediaElement::setNetworkState): Fix bug introduced in r40943
+ (WebCore::HTMLMediaElement::play): Call playInternal if restrictions check out.
+ (WebCore::HTMLMediaElement::playInternal): New, guts of old play()
+ (WebCore::HTMLMediaElement::pause): Call pauseInternal if restrictions check out.
+ (WebCore::HTMLMediaElement::pauseInternal): New, guts of old pause()
+ (WebCore::HTMLMediaElement::togglePlayState): Call playInternal/pauseInternal
+ (WebCore::HTMLMediaElement::deliverNotification): Remove unnecessary white space.
+ * html/HTMLMediaElement.h: Rename m_loadRestrictions to m_Restrictions, add m_internalCall,
+ add RequireUserGestureRateChangeRestriction.
+
+2009-02-20 Darin Fisher <darin@chromium.org>
+
+ Fix build bustage in FileSystemWin.cpp.
+
+ Need to return CString() instead of 0 since there are now two CString
+ constructors that take a pointer type.
+
+ * platform/win/FileSystemWin.cpp:
+ (WebCore::openTemporaryFile):
+
+2009-02-20 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23999
+ Change license headers to accurately reflect code history.
+
+ * platform/ContentType.cpp:
+ * platform/ContentType.h:
+
+2009-02-18 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Antti Koivisto.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23999
+ Split off MIME type parsing into its own class.
+
+ * GNUmakefile.am: Added ContentType sources.
+ * WebCore.pro: Ditto.
+ * WebCore.scons: Ditto.
+ * WebCore.vcproj/WebCore.vcproj: Ditto.
+ * WebCore.xcodeproj/project.pbxproj: Ditto.
+ * WebCoreSources.bkl: Ditto.
+ * html/HTMLMediaElement.cpp: Changed to use ContentType.
+ (WebCore::HTMLMediaElement::selectMediaURL):
+ * platform/ContentType.cpp: Added.
+ (WebCore::ContentType::ContentType):
+ (WebCore::ContentType::parameter):
+ (WebCore::ContentType::type):
+ * platform/ContentType.h: Added.
+ (WebCore::ContentType::raw):
+ * platform/MIMETypeRegistry.cpp:
+ * platform/MIMETypeRegistry.h:
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::load):
+ * rendering/style/ContentData.h: Renamed ContentType to StyleContentType.
+ * rendering/style/RenderStyleConstants.h: Ditto.
+ (WebCore::):
+
+2009-02-20 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Unreviewed build fix.
+
+ Use CString() instead of 0.
+
+ * platform/gtk/FileSystemGtk.cpp:
+ (WebCore::openTemporaryFile):
+ * platform/qt/FileSystemQt.cpp:
+ (WebCore::openTemporaryFile):
+
+2009-02-20 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ When dealing with local files, use a path instead of an URI. GFile
+ has problems decoding URIs with percent signs on them.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::startGio):
+
+2009-02-20 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Protect the ResourceHandle instance from being destroyed by
+ didReceiveData inside the GIO readCallback call, so that
+ cancelling caused by scripts is handled correctly.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::readCallback):
+
+2009-02-20 David Kilzer <ddkilzer@apple.com>
+
+ Make IconDatabaseNone.cpp compile with -Wunused and pass check-for-exit-time-destructors
+
+ Reviewed by Sam Weinig.
+
+ * loader/icon/IconDatabaseNone.cpp:
+ (WebCore::IconDatabase::defaultDatabaseFilename): Use DEFINE_STATIC_LOCAL().
+ (WebCore::IconDatabase::open): Commented out unused parameter.
+ (WebCore::IconDatabase::setPrivateBrowsingEnabled): Ditto.
+ (WebCore::IconDatabase::iconForPageURL): Ditto.
+ (WebCore::IconDatabase::iconURLForPageURL): Ditto.
+ (WebCore::IconDatabase::defaultIcon): Ditto.
+ (WebCore::IconDatabase::retainIconForPageURL): Ditto.
+ (WebCore::IconDatabase::releaseIconForPageURL): Ditto.
+ (WebCore::IconDatabase::setIconDataForIconURL): Ditto.
+ (WebCore::IconDatabase::setIconURLForPageURL): Ditto.
+ (WebCore::IconDatabase::setEnabled): Ditto.
+ (WebCore::IconDatabase::pageURLMappingCount): Added stub.
+ (WebCore::IconDatabase::retainedPageURLCount): Ditto.
+ (WebCore::IconDatabase::iconRecordCount): Ditto.
+ (WebCore::IconDatabase::iconRecordCountWithData): Ditto.
+
+2009-02-20 David Kilzer <ddkilzer@apple.com>
+
+ Add comment to generated code when shadowing a built-in object
+
+ Reviewed by Sam Weinig.
+
+ * bindings/scripts/CodeGeneratorJS.pm: Added comment to
+ generated code output.
+
+2009-02-20 Avi Drissman <avi@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24036
+ Keyboard events need disambiguation on the Linux platform too.
+
+ * platform/chromium/PlatformKeyboardEventChromium.cpp:
+ (WebCore::PlatformKeyboardEvent::disambiguateKeyDownEvent):
+
+2009-02-19 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24046
+
+ Several improvements to CString:
+ 1- Make it possible to initialize a CString from a CStringBuffer
+ 2- Make it possible to get a CStringBuffer from a CString
+ 3- Change CStringBuffer::data() to return a const pointer to ward off mutation
+ 4- Remove unused releaseBuffer() methods.
+ 5- Make CStringBuffer::create() private to force consumers to get a CStringBuffer from a CString.
+
+ * platform/text/CString.cpp:
+ (WebCore::CString::init):
+ (WebCore::CString::mutableData):
+ (WebCore::CString::newUninitialized):
+ (WebCore::CString::copyBufferIfNeeded):
+ * platform/text/CString.h:
+ (WebCore::CStringBuffer::data):
+ (WebCore::CStringBuffer::length):
+ (WebCore::CStringBuffer::create):
+ (WebCore::CStringBuffer::mutableData):
+ (WebCore::CString::CString):
+ (WebCore::CString::buffer):
+
+2009-02-19 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24017
+ Remove some usage of Document in Worker.
+
+ * dom/WorkerContext.h:
+ (WebCore::WorkerContext::userAgent):
+ * dom/Document.cpp:
+ (WebCore::Document::userAgent):
+ * dom/Document.h:
+ * dom/ScriptExecutionContext.h:
+ Added virtual ScriptExecutionContext::userAgent(const KURL&).
+ Document implementation uses FrameLoader::userAgent and
+ WorkerContext receives the string on creation and stores it in a member.
+
+ * dom/Worker.cpp:
+ (WebCore::Worker::Worker):
+ (WebCore::Worker::notifyFinished):
+ * dom/Worker.h:
+ (WebCore::Worker::create):
+ Instead of Document the Worker constructor now gets a ScriptExecutionContext.
+ Start using some methods on SEC (like completeURL() and userAgent()).
+ For others, explicitly case to Document and add a FIXME.
+ Remove Worker::document() too.
+
+2009-02-20 Gustavo Noronha Silva <gns@gnome.org>
+
+ Rubber-stamped by Holger Freyther.
+
+ Do not set httpStatus to SOUP_STATUS_OK when serving local files
+ to match other ports' behavior, fixing xmlhttprequest test
+ regressions.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::queryInfoCallback):
+
+2009-02-19 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ - WebCore part of fixing https://bugs.webkit.org/show_bug.cgi?id=24027
+ Do not send loader callbacks during CSS styling
+
+ Undo the iChat-specific quirk added in
+ <http://trac.webkit.org/changeset/41071>. Instead, always suspend memory
+ cache client callbacks during attach() and recalcStyle().
+
+ * WebCore.base.exp: Removed
+ Settings::setNeedsIChatMemoryCacheCallsQuirk().
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::suspendPostAttachCallbacks): Disable memory
+ cache client callbacks and remember to enable them afterwards if needed.
+ (WebCore::ContainerNode::resumePostAttachCallbacks): Re-enable memory
+ cache client callbacks if they were disabled in
+ suspendPostAttachCallbacks().
+ (WebCore::ContainerNode::attach): Use suspendPostAttachCallbacks() and
+ resumePostAttachCallbacks().
+ * dom/ContainerNode.h: Made suspendPostAttachCallbacks()
+ and resumePostAttachCallbacks() non-static.
+ * dom/Document.cpp:
+ (WebCore::Document::dispatchImageLoadEventsNow): Reverted iChat-specific
+ workaround.
+ * page/Settings.cpp: Removed m_needsIChatMemoryCacheCallsQuirk and
+ related code.
+ (WebCore::Settings::Settings):
+ * page/Settings.h:
+
+2009-02-19 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Unreviewed build fix.
+
+ Build fix after r41092. Make the memoryUsage method
+ public. It will be shadowed by cf/mac and for curl/soup/qt
+ the implementation from ResourceResponseBase will be used.
+
+ * platform/network/ResourceResponseBase.h:
+ (WebCore::ResourceResponseBase::memoryUsage):
+
+2009-02-19 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Fix for <rdar://problem/6077775> Should be able to specify
+ inactive ::selection color
+
+ This patch makes the ::selction pseudo-element work with
+ the :window-inactive pseudo type. This was, a user can specify a
+ different ::selection style when a window is inactive.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::selectionBackgroundColor):
+ (WebCore::RenderObject::selectionForegroundColor):
+
+2009-02-19 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Beth Dakin.
+
+ Patch for https://bugs.webkit.org/show_bug.cgi?id=24044
+ Update querySelector/querySelectorAll to match the latest spec
+
+ Update querySelector and querySelectorAll to match the latest version
+ of the Selectors API spec. We now stringify null and undefined to "null"
+ and "undefined" respectively instead of to "".
+
+ Test: fast/dom/SelectorAPI/undefined-null-stringify.html
+
+ * dom/Document.idl:
+ * dom/DocumentFragment.idl:
+ * dom/Element.idl:
+
+2009-02-19 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Geoffrey Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23732
+ Rework CachedResource overhead accounting to allow platforms to diverge
+ in numbers.
+
+ * loader/CachedResource.cpp:
+ (WebCore::CachedResource::overheadSize): Changed to ask ResourceResponse
+ for its size and to use actual URL size.
+ * platform/network/ResourceResponseBase.h:
+ (WebCore::ResourceResponseBase::size): Added default size method.
+ * platform/network/cf/ResourceResponse.h:
+ (WebCore::ResourceResponse::size): Added Win/CF size method
+ * platform/network/mac/ResourceResponse.h:
+ (WebCore::ResourceResponse::size): Added Mac size method.
+
+2009-02-19 Anders Carlsson <andersca@apple.com>
Reviewed by Kevin Decker.
@@ -14,11 +10332,167 @@
* platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
(WebCore::MediaPlayerPrivate::paint):
-2009-02-18 Mark Rowe <mrowe@apple.com>
+2009-02-19 David Hyatt <hyatt@apple.com>
+
+ Fix a bug where reflections didn't work properly if opacity was < 1. Make sure that replaced elements
+ also consider reflections to be part of their visual overflow. This had already been done for blocks
+ and lines, but it wasn't being done yet for replaced elements.
+
+ Also make sure that when the object being reflected has opacity < 1 that we don't end up popping the outer
+ transparency layer early. Since the reflected object paints twice, we don't want to end the transparency
+ layer it pushed until we're done painting the real object (rather than the reflection).
+
+ Reviewed by Dan Bernstein
+
+ Added fast/reflections/reflection-masks-opacity.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayer):
+ * rendering/RenderPartObject.cpp:
+ (WebCore::RenderPartObject::layout):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::layout):
+ (WebCore::RenderReplaced::adjustOverflowForBoxShadowAndReflect):
+ * rendering/RenderReplaced.h:
+
+2009-02-19 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23980: WorkerRunLoop needs a way to run in a given mode similar to CFRunLoopInMode.
+ <https://bugs.webkit.org/show_bug.cgi?id=23980>
+
+ WorkerRunLoop has the ability to run in a mode which filters the tasks to be run.
+ * When WorkerRunLoop::runInMode is called, only task for that mode will run.
+ * When WorkerRunLoop::run is called (or the default mode is used), then all tasks
+ will run regardless of their posted mode.
+
+ Here's a demonstration of the api:
+
+ RefPtr<NameResolution> nameResolution = NameResolution::create(workerRunLoop);
+
+ // Internally nameResolution will do workerRunLoop.postTaskForMode(task, "MyCoolMode")
+ // for any tasks that need to be run during this loop.
+ nameResolution->setTaskMode("MyCoolMode");
+
+ nameResolution->start();
+ while (!nameResolution->done()) {
+ // Only tasks which are posted for "MyCoolMode" will run.
+ workerRunLoop.runInMode(context, "MyCoolMode");
+ }
+
+ No observable change in behavior, so no test.
+
+ * dom/WorkerRunLoop.cpp:
+ (WebCore::ModePredicate::ModePredicate):
+ (WebCore::ModePredicate::operator()):
+ (WebCore::WorkerRunLoop::WorkerRunLoop):
+ (WebCore::WorkerRunLoop::~WorkerRunLoop):
+ (WebCore::WorkerRunLoop::setSharedTimer):
+ (WebCore::WorkerRunLoop::resetSharedTimer):
+ (WebCore::WorkerRunLoop::run):
+ (WebCore::WorkerRunLoop::runInMode):
+ (WebCore::WorkerRunLoop::postTask):
+ (WebCore::WorkerRunLoop::postTaskForMode):
+ * dom/WorkerRunLoop.h:
+ (WebCore::WorkerRunLoop::Task::create):
+ (WebCore::WorkerRunLoop::Task::mode):
+ (WebCore::WorkerRunLoop::Task::performTask):
+ (WebCore::WorkerRunLoop::Task::Task):
+
+2009-02-19 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24034
+ Fix up Selection->VisibleSelection change.
+
+ * page/chromium/EventHandlerChromium.cpp:
+ (WebCore::EventHandler::passMousePressEventToSubframe): Renamed Selection
+ to VisibleSelection.
+
+2009-02-19 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24041
+ Correct Skia type conversion issues, fix Chromium Linux build.
- Merge r41071.
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::Font::drawGlyphs): changed parameters to RGBA32, not WebCore::Color.
- 2009-02-18 Dan Bernstein <mitz@apple.com>
+2009-02-19 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20531
+ Chromium-part follow-up to the patch landed in r40636
+ for bug 20531.
+ Remove a static member function alternateFamilyName
+ from Chromium's Win/Linux ports of FontCache. In r40636,
+ alternateFamilyName was customized using #ifdef PLATFORM(WIN_OS).
+ So, there's no more need for the static member function per
+ platform.
+
+ * platform/graphics/chromium/FontCacheChromiumWin.cpp:
+ * platform/graphics/chromium/FontCacheLinux.cpp:
+
+2009-02-19 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ Call documentWillBecomeInactive() from Document::detach to ensure that
+ media elements are shut down, because they may be kept alive by references
+ from JS past document teardown.
+
+ documentWillBecomeInactive() calls renderView()->willMoveOffscreen(), so no
+ need to do that in detach() as well.
+
+ We no longer need to call documentWillBecomeInactive() from ~Page() (which
+ was added for <https://bugs.webkit.org/show_bug.cgi?id=21116>), since this
+ supersedes that change.
+
+ * dom/Document.cpp:
+ (WebCore::Document::detach):
+ * page/Page.cpp:
+ (WebCore::Page::~Page):
+
+2009-02-19 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24028
+ Fix up Skia path changes.
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::strokePath): Removed illegal indirection.
+ * platform/graphics/skia/PathSkia.cpp:
+ (WebCore::boundingBoxForCurrentStroke): Changed call name.
+
+2009-02-19 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Ignore ports on local URLs. This fixes a regression in
+ fast/loader/file-URL-with-port-number.html
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::startGio):
+
+2009-02-19 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24011
+ KURL's setPort doesn't unset port if 0 is given
+
+ Make setPort remove port if 0 is given to it, as promised by the
+ comment in KURL's header.
+
+ * platform/KURL.cpp:
+ (WebCore::KURL::setPort):
+
+2009-02-18 Dan Bernstein <mitz@apple.com>
Reviewed by Brady Eidson.
@@ -50,11 +10524,356 @@
* page/Settings.h:
(WebCore::Settings::needsIChatMemoryCacheCallsQuirk): Added this getter.
-2009-02-16 Mark Rowe <mrowe@apple.com>
+2009-02-18 Adam Roben <aroben@apple.com>
+
+ Export WebCore::handCursor and Cursor.h
+
+ Reviewed by John Sullivan.
+
+ * WebCore.base.exp: Added WebCore::handCursor.
+ * WebCore.xcodeproj/project.pbxproj: Made Cursor.h private.
+
+2009-02-18 Ojan Vafai <ojan@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23992
+ REGRESSION: crash on windows loading http://www.stickam.com/liveStreams.do
+
+ Unable to reduce to a layout test.
+
+ * page/Frame.cpp:
+ (WebCore::Frame::contentRenderer):
+
+2009-02-18 Evan Stade <estade@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23861
+ Stroke font outlines on chromium linux
+
+ TEST=LayoutTests/svg/custom/pointer-events-text.svg
+
+ * platform/graphics/chromium/FontLinux.cpp:
+ (WebCore::Font::drawGlyphs):
+
+2009-02-18 Evan Stade <estade@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23860
+ Resync some graphics/skia files with their chromium counterparts
+
+ This comes from chromium patches <http://codereview.chromium.org/17633>
+ and <http://codereview.chromium.org/17454>
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::clipPath):
+ (WebCore::GraphicsContext::fillPath):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::addPath):
+ (PlatformContextSkia::currentPath):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2009-02-18 Gustavo Noronha Silva <gns@gnome.org>
+
+ Unreviewed.
+
+ Build fix after r41060.
+
+ * GNUmakefile.am:
+
+2009-02-18 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=24005
+ Add an include to fix Chromium build.
+
+ * page/animation/AnimationController.cpp: Add UnusedParam.h include.
+
+2009-02-18 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ Fix symbols.filter location, and add other missing files to the
+ autotools build, so that make dist works.
+
+ * GNUmakefile.am:
+
+2009-02-18 Zan Dobersek <zandobersek@gmail.com>
+
+ Rubber-stamped by Holger Hans Peter Freyther.
+
+ Allow POST method for local requests.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::startGio):
+
+2009-02-18 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Holger Hans Peter Freyther.
+
+ Use KURL in startGio instead of passing a string with the URL, so
+ that we can handle removing refs and queries more elegantly. This
+ is fixing more regressions that came from the curl->soup switch.
+
+ Original work by Zan Dobersek.
+
+ * platform/network/ResourceHandle.h:
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::start):
+ (WebCore::ResourceHandle::startGio):
+
+2009-02-18 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Implement ResourceHandle::loadResourceSynchronously in ResourceHandleSoup.cpp
+
+ The implementation is needed to have synchronous loading, e.g. for
+ JavaScript interaction. This is fixing various regressions that
+ came from the curl->soup switch.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::WebCoreSynchronousLoader::WebCoreSynchronousLoader):
+ (WebCore::WebCoreSynchronousLoader::~WebCoreSynchronousLoader):
+ (WebCore::WebCoreSynchronousLoader::didReceiveResponse):
+ (WebCore::WebCoreSynchronousLoader::didReceiveData):
+ (WebCore::WebCoreSynchronousLoader::didFinishLoading):
+ (WebCore::WebCoreSynchronousLoader::didFail):
+ (WebCore::WebCoreSynchronousLoader::run):
+ (WebCore::ResourceHandle::loadResourceSynchronously):
+
+2009-02-18 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23989
+
+ Based on a patch by Bo Yang <techrazy.yang@gmail.com>
+
+ Make the cursor cache global, that's all we really need and
+ otherwise we can miss cursor transitions in some situations (see
+ the bug for one testcase). Also remove some now useless code.
+
+ * platform/Widget.h:
+ * platform/gtk/WidgetGtk.cpp:
+ (WebCore::Widget::Widget):
+ (WebCore::Widget::~Widget):
+ (WebCore::Widget::setCursor):
+
+2009-02-17 Adam Roben <aroben@apple.com>
+
+ Windows build fix
+
+ * loader/FrameLoader.cpp:
+ (WebCore::toPlugInElement): Don't rely on #if being processed before
+ ASSERT.
+
+2009-02-17 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23977: Unnecessary timer related headers in files.
+ <https://bugs.webkit.org/show_bug.cgi?id=23977>
+
+ No observable change in behavior, so no test.
+
+ * dom/Document.cpp:
+ * dom/WorkerRunLoop.cpp:
+ * dom/WorkerRunLoop.h:
+
+2009-02-17 Peter Abrahamsen <rainhead@gmail.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23958
+ <rdar://problem/6587815>
+
+ Updated XMLHttpRequest with new header names from the latest Access
+ Control draft: http://www.w3.org/TR/access-control/
+ - Access-Control-Origin becomes Access-Control-Allow-Origin
+ - Access-Control-Credentials becomes Access-Control-Allow-Credentials
+
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::accessControlCheck):
+
+2009-02-17 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix. Add missing constructor used for empty values.
+
+ * platform/graphics/wx/FontPlatformData.h:
+ (WebCore::FontPlatformData::FontPlatformData):
+
+2009-02-17 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Dave Kilzer.
+
+ <rdar://problem/6592446> dynamically updating page doesn't seem to draw when updated
+
+ Need update after callback.
+
+ * bindings/js/JSCustomPositionCallback.cpp:
+ (WebCore::JSCustomPositionCallback::handleEvent):
+ * bindings/js/JSCustomPositionErrorCallback.cpp:
+ (WebCore::JSCustomPositionErrorCallback::handleEvent):
+
+2009-02-17 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Antti Koivisto.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23917
+ Allow a WebKit plug-in to act as a proxy for the <audio> and <video>
+ element.
+
+ * DerivedSources.make: add media element proxy exports to .exp file when feature is defined.
+
+ * WebCore.VideoProxy.exp: New, define the informal protocol exported by a media element proxy.
+
+ * WebCore.xcodeproj/project.pbxproj: Add MediaPlayerProxy.h.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_needWidgetUpdate.
+ (WebCore::HTMLMediaElement::attributeChanged): Don't detach+attach when PLUGIN_PROXY_FOR_VIDEO, the
+ proxy plug-in handles the poster frame.
+ (WebCore::HTMLMediaElement::rendererIsNeeded): New logic for PLUGIN_PROXY_FOR_VIDEO.
+ (WebCore::HTMLMediaElement::createRenderer): Create RenderPartObject when PLUGIN_PROXY_FOR_VIDEO.
+ (WebCore::HTMLMediaElement::attach): Set m_needWidgetUpdate when PLUGIN_PROXY_FOR_VIDEO
+ (WebCore::HTMLMediaElement::load): Don't reallocate MediaPlayer when PLUGIN_PROXY_FOR_VIDEO, we keep the
+ same plug-in for the life of the element.
+ (WebCore::HTMLMediaElement::mediaPlayerNetworkStateChanged): update m_networkState when media player
+ network state changes to EMPTY, otherwise we can get out of sync with engine.
+ (WebCore::HTMLMediaElement::defaultEventHandler): pass event to widget when PLUGIN_PROXY_FOR_VIDEO
+ (WebCore::HTMLMediaElement::deliverNotification): New, deliver notification from proxy plug-in to
+ media player.
+ (WebCore::HTMLMediaElement::setMediaPlayerProxy): New, pass proxy object to media player.
+ (WebCore::HTMLMediaElement::initialURL): New, return the url from the "src" attr or the appropriate
+ <source> element to be used as the initial url for the proxy.
+ (WebCore::HTMLMediaElement::finishParsingChildren): New, allocate MediaPlayer and update widget.
+ * html/HTMLMediaElement.h: Declare new methods for proxy, add m_needWidgetUpdate.
+ (WebCore::HTMLMediaElement::setNeedWidgetUpdate):
+
+ * html/HTMLVideoElement.cpp:
+ (WebCore::HTMLVideoElement::attach): Poster image is handled by proxy when PLUGIN_PROXY_FOR_VIDEO.
+ (WebCore::HTMLVideoElement::parseMappedAttribute): Ditto.
+ * html/HTMLVideoElement.h:
+
+ * loader/FrameLoader.cpp:
+ (WebCore::toPlugInElement): Allow cast if element is <video> or <audio>
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::MediaPlayer::MediaPlayer): Remove white space.
+ (WebCore::MediaPlayer::setPoster): New, forward call to private player.
+ (WebCore::MediaPlayer::deliverNotification): Ditto.
+ (WebCore::MediaPlayer::setMediaPlayerProxy): Ditto.
+ * platform/graphics/MediaPlayer.h:
+ (WebCore::MediaPlayer::mediaPlayerClient):
+
+ * platform/graphics/mac/MediaPlayerProxy.h: New, defines media player proxy interface.
+
+ * rendering/RenderPart.cpp:
+ (WebCore::RenderPart::RenderPart): Change constructor to take Element* instead of Node* as a
+ non-element node doesn't need a renderer
+ * rendering/RenderPart.h: Ditto.
+
+ * rendering/RenderPartObject.cpp:
+ (WebCore::RenderPartObject::RenderPartObject): Ditto.
+ (WebCore::RenderPartObject::updateWidget): Package params for proxy plug-in when element is
+ <video> or <audio>.
+ * rendering/RenderPartObject.h:
+
+2009-02-17 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23985
+
+ Don't allow legends to be anything but display:block.
+
+ Added fast/forms/inline-ignored-on-legend.html
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * css/html4.css:
+ * html/HTMLLegendElement.cpp:
+ * html/HTMLLegendElement.h:
+ * rendering/RenderLegend.cpp: Removed.
+ * rendering/RenderLegend.h: Removed.
+ * wml/WMLInsertedLegendElement.cpp:
+ * wml/WMLInsertedLegendElement.h:
+
+2009-02-13 Brett Wilson <brettw@dhcp-172-22-71-167.mtv.corp.google.com>
- Merge r41027.
+ Reviewed by Simon Fraser.
- 2009-02-16 Dan Bernstein <mitz@apple.com>
+ https://bugs.webkit.org/attachment.cgi?id=27666
+ Fix Chromium build build: forgotten include in RenderObject, sync
+ RenderTheme to the recent changes in RenderObject.
+
+ * rendering/RenderObject.cpp:
+ * rendering/RenderThemeChromiumMac.mm:
+ (WebCore::RenderThemeChromiumMac::updatePressedState):
+
+2009-02-17 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22966
+ crash when destroying a webview that opened a page containing <script>
+ tags
+
+ Fix m_group being set to 0 instead of to m_singlePageGroup when
+ GroupName is set to empty
+
+ * page/Page.cpp:
+ (WebCore::Page::setGroupName):
+
+2009-02-16 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fix for <rdar://problem/6386623>
+
+ I made m_numParsedProperties and m_maxParsedProperties unsigned
+ instead of int, and then added an early return from addPropery() if
+ m_maxParsedProperties exceeds the max value.
+
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::addProperty):
+ (WebCore::CSSParser::rollbackLastProperties):
+ (WebCore::CSSParser::clearProperties):
+ (WebCore::CSSParser::createFontFaceRule):
+ (WebCore::CSSParser::deleteFontFaceOnlyValues):
+ * css/CSSParser.h:
+
+2009-02-16 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=16309
+ HTML5: The third execCommand argument for insert{un}orderedlist should be ignored
+
+ When we originally implemented this command, MSDN documentation said that IE set the
+ id attribute of inserted lists to the third argument to execCommand, but IE doesn't
+ do this nor do any other browsers.
+
+ * editing/EditorCommand.cpp:
+ (WebCore::executeInsertOrderedList):
+ (WebCore::executeInsertUnorderedList):
+ * editing/IndentOutdentCommand.cpp:
+ (WebCore::IndentOutdentCommand::outdentParagraph):
+ * editing/InsertListCommand.cpp:
+ (WebCore::InsertListCommand::insertList):
+ (WebCore::InsertListCommand::InsertListCommand):
+ (WebCore::InsertListCommand::doApply):
+ * editing/InsertListCommand.h:
+ (WebCore::InsertListCommand::create):
+
+2009-02-16 Dan Bernstein <mitz@apple.com>
Reviewed by Geoffrey Garen.
@@ -67,11 +10886,2055 @@
pointer-events property in Dashboard backwards compatibility mode,
in order to work around misuse of that property by the Stocks widget.
-2009-02-11 Mark Rowe <mrowe@apple.com>
+2009-02-16 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=15381
+ execCommand justify modifies the contentEditable node
+
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary): Avoid modifying not just
+ the body element, but any root editable element.
+
+2009-02-16 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ Bug 23979: AX: alt tag not returned for <input type="image">
+ https://bugs.webkit.org/show_bug.cgi?id=23979
+
+ Test: accessibility/input-image-alt.html
+
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::accessibilityDescription):
+
+2009-02-16 Kevin Watters <kevinwatters@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ The ref data is not properly set unless we use the CreateMatrix function.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23978
+
+ * platform/graphics/wx/TransformationMatrixWx.cpp:
+ (WebCore::TransformationMatrix::operator wxGraphicsMatrix):
+
+2009-02-16 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by John Sullivan.
+
+ - fix <rdar://problem/6516829> FontPlatformData constructor passes NULL to CTFontCopyGraphicsFont and CTFontGetPlatformFont
+
+ * platform/graphics/FontCache.cpp:
+ (WebCore::FontDataCacheKeyTraits::emptyValue): Changed to use the
+ FontPlatformData(float, bool, bool) constructor.
+ * platform/graphics/mac/FontCacheMac.mm:
+ (WebCore::FontCache::createFontPlatformData): Changed to pass a valid
+ NSFont to the FontPlatformData constructor, instead of implicitly
+ passing 0 and then calling setFont().
+ * platform/graphics/mac/FontPlatformData.h: Made the NSFont parameter
+ of the constructor mandatory.
+
+2009-02-15 David Kilzer <ddkilzer@apple.com>
+
+ Move duplicate caretWidth constants to RenderObject.h
+
+ Reviewed by Dan Bernstein.
+
+ No test since no change in behavior.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::localCaretRect): Removed caretWidth.
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::localCaretRect): Ditto.
+ * rendering/RenderObject.h: Added caretWidth definition.
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::localCaretRect): Removed caretWidth.
+
+2009-02-13 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23955
+ V8HTMLPlugInCustom returns undefined, which fools interceptors.
+
+ * bindings/v8/custom/V8HTMLPlugInElementCustom.cpp:
+ (WebCore::NAMED_PROPERTY_GETTER): Use deferToInterceptor() return value.
+ (WebCore::NAMED_PROPERTY_SETTER): Ditto.
+ (WebCore::INDEXED_PROPERTY_GETTER): Ditto.
+ (WebCore::INDEXED_PROPERTY_SETTER): Ditto.
+
+2009-02-13 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23954
+ Add V8 custom bindings for CanvasRenderingContext2D.
+
+ * bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp: Added.
+ (WebCore::toV8):
+ (WebCore::toCanvasStyle):
+ (WebCore::ACCESSOR_GETTER):
+ (WebCore::ACCESSOR_SETTER):
+
+2009-02-13 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Darin Adler and Dan Bernstein.
+
+ <rdar://problem/6583187>
+
+ * page/NavigatorBase.cpp:
+ Handle PPC64 and X86_64 as well.
+
+2009-02-13 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Fix broken tokenizer regression test that reflected a lifetime bug
+ in the document.write optimization. The test failure was trivial to
+ reproduce in COLLECT_ON_EVERY_ALLOCATION mode.
+
+ * bindings/js/JSHTMLDocumentCustom.cpp:
+ (WebCore::documentWrite): Convert strings to String rather than passing
+ the pointer and length to SegmentedString. The optimization is thus
+ mostly gone. However, there are two ways to bring it back: 1) Apply
+ the patch that makes UString and String share the same buffers.
+ 2) Add a UString feature to SegmentedString; simple to do but might
+ risk slowing down normal document parsing.
+
+2009-02-13 Adam Treat <adam.treat@torchmobile.com>
+
+ Caught by Darin Adler.
+
+ No reason to check m_tokenizer twice for 0 in a row.
+
+ * dom/Document.cpp:
+ (WebCore::Document::write):
+
+2009-02-13 Lyon Chen <lyon.chen@torchmobile.com>
+
+ Reviewed by Dave Hyatt.
+
+ Take into account y() + height() when calculating getLowerRightCorner.
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::getLowerRightCorner):
+
+2009-02-13 Antti Koivisto <antti@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Most of this code was in RenderBox, restore the copyright lines.
+
+ * rendering/RenderBoxModelObject.cpp:
+ * rendering/RenderBoxModelObject.h:
+
+2009-02-13 David Hyatt <hyatt@apple.com>
+
+ Get rid of printBoxDecorations, since it is dead code.
+
+ Reviewed by Dan Bernstein
+
+ * rendering/RenderObject.h:
+
+2009-02-13 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23952
+ Add Document::write overload which takes a SegmentedString since this
+ is what the tokenizer expects anyway. Modified JSHTMLDocument so it once
+ again calls Document::write instead of injecting the string directly into
+ the tokenizer. This ensures that all document.write's are funneled through
+ one method again, but should still be just as fast for JSHTMLDocumentCustom.
+
+ * bindings/js/JSHTMLDocumentCustom.cpp:
+ (WebCore::documentWrite):
+ * dom/Document.cpp:
+ (WebCore::Document::write):
+ * dom/Document.h:
+
+2009-02-13 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Simon Fraser
+
+ Remove updateWidgetPosition on RenderObject. Change RenderView's set of widgets
+ to have a tighter type: RenderWidget instead of RenderObject. Devirtualize
+ updateWidgetPosition, since all RenderWidgets (except for applets) are now
+ RenderParts also.
+
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ * rendering/RenderPart.cpp:
+ * rendering/RenderPart.h:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::updateWidgetPositions):
+ (WebCore::RenderView::addWidget):
+ (WebCore::RenderView::removeWidget):
+ * rendering/RenderView.h:
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::updateWidgetPosition):
+ * rendering/RenderWidget.h:
+
+2009-02-13 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Remove isEditable() on RenderObject. It is dead code.
+
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+
+2009-02-13 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Add isTextControl() to RenderObject. Patch call sites thats asked isTextField() || isTextArea() to just use
+ isTextControl() instead.
+
+ Add a toRenderTextControl converter for doing checked casting to RenderTextControls.
+
+ * dom/Document.cpp:
+ (WebCore::Document::setFocusedNode):
+ * dom/InputElement.cpp:
+ (WebCore::InputElement::updateSelectionRange):
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplacementFragment::ReplacementFragment):
+ * editing/TextIterator.cpp:
+ (WebCore::TextIterator::handleReplacedElement):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::selectionStart):
+ (WebCore::HTMLInputElement::selectionEnd):
+ (WebCore::HTMLInputElement::setSelectionStart):
+ (WebCore::HTMLInputElement::setSelectionEnd):
+ (WebCore::HTMLInputElement::select):
+ (WebCore::HTMLInputElement::defaultEventHandler):
+ (WebCore::HTMLInputElement::selection):
+ * html/HTMLTextAreaElement.cpp:
+ (WebCore::HTMLTextAreaElement::selectionStart):
+ (WebCore::HTMLTextAreaElement::selectionEnd):
+ (WebCore::HTMLTextAreaElement::setSelectionStart):
+ (WebCore::HTMLTextAreaElement::setSelectionEnd):
+ (WebCore::HTMLTextAreaElement::select):
+ (WebCore::HTMLTextAreaElement::setSelectionRange):
+ (WebCore::HTMLTextAreaElement::appendFormData):
+ (WebCore::HTMLTextAreaElement::updateValue):
+ (WebCore::HTMLTextAreaElement::selection):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::isNativeTextControl):
+ (WebCore::AccessibilityRenderObject::text):
+ (WebCore::AccessibilityRenderObject::selectedText):
+ (WebCore::AccessibilityRenderObject::selectedTextRange):
+ (WebCore::AccessibilityRenderObject::setSelectedTextRange):
+ (WebCore::AccessibilityRenderObject::visiblePositionForIndex):
+ (WebCore::AccessibilityRenderObject::indexForVisiblePosition):
+ (WebCore::AccessibilityRenderObject::observableObject):
+ * page/Frame.cpp:
+ (WebCore::Frame::notifyRendererOfSelectionChange):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isTextControl):
+ (WebCore::objectIsRelayoutBoundary):
+ * rendering/RenderTextControl.h:
+ (WebCore::RenderTextControl::isTextControl):
+ (WebCore::toRenderTextControl):
+ * rendering/TextControlInnerElements.cpp:
+ (WebCore::TextControlInnerTextElement::defaultEventHandler):
+ * wml/WMLInputElement.cpp:
+ (WebCore::WMLInputElement::select):
+ (WebCore::WMLInputElement::defaultEventHandler):
+ (WebCore::WMLInputElement::isConformedToInputMask):
+
+2009-02-13 David Hyatt <hyatt@apple.com>
+
+ Get rid of isEdited/setEdited on RenderObject. Devirtualize isEdited/setEdited on RenderTextControl.
+ Callers were already asking if the renderer was a text field (or a text area), so it was especially
+ pointless to waste a second virtual function call after making one just to determine the object type.
+
+ Reviewed by Simon Fraser
+
+ * dom/Document.cpp:
+ (WebCore::Document::setFocusedNode):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::defaultEventHandler):
+ * rendering/RenderObject.h:
+ * rendering/RenderTextControl.h:
+ (WebCore::RenderTextControl::isEdited):
+ (WebCore::RenderTextControl::setEdited):
+
+2009-02-13 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23934
+ Skia platform doesn't render text decoration shadows.
+
+ Makes Skia render text decoration shadows correctly. We weren't
+ preparing the SkPaint correctly and didn't have a couple of checks
+ CG has. Additionally makes the fillColor/strokeColor methods
+ consistent.
+
+ This behavior is covered by existing layout tests (see bug for list).
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::drawLineForText):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::effectiveFillColor):
+ (PlatformContextSkia::effectiveStrokeColor):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2009-02-12 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23944
+ KURLGoogle's pre-parsed canonicalSpec constructor should take a CString
+
+ * platform/KURL.h:
+ * platform/KURLGoogle.cpp:
+ (WebCore::KURLGooglePrivate::setUtf8):
+ (WebCore::KURLGooglePrivate::setAscii):
+ (WebCore::KURLGooglePrivate::init):
+ (WebCore::KURLGooglePrivate::replaceComponents):
+ (WebCore::KURL::KURL):
+ * platform/KURLGooglePrivate.h:
+
+2009-02-13 David Hyatt <hyatt@apple.com>
+
+ Remove leftmost/rightmost/lowestPosition from RenderObject. They only need to be called on boxes.
+
+ Reviewed by Dan Bernstein
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::lowestPosition):
+ (WebCore::RenderBlock::rightmostPosition):
+ (WebCore::RenderBlock::leftmostPosition):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::computeScrollDimensions):
+ * rendering/RenderMedia.cpp:
+ (WebCore::RenderMedia::lowestPosition):
+ (WebCore::RenderMedia::rightmostPosition):
+ (WebCore::RenderMedia::leftmostPosition):
+ * rendering/RenderObject.h:
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::lowestPosition):
+ (WebCore::RenderTableSection::rightmostPosition):
+ (WebCore::RenderTableSection::leftmostPosition):
+
+2009-02-12 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build with ACCELERATED_COMPOSITING turned on.
+
+ toRenderBox()->x() asserts for a layer on an inline; use
+ m_owningLayer->renderBoxX() instead.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::paintIntoLayer):
+
+2009-02-12 Darin Adler <darin@apple.com>
- Merge r40847.
+ Reviewed by Oliver Hunt.
+
+ Speed up document.write a bit.
+
+ * bindings/js/JSHTMLDocumentCustom.cpp:
+ (WebCore::documentWrite): Added. Uses SegmentedString to avoid conversion from
+ UString to String and to avoid appending strings. Also added code to handle
+ newlines efficiently.
+ (WebCore::JSHTMLDocument::write): Changed to use documentWrite.
+ (WebCore::JSHTMLDocument::writeln): Ditto.
+
+ * dom/Document.cpp:
+ (WebCore::Document::prepareToWrite): Added. Refactored the initialization part
+ of write into a separate function for use in the JavaScript binding.
+ (WebCore::Document::write): Changed to call prepareToWrite.
+
+ * dom/Document.h: Added declaration for prepareToWrite.
+
+2009-02-13 Prasanth Ullattil <pullatti@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fixes crash in the Qt port on Windows with comboboxes
+
+ The focusWidget in the input context is not reset properly.
+ The QApplication::setFocusWidget() wont reset the IC if the reason is
+ PopupFocusReason, this is not ideal. For the time being we are going
+ to do this from webkit itself.
+
+ * platform/qt/QWebPopup.cpp:
+ (WebCore::QWebPopup::hidePopup):
+
+2009-02-12 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix, typo while tweaking last patch for commit.
+
+ * platform/wx/wxcode/gtk/fontprops.cpp:
+ (GetTextExtent):
+
+2009-02-12 miggilin <mr.diggilin@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ Use Cairo/PANGO to fix text measurements and implement proper
+ non-kerned text drawing on wxGTK.
+
+ https://bugs.webkit.org/show_bug.cgi?id=17727
+
+ * platform/graphics/GlyphBuffer.h:
+ * platform/graphics/wx/FontPlatformDataWx.cpp:
+ (WebCore::fontWeightToWxFontWeight):
+ * platform/graphics/wx/SimpleFontDataWx.cpp:
+ (WebCore::SimpleFontData::platformWidthForGlyph):
+ * platform/wx/wxcode/fontprops.h:
+ * platform/wx/wxcode/gtk/fontprops.cpp:
+ (wxFontProperties::wxFontProperties):
+ (GetTextExtent):
+ * platform/wx/wxcode/gtk/non-kerned-drawing.cpp:
+ (WebCore::pangoFontMap):
+ (WebCore::createPangoFontForFont):
+ (WebCore::createScaledFontForFont):
+ (WebCore::pango_font_get_glyph):
+ (WebCore::drawTextWithSpacing):
+ * platform/wx/wxcode/non-kerned-drawing.h:
+
+2009-02-12 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=23942
+
+ Hook up 3D CSS transforms to the accelerated compositor backend.
+ Not enabled by default.
+
+ * page/animation/AnimationBase.cpp:
+ (WebCore::blendFunc):
+ (WebCore::ensurePropertyMap):
+ * page/animation/CompositeAnimation.cpp:
+ (WebCore::CompositeAnimationPrivate::updateTransitions):
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::willNeedService):
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::willNeedService):
+ * platform/graphics/GraphicsLayer.cpp:
+ (WebCore::GraphicsLayer::TransformValueList::makeFunctionList):
+ (WebCore::GraphicsLayer::dumpProperties):
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::copyTransform):
+ (WebCore::getValueFunctionNameForTransformOperation):
+ (WebCore::GraphicsLayerCA::animateTransform):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::updateBoxModelInfoFromStyle):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateTransform):
+ (WebCore::RenderLayer::hasTransformStyle3D):
+ (WebCore::RenderLayer::hasPerspective):
+ (WebCore::RenderLayer::perspectiveTransform):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayers):
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ (WebCore::RenderLayerBacking::computeTransformOrigin):
+ (WebCore::RenderLayerBacking::computePerspectiveOrigin):
+ * rendering/RenderLayerBacking.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::has3DContent):
+ (WebCore::requiresCompositingLayerForTransform):
+ (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+ (WebCore::RenderLayerCompositor::layerHas3DContent):
+ * rendering/RenderLayerCompositor.h:
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Get rid of containingBlockHeight(), since it had only one implementation (despite being virtual) and just returned
+ containingBlock()->availableHeight(). The latter reads better anyway. Rename containingBlockWidth() to
+ containingBlockWidthForContent() and move it to RenderBoxModelObject.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::localCaretRect):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::containingBlockWidthForContent):
+ (WebCore::RenderBox::calcWidth):
+ (WebCore::RenderBox::calcReplacedWidthUsing):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::relativePositionOffsetX):
+ (WebCore::RenderBoxModelObject::relativePositionOffsetY):
+ (WebCore::RenderBoxModelObject::containingBlockWidthForContent):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::marginLeft):
+ (WebCore::RenderInline::marginRight):
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ * rendering/RenderSVGContainer.cpp:
+ (WebCore::RenderSVGContainer::calcReplacedWidth):
+
+2009-02-12 Simon Fraser <simon.fraser@apple.com>
+
+ Fix non-Mac builds by adding Matrix3DTransformOperation.* and
+ PerspectiveTransformOperation.*. Cleaned out some cruft in
+ the WebCore.vcproj fle.
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+
+2009-02-12 David Smith <catfish.man@gmail.com>
+
+ Reviewed by Dave Hyatt.
+
+ Fix https://bugs.webkit.org/show_bug.cgi?id=23935
+ Nested :not() and non-simple selectors in :not() should be invalid
+
+ * css/CSSGrammar.y: Reject nested :not()
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): ASSERT() rather than checking, since the parser enforces it now
+
+2009-02-12 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fixes.
+
+ * WebCoreSources.bkl:
+
+2009-02-12 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build with ACCELERATED_COMPOSITING turned on.
+
+ Need to cast toRenderBox() in order to call overflowClipRect().
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+
+2009-02-12 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Fix windows build.
+
+ * css/CSSParser.h:
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Rename getOverflowClipRect and getClipRect to overflowClipRect and clipRect. Move them to RenderBox, since these methods
+ only apply to boxes. Devirtualize clipRect, since it was not subclassed. Move controlClip stuff to RenderBox also.
+
+ Reviewed by Simon Fraser
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::insideVisibleArea):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::overflowClipRect):
+ (WebCore::RenderBox::clipRect):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::hasControlClip):
+ (WebCore::RenderBox::controlClipRect):
+ * rendering/RenderForeignObject.cpp:
+ (WebCore::RenderForeignObject::paint):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::calculateClipRects):
+ (WebCore::RenderLayer::calculateRects):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::hasClip):
+ (WebCore::RenderObject::hasOverflowClip):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::overflowClipRect):
+ * rendering/RenderTable.h:
+
+2009-02-12 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build with ACCELERATED_COMPOSITING turned on (simple copy/paste error)
+
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::GraphicsLayerCA::setBasicAnimation):
+
+2009-02-12 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Not reviewed.
+
+ Release build fix when VIDEO is disabled (it should also
+ help the builds with WORKERS or XSLT disabled).
+
+ * bindings/js/JSDOMWindowBase.cpp:
+ (jsDOMWindowBaseAudio): Added an UNUSED_PARAM for exec and slot when
+ VIDEO is disabled.
+ (jsDOMWindowBaseWorker): Ditto for WORKERS.
+ (jsDOMWindowBaseXSLTProcessor): Ditto for XSLT.
+
+2009-02-12 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23923
+ Implement mediaPlayerVolumeChanged so a media engine can report autonomous volume changes.
+ Supporting this requires that we know when we are processing a media engine callback so
+ we don't turn around and tell the media player to change the volume when it is reporting
+ a volume change.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): initialize m_processingMediaPlayerCallback
+ (WebCore::HTMLMediaElement::mediaPlayerNetworkStateChanged): call begin/endProcessingMediaPlayerCallback
+ (WebCore::HTMLMediaElement::setNetworkState): logic split out of mediaPlayerNetworkStateChanged
+ to make it easier to maintain m_processingMediaPlayerCallback.
+ (WebCore::HTMLMediaElement::mediaPlayerReadyStateChanged): call begin/endProcessingMediaPlayerCallback
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Ditto.
+ (WebCore::HTMLMediaElement::mediaPlayerRepaint): Ditto.
+ (WebCore::HTMLMediaElement::mediaPlayerVolumeChanged): New
+ (WebCore::HTMLMediaElement::updateVolume): Don't change media engine volume if we are processing
+ a callback from the engine.
+ * html/HTMLMediaElement.h:
+ (WebCore::HTMLMediaElement::processingMediaPlayerCallback): New, return true if (m_processingMediaPlayerCallback>0)
+ (WebCore::HTMLMediaElement::beginProcessingMediaPlayerCallback): New, increment m_processingMediaPlayerCallback
+ (WebCore::HTMLMediaElement::endProcessingMediaPlayerCallback): New, decrement m_processingMediaPlayerCallback
+
+2009-02-12 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ Support MPEG content on Mac and Windows.
+ <rdar://problem/5917509>
+ https://bugs.webkit.org/show_bug.cgi?id=23495
+
+ Test: media/audio-mpeg-supported.html
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivate::disableUnsupportedTracks):
+
+ * platform/graphics/win/QTMovieWin.cpp:
+ (QTMovieWin::disableUnsupportedTracks):
+
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h: fix typo added in r40925
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Sam Weinig
+
+ Move containsFloats, hasOverhangingFloats, shrinkToAvoidFloats and avoidsFloats down to
+ RenderBox, since these methods only apply to boxes.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::collapseMargins):
+ (WebCore::RenderBlock::clearFloatsIfNeeded):
+ (WebCore::RenderBlock::layoutBlockChildren):
+ (WebCore::RenderBlock::clearFloats):
+ (WebCore::RenderBlock::markAllDescendantsWithFloatsForLayout):
+ (WebCore::RenderBlock::calcBlockPrefWidths):
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::containsFloats):
+ (WebCore::RenderBlock::hasOverhangingFloats):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::shrinkToAvoidFloats):
+ (WebCore::RenderBox::avoidsFloats):
+ * rendering/RenderBox.h:
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isFloatingOrPositioned):
+ * rendering/RenderView.h:
+
+2009-02-12 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23908
+
+ Added parsing of 3d transform functions and properties
+ (perspective, perspective-origin, transform-style-3d,
+ and backface-visibility).
+
+ Test: transforms/3d/cssmatrix-3d-interface.xhtml
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::):
+ (WebCore::computedTransform):
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * css/CSSMutableStyleDeclaration.cpp:
+ (WebCore::CSSMutableStyleDeclaration::getPropertyValue):
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ (WebCore::CSSParser::parseFillProperty):
+ (WebCore::CSSParser::parseTransformOriginShorthand):
+ (WebCore::TransformOperationInfo::TransformOperationInfo):
+ (WebCore::CSSParser::parseTransform):
+ (WebCore::CSSParser::parseTransformOrigin):
+ (WebCore::CSSParser::parsePerspectiveOrigin):
+ * css/CSSParser.h:
+ * css/CSSPrimitiveValue.h:
+ (WebCore::CSSPrimitiveValue::isUnitTypeLength):
+ * css/CSSPropertyNames.in:
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::adjustRenderStyle):
+ (WebCore::convertToLength):
+ (WebCore::CSSStyleSelector::applyProperty):
+ (WebCore::CSSStyleSelector::mapFillSize):
+ (WebCore::CSSStyleSelector::mapFillXPosition):
+ (WebCore::CSSStyleSelector::mapFillYPosition):
+ (WebCore::getTransformOperationType):
+ (WebCore::CSSStyleSelector::createTransformOperations):
+ * css/CSSValueKeywords.in:
+ * css/WebKitCSSTransformValue.cpp:
+ (WebCore::WebKitCSSTransformValue::cssText):
+ * css/WebKitCSSTransformValue.h:
+ (WebCore::WebKitCSSTransformValue::):
+ * css/WebKitCSSTransformValue.idl:
+ * platform/graphics/transforms/Matrix3DTransformOperation.cpp:
+ * platform/graphics/transforms/Matrix3DTransformOperation.h:
+ * platform/graphics/transforms/PerspectiveTransformOperation.cpp:
+ * platform/graphics/transforms/PerspectiveTransformOperation.h:
+ * platform/graphics/transforms/RotateTransformOperation.cpp:
+ (WebCore::RotateTransformOperation::blend):
+ * platform/graphics/transforms/RotateTransformOperation.h:
+ (WebCore::RotateTransformOperation::RotateTransformOperation):
+ * platform/graphics/transforms/ScaleTransformOperation.h:
+ (WebCore::ScaleTransformOperation::ScaleTransformOperation):
+ * platform/graphics/transforms/TransformOperation.h:
+ (WebCore::TransformOperation::is3DOperation):
+ * platform/graphics/transforms/TransformOperations.h:
+ (WebCore::TransformOperations::has3DOperation):
+ * platform/graphics/transforms/TranslateTransformOperation.h:
+ (WebCore::TranslateTransformOperation::TranslateTransformOperation):
+
+2009-02-12 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fix.
+
+ * webcore-base.bkl:
+
+2009-02-12 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Darin Adler
+
+ Fix potential ref-count or null-deref problems with C++ objects as Obj-C members.
+
+ * platform/mac/SharedBufferMac.mm: Change to use RefPtr<> instead of ref()/deref().
+ (-[WebCoreSharedBufferData dealloc]):
+ (-[WebCoreSharedBufferData finalize]):
+ (-[WebCoreSharedBufferData initWithSharedBuffer:]):
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Remove calcWidth from RenderObject. Nobody ever called it on RenderObjects.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderObject.h:
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Mark Rowe
+
+ Fix for regression where form controls would paint yellow highlights. The containsComposition check needs to
+ null check node() now.
+
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paint):
+
+2009-02-12 Simon Fraser <simon.fraser@apple.com>
+
+ Build fix
+
+ Change Animation::setDirection() to take the new enum value, and fix
+ the single caller.
+
+ Fix build error in MediaPlayerPrivateQTKit.h.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::mapAnimationDirection):
+ * platform/animation/Animation.h:
+ (WebCore::Animation::setDirection):
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Simon Fraser
+
+ Remove the overrideSize methods from RenderObject. Devirtualize all of the accessors on RenderBox.
+
+ * rendering/RenderBox.h:
+ * rendering/RenderObject.h:
+
+2009-02-12 Eric Carlson <eric.carlson@apple.com>
+
+ Darin Adler, Antti Koivisto, Holger Hans Peter Freyther
+
+ Bug 23797: A platform should be able to use more than one media engine for <video> and <audio>
+ https://bugs.webkit.org/show_bug.cgi?id=23797
+
+ * WebCore.xcodeproj/project.pbxproj: add MediaPlayerPrivate.h
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::load): selectMediaURL now also returns a MIME type, pass it to
+ MediaPlayer::load so it can choose the right media engine
+ (WebCore::HTMLMediaElement::selectMediaURL): renamed from pickMedia. use MIMETypeRegistry
+ functions to strip params from the url and extract the codecs parameter. call
+ MediaPlayer::supportsType to see if we can open the file since only a media engine can
+ answer questions about supported type+codecs.
+ * html/HTMLMediaElement.h:
+
+ * platform/MIMETypeRegistry.cpp:
+ (WebCore::MIMETypeRegistry::getParameterFromMIMEType): New, find and return a MIME type parameter
+ (WebCore::MIMETypeRegistry::stripParametersFromMIMEType): New, strip all parameters from a MIME type
+ * platform/MIMETypeRegistry.h:
+
+ * platform/graphics/MediaPlayer.cpp:
+ (WebCore::NullMediaPlayerPrivate::NullMediaPlayerPrivate):
+ (WebCore::NullMediaPlayerPrivate::load):
+ (WebCore::NullMediaPlayerPrivate::cancelLoad):
+ (WebCore::NullMediaPlayerPrivate::play):
+ (WebCore::NullMediaPlayerPrivate::pause):
+ (WebCore::NullMediaPlayerPrivate::naturalSize):
+ (WebCore::NullMediaPlayerPrivate::hasVideo):
+ (WebCore::NullMediaPlayerPrivate::setVisible):
+ (WebCore::NullMediaPlayerPrivate::duration):
+ (WebCore::NullMediaPlayerPrivate::currentTime):
+ (WebCore::NullMediaPlayerPrivate::seek):
+ (WebCore::NullMediaPlayerPrivate::seeking):
+ (WebCore::NullMediaPlayerPrivate::setEndTime):
+ (WebCore::NullMediaPlayerPrivate::setRate):
+ (WebCore::NullMediaPlayerPrivate::paused):
+ (WebCore::NullMediaPlayerPrivate::setVolume):
+ (WebCore::NullMediaPlayerPrivate::networkState):
+ (WebCore::NullMediaPlayerPrivate::readyState):
+ (WebCore::NullMediaPlayerPrivate::maxTimeSeekable):
+ (WebCore::NullMediaPlayerPrivate::maxTimeBuffered):
+ (WebCore::NullMediaPlayerPrivate::dataRate):
+ (WebCore::NullMediaPlayerPrivate::totalBytesKnown):
+ (WebCore::NullMediaPlayerPrivate::totalBytes):
+ (WebCore::NullMediaPlayerPrivate::bytesLoaded):
+ (WebCore::NullMediaPlayerPrivate::setRect):
+ (WebCore::NullMediaPlayerPrivate::paint):
+ (WebCore::createNullMediaPlayer):
+ Do nothing media player so MediaPlayer doesn't have to NULL check before calling current engine.
+
+ (WebCore::MediaPlayerFactory::MediaPlayerFactory): New, factory constructor.
+ (WebCore::installedMediaEngines): New, returns vector of all installed engines.
+ (WebCore::addMediaEngine): New, add a media engine to the cache.
+ (WebCore::chooseBestEngineForTypeAndCodecs): New, return an engine that might support a MIME type.
+ (WebCore::MediaPlayer::MediaPlayer): create NULL media player so we have a default. Initialize m_currentMediaEngine.
+ (WebCore::MediaPlayer::~MediaPlayer): don't need to delete m_private, it is now an OwnPtr.
+ (WebCore::MediaPlayer::load): Take MIME type as well as url, since we need it to find the right
+ media engine. If no MIME type is provided, try to devine one from the url. Choose a media engine
+ based on the MIME type and codecs parameter.
+ (WebCore::MediaPlayer::currentTime): Remove excess white space.
+ (WebCore::MediaPlayer::supportsType): Take codecs param as well as MIME type. Return enum so we can
+ indicate "maybe" condition.
+ (WebCore::MediaPlayer::getSupportedTypes): Build up list of MIME types by consulting all engines.
+ (WebCore::MediaPlayer::isAvailable): return true if any media engine is installed.
+
+ * platform/graphics/MediaPlayer.h:
+ (WebCore::MediaPlayer::):
+ (WebCore::MediaPlayer::frameView): accessor function.
+
+ * platform/graphics/MediaPlayerPrivate.h: New, declares abstract interface for media engines.
+ (WebCore::MediaPlayerPrivateInterface::~MediaPlayerPrivateInterface):
+ (WebCore::MediaPlayerPrivateInterface::totalBytesKnown):
+
+ * platform/graphics/chromium/MediaPlayerPrivateChromium.h: Add support for engine factory
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivate::create): New, media engine factory function
+ (WebCore::MediaPlayerPrivate::registerMediaEngine): Register engine with MediaPlayer factory
+ (WebCore::MediaPlayerPrivate::load): URL is a const String.
+ (WebCore::MediaPlayerPrivate::duration): Declare const.
+ (WebCore::MediaPlayerPrivate::naturalSize): Ditto.
+ (WebCore::MediaPlayerPrivate::hasVideo): Ditto.
+ (WebCore::MediaPlayerPrivate::networkState): Ditto.
+ (WebCore::MediaPlayerPrivate::readyState): Ditto.
+ (WebCore::MediaPlayerPrivate::maxTimeBuffered): Ditto.
+ (WebCore::MediaPlayerPrivate::maxTimeSeekable): Ditto.
+ (WebCore::MediaPlayerPrivate::maxTimeLoaded): Ditto.
+ (WebCore::MediaPlayerPrivate::bytesLoaded): Ditto.
+ (WebCore::MediaPlayerPrivate::totalBytesKnown): Ditto.
+ (WebCore::MediaPlayerPrivate::totalBytes): Ditto.
+ (WebCore::MediaPlayerPrivate::supportsType): Return MediaPlayer::SupportsType enum instead of bool.
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h:
+ (WebCore::MediaPlayerPrivate::isAvailable):
+
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.h:
+ * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
+ (WebCore::MediaPlayerPrivateQTKit::create): New, media engine factory function
+ (WebCore::MediaPlayerPrivateQTKit::registerMediaEngine): Register engine with MediaPlayer factory
+ (WebCore::MediaPlayerPrivate::createQTMovieView): don't access MediaPlayer->m_frameView directly,
+ use accessor function.
+ (WebCore::MediaPlayerPrivate::setUpVideoRendering): Ditto.
+ (WebCore::MediaPlayerPrivate::paint): Ditto.
+ (WebCore::mimeTypeCache): New.
+ (WebCore::MediaPlayerPrivate::getSupportedTypes): New, media engine factory function.
+ (WebCore::MediaPlayerPrivate::supportsType): return MediaPlayer::SupportsType enum instead of bool
+ (-[WebCoreMovieObserver initWithCallback:]): fix formatting
+
+ * platform/graphics/qt/MediaPlayerPrivatePhonon.cpp:
+ (WebCore::MediaPlayerPrivate::create):
+ (WebCore::MediaPlayerPrivate::registerMediaEngine):
+ (WebCore::MediaPlayerPrivate::supportsType):
+ (WebCore::MediaPlayerPrivate::load): URL is a const String.
+ * platform/graphics/qt/MediaPlayerPrivatePhonon.h:
+ (WebCore::MediaPlayerPrivate::isAvailable):
+
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp:
+ (WebCore::MediaPlayerPrivate::create): New, media engine factory function
+ (WebCore::MediaPlayerPrivate::registerMediaEngine): New, register engine with MediaPlayer factory
+ (WebCore::MediaPlayerPrivate::load): URL is a const String.
+ (WebCore::MediaPlayerPrivate::paint): don't access MediaPlayer->m_frameView directly,
+ use accessor function.
+ (WebCore::mimeTypeCache): New.
+ (WebCore::MediaPlayerPrivateQTWin::getSupportedTypes): New, media engine factory function.
+ (WebCore::MediaPlayerPrivateQTWin::supportsType): return MediaPlayer::SupportsType enum instead of bool
+ * platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h:
+
+2009-02-12 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Test: fast/dom/prefixed-image-tag.xhtml
+
+ Bug 23915: Remove setPrefix work-around in Document::createElement(QualifiedName, bool)
+
+ Instead we now directly propage the QualifiedName inside the generated Factory.
+
+ Test: fast/dom/prefixed-image-tag.xhtml
+
+ * dom/Document.cpp:
+ (WebCore::Document::createElement): Removed the setPrefix work-around
+ and replaced it with an ASSERT to catch mistakes inside the Factory code.
+ Remove the unneeded ExceptionCode argument.
+
+ (WebCore::Document::createElementNS): Removed ExceptionCode argument.
+ * dom/Document.h: Updated the signature.
+ * dom/XMLTokenizerLibxml2.cpp:
+ (WebCore::XMLTokenizer::startElementNs): Removed ExceptionCode argument.
+ * dom/XMLTokenizerQt.cpp: Ditto.
+ (WebCore::XMLTokenizer::parseStartElement): Ditto.
+
+ * dom/make_names.pl: Implemented the QualifiedName propogation logic
+ in the Factory.
+
+2009-02-12 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23188
+
+ Define enum values for Animation::direction(), and one for
+ IterationCountInfinite to make the code more self-documenting.
+
+ Order the member vars of Animation to optimize packing.
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * platform/animation/Animation.cpp:
+ (WebCore::Animation::Animation):
+ (WebCore::Animation::operator=):
+ (WebCore::Animation::animationsMatch):
+ * platform/animation/Animation.h:
+ (WebCore::Animation::):
+ (WebCore::Animation::direction):
+ (WebCore::Animation::initialAnimationDirection):
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::GraphicsLayerCA::setBasicAnimation):
+ (WebCore::GraphicsLayerCA::setKeyframeAnimation):
+
+2009-02-12 Christian Dywan <christian@twotoasts.de>
+
+ Reviewed by Holger Freyther.
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::ResourceHandle::startHttp): Don't use O_CLOEXEC for now.
+
+2009-02-12 Julien Chaffraix <jchaffraix@webkit.org>
- 2009-02-10 Jon Honeycutt <jhoneycutt@apple.com>
+ Reviewed by Darin Adler.
+
+ Bug 23826: Potential bug with before/after rule while moving element from one document to another
+
+ Moved the document before/after toggle from the constructor to insertedIntoDocument.
+
+ Test: fast/css-generated-content/beforeAfter-interdocument.html
+
+ * html/HTMLQuoteElement.cpp:
+ (WebCore::HTMLQuoteElement::HTMLQuoteElement):
+ (WebCore::HTMLQuoteElement::insertedIntoDocument):
+ * html/HTMLQuoteElement.h:
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Reviewed by Simon Fraser
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23912
+
+ I have no idea why this broke. As far as I can tell the old code never should have worked in
+ the first place. Add code to handleWheelEvent that will find an enclosing renderer for a node
+ in order to attempt a wheel scroll.
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::handleWheelEvent):
+
+2009-02-12 David Hyatt <hyatt@apple.com>
+
+ Move the functions that paint borders, box shadows and border images into RenderBoxModelObject. drawBorder and drawBorderArc, because they are used
+ for outlines as well as borders, need to stay in RenderObject. Rename them to drawLineForBoxSide and drawArcForBoxSide in order to reflect their
+ more generic use. Rename the BorderSide struct to BoxSide, since the concept of "side" is just a rectangle concept and not a border concept.
+
+ Reviewed by Simon Fraser
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::paintFillLayer):
+ (WebCore::InlineFlowBox::paintBoxShadow):
+ (WebCore::InlineFlowBox::paintBoxDecorations):
+ (WebCore::InlineFlowBox::paintMask):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintColumns):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintNinePieceImage):
+ (WebCore::RenderBoxModelObject::paintBorder):
+ (WebCore::RenderBoxModelObject::paintBoxShadow):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderFieldset.cpp:
+ (WebCore::RenderFieldset::paintBorderMinusLegend):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::paintOutlineForLine):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::drawLineForBoxSide):
+ (WebCore::RenderObject::drawArcForBoxSide):
+ (WebCore::RenderObject::paintOutline):
+ * rendering/RenderObject.h:
+ (WebCore::):
+ (WebCore::RenderObject::hasBoxDecorations):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::CollapsedBorders::addBorder):
+ (WebCore::RenderTableCell::paintCollapsedBorder):
+
+2009-02-12 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser
+
+ Bug 18322: video element should have ui when scripting is disabled
+ https://bugs.webkit.org/show_bug.cgi?id=18322
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::controls): always return 'true' when JavaScript is disabled.
+ * manual-tests/media-controls-when-javascript-disabled.html: Added.
+
+2009-02-12 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23906
+ Add custom V8 bindings for HTMLPlugInElement.
+
+ * bindings/v8/custom/V8HTMLPlugInElementCustom.cpp: Added.
+ (WebCore::NAMED_PROPERTY_GETTER):
+ (WebCore::NAMED_PROPERTY_SETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ (WebCore::INDEXED_PROPERTY_GETTER):
+ (WebCore::INDEXED_PROPERTY_SETTER):
+
+2009-02-12 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Mark Rowe.
+
+ [GTK] Soup backend must handle upload of multiple files
+ https://bugs.webkit.org/show_bug.cgi?id=18343
+
+ * platform/network/soup/ResourceHandleSoup.cpp:
+ (WebCore::):
+ (WebCore::freeFileMapping):
+ (WebCore::ResourceHandle::startHttp): Support multipart request bodies
+ mmap'ing files to be uploaded.
+
+2009-02-12 Adam Treat <adam.treat@torchmobile.com>
+
+ Fix the Qt build following r40871 which changed RenderObject::element()
+ into RenderObject::node().
+
+ * platform/qt/RenderThemeQt.cpp:
+ (WebCore::RenderThemeQt::getMediaElementFromRenderObject):
+ (WebCore::RenderThemeQt::getMediaControlForegroundColor):
+
+2009-02-12 Alexey Proskuryakov <ap@webkit.org>
+
+ Build fix.
+
+ * platform/graphics/transforms/RotateTransformOperation.cpp: Include <algorithm>.
+
+2009-02-12 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Change worker code to use different proxy class pointers.
+ https://bugs.webkit.org/show_bug.cgi?id=23859
+
+ This is a step towards using separate proxies in multi-process implementation.
+
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::evaluate):
+ * dom/Worker.cpp:
+ (WebCore::Worker::Worker):
+ (WebCore::Worker::~Worker):
+ (WebCore::Worker::postMessage):
+ (WebCore::Worker::terminate):
+ (WebCore::Worker::hasPendingActivity):
+ (WebCore::Worker::notifyFinished):
+ (WebCore::Worker::dispatchMessage):
+ * dom/Worker.h:
+ * dom/WorkerContext.cpp:
+ (WebCore::WorkerContext::~WorkerContext):
+ (WebCore::WorkerContext::reportException):
+ (WebCore::WorkerContext::addMessage):
+ (WebCore::WorkerContext::postMessage):
+ (WebCore::WorkerContext::dispatchMessage):
+ * dom/WorkerContext.h:
+ * dom/WorkerContextProxy.h:
+ * dom/WorkerMessagingProxy.cpp:
+ (WebCore::MessageWorkerContextTask::performTask):
+ (WebCore::MessageWorkerTask::performTask):
+ (WebCore::WorkerContextProxy::create):
+ (WebCore::WorkerMessagingProxy::WorkerMessagingProxy):
+ (WebCore::WorkerMessagingProxy::~WorkerMessagingProxy):
+ (WebCore::WorkerMessagingProxy::startWorkerContext):
+ (WebCore::postConsoleMessageTask):
+ (WebCore::WorkerMessagingProxy::postConsoleMessageToWorkerObject):
+ (WebCore::WorkerMessagingProxy::workerThreadCreated):
+ * dom/WorkerMessagingProxy.h:
+ * dom/WorkerObjectProxy.h:
+ * dom/WorkerThread.cpp:
+ (WebCore::WorkerThread::create):
+ (WebCore::WorkerThread::WorkerThread):
+ (WebCore::WorkerThread::workerThread):
+ * dom/WorkerThread.h:
+ (WebCore::WorkerThread::workerObjectProxy):
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
+
+2009-02-12 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23688: ThreadableLoader needs a sync implementation for Workers.
+ <https://bugs.webkit.org/show_bug.cgi?id=23688>
+
+ Add ResourceError to ThreadableLoaderClient.
+
+ No observable change in behavior, so no test.
+
+ * loader/DocumentThreadableLoader.cpp:
+ (WebCore::DocumentThreadableLoader::create):
+ (WebCore::DocumentThreadableLoader::willSendRequest):
+ (WebCore::DocumentThreadableLoader::didFail):
+ * loader/ThreadableLoaderClient.h:
+ (WebCore::ThreadableLoaderClient::didFail):
+ (WebCore::ThreadableLoaderClient::didFailWillSendRequestCheck):
+ * loader/ThreadableLoaderClientWrapper.h:
+ (WebCore::ThreadableLoaderClientWrapper::didFail):
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader):
+ (WebCore::workerContextDidFail):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFail):
+ * loader/WorkerThreadableLoader.h:
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::didFail):
+ (WebCore::XMLHttpRequest::didFailWillSendRequestCheck):
+ * xml/XMLHttpRequest.h:
+
+2009-02-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ Fix the build on Leopard with ACCELERATED_COMPOSITING turned on.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ FloatPoint3D needs to be a private header, since it's included by GraphicsLayer.h
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::getTransformFunctionValue):
+ (WebCore::caValueFunctionSupported):
+ (WebCore::GraphicsLayerCA::setAnchorPoint):
+ (WebCore::GraphicsLayerCA::setPreserves3D):
+ (WebCore::GraphicsLayerCA::setContentsToImage):
+ (WebCore::GraphicsLayerCA::setBasicAnimation):
+ (WebCore::GraphicsLayerCA::setKeyframeAnimation):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::isRootLayer):
+ Fix isRootLayer to return true for the renderView's layer, not the root
+ renderer's layer.
+
+2009-02-11 Adele Peterson <adele@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23910
+ <rdar://problem/6160546> REGRESSION: In Full page mode, movie controller hides when I drag the knob if movie is playing
+
+ * rendering/RenderMedia.cpp: (WebCore::RenderMedia::forwardEvent):
+ When we get a mouseOut event, consider the mouse as still within the RenderMedia if the relatedTarget is a descendant.
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ Remove all of the inline box wrapper functions from RenderObject, since they only apply to RenderBox. Devirtualize the functions.
+ Patch all of the call sites to convert to a RenderBox.
+
+ Reviewed by Simon Fraser
+
+ * dom/Position.cpp:
+ (WebCore::nextRenderedEditable):
+ (WebCore::previousRenderedEditable):
+ (WebCore::Position::getInlineBoxAndOffset):
+ * rendering/InlineBox.cpp:
+ (WebCore::InlineBox::deleteLine):
+ (WebCore::InlineBox::extractLine):
+ (WebCore::InlineBox::attachLine):
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::dirtyLinesFromChangedChild):
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::removeChildNode):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::textWithHardLineBreaks):
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ Eliminate createInlineBox and dirtyLineBoxes from RenderObject. These functions have been devirtualized.
+ The single call site now calls a helper function that just bit checks and casts before calling the correct
+ type. RenderBlock's dirtyLineBoxes function was dead code (caused by the RenderFlow deletion), so it has
+ just been removed.
+
+ Reviewed by Eric Seidel
+
+ * rendering/RenderBR.cpp:
+ * rendering/RenderBR.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::createRootInlineBox):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::createInlineBox):
+ * rendering/RenderBox.h:
+ * rendering/RenderCounter.cpp:
+ * rendering/RenderCounter.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::createInlineFlowBox):
+ * rendering/RenderInline.h:
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::createTextBox):
+ * rendering/RenderSVGInlineText.h:
+ (WebCore::RenderSVGInlineText::isSVGText):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::createTextBox):
+ (WebCore::RenderText::createInlineTextBox):
+ * rendering/RenderText.h:
+ * rendering/bidi.cpp:
+ (WebCore::createInlineBoxForRenderer):
+ (WebCore::RenderBlock::createLineBoxes):
+ (WebCore::RenderBlock::constructLine):
+ (WebCore::RenderBlock::layoutInlineChildren):
+
+2009-02-11 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23905
+
+ Adds support for 3D CSS properties (transform-style-3d, perspective,
+ perspective-origin, and backface-visibility) to RenderStyle and friends
+
+ * platform/graphics/transforms/TransformOperation.h
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::diff):
+ (WebCore::RenderStyle::applyTransform):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::transformOriginZ):
+ (WebCore::InheritedFlags::hasTransformRelatedProperty):
+ (WebCore::InheritedFlags::transformStyle3D):
+ (WebCore::InheritedFlags::backfaceVisibility):
+ (WebCore::InheritedFlags::perspective):
+ (WebCore::InheritedFlags::perspectiveOriginX):
+ (WebCore::InheritedFlags::perspectiveOriginY):
+ (WebCore::InheritedFlags::setTransformOriginZ):
+ (WebCore::InheritedFlags::setTransformStyle3D):
+ (WebCore::InheritedFlags::setBackfaceVisibility):
+ (WebCore::InheritedFlags::setPerspective):
+ (WebCore::InheritedFlags::setPerspectiveOriginX):
+ (WebCore::InheritedFlags::setPerspectiveOriginY):
+ (WebCore::InheritedFlags::initialTransformOriginZ):
+ (WebCore::InheritedFlags::initialTransformStyle3D):
+ (WebCore::InheritedFlags::initialBackfaceVisibility):
+ (WebCore::InheritedFlags::initialPerspective):
+ (WebCore::InheritedFlags::initialPerspectiveOriginX):
+ (WebCore::InheritedFlags::initialPerspectiveOriginY):
+ * rendering/style/RenderStyleConstants.h:
+ (WebCore::):
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
+ (WebCore::StyleRareNonInheritedData::operator==):
+ * rendering/style/StyleRareNonInheritedData.h:
+ * rendering/style/StyleTransformData.cpp:
+ (WebCore::StyleTransformData::StyleTransformData):
+ (WebCore::StyleTransformData::operator==):
+ * rendering/style/StyleTransformData.h:
+
+2009-02-11 Simon Fraser <simon.fraser@apple.com>
+
+ No review.
+
+ Fix ACCELERATED_COMPOSITING build.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::createGraphicsLayer):
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateLayerCompositingState):
+
+2009-02-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23862
+
+ Add a bit on RenderStyle that gets set when running accelerated
+ transitions of transform or opacity. These ensure that styles
+ compare as different during the transition, so that interruption
+ can be detected reliably.
+
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::animate):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::isRunningAcceleratedAnimation):
+ (WebCore::InheritedFlags::setIsRunningAcceleratedAnimation):
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::StyleRareNonInheritedData):
+ (WebCore::StyleRareNonInheritedData::operator==):
+ * rendering/style/StyleRareNonInheritedData.h:
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ Eliminate the virtual position() function from RenderObject. Rename the position() overrides
+ in RenderText and RenderBox to positionLineBox and devirtualize them.
+
+ Patch the one call site to just check for isText() and isBox() and call the methods directly.
+
+ Remove some unnecessary overrides of position() on table sections and rows.
+
+ Reviewed by Simon Fraser
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::positionLineBox):
+ * rendering/RenderBox.h:
+ * rendering/RenderObject.h:
+ * rendering/RenderSVGRoot.cpp:
+ * rendering/RenderSVGRoot.h:
+ * rendering/RenderTableRow.h:
+ (WebCore::RenderTableRow::lineHeight):
+ * rendering/RenderTableSection.h:
+ (WebCore::RenderTableSection::lineHeight):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::positionLineBox):
+ * rendering/RenderText.h:
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::computeVerticalPositionsForLine):
+
+2009-02-11 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23901
+ Add HTML options/collections V8 custom bindings.
+
+ * bindings/v8/custom/V8HTMLCollectionCustom.cpp: Added.
+ (WebCore::getNamedItems):
+ (WebCore::getItem):
+ (WebCore::NAMED_PROPERTY_GETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8HTMLFormElementCustom.cpp: Added.
+ (WebCore::NAMED_PROPERTY_GETTER):
+ * bindings/v8/custom/V8HTMLInputElementCustom.cpp:
+ (WebCore::ACCESSOR_GETTER):
+ (WebCore::ACCESSOR_SETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp:
+ (WebCore::CALLBACK_FUNC_DECL):
+ (WebCore::ACCESSOR_SETTER):
+ * bindings/v8/custom/V8HTMLSelectElementCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ (WebCore::removeElement):
+ * bindings/v8/custom/V8HTMLSelectElementCustom.h: Added.
+ * bindings/v8/custom/V8NamedNodesCollection.cpp: Added.
+ (WebCore::V8NamedNodesCollection::item):
+ (WebCore::V8NamedNodesCollection::itemWithName):
+ * bindings/v8/custom/V8NamedNodesCollection.h: Added.
+ (WebCore::V8NamedNodesCollection::V8NamedNodesCollection):
+ (WebCore::V8NamedNodesCollection::length):
+
+2009-02-11 Dimitri Dupuis-latour <dupuislatour@apple.com>
+
+ Added a preference to disable some Inspector's panels (rdar://6419624, rdar://6419645).
+ This is controlled via the 'WebKitInspectorHiddenPanels' key; if nothing is specified, all panels are shown.
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/InspectorClient.h:
+ * inspector/InspectorController.cpp:
+ (WebCore::hiddenPanels):
+ (WebCore::InspectorController::hiddenPanels):
+ (WebCore::InspectorController::windowScriptObjectAvailable):
+ * inspector/InspectorController.h:
+ * inspector/front-end/inspector.js:
+ (WebInspector.loaded):
+ * loader/EmptyClients.h:
+ (WebCore::EmptyInspectorClient::hiddenPanels):
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ Combine RenderObject::element() and RenderObject::node() into a single function.
+ node() now has the "anonymous bit" checking behavior of element() and will
+ return 0 for anonymous content. This patch switches all callers of element()
+ to node() and patches old callers of node() to deal with situations where they
+ did not expect node() to be 0. A bunch of node() calls were calling stuff on
+ Document that they clearly didn't intend, so overall this is a nice improvement.
+
+ Reviewed by Sam Weinig
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::getUpperLeftCorner):
+ * dom/Element.cpp:
+ (WebCore::Element::offsetParent):
+ * dom/Position.cpp:
+ (WebCore::Position::hasRenderedNonAnonymousDescendantsWithHeight):
+ * editing/ModifySelectionListLevel.cpp:
+ (WebCore::getStartEndListChildren):
+ (WebCore::IncreaseSelectionListLevelCommand::doApply):
+ (WebCore::DecreaseSelectionListLevelCommand::doApply):
+ * editing/TextIterator.cpp:
+ (WebCore::TextIterator::advance):
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::leftVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::rightVisuallyDistinctCandidate):
+ * editing/visible_units.cpp:
+ (WebCore::startPositionForLine):
+ (WebCore::endPositionForLine):
+ * page/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::get):
+ * page/AccessibilityList.cpp:
+ (WebCore::AccessibilityList::isUnorderedList):
+ (WebCore::AccessibilityList::isOrderedList):
+ (WebCore::AccessibilityList::isDefinitionList):
+ * page/AccessibilityListBox.cpp:
+ (WebCore::AccessibilityListBox::doAccessibilityHitTest):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::isPasswordField):
+ (WebCore::AccessibilityRenderObject::isFileUploadButton):
+ (WebCore::AccessibilityRenderObject::isInputImage):
+ (WebCore::AccessibilityRenderObject::isMultiSelect):
+ (WebCore::AccessibilityRenderObject::isControl):
+ (WebCore::AccessibilityRenderObject::getAttribute):
+ (WebCore::AccessibilityRenderObject::anchorElement):
+ (WebCore::AccessibilityRenderObject::actionElement):
+ (WebCore::AccessibilityRenderObject::mouseButtonListener):
+ (WebCore::AccessibilityRenderObject::helpText):
+ (WebCore::AccessibilityRenderObject::textUnderElement):
+ (WebCore::AccessibilityRenderObject::hasIntValue):
+ (WebCore::AccessibilityRenderObject::intValue):
+ (WebCore::AccessibilityRenderObject::labelElementContainer):
+ (WebCore::AccessibilityRenderObject::title):
+ (WebCore::AccessibilityRenderObject::accessibilityDescription):
+ (WebCore::AccessibilityRenderObject::boundingBoxRect):
+ (WebCore::AccessibilityRenderObject::checkboxOrRadioRect):
+ (WebCore::AccessibilityRenderObject::titleUIElement):
+ (WebCore::AccessibilityRenderObject::accessibilityIsIgnored):
+ (WebCore::AccessibilityRenderObject::text):
+ (WebCore::AccessibilityRenderObject::ariaSelectedTextDOMRange):
+ (WebCore::AccessibilityRenderObject::accessKey):
+ (WebCore::AccessibilityRenderObject::setSelectedTextRange):
+ (WebCore::AccessibilityRenderObject::url):
+ (WebCore::AccessibilityRenderObject::isFocused):
+ (WebCore::AccessibilityRenderObject::setFocused):
+ (WebCore::AccessibilityRenderObject::setValue):
+ (WebCore::AccessibilityRenderObject::isEnabled):
+ (WebCore::AccessibilityRenderObject::visiblePositionRange):
+ (WebCore::AccessibilityRenderObject::index):
+ (WebCore::AccessibilityRenderObject::activeDescendant):
+ (WebCore::AccessibilityRenderObject::handleActiveDescendantChanged):
+ (WebCore::AccessibilityRenderObject::observableObject):
+ (WebCore::AccessibilityRenderObject::roleValue):
+ (WebCore::AccessibilityRenderObject::canSetFocusAttribute):
+ (WebCore::AccessibilityRenderObject::ariaListboxSelectedChildren):
+ * page/AccessibilityTable.cpp:
+ (WebCore::AccessibilityTable::isTableExposableThroughAccessibility):
+ (WebCore::AccessibilityTable::title):
+ * page/AccessibilityTableCell.cpp:
+ (WebCore::AccessibilityTableCell::titleUIElement):
+ * page/AccessibilityTableColumn.cpp:
+ (WebCore::AccessibilityTableColumn::headerObjectForSection):
+ * page/AccessibilityTableRow.cpp:
+ (WebCore::AccessibilityTableRow::headerObject):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::dispatchMouseEvent):
+ (WebCore::EventHandler::canMouseDownStartSelect):
+ (WebCore::EventHandler::canMouseDragExtendSelect):
+ (WebCore::EventHandler::shouldDragAutoNode):
+ * page/Frame.cpp:
+ (WebCore::Frame::searchForLabelsAboveCell):
+ (WebCore::Frame::setFocusedNodeIfNeeded):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateOverflowStatus):
+ * page/animation/AnimationBase.cpp:
+ (WebCore::AnimationBase::updateStateMachine):
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::updateAnimationTimer):
+ (WebCore::AnimationController::cancelAnimations):
+ (WebCore::AnimationController::updateAnimations):
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::KeyframeAnimation):
+ (WebCore::KeyframeAnimation::endAnimation):
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (blockquoteLevel):
+ (AXAttributeStringSetHeadingLevel):
+ * page/mac/FrameMac.mm:
+ (WebCore::Frame::searchForNSLabelsAboveCell):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::verticallyAlignBoxes):
+ (WebCore::InlineFlowBox::paint):
+ (WebCore::shouldDrawTextDecoration):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paintDocumentMarkers):
+ * rendering/RenderBR.cpp:
+ (WebCore::RenderBR::positionForCoordinates):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::layoutBlock):
+ (WebCore::RenderBlock::handleRunInChild):
+ (WebCore::RenderBlock::paintObject):
+ (WebCore::RenderBlock::isSelectionRoot):
+ (WebCore::RenderBlock::rightmostPosition):
+ (WebCore::RenderBlock::positionForBox):
+ (WebCore::RenderBlock::positionForRenderer):
+ (WebCore::RenderBlock::positionForCoordinates):
+ (WebCore::RenderBlock::hasLineIfEmpty):
+ (WebCore::RenderBlock::updateFirstLetter):
+ (WebCore::RenderBlock::updateHitTestResult):
+ (WebCore::RenderBlock::addFocusRingRects):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::styleWillChange):
+ (WebCore::RenderBox::updateBoxModelInfoFromStyle):
+ (WebCore::RenderBox::paintRootBoxDecorations):
+ (WebCore::RenderBox::positionForCoordinates):
+ * rendering/RenderButton.cpp:
+ (WebCore::RenderButton::updateFromElement):
+ (WebCore::RenderButton::canHaveChildren):
+ * rendering/RenderCounter.cpp:
+ (WebCore::planCounter):
+ * rendering/RenderFieldset.cpp:
+ (WebCore::RenderFieldset::findLegend):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutVerticalBox):
+ * rendering/RenderForeignObject.cpp:
+ (WebCore::RenderForeignObject::translationForAttributes):
+ (WebCore::RenderForeignObject::calculateLocalTransform):
+ * rendering/RenderFrame.h:
+ (WebCore::RenderFrame::element):
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::paintReplaced):
+ (WebCore::RenderImage::imageMap):
+ (WebCore::RenderImage::nodeAtPoint):
+ (WebCore::RenderImage::updateAltText):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::cloneInline):
+ (WebCore::RenderInline::updateHitTestResult):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::isTransparent):
+ (WebCore::RenderLayer::scrollToOffset):
+ (WebCore::RenderLayer::resize):
+ (WebCore::RenderLayer::createScrollbar):
+ (WebCore::RenderLayer::updateOverflowStatus):
+ (WebCore::RenderLayer::updateScrollInfoAfterLayout):
+ (WebCore::RenderLayer::enclosingElement):
+ (WebCore::RenderLayer::updateHoverActiveState):
+ (WebCore::RenderLayer::updateScrollCornerStyle):
+ (WebCore::RenderLayer::updateResizerStyle):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::isRootLayer):
+ * rendering/RenderListItem.cpp:
+ (WebCore::getParentOfFirstLineBox):
+ * rendering/RenderMarquee.cpp:
+ (WebCore::RenderMarquee::marqueeSpeed):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::RenderObject):
+ (WebCore::RenderObject::isBody):
+ (WebCore::RenderObject::isHR):
+ (WebCore::RenderObject::isHTMLMarquee):
+ (WebCore::RenderObject::isEditable):
+ (WebCore::RenderObject::addPDFURLRect):
+ (WebCore::RenderObject::showTreeForThis):
+ (WebCore::RenderObject::draggableNode):
+ (WebCore::RenderObject::hasOutlineAnnotation):
+ (WebCore::RenderObject::positionForCoordinates):
+ (WebCore::RenderObject::updateDragState):
+ (WebCore::RenderObject::updateHitTestResult):
+ (WebCore::RenderObject::getUncachedPseudoStyle):
+ (WebCore::RenderObject::getTextDecorationColors):
+ (WebCore::RenderObject::caretMaxOffset):
+ (WebCore::RenderObject::offsetParent):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isRoot):
+ (WebCore::RenderObject::isInlineContinuation):
+ (WebCore::RenderObject::node):
+ (WebCore::RenderObject::setNode):
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::destroyLeftoverChildren):
+ * rendering/RenderPart.cpp:
+ (WebCore::RenderPart::updateWidgetPosition):
+ * rendering/RenderPartObject.cpp:
+ (WebCore::RenderPartObject::updateWidget):
+ (WebCore::RenderPartObject::viewCleared):
+ * rendering/RenderPath.cpp:
+ (WebCore::RenderPath::calculateLocalTransform):
+ (WebCore::RenderPath::layout):
+ (WebCore::RenderPath::paint):
+ (WebCore::RenderPath::drawMarkersIfNeeded):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::positionForCoordinates):
+ (WebCore::RenderReplaced::isSelected):
+ * rendering/RenderSVGGradientStop.cpp:
+ (WebCore::RenderSVGGradientStop::gradientElement):
+ * rendering/RenderSVGImage.cpp:
+ (WebCore::RenderSVGImage::calculateLocalTransform):
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::positionForCoordinates):
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::layout):
+ (WebCore::RenderSVGRoot::applyContentTransforms):
+ (WebCore::RenderSVGRoot::paint):
+ (WebCore::RenderSVGRoot::calcViewport):
+ (WebCore::RenderSVGRoot::absoluteTransform):
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::calculateLocalTransform):
+ (WebCore::RenderSVGText::layout):
+ * rendering/RenderSVGTextPath.cpp:
+ (WebCore::RenderSVGTextPath::layoutPath):
+ (WebCore::RenderSVGTextPath::startOffset):
+ (WebCore::RenderSVGTextPath::exactAlignment):
+ (WebCore::RenderSVGTextPath::stretchMethod):
+ * rendering/RenderSVGTransformableContainer.cpp:
+ (WebCore::RenderSVGTransformableContainer::calculateLocalTransform):
+ * rendering/RenderSVGViewportContainer.cpp:
+ (WebCore::RenderSVGViewportContainer::calcViewport):
+ (WebCore::RenderSVGViewportContainer::viewportTransform):
+ (WebCore::RenderSVGViewportContainer::nodeAtPoint):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::addChild):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::updateFromElement):
+ (WebCore::RenderTableCell::calcPrefWidths):
+ * rendering/RenderTableCol.cpp:
+ (WebCore::RenderTableCol::updateFromElement):
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::addChild):
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::addChild):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::originalText):
+ (WebCore::RenderText::positionForCoordinates):
+ * rendering/RenderTextControlMultiLine.cpp:
+ (WebCore::RenderTextControlMultiLine::nodeAtPoint):
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::nodeAtPoint):
+ * rendering/RenderTextFragment.cpp:
+ (WebCore::RenderTextFragment::originalText):
+ (WebCore::RenderTextFragment::previousCharacter):
+ * rendering/RenderTheme.cpp:
+ (WebCore::RenderTheme::isActive):
+ (WebCore::RenderTheme::isChecked):
+ (WebCore::RenderTheme::isIndeterminate):
+ (WebCore::RenderTheme::isEnabled):
+ (WebCore::RenderTheme::isFocused):
+ (WebCore::RenderTheme::isPressed):
+ (WebCore::RenderTheme::isReadOnlyControl):
+ (WebCore::RenderTheme::isHovered):
+ * rendering/RenderThemeMac.mm:
+ (WebCore::RenderThemeMac::updatePressedState):
+ (WebCore::RenderThemeMac::paintMediaFullscreenButton):
+ (WebCore::RenderThemeMac::paintMediaMuteButton):
+ (WebCore::RenderThemeMac::paintMediaPlayButton):
+ (WebCore::RenderThemeMac::paintMediaSeekBackButton):
+ (WebCore::RenderThemeMac::paintMediaSeekForwardButton):
+ (WebCore::RenderThemeMac::paintMediaSliderTrack):
+ (WebCore::RenderThemeMac::paintMediaSliderThumb):
+ (WebCore::RenderThemeMac::paintMediaTimelineContainer):
+ (WebCore::RenderThemeMac::paintMediaCurrentTime):
+ (WebCore::RenderThemeMac::paintMediaTimeRemaining):
+ * rendering/RenderThemeSafari.cpp:
+ (WebCore::RenderThemeSafari::paintMediaMuteButton):
+ (WebCore::RenderThemeSafari::paintMediaPlayButton):
+ (WebCore::RenderThemeSafari::paintMediaSliderTrack):
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::operator<<):
+ (WebCore::writeSelection):
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::setWidgetGeometry):
+ (WebCore::RenderWidget::updateWidgetPosition):
+ (WebCore::RenderWidget::nodeAtPoint):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::isEditableLeaf):
+ * rendering/SVGRenderSupport.cpp:
+ (WebCore::prepareToRenderSVGContent):
+ * rendering/SVGRenderTreeAsText.cpp:
+ (WebCore::write):
+ * rendering/SVGRootInlineBox.cpp:
+ (WebCore::SVGRootInlineBox::buildLayoutInformation):
+ (WebCore::SVGRootInlineBox::layoutInlineBoxes):
+ (WebCore::SVGRootInlineBox::buildLayoutInformationForTextBox):
+ (WebCore::SVGRootInlineBox::buildTextChunks):
+ * rendering/style/SVGRenderStyle.cpp:
+ (WebCore::SVGRenderStyle::cssPrimitiveToLength):
+ * svg/SVGFont.cpp:
+ (WebCore::SVGTextRunWalker::walk):
+ (WebCore::floatWidthOfSubStringUsingSVGFont):
+ (WebCore::Font::drawTextUsingSVGFont):
+ * svg/SVGTextContentElement.cpp:
+ (WebCore::findInlineTextBoxInTextChunks):
+ * svg/graphics/SVGPaintServer.cpp:
+ (WebCore::SVGPaintServer::fillPaintServer):
+ (WebCore::SVGPaintServer::strokePaintServer):
+
+2009-02-11 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Darin Adler
+
+ <rdar://problem/3541409> - Further FrameLoader and page cache cleanup
+
+ * history/CachedFrame.cpp:
+ (WebCore::CachedFrame::restore): Moved updatePlatformScriptObjects() here.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::commitProvisionalLoad): Rolled opened() into this method. This method was
+ the only caller and - in the future - will benefit from doing parts of opened()'s work differently.
+ (WebCore::FrameLoader::open): Split off per-frame logic into open(CachedFrame&) method.
+ (WebCore::FrameLoader::closeAndRemoveChild): Added. Do the non-tree related cleanup that
+ FrameTree::removeChild() used to do.
+ (WebCore::FrameLoader::detachFromParent): Call ::closeAndRemoveChild() instead.
+ (WebCore::FrameLoader::cachePageForHistoryItem): Perform the "can cache page" check here.
+ * loader/FrameLoader.h:
+
+ * page/FrameTree.cpp:
+ (WebCore::FrameTree::removeChild): Just remove the Frame from the tree. Closing it and other
+ cleanup is the responsibility of the FrameLoader.
+ * page/FrameTree.h:
+ (WebCore::FrameTree::detachFromParent): Added to just clear a Frame's parent pointer
+
+2009-02-11 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23882
+ GraphicsContextSkia draws round rects as solid rects
+
+ Fixes two bugs in Skia's GraphicsContext::fillRoundedRect:
+ . fillRoundedRect had an extra call to fillRect, resulting in always
+ drawing a solid rectangle.
+ . if the total radius along a given axis is greater than the size of
+ the axis to draw, a solid rect should be drawn.
+
+ The layout tests LayoutTests/fast/css/shadow-multiple.html and
+ LayoutTests/fast/box-shadow/basic-shadows.html cover this.
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::fillRoundedRect):
+
+2009-02-11 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Bug 23536: Auto-generate HTMLElementFactory
+
+ Remove the HTMLElementFactory files. Farewell.
+
+ * html/HTMLElementFactory.cpp: Removed.
+ * html/HTMLElementFactory.h: Removed.
+
+2009-02-11 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Bug 23536: Auto-generate HTMLElementFactory
+
+ Make the platform auto-generate the HTMLElementFactory.
+
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * webcore-base.bkl:
+
+2009-02-11 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Remove unneeded ASSERTS.
+
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::width):
+ (WebCore::RenderBox::height):
+ (WebCore::RenderBox::size):
+ (WebCore::RenderBox::frameRect):
+
+2009-02-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ Add function to RenderStyle to ask whether a background image has been specified.
+
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::hasBackgroundImage):
+
+2009-02-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23548
+
+ When opacity or transform change on an object which has a compositing layer,
+ avoid repainting the layer.
+
+ Added a new StyleDifference value, StyleDifferenceRecompositeLayer, which indicates
+ that the only thing styleChanged() has to do is to update composited properties of
+ the layer. RenderStyle::diff() now has an out param for a bitmask of "context sensitive"
+ properties, currently for opacity and transform. When one of these changes, we need
+ to see if we have a compositing layer before we decide whether to layout/repaint,
+ or just update the composited layer, via adjustStyleDifference().
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::adjustStyleDifference):
+ (WebCore::RenderObject::setStyle):
+ (WebCore::RenderObject::styleDidChange):
+ * rendering/RenderObject.h:
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::diff):
+ * rendering/style/RenderStyle.h:
+ * rendering/style/RenderStyleConstants.h:
+ (WebCore::):
+
+2009-02-11 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6562920> Pasted text should be normalized to NFC
+
+ Testing requires putting non-HTML content in pasteboard, so it cannot be done with WebKit alone.
+
+ * platform/mac/PasteboardMac.mm: (WebCore::Pasteboard::plainText): Route the text through
+ -[NSString precomposedStringWithCanonicalMapping].
+
+2009-02-10 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23883
+
+ Added new TransformOperation subclasses and methods to existing ones
+ to support 3D.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/graphics/transforms/IdentityTransformOperation.h:
+ (WebCore::IdentityTransformOperation::isAffine):
+ * platform/graphics/transforms/Matrix3DTransformOperation.cpp: Added.
+ (WebCore::Matrix3DTransformOperation::blend):
+ * platform/graphics/transforms/Matrix3DTransformOperation.h: Added.
+ (WebCore::Matrix3DTransformOperation::create):
+ (WebCore::Matrix3DTransformOperation::isIdentity):
+ (WebCore::Matrix3DTransformOperation::isAffine):
+ (WebCore::Matrix3DTransformOperation::getOperationType):
+ (WebCore::Matrix3DTransformOperation::isSameType):
+ (WebCore::Matrix3DTransformOperation::operator==):
+ (WebCore::Matrix3DTransformOperation::apply):
+ (WebCore::Matrix3DTransformOperation::Matrix3DTransformOperation):
+ * platform/graphics/transforms/MatrixTransformOperation.h:
+ (WebCore::MatrixTransformOperation::isAffine):
+ (WebCore::MatrixTransformOperation::apply):
+ * platform/graphics/transforms/PerspectiveTransformOperation.cpp: Added.
+ (WebCore::PerspectiveTransformOperation::blend):
+ * platform/graphics/transforms/PerspectiveTransformOperation.h: Added.
+ (WebCore::PerspectiveTransformOperation::create):
+ (WebCore::PerspectiveTransformOperation::isIdentity):
+ (WebCore::PerspectiveTransformOperation::isAffine):
+ (WebCore::PerspectiveTransformOperation::getOperationType):
+ (WebCore::PerspectiveTransformOperation::isSameType):
+ (WebCore::PerspectiveTransformOperation::operator==):
+ (WebCore::PerspectiveTransformOperation::apply):
+ (WebCore::PerspectiveTransformOperation::PerspectiveTransformOperation):
+ * platform/graphics/transforms/RotateTransformOperation.cpp:
+ (WebCore::RotateTransformOperation::blend):
+ * platform/graphics/transforms/RotateTransformOperation.h:
+ (WebCore::RotateTransformOperation::create):
+ (WebCore::RotateTransformOperation::angle):
+ (WebCore::RotateTransformOperation::isAffine):
+ (WebCore::RotateTransformOperation::operator==):
+ (WebCore::RotateTransformOperation::apply):
+ (WebCore::RotateTransformOperation::RotateTransformOperation):
+ * platform/graphics/transforms/ScaleTransformOperation.cpp:
+ (WebCore::ScaleTransformOperation::blend):
+ * platform/graphics/transforms/ScaleTransformOperation.h:
+ (WebCore::ScaleTransformOperation::create):
+ (WebCore::ScaleTransformOperation::z):
+ (WebCore::ScaleTransformOperation::isIdentity):
+ (WebCore::ScaleTransformOperation::isAffine):
+ (WebCore::ScaleTransformOperation::operator==):
+ (WebCore::ScaleTransformOperation::apply):
+ (WebCore::ScaleTransformOperation::ScaleTransformOperation):
+ * platform/graphics/transforms/SkewTransformOperation.h:
+ (WebCore::SkewTransformOperation::isAffine):
+ * platform/graphics/transforms/TransformOperation.h:
+ (WebCore::TransformOperation::):
+ (WebCore::TransformOperation::is3DOperation):
+ * platform/graphics/transforms/TransformOperations.h:
+ (WebCore::TransformOperations::isAffine):
+ (WebCore::TransformOperations::has3DOperation):
+ * platform/graphics/transforms/TranslateTransformOperation.cpp:
+ (WebCore::TranslateTransformOperation::blend):
+ * platform/graphics/transforms/TranslateTransformOperation.h:
+ (WebCore::TranslateTransformOperation::create):
+ (WebCore::TranslateTransformOperation::z):
+ (WebCore::TranslateTransformOperation::isIdentity):
+ (WebCore::TranslateTransformOperation::isAffine):
+ (WebCore::TranslateTransformOperation::operator==):
+ (WebCore::TranslateTransformOperation::apply):
+ (WebCore::TranslateTransformOperation::TranslateTransformOperation):
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ Move createAnonymousBlock() to RenderBlock. Since anonymous blocks are always parented to some other block,
+ we can move this function to RenderBlock. Fix a couple of call sites as a result of this restriction.
+
+ Reviewed by Simon Fraser
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::createAnonymousBlock):
+ * rendering/RenderBlock.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::childBecameNonInline):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::handleDynamicFloatPositionChange):
+ * rendering/RenderObject.h:
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=23895
+
+ Remove two complete nonsense lines that I accidentally added from a cut and paste error. This
+ restores the original logic.
+
+ Reviewed by Simon Fraser
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+
+2009-02-11 David Hyatt <hyatt@apple.com>
+
+ Rename getBaselineOfFirstLineBox to firstLineBoxBaseline. Rename getBaselineOfLastLineBox to
+ lastLineBoxBaseline. Remove the functions from RenderObject and add them to RenderBox instead.
+
+ Reviewed by Eric Seidel
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::baselinePosition):
+ (WebCore::RenderBlock::firstLineBoxBaseline):
+ (WebCore::RenderBlock::lastLineBoxBaseline):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::firstLineBoxBaseline):
+ (WebCore::RenderBox::lastLineBoxBaseline):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutHorizontalBox):
+ * rendering/RenderObject.h:
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::firstLineBoxBaseline):
+ * rendering/RenderTable.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::baselinePosition):
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::firstLineBoxBaseline):
+ * rendering/RenderTableSection.h:
+
+2009-02-11 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=23877
+ Allow port to disable progress events from <video> and <audio> elements
+
+ * html/HTMLMediaElement.cpp: Initialize m_sendProgressEvents.
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Don't post progress events if m_sendProgressEvents is false.
+ (WebCore::HTMLMediaElement::initAndDispatchProgressEvent): Ditto.
+ (WebCore::HTMLMediaElement::load): Ditto.
+ * html/HTMLMediaElement.h: Add m_sendProgressEvents
+
+2009-02-11 Adam Roben <aroben@apple.com>
+
+ Windows build fix
+
+ * DerivedSources.cpp: Removed SVGElementFactory.cpp, since including
+ it leads to ambiguities for symbols like "aTag", which exist in both
+ the HTMLNames and SVGNames namespaces.
+
+ * WebCore.vcproj/WebCore.vcproj: Added SVGElementFactory.cpp to the
+ project directly. VS also decided to reformat this file a little bit.
+
+2009-02-10 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Bug 23536: Auto-generate HTMLElementFactory
+
+ Those are the last auto-generation bits needed to have a working generated HTMLElementFactory:
+
+ - Added a new option mapToTagName that enables a tag to use another's options and tagName (<image>
+ uses imgTag for example) and wired the code generation to be consistent with the current factory.
+
+ - Disabled dashboard compatibility check for HTMLElementFactory as it would make at least one test case fail.
+
+ - Pass the QualifiedName down to the Element constructor for shared constructors to make the generated code as
+ close as possible to the current one. We will pass the QualifiedName for all Element in a forthcoming patch.
+
+ * dom/make_names.pl: Did all the above points and tweaked the code generation to match the current HTMLElementFactory
+ as closely as possible.
+
+ * html/HTMLElementFactory.cpp:
+ (WebCore::quoteConstructor):
+ * html/HTMLQuoteElement.cpp:
+ (WebCore::HTMLQuoteElement::HTMLQuoteElement): Moved setUsesBeforeAfterRules to HTMLQuoteElement' constructor because some
+ part of the code creates elements without using the HTMLElementFactory. Also added a FIXME as it is not the right place.
+
+ * html/HTMLTagNames.in: Corrected <image> parameters.
+
+2009-02-10 David Hyatt <hyatt@apple.com>
+
+ Fix for pixel test regression in fast/text. Make sure not to add in
+ the borderTop and paddingTop of the block to the baseline when painting
+ strict mode text decorations.
+
+ Reviewed by Mark Rowe
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::paintTextDecorations):
+ * rendering/InlineFlowBox.h:
+
+2009-02-10 Jon Honeycutt <jhoneycutt@apple.com>
+
+ Windows build fix after r40837.
+
+ Not reviewed.
+
+ * DerivedSources.cpp:
+
+2009-02-10 Jon Honeycutt <jhoneycutt@apple.com>
<rdar://6349412> REGRESSION(r37204): Page is not repainted during and
after pan scrolling
@@ -82,11 +12945,832 @@
(WebCore::ScrollView::scrollContents): Don't repaint the pan scroll
icon rect immediately; we will paint after the view has been scrolled.
-2009-02-11 Mark Rowe <mrowe@apple.com>
+2009-02-10 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Adele Peterson.
+
+ <rdar://problem/6156755> onMouseOver events do not fire properly for cross frame drag and drop
+
+ This problem was caused by incorrectly ignoring whether or not the
+ default behaviour of the mousedown event was suppressed. If a
+ mousedown handler in a frame prevents default handling then the
+ subsequent mousemove events fired for the drag should not be
+ captured by that frame, should the mouse move out of its bounds.
+
+ Test: fast/events/mouse-drag-from-frame.html
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::EventHandler):
+ (WebCore::EventHandler::clear):
+ (WebCore::EventHandler::handleMouseReleaseEvent):
+ Reset new m_capturesDragging flag
+
+ (WebCore::EventHandler::handleMousePressEvent):
+ Respect the m_capturesDragging flag when we propagate
+ a mousedown event to a subframe.
+
+ * page/EventHandler.h:
+ (WebCore::EventHandler::capturesDragging):
+
+2009-02-10 Kevin Ollivier <kevino@theolliviers.com>
+
+ wx build fixes for recent changes to TransformationMatrix and DOMElement.
+
+ * WebCoreSources.bkl:
+ * dom/Element.cpp:
+ * platform/graphics/transforms/TransformationMatrix.h:
+ * platform/graphics/wx/TransformationMatrixWx.cpp:
+ (WebCore::TransformationMatrix::operator wxGraphicsMatrix):
+
+2009-02-10 David Hyatt <hyatt@apple.com>
+
+ Some renames on line boxes. xPos()/yPos() -> x()/y(). setXPos()/setYPos() -> setX()/setY(). m_object/object() -> m_renderer/renderer(). textObject() -> textRenderer().
+
+ Reviewed by Sam Weinig
+
+ * dom/Position.cpp:
+ (WebCore::Position::upstream):
+ (WebCore::Position::downstream):
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::leftVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::rightVisuallyDistinctCandidate):
+ (WebCore::VisiblePosition::localCaretRect):
+ * editing/visible_units.cpp:
+ (WebCore::startPositionForLine):
+ (WebCore::endPositionForLine):
+ (WebCore::previousLinePosition):
+ (WebCore::nextLinePosition):
+ * rendering/EllipsisBox.cpp:
+ (WebCore::EllipsisBox::paint):
+ (WebCore::EllipsisBox::nodeAtPoint):
+ * rendering/InlineBox.cpp:
+ (WebCore::InlineBox::showTreeForThis):
+ (WebCore::InlineBox::height):
+ (WebCore::InlineBox::caretMinOffset):
+ (WebCore::InlineBox::caretMaxOffset):
+ (WebCore::InlineBox::deleteLine):
+ (WebCore::InlineBox::extractLine):
+ (WebCore::InlineBox::attachLine):
+ (WebCore::InlineBox::adjustPosition):
+ (WebCore::InlineBox::paint):
+ (WebCore::InlineBox::nodeAtPoint):
+ (WebCore::InlineBox::selectionState):
+ (WebCore::InlineBox::canAccommodateEllipsis):
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::InlineBox):
+ (WebCore::InlineBox::renderer):
+ (WebCore::InlineBox::setX):
+ (WebCore::InlineBox::x):
+ (WebCore::InlineBox::setY):
+ (WebCore::InlineBox::y):
+ (WebCore::InlineBox::topOverflow):
+ (WebCore::InlineBox::bottomOverflow):
+ (WebCore::InlineBox::leftOverflow):
+ (WebCore::InlineBox::rightOverflow):
+ (WebCore::InlineBox::visibleToHitTesting):
+ (WebCore::InlineBox::boxModelObject):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::height):
+ (WebCore::InlineFlowBox::addToLine):
+ (WebCore::InlineFlowBox::removeLineBoxFromRenderObject):
+ (WebCore::InlineFlowBox::extractLineBoxFromRenderObject):
+ (WebCore::InlineFlowBox::attachLineBoxToRenderObject):
+ (WebCore::InlineFlowBox::rendererLineBoxes):
+ (WebCore::InlineFlowBox::onEndChain):
+ (WebCore::InlineFlowBox::determineSpacingForFlowBoxes):
+ (WebCore::InlineFlowBox::placeBoxesHorizontally):
+ (WebCore::InlineFlowBox::verticallyAlignBoxes):
+ (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
+ (WebCore::verticalPositionForBox):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ (WebCore::InlineFlowBox::placeBoxesVertically):
+ (WebCore::InlineFlowBox::nodeAtPoint):
+ (WebCore::InlineFlowBox::paint):
+ (WebCore::InlineFlowBox::paintFillLayer):
+ (WebCore::InlineFlowBox::paintBoxShadow):
+ (WebCore::InlineFlowBox::paintBoxDecorations):
+ (WebCore::InlineFlowBox::paintMask):
+ (WebCore::InlineFlowBox::paintTextDecorations):
+ * rendering/InlineFlowBox.h:
+ (WebCore::InlineFlowBox::borderLeft):
+ (WebCore::InlineFlowBox::borderRight):
+ (WebCore::InlineFlowBox::borderTop):
+ (WebCore::InlineFlowBox::borderBottom):
+ (WebCore::InlineFlowBox::baseline):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::height):
+ (WebCore::InlineTextBox::selectionState):
+ (WebCore::InlineTextBox::selectionRect):
+ (WebCore::InlineTextBox::deleteLine):
+ (WebCore::InlineTextBox::extractLine):
+ (WebCore::InlineTextBox::attachLine):
+ (WebCore::InlineTextBox::placeEllipsisBox):
+ (WebCore::InlineTextBox::isLineBreak):
+ (WebCore::InlineTextBox::nodeAtPoint):
+ (WebCore::InlineTextBox::paint):
+ (WebCore::InlineTextBox::selectionStartEnd):
+ (WebCore::InlineTextBox::paintSelection):
+ (WebCore::InlineTextBox::paintCompositionBackground):
+ (WebCore::InlineTextBox::paintCustomHighlight):
+ (WebCore::InlineTextBox::paintDecoration):
+ (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+ (WebCore::InlineTextBox::paintTextMatchMarker):
+ (WebCore::InlineTextBox::paintDocumentMarkers):
+ (WebCore::InlineTextBox::paintCompositionUnderline):
+ (WebCore::InlineTextBox::textPos):
+ (WebCore::InlineTextBox::offsetForPosition):
+ (WebCore::InlineTextBox::positionForOffset):
+ * rendering/InlineTextBox.h:
+ (WebCore::InlineTextBox::textRenderer):
+ * rendering/ListMarkerBox.cpp:
+ (WebCore::ListMarkerBox::isText):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintEllipsisBoxes):
+ (WebCore::RenderBlock::lowestPosition):
+ (WebCore::RenderBlock::rightmostPosition):
+ (WebCore::RenderBlock::leftmostPosition):
+ (WebCore::RenderBlock::positionForBox):
+ (WebCore::RenderBlock::positionForCoordinates):
+ (WebCore::RenderBlock::getBaselineOfFirstLineBox):
+ (WebCore::RenderBlock::getBaselineOfLastLineBox):
+ (WebCore::RenderBlock::adjustForBorderFit):
+ (WebCore::RenderBlock::addFocusRingRects):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::paintCustomHighlight):
+ (WebCore::RenderBox::position):
+ (WebCore::RenderBox::containingBlockWidthForPositioned):
+ (WebCore::RenderBox::calcAbsoluteHorizontalValues):
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutVerticalBox):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::absoluteRects):
+ (WebCore::RenderInline::absoluteQuads):
+ (WebCore::RenderInline::offsetLeft):
+ (WebCore::RenderInline::offsetTop):
+ (WebCore::RenderInline::linesBoundingBox):
+ (WebCore::RenderInline::relativePositionedInlineOffset):
+ (WebCore::RenderInline::addFocusRingRects):
+ (WebCore::RenderInline::paintOutline):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::localBoundingBox):
+ * rendering/RenderSVGTSpan.cpp:
+ (WebCore::RenderSVGTSpan::absoluteRects):
+ (WebCore::RenderSVGTSpan::absoluteQuads):
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::absoluteRects):
+ (WebCore::RenderSVGText::absoluteQuads):
+ (WebCore::RenderSVGText::relativeBBox):
+ * rendering/RenderSVGTextPath.cpp:
+ (WebCore::RenderSVGTextPath::absoluteRects):
+ (WebCore::RenderSVGTextPath::absoluteQuads):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::absoluteRects):
+ (WebCore::RenderText::absoluteRectsForRange):
+ (WebCore::RenderText::absoluteQuads):
+ (WebCore::RenderText::absoluteQuadsForRange):
+ (WebCore::RenderText::localCaretRect):
+ (WebCore::RenderText::linesBoundingBox):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::height):
+ (WebCore::RootInlineBox::clearTruncation):
+ (WebCore::RootInlineBox::placeEllipsis):
+ (WebCore::RootInlineBox::paintEllipsisBox):
+ (WebCore::RootInlineBox::addHighlightOverflow):
+ (WebCore::RootInlineBox::paintCustomHighlight):
+ (WebCore::RootInlineBox::paint):
+ (WebCore::RootInlineBox::nodeAtPoint):
+ (WebCore::RootInlineBox::childRemoved):
+ (WebCore::RootInlineBox::fillLineSelectionGap):
+ (WebCore::RootInlineBox::block):
+ (WebCore::isEditableLeaf):
+ (WebCore::RootInlineBox::closestLeafChildForXPos):
+ (WebCore::RootInlineBox::setVerticalOverflowPositions):
+ * rendering/RootInlineBox.h:
+ (WebCore::RootInlineBox::bottomOverflow):
+ (WebCore::RootInlineBox::floats):
+ (WebCore::RootInlineBox::setHorizontalOverflowPositions):
+ (WebCore::RootInlineBox::setVerticalSelectionPositions):
+ * rendering/SVGCharacterLayoutInfo.cpp:
+ (WebCore::SVGCharacterLayoutInfo::addLayoutInformation):
+ * rendering/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::calculateGlyphWidth):
+ (WebCore::SVGInlineTextBoxClosestCharacterToPositionWalker::chunkPortionCallback):
+ (WebCore::SVGInlineTextBoxSelectionRectWalker::chunkPortionCallback):
+ (WebCore::SVGInlineTextBox::svgCharacterHitsPosition):
+ (WebCore::SVGInlineTextBox::nodeAtPoint):
+ (WebCore::SVGInlineTextBox::paintCharacters):
+ (WebCore::SVGInlineTextBox::paintSelection):
+ (WebCore::SVGInlineTextBox::paintDecoration):
+ * rendering/SVGRenderTreeAsText.cpp:
+ (WebCore::writeSVGInlineTextBox):
+ * rendering/SVGRootInlineBox.cpp:
+ (WebCore::SVGRootInlineBoxPaintWalker::SVGRootInlineBoxPaintWalker):
+ (WebCore::SVGRootInlineBoxPaintWalker::chunkStartCallback):
+ (WebCore::SVGRootInlineBoxPaintWalker::chunkEndCallback):
+ (WebCore::SVGRootInlineBoxPaintWalker::chunkSetupFillCallback):
+ (WebCore::SVGRootInlineBoxPaintWalker::chunkSetupStrokeCallback):
+ (WebCore::SVGRootInlineBoxPaintWalker::chunkPortionCallback):
+ (WebCore::SVGRootInlineBox::paint):
+ (WebCore::cummulatedWidthOfInlineBoxCharacterRange):
+ (WebCore::cummulatedHeightOfInlineBoxCharacterRange):
+ (WebCore::svgTextRunForInlineTextBox):
+ (WebCore::cummulatedWidthOrHeightOfTextChunk):
+ (WebCore::applyTextAnchorToTextChunk):
+ (WebCore::SVGRootInlineBox::buildLayoutInformation):
+ (WebCore::SVGRootInlineBox::layoutInlineBoxes):
+ (WebCore::SVGRootInlineBox::buildLayoutInformationForTextBox):
+ (WebCore::SVGRootInlineBox::buildTextChunks):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::constructLine):
+ (WebCore::RenderBlock::computeVerticalPositionsForLine):
+ (WebCore::RenderBlock::layoutInlineChildren):
+ (WebCore::RenderBlock::checkLinesForTextOverflow):
+ * svg/SVGTextContentElement.cpp:
+ (WebCore::cumulativeCharacterRangeLength):
+ (WebCore::SVGInlineTextBoxQueryWalker::chunkPortionCallback):
+ (WebCore::findInlineTextBoxInTextChunks):
+
+2009-02-10 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ Clean up "fallbackAnimating" logic in AnimationBase. This flag indicates
+ that animation of an accelerated property must run in software for some reason.
+
+ Also remove use of private headers in GraphicsLayerCA related to a case
+ where we may have to fall back on software animation of transform.
+
+ * page/animation/AnimationBase.cpp:
+ (WebCore::AnimationBase::blendProperties):
+ * page/animation/AnimationBase.h:
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::animate):
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::animate):
+ * platform/graphics/mac/GraphicsLayerCA.h:
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (WebCore::getValueFunctionNameForTransformOperation):
+ (WebCore::caValueFunctionSupported):
+ (WebCore::GraphicsLayerCA::setBackgroundColor):
+ (WebCore::GraphicsLayerCA::setOpacity):
+ (WebCore::GraphicsLayerCA::animateTransform):
+ (WebCore::GraphicsLayerCA::animateFloat):
+ (WebCore::GraphicsLayerCA::setBasicAnimation):
+ (WebCore::GraphicsLayerCA::setKeyframeAnimation):
+
+2009-02-10 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ Move enclosingCompositingLayer() from RenderObject to RenderLayer, since it
+ relates to the RenderLayer z-order/overflow structure, rather than the render tree
+ parent chain. Add a convenience method, ancestorCompositingLayer(), which finds
+ the enclosing layer excluding self.
+
+ Fix enclosingCompositingLayer() to correctly look at stacking context and overflow
+ lists.
+
+ Check for documentBeingDestroyed() in a few places to avoid work on document
+ teardown.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::enclosingCompositingLayer):
+ (WebCore::RenderLayer::setParent):
+ (WebCore::RenderLayer::dirtyZOrderLists):
+ (WebCore::RenderLayer::dirtyOverflowList):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::ancestorCompositingLayer):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateLayerCompositingState):
+ (WebCore::RenderLayerCompositor::calculateCompositedBounds):
+ (WebCore::RenderLayerCompositor::layerWillBeRemoved):
+ (WebCore::RenderLayerCompositor::clippedByAncestor):
+ * rendering/RenderLayerCompositor.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::containerForRepaint):
+ * rendering/RenderObject.h:
+
+2009-02-10 David Hyatt <hyatt@apple.com>
+
+ Rename xPos() and yPos() on RenderLayer to x() and y() to match RenderBox. Rename setPos to setLocation.
+
+ Reviewed by Simon Fraser
+
+ * dom/MouseRelatedEvent.cpp:
+ (WebCore::MouseRelatedEvent::receivedTarget):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateLayerPosition):
+ (WebCore::RenderLayer::convertToLayerCoords):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::x):
+ (WebCore::RenderLayer::y):
+ (WebCore::RenderLayer::setLocation):
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::write):
+ (WebCore::externalRepresentation):
+
+2009-02-10 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23879
+ Add missing PLATFORM(SKIA) changes to TransformationMatrix.h
+
+ * platform/graphics/transforms/TransformationMatrix.h:
+
+2009-02-10 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=15897
+ Please implement getBoundingClientRect and getClientRects
+ <rdar://problem/6139669>
+
+ Cursory implementation of Element.getBoundingClientRect and
+ Element.getClientRects. Adds necessary infrastructure classes
+ ClientRect and ClientRectList.
+
+ Tests: fast/dom/getBoundingClientRect.html
+ fast/dom/getClientRects.html
+
+ * DerivedSources.make:
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * dom/ClientRect.cpp: Added.
+ (WebCore::ClientRect::ClientRect):
+ * dom/ClientRect.h: Added.
+ (WebCore::ClientRect::create):
+ (WebCore::ClientRect::top):
+ (WebCore::ClientRect::right):
+ (WebCore::ClientRect::bottom):
+ (WebCore::ClientRect::left):
+ (WebCore::ClientRect::width):
+ (WebCore::ClientRect::height):
+ * dom/ClientRect.idl: Added.
+ * dom/ClientRectList.cpp: Added.
+ (WebCore::ClientRectList::ClientRectList):
+ (WebCore::ClientRectList::~ClientRectList):
+ (WebCore::ClientRectList::length):
+ (WebCore::ClientRectList::item):
+ * dom/ClientRectList.h: Added.
+ (WebCore::ClientRectList::create):
+ * dom/ClientRectList.idl: Added.
+ * dom/Element.cpp:
+ (WebCore::Element::getClientRects):
+ (WebCore::Element::getBoundingClientRect):
+ * dom/Element.h:
+ * dom/Element.idl:
+ * page/DOMWindow.idl:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::absoluteRects):
+ (WebCore::RenderInline::absoluteQuads):
- Merge r40808.
+2009-02-10 David Hyatt <hyatt@apple.com>
- 2009-02-09 Dan Bernstein <mitz@apple.com>
+ Get rid of capsLockStateMayHaveChanged on RenderObject. It is only implemented by one class (text fields),
+ so devirtualize and just query at the single call site.
+
+ Reviewed by Eric Seidel
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::capsLockStateMayHaveChanged):
+ * rendering/RenderObject.h:
+ * rendering/RenderTextControlSingleLine.h:
+
+2009-02-10 David Hyatt <hyatt@apple.com>
+
+ Shrink the size of all RenderObjects (except for RenderInlines) by 4 bytes. This patch moves the cached vertical position member to RenderInlines,
+ since they were the only objects being queried across multiple lines.
+
+ Reviewed by Sam Weinig
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::verticalPositionForBox):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::verticalPosition):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::RenderInline):
+ (WebCore::RenderInline::verticalPositionFromCache):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::invalidateVerticalPosition):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::RenderObject):
+ * rendering/RenderObject.h:
+ * rendering/RenderText.cpp:
+ * rendering/RenderText.h:
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren):
+
+2009-02-10 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Mark Rowe.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23868
+ Fix code style issues: removed 80-col wrapping, incorrect include style, if statement body on same line.
+
+ * bindings/v8/custom/V8HTMLInputElementCustom.cpp:
+ * bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp:
+
+2009-02-10 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23868
+ Add HTMLInputElement and HTMLOptionsCollection V8 custom bindings.
+
+ * bindings/v8/custom/V8HTMLInputElementCustom.cpp: Added.
+ (WebCore::ACCESSOR_GETTER):
+ (WebCore::ACCESSOR_SETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp: Added.
+ (WebCore::ACCESSOR_GETTER):
+ (WebCore::ACCESSOR_SETTER):
+
+2009-02-10 Adam Roben <aroben@apple.com>
+
+ Fix Bug 23871: Assertion failure beneath WebCore::openFunc when
+ running http/tests/security/xss-DENIED-xsl-document-redirect.xml
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23871>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Covered by existing tests.
+
+ * dom/XMLTokenizerLibxml2.cpp:
+ (WebCore::openFunc): Use the two-parameter KURL constructor so that
+ the string will be parsed. libxml2 gives us a UTF-8-encoded string
+ that needs to be parsed.
+
+2009-02-10 David Hyatt <hyatt@apple.com>
+
+ Shrink the size of all replaced elements (images, form controls, plugins) by 4 bytes by packing the
+ overflow boolean into the RenderObject base class.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::RenderObject):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::replacedHasOverflow):
+ (WebCore::RenderObject::setReplacedHasOverflow):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::RenderReplaced):
+ (WebCore::RenderReplaced::~RenderReplaced):
+ (WebCore::RenderReplaced::adjustOverflowForBoxShadow):
+ (WebCore::RenderReplaced::overflowHeight):
+ (WebCore::RenderReplaced::overflowWidth):
+ (WebCore::RenderReplaced::overflowLeft):
+ (WebCore::RenderReplaced::overflowTop):
+ (WebCore::RenderReplaced::overflowRect):
+ * rendering/RenderReplaced.h:
+
+2009-02-10 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23870
+ Make it possible for a port to require a user gesture for an <audio> or <video> element
+ to load a url.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::HTMLMediaElement): Initialize m_loadRestrictions.
+ (WebCore::HTMLMediaElement::attributeChanged): Only one attribute can change so put an "else" between tests.
+ (WebCore::HTMLMediaElement::load): Return INVALID_STATE_ERR if RequireUserGestureLoadRestriction is set
+ and we are not preocessing a user gesture.
+ (WebCore::HTMLMediaElement::mediaPlayerNetworkStateChanged): Remove unnecessary white space.
+ (WebCore::HTMLMediaElement::play): Ditto.
+ (WebCore::HTMLMediaElement::endScrubbing): Remove unnecessary braces added in r40789.
+ (WebCore::HTMLMediaElement::mediaPlayerTimeChanged): Cache currentTime() in a local instead of calling it
+ multiple times.
+ (WebCore::HTMLMediaElement::processingUserGesture): New.
+ * html/HTMLMediaElement.h:
+ (WebCore::HTMLMediaElement::): Define LoadRestrictions, add m_loadRestrictions.
+
+2009-02-10 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Sam Weinig.
+
+ Remove the SVG checks from FloatPoint3D as it is used
+ by TransformationMatrix.
+
+ * platform/graphics/FloatPoint3D.cpp:
+ * platform/graphics/FloatPoint3D.h:
+
+2009-02-10 David Hyatt <hyatt@apple.com>
+
+ Remove the m_baseline member variable from all line boxes, since it can easily be computed when needed and did not need to be cached.
+
+ Reviewed by Sam Weinig
+
+ * rendering/EllipsisBox.cpp:
+ (WebCore::EllipsisBox::paint):
+ (WebCore::EllipsisBox::nodeAtPoint):
+ * rendering/EllipsisBox.h:
+ (WebCore::EllipsisBox::EllipsisBox):
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::InlineBox):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::verticallyAlignBoxes):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ (WebCore::InlineFlowBox::placeBoxesVertically):
+ (WebCore::InlineFlowBox::paintTextDecorations):
+ * rendering/InlineFlowBox.h:
+ (WebCore::InlineFlowBox::marginBorderPaddingLeft):
+ (WebCore::InlineFlowBox::marginBorderPaddingRight):
+ (WebCore::InlineFlowBox::marginLeft):
+ (WebCore::InlineFlowBox::marginRight):
+ (WebCore::InlineFlowBox::borderLeft):
+ (WebCore::InlineFlowBox::borderRight):
+ (WebCore::InlineFlowBox::borderTop):
+ (WebCore::InlineFlowBox::borderBottom):
+ (WebCore::InlineFlowBox::paddingLeft):
+ (WebCore::InlineFlowBox::paddingRight):
+ (WebCore::InlineFlowBox::paddingTop):
+ (WebCore::InlineFlowBox::paddingBottom):
+ (WebCore::InlineFlowBox::includeLeftEdge):
+ (WebCore::InlineFlowBox::includeRightEdge):
+ (WebCore::InlineFlowBox::baseline):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paint):
+ (WebCore::InlineTextBox::paintDecoration):
+ (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+ (WebCore::InlineTextBox::paintCompositionUnderline):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::getBaselineOfFirstLineBox):
+ (WebCore::RenderBlock::getBaselineOfLastLineBox):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::baselinePosition):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::placeEllipsis):
+ * rendering/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::paintDecoration):
+ * rendering/SVGRootInlineBox.cpp:
+ (WebCore::applyTextAnchorToTextChunk):
+ (WebCore::SVGRootInlineBox::layoutInlineBoxes):
+
+2009-02-10 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23867
+ Eliminate obsolete frame->document() checks
+
+ * page/FrameView.cpp: (WebCore::FrameView::paintContents): Apparently due to a typo
+ (document vs. !document), fillWithRed was always set to false, and other branches were
+ never taken. Removing the check for document restores debug-only red color filling.
+
+ * loader/FrameLoader.cpp: (WebCore::FrameLoader::begin): Only call dispatchWindowObjectAvailable()
+ after a document is created. A client can do anything in its delegate method, so we'd need
+ to have frame->document() checks otherwise. DumpRenderTree uses this delegate to add its
+ custom property, and it was crashing due to null document in JSDOMWindowBase::getOwnPropertySlot().
+
+ * bindings/js/JSDOMWindowBase.cpp:
+ (WebCore::JSDOMWindowBase::getOwnPropertySlot):
+ * bindings/js/JSDOMWindowCustom.cpp:
+ (WebCore::JSDOMWindow::addEventListener):
+ (WebCore::JSDOMWindow::removeEventListener):
+ * bindings/js/JSNavigatorCustom.cpp:
+ (WebCore::needsYouTubeQuirk):
+ * bindings/js/ScheduledAction.cpp:
+ (WebCore::ScheduledAction::execute):
+ * bindings/js/ScriptControllerMac.mm:
+ (WebCore::updateRenderingForBindings):
+ * dom/Document.cpp:
+ (WebCore::Document::initSecurityContext):
+ * editing/Editor.cpp:
+ (WebCore::Editor::deleteWithDirection):
+ (WebCore::Editor::dispatchCPPEvent):
+ (WebCore::Editor::applyStyle):
+ (WebCore::Editor::applyParagraphStyle):
+ * editing/EditorCommand.cpp:
+ (WebCore::Editor::Command::execute):
+ (WebCore::Editor::Command::isEnabled):
+ (WebCore::Editor::Command::state):
+ (WebCore::Editor::Command::value):
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::recomputeCaretRect):
+ (WebCore::SelectionController::selectFrameElementInParentIfFullySelected):
+ (WebCore::SelectionController::selectAll):
+ (WebCore::SelectionController::setFocused):
+ * inspector/InspectorController.cpp:
+ (WebCore::getResourceDocumentNode):
+ * inspector/JavaScriptDebugServer.cpp:
+ (WebCore::JavaScriptDebugServer::setJavaScriptPaused):
+ * loader/DocumentLoader.cpp:
+ (WebCore::canonicalizedTitle):
+ (WebCore::DocumentLoader::stopLoading):
+ (WebCore::DocumentLoader::isLoadingInAPISense):
+ (WebCore::DocumentLoader::subresource):
+ (WebCore::DocumentLoader::getSubresources):
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::urlSelected):
+ (WebCore::FrameLoader::stop):
+ (WebCore::FrameLoader::iconURL):
+ (WebCore::FrameLoader::executeIfJavaScriptURL):
+ (WebCore::FrameLoader::clear):
+ (WebCore::FrameLoader::endIfNotLoadingMainResource):
+ (WebCore::FrameLoader::restoreDocumentState):
+ (WebCore::FrameLoader::gotoAnchor):
+ (WebCore::FrameLoader::loadDone):
+ (WebCore::FrameLoader::checkCompleted):
+ (WebCore::FrameLoader::checkCallImplicitClose):
+ (WebCore::FrameLoader::scheduleRefresh):
+ (WebCore::FrameLoader::outgoingOrigin):
+ (WebCore::FrameLoader::canCachePageContainingThisFrame):
+ (WebCore::FrameLoader::logCanCacheFrameDecision):
+ (WebCore::FrameLoader::updatePolicyBaseURL):
+ (WebCore::FrameLoader::setPolicyBaseURL):
+ (WebCore::FrameLoader::frameDetached):
+ (WebCore::FrameLoader::shouldScrollToAnchor):
+ (WebCore::FrameLoader::saveDocumentState):
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ (WebCore::LegacyWebArchive::create):
+ * loader/icon/IconFetcher.cpp:
+ (WebCore::IconFetcher::create):
+ * loader/icon/IconLoader.cpp:
+ (WebCore::IconLoader::startLoading):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::visiblePositionForPoint):
+ * page/Chrome.cpp:
+ (WebCore::PageGroupLoadDeferrer::PageGroupLoadDeferrer):
+ (WebCore::PageGroupLoadDeferrer::~PageGroupLoadDeferrer):
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::sessionStorage):
+ (WebCore::DOMWindow::alert):
+ (WebCore::DOMWindow::confirm):
+ (WebCore::DOMWindow::prompt):
+ (WebCore::DOMWindow::scrollX):
+ (WebCore::DOMWindow::scrollY):
+ (WebCore::DOMWindow::getMatchedCSSRules):
+ (WebCore::DOMWindow::openDatabase):
+ (WebCore::DOMWindow::scrollBy):
+ (WebCore::DOMWindow::scrollTo):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::allowDHTMLDrag):
+ (WebCore::EventHandler::scrollOverflow):
+ (WebCore::EventHandler::handleMousePressEvent):
+ (WebCore::EventHandler::handleMouseDoubleClickEvent):
+ (WebCore::EventHandler::handleMouseMoveEvent):
+ (WebCore::EventHandler::handleMouseReleaseEvent):
+ (WebCore::EventHandler::updateDragAndDrop):
+ (WebCore::EventHandler::handleWheelEvent):
+ (WebCore::EventHandler::sendContextMenuEvent):
+ (WebCore::EventHandler::capsLockStateMayHaveChanged):
+ (WebCore::EventHandler::sendResizeEvent):
+ (WebCore::EventHandler::sendScrollEvent):
+ * page/FocusController.cpp:
+ (WebCore::deepFocusableNode):
+ (WebCore::FocusController::advanceFocus):
+ * page/Frame.cpp:
+ (WebCore::Frame::setFocusedNodeIfNeeded):
+ (WebCore::Frame::shouldApplyTextZoom):
+ (WebCore::Frame::shouldApplyPageZoom):
+ (WebCore::Frame::setZoomFactor):
+ (WebCore::Frame::setPrinting):
+ (WebCore::Frame::reapplyStyles):
+ (WebCore::Frame::isContentEditable):
+ (WebCore::Frame::computeAndSetTypingStyle):
+ (WebCore::Frame::selectionComputedStyle):
+ (WebCore::Frame::applyEditingStyleToBodyElement):
+ (WebCore::Frame::removeEditingStyleFromBodyElement):
+ (WebCore::Frame::contentRenderer):
+ (WebCore::Frame::styleForSelectionStart):
+ (WebCore::Frame::setSelectionFromNone):
+ (WebCore::Frame::findString):
+ (WebCore::Frame::markAllMatchesForText):
+ (WebCore::Frame::setMarkedTextMatchesAreHighlighted):
+ (WebCore::Frame::documentTypeString):
+ (WebCore::Frame::shouldClose):
+ (WebCore::Frame::respondToChangedSelection):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::~FrameView):
+ (WebCore::FrameView::createScrollbar):
+ (WebCore::FrameView::layout):
+ (WebCore::FrameView::layoutTimerFired):
+ (WebCore::FrameView::scheduleRelayout):
+ (WebCore::FrameView::needsLayout):
+ (WebCore::FrameView::unscheduleRelayout):
+ (WebCore::FrameView::windowClipRect):
+ * page/Geolocation.cpp:
+ (WebCore::Geolocation::disconnectFrame):
+ * page/Page.cpp:
+ (WebCore::networkStateChanged):
+ (WebCore::Page::~Page):
+ (WebCore::Page::unmarkAllTextMatches):
+ (WebCore::Page::setMediaVolume):
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::updateRenderingDispatcherFired):
+ * page/mac/EventHandlerMac.mm:
+ (WebCore::EventHandler::currentKeyboardEvent):
+ (WebCore::EventHandler::needsKeyboardEventDisambiguationQuirks):
+ * page/mac/FrameMac.mm:
+ (WebCore::Frame::dashboardRegionsDictionary):
+ (WebCore::Frame::setUserStyleSheetLocation):
+ (WebCore::Frame::setUserStyleSheet):
+ * storage/LocalStorageArea.cpp:
+ (WebCore::LocalStorageArea::dispatchStorageEvent):
+ * storage/SessionStorageArea.cpp:
+ (WebCore::SessionStorageArea::dispatchStorageEvent):
+ * svg/graphics/SVGImage.cpp:
+ (WebCore::SVGImage::setContainerSize):
+ (WebCore::SVGImage::usesContainerSize):
+ (WebCore::SVGImage::size):
+ (WebCore::SVGImage::hasRelativeWidth):
+ (WebCore::SVGImage::hasRelativeHeight):
+ Removed frame->document() checks.
+
+2009-02-10 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Attempt to fix the Qt build after r40791.
+
+ * rendering/RenderSVGRoot.cpp:
+
+2009-02-10 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by George Staikos.
+
+ Minor code cleanup.
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::replaceChild):
+
+2009-02-10 Adam Treat <adam.treat@torchmobile.com>
+
+ Fix Qt build following r40793.
+
+ * editing/qt/EditorQt.cpp:
+
+2009-02-10 Feng Qian <feng@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Fix crashes when accessing navigator object of a deleted frame.
+ https://bugs.webkit.org/show_bug.cgi?id=23626
+ A layout test is added: fast/dom/navigator-detached-no-crash.html
+
+ * page/Navigator.cpp:
+ (WebCore::Navigator::cookieEnabled):
+ (WebCore::Navigator::javaEnabled):
+
+2009-02-10 Sverrir Berg <sverrir@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23630
+ Add complex font rendering using Skia instead of Windows ScriptTextOut.
+ This adds support for enhanced webkit styles when drawing complex
+ glyphs.
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+ * platform/graphics/chromium/UniscribeHelper.cpp:
+ (WebCore::containsMissingGlyphs):
+ (WebCore::UniscribeHelper::draw):
+ (WebCore::UniscribeHelper::shape):
+ * platform/graphics/chromium/UniscribeHelper.h:
+ * platform/graphics/skia/SkiaFontWin.cpp:
+ (WebCore::windowsCanHandleTextDrawing):
+ (WebCore::skiaDrawText):
+ (WebCore::paintSkiaText):
+ * platform/graphics/skia/SkiaFontWin.h:
+
+2009-02-10 Darin Fisher <darin@chromium.org>
+
+ Revert r40797 as requested by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23809
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * dom/Document.idl:
+ * html/HTMLCanvasElement.idl:
+
+2009-02-09 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23855
+ Fix TransformationMatrixSkia.cpp and GraphicsContextSkia.cpp bustage
+
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::getCTM):
+ * platform/graphics/skia/TransformationMatrixSkia.cpp:
+ (WebCore::TransformationMatrix::operator SkMatrix):
+
+2009-02-09 Dan Bernstein <mitz@apple.com>
Reviewed by Dave Hyatt.
@@ -98,11 +13782,634 @@
otherwise that function returns incorrect results for the default UI
font at a certain size.
-2009-02-11 Mark Rowe <mrowe@apple.com>
+2009-02-09 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser
+
+ https://bugs.webkit.org/show_bug.cgi?id=23689
+
+ Added 3D functions to WebKitCSSMatrix. This depends on the 3D functions
+ added to TransformationMatrix in https://bugs.webkit.org/show_bug.cgi?id=6868
+
+ Test: transforms/3d/cssmatrix-3d-interface.xhtml
+
+ * css/WebKitCSSMatrix.cpp:
+ * css/WebKitCSSMatrix.h:
+ * css/WebKitCSSMatrix.idl:
+
+2009-02-09 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Fix <https://bugs.webkit.org/show_bug.cgi?id=23858>
+ Bug 23858: Crash when removing a HTMLSelectElement from the document from inside its focus event handler
+
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::menuListDefaultEventHandler): Don't store the renderer in a local variable
+ as it can be invalidated by any of the calls to focus() within the function. Instead, retrieve it and
+ null-check it when it is needed.
+
+2009-02-09 David Hyatt <hyatt@apple.com>
+
+ Remove the m_height member from InlineBox. This shaves 4 bytes off of all inline boxes. Unfortunately SVG
+ sets heights that are independent of the renderer or of the font, and so all SVG boxes have to retain m_height
+ member variables.
+
+ height() on InlineBox is now a virtual function that does a dynamic computation (including shrinking boxes
+ with no text children). For SVG boxes there is also a non-virtual setHeight function for updating the
+ m_height member variable like before.
+
+ Reviewed by Darin Adler
+
+ * rendering/EllipsisBox.cpp:
+ (WebCore::EllipsisBox::nodeAtPoint):
+ * rendering/EllipsisBox.h:
+ (WebCore::EllipsisBox::EllipsisBox):
+ * rendering/InlineBox.cpp:
+ (WebCore::InlineBox::height):
+ (WebCore::InlineBox::root):
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::InlineBox):
+ (WebCore::InlineBox::isInlineFlowBox):
+ (WebCore::InlineBox::isRootInlineBox):
+ (WebCore::InlineBox::topOverflow):
+ (WebCore::InlineBox::bottomOverflow):
+ (WebCore::InlineBox::leftOverflow):
+ (WebCore::InlineBox::rightOverflow):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::height):
+ (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ (WebCore::InlineFlowBox::placeBoxesVertically):
+ (WebCore::InlineFlowBox::shrinkBoxesWithNoTextChildren):
+ (WebCore::InlineFlowBox::nodeAtPoint):
+ * rendering/InlineFlowBox.h:
+ (WebCore::InlineFlowBox::isInlineFlowBox):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::height):
+ (WebCore::InlineTextBox::nodeAtPoint):
+ (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+ (WebCore::InlineTextBox::paintCompositionUnderline):
+ * rendering/InlineTextBox.h:
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::height):
+ (WebCore::RootInlineBox::placeEllipsis):
+ (WebCore::RootInlineBox::setVerticalOverflowPositions):
+ * rendering/RootInlineBox.h:
+ (WebCore::RootInlineBox::isRootInlineBox):
+ (WebCore::RootInlineBox::topOverflow):
+ (WebCore::RootInlineBox::bottomOverflow):
+ (WebCore::RootInlineBox::leftOverflow):
+ (WebCore::RootInlineBox::rightOverflow):
+ (WebCore::RootInlineBox::selectionBottom):
+ (WebCore::RootInlineBox::Overflow::Overflow):
+ (WebCore::RootInlineBox::setVerticalSelectionPositions):
+ * rendering/SVGInlineFlowBox.h:
+ (WebCore::SVGInlineFlowBox::SVGInlineFlowBox):
+ (WebCore::SVGInlineFlowBox::height):
+ (WebCore::SVGInlineFlowBox::setHeight):
+ * rendering/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::SVGInlineTextBox):
+ * rendering/SVGInlineTextBox.h:
+ (WebCore::SVGInlineTextBox::height):
+ (WebCore::SVGInlineTextBox::setHeight):
+ * rendering/SVGRootInlineBox.cpp:
+ (WebCore::SVGRootInlineBox::layoutInlineBoxes):
+ * rendering/SVGRootInlineBox.h:
+ (WebCore::SVGRootInlineBox::SVGRootInlineBox):
+ (WebCore::SVGRootInlineBox::height):
+ (WebCore::SVGRootInlineBox::setHeight):
+
+2009-02-09 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ Document our Selection DOM extensions
+ (in preparation for re-writing Selection to work with ranges)
+
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::type):
+ * page/DOMSelection.h:
+ * page/DOMSelection.idl:
+
+2009-02-09 Eric Seidel <eric@webkit.org>
+
+ Attempt to fix wx build
+
+ * WebCoreSources.bkl: change Selection to VisibleSelection
+
+2009-02-06 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23809
+ Return CanvasRenderingContext2D instead of DOMObject in IDL to avoid V8 #ifdefs
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * dom/Document.idl:
+ * html/HTMLCanvasElement.idl:
+
+2009-02-09 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ Transform the gradient instead of the context for most platforms and
+ transform the context after CGContextReplacePathWithStrokedPath for CG.
+
+ REGRESSION: SVG gradient transformation/BoundingBox can cause ugly stroke thickness
+ https://bugs.webkit.org/show_bug.cgi?id=23547
+
+ * platform/graphics/Gradient.h:
+ (WebCore::Gradient::setGradientSpaceTransform):
+ (WebCore::Gradient::gradientSpaceTransform):
+ * platform/graphics/cairo/GradientCairo.cpp:
+ (WebCore::Gradient::platformGradient):
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ (WebCore::GraphicsContext::fillRect):
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ (WebCore::GraphicsContext::fillRect):
+ * platform/graphics/skia/GradientSkia.cpp:
+ (WebCore::Gradient::platformGradient):
+ * svg/graphics/SVGPaintServerGradient.cpp:
+ (WebCore::SVGPaintServerGradient::SVGPaintServerGradient):
+ (WebCore::clipToTextMask):
+ (WebCore::SVGPaintServerGradient::setup):
+ (WebCore::SVGPaintServerGradient::teardown):
+
+2009-02-09 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Fix the highlight when inspecting inline elements.
+
+ * inspector/InspectorController.cpp:
+ (WebCore::drawHighlightForBox):
+ (WebCore::drawHighlightForLineBoxes):
+ (WebCore::InspectorController::drawNodeHighlight):
+
+2009-02-09 Eric Seidel <eric@webkit.org>
+
+ Fix the gtk build by adding VisibleSelection and removing Selection.
+
+ * GNUmakefile.am:
+
+2009-02-09 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Dave Hyatt.
+
+ Rename Selection to VisibleSelection to allow us to separate
+ the selections the user works with from the ones used by
+ the JS editing APIs.
+ https://bugs.webkit.org/show_bug.cgi?id=23852
+
+ No functional changes, thus no tests.
+
+ * WebCore.base.exp:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Element.cpp:
+ (WebCore::Element::updateFocusAppearance):
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::updateStartEnd):
+ (WebCore::ApplyStyleCommand::surroundNodeRangeWithElement):
+ * editing/BreakBlockquoteCommand.cpp:
+ (WebCore::BreakBlockquoteCommand::doApply):
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::inputText):
+ (WebCore::CompositeEditCommand::deleteSelection):
+ (WebCore::CompositeEditCommand::rebalanceWhitespace):
+ (WebCore::CompositeEditCommand::pushAnchorElementDown):
+ (WebCore::CompositeEditCommand::pushPartiallySelectedAnchorElementsDown):
+ (WebCore::CompositeEditCommand::moveParagraphs):
+ (WebCore::CompositeEditCommand::breakOutOfEmptyListItem):
+ (WebCore::CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph):
+ * editing/CompositeEditCommand.h:
+ * editing/CreateLinkCommand.cpp:
+ (WebCore::CreateLinkCommand::doApply):
+ * editing/DeleteButtonController.cpp:
+ (WebCore::enclosingDeletableElement):
+ (WebCore::DeleteButtonController::respondToChangedSelection):
+ * editing/DeleteButtonController.h:
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::DeleteSelectionCommand::DeleteSelectionCommand):
+ (WebCore::DeleteSelectionCommand::clearTransientState):
+ (WebCore::DeleteSelectionCommand::doApply):
+ * editing/DeleteSelectionCommand.h:
+ (WebCore::DeleteSelectionCommand::create):
+ * editing/EditCommand.cpp:
+ (WebCore::EditCommand::setStartingSelection):
+ (WebCore::EditCommand::setEndingSelection):
+ * editing/EditCommand.h:
+ (WebCore::EditCommand::startingSelection):
+ (WebCore::EditCommand::endingSelection):
+ * editing/Editor.cpp:
+ (WebCore::Editor::selectionForCommand):
+ (WebCore::Editor::respondToChangedSelection):
+ (WebCore::Editor::respondToChangedContents):
+ (WebCore::Editor::applyStyle):
+ (WebCore::Editor::applyParagraphStyle):
+ (WebCore::Editor::appliedEditing):
+ (WebCore::Editor::unappliedEditing):
+ (WebCore::Editor::reappliedEditing):
+ (WebCore::Editor::insertTextWithoutSendingTextEvent):
+ (WebCore::Editor::selectComposition):
+ (WebCore::Editor::confirmComposition):
+ (WebCore::Editor::advanceToNextMisspelling):
+ (WebCore::Editor::markMisspellingsAfterTypingToPosition):
+ (WebCore::markMisspellingsOrBadGrammar):
+ (WebCore::Editor::markMisspellings):
+ (WebCore::Editor::markBadGrammar):
+ (WebCore::Editor::rangeForPoint):
+ (WebCore::Editor::transpose):
+ * editing/Editor.h:
+ * editing/EditorCommand.cpp:
+ (WebCore::expandSelectionToGranularity):
+ (WebCore::executeSwapWithMark):
+ (WebCore::enabledVisibleSelection):
+ (WebCore::enabledVisibleSelectionAndMark):
+ (WebCore::enableCaretInEditableText):
+ * editing/FormatBlockCommand.cpp:
+ (WebCore::FormatBlockCommand::modifyRange):
+ (WebCore::FormatBlockCommand::doApply):
+ * editing/IndentOutdentCommand.cpp:
+ (WebCore::IndentOutdentCommand::indentRegion):
+ (WebCore::IndentOutdentCommand::outdentRegion):
+ (WebCore::IndentOutdentCommand::doApply):
+ * editing/InsertLineBreakCommand.cpp:
+ (WebCore::InsertLineBreakCommand::doApply):
+ * editing/InsertListCommand.cpp:
+ (WebCore::InsertListCommand::modifyRange):
+ (WebCore::InsertListCommand::doApply):
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply):
+ * editing/InsertTextCommand.cpp:
+ (WebCore::InsertTextCommand::performTrivialReplace):
+ (WebCore::InsertTextCommand::input):
+ * editing/ModifySelectionListLevel.cpp:
+ (WebCore::getStartEndListChildren):
+ (WebCore::canIncreaseListLevel):
+ (WebCore::canDecreaseListLevel):
+ * editing/MoveSelectionCommand.cpp:
+ (WebCore::MoveSelectionCommand::doApply):
+ * editing/RemoveFormatCommand.cpp:
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplacementFragment::ReplacementFragment):
+ (WebCore::ReplaceSelectionCommand::doApply):
+ (WebCore::ReplaceSelectionCommand::completeHTMLReplacement):
+ * editing/Selection.cpp: Removed.
+ * editing/Selection.h: Removed.
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::moveTo):
+ (WebCore::SelectionController::setSelection):
+ (WebCore::SelectionController::nodeWillBeRemoved):
+ (WebCore::SelectionController::clear):
+ (WebCore::SelectionController::setBase):
+ (WebCore::SelectionController::setExtent):
+ (WebCore::SelectionController::selectFrameElementInParentIfFullySelected):
+ (WebCore::SelectionController::selectAll):
+ (WebCore::SelectionController::setSelectedRange):
+ * editing/SelectionController.h:
+ (WebCore::SelectionController::selection):
+ (WebCore::SelectionController::selectionType):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::insertText):
+ (WebCore::TypingCommand::deleteKeyPressed):
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ * editing/TypingCommand.h:
+ * editing/VisiblePosition.cpp:
+ (WebCore::VisiblePosition::honorEditableBoundaryAtOrBefore):
+ (WebCore::VisiblePosition::honorEditableBoundaryAtOrAfter):
+ * editing/VisibleSelection.cpp: Added.
+ (WebCore::VisibleSelection::VisibleSelection):
+ (WebCore::VisibleSelection::selectionFromContentsOfNode):
+ (WebCore::VisibleSelection::setBase):
+ (WebCore::VisibleSelection::setExtent):
+ (WebCore::VisibleSelection::firstRange):
+ (WebCore::VisibleSelection::toNormalizedRange):
+ (WebCore::VisibleSelection::expandUsingGranularity):
+ (WebCore::makeSearchRange):
+ (WebCore::VisibleSelection::appendTrailingWhitespace):
+ (WebCore::VisibleSelection::setBaseAndExtentToDeepEquivalents):
+ (WebCore::VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity):
+ (WebCore::VisibleSelection::updateSelectionType):
+ (WebCore::VisibleSelection::validate):
+ (WebCore::VisibleSelection::setWithoutValidation):
+ (WebCore::VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries):
+ (WebCore::VisibleSelection::isContentEditable):
+ (WebCore::VisibleSelection::isContentRichlyEditable):
+ (WebCore::VisibleSelection::rootEditableElement):
+ (WebCore::VisibleSelection::shadowTreeRootNode):
+ (WebCore::VisibleSelection::debugPosition):
+ (WebCore::VisibleSelection::formatForDebugger):
+ (WebCore::VisibleSelection::showTreeForThis):
+ (showTree):
+ * editing/VisibleSelection.h: Added.
+ (WebCore::VisibleSelection::):
+ (WebCore::VisibleSelection::selectionType):
+ (WebCore::VisibleSelection::setAffinity):
+ (WebCore::VisibleSelection::affinity):
+ (WebCore::VisibleSelection::base):
+ (WebCore::VisibleSelection::extent):
+ (WebCore::VisibleSelection::start):
+ (WebCore::VisibleSelection::end):
+ (WebCore::VisibleSelection::visibleStart):
+ (WebCore::VisibleSelection::visibleEnd):
+ (WebCore::VisibleSelection::isNone):
+ (WebCore::VisibleSelection::isCaret):
+ (WebCore::VisibleSelection::isRange):
+ (WebCore::VisibleSelection::isCaretOrRange):
+ (WebCore::VisibleSelection::isBaseFirst):
+ (WebCore::VisibleSelection::granularity):
+ (WebCore::operator==):
+ (WebCore::operator!=):
+ * editing/htmlediting.cpp:
+ (WebCore::selectionForParagraphIteration):
+ (WebCore::avoidIntersectionWithNode):
+ * editing/htmlediting.h:
+ * editing/markup.cpp:
+ (WebCore::createMarkup):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::selection):
+ * html/HTMLInputElement.h:
+ * html/HTMLTextAreaElement.cpp:
+ (WebCore::HTMLTextAreaElement::selection):
+ * html/HTMLTextAreaElement.h:
+ * page/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::selection):
+ (WebCore::AccessibilityObject::visiblePositionRangeForUnorderedPositions):
+ * page/AccessibilityObject.h:
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::selection):
+ (WebCore::AccessibilityRenderObject::setSelectedTextRange):
+ (WebCore::AccessibilityRenderObject::visiblePositionRangeForLine):
+ (WebCore::AccessibilityRenderObject::setSelectedVisiblePositionRange):
+ (WebCore::AccessibilityRenderObject::doAXRangeForLine):
+ * page/AccessibilityRenderObject.h:
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::anchorNode):
+ (WebCore::DOMSelection::anchorOffset):
+ (WebCore::DOMSelection::focusNode):
+ (WebCore::DOMSelection::focusOffset):
+ (WebCore::DOMSelection::collapseToEnd):
+ (WebCore::DOMSelection::collapseToStart):
+ (WebCore::DOMSelection::getRangeAt):
+ (WebCore::DOMSelection::addRange):
+ * page/DOMSelection.h:
+ * page/DragController.cpp:
+ (WebCore::DragController::tryDocumentDrag):
+ (WebCore::setSelectionToDragCaret):
+ (WebCore::DragController::concludeEditDrag):
+ (WebCore::prepareClipboardForImageDrag):
+ (WebCore::DragController::startDrag):
+ (WebCore::DragController::placeDragCaret):
+ * page/EditorClient.h:
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::selectClosestWordFromMouseEvent):
+ (WebCore::EventHandler::selectClosestWordOrLinkFromMouseEvent):
+ (WebCore::EventHandler::handleMousePressEventTripleClick):
+ (WebCore::EventHandler::handleMousePressEventSingleClick):
+ (WebCore::EventHandler::updateSelectionForMouseDrag):
+ (WebCore::EventHandler::handleMouseReleaseEvent):
+ * page/Frame.cpp:
+ (WebCore::Frame::mark):
+ (WebCore::Frame::setMark):
+ (WebCore::Frame::selectionLayoutChanged):
+ (WebCore::Frame::shouldChangeSelection):
+ (WebCore::Frame::shouldDeleteSelection):
+ (WebCore::Frame::revealSelection):
+ (WebCore::Frame::setSelectionFromNone):
+ (WebCore::Frame::findString):
+ (WebCore::Frame::respondToChangedSelection):
+ * page/Frame.h:
+ * page/Page.cpp:
+ (WebCore::Page::selection):
+ * page/Page.h:
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (-[AccessibilityObjectWrapper textMarkerRangeForSelection]):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::fillInlineSelectionGaps):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::setSelectionRange):
+ (WebCore::RenderTextControl::selection):
+ * rendering/RenderTextControl.h:
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::writeSelection):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::fillLineSelectionGap):
+ * svg/SVGTextContentElement.cpp:
+ (WebCore::SVGTextContentElement::selectSubString):
+
+2009-02-09 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23806
+ Fix a regression crash where an empty src value and a "text/html" type
+ on an EMBED element did not finish ResourceRequest initialization due to
+ an early return.
+
+ Test: fast/loader/empty-embed-src-attribute.html
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::addExtraFieldsToRequest):
+
+2009-02-09 Rob Buis <rwlbuis@gmail.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23816
+ Clean up RenderSVGRoot.cpp
+
+ Clean up RenderSVGRoot.cpp.
+
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::paint):
+ (WebCore::RenderSVGRoot::calcViewport):
+
+2009-02-09 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Antti Koivisto
+
+ https://bugs.webkit.org/show_bug.cgi?id=23737
+ Make it possible to control media element playback without knowing so many
+ internal implementation details.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::togglePlayState): New, toggle between playing and paused state.
+ (WebCore::HTMLMediaElement::beginScrubbing): New, pause as necessary for scrubbing mode.
+ (WebCore::HTMLMediaElement::endScrubbing): New, resume playback if paused for scrubbing mode.
+ * html/HTMLMediaElement.h:
+
+ (WebCore::HTMLMediaElement::hasVideo): New, added so clients don't need to access MediaPlayer directly.
+ * html/HTMLVideoElement.h:
+
+ (WebCore::HTMLVideoElement::hasVideo): New.
+
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaControlPlayButtonElement::defaultEventHandler): Use new media element
+ togglePlayState method.
+ (WebCore::MediaControlTimelineElement::defaultEventHandler): Tell media element when scrubbing
+ begins and ends so it can deal with pausing logic. Don't call setCurrentTime unless the time
+ will change.
+
+ * rendering/RenderMedia.cpp:
+ (WebCore::RenderMedia::updateControls): Ask media element if it is able to play instead of including
+ internal logic here.
+ (WebCore::RenderMedia::updateControlVisibility): Ditto.
+
+2009-02-09 Eric Carlson <eric.carlson@apple.com>
+
+ Reviewed by Antti Koivisto
+
+ Change RenderPart and RenderPartObject constructors to take a Node*
+ instead of a HTMLFrameOwnerElement* since that is all then need.
+
+ * rendering/RenderPart.cpp:
+ (WebCore::RenderPart::RenderPart): take Node* instead of HTMLFrameOwnerElement*
+ * rendering/RenderPart.h:
+ * rendering/RenderPartObject.cpp:
+ (WebCore::RenderPartObject::RenderPartObject): take Node* instead of HTMLFrameOwnerElement*
+ * rendering/RenderPartObject.h:
+
+2009-02-09 Dan Bernstein <mitz@apple.com>
+
+ - fix -Wmissing-prototypes builds
+
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::isHeaderElement): Marked this function static.
+ (WebCore::haveSameTagName): Ditto.
+ * editing/markup.cpp:
+ (WebCore::isSpecialAncestorBlock): Ditto.
+ * platform/graphics/transforms/TransformationMatrix.cpp:
+ (WebCore::makeMapBetweenRects): Removed unused function.
+ * platform/graphics/transforms/TransformationMatrix.h: Removed unused
+ declaration of private member makeMapBetweenRects().
+
+2009-02-09 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23850
+ Code cleanup of HTMLParser class which was using a mix of m_* and bare
+ class member variable names which helps to obfuscate the code. Also
+ changed a few of the static helper functions to take a const pointer type
+ as they should not be modifying the node.
+
+ * html/HTMLParser.cpp:
+ (WebCore::HTMLParser::HTMLParser):
+ (WebCore::HTMLParser::~HTMLParser):
+ (WebCore::HTMLParser::reset):
+ (WebCore::HTMLParser::setCurrent):
+ (WebCore::HTMLParser::parseToken):
+ (WebCore::HTMLParser::parseDoctypeToken):
+ (WebCore::isTableSection):
+ (WebCore::isTablePart):
+ (WebCore::isTableRelated):
+ (WebCore::HTMLParser::insertNode):
+ (WebCore::HTMLParser::handleError):
+ (WebCore::HTMLParser::textCreateErrorCheck):
+ (WebCore::HTMLParser::commentCreateErrorCheck):
+ (WebCore::HTMLParser::headCreateErrorCheck):
+ (WebCore::HTMLParser::bodyCreateErrorCheck):
+ (WebCore::HTMLParser::framesetCreateErrorCheck):
+ (WebCore::HTMLParser::formCreateErrorCheck):
+ (WebCore::HTMLParser::isindexCreateErrorCheck):
+ (WebCore::HTMLParser::noscriptCreateErrorCheck):
+ (WebCore::HTMLParser::pCloserStrictCreateErrorCheck):
+ (WebCore::HTMLParser::mapCreateErrorCheck):
+ (WebCore::HTMLParser::getNode):
+ (WebCore::HTMLParser::allowNestedRedundantTag):
+ (WebCore::HTMLParser::processCloseTag):
+ (WebCore::HTMLParser::isInline):
+ (WebCore::HTMLParser::handleResidualStyleCloseTagAcrossBlocks):
+ (WebCore::HTMLParser::reopenResidualStyleTags):
+ (WebCore::HTMLParser::pushBlock):
+ (WebCore::HTMLParser::popBlock):
+ (WebCore::HTMLParser::popOneBlockCommon):
+ (WebCore::HTMLParser::popOneBlock):
+ (WebCore::HTMLParser::moveOneBlockToStack):
+ (WebCore::HTMLParser::checkIfHasPElementInScope):
+ (WebCore::HTMLParser::popInlineBlocks):
+ (WebCore::HTMLParser::freeBlock):
+ (WebCore::HTMLParser::createHead):
+ (WebCore::HTMLParser::handleIsindex):
+ (WebCore::HTMLParser::startBody):
+ (WebCore::HTMLParser::finished):
+ (WebCore::HTMLParser::reportErrorToConsole):
+ * html/HTMLParser.h:
+
+2009-02-09 Alexey Proskuryakov <ap@webkit.org>
+
+ Applying review comment on a second location.
+
+ * rendering/RenderText.cpp: (WebCore::RenderText::nextOffset):
+ Use "ifdef BUILDING_ON_TIGER".
+
+2009-02-09 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23845
+ editing/deleting/backward-deletion.html fails on Tiger
+
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::previousOffset):
+ (WebCore::RenderText::nextOffset):
+ Work around a bug in older ICU versions by hardcoding narrow voiced marks.
+
+2009-02-09 Adam Roben <aroben@apple.com>
- Merge r40778.
+ Windows build fix
+
+ * WebCore.vcproj/WebCore.vcproj: Fix the XML syntax.
+
+2009-02-09 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Make WorkerMessagingProxy derive from two base proxy classes.
+ https://bugs.webkit.org/show_bug.cgi?id=23777
+
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::evaluate):
+ * dom/Worker.cpp:
+ (WebCore::Worker::terminate):
+ (WebCore::Worker::hasPendingActivity):
+ * dom/WorkerContext.cpp:
+ (WebCore::WorkerContext::reportException):
+ * dom/WorkerMessagingProxy.cpp:
+ (WebCore::WorkerThreadActivityReportTask::performTask):
+ (WebCore::WorkerMessagingProxy::postExceptionToWorkerObject):
+ (WebCore::WorkerMessagingProxy::workerObjectDestroyed):
+ (WebCore::WorkerMessagingProxy::terminateWorkerContext):
+ (WebCore::WorkerMessagingProxy::confirmWorkerThreadMessage):
+ (WebCore::WorkerMessagingProxy::reportPendingActivity):
+ (WebCore::WorkerMessagingProxy::reportPendingActivityInternal):
+ (WebCore::WorkerMessagingProxy::hasPendingActivity):
+ * dom/WorkerMessagingProxy.h:
- 2009-02-08 David Hyatt <hyatt@apple.com>
+2009-02-09 Jian Li <jianli@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Introduce 2 base classes to split WorkerMessagingProxy.
+ https://bugs.webkit.org/show_bug.cgi?id=23776
+
+ * GNUmakefile.am:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/WorkerContextProxy.h: Added.
+ (WebCore::WorkerContextProxy::~WorkerContextProxy):
+ * dom/WorkerObjectProxy.h: Added.
+ (WebCore::WorkerObjectProxy::~WorkerObjectProxy):
+
+2009-02-08 David Hyatt <hyatt@apple.com>
Fix for https://bugs.webkit.org/show_bug.cgi?id=23839
@@ -116,11 +14423,852 @@
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::handleRunInChild):
-2009-02-11 Mark Rowe <mrowe@apple.com>
+2009-02-08 David Hyatt <hyatt@apple.com>
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23832, crash when inspecting an image using the
+ Web inspector.
+
+ Reviewed by Mark Rowe
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::absoluteRectsForRange):
+ (WebCore::RenderObject::absoluteQuadsForRange):
+
+2009-02-08 Dirk Schulze <krit@webkit.org>
+
+ Unreviewed Qt build fix.
+
+ TransformationMatrix changes in r40761 broke QT build.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::getCTM):
+ (WebCore::GraphicsContext::scale):
+
+2009-02-08 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Holger Freyther.
+
+ This is a follow up of the last commit. It cleans up TransformationMatrix.h
+ and convert to a series of #elif.
+
+ * platform/graphics/transforms/TransformationMatrix.h:
+
+2009-02-08 Gustavo Noronha Silva <gns@gnome.org>
+
+ Reviewed by Simon Fraser.
+
+ [CAIRO] build broken by TransformationMatrix rework
+ https://bugs.webkit.org/show_bug.cgi?id=23831
+
+ Fixed cairo build after the TransformationMatrix rework done in
+ revision 40761.
+
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::getCTM):
+ (WebCore::GraphicsContext::concatCTM):
+ * platform/graphics/cairo/TransformationMatrixCairo.cpp:
+ (WebCore::TransformationMatrix::operator cairo_matrix_t):
+ * platform/graphics/transforms/TransformationMatrix.h:
+
+2009-02-07 David Hyatt <hyatt@apple.com>
+
+ Shrink the size of all InlineTextBoxes and all InlineBoxes (for images and replaced elements) by four bytes.
+ Change the overflow variable on InlineFlowBoxes into a short and move the bits for InlineFlowBoxes out of the
+ base InlineBox class. Since the number of bits in the base class was 35, shoving the 3 bits for InlineFlowBoxes
+ back down into that class (into the 16 bits exposed by making the overflow variable into a short), all text
+ boxes and image boxes shrink by 4 bytes.
+
+ Reviewed by Anders
+
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::InlineBox):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::placeBoxesHorizontally):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ (WebCore::InlineFlowBox::placeBoxesVertically):
+ * rendering/InlineFlowBox.h:
+ (WebCore::InlineFlowBox::InlineFlowBox):
+ (WebCore::InlineFlowBox::maxHorizontalVisualOverflow):
+ (WebCore::InlineFlowBox::hasTextChildren):
+
+2009-02-07 Dean Jackson <dino@apple.com>
+
+ Attempted build fix for Qt. Not reviewed.
- Merge r40729.
+ TransformationMatrix changes in r40761 broke non-Apple builds.
- 2009-02-06 Dan Bernstein <mitz@apple.com>
+ * platform/graphics/qt/TransformationMatrixQt.cpp:
+ (WebCore::TransformationMatrix::operator QMatrix):
+ * platform/graphics/transforms/TransformationMatrix.h:
+
+2009-02-07 David Hyatt <hyatt@apple.com>
+
+ This patch changes the base class of RenderInline from RenderBox to RenderBoxModelObject. This shift
+ in base class knocks 32 bytes off the size of every RenderInline. All of the necessary functions
+ for both RenderInline and RenderBox have either been pulled up into RenderBoxModelObject for sharing
+ or split into two functions (one in each derived class).
+
+ Reviewed by Anders and Antti
+
+ * dom/Element.cpp:
+ (WebCore::Element::offsetLeft):
+ (WebCore::Element::offsetTop):
+ (WebCore::Element::offsetWidth):
+ (WebCore::Element::offsetHeight):
+ (WebCore::Element::offsetParent):
+ (WebCore::Element::clientWidth):
+ (WebCore::Element::clientHeight):
+ (WebCore::Element::scrollWidth):
+ (WebCore::Element::scrollHeight):
+ * dom/Node.cpp:
+ (WebCore::Node::renderBox):
+ (WebCore::Node::renderBoxModelObject):
+ * dom/Node.h:
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::isKeyboardFocusable):
+ * rendering/InlineBox.h:
+ (WebCore::InlineBox::boxModelObject):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::marginLeft):
+ (WebCore::InlineFlowBox::marginRight):
+ (WebCore::InlineFlowBox::placeBoxesHorizontally):
+ (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+ (WebCore::InlineFlowBox::placeBoxesVertically):
+ (WebCore::InlineFlowBox::shrinkBoxesWithNoTextChildren):
+ * rendering/InlineFlowBox.h:
+ (WebCore::InlineFlowBox::borderLeft):
+ (WebCore::InlineFlowBox::borderRight):
+ (WebCore::InlineFlowBox::paddingLeft):
+ (WebCore::InlineFlowBox::paddingRight):
+ * rendering/RenderBlock.cpp:
+ (WebCore::getBorderPaddingMargin):
+ (WebCore::RenderBlock::calcInlinePrefWidths):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::imageChanged):
+ (WebCore::RenderBox::calcReplacedWidthUsing):
+ (WebCore::RenderBox::calcReplacedHeightUsing):
+ (WebCore::RenderBox::containingBlockWidthForPositioned):
+ (WebCore::RenderBox::containingBlockHeightForPositioned):
+ (WebCore::RenderBox::calcAbsoluteHorizontal):
+ (WebCore::RenderBox::calcAbsoluteHorizontalValues):
+ (WebCore::RenderBox::calcAbsoluteVertical):
+ (WebCore::RenderBox::calcAbsoluteVerticalValues):
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+ (WebCore::RenderBox::calcAbsoluteVerticalReplaced):
+ (WebCore::RenderBox::positionForCoordinates):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::borderBoundingBox):
+ (WebCore::RenderBox::offsetHeight):
+ (WebCore::RenderBox::marginTop):
+ (WebCore::RenderBox::marginBottom):
+ (WebCore::RenderBox::marginLeft):
+ (WebCore::RenderBox::marginRight):
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::offsetLeft):
+ (WebCore::RenderBoxModelObject::offsetTop):
+ (WebCore::RenderBoxModelObject::paddingTop):
+ (WebCore::RenderBoxModelObject::paddingBottom):
+ (WebCore::RenderBoxModelObject::paddingLeft):
+ (WebCore::RenderBoxModelObject::paddingRight):
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ (WebCore::RenderBoxModelObject::calculateBackgroundSize):
+ (WebCore::RenderBoxModelObject::calculateBackgroundImageGeometry):
+ * rendering/RenderBoxModelObject.h:
+ (WebCore::RenderBoxModelObject::borderTop):
+ (WebCore::RenderBoxModelObject::borderBottom):
+ (WebCore::RenderBoxModelObject::borderLeft):
+ (WebCore::RenderBoxModelObject::borderRight):
+ (WebCore::RenderBoxModelObject::hasHorizontalBordersPaddingOrMargin):
+ (WebCore::RenderBoxModelObject::hasHorizontalBordersOrPadding):
+ (WebCore::RenderBoxModelObject::childBecameNonInline):
+ (WebCore::RenderBoxModelObject::isBoxModelObject):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::RenderInline):
+ (WebCore::RenderInline::destroy):
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::nextContinuation):
+ (WebCore::RenderInline::continuationBefore):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::splitFlow):
+ (WebCore::RenderInline::addChildToContinuation):
+ (WebCore::RenderInline::absoluteRects):
+ (WebCore::RenderInline::offsetLeft):
+ (WebCore::RenderInline::offsetTop):
+ (WebCore::RenderInline::marginLeft):
+ (WebCore::RenderInline::marginRight):
+ (WebCore::RenderInline::positionForCoordinates):
+ (WebCore::RenderInline::clippedOverflowRectForRepaint):
+ (WebCore::RenderInline::rectWithOutlineForRepaint):
+ (WebCore::RenderInline::computeRectForRepaint):
+ (WebCore::RenderInline::updateDragState):
+ (WebCore::RenderInline::childBecameNonInline):
+ (WebCore::RenderInline::updateHitTestResult):
+ (WebCore::RenderInline::imageChanged):
+ (WebCore::RenderInline::addFocusRingRects):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::marginTop):
+ (WebCore::RenderInline::marginBottom):
+ (WebCore::RenderInline::continuation):
+ (WebCore::RenderInline::setContinuation):
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::paint):
+ (WebCore::RenderLineBoxList::hitTest):
+ * rendering/RenderLineBoxList.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::addLayers):
+ (WebCore::RenderObject::removeLayers):
+ (WebCore::RenderObject::moveLayers):
+ (WebCore::RenderObject::findNextLayer):
+ (WebCore::RenderObject::enclosingLayer):
+ (WebCore::RenderObject::enclosingCompositingLayer):
+ (WebCore::RenderObject::setLayerNeedsFullRepaint):
+ (WebCore::RenderObject::handleDynamicFloatPositionChange):
+ (WebCore::RenderObject::destroy):
+ (WebCore::RenderObject::offsetParent):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isInlineContinuation):
+ * rendering/RenderSVGTSpan.cpp:
+ (WebCore::RenderSVGTSpan::absoluteRects):
+ (WebCore::RenderSVGTSpan::absoluteQuads):
+ * rendering/RenderSVGTextPath.cpp:
+ (WebCore::RenderSVGTextPath::absoluteRects):
+ (WebCore::RenderSVGTextPath::absoluteQuads):
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::operator<<):
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::setBestTruncatedAt):
+ * rendering/RenderView.h:
+ * rendering/bidi.cpp:
+ (WebCore::getBorderPaddingMargin):
+ (WebCore::inlineWidth):
+ (WebCore::RenderBlock::layoutInlineChildren):
+ (WebCore::inlineFlowRequiresLineBox):
+ (WebCore::requiresLineBox):
+ (WebCore::RenderBlock::findNextLineBreak):
+ * wml/WMLAElement.cpp:
+ (WebCore::WMLAElement::isKeyboardFocusable):
+
+2009-02-07 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Timothy Hatcher <timothy@hatcher.name>
+
+ Partial fix for <https://bugs.webkit.org/show_bug.cgi?id=21051>
+ Include localStorage and sessionStorage in DatabasesPanel.
+
+ * WebCore.vcproj/WebCore.vcproj:
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorDOMStorageResource::create):
+ (WebCore::InspectorDOMStorageResource::setScriptObject):
+ (WebCore::InspectorDOMStorageResource::InspectorDOMStorageResource):
+ (WebCore::InspectorController::populateScriptObjects):
+ (WebCore::InspectorController::addDOMStorageScriptResource):
+ (WebCore::InspectorController::removeDOMStorageScriptResource):
+ (WebCore::InspectorController::resetScriptObjects):
+ (WebCore::InspectorController::didCommitLoad):
+ (WebCore::InspectorController::didUseDOMStorage):
+ * inspector/InspectorController.h:
+ * inspector/front-end/DOMStorage.js: Added.
+ (WebInspector.DOMStorage):
+ (WebInspector.DOMStorage.prototype.get domStorage):
+ (WebInspector.DOMStorage.prototype.set domStorage):
+ (WebInspector.DOMStorage.prototype.get domain):
+ (WebInspector.DOMStorage.prototype.set domain):
+ (WebInspector.DOMStorage.prototype.get isLocalStorage):
+ (WebInspector.DOMStorage.prototype.set isLocalStorage):
+ * inspector/front-end/DOMStorageItemsView.js: Added.
+ (WebInspector.DOMStorageItemsView):
+ (WebInspector.DOMStorageItemsView.prototype.show):
+ (WebInspector.DOMStorageItemsView.prototype.update):
+ * inspector/front-end/DatabaseQueryView.js:
+ (WebInspector.DatabaseQueryView):
+ * inspector/front-end/DatabaseTableView.js:
+ (WebInspector.DatabaseTableView):
+ (WebInspector.DatabaseTableView.prototype._queryFinished):
+ (WebInspector.DatabaseTableView.prototype._queryError):
+ * inspector/front-end/DatabasesPanel.js:
+ (WebInspector.DatabasesPanel):
+ (WebInspector.DatabasesPanel.prototype.reset):
+ (WebInspector.DatabasesPanel.prototype.addDatabase):
+ (WebInspector.DatabasesPanel.prototype.addDOMStorage):
+ (WebInspector.DatabasesPanel.prototype.showDatabase):
+ (WebInspector.DatabasesPanel.prototype.showDOMStorage):
+ (WebInspector.DatabasesPanel.prototype.closeVisibleView):
+ (WebInspector.DatabasesPanel.prototype.updateDatabaseTables):
+ (WebInspector.DatabasesPanel.prototype.dataGridForDOMStorage):
+ (WebInspector.DatabasesPanel.prototype._updateSidebarWidth):
+ (WebInspector.DOMStorageSidebarTreeElement):
+ (WebInspector.DOMStorageSidebarTreeElement.prototype.onselect):
+ (WebInspector.DOMStorageSidebarTreeElement.prototype.get mainTitle):
+ (WebInspector.DOMStorageSidebarTreeElement.prototype.set mainTitle):
+ (WebInspector.DOMStorageSidebarTreeElement.prototype.get subtitle):
+ (WebInspector.DOMStorageSidebarTreeElement.prototype.set subtitle):
+ * inspector/front-end/Images/domStorage.png: Added.
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/inspector.css:
+ * inspector/front-end/inspector.html:
+ * inspector/front-end/inspector.js:
+ (WebInspector.addDOMStorage):
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::sessionStorage):
+ (WebCore::DOMWindow::localStorage):
+
+2009-02-07 Feng Qian <feng@chromium.org>
+
+ Reviewed by Eric Seidel <eric@webkit.org>
+
+ Put #if ENABLE(PAN_SCROLLING) around EventHandler::setPanScrollCursor.
+ https://bugs.webkit.org/show_bug.cgi?id=23574
+
+ * page/EventHandler.cpp:
+ * page/EventHandler.h:
+
+2009-02-07 Zalan Bujtas <zbujtas@gmail.com>
+
+ Reviewed by Rob Buis <rwlbuis@gmail.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=23788
+ call style()->isOriginalDisplayInlineType() on RenderBox instead of RenderObject.
+
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::skipLeadingWhitespace):
+
+2009-02-07 Rob Buis <rwlbuis@gmail.com>
+
+ Reviewed by Darin.
+
+ https://bugs.webkit.org/show_bug.cgi?id=3248
+ Bug 3248: Mouse events on OPTION element seem to be ignored
+
+ Support mouse events on options in a select when it forms a list box.
+
+ Test: fast/forms/option-mouseevents.html
+
+ * html/HTMLSelectElement.cpp: Convert to coords relative to the list box.
+ (WebCore::HTMLSelectElement::listBoxDefaultEventHandler):
+ * rendering/RenderListBox.cpp: Handle hit testing for option elements.
+ (WebCore::RenderListBox::nodeAtPoint):
+ * rendering/RenderListBox.h:
+
+2009-02-07 Adam Treat <adam.treat@torchmobile.com>
+
+ Prospective build fix for all non-Apple platforms.
+
+ * platform/graphics/transforms/TransformationMatrix.h:
+
+2009-02-06 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Simon Fraser.
+
+ https://bugs.webkit.org/show_bug.cgi?id=6868
+
+ I have not only made TransformationMatrix platform independent
+ but I've also added 3D methods, which will be used when I update
+ WebKitCSSMatrix to include 3D (see https://bugs.webkit.org/show_bug.cgi?id=23689).
+ I am now keeping a full 4x4 matrix in TransformationMatrix. I'm also doing all
+ the math as doubles rather than floats. This makes a TransformationMatrix
+ go from 24 bytes to 128 bytes, but I don't think this class is used enough to
+ make this overhead will be significant.
+
+ The change from floats to doubles has caused some differences in rounding and
+ display (sometimes things that displayed as -0.0 now display as 0.0 or vice versa),
+ so I've had to change some LayoutTest results in the SVG tests.
+
+ * platform/graphics/FloatPoint.cpp:
+ (WebCore::FloatPoint::matrixTransform):
+ * platform/graphics/cg/GraphicsContextCG.cpp:
+ (WebCore::GraphicsContext::getCTM):
+ * platform/graphics/cg/TransformationMatrixCG.cpp:
+ (WebCore::TransformationMatrix::operator CGAffineTransform):
+ * platform/graphics/transforms/TransformationMatrix.cpp:
+ (WebCore::determinant2x2):
+ (WebCore::determinant3x3):
+ (WebCore::determinant4x4):
+ (WebCore::adjoint):
+ (WebCore::inverse):
+ (WebCore::transposeMatrix4):
+ (WebCore::v4MulPointByMatrix):
+ (WebCore::v3Length):
+ (WebCore::v3Scale):
+ (WebCore::v3Dot):
+ (WebCore::v3Combine):
+ (WebCore::v3Cross):
+ (WebCore::decompose):
+ (WebCore::slerp):
+ (WebCore::TransformationMatrix::scale):
+ (WebCore::TransformationMatrix::rotateFromVector):
+ (WebCore::TransformationMatrix::flipX):
+ (WebCore::TransformationMatrix::flipY):
+ (WebCore::makeMapBetweenRects):
+ (WebCore::TransformationMatrix::projectPoint):
+ (WebCore::TransformationMatrix::mapPoint):
+ (WebCore::TransformationMatrix::mapRect):
+ (WebCore::TransformationMatrix::mapQuad):
+ (WebCore::TransformationMatrix::scale3d):
+ (WebCore::TransformationMatrix::rotate3d):
+ (WebCore::TransformationMatrix::translate):
+ (WebCore::TransformationMatrix::translate3d):
+ (WebCore::TransformationMatrix::skew):
+ (WebCore::TransformationMatrix::applyPerspective):
+ (WebCore::TransformationMatrix::multLeft):
+ (WebCore::TransformationMatrix::multVecMatrix):
+ (WebCore::TransformationMatrix::isInvertible):
+ (WebCore::TransformationMatrix::inverse):
+ (WebCore::blendFloat):
+ (WebCore::TransformationMatrix::blend):
+ (WebCore::TransformationMatrix::decompose):
+ (WebCore::TransformationMatrix::recompose):
+ * platform/graphics/transforms/TransformationMatrix.h:
+ (WebCore::TransformationMatrix::TransformationMatrix):
+ (WebCore::TransformationMatrix::setMatrix):
+ (WebCore::TransformationMatrix::operator =):
+ (WebCore::TransformationMatrix::makeIdentity):
+ (WebCore::TransformationMatrix::isIdentity):
+ (WebCore::TransformationMatrix::map):
+ (WebCore::TransformationMatrix::m11):
+ (WebCore::TransformationMatrix::setM11):
+ (WebCore::TransformationMatrix::m12):
+ (WebCore::TransformationMatrix::setM12):
+ (WebCore::TransformationMatrix::m13):
+ (WebCore::TransformationMatrix::setM13):
+ (WebCore::TransformationMatrix::m14):
+ (WebCore::TransformationMatrix::setM14):
+ (WebCore::TransformationMatrix::m21):
+ (WebCore::TransformationMatrix::setM21):
+ (WebCore::TransformationMatrix::m22):
+ (WebCore::TransformationMatrix::setM22):
+ (WebCore::TransformationMatrix::m23):
+ (WebCore::TransformationMatrix::setM23):
+ (WebCore::TransformationMatrix::m24):
+ (WebCore::TransformationMatrix::setM24):
+ (WebCore::TransformationMatrix::m31):
+ (WebCore::TransformationMatrix::setM31):
+ (WebCore::TransformationMatrix::m32):
+ (WebCore::TransformationMatrix::setM32):
+ (WebCore::TransformationMatrix::m33):
+ (WebCore::TransformationMatrix::setM33):
+ (WebCore::TransformationMatrix::m34):
+ (WebCore::TransformationMatrix::setM34):
+ (WebCore::TransformationMatrix::m41):
+ (WebCore::TransformationMatrix::setM41):
+ (WebCore::TransformationMatrix::m42):
+ (WebCore::TransformationMatrix::setM42):
+ (WebCore::TransformationMatrix::m43):
+ (WebCore::TransformationMatrix::setM43):
+ (WebCore::TransformationMatrix::m44):
+ (WebCore::TransformationMatrix::setM44):
+ (WebCore::TransformationMatrix::a):
+ (WebCore::TransformationMatrix::setA):
+ (WebCore::TransformationMatrix::b):
+ (WebCore::TransformationMatrix::setB):
+ (WebCore::TransformationMatrix::c):
+ (WebCore::TransformationMatrix::setC):
+ (WebCore::TransformationMatrix::d):
+ (WebCore::TransformationMatrix::setD):
+ (WebCore::TransformationMatrix::e):
+ (WebCore::TransformationMatrix::setE):
+ (WebCore::TransformationMatrix::f):
+ (WebCore::TransformationMatrix::setF):
+ (WebCore::TransformationMatrix::multiply):
+ (WebCore::TransformationMatrix::rotate):
+ (WebCore::TransformationMatrix::skewX):
+ (WebCore::TransformationMatrix::skewY):
+ (WebCore::TransformationMatrix::hasPerspective):
+ (WebCore::TransformationMatrix::):
+ (WebCore::TransformationMatrix::isAffine):
+ (WebCore::TransformationMatrix::operator==):
+ (WebCore::TransformationMatrix::operator*=):
+ (WebCore::TransformationMatrix::operator*):
+ * rendering/RenderForeignObject.cpp:
+ (WebCore::RenderForeignObject::nodeAtPoint):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateTransform):
+ * rendering/RenderPath.cpp:
+ (WebCore::RenderPath::mapAbsolutePointToLocal):
+ * rendering/RenderSVGImage.cpp:
+ (WebCore::RenderSVGImage::nodeAtPoint):
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::nodeAtPoint):
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::nodeAtPoint):
+ * rendering/RenderSVGViewportContainer.cpp:
+ (WebCore::RenderSVGViewportContainer::nodeAtPoint):
+ * svg/SVGAnimateMotionElement.cpp:
+ (WebCore::SVGAnimateMotionElement::resetToBaseValue):
+ (WebCore::SVGAnimateMotionElement::calculateAnimatedValue):
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::viewport):
+ * svg/SVGTransform.cpp:
+ (SVGTransform::setTranslate):
+ (SVGTransform::setScale):
+ (SVGTransform::setRotate):
+ (SVGTransform::setSkewX):
+ (SVGTransform::setSkewY):
+ * svg/graphics/SVGResourceMarker.cpp:
+ (WebCore::SVGResourceMarker::draw):
+
+2009-02-07 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ For the Qt port implement Image::drawPattern via
+ BitmapImage::drawPatterns' implementation and implement
+ Gradient::fill.
+
+ This partially fixes rendering of generated gradient content.
+
+ * platform/graphics/BitmapImage.h: Remove the drawPattern
+ implementation for the Qt port in BitmapImage, it's been moved to
+ Image::drawPattern.
+ * platform/graphics/qt/GradientQt.cpp:
+ (WebCore::Gradient::fill): Implement using a simple fillRect.
+ * platform/graphics/qt/ImageQt.cpp:
+ (WebCore::Image::drawPattern): Moved implementation from
+ BitmapImage::drawPattern.
+
+2009-02-06 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Justin Garcia.
+
+ DOMSelection.getRangeAt() returns a different range than the selection
+ https://bugs.webkit.org/show_bug.cgi?id=23601
+
+ Rename toRange to toNormalizedRange and add new firstRange which returns an unmodified range
+
+ Test: fast/dom/Selection/getRangeAt.html
+
+ * WebCore.base.exp:
+ * dom/InputElement.cpp:
+ (WebCore::InputElement::handleBeforeTextInsertedEvent):
+ * editing/DeleteButtonController.cpp:
+ (WebCore::enclosingDeletableElement):
+ * editing/Editor.cpp:
+ (WebCore::Editor::selectedRange):
+ (WebCore::Editor::fontForSelection):
+ (WebCore::Editor::applyStyleToSelection):
+ (WebCore::Editor::applyParagraphStyleToSelection):
+ (WebCore::Editor::insertTextWithoutSendingTextEvent):
+ (WebCore::Editor::insertLineBreak):
+ (WebCore::Editor::insertParagraphSeparator):
+ (WebCore::Editor::ignoreSpelling):
+ (WebCore::Editor::isSelectionUngrammatical):
+ (WebCore::Editor::guessesForUngrammaticalSelection):
+ (WebCore::markMisspellingsOrBadGrammar):
+ (WebCore::Editor::rangeForPoint):
+ * editing/EditorCommand.cpp:
+ (WebCore::expandSelectionToGranularity):
+ (WebCore::executeDeleteToMark):
+ (WebCore::executeSelectToMark):
+ * editing/RemoveFormatCommand.cpp:
+ (WebCore::RemoveFormatCommand::doApply):
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplacementFragment::ReplacementFragment):
+ * editing/Selection.cpp:
+ (WebCore::Selection::firstRange):
+ (WebCore::Selection::toNormalizedRange):
+ * editing/Selection.h:
+ * editing/SelectionController.h:
+ (WebCore::SelectionController::toNormalizedRange):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::deleteKeyPressed):
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ * editing/markup.cpp:
+ (WebCore::createMarkup):
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ (WebCore::LegacyWebArchive::createFromSelection):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::ariaSelectedTextDOMRange):
+ * page/ContextMenuController.cpp:
+ (WebCore::ContextMenuController::contextMenuItemSelected):
+ * page/DOMSelection.cpp:
+ (WebCore::DOMSelection::getRangeAt):
+ (WebCore::DOMSelection::addRange):
+ (WebCore::DOMSelection::deleteFromDocument):
+ (WebCore::DOMSelection::containsNode):
+ (WebCore::DOMSelection::toString):
+ * page/DragController.cpp:
+ (WebCore::setSelectionToDragCaret):
+ (WebCore::DragController::concludeEditDrag):
+ (WebCore::DragController::startDrag):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::dispatchMouseEvent):
+ * page/Frame.cpp:
+ (WebCore::Frame::selectedText):
+ (WebCore::Frame::shouldChangeSelection):
+ (WebCore::Frame::shouldDeleteSelection):
+ (WebCore::Frame::selectionComputedStyle):
+ (WebCore::Frame::selectionTextRects):
+ (WebCore::Frame::findString):
+ (WebCore::Frame::respondToChangedSelection):
+ * platform/ContextMenu.cpp:
+ (WebCore::selectionContainsPossibleWord):
+
+2009-02-06 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Dan Bernstein
+
+ <rdar://problem/6563402> - Workaround a case where ::didReceiveData() might be called on a ResourceHandleClient
+ before ::didReceiveResponse().
+
+ No layout test, as we don't have a concrete way to reproduce these conditions. To that effect, I've added an ASSERT
+ to catch the conditions before the workaround takes effect in case any WebKit Debug-build developer runs across
+ this case and can come up with something more reproducible.
+
+ * loader/MainResourceLoader.cpp:
+ (WebCore::MainResourceLoader::didReceiveData): If the response is null create a dummy response. This is much
+ like the FrameLoader::init() response that is used for initial document creation.
+
+2009-02-06 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix.
+
+ * WebCore.base.exp:
+
+2009-02-06 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23621
+
+ Do not use m_scrollOffset to check if we are setting the same
+ value than we already have.
+
+ m_scrollOffset starts at 0 for ScrollView, so when opening a new
+ page and scrolling to 0 (the usual case) the check will fail and
+ we won't update the adjustment value, resulting in a possibly
+ mispositioned scrollbar. Use the adjustment value directly
+ instead, which is what we are updating anyway.
+
+ * platform/gtk/ScrollViewGtk.cpp:
+ (WebCore::ScrollView::platformHandleHorizontalAdjustment):
+ (WebCore::ScrollView::platformHandleVerticalAdjustment):
+
+2009-02-06 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23800
+ Header elements are not always preserved during paste
+
+ At paste time, don't merge out of header elements. At copy time, be sure to include
+ headers in the list of special common ancestor blocks, so that copying a paragraph or less
+ of content inside a header will include the header element in the copied markup.
+
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::areSameHeaderElements):
+ (WebCore::ReplaceSelectionCommand::shouldMerge):
+ * editing/markup.cpp:
+ (WebCore::isSpecialAncestorBlock):
+ (WebCore::createMarkup):
+
+2009-02-06 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Part III of <rdar://problem/6552272>.
+
+ Make redirect data available to WebKit. (I tried having WebKit track this
+ data for itself, but that went wrong -- it's just too hard to figure
+ out the weird corners of the WebCore loader from within another framework.)
+
+ * loader/DocumentLoader.cpp:
+ (WebCore::DocumentLoader::DocumentLoader):
+ * loader/DocumentLoader.h: Store a flag indicating whether we created
+ a global history entry. If we didn't, then we know that the next redirect
+ should not link to us, since we're not in history.
+
+ (WebCore::DocumentLoader::clientRedirectSourceForHistory):
+ (WebCore::DocumentLoader::clientRedirectDestinationForHistory):
+ (WebCore::DocumentLoader::setClientRedirectSourceForHistory):
+ (WebCore::DocumentLoader::serverRedirectSourceForHistory):
+ (WebCore::DocumentLoader::serverRedirectDestinationForHistory):
+ (WebCore::DocumentLoader::didCreateGlobalHistoryEntry):
+ (WebCore::DocumentLoader::setDidCreateGlobalHistoryEntry): Added accessors
+ to help WebKit wade through the muck of WebCore history.
+
+ * loader/EmptyClients.h:
+ (WebCore::EmptyFrameLoaderClient::updateGlobalHistoryRedirectLinks): Renamed
+ this client function to say what it does, instead of when it's called.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::load):
+ (WebCore::FrameLoader::loadWithNavigationAction): In the case of a redirect,
+ store a link to the previous history URL in the new DocumentLoader, so
+ it can update WebKit with that link when the load commits.
+
+ (WebCore::FrameLoader::updateHistory*): Use our new flags and names,
+ described above.
+
+ * loader/FrameLoader.h:
+ (WebCore::FrameLoader::documentLoader):
+ (WebCore::FrameLoader::policyDocumentLoader):
+ (WebCore::FrameLoader::provisionalDocumentLoader):
+ (WebCore::FrameLoader::state): Inlined a few trivial functions because
+ performance mistakes give me the itches.
+
+ * loader/FrameLoaderClient.h: Renamed this client function to say what
+ it does, instead of when it's called.
+
+2009-02-06 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Justin Garcia.
+
+ Minor refactoring and cleanup to Selection code
+ https://bugs.webkit.org/show_bug.cgi?id=23774
+
+ No functional changes, thus no tests.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::applyStyle):
+ (WebCore::Editor::applyParagraphStyle):
+ * editing/Selection.cpp:
+ (WebCore::Selection::Selection):
+ (WebCore::Selection::setBaseAndExtentToDeepEquivalents):
+ (WebCore::Selection::setStartAndEndFromBaseAndExtentRespectingGranularity):
+ (WebCore::Selection::updateSelectionType):
+ (WebCore::Selection::validate):
+ (WebCore::Selection::setWithoutValidation):
+ (WebCore::Selection::adjustSelectionToAvoidCrossingEditingBoundaries):
+ * editing/Selection.h:
+ (WebCore::Selection::):
+ (WebCore::Selection::selectionType):
+ (WebCore::Selection::extent):
+ (WebCore::Selection::isNone):
+ (WebCore::Selection::isCaret):
+ (WebCore::Selection::isRange):
+ (WebCore::Selection::isCaretOrRange):
+ * editing/SelectionController.h:
+ (WebCore::SelectionController::selectionType):
+ * editing/TypingCommand.cpp:
+ (WebCore::TypingCommand::deleteKeyPressed):
+ (WebCore::TypingCommand::forwardDeleteKeyPressed):
+ * page/Frame.cpp:
+ (WebCore::Frame::revealSelection):
+
+2009-02-06 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23801
+ Add custom V8 bindings for SVG.
+
+ * bindings/v8/custom/V8SVGElementInstanceCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8SVGLengthCustom.cpp: Added.
+ (WebCore::ACCESSOR_GETTER):
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8SVGMatrixCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+
+2009-02-06 David Levin <levin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Bug 23792: unused param is used in RenderLayer.cpp but not #include'd
+ <https://bugs.webkit.org/show_bug.cgi?id=23792>
+
+ Add include file for UnusedParam which is used in this file.
+
+ * rendering/RenderLayer.cpp:
+
+2009-02-06 David Levin <levin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ <https://bugs.webkit.org/show_bug.cgi?id=23741>
+
+ Bug 23798: KURLGoogle needs support for protocolInHTTPFamily
+ <https://bugs.webkit.org/show_bug.cgi?id=23798>
+
+ Add protocolInHTTPFamily() to the KURLGoogle implementation.
+ This is another chromium build fix to mirror r40553.
+
+ While in this file, I did some style fixes and consistency fixes:
+ + fixed many_occurences_of_underscoring_naming
+ + usages of NULL
+ + comparisons to 0
+ + changed the copyright remove an extraneous , and capitalize the (C)
+ which was suggested for other files that I've submitted.
+
+ No observable change in behavior, so no test.
+
+ * platform/KURL.h:
+ (WebCore::KURL::protocolInHTTPFamily):
+ * platform/KURLGoogle.cpp:
+ (WebCore::KURLCharsetConverter::ConvertFromUTF16):
+ (WebCore::lowerCaseEqualsASCII):
+ (WebCore::KURLGooglePrivate::KURLGooglePrivate):
+ (WebCore::KURLGooglePrivate::setUtf8):
+ (WebCore::KURLGooglePrivate::setAscii):
+ (WebCore::KURLGooglePrivate::init):
+ (WebCore::KURLGooglePrivate::initProtocolInHTTPFamily):
+ (WebCore::KURLGooglePrivate::copyTo):
+ (WebCore::KURLGooglePrivate::replaceComponents):
+ (WebCore::KURL::KURL):
+ (WebCore::KURL::createCFURL):
+ (WebCore::KURL::isEmpty):
+ (WebCore::KURL::protocolInHTTPFamily):
+ (WebCore::KURL::query):
+ (WebCore::decodeURLEscapeSequences):
+ (WebCore::KURL::protocolIs):
+ (WebCore::encodeWithURLEscapeSequences):
+ (WebCore::KURL::invalidate):
+ (WebCore::equalIgnoringRef):
+ * platform/KURLGooglePrivate.h:
+
+2009-02-06 David Kilzer <ddkilzer@apple.com>
+
+ Bug 23741: StyleRareNonInheritedData::operator==() should not compare ContentData objects by pointer
+
+ Reviewed by Darin Adler.
+
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::contentDataEquivalent): Moved method to
+ WebCore::StyleRareNonInheritedData class.
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::contentDataEquivalent): Replaced declaration
+ with inline method that calls contentDataEquivalent() on
+ WebCore::StyleRareNonInheritedData instead.
+ * rendering/style/StyleRareNonInheritedData.cpp:
+ (WebCore::StyleRareNonInheritedData::operator==): This is the bug fix!
+ Replaced pointer comparison of ContentData objects with call to
+ StyleRareNonInheritedData::contentDataEquivalent().
+ (WebCore::StyleRareNonInheritedData::contentDataEquivalent): Added.
+ * rendering/style/StyleRareNonInheritedData.h:
+ (WebCore::StyleRareNonInheritedData::contentDataEquivalent): Added
+ declaration.
+
+2009-02-06 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Factor code that checks whether the object is rooted in
+ repaint() and repaintRectangle() into a common isRooted()
+ method.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::repaint):
+ (WebCore::RenderObject::repaintRectangle):
+ (WebCore::RenderObject::isRooted):
+ * rendering/RenderObject.h:
+
+2009-02-06 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Expose an isRootLayer() method on RenderLayer that works whether the
+ layer is rooted or not, and use that in a few places in the
+ accelerated compositing code.
+
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::isRootLayer):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::paintingGoesToWindow):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
+ (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+
+2009-02-06 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler.
@@ -148,11 +15296,121 @@
* platform/graphics/wx/SimpleFontDataWx.cpp:
(WebCore::SimpleFontData::platformDestroy): Ditto.
-2009-02-06 Mark Rowe <mrowe@apple.com>
+2009-02-06 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Eric Seidel
+
+ Make RenderStyle::transitionForProperty() const.
+
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::transitionForProperty):
+ * rendering/style/RenderStyle.h:
+
+2009-02-06 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build when ACCELERATED_COMPOSITING is turned on.
- Merge r40712.
+ Remove font smoothing changes that will be committed
+ separately.
- 2009-02-05 Maciej Stachowiak <mjs@apple.com> and Brady Eidson <beidson@apple.com>
+ * platform/graphics/mac/WebLayer.mm:
+ (WebCore::if):
+
+2009-02-06 Anders Carlsson <andersca@apple.com>
+
+ Build fix.
+
+ * bridge/npapi.h:
+
+2009-02-06 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23790
+ Custom -> JSCCustom in SVGPointList.idl
+
+ * svg/SVGPointList.idl:
+
+2009-02-06 Anantanarayanan Iyengar <ananta@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23309
+ Fix whitespace indent errors. The rest of the original patch has already
+ landed.
+
+ * platform/graphics/cairo/ImageSourceCairo.cpp:
+ (WebCore::ImageSource::clear):
+ * platform/graphics/cg/ImageSourceCG.cpp:
+ (WebCore::ImageSource::clear):
+ * platform/graphics/qt/ImageSourceQt.cpp:
+ (WebCore::ImageSource::clear):
+ * platform/graphics/wx/ImageSourceWx.cpp:
+ (WebCore::ImageSource::clear):
+
+2009-02-06 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ Fix bug in clearRect(). Use fillRect() instead of eraseRect() to get
+ the context transparent.
+
+ [QT] clearRect fill's a given rect with white
+ https://bugs.webkit.org/show_bug.cgi?id=23728
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::clearRect):
+
+2009-02-06 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23781
+
+ When the document is attached and detached, and when it becomes active/inactive
+ (e.g. coming out or going into the page cache) we need to call
+ RenderView::didMoveOnscreen()/willMoveOffscreen() to hook and unhook the composited
+ layers.
+
+ Also, if Document::recalcStyle() does not do a layout, it needs to
+ update the compositing layers.
+
+ * dom/Document.cpp:
+ (WebCore::Document::updateRendering):
+ (WebCore::Document::updateLayout):
+ (WebCore::Document::attach):
+ (WebCore::Document::detach):
+ (WebCore::Document::documentWillBecomeInactive):
+ (WebCore::Document::documentDidBecomeActive):
+
+2009-02-06 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Added support for different ownership models for wrapped QObjects in
+ the JavaScript environment.
+
+ * bindings/js/ScriptControllerQt.cpp:
+ (WebCore::ScriptController::createScriptInstanceForWidget): Specify
+ QtOwnership for scriptable widgets.
+ * bridge/npruntime_internal.h: Add "NormalState" to the list of
+ undef'ed macros as an included Qt header uses "NormalState" as value
+ in an enum.
+ * bridge/qt/qt_instance.cpp:
+ (JSC::Bindings::QtInstance::QtInstance): Save and initialize ownership
+ member.
+ (JSC::Bindings::QtInstance::~QtInstance): Respect
+ QScriptEngine::ValueOwnership policy with regards to wrapped m_object.
+ (JSC::Bindings::QtInstance::getQtInstance): Pass the ownership down to
+ the instance.
+ * bridge/qt/qt_instance.h:
+ (JSC::Bindings::QtInstance::create): Ditto.
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::convertQVariantToValue): Use QtOwnership for
+ automatically wrapped QObjects.
+ (JSC::Bindings::QtConnectionObject::execute): Ditto.
+
+2009-02-05 Maciej Stachowiak <mjs@apple.com> and Brady Eidson <beidson@apple.com>
Reviewed by Dan Bernstein and Geoff Garen.
@@ -187,11 +15445,1678 @@
(WebCore::HistoryItem::weeklyVisitCounts): Ditto for weekly counts.
* WebCore.base.exp: Add new symbols and sort.
-2009-02-06 Mark Rowe <mrowe@apple.com>
+2009-02-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6438271> Improve backspace handling of accented characters
+
+ Test: platform/mac/editing/deleting/backward-delete.html
+
+ This change makes WebKit behave like AppKit on the Mac. Other platforms are not affected,
+ because the current behavior matches their standards (tested on Windows, assumed elsewhere).
+
+ * dom/Position.cpp:
+ (WebCore::Position::previous):
+ (WebCore::Position::next):
+ (WebCore::Position::uncheckedPreviousOffsetForBackwardDeletion):
+ * dom/Position.h:
+ Added a new option for previous(), used to move to a next position for backward deletion.
+ Renamed EUsingComposedCharacters to PositionMoveType.
+
+ * editing/TypingCommand.cpp: (WebCore::TypingCommand::deleteKeyPressed):
+ Use previous(BackwardDeletion) to find a proper range to delete. Also, simplified a check
+ surrounding this code a little.
+
+ * editing/htmlediting.cpp:
+ (WebCore::nextVisuallyDistinctCandidate):
+ (WebCore::previousVisuallyDistinctCandidate):
+ Adjusted for renamed enum values.
+
+ * rendering/RenderObject.cpp:
+ * rendering/RenderObject.h:
+ * rendering/RenderText.h:
+ Added previousOffsetForBackwardDeletion().
+
+ * rendering/RenderText.cpp: (WebCore::RenderText::previousOffsetForBackwardDeletion):
+ On PLATFORM(MAC), use an algorithm that matches the one AppKit has for backward deletion.
+
+2009-02-05 Adam Roben <aroben@apple.com>
+
+ Fix a crash in RenderWidget::destroy when navigating away from a page
+ with an <iframe>
+
+ This was a regression caused by r40679
+
+ Reviewed by Dave Hyatt.
+
+ Tested by many many tests.
+
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::destroy): Only deref the RenderWidget after we
+ finish accessing its members.
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Anders Carlsson
+
+ getAnimatedStyleForRenderer() should not create a new
+ CompositeAnimation if the object isn't already animating, and
+ it should just fall back to returning renderer->style().
+
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::getAnimatedStyleForRenderer):
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build when ACCELERATED_COMPOSITING is turned on.
+
+ Give RenderLayerBacking some love after the great
+ RenderBoxModelObject split.
+
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateLayerTransform):
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ (WebCore::RenderLayerBacking::contentsBox):
+ (WebCore::RenderLayerBacking::paintIntoLayer):
+ (WebCore::RenderLayerBacking::startAnimation):
+ (WebCore::RenderLayerBacking::startTransition):
+ * rendering/RenderLayerBacking.h:
+ (WebCore::RenderLayerBacking::renderer):
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build when ACCELERATED_COMPOSITING is turned on.
+
+ writeIndent() needs to be static to avoid warnings on some OSes,
+ and remove unused CAToTransform3D() method.
+
+ * platform/graphics/GraphicsLayer.cpp:
+ (WebCore::writeIndent):
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Anders Carlsson
+
+ Add some methods to the TransformOperation classes that are required
+ by GraphicsLayer when ACCELERATED_COMPOSITING is turned on.
+
+ * platform/graphics/transforms/MatrixTransformOperation.h:
+ (WebCore::MatrixTransformOperation::create):
+ (WebCore::MatrixTransformOperation::MatrixTransformOperation):
+ * platform/graphics/transforms/ScaleTransformOperation.h:
+ (WebCore::ScaleTransformOperation::x):
+ (WebCore::ScaleTransformOperation::y):
+ * platform/graphics/transforms/TranslateTransformOperation.h:
+ (WebCore::TranslateTransformOperation::x):
+ (WebCore::TranslateTransformOperation::y):
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Minor clenaup: fix brace style in CompositeAnimationPrivate::updateTransitions(),
+ and correct a usage of UNUSED_PARAM().
+
+ * page/animation/CompositeAnimation.cpp:
+ (WebCore::CompositeAnimationPrivate::updateTransitions):
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::startAnimation):
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Fix build when ACCELERATED_COMPOSITING is turned on.
+
+ animationOfPropertyIsAccelerated() needs to be public because
+ it is called from AnimationController.
+
+ * page/animation/AnimationBase.h:
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Anders Carlsson
+
+ Fix mis-typed enum value which is hidden inside #ifdefs so didn't break
+ the build.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateCompositingLayers):
+
+2009-02-05 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix missing checked toRenderBlock casts.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::clearFloats):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::availableHeightUsing):
+
+2009-02-05 Sam Weinig <sam@webkit.org>
+
+ Patch from Darin Adler.
+ Reviewed by Sam Weinig.
+
+ Fix case where we were casting to RenderView.
+
+ No test case possible.
+
+ * editing/mac/SelectionControllerMac.mm:
+ (WebCore::SelectionController::notifyAccessibilityForSelectionChange):
+
+2009-02-05 Aaron Boodman <aa@chromium.org>
+
+ Reviewed by Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23708
+ Adds documentElementAvailable() callback to FrameLoaderClient.
+
+ * dom/XMLTokenizerLibxml2.cpp:
+ (WebCore::XMLTokenizer::startElementNs):
+ Add call to dispatchDocumentElementAvailable()
+ * dom/XMLTokenizerQt.cpp:
+ (WebCore::XMLTokenizer::parseStartElement):
+ Ditto.
+ * html/HTMLParser.cpp:
+ (WebCore::HTMLParser::insertNode):
+ Ditto.
+ * loader/EmptyClients.h:
+ (WebCore::EmptyFrameLoaderClient::documentElementAvailable):
+ Stub out documentElementAvailable().
+ * loader/FrameLoader.cpp:
+ documentElementAvailable() callback plumbing.
+ * loader/FrameLoader.h:
+ Ditto.
+ * loader/FrameLoaderClient.h:
+ Add new documentElementAvailable() callback.
+
+2009-02-05 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23766
+ CanvasRenderingContext2D::setShadow needs else for other platforms.
+
+ Implements the CMYK variant of CanvasRenderingContext2D::setShadow for
+ other platforms using the CMYK color constructor.
+
+ * html/CanvasRenderingContext2D.cpp:
+ (WebCore::CanvasRenderingContext2D::setShadow):
+
+2009-02-05 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23687
+ Wires up Skia'a ImageBuffer::toDataURL to support pngs.
+ This helps Chromium pass a couple of layout tests.
+
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::toDataURL):
+ * platform/image-encoders: Added.
+ * platform/image-encoders/skia: Added.
+ * platform/image-encoders/skia/PNGImageEncoder.cpp: Added.
+ (WebCore::):
+ (WebCore::PngEncoderState::EncoderWriteCallback):
+ (WebCore::PngEncoderState::ConvertBGRAtoRGB):
+ (WebCore::PngEncoderState::PngWriteStructDestroyer::PngWriteStructDestroyer):
+ (WebCore::PngEncoderState::PngWriteStructDestroyer::~PngWriteStructDestroyer):
+ (WebCore::PNGImageEncoder::encode):
+ * platform/image-encoders/skia/PNGImageEncoder.h: Added.
+
+2009-02-05 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Fix missing checked cast.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::containingBlock):
+
+2009-02-05 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Not reviewed. Fix WML enabled builds.
+
+ FrameLoader::load() got an additional 'lockHistory' parameter, pass 'false'.
+
+ * wml/WMLGoElement.cpp:
+ (WebCore::WMLGoElement::executeTask):
+
+2009-02-05 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23625
+ Additional fix: Skia platform doesn't render text to a canvas or support clipping to an image buffer
+
+ Fixes three bugs in PlatformContextSkia:
+
+ * When a new layer was started clipped to an image we used the
+ assignment operator to copy the SkBitmap. If the SkBitmap owns it's
+ pixels, this is not the right thing to do. Instead we need to create
+ a copy of the image.
+ * State holds an SkBitmap by value. State's copy constructor does a
+ memcpy. This is confusing and subtle, I've converted to use a member
+ initializer list which I think is clearer and less error prone.
+ * When creating a new layer there is no need to copy the clip image.
+
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::State::State):
+ (PlatformContextSkia::save):
+ (PlatformContextSkia::beginLayerClippedToImage):
+
+2009-02-05 Scott Violet <sky@google.com>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23462
+ Changes call from setFillColor to setStrokeColor.
+
+ * html/CanvasStyle.cpp:
+ (WebCore::CanvasStyle::applyStrokeColor):
+
+2009-02-05 David Hyatt <hyatt@apple.com>
+
+ Fix crash on svg custom stop test. A virtual function didn't get patched properly.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::clippedOverflowRectForRepaint):
+ * rendering/RenderSVGGradientStop.h:
+ (WebCore::RenderSVGGradientStop::clippedOverflowRectForRepaint):
+
+2009-02-05 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23765
+
+ Add toRenderBoxModelObject() so that we can cast objects that
+ can have layers.
+
+ Fix getComputedStyle to return the current value of style
+ properties that are undergoing accelerated animations, by
+ asking the AnimationController if the property has accelerated
+ animations, and, if so, asking it to generate an appropriate
+ style.
+
+ Tightened up some type safety (CSSPropertyID), and code clarity
+ (replace bool with enum).
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::hasCompositedLayer):
+ (WebCore::computedTransform):
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::isAnimatingPropertyOnRenderer):
+ (WebCore::AnimationController::isAnimatingPropertyOnRenderer):
+ (WebCore::AnimationController::supportsAcceleratedAnimationOfProperty):
+ * page/animation/AnimationController.h:
+ * page/animation/AnimationControllerPrivate.h:
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::startAnimation):
+ (WebCore::ImplicitAnimation::endAnimation):
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::startAnimation):
+ (WebCore::KeyframeAnimation::endAnimation):
+ * rendering/RenderBoxModelObject.h:
+ (WebCore::RenderBoxModelObject::isBoxModelObject):
+ (WebCore::toRenderBoxModelObject):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateLayerTransform):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isBoxModelObject):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::applyTransform):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::):
+
+2009-02-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23767
+ Add custom V8 bindings for HTML5 database.
+
+ * bindings/v8/custom/V8CustomSQLStatementCallback.cpp: Added.
+ (WebCore::V8CustomSQLStatementCallback::V8CustomSQLStatementCallback):
+ (WebCore::V8CustomSQLStatementCallback::~V8CustomSQLStatementCallback):
+ (WebCore::V8CustomSQLStatementCallback::handleEvent):
+ * bindings/v8/custom/V8CustomSQLStatementCallback.h: Added.
+ (WebCore::V8CustomSQLStatementCallback::create):
+ * bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp: Added.
+ (WebCore::V8CustomSQLStatementErrorCallback::V8CustomSQLStatementErrorCallback):
+ (WebCore::V8CustomSQLStatementErrorCallback::~V8CustomSQLStatementErrorCallback):
+ (WebCore::V8CustomSQLStatementErrorCallback::handleEvent):
+ * bindings/v8/custom/V8CustomSQLStatementErrorCallback.h: Added.
+ (WebCore::V8CustomSQLStatementErrorCallback::create):
+ * bindings/v8/custom/V8CustomSQLTransactionCallback.cpp: Added.
+ (WebCore::V8CustomSQLTransactionCallback::V8CustomSQLTransactionCallback):
+ (WebCore::V8CustomSQLTransactionCallback::~V8CustomSQLTransactionCallback):
+ (WebCore::V8CustomSQLTransactionCallback::handleEvent):
+ * bindings/v8/custom/V8CustomSQLTransactionCallback.h: Added.
+ (WebCore::V8CustomSQLTransactionCallback::create):
+ * bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp: Added.
+ (WebCore::V8CustomSQLTransactionErrorCallback::V8CustomSQLTransactionErrorCallback):
+ (WebCore::V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback):
+ (WebCore::V8CustomSQLTransactionErrorCallback::handleEvent):
+ * bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h: Added.
+ (WebCore::V8CustomSQLTransactionErrorCallback::create):
+ * bindings/v8/custom/V8CustomVoidCallback.cpp: Added.
+ (WebCore::V8CustomVoidCallback::V8CustomVoidCallback):
+ (WebCore::V8CustomVoidCallback::~V8CustomVoidCallback):
+ (WebCore::V8CustomVoidCallback::handleEvent):
+ (WebCore::invokeCallback):
+ * bindings/v8/custom/V8CustomVoidCallback.h: Added.
+ (WebCore::V8CustomVoidCallback::create):
+ * bindings/v8/custom/V8DatabaseCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8SQLResultSetRowListCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+ * bindings/v8/custom/V8SQLTransactionCustom.cpp: Added.
+ (WebCore::CALLBACK_FUNC_DECL):
+
+2009-02-05 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23747
+ Add Chromium threading-related files.
+
+ * platform/chromium/TemporaryLinkStubs.cpp: Removed theading-related stubs.
+
+2009-02-05 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Add toRenderButton methods for casting RenderObjects to RenderButtons. The methods will assert if the object
+ is not a RenderButton. Also add a toRenderButton method that takes a RenderButton but returns void and that
+ is unimplemented. This method will catch anyone trying to do a cast when the object is already a RenderButton.
+
+ * rendering/RenderButton.h:
+ (WebCore::RenderButton::isRenderButton):
+ (WebCore::toRenderButton):
+ * rendering/RenderFileUploadControl.cpp:
+ (WebCore::RenderFileUploadControl::paintObject):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isRenderButton):
+
+2009-02-05 David Hyatt <hyatt@apple.com>
+
+ Move the m_layer member variable of RenderBox up into RenderBoxModelObject. Refactor styleDidChange'
+ of RenderObject, RenderBoxModelObject and RenderBox to get more of the code in the correct subclass.
+ In order to set the various RenderObject bits properly prior to the test for whether a layer is
+ required, I added an additional method, updateBoxModelInfoAfterStyleChange, that is responsible
+ for setting all of the bits.
+
+ Eliminate hasStaticX/Y, staticX/Y, and setStaticX/Y from the render tree. Move hasStaticX/Y to
+ RenderStyle, and just use the corresponding layer() methods for the
+ staticX/Y getters/setters.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::layoutBlock):
+ (WebCore::RenderBlock::adjustPositionedBlock):
+ (WebCore::RenderBlock::layoutOnlyPositionedObjects):
+ (WebCore::RenderBlock::layoutPositionedObjects):
+ (WebCore::RenderBlock::paintObject):
+ (WebCore::RenderBlock::nodeAtPoint):
+ (WebCore::RenderBlock::offsetForContents):
+ (WebCore::RenderBlock::calcPrefWidths):
+ (WebCore::RenderBlock::baselinePosition):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::RenderBox):
+ (WebCore::RenderBox::destroy):
+ (WebCore::RenderBox::styleWillChange):
+ (WebCore::RenderBox::styleDidChange):
+ (WebCore::RenderBox::updateBoxModelInfoFromStyle):
+ (WebCore::RenderBox::scrollWidth):
+ (WebCore::RenderBox::scrollHeight):
+ (WebCore::RenderBox::scrollLeft):
+ (WebCore::RenderBox::scrollTop):
+ (WebCore::RenderBox::setScrollLeft):
+ (WebCore::RenderBox::setScrollTop):
+ (WebCore::RenderBox::getOverflowClipRect):
+ (WebCore::RenderBox::localToAbsolute):
+ (WebCore::RenderBox::absoluteToLocal):
+ (WebCore::RenderBox::localToContainerQuad):
+ (WebCore::RenderBox::position):
+ (WebCore::RenderBox::computeRectForRepaint):
+ (WebCore::RenderBox::calcAbsoluteHorizontal):
+ (WebCore::RenderBox::calcAbsoluteVertical):
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+ (WebCore::RenderBox::calcAbsoluteVerticalReplaced):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::RenderBoxModelObject):
+ (WebCore::RenderBoxModelObject::destroy):
+ (WebCore::RenderBoxModelObject::styleWillChange):
+ (WebCore::RenderBoxModelObject::styleDidChange):
+ (WebCore::RenderBoxModelObject::updateBoxModelInfoFromStyle):
+ * rendering/RenderBoxModelObject.h:
+ (WebCore::RenderBoxModelObject::layer):
+ (WebCore::RenderBoxModelObject::requiresLayer):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutBlock):
+ (WebCore::RenderFlexibleBox::layoutHorizontalBox):
+ (WebCore::RenderFlexibleBox::layoutVerticalBox):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::updateBoxModelInfoFromStyle):
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::RenderInline::relativePositionedInlineOffset):
+ * rendering/RenderInline.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::setStaticY):
+ (WebCore::RenderLayer::updateLayerPosition):
+ * rendering/RenderLayer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::setStyle):
+ (WebCore::RenderObject::styleDidChange):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::markContainingBlocksForLayout):
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::paint):
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::destroy):
+ * rendering/bidi.cpp:
+ (WebCore::appendRunsForObject):
+ (WebCore::RenderBlock::layoutInlineChildren):
+ (WebCore::RenderBlock::skipTrailingWhitespace):
+ (WebCore::RenderBlock::skipLeadingWhitespace):
+ (WebCore::RenderBlock::findNextLineBreak):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::hasStaticX):
+ (WebCore::InheritedFlags::hasStaticY):
+
+2009-02-05 Sam Weinig <sam@webkit.org>
+
+ Fix the windows build.
+
+ * bindings/scripts/CodeGeneratorCOM.pm:
+ * dom/Node.idl:
+
+2009-02-05 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Kevin Decker.
+
+ Update to match Gecko.
+
+ * bridge/npapi.h:
+ * plugins/npfunctions.h:
+
+2009-02-05 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Finish merging EventTargetNode up into Node.
+
+ This also fixes a small recently introduced issue where EventListeners
+ would not be removed from the document if they were attached to comment
+ nodes outside of the documentElement.
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * bindings/js/JSEventTargetNodeCustom.cpp: Removed.
+ * bindings/js/JSNodeCustom.cpp:
+ (WebCore::JSNode::addEventListener):
+ (WebCore::JSNode::removeEventListener):
+ (WebCore::JSNode::pushEventHandlerScope):
+ * bindings/scripts/CodeGenerator.pm:
+ * dom/CharacterData.cpp:
+ (WebCore::CharacterData::CharacterData):
+ (WebCore::CharacterData::rendererIsNeeded):
+ * dom/CharacterData.h:
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::willRemove):
+ (WebCore::ContainerNode::attach):
+ (WebCore::ContainerNode::detach):
+ (WebCore::ContainerNode::insertedIntoDocument):
+ (WebCore::ContainerNode::removedFromDocument):
+ (WebCore::ContainerNode::setFocus):
+ (WebCore::ContainerNode::setActive):
+ (WebCore::ContainerNode::setHovered):
+ (WebCore::dispatchChildInsertionEvents):
+ (WebCore::dispatchChildRemovalEvents):
+ * dom/ContainerNode.h:
+ (WebCore::ContainerNode::ContainerNode):
+ * dom/Document.cpp:
+ (WebCore::Document::removeAllEventListenersFromAllNodes):
+ (WebCore::Document::removeAllDisconnectedNodeEventListeners):
+ (WebCore::Document::setFocusedNode):
+ * dom/EventTargetNode.cpp: Removed.
+ * dom/EventTargetNode.h: Removed.
+ * dom/Node.cpp:
+ (WebCore::Node::scriptExecutionContext):
+ (WebCore::Node::eventListeners):
+ (WebCore::Node::insertedIntoDocument):
+ (WebCore::Node::removedFromDocument):
+ (WebCore::Node::willMoveToNewOwnerDocument):
+ (WebCore::Node::didMoveToNewOwnerDocument):
+ (WebCore::updateSVGElementInstancesAfterEventListenerChange):
+ (WebCore::Node::addEventListener):
+ (WebCore::Node::removeEventListener):
+ (WebCore::Node::removeAllEventListenersSlowCase):
+ (WebCore::Node::handleLocalEvents):
+ (WebCore::eventTargetAsSVGElementInstance):
+ (WebCore::eventTargetRespectingSVGTargetRules):
+ (WebCore::Node::dispatchEvent):
+ (WebCore::Node::dispatchGenericEvent):
+ (WebCore::Node::dispatchSubtreeModifiedEvent):
+ (WebCore::Node::dispatchWindowEvent):
+ (WebCore::Node::dispatchUIEvent):
+ (WebCore::Node::dispatchKeyEvent):
+ (WebCore::Node::dispatchMouseEvent):
+ (WebCore::Node::dispatchSimulatedMouseEvent):
+ (WebCore::Node::dispatchSimulatedClick):
+ (WebCore::Node::dispatchWheelEvent):
+ (WebCore::Node::dispatchWebKitAnimationEvent):
+ (WebCore::Node::dispatchWebKitTransitionEvent):
+ (WebCore::Node::dispatchFocusEvent):
+ (WebCore::Node::dispatchBlurEvent):
+ (WebCore::Node::dispatchEventForType):
+ (WebCore::Node::dispatchProgressEvent):
+ (WebCore::Node::dispatchStorageEvent):
+ (WebCore::Node::removeInlineEventListenerForType):
+ (WebCore::Node::setInlineEventListenerForType):
+ (WebCore::Node::setInlineEventListenerForTypeAndAttribute):
+ (WebCore::Node::inlineEventListenerForType):
+ (WebCore::Node::disabled):
+ (WebCore::Node::defaultEventHandler):
+ (WebCore::Node::onabort):
+ (WebCore::Node::setOnabort):
+ (WebCore::Node::onblur):
+ (WebCore::Node::setOnblur):
+ (WebCore::Node::onchange):
+ (WebCore::Node::setOnchange):
+ (WebCore::Node::onclick):
+ (WebCore::Node::setOnclick):
+ (WebCore::Node::oncontextmenu):
+ (WebCore::Node::setOncontextmenu):
+ (WebCore::Node::ondblclick):
+ (WebCore::Node::setOndblclick):
+ (WebCore::Node::onerror):
+ (WebCore::Node::setOnerror):
+ (WebCore::Node::onfocus):
+ (WebCore::Node::setOnfocus):
+ (WebCore::Node::oninput):
+ (WebCore::Node::setOninput):
+ (WebCore::Node::onkeydown):
+ (WebCore::Node::setOnkeydown):
+ (WebCore::Node::onkeypress):
+ (WebCore::Node::setOnkeypress):
+ (WebCore::Node::onkeyup):
+ (WebCore::Node::setOnkeyup):
+ (WebCore::Node::onload):
+ (WebCore::Node::setOnload):
+ (WebCore::Node::onmousedown):
+ (WebCore::Node::setOnmousedown):
+ (WebCore::Node::onmousemove):
+ (WebCore::Node::setOnmousemove):
+ (WebCore::Node::onmouseout):
+ (WebCore::Node::setOnmouseout):
+ (WebCore::Node::onmouseover):
+ (WebCore::Node::setOnmouseover):
+ (WebCore::Node::onmouseup):
+ (WebCore::Node::setOnmouseup):
+ (WebCore::Node::onmousewheel):
+ (WebCore::Node::setOnmousewheel):
+ (WebCore::Node::onbeforecut):
+ (WebCore::Node::setOnbeforecut):
+ (WebCore::Node::oncut):
+ (WebCore::Node::setOncut):
+ (WebCore::Node::onbeforecopy):
+ (WebCore::Node::setOnbeforecopy):
+ (WebCore::Node::oncopy):
+ (WebCore::Node::setOncopy):
+ (WebCore::Node::onbeforepaste):
+ (WebCore::Node::setOnbeforepaste):
+ (WebCore::Node::onpaste):
+ (WebCore::Node::setOnpaste):
+ (WebCore::Node::ondragenter):
+ (WebCore::Node::setOndragenter):
+ (WebCore::Node::ondragover):
+ (WebCore::Node::setOndragover):
+ (WebCore::Node::ondragleave):
+ (WebCore::Node::setOndragleave):
+ (WebCore::Node::ondrop):
+ (WebCore::Node::setOndrop):
+ (WebCore::Node::ondragstart):
+ (WebCore::Node::setOndragstart):
+ (WebCore::Node::ondrag):
+ (WebCore::Node::setOndrag):
+ (WebCore::Node::ondragend):
+ (WebCore::Node::setOndragend):
+ (WebCore::Node::onreset):
+ (WebCore::Node::setOnreset):
+ (WebCore::Node::onresize):
+ (WebCore::Node::setOnresize):
+ (WebCore::Node::onscroll):
+ (WebCore::Node::setOnscroll):
+ (WebCore::Node::onsearch):
+ (WebCore::Node::setOnsearch):
+ (WebCore::Node::onselect):
+ (WebCore::Node::setOnselect):
+ (WebCore::Node::onselectstart):
+ (WebCore::Node::setOnselectstart):
+ (WebCore::Node::onsubmit):
+ (WebCore::Node::setOnsubmit):
+ (WebCore::Node::onunload):
+ (WebCore::Node::setOnunload):
+ * dom/Node.h:
+ * editing/Editor.cpp:
+ (WebCore::Editor::dispatchCPPEvent):
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::handleLocalEvents):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::defaultEventHandler):
+ * html/HTMLTokenizer.cpp:
+ (WebCore::HTMLTokenizer::notifyFinished):
+ * loader/MediaDocument.cpp:
+ (WebCore::MediaDocument::defaultEventHandler):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::mouseButtonListener):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::dispatchDragEvent):
+ (WebCore::EventHandler::updateMouseEventTargetNode):
+ (WebCore::EventHandler::dispatchMouseEvent):
+ (WebCore::EventHandler::handleWheelEvent):
+ (WebCore::EventHandler::canMouseDownStartSelect):
+ (WebCore::EventHandler::canMouseDragExtendSelect):
+ (WebCore::eventTargetNodeForDocument):
+ (WebCore::EventHandler::keyEvent):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::scheduleEvent):
+ (WebCore::FrameView::updateOverflowStatus):
+ * page/FrameView.h:
+ * page/Page.cpp:
+ (WebCore::networkStateChanged):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollToOffset):
+ (WebCore::RenderLayer::updateOverflowStatus):
+ * rendering/RenderListBox.cpp:
+ (WebCore::RenderListBox::valueChanged):
+ * rendering/RenderMedia.h:
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::selectionChanged):
+ * svg/SVGElementInstance.h:
+ (WebCore::SVGElementInstance::toNode):
+ * xml/XPathExpression.cpp:
+ (WebCore::XPathExpression::evaluate):
+ * xml/XPathResult.cpp:
+ (WebCore::XPathResult::XPathResult):
+
+2009-02-05 Adam Treat <adam.treat@torchmobile.com>
+
+ Fix the Qt build now that EventTargetNode.idl was removed in r40672.
+
+ * WebCore.pro:
+
+2009-02-05 Scott Violet <sky@google.com>
+
+ Reviewed by Sam Weinig.
+
+ Bug 23462: Add RGB -> CMYK conversion algorithm
+ <https://bugs.webkit.org/show_bug.cgi?id=23462>
+
+ Adds an RGB -> CMYK converter. This isn't perfect, but better than
+ nothing.
+
+ * html/CanvasStyle.cpp:
+ (WebCore::CanvasStyle::applyStrokeColor):
+ (WebCore::CanvasStyle::applyFillColor):
+ (WebCore::CanvasStyle::cmykToRGB):
+ * html/CanvasStyle.h:
+
+2009-02-04 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ First stage of merging EventTargetNode up into Node. The intent of this change
+ is to both simplify the inheritance hierarchy (at the same time making it more
+ closely match the spec which states that all Nodes are EventTargets) and save
+ 4 bytes per Node that the polymorphic multiple-inheritance was costing us.
+
+ This does the bare minimum to get things compiling, the next patch will clean
+
+ * DerivedSources.make:
+ * WebCore.base.exp:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSDocumentCustom.cpp:
+ (WebCore::JSDocument::mark):
+ * bindings/js/JSEventListener.cpp:
+ (WebCore::JSLazyEventListener::parseCode):
+ * bindings/js/JSEventTarget.cpp:
+ (WebCore::toEventTarget):
+ * bindings/js/JSEventTarget.h:
+ * bindings/js/JSEventTargetNodeCustom.cpp:
+ (WebCore::JSNode::addEventListener):
+ (WebCore::JSNode::removeEventListener):
+ (WebCore::JSNode::pushEventHandlerScope):
+ * bindings/js/JSStyleSheetCustom.cpp:
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * bindings/scripts/CodeGeneratorObjC.pm:
+ * dom/Attr.idl:
+ * dom/CharacterData.h:
+ * dom/CharacterData.idl:
+ * dom/Document.idl:
+ * dom/DocumentFragment.idl:
+ * dom/Element.idl:
+ * dom/EventTarget.cpp:
+ (WebCore::EventTarget::toNode):
+ * dom/EventTarget.h:
+ * dom/EventTarget.idl:
+ * dom/EventTargetNode.cpp:
+ (WebCore::Node::scriptExecutionContext):
+ (WebCore::Node::eventListeners):
+ (WebCore::Node::insertedIntoDocument):
+ (WebCore::Node::removedFromDocument):
+ (WebCore::Node::willMoveToNewOwnerDocument):
+ (WebCore::Node::didMoveToNewOwnerDocument):
+ (WebCore::Node::addEventListener):
+ (WebCore::Node::removeEventListener):
+ (WebCore::Node::removeAllEventListenersSlowCase):
+ (WebCore::Node::handleLocalEvents):
+ (WebCore::Node::dispatchEvent):
+ (WebCore::Node::dispatchGenericEvent):
+ (WebCore::Node::dispatchSubtreeModifiedEvent):
+ (WebCore::Node::dispatchWindowEvent):
+ (WebCore::Node::dispatchUIEvent):
+ (WebCore::Node::dispatchKeyEvent):
+ (WebCore::Node::dispatchMouseEvent):
+ (WebCore::Node::dispatchSimulatedMouseEvent):
+ (WebCore::Node::dispatchSimulatedClick):
+ (WebCore::Node::dispatchWheelEvent):
+ (WebCore::Node::dispatchWebKitAnimationEvent):
+ (WebCore::Node::dispatchWebKitTransitionEvent):
+ (WebCore::Node::dispatchFocusEvent):
+ (WebCore::Node::dispatchBlurEvent):
+ (WebCore::Node::dispatchEventForType):
+ (WebCore::Node::dispatchProgressEvent):
+ (WebCore::Node::dispatchStorageEvent):
+ (WebCore::Node::removeInlineEventListenerForType):
+ (WebCore::Node::setInlineEventListenerForType):
+ (WebCore::Node::setInlineEventListenerForTypeAndAttribute):
+ (WebCore::Node::inlineEventListenerForType):
+ (WebCore::Node::disabled):
+ (WebCore::Node::defaultEventHandler):
+ (WebCore::Node::onabort):
+ (WebCore::Node::setOnabort):
+ (WebCore::Node::onblur):
+ (WebCore::Node::setOnblur):
+ (WebCore::Node::onchange):
+ (WebCore::Node::setOnchange):
+ (WebCore::Node::onclick):
+ (WebCore::Node::setOnclick):
+ (WebCore::Node::oncontextmenu):
+ (WebCore::Node::setOncontextmenu):
+ (WebCore::Node::ondblclick):
+ (WebCore::Node::setOndblclick):
+ (WebCore::Node::onerror):
+ (WebCore::Node::setOnerror):
+ (WebCore::Node::onfocus):
+ (WebCore::Node::setOnfocus):
+ (WebCore::Node::oninput):
+ (WebCore::Node::setOninput):
+ (WebCore::Node::onkeydown):
+ (WebCore::Node::setOnkeydown):
+ (WebCore::Node::onkeypress):
+ (WebCore::Node::setOnkeypress):
+ (WebCore::Node::onkeyup):
+ (WebCore::Node::setOnkeyup):
+ (WebCore::Node::onload):
+ (WebCore::Node::setOnload):
+ (WebCore::Node::onmousedown):
+ (WebCore::Node::setOnmousedown):
+ (WebCore::Node::onmousemove):
+ (WebCore::Node::setOnmousemove):
+ (WebCore::Node::onmouseout):
+ (WebCore::Node::setOnmouseout):
+ (WebCore::Node::onmouseover):
+ (WebCore::Node::setOnmouseover):
+ (WebCore::Node::onmouseup):
+ (WebCore::Node::setOnmouseup):
+ (WebCore::Node::onmousewheel):
+ (WebCore::Node::setOnmousewheel):
+ (WebCore::Node::onbeforecut):
+ (WebCore::Node::setOnbeforecut):
+ (WebCore::Node::oncut):
+ (WebCore::Node::setOncut):
+ (WebCore::Node::onbeforecopy):
+ (WebCore::Node::setOnbeforecopy):
+ (WebCore::Node::oncopy):
+ (WebCore::Node::setOncopy):
+ (WebCore::Node::onbeforepaste):
+ (WebCore::Node::setOnbeforepaste):
+ (WebCore::Node::onpaste):
+ (WebCore::Node::setOnpaste):
+ (WebCore::Node::ondragenter):
+ (WebCore::Node::setOndragenter):
+ (WebCore::Node::ondragover):
+ (WebCore::Node::setOndragover):
+ (WebCore::Node::ondragleave):
+ (WebCore::Node::setOndragleave):
+ (WebCore::Node::ondrop):
+ (WebCore::Node::setOndrop):
+ (WebCore::Node::ondragstart):
+ (WebCore::Node::setOndragstart):
+ (WebCore::Node::ondrag):
+ (WebCore::Node::setOndrag):
+ (WebCore::Node::ondragend):
+ (WebCore::Node::setOndragend):
+ (WebCore::Node::onreset):
+ (WebCore::Node::setOnreset):
+ (WebCore::Node::onresize):
+ (WebCore::Node::setOnresize):
+ (WebCore::Node::onscroll):
+ (WebCore::Node::setOnscroll):
+ (WebCore::Node::onsearch):
+ (WebCore::Node::setOnsearch):
+ (WebCore::Node::onselect):
+ (WebCore::Node::setOnselect):
+ (WebCore::Node::onselectstart):
+ (WebCore::Node::setOnselectstart):
+ (WebCore::Node::onsubmit):
+ (WebCore::Node::setOnsubmit):
+ (WebCore::Node::onunload):
+ (WebCore::Node::setOnunload):
+ * dom/EventTargetNode.h:
+ (WebCore::toEventTargetNode):
+ (WebCore::EventTargetNodeCast):
+ * dom/EventTargetNode.idl: Removed.
+ * dom/MouseEvent.cpp:
+ (WebCore::MouseEvent::MouseEvent):
+ (WebCore::MouseEvent::initMouseEvent):
+ (WebCore::MouseEvent::toElement):
+ (WebCore::MouseEvent::fromElement):
+ * dom/MouseEvent.h:
+ (WebCore::MouseEvent::create):
+ (WebCore::MouseEvent::relatedTarget):
+ * dom/Node.cpp:
+ (WebCore::Node::~Node):
+ * dom/Node.h:
+ (WebCore::Node::isEventTargetNode):
+ (WebCore::Node::toNode):
+ (WebCore::Node::removeAllEventListeners):
+ (WebCore::Node::refEventTarget):
+ (WebCore::Node::derefEventTarget):
+ * dom/Node.idl:
+ * page/EventHandler.h:
+ * page/FrameView.h:
+ * xml/XPathResult.h:
+ (WebCore::XPathResult::create):
+
+2009-02-04 David Hyatt <hyatt@apple.com>
+
+ Convert RenderLayer from having a RenderBox* m_renderer to having a RenderBoxModelObject*. The
+ container-relative repaint methods all had to be changed as a result to use RenderBoxModelObject* also.
+
+ All of RenderLayer.cpp now uses what will be the new style for dealing with an object that can be a block
+ or an inline flow. x()/y()/width()/height() can't be queried on an inline flow, nor can many other
+ properties (like scrollWidth() / scrollHeight()), so the code has to be tightened up to convert to RenderBox
+ under the right conditions.
+
+ There was a bogus subtraction of renderer()->y() in localBounding box for RenderInlines. Since y was always
+ 0, this subtraction wasn't necessary. It has been removed.
+
+ Reviewed by Adam Roben
+
+ * page/animation/AnimationBase.cpp:
+ * rendering/RenderBR.h:
+ (WebCore::RenderBR::selectionRectForRepaint):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::selectionGapRectsForRepaint):
+ (WebCore::RenderBlock::rectWithOutlineForRepaint):
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::selectionRectForRepaint):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::outlineBoundsForRepaint):
+ (WebCore::RenderBox::localToContainerQuad):
+ (WebCore::RenderBox::clippedOverflowRectForRepaint):
+ (WebCore::RenderBox::computeRectForRepaint):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::relativePositionOffsetX):
+ (WebCore::RenderBoxModelObject::relativePositionOffsetY):
+ * rendering/RenderBoxModelObject.h:
+ (WebCore::RenderBoxModelObject::relativePositionOffset):
+ * rendering/RenderForeignObject.cpp:
+ (WebCore::RenderForeignObject::computeRectForRepaint):
+ * rendering/RenderForeignObject.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::clippedOverflowRectForRepaint):
+ (WebCore::RenderInline::rectWithOutlineForRepaint):
+ * rendering/RenderInline.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::updateLayerPositions):
+ (WebCore::RenderLayer::updateTransform):
+ (WebCore::RenderLayer::setHasVisibleContent):
+ (WebCore::RenderLayer::updateLayerPosition):
+ (WebCore::RenderLayer::scrollToOffset):
+ (WebCore::RenderLayer::scrollRectToVisible):
+ (WebCore::resizerCornerRect):
+ (WebCore::RenderLayer::scrollbarCornerPresent):
+ (WebCore::RenderLayer::invalidateScrollbarRect):
+ (WebCore::RenderLayer::positionOverflowControls):
+ (WebCore::RenderLayer::computeScrollDimensions):
+ (WebCore::RenderLayer::updateScrollInfoAfterLayout):
+ (WebCore::RenderLayer::paintScrollCorner):
+ (WebCore::RenderLayer::paintResizer):
+ (WebCore::RenderLayer::isPointInResizeControl):
+ (WebCore::RenderLayer::hitTestOverflowControls):
+ (WebCore::RenderLayer::paintLayer):
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::localBoundingBox):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::renderer):
+ (WebCore::RenderLayer::renderBox):
+ (WebCore::RenderLayer::renderBoxX):
+ (WebCore::RenderLayer::renderBoxY):
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::selectionRectForRepaint):
+ * rendering/RenderListMarker.h:
+ * rendering/RenderMarquee.cpp:
+ (WebCore::RenderMarquee::computePosition):
+ (WebCore::RenderMarquee::timerFired):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::containerForRepaint):
+ (WebCore::RenderObject::repaintUsingContainer):
+ (WebCore::RenderObject::repaint):
+ (WebCore::RenderObject::repaintRectangle):
+ (WebCore::RenderObject::repaintAfterLayoutIfNeeded):
+ (WebCore::RenderObject::rectWithOutlineForRepaint):
+ (WebCore::RenderObject::clippedOverflowRectForRepaint):
+ (WebCore::RenderObject::computeRectForRepaint):
+ (WebCore::RenderObject::localToContainerQuad):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::selectionRectForRepaint):
+ (WebCore::RenderObject::outlineBoundsForRepaint):
+ * rendering/RenderPath.cpp:
+ (WebCore::RenderPath::clippedOverflowRectForRepaint):
+ (WebCore::RenderPath::outlineBoundsForRepaint):
+ * rendering/RenderPath.h:
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::selectionRectForRepaint):
+ (WebCore::RenderReplaced::clippedOverflowRectForRepaint):
+ * rendering/RenderReplaced.h:
+ * rendering/RenderSVGContainer.cpp:
+ (WebCore::RenderSVGContainer::clippedOverflowRectForRepaint):
+ (WebCore::RenderSVGContainer::outlineBoundsForRepaint):
+ * rendering/RenderSVGContainer.h:
+ * rendering/RenderSVGHiddenContainer.cpp:
+ (WebCore::RenderSVGHiddenContainer::clippedOverflowRectForRepaint):
+ * rendering/RenderSVGHiddenContainer.h:
+ * rendering/RenderSVGImage.cpp:
+ (WebCore::RenderSVGImage::clippedOverflowRectForRepaint):
+ * rendering/RenderSVGImage.h:
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::selectionRectForRepaint):
+ (WebCore::RenderSVGInlineText::computeRepaintRectForRange):
+ * rendering/RenderSVGInlineText.h:
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::clippedOverflowRectForRepaint):
+ * rendering/RenderSVGRoot.h:
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::clippedOverflowRectForRepaint):
+ * rendering/RenderSVGText.h:
+ * rendering/RenderSelectionInfo.h:
+ (WebCore::RenderSelectionInfoBase::repaintContainer):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::clippedOverflowRectForRepaint):
+ (WebCore::RenderTableCell::computeRectForRepaint):
+ (WebCore::RenderTableCell::localToContainerQuad):
+ * rendering/RenderTableCell.h:
+ * rendering/RenderTableCol.cpp:
+ (WebCore::RenderTableCol::clippedOverflowRectForRepaint):
+ * rendering/RenderTableCol.h:
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::clippedOverflowRectForRepaint):
+ * rendering/RenderTableRow.h:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::clippedOverflowRectForRepaint):
+ (WebCore::RenderText::selectionRectForRepaint):
+ * rendering/RenderText.h:
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::write):
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::localToContainerQuad):
+ (WebCore::RenderView::computeRectForRepaint):
+ * rendering/RenderView.h:
+
+2009-02-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Build fix.
+
+ * page/animation/KeyframeAnimation.h: A function prototype had two "fromStyle" arguments.
+
+2009-02-05 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Alexey Proskuryakov.
+ Landed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23733
+
+ Use a 2 arguments constructor for KURL to avoid ASSERT failure.
+
+ * page/SecurityOrigin.cpp:
+ (WebCore::SecurityOrigin::createFromDatabaseIdentifier):
+
+2009-02-04 Feng Qian <feng@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Add Android-specific files to WebCore/editing directory.
+ https://bugs.webkit.org/show_bug.cgi?id=23294
+
+ * editing/android: Added.
+ * editing/android/EditorAndroid.cpp: Added.
+ (WebCore::Editor::newGeneralClipboard):
+
+2009-02-04 Dean Jackson <dino@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Remove -webkit-animation-play-state
+ The AnimationController still has the code to execute the property, but
+ it is no longer parsed or recorded.
+ https://bugs.webkit.org/show_bug.cgi?id=22907
+
+ * css/CSSComputedStyleDeclaration.cpp:
+ (WebCore::):
+ (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+ * css/CSSParser.cpp:
+ (WebCore::CSSParser::parseValue):
+ (WebCore::CSSParser::parseAnimationProperty):
+ * css/CSSParser.h:
+ * css/CSSPropertyNames.in:
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty):
+ * css/CSSStyleSelector.h:
+ * platform/animation/Animation.h:
+ * rendering/style/RenderStyleConstants.h:
+
+2009-02-04 Tor Arne Vestbø <tavestbo@trolltech.com>
+
+ Reviewed by Darin Adler.
+
+ Make sure we don't load on removing the media element from the document
+ https://bugs.webkit.org/show_bug.cgi?id=22105
+
+ Test: media/remove-from-document-no-load.html
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::removedFromDocument):
+
+2009-02-04 David Hyatt <hyatt@apple.com>
+
+ Add a new RenderBoxModelObject class that will eventually act as the direct base class for RenderInlines. For
+ now just adding the class and putting it in between RenderObject and RenderBox in the hierarchy. RenderInline remains
+ derived from RenderBox for now.
+
+ Reviewed by Sam Weinig
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::RenderBox):
+ (WebCore::RenderBox::destroy):
+ (WebCore::RenderBox::styleWillChange):
+ (WebCore::RenderBox::styleDidChange):
+ (WebCore::RenderBox::computeRectForRepaint):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp: Added.
+ (WebCore::RenderBoxModelObject::RenderBoxModelObject):
+ (WebCore::RenderBoxModelObject::~RenderBoxModelObject):
+ * rendering/RenderBoxModelObject.h: Added.
+ * rendering/RenderObject.h:
+
+2009-02-04 Chris Marrin <cmarrin@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ Added accelerated animation support to AnimationController and friends. The primary
+ changes are:
+ * accelerated animations get their start time from the compositing engine, so we
+ wait for a callback (notifyAnimationStarted()) in order to get the start time.
+ * if software and accelerated animations start in the same cycle, they all need
+ to use the same start time, which is that of the accelerated animations.
+
+ Added AnimationControllerPrivate to preserve the encapsulation under
+ AnimationController.
+
+ * GNUmakefile.am:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * page/animation/AnimationBase.cpp:
+ (WebCore::PropertyWrapperBase::animationIsAccelerated):
+ (WebCore::PropertyWrapperAcceleratedOpacity::PropertyWrapperAcceleratedOpacity):
+ (WebCore::PropertyWrapperAcceleratedOpacity::animationIsAccelerated):
+ (WebCore::PropertyWrapperAcceleratedOpacity::blend):
+ (WebCore::PropertyWrapperAcceleratedTransform::PropertyWrapperAcceleratedTransform):
+ (WebCore::PropertyWrapperAcceleratedTransform::animationIsAccelerated):
+ (WebCore::PropertyWrapperAcceleratedTransform::blend):
+ (WebCore::ensurePropertyMap):
+ (WebCore::AnimationBase::AnimationBase):
+ (WebCore::AnimationBase::~AnimationBase):
+ (WebCore::AnimationBase::blendProperties):
+ (WebCore::AnimationBase::animationOfPropertyIsAccelerated):
+ (WebCore::AnimationBase::updateStateMachine):
+ (WebCore::AnimationBase::fireAnimationEventsIfNeeded):
+ (WebCore::AnimationBase::willNeedService):
+ (WebCore::AnimationBase::getTimeToNextEvent):
+ (WebCore::AnimationBase::goIntoEndingOrLoopingState):
+ (WebCore::AnimationBase::beginAnimationUpdateTime):
+ * page/animation/AnimationBase.h:
+ (WebCore::AnimationBase::onAnimationStartResponse):
+ (WebCore::AnimationBase::getAnimatedStyle):
+ (WebCore::AnimationBase::isAnimatingProperty):
+ (WebCore::AnimationBase::endAnimation):
+ (WebCore::AnimationBase::isFallbackAnimating):
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationControllerPrivate::AnimationControllerPrivate):
+ (WebCore::AnimationControllerPrivate::accessCompositeAnimation):
+ (WebCore::AnimationControllerPrivate::addNodeChangeToDispatch):
+ (WebCore::AnimationControllerPrivate::animationTimerFired):
+ (WebCore::AnimationControllerPrivate::pauseAnimationAtTime):
+ (WebCore::AnimationControllerPrivate::pauseTransitionAtTime):
+ (WebCore::AnimationControllerPrivate::beginAnimationUpdateTime):
+ (WebCore::AnimationControllerPrivate::getAnimatedStyleForRenderer):
+ (WebCore::AnimationControllerPrivate::styleAvailable):
+ (WebCore::AnimationControllerPrivate::addToStartTimeResponseWaitList):
+ (WebCore::AnimationControllerPrivate::removeFromStartTimeResponseWaitList):
+ (WebCore::AnimationControllerPrivate::startTimeResponse):
+ (WebCore::AnimationController::getAnimatedStyleForRenderer):
+ (WebCore::AnimationController::notifyAnimationStarted):
+ (WebCore::AnimationController::endAnimationUpdate):
+ * page/animation/AnimationController.h:
+ * page/animation/AnimationControllerPrivate.h: Added.
+ (WebCore::AnimationControllerPrivate::hasAnimations):
+ (WebCore::AnimationControllerPrivate::setBeginAnimationUpdateTime):
+ (WebCore::AnimationControllerPrivate::endAnimationUpdate):
+ (WebCore::AnimationControllerPrivate::receivedStartTimeResponse):
+ * page/animation/CompositeAnimation.cpp:
+ (WebCore::CompositeAnimationPrivate::CompositeAnimationPrivate):
+ (WebCore::CompositeAnimationPrivate::animationControllerPriv):
+ (WebCore::CompositeAnimationPrivate::updateTransitions):
+ (WebCore::CompositeAnimationPrivate::updateKeyframeAnimations):
+ (WebCore::CompositeAnimationPrivate::animate):
+ (WebCore::CompositeAnimationPrivate::getAnimatedStyle):
+ (WebCore::CompositeAnimationPrivate::addToStartTimeResponseWaitList):
+ (WebCore::CompositeAnimationPrivate::removeFromStartTimeResponseWaitList):
+ (WebCore::CompositeAnimation::CompositeAnimation):
+ (WebCore::CompositeAnimation::animationControllerPriv):
+ (WebCore::CompositeAnimation::getAnimatedStyle):
+ (WebCore::CompositeAnimation::addToStartTimeResponseWaitList):
+ (WebCore::CompositeAnimation::removeFromStartTimeResponseWaitList):
+ * page/animation/CompositeAnimation.h:
+ (WebCore::CompositeAnimation::create):
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::shouldSendEventForListener):
+ (WebCore::ImplicitAnimation::animate):
+ (WebCore::ImplicitAnimation::getAnimatedStyle):
+ (WebCore::ImplicitAnimation::startAnimation):
+ (WebCore::ImplicitAnimation::endAnimation):
+ (WebCore::ImplicitAnimation::sendTransitionEvent):
+ (WebCore::ImplicitAnimation::willNeedService):
+ * page/animation/ImplicitAnimation.h:
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::getKeyframeAnimationInterval):
+ (WebCore::KeyframeAnimation::animate):
+ (WebCore::KeyframeAnimation::getAnimatedStyle):
+ (WebCore::KeyframeAnimation::startAnimation):
+ (WebCore::KeyframeAnimation::endAnimation):
+ (WebCore::KeyframeAnimation::shouldSendEventForListener):
+ (WebCore::KeyframeAnimation::sendAnimationEvent):
+ (WebCore::KeyframeAnimation::willNeedService):
+ * page/animation/KeyframeAnimation.h:
+ * platform/graphics/GraphicsLayerClient.h:
+ * platform/graphics/mac/GraphicsLayerCA.mm:
+ (-[WebAnimationDelegate animationDidStart:]):
+ * rendering/RenderLayerBacking.h:
+
+2009-02-04 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Not reviewed, build fix.
+
+ Remove duplicate definition of msSans in FontCache::alternateFamilyName.
+
+ * platform/graphics/FontCache.cpp:
+ (WebCore::alternateFamilyName):
+
+2009-02-04 Eric Seidel <eric@webkit.org>
+
+ Reviewed by George Staikos.
+
+ Reverse the meaning of the if check so that Android
+ (dpad devices) do not scroll on focus and normal platforms do
+ http://trac.webkit.org/changeset/40647
+
+ This was caught by George Staikos, and I wrote the patch.
+
+ * dom/Element.cpp:
+ (WebCore::Element::updateFocusAppearance):
+
+2009-02-04 David Hyatt <hyatt@apple.com>
+
+ Eliminate RenderContainer.
+
+ Reviewed by Sam and Anders
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::RenderBlock):
+ (WebCore::RenderBlock::destroy):
+ (WebCore::RenderBlock::styleWillChange):
+ (WebCore::RenderBlock::styleDidChange):
+ (WebCore::RenderBlock::addChild):
+ (WebCore::RenderBlock::dirtyLineBoxes):
+ (WebCore::RenderBlock::createInlineBox):
+ (WebCore::RenderBlock::removeChild):
+ (WebCore::RenderBlock::setSelectionState):
+ (WebCore::RenderBlock::avoidsFloats):
+ (WebCore::RenderBlock::positionForCoordinates):
+ (WebCore::RenderBlock::calcInlinePrefWidths):
+ (WebCore::RenderBlock::baselinePosition):
+ (WebCore::RenderBlock::getBaselineOfFirstLineBox):
+ (WebCore::RenderBlock::getBaselineOfLastLineBox):
+ (WebCore::RenderBlock::rectWithOutlineForRepaint):
+ (WebCore::RenderBlock::hoverAncestor):
+ (WebCore::RenderBlock::updateDragState):
+ (WebCore::RenderBlock::localCaretRect):
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::virtualChildren):
+ (WebCore::RenderBlock::children):
+ * rendering/RenderContainer.cpp: Removed.
+ * rendering/RenderContainer.h: Removed.
+ * rendering/RenderFrameSet.cpp:
+ (WebCore::RenderFrameSet::RenderFrameSet):
+ (WebCore::RenderFrameSet::nodeAtPoint):
+ (WebCore::RenderFrameSet::layout):
+ * rendering/RenderFrameSet.h:
+ (WebCore::RenderFrameSet::virtualChildren):
+ (WebCore::RenderFrameSet::children):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::RenderInline):
+ (WebCore::RenderInline::destroy):
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::nextContinuation):
+ (WebCore::RenderInline::continuationBefore):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::splitFlow):
+ (WebCore::RenderInline::addChildToContinuation):
+ (WebCore::RenderInline::offsetLeft):
+ (WebCore::RenderInline::offsetTop):
+ (WebCore::RenderInline::positionForCoordinates):
+ (WebCore::RenderInline::clippedOverflowRectForRepaint):
+ (WebCore::RenderInline::rectWithOutlineForRepaint):
+ (WebCore::RenderInline::updateDragState):
+ (WebCore::RenderInline::childBecameNonInline):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::virtualChildren):
+ (WebCore::RenderInline::children):
+ (WebCore::RenderInline::continuation):
+ (WebCore::RenderInline::setContinuation):
+ * rendering/RenderLineBoxList.h:
+ * rendering/RenderObject.h:
+ * rendering/RenderObjectChildList.h:
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::computeRepaintRectForRange):
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::RenderSVGRoot):
+ (WebCore::RenderSVGRoot::applyContentTransforms):
+ (WebCore::RenderSVGRoot::paint):
+ (WebCore::RenderSVGRoot::absoluteTransform):
+ (WebCore::RenderSVGRoot::nodeAtPoint):
+ (WebCore::RenderSVGRoot::position):
+ * rendering/RenderSVGRoot.h:
+ (WebCore::RenderSVGRoot::virtualChildren):
+ (WebCore::RenderSVGRoot::children):
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::absoluteRects):
+ (WebCore::RenderSVGText::absoluteQuads):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::addChild):
+ (WebCore::RenderTable::removeChild):
+ * rendering/RenderTableCol.cpp:
+ (WebCore::RenderTableCol::RenderTableCol):
+ * rendering/RenderTableCol.h:
+ (WebCore::RenderTableCol::virtualChildren):
+ (WebCore::RenderTableCol::children):
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::RenderTableRow):
+ (WebCore::RenderTableRow::destroy):
+ (WebCore::RenderTableRow::styleWillChange):
+ (WebCore::RenderTableRow::addChild):
+ * rendering/RenderTableRow.h:
+ (WebCore::RenderTableRow::virtualChildren):
+ (WebCore::RenderTableRow::children):
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::RenderTableSection):
+ (WebCore::RenderTableSection::destroy):
+ (WebCore::RenderTableSection::addChild):
+ (WebCore::RenderTableSection::removeChild):
+ (WebCore::RenderTableSection::lowestPosition):
+ (WebCore::RenderTableSection::rightmostPosition):
+ (WebCore::RenderTableSection::leftmostPosition):
+ * rendering/RenderTableSection.h:
+ (WebCore::RenderTableSection::virtualChildren):
+ (WebCore::RenderTableSection::children):
+
+2009-02-04 Mads Adger <mad@chromium.org>
+
+ Reviewed by Antti Koivisto.
+
+ Bug 23180 Reading freed memory at DocumentLoader::checkForPendingPreloads
+ https://bugs.webkit.org/show_bug.cgi?id=23180
+
+ Added a protector for the document potentially holding on the last reference to the loader we are interating with.
+
+ * loader/loader.cpp:
+ (WebCore::Loader::Host::didFinishLoading):
+ (WebCore::Loader::Host::didFail):
+
+2009-02-04 Cary Clark <caryclark@google.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23163
+ Don't scroll to show current focus on devices that use
+ directional pads for navigation.
+
+ * dom/Element.cpp:
+ (WebCore::Element::updateFocusAppearance):
+
+2009-02-04 Cary Clark <caryclark@google.com>
+
+ Reviewed by Darin Adler.
+
+ Change RenderBlock::columnGap() access permissions from protected to
+ public. ANDROID creates an array of focus rectangles for navigation
+ with a trackball or directional pad, and needs access to the column gap
+ to implement this logic.
+
+ Android has no testing harness @ webkit.org, thus no tests.
+
+ * rendering/RenderBlock.h:
+
+2009-02-04 Cary Clark <caryclark@google.com>
+
+ Reviewed by Darin Adler and Eric Seidel.
+
+ Fixes: https://bugs.webkit.org/show_bug.cgi?id=22917
+
+ Add ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL to permit the ANDROID
+ platform to select all when focusing on a textarea. This matches
+ the user interface guidelines other applications on the platform.
+
+ * html/HTMLTextAreaElement.cpp:
+ (WebCore::HTMLTextAreaElement::updateFocusAppearance):
+
+2009-02-04 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Fix for <rdar://problem/6386112> Some inline-elements are not
+ becoming proper dashboard-regions
+
+ RenderInline needs its own implementation of addDashboardRegions
+ because otherwise all of the coordinate calculations are
+ inaccurate.
+
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::addDashboardRegions):
+ * rendering/RenderInline.h:
+ * rendering/RenderObject.h:
+
+2009-02-04 David Hyatt <hyatt@apple.com>
+
+ Move addChild/removeChild from RenderContainer to RenderObject.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderContainer.cpp:
+ * rendering/RenderContainer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::updateListMarkerNumbers):
+ (WebCore::RenderObject::addChild):
+ (WebCore::RenderObject::removeChild):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::addChildIgnoringContinuation):
+ * rendering/RenderSVGContainer.cpp:
+ * rendering/RenderSVGContainer.h:
+
+2009-02-04 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Sam Weinig
+
+ <rdar://problem/3541409> - Further HistoryItem / BF cache cleanup
+
+ * history/CachedFrame.cpp:
+ (WebCore::CachedFrame::CachedFrame):
+ (WebCore::CachedFrame::restore):
+ * history/CachedFrame.h:
+
+ * history/CachedPage.cpp:
+ (WebCore::CachedPage::restore):
+ * history/CachedPage.h:
+ (WebCore::CachedPage::mainFrameView):
+
+ * history/HistoryItem.cpp:
+ (WebCore::HistoryItem::HistoryItem):
+ (WebCore::HistoryItem::~HistoryItem):
+ * history/HistoryItem.h:
+ (WebCore::HistoryItem::isInPageCache):
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::open):
+
+2009-02-04 Peter Kasting <pkasting@google.com>
+
+ Reviewed by David Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23743
+ Fix memory corruption with open-source GIF decoders.
+
+ * platform/image-decoders/ImageDecoder.h:
+ (WebCore::RGBA32Buffer::clear):
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::clearFrameBufferCache):
+ * platform/image-decoders/skia/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::clearFrameBufferCache):
+ (WebCore::GIFImageDecoder::initFrameBuffer):
+ * platform/image-decoders/skia/ImageDecoder.h:
+ (WebCore::RGBA32Buffer::clear):
+
+2009-02-04 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23360
+
+ When using accelerated compositing, make repaints use the correct
+ repaint container. Hook up the RenderLayerCompositor in RenderView,
+ and add to RenderView a method that repaints both the view
+ contents, and any intersecting composited layers.
+
+ Make enclosingCompositingLayer() a method on RenderObject, and update
+ the compositor to use that. Add a helper method on the compositor to
+ get the non-self compositing ancestor: ancestorCompositingLayer().
+
+ Call repaintRectangleInViewAndCompositedLayers() in places that don't do
+ container-relative repainting: selection redraw on focus change, caret,
+ and widget updates.
+
+ Fix a bug in RenderLayerCompositor where the m_compositingLayersNeedUpdate flag
+ would get cleared for partial updates, thus preventing subsequent full updates.
+
+ Fix a bug in RenderLayer::ensureBacking() that made new backing every time.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::recomputeCaretRect):
+ (WebCore::SelectionController::invalidateCaretRect):
+ (WebCore::SelectionController::focusedOrActiveStateChanged):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::clippedOverflowRectForRepaint):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::compositor):
+ (WebCore::RenderLayer::updateLayerPositions):
+ (WebCore::RenderLayer::removeChild):
+ (WebCore::RenderLayer::ensureBacking):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::backing):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+ (WebCore::RenderLayerBacking::paintIntoLayer):
+ (WebCore::RenderLayerBacking::notifyTransitionStarted):
+ (WebCore::RenderLayerBacking::notifyAnimationStarted):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateCompositingLayers):
+ (WebCore::RenderLayerCompositor::updateLayerCompositingState):
+ (WebCore::RenderLayerCompositor::layerWillBeRemoved):
+ (WebCore::RenderLayerCompositor::ancestorCompositingLayer):
+ (WebCore::RenderLayerCompositor::clippedByAncestor):
+ * rendering/RenderLayerCompositor.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::enclosingCompositingLayer):
+ (WebCore::RenderObject::containingBlockWidth):
+ (WebCore::RenderObject::containingBlockHeight):
+ (WebCore::RenderObject::containerForRepaint):
+ (WebCore::RenderObject::repaintUsingContainer):
+ * rendering/RenderObject.h:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::shouldRepaint):
+ (WebCore::RenderView::repaintViewRectangle):
+ (WebCore::RenderView::repaintRectangleInViewAndCompositedLayers):
+ (WebCore::RenderView::setMaximalOutlineSize):
+ (WebCore::RenderView::usesCompositing):
+ (WebCore::RenderView::compositor):
+ (WebCore::RenderView::didMoveOnscreen):
+ (WebCore::RenderView::willMoveOffscreen):
+ * rendering/RenderView.h:
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::updateWidgetPosition):
+
+2009-02-04 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Add toRenderImage methods for casting RenderObjects to RenderImages. The methods will assert if the object
+ is not a RenderImage. Also add a toRenderImage method that takes a RenderImage but returns void and that
+ is unimplemented. This method will catch anyone trying to do a cast when the object is already a RenderImage.
+
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::defaultEventHandler):
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::attach):
+ * html/HTMLImageElement.cpp:
+ (WebCore::HTMLImageElement::parseMappedAttribute):
+ (WebCore::HTMLImageElement::attach):
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::parseMappedAttribute):
+ (WebCore::HTMLInputElement::attach):
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::attach):
+ * html/HTMLVideoElement.cpp:
+ (WebCore::HTMLVideoElement::attach):
+ * loader/ImageLoader.cpp:
+ (WebCore::ImageLoader::setImage):
+ (WebCore::ImageLoader::updateFromElement):
+ (WebCore::ImageLoader::notifyFinished):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::accessibilityIsIgnored):
+ (WebCore::AccessibilityRenderObject::addChildren):
+ * page/DragController.cpp:
+ (WebCore::getCachedImage):
+ (WebCore::getImage):
+ * platform/mac/PasteboardMac.mm:
+ (WebCore::Pasteboard::writeImage):
+ * rendering/RenderImage.h:
+ (WebCore::toRenderImage):
+ * wml/WMLImageElement.cpp:
+ (WebCore::WMLImageElement::parseMappedAttribute):
+ (WebCore::WMLImageElement::attach):
+
+2009-02-04 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Eric Seidel and Dave Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=20531
+
+ Make alternateFamilyName customized for Windows and Chromium.
+
+ * platform/graphics/FontCache.cpp:
+ (WebCore::alternateFamilyName):
+
+2009-02-04 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ This comes from Chromium patch (http://codereview.chromium.org/17624).
+
+ Add m_disableFontFallback to UniscriberHelper class and set it
+ to true when filling up glyph pages for non-BMP code points.
+ When it's set true, UniscriberHelper does not do its own font
+ fallback. Neither does it do glyph placement. Font fallback
+ will be taken care of in the simple script font path and glyph
+ placement is not necessary for simple scripts.
+
+ Layout test is missing at the moment due to the lack of freely
+ distributable font covering a non-BMP code page. A test page
+ is available at http://i18nl10n.com/webkit/nonbmp2.html
+
+ See also https://bugs.webkit.org/show_bug.cgi?id=23602
+
+ * platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp:
+ (WebCore::fillNonBMPGlyphs):
+ * platform/graphics/chromium/UniscribeHelper.cpp:
+ (WebCore::UniscribeHelper::UniscribeHelper):
+ (WebCore::UniscribeHelper::shape):
+ (WebCore::UniscribeHelper::fillShapes):
+ * platform/graphics/chromium/UniscribeHelper.h:
+ (WebCore::UniscribeHelper::setDisableFontFallback):
+
+2009-02-04 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Remove some unnecessary #includes of RenderStyle.h
+
+ * css/CSSPrimitiveValueMappings.h:
+ * css/SVGCSSComputedStyleDeclaration.cpp:
+ * dom/Node.h:
+ * rendering/PointerEventsHitRules.h:
+ * rendering/RenderImageGeneratedContent.h:
+ * rendering/RenderMarquee.h:
+ * rendering/RenderScrollbar.h:
+
+2009-02-04 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Sam Weinig.
- Merge r40629.
+ https://bugs.webkit.org/show_bug.cgi?id=23657
+ Clean up WebCore/storage IDLs.
- 2009-02-04 David Hyatt <hyatt@apple.com>
+ * storage/SQLError.idl: Changed to match spec.
+ * storage/SQLResultSet.idl: Changed to match spec.
+ * storage/SQLStatementCallback.idl: Removed.
+ * storage/SQLStatementErrorCallback.idl: Removed.
+ * storage/SQLTransactionCallback.idl: Removed.
+ * storage/SQLTransactionErrorCallback.idl: Removed.
+
+2009-02-04 David Hyatt <hyatt@apple.com>
Fix for https://bugs.webkit.org/show_bug.cgi?id=23734, blank content on blogs.msdn.com.
@@ -220,11 +17145,204 @@
(WebCore::RenderTableSection::calcRowHeight):
(WebCore::RenderTableSection::layoutRows):
-2009-02-06 Mark Rowe <mrowe@apple.com>
+2009-02-04 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David Hyatt.
+
+ Rename RenderStyle::Diff to StyleDifference and move it to
+ RenderStyleConstants.h.
+
+ * rendering/RenderBR.cpp:
+ (WebCore::RenderBR::styleDidChange):
+ * rendering/RenderBR.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::styleWillChange):
+ (WebCore::RenderBlock::styleDidChange):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::styleWillChange):
+ (WebCore::RenderBox::styleDidChange):
+ * rendering/RenderBox.h:
+ * rendering/RenderButton.cpp:
+ (WebCore::RenderButton::styleWillChange):
+ (WebCore::RenderButton::styleDidChange):
+ * rendering/RenderButton.h:
+ * rendering/RenderFieldset.cpp:
+ (WebCore::RenderFieldset::styleDidChange):
+ * rendering/RenderFieldset.h:
+ * rendering/RenderFileUploadControl.cpp:
+ (WebCore::RenderFileUploadControl::styleDidChange):
+ * rendering/RenderFileUploadControl.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::styleDidChange):
+ * rendering/RenderInline.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::styleChanged):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateLayerCompositingState):
+ (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree):
+ * rendering/RenderLayerCompositor.h:
+ * rendering/RenderListBox.cpp:
+ (WebCore::RenderListBox::styleDidChange):
+ * rendering/RenderListBox.h:
+ * rendering/RenderListItem.cpp:
+ (WebCore::RenderListItem::styleDidChange):
+ * rendering/RenderListItem.h:
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::styleWillChange):
+ (WebCore::RenderListMarker::styleDidChange):
+ * rendering/RenderListMarker.h:
+ * rendering/RenderMenuList.cpp:
+ (WebCore::RenderMenuList::styleDidChange):
+ * rendering/RenderMenuList.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::setStyle):
+ (WebCore::RenderObject::styleWillChange):
+ (WebCore::RenderObject::styleDidChange):
+ * rendering/RenderObject.h:
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::styleDidChange):
+ * rendering/RenderReplaced.h:
+ * rendering/RenderSVGGradientStop.cpp:
+ (WebCore::RenderSVGGradientStop::styleDidChange):
+ * rendering/RenderSVGGradientStop.h:
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::styleDidChange):
+ * rendering/RenderSVGInlineText.h:
+ * rendering/RenderScrollbarPart.cpp:
+ (WebCore::RenderScrollbarPart::styleWillChange):
+ (WebCore::RenderScrollbarPart::styleDidChange):
+ * rendering/RenderScrollbarPart.h:
+ * rendering/RenderSlider.cpp:
+ (WebCore::RenderSlider::styleDidChange):
+ * rendering/RenderSlider.h:
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::styleDidChange):
+ * rendering/RenderTable.h:
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::styleWillChange):
+ (WebCore::RenderTableCell::styleDidChange):
+ * rendering/RenderTableCell.h:
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::styleWillChange):
+ * rendering/RenderTableRow.h:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::styleDidChange):
+ * rendering/RenderText.h:
+ (WebCore::RenderText::styleWillChange):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::styleDidChange):
+ * rendering/RenderTextControl.h:
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::styleDidChange):
+ * rendering/RenderTextControlSingleLine.h:
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::styleDidChange):
+ * rendering/RenderWidget.h:
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::diff):
+ (WebCore::RenderStyle::setClip):
+ * rendering/style/RenderStyle.h:
+ * rendering/style/RenderStyleConstants.h:
+ (WebCore::):
+
+2009-02-03 Sam Weinig <sam@webkit.org>
- Merge r40623.
+ Reviewed by David Hyatt.
- 2009-02-04 David Kilzer <ddkilzer@apple.com>
+ Move PseudoId enum out of RenderStyle and into RenderStyleConstants.h
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::matchRulesForList):
+ (WebCore::CSSStyleSelector::initForStyleResolve):
+ (WebCore::CSSStyleSelector::SelectorChecker::SelectorChecker):
+ (WebCore::CSSStyleSelector::SelectorChecker::checkSelector):
+ (WebCore::CSSStyleSelector::styleForElement):
+ (WebCore::CSSStyleSelector::pseudoStyleForElement):
+ (WebCore::CSSStyleSelector::checkSelector):
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+ (WebCore::CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass):
+ (WebCore::CSSStyleSelector::applyProperty):
+ * css/CSSStyleSelector.h:
+ * dom/Node.cpp:
+ (WebCore::Node::diff):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::createScrollbar):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::paint):
+ * rendering/MediaControlElements.cpp:
+ (WebCore::MediaTextDisplayElement::MediaTextDisplayElement):
+ (WebCore::MediaTimeDisplayElement::MediaTimeDisplayElement):
+ (WebCore::MediaControlInputElement::MediaControlInputElement):
+ (WebCore::MediaControlMuteButtonElement::MediaControlMuteButtonElement):
+ (WebCore::MediaControlPlayButtonElement::MediaControlPlayButtonElement):
+ (WebCore::MediaControlSeekButtonElement::MediaControlSeekButtonElement):
+ (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
+ (WebCore::MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement):
+ * rendering/MediaControlElements.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::styleDidChange):
+ (WebCore::RenderBlock::updateBeforeAfterContent):
+ (WebCore::RenderBlock::firstLineBlock):
+ (WebCore::RenderBlock::updateFirstLetter):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::isAfterContent):
+ * rendering/RenderButton.cpp:
+ (WebCore::RenderButton::updateBeforeAfterContent):
+ * rendering/RenderButton.h:
+ * rendering/RenderFileUploadControl.cpp:
+ (WebCore::RenderFileUploadControl::createButtonStyle):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::isAfterContent):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::splitInlines):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::createScrollbar):
+ (WebCore::RenderLayer::updateScrollCornerStyle):
+ (WebCore::RenderLayer::updateResizerStyle):
+ * rendering/RenderListBox.cpp:
+ (WebCore::RenderListBox::createScrollbar):
+ * rendering/RenderMedia.cpp:
+ (WebCore::RenderMedia::createPanel):
+ (WebCore::RenderMedia::createTimelineContainer):
+ * rendering/RenderMenuList.cpp:
+ (WebCore::RenderMenuList::createScrollbar):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::selectionBackgroundColor):
+ (WebCore::RenderObject::selectionForegroundColor):
+ (WebCore::RenderObject::firstLineStyleSlowCase):
+ (WebCore::RenderObject::getCachedPseudoStyle):
+ (WebCore::RenderObject::getUncachedPseudoStyle):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isAnonymousBlock):
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::RenderObjectChildList::destroyLeftoverChildren):
+ (WebCore::beforeAfterContainer):
+ (WebCore::RenderObjectChildList::invalidateCounters):
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent):
+ * rendering/RenderObjectChildList.h:
+ * rendering/RenderScrollbar.cpp:
+ (WebCore::RenderScrollbar::getScrollbarPseudoStyle):
+ (WebCore::pseudoForScrollbarPart):
+ * rendering/RenderScrollbar.h:
+ * rendering/RenderSlider.cpp:
+ (WebCore::RenderSlider::createThumbStyle):
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::createInnerTextStyle):
+ (WebCore::RenderTextControlSingleLine::createResultsButtonStyle):
+ (WebCore::RenderTextControlSingleLine::createCancelButtonStyle):
+ (WebCore::RenderTextControlSingleLine::createScrollbar):
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::pseudoBit):
+ * rendering/style/RenderStyle.h:
+ (WebCore::):
+ * rendering/style/RenderStyleConstants.h:
+ (WebCore::):
+
+2009-02-04 David Kilzer <ddkilzer@apple.com>
CrashTracer: [REGRESSION] 53 crashes in Safari at com.apple.WebCore: WebCore::LegacyWebArchive::create + 2706
@@ -237,27 +17355,177 @@
Check for the value returned from WebCore::IconDatabase::iconForPageURL(),
not WebCore::Image::data().
-2009-02-06 Mark Rowe <mrowe@apple.com>
+2009-02-04 David Hyatt <hyatt@apple.com>
- Merge r40537.
+ Rename removeFromObjectLists and move it into RenderBox, since it only applies to boxes.
- 2009-02-03 David Kilzer <ddkilzer@apple.com>
+ Reviewed by Adam Roben
- CrashTracer: [REGRESSION] 53 crashes in Safari at com.apple.WebCore: WebCore::LegacyWebArchive::create + 2706
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::removeFloatingOrPositionedChildFromBlockLists):
+ (WebCore::RenderBox::styleWillChange):
+ * rendering/RenderBox.h:
+ * rendering/RenderContainer.cpp:
+ (WebCore::RenderContainer::removeChild):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::styleWillChange):
+ * rendering/RenderObject.h:
+ * rendering/RenderSVGContainer.cpp:
+ (WebCore::RenderSVGContainer::removeChild):
- <rdar://problem/6509514>
+2009-02-04 Jeremy Moskovich <jeremy@chromium.org>
- Reviewed by Adam Roben.
+ Reviewed by Dave Hyatt.
- * loader/archive/cf/LegacyWebArchive.cpp:
- (WebCore::LegacyWebArchive::create): Null check the value returned
- from WebCore::IconDatabase::iconForPageURL().
+ https://bugs.webkit.org/show_bug.cgi?id=23471
+ Fix text-overflow:ellipsis; for RTL case.
+
+ Test: fast/css/text-overflow-ellipses.html
+
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::placeEllipsisBox): Add support for rtl placement.
+ (WebCore::InlineTextBox::paintDecoration): Correctly draw decorations
+ for rtl truncation.
+
+2009-02-04 Dimitri Glazkov <dglazkov@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23700
+ Upstream local changes to due to unforking of SimpleFontData
+ (corresponds to Chromium check-in http://src.chromium.org/viewvc/chrome?view=rev&revision=8646).
+
+ * platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp:
+ (WebCore::fillBMPGlyphs): Removed extra checks for ZWS chars.
+
+2009-02-04 David Hyatt <hyatt@apple.com>
+
+ <rdar://problem/6554115> REGRESSION (r40475): World leak (JS global object) after viewing a photo on Facebook
+
+ Fix a ginormous leak. (GINORMOUS!) Make sure to disconnect the event listeners attached to the Document,
+ because, like, they point to a lot of stuff... like ... everything...
+
+ Reviewed by Darin Adler
+
+ * dom/Document.cpp:
+ (WebCore::Document::removeAllEventListenersFromAllNodes):
+
+2009-02-04 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23731
+ Add JSCCustom and V8Custom as extended IDL attributes
+
+ This helps avoid having to add #ifdefs to the IDL files to support V8 bindings.
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * dom/Document.idl:
+ * dom/Node.idl:
+ * svg/SVGPathSegList.idl:
+ * svg/SVGPointList.idl:
+ * svg/SVGTransformList.idl:
+
+2009-02-04 Dan Bernstein <mitz@apple.com>
+
+ - build fix
+
+ * rendering/RenderImageGeneratedContent.h:
+
+2009-02-04 miggilin <mr.diggilin@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ Switch to using a ref-counted wxFont pointer for FontPlatformData to fix a crash
+ with assigning to uninitialized HashTable buckets.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23669
+
+ * platform/graphics/SimpleFontData.h:
+ (WebCore::SimpleFontData::getWxFont):
+ * platform/graphics/wx/FontPlatformData.h:
+ (WebCore::):
+ (WebCore::FontPlatformData::FontPlatformData):
+ (WebCore::FontPlatformData::font):
+ (WebCore::FontPlatformData::operator==):
+ * platform/graphics/wx/FontPlatformDataWx.cpp:
+ (WebCore::FontPlatformData::FontPlatformData):
+ (WebCore::FontPlatformData::computeHash):
+ (WebCore::FontPlatformData::~FontPlatformData):
+ * platform/graphics/wx/SimpleFontDataWx.cpp:
+ (WebCore::SimpleFontData::platformInit):
+ (WebCore::SimpleFontData::determinePitch):
+ (WebCore::SimpleFontData::platformWidthForGlyph):
+ * platform/wx/wxcode/gtk/non-kerned-drawing.cpp:
+ (WebCore::drawTextWithSpacing):
+
+2009-02-04 David Hyatt <hyatt@apple.com>
+
+ Fix a crash in generated content when a generated image with an already-cached background image gets
+ created. It's not completely clear how to reproduce this crash.
+
+ Reviewed by Adam Roben
+
+ * rendering/RenderImageGeneratedContent.h:
+ (WebCore::RenderImageGeneratedContent::imagePtr):
+
+2009-02-04 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Unreviewed Qt build fix.
+
+ Changed ASSERT(image) to ASSERT(!image.isNull()).
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
+2009-02-04 Trenton Schulz <trenton.schulz@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix implementation of PluginViewMac::invalidateRect to update only the
+ specified rect, not the entire browser window.
+
+ * plugins/mac/PluginViewMac.cpp:
+ (WebCore::PluginView::invalidateRect):
+
+2009-02-04 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Rubber stamped by Mark Rowe.
+
+ FramePrivate was removed in r40024 remove the forward
+ declaration as well.
+
+ * page/Frame.h:
+
+2009-02-04 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23426
-2009-02-06 Mark Rowe <mrowe@apple.com>
+ Make isFrameSet virtual and by default return false. Reimplement
+ it in HTMLDocument.
- Merge r40606.
+ * dom/Document.cpp:
+ * dom/Document.h:
+ (WebCore::Document::isFrameSet):
+ * html/HTMLDocument.cpp:
+ (WebCore::HTMLDocument::isFrameSet):
+ * html/HTMLDocument.h:
+
+2009-02-03 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by John Sullivan.
- 2009-02-03 David Hyatt <hyatt@apple.com>
+ <rdar://problem/6554092> Slow script dialog starts coming up over and over again
+
+ Work around <rdar://problem/6554067> by consuming any exceptions that are
+ thrown by _web_localizedDescription
+
+ * platform/network/mac/ResourceErrorMac.mm:
+ (WebCore::ResourceError::platformLazyInit):
+
+2009-02-03 David Hyatt <hyatt@apple.com>
Move the isRenderInline checks for clientWidth/Height and scrollWidth/Height to the DOM element
versions of the functions. Since internal render tree usage doesn't ever (incorrectly) call these
@@ -277,53 +17545,900 @@
(WebCore::RenderBox::scrollWidth):
(WebCore::RenderBox::scrollHeight):
-2009-02-06 Mark Rowe <mrowe@apple.com>
+2009-02-03 Brad Garcia <bgarcia@google.com>
+
+ Reviewed by Eric Seidel.
- Merge r40502.
+ https://bugs.webkit.org/show_bug.cgi?id=20443
+ Remove call to canResize when trying to determine if pointer
+ is within a frame.
+ Also removed the implementation of canResize as it is no longer used.
- 2009-02-02 David Hyatt <hyatt@apple.com>
+ Test: fast/frames/frame-dead-region.html
- Make sure scrollWidth/Height just return 0 for inline flows.
+ * rendering/RenderFrameSet.cpp:
+ (WebCore::RenderFrameSet::nodeAtPoint):
+ * rendering/RenderFrameSet.h:
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Reduce the number of calls to virtualChildren (indirectly made via RenderObject::firstChild()).
+ This is a small gain on the PLT.
+
+ Reviewed by Mark Rowe
+
+ * rendering/bidi.cpp:
+ (WebCore::inlineWidth):
+ (WebCore::bidiNext):
+
+2009-02-03 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23628
+
+ Fix selection repainting to do container-relative repaints. RenderView now
+ repaints the selection using the containerForRepaint() for each RenderSelectionInfo.
+ selectionRect() is now a wrapper for selectionRectForRepaint() with no container.
+
+ Pull SelectionInfo out of RenderObject.h, and BlockSelectionInfo out
+ of RenderBlock.h and move them into RenderSelectionInfo.h, with some
+ sharing and refactoring.
+
+ RenderBlock::selectionGapRectsForRepaint() is not yet container-aware.
+
+ * GNUmakefile.am:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderBR.h:
+ (WebCore::RenderBR::selectionRectForRepaint):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::selectionGapRectsForRepaint):
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::selectionRectForRepaint):
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::paint):
+ (WebCore::RenderListMarker::selectionRectForRepaint):
+ * rendering/RenderListMarker.h:
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::selectionRect):
+ (WebCore::RenderObject::selectionRectForRepaint):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::selectionRectForRepaint):
+ * rendering/RenderReplaced.h:
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::absoluteRects):
+ (WebCore::RenderSVGInlineText::absoluteQuads):
+ (WebCore::RenderSVGInlineText::selectionRectForRepaint):
+ (WebCore::RenderSVGInlineText::computeRepaintRectForRange):
+ * rendering/RenderSVGInlineText.h:
+ * rendering/RenderSelectionInfo.h: Added.
+ (WebCore::RenderSelectionInfoBase::RenderSelectionInfoBase):
+ (WebCore::RenderSelectionInfoBase::object):
+ (WebCore::RenderSelectionInfoBase::repaintContainer):
+ (WebCore::RenderSelectionInfoBase::state):
+ (WebCore::RenderSelectionInfo::RenderSelectionInfo):
+ (WebCore::RenderSelectionInfo::repaint):
+ (WebCore::RenderSelectionInfo::rect):
+ (WebCore::RenderBlockSelectionInfo::RenderBlockSelectionInfo):
+ (WebCore::RenderBlockSelectionInfo::repaint):
+ (WebCore::RenderBlockSelectionInfo::block):
+ (WebCore::RenderBlockSelectionInfo::rects):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::selectionRectForRepaint):
+ * rendering/RenderText.h:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::selectionBounds):
+ (WebCore::RenderView::setSelection):
+ * rendering/RenderView.h:
+ * rendering/RenderWidget.cpp:
+ (WebCore::RenderWidget::paint):
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Add inline capacity back to CSSMutableStyleDeclaration now that the bug in Vector has been fixed.
+
+ Reviewed by Darin Adler & Sam Weinig
+
+ * css/CSSMutableStyleDeclaration.cpp:
+ (WebCore::CSSMutableStyleDeclaration::removePropertiesInSet):
+ * css/CSSMutableStyleDeclaration.h:
+
+2009-02-03 Justin Garcia <justin.garcia@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=13490
+ Implement execCommand("styleWithCSS", ...)
+
+ Determine whether or not to use HTML formatting tags for styling on the new
+ boolean on Editor instead of whether or not the document is quirks mode.
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::StyleChange::StyleChange):
+ (WebCore::StyleChange::init):
+ (WebCore::ApplyStyleCommand::applyBlockStyle):
+ (WebCore::ApplyStyleCommand::applyTextDecorationStyle):
+ (WebCore::ApplyStyleCommand::addInlineStyleIfNeeded):
+ * editing/Editor.cpp:
+ (WebCore::Editor::Editor):
+ (WebCore::Editor::clear):
+ * editing/Editor.h:
+ (WebCore::Editor::setShouldStyleWithCSS):
+ (WebCore::Editor::shouldStyleWithCSS):
+ * editing/EditorCommand.cpp:
+ (WebCore::executeStyleWithCSS):
+ (WebCore::stateStyleWithCSS):
+ (WebCore::CommandEntry::):
+
+2009-02-03 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ This is a follow up of r40546. Call toImage() once speeds up ImageBuffer::getImageData()
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
+2009-02-03 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Kevin Decker.
+
+ - Fix for <rdar://problem/6549743>
+
+ On Tiger, create an autorelease pool before creating the NSGraphicsContext and drain it immediately
+ after the call to -[NSView displayRectIgnoringOpacity:inContext:].
+
+ * platform/mac/WidgetMac.mm:
+ (WebCore::Widget::paint):
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Back this change out since it is causing layout tests to crash. There is something subtle going on
+ here.
+
+ Reviewed by Darin Adler
+
+ * css/CSSMutableStyleDeclaration.cpp:
+ (WebCore::CSSMutableStyleDeclaration::removePropertiesInSet):
+ * css/CSSMutableStyleDeclaration.h:
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Give the properties vector of mutable style declarations an initial inline capacity to reduce malloc churn.
+
+ Reviewed by Sam Weinig
+
+ * css/CSSMutableStyleDeclaration.cpp:
+ (WebCore::CSSMutableStyleDeclaration::removePropertiesInSet):
+ * css/CSSMutableStyleDeclaration.h:
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Avoid creating extra copies of NSURLRequests for non-HTTP URLs. Only mark platform requests
+ as needing updating when HTTP fields change if the scheme of the URL is actually HTTP or HTTPS.
+ Thus cuts down significantly on the number of copied NSURLRequests and is about a 1% gain on the PLT.
+
+ Reviewed by Darin Adler
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::addExtraFieldsToRequest):
+ * platform/KURL.cpp:
+ (WebCore::KURL::invalidate):
+ (WebCore::KURL::KURL):
+ * platform/KURL.h:
+ (WebCore::KURL::isHTTPOrHTTPS):
+ * platform/network/ResourceRequestBase.cpp:
+ (WebCore::ResourceRequestBase::setCachePolicy):
+ (WebCore::ResourceRequestBase::setTimeoutInterval):
+ (WebCore::ResourceRequestBase::setMainDocumentURL):
+ (WebCore::ResourceRequestBase::setHTTPMethod):
+ (WebCore::ResourceRequestBase::setHTTPHeaderField):
+ (WebCore::ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray):
+ (WebCore::ResourceRequestBase::setHTTPBody):
+ (WebCore::ResourceRequestBase::setAllowHTTPCookies):
+
+2009-02-03 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23711
+
+ Add manual test for floating divs with scrollbars.
+
+ * manual-tests/gtk/floatingdiv.html: Added.
+
+2009-02-03 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23711
+
+ There's no need to hold an extra ref to the scrollbar, calling
+ setPlatformWidget takes ownership of it.
+
+ Also do not disconnect the signals when destroying the widget,
+ it's superfluous.
+
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::ScrollbarGtk):
+ * platform/gtk/ScrollbarGtk.h:
+
+2009-02-03 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23711
+
+ Declare scrollBar as GtkWidget* to avoid needless
+ casting.
+
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::ScrollbarGtk):
+ (ScrollbarGtk::~ScrollbarGtk):
+
+2009-02-03 Xan Lopez <xan@gnome.org>
+
+ Reviewed by Holger Freyther.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23711
+
+ Properly calculate the scrollbar location for their
+ usage in RenderLayout.
+
+ * platform/gtk/ScrollbarGtk.cpp:
+ (ScrollbarGtk::frameRectsChanged):
+
+2009-02-03 David Hyatt <hyatt@apple.com>
+
+ Rename addLineBoxRects to absoluteRectsForRange, and do the same thing for the corresponding quads methods. Move the RenderContainer implementations
+ of these methods up to RenderObject.
Reviewed by Beth Dakin
- * rendering/RenderBox.cpp:
- (WebCore::RenderBox::scrollWidth):
- (WebCore::RenderBox::scrollHeight):
+ * bindings/objc/DOM.mm:
+ (-[DOMNode lineBoxRects]):
+ * dom/Range.cpp:
+ (WebCore::Range::addLineBoxRects):
+ * inspector/InspectorController.cpp:
+ (WebCore::InspectorController::drawNodeHighlight):
+ * rendering/RenderContainer.cpp:
+ * rendering/RenderContainer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::absoluteRectsForRange):
+ (WebCore::RenderObject::absoluteQuadsForRange):
+ * rendering/RenderObject.h:
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::absoluteRectsForRange):
+ (WebCore::RenderText::absoluteQuadsForRange):
+ * rendering/RenderText.h:
+
+2009-02-03 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Sam Weinig and Oliver Hunt.
+
+ Added getImageData() support for QtWebKit.
+
+ [QT] lacks getImageData / putImageData support in Canvas
+ https://bugs.webkit.org/show_bug.cgi?id=22186
+
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::ImageBuffer::getImageData):
+
+2009-02-03 Eric Roman <eroman@chromium.org>
+
+ Reviewed by Holger Freyther.
+
+ Fix FrameChromium.cpp following r40473 which moved Frame::adjustPageHeight to FrameView::adjustPageHeight.
+
+ * page/chromium/FrameChromium.cpp:
+ (WebCore::computePageRectsForFrame):
+
+2009-02-02 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23358
+
+ Hook accelerated compositing into RenderLayer.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::~RenderLayer):
+ Init and clean up backing and the hasCompositingDescendant bit.
+
+ (WebCore::RenderLayer::compositor):
+ Shortcut to get to the RenderLayerCompositor.
+
+ (WebCore::RenderLayer::updateLayerPositions):
+ We need to let full repaints propagate to all compositing layers, and
+ update the backing after layout here.
+
+ (WebCore::RenderLayer::transparentAncestor):
+ (WebCore::transparencyClipBox):
+ (WebCore::RenderLayer::beginTransparencyLayers):
+ Account for the fact that opacity may be rendered via the compositing
+ layer sometimes.
+
+ (WebCore::RenderLayer::addChild):
+ (WebCore::RenderLayer::removeChild):
+ (WebCore::RenderLayer::removeOnlyThisLayer):
+ Tell the compositor when the RenderLayer hierarchy changes.
+
+ (WebCore::RenderLayer::scrollToOffset):
+ Update layer geometry after scrolling.
+
+ (WebCore::RenderLayer::paintLayer):
+ We short-circuit painting on composited layers, because these layers
+ are painted on a callback from the compositing system.
+
+ (WebCore::RenderLayer::hitTestLayer):
+ Only apply transforms if we are rendering them in software.
+
+ (WebCore::RenderLayer::localBoundingBox):
+ (WebCore::RenderLayer::boundingBox):
+ (WebCore::RenderLayer::absoluteBoundingBox):
+ Refactor bounding box code that we can compute local, and ancestor-relative
+ bounding box, as well as absolute.
+
+ (WebCore::RenderLayer::ensureBacking):
+ (WebCore::RenderLayer::clearBacking):
+ RenderLayerBacking creation and destruction.
+
+ (WebCore::RenderLayer::setParent):
+ Tell the compositor when the RenderLayer hierarchy changes.
+
+ (WebCore::RenderLayer::dirtyZOrderLists):
+ (WebCore::RenderLayer::dirtyStackingContextZOrderLists):
+ (WebCore::RenderLayer::dirtyOverflowList):
+ When the z-order and overflow lists change, we need to tell the
+ compositor that the composited layers need to be rejiggered soon.
+
+ (WebCore::RenderLayer::updateZOrderLists):
+ Whitespace cleanup.
+
+ (WebCore::RenderLayer::setBackingNeedsRepaint):
+ (WebCore::RenderLayer::setBackingNeedsRepaintInRect):
+ Dirty composited layer contents for painting.
+
+ (WebCore::RenderLayer::styleChanged):
+ Update the layer backing after style changes.
+
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::isComposited):
+ (WebCore::RenderLayer::backing):
+ Accessors for testing and getting the backing for this RenderLayer.
+
+ (WebCore::RenderLayer::paintsWithTransparency):
+ (WebCore::RenderLayer::paintsWithTransform):
+ Transform and opacity can be applied via the compositing layer, or rendered
+ in software. These methods tell us if we need to account for them in the
+ non-compositing path.
+
+ (WebCore::RenderLayer::hasCompositingDescendant):
+ (WebCore::RenderLayer::setHasCompositingDescendant):
+ Maintain a bit to tell if this layer has composited descendants.
+
+2009-02-03 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23365
+
+ Hook up accelerated compositing layers the native
+ view system on Mac.
+
+ * WebCore.base.exp:
+ Export new Page methods.
+
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::attachRootGraphicsLayer):
+ (WebCore::ChromeClient::setNeedsOneShotDrawingSynchronization):
+ New methods for attaching/detaching the root GraphicsLayer, and
+ synchronizing layer changes with window drawing.
+
+ * page/FrameView.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::updateCompositingLayers):
+ (WebCore::FrameView::setNeedsOneShotDrawingSynchronization):
+ (WebCore::FrameView::didMoveOnscreen):
+ (WebCore::FrameView::willMoveOffscreen):
+ New methods to update the compositing layer hierarchy,
+ and pass-throughs to the RenderLayerCompositor.
+
+ (WebCore::FrameView::layout):
+ Update compositing layers after layout() and updateLayerPositions().
+
+ * page/Page.cpp:
+ (WebCore::Page::didMoveOnscreen):
+ (WebCore::Page::willMoveOffscreen):
+ * page/Page.h:
+ New methods to allow the native view system to tell the Page when it
+ starts to be presented on-screen, and when it will be hidden.
+
+ * rendering/RenderLayerCompositor.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::updateLayerCompositingState):
+ (WebCore::RenderLayerCompositor::didMoveOnscreen):
+ (WebCore::RenderLayerCompositor::willMoveOffscreen):
+ (WebCore::RenderLayerCompositor::ensureRootPlatformLayer):
+ Rename 'attached' methods to 'moveOnscreen/moveOffscreen' to match
+ the calls through from Page, FrameView.
+
+ (WebCore::RenderLayerCompositor::layerWillBeRemoved):
+ Dont' try to repaint or update layers if the document is being torn
+ down.
+
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::didMoveOnscreen):
+ (WebCore::RenderView::willMoveOffscreen):
+ * rendering/RenderView.h:
+ New methods.
+
+2009-02-03 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Holger Hans Peter Freyther.
+
+ Fixed getImageData and putImageData and respect pre-
+ multiplied colors.
+
+ Cairo's ImageBuffer::getImageData() does not handle alpha=0 case correctly
+ https://bugs.webkit.org/show_bug.cgi?id=21575
+
+ * platform/graphics/cairo/ImageBufferCairo.cpp:
+ (WebCore::ImageBuffer::getImageData):
+ (WebCore::ImageBuffer::putImageData):
+
+2009-02-03 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Brady Eidson.
+
+ - fix <rdar://problem/6550530> REGRESSION (r40508): Window opened with window.open has no initial history item (global and back/forward)
+
+ Test: fast/history/window-open.html
+
+ * bindings/js/JSDOMWindowBase.cpp:
+ (WebCore::createWindow): Pass the missing lockBackForwardList parameter
+ to FrameLoader::changeLocation().
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-02-03 Adam Treat <adam.treat@torchmobile.com>
- Merge r40516.
+ Fix the Qt build after r40536.
- 2009-02-02 Geoffrey Garen <ggaren@apple.com>
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::convertQVariantToValue):
+
+2009-02-03 Dan Bernstein <mitz@apple.com>
+
+ - fix -Wmissing-prototypes builds
+
+ * loader/WorkerThreadableLoader.cpp:
+ (WebCore::workerContextDidSendData): Marked this function static.
+ (WebCore::workerContextDidReceiveResponse): Ditto.
+ (WebCore::workerContextDidReceiveData): Ditto.
+ (WebCore::workerContextDidFinishLoading): Ditto.
+ (WebCore::workerContextDidFail): Ditto.
+ (WebCore::workerContextDidGetCancelled): Ditto.
+ (WebCore::workerContextDidReceiveAuthenticationCancellation): Ditto.
+
+2009-02-03 David Kilzer <ddkilzer@apple.com>
+
+ CrashTracer: [REGRESSION] 53 crashes in Safari at com.apple.WebCore: WebCore::LegacyWebArchive::create + 2706
+
+ <rdar://problem/6509514>
+
+ Reviewed by Adam Roben.
+
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ (WebCore::LegacyWebArchive::create): Null check the value returned
+ from WebCore::IconDatabase::iconForPageURL().
+
+2009-02-03 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Fix conversion of QByteArray to JavaScript and back. Instead of
+ converting it to a String (data loss!) we now map it to JSByteArray.
+
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::):
+ (JSC::Bindings::valueRealType): Added JSByteArray as converstion type.
+ (JSC::Bindings::convertValueToQVariant): Convert from JSByteArray to
+ QVariant(QByteArray).
+ (JSC::Bindings::convertQVariantToValue): Convert from
+ QVariant::ByteArray to jsByteArray.
+
+2009-02-03 Alexey Proskuryakov <ap@webkit.org>
Build fix.
- * plugins/PluginView.cpp:
- (WebCore::PluginView::performRequest):
+ * GNUmakefile.am: Removed WorkerTask.{h,cpp}.
+
+2009-02-03 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22718
+ Implement WindowTimers interface in Workers.
+
+ This patch moves timeoutID from Document to ScriptExecutionContext
+ and exposes JS methods setTimeout/setInterval/clearTimeout/clearInterval inside of a Worker.
+ Also added a test for those methods.
+
+ Test: fast/workers/worker-timeout.html
+
+ * bindings/js/JSWorkerContextCustom.cpp:
+ (WebCore::setTimeoutOrInterval):
+ Creates ScheduledAction and calls WorkerContext::installTimeout to actually add a timer.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ (WebCore::JSWorkerContext::setTimeout):
+ (WebCore::JSWorkerContext::clearTimeout):
+ (WebCore::JSWorkerContext::setInterval):
+ (WebCore::JSWorkerContext::clearInterval):
+ Added methods exposed to JS.
- Merge r40514.
+ * dom/Document.cpp:
+ * dom/Document.h:
+ * dom/ScriptExecutionContext.cpp:
+ (WebCore::ScriptExecutionContext::addTimeout):
+ (WebCore::ScriptExecutionContext::removeTimeout):
+ (WebCore::ScriptExecutionContext::findTimeout):
+ * dom/ScriptExecutionContext.h:
+ The timerID map moves from Document to ScriptExecutionContext,
+ to be available to Document and to WorkerContext.
- 2009-02-02 Geoffrey Garen <ggaren@apple.com>
+ * dom/WorkerContext.cpp:
+ (WebCore::WorkerContext::installTimeout): Adds a DOMTimeout.
+ (WebCore::WorkerContext::removeTimeout): Removes a DOMTimeout.
+ * dom/WorkerContext.h:
+
+ * page/DOMTimer.cpp:
+ (WebCore::DOMTimer::DOMTimer):
+ (WebCore::DOMTimer::~DOMTimer):
+ (WebCore::DOMTimer::removeById):
+ Code change here reflects move of timeoutID map to the ScriptExecutionContext.
+ Some checks and casts are no longer needed.
+
+2009-02-03 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23560
+ Implement SharedTimer for Workers.
+
+ * dom/WorkerRunLoop.cpp:
+ Added private class WorkerSharedTimer that implements SharedTimer interface for worker threads.
+ (WebCore::WorkerSharedTimer::WorkerSharedTimer):
+ (WebCore::WorkerSharedTimer::setFiredFunction):
+ (WebCore::WorkerSharedTimer::setFireTime):
+ (WebCore::WorkerSharedTimer::stop):
+ (WebCore::WorkerSharedTimer::isActive):
+ (WebCore::WorkerSharedTimer::fireTime):
+ (WebCore::WorkerSharedTimer::fire):
+ (WebCore::WorkerRunLoop::WorkerRunLoop):
+ Initializes a WorkerSharedTimer instance.
+ (WebCore::WorkerRunLoop::~WorkerRunLoop):
+ The destructor is here so compiler is ok with having OwnPtr<WorkerSharedTimer> in .h file w/o defining WorkerSharedTimer.
+ (WebCore::WorkerRunLoop::run):
+ Set/reset shared timer interface on ThreadTimers, use MessageQueue::waitForMessageTimed() if timer is active.
+ * dom/WorkerRunLoop.h:
+ Add member of type OwnPtr<WorkerSharedTimer>
+
+2009-02-03 Steve Falkenburg <sfalken@apple.com>
Build fix.
- * WebCore.base.exp:
+ * WebCore.vcproj/WebCore.vcproj:
+
+2009-02-03 Alexey Proskuryakov <ap@webkit.org>
+
+ Windows build fix.
+
+ * dom/CrossThreadCopier.h: Changed forward declarations to use struct instead of class where
+ appropriate.
+
+2009-02-02 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23636: Make the async api of ThreadableLoader functional for the worker context.
+ <https://bugs.webkit.org/show_bug.cgi?id=23636>
+
+ Enable the async portion of ThreadableLoader for workers.
+
+ No observable change in behavior, so no test.
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * dom/CrossThreadCopier.h:
+ * dom/GenericWorkerTask.h:
+ * dom/WorkerThread.cpp:
+ * loader/ThreadableLoader.cpp:
+ (WebCore::ThreadableLoader::create):
+ * loader/ThreadableLoaderClient.h:
+ (WebCore::ThreadableLoaderClient::didFinishLoading):
+ * loader/ThreadableLoaderClientWrapper.h: Added.
+ (WebCore::ThreadableLoaderClientWrapper::create):
+ (WebCore::ThreadableLoaderClientWrapper::clearClient):
+ (WebCore::ThreadableLoaderClientWrapper::didSendData):
+ (WebCore::ThreadableLoaderClientWrapper::didReceiveResponse):
+ (WebCore::ThreadableLoaderClientWrapper::didReceiveData):
+ (WebCore::ThreadableLoaderClientWrapper::didFinishLoading):
+ (WebCore::ThreadableLoaderClientWrapper::didFail):
+ (WebCore::ThreadableLoaderClientWrapper::didGetCancelled):
+ (WebCore::ThreadableLoaderClientWrapper::didReceiveAuthenticationCancellation):
+ (WebCore::ThreadableLoaderClientWrapper::ThreadableLoaderClientWrapper):
+ * loader/WorkerThreadableLoader.cpp: Added.
+ (WebCore::WorkerThreadableLoader::WorkerThreadableLoader):
+ (WebCore::WorkerThreadableLoader::~WorkerThreadableLoader):
+ (WebCore::WorkerThreadableLoader::cancel):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::MainThreadBridge):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::mainThreadDestroy):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::destroy):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::mainThreadCancel):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::cancel):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::clearClientWrapper):
+ (WebCore::workerContextDidSendData):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didSendData):
+ (WebCore::workerContextDidReceiveResponse):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didReceiveResponse):
+ (WebCore::workerContextDidReceiveData):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didReceiveData):
+ (WebCore::workerContextDidFinishLoading):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFinishLoading):
+ (WebCore::workerContextDidFail):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didFail):
+ (WebCore::workerContextDidGetCancelled):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didGetCancelled):
+ (WebCore::workerContextDidReceiveAuthenticationCancellation):
+ (WebCore::WorkerThreadableLoader::MainThreadBridge::didReceiveAuthenticationCancellation):
+ * loader/WorkerThreadableLoader.h: Added.
+ (WebCore::WorkerThreadableLoader::create):
+ (WebCore::WorkerThreadableLoader::refThreadableLoader):
+ (WebCore::WorkerThreadableLoader::derefThreadableLoader):
+
+2009-02-02 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23636: Make the async api of ThreadableLoader functional for the worker context.
+ <https://bugs.webkit.org/show_bug.cgi?id=23636>
+
+ No observable change in behavior, so no test.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Worker.cpp:
+ * dom/Worker.h:
+ * dom/WorkerContext.cpp:
+ (WebCore::WorkerContext::addMessage):
+ (WebCore::WorkerContext::postTask):
+ (WebCore::WorkerContext::postTaskToWorkerObject):
+ * dom/WorkerContext.h:
+ * dom/WorkerMessagingProxy.cpp:
+ (WebCore::MessageWorkerContextTask::performTask):
+ (WebCore::WorkerMessagingProxy::postMessageToWorkerContext):
+ (WebCore::WorkerMessagingProxy::postTaskToWorkerContext):
+ Expose postTaskToWorkerContext for use by the worker object thread.
+
+ (WebCore::WorkerMessagingProxy::postTaskToWorkerObject):
+ Change the name of postTaskToParentContext to postTaskToWorkerObject for consistency
+ with postMessageToWorkerObject.
+
+ * dom/WorkerMessagingProxy.h:
+ * dom/WorkerRunLoop.cpp:
+ (WebCore::WorkerRunLoop::run):
+ (WebCore::WorkerRunLoop::postTask):
+ * dom/WorkerRunLoop.h:
+ * dom/WorkerTask.cpp: Removed.
+ * dom/WorkerTask.h: Removed.
+ Removed WorkerTask and replaced with the existing ScriptExecutionContext::Task.
+
+ The resulted in the class going away along with an adapter that made
+ a ScriptExecutionContext::Task look like a WorkerTask.
+
+ * dom/WorkerThread.cpp:
+ * dom/WorkerThread.h:
+
+2009-02-02 David Levin <levin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23618: Templated worker tasks should be more error proof to use.
+ <https://bugs.webkit.org/show_bug.cgi?id=23618>
+
+ Add the generic worker tasks templates needed for the WorkerThreadableLoader.
+
+ No observable change in behavior, so no test.
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * dom/CrossThreadCopier.cpp: Added.
+ * dom/CrossThreadCopier.h: Added.
+ (WebCore::CrossThreadCopierPassThrough::copy):
+ * dom/GenericWorkerTask.h:
+ Stop doing the WorkerMessagingProxy::askedToTerminate call automatically
+ in performTask because was not obvious that it would be done and not always needed.
+
+ (WebCore::GenericWorkerTask1::create):
+ (WebCore::GenericWorkerTask1::GenericWorkerTask1):
+ (WebCore::GenericWorkerTask1::performTask):
+ (WebCore::GenericWorkerTask2::create):
+ (WebCore::GenericWorkerTask2::GenericWorkerTask2):
+ (WebCore::GenericWorkerTask2::performTask):
+ (WebCore::GenericWorkerTask3::create):
+ (WebCore::GenericWorkerTask3::GenericWorkerTask3):
+ (WebCore::GenericWorkerTask3::performTask):
+ (WebCore::GenericWorkerTask4::create):
+ (WebCore::GenericWorkerTask4::GenericWorkerTask4):
+ (WebCore::GenericWorkerTask4::performTask):
+ (WebCore::GenericWorkerTask5::create):
+ (WebCore::GenericWorkerTask5::GenericWorkerTask5):
+ (WebCore::GenericWorkerTask5::performTask):
+ (WebCore::GenericWorkerTask6::create):
+ (WebCore::GenericWorkerTask6::GenericWorkerTask6):
+ (WebCore::GenericWorkerTask6::performTask):
+ (WebCore::GenericWorkerTask7::create):
+ (WebCore::GenericWorkerTask7::GenericWorkerTask7):
+ (WebCore::GenericWorkerTask7::performTask):
+ (WebCore::createCallbackTask):
+ * dom/WorkerContext.cpp:
+ (WebCore::addMessageTask):
+ (WebCore::WorkerContext::addMessage):
+ * dom/WorkerMessagingProxy.h:
+ (WebCore::WorkerMessagingProxy::askedToTerminate):
+
+2009-02-02 Sam Weinig <sam@webkit.org>
+
+ Reviewed by David "The Barnabas Jones" Hyatt.
+
+ Move removeChildNode, appendChildNode and insertChildNode from
+ RenderContainer into RenderObjectChildList. Make moveChildNode
+ static in RenderBlock, as that was the only user.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::moveChild):
+ (WebCore::RenderBlock::makeChildrenNonInline):
+ (WebCore::RenderBlock::removeChild):
+ (WebCore::RenderBlock::handleRunInChild):
+ * rendering/RenderContainer.cpp:
+ (WebCore::RenderContainer::addChild):
+ (WebCore::RenderContainer::removeChild):
+ * rendering/RenderContainer.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::splitFlow):
+ (WebCore::RenderInline::childBecameNonInline):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::handleDynamicFloatPositionChange):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::createsAnonymousWrapper):
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::updateListMarkerNumbers):
+ (WebCore::RenderObjectChildList::removeChildNode):
+ (WebCore::RenderObjectChildList::appendChildNode):
+ (WebCore::RenderObjectChildList::insertChildNode):
+ * rendering/RenderObjectChildList.h:
+ * rendering/RenderSVGContainer.cpp:
+ (WebCore::RenderSVGContainer::addChild):
+ (WebCore::RenderSVGContainer::removeChild):
+ * rendering/RenderSVGContainer.h:
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::removeChild):
+ * rendering/RenderTable.h:
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::removeChild):
+ * rendering/RenderTableSection.h:
+
+2009-02-02 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Alder.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23697
+ Leaks seen on Worker tests
+
+ * dom/WorkerMessagingProxy.cpp: (WebCore::WorkerMessagingProxy::workerContextDestroyedInternal):
+ Zero out m_workerThread, so that the proxy could be deleted once workerObjectDestroyed()
+ is called.
+
+2009-02-02 David Hyatt <hyatt@apple.com>
+
+ Move positionForCoordinates up from RenderContainer into RenderBox.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::positionForCoordinates):
+ * rendering/RenderBox.h:
+ * rendering/RenderContainer.cpp:
+ * rendering/RenderContainer.h:
+
+2009-02-02 Hiroaki Nakamura <hnakamur@gmail.com>
+
+ Reviewed by Adam Roben.
+
+ Fixes https://bugs.webkit.org/show_bug.cgi?id=15813
+ Modify pre-build step to properly handle the errorlevel
+ shell command.
+
+ * WebCore.vcproj/WebCore.vcproj: Change errorlevel handling
+ for all targets so prefast is only enabled in builds
+ where /analyze is available.
+
+2009-02-02 David Hyatt <hyatt@apple.com>
+
+ Refactor the handling of before/after content and generated content. Move most of the functions from
+ RenderContainer into RenderObjectChildList.
+
+ Reviewed by Sam Weinig
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::updateBeforeAfterContent):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::isAfterContent):
+ * rendering/RenderBox.h:
+ * rendering/RenderButton.cpp:
+ (WebCore::RenderButton::updateBeforeAfterContent):
+ * rendering/RenderContainer.cpp:
+ * rendering/RenderContainer.h:
+ * rendering/RenderCounter.cpp:
+ (WebCore::destroyCounterNodeChildren):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::splitInlines):
+ * rendering/RenderObject.h:
+ * rendering/RenderObjectChildList.cpp:
+ (WebCore::beforeAfterContainer):
+ (WebCore::findBeforeAfterParent):
+ (WebCore::invalidateCountersInContainer):
+ (WebCore::RenderObjectChildList::invalidateCounters):
+ (WebCore::RenderObjectChildList::updateBeforeAfterContent):
+ * rendering/RenderObjectChildList.h:
+
+2009-02-02 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23661
+ Fix Chromium build.
+
+ * history/HistoryItem.h: need to include <wtf/OwnPtr.h>
+
+ * rendering/RenderThemeChromiumMac.mm:
+ (WebCore::RenderThemeChromiumMac::adjustMenuListStyle): isEnabled() is now on FormControlElement.
+
+2009-02-02 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ * plugins/PluginView.cpp:
+ (WebCore::PluginView::performRequest):
+
+2009-02-02 Geoffrey Garen <ggaren@apple.com>
- Merge r40508.
+ Build fix.
+
+ * WebCore.base.exp:
- 2009-02-02 Geoffrey Garen <ggaren@apple.com>
+2009-02-02 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
Track redirects in global history.
* WebCore.base.exp: Renamed some exports.
-
+
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::createWindow):
(windowProtoFuncOpen):
@@ -362,7 +18477,7 @@
* loader/EmptyClients.h:
(WebCore::EmptyFrameLoaderClient::updateGlobalHistoryForRedirectWithoutHistoryItem):
Stubbed out a client function to keep things building.
-
+
* loader/FrameLoader.cpp:
(WebCore::isBackForwardLoadType):
(WebCore::FrameLoader::restoreDocumentState): Renamed FrameLoadTypeRedirect =>
@@ -393,13 +18508,13 @@
(WebCore::FrameLoader::continueFragmentScrollAfterNavigationPolicy):
(WebCore::FrameLoader::continueLoadAfterNewWindowPolicy):
(WebCore::FrameLoader::loadItem): Updated for extra parameter and rename.
-
+
(WebCore::FrameLoader::updateHistory*): Notify WebKit about redirect
navigations even if they don't create new history items, so we can track
the redirect in the existing history item.
* loader/FrameLoader.h: See above.
-
+
* loader/FrameLoaderClient.h: New client interface used by
FrameLoader::updateHistory* to record a redirect even if it doesn't create
a new history item of its own.
@@ -412,29 +18527,998 @@
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::dataChanged): Updated for extra parameter.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-02-02 David Hyatt <hyatt@apple.com>
- Merge r40380.
+ Make calcPrefWidths non-abstract on RenderBox and just give it RenderContainer's implementation.
+ Remove RenderSVGContainer's implementation, since it was never called.
- 2009-01-29 Sam Weinig <sam@webkit.org>
+ Reviewed by Beth Dakin
- Reviewed by Mark Rowe.
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::minPrefWidth):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::calcPrefWidths):
+ * rendering/RenderContainer.h:
+ (WebCore::RenderContainer::moveChildNode):
+ * rendering/RenderSVGContainer.h:
- First step in tracking the urls a HistoryItem was redirected through.
+2009-02-02 Anders Carlsson <andersca@apple.com>
- * WebCore.base.exp:
+ Reviewed by Sam Weinig.
+
+ Add jsObjectForPluginElement to ScriptController, and have createScriptObjectForPluginElement call it.
+
+ * WebCore.LP64.exp:
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::createScriptObjectForPluginElement):
+ (WebCore::ScriptController::jsObjectForPluginElement):
+ * bindings/js/ScriptController.h:
+
+2009-02-02 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel (and Ojan Vafai).
+
+ https://bugs.webkit.org/show_bug.cgi?id=23696
+ Select element doesn't show new value when focus is switched in
+ onchange event.
+
+ Fix PopupMenuChromium to hide itself before calling valueChanged. This
+ better matches the behavior of the other ports.
+
+ * platform/chromium/PopupMenuChromium.cpp:
+ (WebCore::PopupListBox::create):
+ (WebCore::PopupContainer::PopupContainer):
+ (WebCore::PopupContainer::showPopup):
+ (WebCore::PopupContainer::hidePopup):
+ (WebCore::PopupListBox::abandon):
+ (WebCore::PopupListBox::acceptIndex):
+ (WebCore::PopupMenu::show):
+ (WebCore::PopupMenu::hide):
+
+2009-02-02 David Hyatt <hyatt@apple.com>
+
+ Make sure scrollWidth/Height just return 0 for inline flows.
+
+ Reviewed by Beth Dakin
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::scrollWidth):
+ (WebCore::RenderBox::scrollHeight):
+
+2009-02-02 Darin Adler <darin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Bug 23676: Speed up uses of reserveCapacity on new vectors by adding a new reserveInitialCapacity
+ https://bugs.webkit.org/show_bug.cgi?id=23676
+
+ * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+ (WebCore::cssPropertyName):
+ * css/CSSMutableStyleDeclaration.cpp:
+ (WebCore::CSSMutableStyleDeclaration::CSSMutableStyleDeclaration):
+ (WebCore::CSSMutableStyleDeclaration::removePropertiesInSet):
+ * css/CSSPrimitiveValue.cpp:
+ (WebCore::CSSPrimitiveValue::cssText):
+ * css/CSSStyleDeclaration.cpp:
+ (WebCore::CSSStyleDeclaration::copyPropertiesInSet):
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::sortMatchedRules):
+ * dom/Document.cpp:
+ (WebCore::Document::formElementsState):
+ * dom/NamedAttrMap.h:
+ (WebCore::NamedAttrMap::reserveInitialCapacity):
+ * editing/TextIterator.cpp:
+ (WebCore::CharacterIterator::string):
+ (WebCore::SearchBuffer::SearchBuffer):
+ (WebCore::plainTextToMallocAllocatedBuffer):
+ * editing/markup.cpp:
+ (WebCore::joinMarkups):
* history/HistoryItem.cpp:
(WebCore::HistoryItem::HistoryItem):
- (WebCore::HistoryItem::addRedirectURL):
- (WebCore::HistoryItem::redirectURLs):
- (WebCore::HistoryItem::setRedirectURLs):
- * history/HistoryItem.h:
+ * html/HTMLTokenizer.cpp:
+ (WebCore::Token::addAttribute):
+ * loader/appcache/DOMApplicationCache.cpp:
+ (WebCore::DOMApplicationCache::items):
+ * page/SecurityOrigin.cpp:
+ (WebCore::SecurityOrigin::toString):
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (convertToVector):
+ * platform/graphics/FontCache.cpp:
+ (WebCore::FontCache::purgeInactiveFontData):
+ (WebCore::FontCache::invalidate):
+ * platform/network/FormData.cpp:
+ (WebCore::FormData::deepCopy):
+ * platform/network/HTTPHeaderMap.cpp:
+ (WebCore::HTTPHeaderMap::copyData):
+ * platform/network/ResourceRequestBase.cpp:
+ (WebCore::ResourceRequestBase::copyData):
+ * platform/network/mac/FormDataStreamMac.mm:
+ (WebCore::formCreate):
+ * xml/XPathNodeSet.cpp:
+ (WebCore::XPath::NodeSet::sort):
+ Use reserveInitialCapacity instead of of reserveCapacity in all these call sites,
+ which are working on new vectors that are guaranteed not to be empty.
+
+2009-02-26 Jon Honeycutt <jhoneycutt@apple.com>
+
+ Build fix after r40486.
+
+ Rubber-stamped by Ada Chan.
+
+ * dom/Document.h: Changed HitTestRequest to a class from a struct.
+ * page/EventHandler.h: Ditto.
+ * rendering/EllipsisBox.h: Ditto.
+ * rendering/InlineBox.h: Ditto.
+ * rendering/InlineFlowBox.h: Ditto.
+ * rendering/RenderLayer.h: Ditto.
+
+2009-02-02 Darin Adler <darin@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ Bug 23694: REGRESSION: Running svg/custom tests crashes, randomly, depending on the order of tests
+ https://bugs.webkit.org/show_bug.cgi?id=23694
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::insertedIntoDocument): Added back the call through to EventTargetNode.
+ (WebCore::ContainerNode::removedFromDocument): Ditto.
+ * dom/EventTargetNode.cpp:
+ (WebCore::EventTargetNode::insertedIntoDocument): Changed this to not call through to Node.
+ (WebCore::EventTargetNode::removedFromDocument): Ditto.
+ * dom/Node.cpp:
+ (WebCore::Node::insertedIntoDocument): Updated comment.
+ (WebCore::Node::removedFromDocument): Ditto.
+
+2009-02-02 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ More plug-in cleanup.
+
+ * WebCore.NPAPI.exp:
+ Add new symbols.
+
+ * bindings/objc/DOM.mm:
+ * bindings/objc/DOMPrivate.h:
+ Remove methods that WebKit doesn't use anymore.
+
+2009-02-02 Jay Campan <jcampan@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Clean up PopupMenuChromium a little.
+ https://bugs.webkit.org/show_bug.cgi?id=23653
+
+ No functional changes, only code cleanup, thus no tests.
+
+ * platform/chromium/PopupMenuChromium.cpp:
+ (WebCore::):
+ (WebCore::PopupListBox::PopupListBox):
+ (WebCore::PopupContainer::create):
+ (WebCore::PopupContainer::PopupContainer):
+ (WebCore::PopupContainer::showPopup):
+ (WebCore::PopupListBox::handleKeyEvent):
+ (WebCore::PopupListBox::isSelectableItem):
+ (WebCore::PopupListBox::selectNextRow):
+ (WebCore::PopupListBox::selectPreviousRow):
+ (WebCore::PopupMenu::show):
+ * platform/chromium/PopupMenuChromium.h:
+
+2009-02-02 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Change createPlugin to take a HTMLPlugInElement, and createJavaAppletWidget to take a HTMLAppletElement.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/EmptyClients.h:
+ (WebCore::EmptyFrameLoaderClient::createPlugin):
+ (WebCore::EmptyFrameLoaderClient::createJavaAppletWidget):
+ * loader/FrameLoader.cpp:
+ (WebCore::toPlugInElement):
+ (WebCore::FrameLoader::loadPlugin):
+ (WebCore::FrameLoader::loadItem):
+ * loader/FrameLoader.h:
+ * loader/FrameLoaderClient.h:
+
+2009-02-02 Genevieve Mak <gen@staikos.net>
+
+ Reviewed by George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23508
+ Returns Blank Page for all "about" protocols
+
+ * loader/MainResourceLoader.cpp:
+ Fix shouldLoadAsEmptyDocument() to return a blank page for an empty
+ url or about:blank only (for now, exclusively for Torch Mobile platform).
+
+2009-02-02 Brent Fulgham <bfulgham@webkit.org>
+
+ Reviewed by George Staikos.
+
+ Fixes https://bugs.webkit.org/show_bug.cgi?id=23691.
+ Correct build break caused by @r40366 by moving the
+ common code implmentations from GraphicsContextCGWin.cpp
+ into the base Windows class (GraphicsContextWin.cpp). Also
+ move inTransparencyLayer since it is identical in both
+ children.
+
+ * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h:
+ Added member m_shouldIncludeChildWindows to Windows version,
+ similar to GraphicsContextPlatformPrivateCG.h.
+ * platform/graphics/win/GraphicsContextCGWin.cpp: Remove the
+ implementations of shouldIncludeChildWindows,
+ setShouldIncludeChildWindows, and inTransparencyLayer.
+ * platform/graphics/win/GraphicsContextCairoWin.cpp: Remove
+ the implementation of inTransparencyLayer.
+ * platform/graphics/win/GraphicsContextWin.cpp: Move common code
+ from GraphicsContextCGWin.cpp and GraphicsContextCairoWin.cpp.
+ (WebCore::GraphicsContext::inTransparencyLayer):
+ (WebCore::GraphicsContext::setShouldIncludeChildWindows):
+ (WebCore::GraphicsContext::shouldIncludeChildWindows):
+
+2009-02-02 Darin Adler <darin@apple.com>
+
+ Try to fix Wx build, and maybe Chromium build too.
+
+ * WebCore.scons: Added IdentifierRep.cpp.
+ * WebCoreSources.bkl: Ditto.
+
+2009-02-02 Darin Adler <darin@apple.com>
+
+ Try to fix Wx build.
+
+ * html/HTMLAreaElement.cpp: Added missing include of "Path.h".
+
+2009-02-02 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Nikolas Zimmermann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23587
+ Refactor HitTestRequest to eliminate all the ugly boolean arguments and
+ use an enum bitflag instead. Cleanup all the code that constructs the
+ various HitTestRequests to make the code more readable.
+
+ * dom/Document.cpp:
+ (WebCore::Document::elementFromPoint):
+ (WebCore::Document::prepareMouseEvent):
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::contains):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::visiblePositionForPoint):
+ (WebCore::AccessibilityRenderObject::doAccessibilityHitTest):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::eventMayStartDrag):
+ (WebCore::EventHandler::updateSelectionForMouseDrag):
+ (WebCore::EventHandler::hitTestResultAtPoint):
+ (WebCore::EventHandler::handleMousePressEvent):
+ (WebCore::EventHandler::handleMouseDoubleClickEvent):
+ (WebCore::EventHandler::handleMouseMoveEvent):
+ (WebCore::EventHandler::handleMouseReleaseEvent):
+ (WebCore::EventHandler::updateDragAndDrop):
+ (WebCore::EventHandler::handleWheelEvent):
+ (WebCore::EventHandler::sendContextMenuEvent):
+ (WebCore::EventHandler::hoverTimerFired):
+ (WebCore::EventHandler::handleDrag):
+ * page/EventHandler.h:
+ * rendering/HitTestRequest.h:
+ (WebCore::HitTestRequest::):
+ (WebCore::HitTestRequest::HitTestRequest):
+ (WebCore::HitTestRequest::readOnly):
+ (WebCore::HitTestRequest::active):
+ (WebCore::HitTestRequest::mouseMove):
+ (WebCore::HitTestRequest::mouseUp):
+ (WebCore::HitTestRequest::ignoreClipping):
+ * rendering/RenderFrameSet.cpp:
+ (WebCore::RenderFrameSet::nodeAtPoint):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTest):
+ (WebCore::RenderLayer::hitTestLayer):
+ (WebCore::RenderLayer::updateHoverActiveState):
+
+2009-02-02 George Staikos <george.staikos@torchmobile.com>
+
+ Reviewed by Niko Zimmermann.
+
+ Fix WML build by including the inlined renderStyle().
+
+ * wml/WMLOptGroupElement.cpp:
+ * wml/WMLOptionElement.cpp:
+
+2009-02-02 Darin Adler <darin@apple.com>
+
+ Reviewed by Niko Zimmermann.
+
+ Bug 23686: REGRESSION (r40475): Failure in fast/xpath/4XPath/Core/test_core_functions.html
+ https://bugs.webkit.org/show_bug.cgi?id=23686
+ rdar://problem/6547971
+
+ Also fix other XPath tests that are crashing.
+
+ * xml/XPathFunctions.cpp:
+ (WebCore::XPath::FunLang::evaluate): Fix order of arguments when creating QualifiedName.
+ * xml/XPathStep.cpp:
+ (WebCore::XPath::Step::nodesInAxis): Use createAttrIfNeeded() rather than attr() since we
+ need to make Attr nodes here. Yuck!
+
+2009-02-02 Yichao Yin <yichao.yin@torchmobile.com.cn>
+
+ Reviewed by Niko Zimmermann.
+
+ Test: wml/input-format.html
+
+ * wml/WMLInputElement.cpp:
+ (WebCore::WMLInputElement::WMLInputElement):
+ (WebCore::formatCodes):
+ (WebCore::WMLInputElement::dispatchBlurEvent):
+ (WebCore::WMLInputElement::parseMappedAttribute):
+ (WebCore::WMLInputElement::attach):
+ (WebCore::WMLInputElement::defaultEventHandler):
+ (WebCore::WMLInputElement::init):
+ (WebCore::WMLInputElement::validateInputMask):
+ (WebCore::WMLInputElement::isConformedToInputMask):
+ (WebCore::WMLInputElement::cursorPositionToMaskIndex):
+ * wml/WMLInputElement.h:
+
+2009-02-02 Brent Fulgham <bfulgham@webkit.org>
+
+ Build fix only, no review.
+
+ Fixes https://bugs.webkit.org/show_bug.cgi?id=23685.
+ Correct build break caused by @r40473.
+
+ * page/win/FrameWin.cpp: Correct access for adjustPageHeight.
+ (WebCore::computePageRectsForFrame):
+
+2009-02-02 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Not reviewed. Fix WML enabled builds.
+ FrameLoader::urlSelected() got a new parameter: lockBackForwardList. Pass 'false', as HTMLAnchorElement does.
+
+ * wml/WMLAElement.cpp:
+ (WebCore::WMLAElement::defaultEventHandler):
+
+2009-02-02 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6451610> Reloading a AppCache page doesn't ever hit the server
+
+ Not easily testable.
+
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::createResourceHandle): A new method that creates a resource
+ handle in a manner that is closer to what CachedResource does. We now make conditional
+ requests for better performance, and set max-age to ensure that stale responses are not used.
+ (WebCore::ApplicationCacheGroup::update): Use the new createResourceHandle() method.
+ (WebCore::ApplicationCacheGroup::didReceiveResponse): If the response code for the resource
+ is 304, take it from the newest cache.
+ (WebCore::ApplicationCacheGroup::didFail): Pre-compute request URL.
+ (WebCore::ApplicationCacheGroup::didReceiveManifestResponse): Don't create a resource for
+ the manifest if the response code was 304 - it won't be needed.
+ (WebCore::ApplicationCacheGroup::didReceiveManifestData): Replaced an assertion that
+ m_manifestResource is not null with a check.
+ (WebCore::ApplicationCacheGroup::didFinishLoadingManifest): Treat null m_manifestResource as
+ an indication that the response was 304.
+ (WebCore::ApplicationCacheGroup::startLoadingEntry): Use createResourceHandle().
+
+ * loader/appcache/ApplicationCacheGroup.h: Added createResourceHandle().
+
+2009-02-01 Darin Adler <darin@apple.com>
+
+ Reviewed by Dave Hyatt.
+
+ Bug 23674: Speed up some things based on profiling the page load test
+ https://bugs.webkit.org/show_bug.cgi?id=23674
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::canShareStyleWithElement): Use the newly named cssTarget instead
+ of the old name, getCSSTarget.
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): Ditto.
+
+ * dom/ContainerNode.cpp:
+ (WebCore::ContainerNode::insertedIntoDocument): Moved code from Node in here rather than
+ calling through to EventTargetNode::insertedIntoDocument.
+ (WebCore::ContainerNode::removedFromDocument): Ditto.
+ (WebCore::ContainerNode::insertedIntoTree): Tweaked a bit.
+ (WebCore::ContainerNode::removedFromTree): Ditto.
+
+ * dom/ContainerNode.h: Moved the constructor definition here and made it inline.
+
+ * dom/Document.cpp:
+ (WebCore::Document::removeAllEventListenersFromAllNodes): Iterate the document element and
+ its contents only to avoid the document type node. This allows us to remove the virtual
+ function call to isEventTargetNode from the loop.
+ (WebCore::Document::setCSSTarget): Changed argument to be an Element rather than Node.
+
+ * dom/Document.h: Changed CSS target to be an Element rather than a Node. Renamed
+ getCSSTarget to cssTarget.
+
+ * dom/EventTargetNode.cpp:
+ (WebCore::EventTargetNode::removeAllEventListenersSlowCase): Renamed and turned the
+ rare data check into an assertion.
+
+ * dom/EventTargetNode.h: Made the fast case of removeAllEventListeners be inline.
+ Also moved the constructor definition here and made it inline. And added toEventTargetNode,
+ matching the design of the render tree checked casts. Later we can migrate all callers
+ from EventTargetNodeCast to toEventTargetNode.
+
+ * dom/NamedAttrMap.cpp:
+ (WebCore::NamedAttrMap::detachAttributesFromElement): Added. Factored out from
+ clearAttributes, so we could use this loop in cases where we're not clearing the attributes.
+ (WebCore::NamedAttrMap::~NamedAttrMap): Call detachAttributesFromElement instead of
+ clearAttributes here.
+ (WebCore::NamedAttrMap::clearAttributes): Call detachAttributesFromElement here.
+ (WebCore::NamedAttrMap::detachFromElement): Call detachAttributesFromElement instead of
+ clearAttributes. We don't need to clear the attributes array just because the element is
+ going away, so don't.
+ (WebCore::NamedAttrMap::virtualLength): Added.
+
+ * dom/NamedAttrMap.h: Made all the virtual functions inherited from NamedNodeMap be private.
+ These are all unnecessarily inefficient for use outside the DOM. Changed length to be a
+ non-virtual function. This was a fairly hot function.
+
+ * dom/NamedMappedAttrMap.cpp:
+ (WebCore::NamedMappedAttrMap::setClass): Changed to use element() function now that the
+ m_element data member is private.
+
+ * dom/NamedMappedAttrMap.h: Made a few functions private. Made the
+ hasMappedAttributes function non-virtual.
+
+ * dom/NamedNodeMap.h: Made length a non-virtual inline function that calls a virtual
+ function, name virtualLength. This lets NamedAttrMap::length be a non-virtual function.
+
+ * dom/Node.cpp:
+ (WebCore::Node::insertedIntoDocument): Removed call to insertedIntoTree, since it's
+ only non-empty in subclasses of ContainerNode.
+ (WebCore::Node::removedFromDocument): Ditto. Also removed setCSSTarget. Since a CSS
+ target has to be an Element, this can be moved down to ContainerNode (or it could be
+ moved down to Element for that matter).
+
+ * dom/QualifiedName.cpp:
+ (WebCore::QualifiedName::QualifiedName): Removed double initialization of m_impl.
+
+ * dom/QualifiedName.h: Moved the destructor, copy constructor, assignment operator, and
+ setPrefix function definitions into the header and made them inline.
+
+ * html/HTMLAreaElement.cpp:
+ (WebCore::HTMLAreaElement::mapMouseEvent): Updated since the stored region is now
+ an OwnPtr.
+ (WebCore::HTMLAreaElement::accessKey): Use AtomicString.
+ (WebCore::HTMLAreaElement::setAccessKey): Ditto.
+ (WebCore::HTMLAreaElement::alt): Ditto.
+ (WebCore::HTMLAreaElement::setAlt): Ditto.
+ (WebCore::HTMLAreaElement::coords): Ditto.
+ (WebCore::HTMLAreaElement::setCoords): Ditto.
+ (WebCore::HTMLAreaElement::setHref): Ditto.
+ (WebCore::HTMLAreaElement::shape): Ditto.
+ (WebCore::HTMLAreaElement::setShape): Ditto.
+ (WebCore::HTMLAreaElement::setTarget): Ditto.
+
+ * html/HTMLAreaElement.h: Use AtomicString in the getter and setter DOM operations.
+ Change the region data member to be an OwnPtr<Path> instead of a Path to optimize
+ the common case where an area element is parsed but never hit-tested. This could
+ also have been done by changing the Path class's null case to be more efficient,
+ but this seems fine.
+
+ * html/HTMLViewSourceDocument.cpp:
+ (WebCore::HTMLViewSourceDocument::createContainingTable): Use addAttribute instead
+ of insertAttribute.
+ (WebCore::HTMLViewSourceDocument::addSpanWithClassName): Ditto.
+ (WebCore::HTMLViewSourceDocument::addLine): Ditto.
+ (WebCore::HTMLViewSourceDocument::addLink): Ditto.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::gotoAnchor): Use cssTarget under its new name instead
+ of its old name getCSSTarget.
+
+ * platform/graphics/GlyphWidthMap.cpp:
+ (WebCore::GlyphWidthMap::locatePageSlowCase): Refactored from locatePage.
+
+ * platform/graphics/GlyphWidthMap.h: Made most of this class inline.
+ Changed m_pages to use OwnPtr.
+
+ * platform/text/PlatformString.h: Remove include no longer needed since
+ StringImpl.h includes it.
+
+ * platform/text/StringImpl.cpp:
+ (WebCore::StringImpl::createStrippingNullCharactersSlowCase): Refactored
+ from createStrippingNullCharacters.
+ * platform/text/StringImpl.h: Moved the definition of
+ createStrippingNullCharacters here and made it inline.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::firstLineStyleSlowCase): Refactored from
+ firstLineStyle.
+
+ * rendering/RenderObject.h: Moved the definition of the firstLineStyle
+ function here and made it inline. Moved the definition of the
+ documentBeingDestroyed function here and made it inline.
+
+ * svg/SVGSVGElement.cpp:
+ (WebCore::SVGSVGElement::getCTM): Use getAttributeItem instead of
+ getNamedItem here since it accomplishes the same thing but is more efficient.
+ (WebCore::SVGSVGElement::getScreenCTM): Ditto.
+ * svg/SVGStyledElement.cpp:
+ (WebCore::SVGStyledElement::getPresentationAttribute): Ditto.
+
+ * xml/XPathFunctions.cpp:
+ (WebCore::XPath::FunLang::evaluate): Use getAttributeItem instead of
+ getNamedItemNS.
+
+ * xml/XPathStep.cpp:
+ (WebCore::XPath::Step::nodesInAxis): Use attributeItem instead of item here.
+
+2009-02-02 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Darin Adler.
+
+ Move Frame::forceLayout, Frame::adjustPageHeight and Frame::forceLayoutWithPageWidthRange to FrameView
+
+ https://bugs.webkit.org/show_bug.cgi?id=23428
+
+ FrameView::forceLayout could be killed but the comment might
+ contain a value over the the plain FrameView::layout...
+
+ Adjust the WebCore/WebKit consumers of these methods.
+
+ * WebCore.base.exp:
+ * page/Frame.cpp:
+ (WebCore::Frame::setPrinting):
+ * page/Frame.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::forceLayout):
+ (WebCore::FrameView::forceLayoutWithPageWidthRange):
+ (WebCore::FrameView::adjustPageHeight):
+ * page/FrameView.h:
+ * page/PrintContext.cpp:
+ (WebCore::PrintContext::computePageRects):
+
+2009-02-01 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by John Sullivan.
+
+ - fix <rdar://problem/6546625> REGRESSION (r40432): iframes added to global history at haaretz.co.il
+
+ Fixes http/tests/navigation/multiple-back-forward-entries.html
+
+ r40432 added a parameter to FrameLoader::scheduleLocationChange() and
+ failed to update all call sites.
+
+ * bindings/js/JSDOMWindowBase.cpp:
+ (WebCore::createWindow): Pass the lockBackForwardHistory parameter,
+ giving it the same value as the lockHistory parameter.
+ (windowProtoFuncOpen): Ditto.
+ * bindings/js/JSDOMWindowCustom.cpp:
+ (WebCore::JSDOMWindow::setLocation): Ditto.
+ * bindings/js/JSDocumentCustom.cpp:
+ (WebCore::JSDocument::setLocation): Ditto.
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::requestFrame): Ditto.
+
+2009-01-31 Dan Bernstein <mitz@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ - fix <rdar://problem/6546549> Eliminate some RenderText::width() overhead from findNextLineBreak()
+
+ On the PLT, this results in 0.36x the number of virtual function calls
+ to RenderText::width() and 0.69x the number of calls to
+ Font::isFixedPitch(), but makes 1.0004x the number of calls to
+ Font::width().
+
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::width): Replaced bounds checks on 'from' and 'len'
+ with an assertion.
+ * rendering/bidi.cpp:
+ (WebCore::textWidth): Added this inlined helper function which calls
+ Font::width() directly in the non-fixed-pitch, non-full-range case, and
+ otherwise calls RenderText::width().
+ (WebCore::RenderBlock::findNextLineBreak): Cache whether the font has
+ fixed pitch (in which case RenderText::width() will be called in order
+ to take advantage of the widthFromCache() optimization for fixed-pitch
+ fonts). Replaced all calls to RenderText::width() with calls to the
+ textWidth() helper function.
+
+2009-01-31 David Hyatt <hyatt@apple.com>
+
+ Inline all of the setNeedsLayout method and its associated functions. Also inline setChildNeedsLayout
+ and setNeedsPositionedMovementLayout.
+
+ Reviewed by Dan Bernstein
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::setLayerNeedsFullRepaint):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::setNeedsLayout):
+ (WebCore::RenderObject::setChildNeedsLayout):
+ (WebCore::RenderObject::setNeedsPositionedMovementLayout):
+ (WebCore::objectIsRelayoutBoundary):
+ (WebCore::RenderObject::markContainingBlocksForLayout):
+
+2009-01-31 Darin Adler <darin@apple.com>
+
+ Fix Mac build.
+
+ * loader/FrameLoader.cpp: Moved FrameLoaderClient::hasHTMLView in here.
+ We need it to not be an inline. Sadly, FrameLoaderClient.cpp was prematurely
+ deleted and I don't want to bring it back just to fix the build.
+
+ * loader/FrameLoaderClient.h: Rearrange virtual functions and corrected
+ a possibly-confusing comment.
+
+2009-01-31 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by David Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23664
+ Remove unused dead code from RenderTable class. The dead code includes
+ two enums and the associated member variables as well as one getter function.
+
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::RenderTable):
+ * rendering/RenderTable.h:
+
+2009-01-31 David Hyatt <hyatt@apple.com>
+
+ More removal of code from RenderContainer. Move removeLeftoverAnonymousBlock down into RenderBlock.
+ Move destroyLeftoverChildren into the RenderObjectChildList. Convert all containers to use the
+ RenderObjectChildList.
+
+ Reviewed by Sam Weinig
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::destroy):
+ (WebCore::RenderBlock::addChild):
+ (WebCore::RenderBlock::removeLeftoverAnonymousBlock):
+ (WebCore::RenderBlock::layoutPositionedObjects):
+ (WebCore::RenderBlock::childBecameNonInline):
+ * rendering/RenderBlock.h:
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::layout):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::firstChildBox):
+ (WebCore::RenderBox::lastChildBox):
+ * rendering/RenderContainer.cpp:
+ (WebCore::RenderContainer::addChild):
+ (WebCore::RenderContainer::removeChildNode):
+ (WebCore::RenderContainer::updateBeforeAfterContentForContainer):
+ (WebCore::RenderContainer::appendChildNode):
+ (WebCore::RenderContainer::insertChildNode):
+ (WebCore::RenderContainer::positionForCoordinates):
+ (WebCore::RenderContainer::addLineBoxRects):
+ (WebCore::RenderContainer::collectAbsoluteLineBoxQuads):
+ * rendering/RenderContainer.h:
+ (WebCore::RenderContainer::virtualChildren):
+ (WebCore::RenderContainer::children):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::destroy):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::layout):
+ * rendering/RenderMedia.cpp:
+ (WebCore::RenderMedia::destroy):
+ (WebCore::RenderMedia::children):
+ * rendering/RenderMedia.h:
+ (WebCore::RenderMedia::virtualChildren):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::destroy):
+ (WebCore::RenderObject::layout):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::firstChild):
+ (WebCore::RenderObject::lastChild):
+ (WebCore::RenderObject::virtualChildren):
+ (WebCore::RenderObject::canHaveChildren):
+ * rendering/RenderObjectChildList.cpp: Added.
+ (WebCore::RenderObjectChildList::destroyLeftoverChildren):
+ * rendering/RenderObjectChildList.h:
+ * rendering/RenderReplaced.h:
+ (WebCore::RenderReplaced::canHaveChildren):
+ * rendering/RenderSVGContainer.cpp:
+ (WebCore::RenderSVGContainer::RenderSVGContainer):
+ (WebCore::RenderSVGContainer::destroy):
+ (WebCore::RenderSVGContainer::removeChildNode):
+ (WebCore::RenderSVGContainer::appendChildNode):
+ (WebCore::RenderSVGContainer::insertChildNode):
+ * rendering/RenderSVGContainer.h:
+ (WebCore::RenderSVGContainer::virtualChildren):
+ (WebCore::RenderSVGContainer::children):
+
+2009-01-31 David Hyatt <hyatt@apple.com>
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=11363
+
+ Remove the hacks in table code around the DeleteButtonController and fix tables so that positioned children don't get wrapped in anonymous objects.
+ With the removal of a non-positioned DeleteButtonController renderer, table layout can be tightened up to only lay out table sections. Table section
+ layout is tightened up to ignore non-table rows. When a table has multiple captions, only the real one will do a layout now. The other ones will
+ be properly ignored.
+
+ Reviewed by Oliver Hunt
+
+ * editing/DeleteButtonController.cpp:
+ (WebCore::DeleteButtonController::createDeletionUI):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::addChild):
+ (WebCore::RenderTable::layout):
+ * rendering/RenderTableSection.cpp:
+ (WebCore::RenderTableSection::layout):
+ * rendering/RenderTableSection.h:
+
+2009-01-31 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23663
+ Add a void toRenderBox() method which catches unnecessary casts at compile
+ time and also fix the four cases where this was happening.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::determineHorizontalPosition):
+ * rendering/RenderBox.h:
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutHorizontalBox):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::updateHitTestResult):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateLayerPosition):
+
+2009-01-30 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Sam Weinig.
+
+ Add a pref to disable web security.
+
+ * WebCore.base.exp:
+ * dom/Document.cpp:
+ (WebCore::Document::initSecurityContext):
+ * page/SecurityOrigin.cpp:
+ (WebCore::SecurityOrigin::SecurityOrigin):
+ (WebCore::SecurityOrigin::canAccess):
+ (WebCore::SecurityOrigin::canRequest):
+ (WebCore::SecurityOrigin::grantUniversalAccess):
+ * page/SecurityOrigin.h:
+ * page/Settings.cpp:
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setWebSecurityEnabled):
+ * page/Settings.h:
+ (WebCore::Settings::isWebSecurityEnabled):
+
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Build fix.
+
+ Move the inline virtual destructor after a non-inline virtual
+ function so that the symbol for the vtable is not marked as a
+ weakly exported symbol.
+
+ This trick was previously used at revision 36122 in JSObject.h
+
+ * loader/FrameLoaderClient.h:
+ (WebCore::FrameLoaderClient::~FrameLoaderClient):
+
+2009-01-30 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Stephanie Lewis
+
+ Inline SimpleFontData::widthForGlyph for a minor page load improvement.
+
+ * platform/graphics/SimpleFontData.cpp:
+ * platform/graphics/SimpleFontData.h:
+ (WebCore::SimpleFontData::widthForGlyph):
+
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Build fix for WX and maybe even Windows.
+
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCoreSources.bkl:
+
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Darin Adler.
+
+ Move Frame::sendResizeEvent and Frame::sendScrollEvent to EventHandler
+
+ Carry out the move and catch up in two call sites.
+
+ * WebCore.base.exp:
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::sendResizeEvent):
+ (WebCore::EventHandler::sendScrollEvent):
+ * page/EventHandler.h:
+ * page/Frame.cpp:
+ * page/Frame.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::performPostLayoutTasks):
+ (WebCore::FrameView::valueChanged):
+
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Darin Adler.
+
+ Move Frame::isFrameSet to Document::isFrameSet
+
+ Changed the FrameLoader callsite. I assume that as this
+ point m_frame.document() might return a null pointer. Change
+ the condition to either not having a document or not having a
+ frame set. This should be semantically equivalent to the
+ old code.
+
+ Make Document::body() const to be able to call it from within
+ Document::isFrameSet. Leave the isHTMLDocument() check as this
+ is a stronger condition than simply having a HTMLElement in the
+ DOM.
+
+ * WebCore.base.exp:
+ * dom/Document.cpp:
+ (WebCore::Document::isFrameSet):
+ (WebCore::Document::body):
+ * dom/Document.h:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::shouldScrollToAnchor):
+ * loader/archive/cf/LegacyWebArchive.cpp:
+ (WebCore::LegacyWebArchive::createFromSelection):
+ * page/Frame.cpp:
+ * page/Frame.h:
+
+2009-01-30 Aurelian Maga <aurelianmaga@yahoo.com>
+
+ Reviewed by Holger Freyther.
+
+ [GTK] Logic fixes and build fixes
+
+ https://bugs.webkit.org/show_bug.cgi?id=22022
+
+ Catch up with the internal GeoLocation API and fix the logic of
+ the previous version.
+
+ * platform/gtk/GeolocationServiceGtk.cpp:
+ (WebCore::GeolocationServiceGtk::startUpdating):
+ (WebCore::GeolocationServiceGtk::updateLocationInformation):
+ (WebCore::GeolocationServiceGtk::position_changed):
+
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ [GTK] Implement GeolocationService using the Geoclue library
+
+ https://bugs.webkit.org/show_bug.cgi?id=22022
+
+ Untested implementation of the GeolocationService using the geoclue
+ library. Velocity handling is completely missing and the accuracy
+ handling might be wrong.
+
+ * platform/gtk/GeolocationServiceGtk.cpp:
+ (WTF::GeoclueAccuracy):
+ (WebCore::GeolocationServiceGtk::GeolocationServiceGtk):
+ (WebCore::GeolocationServiceGtk::~GeolocationServiceGtk):
+ (WebCore::GeolocationServiceGtk::startUpdating):
+ (WebCore::GeolocationServiceGtk::stopUpdating):
+ (WebCore::GeolocationServiceGtk::suspend):
+ (WebCore::GeolocationServiceGtk::resume):
+ (WebCore::GeolocationServiceGtk::lastPosition):
+ (WebCore::GeolocationServiceGtk::lastError):
+ (WebCore::GeolocationServiceGtk::updateLocationInformation):
+ (WebCore::GeolocationServiceGtk::updatePosition):
+ (WebCore::GeolocationServiceGtk::position_changed):
+ (WebCore::GeolocationServiceGtk::setError):
+ * platform/gtk/GeolocationServiceGtk.h:
+
+2009-01-30 Mark Rowe <mrowe@apple.com>
+
+ Build fix. Declare preferredSize as static.
+
+ * platform/text/cf/StringImplCF.cpp:
+ (WebCore::StringWrapperCFAllocator::preferredSize):
+
+2009-01-30 Darin Adler <darin@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Bug 23622: create CFString and NSString objects from WebCore::String without copying the characters
+ https://bugs.webkit.org/show_bug.cgi?id=23622
+
+ * platform/text/cf/StringImplCF.cpp:
+ (WebCore::StringWrapperCFAllocator::allocator): Added. Returns the allocator.
+ (WebCore::StringWrapperCFAllocator::retain): Added. Callback for allocator.
+ (WebCore::StringWrapperCFAllocator::release): Ditto.
+ (WebCore::StringWrapperCFAllocator::copyDescription): Ditto.
+ (WebCore::StringWrapperCFAllocator::allocate): Ditto.
+ (WebCore::StringWrapperCFAllocator::reallocate): Ditto.
+ (WebCore::StringWrapperCFAllocator::deallocate): Ditto.
+ (WebCore::StringWrapperCFAllocator::preferredSize): Ditto.
+ (WebCore::StringWrapperCFAllocator::create): Added. Creates the allocator, but
+ returns 0 if garbage collection is enabled.
+ (WebCore::StringImpl::createCFString): Use StringWrapperCFAllocator if possible.
+
+ * platform/text/mac/StringImplMac.mm:
+ (WebCore::StringImpl::operator NSString *): Use CFString and toll-free bridging,
+ rather than using NSString directly. This lets NSString benefit from the above.
+
+2009-01-30 Darin Adler <darin@apple.com>
+
+ * page/Frame.cpp:
+ (WebCore::Frame::createView): Fix debug build by removing get() from assert.
+
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22056
+
+ Kill FrameLoaderClient.cpp, move the code over to Frame::createView
+
+ FrameLoaderClient is supposed to be an interface, move the
+ to be shared code to Frame which is a controller and is
+ allowed to create a FrameView.
+
+ * GNUmakefile.am:
+ * WebCore.base.exp:
+ * WebCore.pro:
+ * WebCore.xcodeproj/project.pbxproj:
+ * loader/FrameLoaderClient.cpp: Removed.
+ * loader/FrameLoaderClient.h:
+ (WebCore::FrameLoaderClient::~FrameLoaderClient):
+ * page/Frame.cpp:
+ (WebCore::Frame::createView):
+ * page/Frame.h:
+
+2009-01-30 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23357
+
+ New files to support accelerated compositing at the RenderLayer
+ level.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ New files added to project, and run through the sort script.
+
+ * rendering/RenderLayerBacking.cpp: Added.
+ * rendering/RenderLayerBacking.h: Added.
+ New object to store compositing-related data for a single
+ RenderLayer.
+
+ * rendering/RenderLayerCompositor.cpp: Added.
+ * rendering/RenderLayerCompositor.h: Added.
+ Per-RenderView controller object for compositing hierarchy
+ maintenance.
+
+2009-01-30 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23356
+
+ Add new files related to accelerated compositing:
+
+ * WebCore.xcodeproj/project.pbxproj:
+ Add the files to the project. Also add ColorCG.cpp, for the
+ Color(CGColorRef) constructor.
+
+ * platform/graphics/GraphicsLayer.cpp: Added.
+ * platform/graphics/GraphicsLayer.h: Added.
+ GraphicsLayer is a platform abstraction for a hardware-backed
+ layer.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ * platform/graphics/GraphicsLayerClient.h: Added.
+ Client of GraphicsLayer, allowing GraphicsLayer to call out
+ to WebCore code.
- Merge r40432.
+ * platform/graphics/mac/GraphicsLayerCA.h: Added.
+ * platform/graphics/mac/GraphicsLayerCA.mm: Added.
+ Mac Core Animation implementation of GraphicsLayer.
- 2009-01-30 Geoffrey Garen <ggaren@apple.com>
+ * platform/graphics/mac/WebLayer.h: Added.
+ * platform/graphics/mac/WebLayer.mm: Added.
+ * platform/graphics/mac/WebTiledLayer.h: Added.
+ * platform/graphics/mac/WebTiledLayer.mm: Added.
+ Subclasses of CALayer and CATiledLayer -- helpers for the
+ GraphicsLayerCA implementation.
+
+2009-01-30 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
@@ -490,11 +19574,73 @@
* svg/SVGAElement.cpp:
(WebCore::SVGAElement::defaultEventHandler):
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-30 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Dan Bernstein.
+
+ Fix for <rdar://problem/6545095>
+ ASSERTION FAILED: RenderBlock.h:519: !o || o->isRenderBlock()
+
+ Test: fast/block/float/crash-replaced-display-block.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::layoutBlockChildren): Move RenderBlock only code into
+ isRenderBlock if-statement.
+
+2009-01-30 Chris Fleizach <cfleizach@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 23656: AX hierarchy for iFrames is incorrect
+ https://bugs.webkit.org/show_bug.cgi?id=23656
- Merge r40424.
+ The AX hierarchy when an iFrame was present was incorrect. A different scroll area was
+ returned when going down compared to when going up.
- 2009-01-30 Geoffrey Garen <ggaren@apple.com>
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (convertToNSArray):
+
+2009-01-30 Adam Treat <adam.treat@torchmobile.com>
+
+ Fix Qt build to include new class IdentifierRep introduced in revision 40412.
+
+ * WebCore.pro:
+
+2009-01-30 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Make IdentifierRep.h a private header, and add symbols needed by WebKit to WebCore.LP64.exp.
+
+ * WebCore.LP64.exp:
+ * WebCore.xcodeproj/project.pbxproj:
+
+2009-01-30 Sam Weinig <sam@webkit.org>
+
+ Commit files I forgot to in the previous commit.
+
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::layoutCount):
+ * page/Frame.cpp:
+ (WebCore::Frame::contentRenderer):
+ (WebCore::Frame::forceLayoutWithPageWidthRange):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::layout):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::nodeAtPoint):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::repaintUsingContainer):
+ (WebCore::RenderObject::repaint):
+ (WebCore::RenderObject::repaintRectangle):
+ (WebCore::RenderObject::view):
+ (WebCore::RenderObject::scheduleRelayout):
+ (WebCore::RenderObject::maximalOutlineSize):
+ * rendering/SVGRenderSupport.cpp:
+ (WebCore::clampImageBufferSizeToViewport):
+ * svg/SVGLength.cpp:
+ (WebCore::SVGLength::PercentageOfViewport):
+
+2009-01-30 Geoffrey Garen <ggaren@apple.com>
Reviewed by Darin Adler.
@@ -547,125 +19693,338 @@
(WebCore::FrameLoader::continueFragmentScrollAfterNavigationPolicy):
(WebCore::FrameLoader::loadItem): Use the lockHistory parameter.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
- Merge r40376.
+ Reviewed by Mark Rowe.
- 2009-01-29 Geoffrey Garen <ggaren@apple.com>
+ [Gtk+] Use AccessibilityObject::stringValue for the AtkObject name
- Reviewed by Oliver Hunt.
+ https://bugs.webkit.org/show_bug.cgi?id=21546
- Cleaned up some naming in ScheduledRedirection.
+ The API documentation at http://library.gnome.org/devel/atk/stable/AtkText.html
+ states that: "AtkObjects whose text content is simple, unattributed, and very
+ brief may expose that content via atk_object_get_name instead"
- * loader/FrameLoader.cpp:
- (WebCore::ScheduledRedirection::ScheduledRedirection):
+ As we are currently not able to always provide a AtkTextInterface
+ implementation this will make the whole content available to accerciser,
+ and other tools.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ * page/gtk/AccessibilityObjectWrapperAtk.cpp:
- Merge r40373.
+2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org>
- 2009-01-29 Geoffrey Garen <ggaren@apple.com>
+ Unreviewed build fix.
- Reviewed by Oliver Hunt.
+ Include string.h for strdup.
- Removed an unused case of "lockHistory" to help make the other cases
- clearer.
+ * bridge/IdentifierRep.h:
- * page/FrameLoadRequest.h:
- (WebCore::FrameLoadRequest::FrameLoadRequest):
+2009-01-30 Sam Weinig <sam@webkit.org>
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ Reviewed by Dan Bernstein.
- Merge r40353.
+ Add toRenderView methods for casting RenderObjects to RenderViews. The methods will assert if the object
+ is not a RenderView.
- 2009-01-28 Geoffrey Garen <ggaren@apple.com>
+ * dom/Document.cpp:
+ (WebCore::Document::renderView):
+ * editing/SelectionController.cpp:
+ (WebCore::SelectionController::nodeWillBeRemoved):
+ (WebCore::SelectionController::recomputeCaretRect):
+ (WebCore::SelectionController::invalidateCaretRect):
+ (WebCore::SelectionController::focusedOrActiveStateChanged):
+ * editing/mac/SelectionControllerMac.mm:
+ (WebCore::SelectionController::notifyAccessibilityForSelectionChange):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::styleDidChange):
+ (WebCore::RenderBox::repaintLayerRectsForImage):
+ (WebCore::RenderBox::availableHeightUsing):
+ * rendering/RenderView.h:
+ (WebCore::toRenderView):
- Reviewed by Sam Weinig.
+2009-01-30 Simon Fraser <simon.fraser@apple.com>
- Merged FrameLoadTypeReloadAllowingStaleData with FrameLoadTypeReload.
+ Reviewed by Dave Hyatt
- Technically, selecting View->Text Encoding->[Non-Default Encoding] on
- a page with frames may now be slightly slower than it used to be. Oh well.
+ https://bugs.webkit.org/show_bug.cgi?id=23360
- * loader/FrameLoader.cpp:
- (WebCore::isBackForwardLoadType):
- (WebCore::FrameLoader::restoreDocumentState): Subbed in FrameLoadTypeReload.
+ Really use the container-relative repaint rect methods
+ for repaint during layout
- (WebCore::FrameLoader::loadURLIntoChildFrame): No need to account for
- non-back-forward navigations anymore.
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::LayoutRepainter::LayoutRepainter):
- (WebCore::FrameLoader::canCachePage):
- (WebCore::FrameLoader::logCanCachePageDecision):
- (WebCore::FrameLoader::reloadWithOverrideEncoding):
- (WebCore::FrameLoader::transitionToCommitted):
- (WebCore::FrameLoader::loadItem): Subbed in FrameLoadTypeReload.
+2009-01-30 Anders Carlsson <andersca@apple.com>
- * loader/FrameLoader.h: Renamed reloadAllowingStaleData => reloadWithOverrideEncoding,
- since that's what it actually does.
+ Reviewed by Darin Adler.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ Get rid of PrivateIdentifier and use IdentifierRep instead.
- Merge r40558.
+ * bridge/NP_jsobject.cpp:
+ (_NPN_Invoke):
+ (_NPN_GetProperty):
+ (_NPN_SetProperty):
+ (_NPN_RemoveProperty):
+ (_NPN_HasProperty):
+ (_NPN_HasMethod):
+ * bridge/c/c_instance.cpp:
+ (JSC::Bindings::CInstance::getPropertyNames):
+ * bridge/c/c_utility.cpp:
+ (JSC::Bindings::convertNPStringToUTF16):
+ * bridge/c/c_utility.h:
+ * bridge/npruntime.cpp:
+ (_NPN_GetStringIdentifier):
+ (_NPN_GetStringIdentifiers):
+ (_NPN_GetIntIdentifier):
+ (_NPN_IdentifierIsString):
+ (_NPN_UTF8FromIdentifier):
+ (_NPN_IntFromIdentifier):
- 2009-02-03 Anders Carlsson <andersca@apple.com>
+2009-01-30 Anders Carlsson <andersca@apple.com>
- Reviewed by Kevin Decker.
+ Reviewed by Sam Weinig and Darin Adler.
- - Fix for <rdar://problem/6549743>
+ Make IdentifierRep a real class, add necessary class methods.
- On Tiger, create an autorelease pool before creating the NSGraphicsContext and drain it immediately
- after the call to -[NSView displayRectIgnoringOpacity:inContext:].
+ * bridge/IdentifierRep.cpp:
+ (WebCore::identifierSet):
+ Returns a set of all identifiers.
- * platform/mac/WidgetMac.mm:
- (WebCore::Widget::paint):
+ (WebCore::IdentifierRep::isValid):
+ Return whether an identifier is valid, meaning that it's present in the
+ set of identifiers.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ * bridge/IdentifierRep.h:
+ (WebCore::IdentifierRep::isString):
+ (WebCore::IdentifierRep::number):
+ (WebCore::IdentifierRep::string):
+ (WebCore::IdentifierRep::IdentifierRep):
+ (WebCore::IdentifierRep::):
- Merge r40541.
+2009-01-30 Anders Carlsson <andersca@apple.com>
- 2009-02-03 Dan Bernstein <mitz@apple.com>
+ Reviewed by Sam Weinig.
- Reviewed by Brady Eidson.
+ Add IdentifierRep which will be used by both plug-in implementations.
- - fix <rdar://problem/6550530> REGRESSION (r40508): Window opened with window.open has no initial history item (global and back/forward)
+ * GNUmakefile.am:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bridge/IdentifierRep.cpp: Added.
+ (WebCore::IdentifierRep::IdentifierRep):
+ (WebCore::IdentifierRep::):
+ (WebCore::intIdentifierMap):
+ (WebCore::identifierRep):
+ (WebCore::stringIdentifierMap):
+ * bridge/IdentifierRep.h: Added.
+ * bridge/c/c_utility.h:
+ * platform/text/PlatformString.h:
+ * platform/text/String.cpp:
+ (WebCore::String::fromUTF8WithLatin1Fallback):
- Test: fast/history/window-open.html
+2009-01-30 Sam Weinig <sam@webkit.org>
- * bindings/js/JSDOMWindowBase.cpp:
- (WebCore::createWindow): Pass the missing lockBackForwardList parameter
- to FrameLoader::changeLocation().
+ Reviewed by David Hyatt.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ Add toRenderInline methods for casting RenderObjects to RenderInlines. The methods will assert if the object
+ is not a RenderInline.
- Merge r40472.
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::removeLineBoxFromRenderObject):
+ (WebCore::InlineFlowBox::extractLineBoxFromRenderObject):
+ (WebCore::InlineFlowBox::attachLineBoxToRenderObject):
+ (WebCore::InlineFlowBox::rendererLineBoxes):
+ (WebCore::InlineFlowBox::determineSpacingForFlowBoxes):
+ (WebCore::InlineFlowBox::paint):
+ * rendering/LayoutState.cpp:
+ (WebCore::LayoutState::LayoutState):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintObject):
+ (WebCore::RenderBlock::addFocusRingRects):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::offsetFromContainer):
+ (WebCore::RenderBox::computeRectForRepaint):
+ (WebCore::RenderBox::containingBlockWidthForPositioned):
+ (WebCore::RenderBox::containingBlockHeightForPositioned):
+ (WebCore::RenderBox::calcAbsoluteHorizontalValues):
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+ * rendering/RenderContainer.cpp:
+ (WebCore::RenderContainer::updateBeforeAfterContentForContainer):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::inlineContinuation):
+ (WebCore::nextContinuation):
+ (WebCore::RenderInline::splitInlines):
+ * rendering/RenderInline.h:
+ (WebCore::toRenderInline):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateLayerPosition):
+ (WebCore::RenderLayer::boundingBox):
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::dirtyLinesFromChangedChild):
+ * rendering/RenderText.h:
+ * rendering/RenderTreeAsText.cpp:
+ (WebCore::operator<<):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::createLineBoxes):
+ (WebCore::RenderBlock::layoutInlineChildren):
- 2009-02-01 Dan Bernstein <mitz@apple.com>
+2009-01-30 Darin Fisher <darin@chromium.org>
- Reviewed by John Sullivan.
+ Reviewed by Eric Seidel.
- - fix <rdar://problem/6546625> REGRESSION (r40432): iframes added to global history at haaretz.co.il
+ https://bugs.webkit.org/show_bug.cgi?id=23647
+ Fix PLATFORM(SKIA)'s ImageSource::clear method to match other ports
- Fixes http/tests/navigation/multiple-back-forward-entries.html
+ * platform/graphics/skia/ImageSourceSkia.cpp:
+ (WebCore::ImageSource::clear):
- r40432 added a parameter to FrameLoader::scheduleLocationChange() and
- failed to update all call sites.
+2009-01-30 David Hyatt <hyatt@apple.com>
+
+ Add toRenderBlock methods for casting RenderObjects to RenderBlocks. The methods will assert if the object
+ is not a RenderBlock. Also add a toRenderBlock method that takes a RenderBlock but returns void and that
+ is unimplemented. This method will catch anyone trying to do a cast when the object is already a RenderBlock.
+
+ Making this change caught a bad cast in RenderBlock::layoutBlockChildren, so that is also fixed by this
+ patch with a containsFloats() check.
+
+ Reviewed by Darin Adler
+
+ * dom/PositionIterator.cpp:
+ (WebCore::PositionIterator::isCandidate):
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::addBlockPlaceholderIfNeeded):
+ * editing/Editor.cpp:
+ (WebCore::Editor::hasBidiSelection):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::anchorElement):
+ (WebCore::AccessibilityRenderObject::accessibilityIsIgnored):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::styleWillChange):
+ (WebCore::RenderBlock::removeChild):
+ (WebCore::RenderBlock::layoutBlock):
+ (WebCore::RenderBlock::collapseMargins):
+ (WebCore::RenderBlock::clearFloatsIfNeeded):
+ (WebCore::RenderBlock::layoutBlockChildren):
+ (WebCore::RenderBlock::fillBlockSelectionGaps):
+ (WebCore::RenderBlock::markAllDescendantsWithFloatsForLayout):
+ (WebCore::RenderBlock::firstLineBlock):
+ (WebCore::getLineAtIndex):
+ (WebCore::getHeightForLineCount):
+ (WebCore::RenderBlock::lineCount):
+ (WebCore::RenderBlock::adjustForBorderFit):
+ (WebCore::RenderBlock::clearTruncation):
+ * rendering/RenderBlock.h:
+ (WebCore::toRenderBlock):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::offsetFromContainer):
+ (WebCore::RenderBox::computeRectForRepaint):
+ (WebCore::RenderBox::calcReplacedHeightUsing):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutHorizontalBox):
+ (WebCore::RenderFlexibleBox::layoutVerticalBox):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::inlineContinuation):
+ (WebCore::nextContinuation):
+ (WebCore::RenderInline::positionForCoordinates):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateScrollInfoAfterLayout):
+ * rendering/RenderListItem.cpp:
+ (WebCore::getParentOfFirstLineBox):
+ (WebCore::RenderListItem::positionListMarker):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::containingBlock):
+ (WebCore::RenderObject::computeRectForRepaint):
+ (WebCore::RenderObject::removeFromObjectLists):
+ (WebCore::RenderObject::getTextDecorationColors):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::addChild):
+ (WebCore::RenderTable::recalcSections):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::RenderTextControl::styleDidChange):
+ * rendering/RenderTextControlSingleLine.cpp:
+ (WebCore::RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::block):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::createLineBoxes):
+
+2009-01-30 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Sam Weinig
+
+ - Let CachedFrame handle the suspending/resuming of active DOM objects itself instead of
+ relying on some outside force.
+ - Clear the previous history item inside FrameLoader instead of relying on multiple
+ FrameLoaderClients to do it.
+
+ * history/CachedFrame.cpp:
+ (WebCore::CachedFrame::CachedFrame): Suspend active DOM objects here.
+ (WebCore::CachedFrame::restore): Resume those DOM objects here.
+ * history/CachedFrame.h:
+ (WebCore::CachedFrame::domWindow):
- * bindings/js/JSDOMWindowBase.cpp:
- (WebCore::createWindow): Pass the lockBackForwardHistory parameter,
- giving it the same value as the lockHistory parameter.
- (windowProtoFuncOpen): Ditto.
- * bindings/js/JSDOMWindowCustom.cpp:
- (WebCore::JSDOMWindow::setLocation): Ditto.
- * bindings/js/JSDocumentCustom.cpp:
- (WebCore::JSDocument::setLocation): Ditto.
* loader/FrameLoader.cpp:
- (WebCore::FrameLoader::requestFrame): Ditto.
+ (WebCore::FrameLoader::commitProvisionalLoad): Let CachedFrame creation handle the
+ suspending of active DOM objects.
+ (WebCore::FrameLoader::open): Let CachedFrame::restore() handle resuming those DOM objects.
+ (WebCore::FrameLoader::checkLoadCompleteForThisFrame): Call frameLoadCompleted() instead
+ of performing a client call by itself.
+ (WebCore::FrameLoader::frameLoadCompleted):
+
+2009-01-30 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/6448823> Application Cache is kept after a private browsing session
+
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ (WebCore::ApplicationCacheGroup::selectCache):
+ (WebCore::ApplicationCacheGroup::update):
+ Cache update will not be started if private browsing is enabled. Existing cache version
+ from disk database will be used.
+
+ * loader/appcache/ApplicationCacheGroup.h: Made postListenerTask() static, in order to call
+ it when refusing to update from selectCache().
+
+ * loader/appcache/ApplicationCache.cpp:
+ (WebCore::ApplicationCache::addDynamicEntry):
+ (WebCore::ApplicationCache::removeDynamicEntry):
+ Added reminders about private browsing to unimplemented methods.
+
+2009-01-30 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Bug 23580: GNU mode RVCT compilation support
+ <https://bugs.webkit.org/show_bug.cgi?id=23580>
+
+ * html/PreloadScanner.cpp: Use COMPILER(GCC) instead of __GNUC__.
+
+2009-01-30 David Levin <levin@chromium.org>
-2009-02-03 Mark Rowe <mrowe@apple.com>
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23616: Various "template helpers" should be consolidated from isolated files in JavaScriptCore.
+ <https://bugs.webkit.org/show_bug.cgi?id=23616>
+
+ Added forwarding header.
+
+ * ForwardingHeaders/wtf/TypeTraits.h: Added.
+
+2009-01-30 David Levin <levin@chromium.org>
- Merge r40397.
+ Reviewed by Alexey Proskuryakov.
+
+ Bug 23599: ResourceError needs to be copyable for use in another thread.
+ <https://bugs.webkit.org/show_bug.cgi?id=23599>
+
+ Add ResourceErrorBase::copy method. (Not yet used.)
+
+ * platform/network/ResourceErrorBase.cpp:
+ (WebCore::ResourceErrorBase::copy):
+ * platform/network/ResourceErrorBase.h:
- 2009-01-29 Stephanie Lewis <slewis@apple.com>
+2009-01-29 Stephanie Lewis <slewis@apple.com>
RS by Oliver Hunt.
@@ -673,11 +20032,460 @@
* WebCore.order:
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-29 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23488
+
+ Make TimerBase thread-aware (for Workers).
+ Added new class ThreadTimers - it keeps a heap of all timers for a thread (previously kept in a static global).
+ Pointer to instance of ThreadTimers is stored in GlobalThreadData.
+ Most static methods of TimerBase went to ThreadTimers.
+
+ The TimerBase functionality did not change (it maintains the timer heap which computes the nearest firing).
+
+ Added new abstract class SharedTimer, so worker threads can provide their own implementation (will be implemented on WorkerRunLoop).
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.scons:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ Added new ThreadTimers.cpp to build files.
+
+ * platform/SharedTimer.h:
+ (WebCore::SharedTimer::~SharedTimer):
+ (WebCore::MainThreadSharedTimer::setFiredFunction):
+ (WebCore::MainThreadSharedTimer::setFireTime):
+ (WebCore::MainThreadSharedTimer::stop):
+ Added abstract SharedTimer and MainThreadSharedTimer which redirects to the existing port-supplied functions.
+
+ * platform/ThreadGlobalData.cpp:
+ (WebCore::ThreadGlobalData::ThreadGlobalData):
+ (WebCore::ThreadGlobalData::~ThreadGlobalData):
+ * platform/ThreadGlobalData.h:
+ (WebCore::ThreadGlobalData::threadTimers):
+ Added ThreadTimers to ThreadGlobalData.
+
+ * platform/ThreadTimers.cpp: Added.
+ (WebCore::mainThreadSharedTimer):
+ Static getter for a MainThreadSharedTimer singleton.
+
+ (WebCore::ThreadTimers::ThreadTimers):
+ (WebCore::ThreadTimers::setSharedTimer):
+ (WebCore::ThreadTimers::updateSharedTimer):
+ (WebCore::ThreadTimers::collectFiringTimers):
+ (WebCore::ThreadTimers::fireTimers):
+ (WebCore::ThreadTimers::sharedTimerFired):
+ (WebCore::ThreadTimers::sharedTimerFiredInternal):
+ (WebCore::ThreadTimers::fireTimersInNestedEventLoop):
+ ThreadTimers implementation. Most of the code is moved from previous static functions on TimerBase.
+ Need a new class so each thread may get ts own copy of the timer heap.
+
+ * platform/ThreadTimers.h: Added.
+ (WebCore::ThreadTimers::timerHeap):
+ (WebCore::ThreadTimers::timersReadyToFire):
+
+ * platform/Timer.cpp:
+ (WebCore::timerHeap):
+ (WebCore::timersReadyToFire):
+ (WebCore::TimerHeapElement::TimerHeapElement):
+ (WebCore::TimerHeapElement::checkConsistency):
+ (WebCore::TimerHeapElement::operator=):
+ (WebCore::TimerHeapIterator::checkConsistency):
+ (WebCore::TimerBase::TimerBase):
+ (WebCore::TimerBase::~TimerBase):
+ (WebCore::TimerBase::isActive):
+ (WebCore::TimerBase::checkHeapIndex):
+ (WebCore::TimerBase::heapDelete):
+ (WebCore::TimerBase::heapDeleteMin):
+ (WebCore::TimerBase::heapInsert):
+ (WebCore::TimerBase::heapPopMin):
+ (WebCore::TimerBase::setNextFireTime):
+ (WebCore::TimerBase::fireTimersInNestedEventLoop):
+ Now instead of static timer heap these use accessor functions that pull thread-specific heap instance.
+
+ * platform/Timer.h:
+ static methods moved to ThreadTimers.
+
+2009-01-29 David Hyatt <hyatt@apple.com>
+
+ Beginning of work to eliminate RenderContainer and make containership "pluggable" into any spot in the render tree. The first step is to create
+ the new object that will handle children: RenderObjectChildList and move RenderContainer's member variables into it. Subsequent patches will begin
+ moving RenderContainer's functionality into RenderObjectChildList.
+
+ Reviewed by Eric Seidel
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * rendering/RenderContainer.cpp:
+ (WebCore::RenderContainer::RenderContainer):
+ (WebCore::RenderContainer::destroyLeftoverChildren):
+ (WebCore::RenderContainer::addChild):
+ (WebCore::RenderContainer::removeChildNode):
+ (WebCore::RenderContainer::updateBeforeAfterContentForContainer):
+ (WebCore::RenderContainer::appendChildNode):
+ (WebCore::RenderContainer::insertChildNode):
+ (WebCore::RenderContainer::layout):
+ (WebCore::RenderContainer::removeLeftoverAnonymousBlock):
+ (WebCore::RenderContainer::positionForCoordinates):
+ (WebCore::RenderContainer::addLineBoxRects):
+ (WebCore::RenderContainer::collectAbsoluteLineBoxQuads):
+ * rendering/RenderContainer.h:
+ (WebCore::RenderContainer::firstChild):
+ (WebCore::RenderContainer::lastChild):
+ (WebCore::RenderContainer::firstChildBox):
+ (WebCore::RenderContainer::lastChildBox):
+ * rendering/RenderObjectChildList.h: Added.
+ (WebCore::RenderObjectChildList::RenderObjectChildList):
+ (WebCore::RenderObjectChildList::firstChild):
+ (WebCore::RenderObjectChildList::lastChild):
+ (WebCore::RenderObjectChildList::setFirstChild):
+ (WebCore::RenderObjectChildList::setLastChild):
+
+2009-01-29 Jungshik Shin <jshin@chromium.org>
+
+ Reviewed by Alexey Proskuryakov.
+
+ http://bugs.webkit.org/show_bug.cgi?id=23598
+ Replace smart-quotes in UTF-8 with ASCII double-quotes to avoid
+ the compilation error on CJK Windows
+
+ * wml/WMLTableElement.cpp:
+ (WebCore::WMLTableElement::parseMappedAttribute):
+
+2009-01-29 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23627
+ Fix the PLATFORM(SKIA) build.
+
+ * svg/graphics/SVGPaintServer.cpp:
+ (WebCore::SVGPaintServer::teardown):
+
+2009-01-29 Scott Violet <sky@google.com>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23625
+ Skia platform doesn't render text to a canvas or support clipping to an image buffer
+
+ Fixes two bugs in Skia rendering to a canvas:
+ . Text was not rendered at all. This is because we never properly
+ fixed up the alpha values. The fix is to create a layer when
+ rendering text to a layer.
+ . We were not honoring clipping to an image buffer.
+
+ * platform/graphics/chromium/FontChromiumWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/skia/GraphicsContextSkia.cpp:
+ (WebCore::GraphicsContext::clipToImageBuffer):
+ * platform/graphics/skia/ImageBufferSkia.cpp:
+ (WebCore::ImageBuffer::ImageBuffer):
+ * platform/graphics/skia/PlatformContextSkia.cpp:
+ (PlatformContextSkia::PlatformContextSkia):
+ (PlatformContextSkia::setDrawingToImageBuffer):
+ (PlatformContextSkia::isDrawingToImageBuffer):
+ (PlatformContextSkia::beginLayerClippedToImage):
+ (PlatformContextSkia::restore):
+ (PlatformContextSkia::applyClipFromImage):
+ * platform/graphics/skia/PlatformContextSkia.h:
+
+2009-01-29 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Mark Rowe.
+
+ First step in tracking the urls a HistoryItem was redirected through.
+
+ * WebCore.base.exp:
+ * history/HistoryItem.cpp:
+ (WebCore::HistoryItem::HistoryItem):
+ (WebCore::HistoryItem::addRedirectURL):
+ (WebCore::HistoryItem::redirectURLs):
+ (WebCore::HistoryItem::setRedirectURLs):
+ * history/HistoryItem.h:
+
+2009-01-29 Dirk Schulze <krit@webkit.org>
+
+ Reviewed by Nikolas Zimmermann, Eric Seidel.
+
+ Just transform the pattern directly instead of transforming the context fixes this
+ problem. Texts or strokes are no longer affected by transformations.
+
+ SVG pattern transformation/BoundingBox can cause ugly stroke thickness or text positions
+ https://bugs.webkit.org/show_bug.cgi?id=23472
+
+ Test: svg/custom/pattern-with-transformation.svg
+
+ * platform/graphics/Pattern.h:
+ (WebCore::Pattern::setPatternSpaceTransform):
+ * platform/graphics/cairo/PatternCairo.cpp:
+ (WebCore::Pattern::createPlatformPattern):
+ * platform/graphics/cg/PatternCG.cpp:
+ (WebCore::Pattern::createPlatformPattern):
+ * platform/graphics/qt/PatternQt.cpp:
+ (WebCore::Pattern::createPlatformPattern):
+ * svg/graphics/SVGPaintServerPattern.cpp:
+ (WebCore::SVGPaintServerPattern::setup):
+
+2009-01-29 David Hyatt <hyatt@apple.com>
+
+ Move the line box list member out of RenderFlow and down into RenderBlock and RenderInline. Eliminate RenderFlow from the tree.
+
+ Reviewed by Sam Weinig
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * html/HTMLAnchorElement.cpp:
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::rendererLineBoxes):
+ (WebCore::InlineFlowBox::determineSpacingForFlowBoxes):
+ * rendering/InlineFlowBox.h:
+ * rendering/LayoutState.cpp:
+ (WebCore::LayoutState::LayoutState):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::RenderBlock):
+ (WebCore::RenderBlock::destroy):
+ (WebCore::RenderBlock::styleWillChange):
+ (WebCore::RenderBlock::styleDidChange):
+ (WebCore::RenderBlock::dirtyLineBoxes):
+ (WebCore::RenderBlock::removeChild):
+ (WebCore::RenderBlock::setSelectionState):
+ (WebCore::RenderBlock::avoidsFloats):
+ (WebCore::RenderBlock::positionForCoordinates):
+ (WebCore::RenderBlock::calcInlinePrefWidths):
+ (WebCore::RenderBlock::baselinePosition):
+ (WebCore::RenderBlock::getBaselineOfFirstLineBox):
+ (WebCore::RenderBlock::getBaselineOfLastLineBox):
+ (WebCore::RenderBlock::rectWithOutlineForRepaint):
+ (WebCore::RenderBlock::hoverAncestor):
+ (WebCore::RenderBlock::updateDragState):
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::lineBoxes):
+ (WebCore::RenderBlock::firstLineBox):
+ (WebCore::RenderBlock::lastLineBox):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::offsetFromContainer):
+ (WebCore::RenderBox::computeRectForRepaint):
+ (WebCore::RenderBox::containingBlockWidthForPositioned):
+ (WebCore::RenderBox::calcAbsoluteHorizontalValues):
+ (WebCore::RenderBox::calcAbsoluteHorizontalReplaced):
+ * rendering/RenderBox.h:
+ * rendering/RenderFlow.cpp: Removed.
+ * rendering/RenderFlow.h: Removed.
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::RenderInline):
+ (WebCore::RenderInline::destroy):
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::cloneInline):
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::offsetLeft):
+ (WebCore::RenderInline::offsetTop):
+ (WebCore::RenderInline::positionForCoordinates):
+ (WebCore::RenderInline::rectWithOutlineForRepaint):
+ (WebCore::RenderInline::updateDragState):
+ (WebCore::RenderInline::relativePositionedInlineOffset):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::lineBoxes):
+ (WebCore::RenderInline::firstLineBox):
+ (WebCore::RenderInline::lastLineBox):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateLayerPosition):
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::dirtyLinesFromChangedChild):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::rendererLineBoxes):
+ * rendering/RootInlineBox.h:
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::createLineBoxes):
+ * wml/WMLAElement.cpp:
+
+2009-01-29 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Cleaned up some naming in ScheduledRedirection.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::ScheduledRedirection::ScheduledRedirection):
+
+2009-01-29 Anders Carlsson <andersca@apple.com>
+
+ Reviewed by Dan Bernstein.
+
+ Update to use new API.
+
+ * platform/graphics/mac/FontCustomPlatformData.cpp:
+ (WebCore::FontCustomPlatformData::~FontCustomPlatformData):
+ (WebCore::createFontCustomPlatformData):
+
+2009-01-29 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23619
+ ASSERT(!error.isNull()) in DocumentLoader::mainReceivedError() when an SVG image load
+ is cancelled
+
+ Covered by existing tests (as a random crash).
+
+ * loader/EmptyClients.h:
+ (WebCore::EmptyFrameLoaderClient::cancelledError):
+ (WebCore::EmptyFrameLoaderClient::blockedError):
+ (WebCore::EmptyFrameLoaderClient::cannotShowURLError):
+ (WebCore::EmptyFrameLoaderClient::interruptForPolicyChangeError):
+ (WebCore::EmptyFrameLoaderClient::cannotShowMIMETypeError):
+ (WebCore::EmptyFrameLoaderClient::fileDoesNotExistError):
+ (WebCore::EmptyFrameLoaderClient::pluginWillHandleLoadError):
+ Create non-null errors.
+
+2009-01-29 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Removed an unused case of "lockHistory" to help make the other cases
+ clearer.
+
+ * page/FrameLoadRequest.h:
+ (WebCore::FrameLoadRequest::FrameLoadRequest):
+
+2009-01-29 David Hyatt <hyatt@apple.com>
+
+ Move all of the contination insertion code from RenderFlow to RenderInline. addChildToFlow is renamed to addChildIgnoringContinuation, and it has been moved to
+ RenderContainer so that it can still be called on either blocks or inlines. The base class implementation in RenderContainer is what RenderBlock uses. RenderInline
+ subclasses it to do all the work it used to do in addChildToFlow.
+
+ RenderBlock's old addChildToFlow can just become addChild. This simplification is possible because addChild was actually never being called on anonymous
+ block continuations.
+
+ The code dealing with anonymous table parts in the old addChildWithContinuation method can now be removed as a result with no harmful side effects. Falling through to the
+ base class and ignoring a block continuation makes the right thing happen.
+
+ addChildWithContinuation moved to RenderInline and has been renamed to addChildToContinuation.
+
+ Reviewed by Eric Seidel
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::addChild):
+ * rendering/RenderBlock.h:
+ * rendering/RenderContainer.h:
+ (WebCore::RenderContainer::addChildIgnoringContinuation):
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::RenderInline::addChild):
+ (WebCore::nextContinuation):
+ (WebCore::RenderInline::continuationBefore):
+ (WebCore::RenderInline::addChildIgnoringContinuation):
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::splitFlow):
+ (WebCore::RenderInline::addChildToContinuation):
+ (WebCore::RenderInline::childBecameNonInline):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::continuation):
+ (WebCore::RenderInline::setContinuation):
+
+2009-01-29 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Oliver Hunt
+
+ <rdar://problem/6337157> hyundaiusa.com closes window or tab during load
+
+ Test: fast/loader/subframe-self-close.html
+
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::close): Only allow mainframes to close the window.
+
+2009-01-29 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Reviewed by David Hyatt.
+
+ Fixes: https://bugs.webkit.org/show_bug.cgi?id=23539
+
+ Remove several virtual functions from Node & Element related to form control / input elements,
+ that shouldn't reside there, but move to approriate locations, in the new form control /
+ input element abstract base classes.
- Merge r40368.
+ Remove the isControl() method from Node, as it's redundant - isFormControlElement() provides the same information.
+ Move isEnabled( / isReadOnlyControl() / isTextControl() from Node to FormControlElement.
+ Move isAutofilled() / isChecked() / isIndeterminate() from Node to InputElement.
+ Move isInputTypeHidden() / isPasswordField() from Element to InputElement.
- 2009-01-29 Alexey Proskuryakov <ap@webkit.org>
+ Querying these methods requires using the toInputElement/toFormControlElement casting helper functions
+ to cast Element pointers to InputElement/FormControlElement pointers.
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::canShareStyleWithElement):
+ (WebCore::CSSStyleSelector::adjustRenderStyle):
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+ * dom/Element.h:
+ (WebCore::Element::isFormControlElementWithState):
+ * dom/FormControlElement.h:
+ * dom/InputElement.h:
+ * dom/Node.h:
+ * editing/TextIterator.cpp:
+ (WebCore::TextIterator::advance):
+ * html/HTMLFormControlElement.cpp:
+ (WebCore::HTMLFormControlElement::attach):
+ * html/HTMLFormControlElement.h:
+ (WebCore::HTMLFormControlElement::isTextControl):
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::CheckedRadioButtons::removeButton):
+ * html/HTMLInputElement.h:
+ (WebCore::HTMLInputElement::isAutofilled):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::isPasswordField):
+ (WebCore::AccessibilityRenderObject::isIndeterminate):
+ (WebCore::AccessibilityRenderObject::isChecked):
+ (WebCore::AccessibilityRenderObject::isControl):
+ (WebCore::AccessibilityRenderObject::isEnabled):
+ (WebCore::AccessibilityRenderObject::canSetFocusAttribute):
+ * page/mac/AccessibilityObjectWrapper.mm:
+ (textMarkerForVisiblePosition):
+ * platform/ContextMenu.cpp:
+ (WebCore::ContextMenu::populate):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::resize):
+ * rendering/RenderMenuList.cpp:
+ (WebCore::RenderMenuList::itemIsEnabled):
+ * rendering/RenderTextControl.cpp:
+ (WebCore::updateUserModifyProperty):
+ (WebCore::RenderTextControl::adjustInnerTextStyle):
+ (WebCore::RenderTextControl::updateFromElement):
+ * rendering/RenderTheme.cpp:
+ (WebCore::RenderTheme::isChecked):
+ (WebCore::RenderTheme::isIndeterminate):
+ (WebCore::RenderTheme::isEnabled):
+ (WebCore::RenderTheme::isReadOnlyControl):
+ * rendering/RenderThemeMac.mm:
+ (WebCore::RenderThemeMac::adjustMenuListStyle):
+ * wml/WMLFormControlElement.cpp:
+ (WebCore::WMLFormControlElement::isFocusable):
+ * wml/WMLFormControlElement.h:
+ (WebCore::WMLFormControlElement::isEnabled):
+ (WebCore::WMLFormControlElement::isReadOnlyControl):
+ (WebCore::WMLFormControlElement::isTextControl):
+ * wml/WMLInputElement.cpp:
+ (WebCore::WMLInputElement::isKeyboardFocusable):
+ (WebCore::WMLInputElement::isMouseFocusable):
+ * wml/WMLInputElement.h:
+ (WebCore::WMLInputElement::isAutofilled):
+
+2009-01-29 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
+
+ Not reviewed. Fix WML build - apply same fix as HTMLAnchorElement received.
+
+ * wml/WMLAElement.cpp:
+ (WebCore::WMLAElement::isKeyboardFocusable):
+
+2009-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Anders Carlsson.
@@ -697,11 +20505,23 @@
(WebCore::ApplicationCacheGroup::didReceiveResponse): Fixed to check for redirects correctly.
(WebCore::ApplicationCacheGroup::didReceiveManifestResponse): Ditto.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-29 David Hyatt <hyatt@apple.com>
- Merge r40366.
+ Move dirtyLinesFromChangedChild into RenderLineBoxList so that it can be shared by RenderBlock and RenderInline.
- 2009-01-29 Adam Roben <aroben@apple.com>
+ Reviewed by Sam Weinig
+
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::dirtyLinesFromChangedChild):
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::dirtyLinesFromChangedChild):
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::dirtyLinesFromChangedChild):
+ * rendering/RenderLineBoxList.h:
+
+2009-01-29 Adam Roben <aroben@apple.com>
Fix Bug 23623: Windowed Flash instances aren't captured when a WebView
receives a WM_PRINTCLIENT message
@@ -762,22 +20582,73 @@
(WebCore::PluginView::init): Call setUpOffscreenPaintingHooks to make
our WM_PRINTCLIENT trick work.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-29 David Hyatt <hyatt@apple.com>
+
+ Move RenderFlow::destroy down into RenderBlock and RenderInline.
+
+ Reviewed by Anders Carlsson
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::destroy):
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::destroy):
+
+2009-01-29 David Kilzer <ddkilzer@apple.com>
+
+ Remove semi-colons from the end of ObjC method implementations
+
+ Rubber-stamped by Adam Roben.
+
+ $ find WebCore -name \*.m -o -name \*.mm -exec perl -e 'undef $/; $s = <>; while ($s =~ m/[\n\r][-+].*;[\s\r\n]+\{/g) { print "$ARGV: $&\n"; }' {} \;
+
+ * bridge/testbindings.mm:
+
+2009-01-29 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23609
+ Use the two-arg constructor for implicit QUrl->KURL conversion as the
+ single argument ctors assume that KURL::parse has already been called
+ and assert if the parse results in a different string. This was causing
+ an assert for QUrl's with no path and without a trailing slash.
+
+ * platform/qt/KURLQt.cpp:
+ (WebCore::KURL::KURL):
+
+2009-01-29 Alexey Proskuryakov <ap@webkit.org>
- Merge r40358.
+ Rubber-stamped by Darin Adler.
+
+ Renamed ApplicationCacheResource::Implicit to Master, because that's the word HTML5 uses,
+ and it describes the meaning better.
+
+ * loader/appcache/ApplicationCache.cpp:
+ * loader/appcache/ApplicationCacheGroup.cpp:
+ * loader/appcache/ApplicationCacheResource.cpp:
+ * loader/appcache/ApplicationCacheResource.h:
- 2009-01-29 Alexey Proskuryakov <ap@webkit.org>
+2009-01-29 Alexey Proskuryakov <ap@webkit.org>
Release build fix.
* loader/appcache/ApplicationCacheGroup.cpp: (WebCore::ApplicationCacheGroup::selectCache):
Got rid of a variable that wasn't used in release builds.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-29 David Hyatt <hyatt@apple.com>
- Merge r40356.
+ Get rid of createAnonymousFlow. It was only called in one spot, so just inline the code.
- 2009-01-29 Alexey Proskuryakov <ap@webkit.org>
+ Reviewed by Oliver Hunt
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::updateFirstLetter):
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+
+2009-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Anders Carlsson.
@@ -792,11 +20663,7 @@
(WebCore::ApplicationCacheGroup::didReceiveManifestResponse):
Fail if response code isn't 2xx.
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40355.
-
- 2009-01-29 Alexey Proskuryakov <ap@webkit.org>
+2009-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Anders Carlsson.
@@ -809,11 +20676,7 @@
line. Removed code that replaced nulls with 0xFFFD characters, because there is no such
requirement in the spec.
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40354.
-
- 2009-01-28 Alexey Proskuryakov <ap@webkit.org>
+2009-01-28 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Anders Carlsson.
@@ -881,11 +20744,81 @@
(WebCore::ApplicationCacheGroup::postListenerTask):
Rewrote the update algorithm.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-28 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
- Merge r40343.
+ Merged FrameLoadTypeReloadAllowingStaleData with FrameLoadTypeReload.
- 2009-01-28 David Hyatt <hyatt@apple.com>
+ Technically, selecting View->Text Encoding->[Non-Default Encoding] on
+ a page with frames may now be slightly slower than it used to be. Oh well.
+
+ * loader/FrameLoader.cpp:
+ (WebCore::isBackForwardLoadType):
+ (WebCore::FrameLoader::restoreDocumentState): Subbed in FrameLoadTypeReload.
+
+ (WebCore::FrameLoader::loadURLIntoChildFrame): No need to account for
+ non-back-forward navigations anymore.
+
+ (WebCore::FrameLoader::canCachePage):
+ (WebCore::FrameLoader::logCanCachePageDecision):
+ (WebCore::FrameLoader::reloadWithOverrideEncoding):
+ (WebCore::FrameLoader::transitionToCommitted):
+ (WebCore::FrameLoader::loadItem): Subbed in FrameLoadTypeReload.
+
+ * loader/FrameLoader.h: Renamed reloadAllowingStaleData => reloadWithOverrideEncoding,
+ since that's what it actually does.
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move hit testing and painting of lines from RenderFlow into RenderLineBoxList.
+
+ Reviewed by Oliver Hunt
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintContents):
+ (WebCore::RenderBlock::hitTestContents):
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::paint):
+ (WebCore::RenderInline::nodeAtPoint):
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::paint):
+ (WebCore::RenderLineBoxList::hitTest):
+ * rendering/RenderLineBoxList.h:
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Fix SVG pixel test regressions. I wish I could say that I understand this fix, but I don't. For
+ some reason the original code returned 0 for RenderSVGInlineText::yPos() and somehow my literal
+ replacement of yPos() with the body of that method changed the results. I am completely baffled,
+ but all SVG pixel tests pass again when I just take the code out.
+
+ Reviewed by Oliver Hunt
+
+ * rendering/RenderSVGInlineText.cpp:
+ (WebCore::RenderSVGInlineText::computeAbsoluteRectForRange):
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move dirtyLineBoxes from RenderFlow to RenderInline and RenderBlock.
+
+ Reviewed by Oliver Hunt
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::dirtyLineBoxes):
+ * rendering/RenderBlock.h:
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::dirtyLineBoxes):
+ * rendering/RenderInline.h:
+ * rendering/RenderLineBoxList.cpp:
+ (WebCore::RenderLineBoxList::dirtyLineBoxes):
+ * rendering/RenderLineBoxList.h:
+
+2009-01-28 David Hyatt <hyatt@apple.com>
Back out my change to scrollWidth/Height from an earlier checkin since it broke stuff. The current
behavior is not correct, but this will need to be investigated before being changed again.
@@ -894,11 +20827,51 @@
(WebCore::RenderBox::scrollWidth):
(WebCore::RenderBox::scrollHeight):
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move paintOutline and paintOutlineWithLine from RenderFlow to RenderInline, since they only apply to inlines. Tighten up all of the code that
+ called paintOutline to use RenderInline as the type instead of RenderFlow.
+
+ Reviewed by cpst
+
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::paint):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paintObject):
+ (WebCore::RenderBlock::addContinuationWithOutline):
+ (WebCore::RenderBlock::paintContinuationOutlines):
+ * rendering/RenderFlow.cpp:
+ (WebCore::RenderFlow::paintLines):
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::paintOutline):
+ (WebCore::RenderInline::paintOutlineForLine):
+ * rendering/RenderInline.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::paintOutline):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::PaintInfo::PaintInfo):
+
+2009-01-28 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23596
+ XMLHttpRequest.cpp no longer compiles without USE(JSC)
+
+ * xml/XMLHttpRequest.cpp:
+
+2009-01-28 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23597
+ Make it possible to compile Database.cpp when USE(JSC) is not defined
- Merge r40335.
+ * storage/Database.cpp:
+ (WebCore::Database::Database):
- 2009-01-28 Dan Bernstein <mitz@apple.com>
+2009-01-28 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler.
@@ -913,11 +20886,35 @@
at the time) and subsequently having to be fetched asynchronously from
the database when the page-to-icon mapping was established.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move addFocusRingRects from RenderFlow down into RenderBlock and RenderInline.
+
+ Reviewed by Oliver Hunt
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::addFocusRingRects):
+ * rendering/RenderBlock.h:
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::addFocusRingRects):
+ * rendering/RenderInline.h:
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move localCaretRect from RenderFlow into RenderBlock, since it only applied to blocks anyway and
+ was misplaced from the start.
- Merge r40332.
+ Reviewed by Antti Koivisto.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::localCaretRect):
+ * rendering/RenderBlock.h:
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
- 2009-01-28 Sam Weinig <sam@webkit.org>
+2009-01-28 Sam Weinig <sam@webkit.org>
Reviewed by Geoff Garen.
@@ -925,13 +20922,204 @@
* ForwardingHeaders/debugger/DebuggerActivation.h: Added.
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move createInlineBox out of RenderFlow and down into RenderInline and RenderBlock.
+
+ Reviewed by Beth Dakin
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::createInlineBox):
+ * rendering/RenderBlock.h:
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::createInlineBox):
+ * rendering/RenderInline.h:
+ * rendering/bidi.cpp:
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Move calcMargins from RenderFlow to RenderInline, since it was only ever called on RenderInlines.
+
+ Reviewed by Oliver Hunt
+
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::calcMargins):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren):
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Refactor the first and last line box member variables from RenderFlow. Encapsulate them into a new class called RenderLineBoxList that manages all modifications to
+ the list. This change will make it easier to give RenderInline and RenderBlock separate versions of the line box list without having to duplicate very much code.
+
+ Reviewed by Oliver Hunt
+
+ * GNUmakefile.am:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCoreSources.bkl:
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::deleteLine):
+ (WebCore::InlineFlowBox::removeLineBoxFromRenderObject):
+ (WebCore::InlineFlowBox::extractLine):
+ (WebCore::InlineFlowBox::extractLineBoxFromRenderObject):
+ (WebCore::InlineFlowBox::attachLine):
+ (WebCore::InlineFlowBox::attachLineBoxToRenderObject):
+ * rendering/InlineFlowBox.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::deleteLineBoxTree):
+ * rendering/RenderFlow.cpp:
+ (WebCore::RenderFlow::destroy):
+ (WebCore::RenderFlow::dirtyLineBoxes):
+ (WebCore::RenderFlow::createInlineBox):
+ * rendering/RenderFlow.h:
+ (WebCore::RenderFlow::RenderFlow):
+ (WebCore::RenderFlow::lineBoxes):
+ (WebCore::RenderFlow::firstLineBox):
+ (WebCore::RenderFlow::lastLineBox):
+ * rendering/RenderLineBoxList.cpp: Added.
+ (WebCore::RenderLineBoxList::~RenderLineBoxList):
+ (WebCore::RenderLineBoxList::appendLineBox):
+ (WebCore::RenderLineBoxList::deleteLineBoxTree):
+ (WebCore::RenderLineBoxList::extractLineBox):
+ (WebCore::RenderLineBoxList::attachLineBox):
+ (WebCore::RenderLineBoxList::removeLineBox):
+ (WebCore::RenderLineBoxList::deleteLineBoxes):
+ (WebCore::RenderLineBoxList::checkConsistency):
+ * rendering/RenderLineBoxList.h: Added.
+ (WebCore::RenderLineBoxList::RenderLineBoxList):
+ (WebCore::RenderLineBoxList::firstLineBox):
+ (WebCore::RenderLineBoxList::lastLineBox):
+ (WebCore::RenderLineBoxList::checkConsistency):
+ * rendering/RenderSVGInline.cpp:
+ (WebCore::RenderSVGInline::createInlineBox):
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::createInlineBox):
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::removeLineBoxFromRenderObject):
+ (WebCore::RootInlineBox::extractLineBoxFromRenderObject):
+ (WebCore::RootInlineBox::attachLineBoxToRenderObject):
+ * rendering/RootInlineBox.h:
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren):
+
+2009-01-28 David Kilzer <ddkilzer@apple.com>
+
+ Clean up FontPlatformData constructor
+
+ Reviewed by David Hyatt.
+
+ * platform/graphics/mac/FontPlatformData.h: Updated copyright.
+ (WebCore::FontPlatformData::FontPlatformData): Provide readable
+ names for constructor arguments and reformat member variables.
+ * platform/graphics/mac/FontPlatformDataMac.mm: Updated copyright.
+ (WebCore::FontPlatformData::FontPlatformData): Provide readable
+ names for constructor arguments and reformat member variables.
+
+2009-01-28 Tony Chang <tony@chromium.org>
+
+ Reviewed by David Hyatt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23593
+ Compile fixes for RenderThemeChromiumMac and RenderThemeChromiumWin.
+ This is a follow up for hyatt's RenderBox changes.
+
+ * rendering/RenderThemeChromiumMac.mm:
+ (WebCore::RenderThemeChromiumMac::baselinePosition):
+ * rendering/RenderThemeChromiumWin.cpp:
+ (WebCore::RenderThemeChromiumWin::paintMenuList):
+
+2009-01-28 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23582
+
+ Fix assertions when inline elements have both opacity (or something
+ else that creates a RenderLayer), and transform by ensuring that
+ setHasTransform() is only called for non-inline or replaced elements.
+ We also have to ensure that RenderReplicas will get transforms applied
+ to them by lying about them being replaced.
+
+ Tests: fast/transforms/transform-on-inline.html
+ fast/transforms/transform-table-row.html
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::styleDidChange):
+ * rendering/RenderReplica.cpp:
+ (WebCore::RenderReplica::RenderReplica):
+ * rendering/RenderTableRow.h:
+ (WebCore::RenderTableRow::requiresLayer):
+
+2009-01-28 Hironori Bono <hbono@chromium.org>
+
+ Reviewed by Justin Garcia.
+
+ https://bugs.webkit.org/show_bug.cgi?id=18835
+ Spelling underlines disappear when they shouldn't
+
+ The WebCore::InsertLineBreakCommand::doApply() function splits a text node
+ without copying existing markers. To fix this bug, change code which
+ manually splits a text node into a CompositeEditCommand::splitTextNode() call.
+
+ Test: editing/spelling/spelling-linebreak.html
+
+ * editing/InsertLineBreakCommand.cpp:
+ (WebCore::InsertLineBreakCommand::doApply):
- Merge r40313.
+2009-01-28 David Hyatt <hyatt@apple.com>
- 2009-01-28 David Hyatt <hyatt@apple.com>
+ Move the m_lineHeight member variable out of RenderFlow and down into RenderBlock and RenderInline. Shift the line height computation into RenderStyle so
+ that it isn't repeated in three places.
- Fix for
+ Reviewed by Sam Weinig
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::RenderBlock):
+ (WebCore::RenderBlock::lineHeight):
+ * rendering/RenderBlock.h:
+ * rendering/RenderFlow.cpp:
+ * rendering/RenderFlow.h:
+ (WebCore::RenderFlow::RenderFlow):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::RenderInline):
+ (WebCore::RenderInline::lineHeight):
+ * rendering/RenderInline.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::lineHeight):
+ * rendering/style/RenderStyle.h:
+ (WebCore::InheritedFlags::computedLineHeight):
+
+2009-01-28 Zachary Kuznia <zork@chromiuum.org>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=22070
+ Add an option to allow scripts to close windows.
+
+ * page/Settings.cpp:
+ (WebCore::Settings::Settings):
+ (WebCore::Settings::setAllowScriptsToCloseWindows):
+ * page/Settings.h:
+ (WebCore::Settings::allowScriptsToCloseWindows):
+
+2009-01-28 Adam Langley <agl@google.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23573
+ Make PlatformWidget on chromium an intptr_t to match changes made in Chromium
+
+ * platform/chromium/PlatformWidget.h:
+
+2009-01-28 David Hyatt <hyatt@apple.com>
+
+ Fix for
<rdar://problem/6531287> REGRESSION: CrashTracer: [USER] 12 crashes in Safari at com.apple.WebCore • WebCore::RenderBlock::removeFloatingObject + 59
@@ -941,11 +21129,255 @@
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::markAllDescendantsWithFloatsForLayout):
-2009-02-03 Mark Rowe <mrowe@apple.com>
+2009-01-27 David Hyatt <hyatt@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=23576
+
+ Work towards eliminating RenderFlow from the tree.
+
+ Move the m_continuation variable down from RenderFlow into RenderInline and RenderBlock. Since a block can only have an inline continuation following it, the type
+ of the member and methods reflect this (inlineContinuation() and m_inlineContinuation). Since an inline can have either a block or an inline continuation following it,
+ a base class of RenderBox* is used for the type of object returned (in anticipation of the removal of RenderFlow).
+
+ Since moving the continuation variable down into the subclasses increased the size of RenderInline and RenderBlock by 4 bytes, this patch also moves all of the bitfield
+ members of RenderFlow up to RenderObject. Since they fit within the available bits on RenderObject, this patch actually results in a net savings of 4 bytes on RenderInlines
+ and RenderBlocks!
+
+ One bitfield member was eliminated rather than moved: m_firstLine. This was really more of a state variable used during line layout only, so I removed it as a member
+ and just passed firstLine down to various methods as needed. Doing so uncovered some potential bugs where the first line state was not being respected when querying for
+ line offsets.
+
+ Continuations have been completely hidden from all files except for RenderFlow, RenderBlock and RenderInline. All of the code that referenced continuations directly
+ from base classes has been refactored to use virtual methods on RenderBlock and RenderInline instead.
+
+ RenderFlow still has a common addChildWithContinuation method that is used by both blocks and inlines. Since refactoring that method will be pretty tricky, I've held
+ off on that for a later patch.
+
+ Reviewed by Oliver Hunt
+
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::isKeyboardFocusable):
+ * page/AccessibilityRenderObject.cpp:
+ (WebCore::AccessibilityRenderObject::anchorElement):
+ (WebCore::AccessibilityRenderObject::boundingBoxRect):
+ * rendering/InlineFlowBox.cpp:
+ (WebCore::InlineFlowBox::determineSpacingForFlowBoxes):
+ (WebCore::InlineFlowBox::paint):
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::RenderBlock):
+ (WebCore::RenderBlock::~RenderBlock):
+ (WebCore::RenderBlock::destroy):
+ (WebCore::RenderBlock::addChildToFlow):
+ (WebCore::RenderBlock::makeChildrenNonInline):
+ (WebCore::RenderBlock::removeChild):
+ (WebCore::RenderBlock::layoutBlock):
+ (WebCore::RenderBlock::expandsToEncloseOverhangingFloats):
+ (WebCore::RenderBlock::collapseMargins):
+ (WebCore::RenderBlock::determineHorizontalPosition):
+ (WebCore::RenderBlock::setCollapsedBottomMargin):
+ (WebCore::RenderBlock::layoutOnlyPositionedObjects):
+ (WebCore::RenderBlock::paintObject):
+ (WebCore::RenderBlock::addContinuationWithOutline):
+ (WebCore::RenderBlock::setSelectionState):
+ (WebCore::RenderBlock::shouldPaintSelectionGaps):
+ (WebCore::RenderBlock::fillSelectionGaps):
+ (WebCore::RenderBlock::leftSelectionOffset):
+ (WebCore::RenderBlock::rightSelectionOffset):
+ (WebCore::RenderBlock::leftOffset):
+ (WebCore::RenderBlock::leftRelOffset):
+ (WebCore::RenderBlock::rightOffset):
+ (WebCore::RenderBlock::rightRelOffset):
+ (WebCore::RenderBlock::lineWidth):
+ (WebCore::RenderBlock::lowestPosition):
+ (WebCore::RenderBlock::rightmostPosition):
+ (WebCore::RenderBlock::leftmostPosition):
+ (WebCore::RenderBlock::getClearDelta):
+ (WebCore::RenderBlock::nodeAtPoint):
+ (WebCore::RenderBlock::offsetForContents):
+ (WebCore::RenderBlock::availableWidth):
+ (WebCore::RenderBlock::setDesiredColumnCountAndWidth):
+ (WebCore::RenderBlock::desiredColumnWidth):
+ (WebCore::RenderBlock::desiredColumnCount):
+ (WebCore::RenderBlock::columnRects):
+ (WebCore::RenderBlock::layoutColumns):
+ (WebCore::RenderBlock::adjustPointToColumnContents):
+ (WebCore::RenderBlock::adjustRectForColumns):
+ (WebCore::RenderBlock::absoluteRects):
+ (WebCore::RenderBlock::absoluteQuads):
+ (WebCore::RenderBlock::rectWithOutlineForRepaint):
+ (WebCore::RenderBlock::hoverAncestor):
+ (WebCore::RenderBlock::updateDragState):
+ (WebCore::RenderBlock::outlineStyleForRepaint):
+ (WebCore::RenderBlock::childBecameNonInline):
+ (WebCore::RenderBlock::updateHitTestResult):
+ * rendering/RenderBlock.h:
+ (WebCore::RenderBlock::rightOffset):
+ (WebCore::RenderBlock::leftOffset):
+ (WebCore::RenderBlock::inlineContinuation):
+ (WebCore::RenderBlock::setInlineContinuation):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::absoluteRects):
+ (WebCore::RenderBox::absoluteQuads):
+ (WebCore::RenderBox::addFocusRingRects):
+ (WebCore::RenderBox::containingBlockWidth):
+ * rendering/RenderBox.h:
+ (WebCore::RenderBox::collapsedMarginBottom):
+ (WebCore::RenderBox::childBecameNonInline):
+ * rendering/RenderContainer.cpp:
+ (WebCore::RenderContainer::updateBeforeAfterContentForContainer):
+ (WebCore::RenderContainer::removeLeftoverAnonymousBlock):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutVerticalBox):
+ * rendering/RenderFlow.cpp:
+ (WebCore::nextContinuation):
+ (WebCore::RenderFlow::continuationBefore):
+ (WebCore::RenderFlow::addChildWithContinuation):
+ (WebCore::RenderFlow::addChild):
+ (WebCore::RenderFlow::destroy):
+ (WebCore::RenderFlow::addFocusRingRects):
+ * rendering/RenderFlow.h:
+ (WebCore::RenderFlow::RenderFlow):
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::RenderInline):
+ (WebCore::RenderInline::destroy):
+ (WebCore::RenderInline::inlineContinuation):
+ (WebCore::RenderInline::styleDidChange):
+ (WebCore::RenderInline::addChildToFlow):
+ (WebCore::RenderInline::cloneInline):
+ (WebCore::RenderInline::splitInlines):
+ (WebCore::RenderInline::splitFlow):
+ (WebCore::RenderInline::positionForCoordinates):
+ (WebCore::RenderInline::rectWithOutlineForRepaint):
+ (WebCore::RenderInline::updateDragState):
+ (WebCore::RenderInline::childBecameNonInline):
+ (WebCore::RenderInline::updateHitTestResult):
+ * rendering/RenderInline.h:
+ (WebCore::RenderInline::isRenderInline):
+ (WebCore::RenderInline::continuation):
+ (WebCore::RenderInline::setContinuation):
+ * rendering/RenderListItem.cpp:
+ (WebCore::RenderListItem::positionListMarker):
+ * rendering/RenderListMarker.cpp:
+ (WebCore::RenderListMarker::RenderListMarker):
+ (WebCore::RenderListMarker::setSelectionState):
+ * rendering/RenderListMarker.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::RenderObject):
+ (WebCore::RenderObject::repaintAfterLayoutIfNeeded):
+ (WebCore::RenderObject::rectWithOutlineForRepaint):
+ (WebCore::RenderObject::handleDynamicFloatPositionChange):
+ (WebCore::RenderObject::updateDragState):
+ (WebCore::RenderObject::updateHitTestResult):
+ (WebCore::RenderObject::getTextDecorationColors):
+ (WebCore::RenderObject::adjustRectForOutlineAndShadow):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::isInlineBlockOrInlineTable):
+ (WebCore::RenderObject::childrenInline):
+ (WebCore::RenderObject::setChildrenInline):
+ (WebCore::RenderObject::hasColumns):
+ (WebCore::RenderObject::setHasColumns):
+ (WebCore::RenderObject::cellWidthChanged):
+ (WebCore::RenderObject::setCellWidthChanged):
+ (WebCore::RenderObject::isInlineContinuation):
+ (WebCore::RenderObject::hoverAncestor):
+ (WebCore::RenderObject::outlineStyleForRepaint):
+ (WebCore::RenderObject::setHasMarkupTruncation):
+ (WebCore::RenderObject::hasMarkupTruncation):
+ (WebCore::RenderObject::selectionState):
+ (WebCore::RenderObject::setSelectionState):
+ (WebCore::RenderObject::hasSelectedChildren):
+ (WebCore::RenderObject::isTopMarginQuirk):
+ (WebCore::RenderObject::isBottomMarginQuirk):
+ (WebCore::RenderObject::setTopMarginQuirk):
+ (WebCore::RenderObject::setBottomMarginQuirk):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::RenderReplaced):
+ (WebCore::RenderReplaced::setSelectionState):
+ * rendering/RenderReplaced.h:
+ (WebCore::RenderReplaced::canBeSelectionLeaf):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::calcWidth):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::updateWidth):
+ (WebCore::RenderTableCell::layout):
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::RenderText):
+ (WebCore::RenderText::localCaretRect):
+ (WebCore::RenderText::setSelectionState):
+ * rendering/RenderText.h:
+ (WebCore::RenderText::canBeSelectionLeaf):
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::updateHitTestResult):
+ * rendering/RenderView.h:
+ * rendering/RootInlineBox.cpp:
+ (WebCore::RootInlineBox::selectionTop):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::createLineBoxes):
+ (WebCore::RenderBlock::constructLine):
+ (WebCore::RenderBlock::computeHorizontalPositionsForLine):
+ (WebCore::RenderBlock::layoutInlineChildren):
+ (WebCore::RenderBlock::determineStartPosition):
+ (WebCore::RenderBlock::skipTrailingWhitespace):
+ (WebCore::RenderBlock::skipLeadingWhitespace):
+ (WebCore::RenderBlock::fitBelowFloats):
+ (WebCore::RenderBlock::findNextLineBreak):
+ (WebCore::RenderBlock::checkLinesForTextOverflow):
+
+2009-01-28 Adam Treat <adam.treat@torchmobile.com>
+
+ Reviewed by Nikolas Zimmermann and George Staikos.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23557
+ Allow option of hit testing frame content without clipping to the visible
+ viewport.
+
+ * WebCore.base.exp:
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::hitTestResultAtPoint):
+ * page/EventHandler.h:
+ * rendering/HitTestRequest.h:
+ (WebCore::HitTestRequest::HitTestRequest):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hitTest):
+
+2009-01-28 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Holger Freyther.
+
+ Fix the build with Qt on Windows.
+
+ Make sure that the QTWEBKIT_EXPORT macro becomes the Q_DECL_EXPORT macro
+ instead of the import macro when building the dll, by defining
+ QT_MAKEDLL.
+
+ SystemTimeWin.cpp is needed on Windows for userIdleTime(), which for the
+ other Qt platforms comes from TemporaryLinkStubs.cpp.
+
+ * WebCore.pro:
+
+2009-01-28 Ariya Hidayat <ariya.hidayat@trolltech.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Speed-up clipping: avoid calling expensive QPainter::clipRegion().
+ Beside, the check is not necessary since QPainter::setClipRect() will
+ work just fine if there is no clip region yet.
+
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::clip):
+
+2009-01-28 Darin Fisher <darin@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23546
+ Upstream GoogleURL implementation of KURL
- Merge r40305.
+ * platform/KURL.h:
+ * platform/KURLGoogle.cpp: Added.
+ * platform/KURLGooglePrivate.h: Added.
- 2009-01-27 Darin Adler <darin@apple.com>
+2009-01-27 Darin Adler <darin@apple.com>
Reviewed by Sam Weinig.
@@ -961,11 +21393,7 @@
even if we don't have a plug-in that implements Active X, existing
clients, such as Safari, don't expect that.
-2009-02-03 Mark Rowe <mrowe@apple.com>
-
- Merge r40304.
-
- 2009-01-27 Dan Bernstein <mitz@apple.com>
+2009-01-27 Dan Bernstein <mitz@apple.com>
Reviewed by Steve Falkenburg.
@@ -976,6 +21404,261 @@
(WebCore::Font::drawGlyphs): Changed to use GDI rather than Core
Graphics if the client has turned font smoothing off.
+2009-01-27 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23360
+
+ Use the new container-relative repaint methods to compute
+ post-layout repaints, and repaints using RenderLayer's
+ cached repaintRect() relative to that container, rather than
+ using absolute coords.
+
+ Replaced lots of boilerplate old/new rect code in various
+ layout methods with a stack-based LayoutRepainter class, and
+ fixed a bug in RenderTable which set didFullRepaint to
+ 'true' every time.
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::layoutBlock):
+ * rendering/RenderFlexibleBox.cpp:
+ (WebCore::RenderFlexibleBox::layoutBlock):
+ * rendering/RenderForeignObject.cpp:
+ (WebCore::RenderForeignObject::layout):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateLayerPositions):
+ (WebCore::RenderLayer::setHasVisibleContent):
+ * rendering/RenderLayer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::repaintUsingContainer):
+ (WebCore::RenderObject::repaint):
+ (WebCore::RenderObject::repaintRectangle):
+ (WebCore::RenderObject::repaintAfterLayoutIfNeeded):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::LayoutRepainter::LayoutRepainter):
+ (WebCore::RenderObject::LayoutRepainter::repaintAfterLayout):
+ (WebCore::RenderObject::LayoutRepainter::checkForRepaint):
+ * rendering/RenderPath.cpp:
+ (WebCore::RenderPath::layout):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::layout):
+ * rendering/RenderSVGContainer.cpp:
+ (WebCore::RenderSVGContainer::layout):
+ * rendering/RenderSVGImage.cpp:
+ (WebCore::RenderSVGImage::layout):
+ * rendering/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::layout):
+ * rendering/RenderSVGText.cpp:
+ (WebCore::RenderSVGText::layout):
+ * rendering/RenderSVGViewportContainer.cpp:
+ (WebCore::RenderSVGViewportContainer::layout):
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::layout):
+ * rendering/bidi.cpp:
+ (WebCore::RenderBlock::layoutInlineChildren):
+
+2009-01-27 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Darin Adler
+
+ <rdar://problem/3541409> - More groundwork and cleanup for CachedFrames
+
+ * history/CachedFrame.cpp:
+ (WebCore::CachedFrame::CachedFrame): Make the savePlatformDataToCachedFrame() client call here,
+ and add the code for caching subframes.
+ (WebCore::CachedFrame::clear):
+ * history/CachedFrame.h: Change to be RefCounted
+ (WebCore::CachedFrame::create):
+ (WebCore::CachedFrame::url):
+
+ * history/CachedPage.cpp:
+ (WebCore::CachedPage::CachedPage):
+ (WebCore::CachedPage::restore):
+ * history/CachedPage.h:
+ (WebCore::CachedPage::document):
+ (WebCore::CachedPage::documentLoader):
+ (WebCore::CachedPage::view):
+ (WebCore::CachedPage::url):
+ (WebCore::CachedPage::domWindow):
+ (WebCore::CachedPage::cachedMainFrame):
+
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::cachePageForHistoryItem): Move the platform data saving into the
+ CachedFrame itself.
+
+2009-01-27 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ Flip the arguments of computeRectForRepaint() from
+ computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool)
+ to
+ computeRectForRepaint(RenderBox* repaintContainer, IntRect&, bool)
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::clippedOverflowRectForRepaint):
+ (WebCore::RenderBox::computeRectForRepaint):
+ * rendering/RenderBox.h:
+ * rendering/RenderForeignObject.cpp:
+ (WebCore::RenderForeignObject::computeRectForRepaint):
+ * rendering/RenderForeignObject.h:
+ * rendering/RenderInline.cpp:
+ (WebCore::RenderInline::clippedOverflowRectForRepaint):
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::computeRectForRepaint):
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::computeAbsoluteRepaintRect):
+ * rendering/RenderReplaced.cpp:
+ (WebCore::RenderReplaced::clippedOverflowRectForRepaint):
+ * rendering/RenderTableCell.cpp:
+ (WebCore::RenderTableCell::clippedOverflowRectForRepaint):
+ (WebCore::RenderTableCell::computeRectForRepaint):
+ * rendering/RenderTableCell.h:
+ * rendering/RenderView.cpp:
+ (WebCore::RenderView::computeRectForRepaint):
+ * rendering/RenderView.h:
+
+2009-01-27 David Kilzer <ddkilzer@apple.com>
+
+ Add missing header guards to AccessibilityObjectWrapper.h
+
+ Reviewed by Anders Carlsson.
+
+ * page/mac/AccessibilityObjectWrapper.h: Added missing header guards.
+
+2009-01-27 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Dave Hyatt
+
+ https://bugs.webkit.org/show_bug.cgi?id=23567
+
+ Fix crash of svg/custom/stop-crash.svg testcase because of
+ infinite recursion, as I missed replacing absoluteClippedOverflowRect()
+ with clippedOverflowRectForRepaint() in RenderSVGGradientStop.
+
+ Also fix a missed conversion in RenderTableCol, and add a couple
+ of comments.
+
+ * rendering/RenderSVGGradientStop.h:
+ (WebCore::RenderSVGGradientStop::clippedOverflowRectForRepaint):
+ * rendering/RenderSVGImage.cpp:
+ (WebCore::RenderSVGImage::imageChanged):
+ * rendering/RenderTableCol.cpp:
+ (WebCore::RenderTableCol::clippedOverflowRectForRepaint):
+ * rendering/RenderTableRow.cpp:
+ (WebCore::RenderTableRow::layout):
+
+2009-01-27 Adele Peterson <adele@apple.com>
+
+ RS by Dave Hyatt
+
+ Use the textfield appearance for search fields in themeWin.css so the border/background
+ styling will work correctly on these fields.
+
+ * css/themeWin.css:
+
+2009-01-27 Dan Bernstein <mitz@apple.com>
+
+ - build fix
+
+ * bindings/js/JSHTMLInputElementCustom.cpp:
+ (WebCore::JSHTMLInputElement::setSelectionStart):
+ (WebCore::JSHTMLInputElement::setSelectionEnd):
+ (WebCore::JSHTMLInputElement::setSelectionRange):
+
+2009-01-27 Dan Bernstein <mitz@apple.com>
+
+ - build fix
+
+ * platform/graphics/Gradient.cpp:
+ (WebCore::Gradient::setSpreadMethod):
+
+2009-01-27 Paul Godavari <paul@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23561
+ Explicitly send the MIME type from an image dragged from a web
+ page to the desktop, to Chromium so that it can properly generate
+ a file name.
+
+ * platform/chromium/ChromiumDataObject.cpp:
+ (WebCore::ChromiumDataObject::clear):
+ (WebCore::ChromiumDataObject::hasData):
+ * platform/chromium/ChromiumDataObject.h:
+ * platform/chromium/ClipboardChromium.cpp:
+ (WebCore::writeImageToDataObject):
+
+2009-01-27 Mads Ager <ager@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23300
+ Follow Firefox in throwing exceptions when using selection
+ functions on HTMLInputElements that cannot have selection.
+
+ This requires custom setSelectionRange, setSelectionStart and
+ setSelectionEnd implementations, but it gets rid of the custom
+ getOwnPropertySlot.
+
+ * bindings/js/JSHTMLInputElementCustom.cpp:
+ (WebCore::JSHTMLInputElement::selectionStart):
+ (WebCore::JSHTMLInputElement::selectionEnd):
+ (WebCore::JSHTMLInputElement::setSelectionRange):
+ * html/HTMLInputElement.idl:
+
+2009-01-27 Evan Stade <estade@chromium.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=23435
+ Make spreadMethod a member of Gradient rather than GraphicsContext.
+ Implement spreadMethod for Skia.
+
+ * platform/graphics/Gradient.cpp:
+ (WebCore::Gradient::Gradient):
+ * platform/graphics/Gradient.h:
+ (WebCore::Gradient::setSpreadMethod):
+ (WebCore::Gradient::spreadMethod):
+ * platform/graphics/GraphicsContext.cpp:
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/GraphicsContextPrivate.h:
+ * platform/graphics/GraphicsTypes.h:
+ (WebCore::):
+ * platform/graphics/cairo/GradientCairo.cpp:
+ (WebCore::Gradient::platformGradient):
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ * platform/graphics/qt/GradientQt.cpp:
+ (WebCore::Gradient::platformGradient):
+ * platform/graphics/qt/GraphicsContextQt.cpp:
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ * platform/graphics/skia/GradientSkia.cpp:
+ (WebCore::Gradient::platformGradient):
+ * svg/SVGLinearGradientElement.cpp:
+ (WebCore::SVGLinearGradientElement::buildGradient):
+ * svg/SVGRadialGradientElement.cpp:
+ (WebCore::SVGRadialGradientElement::buildGradient):
+ * svg/graphics/SVGPaintServerGradient.cpp:
+ (WebCore::SVGPaintServerGradient::SVGPaintServerGradient):
+ (WebCore::SVGPaintServerGradient::setup):
+ (WebCore::SVGPaintServerGradient::externalRepresentation):
+ * svg/graphics/SVGPaintServerGradient.h:
+
+2009-01-27 Ariya Hidayat <ariya.hidayat@trolltech.com>
+
+ Rubber-stamped by Simon Hausmann.
+
+ http://www.qtsoftware.com/developer/task-tracker/index_html?id=238662&method=entry
+
+ [Qt] Map function keys F1 to F24.
+
+ * platform/qt/PlatformKeyboardEventQt.cpp:
+ (WebCore::windowsKeyCodeForKeyEvent):
+
2009-01-27 Brady Eidson <beidson@apple.com>
Reviewed by Dan Bernstein
@@ -1080,7 +21763,7 @@
2009-01-26 Simon Fraser <simon.fraser@apple.com>
Reviewed by David Hyatt
-
+
Back out r40285, because it was checked in with no bug number, no
testcase, is rendering change that did not get thorough review,
and broke the Mac build.
@@ -1099,7 +21782,7 @@
-Make the recently added back/forward cache logging much better by actually
walking the entire frame tree and indenting the resulting output.
- -Fix a null-termination bug in HistoryItem tree logging
+ -Fix a null-termination bug in HistoryItem tree logging
* history/HistoryItem.cpp:
(WebCore::HistoryItem::showTreeWithIndent):
@@ -1168,7 +21851,7 @@
2009-01-26 Anders Carlsson <andersca@apple.com>
Fix 64-bit build.
-
+
* WebCore.LP64.exp:
2009-01-26 Dmitry Titov <dimich@chromium.org>
@@ -1581,7 +22264,7 @@
Fix for <rdar://problem/6525392> REGRESSION (r40180): Scroll wheel events over text scroll the page
instead of the ancestor overflow (23525)
-
+
Make sure that we always call scroll() on the nearest enclosing RenderBox. No test case is possible
here, since wheel scrolling is currently untestable (the offset varies from machine to machine).
@@ -1880,7 +22563,7 @@
https://bugs.webkit.org/show_bug.cgi?id=23467
Change styleAvailable functionality to be a linked list
- rather than scanning every CompositeAnimation for
+ rather than scanning every CompositeAnimation for
Animations that are waiting for styleAvailable. This has
potential for large performance improvement in cases where
there are many animations firing at once. But it will also
@@ -2217,7 +22900,7 @@
Bug 23509: Crash at -[WebCoreAXObject doAXNextSentenceEndTextMarkerForTextMarker:]
https://bugs.webkit.org/show_bug.cgi?id=23509
-
+
Add null checking in makeRange instead of AX code
* editing/VisiblePosition.cpp:
@@ -2271,7 +22954,7 @@
Reviewed by Kevin Ollivier.
- Fix drawing in situations where sub-portions of the bitmap are to be
+ Fix drawing in situations where sub-portions of the bitmap are to be
drawn to the screen.
* platform/graphics/wx/ImageWx.cpp:
@@ -2288,10 +22971,10 @@
2009-01-23 Eric Carlson <eric.carlson@apple.com>
Reviewed by Adele Peterson
-
+
Fix for https://bugs.webkit.org/show_bug.cgi?id=23407
- Implement QTMovieWin::hasVideo so the controller on an audio-only <video> element
+ Implement QTMovieWin::hasVideo so the controller on an audio-only <video> element
is never hidden (as with an <audio> element).
Test: media/video-controls-visible-audio-only.html
@@ -2417,7 +23100,7 @@
Bug 23509: Crash at -[WebCoreAXObject doAXNextSentenceEndTextMarkerForTextMarker:]
https://bugs.webkit.org/show_bug.cgi?id=23509
-
+
Add null checking around next/previous sentence retrieval in AX code
* page/AccessibilityObject.cpp:
@@ -2603,7 +23286,7 @@
2009-01-23 Anders Carlsson <andersca@apple.com>
Fix tyop.
-
+
* editing/markup.cpp:
(WebCore::joinMarkups):
@@ -2613,11 +23296,11 @@
* Configurations/Base.xcconfig:
Fix GCC 4.0 build.
-
+
* editing/markup.cpp:
(WebCore::joinMarkups):
Pass a const reference to the vector.
-
+
* html/HTMLElement.cpp:
* platform/text/String.cpp:
Add comments indicating that these functions are for use in the debugger.
@@ -2627,7 +23310,7 @@
Reviewed by Sam Weinig.
Turn on -Wmissing-prototypes and fix the resulting warnings.
-
+
* Configurations/Base.xcconfig:
* bindings/js/JSHistoryCustom.cpp:
(WebCore::nonCachingStaticBackFunctionGetter):
@@ -3209,7 +23892,7 @@
add extra space above and below the content of a cell. This system was not confined to the table code and spilled out into all the other RenderObjects.
The y-position of the table cell box was set to the outer edge of the cell, but the y() method of RenderBox lied and added in borderTopExtra(). height()
also excluded the extra space, so did not accurately reflect the true size of the cell.
-
+
With the new system, the table cell box is completely accurate. The extra space becomes part of the padding of the cell. Padding has been reworked so that
additional intrinsic padding can be added on to the specified padding from style. Only the table code has to deal with the extra cell padding.
@@ -3223,7 +23906,7 @@
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
Make CSSComputedStyleDeclaration ask for padding values that exclude the built-in intrinsic padding. This ensures that getComputedStyle continues
to give the right answer.
-
+
* dom/ContainerNode.cpp:
(WebCore::ContainerNode::getLowerRightCorner):
* editing/visible_units.cpp:
@@ -3232,18 +23915,18 @@
* rendering/LayoutState.cpp:
(WebCore::LayoutState::LayoutState):
Remove borderTopExtra()/borderBottomExtra() hacks and localToAbsoluteForContent calls.
-
+
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::overflowRect):
Remove borderTopExtra()/borderBottomExtra() hacks and localToAbsoluteForContent calls.
-
+
(WebCore::RenderBlock::layoutBlock):
(WebCore::RenderBlock::expandsToEncloseOverhangingFloats):
The expandsToEncloseOverhangingFloats logic has been reworked. Table cells and fieldsets did not properly handle floats that spilled into the bottom padding. The
resulting box needed to not only expand to encompass the float, but also needed to place the full bottom padding after the float. The switch to make the extra table cell
space into padding exposed this issue. No extra layout test is required, since an existing table layout test exposes this issue and progresses to match Firefox with
this change.
-
+
(WebCore::RenderBlock::selectionGapRects):
(WebCore::RenderBlock::paintSelection):
(WebCore::RenderBlock::fillSelectionGaps):
@@ -3251,7 +23934,7 @@
(WebCore::RenderBlock::positionForCoordinates):
(WebCore::RenderBlock::offsetForContents):
Remove borderTopExtra()/borderBottomExtra() hacks and localToAbsoluteForContent calls.
-
+
* rendering/RenderBlock.h:
Add the new simplified method for expanding to encompass overhanging floats. The method has been devirtualized and made to include all of the cases (and not just a subset).
@@ -3266,7 +23949,7 @@
(WebCore::RenderBox::absoluteToLocal):
(WebCore::RenderBox::localToAbsoluteQuad):
Remove borderTopExtra()/borderBottomExtra() hacks and localToAbsoluteForContent calls.
-
+
* rendering/RenderBox.h:
(WebCore::RenderBox::y):
(WebCore::RenderBox::location):
@@ -3313,10 +23996,10 @@
(WebCore::RenderTableCell::paddingTop):
(WebCore::RenderTableCell::paddingBottom):
The new paddingTop() and paddingBottom() methods on table cells include the extra intrinsic padding.
-
+
(WebCore::RenderTableCell::setOverrideSize):
When a table's override size gets altered, the intrinsic padding needs to be cleared.
-
+
(WebCore::RenderTableCell::absoluteClippedOverflowRect):
(WebCore::RenderTableCell::computeAbsoluteRepaintRect):
(WebCore::RenderTableCell::baselinePosition):
@@ -3325,7 +24008,7 @@
(WebCore::RenderTableCell::paintBoxDecorations):
(WebCore::RenderTableCell::paintMask):
Remove borderTopExtra()/borderBottomExtra() hacks and localToAbsoluteForContent calls.
-
+
* rendering/RenderTableCell.h:
(WebCore::RenderTableCell::setIntrinsicPaddingTop):
(WebCore::RenderTableCell::setIntrinsicPaddingBottom):
@@ -3334,21 +24017,21 @@
(WebCore::RenderTableCell::intrinsicPaddingTop):
(WebCore::RenderTableCell::intrinsicPaddingBottom):
Add new helper methods for getting/setting a cell's intrinsic padding.
-
+
* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::calcRowHeight):
calcRowHeight has been modified to exclude the intrinsic padding when calculating the base height of rows prior to flexing. Because a cell now includes that
extra space, it has to be subtracted out in this method.
-
+
(WebCore::RenderTableSection::layoutRows):
Modify the code that sets up the intrinsic padding so that it does a relayout if the intrinsic padding changes. There was also an error where the baseline
position mismatched leading to negative intrinsic padding being added in (this error exists in ToT). The code now properly ignores cells that don't establish
a baseline. A number of tests progress with this change.
-
+
* rendering/RenderText.cpp:
(WebCore::RenderText::addLineBoxRects):
Remove borderTopExtra()/borderBottomExtra() hacks and localToAbsoluteForContent calls.
-
+
* rendering/RenderTreeAsText.cpp:
(WebCore::operator<<):
(WebCore::writeTextRun):
@@ -3358,6 +24041,18 @@
2009-01-22 Eric Seidel <eric@webkit.org>
+ Reviewed by Darin Adler.
+
+ Remove <strong>/<em> tags when toggling bold/italic since IE inserts them instead of <b>/<i>
+ https://bugs.webkit.org/show_bug.cgi?id=23486
+
+ Test: editing/execCommand/toggle-styles.html
+
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::isHTMLStyleNode):
+
+2009-01-22 Eric Seidel <eric@webkit.org>
+
Reviewed by Justin Garcia.
Remove <span> turds left by editing commands
@@ -4215,7 +24910,7 @@
* WebCore.LP64.exp:
Add some bridge related symbols.
-
+
* WebCore.xcodeproj/project.pbxproj:
Make runtime_object.h a private header.
@@ -4302,7 +24997,7 @@
Fix for https://bugs.webkit.org/show_bug.cgi?id=23317
The high CPU usage was really from repeatedly firing transitions caused
- by a bug in the way we handle background-color animations. If animating
+ by a bug in the way we handle background-color animations. If animating
from a valid background color to no background color, we sometimes left
(based on timing) the background color as transparent black, but valid
rather than invalid, which it should be. Fixing that got rid of the
@@ -4368,7 +25063,7 @@
Reviewed by Beth Dakin.
- Bug 23443: Table accessibility should be re-enabled after fixing crash that occurs at WebCore::AccessibilityTable::isTableExposableThroughAccessibility()
+ Bug 23443: Table accessibility should be re-enabled after fixing crash that occurs at WebCore::AccessibilityTable::isTableExposableThroughAccessibility()
https://bugs.webkit.org/show_bug.cgi?id=23443
Test: accessibility/table-modification-crash.html
@@ -4411,7 +25106,7 @@
Fix execCommand() 'super' and 'sub' commands to add <sup> and <sub> in quirks mode, and to toggle when called twice
https://bugs.webkit.org/show_bug.cgi?id=17733
-
+
Test changed: editing/execCommand/toggle-styles-expected.txt
* editing/ApplyStyleCommand.cpp:
@@ -4811,7 +25506,7 @@
Bug 23438: Provide a default value to the .in file parser
- Added the default value 1 as it simplifies some of
+ Added the default value 1 as it simplifies some of
the format by removing some "=1" that were awkward.
This was suggested by Darin Adler as par of a previous
@@ -4835,32 +25530,32 @@
* bridge/c/c_class.cpp:
* bridge/c/c_class.h:
Get rid of CClass::name().
-
+
* bridge/jni/jni_class.h:
Get rid of JavaClass::name().
-
+
* bridge/objc/objc_class.h:
* bridge/objc/objc_class.mm:
Get rid of ObjcClass::name().
-
+
* bridge/objc/objc_instance.h:
Get rid of supportsSetValueOfUndefinedField.
-
+
* bridge/objc/objc_instance.mm:
(ObjcInstance::setValueOfUndefinedField):
Fold supportsSetValueOfUndefinedField into setValueOfUndefinedField.
-
+
* bridge/runtime.cpp:
Get rid of getValueOfField and setValueOfField.
-
+
* bridge/runtime.h:
(JSC::Bindings::Instance::setValueOfUndefinedField):
Have this return a bool and get rid of supportsSetValueOfUndefinedField
-
+
* bridge/runtime_object.cpp:
(JSC::RuntimeObjectImp::fieldGetter):
Call Field::valueFromInstance on the field.
-
+
(JSC::RuntimeObjectImp::put):
Call Field::setValueToInstance on the field.
@@ -5434,7 +26129,7 @@
Build fix: remove duplicate entries in the Xcode project, and
sort the project with sort-Xcode-project-file .
-
+
* WebCore.xcodeproj/project.pbxproj:
2009-01-19 Simon Fraser <simon.fraser@apple.com>
@@ -5456,11 +26151,11 @@
* WebCore.xcodeproj/project.pbxproj:
* WebCoreSources.bkl:
Add CSSPropertyLonghand.h/cpp.
-
+
* css/CSSMutableStyleDeclaration.cpp:
(WebCore::CSSMutableStyleDeclaration::removeShorthandProperty):
Move CSSPropertyLonghand to its own file.
-
+
* css/CSSPropertyLonghand.cpp: Added.
(WebCore::initShorthandMap):
(WebCore::longhandForProperty):
@@ -5666,7 +26361,7 @@
Reviewed by Kevin Decker.
Allow plug-in views to return an instance directly.
-
+
* bindings/js/ScriptControllerMac.mm:
(WebCore::ScriptController::createScriptInstanceForWidget):
@@ -5822,7 +26517,7 @@
2009-01-18 Eric Carlson <eric.carlson@apple.com>
- Build fix for !ENABLE(VIDEO) following r40016.
+ Build fix for !ENABLE(VIDEO) following r40016.
* rendering/RenderSlider.cpp:
(WebCore::RenderSlider::mouseEventIsInThumb):
@@ -5924,16 +26619,16 @@
* WebCore.xcodeproj/project.pbxproj: add mediaControlsQT.css
* css/CSSPrimitiveValueMappings.h:
- (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): add MediaTimelineContainerPart,
+ (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): add MediaTimelineContainerPart,
CSSValueMediaCurrentTimeDisplay, and CSSValueMediaTimeRemainingDisplay
* css/CSSSelector.cpp:
(WebCore::CSSSelector::extractPseudoType): include new media controller element styles
- * css/CSSSelector.h:
+ * css/CSSSelector.h:
(WebCore::CSSSelector::): Ditto.
* css/CSSStyleSelector.cpp:
- (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): include new media
+ (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector): include new media
controller element styles
* css/CSSValueKeywords.in: add keywords for new media time display controls
@@ -5977,7 +26672,7 @@
* rendering/RenderMedia.h: Updated
* rendering/RenderSlider.cpp:
- (WebCore::RenderSlider::mouseEventIsInThumb): When slider is media timeline control, call
+ (WebCore::RenderSlider::mouseEventIsInThumb): When slider is media timeline control, call
element hitTest() method instead of assuming it is rectangular
* rendering/RenderSlider.h: make mouseEventIsInThumb virtual
@@ -6190,9 +26885,9 @@
2009-01-16 Steve Falkenburg <sfalken@apple.com>
<rdar://problem/6502511> Safari crashes if it's running while the desktop theme is changed.
-
+
This was caused by mismatched ENABLE definitions across WebCore and WebKit.
-
+
Several virtual methods were added to RenderTheme.h, conditionalized by ENABLE(VIDEO).
In addition to adding ENABLE_VIDEO to WebKit, this change also adds ENABLE_DATABASE and ENABLE_ICONDATABASE
to Windows WebCore/WebKit, and adds ENABLE_WORKERS, and several ENABLE_SVG_ flags to WebKit on Windows.
@@ -6518,7 +27213,7 @@
Reviewed by Sam Weinig.
Clean up the bridge code and get rid of Field::name() and Method::name().
-
+
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::invokeMethod):
* bridge/c/c_runtime.cpp:
@@ -6607,9 +27302,9 @@
which causes an infinite loop. I fixed this by deferring the setChanged to the next
run loop iteration. That made it not infinite loop, but it still retriggers the
transition forever. The problem is that there is both an 'all' and specific transition
- on 'opacity'. This tickled a bug in AnimationController which causes the opacity
+ on 'opacity'. This tickled a bug in AnimationController which causes the opacity
transition to get constantly cancelled and then retriggered. The problem is that
- the specific opacity transition has a duration of 0. I got rid of the logic to
+ the specific opacity transition has a duration of 0. I got rid of the logic to
flush out 0 duration transitions and it is no longer constantly triggered. The
logic to flush them was just an optimization, and you really need to keep them
around to make the logic to override earlier animations by later ones work. And there is
@@ -6755,22 +27450,22 @@
2009-01-15 Justin Garcia <justin.garcia@apple.com>
Reviewed by Oliver Hunt.
-
+
<rdar://problem/6444148> Styling a selection that ends in a line break can sometimes style what's after the break
If the range to style ended at [node, 0] or inside node (and if for some reason the node didn't get split),
applyInlineStyle would style node.
* editing/ApplyStyleCommand.cpp:
- (WebCore::ApplyStyleCommand::applyInlineStyle): Rename pastLast to pastEndNode, since it doesn't come from
+ (WebCore::ApplyStyleCommand::applyInlineStyle): Rename pastLast to pastEndNode, since it doesn't come from
Range::pastLastNode() anymore. pastEndNode is the node after the last one that is fully selected, since
the work done in the loop that follows should only be performed on fully selected nodes.
* editing/InsertLineBreakCommand.cpp:
(WebCore::InsertLineBreakCommand::doApply): Explicitly handle insertion into containers and after non-text nodes.
Those were handled accidently before.
* editing/htmlediting.cpp:
- (WebCore::caretMaxOffset): In various places we call this with a container and expect to be given the number
- of children in that container, so I changed it to match that. RenderBR and RenderObject::caretMaxOffset() should
+ (WebCore::caretMaxOffset): In various places we call this with a container and expect to be given the number
+ of children in that container, so I changed it to match that. RenderBR and RenderObject::caretMaxOffset() should
also be eliminated since maxDeepOffset handles non-text nodes.
2009-01-15 Anders Carlsson <andersca@apple.com>
@@ -6803,7 +27498,7 @@
2009-01-15 Anders Carlsson <andersca@apple.com>
Another attempt at fixing the Qt build.
-
+
* bridge/qt/qt_instance.cpp:
(JSC::Bindings::QtInstance::getOwnPropertySlot):
(JSC::Bindings::QtInstance::put):
@@ -6872,7 +27567,7 @@
Reviewed by Geoffrey Garen.
Make Instance::createRuntimeObject a virtual function and override it for QtInstance.
-
+
* bindings/js/JSPluginElementFunctions.cpp:
(WebCore::getRuntimeObject):
* bridge/c/c_utility.cpp:
@@ -7093,13 +27788,13 @@
No new tests added. In the future, we need to update DumpRenderTree to be able to run with different RenderThemes and
we'll need a separate set of results for different themes.
-
+
* css/themeWin.css: Renable search fields. Added new rules for sub-element placement.
-
+
* rendering/RenderTextControlSingleLine.cpp:
(WebCore::RenderTextControlSingleLine::textBlockWidth): Consider margin set on the sub-elements when computing the
desired width for the text block.
-
+
* rendering/RenderThemeWin.cpp:
(WebCore::RenderThemeWin::supportsFocus): Treat SearchFieldPart the same as TextFieldPart.
(WebCore::RenderThemeWin::determineState): ditto.
@@ -7290,10 +27985,10 @@
2009-01-14 Dimitri Glazkov <dglazkov@chromium.org>
Reviewed by Eric Seidel.
-
+
https://bugs.webkit.org/show_bug.cgi?id=23321
Upstream more bits of graphics/chromium.
-
+
* platform/graphics/chromium/FontPlatformDataChromiumWin.cpp: Added.
(WebCore::FontPlatformData::FontPlatformData):
(WebCore::FontPlatformData::operator=):
@@ -8090,7 +28785,7 @@
Reviewed by Simon Hausmann.
[Qt] Make sure media elements dispatch the 'loaded' event
-
+
We assume that when Phonon goes into paused state that we have the
complete media file. Once we do media loading ourselves we can
distinguish between loading the first frame and the complete media.
@@ -8191,12 +28886,12 @@
Reviewed by Simon Hausmann.
Change how themes adjust mediaControls.css to match html4/quicks.css
-
+
Instead of providing the full style sheet, the themes provide extra
overrides to the default style defined in UserAgentStyleSheetsData.
-
+
https://bugs.webkit.org/show_bug.cgi?id=23210
-
+
Also, merge WebKitResources.qrc and WebCoreResources.qrc to speed up
build time for the Qt port.
@@ -8248,13 +28943,13 @@
Reviewed by Darin Adler
Fix for <https://bugs.webkit.org/show_bug.cgi?id=22096>
- Bug 22096: REGRESSION (r35879) scrolldelay is counted in seconds
+ Bug 22096: REGRESSION (r35879) scrolldelay is counted in seconds
instead of miliseconds
Test: fast/css/webkit-marquee-speed-unit-in-quirksmode.html
* css/CSSParser.cpp:
- (WebCore::CSSParser::validUnit): treat unitless values in quirks mode
+ (WebCore::CSSParser::validUnit): treat unitless values in quirks mode
as miliseconds instead of seconds.
2009-01-12 David Hyatt <hyatt@apple.com>
@@ -8283,7 +28978,7 @@
!ENABLE(SVG_FONTS) build fix. Move defaultUnitsPerEm into a non-SVG header
so it can be used by all builds.
-
+
* platform/graphics/Font.h:
* platform/graphics/SimpleFontData.cpp:
* svg/SVGFontFaceElement.cpp:
@@ -8345,7 +29040,7 @@
In RenderBox::repaintLayerRectsForImage(), the repaint rect does not have
to be computed in absolute coordintes. Instead, we compute a repaintRect
relative to the RenderObject, which can repaint itself.
-
+
* rendering/RenderBox.cpp:
(WebCore::RenderBox::repaintLayerRectsForImage):
@@ -8410,14 +29105,14 @@
(WebCore::FontCache::FontCache):
2009-01-12 Eric Roman <eroman@chromium.org>
-
+
Reviewed by Darin Adler.
-
+
Fix some bugs with Selection::appendTrailingWhitespace().
https://bugs.webkit.org/show_bug.cgi?id=23232
-
+
Test: editing/selection/doubleclick-whitespace-crash.html
-
+
* editing/Selection.cpp:
(WebCore::makeSearchRange):
(WebCore::Selection::appendTrailingWhitespace):
@@ -8874,12 +29569,12 @@
Reviewed by Oliver Hunt
https://bugs.webkit.org/show_bug.cgi?id=23242
-
+
Fix CanvasRenderingContext2D::transform to do a pre-multiply,
rather than a post-multiply into m_transform. This bug did not affect
drawing, but did cause m_transform to be incorrect, which impacted
willDraw(), and isPointInPath.
-
+
Test: fast/canvas/canvas-incremental-repaint-2.html
* html/CanvasRenderingContext2D.cpp:
@@ -9000,7 +29695,7 @@
Checking whether malloc can allocate memory or not. If it can't, CRASH macro is invoked
(like in fastMalloc).
-
+
* bridge/npruntime.cpp:
(_NPN_GetStringIdentifier):
(_NPN_GetIntIdentifier):
@@ -9041,7 +29736,7 @@
Test: editing/selection/extend-selection-bidi.html
* rendering/RootInlineBox.cpp: (WebCore::RootInlineBox::fillLineSelectionGap):
- Make this function not assume a contiguous visual LTR selection range.
+ Make this function not assume a contiguous visual LTR selection range.
2009-01-11 Dmitry Titov <dimich@chromium.org>
@@ -9130,7 +29825,7 @@
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::styleForElement): call theme()->styleSheetForMediaControls to
- get the media controller style sheet
+ get the media controller style sheet
* rendering/MediaControlElements.cpp:
(WebCore::MediaControlInputElement::hitTest): Added
@@ -9150,11 +29845,11 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=23222
-
+
We need to disable LayoutState when an object has transforms,
because LayoutState is not transform-aware and therefore
repaint rects can be computed incorrectly.
-
+
Test: fast/repaint/transform-disable-layoutstate.html
* rendering/RenderBlock.cpp:
@@ -9209,7 +29904,7 @@
Fix infinite recursion in clientPaddingLeft and clientPaddingRight. This changes the code back to
how it was before RenderTextControlSingleLine was split out from RenderTextControl.
-
+
No test added since this code is only exercised when trying to place a search field's recent searches popup menu.
* rendering/RenderTextControlSingleLine.cpp:
@@ -9291,7 +29986,7 @@
2009-01-09 Anders Carlsson <andersca@apple.com>
Fix build.
-
+
* WebCore.LP64.exp:
2009-01-09 Dimitri Glazkov <dglazkov@chromium.org>
@@ -9500,7 +30195,7 @@
Reviewed by Simon Hausmann.
Prevent qmake from generating duplicate rules for embedded stylesheets
-
+
The STYLESHEETS_EMBED variable used to contain only one file name, but
now that it is a list of files we need to change it to be a dependency
for the stylesheet generator instead of the input.
@@ -9621,7 +30316,7 @@
Add ImageSourceSkia to platform/graphics/skia
https://bugs.webkit.org/show_bug.cgi?id=23200
-
+
ImageSourceSkia is mostly a hack to support our
ICO decoder model. See ImageSourceSkia.h for more
explanation. Eventually we'd like to make our ICO
@@ -9712,9 +30407,9 @@
Reviewed by Oliver Hunt.
- Fix <rdar://problem/6467206>
+ Fix <rdar://problem/6467206>
Resources loaded from the memory cache do not get correctly inserted into the DocLoader resource map (22994)
-
+
Use CachedResourceHandle in document resource map so resources get updated correctly when using
using cache validation conditionals.
@@ -10021,7 +30716,7 @@
Reviewed by Darin Adler.
- Part one of
+ Part one of
https://bugs.webkit.org/show_bug.cgi?id=23165
Add support for application cache dynamic entries
@@ -10055,7 +30750,7 @@
* loader/appcache/ApplicationCache.h: Added a list of pending dynamic entry actions, to be
used in the near future.
- * loader/appcache/DOMApplicationCache.idl: Updated for spec changes. Instead of length
+ * loader/appcache/DOMApplicationCache.idl: Updated for spec changes. Instead of length
attribute and item(), we now have an items attribute that returns a DOMStringList, and a
hasItem convenience method.
@@ -10201,7 +30896,7 @@
2009-01-07 Anders Carlsson <andersca@apple.com>
Another build fix.
-
+
* WebCore.LP64.exp:
2008-12-16 David Hyatt <hyatt@apple.com>
@@ -10288,7 +30983,7 @@
Reviewed by Oliver Hunt.
<rdar://problem/6391734> SnowLeopard: Crash doing Copy Image from context menu
-
+
Can't create an automated test case for specific contextual menu items yet and
a normal Copy doesn't cause a crash.
@@ -10945,18 +31640,18 @@
animations/simultaneous-start-transform.html
Fixed https://bugs.webkit.org/show_bug.cgi?id=22870
-
+
I added calls beginAnimationUpdate() and endAnimationUpdate() calls
to AnimationController. These are called by Document at the start
- and end of the recalcStyle cycle. Right now, I'm just using the
+ and end of the recalcStyle cycle. Right now, I'm just using the
beginAnimationUpdate() method to reset an animation time value.
The first time the animation time is accessed after this reset I set
it to the currentTime. So all animations in that cycle get the same
- start time.
+ start time.
The test cases checked in test this, but in the case of the 'left'
test it actually doesn't make any difference in most cases. This is
- because values are clamped to whole pixels, so the start times would
+ because values are clamped to whole pixels, so the start times would
have to be pretty far off for the test to fail using the old
currentTime() model. Still, under really heavy load, it's possible for
the test to fail without these changes.
@@ -11012,9 +31707,9 @@
Reviewed by Sam Weinig.
- Add a way for frame loader clients to always create a PluginDocument, regardless of
+ Add a way for frame loader clients to always create a PluginDocument, regardless of
the real document MIME type.
-
+
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::begin):
(WebCore::FrameLoader::shouldUsePlugin):
@@ -11083,7 +31778,7 @@
2009-01-06 David Smith <catfish.man@gmail.com>
Reviewed by Darin Adler.
-
+
https://bugs.webkit.org/show_bug.cgi?id=23129
Devirtualize Node::childNodes().
@@ -11148,18 +31843,18 @@
Reviewed by Dave Hyatt
https://bugs.webkit.org/show_bug.cgi?id=22985
-
+
Add an assertion that clip rects are being used when painting with the same
rootLayer that they were computed with.
-
+
Fix two issues detected by the assertion:
RenderLayer::updateClipRects() should not unconditionally update the clip rects
on its parent, but stop when reaching rootLayer (just like calculateClipRects()).
-
+
We need to pass the temporaryClipRects flag down through reflection painting
to handle the case of nested reflections.
-
+
Also use temporary clip rects in RenderTreeAsText, since that code does not
reset the painting root for transformed layers, so cached clip rects will not
match those used for painting.
@@ -11223,17 +31918,17 @@
Implement 'pointer-events' for HTML content. This involved
adding a new value 'auto' which behaves as 'visiblePainted'
- in SVG content.
-
+ in SVG content.
+
Moved the property out of the SVG CSS code and into
- the general CSS (both parsing and RenderStyle).
-
+ the general CSS (both parsing and RenderStyle).
+
Changes to the hit testing functionality of the Render tree,
- specifically the nodeAtPoint methods. Where they used to
+ specifically the nodeAtPoint methods. Where they used to
test for visibility, they now use a helper function defined
on base classes (RenderObject and InlineBox) that checks both
visibility and pointer-events.
-
+
https://bugs.webkit.org/show_bug.cgi?id=11395
Tests: fast/events/pointer-events-2.html
@@ -11310,7 +32005,7 @@
Reviewed by Gavin Barraclough.
- CanvasPixelArray performance is too slow
+ CanvasPixelArray performance is too slow
<https://bugs.webkit.org/show_bug.cgi?id=23123>
Remove the WebCore CanvasPixelArray implementation and replace
@@ -11365,18 +32060,18 @@
2009-01-05 Anders Carlsson <andersca@apple.com>
Build fix.
-
+
* plugins/PluginView.h:
(WebCore::PluginManualLoader::~PluginManualLoader):
2009-01-05 Anders Carlsson <andersca@apple.com>
Reviewed by Kevin Decker.
-
- Add an abstract PluginManualLoader class and make PluginView inherit from it.
-
+
+ Add an abstract PluginManualLoader class and make PluginView inherit from it.
+
Add some error checking that currently exists in WebKit (but not for long!)
-
+
* plugins/PluginView.cpp:
(WebCore::PluginView::didReceiveResponse):
(WebCore::PluginView::didReceiveData):
@@ -11674,7 +32369,7 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=23090
-
+
If an object gets a Layout hint, and the style change will result in
the creation of a RenderLayer, then we need to repaint the old position
of the object. This was done for transform, but we have to test opacity too.
@@ -11757,9 +32452,9 @@
Reverse the order in the icon database main thread loop to
write the pending icons to the database before trying
- to read any requested icons. This ensures that a requested icon
+ to read any requested icons. This ensures that a requested icon
has the correct data when read.
-
+
* loader/icon/IconDatabase.cpp:
(WebCore::IconDatabase::syncThreadMainLoop):
@@ -11776,7 +32471,7 @@
https://bugs.webkit.org/show_bug.cgi?id=23025
DOMTimer lifetime cleanup: timeoutMap methods on Document now do not delete the timer.
Instead, all 3 places that delete timers do it directly calling 'delete' and then timer's dtor removes the ID from the timeoutMap.
- Note that in case the context is destroyed and timers are deleted at once, the check in ~DOMTimer() prevents
+ Note that in case the context is destroyed and timers are deleted at once, the check in ~DOMTimer() prevents
unnecessary HashMap remove in case the Document is being destroyed.
* bindings/js/DOMTimer.cpp:
@@ -11847,10 +32542,10 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=23082
-
+
Fix GIF animation by ensuring that the signature of
startAnimation() in the base class matches the method in BitmapImage.
-
+
Test: fast/backgrounds/animated-gif-as-background.html
* platform/graphics/Image.h:
@@ -11859,10 +32554,10 @@
2009-01-02 David Smith <catfish.man@gmail.com>
Reviewed by Darin Adler.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22699
Enable NodeList caching for getElementsByTagName
-
+
test: fast/dom/getelementsbytagnamens-mixed-namespaces.html
* dom/Document.cpp:
@@ -11878,7 +32573,7 @@
(WebCore::MappedAttributeHash::hash): Use WTF::stringHashingStartValue
* dom/TagNodeList.cpp:
(WebCore::TagNodeList::TagNodeList): Add a NodeList cache argument
- * dom/TagNodeList.h:
+ * dom/TagNodeList.h:
(WebCore::TagNodeList::create): Add a NodeList cache argument
* platform/text/StringHash.h:
(WebCore::CaseFoldingHash::hash): Use WTF::stringHashingStartValue
@@ -11889,7 +32584,7 @@
Reviewed by Darin Adler
- Fix for https://bugs.webkit.org/show_bug.cgi?id=23066 & <rdar://problem/6028417>
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=23066 & <rdar://problem/6028417>
Full Page Zoom: a <video> element that doesn't include width/height attribute does not scale
* rendering/RenderVideo.cpp:
@@ -11954,7 +32649,7 @@
Reviewed by Darin Adler
Use an OwnPtr for m_chromeClient.
-
+
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::~SVGImage):
(WebCore::SVGImage::dataChanged):
@@ -11973,7 +32668,7 @@
a rect parameter for the changed rect, allowing incremental repaints.
Fix RenderImage::imageChanged to take advantage of this changedRect to
only repaint the changed parts of the image.
-
+
This also enables incremental painting for canvas-as-image, so
add tests for that too.
@@ -12217,11 +32912,11 @@
Reviewed by Darin Adler, Oliver Hunt
https://bugs.webkit.org/show_bug.cgi?id=23065
-
+
Enable incremental painting of canvas. This turns incremental painting
back on, and fixes issues with stroke width and miters, calling willDraw()
for strokeText and fillText, and taking shadows into account.
-
+
Test: fast/canvas/canvas-incremental-repaint.html
* html/CanvasRenderingContext2D.cpp:
@@ -12388,11 +33083,11 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=23042
-
+
Rather than doing a repaint() inside of computeAbsoluteRepaintRect()
when there is a reflection, compute the location of the rect inside
the reflection and take the union of the unreflected and reflected rects.
-
+
Test: fast/repaint/reflection-redraw.html
* rendering/RenderBox.cpp:
@@ -12552,9 +33247,9 @@
Reviewed by Brady Eidson.
Fix for https://bugs.webkit.org/show_bug.cgi?id=21797
- <rdar://problem/6310682> REGRESSION: Crash in CFHTTPCookieStorageCopy beneath WebCore::cookies() when
+ <rdar://problem/6310682> REGRESSION: Crash in CFHTTPCookieStorageCopy beneath WebCore::cookies() when
running fast/dom/document-attribute-js-null.html and http/tests/security/cookies/create-document.html
-
+
Return early if the document is trying to get or set a cookie with an empty cookie url.
* dom/Document.cpp:
@@ -12840,7 +33535,7 @@
Prepare to add create/remove timeout methods to JSWorkerContext by moving
timer-specific code from JSDOMWindowBase to DOMTimer.
Moved everything JS-related from DOMTimer to ScheduledAction.
- Now ScheduledAction is what it wanted to be all the time: a JS engine-specific
+ Now ScheduledAction is what it wanted to be all the time: a JS engine-specific
container for timer callback that knows how to invoke it.
DOMTimer is not anymore JS-specific.
@@ -12950,9 +33645,9 @@
Reviewed by Oliver Hunt.
<rdar://problem/6465669> Frequent !isPurgeable() assertion in WebCore::CachedResource::addClient
-
+
Disallow turning resources that are being revalidated to purgable state.
-
+
No test, the condition is difficult to produce in DRT.
* loader/CachedCSSStyleSheet.cpp:
@@ -13049,10 +33744,10 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=22941
-
+
If the document element has opacity, we need to erase the view background to
white before painting.
-
+
Test: fast/backgrounds/opacity-on-document-element.html
* rendering/RenderView.cpp:
@@ -13063,10 +33758,10 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=21910
-
+
Fix SVGImage painting by ensuring that the SVGImage resizes its FrameView correctly.
Otherwise the FrameView is left at 0x0, and nothing paints.
-
+
* svg/graphics/SVGImage.cpp:
(WebCore::SVGImage::draw):
@@ -13977,7 +34672,7 @@
Reviewed by Kevin Ollivier.
Add Context Menu support to wx bindings.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22675
* platform/ContextMenu.h:
@@ -13994,12 +34689,12 @@
Reviewed by Darin Adler.
- Temporary band-aide fix for <rdar://problem/6372481> In Gmail, a
- crash occurs at
- AccessibilityTable::isTableExposableThroughAccessibility() when
+ Temporary band-aide fix for <rdar://problem/6372481> In Gmail, a
+ crash occurs at
+ AccessibilityTable::isTableExposableThroughAccessibility() when
attempting to create a link in a rich text message
- We need to disable Accessibility Tables until we get this fixed for
+ We need to disable Accessibility Tables until we get this fixed for
real to prevent rampant crashing.
* page/AccessibilityTable.cpp:
@@ -14010,10 +34705,10 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=22938
-
+
When the document element is transformed, we need to paint
the view background to avoid unpainted areas.
-
+
Test: fast/transforms/transformed-document-element.html
* rendering/RenderView.cpp:
@@ -14131,7 +34826,7 @@
storage is disallowed, all authentication challenges are sent to
the client.
- let the FrameLoaderClient decide whether to use the credential
- storage.
+ storage.
* loader/EmptyClients.h:
(WebCore::EmptyFrameLoaderClient::shouldUseCredentialStorage): Added.
@@ -14141,7 +34836,7 @@
to the FrameLoaderClient.
* loader/FrameLoader.h: Declared shouldUseCredentialStorage().
* loader/FrameLoaderClient.h: Declared shouldUseCredentialStorage().
- * loader/ResourceLoader.cpp:
+ * loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::shouldUseCredentialStorage): Added. Calls
through to the FrameLoader.
* loader/ResourceLoader.h:
@@ -14215,7 +34910,7 @@
Reviewed by John Sullivan.
- Add new FrameLoaderClient method to indicate the first visually
+ Add new FrameLoaderClient method to indicate the first visually
non-empty layout based on an heuristic. Right now that heuristic
is the first layout after an image, text or plugin has been added
to the render tree, but I can imagine it becoming much smarter.
@@ -14389,7 +35084,7 @@
If JavaScript is not currently executing, the handleEvent member function
of JSAbstractEventListener should set the dynamic global object to the
global object of the context in which the event occurred.
-
+
If this is not set, then JavaScriptCore will simply take the global object
of the context where the event handler function was created, which may be
a different frame. This will cause the popup blocker to incorrectly block
@@ -14405,13 +35100,13 @@
Reviewed by Dave Hyatt
https://bugs.webkit.org/show_bug.cgi?id=22570
-
+
Add the ability to compute clip rects independently from
- caching them on the RenderLayer. When painting reflections, use
+ caching them on the RenderLayer. When painting reflections, use
such temporarily computed clipRects, otherwise the layer may cache
clipRects which are invalid, since they have been computed with
a rootLayer that is not the one usually used to paint.
-
+
Test: fast/reflections/reflection-overflow-hidden.html
* rendering/RenderLayer.cpp:
@@ -14441,7 +35136,7 @@
https://bugs.webkit.org/show_bug.cgi?id=22618
- Fix MinGW QtWebKit linking problems and also make the
+ Fix MinGW QtWebKit linking problems and also make the
QtWebKit build system more robust.
* WebCore.pro:
@@ -14554,9 +35249,9 @@
Reviewed by Geoff Garen.
- Change HTTPHeaderMap to use an AtomicString as its key.
+ Change HTTPHeaderMap to use an AtomicString as its key.
Shaves ~1MB off of the Mozilla Memory Test
- No functionality difference
+ No functionality difference
* WebCore.xcodeproj/project.pbxproj:
* inspector/InspectorController.cpp:
@@ -14645,7 +35340,7 @@
Fix for https://bugs.webkit.org/show_bug.cgi?id=22871
<rdar://problem/6417316> RenderThemeWin buttons are too short/thin
- * rendering/RenderButton.cpp: (WebCore::RenderButton::setupInnerStyle):
+ * rendering/RenderButton.cpp: (WebCore::RenderButton::setupInnerStyle):
Check if the button's style (not the new inner style) has appearance set to determine whether we should set padding on the inner style.
2008-12-15 Nikolas Zimmermann <nikolas.zimmermann@torchmobile.com>
@@ -14725,7 +35420,7 @@
* bindings/js/JSGeolocationCustom.cpp:
(WebCore::createPositionOptions): Added. Extracts the enableHighAccuracy
- and timeout fields from a vanilla JS object in order to create the
+ and timeout fields from a vanilla JS object in order to create the
PositionOptions object, checking for exceptions as necessary.
(WebCore::JSGeolocation::getCurrentPosition): Use createPositionOptions
instead of toPositionOptions.
@@ -14847,13 +35542,13 @@
Reviewed by Darin Adler.
When a resource is cached locally, WebKit should follow RFC 2616 "Specific end-to-end revalidation" instead of "Unspecified end-to-end revalidation"
- https://bugs.webkit.org/show_bug.cgi?id=17998
-
- - Enable conditional revalidation for reloads by default.
+ https://bugs.webkit.org/show_bug.cgi?id=17998
+
+ - Enable conditional revalidation for reloads by default.
- Add a parameter to FrameLoader::reload() for forcing end-to-end reload.
- - To avoid duplicating state remove m_cachePolicy variables from FrameLoader and DocLoader.
+ - To avoid duplicating state remove m_cachePolicy variables from FrameLoader and DocLoader.
Instead synthezise the policy on demand.
-
+
This speeds up reloads and makes them use way less bandwidth.
* WebCore.base.exp:
@@ -14864,10 +35559,10 @@
(WebCore::DocLoader::checkForReload): Support CachePolicyRevalidate.
(WebCore::DocLoader::requestResource):
(WebCore::DocLoader::cachePolicy):
- * loader/DocLoader.h: Get rid of m_cachePolicy member.
+ * loader/DocLoader.h: Get rid of m_cachePolicy member.
* loader/FrameLoader.cpp:
- (WebCore::ScheduledRedirection::ScheduledRedirection):
- Add parameter to differentiate refresh from other types of redirects.
+ (WebCore::ScheduledRedirection::ScheduledRedirection):
+ Add parameter to differentiate refresh from other types of redirects.
m_cachePolicy was used for signaling this before.
(WebCore::isBackForwardLoadType):
(WebCore::FrameLoader::FrameLoader):
@@ -14883,11 +35578,11 @@
(WebCore::FrameLoader::redirectionTimerFired):
(WebCore::FrameLoader::canCachePage):
(WebCore::FrameLoader::loadURL):
- (WebCore::FrameLoader::reload):
+ (WebCore::FrameLoader::reload):
Differentiate between revalidation and reload.
No need to use setHTTPHeaderField here, addExtraFieldsToRequest will set the headers.
(WebCore::FrameLoader::transitionToCommitted):
- (WebCore::FrameLoader::cachePolicy): Determine the cache policy based on current load type.
+ (WebCore::FrameLoader::cachePolicy): Determine the cache policy based on current load type.
(WebCore::FrameLoader::checkLoadCompleteForThisFrame):
(WebCore::FrameLoader::addExtraFieldsToRequest): Set Cache-control: no-cache for FrameLoadTypeReloadFromOrigin
(WebCore::FrameLoader::shouldScrollToAnchor):
@@ -14898,7 +35593,7 @@
* loader/FrameLoader.h:
* loader/FrameLoaderTypes.h: Add FrameLoadTypeReloadFromOrigin
(WebCore::):
- * loader/NavigationAction.cpp:
+ * loader/NavigationAction.cpp:
(WebCore::navigationType): Support FrameLoadTypeReloadFromOrigin
* loader/loader.cpp:
(WebCore::Loader::Host::servePendingRequests):
@@ -15291,7 +35986,7 @@
* platform/win/DragImageCGWin.cpp:
(WebCore::deallocContext): Add a generic CGContextRef destructor.
* platform/win/DragImageCairoWin.cpp:
- (WebCore::deallocContext): Add a generic cairo_* destructor.
+ (WebCore::deallocContext): Add a generic cairo_* destructor.
(WebCore::allocImage): New implementation to allocate a Cairo
surface of a specified size.
(WebCore::createCairoContextFromBitmap): New implementation to
@@ -15310,7 +36005,7 @@
WebKitCSSKeyframesRule to Window object.
This required generating constructors for the event
interfaces.
-
+
https://bugs.webkit.org/show_bug.cgi?id=20560
* dom/WebKitAnimationEvent.idl:
@@ -15373,19 +36068,19 @@
Delete the previous timer-queue timer in the main thread, just prior to scheduling a new timer.
The code previously called DeleteTimerQueueTimer in the timer callback proc.
-
+
The new technique simplifies the code, since we now create and delete timers on the
same thread, and don't access the timer queue or timer handles in the callback.
This allows us to remove some mutex use, and more importantly, it solves a race
condition that was occuring between ChangeTimerQueueTimer and DeleteTimerQueueTimer.
-
+
Since the timer callback isn't passed the timer handle, we were retrieving that handle
via a global. If the timer callback code was entered, but then a new timer was immediately
scheduled (prior to the callback acquiring the mutex and calling DeleteTimerQueueTimer),
there was a small window where the timer could be re-scheduled via ChangeTimerQueueTimer
and then immediately deleted once the already running callback acquired the mutex and
then called DeleteTimerQueueTimer. This resulted in the newly scheduled timer never firing.
-
+
Reviewed by Oliver Hunt.
* platform/win/SharedTimerWin.cpp:
@@ -15522,7 +36217,7 @@
Reviewed by Simon Hausmann.
Implement ImageSource::filenameExtension() for the Qt port
-
+
We're using QImageReader::imageFormat().toLower() to check
that the image format is supported, and if it is we store
the resulting extension when creating the ImageDecoderQt.
@@ -15541,11 +36236,11 @@
Reviewed by Geoff Garen
Account for the size of the response and request headers as well as other overhead
- when calculating the size a resource takes up in the cache. Halts unbounded
+ when calculating the size a resource takes up in the cache. Halts unbounded
growth in the cache. Reduced stress test memory high water marks by > 50%.
- Uses estimates gathered from the stress test to set the overhead size.
- A version of the patch was created that calculated most of the sizes, but it was
+ Uses estimates gathered from the stress test to set the overhead size.
+ A version of the patch was created that calculated most of the sizes, but it was
decided that the patch was still at a basic level an estimate. What gains it made
in accuracy was offset by the complexity involved in creating and updating the
estimate.
@@ -15722,7 +36417,7 @@
I had to add one more bit of code. When animation timers used to fire the animation events.
This would always happen from the RunLoop, so any style changes that happened in the
event handler would get picked up on the next updateRendering() call. But now the start
- event is generated during the styleIsAvailable() call, which is in the middle of the
+ event is generated during the styleIsAvailable() call, which is in the middle of the
updateRendering() cycle. And calling an event handler in the middle of updateRendering()
is not allowed and causes style changes to get missed. We already have a mechanism in
AnimationController to defer updateRendering() calls. So I added logic to defer all
@@ -16081,7 +36776,7 @@
Reviewed by Antti Koivisto
<rdar://problem/6431224>
-
+
When updating the value of a slider, don't mark the parents
as needing layout, because the size of the slider can never
change. This fixes full-page repaints in some cases.
@@ -16093,7 +36788,7 @@
Potential build fix. The forward declaration of FloatPoint should
be inside the WebCore namespace.
-
+
* platform/graphics/FloatPoint3D.h:
2008-12-10 Simon Fraser <simon.fraser@apple.com>
@@ -16105,7 +36800,7 @@
Cleanup FloatPoint3D: inline the getters and setters,
fix a potential divide-by-zero in normalize(), and add
a FloatPoint constructor.
-
+
* platform/graphics/FloatPoint3D.cpp:
(WebCore::FloatPoint3D::FloatPoint3D):
(WebCore::FloatPoint3D::normalize):
@@ -16197,7 +36892,7 @@
Part of
https://bugs.webkit.org/show_bug.cgi?id=22570
-
+
Rename methods on RenderLayer for clarity:
clearClipRects -> clearClipRectsIncludingDescendants
clearClipRect -> clearClipRects
@@ -16219,7 +36914,7 @@
2008-12-10 Kevin Ollivier <kevino@theolliviers.com>
wx build fix after the script call stack/frame additions.
-
+
* WebCoreSources.bkl:
2008-12-10 Srinivasa Rao M. Hamse <msrinirao@gmail.com>
@@ -16459,7 +37154,7 @@
* bindings/js/ScriptValue.h: Added isNull and isUndefined
* bindings/scripts/CodeGeneratorJS.pm: Add handling for
CustomArgumentHandling attribute.
- * inspector/InspectorController.cpp: Refactored to use
+ * inspector/InspectorController.cpp: Refactored to use
ScriptCallFrame and ScriptCallStack.
(WebCore::ConsoleMessage::ConsoleMessage):
(WebCore::InspectorController::addMessageToConsole):
@@ -16914,11 +37609,11 @@
Fix issues which break reading inline style for -webkit-transition
and -webkit-transform-origin.
-
+
Test: fast/css/transform-inline-style.html
* css/CSSMutableStyleDeclaration.cpp:
- (WebCore::CSSMutableStyleDeclaration::getPropertyValue): Add cases
+ (WebCore::CSSMutableStyleDeclaration::getPropertyValue): Add cases
for CSSPropertyWebkitTransformOrigin and CSSPropertyWebkitTransition
so that these shorthand properties are returned correctly.
* css/CSSParser.cpp:
@@ -16935,12 +37630,12 @@
https://bugs.webkit.org/show_bug.cgi?id=22717
Make CSS values use less memory
-
+
Share CSSPrimitiveValue objects for commonly used values including
- idents
- colors
- small integers
-
+
This reduces the amount CSSPrimitiveValue instances by > 80%.
* css/CSSPrimitiveValue.cpp:
@@ -16960,11 +37655,11 @@
Get CSSValues off from the common StyleBase base class. They don't
need a parent pointer or anything else there and there is no real
reason to have them in same data structures with other CSSOM objects.
-
- Disabled (instead of refactoring around the lack of common base) the ability
- to have style declaration blocks as CSS variable values. They don't exist in
- the spec so I wasn't sure if they have future or not. It would not be hard to
- get them back. CSS variables are in any case an experimental feature and
+
+ Disabled (instead of refactoring around the lack of common base) the ability
+ to have style declaration blocks as CSS variable values. They don't exist in
+ the spec so I wasn't sure if they have future or not. It would not be hard to
+ get them back. CSS variables are in any case an experimental feature and
not enabled by default.
* css/CSSInitialValue.h:
@@ -17064,9 +37759,9 @@
https://bugs.webkit.org/show_bug.cgi?id=22379
Make CSSOM use less memory
-
+
Use vector instead of a double linked list for properties in CSSMutableStyleDeclaration.
-
+
Taught setter functions to use existing slots to avoid memory moves, plus some
other optimizations.
@@ -17141,7 +37836,7 @@
Fix logic related to repainting when transform changes:
If an object has a layer, and the transform changes, then we need
to do a repaintIncludingDescendants(), not just a repaint.
-
+
Test: fast/repaint/transform-repaint-descendants.html
* rendering/RenderObject.cpp:
@@ -17167,7 +37862,7 @@
Reviewed by Dave Hyatt
https://bugs.webkit.org/show_bug.cgi?id=15671
-
+
Fix caret rendering to behave correctly with transforms:
* Rename caretRect() methods to localCaretRect() and
absoluteCaretBounds() as appropriate
@@ -17505,7 +38200,7 @@
Bug 22579: Providing a function to ScrollbarClient.h which allows us to get at the tickmarks
without relying on high-level WebCore types, as requested by Dave Hyatt.
-
+
No functional changes, thus no test cases.
* page/FrameView.cpp:
@@ -17655,9 +38350,9 @@
Reviewed by Kevin Ollivier.
Add a MIME mapping for the .htm extension to wx and GTK ports.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22668
-
+
* platform/gtk/MIMETypeRegistryGtk.cpp:
(WebCore::):
* platform/wx/MimeTypeRegistryWx.cpp:
@@ -17669,7 +38364,7 @@
Implement basic text paste support in wx and add notImplemented stubs
to catch other methods.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22667
* platform/wx/PasteboardWx.cpp:
@@ -17701,7 +38396,7 @@
Reviewed by Kevin Ollivier.
Turn off styled controls until we can implement them properly.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22662
* platform/wx/RenderThemeWx.cpp:
@@ -17992,7 +38687,7 @@
makes it unnecessary to 'serialize' them into special PausedTimeouts
instance, so pause/resumeTimeouts implementation in JSDOMWindowBase can also be removed.
Also, moving TimeoutMap from JSDOMWindowBase to Document matches lifetime
- of timeouts and makes it possible to not roundtrip them via PausedTimeouts
+ of timeouts and makes it possible to not roundtrip them via PausedTimeouts
every time when JSDOMWindow wrapper is destroyed while the page is in the b/f cache.
Timeouts are now paused with other ActiveDOMObjects:
@@ -18021,7 +38716,7 @@
* bindings/js/DOMTimer.h:
* bindings/js/JSDOMBinding.cpp: ActiveDOMObject can have no JS wrapper
- (WebCore::markActiveObjectsForContext):
+ (WebCore::markActiveObjectsForContext):
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::~JSDOMWindowBase):
@@ -18050,7 +38745,7 @@
* inspector/JavaScriptDebugServer.h:
* loader/FrameLoader.cpp:
- (WebCore::FrameLoader::commitProvisionalLoad):
+ (WebCore::FrameLoader::commitProvisionalLoad):
removed clearAllTimeouts since all ActiveDOMObjects will be stopped in FrameLoader::clear();
I don't see how the old comment can be correct - the code in the same method proceeds to invoke 'onunload'
and then calls into client which can be external code and can cause any active object created in onunload
@@ -18067,13 +38762,13 @@
Reviewed by Beth Dakin.
<rdar://problem/6018653> Extra blank line when pasting paragraph in plain text
-
+
In SnowLeopard, Mail occasionally adds an empty, unstyled paragraph at the
end of pasted content so that users don't get stuck with non-standard pargraph
spacing. This content threw off our handling of interchange newlines. Any interchange
newline, regardless of it's position in the incoming fragment was considered to be
- "at the start" of the fragment, and would result in us inserting in a newline before
- inserted content. This patch makes the checks for interchange newlines more strict,
+ "at the start" of the fragment, and would result in us inserting in a newline before
+ inserted content. This patch makes the checks for interchange newlines more strict,
and treats interchange newlines found elsewhere as normal <br>s.
* editing/ReplaceSelectionCommand.cpp:
@@ -18475,7 +39170,7 @@
Reduce size of the CSSSelector by 3/8 by moving rarely used fields to a rare data
struct. Browsing around with some instrumentation showed that ~0.1% of all selectors
encountered had rare data.
-
+
This also eliminates the CSSNthSelector subclass which will make possible to store
CSSSelectors in an array instead of a linked list for futher memory savings.
@@ -18595,11 +39290,11 @@
Reviewed by Dave Hyatt
https://bugs.webkit.org/show_bug.cgi?id=22472
-
+
Override absoluteClippedOverflowRect() in RenderReplaced to return a rect
that is large enough to encompass the selection, so that the repainting of
selected replaced elements works correctly.
-
+
Test: fast/repaint/selected-replaced.html
* rendering/RenderReplaced.cpp:
@@ -18651,7 +39346,7 @@
Bug 22596: Some elements don't report AXBlockQuoteLevel
https://bugs.webkit.org/show_bug.cgi?id=22596
-
+
Reviewed by John Sullivan.
* page/mac/AccessibilityObjectWrapper.mm:
@@ -18687,14 +39382,14 @@
Reviewed by Eric Seidel.
https://bugs.webkit.org/show_bug.cgi?id=22538
-
+
startsWith uses find which searches through the whole string if no match is found.
Using reverseFind with an index of 0 has the benefit of only searching for the match
at the beginning of the string. This may only be a small benefit in the overall program,
but it may help in some cases when the string is big.
No observable change in behavior, so no test.
-
+
* platform/text/StringImpl.h:
(WebCore::StringImpl::startsWith):
@@ -18779,7 +39474,7 @@
Move securityOrigin() from Document and WorkerContext into ScriptExecutionContext.
No observable change in behavior, so no test.
-
+
* dom/Document.cpp:
(WebCore::Document::open):
(WebCore::Document::domain):
@@ -18795,7 +39490,7 @@
(WebCore::WorkerContext::WorkerContext):
* dom/WorkerContext.h:
These changes are for the move of securityOrigin().
-
+
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::createRequest):
(WebCore::XMLHttpRequest::makeSimpleCrossSiteAccessRequest):
@@ -18824,22 +39519,22 @@
Reviewed by Dan Bernstein.
- Fix for https://bugs.webkit.org/show_bug.cgi?id=13736 REGRESSION
- (r19811): Using the down arrow in a textarea gets "stuck" at the
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=13736 REGRESSION
+ (r19811): Using the down arrow in a textarea gets "stuck" at the
end of a wrapped line
And corresponding: <rdar://problem/5347931>
- The basic problem here is that Position::getInlineBoxAndOffset()
- failed to look beyond a single renderer. This patch looks for a
- better match beyond the first renderer when the affinity is
- downstream and we failed to find a "perfect" match.
+ The basic problem here is that Position::getInlineBoxAndOffset()
+ failed to look beyond a single renderer. This patch looks for a
+ better match beyond the first renderer when the affinity is
+ downstream and we failed to find a "perfect" match.
* dom/Position.cpp:
(WebCore::isNonTextLeafChild):
(WebCore::searchAheadForBetterMatch):
(WebCore::Position::getInlineBoxAndOffset):
- This is a fix I made based on code inspection. It looks like the
- old code here and skipped over the parent as a possible match.
+ This is a fix I made based on code inspection. It looks like the
+ old code here and skipped over the parent as a possible match.
* rendering/RenderObject.cpp:
(WebCore::RenderObject::nextInPreOrderAfterChildren):
@@ -18852,7 +39547,7 @@
* WebCore.vcproj/WebCore.vcproj:
1. Add files from the wml directory to the set of windows files.
- 2. Extend include paths with new wml directory.
+ 2. Extend include paths with new wml directory.
3. Add new autogenerated WML files to DerivedSources.
4. Alphabetize preprocesor includes (holdover from earlier debugging).
@@ -18860,7 +39555,7 @@
Revise node/selection image fix.
Moved updateLayout call so selection rect is fetched after the layout.
-
+
Reviewed by Adam Roben.
* page/win/FrameCGWin.cpp:
@@ -18888,7 +39583,7 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=22581
-
+
Fix the painting of the caps lock indicator for transformed text inputs,
by replacing a call to absoluteContentBox() with code that computes the
painting rect for the input contents.
@@ -19098,7 +39793,7 @@
them. So now the pointer is valid throughout the entire sequence of callback code.
The testcase for https://bugs.webkit.org/show_bug.cgi?id=22052 also exhibits a
- crash which this patch fixes.
+ crash which this patch fixes.
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::updateStateMachine):
@@ -19281,7 +39976,7 @@
Fixes: https://bugs.webkit.org/show_bug.cgi?id=22549
- Add <do> element support. It provides a way to bind a task element to a <template>/<card> element.
+ Add <do> element support. It provides a way to bind a task element to a <template>/<card> element.
Changes numerous of layout tests which contain <do> elements, as they render as buttons now.
* WebCore.xcodeproj/project.pbxproj:
@@ -19479,7 +40174,7 @@
upper-case glyph defined in the set of available fonts.
This changes Font.cpp to check if the font being used exists before trying to apply the small-caps variant.
-
+
Test: fast/css/small-caps-crash.html
* platform/graphics/Font.cpp:
@@ -20008,7 +40703,7 @@
2008-11-25 Kevin Ollivier <kevino@theolliviers.com>
wx build fix - we don't support PurgeableBuffer on Leopard for now.
-
+
* platform/PurgeableBuffer.h:
2008-11-25 Antti Koivisto <antti@apple.com>
@@ -20017,7 +40712,7 @@
Fix https://bugs.webkit.org/show_bug.cgi?id=22483
Assertion failure in CachedResource::makePurgeable during layout tests
-
+
Deleting SVG image can re-enter destroyDecodedData.
* loader/CachedImage.cpp:
@@ -20084,7 +40779,7 @@
http/tests/misc/url-in-utf32be.html
http/tests/misc/url-in-utf32le.html
http/tests/misc/url-in-utf7.html
-
+
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::formData):
* loader/TextResourceDecoder.cpp:
@@ -20114,13 +40809,13 @@
2008-11-24 Antti Koivisto <antti@apple.com>
Reviewed by Darin Adler.
-
+
Fix for https://bugs.webkit.org/show_bug.cgi?id=22073
REGRESSION(r33544): Palace in the Sky crashes WebKit
-
+
HTMLTokenizer::m_hasScriptsWaitingForStylesheets would still be set while
- there were no scripts left to execute.
-
+ there were no scripts left to execute.
+
If m_hasScriptsWaitingForStylesheets becomes true during script execution
bail out from executing more scripts synchronously.
@@ -20187,11 +40882,11 @@
https://bugs.webkit.org/show_bug.cgi?id=22214
Keep dead resources in memory cache in purgeable memory.
<rdar://problem/6333088>
-
+
OS X 10.5 has purgeable memory kernel facility that allows marking reserved memory
areas as less important. Under memory pressure system can steal pages that have
been marked purgeable for (hopefully) better uses. This is ideal for caches.
-
+
Only resources larger than 16KB will be moved to the purgeable memory.
* WebCore.base.exp:
@@ -20426,7 +41121,7 @@
Bug 22461: AccessibilityListBox::doAccessibilityHitTest() signature does not match the base class
https://bugs.webkit.org/show_bug.cgi?id=22461
-
+
Changing AccessibilityListBox to use its parent's signature for hit testing
* page/AccessibilityListBox.cpp:
@@ -20447,8 +41142,8 @@
http://bugs.webkit.org/show_bug.cgi?id=18703
"Changing the 'size' property on a text input does not affect its length"
- Text fields would not repaint themselves after having their "size"
- attributes modified. This fix tells the object to recalculate its
+ Text fields would not repaint themselves after having their "size"
+ attributes modified. This fix tells the object to recalculate its
width and repaint itself when its "size" attribute is parsed.
Test: fast/js/text-field-resize.html
@@ -20461,7 +41156,7 @@
Reviewed by Darin Adler
Followup from changes for https://bugs.webkit.org/show_bug.cgi?id=22433
-
+
Make RenderView::selectionRect() private to cause compile-time
errors if someone tries to call it.
@@ -20472,7 +41167,7 @@
Reviewed by Dan Bernstein
Via: https://bugs.webkit.org/show_bug.cgi?id=22433
-
+
Rename RenderView::selectionRect() to selectionBounds(), to remove
longstanding ambiguity with the base class selectionRect() method.
Do the same on Frame for consistency with RenderView. Assert
@@ -20774,7 +41469,7 @@
Improve wx image drawing performance considerably when using wxGraphicsContext
by avoiding unnecessary copies and drawing.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22404
* platform/graphics/wx/ImageWx.cpp:
@@ -20787,7 +41482,7 @@
Reviewed by Kevin Ollivier.
Implementation of AffineTransform::mapRect for wx.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22401
* platform/graphics/wx/AffineTransformWx.cpp:
@@ -20798,20 +41493,20 @@
Reviewed by Darin Adler.
<rdar://problem/5381788> Match NSTextView editing behavior at the end of hyperlink text
-
- Change link editing behavior to match TextEdit and MS Word when editing before and after
- a link (Pages has two caret positions at link boundaries, Thunderbird and FF behave like we
+
+ Change link editing behavior to match TextEdit and MS Word when editing before and after
+ a link (Pages has two caret positions at link boundaries, Thunderbird and FF behave like we
used to, so it's difficult to get out of link editing mode):
When inserting before or after a link, always insert content outside of the link. This
- makes it impossible to get stuck in link editing mode, while making it slightly more
- difficult to edit link labels. WebKit editors that care about this can add UI for editing
+ makes it impossible to get stuck in link editing mode, while making it slightly more
+ difficult to edit link labels. WebKit editors that care about this can add UI for editing
link labels, like GMail and GoogleDocs have done. We never actually had any bugs complaining
- about how it was difficult to edit link labels at the start/end, the code was just introduced
+ about how it was difficult to edit link labels at the start/end, the code was just introduced
with another bug fix without much thought.
-
- Don't remember removed links anymore, no other editor does this and it made it
+
+ Don't remember removed links anymore, no other editor does this and it made it
difficult/impossible to get out of link editing mode. This code was added to fix
- <rdar://problem/4069359>, which is fixed instead by removing the styles from an
+ <rdar://problem/4069359>, which is fixed instead by removing the styles from an
enclosing anchor element from those styles that we remember when we delete content.
* editing/CompositeEditCommand.cpp:
@@ -20896,7 +41591,7 @@
RenderBox::absoluteClippedOverflowRect() needs to inflate the rect by
maximalOutlineSize(), since a child might have an outline which projects
outside the parent overflowRect().
-
+
We also need to ensure that maximalOutlineSize() is updated early in styleDidChange,
so that it is valid for these repaints.
@@ -20958,12 +41653,12 @@
Reviewed by Darin Adler.
Bug 22388: Add JSInterfaceName to the .in files
- https://bugs.webkit.org/show_bug.cgi?id=22388
+ https://bugs.webkit.org/show_bug.cgi?id=22388
Add JSInterfaceName that is similar to interfaceName but
for the JS wrappers. JSInterfaceName is always equal to interfaceName
unless explicitly set.
-
+
* dom/make_names.pl:
* html/HTMLTagNames.in:
* svg/svgtags.in:
@@ -21173,12 +41868,12 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=19623
-
+
When an non-layer object gained a transform, it would only repaint
the bounds of the new layer, which could result in redraw artifacts
if the new layer was smaller. So if we're gaining a transform, we
repaint.
-
+
Test: fast/repaint/change-transform.html
* rendering/RenderObject.cpp:
@@ -21186,7 +41881,7 @@
2008-11-20 Adele Peterson <adele@apple.com>
- Reviewed by Darin Adler.
+ Reviewed by Darin Adler.
Fix for <rdar://problem/6111436> Support upload progress events on Windows
@@ -21199,7 +41894,7 @@
Reviewed by Darin Adler.
<rdar://problem/2610675> Blank line that is quoted can't be deleted
-
+
If the caret is in an empty quoted paragraph, and either there is nothing before that
paragraph, or what is before is unquoted, and the user presses delete, unquote that
paragraph.
@@ -21253,7 +41948,7 @@
computed values for transform-origin-x, transform-origin-y, and just
return transform-origin instead. Return "none" for default animation-name,
and fix the initial value.
-
+
Tests: animations/computed-style.html
transforms/computed-style-origin.html
@@ -21269,25 +41964,25 @@
2008-11-20 Justin Garcia <justin.garcia@apple.com>
Reviewed by Beth Dakin.
-
+
Preparation for:
<rdar://problem/2610675> Blank line that is quoted can't be deleted
-
+
To fix this we need to make changes to the code that creates selections to delete
when the user does a backward or forward delete with a caret selection. For certain
caret positions, we now want to remove something other than the standard "caret extended
- backward/forward by one unit". The problem is that there were two pieces of code
- responsible for doing this, one in Editor::deleteWithDirection, and another inside
- TypingCommand::deleteKeyPressed. The code in deleteWithDirection is a recent
- addition (r19172), and adding it there caused regressions because it prevented the
- code in deleteKeyPressed from ever running. The regressions were never caught because
+ backward/forward by one unit". The problem is that there were two pieces of code
+ responsible for doing this, one in Editor::deleteWithDirection, and another inside
+ TypingCommand::deleteKeyPressed. The code in deleteWithDirection is a recent
+ addition (r19172), and adding it there caused regressions because it prevented the
+ code in deleteKeyPressed from ever running. The regressions were never caught because
JS deletion uses deleteKeyPressed while manual deletion uses deleteWithDirection.
-
+
This patch removes selection creation code from deleteWithDirection so that deleteKeyPressed
can handle it. That required moving code to handle the kill ring down into deleteKeyPressed.
-
- Follow up patches will fix <rdar://problem/2610675>, and attempt to eliminate the rest of the
- discrepancies between the behavior of JS deletions and manual deletions, so that we
+
+ Follow up patches will fix <rdar://problem/2610675>, and attempt to eliminate the rest of the
+ discrepancies between the behavior of JS deletions and manual deletions, so that we
have better test coverage.
* editing/Editor.cpp:
@@ -21378,11 +42073,11 @@
it into the coords of the part's renderer (which is the one that is painting).
To do this we need to compute an offset relative to some container, so expose
a method on RenderObject for that.
-
+
Also fix the location at which the search popup shows up to take transforms
into account, and fix the math that is used to figure out if the search
results button, or the cancel button should get the mouse events.
-
+
Test: fast/forms/search-transformed.html
* rendering/RenderBox.h:
@@ -21431,7 +42126,7 @@
https://bugs.webkit.org/show_bug.cgi?id=22379
Make CSSOM use less memory
-
+
- Shrink CSSProperty by half by using bitfields.
- Get rid of m_strictParsing field in StyleBase by moving it up to CSSStyleSheet
and CSSMutableStyleDeclaration. This reduces size of many highly popular objects.
@@ -21458,7 +42153,7 @@
https://bugs.webkit.org/show_bug.cgi?id=22373
Ports busted by addition of ScriptValue.{h,cpp}
-
+
* plugins/PluginView.cpp:
(WebCore::PluginView::performRequest):
@@ -21506,11 +42201,11 @@
Reviewed by Justin Garcia.
- Fix for <rdar://problem/5472507> Remove color property when a user
+ Fix for <rdar://problem/5472507> Remove color property when a user
sets color to black
- This patch prevents us from inserting font nodes during the
- ApplyStyleCommand if they will not change the computed style of an
+ This patch prevents us from inserting font nodes during the
+ ApplyStyleCommand if they will not change the computed style of an
element.
* editing/ApplyStyleCommand.cpp:
@@ -21522,9 +42217,9 @@
2008-11-19 Simon Fraser <simon.fraser@apple.com>
Reviewed by Antti Koivisto
-
+
https://bugs.webkit.org/show_bug.cgi?id=22111
-
+
Fix hit testing in controls on transformed video elements
by replacing absoluteBoundingBoxRect().contains() with
code that maps the point into local coords, taking
@@ -21542,7 +42237,7 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=22348
-
+
Need to educate style sharing about autofill, so that style does not
get shared between input elements that are autofilled, and those
that are not. Setting autofill should also do a setChanged on the node.
@@ -22219,7 +42914,7 @@
2008-11-17 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
-
+
Updated for JavaScriptCore renames.
* WebCore.pro:
@@ -22230,8 +42925,8 @@
Reviewed by Beth Dakin.
<rdar://problem/4922709> Copying less than a paragraph of quoted text and pasting it doesn't retain quote level
-
- There was code to intentionally avoid quoting pasted content if less than a paragraph of
+
+ There was code to intentionally avoid quoting pasted content if less than a paragraph of
it was copied. That was added for <rdar://problem/5006779>, but was unnecessary because
that bug was about Paste and Match style for single paragraphs. And quote stripping for
Paste and Match style is handled elsewhere.
@@ -22242,7 +42937,7 @@
2008-11-17 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
-
+
Updated for JavaScriptCore rename.
* ForwardingHeaders/interpreter/CallFrame.h: Copied from WebCore/ForwardingHeaders/runtime/ExecState.h.
@@ -22294,7 +42989,7 @@
2008-11-17 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
-
+
Updated for JavaScriptCore renames.
* ForwardingHeaders/VM: Removed.
@@ -22339,7 +43034,7 @@
Remove use of static C++ objects that are destroyed at exit time (destructors)
Find some missing DEFINE_STATIC_LOCAL use cases.
-
+
* bindings/js/JSSVGPODTypeWrapper.h:
(WebCore::PODTypeWrapperCacheInfoTraits::emptyValue):
(WebCore::JSSVGDynamicPODTypeWrapperCache::dynamicWrapperHashMap):
@@ -22365,11 +43060,11 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=22118
-
- Fix resize corner tracking in transformed elements by using
+
+ Fix resize corner tracking in transformed elements by using
mapping the point into local coords using absoluteToLocal,
rather than convertToLayerCoords.
-
+
Test: fast/css/resize-corner-tracking-transformed.html
* page/EventHandler.h:
@@ -22732,7 +43427,7 @@
Reviewed by Timothy Hatcher.
Initialize m_networkStateChangedFunction to 0 as otherwise the check for null will fail.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22284
* platform/network/NetworkStateNotifier.h:
@@ -22769,7 +43464,7 @@
2008-11-15 Geoffrey Garen <ggaren@apple.com>
Reviewed by Sam Weinig.
-
+
Updated for JavaScriptCore renames.
* bindings/js/JSNodeCustom.cpp:
@@ -22797,10 +43492,10 @@
https://bugs.webkit.org/show_bug.cgi?id=21810
Remove use of static C++ objects that are destroyed at exit time (destructors)
- Create DEFINE_STATIC_LOCAL macro. Change static local objects to leak to avoid
- exit-time destructor. Update code that was changed to fix this issue that ran
- into a gcc bug (<rdar://problem/6354696> Codegen issue with C++ static reference
- in gcc build 5465). Also typdefs for template types needed to be added in some
+ Create DEFINE_STATIC_LOCAL macro. Change static local objects to leak to avoid
+ exit-time destructor. Update code that was changed to fix this issue that ran
+ into a gcc bug (<rdar://problem/6354696> Codegen issue with C++ static reference
+ in gcc build 5465). Also typdefs for template types needed to be added in some
cases so the type could make it through the macro successfully.
Basically code of the form:
@@ -23182,7 +43877,7 @@
https://bugs.webkit.org/show_bug.cgi?id=22264
Need to update to latest Geolocation spec (13 November 2008)
-
+
Update to new error code constants and values.
* page/Geolocation.cpp: Use new named ErrorCode enums
@@ -23197,23 +43892,23 @@
Reviewed by Justin Garcia.
- Fix (again) for <rdar://problem/5089327> Too much indentation when
+ Fix (again) for <rdar://problem/5089327> Too much indentation when
pasting quoted paragraphs
- This patch goes back to Justin's original approach to fix this bug,
- written in revision 38273. That fix was mostly rolled out by
- revision 38310 because of styling issues created by the addition of
- extra blockquote nodes. This patch again goes back to Justin's
- original fix because of cases we discovered the newer fix could not
- possibly cover. This version of the patch minimizes the styling
- issues of extra blockquotes by opting into the merge start code.
+ This patch goes back to Justin's original approach to fix this bug,
+ written in revision 38273. That fix was mostly rolled out by
+ revision 38310 because of styling issues created by the addition of
+ extra blockquote nodes. This patch again goes back to Justin's
+ original fix because of cases we discovered the newer fix could not
+ possibly cover. This version of the patch minimizes the styling
+ issues of extra blockquotes by opting into the merge start code.
* editing/ReplaceSelectionCommand.cpp:
- (WebCore::hasMatchingQuoteLevel): We want shouldMergeStart to
- return true when the quoting level of the end of the inserted
- content matches the quoting level of the end of the existing
+ (WebCore::hasMatchingQuoteLevel): We want shouldMergeStart to
+ return true when the quoting level of the end of the inserted
+ content matches the quoting level of the end of the existing
content.
- (WebCore::ReplaceSelectionCommand::shouldMergeStart): Now calls
+ (WebCore::ReplaceSelectionCommand::shouldMergeStart): Now calls
hasMatchingQuoteLevel
(WebCore::ReplaceSelectionCommand::doApply):
@@ -23303,15 +43998,15 @@
Reviewed by Beth Dakin.
<rdar://problem/4230923> "Make Plain Text" doesn't reset text alignment in single paragraph messages
-
+
When applying block styles, we would add block properties to the body element, and Mail's
Make Plain Text feature isn't equipped to remove those. This could have been fixed on our side,
but this change has the advantage that it fixes the bug on Tiger, where Mail does not plan future updates.
-
+
We have code that puts the paragraphs that we're operating on into blocks of their own before
- adding or removing block properties from the blocks that enclose them. We need to run this code
+ adding or removing block properties from the blocks that enclose them. We need to run this code
when the enclosing block is the body element.
-
+
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::insertNewDefaultParagraphElementAt): Added, moved code from moveParagraphContents
to here.
@@ -23375,11 +44070,11 @@
* platform/text/AtomicString.cpp:
(WebCore::AtomicString::add):
-
+
2008-11-13 Justin Garcia <justin.garcia@apple.com>
Reviewed by Darin Adler.
-
+
https://bugs.webkit.org/show_bug.cgi?id=18620
Long hang under TextIterator::advance() when loading http://www.lsvd.de/
@@ -23387,8 +44082,8 @@
we create VisiblePositions unnecessarily.
* editing/TextIterator.cpp:
- (WebCore::TextIterator::shouldRepresentNodeOffsetZero): Don't proceed to VisiblePosition
- creation if m_node is unrendered or invisible. The answers wouldn't have much meaning
+ (WebCore::TextIterator::shouldRepresentNodeOffsetZero): Don't proceed to VisiblePosition
+ creation if m_node is unrendered or invisible. The answers wouldn't have much meaning
and would be wasteful. Also fixed some comments to reflect the fact that this function
isn't specifically about emitting a newline.
@@ -23669,15 +44364,15 @@
it may be the bounding outline box of a transformed element, and fix it
to respect transforms by mapping the outline box to an absolute quad and
taking the enclosing rect.
-
+
RenderBox::localToAbsoluteQuad() can no longer assert that there is no
LayoutState, but LayoutState cannot be used during quad mapping (it knows
nothing about transforms).
-
+
Finally, fix a bug in RenderBox::localToAbsoluteQuad() which was getting
borderTopExtra() from the object, rather than its container (as localToAbsolute()
does).
-
+
Test: fast/repaint/transform-absolute-child.html
* rendering/RenderBlock.cpp:
@@ -23718,14 +44413,14 @@
https://bugs.webkit.org/show_bug.cgi?id=21942
https://bugs.webkit.org/show_bug.cgi?id=18557
-
+
Add methods which can be used to map renderer-local rectangles
to quads in absolute coordinates, taking transforms into account:
localToAbsoluteQuad() converts a local rect into an absolute quad.
collectAbsoluteLineBoxQuads() is an analogue of addLineBoxRects()
that works with quads.
absoluteQuads() is an analogue of absoluteRects(), for quads.
-
+
Use the quad methods to fix the inspector highlight for transformed
elements.
@@ -23848,7 +44543,7 @@
https://bugs.webkit.org/show_bug.cgi?id=17840
Patch 2
-
+
Code cleanup in RenderBox::computeAbsoluteRepaintRect().
* rendering/RenderBox.cpp:
@@ -23872,24 +44567,24 @@
(WebCore::RenderBox::computeAbsoluteRepaintRect):
2008-11-12 Justin Garcia <justin.garcia@apple.com>
-
+
Reviewed by Beth Dakin.
-
+
<rdar://problem/5495723> Selecting and deleting quoted text quotes other text
<rdar://problem/4775313> Deleting lines from the bottom of a messages leaves the last blank line quoted
-
- We don't want to merge into a block if it will mean changing the quote level of content after deleting
- selections that contain a whole number paragraphs plus a line break, since it is unclear to most users
+
+ We don't want to merge into a block if it will mean changing the quote level of content after deleting
+ selections that contain a whole number paragraphs plus a line break, since it is unclear to most users
that such a selection actually ends at the start of the next paragraph. Instead we want to completely
- remove the selected paragraph(s) and all evidence of the first one's quote level. This matches TextEdit behavior
+ remove the selected paragraph(s) and all evidence of the first one's quote level. This matches TextEdit behavior
for indented paragraphs.
-
+
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::initializePositionData): For the selections described above, do not
try to merge after the deletion. Instead try and prune the start block or blocks if they've been emptied
so that we remove evidence of the deleted paragraphs' quote level.
- (WebCore::DeleteSelectionCommand::mergeParagraphs): Try and prune the start block(s) if necessary. Also
- make sure that the caret is placed correctly so that it ends up on the same line that the deleted selection
+ (WebCore::DeleteSelectionCommand::mergeParagraphs): Try and prune the start block(s) if necessary. Also
+ make sure that the caret is placed correctly so that it ends up on the same line that the deleted selection
started on, instead of one higher.
* editing/DeleteSelectionCommand.h:
* editing/htmlediting.cpp:
@@ -24104,22 +44799,22 @@
Reviewed by Darin Adler.
- Fix for <rdar://problem/5089327> Too much indentation when pasting
+ Fix for <rdar://problem/5089327> Too much indentation when pasting
quoted paragraphs
- This patch re-addresses pasting blockquotes into blockquotes. It
- backs out most of revision 38273. 38273 fixed the bug by inserting
- the pasted content as a sibling blockquote node to the pre-existing
- blockquote node. The problem with that is that by default,
- blockquotes have a giant margin, so visually, this can be weird.
- This patch instead inserts the pasted content as siblings of the
- the content already inside the outer blockquote, and then removes
- the blockquote node from the pasted content itself, so that it
+ This patch re-addresses pasting blockquotes into blockquotes. It
+ backs out most of revision 38273. 38273 fixed the bug by inserting
+ the pasted content as a sibling blockquote node to the pre-existing
+ blockquote node. The problem with that is that by default,
+ blockquotes have a giant margin, so visually, this can be weird.
+ This patch instead inserts the pasted content as siblings of the
+ the content already inside the outer blockquote, and then removes
+ the blockquote node from the pasted content itself, so that it
doesn't nest itself into the outer blockquote.
* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::doApply):
- Move contains() from Element to Node since there is nothing
+ Move contains() from Element to Node since there is nothing
Element-specific about it.
* dom/Element.cpp:
* dom/Element.h:
@@ -24193,7 +44888,7 @@
PatternCairo needs to invert the pattern matrix because
of transformation from user space to pattern space.
- Give a identity matrix to pattern for Qt and Cairo. Because the
+ Give a identity matrix to pattern for Qt and Cairo. Because the
context is transformed already.
[CAIRO][QT] Canvas transformations applied twice to Patterns
@@ -24240,15 +44935,15 @@
Reviewed by Beth Dakin.
- <rdar://problem/4037481> REGRESSION (Mail): pasting quoted text
+ <rdar://problem/4037481> REGRESSION (Mail): pasting quoted text
into quoted text yields double-quoting
-
- Don't nest inserted content in Mail blockquotes. Perform a
+
+ Don't nest inserted content in Mail blockquotes. Perform a
BreakBlockquoteCommand if we're in
one and insert the incoming fragment between the split blockquotes.
* editing/ReplaceSelectionCommand.cpp:
- (WebCore::ReplaceSelectionCommand::shouldMerge): Renamed from ->
+ (WebCore::ReplaceSelectionCommand::shouldMerge): Renamed from ->
source and to -> destination.
(WebCore::ReplaceSelectionCommand::doApply):
@@ -24399,10 +45094,10 @@
2008-11-08 Antti Koivisto <antti@apple.com>
Reviewed by Sam Weinig.
-
+
Fix https://bugs.webkit.org/show_bug.cgi?id=22141
REGRESSION: Safari error page is not fully styled when loaded from cache
-
+
Reset text decoder on flush so it does not pass through the BOM when it is reused.
Test: fast/encoding/css-cached-bom.html
@@ -24411,7 +45106,7 @@
(WebCore::TextResourceDecoder::flush):
2008-11-08 Kevin Ollivier <kevino@theolliviers.com>
-
+
Reviewed by Mark Rowe.
Send URL errors to stderr rather than stdout. While debugging wx DumpRenderTree,
@@ -24422,7 +45117,7 @@
2008-11-08 Kevin Ollivier <kevino@theolliviers.com>
- wx build fixes after addition of JSCore parser and bycompiler dirs.
+ wx build fixes after addition of JSCore parser and bycompiler dirs.
* webcore-base.bkl:
* webcore-wx.bkl:
@@ -24432,13 +45127,13 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=21906
-
+
Override addFocusRingRects() in RenderTextControl to avoid
the RenderFlow behavior of recursing on descendent renderers.
RenderTextControl should only ever need a simple focus rect.
-
+
This fixes focus ring issues with transforms on text controls.
-
+
Test: fast/transforms/transformed-focused-text-input.html
* rendering/RenderTextControl.cpp:
@@ -24532,7 +45227,7 @@
Reviewed by Dan Bernstein
https://bugs.webkit.org/show_bug.cgi?id=22122
-
+
Use a stack-based object to simplify the pushLayoutState/popLayoutState
code. LayoutStateMaintainer either pushes in the constructor, or allows
an explicit push() later. Both cases require an explicit pop().
@@ -24608,10 +45303,10 @@
Reviewed by Dan Bernstein.
https://bugs.webkit.org/show_bug.cgi?id=22093
-
+
Delaying the text decoding caused regression since the decoding
- also determines the encoding in case of @charset rule.
-
+ also determines the encoding in case of @charset rule.
+
Decode immediately in data() and keep the decoded string around
during the checkNotify().
@@ -24666,7 +45361,7 @@
NPN_HasPropertyUPP and NPN_HasMethodUPP entries in NPNetscapeFuncs are NULL
Export _NPN_HasMethod and _NPN_HasProperty.
-
+
* WebCore.NPAPI.exp:
2008-11-06 Simon Fraser <simon.fraser@apple.com>
@@ -24674,7 +45369,7 @@
Reviewed by Antti Koivisto
https://bugs.webkit.org/show_bug.cgi?id=15678
-
+
Fix transformed menu selects to show the popup in the correct
location.
@@ -24762,7 +45457,7 @@
2008-11-06 Steve Falkenburg <sfalken@apple.com>
Fix failed assert at launch caused by unintialized data member.
-
+
Reviewed by Maciej Stachowiak.
* platform/network/win/NetworkStateNotifierWin.cpp:
@@ -24991,10 +45686,10 @@
Reviewed by Dave Hyatt
https://bugs.webkit.org/show_bug.cgi?id=21870
-
+
Implement absoluteToLocal() to convert a point from absolute
to local coordinates, optionally taking transforms into account.
-
+
Use this to set offsetX/offsetY in mouse events, thus fixing
offsetX/offsetY in events on elements with transforms.
@@ -25187,15 +45882,15 @@
2008-11-05 Antti Koivisto <antti@apple.com>
Reviewed by Dan Bernstein.
-
+
https://bugs.webkit.org/show_bug.cgi?id=22093
Don't keep decoded stylesheet data in cache
-
+
<rdar://problem/6343588>
Don't keep decoded stylesheet string around in the cache. There are no sharing benefits and
performance benefits are negligible (no measured PLT impact). Reduces memory consumption of
- style sheet data in cache by 2/3 in common case.
+ style sheet data in cache by 2/3 in common case.
* loader/CachedCSSStyleSheet.cpp:
(WebCore::CachedCSSStyleSheet::sheetText):
@@ -25291,10 +45986,10 @@
Reviewed by Beth Dakin.
<rdar://problem/5480736> In Mail and Gmail, copied indented text pastes with line break
-
- As a rule, we don't allow merges out of blockquotes. In the bug, we are inserting a text node
+
+ As a rule, we don't allow merges out of blockquotes. In the bug, we are inserting a text node
between two blockquotes. Because the start merge moves the text node into a blockquote, when we
- determine whether or not we should do the end merge, it incorrectly appears as though the end merge
+ determine whether or not we should do the end merge, it incorrectly appears as though the end merge
is merging out of a blockquote. The fix is to determine whether or not we should do the end merge
before we do the start merge, so that the start merge doesn't effect our decision.
@@ -25406,7 +46101,7 @@
Reviewed by Dan Bernstein.
Remove two global destructors from CoreTextController.
-
+
* platform/graphics/mac/CoreTextController.cpp:
(WebCore::CoreTextController::collectCoreTextRunsForCharacters):
@@ -25557,12 +46252,12 @@
reported by zdobersek in #webkit.
2008-11-04 Darin Fisher <darin@chromium.org>
-
+
Reviewed by Anders Carlsson.
-
+
No need to clobber all ResourceRequest fields in FrameLoader::reload()
https://bugs.webkit.org/show_bug.cgi?id=21949
-
+
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::reload):
@@ -26220,7 +46915,7 @@
When computing the bounds of the transparency layer, we need to
map the clipRect through the enclosing transform.
-
+
Test: fast/layers/opacity-transforms.html
* rendering/RenderLayer.cpp:
@@ -26232,7 +46927,7 @@
https://bugs.webkit.org/show_bug.cgi?id=22053
- Added additional support needed for the NPDrawingModelCoreAnimation drawing model.
+ Added additional support needed for the NPDrawingModelCoreAnimation drawing model.
* bridge/npapi.h:
@@ -26446,7 +47141,7 @@
WebCore Windows part of fix for <rdar://problem/5839256> FILE CONTROL: multi-file upload.
https://bugs.webkit.org/show_bug.cgi?id=22008
- * platform/FileChooser.cpp: (WebCore::FileChooser::chooseIcon):
+ * platform/FileChooser.cpp: (WebCore::FileChooser::chooseIcon):
Rename newIconForFile and newIconForFiles to createIconForFile and createIconForFiles.
* platform/graphics/Icon.h: ditto.
* platform/graphics/gtk/IconGtk.cpp:
@@ -26465,9 +47160,9 @@
(WebCore::Icon::createIconForFile): ditto.
(WebCore::Icon::createIconForFiles): Add creation of an icon for multiple files.
- * rendering/RenderThemeWin.cpp: (WebCore::RenderThemeWin::paintSearchFieldResultsDecoration):
+ * rendering/RenderThemeWin.cpp: (WebCore::RenderThemeWin::paintSearchFieldResultsDecoration):
Improve icon creation code to match new code in Icon::createIconForFiles
-
+
2008-10-31 Timothy Hatcher <timothy@apple.com>
Add manual tests that check breakpoints on a blockless body of "for" loops.
@@ -26627,7 +47322,7 @@
Reviewed by Sam Weinig
https://bugs.webkit.org/show_bug.cgi?id=21967
-
+
For some platforms the GeolocationService must be suspended and resumed.
* page/Geolocation.cpp:
@@ -26646,7 +47341,7 @@
Reviewed by Sam Weinig
https://bugs.webkit.org/show_bug.cgi?id=21966
-
+
The Geolocation spec was updated on 10/27/2008. This brings WebCore up to date.
http://dev.w3.org/geo/api/spec-source.html
@@ -26680,15 +47375,15 @@
<rdar://problem/6104369> Hitting return at the end of a quoted line creates an extraneous quoted line
* editing/BreakBlockquoteCommand.cpp:
- (WebCore::BreakBlockquoteCommand::doApply):
- Don't store the endingSelection() in selection, just call endingSelection() in the few places it's
+ (WebCore::BreakBlockquoteCommand::doApply):
+ Don't store the endingSelection() in selection, just call endingSelection() in the few places it's
needed. This function is cheap since it just returns a reference to a Selection instead of creating one.
Don't store an affinity. In the one place that it was used, isLastVisiblePositionInNode(VisiblePosition(pos, affinity), topBlockquote),
we now use visiblePos (in order to avoid VisiblePosition creation).
- Set pos after we delete the current selection (if there is one), and be consistent about what we set
+ Set pos after we delete the current selection (if there is one), and be consistent about what we set
pos to. Before, we upstream()ed it if there was a selection to delete and left it alone otherwise. In fact...
- ...we need to use downstream() for pos so that when a caret is at the boundary between two nodes, pos is
- in the first node that we want to move. This fixes the bug, since it lets code that checks for the case
+ ...we need to use downstream() for pos so that when a caret is at the boundary between two nodes, pos is
+ in the first node that we want to move. This fixes the bug, since it lets code that checks for the case
where the caret is between text and a br work correctly.
2008-10-30 Yael Aharon <yael.aharon@nokia.com>
@@ -26715,10 +47410,10 @@
<rdar://problem/6104369> Hitting return at the end of a quoted line creates an extraneous quoted line
* editing/BreakBlockquoteCommand.cpp:
- (WebCore::BreakBlockquoteCommand::doApply): Added comments. Don't need to use newStartNode. If the
- startNode needs to change, change it. Afterwords, check to make sure that it hasn't left topBlockquote.
- This is slightly stricter than before, where we just made sure that it still had a topBlockquote. This
- doesn't really fix a bug, since we can't really get into a situation where we move to a different
+ (WebCore::BreakBlockquoteCommand::doApply): Added comments. Don't need to use newStartNode. If the
+ startNode needs to change, change it. Afterwords, check to make sure that it hasn't left topBlockquote.
+ This is slightly stricter than before, where we just made sure that it still had a topBlockquote. This
+ doesn't really fix a bug, since we can't really get into a situation where we move to a different
topBlockquote, but it simplifies the code.
2008-10-30 Dirk Schulze <vbs85@gmx.de>
@@ -26884,7 +47579,7 @@
Some preparation for:
<rdar://problem/6104369> Hitting return at the end of a quoted line creates an extraneous quoted line
-
+
Added an early return to avoid a level of if-nesting. No other changes. We probably don't
need to rebalance whitespace before the early return but for now don't risk any change in behavior
I'll revisit that later.
@@ -26895,7 +47590,7 @@
2008-10-29 Kevin Ollivier <kevino@theolliviers.com>
wx build fixes after addition of runtime and ImageBuffer changes.
-
+
* platform/graphics/wx/ImageBufferData.h: Added.
* platform/graphics/wx/ImageBufferWx.cpp:
(WebCore::ImageBufferData::ImageBufferData):
@@ -27043,7 +47738,7 @@
(WebCore::Document::~Document):
Moved active object and MessagePort tracking up to ScriptExecutionContext, to share code
with workers.
-
+
* dom/Document.h:
(WebCore::Document::isDocument):
(WebCore::Document::refScriptExecutionContext):
@@ -27116,8 +47811,8 @@
* editing/Editor.cpp:
(WebCore::Editor::ignoreSpelling): Remove misspelling markers from the word.
- (WebCore::Editor::learnSpelling): Added a FIXME about <rdar://problem/5396072>, which
- will probably require a change more complicated than just marking the learned word as
+ (WebCore::Editor::learnSpelling): Added a FIXME about <rdar://problem/5396072>, which
+ will probably require a change more complicated than just marking the learned word as
misspelled. I'll address it with a separate patch.
* editing/EditorCommand.cpp:
(WebCore::executeIgnoreSpelling): Added.
@@ -27564,10 +48259,10 @@
2008-10-27 Kevin Watters <kevinwatters@gmail.com>
Reviewed by Kevin Ollivier.
-
+
Update the active state as well as the focused state as both need to be true
for the caret to be drawn.
-
+
https://bugs.webkit.org/show_bug.cgi?id=21900
* WebView.cpp:
@@ -27655,7 +48350,7 @@
Reviewed by Sam Weinig.
No need to call release if the connection is null.
-
+
* platform/network/mac/ResourceHandleMac.mm:
(WebCore::ResourceHandle::start):
@@ -27664,9 +48359,9 @@
Reviewed by Kevin Decker.
<rdar://problem/6322650> Crash in fast/loader/simultaneous-reloads-assert.html
-
+
Make sure to null check the NSURLConnection object.
-
+
* platform/network/mac/ResourceHandleMac.mm:
(WebCore::ResourceHandle::start):
(WebCore::ResourceHandle::setDefersLoading):
@@ -27708,7 +48403,7 @@
2008-10-25 Geoffrey Garen <ggaren@apple.com>
Not reviewed.
-
+
Try to fix Mac debug build on the buildbot.
* platform/FileChooser.cpp:
@@ -27837,40 +48532,40 @@
Reviewed by Sam Weinig.
<rdar://problem/5440917> Support NPN_Construct
-
+
* WebCore.NPAPI.exp:
Export _NPN_Construct.
-
+
* bridge/NP_jsobject.cpp:
(_NPN_Construct):
Implement this.
-
+
* bridge/c/c_instance.cpp:
(JSC::Bindings::CInstance::supportsConstruct):
(JSC::Bindings::CInstance::invokeConstruct):
Have this call the appropriate NPClass method.
-
+
* bridge/npruntime.h:
Add NPN_Construct.
* bridge/npruntime_impl.h:
Add _NPN_Construct.
-
+
* bridge/runtime.h:
(JSC::Bindings::Instance::supportsConstruct):
(JSC::Bindings::Instance::invokeConstruct):
New methods.
-
+
* bridge/runtime_object.cpp:
(JSC::callRuntimeConstructor):
Call the native instance.
-
+
(JSC::RuntimeObjectImp::getConstructData):
Implement this.
-
+
* bridge/runtime_object.h:
Add new method declarations.
-
+
* plugins/gtk/PluginPackageGtk.cpp:
(WebCore::PluginPackage::load):
* plugins/qt/PluginPackageQt.cpp:
@@ -27912,9 +48607,9 @@
This is consistent with the direction HTML5 will be going in the future.
The initial implementation here will show "n files" as the text next to the control when multiple files are selected. You can view
- the individual files in a tooltip for now. Improvements to this control will come later.
+ the individual files in a tooltip for now. Improvements to this control will come later.
- Web developers will be able to access the FileList from the HTMLInputElement element, where they can get a base name and a size for each file.
+ Web developers will be able to access the FileList from the HTMLInputElement element, where they can get a base name and a size for each file.
These FileList Files can also be sent in an XMLHTTPRequest.
* manual-tests/post-multi-file-upload.html: Added.
@@ -27932,7 +48627,7 @@
but we don't want to break the behavior for existing websites that may rely on this.
(WebCore::HTMLInputElement::setValue): ditto.
(WebCore::HTMLInputElement::setValueFromRenderer): This is no longer used for file upload controls. setFileListFromRenderer is used instead.
- (WebCore::HTMLInputElement::setFileListFromRenderer): Added.
+ (WebCore::HTMLInputElement::setFileListFromRenderer): Added.
* html/HTMLInputElement.h:
* page/Chrome.cpp: (WebCore::Chrome::setToolTip): Show a tooltip with the file name list for the multi-file upload control.
@@ -28002,9 +48697,9 @@
Reviewed by Sam Weinig.
https://bugs.webkit.org/show_bug.cgi?id=21475
-
+
Provide support for the Geolocation API
-
+
http://dev.w3.org/geo/api/spec-source.html
Test: geolocation/geolocation-not-implemented.html
@@ -28119,7 +48814,7 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=21818
-
+
Add HashTraits for AtomicString so that AtomicString can be used as
the key for a HashMap or HashSet.
@@ -28147,7 +48842,7 @@
Add WebKitCSSKeyframeRule and WebKitCSSKeyframesRule to the
switch in _wrapCSSRule.
-
+
* bindings/objc/DOMCSS.mm:
(+[DOMCSSRule _wrapCSSRule:WebCore::]):
@@ -28453,9 +49148,9 @@
Reviewed by Sam Weinig.
https://bugs.webkit.org/show_bug.cgi?id=21475
-
+
Provide support for the Geolocation API
-
+
http://dev.w3.org/geo/api/spec-source.html
Test: geolocation/geolocation-not-implemented.html
@@ -28678,7 +49373,7 @@
Reviewed by Oliver Hunt.
* platform/network/curl/ResourceRequest.h: A better implementation
- of CFURLRequest, rather than void*. This gives better compatibility
+ of CFURLRequest, rather than void*. This gives better compatibility
with the WebKit.idl interface.
(WebCore::ResourceRequest::cfURLRequest):
@@ -28878,7 +49573,7 @@
- fix https://bugs.webkit.org/show_bug.cgi?id=21809
- Remove PLATFORM(MAC) wrapping USE(ATSUI). It's redundant and inhibits
+ Remove PLATFORM(MAC) wrapping USE(ATSUI). It's redundant and inhibits
its use for PLATFORM(CHROMIUM) in the future.
* platform/graphics/SimpleFontData.h:
@@ -28886,7 +49581,7 @@
2008-10-22 David Smith <catfish.man@gmail.com>
Reviewed by Anders Carlsson.
-
+
https://bugs.webkit.org/show_bug.cgi?id=19974
getElementsByClassName not live enough
@@ -28959,11 +49654,11 @@
<rdar://6261773> - autocomplete="off" doesn't work on Windows
- Visual Studio makes a poor decision regarding the combination of enums and bitfields, such that a
- statement like "m_autocomplete = Off" followed by "return m_autocomplete == Off" would return "false"
+ Visual Studio makes a poor decision regarding the combination of enums and bitfields, such that a
+ statement like "m_autocomplete = Off" followed by "return m_autocomplete == Off" would return "false"
instead of the much more correct "true."
-
- In the past we have worked around this by declaring the bitfield member as an unsigned instead
+
+ In the past we have worked around this by declaring the bitfield member as an unsigned instead
of the enum type.
For more discussion, see http://trac.webkit.org/changeset/25329
@@ -29047,11 +49742,11 @@
Make sure that the AtomicString that identifies a set of animation keyframes
stays live by keeping a copy in the WebKitCSSKeyframesRule.
-
+
Also call styleSheetChanged() when the keyframes name changes, but
add an internal method that doesn't call styleSheetChanged() for use
during normal stylesheet parsing.
-
+
Test: animations/change-keyframes-name.html
* css/CSSGrammar.y:
@@ -29183,14 +49878,14 @@
Reviewed by Darin Adler.
- Fix for https://bugs.webkit.org/show_bug.cgi?id=20352
- REGRESSION(r31030-31055): Choosing "Print window" from frame set
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=20352
+ REGRESSION(r31030-31055): Choosing "Print window" from frame set
prints blank page
and corresponding: <rdar://problem/6142398>
- viewHeight() and viewWidth() only return valuable information if we
- are not printing. Everywhere else in the code, we make sure we are
- not printing before we call these functions. Adding a check for
+ viewHeight() and viewWidth() only return valuable information if we
+ are not printing. Everywhere else in the code, we make sure we are
+ not printing before we call these functions. Adding a check for
printing here fixes this bug, and framesets print again.
* rendering/RenderFrameSet.cpp:
@@ -29213,7 +49908,7 @@
Add a comment explaining layoutDelta(), and an assertion
that checks that delta changes were correctly paired during layout.
-
+
* rendering/RenderView.cpp:
(WebCore::RenderView::layout):
* rendering/RenderView.h:
@@ -29269,9 +49964,9 @@
Fix https://bugs.webkit.org/show_bug.cgi?id=21763
REGRESSION (r36108-r36113): Can't load picture content on wired.com galleries
<rdar://problem/6285025
-
+
If we get 304 response we need to explicitly check if that completes the frame load.
-
+
No test case, simulating the condition is pretty difficult.
* loader/loader.cpp:
@@ -29282,9 +49977,9 @@
Reviewed by Mark Rowe.
Work around <rdar://problem/6301728>.
-
+
Don't assert that loads are deferred when we're using CFNetwork on Mac or Windows.
-
+
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::didReceiveResponse):
(WebCore::MainResourceLoader::didReceiveData):
@@ -29295,13 +49990,13 @@
Reviewed by Adele Peterson.
- Speculative fix for <rdar://problem/6242585> CrashTracer: [USER] 19
+ Speculative fix for <rdar://problem/6242585> CrashTracer: [USER] 19
crashes in Safari at com.apple.WebCore
WebCore::ScrollView::visibleContentRect const + 153
- d->m_view can be null and is null-checked at other points in the
- code. The logs indicate that this crash occurs when closing a
- window containing a PDF, so in case where we crash, the PDF's view
+ d->m_view can be null and is null-checked at other points in the
+ code. The logs indicate that this crash occurs when closing a
+ window containing a PDF, so in case where we crash, the PDF's view
is probably already null. So the fix is to simply add a null-check.
* page/Frame.cpp:
@@ -29532,7 +50227,7 @@
Reviewed by Jon Honeycutt
- Fix a crash in Accessibility where a table section was being
+ Fix a crash in Accessibility where a table section was being
referenced without first checking if it was null
https://bugs.webkit.org/show_bug.cgi?id=21721
@@ -29650,7 +50345,7 @@
(WebCore::JavaScriptDebugServer::recompileAllJSFunctionsSoon):
(WebCore::JavaScriptDebugServer::didAddListener):
(WebCore::JavaScriptDebugServer::didRemoveListener):
- * inspector/JavaScriptDebugServer.h: Exported an API for recompiling,
+ * inspector/JavaScriptDebugServer.h: Exported an API for recompiling,
used by the Settings object.
* page/Settings.cpp:
@@ -30491,9 +51186,9 @@
2008-10-17 Kevin Watters <kevinwatters@gmail.com>
Reviewed by Kevin Ollivier
-
+
Fix wx port's scrollbar and drawing handling after recent changes.
-
+
https://bugs.webkit.org/show_bug.cgi?id=21720
* platform/ScrollView.h:
@@ -31032,7 +51727,7 @@
https://bugs.webkit.org/show_bug.cgi?id=21587
NPN_PluginThreadAsyncCall does not work properly
-
+
* plugins/PluginMainThreadScheduler.cpp:
(WebCore::PluginMainThreadScheduler::dispatchCalls):
Make sure to set m_callPending to false once the queue has been cleared.
@@ -31155,7 +51850,7 @@
Reviewed by Sam Weinig.
- Implement didSendBodyData delegate method, and use older code path when that delegate doesn't exist.
+ Implement didSendBodyData delegate method, and use older code path when that delegate doesn't exist.
* platform/network/ResourceHandle.h:
* platform/network/mac/FormDataStreamMac.mm: (WebCore::formRead):
@@ -31240,11 +51935,11 @@
Reviewed by Darin Adler, tweaked and landed by Beth.
- * WebCore.base.exp: Exposes two functions to be able to create a
- selection from a point on the screen. Also exposes the new
+ * WebCore.base.exp: Exposes two functions to be able to create a
+ selection from a point on the screen. Also exposes the new
TextIterator::currentNode function.
* WebCore/editing/TextIterator.cpp:
- (TextIterator::currentNode) : New function that returns the current
+ (TextIterator::currentNode) : New function that returns the current
text node or NULL if there is no text node.
2008-10-15 Marco Barisione <marco.barisione@collabora.co.uk>
@@ -31487,7 +52182,7 @@
2008-10-14 Tor Arne Vestbø <tavestbo@trolltech.com>
Reviewed by Simon.
-
+
Fix QtWebKit scrollbar painting errors
* platform/qt/ScrollbarThemeQt.cpp:
@@ -31508,7 +52203,7 @@
Reviewed by Simon.
Use style-painter to draw scrollbars in ScrollbarThemeQt
-
+
This has the benefit of setting up the painter properly without
antialiasing and saving and restoring the brush. It also ensures
that we use the style of the QWebView over the QApplication style
@@ -31589,7 +52284,7 @@
2008-10-13 Maciej Stachowiak <mjs@apple.com>
Rubber stamped by Mark Rowe.
-
+
- use gcc 4.2 when building with Xcode 3.1 or newer on Leopard, even though this is not the default
* Configurations/DebugRelease.xcconfig:
@@ -31621,7 +52316,7 @@
Links from image maps were not being included in the web area's AXLinkUIElements attribute.
The position of image map links was being reported incorrectly and the parent-chain
hierarchy for image map links was incorrect because image map links did not have a reference
- to their parent image.
+ to their parent image.
Test: accessibility/document-links.html
@@ -31845,7 +52540,7 @@
but changes \r, \n, and \r\n to a single space.
Tests: editing/pasteboard/paste-multiline-text-input.html
-
+
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::constrainValue):
@@ -31887,8 +52582,8 @@
Reviewed by Alp Toker.
- Add version parsing for Flash, and the PluginQuirkDontSetNullWindowHandleOnDestroy
- plugin quirk if Flash 10 or newer since at least in b218, setting a NULL window
+ Add version parsing for Flash, and the PluginQuirkDontSetNullWindowHandleOnDestroy
+ plugin quirk if Flash 10 or newer since at least in b218, setting a NULL window
handler on destroy crashes WebKit <https://bugs.webkit.org/show_bug.cgi?id=19859>
* plugins/gtk/PluginPackageGtk.cpp:
@@ -32283,7 +52978,7 @@
Reviewed by Darin Adler
https://bugs.webkit.org/show_bug.cgi?id=21538
-
+
The blendFunc() for TransformOperations should never mess with the
operation lists by replacing some ops with identity, otherwise the lists
no longer match and transitions break.
@@ -32301,7 +52996,7 @@
Fix re-targetting a running transition; if the target property
changes, we do need to make a new ImplicitAnimation.
-
+
Test: transitions/retargetted-transition.html
* page/animation/CompositeAnimation.cpp:
@@ -32532,7 +53227,7 @@
Redesigned how animation events are sent in order to get rid of
AnimationEventDispatcher. ImplicitAnimation and KeyframeAnimation
- are now ref counted. While calling the event handler, I keep a
+ are now ref counted. While calling the event handler, I keep a
reference to this class to avoid it getting destroyed out from under me.
I also moved most of the functionality of CompositeAnimation to
@@ -32648,7 +53343,7 @@
Media controls should not show when element is not visible
https://bugs.webkit.org/show_bug.cgi?id=21155
-
+
Reviewed by Adele Peterson.
* html/HTMLMediaElement.cpp:
@@ -32905,7 +53600,7 @@
Gradient clips were not getting cleared after filling the
gradient, this was causing nothing to draw in Canvex
https://bugs.webkit.org/show_bug.cgi?id=21498
-
+
Tests forthcoming.
* WebCore.xcodeproj/project.pbxproj:
@@ -32917,10 +53612,10 @@
2008-10-09 Eric Seidel <eric@webkit.org>
Reviewed by Oliver Hunt.
-
+
Fix transformed patterns
https://bugs.webkit.org/show_bug.cgi?id=21498
-
+
Test: fast/canvas/patternfill-repeat.html
* WebCore.xcodeproj/project.pbxproj:
@@ -33329,7 +54024,7 @@
Reviewed by Antti Koivisto.
<rdar://problem/6273887> Crash in ApplicationCacheGroup
-
+
Make sure to stop loading even before a cache update is in progress so that the
manifest load will be stopped.
@@ -33431,7 +54126,7 @@
scrollbar-corner
scrollbar-thumb
scrollbar-track
-
+
These elements will work with all the usual pseudo-classes (:hover, :active, :enabled, :disabled, etc.) and with
the following new pseudo-classes:
scrollbar-active
@@ -33439,7 +54134,7 @@
scrollbar-forward
scrollbar-horizontal
scrollbar-vertical
-
+
Reviewed by Adele
* css/CSSSelector.cpp:
@@ -33572,7 +54267,7 @@
2008-10-06 Jeremy Moskovich <jeremy@chromium.org>
Reviewed by Dan Bernstein.
-
+
Added C++ forward declaration for the NSURLAuthenticationChallenge class
so that the m_currentMacChallenge variable doesn't cause a
compilation error when ResourceHandleInternal.h is included from a C++ file.
@@ -33590,7 +54285,7 @@
https://bugs.webkit.org/show_bug.cgi?id=21416
Add missing null checks identified by Application Verifier.
-
+
Reviewed by Darin Adler.
* platform/win/SharedTimerWin.cpp:
@@ -33634,7 +54329,7 @@
2008-10-03 Steve Falkenburg <sfalken@apple.com>
<rdar://problem/6249833> Fix default button appearance
-
+
Reviewed by Adele Peterson.
* rendering/RenderThemeWin.cpp:
@@ -33714,7 +54409,7 @@
SVG should support ascent and descent properties <font-face> instead of <font>!
https://bugs.webkit.org/show_bug.cgi?id=21365
-
+
Tested by many many existing SVG tests.
* svg/SVGFontFaceElement.cpp:
@@ -33829,7 +54524,7 @@
The solution is to track whether we are entering or reentering the parsing
of a script element. We do this simply by 0 checking scriptStartLineno,
- and resetting it after we complete parsing of each script element.
+ and resetting it after we complete parsing of each script element.
Test: http/tests/incremental/pause-in-script-element.pl
@@ -34461,11 +55156,11 @@
2008-10-03 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=21340
-
+
Remove "containingWindow()/setContainingWindow()" from Widget. HostWindow covers this now.
-
+
Reviewed by Dan Bernstein & Darin Adler
-
+
* platform/ScrollView.cpp:
(WebCore::ScrollView::addChild):
* platform/Widget.cpp:
@@ -34532,7 +55227,7 @@
Reviewed by Dan Bernstein.
- Fix for <rdar://problem/6012018>
+ Fix for <rdar://problem/6012018>
https://bugs.webkit.org/show_bug.cgi?id=21335
CrashTracer: [USER] 4959 crashes in Safari at com.apple.WebCore: WebCore::Frame::settings const + 8
@@ -34562,7 +55257,7 @@
2008-10-03 David Hyatt <hyatt@apple.com>
Remove addToDirtyRegion.
-
+
Reviewed by Oliver Hunt
* page/Chrome.cpp:
@@ -34577,7 +55272,7 @@
Reviewed by Maciej Stachowiak.
- - fix a CachedResource leak introduced in r37176
+ - fix a CachedResource leak introduced in r37176
Undo r37176 and instead allow pruneDeadResources() to be re-entered, but
afterwards bail out of the outer pruneDeadResources().
@@ -34594,7 +55289,7 @@
Fix Gtk adjustments so that they are properly checked again before creating horizontal/vertical
scrollbars.
-
+
Reviewed by Oliver Hunt
* platform/ScrollView.cpp:
@@ -34649,16 +55344,16 @@
2008-10-02 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=21328
-
+
Make widget invalidation more cross-platform.
-
+
(1) Make invalidateRect a pure virtual function on Widget. All leaf widgets must now implement this function.
-
+
(2) Scrollbars now send invalidations through the ScrollbarClient. windowClipRect on ScrollbarClient has been removed and replaced with this invalidation call.
This allows all scrollbar invalidations to go through the render tree so that transforms and reflections will be respected.
-
+
(3) Plugins now have the native window invalidation code for windowed plugins. Windowless plugins do a repaintRectangle on the plugin's renderer.
-
+
(4) FrameViews now do a repaintRectangle on their owner element's renderer.
Reviewed by Sam Weinig
@@ -34733,7 +55428,7 @@
Reviewed by Dave Hyatt
- Fix RenderFileUploadControl::setStyle() and
+ Fix RenderFileUploadControl::setStyle() and
RenderMenuList::setStyle() to not touch the style; replace
with html4.css and CSSStyleSelector changes.
@@ -34754,9 +55449,9 @@
Clean up code that changes the RenderStyle passed in to
table renderer setStyle() methods.
-
+
https://bugs.webkit.org/show_bug.cgi?id=21287
-
+
Tests: fast/table/floating-th.html
fast/table/table-display-types-strict.html
fast/table/table-display-types.html
@@ -34844,7 +55539,7 @@
- fix a Database leak that resulted in Document leaks
* storage/Database.cpp:
- (WebCore::Database::openDatabase): Account for the fact that RefCounted
+ (WebCore::Database::openDatabase): Account for the fact that RefCounted
objects start out with a ref count of 1.
2008-10-02 Sam Weinig <sam@webkit.org>
@@ -34859,7 +55554,7 @@
2008-10-02 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=21314
-
+
Make scrollBackingStore cross-platform.
Reviewed by Sam Weinig
@@ -34942,14 +55637,14 @@
2008-10-01 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=21298
-
+
Make updateScrollbars cross-platform. For now a stubbed out scrollContents function is invoked to do the scrolling of the backing store. Next patch
- will make that cross-platform.
-
+ will make that cross-platform.
+
The ScrollView now implements ScrollbarClient, which means that there was a clash of windowClipRect methods from the
multiple inheritance. For now I solved this by adding a Scrollbar* to the ScrollbarClient version of the method, but longer term
windowClipRect is going to be removed from ScrollbarClient (when Widget invalidation gets rewritten).
-
+
Reviewed by Sam Weinig
* page/FrameView.cpp:
@@ -35043,7 +55738,7 @@
(WebCore::XMLHttpRequest::detachRequests):
(WebCore::XMLHttpRequest::setPendingActivity):
(WebCore::XMLHttpRequest::unsetPendingActivity):
- Moved XMLHttpRequest tracking from a global map to Document.
+ Moved XMLHttpRequest tracking from a global map to Document.
* bindings/js/JSDOMBinding.cpp:
(WebCore::wrapperSet):
@@ -35131,7 +55826,7 @@
2008-10-02 Geoffrey Garen <ggaren@apple.com>
Not reviewed.
-
+
Try to fix Windows build.
* WebCore.vcproj/WebCore.vcproj:
@@ -35202,7 +55897,7 @@
(WebCore::JavaScriptDebugServer::didExecuteProgram):
(WebCore::JavaScriptDebugServer::didReachBreakpoint):
* page/JavaScriptDebugServer.h:
- * page/inspector/ScriptsPanel.js: Renamed internal uses of sourceId and
+ * page/inspector/ScriptsPanel.js: Renamed internal uses of sourceId and
sourceIdentifier to sourceID.
2008-10-01 Dan Bernstein <mitz@apple.com>
@@ -35275,7 +55970,7 @@
2008-10-01 Evan Martin <evan@chromium.org>
Reviewed by Eric Seidel.
-
+
https://bugs.webkit.org/show_bug.cgi?id=20669
* css/makeprop.pl:
@@ -35295,7 +55990,7 @@
- fix an assertion failure in http/tests/security/canvas-remote-read-svg-image.html due to re-entry into Cache::pruneDeadResources()
* loader/Cache.cpp:
- (WebCore::Cache::remove): Disable pruning temporarily during
+ (WebCore::Cache::remove): Disable pruning temporarily during
CachedResource deletion.
2008-10-01 Dan Bernstein <mitz@apple.com>
@@ -35435,9 +56130,9 @@
2008-10-01 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=21282
-
+
Make contentsToScreen/screenToContents cross-platform. Only implemented by Mac/Win right now.
-
+
Reviewed by Adam Roben
* loader/EmptyClients.h:
@@ -35649,7 +56344,7 @@
Reviewed by Sam Weinig.
- fix HTMLViewSourceDocument leaks by breaking a ref cycle which
- was fixed in r17249 and re-introduced in r31435.
+ was fixed in r17249 and re-introduced in r31435.
* html/HTMLViewSourceDocument.cpp:
(WebCore::HTMLViewSourceDocument::HTMLViewSourceDocument):
@@ -35665,7 +56360,7 @@
More for https://bugs.webkit.org/show_bug.cgi?id=21122
Autogenerate JS event listeners
- - Make EventListener getter/setters names in c++ files match those in
+ - Make EventListener getter/setters names in c++ files match those in
JS (ie. onLoadListener -> onload).
- Add standard way to access the frame associated with the EventTarget
for EventListener lookup.
@@ -35855,12 +56550,12 @@
Reviewed by Darin Adler.
- Fix for https://bugs.webkit.org/show_bug.cgi?id=20396 Abort caused
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=20396 Abort caused
by failed allocation due to invalid counter/attr
and corresponding: <rdar://problem/6152371>
* css/CSSParser.cpp:
- (WebCore::CSSParser::parseCounterContent): The spec indicates that
+ (WebCore::CSSParser::parseCounterContent): The spec indicates that
only identifiers should be accepted here.
2008-09-30 Kevin McCullough <kmccullough@apple.com>
@@ -35894,7 +56589,7 @@
(3) Used on Qt, but implemented incorrectly to cause a full repaint for no reason.
(4) Used on Gtk, but implemented incorrectly to cause a full repaint for no reason.
(5) Used on wx, but probably not needed (since wx has platform widgets like Mac).
-
+
There is now a paint method on HostWindow that does an immediate mode repaint of an empty rect to
cause the display/flush to happen if needed (thus saving an extra method on ChromeClient).
With the changes to this method, the new behavior is as follows:
@@ -35903,10 +56598,10 @@
(3) Nothing happens on Qt, but only because they have not implemented immediate mode updating.
(4) Gtk now behaves like Windows and will process updates but not do any incorrect additional invalidation.
(5) Not used on wx
-
+
This method was originally added for Windows. It's not clear the display/flush is really even necessary on the other
platforms. At the very least stopping unnecessary full invalidations on Qt/Gtk is a good thing. :)
-
+
Reviewed by Sam Weinig
* ChangeLog:
@@ -35977,7 +56672,7 @@
2008-09-30 Dave Hyatt <hyatt@apple.com>
http://bugs.webkit.org/show_bug.cgi?id=21250
-
+
Rename updateContents to repaintContentRectangle and make it cross-platform by always sending
repaints up through the ChromeClient.
@@ -36192,8 +56887,8 @@
Reviewed by Anders Carlsson.
- * bridge/npapi.h: Tweaked NPNVariable enum. NPNVsupportsCocoaBool, NPNVsupportsCarbonBool are now in the 3000 range instead of
- 2000.
+ * bridge/npapi.h: Tweaked NPNVariable enum. NPNVsupportsCocoaBool, NPNVsupportsCarbonBool are now in the 3000 range instead of
+ 2000.
2008-09-29 Dan Bernstein <mitz@apple.com>
@@ -36286,7 +56981,7 @@
Reviewed by Anders Carlsson
- Fix RenderStyle leak in animation code, and assert that
+ Fix RenderStyle leak in animation code, and assert that
keyframe resolution in CSSStyleSelector is not going to clobber
m_style.
@@ -36301,7 +56996,7 @@
Fixed https://bugs.webkit.org/show_bug.cgi?id=20995
Rewrite keyframe resolution to be like styleForElement()
-
+
Test: animations/lineheight-animation.html
* css/CSSStyleSelector.cpp:
@@ -36353,7 +57048,7 @@
Clean up fix in PropertyWrapperGetter::equals
https://bugs.webkit.org/show_bug.cgi?id=21011
-
+
Test: transitions/override-transition-crash.html
* page/animation/AnimationBase.cpp:
@@ -36948,10 +57643,10 @@
fix https://bugs.webkit.org/show_bug.cgi?id=20994
<rdar://problem/6171023> HTMLVideoElement width and height attributes are now unsigned
-
+
HTML5 spec says HTMLVideoElement width and height attributes should be unsigned. Convert
all unsigned media attributes from string with toUInt() instead of toInt().
-
+
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::playCount): convert from attribute with toUInt().
@@ -37002,7 +57697,7 @@
There was a lot wrong with 17589, so more patches will be coming to deal with the fallout of this patch
(which should never have landed in the first place).
-
+
Reviewed by Tim Hatcher, Sam Weinig
* platform/win/ScrollViewWin.cpp:
@@ -37767,7 +58462,7 @@
Reviewed by Antti
https://bugs.webkit.org/show_bug.cgi?id=21116
- <rdar://problem/5726325> Audio from <video> can still be heard after navigating
+ <rdar://problem/5726325> Audio from <video> can still be heard after navigating
back to page with <video>, then closing tab
Rename willSaveToCache/didRestoreFromCache callbacks to documentWillBecomeInactive/
@@ -37864,8 +58559,8 @@
The solution to this is to make sure we cache these constructors
in the same way as all the other DOM constructors. To achieve this
without causing any refcount cycles it is necessary to replace the
- refcounted document pointer in the Image, MessageChannel, Option,
- XMLHttpRequest, and Audio constructor objects with a reference to
+ refcounted document pointer in the Image, MessageChannel, Option,
+ XMLHttpRequest, and Audio constructor objects with a reference to
the document's JS wrapper.
Tests: fast/dom/constructors-cached-navigate.html
@@ -37958,7 +58653,7 @@
2008-09-25 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=21133
-
+
Rename resizeContents method on ScrollView to setContentsSize (to match contentsSize()). Make it
cross-platform.
@@ -38153,15 +58848,15 @@
2008-09-25 David Smith <catfish.man@gmail.com>
Reviewed by Darin Adler.
-
+
https://bugs.webkit.org/show_bug.cgi?id=20980
Split off uncommonly used data from Node similar to ElementRareData
-
+
Saves an OwnPtr and a short on Node, as well as providing room for an isContainer bit,
which in turn allows inlining firstChild(), lastChild(), childNodeCount(), and childNode()
for a 5-10+% performance win on SlickSpeed and assorted speedups on other tests.
- * WebCore.base.exp:
+ * WebCore.base.exp:
* WebCore.xcodeproj/project.pbxproj:
* dom/ChildNodeList.cpp: Include ContainerNode to pick up its definitions for childNodeCount(), etc...
* dom/ContainerNode.cpp: Set isContainer to true
@@ -38172,7 +58867,7 @@
(WebCore::Node::containerFirstChild): ditto
(WebCore::Node::containerLastChild): ditto
* dom/Element.cpp: Most of the changes here are moving ElementRareData to ElementRareData.h and NodeRareData.h
- (WebCore::Element::Element):
+ (WebCore::Element::Element):
(WebCore::Element::~Element):
(WebCore::Element::rareData):
(WebCore::Element::ensureRareData): Renamed from createRareData
@@ -38343,9 +59038,9 @@
https://bugs.webkit.org/show_bug.cgi?id=21052
Generalize id selector special case for querySelectorAll
-
+
By checking the element we get with getElementById against the selector, we can use the special case in many more circumstances.
- Changes results on http://native.khan.mozilla.org
+ Changes results on http://native.khan.mozilla.org
from
#title: 2ms
h1#title: 55ms
@@ -38355,7 +59050,7 @@
#title: 1ms
h1#title: 2ms
div #title: 5ms
-
+
* dom/Node.cpp:
(WebCore::Node::querySelector):
* dom/SelectorNodeList.cpp:
@@ -38519,7 +59214,7 @@
2008-09-25 Eric Carlson <eric.carlson@apple.com>
Reviewed by Eric Seidel.
-
+
<rdar://problem/6171047> HTMLMediaElement "begin" event is now "loadstart"
https://bugs.webkit.org/show_bug.cgi?id=21003
@@ -38656,10 +59351,10 @@
2008-09-25 David Smith <catfish.man@gmail.com>
Reviewed by Eric Seidel
-
+
fix https://bugs.webkit.org/show_bug.cgi?id=21091
Regression: querySelector matches tag names case sensitively
-
+
Tests: fast/dom/SelectorAPI/caseTag.html
fast/dom/SelectorAPI/caseTagX.xhtml
@@ -38746,7 +59441,7 @@
Reviewed by Dan Bernstein.
Test: editing/spelling/inline_spelling_markers.html
-
+
- https://bugs.webkit.org/show_bug.cgi?id=20092
Spelling markers positioned incorrectly in RTL text
@@ -39397,7 +60092,7 @@
Fix for bug 21012. The Aqua scrollbar was returning the wrong track rect on Windows Aqua theme. Make
sure to not accidentally fall into the vertical scrollbar case for horizontal scrollbars. :)
-
+
Reviewed by Sam Weinig
* platform/mac/ScrollbarThemeMac.mm:
@@ -39410,11 +60105,11 @@
Reviewed by Sam Weinig.
- Fix for https://bugs.webkit.org/show_bug.cgi?id=21041 "Add Contact"
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=21041 "Add Contact"
link at gmail does not support AXPress action
and corresponding: <rdar://problem/6216178>
- I fixed this bug by making AccessibilityObject::anchorElement
+ I fixed this bug by making AccessibilityObject::anchorElement
support ARIA links.
* page/AccessibilityImageMapLink.cpp:
@@ -39439,7 +60134,7 @@
Bug 20949: Catch repeated messages in Inspector Controller to limit
memory usage
- - Store the repeat count in the Console Message object, in the
+ - Store the repeat count in the Console Message object, in the
Inspector Controller and JS ConsoleMessage object.
* page/InspectorController.cpp:
@@ -39626,7 +60321,7 @@
~2% speedup on EarleyBoyer
(WebCore updates.)
-
+
* bindings/js/JSQuarantinedObjectWrapper.h:
(WebCore::JSQuarantinedObjectWrapper::createStructureID):
@@ -39669,7 +60364,7 @@
2008-09-23 Eric Seidel <eric@webkit.org>
No review, build fix only.
-
+
Third time's the charm, eh? My local build is sadly still not done...
* platform/graphics/AffineTransform.cpp: remove extra &
@@ -39849,7 +60544,7 @@
transition end event when -webkit-transition-property: all puts wrong
propertyName in event
https://bugs.webkit.org/show_bug.cgi?id=20903
-
+
* page/animation/ImplicitAnimation.cpp:
(WebCore::ImplicitAnimation::sendTransitionEvent):
@@ -39914,7 +60609,7 @@
- speed up instanceof operator by replacing implementsHasInstance method with a TypeInfo flag
Partial work towards <https://bugs.webkit.org/show_bug.cgi?id=20818>
-
+
2.2% speedup on EarleyBoyer benchmark.
* bindings/js/JSQuarantinedObjectWrapper.cpp:
@@ -39933,11 +60628,11 @@
Reviewed by Dave Hyatt.
Based on initial work by Darin Adler.
-
+
- replace masqueradesAsUndefined virtual method with a flag in TypeInfo
- use this to JIT inline code for eq_null and neq_null
https://bugs.webkit.org/show_bug.cgi?id=20823
-
+
* WebCore.xcodeproj/project.pbxproj:
* WebCore.vcproj/WebCore.vcproj:
* bindings/js/JSCSSStyleDeclarationCustom.cpp:
@@ -40062,7 +60757,7 @@
- introduce a TypeInfo class, for holding per-type (in the C++ class sense) date in StructureID
https://bugs.webkit.org/show_bug.cgi?id=20981
-
+
* bindings/js/JSAudioConstructor.cpp:
(WebCore::JSAudioConstructor::JSAudioConstructor):
* bindings/js/JSCSSStyleDeclarationCustom.cpp:
@@ -40125,7 +60820,7 @@
2008-09-21 Steve Falkenburg <sfalken@apple.com>
Removed unnecessary nested timer check.
-
+
Rubber-stamped by Dan Bernstein.
* platform/win/SharedTimerWin.cpp:
@@ -40135,14 +60830,14 @@
Improve timer resolution on WinXP.
https://bugs.webkit.org/show_bug.cgi?id=20979
-
+
Removed last-chance timer. It should not be necessary.
Change timeEndPeriod timer to fire in 300ms instead of 20ms. Calling timeBeginPeriod/timeEndPeriod too often throws off accuracy.
Remove Vista checks. We now run the same code on both XP and Vista.
-
+
Call through to JSC::getCurrentUTCTimeWithMicroseconds from WebCore::currentTime.
The code previously called GetSystemTimeAsFileTime, which is always low-resolution on XP, even within timeBeginPeriod(1).
-
+
Reviewed by Maciej Stachowiak.
* platform/win/SharedTimerWin.cpp:
@@ -40276,7 +60971,7 @@
Reviewed by Dan Bernstein.
Fix memory leak.
-
+
https://bugs.webkit.org/show_bug.cgi?id=20505
* platform/wx/wxcode/mac/carbon/fontprops.cpp:
@@ -40568,7 +61263,7 @@
2008-09-19 David Hyatt <hyatt@apple.com>
- Add support for hit testing of all five possible scrollbar button placements.
+ Add support for hit testing of all five possible scrollbar button placements.
Reviewed by Sam Weinig
@@ -40712,7 +61407,7 @@
Fix for <rdar://problem/6231308> crash in AutoTableLayout
- The code assumes later on that a TableSection's grid's row vector
+ The code assumes later on that a TableSection's grid's row vector
will never be empty. So make 1 the minimum number of columns.
* rendering/RenderTableSection.cpp:
@@ -40742,7 +61437,7 @@
2008-09-19 Steve Falkenburg <sfalken@apple.com>
Roll out r36626. It is causing variance in SunSpider numbers on XP.
-
+
Rubber stamped by Mark Rowe.
* platform/win/SharedTimerWin.cpp:
@@ -40972,7 +61667,7 @@
(WebCore::CoreTextController::CoreTextController): Added a
mayUseNaturalWritingDirection parameter.
(WebCore::CoreTextController::collectCoreTextRunsForCharacters): Changed
- to force the bidi embedding level whenever
+ to force the bidi embedding level whenever
m_mayUseNaturalWritingDirectrion is false. Since this is now a common
case, made the typesetter options dictionaries static.
* platform/graphics/mac/CoreTextController.h:
@@ -41030,7 +61725,7 @@
<rdar://problem/6213171> WebKit should use new array-centric methods for AX performance
- Implement a few AX API methods that will be called by AppKit, which will
+ Implement a few AX API methods that will be called by AppKit, which will
speed up access to accessibility objects
* page/mac/AccessibilityObjectWrapper.mm:
@@ -41280,7 +61975,7 @@
https://bugs.webkit.org/show_bug.cgi?id=20690
Invoke WebCore::prefetchDNS() on host names that appear in
- in the href of hyperlinks and <link rel="dns-prefetch">. This
+ in the href of hyperlinks and <link rel="dns-prefetch">. This
can be used to implement DNS prefetching.
* WebCore.vcproj/WebCore.vcproj:
@@ -41603,7 +62298,7 @@
Reviewed by Beth Dakin
- <rdar://problem/6224222> AX: should not expose a <table> as an AXTable if ARIA
+ <rdar://problem/6224222> AX: should not expose a <table> as an AXTable if ARIA
role specifies otherwise
If a <table> isn't an AXTable, the rows and cells should default to AccessibilityRenderObject
@@ -41630,7 +62325,7 @@
2008-09-18 Steve Falkenburg <sfalken@apple.com>
Use higher-resolution timers on all variants of Windows.
-
+
Reviewed by Darin Adler.
* platform/win/SharedTimerWin.cpp:
@@ -41669,17 +62364,17 @@
Reviewed by Dave Hyatt.
- Fix for https://bugs.webkit.org/show_bug.cgi?id=20515 Crash upon
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=20515 Crash upon
parsing CSS: unicode-range: searchfield-cancel-buttonpt=-webkit-
dashboard-region=
and corresponding: <rdar://problem/6174100>
- This patch makes CSSParserValue::createCSSValue handle unknown
+ This patch makes CSSParserValue::createCSSValue handle unknown
identifiers.
* css/CSSParserValues.cpp:
- (WebCore::CSSParserValue::createCSSValue): If we have an identifier
- with no id (an unknown identifier) create a CSSPrimitiveValue of
+ (WebCore::CSSParserValue::createCSSValue): If we have an identifier
+ with no id (an unknown identifier) create a CSSPrimitiveValue of
type CSS_PARSER_IDENTIFIER
* css/CSSPrimitiveValue.cpp:
(WebCore::CSSPrimitiveValue::cssText):
@@ -41868,7 +62563,7 @@
<rdar://problem/5722310> gracefully handle too many console messages
(20904)
- - Keep track of the most previous message and then compare it to the
+ - Keep track of the most previous message and then compare it to the
subsequent messages as they come in. If there are multiple of the same
message create a count that indicates the current number.
@@ -41960,7 +62655,7 @@
Rubber-stamped with love by David Hyatt.
- Split IdentityTransformOperation, MatrixTransformOperation, RotateTransformOperation,
+ Split IdentityTransformOperation, MatrixTransformOperation, RotateTransformOperation,
ScaleTransformOperation, SkewTransformOperation, StyleTransformData, TransformOperation,
TransformOperations and TranslateTransformOperation out of RenderStyle.h/cpp
@@ -42176,7 +62871,7 @@
2008-09-17 Steve Falkenburg <sfalken@apple.com>
Add back isFrameView check to fix failed assertion during scroll bar teardown.
-
+
Reviewed by Dave Hyatt.
* platform/Scrollbar.cpp:
@@ -42255,7 +62950,7 @@
This is a better fix for: Invalid CSS code crashes Safari
https://bugs.webkit.org/show_bug.cgi?id=20512
- The spec indicates that the only valid input for a counter is a
+ The spec indicates that the only valid input for a counter is a
number or an identifier. So that is exactly what we allow.
* css/CSSParser.cpp:
@@ -42278,7 +62973,7 @@
Reviewed by Adele Peterson.
- Patch for <rdar://problem/6133884>
+ Patch for <rdar://problem/6133884>
Calling window.resizeTo() on a subframe shouldn't change the window size
Test: fast/dom/Window/window-resize-and-move-sub-frame.html
@@ -42293,13 +62988,13 @@
Reviewed by Adam Roben.
- Fix for https://bugs.webkit.org/show_bug.cgi?id=20512 Invalid CSS
- code crashes Safari
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=20512 Invalid CSS
+ code crashes Safari
and corresponding: <rdar://problem/6173832>
- Reading through the spec, it seems like a function is not valid
- input for a counter. So this patch checks for that and bails in the
- case of invalid input.
+ Reading through the spec, it seems like a function is not valid
+ input for a counter. So this patch checks for that and bails in the
+ case of invalid input.
* css/CSSParser.cpp:
(WebCore::CSSParser::parseCounterContent):
@@ -42308,9 +63003,9 @@
Reviewed by Antti Koivisto.
- Fix <rdar://problem/6227089>
+ Fix <rdar://problem/6227089>
Crash in WebCore::Frame::setNeedsReapplyStyles()
-
+
View is null checked elsewhere too.
* page/Frame.cpp:
@@ -42853,7 +63548,7 @@
Convert Qt over to its ScrollbarTheme. Add cross-platform support for jumping the thumb location directly
to a pressed location on the track (this is done with the middle mouse on Qt and with Shift-Click on Windows).
-
+
Reviewed by Sam Weinig
* platform/ScrollBar.cpp:
@@ -42896,9 +63591,9 @@
2008-09-15 David Smith <catfish.man@gmail.com>
Reviewed by Sam Weinig.
-
+
https://bugs.webkit.org/show_bug.cgi?id=20180
-
+
Cache the result of parsing the an+b expression in :nth-child(an+b). Roughly a 2x speedup for :nth-child on SlickSpeed.
* GNUmakefile.am: Add CSSNthSelector
@@ -42948,10 +63643,10 @@
Completely switch Windows scrollbars over to ScrollbarTheme. The Aqua windows scrollbar and native scrollbar
now share most of their code.
-
+
Also removing mini size scrollbar support, since it would have crashed Windows had it ever been used, and it
also is never used in our code anyway.
-
+
Reviewed by Sam Weinig
* WebCore.vcproj/WebCore.vcproj:
@@ -42996,7 +63691,7 @@
Lists are now exposed through AX. On the mac (in SnowLeopard) they use two new subroles
AXContentList for <ul>, <ol> and AXDefinitionList for <dl>
- Inside the definition list, each <dt> "term" has an accessibility description ("term"),
+ Inside the definition list, each <dt> "term" has an accessibility description ("term"),
as does each <dd> tag ("definition")
Test: accessibility/lists.html
@@ -43184,7 +63879,7 @@
Convert PlatformScrollbarWin to use ScrollbarTheme for hit testing. PlatformScrollbarQt/Gtk still
need to be converted.
-
+
Reviewed by Sam Weinig
* platform/ScrollBar.cpp:
@@ -43372,12 +64067,12 @@
Reviewed by Maciej.
- <rdar://problem/6163988>
+ <rdar://problem/6163988>
https://bugs.webkit.org/show_bug.cgi?id=20457
Canvas: createPattern crashes WebKit in WTF::RefPtr<WebCore::Image>::operator!() const + 9 with a 1D pattern
-
+
Check the width and height and throw an exception if any of them are 0.
-
+
* html/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::createPattern):
@@ -43432,11 +64127,11 @@
Reviewed by Dave Hyatt.
https://bugs.webkit.org/show_bug.cgi?id=20180
-
+
>2x speedup on querySelector[All] with :nth-child by removing the collectRulesOnly argument on SelectorChecker.
With collectRulesOnly set to true (the default) an optimization is turned off, and no callers were intentionally leaving it true.
querySelector[All] assumed that the default was probably the right way to go, and so ended up being slow.
-
+
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::CSSStyleSelector):
(WebCore::CSSStyleSelector::SelectorChecker::SelectorChecker):
@@ -43446,7 +64141,7 @@
Refactor PlatformScrollbarWin's painting so that it is now done by ScrollbarThemeWin. PlatformScrollbarSafari
is still painting itself (a subsequent patch will move its painting into ScrollbarThemeSafari).
-
+
Reviewed by Sam Weinig
* platform/ScrollBar.h:
@@ -43556,7 +64251,7 @@
Add a new ScrollbarThemeComposite base class that is shared by ScrollbarThemeSafari and
ScrollbarThemeWin. Any scrollbar that wants to render by ScrollbarPart can subclass from this
theme.
-
+
Reviewed by Sam Weinig
* WebCore.vcproj/WebCore.vcproj:
@@ -43726,7 +64421,7 @@
Remove scrollbar's setRect method. Clients can now just call setFrameGeometry (the corresponding Widget) method
to set the dimensions of a scrollbar.
-
+
Reviewed by Sam Weinig
* platform/ScrollBar.h:
@@ -43761,7 +64456,7 @@
2008-09-13 Dave Hyatt <hyatt@apple.com>
Remove setEnabled() from all Scrollbar classes that were just using their Widget base class methods.
-
+
Reviewed by Sam Weinig
* platform/ScrollBar.h:
@@ -43838,17 +64533,17 @@
(WebCore::FontCache::getLastResortFallbackFont): Removed an outdated
comment (the user's preferred standard font is included in the search
thanks to code in FontCache::getFontData()) and changed to return the
- LastResort font.
+ LastResort font.
2008-09-13 Dave Hyatt <hyatt@apple.com>
This patch adds ScrollbarTheme to the build. ScrollbarTheme is similar to RenderTheme (but for
scrollbars only). For now ScrollbarTheme just handles returning the size of scrollbars. Subsequent
patches will move rendering and hit testing functionality into this class.
-
+
Implemented ScrollbarTheme subclasses for four ports (Mac, Win, Gtk, Qt). The wxWidgets port does not
implement scrollbars yet, so I added a temporary link stub to keep things compiling on wx.
-
+
Reviewed by Sam Weinig
* GNUmakefile.am:
@@ -43950,7 +64645,7 @@
Move the member variables of PlatformScrollbar up into Scrollbar. Move autoscroll timer handling
up into scrollbar. Make sure a bunch of cross-platform code now just uses "Scrollbar" instead of
"PlatformScrollbar."
-
+
Reviewed by Sam Weinig
* WebCore.vcproj/WebCore.vcproj:
@@ -44071,7 +64766,7 @@
* page/EventHandler.cpp: (WebCore::EventHandler::hitTestResultAtPoint):
Hit testing again on the main frame will only work if we aren't already on the main frame. If we are already on the main frame, that will
- cause infinite recursion. This change checks that we're not already on the main frame before hit testing again.
+ cause infinite recursion. This change checks that we're not already on the main frame before hit testing again.
2008-09-12 Kevin McCullough <kmccullough@apple.com>
@@ -44122,7 +64817,7 @@
Preparation for major scrollbar rearchitecture. Eliminate the concept of non-widget based
scrollbars (which we never supported anyway). Make Scrollbar derive from Widget directly.
Remove all the isWidget and hasPlatformScrollbars guards.
-
+
Reviewed by Tim Hatcher
* platform/ScrollBar.h:
@@ -44245,7 +64940,7 @@
Reviewed by Darin
https://bugs.webkit.org/show_bug.cgi?id=20180
-
+
This speeds up :nth-child matching as tested by querySelectorAll by around 10% by inlining the common case of Node::renderStyle(). Many thanks to mitzpettel and othermaciej for suggestions and help.
* WebCore.xcodeproj/project.pbxproj: Add NodeRenderStyle.h
@@ -44379,7 +65074,7 @@
2008-09-09 Dave Hyatt <hyatt@apple.com
Resurrect PlatformScrollbarWin.
-
+
Reviewed by Adam Roben
* WebCore.vcproj/WebCore.vcproj:
@@ -44464,7 +65159,7 @@
Make the Windows classic case work again. Overlap in slider constants and other constants broke
the push state for buttons and checkboxes. Make sure to check the RenderObject's appearance
value to make sure it's really a slider thumb to resolve this conflict.
-
+
Reviewed by Adam Roben
* rendering/RenderThemeWin.cpp:
@@ -44489,11 +65184,11 @@
RenderThemeWin that does not have any Skia dependencies should provide a good basis for a potential
merge of Google Chrome's RenderThemeWin (to help us see where the Skia stuff can be cut and to see
what changes have been made as compared with the old RenderThemeWin).
-
+
Fix CSS2 system fonts to properly set both the rendering mode (so that they properly pick up GDI vs. CG
text rendering modes) and the printer font setting (so that OS X system fonts properly pick up screen
vs. printer advancement rounding).
-
+
Reviewed by Adam/Sam
* css/CSSStyleSelector.cpp:
@@ -44610,7 +65305,7 @@
Reviewed by Alexey Proskuryakov.
- Try MIME charset names before trying IANA names
+ Try MIME charset names before trying IANA names
( https://bugs.webkit.org/show_bug.cgi?id=17537 )
With this change, shorter and more widely used names (preferred MIME
@@ -44618,8 +65313,8 @@
document.inputEncoding rather than IANA names. This helps
fixing bug 18085 in addition to web developers who are more familiar
with MIME names. For instance, EUC-JP, ISO-8859-X and US-ASCII will be
- returned instead of Extended_UNIX_Code_Packed_Format_for_Japanese,
- ISO-8859-X:19xx, and ANSI_X3.4-1968. It also replaces IBM8xx with cp8xx.
+ returned instead of Extended_UNIX_Code_Packed_Format_for_Japanese,
+ ISO-8859-X:19xx, and ANSI_X3.4-1968. It also replaces IBM8xx with cp8xx.
Note that cp/IBM 8xx are extremly rare in today's web. Even if they're
used, the former is still recognized as aliases to the latter so that
there's very little, if any, to worry about.
@@ -44723,12 +65418,12 @@
Reviewed by Maciej.
<rdar://problem/5850387> Showing bookmarks reloads Google Reader instead.
-
+
In some cases, timeouts scheduled by a page in the onunload handler could fire even when the
page had been unloaded and replaced by a non-HTML representation based view (such as the bookmarks view).
-
+
Fix this by clearing timeouts for pages that aren't cached when the provisional load is committed.
-
+
* bindings/js/JSDOMWindowBase.h:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::commitProvisionalLoad):
@@ -45235,7 +65930,7 @@
(WebCore::): Added NodeMessageLevel.
* page/Console.idl: Added console.dirxml.
* page/inspector/Console.js: A NodeMessage creates a ElementsTreeOutline.
- * page/inspector/ElementsPanel.js: Modified to use ElementsTreeOutline. The ElementsTreeOutline
+ * page/inspector/ElementsPanel.js: Modified to use ElementsTreeOutline. The ElementsTreeOutline
in the ElementsPanel has includeRootDOMNode and selectEnabled set to true.
* page/inspector/ElementsTreeOutline.js: Added.
(WebInspector.ElementsTreeOutline): A subclass of TreeOutline for displaying a DOM node tree.
@@ -45296,19 +65991,19 @@
Reviewed by Dave Hyatt.
- <rdar://problem/6187043>
+ <rdar://problem/6187043>
Don't parse full HTML user agent style sheet unless it is actually needed
- <rdar://problem/6131889>
+ <rdar://problem/6131889>
WebView is significantly more expensive to create recently
-
+
Parsing the html4.css takes significant amount of time and memory (~50kb) on application
startup. Some clients may never use most of the rules.
-
- With this patch we use simplified UA stylesheet until we hit something it can't handle.
+
+ With this patch we use simplified UA stylesheet until we hit something it can't handle.
This avoids full stylesheet parsing on application startup (due to empty document construction)
- and also makes it possible for clients with very simple demands (divs and spans only) never to load
+ and also makes it possible for clients with very simple demands (divs and spans only) never to load
the full style.
-
+
It also delays view source style parsing until it is used.
* css/CSSStyleSelector.cpp:
@@ -45342,7 +66037,7 @@
Fix <rdar://problem/6201644>
https://bugs.webkit.org/show_bug.cgi?id=20493
Crash after OK in dialog box and reloading page in secure mode
-
+
Limited loader only fix since the general timer fix is causing problems on Windows.
* loader/loader.cpp:
@@ -45526,7 +66221,7 @@
2008-09-05 Antti Koivisto <antti@apple.com>
Build fixes.
-
+
* WebCore.xcodeproj/project.pbxproj:
* svg/graphics/filters/SVGFEImage.cpp:
(WebCore::FEImage::cachedImage):
@@ -45541,17 +66236,17 @@
Implement HTTP 1.1 "Specific end-to-end revalidation" for WebCore memory cache. This patch does
not yet enable it for the biggest use case, reloading. However it is good for general browsing as
well. Doing this in WebCore level as opposed to relying on disk cache has big benefit that
- we avoid re-decoding resources, especially images.
-
+ we avoid re-decoding resources, especially images.
+
To be exact the enabled case is not actually the "Specific end-to-end revalidation" since it does not include
CacheControl: max-age=0 header. That would be added in reload case.
-
+
The approach for revalidation is to kick the original resource out from the memory cache
and create a new CachedResource that represents the revalidation request. In case
- we get 304 back for the request we put the original resource back to the cache, update
+ we get 304 back for the request we put the original resource back to the cache, update
its expiration date and switch the clients registered to revalidation resource to be
clients of the original resource.
-
+
All heap allocated CachedImage pointers now use CachedResourceHandle<CachedImage> (and so on) instead.
This allows updating the handles to point to the original resource when the revalidation succeeds. It
also acts as refcounting smart pointer.
@@ -45651,10 +66346,10 @@
<rdar://problem/6180236> - Safari times out connections after 1 or 2 minutes
- A 60-second default timeout was added in http://trac.webkit.org/changeset/17144 in an attempt
- to model default NSURLRequest behavior in a cross-platform manner.
+ A 60-second default timeout was added in http://trac.webkit.org/changeset/17144 in an attempt
+ to model default NSURLRequest behavior in a cross-platform manner.
- Sadly by always enforcing this 60 second timeout, WebCore was stomping over the wishes of any Webkit
+ Sadly by always enforcing this 60 second timeout, WebCore was stomping over the wishes of any Webkit
client that wished to enforce a much larger default timeout using NSURLRequest API.
Additionally, upon reviewing what all other browsers do, it seems apparent that "no limit" is desirable
@@ -45670,7 +66365,7 @@
(WebCore::ResourceRequestBase::ResourceRequestBase): Rename the constant to "unspecifiedTimeoutInterval"
and make it UINT_MAX so platforms that do set it have an effective "no timeout." (Windows, for example)
* platform/network/mac/ResourceRequestMac.mm:
- (WebCore::ResourceRequest::doUpdatePlatformRequest): If the timeout for this request is
+ (WebCore::ResourceRequest::doUpdatePlatformRequest): If the timeout for this request is
"unspecifiedTimeoutInterval", then don't bother setting the timeout using NSURLRequest API, allowing
WebKit applications to enforce their own default timeout.
@@ -45684,7 +66379,7 @@
* rendering/RenderButton.cpp:
(WebCore::RenderButton::setStyle): Reset the inner block's style box
- flex to 0 to avoid getting a spurious layout hint.
+ flex to 0 to avoid getting a spurious layout hint.
2008-09-04 Kevin Ollivier <kevino@theolliviers.com>
@@ -45813,11 +66508,11 @@
Reviewed by Simon.
Re-enable support for user stylesheets in QtWebKit
-
+
QtWebKit now follows the FRAME_LOADS_USER_STYLESHEET
code path, which allows us to keep API support for
loading user style sheets from remote URLs.
-
+
As part of the change UserStyleSheetLoader.cpp/h was
moved from WebCore/loader/mac to WebCore/loader.
@@ -45988,7 +66683,7 @@
Remove the rest of the "zombie" code from the profiler.
- There is no longer a need for the ProfilerClient callback mechanism.
- * page/Console.cpp:
+ * page/Console.cpp:
(WebCore::Console::Console):
(WebCore::Console::profile):
(WebCore::Console::profileEnd): Move the variables from the header to
@@ -46231,7 +66926,7 @@
style="color:#gray;" would apply the color gray when it should not.
In the bison template, "hexcolor" was defined as both "HEX maybe_space" OR "IDENT maybe_space".
- This caused identifiers not fitting the appropriate hex format but preceded by a '#' to be
+ This caused identifiers not fitting the appropriate hex format but preceded by a '#' to be
interpreted as a valid color (CSSPrimitiveValue::CSS_PARSER_HEXCOLOR), when it was really just
an ignorable token.
@@ -46331,7 +67026,7 @@
AnimationController.cpp should be split into separate files
https://bugs.webkit.org/show_bug.cgi?id=20604
-
+
Note: All makefiles, except WebCore.xcodeproj have been changed without testing, upon
recommendation of Dave Hyatt.
@@ -46341,7 +67036,7 @@
* WebCore.xcodeproj/project.pbxproj:
* WebCoreSources.bkl:
Build files.
-
+
* page/AnimationController.cpp: Removed.
* page/AnimationController.h: Removed.
* page/animation: Added.
@@ -46661,16 +67356,16 @@
Fix for <rdar://problem/6181588>
- This patch makes hit testing take into account the new concept of a
- disconnected frame, in which some of the content may not be
- visible. The current hit testing mechanism starts at a target frame
- and drills down for a HitTestResult. In some cases, drilling down
- will find a non-visible result. When this happens, we need to try
- again, starting at a higher level -- namely, starting at the main
+ This patch makes hit testing take into account the new concept of a
+ disconnected frame, in which some of the content may not be
+ visible. The current hit testing mechanism starts at a target frame
+ and drills down for a HitTestResult. In some cases, drilling down
+ will find a non-visible result. When this happens, we need to try
+ again, starting at a higher level -- namely, starting at the main
frame.
* editing/Editor.cpp:
- (WebCore::Editor::insideVisibleArea): New function that tests if a
+ (WebCore::Editor::insideVisibleArea): New function that tests if a
point is inside the visible area for a disconnected frame.
* editing/Editor.h:
* page/EventHandler.cpp:
@@ -46678,7 +67373,7 @@
2008-08-29 Adele Peterson <adele@apple.com>
- Reviewed by Adam Roben.
+ Reviewed by Adam Roben.
Rename HTMLTextFieldInnerElement.h/.cpp to TextControlInnerElements.h/.cpp
@@ -46722,7 +67417,7 @@
Fix GeneratedImage to respect Image's refcounting
Fixing potential crashers (future if not current)
https://bugs.webkit.org/show_bug.cgi?id=20567
-
+
I don't know if it's possible to make the current code
crash, thus I've not made a test.
@@ -46758,9 +67453,9 @@
Fix for https://bugs.webkit.org/show_bug.cgi?id=20525
<rdar://problem/6169301>
-
+
Return the size of the movie data instead of 1000.
-
+
Test: media/progress-event-total.html
* platform/graphics/win/QTMovieWin.cpp:
@@ -46925,9 +67620,9 @@
Make all the 'isFoo()' methods on CSSValue const,
and fix the subclasses.
-
+
https://bugs.webkit.org/show_bug.cgi?id=20561
-
+
* css/CSSTimingFunctionValue.h:
* css/CSSValue.h:
(WebCore::CSSValue::isFontValue):
@@ -47022,9 +67717,9 @@
<rdar://problem/6182541>
https://bugs.webkit.org/show_bug.cgi?id=20202
Missing http status line from the http headers.
-
+
Add a status line to the header string.
-
+
* plugins/PluginStream.cpp:
(WebCore::PluginStream::startStream):
@@ -47109,12 +67804,12 @@
https://bugs.webkit.org/show_bug.cgi?id=20373
Changed pattern() to canvasPattern() on CanvasStyle to match canvasGradient()
-
+
Made Generator (aka Gradient) RefCounted so that GraphicsContext didn't
have to store large Gradient objects in the GraphicsContextState
-
+
Made Pattern RefCounted for the same reason.
-
+
Many updates to GraphicsContext to support easier drawing with
Patterns and Gradients.
@@ -47191,14 +67886,14 @@
Close a leak of PausedTimeouts if the JavaScriptDebugServer was destroyed
with timeouts paused.
https://bugs.webkit.org/show_bug.cgi?id=20469
-
+
I attempted to clean up the memory management of PausedTimeouts, I'm not
sure the solution I came up with is "cleaner", but it's in some ways
"safer", since it no longer uses raw pointers and manual new/delete.
-
+
This also now prevents CachedPage from needlessly creating Window
objects when caching pages which didn't already have one. :)
-
+
I also made Chrome.cpp no longer depend on the JavaScript bindings
(aka JSDOMWindowBase.h), since there was no real reason for it to.
@@ -47274,7 +67969,7 @@
2008-08-27 Mario Bensi <mbensi@pleyo.com>
Reviewed by Eric Seidel.
-
+
Fix the data content of an image with a base64.
* platform/network/curl/ResourceHandleManager.cpp:
@@ -47289,10 +67984,10 @@
Crash after OK in dialog box and reloading page in secure mode
https://bugs.webkit.org/show_bug.cgi?id=20493
-
- The new run loop spawned by a modal dialog causes a timer in the loader to run
+
+ The new run loop spawned by a modal dialog causes a timer in the loader to run
synchronously inside didFinishLoading() deleting "this" object.
-
+
Defer all WebCore timers when a modal dialog is up. They are not
safe to execute.
@@ -47494,7 +68189,7 @@
Reviewed by Darin Adler.
Change canvas tainting logic to ask the image if it contains
- any resources outside of its own origin. Since there is no
+ any resources outside of its own origin. Since there is no
way to determine if SVG images contain any resources outside its
origin, we always assume it does.
@@ -47622,8 +68317,8 @@
Reviewed by Mark.
<rdar://problem/6149787> crash @ com.apple.JavaScriptCore: WTF::callOnMainThread + 37.
-
- Initialize threading in the call to WebCoreObjCFinalizeOnMainThread. We currently assume
+
+ Initialize threading in the call to WebCoreObjCFinalizeOnMainThread. We currently assume
(safely) that any class that needs finalization on the main thread will also need to be deallocated
on the main thread, and calling initializeThreading from WebCoreObjCFinalizeOnMainThread instead of
calling it from WebCoreObjCScheduleDeallocateOnMainThread seems safer.
@@ -47674,7 +68369,7 @@
* ForwardingHeaders/VM: Added.
* ForwardingHeaders/VM/Machine.h: Added.
- * page/Console.cpp: Gather the line number and file information when
+ * page/Console.cpp: Gather the line number and file information when
profileEnd has been called, but don't use it until didFinishProfiling is
called. We won't need to wait once we remove the profiler "zombie" mode
which this patch helps pave the foundation for.
@@ -47715,21 +68410,21 @@
2008-08-24 Steve Falkenburg <sfalken@apple.com>
Add a "last chance" WM_TIMER to the Windows shared timer.
-
+
The last chance timer fires every 5 seconds to run any lost WM_TIMER based timers.
Failure to fire a timer is fatal to the cross-platform Timer code, since it won't re-schedule
timers if a timer with an earlier expiration is already pending. This results in no timers
firing from that point on.
-
+
We lose WM_TIMER messages occasionally (in the neighborhood of 1 per hour) probably due to a
buggy window message hook.
-
+
This timer will start when the first WM_TIMER is scheduled, and will
fire every 5 seconds thereafter, causing any lost timers to be fired.
-
+
Found this via one of its symptoms: leaking WebFrames. The fix prevents timers from stalling
and prevents the WebFrame leak.
-
+
Reviewed by Darin Adler, Geoff Garen.
* platform/win/SharedTimerWin.cpp:
@@ -47968,7 +68663,7 @@
Test: fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html
https://bugs.webkit.org/show_bug.cgi?id=20451
-
+
rdar://problem/6166435 Inspector doesn't auto scroll when selecting text (20451)
When we climb up the rendering tree looking for a scrollable renderer, we need to be able to jump outside of an iframe.
This way we can see if what is embedding the iframe can be scrolled even if the iframe content can't.
@@ -48069,9 +68764,9 @@
Fix a race condition in Windows timer code.
Timer function could end up being called with a 0 timer, leading to a Windows exception.
-
+
Don't post a timer message if one is already pending.
-
+
Reviewed by Ada Chan.
* platform/win/SharedTimerWin.cpp:
@@ -48167,15 +68862,15 @@
<rdar://problem/6153432> - Many images broken in Mail
- This can be traced back to the preload scanner. With that change, CachedResources are created a lot
- sooner than before and confuse the WebArchive machinery.
+ This can be traced back to the preload scanner. With that change, CachedResources are created a lot
+ sooner than before and confuse the WebArchive machinery.
- When referencing WebArchive subresources directly through the WebKit API it is appropriate to ignore
- such CachedResources since they are placeholders and have not been submitted to the ResourceLoadDelegate
+ When referencing WebArchive subresources directly through the WebKit API it is appropriate to ignore
+ such CachedResources since they are placeholders and have not been submitted to the ResourceLoadDelegate
machinery and nothing is known about where the data will eventually come from.
* loader/DocumentLoader.cpp:
- (WebCore::DocumentLoader::subresource): Ignore a CachedResource if its preloadResult is
+ (WebCore::DocumentLoader::subresource): Ignore a CachedResource if its preloadResult is
CachedResource::PreloadReferenced.
2008-08-20 Holger Hans Peter Freyther <zecke@selfish.org>
@@ -48208,7 +68903,7 @@
getComputedStyle() for webkitTransform should return a transform
that does not have the transform origin baked into it.
https://bugs.webkit.org/show_bug.cgi?id=20464
-
+
Test: fast/css/getComputedStyle-transform.html
* css/CSSComputedStyleDeclaration.cpp:
@@ -48221,9 +68916,9 @@
Reviewed and landed by Anders.
- <rdar://problem/6163636>
+ <rdar://problem/6163636>
rename NPCocoaEvent's "event" struct to "data" (20446)
-
+
* bridge/npapi.h:
(_NPCocoaEvent::):
@@ -48231,38 +68926,38 @@
Reviewed by Darin Adler.
- Fix for <rdar://problem/6145626>
- This patch fixes a number of remaining problems getting
- disconnected frames to work correctly with markAllMatchesForText()
- and findString(). Details inline.
+ Fix for <rdar://problem/6145626>
+ This patch fixes a number of remaining problems getting
+ disconnected frames to work correctly with markAllMatchesForText()
+ and findString(). Details inline.
- This was a static helper function in Frame, but this patch requires
- the same functionality in Editor, so I just added it as a function
+ This was a static helper function in Frame, but this patch requires
+ the same functionality in Editor, so I just added it as a function
on Node.
* dom/Node.cpp:
(WebCore::Node::isInShadowTree):
* dom/Node.h:
* editing/Editor.cpp:
- (WebCore::Editor::insideVisibleArea): Returns false if
+ (WebCore::Editor::insideVisibleArea): Returns false if
excludeFromTextSearch() is true.
- In a normal (non-disconnected) frame, findString returns a range of
- the document node if the text is not found in the frame. I changed
- firstVisibleRange and lastVisibleRange to match that behavior when
+ In a normal (non-disconnected) frame, findString returns a range of
+ the document node if the text is not found in the frame. I changed
+ firstVisibleRange and lastVisibleRange to match that behavior when
the text is not found
(WebCore::Editor::firstVisibleRange):
(WebCore::Editor::lastVisibleRange):
- Here are the bulk of the changes in the patch. A lot of text was
- not being found in disconnected frames because I failed to account
- for all of the possible problems associated with shadow trees. That
+ Here are the bulk of the changes in the patch. A lot of text was
+ not being found in disconnected frames because I failed to account
+ for all of the possible problems associated with shadow trees. That
is fixed here.
(WebCore::Editor::nextVisibleRange):
* editing/Editor.h:
- excludeFromTextSearch() is new. It allows a WebKit client to mark a
- frame as not-text-searchable through SPI.
+ excludeFromTextSearch() is new. It allows a WebKit client to mark a
+ frame as not-text-searchable through SPI.
* WebCore.base.exp:
* page/Frame.cpp:
(WebCore::Frame::excludeFromTextSearch):
@@ -48272,8 +68967,8 @@
* page/FramePrivate.h:
(WebCore::Frame::findString):
- (WebCore::Frame::markAllMatchesForText): I kept running into an
- assertion failure in paining code because of the forced paint on
+ (WebCore::Frame::markAllMatchesForText): I kept running into an
+ assertion failure in paining code because of the forced paint on
empty visible rects.
2008-08-20 Timothy Hatcher <timothy@apple.com>
@@ -48578,7 +69273,7 @@
Reviewed by Beth Dakin.
<rdar://problem/4003764> Expose tables as AXTables
-
+
Tests: accessibility/table-attributes.html
accessibility/table-cell-spans.html
accessibility/table-cells.html
@@ -48940,7 +69635,7 @@
* rendering/RenderBox.h:
* rendering/RenderImage.cpp:
(WebCore::RenderImage::calcReplacedWidth):
- (WebCore::RenderImage::calcPrefWidths):
+ (WebCore::RenderImage::calcPrefWidths):
* rendering/RenderImage.h:
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::calcPrefWidths):
@@ -49037,7 +69732,7 @@
2008-08-17 Geoffrey Garen <ggaren@apple.com>
Reviewed by Cameron Zwarich.
-
+
Updated project files to XCode 3.1.
* manual-tests/NPN_Invoke/NPN_Invoke.xcodeproj/project.pbxproj:
@@ -49047,10 +69742,10 @@
Reviewed by Cameron Zwarich.
Made room for a free word in JSCell.
-
+
Changed JSDOMWindowBase to store its auxiliary data in a subclass of
JSGlobalData, so the two could share a pointer.
-
+
Added a bunch of ASSERTs, to help catch over-sized objects.
2008-08-15 Mark Rowe <mrowe@apple.com>
@@ -49079,10 +69774,10 @@
Don't start preloading body resources before the head is complete. This prevents
body preloads from slowing down initial display when there is limited amount
of bandwidth available.
-
+
Works by queuing up found body preloads to DocLoader and only issuing them
after document has rendering.
-
+
With bandwidth capped to 300kbit/s this speeds up cnn.com initial display by ~25% or 5s
without affecting complete load time.
@@ -49117,7 +69812,7 @@
Some loader performance tweaks:
- Make stylesheets highest priority instead of scripts. We block script execution on stylesheets.
- Especially if a stylesheet @imports other stylesheets it is important to get them to the front of the queue
+ Especially if a stylesheet @imports other stylesheets it is important to get them to the front of the queue
to not delay rendering.
- Issue the first resource load for a host immediately even if the resource is low priority. TCP connection setup
can take long time when latency is high so it is good to get started early.
@@ -49410,7 +70105,7 @@
- fix <rdar://problem/5993323> REGRESSION (r34210): Apple.com favicon appears stretched/clipped
- * platform/graphics/BitmapImage.cpp:
+ * platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::BitmapImage): Added initialization of
m_hasUniformFrameSize.
(WebCore::BitmapImage::cacheFrame): Added code to get the size of the
@@ -49424,7 +70119,7 @@
* platform/graphics/ImageSource.h: Added frameSizeAtIndex().
* platform/graphics/cg/ImageCG.cpp:
(WebCore::BitmapImage::draw): Changed to use currentFrameSize(). This
- fixes the bug, which resulted from assuming that the frame being drawn
+ fixes the bug, which resulted from assuming that the frame being drawn
was the same size as the first frame.
* platform/graphics/cg/ImageSourceCG.cpp:
(WebCore::ImageSource::frameSizeAtIndex): Renamed size() to this and
@@ -49914,7 +70609,7 @@
Tests: media/video-source-type-params.html
* html/HTMLMediaElement.cpp:
- (WebCore::HTMLMediaElement::pickMedia): only pass the portion before the first ';'
+ (WebCore::HTMLMediaElement::pickMedia): only pass the portion before the first ';'
to isSupportedMediaMIMEType()
2008-08-13 Beth Dakin <bdakin@apple.com>
@@ -49923,21 +70618,21 @@
Fix for <rdar://problem/6141345>
- This patch refines findString and markAllMatchesForText functions'
- interactions with disconnected frames. They no longer rely on
- knowing where a range is relative to the visible region and work
+ This patch refines findString and markAllMatchesForText functions'
+ interactions with disconnected frames. They no longer rely on
+ knowing where a range is relative to the visible region and work
with disconnected frames that contain frames.
* editing/Editor.cpp:
- (WebCore::Editor::insideVisibleArea): Now returns a bool instead of
+ (WebCore::Editor::insideVisibleArea): Now returns a bool instead of
the visiblity enum.
- (WebCore::Editor::firstVisibleRange): This now returns the very
- first visible range in the document. It's no longer dependent on
+ (WebCore::Editor::firstVisibleRange): This now returns the very
+ first visible range in the document. It's no longer dependent on
searching forward.
- (WebCore::Editor::lastVisibleRange): This now returns the very last
- visible range in the document. It's no longer dependent on
+ (WebCore::Editor::lastVisibleRange): This now returns the very last
+ visible range in the document. It's no longer dependent on
searching backwards.
- (WebCore::Editor::nextVisibleRange): This returns the next visible
+ (WebCore::Editor::nextVisibleRange): This returns the next visible
range in the appropriate direction from the current range.
* editing/Editor.h:
* page/Frame.cpp:
@@ -50146,7 +70841,7 @@
2008-08-12 Nikolas Zimmermann <zimmermann@kde.org>
Reviewed by Dave.
-
+
Fixes: https://bugs.webkit.org/show_bug.cgi?id=19798
Masks are translated, and the mask images are swapped on the y-axis.
@@ -50387,7 +71082,7 @@
- Because console messages have group levels now, newly created messages
that do not specify the level lose their message since the number of
arguments is wrong.
-
+
* page/inspector/Console.js:
* page/inspector/Resource.js:
@@ -50476,7 +71171,7 @@
* html/HTMLElement.cpp:
* page/AnimationController.cpp:
do all the new event stuff
-
+
* html/HTMLAttributeNames.in:
the onwebkitanimation* and onwebkittransitionend attrs
diff --git a/WebCore/Configurations/Base.xcconfig b/WebCore/Configurations/Base.xcconfig
index 7dfebc5..d33943d 100644
--- a/WebCore/Configurations/Base.xcconfig
+++ b/WebCore/Configurations/Base.xcconfig
@@ -30,6 +30,11 @@ WARNING_CFLAGS_ppc64 = $(WARNING_CFLAGS_BASE);
WARNING_CFLAGS_x86_64 = $(WARNING_CFLAGS_BASE);
+REAL_PLATFORM_NAME = $(REAL_PLATFORM_NAME_$(PLATFORM_NAME));
+REAL_PLATFORM_NAME_ = $(REAL_PLATFORM_NAME_macosx);
+REAL_PLATFORM_NAME_macosx = macosx;
+
+
// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants.
// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant.
DEBUG_DEFINES_debug = DISABLE_THREAD_CHECK;
diff --git a/WebCore/Configurations/DebugRelease.xcconfig b/WebCore/Configurations/DebugRelease.xcconfig
index 72eadfb..ae4a229 100644
--- a/WebCore/Configurations/DebugRelease.xcconfig
+++ b/WebCore/Configurations/DebugRelease.xcconfig
@@ -1,5 +1,12 @@
#include "Base.xcconfig"
-ARCHS = $(NATIVE_ARCH);
+
+ARCHS = $(ARCHS_$(MAC_OS_X_VERSION_MAJOR));
+ARCHS_ = $(ARCHS_1040);
+ARCHS_1040 = $(NATIVE_ARCH);
+ARCHS_1050 = $(NATIVE_ARCH);
+ARCHS_1060 = $(ARCHS_STANDARD_32_64_BIT);
+
+ONLY_ACTIVE_ARCH = YES;
MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR));
MACOSX_DEPLOYMENT_TARGET_ = 10.4;
diff --git a/WebCore/Configurations/Version.xcconfig b/WebCore/Configurations/Version.xcconfig
index bf339bf..ab0aa9b 100644
--- a/WebCore/Configurations/Version.xcconfig
+++ b/WebCore/Configurations/Version.xcconfig
@@ -1,5 +1,5 @@
-MAJOR_VERSION = 528;
-MINOR_VERSION = 16;
+MAJOR_VERSION = 530;
+MINOR_VERSION = 5;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/WebCore/Configurations/WebCore.xcconfig b/WebCore/Configurations/WebCore.xcconfig
index 3d19f63..99b987d 100644
--- a/WebCore/Configurations/WebCore.xcconfig
+++ b/WebCore/Configurations/WebCore.xcconfig
@@ -11,11 +11,25 @@ FRAMEWORK_SEARCH_PATHS = $(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Frame
HEADER_SEARCH_PATHS = ForwardingHeaders icu /usr/include/libxslt /usr/include/libxml2 $(SQLITE3_HEADER_SEARCH_PATHS) "${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore" $(HEADER_SEARCH_PATHS);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks/WebKit.framework/Versions/A/Frameworks;
+INSTALLHDRS_COPY_PHASE = YES;
+INSTALLHDRS_SCRIPT_PHASE = YES;
PRODUCT_NAME = WebCore;
OTHER_LDFLAGS = -l$(SQLITE3_LIBRARY) -lobjc -sub_library libobjc -umbrella WebKit;
-// This needs to be kept sorted, and in sync with FEATURE_DEFINES in JavaScriptCore.xcconfig, WebKit.xcconfig and the default settings of build-webkit.
-FEATURE_DEFINES = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_WORKERS ENABLE_XPATH ENABLE_XSLT;
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR = $(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_$(REAL_PLATFORM_NAME)_$(CONFIGURATION));
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_macosx_Release = $(JAVASCRIPTCORE_PRIVATE_HEADERS_engineering);
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_macosx_Debug = $(JAVASCRIPTCORE_PRIVATE_HEADERS_engineering);
+JAVASCRIPTCORE_PRIVATE_HEADERS_DIR_macosx_Production = $(NEXT_ROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/JavaScriptCore.framework/PrivateHeaders;
+JAVASCRIPTCORE_PRIVATE_HEADERS_engineering = $(BUILT_PRODUCTS_DIR)/JavaScriptCore.framework/PrivateHeaders;
+
+// This needs to be kept sorted, and in sync with FEATURE_DEFINES in JavaScriptCore.xcconfig, WebKit.xcconfig and
+// the default settings of build-webkit to prevent needless rebuilding when using both Xcode and build-webkit.
+FEATURE_DEFINES = $(FEATURE_DEFINES_$(MAC_OS_X_VERSION_MAJOR));
+FEATURE_DEFINES_BASE = ENABLE_DATABASE ENABLE_DOM_STORAGE ENABLE_ICONDATABASE ENABLE_OFFLINE_WEB_APPLICATIONS ENABLE_SVG ENABLE_SVG_ANIMATION ENABLE_SVG_AS_IMAGE ENABLE_SVG_FONTS ENABLE_SVG_FOREIGN_OBJECT ENABLE_SVG_USE ENABLE_VIDEO ENABLE_WORKERS ENABLE_XPATH ENABLE_XSLT;
+FEATURE_DEFINES_ = $(FEATURE_DEFINES_1040);
+FEATURE_DEFINES_1040 = $(FEATURE_DEFINES_BASE);
+FEATURE_DEFINES_1050 = $(FEATURE_DEFINES_BASE);
+FEATURE_DEFINES_1060 = $(FEATURE_DEFINES_BASE) ENABLE_GEOLOCATION;
SQLITE3_LIBRARY = $(SQLITE3_LIBRARY_$(MAC_OS_X_VERSION_MAJOR));
SQLITE3_LIBRARY_ = WebCoreSQLite3;
diff --git a/WebCore/DerivedSources.cpp b/WebCore/DerivedSources.cpp
index 2324ebb..3b8eeb1 100644
--- a/WebCore/DerivedSources.cpp
+++ b/WebCore/DerivedSources.cpp
@@ -32,6 +32,8 @@
#include "JSCanvasRenderingContext2D.cpp"
#include "JSCDATASection.cpp"
#include "JSCharacterData.cpp"
+#include "JSClientRect.cpp"
+#include "JSClientRectList.cpp"
#include "JSClipboard.cpp"
#include "JSComment.cpp"
#include "JSConsole.cpp"
@@ -67,7 +69,6 @@
#include "JSEntityReference.cpp"
#include "JSEvent.cpp"
#include "JSEventException.cpp"
-#include "JSEventTargetNode.cpp"
#include "JSFile.cpp"
#include "JSFileList.cpp"
#include "JSHistory.cpp"
@@ -317,6 +318,7 @@
#include "JSWebKitCSSKeyframesRule.cpp"
#include "JSWebKitCSSTransformValue.cpp"
#include "JSWebKitCSSMatrix.cpp"
+#include "JSWebKitPoint.cpp"
#include "JSWebKitTransitionEvent.cpp"
#include "JSWheelEvent.cpp"
#include "JSWorker.cpp"
@@ -334,7 +336,6 @@
#include "JSXPathNSResolver.cpp"
#include "JSXPathResult.cpp"
#include "JSXSLTProcessor.cpp"
-#include "SVGElementFactory.cpp"
#include "UserAgentStyleSheetsData.cpp"
// On MSVC, including StaticConstructors.h causes all global objects not to be
diff --git a/WebCore/DerivedSources.make b/WebCore/DerivedSources.make
index bd77060..c26b459 100644
--- a/WebCore/DerivedSources.make
+++ b/WebCore/DerivedSources.make
@@ -39,6 +39,7 @@ VPATH = \
$(WebCore)/storage \
$(WebCore)/xml \
$(WebCore)/wml \
+ $(WebCore)/workers \
$(WebCore)/svg \
#
@@ -67,9 +68,12 @@ DOM_CLASSES = \
CanvasPattern \
CanvasRenderingContext2D \
CharacterData \
+ ClientRect \
+ ClientRectList \
Clipboard \
Comment \
Console \
+ Coordinates \
Counter \
DOMApplicationCache \
DOMCoreException \
@@ -90,7 +94,6 @@ DOM_CLASSES = \
EventException \
EventListener \
EventTarget \
- EventTargetNode \
File \
FileList \
Geolocation \
@@ -161,6 +164,7 @@ DOM_CLASSES = \
HTMLVideoElement \
History \
ImageData \
+ InspectorController \
KeyboardEvent \
Location \
MediaError \
@@ -357,6 +361,7 @@ DOM_CLASSES = \
WebKitCSSKeyframesRule \
WebKitCSSMatrix \
WebKitCSSTransformValue \
+ WebKitPoint \
WebKitTransitionEvent \
WheelEvent \
Worker \
@@ -379,7 +384,7 @@ DOM_CLASSES = \
.PHONY : all
all : \
- $(filter-out JSEventListener.h JSRGBColor.h,$(DOM_CLASSES:%=JS%.h)) \
+ $(filter-out JSEventListener.h JSEventTarget.h JSRGBColor.h,$(DOM_CLASSES:%=JS%.h)) \
\
JSDOMWindowBase.lut.h \
JSRGBColor.lut.h \
@@ -392,6 +397,7 @@ all : \
CSSValueKeywords.h \
ColorData.c \
DocTypeStrings.cpp \
+ HTMLElementFactory.cpp \
HTMLEntityNames.c \
HTMLNames.cpp \
WMLElementFactory.cpp \
@@ -550,16 +556,18 @@ endif
ifdef HTML_FLAGS
-HTMLNames.cpp : dom/make_names.pl html/HTMLTagNames.in html/HTMLAttributeNames.in
- perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --wrapperFactory --extraDefines "$(HTML_FLAGS)"
+HTMLElementFactory.cpp HTMLNames.cpp : dom/make_names.pl html/HTMLTagNames.in html/HTMLAttributeNames.in
+ perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --factory --wrapperFactory --extraDefines "$(HTML_FLAGS)"
else
-HTMLNames.cpp : dom/make_names.pl html/HTMLTagNames.in html/HTMLAttributeNames.in
- perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --wrapperFactory
+HTMLElementFactory.cpp HTMLNames.cpp : dom/make_names.pl html/HTMLTagNames.in html/HTMLAttributeNames.in
+ perl -I $(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --factory --wrapperFactory
endif
+JSHTMLElementWrapperFactory.cpp : HTMLNames.cpp
+
XMLNames.cpp : dom/make_names.pl xml/xmlattrs.in
perl -I $(WebCore)/bindings/scripts $< --attrs $(WebCore)/xml/xmlattrs.in
@@ -709,6 +717,10 @@ ifeq ($(findstring 10.4,$(MACOSX_DEPLOYMENT_TARGET)), 10.4)
WEBCORE_EXPORT_DEPENDENCIES := $(WEBCORE_EXPORT_DEPENDENCIES) WebCore.Tiger.exp
endif
+ifeq ($(findstring ENABLE_PLUGIN_PROXY_FOR_VIDEO,$(FEATURE_DEFINES)), ENABLE_PLUGIN_PROXY_FOR_VIDEO)
+ WEBCORE_EXPORT_DEPENDENCIES := $(WEBCORE_EXPORT_DEPENDENCIES) WebCore.VideoProxy.exp
+endif
+
WebCore.exp : WebCore.base.exp $(WEBCORE_EXPORT_DEPENDENCIES)
cat $^ > $@
diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js
index aa9c0ff..20db8ab 100644
--- a/WebCore/English.lproj/localizedStrings.js
+++ b/WebCore/English.lproj/localizedStrings.js
Binary files differ
diff --git a/WebCore/ForwardingHeaders/wtf/TypeTraits.h b/WebCore/ForwardingHeaders/wtf/TypeTraits.h
new file mode 100644
index 0000000..f82507e
--- /dev/null
+++ b/WebCore/ForwardingHeaders/wtf/TypeTraits.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/TypeTraits.h>
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 8bbeed8..2a25e6a 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -42,6 +42,7 @@ webcore_cppflags += \
-I$(srcdir)/WebCore/plugins \
-I$(srcdir)/WebCore/rendering \
-I$(srcdir)/WebCore/rendering/style \
+ -I$(srcdir)/WebCore/workers \
-I$(srcdir)/WebCore/xml \
-I$(top_builddir)/WebCore/bindings/js
@@ -64,6 +65,8 @@ webcore_built_sources += \
DerivedSources/CSSGrammar.h \
DerivedSources/CSSPropertyNames.h \
DerivedSources/CSSValueKeywords.h \
+ DerivedSources/HTMLElementFactory.cpp \
+ DerivedSources/HTMLElementFactory.h \
DerivedSources/HTMLEntityNames.c \
DerivedSources/HTMLNames.cpp \
DerivedSources/HTMLNames.h \
@@ -102,6 +105,8 @@ IDL_BINDINGS += \
WebCore/dom/Attr.idl \
WebCore/dom/CDATASection.idl \
WebCore/dom/CharacterData.idl \
+ WebCore/dom/ClientRect.idl \
+ WebCore/dom/ClientRectList.idl \
WebCore/dom/Clipboard.idl \
WebCore/dom/Comment.idl \
WebCore/dom/DOMCoreException.idl \
@@ -115,7 +120,6 @@ IDL_BINDINGS += \
WebCore/dom/EntityReference.idl \
WebCore/dom/Event.idl \
WebCore/dom/EventException.idl \
- WebCore/dom/EventTargetNode.idl \
WebCore/dom/KeyboardEvent.idl \
WebCore/dom/MessageChannel.idl \
WebCore/dom/MessageEvent.idl \
@@ -140,9 +144,6 @@ IDL_BINDINGS += \
WebCore/dom/WebKitAnimationEvent.idl \
WebCore/dom/WebKitTransitionEvent.idl \
WebCore/dom/WheelEvent.idl \
- WebCore/dom/Worker.idl \
- WebCore/dom/WorkerContext.idl \
- WebCore/dom/WorkerLocation.idl \
WebCore/html/CanvasGradient.idl \
WebCore/html/CanvasPattern.idl \
WebCore/html/CanvasRenderingContext2D.idl \
@@ -211,8 +212,10 @@ IDL_BINDINGS += \
WebCore/html/ImageData.idl \
WebCore/html/TextMetrics.idl \
WebCore/inspector/JavaScriptCallFrame.idl \
+ WebCore/inspector/InspectorController.idl \
WebCore/page/BarInfo.idl \
WebCore/page/Console.idl \
+ WebCore/page/Coordinates.idl \
WebCore/page/DOMSelection.idl \
WebCore/page/DOMWindow.idl \
WebCore/page/Geolocation.idl \
@@ -222,11 +225,15 @@ IDL_BINDINGS += \
WebCore/page/Navigator.idl \
WebCore/page/PositionError.idl \
WebCore/page/Screen.idl \
+ WebCore/page/WebKitPoint.idl \
WebCore/page/WorkerNavigator.idl \
WebCore/plugins/MimeType.idl \
WebCore/plugins/MimeTypeArray.idl \
WebCore/plugins/Plugin.idl \
WebCore/plugins/PluginArray.idl \
+ WebCore/workers/Worker.idl \
+ WebCore/workers/WorkerContext.idl \
+ WebCore/workers/WorkerLocation.idl \
WebCore/xml/DOMParser.idl \
WebCore/xml/XMLHttpRequest.idl \
WebCore/xml/XMLHttpRequestException.idl \
@@ -277,7 +284,6 @@ webcore_sources += \
WebCore/bindings/js/JSEventTarget.cpp \
WebCore/bindings/js/JSEventTarget.h \
WebCore/bindings/js/JSEventTargetBase.h \
- WebCore/bindings/js/JSEventTargetNodeCustom.cpp \
WebCore/bindings/js/JSGeolocationCustom.cpp \
WebCore/bindings/js/JSHTMLAllCollection.cpp \
WebCore/bindings/js/JSHTMLAllCollection.h \
@@ -308,7 +314,10 @@ webcore_sources += \
WebCore/bindings/js/JSInspectedObjectWrapper.h \
WebCore/bindings/js/JSInspectorCallbackWrapper.cpp \
WebCore/bindings/js/JSInspectorCallbackWrapper.h \
+ WebCore/bindings/js/JSInspectorControllerCustom.cpp \
WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp \
+ WebCore/bindings/js/JSLazyEventListener.cpp \
+ WebCore/bindings/js/JSLazyEventListener.h \
WebCore/bindings/js/JSLocationCustom.cpp \
WebCore/bindings/js/JSLocationCustom.h \
WebCore/bindings/js/JSMessageChannelConstructor.cpp \
@@ -343,6 +352,8 @@ webcore_sources += \
WebCore/bindings/js/JSTreeWalkerCustom.cpp \
WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp \
WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h \
+ WebCore/bindings/js/JSWebKitPointConstructor.cpp \
+ WebCore/bindings/js/JSWebKitPointConstructor.h \
WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp \
WebCore/bindings/js/JSXMLHttpRequestConstructor.h \
WebCore/bindings/js/JSXMLHttpRequestCustom.cpp \
@@ -360,13 +371,21 @@ webcore_sources += \
WebCore/bindings/js/ScriptCallStack.h \
WebCore/bindings/js/ScriptController.cpp \
WebCore/bindings/js/ScriptController.h \
+ WebCore/bindings/js/ScriptFunctionCall.cpp \
+ WebCore/bindings/js/ScriptFunctionCall.h \
WebCore/bindings/js/ScriptInstance.h \
+ WebCore/bindings/js/ScriptObject.cpp \
+ WebCore/bindings/js/ScriptObject.h \
+ WebCore/bindings/js/ScriptObjectQuarantine.cpp \
+ WebCore/bindings/js/ScriptObjectQuarantine.h \
WebCore/bindings/js/ScriptSourceCode.h \
WebCore/bindings/js/ScriptState.h \
WebCore/bindings/js/ScriptString.h \
WebCore/bindings/js/ScriptValue.cpp \
WebCore/bindings/js/ScriptValue.h \
WebCore/bindings/js/StringSourceProvider.h \
+ WebCore/bridge/IdentifierRep.cpp \
+ WebCore/bridge/IdentifierRep.h \
WebCore/bridge/NP_jsobject.cpp \
WebCore/bridge/NP_jsobject.h \
WebCore/bridge/c/c_class.cpp \
@@ -547,6 +566,10 @@ webcore_sources += \
WebCore/dom/ClassNames.h \
WebCore/dom/ClassNodeList.cpp \
WebCore/dom/ClassNodeList.h \
+ WebCore/dom/ClientRect.cpp \
+ WebCore/dom/ClientRect.h \
+ WebCore/dom/ClientRectList.cpp \
+ WebCore/dom/ClientRectList.h \
WebCore/dom/Clipboard.cpp \
WebCore/dom/Clipboard.h \
WebCore/dom/ClipboardAccessPolicy.h \
@@ -589,8 +612,6 @@ webcore_sources += \
WebCore/dom/EventNames.h \
WebCore/dom/EventTarget.cpp \
WebCore/dom/EventTarget.h \
- WebCore/dom/EventTargetNode.cpp \
- WebCore/dom/EventTargetNode.h \
WebCore/dom/ExceptionBase.cpp \
WebCore/dom/ExceptionBase.h \
WebCore/dom/ExceptionCode.cpp \
@@ -761,8 +782,6 @@ webcore_sources += \
WebCore/editing/RemoveNodePreservingChildrenCommand.h \
WebCore/editing/ReplaceSelectionCommand.cpp \
WebCore/editing/ReplaceSelectionCommand.h \
- WebCore/editing/Selection.cpp \
- WebCore/editing/Selection.h \
WebCore/editing/SelectionController.cpp \
WebCore/editing/SelectionController.h \
WebCore/editing/SetNodeAttributeCommand.cpp \
@@ -786,6 +805,8 @@ webcore_sources += \
WebCore/editing/UnlinkCommand.h \
WebCore/editing/VisiblePosition.cpp \
WebCore/editing/VisiblePosition.h \
+ WebCore/editing/VisibleSelection.cpp \
+ WebCore/editing/VisibleSelection.h \
WebCore/editing/WrapContentsInDummySpanCommand.cpp \
WebCore/editing/WrapContentsInDummySpanCommand.h \
WebCore/editing/htmlediting.cpp \
@@ -853,8 +874,6 @@ webcore_sources += \
WebCore/html/HTMLDocument.h \
WebCore/html/HTMLElement.cpp \
WebCore/html/HTMLElement.h \
- WebCore/html/HTMLElementFactory.cpp \
- WebCore/html/HTMLElementFactory.h \
WebCore/html/HTMLEmbedElement.cpp \
WebCore/html/HTMLEmbedElement.h \
WebCore/html/HTMLFieldSetElement.cpp \
@@ -1007,9 +1026,17 @@ webcore_sources += \
WebCore/icu/unicode/utf_old.h \
WebCore/icu/unicode/utypes.h \
WebCore/icu/unicode/uversion.h \
+ WebCore/inspector/ConsoleMessage.cpp \
+ WebCore/inspector/ConsoleMessage.h \
+ WebCore/inspector/InspectorDatabaseResource.cpp \
+ WebCore/inspector/InspectorDatabaseResource.h \
+ WebCore/inspector/InspectorDOMStorageResource.cpp \
+ WebCore/inspector/InspectorDOMStorageResource.h \
WebCore/inspector/InspectorClient.h \
WebCore/inspector/InspectorController.cpp \
WebCore/inspector/InspectorController.h \
+ WebCore/inspector/InspectorResource.cpp \
+ WebCore/inspector/InspectorResource.h \
WebCore/inspector/JavaScriptCallFrame.cpp \
WebCore/inspector/JavaScriptCallFrame.h \
WebCore/inspector/JavaScriptDebugListener.h \
@@ -1040,6 +1067,10 @@ webcore_sources += \
WebCore/loader/CachedXBLDocument.h \
WebCore/loader/CachedXSLStyleSheet.cpp \
WebCore/loader/CachedXSLStyleSheet.h \
+ WebCore/loader/CrossOriginAccessControl.cpp \
+ WebCore/loader/CrossOriginAccessControl.h \
+ WebCore/loader/CrossOriginPreflightResultCache.cpp \
+ WebCore/loader/CrossOriginPreflightResultCache.h \
WebCore/loader/DocLoader.cpp \
WebCore/loader/DocLoader.h \
WebCore/loader/DocumentLoader.cpp \
@@ -1055,7 +1086,6 @@ webcore_sources += \
WebCore/loader/FormState.h \
WebCore/loader/FrameLoader.cpp \
WebCore/loader/FrameLoader.h \
- WebCore/loader/FrameLoaderClient.cpp \
WebCore/loader/FrameLoaderClient.h \
WebCore/loader/FrameLoaderTypes.h \
WebCore/loader/ImageDocument.cpp \
@@ -1090,6 +1120,9 @@ webcore_sources += \
WebCore/loader/ThreadableLoader.cpp \
WebCore/loader/ThreadableLoader.h \
WebCore/loader/ThreadableLoaderClient.h \
+ WebCore/loader/ThreadableLoaderClientWrapper.h \
+ WebCore/loader/WorkerThreadableLoader.cpp \
+ WebCore/loader/WorkerThreadableLoader.h \
WebCore/loader/archive/Archive.h \
WebCore/loader/archive/ArchiveFactory.cpp \
WebCore/loader/archive/ArchiveFactory.h \
@@ -1136,6 +1169,8 @@ webcore_sources += \
WebCore/page/ContextMenuClient.h \
WebCore/page/ContextMenuController.cpp \
WebCore/page/ContextMenuController.h \
+ WebCore/page/Coordinates.h \
+ WebCore/page/Coordinates.cpp \
WebCore/page/DOMSelection.cpp \
WebCore/page/DOMSelection.h \
WebCore/page/DOMTimer.cpp \
@@ -1190,12 +1225,14 @@ webcore_sources += \
WebCore/page/SecurityOriginHash.h \
WebCore/page/Settings.cpp \
WebCore/page/Settings.h \
+ WebCore/page/WebKitPoint.h \
WebCore/page/WindowFeatures.cpp \
WebCore/page/WindowFeatures.h \
WebCore/page/animation/AnimationBase.cpp \
WebCore/page/animation/AnimationBase.h \
WebCore/page/animation/AnimationController.cpp \
WebCore/page/animation/AnimationController.h \
+ WebCore/page/animation/AnimationControllerPrivate.h \
WebCore/page/animation/CompositeAnimation.cpp \
WebCore/page/animation/CompositeAnimation.h \
WebCore/page/animation/ImplicitAnimation.cpp \
@@ -1205,10 +1242,14 @@ webcore_sources += \
WebCore/platform/Arena.cpp \
WebCore/platform/Arena.h \
WebCore/platform/AutodrainedPool.h \
+ WebCore/platform/ContentType.cpp \
+ WebCore/platform/ContentType.h \
WebCore/platform/ContextMenu.cpp \
WebCore/platform/ContextMenu.h \
WebCore/platform/ContextMenuItem.h \
WebCore/platform/CookieJar.h \
+ WebCore/platform/CrossThreadCopier.cpp \
+ WebCore/platform/CrossThreadCopier.h \
WebCore/platform/Cursor.h \
WebCore/platform/DeprecatedPtrList.h \
WebCore/platform/DeprecatedPtrListImpl.cpp \
@@ -1272,6 +1313,8 @@ webcore_sources += \
WebCore/platform/ThreadCheck.h \
WebCore/platform/ThreadGlobalData.cpp \
WebCore/platform/ThreadGlobalData.h \
+ WebCore/platform/ThreadTimers.cpp \
+ WebCore/platform/ThreadTimers.h \
WebCore/platform/Timer.cpp \
WebCore/platform/Timer.h \
WebCore/platform/TreeShared.h \
@@ -1366,6 +1409,10 @@ webcore_sources += \
WebCore/platform/graphics/transforms/IdentityTransformOperation.h \
WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp \
WebCore/platform/graphics/transforms/MatrixTransformOperation.h \
+ WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp \
+ WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h \
+ WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp \
+ WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h \
WebCore/platform/graphics/transforms/RotateTransformOperation.cpp \
WebCore/platform/graphics/transforms/RotateTransformOperation.h \
WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp \
@@ -1446,11 +1493,11 @@ webcore_sources += \
WebCore/platform/text/TextCodecUTF16.h \
WebCore/platform/text/TextCodecUserDefined.cpp \
WebCore/platform/text/TextCodecUserDefined.h \
- WebCore/platform/text/TextDecoder.cpp \
- WebCore/platform/text/TextDecoder.h \
WebCore/platform/text/TextDirection.h \
WebCore/platform/text/TextEncoding.cpp \
WebCore/platform/text/TextEncoding.h \
+ WebCore/platform/text/TextEncodingDetector.h \
+ WebCore/platform/text/TextEncodingDetectorNone.cpp \
WebCore/platform/text/TextEncodingRegistry.cpp \
WebCore/platform/text/TextEncodingRegistry.h \
WebCore/platform/text/TextStream.cpp \
@@ -1517,10 +1564,10 @@ webcore_sources += \
WebCore/rendering/RenderBlock.h \
WebCore/rendering/RenderBox.cpp \
WebCore/rendering/RenderBox.h \
+ WebCore/rendering/RenderBoxModelObject.cpp \
+ WebCore/rendering/RenderBoxModelObject.h \
WebCore/rendering/RenderButton.cpp \
WebCore/rendering/RenderButton.h \
- WebCore/rendering/RenderContainer.cpp \
- WebCore/rendering/RenderContainer.h \
WebCore/rendering/RenderCounter.cpp \
WebCore/rendering/RenderCounter.h \
WebCore/rendering/RenderFieldset.cpp \
@@ -1529,8 +1576,6 @@ webcore_sources += \
WebCore/rendering/RenderFileUploadControl.h \
WebCore/rendering/RenderFlexibleBox.cpp \
WebCore/rendering/RenderFlexibleBox.h \
- WebCore/rendering/RenderFlow.cpp \
- WebCore/rendering/RenderFlow.h \
WebCore/rendering/RenderFrame.cpp \
WebCore/rendering/RenderFrame.h \
WebCore/rendering/RenderFrameSet.cpp \
@@ -1545,8 +1590,9 @@ webcore_sources += \
WebCore/rendering/RenderInline.h \
WebCore/rendering/RenderLayer.cpp \
WebCore/rendering/RenderLayer.h \
- WebCore/rendering/RenderLegend.cpp \
- WebCore/rendering/RenderLegend.h \
+ WebCore/rendering/RenderLayerBacking.h \
+ WebCore/rendering/RenderLineBoxList.cpp \
+ WebCore/rendering/RenderLineBoxList.h \
WebCore/rendering/RenderListBox.cpp \
WebCore/rendering/RenderListBox.h \
WebCore/rendering/RenderListItem.cpp \
@@ -1559,6 +1605,8 @@ webcore_sources += \
WebCore/rendering/RenderMenuList.h \
WebCore/rendering/RenderObject.cpp \
WebCore/rendering/RenderObject.h \
+ WebCore/rendering/RenderObjectChildList.cpp \
+ WebCore/rendering/RenderObjectChildList.h \
WebCore/rendering/RenderPart.cpp \
WebCore/rendering/RenderPart.h \
WebCore/rendering/RenderPartObject.cpp \
@@ -1573,6 +1621,7 @@ webcore_sources += \
WebCore/rendering/RenderScrollbarPart.h \
WebCore/rendering/RenderScrollbarTheme.cpp \
WebCore/rendering/RenderScrollbarTheme.h \
+ WebCore/rendering/RenderSelectionInfo.h \
WebCore/rendering/RenderSlider.cpp \
WebCore/rendering/RenderSlider.h \
WebCore/rendering/RenderTable.cpp \
@@ -1607,9 +1656,13 @@ webcore_sources += \
WebCore/rendering/RenderWordBreak.h \
WebCore/rendering/RootInlineBox.cpp \
WebCore/rendering/RootInlineBox.h \
+ WebCore/rendering/ScrollBehavior.cpp \
+ WebCore/rendering/ScrollBehavior.h \
WebCore/rendering/TableLayout.h \
WebCore/rendering/TextControlInnerElements.cpp \
WebCore/rendering/TextControlInnerElements.h \
+ WebCore/rendering/TransformState.cpp \
+ WebCore/rendering/TransformState.h \
WebCore/rendering/bidi.cpp \
WebCore/rendering/bidi.h \
WebCore/rendering/break_lines.cpp \
@@ -1779,31 +1832,6 @@ webcoregtk_sources += \
WebCore/platform/image-decoders/xbm/XBMImageDecoder.h \
WebCore/platform/text/gtk/TextBreakIteratorInternalICUGtk.cpp
-# ----
-# curl http backend
-# ----
-if USE_CURL
-
-webcore_cppflags += \
- -DWTF_USE_CURL=1 \
- -I$(srcdir)/WebCore/platform/network/curl
-
-webcore_sources += \
- WebCore/platform/network/curl/AuthenticationChallenge.h \
- WebCore/platform/network/curl/CookieJarCurl.cpp \
- WebCore/platform/network/curl/DNSCurl.cpp \
- WebCore/platform/network/curl/FormDataStreamCurl.cpp \
- WebCore/platform/network/curl/FormDataStreamCurl.h \
- WebCore/platform/network/curl/ResourceError.h \
- WebCore/platform/network/curl/ResourceHandleCurl.cpp \
- WebCore/platform/network/curl/ResourceHandleManager.cpp \
- WebCore/platform/network/curl/ResourceHandleManager.h \
- WebCore/platform/network/curl/ResourceRequest.h \
- WebCore/platform/network/curl/ResourceResponse.h
-
-endif # END USE_CURL
-
-if USE_SOUP
webcore_cppflags += \
-DWTF_USE_SOUP=1 \
-I$(srcdir)/WebCore/platform/network/soup
@@ -1817,6 +1845,10 @@ webcore_sources += \
WebCore/platform/network/soup/ResourceHandleSoup.cpp \
WebCore/platform/network/soup/ResourceRequest.h \
WebCore/platform/network/soup/ResourceResponse.h
+
+if USE_GNOMEKEYRING
+webcore_cppflags += \
+ -DWTF_USE_GNOMEKEYRING=1
endif
# ---
@@ -2056,6 +2088,7 @@ webcore_sources += \
WebCore/html/TimeRanges.cpp \
WebCore/html/TimeRanges.h \
WebCore/platform/graphics/MediaPlayer.cpp \
+ WebCore/platform/graphics/MediaPlayerPrivate.h \
WebCore/rendering/MediaControlElements.cpp \
WebCore/rendering/RenderMedia.cpp \
WebCore/rendering/RenderMedia.h \
@@ -2182,23 +2215,25 @@ webcore_sources += \
WebCore/bindings/js/JSWorkerCustom.cpp \
WebCore/bindings/js/WorkerScriptController.cpp \
WebCore/bindings/js/WorkerScriptController.h \
- WebCore/dom/GenericWorkerTask.h \
- WebCore/dom/Worker.cpp \
- WebCore/dom/Worker.h \
- WebCore/dom/WorkerContext.cpp \
- WebCore/dom/WorkerContext.h \
- WebCore/dom/WorkerLocation.cpp \
- WebCore/dom/WorkerLocation.h \
- WebCore/dom/WorkerMessagingProxy.cpp \
- WebCore/dom/WorkerMessagingProxy.h \
- WebCore/dom/WorkerRunLoop.cpp \
- WebCore/dom/WorkerRunLoop.h \
- WebCore/dom/WorkerTask.cpp \
- WebCore/dom/WorkerTask.h \
- WebCore/dom/WorkerThread.cpp \
- WebCore/dom/WorkerThread.h \
WebCore/page/WorkerNavigator.cpp \
- WebCore/page/WorkerNavigator.h
+ WebCore/page/WorkerNavigator.h \
+ WebCore/workers/GenericWorkerTask.h \
+ WebCore/workers/Worker.cpp \
+ WebCore/workers/Worker.h \
+ WebCore/workers/WorkerContext.cpp \
+ WebCore/workers/WorkerContext.h \
+ WebCore/workers/WorkerContextProxy.h \
+ WebCore/workers/WorkerLocation.cpp \
+ WebCore/workers/WorkerLocation.h \
+ WebCore/workers/WorkerMessagingProxy.cpp \
+ WebCore/workers/WorkerMessagingProxy.h \
+ WebCore/workers/WorkerObjectProxy.h \
+ WebCore/workers/WorkerRunLoop.cpp \
+ WebCore/workers/WorkerRunLoop.h \
+ WebCore/workers/WorkerThread.cpp \
+ WebCore/workers/WorkerThread.h \
+ WebCore/workers/WorkerImportScriptsClient.cpp \
+ WebCore/workers/WorkerImportScriptsClient.h
endif
# ----
@@ -2859,8 +2894,7 @@ webcore_sources += \
WebCore/svg/graphics/filters/SVGSpotLightSource.h
webcoregtk_sources += \
- WebCore/svg/graphics/cairo/SVGResourceFilterCairo.cpp \
- WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp
+ WebCore/svg/graphics/cairo/SVGResourceFilterCairo.cpp
# SVG Features
@@ -2995,16 +3029,18 @@ WebCore/%.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/WebCore/%.cpp
$(PERL) $^ -n WebCore > $@
# HTML tag and attribute names
+DerivedSources/HTMLElementFactory.cpp: DerivedSources/HTMLNames.cpp;
+DerivedSources/HTMLElementFactory.h: DerivedSources/HTMLElementFactory.cpp;
DerivedSources/HTMLNames.h: DerivedSources/HTMLNames.cpp;
DerivedSources/JSHTMLElementWrapperFactory.cpp: DerivedSources/HTMLNames.cpp;
DerivedSources/JSHTMLElementWrapperFactory.h: DerivedSources/JSHTMLElementWrapperFactory.cpp;
if HTML_FLAGS
DerivedSources/HTMLNames.cpp: $(WebCore)/dom/make_names.pl $(WebCore)/html/HTMLTagNames.in $(WebCore)/html/HTMLAttributeNames.in
- $(PERL) -I$(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --extraDefines "$(HTML_FEATURES)" --wrapperFactory --outputDir "$(GENSOURCES)"
+ $(PERL) -I$(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --extraDefines "$(HTML_FEATURES)" --factory --wrapperFactory --outputDir "$(GENSOURCES)"
else
DerivedSources/HTMLNames.cpp: $(WebCore)/dom/make_names.pl $(WebCore)/html/HTMLTagNames.in $(WebCore)/html/HTMLAttributeNames.in
- $(PERL) -I$(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --wrapperFactory --outputDir "$(GENSOURCES)"
+ $(PERL) -I$(WebCore)/bindings/scripts $< --tags $(WebCore)/html/HTMLTagNames.in --attrs $(WebCore)/html/HTMLAttributeNames.in --factory --wrapperFactory --outputDir "$(GENSOURCES)"
endif # HTML_FLAGS
DerivedSources/XMLNames.h: DerivedSources/XMLNames.cpp;
@@ -3023,7 +3059,8 @@ IDL_PATH := \
$(WebCore)/storage \
$(WebCore)/svg \
$(WebCore)/xml \
- $(WebCore)/plugins
+ $(WebCore)/plugins \
+ $(WebCore)/workers
vpath %.idl = $(IDL_PATH)
@@ -3076,6 +3113,7 @@ noinst_HEADERS += \
$(IDL_BINDINGS)
webcore_dist += \
+ WebCore/ChangeLog \
WebCore/LICENSE-APPLE \
WebCore/LICENSE-LGPL-2 \
WebCore/LICENSE-LGPL-2.1 \
diff --git a/WebCore/WebCore.LP64.exp b/WebCore/WebCore.LP64.exp
index e393153..cc04718 100644
--- a/WebCore/WebCore.LP64.exp
+++ b/WebCore/WebCore.LP64.exp
@@ -5,6 +5,11 @@ __ZN3JSC8Bindings10RootObjectD1Ev
__ZN3JSC8Bindings8Instance19createRuntimeObjectEPNS_9ExecStateE
__ZN3JSC8Bindings8InstanceC2EN3WTF10PassRefPtrINS0_10RootObjectEEE
__ZN3JSC8Bindings8InstanceD2Ev
+__ZN7WebCore13IdentifierRep3getEi
+__ZN7WebCore13IdentifierRep3getEPKc
+__ZN7WebCore13IdentifierRep7isValidEPS0_
__ZN7WebCore16ScriptController16createRootObjectEPv
+__ZN7WebCore16ScriptController24jsObjectForPluginElementEPNS_17HTMLPlugInElementE
__ZN7WebCore16ScriptController9isEnabledEv
+__ZN7WebCore6String26fromUTF8WithLatin1FallbackEPKcm
__ZN7WebCore6String8fromUTF8EPKcm
diff --git a/WebCore/WebCore.NPAPI.exp b/WebCore/WebCore.NPAPI.exp
index 28dd051..9eb8056 100644
--- a/WebCore/WebCore.NPAPI.exp
+++ b/WebCore/WebCore.NPAPI.exp
@@ -21,3 +21,5 @@ __NPN_SetProperty
__NPN_UTF8FromIdentifier
__ZN7WebCore16ScriptController20windowScriptNPObjectEv
__ZN7WebCore16ScriptController29cleanupScriptObjectsForPluginEPv
+__ZNK7WebCore9FrameView22windowClipRectForLayerEPKNS_11RenderLayerEb
+__ZNK7WebCore12RenderObject4viewEv
diff --git a/WebCore/WebCore.VideoProxy.exp b/WebCore/WebCore.VideoProxy.exp
new file mode 100644
index 0000000..cead63f
--- /dev/null
+++ b/WebCore/WebCore.VideoProxy.exp
@@ -0,0 +1,4 @@
+__ZN7WebCore9HTMLNames8videoTagE
+__ZN7WebCore9HTMLNames8audioTagE
+__ZN7WebCore16HTMLMediaElement19deliverNotificationE32MediaPlayerProxyNotificationType
+__ZN7WebCore16HTMLMediaElement19setMediaPlayerProxyEP19WebMediaPlayerProxy
diff --git a/WebCore/WebCore.base.exp b/WebCore/WebCore.base.exp
index f47858d..f642858 100644
--- a/WebCore/WebCore.base.exp
+++ b/WebCore/WebCore.base.exp
@@ -124,7 +124,7 @@ _WebCoreSetShouldUseFontSmoothing
_WebCoreShouldUseFontSmoothing
_WebCoreTextFloatWidth
__Z26ReportBlockedObjCExceptionP11NSException
-__ZN7WebCore10MouseEventC1ERKNS_12AtomicStringEbbN3WTF10PassRefPtrINS_9DOMWindowEEEiiiiibbbbtNS5_INS_15EventTargetNodeEEENS5_INS_9ClipboardEEEb
+__ZN7WebCore10MouseEventC1ERKNS_12AtomicStringEbbN3WTF10PassRefPtrINS_9DOMWindowEEEiiiiibbbbtNS5_INS_11EventTargetEEENS5_INS_9ClipboardEEEb
__ZN7WebCore10ScrollView17setScrollbarModesENS_13ScrollbarModeES1_
__ZN7WebCore10ScrollView20setCanHaveScrollbarsEb
__ZN7WebCore10StringImpl11reverseFindEPS0_ib
@@ -132,6 +132,8 @@ __ZN7WebCore10StringImpl7replaceEtt
__ZN7WebCore10StringImpl8endsWithEPS0_b
__ZN7WebCore10StringImplD1Ev
__ZN7WebCore10StringImplcvP8NSStringEv
+__ZN7WebCore10StringImpldlEPv
+__ZN7WebCore10handCursorEv
__ZN7WebCore11CachedFrame23cachedFramePlatformDataEv
__ZN7WebCore11CachedFrame26setCachedFramePlatformDataEPNS_23CachedFramePlatformDataE
__ZN7WebCore11ContextMenu22setPlatformDescriptionEP14NSMutableArray
@@ -158,7 +160,6 @@ __ZN7WebCore11FrameLoader20continueLoadWithDataEPNS_12SharedBufferERKNS_6StringE
__ZN7WebCore11FrameLoader21loadURLIntoChildFrameERKNS_4KURLERKNS_6StringEPNS_5FrameE
__ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
__ZN7WebCore11FrameLoader22findFrameForNavigationERKNS_12AtomicStringE
-__ZN7WebCore11FrameLoader22setPreviousHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
__ZN7WebCore11FrameLoader23timeOfLastCompletedLoadEv
__ZN7WebCore11FrameLoader24registerURLSchemeAsLocalERKNS_6StringE
__ZN7WebCore11FrameLoader25setProvisionalHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
@@ -172,6 +173,7 @@ __ZN7WebCore11FrameLoader4loadERKNS_15ResourceRequestEb
__ZN7WebCore11FrameLoader6reloadEb
__ZN7WebCore11FrameLoader7addDataEPKci
__ZN7WebCore11FrameLoader7canLoadERKNS_4KURLERKNS_6StringEPKNS_8DocumentE
+__ZN7WebCore11Geolocation12setIsAllowedEb
__ZN7WebCore11HistoryItem11setReferrerERKNS_6StringE
__ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
__ZN7WebCore11HistoryItem12setURLStringERKNS_6StringE
@@ -202,9 +204,7 @@ __ZN7WebCore11HistoryItemC1Ev
__ZN7WebCore11HistoryItemD1Ev
__ZN7WebCore11IconFetcher6cancelEv
__ZN7WebCore11IconFetcher6createEPNS_5FrameEPNS_17IconFetcherClientE
-__ZN7WebCore11RenderLayer18gAlignCenterAlwaysE
-__ZN7WebCore11RenderLayer19scrollRectToVisibleERKNS_7IntRectEbRKNS0_15ScrollAlignmentES6_
-__ZN7WebCore11RenderLayer20gAlignToEdgeIfNeededE
+__ZN7WebCore11RenderLayer19scrollRectToVisibleERKNS_7IntRectEbRKNS_15ScrollAlignmentES6_
__ZN7WebCore11globalPointERK8_NSPointP8NSWindow
__ZN7WebCore11toUserSpaceERK7_NSRectP8NSWindow
__ZN7WebCore12AtomicString3addEPKc
@@ -216,10 +216,11 @@ __ZN7WebCore12EventHandler10wheelEventEP7NSEvent
__ZN7WebCore12EventHandler12mouseDraggedEP7NSEvent
__ZN7WebCore12EventHandler14currentNSEventEv
__ZN7WebCore12EventHandler14scrollOverflowENS_15ScrollDirectionENS_17ScrollGranularityE
+__ZN7WebCore12EventHandler15sendScrollEventEv
__ZN7WebCore12EventHandler17dragSourceEndedAtERKNS_18PlatformMouseEventENS_13DragOperationE
__ZN7WebCore12EventHandler17dragSourceMovedToERKNS_18PlatformMouseEventE
__ZN7WebCore12EventHandler20handleTextInputEventERKNS_6StringEPNS_5EventEbb
-__ZN7WebCore12EventHandler20hitTestResultAtPointERKNS_8IntPointEb
+__ZN7WebCore12EventHandler20hitTestResultAtPointERKNS_8IntPointEbb
__ZN7WebCore12EventHandler20sendContextMenuEventERKNS_18PlatformMouseEventE
__ZN7WebCore12EventHandler27capsLockStateMayHaveChangedEv
__ZN7WebCore12EventHandler28pendingFrameUnloadEventCountEv
@@ -267,8 +268,8 @@ __ZN7WebCore12createMarkupEPKNS_4NodeENS_13EChildrenOnlyEPN3WTF6VectorIPS0_Lm0EE
__ZN7WebCore12createMarkupEPKNS_5RangeEPN3WTF6VectorIPNS_4NodeELm0EEENS_23EAnnotateForInterchangeEb
__ZN7WebCore12gcControllerEv
__ZN7WebCore12iconDatabaseEv
+__ZN7WebCore13AXObjectCache11getOrCreateEPNS_12RenderObjectE
__ZN7WebCore13AXObjectCache21gAccessibilityEnabledE
-__ZN7WebCore13AXObjectCache3getEPNS_12RenderObjectE
__ZN7WebCore13AXObjectCache42gAccessibilityEnhancedUserInterfaceEnabledE
__ZN7WebCore13HitTestResultC1ERKS0_
__ZN7WebCore13HitTestResultD1Ev
@@ -344,6 +345,8 @@ __ZN7WebCore15FocusController9setActiveEb
__ZN7WebCore15GraphicsContextC1EP9CGContext
__ZN7WebCore15GraphicsContextD1Ev
__ZN7WebCore15JSDOMWindowBase18commonJSGlobalDataEv
+__ZN7WebCore15ScrollAlignment17alignCenterAlwaysE
+__ZN7WebCore15ScrollAlignment19alignToEdgeIfNeededE
__ZN7WebCore15StringTruncator13rightTruncateERKNS_6StringEfRKNS_4FontEb
__ZN7WebCore15StringTruncator14centerTruncateERKNS_6StringEfRKNS_4FontEb
__ZN7WebCore15StringTruncator5widthERKNS_6StringERKNS_4FontEb
@@ -358,7 +361,6 @@ __ZN7WebCore16LegacyWebArchive6createEPNS_12SharedBufferE
__ZN7WebCore16LegacyWebArchive6createEPNS_4NodeE
__ZN7WebCore16LegacyWebArchive6createEPNS_5FrameE
__ZN7WebCore16LegacyWebArchive6createEPNS_5RangeE
-__ZN7WebCore16LegacyWebArchive6createERKNS_6StringEPNS_5FrameERN3WTF6VectorIPNS_4NodeELm0EEE
__ZN7WebCore16LegacyWebArchive6createEv
__ZN7WebCore16MIMETypeRegistry24isSupportedImageMIMETypeERKNS_6StringE
__ZN7WebCore16MIMETypeRegistry26getSupportedImageMIMETypesEv
@@ -369,6 +371,8 @@ __ZN7WebCore16NavigationActionC1ERKNS_4KURLENS_14NavigationTypeE
__ZN7WebCore16NavigationActionC1Ev
__ZN7WebCore16ScriptController10initScriptEv
__ZN7WebCore16ScriptController18windowScriptObjectEv
+__ZN7WebCore16VisibleSelectionC1EPKNS_5RangeENS_9EAffinityE
+__ZN7WebCore16VisibleSelectionC1ERKNS_15VisiblePositionES3_
__ZN7WebCore16colorFromNSColorEP7NSColor
__ZN7WebCore16createFullMarkupEPKNS_4NodeE
__ZN7WebCore16createFullMarkupEPKNS_5RangeE
@@ -376,7 +380,6 @@ __ZN7WebCore16enclosingIntRectERK7_NSRect
__ZN7WebCore16isEndOfParagraphERKNS_15VisiblePositionE
__ZN7WebCore16threadGlobalDataEv
__ZN7WebCore17DOMImplementation14isTextMIMETypeERKNS_6StringE
-__ZN7WebCore17FrameLoaderClientD2Ev
__ZN7WebCore17GlyphPageTreeNode18treeGlyphPageCountEv
__ZN7WebCore17equalIgnoringCaseEPNS_10StringImplES1_
__ZN7WebCore18PlatformMouseEventC1EP7NSEvent
@@ -398,7 +401,7 @@ __ZN7WebCore19InspectorController5closeEv
__ZN7WebCore19InspectorController7inspectEPNS_4NodeE
__ZN7WebCore19InspectorController9showPanelENS0_13SpecialPanelsE
__ZN7WebCore19SelectionController10setFocusedEb
-__ZN7WebCore19SelectionController12setSelectionERKNS_9SelectionEbbb
+__ZN7WebCore19SelectionController12setSelectionERKNS_16VisibleSelectionEbbb
__ZN7WebCore19SelectionController16setSelectedRangeEPNS_5RangeENS_9EAffinityEb
__ZN7WebCore19SelectionController5clearEv
__ZN7WebCore19SelectionController6modifyENS0_11EAlterationENS0_10EDirectionENS_15TextGranularityEb
@@ -406,7 +409,7 @@ __ZN7WebCore19SelectionController9selectAllEv
__ZN7WebCore19SelectionControllerC1EPNS_5FrameEb
__ZN7WebCore19TextResourceDecoder5flushEv
__ZN7WebCore19TextResourceDecoder6decodeEPKcm
-__ZN7WebCore19TextResourceDecoderC1ERKNS_6StringERKNS_12TextEncodingE
+__ZN7WebCore19TextResourceDecoderC1ERKNS_6StringERKNS_12TextEncodingEb
__ZN7WebCore19TextResourceDecoderD1Ev
__ZN7WebCore20ResourceResponseBase24setExpectedContentLengthEx
__ZN7WebCore21ContextMenuController16clearContextMenuEv
@@ -417,7 +420,7 @@ __ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
__ZN7WebCore21WindowsLatin1EncodingEv
__ZN7WebCore21findEventWithKeyStateEPNS_5EventE
__ZN7WebCore21isBackForwardLoadTypeENS_13FrameLoadTypeE
-__ZN7WebCore21reportThreadViolationEPKc
+__ZN7WebCore21reportThreadViolationEPKcNS_20ThreadViolationRoundE
__ZN7WebCore22createFragmentFromTextEPNS_5RangeERKNS_6StringE
__ZN7WebCore22externalRepresentationEPNS_12RenderObjectE
__ZN7WebCore23ApplicationCacheStorage16storeCopyOfCacheERKNS_6StringEPNS_16ApplicationCacheE
@@ -438,8 +441,10 @@ __ZN7WebCore26NetscapePlugInStreamLoader6createEPNS_5FrameEPNS_32NetscapePlugInS
__ZN7WebCore26usesTestModeFocusRingColorEv
__ZN7WebCore29isCharacterSmartReplaceExemptEib
__ZN7WebCore29setUsesTestModeFocusRingColorEb
+__ZN7WebCore31CrossOriginPreflightResultCache5emptyEv
+__ZN7WebCore31CrossOriginPreflightResultCache6sharedEv
__ZN7WebCore32plainTextToMallocAllocatedBufferEPKNS_5RangeERjb
-__ZN7WebCore33setDefaultThreadViolationBehaviorENS_23ThreadViolationBehaviorE
+__ZN7WebCore33setDefaultThreadViolationBehaviorENS_23ThreadViolationBehaviorENS_20ThreadViolationRoundE
__ZN7WebCore36InitializeLoggingChannelsIfNecessaryEv
__ZN7WebCore3macERKNS_23AuthenticationChallengeE
__ZN7WebCore4FontC1ERKNS_16FontPlatformDataEb
@@ -455,7 +460,9 @@ __ZN7WebCore4Page12setGroupNameERKNS_6StringE
__ZN7WebCore4Page14setMediaVolumeEf
__ZN7WebCore4Page15addSchedulePairEN3WTF10PassRefPtrINS_12SchedulePairEEE
__ZN7WebCore4Page15backForwardListEv
+__ZN7WebCore4Page15didMoveOnscreenEv
__ZN7WebCore4Page16setDefersLoadingEb
+__ZN7WebCore4Page17willMoveOffscreenEv
__ZN7WebCore4Page18removeSchedulePairEN3WTF10PassRefPtrINS_12SchedulePairEEE
__ZN7WebCore4Page23clearUndoRedoOperationsEv
__ZN7WebCore4Page23pendingUnloadEventCountEv
@@ -473,13 +480,11 @@ __ZN7WebCore5Cache11setDisabledEb
__ZN7WebCore5Cache13getStatisticsEv
__ZN7WebCore5Cache13setCapacitiesEjjj
__ZN7WebCore5Frame10findStringERKNS_6StringEbbbb
-__ZN7WebCore5Frame11forceLayoutEb
__ZN7WebCore5Frame11shouldCloseEv
__ZN7WebCore5Frame13reapplyStylesEv
__ZN7WebCore5Frame13setZoomFactorEfb
__ZN7WebCore5Frame14frameForWidgetEPKNS_6WidgetE
-__ZN7WebCore5Frame15sendScrollEventEv
-__ZN7WebCore5Frame16adjustPageHeightEPffff
+__ZN7WebCore5Frame15revealSelectionERKNS_15ScrollAlignmentEb
__ZN7WebCore5Frame17setIsDisconnectedEb
__ZN7WebCore5Frame19setInViewSourceModeEb
__ZN7WebCore5Frame20setSelectionFromNoneEv
@@ -489,7 +494,6 @@ __ZN7WebCore5Frame24computeAndSetTypingStyleEPNS_19CSSStyleDeclarationENS_10Edit
__ZN7WebCore5Frame24setExcludeFromTextSearchEb
__ZN7WebCore5Frame25matchLabelsAgainstElementEP7NSArrayPNS_7ElementE
__ZN7WebCore5Frame28searchForLabelsBeforeElementEP7NSArrayPNS_7ElementE
-__ZN7WebCore5Frame29forceLayoutWithPageWidthRangeEffb
__ZN7WebCore5Frame34setMarkedTextMatchesAreHighlightedEb
__ZN7WebCore5Frame4initEv
__ZN7WebCore5Frame6scriptEv
@@ -573,7 +577,6 @@ __ZN7WebCore8Document22createDocumentFragmentEv
__ZN7WebCore8Document23renderedRectsForMarkersENS_14DocumentMarker10MarkerTypeE
__ZN7WebCore8Document24setShouldCreateRenderersEb
__ZN7WebCore8Document36updateLayoutIgnorePendingStylesheetsEv
-__ZN7WebCore8Document4bodyEv
__ZN7WebCore8Document4headEv
__ZN7WebCore8DragDataC1EP11objc_objectRKNS_8IntPointES5_NS_13DragOperationEPNS_16PasteboardHelperE
__ZN7WebCore8FormDataD1Ev
@@ -592,15 +595,19 @@ __ZN7WebCore8Settings20setCursiveFontFamilyERKNS_12AtomicStringE
__ZN7WebCore8Settings20setFantasyFontFamilyERKNS_12AtomicStringE
__ZN7WebCore8Settings20setJavaScriptEnabledEb
__ZN7WebCore8Settings21setStandardFontFamilyERKNS_12AtomicStringE
+__ZN7WebCore8Settings21setWebSecurityEnabledEb
__ZN7WebCore8Settings22setLocalStorageEnabledEb
__ZN7WebCore8Settings22setSansSerifFontFamilyERKNS_12AtomicStringE
__ZN7WebCore8Settings22setShowsURLsInToolTipsEb
__ZN7WebCore8Settings23setDefaultFixedFontSizeEi
__ZN7WebCore8Settings23setEditableLinkBehaviorENS_20EditableLinkBehaviorE
+__ZN7WebCore8Settings23setNeedsTigerMailQuirksEb
+__ZN7WebCore8Settings23setUsesEncodingDetectorEb
__ZN7WebCore8Settings24setApplicationChromeModeEb
__ZN7WebCore8Settings24setTextAreasAreResizableEb
__ZN7WebCore8Settings25setDeveloperExtrasEnabledEb
__ZN7WebCore8Settings25setMinimumLogicalFontSizeEi
+__ZN7WebCore8Settings25setNeedsLeopardMailQuirksEb
__ZN7WebCore8Settings25setPrivateBrowsingEnabledEb
__ZN7WebCore8Settings25setShouldPrintBackgroundsEb
__ZN7WebCore8Settings25setUserStyleSheetLocationERKNS_4KURLE
@@ -615,8 +622,7 @@ __ZN7WebCore8Settings29setWebArchiveDebugModeEnabledEb
__ZN7WebCore8Settings31setShrinksStandaloneImagesToFitEb
__ZN7WebCore8Settings32setNeedsAdobeFrameReloadingQuirkEb
__ZN7WebCore8Settings33setEnforceCSSMIMETypeInStrictModeEb
-__ZN7WebCore8Settings34setNeedsIChatMemoryCacheCallsQuirkEb
-__ZN7WebCore8Settings35disableRangeMutationForOldAppleMailEb
+__ZN7WebCore8Settings35setAllowUniversalAccessFromFileURLsEb
__ZN7WebCore8Settings36setOfflineWebApplicationCacheEnabledEb
__ZN7WebCore8Settings40setJavaScriptCanOpenWindowsAutomaticallyEb
__ZN7WebCore8Settings40setTextDirectionSubmenuInclusionBehaviorENS_37TextDirectionSubmenuInclusionBehaviorE
@@ -630,15 +636,18 @@ __ZN7WebCore9FontCache21purgeInactiveFontDataEi
__ZN7WebCore9FrameTree11appendChildEN3WTF10PassRefPtrINS_5FrameEEE
__ZN7WebCore9FrameTree7setNameERKNS_12AtomicStringE
__ZN7WebCore9FrameTree9clearNameEv
+__ZN7WebCore9FrameView11forceLayoutEb
__ZN7WebCore9FrameView12setMediaTypeERKNS_6StringE
__ZN7WebCore9FrameView14adjustViewSizeEv
__ZN7WebCore9FrameView14initScrollbarsEv
__ZN7WebCore9FrameView14setMarginWidthEi
__ZN7WebCore9FrameView14setTransparentEb
__ZN7WebCore9FrameView15setMarginHeightEi
+__ZN7WebCore9FrameView16adjustPageHeightEPffff
__ZN7WebCore9FrameView18updateControlTintsEv
__ZN7WebCore9FrameView22setBaseBackgroundColorENS_5ColorE
__ZN7WebCore9FrameView23layoutIfNeededRecursiveEv
+__ZN7WebCore9FrameView29forceLayoutWithPageWidthRangeEffb
__ZN7WebCore9FrameView29setShouldUpdateWhileOffscreenEb
__ZN7WebCore9FrameViewC1EPNS_5FrameE
__ZN7WebCore9FrameViewC1EPNS_5FrameERKNS_7IntSizeE
@@ -680,9 +689,6 @@ __ZN7WebCore9PageGroup14addVisitedLinkEPKtm
__ZN7WebCore9PageGroup17closeLocalStorageEv
__ZN7WebCore9PageGroup21removeAllVisitedLinksEv
__ZN7WebCore9PageGroup26setShouldTrackVisitedLinksEb
-__ZN7WebCore9Selection22expandUsingGranularityENS_15TextGranularityE
-__ZN7WebCore9SelectionC1EPKNS_5RangeENS_9EAffinityE
-__ZN7WebCore9SelectionC1ERKNS_15VisiblePositionES3_
__ZN7WebCore9TimerBase4stopEv
__ZN7WebCore9TimerBase5startEdd
__ZN7WebCore9TimerBaseC2Ev
@@ -705,7 +711,6 @@ __ZNK7WebCore10ScrollView18visibleContentRectEb
__ZNK7WebCore11CachedImage5imageEv
__ZNK7WebCore11ContextMenu19platformDescriptionEv
__ZNK7WebCore11FrameLoader10isCompleteEv
-__ZNK7WebCore11FrameLoader14documentLoaderEv
__ZNK7WebCore11FrameLoader14frameHasLoadedEv
__ZNK7WebCore11FrameLoader15containsPluginsEv
__ZNK7WebCore11FrameLoader15firstLayoutDoneEv
@@ -713,7 +718,6 @@ __ZNK7WebCore11FrameLoader16outgoingReferrerEv
__ZNK7WebCore11FrameLoader16responseMIMETypeEv
__ZNK7WebCore11FrameLoader20activeDocumentLoaderEv
__ZNK7WebCore11FrameLoader21isQuickRedirectComingEv
-__ZNK7WebCore11FrameLoader25provisionalDocumentLoaderEv
__ZNK7WebCore11FrameLoader27numPendingOrLoadingRequestsEb
__ZNK7WebCore11FrameLoader8loadTypeEv
__ZNK7WebCore11HistoryItem10visitCountEv
@@ -741,6 +745,7 @@ __ZNK7WebCore12IconDatabase12databasePathEv
__ZNK7WebCore12IconDatabase24shouldStopThreadActivityEv
__ZNK7WebCore12IconDatabase9isEnabledEv
__ZNK7WebCore12RenderObject14enclosingLayerEv
+__ZNK7WebCore12RenderObject15localToAbsoluteENS_10FloatPointEbb
__ZNK7WebCore12SharedBuffer4dataEv
__ZNK7WebCore12SharedBuffer4sizeEv
__ZNK7WebCore12TextEncoding6decodeEPKcmbRb
@@ -790,6 +795,10 @@ __ZNK7WebCore15VisiblePosition4nextEb
__ZNK7WebCore15VisiblePosition8previousEb
__ZNK7WebCore16HTMLInputElement12autoCompleteEv
__ZNK7WebCore16ResourceResponse13nsURLResponseEv
+__ZNK7WebCore16VisibleSelection17isContentEditableEv
+__ZNK7WebCore16VisibleSelection17toNormalizedRangeEv
+__ZNK7WebCore16VisibleSelection19rootEditableElementEv
+__ZNK7WebCore16VisibleSelection23isContentRichlyEditableEv
__ZNK7WebCore17ResourceErrorBase8lazyInitEv
__ZNK7WebCore19AnimationController24numberOfActiveAnimationsEv
__ZNK7WebCore19InspectorController17drawNodeHighlightERNS_15GraphicsContextE
@@ -818,7 +827,6 @@ __ZNK7WebCore4Node9nodeIndexEv
__ZNK7WebCore4Page10pluginDataEv
__ZNK7WebCore4Page34inLowQualityImageInterpolationModeEv
__ZNK7WebCore4Page9groupNameEv
-__ZNK7WebCore5Frame10isFrameSetEv
__ZNK7WebCore5Frame11currentFormEv
__ZNK7WebCore5Frame11typingStyleEv
__ZNK7WebCore5Frame12eventHandlerEv
@@ -827,7 +835,6 @@ __ZNK7WebCore5Frame12selectedTextEv
__ZNK7WebCore5Frame13ownerRendererEv
__ZNK7WebCore5Frame14selectionImageEb
__ZNK7WebCore5Frame15contentRendererEv
-__ZNK7WebCore5Frame15revealSelectionERKNS_11RenderLayer15ScrollAlignmentE
__ZNK7WebCore5Frame15selectionBoundsEb
__ZNK7WebCore5Frame16inViewSourceModeEv
__ZNK7WebCore5Frame17firstRectForRangeEPNS_5RangeE
@@ -886,6 +893,8 @@ __ZNK7WebCore7IntRectcv7_NSRectEv
__ZNK7WebCore8Document11completeURLERKNS_6StringE
__ZNK7WebCore8Document13axObjectCacheEv
__ZNK7WebCore8Document20cacheDocumentElementEv
+__ZNK7WebCore8Document31displayStringModifiedByEncodingERKNS_6StringE
+__ZNK7WebCore8Document4bodyEv
__ZNK7WebCore8Document6domainEv
__ZNK7WebCore8IntPointcv8_NSPointEv
__ZNK7WebCore8Position10downstreamEv
@@ -901,10 +910,6 @@ __ZNK7WebCore9FrameTree4findERKNS_12AtomicStringE
__ZNK7WebCore9FrameTree5childERKNS_12AtomicStringE
__ZNK7WebCore9FrameTree6parentEb
__ZNK7WebCore9FrameView11needsLayoutEv
-__ZNK7WebCore9Selection17isContentEditableEv
-__ZNK7WebCore9Selection19rootEditableElementEv
-__ZNK7WebCore9Selection23isContentRichlyEditableEv
-__ZNK7WebCore9Selection7toRangeEv
__ZNK7WebCore9TimerBase8isActiveEv
__ZTVN7WebCore12ChromeClientE
__ZTVN7WebCore17FileChooserClientE
diff --git a/WebCore/WebCore.order b/WebCore/WebCore.order
index 19797f0..164e74d 100644
--- a/WebCore/WebCore.order
+++ b/WebCore/WebCore.order
@@ -509,7 +509,6 @@ __ZNK7WebCore11FrameLoader5stateEv
__ZNK7WebCore11FrameLoader17subframeIsLoadingEv
__ZN7WebCore11FrameLoader16markLoadCompleteEv
__ZN7WebCore11FrameLoader18frameLoadCompletedEv
-__ZN7WebCore11FrameLoader22setPreviousHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE
__ZN7WebCore14DocumentLoader22stopRecordingResponsesEv
__ZN7WebCore11FrameLoader5beginERKNS_4KURLEbPNS_14SecurityOriginE
__ZN7WebCore11FrameLoader5clearEbb
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index a20f1b1..e992828 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -13,6 +13,8 @@ CONFIG(QTDIR_build) {
include($$QT_SOURCE_TREE/src/qbase.pri)
PRECOMPILED_HEADER = $$PWD/../WebKit/qt/WebKit_pch.h
DEFINES *= NDEBUG
+} else {
+ win32-*:!static: DEFINES += QT_MAKEDLL
}
isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
@@ -108,14 +110,18 @@ CONFIG(QTDIR_build) {
!contains(DEFINES, ENABLE_SVG_USE=.): DEFINES += ENABLE_SVG_USE=1
# HTML5 media support
-contains(QT_CONFIG, phonon):DEFINES += ENABLE_VIDEO=1
-else:DEFINES += ENABLE_VIDEO=0
+!contains(DEFINES, ENABLE_VIDEO=.) {
+ contains(QT_CONFIG, phonon):DEFINES += ENABLE_VIDEO=1
+ else:DEFINES += ENABLE_VIDEO=0
+}
# Nescape plugins support (NPAPI)
-unix|win32-*:!embedded:!wince*:!symbian {
- DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
-} else {
- DEFINES += ENABLE_NETSCAPE_PLUGIN_API=0
+!contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=.) {
+ unix|win32-*:!embedded:!wince*:!symbian {
+ DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
+ } else {
+ DEFINES += ENABLE_NETSCAPE_PLUGIN_API=0
+ }
}
DEFINES += WTF_USE_JAVASCRIPTCORE_BINDINGS=1 WTF_CHANGES=1
@@ -183,6 +189,7 @@ INCLUDEPATH += $$PWD \
$$PWD/xml \
$$PWD/html \
$$PWD/wml \
+ $$PWD/workers \
$$PWD/bindings/js \
$$PWD/svg \
$$PWD/platform/image-decoders \
@@ -263,6 +270,8 @@ IDL_BINDINGS += \
css/WebKitCSSTransformValue.idl \
dom/Attr.idl \
dom/CharacterData.idl \
+ dom/ClientRect.idl \
+ dom/ClientRectList.idl \
dom/Clipboard.idl \
dom/CDATASection.idl \
dom/Comment.idl \
@@ -279,7 +288,6 @@ IDL_BINDINGS += \
dom/EventException.idl \
# dom/EventListener.idl \
# dom/EventTarget.idl \
- dom/EventTargetNode.idl \
dom/KeyboardEvent.idl \
dom/MouseEvent.idl \
dom/MessageChannel.idl \
@@ -304,9 +312,6 @@ IDL_BINDINGS += \
dom/WebKitAnimationEvent.idl \
dom/WebKitTransitionEvent.idl \
dom/WheelEvent.idl \
- dom/Worker.idl \
- dom/WorkerContext.idl \
- dom/WorkerLocation.idl \
html/CanvasGradient.idl \
html/CanvasPattern.idl \
html/CanvasRenderingContext2D.idl \
@@ -375,8 +380,10 @@ IDL_BINDINGS += \
html/ImageData.idl \
html/TextMetrics.idl \
inspector/JavaScriptCallFrame.idl \
+ inspector/InspectorController.idl \
page/BarInfo.idl \
page/Console.idl \
+ page/Coordinates.idl \
page/DOMSelection.idl \
page/DOMWindow.idl \
page/Geolocation.idl \
@@ -386,11 +393,15 @@ IDL_BINDINGS += \
page/Navigator.idl \
page/PositionError.idl \
page/Screen.idl \
+ page/WebKitPoint.idl \
page/WorkerNavigator.idl \
plugins/Plugin.idl \
plugins/MimeType.idl \
plugins/PluginArray.idl \
plugins/MimeTypeArray.idl \
+ workers/Worker.idl \
+ workers/WorkerContext.idl \
+ workers/WorkerLocation.idl \
xml/DOMParser.idl \
xml/XMLHttpRequest.idl \
xml/XMLHttpRequestException.idl \
@@ -424,7 +435,6 @@ SOURCES += \
bindings/js/JSElementCustom.cpp \
bindings/js/JSEventCustom.cpp \
bindings/js/JSEventTarget.cpp \
- bindings/js/JSEventTargetNodeCustom.cpp \
bindings/js/JSGeolocationCustom.cpp \
bindings/js/JSHTMLAllCollection.cpp \
bindings/js/JSHistoryCustom.cpp \
@@ -446,6 +456,7 @@ SOURCES += \
bindings/js/JSImageDataCustom.cpp \
bindings/js/JSInspectedObjectWrapper.cpp \
bindings/js/JSInspectorCallbackWrapper.cpp \
+ bindings/js/JSInspectorControllerCustom.cpp \
bindings/js/JSLocationCustom.cpp \
bindings/js/JSNamedNodeMapCustom.cpp \
bindings/js/JSNamedNodesCollection.cpp \
@@ -463,6 +474,7 @@ SOURCES += \
bindings/js/JSTextCustom.cpp \
bindings/js/JSTreeWalkerCustom.cpp \
bindings/js/JSWebKitCSSMatrixConstructor.cpp \
+ bindings/js/JSWebKitPointConstructor.cpp \
bindings/js/JSXMLHttpRequestConstructor.cpp \
bindings/js/JSXMLHttpRequestCustom.cpp \
bindings/js/JSXMLHttpRequestUploadCustom.cpp \
@@ -476,13 +488,18 @@ SOURCES += \
bindings/js/JSMimeTypeArrayCustom.cpp \
bindings/js/JSDOMBinding.cpp \
bindings/js/JSEventListener.cpp \
+ bindings/js/JSLazyEventListener.cpp \
bindings/js/JSPluginElementFunctions.cpp \
bindings/js/ScriptCachedFrameData.cpp \
bindings/js/ScriptCallFrame.cpp \
bindings/js/ScriptCallStack.cpp \
bindings/js/ScriptController.cpp \
+ bindings/js/ScriptFunctionCall.cpp \
+ bindings/js/ScriptObject.cpp \
+ bindings/js/ScriptObjectQuarantine.cpp \
bindings/js/ScriptValue.cpp \
bindings/js/ScheduledAction.cpp \
+ bridge/IdentifierRep.cpp \
bridge/NP_jsobject.cpp \
bridge/npruntime.cpp \
bridge/runtime_array.cpp \
@@ -562,6 +579,8 @@ SOURCES += \
dom/ChildNodeList.cpp \
dom/ClassNames.cpp \
dom/ClassNodeList.cpp \
+ dom/ClientRect.cpp \
+ dom/ClientRectList.cpp \
dom/Clipboard.cpp \
dom/ClipboardEvent.cpp \
dom/Comment.cpp \
@@ -580,7 +599,6 @@ SOURCES += \
dom/Event.cpp \
dom/EventNames.cpp \
dom/EventTarget.cpp \
- dom/EventTargetNode.cpp \
dom/ExceptionBase.cpp \
dom/ExceptionCode.cpp \
dom/FormControlElementWithState.cpp \
@@ -664,7 +682,6 @@ SOURCES += \
editing/RemoveNodePreservingChildrenCommand.cpp \
editing/ReplaceSelectionCommand.cpp \
editing/SelectionController.cpp \
- editing/Selection.cpp \
editing/SetNodeAttributeCommand.cpp \
editing/SmartReplace.cpp \
editing/SmartReplaceICU.cpp \
@@ -675,6 +692,7 @@ SOURCES += \
editing/TypingCommand.cpp \
editing/UnlinkCommand.cpp \
editing/VisiblePosition.cpp \
+ editing/VisibleSelection.cpp \
editing/visible_units.cpp \
editing/WrapContentsInDummySpanCommand.cpp \
history/BackForwardList.cpp \
@@ -706,7 +724,6 @@ SOURCES += \
html/HTMLDListElement.cpp \
html/HTMLDocument.cpp \
html/HTMLElement.cpp \
- html/HTMLElementFactory.cpp \
html/HTMLEmbedElement.cpp \
html/HTMLFieldSetElement.cpp \
html/HTMLFontElement.cpp \
@@ -768,7 +785,11 @@ SOURCES += \
html/HTMLViewSourceDocument.cpp \
html/ImageData.cpp \
html/PreloadScanner.cpp \
+ inspector/ConsoleMessage.cpp \
+ inspector/InspectorDatabaseResource.cpp \
+ inspector/InspectorDOMStorageResource.cpp \
inspector/InspectorController.cpp \
+ inspector/InspectorResource.cpp \
inspector/JavaScriptCallFrame.cpp \
inspector/JavaScriptDebugServer.cpp \
inspector/JavaScriptProfile.cpp \
@@ -786,12 +807,13 @@ SOURCES += \
loader/CachedResource.cpp \
loader/CachedScript.cpp \
loader/CachedXSLStyleSheet.cpp \
+ loader/CrossOriginAccessControl.cpp \
+ loader/CrossOriginPreflightResultCache.cpp \
loader/DocLoader.cpp \
loader/DocumentLoader.cpp \
loader/DocumentThreadableLoader.cpp \
loader/FormState.cpp \
loader/FrameLoader.cpp \
- loader/FrameLoaderClient.cpp \
loader/FTPDirectoryDocument.cpp \
loader/FTPDirectoryParser.cpp \
loader/icon/IconLoader.cpp \
@@ -810,6 +832,7 @@ SOURCES += \
loader/TextDocument.cpp \
loader/TextResourceDecoder.cpp \
loader/ThreadableLoader.cpp \
+ loader/WorkerThreadableLoader.cpp \
page/AccessibilityImageMapLink.cpp \
page/AccessibilityObject.cpp \
page/AccessibilityList.cpp \
@@ -831,6 +854,7 @@ SOURCES += \
page/Chrome.cpp \
page/Console.cpp \
page/ContextMenuController.cpp \
+ page/Coordinates.cpp \
page/DOMSelection.cpp \
page/DOMTimer.cpp \
page/DOMWindow.cpp \
@@ -866,7 +890,9 @@ SOURCES += \
platform/text/AtomicString.cpp \
platform/text/Base64.cpp \
platform/text/BidiContext.cpp \
+ platform/ContentType.cpp \
platform/ContextMenu.cpp \
+ platform/CrossThreadCopier.cpp \
platform/text/CString.cpp \
platform/DeprecatedPtrListImpl.cpp \
platform/DragData.cpp \
@@ -898,6 +924,8 @@ SOURCES += \
platform/graphics/SimpleFontData.cpp \
platform/graphics/transforms/TransformationMatrix.cpp \
platform/graphics/transforms/MatrixTransformOperation.cpp \
+ platform/graphics/transforms/Matrix3DTransformOperation.cpp \
+ platform/graphics/transforms/PerspectiveTransformOperation.cpp \
platform/graphics/transforms/RotateTransformOperation.cpp \
platform/graphics/transforms/ScaleTransformOperation.cpp \
platform/graphics/transforms/SkewTransformOperation.cpp \
@@ -934,11 +962,12 @@ SOURCES += \
platform/text/TextCodecLatin1.cpp \
platform/text/TextCodecUserDefined.cpp \
platform/text/TextCodecUTF16.cpp \
- platform/text/TextDecoder.cpp \
platform/text/TextEncoding.cpp \
+ platform/text/TextEncodingDetectorNone.cpp \
platform/text/TextEncodingRegistry.cpp \
platform/text/TextStream.cpp \
platform/ThreadGlobalData.cpp \
+ platform/ThreadTimers.cpp \
platform/Timer.cpp \
platform/text/UnicodeRange.cpp \
platform/Widget.cpp \
@@ -963,14 +992,13 @@ SOURCES += \
rendering/RenderArena.cpp \
rendering/RenderBlock.cpp \
rendering/RenderBox.cpp \
+ rendering/RenderBoxModelObject.cpp \
rendering/RenderBR.cpp \
rendering/RenderButton.cpp \
- rendering/RenderContainer.cpp \
rendering/RenderCounter.cpp \
rendering/RenderFieldset.cpp \
rendering/RenderFileUploadControl.cpp \
rendering/RenderFlexibleBox.cpp \
- rendering/RenderFlow.cpp \
rendering/RenderFrame.cpp \
rendering/RenderFrameSet.cpp \
rendering/RenderHTMLCanvas.cpp \
@@ -978,13 +1006,14 @@ SOURCES += \
rendering/RenderImageGeneratedContent.cpp \
rendering/RenderInline.cpp \
rendering/RenderLayer.cpp \
- rendering/RenderLegend.cpp \
+ rendering/RenderLineBoxList.cpp \
rendering/RenderListBox.cpp \
rendering/RenderListItem.cpp \
rendering/RenderListMarker.cpp \
rendering/RenderMarquee.cpp \
rendering/RenderMenuList.cpp \
rendering/RenderObject.cpp \
+ rendering/RenderObjectChildList.cpp \
rendering/RenderPart.cpp \
rendering/RenderPartObject.cpp \
rendering/RenderReplaced.cpp \
@@ -993,15 +1022,15 @@ SOURCES += \
rendering/RenderScrollbarPart.cpp \
rendering/RenderScrollbarTheme.cpp \
rendering/RenderSlider.cpp \
+ rendering/RenderTable.cpp \
rendering/RenderTableCell.cpp \
rendering/RenderTableCol.cpp \
- rendering/RenderTable.cpp \
rendering/RenderTableRow.cpp \
rendering/RenderTableSection.cpp \
+ rendering/RenderText.cpp \
rendering/RenderTextControl.cpp \
rendering/RenderTextControlMultiLine.cpp \
rendering/RenderTextControlSingleLine.cpp \
- rendering/RenderText.cpp \
rendering/RenderTextFragment.cpp \
rendering/RenderTheme.cpp \
rendering/RenderTreeAsText.cpp \
@@ -1010,7 +1039,9 @@ SOURCES += \
rendering/RenderWordBreak.cpp \
rendering/RootInlineBox.cpp \
rendering/SVGRenderTreeAsText.cpp \
+ rendering/ScrollBehavior.cpp \
rendering/TextControlInnerElements.cpp \
+ rendering/TransformState.cpp \
rendering/style/BindingURI.cpp \
rendering/style/ContentData.cpp \
rendering/style/CounterDirectives.cpp \
@@ -1167,6 +1198,8 @@ SOURCES += \
../WebKit/qt/Api/qwebdatabase.cpp
+ win32-*|wince*: SOURCES += platform/win/SystemTimeWin.cpp
+
mac {
SOURCES += \
platform/text/cf/StringCF.cpp \
@@ -1811,8 +1844,7 @@ contains(DEFINES, ENABLE_SVG=1) {
rendering/SVGRootInlineBox.cpp
SOURCES += \
- svg/graphics/qt/SVGResourceFilterQt.cpp \
- svg/graphics/qt/SVGResourceMaskerQt.cpp
+ svg/graphics/qt/SVGResourceFilterQt.cpp
# GENERATOR 5-C:
@@ -1881,7 +1913,7 @@ SOURCES += \
# GENERATOR 6-B:
cssvalues.output = $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.c
cssvalues.input = WALDOCSSVALUES
- cssvalues.commands = $(COPY_FILE) ${QMAKE_FILE_NAME} $$GENERATED_SOURCES_DIR && cd $$GENERATED_SOURCES_DIR && perl $$PWD/css/makevalues.pl && $(DEL_FILE) ${QMAKE_FILE_BASE}.in ${QMAKE_FILE_BASE}.strip ${QMAKE_FILE_BASE}.gperf
+ cssvalues.commands = perl -ne \"print lc\" ${QMAKE_FILE_NAME} > $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.in && cd $$GENERATED_SOURCES_DIR && perl $$PWD/css/makevalues.pl && $(DEL_FILE) ${QMAKE_FILE_BASE}.in ${QMAKE_FILE_BASE}.strip ${QMAKE_FILE_BASE}.gperf
cssvalues.CONFIG = target_predeps no_link
cssvalues.clean = ${QMAKE_FILE_OUT} ${QMAKE_VAR_GENERATED_SOURCES_DIR_SLASH}${QMAKE_FILE_BASE}.h
addExtraCompiler(cssvalues)
@@ -1939,13 +1971,22 @@ addExtraCompilerWithHeader(cssbison)
# GENERATOR 5-A:
htmlnames.output = $$GENERATED_SOURCES_DIR/HTMLNames.cpp
-htmlnames.commands = perl -I$$PWD/bindings/scripts $$PWD/dom/make_names.pl --tags $$PWD/html/HTMLTagNames.in --attrs $$PWD/html/HTMLAttributeNames.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --wrapperFactory --outputDir $$GENERATED_SOURCES_DIR
+htmlnames.commands = perl -I$$PWD/bindings/scripts $$PWD/dom/make_names.pl --tags $$PWD/html/HTMLTagNames.in --attrs $$PWD/html/HTMLAttributeNames.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory --wrapperFactory --outputDir $$GENERATED_SOURCES_DIR
htmlnames.input = HTML_NAMES
htmlnames.dependency_type = TYPE_C
htmlnames.CONFIG = target_predeps
htmlnames.variable_out = GENERATED_SOURCES
addExtraCompilerWithHeader(htmlnames)
+htmlelementfactory.output = $$GENERATED_SOURCES_DIR/HTMLElementFactory.cpp
+htmlelementfactory.commands = @echo -n ''
+htmlelementfactory.input = HTML_NAMES
+htmlelementfactory.depends = $$GENERATED_SOURCES_DIR/HTMLNames.cpp
+htmlelementfactory.CONFIG = target_predeps
+htmlelementfactory.variable_out = GENERATED_SOURCES
+htmlelementfactory.clean += ${QMAKE_FILE_OUT}
+addExtraCompilerWithHeader(htmlelementfactory)
+
elementwrapperfactory.output = $$GENERATED_SOURCES_DIR/JSHTMLElementWrapperFactory.cpp
elementwrapperfactory.commands = @echo -n ''
elementwrapperfactory.input = HTML_NAMES
diff --git a/WebCore/WebCore.scons b/WebCore/WebCore.scons
index 28617a5..914cd57 100644
--- a/WebCore/WebCore.scons
+++ b/WebCore/WebCore.scons
@@ -92,7 +92,6 @@ sources['dom'] = [
'dom/Event.cpp',
'dom/EventNames.cpp',
'dom/EventTarget.cpp',
- 'dom/EventTargetNode.cpp',
'dom/ExceptionBase.cpp',
'dom/ExceptionCode.cpp',
'dom/FormControlElementWithState.cpp',
@@ -141,9 +140,6 @@ sources['dom'] = [
'dom/WebKitAnimationEvent.cpp',
'dom/WebKitTransitionEvent.cpp',
'dom/WheelEvent.cpp',
- 'dom/Worker.cpp',
- 'dom/WorkerContext.cpp',
- 'dom/WorkerLocation.cpp',
'dom/XMLTokenizer.cpp',
'dom/XMLTokenizerLibxml2.cpp',
]
@@ -180,7 +176,6 @@ sources['editing'] = [
'editing/RemoveNodeCommand.cpp',
'editing/RemoveNodePreservingChildrenCommand.cpp',
'editing/ReplaceSelectionCommand.cpp',
- 'editing/Selection.cpp',
'editing/SelectionController.cpp',
'editing/SetNodeAttributeCommand.cpp',
'editing/SmartReplace.cpp',
@@ -194,6 +189,7 @@ sources['editing'] = [
'editing/UnlinkCommand.cpp',
'editing/visible_units.cpp',
'editing/VisiblePosition.cpp',
+ 'editing/VisibleSelection.cpp',
'editing/WrapContentsInDummySpanCommand.cpp',
]
sources['history'] = [
@@ -228,7 +224,6 @@ sources['html'] = [
'html/HTMLDListElement.cpp',
'html/HTMLDocument.cpp',
'html/HTMLElement.cpp',
- 'html/HTMLElementFactory.cpp',
'html/HTMLEmbedElement.cpp',
'html/HTMLFieldSetElement.cpp',
'html/HTMLFontElement.cpp',
@@ -296,7 +291,11 @@ sources['html'] = [
'html/TimeRanges.cpp'
]
sources['inspector'] = [
+ 'inspector/ConsoleMessage.cpp',
+ 'inspector/InspectorDatabaseResource.cpp',
+ 'inspector/InspectorDOMStorageResource.cpp',
'inspector/InspectorController.cpp',
+ 'inspector/InspectorResource.cpp',
'inspector/JavaScriptCallFrame.cpp',
'inspector/JavaScriptDebugServer.cpp',
'inspector/JavaScriptProfile.cpp',
@@ -334,6 +333,8 @@ sources['loader'] = [
'loader/CachedScript.cpp',
'loader/CachedXBLDocument.cpp',
'loader/CachedXSLStyleSheet.cpp',
+ 'loader/CrossOriginAccessControl.cpp',
+ 'loader/CrossOriginPreflightResultCache.cpp',
'loader/DocLoader.cpp',
'loader/DocumentLoader.cpp',
'loader/DocumentThreadableLoader.cpp',
@@ -357,6 +358,7 @@ sources['loader'] = [
'loader/TextResourceDecoder.cpp',
'loader/ThreadableLoader.cpp',
'loader/UserStyleSheetLoader.cpp',
+ 'loader/WorkerThreadableLoader.cpp',
]
sources['page'] = [
'page/AccessibilityImageMapLink.cpp',
@@ -375,6 +377,7 @@ sources['page'] = [
'page/Chrome.cpp',
'page/Console.cpp',
'page/ContextMenuController.cpp',
+ 'page/Coordinates.cpp',
'page/DOMSelection.cpp',
'page/DOMTimer.cpp',
'page/DOMWindow.cpp',
@@ -428,8 +431,6 @@ sources['plugins'] = [
]
sources['rendering'] = [
'rendering/AutoTableLayout.cpp',
- 'rendering/bidi.cpp',
- 'rendering/break_lines.cpp',
'rendering/CounterNode.cpp',
'rendering/EllipsisBox.cpp',
'rendering/FixedTableLayout.cpp',
@@ -443,9 +444,9 @@ sources['rendering'] = [
'rendering/PointerEventsHitRules.cpp',
'rendering/RenderApplet.cpp',
'rendering/RenderArena.cpp',
+ 'rendering/RenderBR.cpp',
'rendering/RenderBlock.cpp',
'rendering/RenderBox.cpp',
- 'rendering/RenderBR.cpp',
'rendering/RenderButton.cpp',
'rendering/RenderContainer.cpp',
'rendering/RenderCounter.cpp',
@@ -474,10 +475,6 @@ sources['rendering'] = [
'rendering/RenderPath.cpp',
'rendering/RenderReplaced.cpp',
'rendering/RenderReplica.cpp',
- 'rendering/RenderScrollbar.cpp',
- 'rendering/RenderScrollbarPart.cpp',
- 'rendering/RenderScrollbarTheme.cpp',
- 'rendering/RenderSlider.cpp',
'rendering/RenderSVGBlock.cpp',
'rendering/RenderSVGContainer.cpp',
'rendering/RenderSVGGradientStop.cpp',
@@ -486,11 +483,15 @@ sources['rendering'] = [
'rendering/RenderSVGInline.cpp',
'rendering/RenderSVGInlineText.cpp',
'rendering/RenderSVGRoot.cpp',
+ 'rendering/RenderSVGTSpan.cpp',
'rendering/RenderSVGText.cpp',
'rendering/RenderSVGTextPath.cpp',
'rendering/RenderSVGTransformableContainer.cpp',
- 'rendering/RenderSVGTSpan.cpp',
'rendering/RenderSVGViewportContainer.cpp',
+ 'rendering/RenderScrollbar.cpp',
+ 'rendering/RenderScrollbarPart.cpp',
+ 'rendering/RenderScrollbarTheme.cpp',
+ 'rendering/RenderSlider.cpp',
'rendering/RenderTable.cpp',
'rendering/RenderTableCell.cpp',
'rendering/RenderTableCol.cpp',
@@ -514,23 +515,21 @@ sources['rendering'] = [
'rendering/SVGRenderSupport.cpp',
'rendering/SVGRenderTreeAsText.cpp',
'rendering/SVGRootInlineBox.cpp',
- 'rendering/TextControlInnerElements.cpp'
+ 'rendering/ScrollBehavior.cpp',
+ 'rendering/TextControlInnerElements.cpp',
+ 'rendering/TransformState.cpp',
+ 'rendering/bidi.cpp',
+ 'rendering/break_lines.cpp',
]
sources['rendering/style'] = [
- 'rendering/style/Animation.cpp',
- 'rendering/style/AnimationList.cpp',
'rendering/style/BindingURI.cpp',
'rendering/style/ContentData.cpp',
'rendering/style/CounterDirectives.cpp',
'rendering/style/FillLayer.cpp',
'rendering/style/KeyframeList.cpp',
- 'rendering/style/MatrixTransformOperation.cpp',
'rendering/style/NinePieceImage.cpp',
'rendering/style/RenderStyle.cpp',
- 'rendering/style/RotateTransformOperation.cpp',
- 'rendering/style/ScaleTransformOperation.cpp',
'rendering/style/ShadowData.cpp',
- 'rendering/style/SkewTransformOperation.cpp',
'rendering/style/StyleBackgroundData.cpp',
'rendering/style/StyleBoxData.cpp',
'rendering/style/StyleCachedImage.cpp',
@@ -546,8 +545,6 @@ sources['rendering/style'] = [
'rendering/style/StyleVisualData.cpp',
'rendering/style/SVGRenderStyle.cpp',
'rendering/style/SVGRenderStyleDefs.cpp',
- 'rendering/style/TransformOperations.cpp',
- 'rendering/style/TranslateTransformOperation.cpp',
]
sources['storage'] = [
'storage/ChangeVersionWrapper.cpp',
@@ -573,6 +570,11 @@ sources['storage'] = [
'storage/StorageEvent.cpp',
'storage/StorageMap.cpp'
]
+sources['workers'] = [
+ 'workers/Worker.cpp',
+ 'workers/WorkerContext.cpp',
+ 'workers/WorkerLocation.cpp',
+]
sources['xml'] = [
'xml/DOMParser.cpp',
'xml/NativeXPathNSResolver.cpp',
@@ -635,7 +637,6 @@ sources['bindings/js'] = [
"bindings/js/JSEventCustom.cpp",
"bindings/js/JSEventListener.cpp",
"bindings/js/JSEventTarget.cpp",
- "bindings/js/JSEventTargetNodeCustom.cpp",
"bindings/js/JSGeolocationCustom.cpp",
"bindings/js/JSHTMLAllCollection.cpp",
"bindings/js/JSHTMLAppletElementCustom.cpp",
@@ -657,6 +658,7 @@ sources['bindings/js'] = [
"bindings/js/JSInspectedObjectWrapper.cpp",
"bindings/js/JSInspectorCallbackWrapper.cpp",
"bindings/js/JSJavaScriptCallFrameCustom.cpp",
+ "bindings/js/JSLazyEventListener.cpp",
"bindings/js/JSLocationCustom.cpp",
"bindings/js/JSMessageChannelConstructor.cpp",
"bindings/js/JSMessageChannelCustom.cpp",
@@ -707,6 +709,7 @@ sources['bindings/js'] = [
"bindings/js/WorkerScriptController.cpp",
]
sources['bridge'] = [
+ 'bridge/IdentifierRep.cpp',
'bridge/NP_jsobject.cpp',
'bridge/npruntime.cpp',
'bridge/runtime.cpp',
@@ -726,7 +729,9 @@ sources['bridge/c'] = [
# These may eventually move to a separate sources file
sources['platform'] = [
'platform/Arena.cpp',
+ 'platform/ContentType.cpp',
'platform/ContextMenu.cpp',
+ 'platform/CrossThreadCopier.cpp',
'platform/DeprecatedPtrListImpl.cpp',
'platform/DragData.cpp',
'platform/DragImage.cpp',
@@ -742,6 +747,7 @@ sources['platform'] = [
'platform/SharedBuffer.cpp',
'platform/Theme.cpp',
'platform/ThreadGlobalData.cpp',
+ 'platform/ThreadTimers.cpp',
'platform/Timer.cpp',
'platform/Widget.cpp'
]
@@ -789,7 +795,9 @@ sources['platform/graphics'] = [
]
sources['platform/graphics/transforms'] = [
'platform/graphics/transforms/MatrixTransformOperation.cpp',
+ 'platform/graphics/transforms/Matrix3DTransformOperation.cpp',
'platform/graphics/transforms/RotateTransformOperation.cpp',
+ 'platform/graphics/transforms/PerspectiveTransformOperation.cpp',
'platform/graphics/transforms/ScaleTransformOperation.cpp',
'platform/graphics/transforms/SkewTransformOperation.cpp',
'platform/graphics/transforms/TransformOperations.cpp',
@@ -831,8 +839,8 @@ sources['platform/text'] = [
'platform/text/TextCodecLatin1.cpp',
'platform/text/TextCodecUserDefined.cpp',
'platform/text/TextCodecUTF16.cpp',
- 'platform/text/TextDecoder.cpp',
'platform/text/TextEncoding.cpp',
+ 'platform/text/TextEncodingDetectorICU.cpp',
'platform/text/TextEncodingRegistry.cpp',
'platform/text/TextStream.cpp',
'platform/text/UnicodeRange.cpp',
diff --git a/WebCore/WebCore.vcproj/MigrateIDLAndScripts b/WebCore/WebCore.vcproj/MigrateIDLAndScripts
index 4ff9002..912361d 100644
--- a/WebCore/WebCore.vcproj/MigrateIDLAndScripts
+++ b/WebCore/WebCore.vcproj/MigrateIDLAndScripts
@@ -155,6 +155,11 @@ $(WEBKIT_OUTPUT)/% : $(WEBCORE)/html/%
$(WEBKIT_OUTPUT)/% : $(WEBCORE)/css/%
$(MIGRATE_CMD)
+# Migrate workers IDLs
+$(WEBKIT_OUTPUT)/% : $(WEBCORE)/workers/%
+ $(MIGRATE_CMD)
+
+
# Migrate generation scripts
$(WEBKIT_OUTPUT)/% : $(WEBCORE)/bindings/scripts/%
$(MIGRATE_CMD)
diff --git a/WebCore/WebCore.vcproj/QTMovieWin.vcproj b/WebCore/WebCore.vcproj/QTMovieWin.vcproj
index db4ac69..8c38094 100644
--- a/WebCore/WebCore.vcproj/QTMovieWin.vcproj
+++ b/WebCore/WebCore.vcproj/QTMovieWin.vcproj
@@ -39,7 +39,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(ProgramFiles)/QuickTime SDK/cincludes&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\QuickTime SDK\CIncludes&quot;;&quot;$(ProgramFiles)/QuickTime SDK/cincludes&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="_USRDLL;QTMOVIEWIN_EXPORTS"
/>
<Tool
@@ -54,9 +54,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="&quot;$(ProgramFiles)\QuickTime SDK\Libraries\QTMLClient.lib&quot; WTF$(WebKitConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib Msimg32.lib user32.lib advapi32.lib"
+ AdditionalDependencies="QTMLClient.lib WTF$(WebKitConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib Msimg32.lib user32.lib advapi32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix).dll"
- AdditionalLibraryDirectories=""
+ AdditionalLibraryDirectories="&quot;$(WebKitLibrariesDir)\QuickTime SDK\Libraries&quot;;&quot;$(ProgramFiles)\QuickTime SDK\Libraries&quot;"
DelayLoadDLLs=""
/>
<Tool
@@ -110,7 +110,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(ProgramFiles)/QuickTime SDK/cincludes&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\QuickTime SDK\CIncludes&quot;;&quot;$(ProgramFiles)/QuickTime SDK/cincludes&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="_USRDLL;QTMOVIEWIN_EXPORTS"
/>
<Tool
@@ -125,9 +125,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="&quot;$(ProgramFiles)\QuickTime SDK\Libraries\QTMLClient.lib&quot; WTF$(WebKitConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib Msimg32.lib user32.lib advapi32.lib"
+ AdditionalDependencies="QTMLClient.lib WTF$(WebKitConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib Msimg32.lib user32.lib advapi32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix).dll"
- AdditionalLibraryDirectories=""
+ AdditionalLibraryDirectories="&quot;$(WebKitLibrariesDir)\QuickTime SDK\Libraries&quot;;&quot;$(ProgramFiles)\QuickTime SDK\Libraries&quot;"
DelayLoadDLLs=""
/>
<Tool
@@ -180,7 +180,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(ProgramFiles)/QuickTime SDK/cincludes&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\Include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include\WebCore\ForwardingHeaders&quot;;&quot;$(WebKitOutputDir)\Include&quot;;&quot;$(WebKitLibrariesDir)\QuickTime SDK\CIncludes&quot;;&quot;$(ProgramFiles)/QuickTime SDK/cincludes&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;"
PreprocessorDefinitions="_USRDLL;QTMOVIEWIN_EXPORTS"
/>
<Tool
@@ -195,9 +195,9 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="&quot;$(ProgramFiles)\QuickTime SDK\Libraries\QTMLClient.lib&quot; WTF$(WebKitConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib Msimg32.lib user32.lib advapi32.lib"
+ AdditionalDependencies="QTMLClient.lib WTF$(WebKitConfigSuffix).lib winmm.lib pthreadVC2$(LibraryConfigSuffix).lib Msimg32.lib user32.lib advapi32.lib"
OutputFile="$(OutDir)\$(ProjectName)$(WebKitConfigSuffix).dll"
- AdditionalLibraryDirectories=""
+ AdditionalLibraryDirectories="&quot;$(WebKitLibrariesDir)\QuickTime SDK\Libraries&quot;;&quot;$(ProgramFiles)\QuickTime SDK\Libraries&quot;"
DelayLoadDLLs=""
/>
<Tool
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index 68728c5..45aa72e 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -24,7 +24,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 0 set EnablePREfast=&quot;false&quot; else set EnablePREfast=&quot;true&quot;&#x0D;&#x0A;if ERRORLEVEL 0 set AnalyzeWithLargeStack=&quot;&quot; AnalyzeWithLargeStack=&quot;/analyze:65536&quot;&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 1 (set EnablePREfast=&quot;true&quot;) else (set EnablePREfast=&quot;false&quot;)&#x0D;&#x0A;if ERRORLEVEL 1 (set AnalyzeWithLargeStack=&quot;/analyze:65536&quot;) else (set AnalyzeWithLargeStack=&quot;&quot;)&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -40,7 +40,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&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\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_DATABASE;ENABLE_DOM_STORAGE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_VIDEO;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
@@ -72,7 +72,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\opentype\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\workers\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -85,7 +85,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 0 set EnablePREfast=&quot;false&quot; else set EnablePREfast=&quot;true&quot;&#x0D;&#x0A;if ERRORLEVEL 0 set AnalyzeWithLargeStack=&quot;&quot; AnalyzeWithLargeStack=&quot;/analyze:65536&quot;&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 1 (set EnablePREfast=&quot;true&quot;) else (set EnablePREfast=&quot;false&quot;)&#x0D;&#x0A;if ERRORLEVEL 1 (set AnalyzeWithLargeStack=&quot;/analyze:65536&quot;) else (set AnalyzeWithLargeStack=&quot;&quot;)&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -101,7 +101,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&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\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_DATABASE;ENABLE_DOM_STORAGE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_VIDEO;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
@@ -133,7 +133,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\opentype\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\workers\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -145,7 +145,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 0 set EnablePREfast=&quot;false&quot; else set EnablePREfast=&quot;true&quot;&#x0D;&#x0A;if ERRORLEVEL 0 set AnalyzeWithLargeStack=&quot;&quot; AnalyzeWithLargeStack=&quot;/analyze:65536&quot;&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 1 (set EnablePREfast=&quot;true&quot;) else (set EnablePREfast=&quot;false&quot;)&#x0D;&#x0A;if ERRORLEVEL 1 (set AnalyzeWithLargeStack=&quot;/analyze:65536&quot;) else (set AnalyzeWithLargeStack=&quot;&quot;)&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -161,7 +161,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&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\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_DATABASE;ENABLE_DOM_STORAGE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_VIDEO;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
@@ -193,7 +193,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\opentype\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\workers\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -206,7 +206,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 0 set EnablePREfast=&quot;false&quot; else set EnablePREfast=&quot;true&quot;&#x0D;&#x0A;if ERRORLEVEL 0 set AnalyzeWithLargeStack=&quot;&quot; AnalyzeWithLargeStack=&quot;/analyze:65536&quot;&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 1 (set EnablePREfast=&quot;true&quot;) else (set EnablePREfast=&quot;false&quot;)&#x0D;&#x0A;if ERRORLEVEL 1 (set AnalyzeWithLargeStack=&quot;/analyze:65536&quot;) else (set AnalyzeWithLargeStack=&quot;&quot;)&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -222,7 +222,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\curl&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cairo&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\image-decoders&quot;;&quot;$(ProjectDir)..\platform\image-decoders\bmp&quot;;&quot;$(ProjectDir)..\platform\image-decoders\gif&quot;;&quot;$(ProjectDir)..\platform\image-decoders\ico&quot;;&quot;$(ProjectDir)..\platform\image-decoders\jpeg&quot;;&quot;$(ProjectDir)..\platform\image-decoders\png&quot;;&quot;$(ProjectDir)..\platform\image-decoders\xbm&quot;;&quot;$(ProjectDir)..\platform\image-decoders\zlib&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\platform\cairo\pixman\src&quot;;&quot;$(ProjectDir)..\platform\cairo\cairo\src&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cairo&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\kcanvas&quot;;&quot;$(ProjectDir)..\kcanvas\device&quot;;&quot;$(ProjectDir)..\kcanvas\device\quartz&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\curl&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cairo&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\platform\image-decoders&quot;;&quot;$(ProjectDir)..\platform\image-decoders\bmp&quot;;&quot;$(ProjectDir)..\platform\image-decoders\gif&quot;;&quot;$(ProjectDir)..\platform\image-decoders\ico&quot;;&quot;$(ProjectDir)..\platform\image-decoders\jpeg&quot;;&quot;$(ProjectDir)..\platform\image-decoders\png&quot;;&quot;$(ProjectDir)..\platform\image-decoders\xbm&quot;;&quot;$(ProjectDir)..\platform\image-decoders\zlib&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\platform\cairo\pixman\src&quot;;&quot;$(ProjectDir)..\platform\cairo\cairo\src&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cairo&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\kcanvas&quot;;&quot;$(ProjectDir)..\kcanvas\device&quot;;&quot;$(ProjectDir)..\kcanvas\device\quartz&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_DATABASE;ENABLE_DOM_STORAGE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
@@ -254,7 +254,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\curl\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\opentype\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\curl\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\workers\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -268,7 +268,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 0 set EnablePREfast=&quot;false&quot; else set EnablePREfast=&quot;true&quot;&#x0D;&#x0A;if ERRORLEVEL 0 set AnalyzeWithLargeStack=&quot;&quot; AnalyzeWithLargeStack=&quot;/analyze:65536&quot;&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 1 (set EnablePREfast=&quot;true&quot;) else (set EnablePREfast=&quot;false&quot;)&#x0D;&#x0A;if ERRORLEVEL 1 (set AnalyzeWithLargeStack=&quot;/analyze:65536&quot;) else (set AnalyzeWithLargeStack=&quot;&quot;)&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -284,7 +284,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\curl&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cairo&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\image-decoders&quot;;&quot;$(ProjectDir)..\platform\image-decoders\bmp&quot;;&quot;$(ProjectDir)..\platform\image-decoders\gif&quot;;&quot;$(ProjectDir)..\platform\image-decoders\ico&quot;;&quot;$(ProjectDir)..\platform\image-decoders\jpeg&quot;;&quot;$(ProjectDir)..\platform\image-decoders\png&quot;;&quot;$(ProjectDir)..\platform\image-decoders\xbm&quot;;&quot;$(ProjectDir)..\platform\image-decoders\zlib&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\platform\cairo\pixman\src&quot;;&quot;$(ProjectDir)..\platform\cairo\cairo\src&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cairo&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\kcanvas&quot;;&quot;$(ProjectDir)..\kcanvas\device&quot;;&quot;$(ProjectDir)..\kcanvas\device\quartz&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\curl&quot;;&quot;$(ProjectDir)..\platform\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cairo&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\platform\image-decoders&quot;;&quot;$(ProjectDir)..\platform\image-decoders\bmp&quot;;&quot;$(ProjectDir)..\platform\image-decoders\gif&quot;;&quot;$(ProjectDir)..\platform\image-decoders\ico&quot;;&quot;$(ProjectDir)..\platform\image-decoders\jpeg&quot;;&quot;$(ProjectDir)..\platform\image-decoders\png&quot;;&quot;$(ProjectDir)..\platform\image-decoders\xbm&quot;;&quot;$(ProjectDir)..\platform\image-decoders\zlib&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\platform\cairo\pixman\src&quot;;&quot;$(ProjectDir)..\platform\cairo\cairo\src&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cairo&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\kcanvas&quot;;&quot;$(ProjectDir)..\kcanvas\device&quot;;&quot;$(ProjectDir)..\kcanvas\device\quartz&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_DATABASE;ENABLE_DOM_STORAGE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="WebCorePrefix.h"
@@ -316,7 +316,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\curl\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\opentype\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\curl\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\workers\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -329,7 +329,7 @@
>
<Tool
Name="VCPreBuildEventTool"
- CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 0 set EnablePREfast=&quot;false&quot; else set EnablePREfast=&quot;true&quot;&#x0D;&#x0A;if ERRORLEVEL 0 set AnalyzeWithLargeStack=&quot;&quot; AnalyzeWithLargeStack=&quot;/analyze:65536&quot;&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
+ CommandLine="set PATH=%SystemDrive%\cygwin\bin;%PATH%&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; grep XX$(ProjectName)XX &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;if errorlevel 1 exit 1&#x0D;&#x0A;echo XX$(ProjectName)XX &gt; &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;touch &quot;$(WebKitOutputDir)\tmp.cpp&quot;&#x0D;&#x0A;cl /analyze /nologo /c &quot;$(WebKitOutputDir)\tmp.cpp&quot; 2&gt;&amp;1 | findstr D9040&#x0D;&#x0A;if ERRORLEVEL 1 (set EnablePREfast=&quot;true&quot;) else (set EnablePREfast=&quot;false&quot;)&#x0D;&#x0A;if ERRORLEVEL 1 (set AnalyzeWithLargeStack=&quot;/analyze:65536&quot;) else (set AnalyzeWithLargeStack=&quot;&quot;)&#x0D;&#x0A;exit /b&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
@@ -346,7 +346,7 @@
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="false"
- AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&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\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\&quot;;&quot;$(ProjectDir)..&quot;;&quot;$(ProjectDir)..\bridge&quot;;&quot;$(ProjectDir)..\bridge\c&quot;;&quot;$(ProjectDir)..\css&quot;;&quot;$(ProjectDir)..\editing&quot;;&quot;$(ProjectDir)..\rendering&quot;;&quot;$(ProjectDir)..\rendering\style&quot;;&quot;$(ProjectDir)..\bindings\js&quot;;&quot;$(ProjectDir)..\dom&quot;;&quot;$(ProjectDir)..\history&quot;;&quot;$(ProjectDir)..\html&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)..\page&quot;;&quot;$(ProjectDir)..\page\animation&quot;;&quot;$(ProjectDir)..\page\win&quot;;&quot;$(ProjectDir)..\platform&quot;;&quot;$(ProjectDir)..\platform\animation&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\network\cf&quot;;&quot;$(ProjectDir)..\platform\graphics&quot;;&quot;$(ProjectDir)..\platform\graphics\transforms&quot;;&quot;$(ProjectDir)..\platform\text&quot;;&quot;$(ProjectDir)..\platform\graphics\cg&quot;;&quot;$(ProjectDir)..\platform\graphics\win&quot;;&quot;$(ProjectDir)..\platform\graphics\opentype&quot;;&quot;$(ProjectDir)..\xml&quot;;&quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources&quot;;&quot;$(ProjectDir)..\plugins&quot;;&quot;$(ProjectDir)..\plugins\win&quot;;&quot;$(ProjectDir)..\svg\graphics&quot;;&quot;$(ProjectDir)..\svg\graphics\cg&quot;;&quot;$(ProjectDir)..\svg\graphics\filters&quot;;&quot;$(ProjectDir)..\svg&quot;;&quot;$(ProjectDir)..\wml&quot;;&quot;$(ProjectDir)..\storage&quot;;&quot;$(ProjectDir)..\workers&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(ProjectDir)..\ForwardingHeaders&quot;;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\icu&quot;;&quot;$(WebKitLibrariesDir)\include\iconv&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include\sqlite&quot;;&quot;$(WebKitLibrariesDir)\include\JavaScriptCore&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders&quot;;&quot;$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility&quot;;&quot;$(WebKitOutputDir)\include\QtMovieWin&quot;;&quot;$(ProjectDir)..\svg\animation&quot;"
PreprocessorDefinitions="__WIN32__;WEBCORE_CONTEXT_MENUS;ENABLE_DATABASE;ENABLE_DOM_STORAGE;ENABLE_ICONDATABASE;ENABLE_OFFLINE_WEB_APPLICATIONS;ENABLE_SVG;ENABLE_SVG_ANIMATION;ENABLE_SVG_AS_IMAGE;ENABLE_SVG_FONTS;ENABLE_SVG_FOREIGN_OBJECT;ENABLE_SVG_USE;ENABLE_VIDEO;ENABLE_WORKERS;ENABLE_XPATH;ENABLE_XSLT"
PrecompiledHeaderThrough="WebCorePrefix.h"
ForcedIncludeFiles="WebCorePrefix.h"
@@ -377,7 +377,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\config.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(WebKitOutputDir)\obj\WebCore\DerivedSources\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\inspector\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\appcache\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\archive\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\loader\icon\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\history\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\html\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\css\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\transforms\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\graphics\opentype\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\text\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\cf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\network\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\sql\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\platform\cairo\cairo\src\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bindings\js\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\animation\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\page\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\bridge\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\plugins\win\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\rendering\style\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\editing\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\dom\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\xml\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\svg\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\storage\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\workers\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\bindings\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\bindings&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\parser&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\runtime&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\masm\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\masm&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\pcre\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\pcre&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\profiler&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wrec&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\ForwardingHeaders\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\WebCore\ForwardingHeaders\wtf\unicode\icu&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\inspector\front-end\*&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\inspector&quot;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;xcopy /y /d /s /exclude:xcopy.excludes &quot;$(ProjectDir)\..\English.lproj\localizedStrings.js&quot; &quot;$(WebKitOutputDir)\bin\WebKit.resources\en.lproj&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -508,6 +508,22 @@
</FileConfiguration>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\HTMLElementFactory.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\HTMLElementFactory.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\HTMLNames.cpp"
>
</File>
@@ -544,6 +560,14 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSClientRect.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSClientRectList.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSClipboard.h"
>
</File>
@@ -556,6 +580,10 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSCoordinates.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSCounter.h"
>
</File>
@@ -688,10 +716,6 @@
>
</File>
<File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSEventTargetNode.h"
- >
- </File>
- <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSFile.h"
>
</File>
@@ -972,6 +996,14 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSInspectorController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSInspectorController.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSJavaScriptCallFrame.h"
>
</File>
@@ -1712,6 +1744,10 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSWebKitPoint.h"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSWebKitTransitionEvent.h"
>
</File>
@@ -1788,6 +1824,10 @@
>
</File>
<File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\SVGElementFactory.cpp"
+ >
+ </File>
+ <File
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\SVGElementFactory.h"
>
</File>
@@ -2024,6 +2064,10 @@
>
</File>
<File
+ RelativePath="..\page\animation\AnimationControllerPrivate.h"
+ >
+ </File>
+ <File
RelativePath="..\page\AXObjectCache.cpp"
>
</File>
@@ -2120,6 +2164,22 @@
>
</File>
<File
+ RelativePath="..\page\Coordinates.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\page\Coordinates.h"
+ >
+ </File>
+ <File
RelativePath="..\page\DOMSelection.cpp"
>
<FileConfiguration
@@ -2532,6 +2592,10 @@
>
</File>
<File
+ RelativePath="..\page\WebKitPoint.h"
+ >
+ </File>
+ <File
RelativePath="..\page\WindowFeatures.cpp"
>
<FileConfiguration
@@ -2740,6 +2804,22 @@
>
</File>
<File
+ RelativePath="..\loader\CrossOriginAccessControl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\CrossOriginAccessControl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\CrossOriginPreflightResultCache.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\CrossOriginPreflightResultCache.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\DocLoader.cpp"
>
</File>
@@ -2764,6 +2844,10 @@
>
</File>
<File
+ RelativePath="..\loader\EmptyClients.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\FormState.cpp"
>
</File>
@@ -2780,10 +2864,6 @@
>
</File>
<File
- RelativePath="..\loader\FrameLoaderClient.cpp"
- >
- </File>
- <File
RelativePath="..\loader\FrameLoaderClient.h"
>
</File>
@@ -2896,6 +2976,26 @@
>
</File>
<File
+ RelativePath="..\loader\cf\ResourceLoaderCFNet.cpp"
+ >
+ <FileConfiguration
+ Name="Debug_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_Cairo|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\loader\SubresourceLoader.cpp"
>
</File>
@@ -2943,6 +3043,14 @@
RelativePath="..\loader\ThreadableLoaderClient.h"
>
</File>
+ <File
+ RelativePath="..\loader\WorkerThreadableLoader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\WorkerThreadableLoader.h"
+ >
+ </File>
<Filter
Name="icon"
>
@@ -3100,6 +3208,14 @@
>
</File>
<File
+ RelativePath="..\platform\ContentType.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\ContentType.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\ContextMenu.cpp"
>
</File>
@@ -3116,6 +3232,22 @@
>
</File>
<File
+ RelativePath="..\platform\CrossThreadCopier.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\platform\CrossThreadCopier.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\Cursor.h"
>
</File>
@@ -3376,6 +3508,14 @@
>
</File>
<File
+ RelativePath="..\platform\ThreadTimers.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\ThreadTimers.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\Timer.cpp"
>
</File>
@@ -4532,11 +4672,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\platform\graphics\win\OpenTypeUtilities.cpp"
+ RelativePath="..\platform\graphics\opentype\OpenTypeUtilities.cpp"
>
</File>
<File
- RelativePath="..\platform\graphics\win\OpenTypeUtilities.h"
+ RelativePath="..\platform\graphics\opentype\OpenTypeUtilities.h"
>
</File>
<File
@@ -5412,124 +5552,32 @@
>
</File>
<File
+ RelativePath="..\platform\graphics\transforms\Matrix3DTransformOperation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\graphics\transforms\Matrix3DTransformOperation.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\graphics\transforms\MatrixTransformOperation.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\platform\graphics\transforms\MatrixTransformOperation.h"
>
</File>
<File
+ RelativePath="..\platform\graphics\transforms\PerspectiveTransformOperation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\platform\graphics\transforms\PerspectiveTransformOperation.h"
+ >
+ </File>
+ <File
RelativePath="..\platform\graphics\transforms\RotateTransformOperation.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\platform\graphics\transforms\RotateTransformOperation.h"
@@ -5538,60 +5586,6 @@
<File
RelativePath="..\platform\graphics\transforms\ScaleTransformOperation.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\platform\graphics\transforms\ScaleTransformOperation.h"
@@ -5600,60 +5594,6 @@
<File
RelativePath="..\platform\graphics\transforms\SkewTransformOperation.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\platform\graphics\transforms\SkewTransformOperation.h"
@@ -5674,60 +5614,6 @@
<File
RelativePath="..\platform\graphics\transforms\TransformOperations.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\platform\graphics\transforms\TransformOperations.h"
@@ -5736,60 +5622,6 @@
<File
RelativePath="..\platform\graphics\transforms\TranslateTransformOperation.cpp"
>
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- ObjectFile="$(IntDir)\$(InputName)1.obj"
- XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
- />
- </FileConfiguration>
</File>
<File
RelativePath="..\platform\graphics\transforms\TranslateTransformOperation.h"
@@ -6929,23 +6761,23 @@
>
</File>
<File
- RelativePath="..\platform\text\TextDecoder.cpp"
+ RelativePath="..\platform\text\TextDirection.h"
>
</File>
<File
- RelativePath="..\platform\text\TextDecoder.h"
+ RelativePath="..\platform\text\TextEncoding.cpp"
>
</File>
<File
- RelativePath="..\platform\text\TextDirection.h"
+ RelativePath="..\platform\text\TextEncoding.h"
>
</File>
<File
- RelativePath="..\platform\text\TextEncoding.cpp"
+ RelativePath="..\platform\text\TextEncodingDetectorICU.cpp"
>
</File>
<File
- RelativePath="..\platform\text\TextEncoding.h"
+ RelativePath="..\platform\text\TextEncodingDetector.h"
>
</File>
<File
@@ -8966,7 +8798,7 @@
>
</File>
<File
- RelativePath="..\rendering\RenderBR.cpp"
+ RelativePath="..\rendering\RenderBoxModelObject.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -8978,11 +8810,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\rendering\RenderBR.h"
+ RelativePath="..\rendering\RenderBoxModelObject.h"
>
</File>
<File
- RelativePath="..\rendering\RenderButton.cpp"
+ RelativePath="..\rendering\RenderBR.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -8994,11 +8826,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\rendering\RenderButton.h"
+ RelativePath="..\rendering\RenderBR.h"
>
</File>
<File
- RelativePath="..\rendering\RenderContainer.cpp"
+ RelativePath="..\rendering\RenderButton.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -9010,7 +8842,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\rendering\RenderContainer.h"
+ RelativePath="..\rendering\RenderButton.h"
>
</File>
<File
@@ -9078,22 +8910,6 @@
>
</File>
<File
- RelativePath="..\rendering\RenderFlow.cpp"
- >
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="true"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\rendering\RenderFlow.h"
- >
- </File>
- <File
RelativePath="..\rendering\RenderForeignObject.cpp"
>
<FileConfiguration
@@ -9222,7 +9038,7 @@
>
</File>
<File
- RelativePath="..\rendering\RenderLegend.cpp"
+ RelativePath="..\rendering\RenderLineBoxList.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -9234,7 +9050,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\rendering\RenderLegend.h"
+ RelativePath="..\rendering\RenderLineBoxList.h"
>
</File>
<File
@@ -9350,6 +9166,22 @@
>
</File>
<File
+ RelativePath="..\rendering\RenderObjectChildList.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\rendering\RenderObjectChildList.h"
+ >
+ </File>
+ <File
RelativePath="..\rendering\RenderPart.cpp"
>
<FileConfiguration
@@ -9478,6 +9310,10 @@
>
</File>
<File
+ RelativePath="..\rendering\RenderSelectionInfo.h"
+ >
+ </File>
+ <File
RelativePath="..\rendering\RenderSlider.cpp"
>
<FileConfiguration
@@ -10068,6 +9904,22 @@
>
</File>
<File
+ RelativePath="..\rendering\ScrollBehavior.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\rendering\ScrollBehavior.h"
+ >
+ </File>
+ <File
RelativePath="..\rendering\SVGCharacterLayoutInfo.cpp"
>
<FileConfiguration
@@ -10183,6 +10035,14 @@
RelativePath="..\rendering\TextControlInnerElements.h"
>
</File>
+ <File
+ RelativePath="..\rendering\TransformState.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\rendering\TransformState.h"
+ >
+ </File>
<Filter
Name="style"
>
@@ -11034,6 +10894,38 @@
>
</File>
<File
+ RelativePath="..\dom\ClientRect.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\dom\ClientRect.h"
+ >
+ </File>
+ <File
+ RelativePath="..\dom\ClientRectList.cpp"
+ >
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\dom\ClientRectList.h"
+ >
+ </File>
+ <File
RelativePath="..\dom\Clipboard.cpp"
>
<FileConfiguration
@@ -11346,22 +11238,6 @@
>
</File>
<File
- RelativePath="..\dom\EventTargetNode.cpp"
- >
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="true"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\dom\EventTargetNode.h"
- >
- </File>
- <File
RelativePath="..\dom\ExceptionBase.cpp"
>
<FileConfiguration
@@ -11394,7 +11270,7 @@
>
</File>
<File
- RelativePath="..\dom\FormControlElementWithState.cpp"
+ RelativePath="..\dom\FormControlElement.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -11406,11 +11282,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\dom\FormControlElementWithState.h"
+ RelativePath="..\dom\FormControlElement.h"
>
</File>
<File
- RelativePath="..\dom\FormControlElement.cpp"
+ RelativePath="..\dom\FormControlElementWithState.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -11422,11 +11298,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\dom\FormControlElement.h"
- >
- </File>
- <File
- RelativePath="..\dom\GenericWorkerTask.h"
+ RelativePath="..\dom\FormControlElementWithState.h"
>
</File>
<File
@@ -11694,7 +11566,7 @@
>
</File>
<File
- RelativePath="..\dom\OptionGroupElement.cpp"
+ RelativePath="..\dom\OptionElement.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -11706,11 +11578,11 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\dom\OptionGroupElement.h"
+ RelativePath="..\dom\OptionElement.h"
>
</File>
<File
- RelativePath="..\dom\OptionElement.cpp"
+ RelativePath="..\dom\OptionGroupElement.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
@@ -11722,7 +11594,7 @@
</FileConfiguration>
</File>
<File
- RelativePath="..\dom\OptionElement.h"
+ RelativePath="..\dom\OptionGroupElement.h"
>
</File>
<File
@@ -12138,88 +12010,104 @@
>
</File>
<File
- RelativePath="..\dom\Worker.cpp"
+ RelativePath="..\dom\XMLTokenizer.cpp"
>
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
</File>
<File
- RelativePath="..\dom\Worker.h"
+ RelativePath="..\dom\XMLTokenizer.h"
>
</File>
<File
- RelativePath="..\dom\WorkerContext.cpp"
+ RelativePath="..\dom\XMLTokenizerLibxml2.cpp"
>
+ <FileConfiguration
+ Name="Release_PGO|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ WholeProgramOptimization="true"
+ />
+ </FileConfiguration>
</File>
+ </Filter>
+ <Filter
+ Name="workers"
+ >
<File
- RelativePath="..\dom\WorkerContext.h"
+ RelativePath="..\workers\GenericWorkerTask.h"
>
</File>
<File
- RelativePath="..\dom\WorkerLocation.cpp"
+ RelativePath="..\workers\Worker.cpp"
>
</File>
<File
- RelativePath="..\dom\WorkerLocation.h"
+ RelativePath="..\workers\Worker.h"
>
</File>
<File
- RelativePath="..\dom\WorkerMessagingProxy.cpp"
+ RelativePath="..\workers\WorkerContext.cpp"
>
</File>
<File
- RelativePath="..\dom\WorkerMessagingProxy.h"
+ RelativePath="..\workers\WorkerContext.h"
>
</File>
<File
- RelativePath="..\dom\WorkerRunLoop.cpp"
+ RelativePath="..\workers\WorkerContextProxy.h"
>
</File>
<File
- RelativePath="..\dom\WorkerRunLoop.h"
+ RelativePath="..\workers\WorkerImportScriptsClient.cpp"
>
</File>
<File
- RelativePath="..\dom\WorkerTask.cpp"
+ RelativePath="..\workers\WorkerImportScriptsClient.h"
>
</File>
<File
- RelativePath="..\dom\WorkerTask.h"
+ RelativePath="..\workers\WorkerLocation.cpp"
>
</File>
<File
- RelativePath="..\dom\WorkerThread.cpp"
+ RelativePath="..\workers\WorkerLocation.h"
>
</File>
<File
- RelativePath="..\dom\WorkerThread.h"
+ RelativePath="..\workers\WorkerMessagingProxy.cpp"
>
</File>
<File
- RelativePath="..\dom\XMLTokenizer.cpp"
+ RelativePath="..\workers\WorkerMessagingProxy.h"
>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="true"
- />
- </FileConfiguration>
</File>
<File
- RelativePath="..\dom\XMLTokenizer.h"
+ RelativePath="..\workers\WorkerObjectProxy.h"
>
</File>
<File
- RelativePath="..\dom\XMLTokenizerLibxml2.cpp"
+ RelativePath="..\workers\WorkerRunLoop.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\workers\WorkerRunLoop.h"
+ >
+ </File>
+ <File
+ RelativePath="..\workers\WorkerThread.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\workers\WorkerThread.h"
>
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="true"
- />
- </FileConfiguration>
</File>
</Filter>
<Filter
@@ -12486,14 +12374,6 @@
>
</File>
<File
- RelativePath="..\editing\Selection.cpp"
- >
- </File>
- <File
- RelativePath="..\editing\Selection.h"
- >
- </File>
- <File
RelativePath="..\editing\SelectionController.cpp"
>
</File>
@@ -12594,6 +12474,14 @@
>
</File>
<File
+ RelativePath="..\editing\VisibleSelection.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\editing\VisibleSelection.h"
+ >
+ </File>
+ <File
RelativePath="..\editing\WrapContentsInDummySpanCommand.cpp"
>
</File>
@@ -13006,22 +12894,6 @@
>
</File>
<File
- RelativePath="..\html\HTMLElementFactory.cpp"
- >
- <FileConfiguration
- Name="Release_PGO|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- WholeProgramOptimization="true"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\html\HTMLElementFactory.h"
- >
- </File>
- <File
RelativePath="..\html\HTMLEmbedElement.cpp"
>
<FileConfiguration
@@ -14265,10 +14137,6 @@
>
</File>
<File
- RelativePath="..\bindings\js\JSEventTargetNodeCustom.cpp"
- >
- </File>
- <File
RelativePath="..\bindings\js\JSGeolocationCustom.cpp"
>
</File>
@@ -14373,10 +14241,22 @@
>
</File>
<File
+ RelativePath="..\bindings\js\JSInspectorControllerCustom.cpp"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\JSJavaScriptCallFrameCustom.cpp"
>
</File>
<File
+ RelativePath="..\bindings\js\JSLazyEventListener.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\JSLazyEventListener.h"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\JSLocationCustom.cpp"
>
</File>
@@ -14549,6 +14429,14 @@
>
</File>
<File
+ RelativePath="..\bindings\js\JSWebKitPointConstructor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\JSWebKitPointConstructor.h"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\JSWorkerConstructor.cpp"
>
</File>
@@ -14649,10 +14537,34 @@
>
</File>
<File
+ RelativePath="..\bindings\js\ScriptFunctionCall.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\ScriptFunctionCall.h"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\ScriptInstance.h"
>
</File>
<File
+ RelativePath="..\bindings\js\ScriptObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\ScriptObject.h"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\ScriptObjectQuarantine.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bindings\js\ScriptObjectQuarantine.h"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\ScriptSourceCode.h"
>
</File>
@@ -15567,26 +15479,6 @@
/>
</FileConfiguration>
</File>
- <File
- RelativePath="..\svg\graphics\cg\SVGResourceMaskerCg.cpp"
- >
- <FileConfiguration
- Name="Debug_Cairo|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_Cairo|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
</Filter>
<Filter
Name="filters"
@@ -15783,42 +15675,6 @@
/>
</FileConfiguration>
</File>
- <File
- RelativePath="..\svg\graphics\cairo\SVGResourceMaskerCairo.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="Release_PGO|Win32"
- ExcludedFromBuild="true"
- >
- <Tool
- Name="VCCLCompilerTool"
- />
- </FileConfiguration>
- </File>
</Filter>
</Filter>
</Filter>
@@ -16346,6 +16202,14 @@
>
</File>
<File
+ RelativePath="..\bridge\IdentifierRep.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\bridge\IdentifierRep.h"
+ >
+ </File>
+ <File
RelativePath="..\bridge\NP_jsobject.cpp"
>
</File>
@@ -16422,6 +16286,14 @@
Name="inspector"
>
<File
+ RelativePath="..\inspector\ConsoleMessage.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\ConsoleMessage.h"
+ >
+ </File>
+ <File
RelativePath="..\inspector\InspectorClient.h"
>
</File>
@@ -16442,6 +16314,30 @@
>
</File>
<File
+ RelativePath="..\inspector\InspectorDatabaseResource.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorDatabaseResource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorDOMStorageResource.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorDOMStorageResource.h"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorResource.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\InspectorResource.h"
+ >
+ </File>
+ <File
RelativePath="..\inspector\JavaScriptCallFrame.cpp"
>
<FileConfiguration
@@ -16533,6 +16429,18 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\DOMStorage.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\DOMStorageDataGrid.js"
+ >
+ </File>
+ <File
+ RelativePath="..\inspector\front-end\DOMStorageItemsView.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\ElementsPanel.js"
>
</File>
@@ -16738,19 +16646,19 @@
>
</File>
<File
- RelativePath="..\wml\WMLFormControlElement.cpp"
+ RelativePath="..\wml\WMLFieldSetElement.cpp"
>
</File>
<File
- RelativePath="..\wml\WMLFormControlElement.h"
+ RelativePath="..\wml\WMLFieldSetElement.h"
>
</File>
<File
- RelativePath="..\wml\WMLFieldSetElement.cpp"
+ RelativePath="..\wml\WMLFormControlElement.cpp"
>
</File>
<File
- RelativePath="..\wml\WMLFieldSetElement.h"
+ RelativePath="..\wml\WMLFormControlElement.h"
>
</File>
<File
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index f09a5ed..c8a7394 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -35,6 +35,7 @@
066C77310AB603FD00238CC4 /* RenderFileUploadControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 066C772F0AB603FD00238CC4 /* RenderFileUploadControl.h */; };
06E81ED70AB5D5E900C87837 /* LocalCurrentGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 06E81ED60AB5D5E900C87837 /* LocalCurrentGraphicsContext.h */; };
06E81EEC0AB5DA9700C87837 /* LocalCurrentGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06E81EEB0AB5DA9700C87837 /* LocalCurrentGraphicsContext.mm */; };
+ 0735EE6A0F40C5E4004A2604 /* MediaPlayerProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
080081960ED3B2DD00C53BC0 /* WMLAnchorElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 080081940ED3B2DD00C53BC0 /* WMLAnchorElement.cpp */; };
080081970ED3B2DD00C53BC0 /* WMLAnchorElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 080081950ED3B2DD00C53BC0 /* WMLAnchorElement.h */; };
0804BF6E0EE09C3B0006C000 /* WMLDoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0804BF6C0EE09C3B0006C000 /* WMLDoElement.cpp */; };
@@ -138,12 +139,32 @@
0B90561B0F2578BF0095FF6A /* ThreadableLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056170F2578BE0095FF6A /* ThreadableLoader.h */; settings = {ATTRIBUTES = (); }; };
0B90561C0F2578BF0095FF6A /* ThreadableLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056180F2578BE0095FF6A /* ThreadableLoaderClient.h */; settings = {ATTRIBUTES = (); }; };
0B90561E0F257E930095FF6A /* ThreadableLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B90561D0F257E930095FF6A /* ThreadableLoader.cpp */; };
- 0BA5D3860F240FB4009B870B /* GenericWorkerTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BA5D3850F240FB4009B870B /* GenericWorkerTask.h */; };
+ 0B9056F80F2685F30095FF6A /* WorkerThreadableLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B9056F60F2685F30095FF6A /* WorkerThreadableLoader.cpp */; };
+ 0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B9056F70F2685F30095FF6A /* WorkerThreadableLoader.h */; settings = {ATTRIBUTES = (); }; };
+ 0BE030A20F3112FB003C1A46 /* RenderLineBoxList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BE030A10F3112FB003C1A46 /* RenderLineBoxList.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F11A54E0F39233100C37884 /* RenderSelectionInfo.h */; };
+ 0F15DA8A0F3AAEE70000CE47 /* AnimationControllerPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15DA890F3AAEE70000CE47 /* AnimationControllerPrivate.h */; };
+ 0F500AAF0F54DB1B00EEF928 /* TransformState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F500AAE0F54DB1B00EEF928 /* TransformState.h */; };
+ 0F500AB10F54DB3100EEF928 /* TransformState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F500AB00F54DB3100EEF928 /* TransformState.cpp */; };
0F56028F0E4B76580065B038 /* RenderMarquee.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F56028D0E4B76580065B038 /* RenderMarquee.h */; };
0F5602900E4B76580065B038 /* RenderMarquee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F56028E0E4B76580065B038 /* RenderMarquee.cpp */; };
+ 0F580B050F12A2550051D689 /* GraphicsLayerCA.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F580B030F12A2540051D689 /* GraphicsLayerCA.mm */; };
+ 0F580B060F12A2550051D689 /* GraphicsLayerCA.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F580B040F12A2550051D689 /* GraphicsLayerCA.h */; };
+ 0F580B0C0F12A2690051D689 /* GraphicsLayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F580B090F12A2690051D689 /* GraphicsLayer.cpp */; };
+ 0F580B0D0F12A2690051D689 /* GraphicsLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F580B0A0F12A2690051D689 /* GraphicsLayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F580B0E0F12A2690051D689 /* GraphicsLayerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F580B0B0F12A2690051D689 /* GraphicsLayerClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F580CFD0F12DE9B0051D689 /* RenderLayerCompositor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F580CF90F12DE9B0051D689 /* RenderLayerCompositor.h */; };
+ 0F580CFE0F12DE9B0051D689 /* RenderLayerCompositor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F580CFA0F12DE9B0051D689 /* RenderLayerCompositor.cpp */; };
+ 0F580CFF0F12DE9B0051D689 /* RenderLayerBacking.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F580CFB0F12DE9B0051D689 /* RenderLayerBacking.h */; };
+ 0F580D000F12DE9B0051D689 /* RenderLayerBacking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F580CFC0F12DE9B0051D689 /* RenderLayerBacking.cpp */; };
0F6ECD450F252F3700BDE271 /* CSSPropertyLonghand.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6ECD430F252F3700BDE271 /* CSSPropertyLonghand.h */; };
0F6ECD460F252F3700BDE271 /* CSSPropertyLonghand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6ECD440F252F3700BDE271 /* CSSPropertyLonghand.cpp */; };
0FC705210EB1815600B90AD8 /* AtomicStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC705200EB1815600B90AD8 /* AtomicStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FCF33240F2B9715004B6795 /* ColorCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCF33230F2B9715004B6795 /* ColorCG.cpp */; };
+ 0FCF332C0F2B9A25004B6795 /* WebTiledLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FCF33280F2B9A25004B6795 /* WebTiledLayer.mm */; };
+ 0FCF332D0F2B9A25004B6795 /* WebTiledLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCF33290F2B9A25004B6795 /* WebTiledLayer.h */; };
+ 0FCF332E0F2B9A25004B6795 /* WebLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FCF332A0F2B9A25004B6795 /* WebLayer.mm */; };
+ 0FCF332F0F2B9A25004B6795 /* WebLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCF332B0F2B9A25004B6795 /* WebLayer.h */; };
0FD723820EC8BD9300CA5DD7 /* FloatQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD723800EC8BD9300CA5DD7 /* FloatQuad.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FD723830EC8BD9300CA5DD7 /* FloatQuad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD723810EC8BD9300CA5DD7 /* FloatQuad.cpp */; };
1402645E0AFDC19B005919E2 /* LoggingMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1402645D0AFDC19B005919E2 /* LoggingMac.mm */; };
@@ -177,14 +198,12 @@
14DC0D3809FED073007B0235 /* JSNode.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 14DC0D3609FED073007B0235 /* JSNode.h */; settings = {ATTRIBUTES = (); }; };
14E8378409F85D1C00B85AE4 /* JSEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14E8378309F85D1C00B85AE4 /* JSEvent.cpp */; };
14E8378E09F85D4F00B85AE4 /* JSEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 14E8378D09F85D4F00B85AE4 /* JSEvent.h */; };
- 14EC267F09CA07E000E1EEEC /* EventTargetNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 14EC267D09CA07E000E1EEEC /* EventTargetNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 14EC268009CA07E000E1EEEC /* EventTargetNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */; };
14FFE31D0AE1963300136BF5 /* HTMLFrameElementBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FFE31B0AE1963300136BF5 /* HTMLFrameElementBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
14FFE31E0AE1963300136BF5 /* HTMLFrameElementBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14FFE31C0AE1963300136BF5 /* HTMLFrameElementBase.cpp */; };
+ 185BCF280F3279CE000EA262 /* ThreadTimers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 185BCF260F3279CE000EA262 /* ThreadTimers.cpp */; };
+ 185BCF290F3279CE000EA262 /* ThreadTimers.h in Headers */ = {isa = PBXBuildFile; fileRef = 185BCF270F3279CE000EA262 /* ThreadTimers.h */; };
188604B30F2E654A000B6443 /* DOMTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 188604B10F2E654A000B6443 /* DOMTimer.cpp */; };
188604B40F2E654A000B6443 /* DOMTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 188604B20F2E654A000B6443 /* DOMTimer.h */; };
- 18A0537C0F26859C00A51705 /* WorkerRunLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18A0537A0F26859C00A51705 /* WorkerRunLoop.cpp */; };
- 18A0537D0F26859C00A51705 /* WorkerRunLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 18A0537B0F26859C00A51705 /* WorkerRunLoop.h */; };
1A0D57360A5C77FE007EDD4C /* OverflowEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0D57340A5C77FE007EDD4C /* OverflowEvent.cpp */; };
1A0D57370A5C77FE007EDD4C /* OverflowEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0D57350A5C77FE007EDD4C /* OverflowEvent.h */; };
1A0D57400A5C7867007EDD4C /* JSOverflowEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A0D573E0A5C7867007EDD4C /* JSOverflowEvent.cpp */; };
@@ -273,6 +292,8 @@
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 */; };
1A750D5D0A90DEE1000FF215 /* JSTreeWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A750D5B0A90DEE1000FF215 /* JSTreeWalker.h */; };
1A750D8D0A90E521000FF215 /* JSNodeIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A750D8B0A90E521000FF215 /* JSNodeIterator.cpp */; };
@@ -459,6 +480,8 @@
1C5FAED10DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C5FAECF0DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp */; };
1C5FAED20DCFD90100D58F78 /* JSJavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C5FAED00DCFD90100D58F78 /* JSJavaScriptCallFrame.h */; };
1C5FAEE70DCFDA6800D58F78 /* JSJavaScriptCallFrameCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C5FAEE60DCFDA6800D58F78 /* JSJavaScriptCallFrameCustom.cpp */; };
+ 1C63A2480F71646600C09D5A /* RunLoopTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C63A2460F71646600C09D5A /* RunLoopTimer.h */; };
+ 1C63A2490F71646600C09D5A /* RunLoopTimerCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C63A2470F71646600C09D5A /* RunLoopTimerCF.cpp */; };
1C81B95A0E97330800266E07 /* InspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81B9560E97330800266E07 /* InspectorController.h */; settings = {ATTRIBUTES = (Private, ); }; };
1C81B95B0E97330800266E07 /* InspectorController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C81B9570E97330800266E07 /* InspectorController.cpp */; };
1C81B95C0E97330800266E07 /* InspectorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81B9580E97330800266E07 /* InspectorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -528,6 +551,23 @@
29FFBB830E7C5A3D00407730 /* AccessibilityList.h in Headers */ = {isa = PBXBuildFile; fileRef = 29FFBB810E7C5A3D00407730 /* AccessibilityList.h */; };
2D9066060BE141D400956998 /* LayoutState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2D9066040BE141D400956998 /* LayoutState.cpp */; };
2D9066070BE141D400956998 /* LayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 2D9066050BE141D400956998 /* LayoutState.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 2E4346440F546A8200B0F1BA /* GenericWorkerTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346320F546A8200B0F1BA /* GenericWorkerTask.h */; };
+ 2E4346450F546A8200B0F1BA /* Worker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346330F546A8200B0F1BA /* Worker.cpp */; };
+ 2E4346460F546A8200B0F1BA /* Worker.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346340F546A8200B0F1BA /* Worker.h */; };
+ 2E4346480F546A8200B0F1BA /* WorkerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346360F546A8200B0F1BA /* WorkerContext.cpp */; };
+ 2E4346490F546A8200B0F1BA /* WorkerContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346370F546A8200B0F1BA /* WorkerContext.h */; };
+ 2E43464B0F546A8200B0F1BA /* WorkerContextProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346390F546A8200B0F1BA /* WorkerContextProxy.h */; };
+ 2E43464C0F546A8200B0F1BA /* WorkerLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E43463A0F546A8200B0F1BA /* WorkerLocation.cpp */; };
+ 2E43464D0F546A8200B0F1BA /* WorkerLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E43463B0F546A8200B0F1BA /* WorkerLocation.h */; };
+ 2E43464F0F546A8200B0F1BA /* WorkerMessagingProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E43463D0F546A8200B0F1BA /* WorkerMessagingProxy.cpp */; };
+ 2E4346500F546A8200B0F1BA /* WorkerMessagingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E43463E0F546A8200B0F1BA /* WorkerMessagingProxy.h */; };
+ 2E4346510F546A8200B0F1BA /* WorkerObjectProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E43463F0F546A8200B0F1BA /* WorkerObjectProxy.h */; };
+ 2E4346520F546A8200B0F1BA /* WorkerRunLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346400F546A8200B0F1BA /* WorkerRunLoop.cpp */; };
+ 2E4346530F546A8200B0F1BA /* WorkerRunLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346410F546A8200B0F1BA /* WorkerRunLoop.h */; };
+ 2E4346540F546A8200B0F1BA /* WorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346420F546A8200B0F1BA /* WorkerThread.cpp */; };
+ 2E4346550F546A8200B0F1BA /* WorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346430F546A8200B0F1BA /* WorkerThread.h */; };
+ 2E4346580F546A9900B0F1BA /* CrossThreadCopier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2E4346560F546A9900B0F1BA /* CrossThreadCopier.cpp */; };
+ 2E4346590F546A9900B0F1BA /* CrossThreadCopier.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4346570F546A9900B0F1BA /* CrossThreadCopier.h */; };
31288E720E3005D6003619AE /* WebKitCSSKeyframeRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */; };
31288E730E3005D6003619AE /* WebKitCSSKeyframeRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */; };
31288E740E3005D6003619AE /* WebKitCSSKeyframesRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */; };
@@ -591,12 +631,31 @@
37ACCF690DA414E70089E602 /* FontDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37ACCE620DA2AA960089E602 /* FontDescription.cpp */; };
37F818FD0D657606005E1F05 /* WebCoreURLResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 37F818FB0D657606005E1F05 /* WebCoreURLResponse.h */; settings = {ATTRIBUTES = (Private, ); }; };
37F818FE0D657606005E1F05 /* WebCoreURLResponse.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37F818FC0D657606005E1F05 /* WebCoreURLResponse.mm */; };
+ 41002CCD0F66EDEF009E660D /* ScriptFunctionCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 41002CCB0F66EDEF009E660D /* ScriptFunctionCall.h */; };
+ 41002CCE0F66EDEF009E660D /* ScriptFunctionCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41002CCC0F66EDEF009E660D /* ScriptFunctionCall.cpp */; };
+ 412A68470F6B03DD000EA66E /* ScriptObjectQuarantine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 412A68460F6B03DD000EA66E /* ScriptObjectQuarantine.cpp */; };
416E75BE0EDF8FD700360E1D /* ScriptCallStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 416E75BC0EDF8FD700360E1D /* ScriptCallStack.h */; };
416E75BF0EDF8FD700360E1D /* ScriptCallStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 416E75BD0EDF8FD700360E1D /* ScriptCallStack.cpp */; };
416E75CB0EDF90C700360E1D /* ScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 416E75C90EDF90C700360E1D /* ScriptCallFrame.h */; };
416E75CC0EDF90C700360E1D /* ScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 416E75CA0EDF90C700360E1D /* ScriptCallFrame.cpp */; };
416F45F00ED7B311008215B6 /* ScriptString.h in Headers */ = {isa = PBXBuildFile; fileRef = 416F45EF0ED7B311008215B6 /* ScriptString.h */; };
+ 419536510F68222400D0C679 /* ScriptObjectQuarantine.h in Headers */ = {isa = PBXBuildFile; fileRef = 419536500F68222400D0C679 /* ScriptObjectQuarantine.h */; };
41C760B10EDE03D300C1655F /* ScriptState.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C760B00EDE03D300C1655F /* ScriptState.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 41D015CA0F4B5C71004A662F /* ContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D015C80F4B5C71004A662F /* ContentType.h */; };
+ 41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41D015C90F4B5C71004A662F /* ContentType.cpp */; };
+ 41F060CD0F5EEB2B00A07EAC /* JSInspectorController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F060CB0F5EEB2B00A07EAC /* JSInspectorController.cpp */; };
+ 41F060CE0F5EEB2B00A07EAC /* JSInspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F060CC0F5EEB2B00A07EAC /* JSInspectorController.h */; };
+ 41F0616A0F5EFBDD00A07EAC /* JSInspectorControllerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F061690F5EFBDD00A07EAC /* JSInspectorControllerCustom.cpp */; };
+ 41F061740F5F00AC00A07EAC /* InspectorDOMStorageResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F061720F5F00AC00A07EAC /* InspectorDOMStorageResource.h */; };
+ 41F061750F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F061730F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp */; };
+ 41F0618E0F5F069800A07EAC /* ConsoleMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F0618C0F5F069800A07EAC /* ConsoleMessage.h */; };
+ 41F0618F0F5F069800A07EAC /* ConsoleMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F0618D0F5F069800A07EAC /* ConsoleMessage.cpp */; };
+ 41F062010F5F0B6600A07EAC /* InspectorResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F061FF0F5F0B6600A07EAC /* InspectorResource.h */; };
+ 41F062020F5F0B6600A07EAC /* InspectorResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F062000F5F0B6600A07EAC /* InspectorResource.cpp */; };
+ 41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */; };
+ 41F062150F5F192600A07EAC /* InspectorDatabaseResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */; };
+ 41F066E40F64BCF600A07EAC /* ScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F066E20F64BCF600A07EAC /* ScriptObject.h */; };
+ 41F066E50F64BCF600A07EAC /* ScriptObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F066E30F64BCF600A07EAC /* ScriptObject.cpp */; };
41F1D21F0EF35C2A00DA8753 /* ScriptCachedFrameData.h in Headers */ = {isa = PBXBuildFile; fileRef = 41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */; settings = {ATTRIBUTES = (Private, ); }; };
41F1D2200EF35C2A00DA8753 /* ScriptCachedFrameData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41F1D21E0EF35C2A00DA8753 /* ScriptCachedFrameData.cpp */; };
4415292E0E1AE8A000C4A2D0 /* HTMLPlugInImageElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4415292C0E1AE8A000C4A2D0 /* HTMLPlugInImageElement.h */; };
@@ -621,6 +680,11 @@
46F9D5DD0B0D60170028EE36 /* aliasCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 46F9D5DA0B0D60170028EE36 /* aliasCursor.png */; };
46F9D5DE0B0D60170028EE36 /* noDropCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 46F9D5DB0B0D60170028EE36 /* noDropCursor.png */; };
46F9D5DF0B0D60170028EE36 /* progressCursor.png in Resources */ = {isa = PBXBuildFile; fileRef = 46F9D5DC0B0D60170028EE36 /* progressCursor.png */; };
+ 494BD7950F55C8EE00747828 /* WebKitPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 494BD7930F55C8EE00747828 /* WebKitPoint.h */; };
+ 494BD7990F55C90E00747828 /* JSWebKitPointConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 494BD7970F55C90E00747828 /* JSWebKitPointConstructor.cpp */; };
+ 494BD79A0F55C90E00747828 /* JSWebKitPointConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 494BD7980F55C90E00747828 /* JSWebKitPointConstructor.h */; };
+ 494BD79D0F55C94C00747828 /* JSWebKitPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 494BD79B0F55C94C00747828 /* JSWebKitPoint.cpp */; };
+ 494BD79E0F55C94C00747828 /* JSWebKitPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 494BD79C0F55C94C00747828 /* JSWebKitPoint.h */; };
4983913F0F1E767500C23782 /* JSWebKitCSSMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4983913D0F1E767500C23782 /* JSWebKitCSSMatrix.cpp */; };
498391400F1E767500C23782 /* JSWebKitCSSMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 4983913E0F1E767500C23782 /* JSWebKitCSSMatrix.h */; };
498391500F1E76B400C23782 /* DOMWebKitCSSMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 4983914D0F1E76B400C23782 /* DOMWebKitCSSMatrix.h */; };
@@ -630,6 +694,10 @@
498391590F1E776900C23782 /* WebKitCSSMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 498391560F1E776900C23782 /* WebKitCSSMatrix.h */; };
498391630F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 498391610F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.cpp */; };
498391640F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 498391620F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.h */; };
+ 49D5DC2B0F423A73008F20FD /* Matrix3DTransformOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D5DC270F423A73008F20FD /* Matrix3DTransformOperation.cpp */; };
+ 49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D5DC280F423A73008F20FD /* Matrix3DTransformOperation.h */; };
+ 49D5DC2D0F423A73008F20FD /* PerspectiveTransformOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D5DC290F423A73008F20FD /* PerspectiveTransformOperation.cpp */; };
+ 49D5DC2E0F423A73008F20FD /* PerspectiveTransformOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D5DC2A0F423A73008F20FD /* PerspectiveTransformOperation.h */; };
49E911C30EF86D47009D0CAF /* TransformationMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E911B30EF86D47009D0CAF /* TransformationMatrix.cpp */; };
49E911C40EF86D47009D0CAF /* TransformationMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E911B40EF86D47009D0CAF /* TransformationMatrix.h */; settings = {ATTRIBUTES = (Private, ); }; };
49E911C50EF86D47009D0CAF /* IdentityTransformOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E911B50EF86D47009D0CAF /* IdentityTransformOperation.h */; };
@@ -814,6 +882,8 @@
550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; };
550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
5D874F130D161D3200796C3B /* NetscapePlugInStreamLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93E227DD0AF589AD00D48324 /* NetscapePlugInStreamLoader.cpp */; };
+ 5D925B670F64D4DD00B847F0 /* ScrollBehavior.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D925B650F64D4DD00B847F0 /* ScrollBehavior.cpp */; };
+ 5D925B680F64D4DD00B847F0 /* ScrollBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D925B660F64D4DD00B847F0 /* ScrollBehavior.h */; settings = {ATTRIBUTES = (Private, ); }; };
5DCF836D0D59159800953BC6 /* PluginInfoStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DCF836C0D59159800953BC6 /* PluginInfoStore.h */; };
5DD0A3810D9AC6070056C122 /* DOMElementTimeControl.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = E415F1680D9A165D0033CE97 /* DOMElementTimeControl.h */; };
5DF7F5C20F01F92A00526B4B /* CSSPropertyNames.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 656580EF09D12B20000E61D7 /* CSSPropertyNames.h */; };
@@ -1867,8 +1937,6 @@
93309E07099E64920056E581 /* RemoveNodePreservingChildrenCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DB8099E64910056E581 /* RemoveNodePreservingChildrenCommand.h */; };
93309E09099E64920056E581 /* ReplaceSelectionCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DBA099E64910056E581 /* ReplaceSelectionCommand.cpp */; };
93309E0A099E64920056E581 /* ReplaceSelectionCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DBB099E64910056E581 /* ReplaceSelectionCommand.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 93309E0B099E64920056E581 /* Selection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DBC099E64910056E581 /* Selection.cpp */; };
- 93309E0C099E64920056E581 /* Selection.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DBD099E64910056E581 /* Selection.h */; settings = {ATTRIBUTES = (Private, ); }; };
93309E0D099E64920056E581 /* SelectionController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DBE099E64910056E581 /* SelectionController.cpp */; };
93309E0E099E64920056E581 /* SelectionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 93309DBF099E64910056E581 /* SelectionController.h */; settings = {ATTRIBUTES = (Private, ); }; };
93309E0F099E64920056E581 /* SetNodeAttributeCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309DC0099E64910056E581 /* SetNodeAttributeCommand.cpp */; };
@@ -1933,6 +2001,8 @@
935C477109AC4D7300A6AAB4 /* PlatformMouseEventMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 935C476F09AC4D7300A6AAB4 /* PlatformMouseEventMac.mm */; };
935C477309AC4D7700A6AAB4 /* WheelEventMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 935C477209AC4D7700A6AAB4 /* WheelEventMac.mm */; };
935C477509AC4D8E00A6AAB4 /* GapRects.h in Headers */ = {isa = PBXBuildFile; fileRef = 935C477409AC4D8D00A6AAB4 /* GapRects.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 935F45420F7C3B5F00D7C1FB /* JSLazyEventListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 935F45400F7C3B5F00D7C1FB /* JSLazyEventListener.cpp */; };
+ 935F45430F7C3B5F00D7C1FB /* JSLazyEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 935F45410F7C3B5F00D7C1FB /* JSLazyEventListener.h */; };
935FBC4509BA00B900E230B1 /* EventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 935FBC4409BA00B900E230B1 /* EventListener.h */; };
935FBCF209BA143B00E230B1 /* ExceptionCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 935FBCF109BA143B00E230B1 /* ExceptionCode.h */; };
9362640B0DE1137D009D5A00 /* CSSReflectionDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9362640A0DE1137D009D5A00 /* CSSReflectionDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2005,7 +2075,7 @@
93F198F608245E59001E9ABC /* TextResourceDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D27902DE43D7018635CA /* TextResourceDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1991808245E59001E9ABC /* Range.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D30402DE4476018635CA /* Range.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1992108245E59001E9ABC /* XMLTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = F523D30A02DE4476018635CA /* XMLTokenizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 93F1992F08245E59001E9ABC /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = F587868402DE3B8601EA4122 /* Cursor.h */; };
+ 93F1992F08245E59001E9ABC /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = F587868402DE3B8601EA4122 /* Cursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1994F08245E59001E9ABC /* Settings.h in Headers */ = {isa = PBXBuildFile; fileRef = F587863A02DE3A1401EA4122 /* Settings.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1995008245E59001E9ABC /* CachePolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = F587864902DE3A9A01EA4122 /* CachePolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
93F1996308245E59001E9ABC /* SSLKeyGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = F587866202DE3B1101EA4122 /* SSLKeyGenerator.h */; };
@@ -2061,8 +2131,9 @@
93F9B7A00BA6032600854064 /* JSCDATASection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F9B79E0BA6032600854064 /* JSCDATASection.cpp */; };
93F9B7A10BA6032600854064 /* JSCDATASection.h in Headers */ = {isa = PBXBuildFile; fileRef = 93F9B79F0BA6032600854064 /* JSCDATASection.h */; };
93FDAFCA0B11307400E2746F /* EditorInsertAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 93FDAFC90B11307400E2746F /* EditorInsertAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A17C81220F2A5CF7005DAAEB /* HTMLElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A17C81200F2A5CF7005DAAEB /* HTMLElementFactory.cpp */; };
+ A17C81230F2A5CF7005DAAEB /* HTMLElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A17C81210F2A5CF7005DAAEB /* HTMLElementFactory.h */; };
A7094AFA0F27AE6000596CEC /* CanvasPixelArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7094AF90F27AE6000596CEC /* CanvasPixelArray.cpp */; };
- A7094AFC0F27AEE300596CEC /* CanvasPixelArray.idl in Resources */ = {isa = PBXBuildFile; fileRef = A7094AFB0F27AEE300596CEC /* CanvasPixelArray.idl */; };
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 */; };
@@ -2094,6 +2165,8 @@
A7D0318E0E93540300E24ACD /* JSImageDataCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */; };
A7D27FC40E0A599F0079AD2B /* SVGFETile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D27FC30E0A599F0079AD2B /* SVGFETile.cpp */; };
A7D3C5240B576B4B002CA450 /* PasteboardHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D3C5230B576B4B002CA450 /* PasteboardHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A7D6B3490F61104500B79FD1 /* WorkerImportScriptsClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D6B3470F61104500B79FD1 /* WorkerImportScriptsClient.h */; };
+ A7D6B34A0F61104500B79FD1 /* WorkerImportScriptsClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7D6B3480F61104500B79FD1 /* WorkerImportScriptsClient.cpp */; };
A809F1470B73793A002E4D7F /* RenderSVGGradientStop.h in Headers */ = {isa = PBXBuildFile; fileRef = A809F1450B73793A002E4D7F /* RenderSVGGradientStop.h */; };
A809F1480B73793B002E4D7F /* RenderSVGGradientStop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A809F1460B73793A002E4D7F /* RenderSVGGradientStop.cpp */; };
A809F1AA0B737FB6002E4D7F /* RenderSVGHiddenContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = A809F1A80B737FB6002E4D7F /* RenderSVGHiddenContainer.h */; };
@@ -2416,14 +2489,14 @@
A86629D209DA2B48009633A5 /* JSMouseEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A86629CC09DA2B47009633A5 /* JSMouseEvent.cpp */; };
A86629D309DA2B48009633A5 /* JSKeyboardEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A86629CD09DA2B47009633A5 /* JSKeyboardEvent.h */; };
A86629D409DA2B48009633A5 /* JSKeyboardEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A86629CE09DA2B47009633A5 /* JSKeyboardEvent.cpp */; };
- A871D4560A127CBC00B12A68 /* HTMLPlugInElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D44C0A127CBC00B12A68 /* HTMLPlugInElement.h */; };
+ A871D4560A127CBC00B12A68 /* HTMLPlugInElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D44C0A127CBC00B12A68 /* HTMLPlugInElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
A871D4570A127CBC00B12A68 /* HTMLPlugInElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A871D44D0A127CBC00B12A68 /* HTMLPlugInElement.cpp */; };
A871D4580A127CBC00B12A68 /* HTMLParamElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D44E0A127CBC00B12A68 /* HTMLParamElement.h */; };
A871D4590A127CBC00B12A68 /* HTMLParamElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A871D44F0A127CBC00B12A68 /* HTMLParamElement.cpp */; };
A871D45A0A127CBC00B12A68 /* HTMLObjectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D4500A127CBC00B12A68 /* HTMLObjectElement.h */; };
A871D45B0A127CBC00B12A68 /* HTMLObjectElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A871D4510A127CBC00B12A68 /* HTMLObjectElement.cpp */; };
A871D45C0A127CBC00B12A68 /* HTMLEmbedElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D4520A127CBC00B12A68 /* HTMLEmbedElement.h */; };
- A871D45D0A127CBC00B12A68 /* HTMLAppletElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D4530A127CBC00B12A68 /* HTMLAppletElement.h */; };
+ A871D45D0A127CBC00B12A68 /* HTMLAppletElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871D4530A127CBC00B12A68 /* HTMLAppletElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
A871D45E0A127CBC00B12A68 /* HTMLAppletElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A871D4540A127CBC00B12A68 /* HTMLAppletElement.cpp */; };
A871D45F0A127CBC00B12A68 /* HTMLEmbedElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A871D4550A127CBC00B12A68 /* HTMLEmbedElement.cpp */; };
A871DB250A150BD600B12A68 /* HTMLTableSectionElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A871DB170A150BD600B12A68 /* HTMLTableSectionElement.h */; };
@@ -2476,6 +2549,8 @@
A871DFE30A15376B00B12A68 /* RenderReplaced.h in Headers */ = {isa = PBXBuildFile; fileRef = A871DFDF0A15376B00B12A68 /* RenderReplaced.h */; settings = {ATTRIBUTES = (Private, ); }; };
A871DFE40A15376B00B12A68 /* RenderWidget.h in Headers */ = {isa = PBXBuildFile; fileRef = A871DFE00A15376B00B12A68 /* RenderWidget.h */; settings = {ATTRIBUTES = (Private, ); }; };
A871DFE50A15376B00B12A68 /* RenderWidget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A871DFE10A15376B00B12A68 /* RenderWidget.cpp */; };
+ A883DF270F3D045D00F19BF6 /* VisibleSelection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A883DF250F3D045D00F19BF6 /* VisibleSelection.cpp */; };
+ A883DF280F3D045D00F19BF6 /* VisibleSelection.h in Headers */ = {isa = PBXBuildFile; fileRef = A883DF260F3D045D00F19BF6 /* VisibleSelection.h */; settings = {ATTRIBUTES = (Private, ); }; };
A88AD52F09524B92001DD196 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A85D7A2F0879EBA9006A9172 /* QuartzCore.framework */; };
A88DD4870B4629A300C02990 /* PathTraversalState.h in Headers */ = {isa = PBXBuildFile; fileRef = A88DD4860B4629A300C02990 /* PathTraversalState.h */; };
A88DD4890B4629B000C02990 /* PathTraversalState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A88DD4880B4629B000C02990 /* PathTraversalState.cpp */; };
@@ -2723,8 +2798,6 @@
A8E545C10CA9D1C20097D09B /* DOMSVGDescElementInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E544C30CA9D1C20097D09B /* DOMSVGDescElementInternal.h */; };
A8EA73C30A1900E300A8EF5F /* RenderFieldset.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8EA73AF0A1900E300A8EF5F /* RenderFieldset.cpp */; };
A8EA73C40A1900E300A8EF5F /* RenderFieldset.h in Headers */ = {isa = PBXBuildFile; fileRef = A8EA73B00A1900E300A8EF5F /* RenderFieldset.h */; };
- A8EA73CA0A1900E300A8EF5F /* RenderLegend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8EA73B60A1900E300A8EF5F /* RenderLegend.cpp */; };
- A8EA73D10A1900E300A8EF5F /* RenderLegend.h in Headers */ = {isa = PBXBuildFile; fileRef = A8EA73BD0A1900E300A8EF5F /* RenderLegend.h */; };
A8EA79F10A1916DF00A8EF5F /* HTMLOListElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A8EA79E50A1916DF00A8EF5F /* HTMLOListElement.h */; };
A8EA79F20A1916DF00A8EF5F /* HTMLUListElement.h in Headers */ = {isa = PBXBuildFile; fileRef = A8EA79E60A1916DF00A8EF5F /* HTMLUListElement.h */; };
A8EA79F30A1916DF00A8EF5F /* HTMLUListElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8EA79E70A1916DF00A8EF5F /* HTMLUListElement.cpp */; };
@@ -3233,7 +3306,6 @@
B24055650B5BE640002A28C0 /* DOMSVGElementInstanceInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B24055630B5BE640002A28C0 /* DOMSVGElementInstanceInternal.h */; };
B24055660B5BE640002A28C0 /* DOMSVGElementInstanceListInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B24055640B5BE640002A28C0 /* DOMSVGElementInstanceListInternal.h */; };
B25599350D00D8BA00BB825C /* SVGResourceFilterCg.mm in Sources */ = {isa = PBXBuildFile; fileRef = B25598990D00D8B800BB825C /* SVGResourceFilterCg.mm */; };
- B25599370D00D8BA00BB825C /* SVGResourceMaskerCg.mm in Sources */ = {isa = PBXBuildFile; fileRef = B255989B0D00D8B800BB825C /* SVGResourceMaskerCg.mm */; };
B25599400D00D8BA00BB825C /* SVGFEHelpersCg.h in Headers */ = {isa = PBXBuildFile; fileRef = B25598A60D00D8B800BB825C /* SVGFEHelpersCg.h */; };
B25599410D00D8BA00BB825C /* SVGFEHelpersCg.mm in Sources */ = {isa = PBXBuildFile; fileRef = B25598A70D00D8B800BB825C /* SVGFEHelpersCg.mm */; };
B25599470D00D8BA00BB825C /* SVGFilterEffectCg.mm in Sources */ = {isa = PBXBuildFile; fileRef = B25598AD0D00D8B800BB825C /* SVGFilterEffectCg.mm */; };
@@ -3479,8 +3551,6 @@
B2C3DA400D006C1D00EF6F26 /* TextCodecUserDefined.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA100D006C1D00EF6F26 /* TextCodecUserDefined.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2C3DA410D006C1D00EF6F26 /* TextCodecUTF16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2C3DA110D006C1D00EF6F26 /* TextCodecUTF16.cpp */; };
B2C3DA420D006C1D00EF6F26 /* TextCodecUTF16.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA120D006C1D00EF6F26 /* TextCodecUTF16.h */; settings = {ATTRIBUTES = (Private, ); }; };
- B2C3DA430D006C1D00EF6F26 /* TextDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2C3DA130D006C1D00EF6F26 /* TextDecoder.cpp */; };
- B2C3DA440D006C1D00EF6F26 /* TextDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA140D006C1D00EF6F26 /* TextDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2C3DA450D006C1D00EF6F26 /* TextDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA150D006C1D00EF6F26 /* TextDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2C3DA460D006C1D00EF6F26 /* TextEncoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2C3DA160D006C1D00EF6F26 /* TextEncoding.cpp */; };
B2C3DA470D006C1D00EF6F26 /* TextEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = B2C3DA170D006C1D00EF6F26 /* TextEncoding.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3520,7 +3590,7 @@
B2CCEC480C6CA9F1006A5424 /* RenderSVGViewportContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = B2CCEC460C6CA9F1006A5424 /* RenderSVGViewportContainer.h */; };
B2D3FC8A0C2212CB00CF3618 /* JSSVGTransformListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2D3FC890C2212CB00CF3618 /* JSSVGTransformListCustom.cpp */; };
B2E27C9F0B0F2B0900F17C7B /* FloatPoint3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2E27C9D0B0F2B0900F17C7B /* FloatPoint3D.cpp */; };
- B2E27CA00B0F2B0900F17C7B /* FloatPoint3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B2E27C9E0B0F2B0900F17C7B /* FloatPoint3D.h */; };
+ B2E27CA00B0F2B0900F17C7B /* FloatPoint3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B2E27C9E0B0F2B0900F17C7B /* FloatPoint3D.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2E4EC970D00C22B00432643 /* SVGZoomEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2E4EC940D00C22B00432643 /* SVGZoomEvent.cpp */; };
B2E4EC980D00C22B00432643 /* SVGZoomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = B2E4EC950D00C22B00432643 /* SVGZoomEvent.h */; };
B2EBDC9C0AF77E3400AE4A68 /* SVGRenderTreeAsText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2EBDC9A0AF77E3400AE4A68 /* SVGRenderTreeAsText.cpp */; };
@@ -3830,6 +3900,7 @@
BC23EE920DAED2BC009FDC91 /* CSSImageGeneratorValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC23EE910DAED2BC009FDC91 /* CSSImageGeneratorValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC23F0DB0DAFF4A4009FDC91 /* GeneratedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BC23F0DA0DAFF4A4009FDC91 /* GeneratedImage.h */; };
BC2441C40E8B65D00055320F /* ScrollView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2441C30E8B65D00055320F /* ScrollView.cpp */; };
+ BC2CC8DF0F32881000A9DF26 /* RenderObjectChildList.h in Headers */ = {isa = PBXBuildFile; fileRef = BC2CC8DE0F32881000A9DF26 /* RenderObjectChildList.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC2ED5550C6B9BD300920BFF /* JSElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */; };
BC2ED6500C6BC48C00920BFF /* JSHTMLIFrameElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2ED64F0C6BC48C00920BFF /* JSHTMLIFrameElementCustom.cpp */; };
BC2ED6BC0C6BD2F000920BFF /* JSAttrCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */; };
@@ -3837,6 +3908,7 @@
BC305C790C076BB300CD20F0 /* JSHTMLObjectElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC305C770C076BB300CD20F0 /* JSHTMLObjectElement.cpp */; };
BC305C7A0C076BB300CD20F0 /* JSHTMLObjectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = BC305C780C076BB300CD20F0 /* JSHTMLObjectElement.h */; };
BC305CA40C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC305CA30C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp */; };
+ BC33FB1B0F30EE85002CDD7C /* RenderLineBoxList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC33FB1A0F30EE85002CDD7C /* RenderLineBoxList.cpp */; };
BC3452430D7E00EA0016574A /* JSRGBColor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3452410D7E00EA0016574A /* JSRGBColor.cpp */; };
BC3452440D7E00EA0016574A /* JSRGBColor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3452420D7E00EA0016574A /* JSRGBColor.h */; };
BC3452560D7E02850016574A /* JSRGBColor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3452550D7E02850016574A /* JSRGBColor.lut.h */; };
@@ -3845,9 +3917,6 @@
BC348BD40DB7F804004ABAB9 /* JSXMLHttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = BC348BD20DB7F804004ABAB9 /* JSXMLHttpRequest.h */; };
BC348BE90DB80354004ABAB9 /* JSXMLHttpRequestConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC348BE70DB80354004ABAB9 /* JSXMLHttpRequestConstructor.cpp */; };
BC348BEA0DB80354004ABAB9 /* JSXMLHttpRequestConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC348BE80DB80354004ABAB9 /* JSXMLHttpRequestConstructor.h */; };
- BC3B7AF30E919CA900D54065 /* JSEventTargetNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3B7AF10E919CA900D54065 /* JSEventTargetNode.cpp */; };
- BC3B7AF40E919CA900D54065 /* JSEventTargetNode.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3B7AF20E919CA900D54065 /* JSEventTargetNode.h */; };
- BC3B7B210E91AAF400D54065 /* JSEventTargetNodeCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3B7B200E91AAF400D54065 /* JSEventTargetNodeCustom.cpp */; };
BC3BC29C0E91AB0F00835588 /* HostWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3BC29B0E91AB0F00835588 /* HostWindow.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC3BE12B0E98092F00835588 /* PopupMenuStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */; settings = {ATTRIBUTES = (Private, ); }; };
BC3BE9930E9C1C7C00835588 /* RenderScrollbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3BE9900E9C1C7C00835588 /* RenderScrollbar.cpp */; };
@@ -3955,6 +4024,7 @@
BC60DA5B0D2A31F700B9918F /* XPathException.h in Headers */ = {isa = PBXBuildFile; fileRef = BC60DA590D2A31F700B9918F /* XPathException.h */; };
BC60DB490D2A3D1E00B9918F /* JSXPathException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */; };
BC60DB4A0D2A3D1E00B9918F /* JSXPathException.h in Headers */ = {isa = PBXBuildFile; fileRef = BC60DB480D2A3D1E00B9918F /* JSXPathException.h */; };
+ BC60EFB70F33A0E700812A93 /* RenderObjectChildList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */; };
BC64B4CB0CB4295D005F2B62 /* CachedFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */; };
BC64B4CC0CB4295D005F2B62 /* CachedFont.h in Headers */ = {isa = PBXBuildFile; fileRef = BC64B4CA0CB4295D005F2B62 /* CachedFont.h */; };
BC64B4D50CB4298A005F2B62 /* CSSFontFace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC64B4CD0CB4298A005F2B62 /* CSSFontFace.cpp */; };
@@ -4028,6 +4098,8 @@
BC94D14F0C275C68006BC617 /* JSHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = BC94D14D0C275C68006BC617 /* JSHistory.h */; };
BC94D1530C275C8B006BC617 /* History.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC94D1500C275C8B006BC617 /* History.cpp */; };
BC94D1540C275C8B006BC617 /* History.h in Headers */ = {isa = PBXBuildFile; fileRef = BC94D1510C275C8B006BC617 /* History.h */; };
+ BC96DB430F3A880E00573CB3 /* RenderBoxModelObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BC96DB420F3A880E00573CB3 /* RenderBoxModelObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BC96DB460F3A882200573CB3 /* RenderBoxModelObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC96DB450F3A882200573CB3 /* RenderBoxModelObject.cpp */; };
BC98543D0CD3D98B00069BC1 /* JSConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC98543B0CD3D98B00069BC1 /* JSConsole.cpp */; };
BC98543E0CD3D98C00069BC1 /* JSConsole.h in Headers */ = {isa = PBXBuildFile; fileRef = BC98543C0CD3D98B00069BC1 /* JSConsole.h */; };
BC98A27D0C0C9950004BEBF7 /* JSStyleSheetCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC98A27C0C0C9950004BEBF7 /* JSStyleSheetCustom.cpp */; };
@@ -4074,6 +4146,14 @@
BCBD21AB0E417AD400A070F2 /* KURLHash.h in Headers */ = {isa = PBXBuildFile; fileRef = BCBD21AA0E417AD400A070F2 /* KURLHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCBFB53C0DCD29CF0019B3E5 /* JSDOMWindowShell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCBFB53A0DCD29CF0019B3E5 /* JSDOMWindowShell.cpp */; };
BCBFB53D0DCD29CF0019B3E5 /* JSDOMWindowShell.h in Headers */ = {isa = PBXBuildFile; fileRef = BCBFB53B0DCD29CF0019B3E5 /* JSDOMWindowShell.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ BCC0657D0F3CE1B700CD2D87 /* ClientRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC065770F3CE1B700CD2D87 /* ClientRect.cpp */; };
+ BCC0657E0F3CE1B700CD2D87 /* ClientRect.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC065780F3CE1B700CD2D87 /* ClientRect.h */; };
+ BCC065800F3CE1B700CD2D87 /* ClientRectList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC0657A0F3CE1B700CD2D87 /* ClientRectList.cpp */; };
+ BCC065810F3CE1B700CD2D87 /* ClientRectList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC0657B0F3CE1B700CD2D87 /* ClientRectList.h */; };
+ BCC065870F3CE2A700CD2D87 /* JSClientRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC065830F3CE2A700CD2D87 /* JSClientRect.cpp */; };
+ BCC065880F3CE2A700CD2D87 /* JSClientRect.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC065840F3CE2A700CD2D87 /* JSClientRect.h */; };
+ BCC065890F3CE2A700CD2D87 /* JSClientRectList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC065850F3CE2A700CD2D87 /* JSClientRectList.cpp */; };
+ BCC0658A0F3CE2A700CD2D87 /* JSClientRectList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC065860F3CE2A700CD2D87 /* JSClientRectList.h */; };
BCC438780E886CC700533DD5 /* JSHTMLInputElementCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCC438770E886CC700533DD5 /* JSHTMLInputElementCustom.cpp */; };
BCC573350D695BBE006EF517 /* DOMProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC573330D695BBE006EF517 /* DOMProgressEvent.h */; };
BCC573360D695BBE006EF517 /* DOMProgressEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCC573340D695BBE006EF517 /* DOMProgressEvent.mm */; };
@@ -4133,6 +4213,8 @@
BCE1C4400D9830F4003B02F2 /* JSLocationCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */; };
BCE3BEC20D222B1D007E06E4 /* TagNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE3BEC00D222B1D007E06E4 /* TagNodeList.cpp */; };
BCE3BEC30D222B1D007E06E4 /* TagNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE3BEC10D222B1D007E06E4 /* TagNodeList.h */; };
+ BCE494AB0F4F5E9E0084E319 /* GeolocationServiceMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE494A90F4F5E9E0084E319 /* GeolocationServiceMac.h */; settings = {ATTRIBUTES = (); }; };
+ BCE494AC0F4F5E9E0084E319 /* GeolocationServiceMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCE494AA0F4F5E9E0084E319 /* GeolocationServiceMac.mm */; };
BCE658FF0EA9248A007E4533 /* Theme.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE658FE0EA9248A007E4533 /* Theme.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCE659A90EA927B9007E4533 /* ThemeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE659A80EA927B9007E4533 /* ThemeTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCE659E60EA92FB2007E4533 /* ThemeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE659E50EA92FB2007E4533 /* ThemeMac.h */; };
@@ -4167,12 +4249,8 @@
BCEA4868097D93020094C9E4 /* RenderView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4829097D93020094C9E4 /* RenderView.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEA4869097D93020094C9E4 /* RenderHTMLCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA482A097D93020094C9E4 /* RenderHTMLCanvas.cpp */; };
BCEA486A097D93020094C9E4 /* RenderHTMLCanvas.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA482B097D93020094C9E4 /* RenderHTMLCanvas.h */; };
- BCEA486B097D93020094C9E4 /* RenderContainer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA482C097D93020094C9E4 /* RenderContainer.cpp */; };
- BCEA486C097D93020094C9E4 /* RenderContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA482D097D93020094C9E4 /* RenderContainer.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEA486D097D93020094C9E4 /* RenderFlexibleBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA482E097D93020094C9E4 /* RenderFlexibleBox.cpp */; };
BCEA486E097D93020094C9E4 /* RenderFlexibleBox.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA482F097D93020094C9E4 /* RenderFlexibleBox.h */; };
- BCEA486F097D93020094C9E4 /* RenderFlow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4830097D93020094C9E4 /* RenderFlow.cpp */; };
- BCEA4870097D93020094C9E4 /* RenderFlow.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4831097D93020094C9E4 /* RenderFlow.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEA4875097D93020094C9E4 /* RenderImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4836097D93020094C9E4 /* RenderImage.cpp */; };
BCEA4876097D93020094C9E4 /* RenderImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEA4837097D93020094C9E4 /* RenderImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEA4877097D93020094C9E4 /* RenderInline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEA4838097D93020094C9E4 /* RenderInline.cpp */; };
@@ -4194,8 +4272,6 @@
BCEC01C20C274DDD009F4EC9 /* JSScreen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEC01C00C274DDD009F4EC9 /* JSScreen.cpp */; };
BCEC01C30C274DDD009F4EC9 /* JSScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEC01C10C274DDD009F4EC9 /* JSScreen.h */; };
BCEC01D70C274EB4009F4EC9 /* PlatformScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEC01D60C274EB4009F4EC9 /* PlatformScreen.h */; settings = {ATTRIBUTES = (Private, ); }; };
- BCEF3434087B563E00BBF833 /* HTMLElementFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEF3432087B563E00BBF833 /* HTMLElementFactory.cpp */; };
- BCEF3435087B563E00BBF833 /* HTMLElementFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEF3433087B563E00BBF833 /* HTMLElementFactory.h */; };
BCEF43CF0E673DA1001C1287 /* StyleImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEF43CE0E673DA1001C1287 /* StyleImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEF43DD0E674012001C1287 /* NinePieceImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEF43DC0E674012001C1287 /* NinePieceImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
BCEF43E00E674110001C1287 /* NinePieceImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEF43DF0E674110001C1287 /* NinePieceImage.cpp */; };
@@ -4227,6 +4303,8 @@
C091588E0DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C09158880DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp */; };
C091588F0DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = C09158890DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h */; };
C0DFC8700DB6841A003EAE7C /* JSConsoleCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0DFC86F0DB6841A003EAE7C /* JSConsoleCustom.cpp */; };
+ C105DA620F3AA68F001DD44F /* TextEncodingDetectorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C105DA610F3AA68F001DD44F /* TextEncodingDetectorICU.cpp */; };
+ C105DA640F3AA6B8001DD44F /* TextEncodingDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */; };
C6D74AD509AA282E000B0A52 /* ModifySelectionListLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */; };
C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
D05CED290A40BB2C00C5AF38 /* FormatBlockCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */; };
@@ -4252,8 +4330,6 @@
E107400E0E77BDC00033AF24 /* JSMessageChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = E107400C0E77BDC00033AF24 /* JSMessageChannel.h */; };
E10743240E7835830033AF24 /* JSMessageChannelConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E10743230E7835830033AF24 /* JSMessageChannelConstructor.cpp */; };
E10743270E7835A50033AF24 /* JSMessageChannelConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E10743260E7835A50033AF24 /* JSMessageChannelConstructor.h */; };
- E108224B0EC3153A00E93953 /* WorkerTask.h in Headers */ = {isa = PBXBuildFile; fileRef = E108224A0EC3153A00E93953 /* WorkerTask.h */; };
- E108224F0EC3156700E93953 /* WorkerTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E108224E0EC3156700E93953 /* WorkerTask.cpp */; };
E10B937C0B73C00A003ED890 /* JSCustomXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E10B937B0B73C00A003ED890 /* JSCustomXPathNSResolver.h */; };
E10B93C30B73C291003ED890 /* JSCustomXPathNSResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E10B93C20B73C291003ED890 /* JSCustomXPathNSResolver.cpp */; };
E10B9B6C0B747599003ED890 /* NativeXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E10B9B6A0B747599003ED890 /* NativeXPathNSResolver.h */; };
@@ -4274,14 +4350,11 @@
E1271A590EEECDE400F61213 /* JSWorkerNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1271A570EEECDE400F61213 /* JSWorkerNavigator.cpp */; };
E12EDB7B0B308A78002704B6 /* EventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = E12EDB7A0B308A78002704B6 /* EventTarget.h */; settings = {ATTRIBUTES = (Private, ); }; };
E12EDBEA0B308E0B002704B6 /* EventTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E12EDBE90B308E0B002704B6 /* EventTarget.cpp */; };
- E14799A70ECDE3A400292BF3 /* WorkerMessagingProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = E14799A60ECDE3A400292BF3 /* WorkerMessagingProxy.h */; };
- E14799B40ECDE9D800292BF3 /* WorkerMessagingProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E14799B30ECDE9D800292BF3 /* WorkerMessagingProxy.cpp */; };
E17A4A1B0D97991D00FC10C6 /* DOMSVGAltGlyphElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 65AA6BAC0D974A00000541AE /* DOMSVGAltGlyphElement.h */; };
E17A4A1C0D97991D00FC10C6 /* DOMSVGAltGlyphElementInternal.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 65AA6BAE0D974A00000541AE /* DOMSVGAltGlyphElementInternal.h */; };
E181B2570F14C1A600FB7847 /* JSDOMStringListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E181B2560F14C1A600FB7847 /* JSDOMStringListCustom.cpp */; };
E181B3510F15008A00FB7847 /* StaticStringList.h in Headers */ = {isa = PBXBuildFile; fileRef = E181B3500F15008A00FB7847 /* StaticStringList.h */; };
E181B3560F1500D700FB7847 /* StaticStringList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E181B3550F1500D700FB7847 /* StaticStringList.cpp */; };
- E182504F0ED2F20200499A8F /* FrameLoaderClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E182504E0ED2F20200499A8F /* FrameLoaderClient.cpp */; };
E182568F0EF2B02D00933242 /* JSWorkerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E182568D0EF2B02D00933242 /* JSWorkerContext.cpp */; };
E18256900EF2B02D00933242 /* JSWorkerContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E182568E0EF2B02D00933242 /* JSWorkerContext.h */; };
E18258AC0EF3CD7000933242 /* JSWorkerContextCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18258AB0EF3CD7000933242 /* JSWorkerContextCustom.cpp */; };
@@ -4303,23 +4376,19 @@
E1ADEDDB0E76BD93004A1A5E /* JSMessagePort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */; };
E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */; };
E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */; };
- E1C2C4240EACE0BC007E61FB /* WorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C2C4230EACE0BC007E61FB /* WorkerThread.h */; };
- E1C2C4290EACE0E0007E61FB /* WorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C2C4280EACE0E0007E61FB /* WorkerThread.cpp */; };
- E1C2C43E0EAD0133007E61FB /* WorkerContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C2C43D0EAD0133007E61FB /* WorkerContext.h */; };
- E1C2C4420EAD017B007E61FB /* WorkerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C2C4410EAD017B007E61FB /* WorkerContext.cpp */; };
E1C362EF0EAF2AA9007410BC /* JSWorkerLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C362ED0EAF2AA9007410BC /* JSWorkerLocation.h */; };
E1C362F00EAF2AA9007410BC /* JSWorkerLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C362EE0EAF2AA9007410BC /* JSWorkerLocation.cpp */; };
- E1C363010EAF2CC6007410BC /* WorkerLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C363000EAF2CC6007410BC /* WorkerLocation.h */; };
- E1C363060EAF2D07007410BC /* WorkerLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C363050EAF2D07007410BC /* WorkerLocation.cpp */; };
E1C36C030EB076D6007410BC /* JSDOMGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C36C020EB076D6007410BC /* JSDOMGlobalObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1C36CBD0EB08062007410BC /* JSDOMGlobalObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C36CBC0EB08062007410BC /* JSDOMGlobalObject.cpp */; };
E1C36D340EB0A094007410BC /* JSWorkerContextBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C36D320EB0A094007410BC /* JSWorkerContextBase.cpp */; };
E1C36D350EB0A094007410BC /* JSWorkerContextBase.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C36D330EB0A094007410BC /* JSWorkerContextBase.h */; };
+ E1C415DA0F655D6F0092D2FB /* CrossOriginPreflightResultCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C415D90F655D6F0092D2FB /* CrossOriginPreflightResultCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E1C415DE0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */; };
+ E1C416120F6562FD0092D2FB /* CrossOriginAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */; };
+ E1C416170F6563180092D2FB /* CrossOriginAccessControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C416160F6563180092D2FB /* CrossOriginAccessControl.cpp */; };
E1C4DE690EA75C1E0023CCD6 /* ActiveDOMObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */; };
E1C4DE6E0EA75C650023CCD6 /* ActiveDOMObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */; };
E1C8BE5D0E8BD15A0064CB7D /* JSWorker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C8BE5C0E8BD15A0064CB7D /* JSWorker.cpp */; };
- E1CA5CA00E8CD73B00E8EF90 /* Worker.h in Headers */ = {isa = PBXBuildFile; fileRef = E1CA5C9F0E8CD73B00E8EF90 /* Worker.h */; };
- E1CA5CA50E8CD78500E8EF90 /* Worker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1CA5CA40E8CD78500E8EF90 /* Worker.cpp */; };
E1CA5CBC0E8CDCAF00E8EF90 /* JSWorkerCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1CA5CBB0E8CDCAF00E8EF90 /* JSWorkerCustom.cpp */; };
E1CA5CD30E8CDE8000E8EF90 /* JSWorkerConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E1CA5CD20E8CDE8000E8EF90 /* JSWorkerConstructor.h */; };
E1CA5CD60E8CDEE900E8EF90 /* JSWorkerConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1CA5CD50E8CDEE900E8EF90 /* JSWorkerConstructor.cpp */; };
@@ -4339,7 +4408,7 @@
E44613A10CD6331000FADA75 /* HTMLAudioElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E446138F0CD6331000FADA75 /* HTMLAudioElement.cpp */; };
E44613A20CD6331000FADA75 /* HTMLAudioElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E44613900CD6331000FADA75 /* HTMLAudioElement.h */; };
E44613A40CD6331000FADA75 /* HTMLMediaElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44613920CD6331000FADA75 /* HTMLMediaElement.cpp */; };
- E44613A50CD6331000FADA75 /* HTMLMediaElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E44613930CD6331000FADA75 /* HTMLMediaElement.h */; };
+ E44613A50CD6331000FADA75 /* HTMLMediaElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E44613930CD6331000FADA75 /* HTMLMediaElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
E44613A70CD6331000FADA75 /* HTMLSourceElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44613950CD6331000FADA75 /* HTMLSourceElement.cpp */; };
E44613A80CD6331000FADA75 /* HTMLSourceElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E44613960CD6331000FADA75 /* HTMLSourceElement.h */; };
E44613AA0CD6331000FADA75 /* HTMLVideoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E44613980CD6331000FADA75 /* HTMLVideoElement.cpp */; };
@@ -4349,7 +4418,7 @@
E44613B00CD6331000FADA75 /* TimeRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = E446139E0CD6331000FADA75 /* TimeRanges.h */; };
E44613B60CD6344E00FADA75 /* VoidCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = E44613B40CD6344E00FADA75 /* VoidCallback.h */; };
E44613E30CD6819F00FADA75 /* MediaPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B41E0C0CBF90BD00AF2ECE /* MediaPlayer.cpp */; };
- E44613E40CD681A200FADA75 /* MediaPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4B41E0D0CBF90BD00AF2ECE /* MediaPlayer.h */; };
+ E44613E40CD681A200FADA75 /* MediaPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4B41E0D0CBF90BD00AF2ECE /* MediaPlayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
E44613E50CD681A600FADA75 /* MediaPlayerPrivateQTKit.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4B41E110CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.mm */; };
E44613E60CD681A900FADA75 /* MediaPlayerPrivateQTKit.h in Headers */ = {isa = PBXBuildFile; fileRef = E4B41E100CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.h */; };
E44613EB0CD681B400FADA75 /* ProgressEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B41E010CBF8EAA00AF2ECE /* ProgressEvent.cpp */; };
@@ -4397,19 +4466,24 @@
F916C48D0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F916C48B0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.cpp */; };
F916C48E0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F916C48C0DB510F80076CD83 /* JSXMLHttpRequestProgressEvent.h */; };
F9F0ED7A0DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F9F0ED770DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h */; };
+ FE6FD4870F676E5700092873 /* Coordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD4840F676E5700092873 /* Coordinates.cpp */; };
+ FE6FD4880F676E5700092873 /* Coordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD4850F676E5700092873 /* Coordinates.h */; };
+ FE6FD4890F676E5700092873 /* Coordinates.idl in Resources */ = {isa = PBXBuildFile; fileRef = FE6FD4860F676E5700092873 /* Coordinates.idl */; };
+ FE6FD48D0F676E9300092873 /* JSCoordinates.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */; };
+ FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6FD48C0F676E9300092873 /* JSCoordinates.h */; };
FE80D7A70E9C1ED2000D6F75 /* JSCustomPositionCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7A20E9C1ED2000D6F75 /* JSCustomPositionCallback.cpp */; };
FE80D7A80E9C1ED2000D6F75 /* JSCustomPositionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7A30E9C1ED2000D6F75 /* JSCustomPositionCallback.h */; };
FE80D7A90E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7A40E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.cpp */; };
FE80D7AA0E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7A50E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.h */; };
FE80D7AB0E9C1ED2000D6F75 /* JSGeolocationCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */; };
FE80D7C50E9C1F25000D6F75 /* Geolocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7B70E9C1F25000D6F75 /* Geolocation.cpp */; };
- FE80D7C60E9C1F25000D6F75 /* Geolocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7B80E9C1F25000D6F75 /* Geolocation.h */; settings = {ATTRIBUTES = (); }; };
+ FE80D7C60E9C1F25000D6F75 /* Geolocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7B80E9C1F25000D6F75 /* Geolocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE80D7C80E9C1F25000D6F75 /* Geoposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80D7BA0E9C1F25000D6F75 /* Geoposition.cpp */; };
FE80D7C90E9C1F25000D6F75 /* Geoposition.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BB0E9C1F25000D6F75 /* Geoposition.h */; };
- FE80D7CB0E9C1F25000D6F75 /* PositionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BD0E9C1F25000D6F75 /* PositionCallback.h */; };
+ FE80D7CB0E9C1F25000D6F75 /* PositionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BD0E9C1F25000D6F75 /* PositionCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE80D7CD0E9C1F25000D6F75 /* PositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7BF0E9C1F25000D6F75 /* PositionError.h */; };
- FE80D7CF0E9C1F25000D6F75 /* PositionErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7C10E9C1F25000D6F75 /* PositionErrorCallback.h */; };
- FE80D7D10E9C1F25000D6F75 /* PositionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7C30E9C1F25000D6F75 /* PositionOptions.h */; };
+ FE80D7CF0E9C1F25000D6F75 /* PositionErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7C10E9C1F25000D6F75 /* PositionErrorCallback.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FE80D7D10E9C1F25000D6F75 /* PositionOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80D7C30E9C1F25000D6F75 /* PositionOptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE80DA630E9C4703000D6F75 /* JSGeolocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */; };
FE80DA640E9C4703000D6F75 /* JSGeolocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA600E9C4703000D6F75 /* JSGeolocation.h */; };
FE80DA650E9C4703000D6F75 /* JSGeoposition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA610E9C4703000D6F75 /* JSGeoposition.cpp */; };
@@ -4417,7 +4491,7 @@
FE80DA710E9C472F000D6F75 /* JSPositionError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE80DA6D0E9C472F000D6F75 /* JSPositionError.cpp */; };
FE80DA720E9C472F000D6F75 /* JSPositionError.h in Headers */ = {isa = PBXBuildFile; fileRef = FE80DA6E0E9C472F000D6F75 /* JSPositionError.h */; };
FEAB90120EA51B9C006348C3 /* GeolocationService.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEAB90100EA51B9C006348C3 /* GeolocationService.cpp */; };
- FEAB90130EA51B9C006348C3 /* GeolocationService.h in Headers */ = {isa = PBXBuildFile; fileRef = FEAB90110EA51B9C006348C3 /* GeolocationService.h */; };
+ FEAB90130EA51B9C006348C3 /* GeolocationService.h in Headers */ = {isa = PBXBuildFile; fileRef = FEAB90110EA51B9C006348C3 /* GeolocationService.h */; settings = {ATTRIBUTES = (Private, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -4889,6 +4963,8 @@
06E81ED60AB5D5E900C87837 /* LocalCurrentGraphicsContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalCurrentGraphicsContext.h; sourceTree = "<group>"; };
06E81EEB0AB5DA9700C87837 /* LocalCurrentGraphicsContext.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = LocalCurrentGraphicsContext.mm; sourceTree = "<group>"; };
070DD8F50F01868000727DEB /* mediaControls.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = mediaControls.css; sourceTree = "<group>"; };
+ 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerProxy.h; sourceTree = "<group>"; };
+ 079F5E4B0F3BEBEA005E0782 /* MediaPlayerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerPrivate.h; sourceTree = "<group>"; };
07AFE5900F1446BD00841617 /* mediaControlsQT.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = mediaControlsQT.css; sourceTree = "<group>"; };
080081940ED3B2DD00C53BC0 /* WMLAnchorElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLAnchorElement.cpp; sourceTree = "<group>"; };
080081950ED3B2DD00C53BC0 /* WMLAnchorElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLAnchorElement.h; sourceTree = "<group>"; };
@@ -4981,12 +5057,32 @@
0B9056170F2578BE0095FF6A /* ThreadableLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadableLoader.h; sourceTree = "<group>"; };
0B9056180F2578BE0095FF6A /* ThreadableLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadableLoaderClient.h; sourceTree = "<group>"; };
0B90561D0F257E930095FF6A /* ThreadableLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadableLoader.cpp; sourceTree = "<group>"; };
- 0BA5D3850F240FB4009B870B /* GenericWorkerTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GenericWorkerTask.h; sourceTree = "<group>"; };
+ 0B9056F60F2685F30095FF6A /* WorkerThreadableLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerThreadableLoader.cpp; sourceTree = "<group>"; };
+ 0B9056F70F2685F30095FF6A /* WorkerThreadableLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerThreadableLoader.h; sourceTree = "<group>"; };
+ 0BE030A10F3112FB003C1A46 /* RenderLineBoxList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderLineBoxList.h; sourceTree = "<group>"; };
+ 0F11A54E0F39233100C37884 /* RenderSelectionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSelectionInfo.h; sourceTree = "<group>"; };
+ 0F15DA890F3AAEE70000CE47 /* AnimationControllerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationControllerPrivate.h; path = animation/AnimationControllerPrivate.h; sourceTree = "<group>"; };
+ 0F500AAE0F54DB1B00EEF928 /* TransformState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformState.h; sourceTree = "<group>"; };
+ 0F500AB00F54DB3100EEF928 /* TransformState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformState.cpp; sourceTree = "<group>"; };
0F56028D0E4B76580065B038 /* RenderMarquee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMarquee.h; sourceTree = "<group>"; };
0F56028E0E4B76580065B038 /* RenderMarquee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMarquee.cpp; sourceTree = "<group>"; };
+ 0F580B030F12A2540051D689 /* GraphicsLayerCA.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GraphicsLayerCA.mm; sourceTree = "<group>"; };
+ 0F580B040F12A2550051D689 /* GraphicsLayerCA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsLayerCA.h; sourceTree = "<group>"; };
+ 0F580B090F12A2690051D689 /* GraphicsLayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsLayer.cpp; sourceTree = "<group>"; };
+ 0F580B0A0F12A2690051D689 /* GraphicsLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsLayer.h; sourceTree = "<group>"; };
+ 0F580B0B0F12A2690051D689 /* GraphicsLayerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsLayerClient.h; sourceTree = "<group>"; };
+ 0F580CF90F12DE9B0051D689 /* RenderLayerCompositor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderLayerCompositor.h; sourceTree = "<group>"; };
+ 0F580CFA0F12DE9B0051D689 /* RenderLayerCompositor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLayerCompositor.cpp; sourceTree = "<group>"; };
+ 0F580CFB0F12DE9B0051D689 /* RenderLayerBacking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderLayerBacking.h; sourceTree = "<group>"; };
+ 0F580CFC0F12DE9B0051D689 /* RenderLayerBacking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLayerBacking.cpp; sourceTree = "<group>"; };
0F6ECD430F252F3700BDE271 /* CSSPropertyLonghand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPropertyLonghand.h; sourceTree = "<group>"; };
0F6ECD440F252F3700BDE271 /* CSSPropertyLonghand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSPropertyLonghand.cpp; sourceTree = "<group>"; };
0FC705200EB1815600B90AD8 /* AtomicStringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicStringHash.h; sourceTree = "<group>"; };
+ 0FCF33230F2B9715004B6795 /* ColorCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorCG.cpp; sourceTree = "<group>"; };
+ 0FCF33280F2B9A25004B6795 /* WebTiledLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebTiledLayer.mm; sourceTree = "<group>"; };
+ 0FCF33290F2B9A25004B6795 /* WebTiledLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebTiledLayer.h; sourceTree = "<group>"; };
+ 0FCF332A0F2B9A25004B6795 /* WebLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebLayer.mm; sourceTree = "<group>"; };
+ 0FCF332B0F2B9A25004B6795 /* WebLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebLayer.h; sourceTree = "<group>"; };
0FD723800EC8BD9300CA5DD7 /* FloatQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatQuad.h; sourceTree = "<group>"; };
0FD723810EC8BD9300CA5DD7 /* FloatQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FloatQuad.cpp; sourceTree = "<group>"; };
1402645D0AFDC19B005919E2 /* LoggingMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = LoggingMac.mm; sourceTree = "<group>"; };
@@ -5031,14 +5127,12 @@
14E836D209F8512000B85AE4 /* Event.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Event.idl; sourceTree = "<group>"; };
14E8378309F85D1C00B85AE4 /* JSEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSEvent.cpp; sourceTree = "<group>"; };
14E8378D09F85D4F00B85AE4 /* JSEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSEvent.h; sourceTree = "<group>"; };
- 14EC267D09CA07E000E1EEEC /* EventTargetNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTargetNode.h; sourceTree = "<group>"; };
- 14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTargetNode.cpp; sourceTree = "<group>"; };
14FFE31B0AE1963300136BF5 /* HTMLFrameElementBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLFrameElementBase.h; sourceTree = "<group>"; };
14FFE31C0AE1963300136BF5 /* HTMLFrameElementBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLFrameElementBase.cpp; sourceTree = "<group>"; };
+ 185BCF260F3279CE000EA262 /* ThreadTimers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadTimers.cpp; sourceTree = "<group>"; };
+ 185BCF270F3279CE000EA262 /* ThreadTimers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadTimers.h; sourceTree = "<group>"; };
188604B10F2E654A000B6443 /* DOMTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMTimer.cpp; sourceTree = "<group>"; };
188604B20F2E654A000B6443 /* DOMTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMTimer.h; sourceTree = "<group>"; };
- 18A0537A0F26859C00A51705 /* WorkerRunLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerRunLoop.cpp; sourceTree = "<group>"; };
- 18A0537B0F26859C00A51705 /* WorkerRunLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerRunLoop.h; sourceTree = "<group>"; };
1A0D57340A5C77FE007EDD4C /* OverflowEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = OverflowEvent.cpp; sourceTree = "<group>"; };
1A0D57350A5C77FE007EDD4C /* OverflowEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = OverflowEvent.h; sourceTree = "<group>"; };
1A0D57380A5C7812007EDD4C /* OverflowEvent.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = OverflowEvent.idl; sourceTree = "<group>"; };
@@ -5133,6 +5227,8 @@
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>"; };
1A750D5A0A90DEE1000FF215 /* JSTreeWalker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSTreeWalker.cpp; sourceTree = "<group>"; };
1A750D5B0A90DEE1000FF215 /* JSTreeWalker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSTreeWalker.h; sourceTree = "<group>"; };
@@ -5150,10 +5246,6 @@
1A762C700A074F2600989F5B /* JSXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXPathNSResolver.h; sourceTree = "<group>"; };
1A762C710A074F2600989F5B /* JSXPathResult.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathResult.cpp; sourceTree = "<group>"; };
1A762C720A074F2600989F5B /* JSXPathResult.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXPathResult.h; sourceTree = "<group>"; };
- 1A7CCB0C0CD9462C00B7B64E /* SQLStatementCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLStatementCallback.idl; sourceTree = "<group>"; };
- 1A7CCB0D0CD9462C00B7B64E /* SQLStatementErrorCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLStatementErrorCallback.idl; sourceTree = "<group>"; };
- 1A7CCB0E0CD9462C00B7B64E /* SQLTransactionCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLTransactionCallback.idl; sourceTree = "<group>"; };
- 1A7CCB0F0CD9462C00B7B64E /* SQLTransactionErrorCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLTransactionErrorCallback.idl; sourceTree = "<group>"; };
1A7CCB150CD9469A00B7B64E /* SQLStatementCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLStatementCallback.h; sourceTree = "<group>"; };
1A7CCB160CD9469A00B7B64E /* SQLStatementErrorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLStatementErrorCallback.h; sourceTree = "<group>"; };
1A7CCB170CD9469A00B7B64E /* SQLTransactionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLTransactionCallback.h; sourceTree = "<group>"; };
@@ -5344,6 +5436,8 @@
1C5FAECF0DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJavaScriptCallFrame.cpp; sourceTree = "<group>"; };
1C5FAED00DCFD90100D58F78 /* JSJavaScriptCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSJavaScriptCallFrame.h; sourceTree = "<group>"; };
1C5FAEE60DCFDA6800D58F78 /* JSJavaScriptCallFrameCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJavaScriptCallFrameCustom.cpp; sourceTree = "<group>"; };
+ 1C63A2460F71646600C09D5A /* RunLoopTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunLoopTimer.h; sourceTree = "<group>"; };
+ 1C63A2470F71646600C09D5A /* RunLoopTimerCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RunLoopTimerCF.cpp; sourceTree = "<group>"; };
1C81B9560E97330800266E07 /* InspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorController.h; sourceTree = "<group>"; };
1C81B9570E97330800266E07 /* InspectorController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorController.cpp; sourceTree = "<group>"; };
1C81B9580E97330800266E07 /* InspectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorClient.h; sourceTree = "<group>"; };
@@ -5415,6 +5509,26 @@
2D9066050BE141D400956998 /* LayoutState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LayoutState.h; sourceTree = "<group>"; };
2D90660B0665D937006B6F1A /* ClipboardMac.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = ClipboardMac.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
2D90660C0665D937006B6F1A /* ClipboardMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ClipboardMac.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 2E4346320F546A8200B0F1BA /* GenericWorkerTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GenericWorkerTask.h; path = workers/GenericWorkerTask.h; sourceTree = "<group>"; };
+ 2E4346330F546A8200B0F1BA /* Worker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Worker.cpp; path = workers/Worker.cpp; sourceTree = "<group>"; };
+ 2E4346340F546A8200B0F1BA /* Worker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Worker.h; path = workers/Worker.h; sourceTree = "<group>"; };
+ 2E4346350F546A8200B0F1BA /* Worker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Worker.idl; path = workers/Worker.idl; sourceTree = "<group>"; };
+ 2E4346360F546A8200B0F1BA /* WorkerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WorkerContext.cpp; path = workers/WorkerContext.cpp; sourceTree = "<group>"; };
+ 2E4346370F546A8200B0F1BA /* WorkerContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerContext.h; path = workers/WorkerContext.h; sourceTree = "<group>"; };
+ 2E4346380F546A8200B0F1BA /* WorkerContext.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WorkerContext.idl; path = workers/WorkerContext.idl; sourceTree = "<group>"; };
+ 2E4346390F546A8200B0F1BA /* WorkerContextProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerContextProxy.h; path = workers/WorkerContextProxy.h; sourceTree = "<group>"; };
+ 2E43463A0F546A8200B0F1BA /* WorkerLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WorkerLocation.cpp; path = workers/WorkerLocation.cpp; sourceTree = "<group>"; };
+ 2E43463B0F546A8200B0F1BA /* WorkerLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerLocation.h; path = workers/WorkerLocation.h; sourceTree = "<group>"; };
+ 2E43463C0F546A8200B0F1BA /* WorkerLocation.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WorkerLocation.idl; path = workers/WorkerLocation.idl; sourceTree = "<group>"; };
+ 2E43463D0F546A8200B0F1BA /* WorkerMessagingProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WorkerMessagingProxy.cpp; path = workers/WorkerMessagingProxy.cpp; sourceTree = "<group>"; };
+ 2E43463E0F546A8200B0F1BA /* WorkerMessagingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerMessagingProxy.h; path = workers/WorkerMessagingProxy.h; sourceTree = "<group>"; };
+ 2E43463F0F546A8200B0F1BA /* WorkerObjectProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerObjectProxy.h; path = workers/WorkerObjectProxy.h; sourceTree = "<group>"; };
+ 2E4346400F546A8200B0F1BA /* WorkerRunLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WorkerRunLoop.cpp; path = workers/WorkerRunLoop.cpp; sourceTree = "<group>"; };
+ 2E4346410F546A8200B0F1BA /* WorkerRunLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerRunLoop.h; path = workers/WorkerRunLoop.h; sourceTree = "<group>"; };
+ 2E4346420F546A8200B0F1BA /* WorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WorkerThread.cpp; path = workers/WorkerThread.cpp; sourceTree = "<group>"; };
+ 2E4346430F546A8200B0F1BA /* WorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerThread.h; path = workers/WorkerThread.h; sourceTree = "<group>"; };
+ 2E4346560F546A9900B0F1BA /* CrossThreadCopier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossThreadCopier.cpp; sourceTree = "<group>"; };
+ 2E4346570F546A9900B0F1BA /* CrossThreadCopier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadCopier.h; sourceTree = "<group>"; };
31288E6E0E3005D6003619AE /* WebKitCSSKeyframeRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframeRule.cpp; sourceTree = "<group>"; };
31288E6F0E3005D6003619AE /* WebKitCSSKeyframeRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSKeyframeRule.h; sourceTree = "<group>"; };
31288E700E3005D6003619AE /* WebKitCSSKeyframesRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSKeyframesRule.cpp; sourceTree = "<group>"; };
@@ -5483,12 +5597,32 @@
37ACCE620DA2AA960089E602 /* FontDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FontDescription.cpp; sourceTree = "<group>"; };
37F818FB0D657606005E1F05 /* WebCoreURLResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreURLResponse.h; sourceTree = "<group>"; };
37F818FC0D657606005E1F05 /* WebCoreURLResponse.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreURLResponse.mm; sourceTree = "<group>"; };
+ 41002CCB0F66EDEF009E660D /* ScriptFunctionCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptFunctionCall.h; sourceTree = "<group>"; };
+ 41002CCC0F66EDEF009E660D /* ScriptFunctionCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptFunctionCall.cpp; sourceTree = "<group>"; };
+ 412A68460F6B03DD000EA66E /* ScriptObjectQuarantine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptObjectQuarantine.cpp; sourceTree = "<group>"; };
416E75BC0EDF8FD700360E1D /* ScriptCallStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptCallStack.h; sourceTree = "<group>"; };
416E75BD0EDF8FD700360E1D /* ScriptCallStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCallStack.cpp; sourceTree = "<group>"; };
416E75C90EDF90C700360E1D /* ScriptCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptCallFrame.h; sourceTree = "<group>"; };
416E75CA0EDF90C700360E1D /* ScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCallFrame.cpp; sourceTree = "<group>"; };
416F45EF0ED7B311008215B6 /* ScriptString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptString.h; sourceTree = "<group>"; };
+ 419536500F68222400D0C679 /* ScriptObjectQuarantine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptObjectQuarantine.h; sourceTree = "<group>"; };
41C760B00EDE03D300C1655F /* ScriptState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptState.h; sourceTree = "<group>"; };
+ 41D015C80F4B5C71004A662F /* ContentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentType.h; sourceTree = "<group>"; };
+ 41D015C90F4B5C71004A662F /* ContentType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentType.cpp; sourceTree = "<group>"; };
+ 41F060AA0F5EE8BB00A07EAC /* InspectorController.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = InspectorController.idl; sourceTree = "<group>"; };
+ 41F060CB0F5EEB2B00A07EAC /* JSInspectorController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorController.cpp; sourceTree = "<group>"; };
+ 41F060CC0F5EEB2B00A07EAC /* JSInspectorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInspectorController.h; sourceTree = "<group>"; };
+ 41F061690F5EFBDD00A07EAC /* JSInspectorControllerCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorControllerCustom.cpp; sourceTree = "<group>"; };
+ 41F061720F5F00AC00A07EAC /* InspectorDOMStorageResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDOMStorageResource.h; sourceTree = "<group>"; };
+ 41F061730F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDOMStorageResource.cpp; sourceTree = "<group>"; };
+ 41F0618C0F5F069800A07EAC /* ConsoleMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleMessage.h; sourceTree = "<group>"; };
+ 41F0618D0F5F069800A07EAC /* ConsoleMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConsoleMessage.cpp; sourceTree = "<group>"; };
+ 41F061FF0F5F0B6600A07EAC /* InspectorResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorResource.h; sourceTree = "<group>"; };
+ 41F062000F5F0B6600A07EAC /* InspectorResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorResource.cpp; sourceTree = "<group>"; };
+ 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDatabaseResource.h; sourceTree = "<group>"; };
+ 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDatabaseResource.cpp; sourceTree = "<group>"; };
+ 41F066E20F64BCF600A07EAC /* ScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptObject.h; sourceTree = "<group>"; };
+ 41F066E30F64BCF600A07EAC /* ScriptObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptObject.cpp; sourceTree = "<group>"; };
41F1D21D0EF35C2A00DA8753 /* ScriptCachedFrameData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptCachedFrameData.h; sourceTree = "<group>"; };
41F1D21E0EF35C2A00DA8753 /* ScriptCachedFrameData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptCachedFrameData.cpp; sourceTree = "<group>"; };
4415292C0E1AE8A000C4A2D0 /* HTMLPlugInImageElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLPlugInImageElement.h; sourceTree = "<group>"; };
@@ -5514,6 +5648,12 @@
46F9D5DA0B0D60170028EE36 /* aliasCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = aliasCursor.png; sourceTree = "<group>"; };
46F9D5DB0B0D60170028EE36 /* noDropCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = noDropCursor.png; sourceTree = "<group>"; };
46F9D5DC0B0D60170028EE36 /* progressCursor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = progressCursor.png; sourceTree = "<group>"; };
+ 494BD7930F55C8EE00747828 /* WebKitPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitPoint.h; sourceTree = "<group>"; };
+ 494BD7940F55C8EE00747828 /* WebKitPoint.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebKitPoint.idl; sourceTree = "<group>"; };
+ 494BD7970F55C90E00747828 /* JSWebKitPointConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitPointConstructor.cpp; sourceTree = "<group>"; };
+ 494BD7980F55C90E00747828 /* JSWebKitPointConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebKitPointConstructor.h; sourceTree = "<group>"; };
+ 494BD79B0F55C94C00747828 /* JSWebKitPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitPoint.cpp; sourceTree = "<group>"; };
+ 494BD79C0F55C94C00747828 /* JSWebKitPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebKitPoint.h; sourceTree = "<group>"; };
4983913D0F1E767500C23782 /* JSWebKitCSSMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitCSSMatrix.cpp; sourceTree = "<group>"; };
4983913E0F1E767500C23782 /* JSWebKitCSSMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebKitCSSMatrix.h; sourceTree = "<group>"; };
4983914D0F1E76B400C23782 /* DOMWebKitCSSMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMWebKitCSSMatrix.h; sourceTree = "<group>"; };
@@ -5524,6 +5664,10 @@
498391570F1E776900C23782 /* WebKitCSSMatrix.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebKitCSSMatrix.idl; sourceTree = "<group>"; };
498391610F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebKitCSSMatrixConstructor.cpp; sourceTree = "<group>"; };
498391620F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWebKitCSSMatrixConstructor.h; sourceTree = "<group>"; };
+ 49D5DC270F423A73008F20FD /* Matrix3DTransformOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Matrix3DTransformOperation.cpp; path = transforms/Matrix3DTransformOperation.cpp; sourceTree = "<group>"; };
+ 49D5DC280F423A73008F20FD /* Matrix3DTransformOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Matrix3DTransformOperation.h; path = transforms/Matrix3DTransformOperation.h; sourceTree = "<group>"; };
+ 49D5DC290F423A73008F20FD /* PerspectiveTransformOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PerspectiveTransformOperation.cpp; path = transforms/PerspectiveTransformOperation.cpp; sourceTree = "<group>"; };
+ 49D5DC2A0F423A73008F20FD /* PerspectiveTransformOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PerspectiveTransformOperation.h; path = transforms/PerspectiveTransformOperation.h; sourceTree = "<group>"; };
49E911B30EF86D47009D0CAF /* TransformationMatrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TransformationMatrix.cpp; path = transforms/TransformationMatrix.cpp; sourceTree = "<group>"; };
49E911B40EF86D47009D0CAF /* TransformationMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TransformationMatrix.h; path = transforms/TransformationMatrix.h; sourceTree = "<group>"; };
49E911B50EF86D47009D0CAF /* IdentityTransformOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IdentityTransformOperation.h; path = transforms/IdentityTransformOperation.h; sourceTree = "<group>"; };
@@ -5735,6 +5879,8 @@
54C50F7A0E801DF3009832A0 /* XMLTokenizerLibxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XMLTokenizerLibxml2.cpp; sourceTree = "<group>"; };
550A0BC7085F6039007353D6 /* QualifiedName.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifiedName.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 5D925B650F64D4DD00B847F0 /* ScrollBehavior.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollBehavior.cpp; sourceTree = "<group>"; };
+ 5D925B660F64D4DD00B847F0 /* ScrollBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollBehavior.h; sourceTree = "<group>"; };
5DCF836C0D59159800953BC6 /* PluginInfoStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginInfoStore.h; sourceTree = "<group>"; };
63189AE20E83A33300012E41 /* NodeRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeRareData.h; sourceTree = "<group>"; };
637B7ADE0E8767B800E32194 /* ElementRareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementRareData.h; sourceTree = "<group>"; };
@@ -6744,8 +6890,6 @@
93309DB8099E64910056E581 /* RemoveNodePreservingChildrenCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoveNodePreservingChildrenCommand.h; sourceTree = "<group>"; };
93309DBA099E64910056E581 /* ReplaceSelectionCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReplaceSelectionCommand.cpp; sourceTree = "<group>"; };
93309DBB099E64910056E581 /* ReplaceSelectionCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplaceSelectionCommand.h; sourceTree = "<group>"; };
- 93309DBC099E64910056E581 /* Selection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Selection.cpp; sourceTree = "<group>"; };
- 93309DBD099E64910056E581 /* Selection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Selection.h; sourceTree = "<group>"; };
93309DBE099E64910056E581 /* SelectionController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionController.cpp; sourceTree = "<group>"; };
93309DBF099E64910056E581 /* SelectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionController.h; sourceTree = "<group>"; };
93309DC0099E64910056E581 /* SetNodeAttributeCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SetNodeAttributeCommand.cpp; sourceTree = "<group>"; };
@@ -6811,6 +6955,8 @@
935C476F09AC4D7300A6AAB4 /* PlatformMouseEventMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformMouseEventMac.mm; sourceTree = "<group>"; };
935C477209AC4D7700A6AAB4 /* WheelEventMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WheelEventMac.mm; sourceTree = "<group>"; };
935C477409AC4D8D00A6AAB4 /* GapRects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GapRects.h; sourceTree = "<group>"; };
+ 935F45400F7C3B5F00D7C1FB /* JSLazyEventListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSLazyEventListener.cpp; sourceTree = "<group>"; };
+ 935F45410F7C3B5F00D7C1FB /* JSLazyEventListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLazyEventListener.h; sourceTree = "<group>"; };
935FBC4409BA00B900E230B1 /* EventListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventListener.h; sourceTree = "<group>"; };
935FBCF109BA143B00E230B1 /* ExceptionCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionCode.h; sourceTree = "<group>"; };
9362640A0DE1137D009D5A00 /* CSSReflectionDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSReflectionDirection.h; sourceTree = "<group>"; };
@@ -6917,6 +7063,8 @@
93F9B79E0BA6032600854064 /* JSCDATASection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCDATASection.cpp; sourceTree = "<group>"; };
93F9B79F0BA6032600854064 /* JSCDATASection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCDATASection.h; sourceTree = "<group>"; };
93FDAFC90B11307400E2746F /* EditorInsertAction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EditorInsertAction.h; sourceTree = "<group>"; };
+ A17C81200F2A5CF7005DAAEB /* HTMLElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLElementFactory.cpp; sourceTree = "<group>"; };
+ A17C81210F2A5CF7005DAAEB /* HTMLElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLElementFactory.h; sourceTree = "<group>"; };
A7094AF90F27AE6000596CEC /* CanvasPixelArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasPixelArray.cpp; sourceTree = "<group>"; };
A7094AFB0F27AEE300596CEC /* CanvasPixelArray.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CanvasPixelArray.idl; sourceTree = "<group>"; };
A718760D0B2A120100A16ECE /* DragActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragActions.h; sourceTree = "<group>"; };
@@ -6951,6 +7099,8 @@
A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSImageDataCustom.cpp; sourceTree = "<group>"; };
A7D27FC30E0A599F0079AD2B /* SVGFETile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFETile.cpp; sourceTree = "<group>"; };
A7D3C5230B576B4B002CA450 /* PasteboardHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PasteboardHelper.h; sourceTree = "<group>"; };
+ A7D6B3470F61104500B79FD1 /* WorkerImportScriptsClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WorkerImportScriptsClient.h; path = workers/WorkerImportScriptsClient.h; sourceTree = "<group>"; };
+ A7D6B3480F61104500B79FD1 /* WorkerImportScriptsClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WorkerImportScriptsClient.cpp; path = workers/WorkerImportScriptsClient.cpp; sourceTree = "<group>"; };
A809F1450B73793A002E4D7F /* RenderSVGGradientStop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGGradientStop.h; sourceTree = "<group>"; };
A809F1460B73793A002E4D7F /* RenderSVGGradientStop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGGradientStop.cpp; sourceTree = "<group>"; };
A809F1A80B737FB6002E4D7F /* RenderSVGHiddenContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGHiddenContainer.h; sourceTree = "<group>"; };
@@ -7197,6 +7347,8 @@
A871DFDF0A15376B00B12A68 /* RenderReplaced.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderReplaced.h; sourceTree = "<group>"; };
A871DFE00A15376B00B12A68 /* RenderWidget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderWidget.h; sourceTree = "<group>"; };
A871DFE10A15376B00B12A68 /* RenderWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderWidget.cpp; sourceTree = "<group>"; };
+ A883DF250F3D045D00F19BF6 /* VisibleSelection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VisibleSelection.cpp; sourceTree = "<group>"; };
+ A883DF260F3D045D00F19BF6 /* VisibleSelection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VisibleSelection.h; sourceTree = "<group>"; };
A88DD4860B4629A300C02990 /* PathTraversalState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathTraversalState.h; sourceTree = "<group>"; };
A88DD4880B4629B000C02990 /* PathTraversalState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathTraversalState.cpp; sourceTree = "<group>"; };
A88FE3330E5EEE87008D8C0F /* GraphicsContextPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsContextPrivate.h; sourceTree = "<group>"; };
@@ -7436,8 +7588,6 @@
A8E544C30CA9D1C20097D09B /* DOMSVGDescElementInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMSVGDescElementInternal.h; sourceTree = "<group>"; };
A8EA73AF0A1900E300A8EF5F /* RenderFieldset.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFieldset.cpp; sourceTree = "<group>"; };
A8EA73B00A1900E300A8EF5F /* RenderFieldset.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderFieldset.h; sourceTree = "<group>"; };
- A8EA73B60A1900E300A8EF5F /* RenderLegend.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLegend.cpp; sourceTree = "<group>"; };
- A8EA73BD0A1900E300A8EF5F /* RenderLegend.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderLegend.h; sourceTree = "<group>"; };
A8EA79E50A1916DF00A8EF5F /* HTMLOListElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTMLOListElement.h; sourceTree = "<group>"; };
A8EA79E60A1916DF00A8EF5F /* HTMLUListElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTMLUListElement.h; sourceTree = "<group>"; };
A8EA79E70A1916DF00A8EF5F /* HTMLUListElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLUListElement.cpp; sourceTree = "<group>"; };
@@ -7977,7 +8127,6 @@
B24055630B5BE640002A28C0 /* DOMSVGElementInstanceInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGElementInstanceInternal.h; sourceTree = "<group>"; };
B24055640B5BE640002A28C0 /* DOMSVGElementInstanceListInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DOMSVGElementInstanceListInternal.h; sourceTree = "<group>"; };
B25598990D00D8B800BB825C /* SVGResourceFilterCg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SVGResourceFilterCg.mm; sourceTree = "<group>"; };
- B255989B0D00D8B800BB825C /* SVGResourceMaskerCg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SVGResourceMaskerCg.mm; sourceTree = "<group>"; };
B25598A60D00D8B800BB825C /* SVGFEHelpersCg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGFEHelpersCg.h; sourceTree = "<group>"; };
B25598A70D00D8B800BB825C /* SVGFEHelpersCg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SVGFEHelpersCg.mm; sourceTree = "<group>"; };
B25598AD0D00D8B800BB825C /* SVGFilterEffectCg.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SVGFilterEffectCg.mm; sourceTree = "<group>"; };
@@ -8227,8 +8376,6 @@
B2C3DA100D006C1D00EF6F26 /* TextCodecUserDefined.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextCodecUserDefined.h; sourceTree = "<group>"; };
B2C3DA110D006C1D00EF6F26 /* TextCodecUTF16.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TextCodecUTF16.cpp; sourceTree = "<group>"; };
B2C3DA120D006C1D00EF6F26 /* TextCodecUTF16.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextCodecUTF16.h; sourceTree = "<group>"; };
- B2C3DA130D006C1D00EF6F26 /* TextDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TextDecoder.cpp; sourceTree = "<group>"; };
- B2C3DA140D006C1D00EF6F26 /* TextDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextDecoder.h; sourceTree = "<group>"; };
B2C3DA150D006C1D00EF6F26 /* TextDirection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextDirection.h; sourceTree = "<group>"; };
B2C3DA160D006C1D00EF6F26 /* TextEncoding.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TextEncoding.cpp; sourceTree = "<group>"; };
B2C3DA170D006C1D00EF6F26 /* TextEncoding.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextEncoding.h; sourceTree = "<group>"; };
@@ -8583,6 +8730,7 @@
BC23EE910DAED2BC009FDC91 /* CSSImageGeneratorValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSImageGeneratorValue.h; sourceTree = "<group>"; };
BC23F0DA0DAFF4A4009FDC91 /* GeneratedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedImage.h; sourceTree = "<group>"; };
BC2441C30E8B65D00055320F /* ScrollView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollView.cpp; sourceTree = "<group>"; };
+ BC2CC8DE0F32881000A9DF26 /* RenderObjectChildList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderObjectChildList.h; sourceTree = "<group>"; };
BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSElementCustom.cpp; sourceTree = "<group>"; };
BC2ED64F0C6BC48C00920BFF /* JSHTMLIFrameElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLIFrameElementCustom.cpp; sourceTree = "<group>"; };
BC2ED6BB0C6BD2F000920BFF /* JSAttrCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAttrCustom.cpp; sourceTree = "<group>"; };
@@ -8590,6 +8738,7 @@
BC305C770C076BB300CD20F0 /* JSHTMLObjectElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLObjectElement.cpp; sourceTree = "<group>"; };
BC305C780C076BB300CD20F0 /* JSHTMLObjectElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLObjectElement.h; sourceTree = "<group>"; };
BC305CA30C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLObjectElementCustom.cpp; sourceTree = "<group>"; };
+ BC33FB1A0F30EE85002CDD7C /* RenderLineBoxList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderLineBoxList.cpp; sourceTree = "<group>"; };
BC3452410D7E00EA0016574A /* JSRGBColor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRGBColor.cpp; sourceTree = "<group>"; };
BC3452420D7E00EA0016574A /* JSRGBColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRGBColor.h; sourceTree = "<group>"; };
BC3452550D7E02850016574A /* JSRGBColor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRGBColor.lut.h; sourceTree = "<group>"; };
@@ -8599,10 +8748,6 @@
BC348BD20DB7F804004ABAB9 /* JSXMLHttpRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXMLHttpRequest.h; sourceTree = "<group>"; };
BC348BE70DB80354004ABAB9 /* JSXMLHttpRequestConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXMLHttpRequestConstructor.cpp; sourceTree = "<group>"; };
BC348BE80DB80354004ABAB9 /* JSXMLHttpRequestConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXMLHttpRequestConstructor.h; sourceTree = "<group>"; };
- BC3B7AEF0E919ADA00D54065 /* EventTargetNode.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetNode.idl; sourceTree = "<group>"; };
- BC3B7AF10E919CA900D54065 /* JSEventTargetNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEventTargetNode.cpp; sourceTree = "<group>"; };
- BC3B7AF20E919CA900D54065 /* JSEventTargetNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEventTargetNode.h; sourceTree = "<group>"; };
- BC3B7B200E91AAF400D54065 /* JSEventTargetNodeCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSEventTargetNodeCustom.cpp; sourceTree = "<group>"; };
BC3BC29B0E91AB0F00835588 /* HostWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostWindow.h; sourceTree = "<group>"; };
BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopupMenuStyle.h; sourceTree = "<group>"; };
BC3BE9900E9C1C7C00835588 /* RenderScrollbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderScrollbar.cpp; sourceTree = "<group>"; };
@@ -8715,6 +8860,7 @@
BC60DA5A0D2A31F700B9918F /* XPathException.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = XPathException.idl; sourceTree = "<group>"; };
BC60DB470D2A3D1E00B9918F /* JSXPathException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXPathException.cpp; sourceTree = "<group>"; };
BC60DB480D2A3D1E00B9918F /* JSXPathException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSXPathException.h; sourceTree = "<group>"; };
+ BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderObjectChildList.cpp; sourceTree = "<group>"; };
BC64B4C90CB4295D005F2B62 /* CachedFont.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedFont.cpp; sourceTree = "<group>"; };
BC64B4CA0CB4295D005F2B62 /* CachedFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedFont.h; sourceTree = "<group>"; };
BC64B4CD0CB4298A005F2B62 /* CSSFontFace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSFontFace.cpp; sourceTree = "<group>"; };
@@ -8789,6 +8935,8 @@
BC94D1500C275C8B006BC617 /* History.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = History.cpp; sourceTree = "<group>"; };
BC94D1510C275C8B006BC617 /* History.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = History.h; sourceTree = "<group>"; };
BC94D1520C275C8B006BC617 /* History.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = History.idl; sourceTree = "<group>"; };
+ BC96DB420F3A880E00573CB3 /* RenderBoxModelObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderBoxModelObject.h; sourceTree = "<group>"; };
+ BC96DB450F3A882200573CB3 /* RenderBoxModelObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderBoxModelObject.cpp; sourceTree = "<group>"; };
BC98543B0CD3D98B00069BC1 /* JSConsole.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSConsole.cpp; sourceTree = "<group>"; };
BC98543C0CD3D98B00069BC1 /* JSConsole.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSConsole.h; sourceTree = "<group>"; };
BC98A27C0C0C9950004BEBF7 /* JSStyleSheetCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStyleSheetCustom.cpp; sourceTree = "<group>"; };
@@ -8838,6 +8986,16 @@
BCBD21AA0E417AD400A070F2 /* KURLHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KURLHash.h; sourceTree = "<group>"; };
BCBFB53A0DCD29CF0019B3E5 /* JSDOMWindowShell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMWindowShell.cpp; sourceTree = "<group>"; };
BCBFB53B0DCD29CF0019B3E5 /* JSDOMWindowShell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMWindowShell.h; sourceTree = "<group>"; };
+ BCC065770F3CE1B700CD2D87 /* ClientRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClientRect.cpp; sourceTree = "<group>"; };
+ BCC065780F3CE1B700CD2D87 /* ClientRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientRect.h; sourceTree = "<group>"; };
+ BCC065790F3CE1B700CD2D87 /* ClientRect.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ClientRect.idl; sourceTree = "<group>"; };
+ BCC0657A0F3CE1B700CD2D87 /* ClientRectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClientRectList.cpp; sourceTree = "<group>"; };
+ BCC0657B0F3CE1B700CD2D87 /* ClientRectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClientRectList.h; sourceTree = "<group>"; };
+ BCC0657C0F3CE1B700CD2D87 /* ClientRectList.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ClientRectList.idl; sourceTree = "<group>"; };
+ BCC065830F3CE2A700CD2D87 /* JSClientRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSClientRect.cpp; sourceTree = "<group>"; };
+ BCC065840F3CE2A700CD2D87 /* JSClientRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSClientRect.h; sourceTree = "<group>"; };
+ BCC065850F3CE2A700CD2D87 /* JSClientRectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSClientRectList.cpp; sourceTree = "<group>"; };
+ BCC065860F3CE2A700CD2D87 /* JSClientRectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSClientRectList.h; sourceTree = "<group>"; };
BCC438770E886CC700533DD5 /* JSHTMLInputElementCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLInputElementCustom.cpp; sourceTree = "<group>"; };
BCC573330D695BBE006EF517 /* DOMProgressEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMProgressEvent.h; sourceTree = "<group>"; };
BCC573340D695BBE006EF517 /* DOMProgressEvent.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMProgressEvent.mm; sourceTree = "<group>"; };
@@ -8898,6 +9056,8 @@
BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSLocationCustom.cpp; sourceTree = "<group>"; };
BCE3BEC00D222B1D007E06E4 /* TagNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagNodeList.cpp; sourceTree = "<group>"; };
BCE3BEC10D222B1D007E06E4 /* TagNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagNodeList.h; sourceTree = "<group>"; };
+ BCE494A90F4F5E9E0084E319 /* GeolocationServiceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeolocationServiceMac.h; sourceTree = "<group>"; };
+ BCE494AA0F4F5E9E0084E319 /* GeolocationServiceMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GeolocationServiceMac.mm; sourceTree = "<group>"; };
BCE658FE0EA9248A007E4533 /* Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Theme.h; sourceTree = "<group>"; };
BCE659A80EA927B9007E4533 /* ThemeTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeTypes.h; sourceTree = "<group>"; };
BCE659E50EA92FB2007E4533 /* ThemeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeMac.h; sourceTree = "<group>"; };
@@ -8935,12 +9095,8 @@
BCEA4829097D93020094C9E4 /* RenderView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderView.h; sourceTree = "<group>"; };
BCEA482A097D93020094C9E4 /* RenderHTMLCanvas.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderHTMLCanvas.cpp; sourceTree = "<group>"; };
BCEA482B097D93020094C9E4 /* RenderHTMLCanvas.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderHTMLCanvas.h; sourceTree = "<group>"; };
- BCEA482C097D93020094C9E4 /* RenderContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderContainer.cpp; sourceTree = "<group>"; };
- BCEA482D097D93020094C9E4 /* RenderContainer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderContainer.h; sourceTree = "<group>"; };
BCEA482E097D93020094C9E4 /* RenderFlexibleBox.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFlexibleBox.cpp; sourceTree = "<group>"; };
BCEA482F097D93020094C9E4 /* RenderFlexibleBox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderFlexibleBox.h; sourceTree = "<group>"; };
- BCEA4830097D93020094C9E4 /* RenderFlow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFlow.cpp; sourceTree = "<group>"; };
- BCEA4831097D93020094C9E4 /* RenderFlow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderFlow.h; sourceTree = "<group>"; };
BCEA4836097D93020094C9E4 /* RenderImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderImage.cpp; sourceTree = "<group>"; };
BCEA4837097D93020094C9E4 /* RenderImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderImage.h; sourceTree = "<group>"; };
BCEA4838097D93020094C9E4 /* RenderInline.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderInline.cpp; sourceTree = "<group>"; };
@@ -8963,8 +9119,6 @@
BCEC01C00C274DDD009F4EC9 /* JSScreen.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSScreen.cpp; sourceTree = "<group>"; };
BCEC01C10C274DDD009F4EC9 /* JSScreen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSScreen.h; sourceTree = "<group>"; };
BCEC01D60C274EB4009F4EC9 /* PlatformScreen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlatformScreen.h; sourceTree = "<group>"; };
- BCEF3432087B563E00BBF833 /* HTMLElementFactory.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLElementFactory.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
- BCEF3433087B563E00BBF833 /* HTMLElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HTMLElementFactory.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
BCEF43CE0E673DA1001C1287 /* StyleImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleImage.h; path = style/StyleImage.h; sourceTree = "<group>"; };
BCEF43DC0E674012001C1287 /* NinePieceImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NinePieceImage.h; path = style/NinePieceImage.h; sourceTree = "<group>"; };
BCEF43DF0E674110001C1287 /* NinePieceImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NinePieceImage.cpp; path = style/NinePieceImage.cpp; sourceTree = "<group>"; };
@@ -9003,6 +9157,8 @@
C09158880DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSQuarantinedObjectWrapper.cpp; sourceTree = "<group>"; };
C09158890DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQuarantinedObjectWrapper.h; sourceTree = "<group>"; };
C0DFC86F0DB6841A003EAE7C /* JSConsoleCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSConsoleCustom.cpp; sourceTree = "<group>"; };
+ C105DA610F3AA68F001DD44F /* TextEncodingDetectorICU.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextEncodingDetectorICU.cpp; sourceTree = "<group>"; };
+ C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextEncodingDetector.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>"; };
D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FormatBlockCommand.cpp; sourceTree = "<group>"; };
@@ -9027,8 +9183,6 @@
E107400C0E77BDC00033AF24 /* JSMessageChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMessageChannel.h; sourceTree = "<group>"; };
E10743230E7835830033AF24 /* JSMessageChannelConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageChannelConstructor.cpp; sourceTree = "<group>"; };
E10743260E7835A50033AF24 /* JSMessageChannelConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMessageChannelConstructor.h; sourceTree = "<group>"; };
- E108224A0EC3153A00E93953 /* WorkerTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerTask.h; sourceTree = "<group>"; };
- E108224E0EC3156700E93953 /* WorkerTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerTask.cpp; sourceTree = "<group>"; };
E10B937B0B73C00A003ED890 /* JSCustomXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomXPathNSResolver.h; sourceTree = "<group>"; };
E10B93C20B73C291003ED890 /* JSCustomXPathNSResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomXPathNSResolver.cpp; sourceTree = "<group>"; };
E10B9B6A0B747599003ED890 /* NativeXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeXPathNSResolver.h; sourceTree = "<group>"; };
@@ -9051,13 +9205,9 @@
E1271A570EEECDE400F61213 /* JSWorkerNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerNavigator.cpp; sourceTree = "<group>"; };
E12EDB7A0B308A78002704B6 /* EventTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTarget.h; sourceTree = "<group>"; };
E12EDBE90B308E0B002704B6 /* EventTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTarget.cpp; sourceTree = "<group>"; };
- E14799A60ECDE3A400292BF3 /* WorkerMessagingProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerMessagingProxy.h; sourceTree = "<group>"; };
- E14799B30ECDE9D800292BF3 /* WorkerMessagingProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerMessagingProxy.cpp; sourceTree = "<group>"; };
E181B2560F14C1A600FB7847 /* JSDOMStringListCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMStringListCustom.cpp; sourceTree = "<group>"; };
E181B3500F15008A00FB7847 /* StaticStringList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticStringList.h; sourceTree = "<group>"; };
E181B3550F1500D700FB7847 /* StaticStringList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticStringList.cpp; sourceTree = "<group>"; };
- E182504E0ED2F20200499A8F /* FrameLoaderClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameLoaderClient.cpp; sourceTree = "<group>"; };
- E182564F0EF2ACE600933242 /* WorkerContext.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WorkerContext.idl; sourceTree = "<group>"; };
E182568D0EF2B02D00933242 /* JSWorkerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerContext.cpp; sourceTree = "<group>"; };
E182568E0EF2B02D00933242 /* JSWorkerContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerContext.h; sourceTree = "<group>"; };
E18258AB0EF3CD7000933242 /* JSWorkerContextCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerContextCustom.cpp; sourceTree = "<group>"; };
@@ -9081,25 +9231,19 @@
E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessagePort.cpp; sourceTree = "<group>"; };
E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XSLTUnicodeSort.cpp; sourceTree = "<group>"; };
E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XSLTUnicodeSort.h; sourceTree = "<group>"; };
- E1C2C4230EACE0BC007E61FB /* WorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerThread.h; sourceTree = "<group>"; };
- E1C2C4280EACE0E0007E61FB /* WorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerThread.cpp; sourceTree = "<group>"; };
- E1C2C43D0EAD0133007E61FB /* WorkerContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerContext.h; sourceTree = "<group>"; };
- E1C2C4410EAD017B007E61FB /* WorkerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerContext.cpp; sourceTree = "<group>"; };
- E1C362BB0EAF29FB007410BC /* WorkerLocation.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WorkerLocation.idl; sourceTree = "<group>"; };
E1C362ED0EAF2AA9007410BC /* JSWorkerLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerLocation.h; sourceTree = "<group>"; };
E1C362EE0EAF2AA9007410BC /* JSWorkerLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerLocation.cpp; sourceTree = "<group>"; };
- E1C363000EAF2CC6007410BC /* WorkerLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerLocation.h; sourceTree = "<group>"; };
- E1C363050EAF2D07007410BC /* WorkerLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerLocation.cpp; sourceTree = "<group>"; };
E1C36C020EB076D6007410BC /* JSDOMGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMGlobalObject.h; sourceTree = "<group>"; };
E1C36CBC0EB08062007410BC /* JSDOMGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMGlobalObject.cpp; sourceTree = "<group>"; };
E1C36D320EB0A094007410BC /* JSWorkerContextBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerContextBase.cpp; sourceTree = "<group>"; };
E1C36D330EB0A094007410BC /* JSWorkerContextBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerContextBase.h; sourceTree = "<group>"; };
+ E1C415D90F655D6F0092D2FB /* CrossOriginPreflightResultCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossOriginPreflightResultCache.h; sourceTree = "<group>"; };
+ E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossOriginPreflightResultCache.cpp; sourceTree = "<group>"; };
+ E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossOriginAccessControl.h; sourceTree = "<group>"; };
+ E1C416160F6563180092D2FB /* CrossOriginAccessControl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossOriginAccessControl.cpp; sourceTree = "<group>"; };
E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveDOMObject.h; sourceTree = "<group>"; };
E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveDOMObject.cpp; sourceTree = "<group>"; };
- E1C8BE440E8BCCBB0064CB7D /* Worker.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Worker.idl; sourceTree = "<group>"; };
E1C8BE5C0E8BD15A0064CB7D /* JSWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorker.cpp; sourceTree = "<group>"; };
- E1CA5C9F0E8CD73B00E8EF90 /* Worker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Worker.h; sourceTree = "<group>"; };
- E1CA5CA40E8CD78500E8EF90 /* Worker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Worker.cpp; sourceTree = "<group>"; };
E1CA5CBB0E8CDCAF00E8EF90 /* JSWorkerCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerCustom.cpp; sourceTree = "<group>"; };
E1CA5CD20E8CDE8000E8EF90 /* JSWorkerConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWorkerConstructor.h; sourceTree = "<group>"; };
E1CA5CD50E8CDEE900E8EF90 /* JSWorkerConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWorkerConstructor.cpp; sourceTree = "<group>"; };
@@ -9219,6 +9363,11 @@
F9F0ED770DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = XMLHttpRequestProgressEvent.h; sourceTree = "<group>"; };
F9F0ED780DB50CA200D16DB9 /* XMLHttpRequestProgressEvent.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = XMLHttpRequestProgressEvent.idl; sourceTree = "<group>"; };
FE49EF970DC51462004266E1 /* DashboardSupportCSSPropertyNames.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DashboardSupportCSSPropertyNames.in; sourceTree = "<group>"; };
+ FE6FD4840F676E5700092873 /* Coordinates.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Coordinates.cpp; sourceTree = "<group>"; };
+ FE6FD4850F676E5700092873 /* Coordinates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Coordinates.h; sourceTree = "<group>"; };
+ FE6FD4860F676E5700092873 /* Coordinates.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Coordinates.idl; sourceTree = "<group>"; };
+ FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCoordinates.cpp; sourceTree = "<group>"; };
+ FE6FD48C0F676E9300092873 /* JSCoordinates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCoordinates.h; sourceTree = "<group>"; };
FE80D7A20E9C1ED2000D6F75 /* JSCustomPositionCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomPositionCallback.cpp; sourceTree = "<group>"; };
FE80D7A30E9C1ED2000D6F75 /* JSCustomPositionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomPositionCallback.h; sourceTree = "<group>"; };
FE80D7A40E9C1ED2000D6F75 /* JSCustomPositionErrorCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomPositionErrorCallback.cpp; sourceTree = "<group>"; };
@@ -9237,7 +9386,6 @@
FE80D7C10E9C1F25000D6F75 /* PositionErrorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionErrorCallback.h; sourceTree = "<group>"; };
FE80D7C20E9C1F25000D6F75 /* PositionErrorCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PositionErrorCallback.idl; sourceTree = "<group>"; };
FE80D7C30E9C1F25000D6F75 /* PositionOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionOptions.h; sourceTree = "<group>"; };
- FE80D7C40E9C1F25000D6F75 /* PositionOptions.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PositionOptions.idl; sourceTree = "<group>"; };
FE80DA5F0E9C4703000D6F75 /* JSGeolocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeolocation.cpp; sourceTree = "<group>"; };
FE80DA600E9C4703000D6F75 /* JSGeolocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGeolocation.h; sourceTree = "<group>"; };
FE80DA610E9C4703000D6F75 /* JSGeoposition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeoposition.cpp; sourceTree = "<group>"; };
@@ -9302,6 +9450,7 @@
1AE82EC90CAAE177002237AE /* storage */,
B22277CA0D00BF1E0071B782 /* svg */,
4C6B99150E52E37300487BB7 /* wml */,
+ 2E4346310F546A6800B0F1BA /* workers */,
E1F0424309839389006694EA /* xml */,
656580EC09D12B20000E61D7 /* Derived Sources */,
089C1665FE841158C02AAC07 /* Resources */,
@@ -9416,6 +9565,8 @@
1A569CC50D7E2B82007C3983 /* c */,
1A569CCE0D7E2B82007C3983 /* jni */,
1A569CE20D7E2B82007C3983 /* objc */,
+ 1A71D5790F33819000F9CE4E /* IdentifierRep.cpp */,
+ 1A71D57A0F33819000F9CE4E /* IdentifierRep.h */,
1A569CDA0D7E2B82007C3983 /* NP_jsobject.cpp */,
1A569CDB0D7E2B82007C3983 /* NP_jsobject.h */,
1A569CDC0D7E2B82007C3983 /* npapi.h */,
@@ -9525,6 +9676,7 @@
children = (
5160306B0CC4362300C8AC25 /* FileSystemCF.cpp */,
1A98956A0AA78F80005EF5EF /* KURLCFNet.cpp */,
+ 1C63A2470F71646600C09D5A /* RunLoopTimerCF.cpp */,
1CEFC9B80D78DC8C007D2579 /* SchedulePair.cpp */,
1CEFC9B70D78DC8C007D2579 /* SchedulePair.h */,
512DD8E20D91E2B4000F89EE /* SharedBufferCF.cpp */,
@@ -9573,16 +9725,12 @@
515B03980CD1642A00B7EA9C /* SQLStatement.cpp */,
515B03970CD1642A00B7EA9C /* SQLStatement.h */,
1A7CCB150CD9469A00B7B64E /* SQLStatementCallback.h */,
- 1A7CCB0C0CD9462C00B7B64E /* SQLStatementCallback.idl */,
1A7CCB160CD9469A00B7B64E /* SQLStatementErrorCallback.h */,
- 1A7CCB0D0CD9462C00B7B64E /* SQLStatementErrorCallback.idl */,
1ABFE7520CD968D000FE4834 /* SQLTransaction.cpp */,
1A7CCB220CD946FD00B7B64E /* SQLTransaction.h */,
1A7CCB230CD946FD00B7B64E /* SQLTransaction.idl */,
1A7CCB170CD9469A00B7B64E /* SQLTransactionCallback.h */,
- 1A7CCB0E0CD9462C00B7B64E /* SQLTransactionCallback.idl */,
1A7CCB180CD9469A00B7B64E /* SQLTransactionErrorCallback.h */,
- 1A7CCB0F0CD9462C00B7B64E /* SQLTransactionErrorCallback.idl */,
51E0BB220DA572A600A9E417 /* SessionStorage.cpp */,
51E0BB210DA572A600A9E417 /* SessionStorage.h */,
514B49DE0DB6D6B6001C3770 /* SessionStorageArea.cpp */,
@@ -9607,6 +9755,8 @@
1C5FAECA0DCFD8C900D58F78 /* Inspector */ = {
isa = PBXGroup;
children = (
+ 41F060CB0F5EEB2B00A07EAC /* JSInspectorController.cpp */,
+ 41F060CC0F5EEB2B00A07EAC /* JSInspectorController.h */,
1C5FAECF0DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp */,
1C5FAED00DCFD90100D58F78 /* JSJavaScriptCallFrame.h */,
);
@@ -9617,9 +9767,18 @@
isa = PBXGroup;
children = (
1C81B9590E97330800266E07 /* front-end */,
+ 41F0618D0F5F069800A07EAC /* ConsoleMessage.cpp */,
+ 41F0618C0F5F069800A07EAC /* ConsoleMessage.h */,
+ 41F062130F5F192600A07EAC /* InspectorDatabaseResource.cpp */,
+ 41F062120F5F192600A07EAC /* InspectorDatabaseResource.h */,
+ 41F061730F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp */,
+ 41F061720F5F00AC00A07EAC /* InspectorDOMStorageResource.h */,
1C81B9580E97330800266E07 /* InspectorClient.h */,
1C81B9570E97330800266E07 /* InspectorController.cpp */,
1C81B9560E97330800266E07 /* InspectorController.h */,
+ 41F060AA0F5EE8BB00A07EAC /* InspectorController.idl */,
+ 41F062000F5F0B6600A07EAC /* InspectorResource.cpp */,
+ 41F061FF0F5F0B6600A07EAC /* InspectorResource.h */,
1C81BA030E97348300266E07 /* JavaScriptCallFrame.cpp */,
1C81BA040E97348300266E07 /* JavaScriptCallFrame.h */,
1C81BA050E97348300266E07 /* JavaScriptCallFrame.idl */,
@@ -9650,6 +9809,33 @@
tabWidth = 4;
usesTabs = 0;
};
+ 2E4346310F546A6800B0F1BA /* workers */ = {
+ isa = PBXGroup;
+ children = (
+ 2E4346320F546A8200B0F1BA /* GenericWorkerTask.h */,
+ 2E4346330F546A8200B0F1BA /* Worker.cpp */,
+ 2E4346340F546A8200B0F1BA /* Worker.h */,
+ 2E4346350F546A8200B0F1BA /* Worker.idl */,
+ 2E4346360F546A8200B0F1BA /* WorkerContext.cpp */,
+ 2E4346370F546A8200B0F1BA /* WorkerContext.h */,
+ 2E4346380F546A8200B0F1BA /* WorkerContext.idl */,
+ 2E4346390F546A8200B0F1BA /* WorkerContextProxy.h */,
+ 2E43463A0F546A8200B0F1BA /* WorkerLocation.cpp */,
+ 2E43463B0F546A8200B0F1BA /* WorkerLocation.h */,
+ 2E43463C0F546A8200B0F1BA /* WorkerLocation.idl */,
+ 2E43463D0F546A8200B0F1BA /* WorkerMessagingProxy.cpp */,
+ 2E43463E0F546A8200B0F1BA /* WorkerMessagingProxy.h */,
+ 2E43463F0F546A8200B0F1BA /* WorkerObjectProxy.h */,
+ 2E4346400F546A8200B0F1BA /* WorkerRunLoop.cpp */,
+ 2E4346410F546A8200B0F1BA /* WorkerRunLoop.h */,
+ 2E4346420F546A8200B0F1BA /* WorkerThread.cpp */,
+ 2E4346430F546A8200B0F1BA /* WorkerThread.h */,
+ A7D6B3470F61104500B79FD1 /* WorkerImportScriptsClient.h */,
+ A7D6B3480F61104500B79FD1 /* WorkerImportScriptsClient.cpp */,
+ );
+ name = workers;
+ sourceTree = "<group>";
+ };
316FE1060E6E1D8400BF6088 /* animation */ = {
isa = PBXGroup;
children = (
@@ -9657,6 +9843,7 @@
316FE1080E6E1DA700BF6088 /* AnimationBase.h */,
316FE1090E6E1DA700BF6088 /* AnimationController.cpp */,
316FE10A0E6E1DA700BF6088 /* AnimationController.h */,
+ 0F15DA890F3AAEE70000CE47 /* AnimationControllerPrivate.h */,
316FE10B0E6E1DA700BF6088 /* CompositeAnimation.cpp */,
316FE10C0E6E1DA700BF6088 /* CompositeAnimation.h */,
316FE10D0E6E1DA700BF6088 /* ImplicitAnimation.cpp */,
@@ -9671,8 +9858,12 @@
isa = PBXGroup;
children = (
49E911B50EF86D47009D0CAF /* IdentityTransformOperation.h */,
+ 49D5DC270F423A73008F20FD /* Matrix3DTransformOperation.cpp */,
+ 49D5DC280F423A73008F20FD /* Matrix3DTransformOperation.h */,
49E911B60EF86D47009D0CAF /* MatrixTransformOperation.cpp */,
49E911B70EF86D47009D0CAF /* MatrixTransformOperation.h */,
+ 49D5DC290F423A73008F20FD /* PerspectiveTransformOperation.cpp */,
+ 49D5DC2A0F423A73008F20FD /* PerspectiveTransformOperation.h */,
49E911B80EF86D47009D0CAF /* RotateTransformOperation.cpp */,
49E911B90EF86D47009D0CAF /* RotateTransformOperation.h */,
49E911BA0EF86D47009D0CAF /* ScaleTransformOperation.cpp */,
@@ -9902,6 +10093,8 @@
656581AC09D14EE6000E61D7 /* CharsetData.cpp */,
656581AD09D14EE6000E61D7 /* ColorData.c */,
6565811C09D12DB2000E61D7 /* DocTypeStrings.cpp */,
+ A17C81200F2A5CF7005DAAEB /* HTMLElementFactory.cpp */,
+ A17C81210F2A5CF7005DAAEB /* HTMLElementFactory.h */,
6565814B09D13043000E61D7 /* HTMLEntityNames.c */,
A8D06B380A265DCD005E7203 /* HTMLNames.cpp */,
A8D06B370A265DCD005E7203 /* HTMLNames.h */,
@@ -10009,8 +10202,10 @@
066C772C0AB603D200238CC4 /* FileChooserMac.mm */,
514B3F750C722055000530DF /* FileSystemMac.mm */,
935C476C09AC4D6300A6AAB4 /* FoundationExtras.h */,
- 6593923909AE435C002C531F /* KURLMac.mm */,
+ BCE494A90F4F5E9E0084E319 /* GeolocationServiceMac.h */,
+ BCE494AA0F4F5E9E0084E319 /* GeolocationServiceMac.mm */,
935C476E09AC4D7300A6AAB4 /* KeyEventMac.mm */,
+ 6593923909AE435C002C531F /* KURLMac.mm */,
9352084409BD43B900F2038D /* Language.mm */,
06E81ED60AB5D5E900C87837 /* LocalCurrentGraphicsContext.h */,
06E81EEB0AB5DA9700C87837 /* LocalCurrentGraphicsContext.mm */,
@@ -10023,17 +10218,17 @@
BC94D1070C274F88006BC617 /* PlatformScreenMac.mm */,
0668E18E0ADD9640004128E0 /* PopupMenuMac.mm */,
E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */,
- 84B2B24F056BF15F00D2B771 /* SSLKeyGeneratorMac.mm */,
1CE24F960D7CAF0E007E04C2 /* SchedulePairMac.mm */,
- 9353676A09AED88B00D35CD6 /* ScrollViewMac.mm */,
BCAA90C20A7EBA60008B1229 /* Scrollbar.cpp */,
BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */,
BCEF869E0E844E9D00A85CD5 /* ScrollbarThemeMac.mm */,
+ 9353676A09AED88B00D35CD6 /* ScrollViewMac.mm */,
AB71709F0B31193B0017123E /* SearchPopupMenuMac.mm */,
1A4A95510B4EDCFF002D8C3C /* SharedBufferMac.mm */,
93309E9F099EB78C0056E581 /* SharedTimerMac.mm */,
0A4844980CA44CB200B7BD48 /* SoftLinking.h */,
4B3043C80AE0371D00A82647 /* SoundMac.mm */,
+ 84B2B24F056BF15F00D2B771 /* SSLKeyGeneratorMac.mm */,
6582A15509999D6D00BEEB6D /* SystemTimeMac.cpp */,
BCE659E50EA92FB2007E4533 /* ThemeMac.h */,
BCE659E80EA92FFA007E4533 /* ThemeMac.mm */,
@@ -10100,6 +10295,9 @@
065AD4F20B0C2EDA005A2B1D /* ContextMenuClient.h */,
065AD4F30B0C2EDA005A2B1D /* ContextMenuController.cpp */,
065AD4F40B0C2EDA005A2B1D /* ContextMenuController.h */,
+ FE6FD4840F676E5700092873 /* Coordinates.cpp */,
+ FE6FD4850F676E5700092873 /* Coordinates.h */,
+ FE6FD4860F676E5700092873 /* Coordinates.idl */,
BC5A86810C33676000EEA649 /* DOMSelection.cpp */,
BC5A86820C33676000EEA649 /* DOMSelection.h */,
BC5A86830C33676000EEA649 /* DOMSelection.idl */,
@@ -10155,7 +10353,6 @@
FE80D7C10E9C1F25000D6F75 /* PositionErrorCallback.h */,
FE80D7C20E9C1F25000D6F75 /* PositionErrorCallback.idl */,
FE80D7C30E9C1F25000D6F75 /* PositionOptions.h */,
- FE80D7C40E9C1F25000D6F75 /* PositionOptions.idl */,
BCEC01BA0C274DAC009F4EC9 /* Screen.cpp */,
BCEC01BB0C274DAC009F4EC9 /* Screen.h */,
BCEC01BC0C274DAC009F4EC9 /* Screen.idl */,
@@ -10164,6 +10361,8 @@
BCD0E0F90E972C3500265DEA /* SecurityOriginHash.h */,
14C9A5E90B3D105F005A0232 /* Settings.cpp */,
F587863A02DE3A1401EA4122 /* Settings.h */,
+ 494BD7930F55C8EE00747828 /* WebKitPoint.h */,
+ 494BD7940F55C8EE00747828 /* WebKitPoint.idl */,
BC8243E60D0CFD7500460C8F /* WindowFeatures.cpp */,
BC8243E70D0CFD7500460C8F /* WindowFeatures.h */,
E1271A130EEEC80400F61213 /* WorkerNavigator.cpp */,
@@ -11339,8 +11538,6 @@
93309DB8099E64910056E581 /* RemoveNodePreservingChildrenCommand.h */,
93309DBA099E64910056E581 /* ReplaceSelectionCommand.cpp */,
93309DBB099E64910056E581 /* ReplaceSelectionCommand.h */,
- 93309DBC099E64910056E581 /* Selection.cpp */,
- 93309DBD099E64910056E581 /* Selection.h */,
93309DBE099E64910056E581 /* SelectionController.cpp */,
93309DBF099E64910056E581 /* SelectionController.h */,
93309DC0099E64910056E581 /* SetNodeAttributeCommand.cpp */,
@@ -11364,6 +11561,8 @@
D086FE9609D53AAB005BC74D /* UnlinkCommand.h */,
93309DD0099E64910056E581 /* VisiblePosition.cpp */,
93309DD1099E64910056E581 /* VisiblePosition.h */,
+ A883DF250F3D045D00F19BF6 /* VisibleSelection.cpp */,
+ A883DF260F3D045D00F19BF6 /* VisibleSelection.h */,
93309DD4099E64910056E581 /* WrapContentsInDummySpanCommand.cpp */,
93309DD5099E64910056E581 /* WrapContentsInDummySpanCommand.h */,
93309D98099E64910056E581 /* htmlediting.cpp */,
@@ -11488,8 +11687,6 @@
F523D23E02DE4396018635CA /* HTMLElement.cpp */,
F523D23F02DE4396018635CA /* HTMLElement.h */,
1A494BBB0A122DCD00FDAFC1 /* HTMLElement.idl */,
- BCEF3432087B563E00BBF833 /* HTMLElementFactory.cpp */,
- BCEF3433087B563E00BBF833 /* HTMLElementFactory.h */,
A871D4550A127CBC00B12A68 /* HTMLEmbedElement.cpp */,
A871D4520A127CBC00B12A68 /* HTMLEmbedElement.h */,
859128790AB222EC00202265 /* HTMLEmbedElement.idl */,
@@ -12173,6 +12370,10 @@
BC686C790E0C330100DE8A08 /* JSCSSVariablesDeclaration.h */,
BC686C7A0E0C330100DE8A08 /* JSCSSVariablesRule.cpp */,
BC686C7B0E0C330100DE8A08 /* JSCSSVariablesRule.h */,
+ BCC065830F3CE2A700CD2D87 /* JSClientRect.cpp */,
+ BCC065840F3CE2A700CD2D87 /* JSClientRect.h */,
+ BCC065850F3CE2A700CD2D87 /* JSClientRectList.cpp */,
+ BCC065860F3CE2A700CD2D87 /* JSClientRectList.h */,
930705D709E0C9B700B17FE4 /* JSCounter.cpp */,
930705D909E0C9BF00B17FE4 /* JSCounter.h */,
BC3C39B40C0D3D8D005F4D7A /* JSMediaList.cpp */,
@@ -12209,6 +12410,8 @@
BCA83E4E0D7CE1E9003421A8 /* JSClipboard.h */,
93F9B6DE0BA0FB7200854064 /* JSComment.cpp */,
93F9B6DF0BA0FB7200854064 /* JSComment.h */,
+ FE6FD48B0F676E9300092873 /* JSCoordinates.cpp */,
+ FE6FD48C0F676E9300092873 /* JSCoordinates.h */,
BC60D7BE0D29A46300B9918F /* JSDOMCoreException.cpp */,
BC60D7BF0D29A46300B9918F /* JSDOMCoreException.h */,
65DF31E309D1CC60000BE325 /* JSDOMImplementation.cpp */,
@@ -12258,8 +12461,6 @@
14E8378D09F85D4F00B85AE4 /* JSEvent.h */,
BC60D9BD0D2A269A00B9918F /* JSEventException.cpp */,
BC60D9BE0D2A269A00B9918F /* JSEventException.h */,
- BC3B7AF10E919CA900D54065 /* JSEventTargetNode.cpp */,
- BC3B7AF20E919CA900D54065 /* JSEventTargetNode.h */,
A86629CE09DA2B47009633A5 /* JSKeyboardEvent.cpp */,
A86629CD09DA2B47009633A5 /* JSKeyboardEvent.h */,
E107400B0E77BDC00033AF24 /* JSMessageChannel.cpp */,
@@ -12822,7 +13023,6 @@
isa = PBXGroup;
children = (
B25598990D00D8B800BB825C /* SVGResourceFilterCg.mm */,
- B255989B0D00D8B800BB825C /* SVGResourceMaskerCg.mm */,
);
path = cg;
sourceTree = "<group>";
@@ -12929,6 +13129,7 @@
B27535290B053814002CE64F /* cg */ = {
isa = PBXGroup;
children = (
+ 0FCF33230F2B9715004B6795 /* ColorCG.cpp */,
B275352B0B053814002CE64F /* FloatPointCG.cpp */,
B275352C0B053814002CE64F /* FloatRectCG.cpp */,
B275352D0B053814002CE64F /* FloatSizeCG.cpp */,
@@ -12972,6 +13173,8 @@
B2AFFC7A0D00A5C10030074D /* FontPlatformDataMac.mm */,
B2AFFC7B0D00A5C10030074D /* GlyphPageTreeNodeMac.cpp */,
B277B4030B22F37C0004BEC6 /* GraphicsContextMac.mm */,
+ 0F580B040F12A2550051D689 /* GraphicsLayerCA.h */,
+ 0F580B030F12A2540051D689 /* GraphicsLayerCA.mm */,
B275358D0B053A66002CE64F /* IconMac.mm */,
B275354E0B053814002CE64F /* ImageMac.mm */,
B275354F0B053814002CE64F /* IntPointMac.mm */,
@@ -12979,7 +13182,12 @@
B27535510B053814002CE64F /* IntSizeMac.mm */,
E4B41E100CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.h */,
E4B41E110CBF90EF00AF2ECE /* MediaPlayerPrivateQTKit.mm */,
+ 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */,
B2AFFC770D00A5C10030074D /* SimpleFontDataMac.mm */,
+ 0FCF332B0F2B9A25004B6795 /* WebLayer.h */,
+ 0FCF332A0F2B9A25004B6795 /* WebLayer.mm */,
+ 0FCF33290F2B9A25004B6795 /* WebTiledLayer.h */,
+ 0FCF33280F2B9A25004B6795 /* WebTiledLayer.mm */,
);
path = mac;
sourceTree = "<group>";
@@ -13035,6 +13243,9 @@
B2A015920AF6CD53006BCE0E /* GraphicsContext.cpp */,
B2A015930AF6CD53006BCE0E /* GraphicsContext.h */,
A88FE3330E5EEE87008D8C0F /* GraphicsContextPrivate.h */,
+ 0F580B090F12A2690051D689 /* GraphicsLayer.cpp */,
+ 0F580B0A0F12A2690051D689 /* GraphicsLayer.h */,
+ 0F580B0B0F12A2690051D689 /* GraphicsLayerClient.h */,
B2A015940AF6CD53006BCE0E /* GraphicsTypes.cpp */,
B2A015950AF6CD53006BCE0E /* GraphicsTypes.h */,
B27535400B053814002CE64F /* Icon.h */,
@@ -13050,6 +13261,7 @@
B27535480B053814002CE64F /* IntSizeHash.h */,
E4B41E0C0CBF90BD00AF2ECE /* MediaPlayer.cpp */,
E4B41E0D0CBF90BD00AF2ECE /* MediaPlayer.h */,
+ 079F5E4B0F3BEBEA005E0782 /* MediaPlayerPrivate.h */,
B27535520B053814002CE64F /* Path.cpp */,
B27535530B053814002CE64F /* Path.h */,
A88DD4880B4629B000C02990 /* PathTraversalState.cpp */,
@@ -13125,11 +13337,11 @@
B2C3DA120D006C1D00EF6F26 /* TextCodecUTF16.h */,
B2C3DA0F0D006C1D00EF6F26 /* TextCodecUserDefined.cpp */,
B2C3DA100D006C1D00EF6F26 /* TextCodecUserDefined.h */,
- B2C3DA130D006C1D00EF6F26 /* TextDecoder.cpp */,
- B2C3DA140D006C1D00EF6F26 /* TextDecoder.h */,
B2C3DA150D006C1D00EF6F26 /* TextDirection.h */,
B2C3DA160D006C1D00EF6F26 /* TextEncoding.cpp */,
B2C3DA170D006C1D00EF6F26 /* TextEncoding.h */,
+ C105DA630F3AA6B8001DD44F /* TextEncodingDetector.h */,
+ C105DA610F3AA68F001DD44F /* TextEncodingDetectorICU.cpp */,
B2C3DA180D006C1D00EF6F26 /* TextEncodingRegistry.cpp */,
B2C3DA190D006C1D00EF6F26 /* TextEncodingRegistry.h */,
B2C3DA1A0D006C1D00EF6F26 /* TextStream.cpp */,
@@ -13216,6 +13428,8 @@
C09158850DB4209200E55AF4 /* JSInspectedObjectWrapper.h */,
C09158860DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp */,
C09158870DB4209200E55AF4 /* JSInspectorCallbackWrapper.h */,
+ 935F45400F7C3B5F00D7C1FB /* JSLazyEventListener.cpp */,
+ 935F45410F7C3B5F00D7C1FB /* JSLazyEventListener.h */,
E10743230E7835830033AF24 /* JSMessageChannelConstructor.cpp */,
E10743260E7835A50033AF24 /* JSMessageChannelConstructor.h */,
BCD9C26C0C17AA81005C90A2 /* JSNamedNodesCollection.cpp */,
@@ -13233,6 +13447,8 @@
B21127A50B3186770009BE53 /* JSSVGPODTypeWrapper.h */,
498391610F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.cpp */,
498391620F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.h */,
+ 494BD7970F55C90E00747828 /* JSWebKitPointConstructor.cpp */,
+ 494BD7980F55C90E00747828 /* JSWebKitPointConstructor.h */,
E1CA5CD50E8CDEE900E8EF90 /* JSWorkerConstructor.cpp */,
E1CA5CD20E8CDE8000E8EF90 /* JSWorkerConstructor.h */,
E1C36D320EB0A094007410BC /* JSWorkerContextBase.cpp */,
@@ -13252,7 +13468,13 @@
93B70D5309EB0C7C009D8468 /* ScriptController.cpp */,
93B70D5409EB0C7C009D8468 /* ScriptController.h */,
A83E1C720E49042B00140B9C /* ScriptControllerMac.mm */,
+ 41002CCC0F66EDEF009E660D /* ScriptFunctionCall.cpp */,
+ 41002CCB0F66EDEF009E660D /* ScriptFunctionCall.h */,
934CC1160EDCAC7300A658F2 /* ScriptInstance.h */,
+ 41F066E20F64BCF600A07EAC /* ScriptObject.h */,
+ 41F066E30F64BCF600A07EAC /* ScriptObject.cpp */,
+ 412A68460F6B03DD000EA66E /* ScriptObjectQuarantine.cpp */,
+ 419536500F68222400D0C679 /* ScriptObjectQuarantine.h */,
934CC1090EDB223900A658F2 /* ScriptSourceCode.h */,
41C760B00EDE03D300C1655F /* ScriptState.h */,
416F45EF0ED7B311008215B6 /* ScriptString.h */,
@@ -13346,7 +13568,6 @@
BC1DEA4E0E268EB60083A73F /* JSDocumentFragmentCustom.cpp */,
BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */,
BCEFAF4D0C317E6900FA81F6 /* JSEventCustom.cpp */,
- BC3B7B200E91AAF400D54065 /* JSEventTargetNodeCustom.cpp */,
FE80D7A60E9C1ED2000D6F75 /* JSGeolocationCustom.cpp */,
BC4EDEF30C08F3FB007EDD49 /* JSHTMLAppletElementCustom.cpp */,
BCCBAD3A0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp */,
@@ -13364,6 +13585,7 @@
AB4CB4EA0B8BDA3D009F40B0 /* JSHTMLSelectElementCustom.h */,
BCE7B1920D4E86960075A539 /* JSHistoryCustom.cpp */,
A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
+ 41F061690F5EFBDD00A07EAC /* JSInspectorControllerCustom.cpp */,
1C5FAEE60DCFDA6800D58F78 /* JSJavaScriptCallFrameCustom.cpp */,
BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
E1A5F99A0E7EAA2500AF85EA /* JSMessageChannelCustom.cpp */,
@@ -13485,6 +13707,8 @@
A9D247F60D757E3300FDF959 /* JSNavigator.h */,
BCEC01C00C274DDD009F4EC9 /* JSScreen.cpp */,
BCEC01C10C274DDD009F4EC9 /* JSScreen.h */,
+ 494BD79B0F55C94C00747828 /* JSWebKitPoint.cpp */,
+ 494BD79C0F55C94C00747828 /* JSWebKitPoint.h */,
);
name = Window;
sourceTree = "<group>";
@@ -13543,6 +13767,10 @@
BCB16C0D0979C3BD00467741 /* CachedXBLDocument.h */,
BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */,
BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */,
+ E1C416160F6563180092D2FB /* CrossOriginAccessControl.cpp */,
+ E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */,
+ E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */,
+ E1C415D90F655D6F0092D2FB /* CrossOriginPreflightResultCache.h */,
BCB16C100979C3BD00467741 /* DocLoader.cpp */,
BCB16C110979C3BD00467741 /* DocLoader.h */,
93E227DB0AF589AD00D48324 /* DocumentLoader.cpp */,
@@ -13558,7 +13786,6 @@
656D37220ADBA5DE00A4554D /* FormState.h */,
932E16080AF578340025F408 /* FrameLoader.cpp */,
656D37240ADBA5DE00A4554D /* FrameLoader.h */,
- E182504E0ED2F20200499A8F /* FrameLoaderClient.cpp */,
656D37260ADBA5DE00A4554D /* FrameLoaderClient.h */,
93B77A370ADD792500EA4B81 /* FrameLoaderTypes.h */,
1A820D8F0A13EBA600AF843C /* ImageDocument.cpp */,
@@ -13595,6 +13822,8 @@
0B9056180F2578BE0095FF6A /* ThreadableLoaderClient.h */,
7284ADDB0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp */,
7284ADDC0E6FEB31002EEFBD /* UserStyleSheetLoader.h */,
+ 0B9056F60F2685F30095FF6A /* WorkerThreadableLoader.cpp */,
+ 0B9056F70F2685F30095FF6A /* WorkerThreadableLoader.h */,
BCB16C130979C3BD00467741 /* loader.cpp */,
BCB16C140979C3BD00467741 /* loader.h */,
);
@@ -13627,10 +13856,14 @@
BCFB2F75097A2E1A00BA703D /* Arena.h */,
51E1ECB10C91C55600DC255B /* AutodrainedPool.h */,
BCC8CFCA0986CD2400140BF2 /* ColorData.gperf */,
+ 41D015C90F4B5C71004A662F /* ContentType.cpp */,
+ 41D015C80F4B5C71004A662F /* ContentType.h */,
93B6A0E70B0BCA6700F5027A /* ContextMenu.cpp */,
93B6A0E50B0BCA5C00F5027A /* ContextMenu.h */,
06027CAC0B1CBFC000884B2D /* ContextMenuItem.h */,
9352088109BD45E900F2038D /* CookieJar.h */,
+ 2E4346560F546A9900B0F1BA /* CrossThreadCopier.cpp */,
+ 2E4346570F546A9900B0F1BA /* CrossThreadCopier.h */,
F587868402DE3B8601EA4122 /* Cursor.h */,
F587869902DE3B8601EA4122 /* DeprecatedPtrList.h */,
F587851602DE375901EA4122 /* DeprecatedPtrListImpl.cpp */,
@@ -13672,6 +13905,7 @@
ABC128760B33AA6D00C693D5 /* PopupMenuClient.h */,
BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */,
E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */,
+ 1C63A2460F71646600C09D5A /* RunLoopTimer.h */,
F587866202DE3B1101EA4122 /* SSLKeyGenerator.h */,
93C09C850B0657AA005ABD4D /* ScrollTypes.h */,
BC2441C30E8B65D00055320F /* ScrollView.cpp */,
@@ -13694,6 +13928,8 @@
51DF6D7D0B92A16D00C2DC85 /* ThreadCheck.h */,
E1FF57A50F01256B00891EBB /* ThreadGlobalData.cpp */,
E1FF57A20F01255B00891EBB /* ThreadGlobalData.h */,
+ 185BCF260F3279CE000EA262 /* ThreadTimers.cpp */,
+ 185BCF270F3279CE000EA262 /* ThreadTimers.h */,
93309EA1099EB78C0056E581 /* Timer.cpp */,
9305B24C098F1B6B00C28855 /* Timer.h */,
1419D2C40CEA6F6100FF507A /* TreeShared.h */,
@@ -14040,10 +14276,10 @@
BCEA4821097D93020094C9E4 /* RenderBlock.h */,
BCEA4822097D93020094C9E4 /* RenderBox.cpp */,
BCEA4823097D93020094C9E4 /* RenderBox.h */,
+ BC96DB450F3A882200573CB3 /* RenderBoxModelObject.cpp */,
+ BC96DB420F3A880E00573CB3 /* RenderBoxModelObject.h */,
BCEA4826097D93020094C9E4 /* RenderButton.cpp */,
BCEA4827097D93020094C9E4 /* RenderButton.h */,
- BCEA482C097D93020094C9E4 /* RenderContainer.cpp */,
- BCEA482D097D93020094C9E4 /* RenderContainer.h */,
9392F1430AD185FE00691BD4 /* RenderCounter.cpp */,
9392F1410AD185F400691BD4 /* RenderCounter.h */,
A8EA73AF0A1900E300A8EF5F /* RenderFieldset.cpp */,
@@ -14052,8 +14288,6 @@
066C772F0AB603FD00238CC4 /* RenderFileUploadControl.h */,
BCEA482E097D93020094C9E4 /* RenderFlexibleBox.cpp */,
BCEA482F097D93020094C9E4 /* RenderFlexibleBox.h */,
- BCEA4830097D93020094C9E4 /* RenderFlow.cpp */,
- BCEA4831097D93020094C9E4 /* RenderFlow.h */,
853CA9EA0AEEC63C002372DC /* RenderForeignObject.cpp */,
853CA9EB0AEEC63C002372DC /* RenderForeignObject.h */,
A871DECC0A1530C700B12A68 /* RenderFrame.cpp */,
@@ -14070,8 +14304,12 @@
BCEA4839097D93020094C9E4 /* RenderInline.h */,
BCEA483A097D93020094C9E4 /* RenderLayer.cpp */,
BCEA483B097D93020094C9E4 /* RenderLayer.h */,
- A8EA73B60A1900E300A8EF5F /* RenderLegend.cpp */,
- A8EA73BD0A1900E300A8EF5F /* RenderLegend.h */,
+ 0F580CFC0F12DE9B0051D689 /* RenderLayerBacking.cpp */,
+ 0F580CFB0F12DE9B0051D689 /* RenderLayerBacking.h */,
+ 0F580CFA0F12DE9B0051D689 /* RenderLayerCompositor.cpp */,
+ 0F580CF90F12DE9B0051D689 /* RenderLayerCompositor.h */,
+ BC33FB1A0F30EE85002CDD7C /* RenderLineBoxList.cpp */,
+ 0BE030A10F3112FB003C1A46 /* RenderLineBoxList.h */,
ABB5419C0ACDDFE4002820EB /* RenderListBox.cpp */,
ABB5419D0ACDDFE4002820EB /* RenderListBox.h */,
A8EA7A480A191A5200A8EF5F /* RenderListItem.cpp */,
@@ -14086,6 +14324,8 @@
ABDDFE740A5C6E7000A3E11D /* RenderMenuList.h */,
BCEA4840097D93020094C9E4 /* RenderObject.cpp */,
BCEA4841097D93020094C9E4 /* RenderObject.h */,
+ BC60EFB60F33A0E700812A93 /* RenderObjectChildList.cpp */,
+ BC2CC8DE0F32881000A9DF26 /* RenderObjectChildList.h */,
A871DEC80A1530C700B12A68 /* RenderPart.cpp */,
A871DECF0A1530C700B12A68 /* RenderPart.h */,
A871DECE0A1530C700B12A68 /* RenderPartObject.cpp */,
@@ -14128,6 +14368,7 @@
BC3BE9920E9C1C7C00835588 /* RenderScrollbarPart.h */,
BC3BE9A40E9C239600835588 /* RenderScrollbarTheme.cpp */,
BC3BE9980E9C1E5D00835588 /* RenderScrollbarTheme.h */,
+ 0F11A54E0F39233100C37884 /* RenderSelectionInfo.h */,
AB247A6A0AFD6383003FA5FD /* RenderSlider.cpp */,
AB247A6B0AFD6383003FA5FD /* RenderSlider.h */,
A8DF4AE20980C42C0052981B /* RenderTable.cpp */,
@@ -14178,9 +14419,13 @@
B2EBDC9B0AF77E3400AE4A68 /* SVGRenderTreeAsText.h */,
853CA9E40AEEC608002372DC /* SVGRootInlineBox.cpp */,
853CA9E50AEEC608002372DC /* SVGRootInlineBox.h */,
+ 5D925B650F64D4DD00B847F0 /* ScrollBehavior.cpp */,
+ 5D925B660F64D4DD00B847F0 /* ScrollBehavior.h */,
A8CFF04C0A154F09000A4234 /* TableLayout.h */,
AB014DE10E689A4300E10445 /* TextControlInnerElements.cpp */,
AB014DE20E689A4300E10445 /* TextControlInnerElements.h */,
+ 0F500AB00F54DB3100EEF928 /* TransformState.cpp */,
+ 0F500AAE0F54DB1B00EEF928 /* TransformState.h */,
BCEA4813097D93020094C9E4 /* bidi.cpp */,
BCEA4814097D93020094C9E4 /* bidi.h */,
BCEA4815097D93020094C9E4 /* break_lines.cpp */,
@@ -14219,6 +14464,12 @@
BC4BF9E30D11E133007D247F /* ClassNames.h */,
BC904B720D10998F00680D32 /* ClassNodeList.cpp */,
BC904B730D10998F00680D32 /* ClassNodeList.h */,
+ BCC065770F3CE1B700CD2D87 /* ClientRect.cpp */,
+ BCC065780F3CE1B700CD2D87 /* ClientRect.h */,
+ BCC065790F3CE1B700CD2D87 /* ClientRect.idl */,
+ BCC0657A0F3CE1B700CD2D87 /* ClientRectList.cpp */,
+ BCC0657B0F3CE1B700CD2D87 /* ClientRectList.h */,
+ BCC0657C0F3CE1B700CD2D87 /* ClientRectList.idl */,
A784941A0B5FE507001E237A /* Clipboard.cpp */,
85031B280A44EFC700F992E0 /* Clipboard.h */,
BCA83E360D7CDC4E003421A8 /* Clipboard.idl */,
@@ -14275,9 +14526,6 @@
E12EDBE90B308E0B002704B6 /* EventTarget.cpp */,
E12EDB7A0B308A78002704B6 /* EventTarget.h */,
85AFA7420AAF298400E84305 /* EventTarget.idl */,
- 14EC267E09CA07E000E1EEEC /* EventTargetNode.cpp */,
- 14EC267D09CA07E000E1EEEC /* EventTargetNode.h */,
- BC3B7AEF0E919ADA00D54065 /* EventTargetNode.idl */,
BC60D8F00D2A11E000B9918F /* ExceptionBase.cpp */,
BC60D8F10D2A11E000B9918F /* ExceptionBase.h */,
93831B560D087D6000E5C984 /* ExceptionCode.cpp */,
@@ -14286,7 +14534,6 @@
085773340F0846010080583E /* FormControlElement.h */,
08B93F730F293481000720C2 /* FormControlElementWithState.cpp */,
08B93F740F293481000720C2 /* FormControlElementWithState.h */,
- 0BA5D3850F240FB4009B870B /* GenericWorkerTask.h */,
08700BE60F086C5300919419 /* InputElement.cpp */,
08591AA40F085C4E009BACB1 /* InputElement.h */,
85031B2D0A44EFC700F992E0 /* KeyboardEvent.cpp */,
@@ -14408,23 +14655,6 @@
85031B3A0A44EFC700F992E0 /* WheelEvent.cpp */,
85031B3B0A44EFC700F992E0 /* WheelEvent.h */,
93EEC1F709C2877700C515D1 /* WheelEvent.idl */,
- E1CA5CA40E8CD78500E8EF90 /* Worker.cpp */,
- E1CA5C9F0E8CD73B00E8EF90 /* Worker.h */,
- E1C8BE440E8BCCBB0064CB7D /* Worker.idl */,
- E1C2C4410EAD017B007E61FB /* WorkerContext.cpp */,
- E1C2C43D0EAD0133007E61FB /* WorkerContext.h */,
- E182564F0EF2ACE600933242 /* WorkerContext.idl */,
- E1C363050EAF2D07007410BC /* WorkerLocation.cpp */,
- E1C363000EAF2CC6007410BC /* WorkerLocation.h */,
- E1C362BB0EAF29FB007410BC /* WorkerLocation.idl */,
- E14799B30ECDE9D800292BF3 /* WorkerMessagingProxy.cpp */,
- E14799A60ECDE3A400292BF3 /* WorkerMessagingProxy.h */,
- 18A0537A0F26859C00A51705 /* WorkerRunLoop.cpp */,
- 18A0537B0F26859C00A51705 /* WorkerRunLoop.h */,
- E108224E0EC3156700E93953 /* WorkerTask.cpp */,
- E108224A0EC3153A00E93953 /* WorkerTask.h */,
- E1C2C4280EACE0E0007E61FB /* WorkerThread.cpp */,
- E1C2C4230EACE0BC007E61FB /* WorkerThread.h */,
F523D30902DE4476018635CA /* XMLTokenizer.cpp */,
F523D30A02DE4476018635CA /* XMLTokenizer.h */,
54C50F7A0E801DF3009832A0 /* XMLTokenizerLibxml2.cpp */,
@@ -14458,6 +14688,7 @@
49E912AB0EFAC906009D0CAF /* Animation.h in Headers */,
316FE1120E6E1DA700BF6088 /* AnimationBase.h in Headers */,
316FE1140E6E1DA700BF6088 /* AnimationController.h in Headers */,
+ 0F15DA8A0F3AAEE70000CE47 /* AnimationControllerPrivate.h in Headers */,
49E912AD0EFAC906009D0CAF /* AnimationList.h in Headers */,
93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */,
1A8F6BBD0DB55CDC001DB794 /* ApplicationCache.h in Headers */,
@@ -14551,9 +14782,10 @@
93F1995008245E59001E9ABC /* CachePolicy.h in Headers */,
BCB16C1A0979C3BD00467741 /* CachedCSSStyleSheet.h in Headers */,
BC64B4CC0CB4295D005F2B62 /* CachedFont.h in Headers */,
+ 51C0AA390F2AA10A001648C2 /* CachedFrame.h in Headers */,
+ 51CBFC990D10E483002DBF51 /* CachedFramePlatformData.h in Headers */,
BCB16C1C0979C3BD00467741 /* CachedImage.h in Headers */,
510184690B08602A004A825F /* CachedPage.h in Headers */,
- 51CBFC990D10E483002DBF51 /* CachedFramePlatformData.h in Headers */,
BCB16C200979C3BD00467741 /* CachedResource.h in Headers */,
BCFB2E5E0979E46400BA703D /* CachedResourceClient.h in Headers */,
BCB16C220979C3BD00467741 /* CachedResourceClientWalker.h in Headers */,
@@ -14576,6 +14808,8 @@
14D824080AF93AEB0004F057 /* ChromeClient.h in Headers */,
BC4BF9E50D11E133007D247F /* ClassNames.h in Headers */,
BC904B770D10998F00680D32 /* ClassNodeList.h in Headers */,
+ BCC0657E0F3CE1B700CD2D87 /* ClientRect.h in Headers */,
+ BCC065810F3CE1B700CD2D87 /* ClientRectList.h in Headers */,
85031B3E0A44EFC700F992E0 /* Clipboard.h in Headers */,
4B8AF4AA0B1CE02B00687690 /* ClipboardAccessPolicy.h in Headers */,
85031B400A44EFC700F992E0 /* ClipboardEvent.h in Headers */,
@@ -14590,6 +14824,7 @@
BC0B36A50CD3C67C00AC7EB5 /* Console.h in Headers */,
A818721C0977D3C0005826D9 /* ContainerNode.h in Headers */,
BC5EB9810E82072500B25965 /* ContentData.h in Headers */,
+ 41D015CA0F4B5C71004A662F /* ContentType.h in Headers */,
93B6A0E60B0BCA5C00F5027A /* ContextMenu.h in Headers */,
065AD4F50B0C2EDA005A2B1D /* ContextMenuClient.h in Headers */,
065AD4F70B0C2EDA005A2B1D /* ContextMenuController.h in Headers */,
@@ -14602,6 +14837,7 @@
9392F14C0AD1861B00691BD4 /* CounterNode.h in Headers */,
D0B0556809C6700100307E43 /* CreateLinkCommand.h in Headers */,
514C766E0CE923A1007EF3CD /* Credential.h in Headers */,
+ 2E4346590F546A9900B0F1BA /* CrossThreadCopier.h in Headers */,
93F1992F08245E59001E9ABC /* Cursor.h in Headers */,
BC2272A20E82E87C00E7F975 /* CursorData.h in Headers */,
BC2272AD0E82E8F300E7F975 /* CursorList.h in Headers */,
@@ -15310,6 +15546,7 @@
DDE63ED50B7D45A800226998 /* DOMTextEvent.h in Headers */,
85E711D90AC5D5350053270F /* DOMTextInternal.h in Headers */,
BCC5733A0D695BF1006EF517 /* DOMTextPrivate.h in Headers */,
+ 188604B40F2E654A000B6443 /* DOMTimer.h in Headers */,
BC1A37BE097C715F0019F3D8 /* DOMTraversal.h in Headers */,
85526CD20AB0B7D9000302EA /* DOMTreeWalker.h in Headers */,
850B41C30AD9E7E700A6ED4F /* DOMTreeWalkerInternal.h in Headers */,
@@ -15393,7 +15630,6 @@
1CA19E160DC255CA0065A994 /* EventLoop.h in Headers */,
939885C408B7E3D100E707C4 /* EventNames.h in Headers */,
E12EDB7B0B308A78002704B6 /* EventTarget.h in Headers */,
- 14EC267F09CA07E000E1EEEC /* EventTargetNode.h in Headers */,
BC60D8F30D2A11E000B9918F /* ExceptionBase.h in Headers */,
935FBCF209BA143B00E230B1 /* ExceptionCode.h in Headers */,
148AFDA50AF58360008CC700 /* ExceptionHandlers.h in Headers */,
@@ -15453,7 +15689,7 @@
935C477509AC4D8E00A6AAB4 /* GapRects.h in Headers */,
BC23F0DB0DAFF4A4009FDC91 /* GeneratedImage.h in Headers */,
BCE04C8A0DAFF7A0007A0F41 /* Generator.h in Headers */,
- 0BA5D3860F240FB4009B870B /* GenericWorkerTask.h in Headers */,
+ 2E4346440F546A8200B0F1BA /* GenericWorkerTask.h in Headers */,
FE80D7C60E9C1F25000D6F75 /* Geolocation.h in Headers */,
FEAB90130EA51B9C006348C3 /* GeolocationService.h in Headers */,
FE80D7C90E9C1F25000D6F75 /* Geoposition.h in Headers */,
@@ -15465,6 +15701,9 @@
B2A015A90AF6CD53006BCE0E /* GraphicsContext.h in Headers */,
A80D67080E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h in Headers */,
A88FE3340E5EEE87008D8C0F /* GraphicsContextPrivate.h in Headers */,
+ 0F580B0D0F12A2690051D689 /* GraphicsLayer.h in Headers */,
+ 0F580B060F12A2550051D689 /* GraphicsLayerCA.h in Headers */,
+ 0F580B0E0F12A2690051D689 /* GraphicsLayerClient.h in Headers */,
B2A015AB0AF6CD53006BCE0E /* GraphicsTypes.h in Headers */,
A8CFF7AB0A156978000A4234 /* HTMLAnchorElement.h in Headers */,
A871D45D0A127CBC00B12A68 /* HTMLAppletElement.h in Headers */,
@@ -15483,7 +15722,7 @@
A8EA7CB70A192B9C00A8EF5F /* HTMLDivElement.h in Headers */,
93F198E508245E59001E9ABC /* HTMLDocument.h in Headers */,
93F198E608245E59001E9ABC /* HTMLElement.h in Headers */,
- BCEF3435087B563E00BBF833 /* HTMLElementFactory.h in Headers */,
+ A17C81230F2A5CF7005DAAEB /* HTMLElementFactory.h in Headers */,
A871D45C0A127CBC00B12A68 /* HTMLEmbedElement.h in Headers */,
A81369D4097374F600D74463 /* HTMLFieldSetElement.h in Headers */,
A8CFF7A60A156978000A4234 /* HTMLFontElement.h in Headers */,
@@ -15560,6 +15799,7 @@
1A2D753D0DE47FAB00F0A648 /* IconFetcher.h in Headers */,
513F14540AB634C400094DDF /* IconLoader.h in Headers */,
51E1ECC10C91C90400DC255B /* IconRecord.h in Headers */,
+ 1A71D57C0F33819000F9CE4E /* IdentifierRep.h in Headers */,
49E911C50EF86D47009D0CAF /* IdentityTransformOperation.h in Headers */,
B27535700B053814002CE64F /* Image.h in Headers */,
B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */,
@@ -15611,6 +15851,8 @@
65DF323C09D1DE65000BE325 /* JSCanvasPattern.h in Headers */,
65DF323E09D1DE65000BE325 /* JSCanvasRenderingContext2D.h in Headers */,
65DF31F409D1CC60000BE325 /* JSCharacterData.h in Headers */,
+ BCC065880F3CE2A700CD2D87 /* JSClientRect.h in Headers */,
+ BCC0658A0F3CE2A700CD2D87 /* JSClientRectList.h in Headers */,
BCA83E500D7CE1E9003421A8 /* JSClipboard.h in Headers */,
93F9B6E10BA0FB7200854064 /* JSComment.h in Headers */,
BC98543E0CD3D98C00069BC1 /* JSConsole.h in Headers */,
@@ -15648,7 +15890,6 @@
93B70D6A09EB0C7C009D8468 /* JSEventListener.h in Headers */,
BC60901F0E91B8EC000C68B5 /* JSEventTarget.h in Headers */,
B25BE5110D06B70800B524C6 /* JSEventTargetBase.h in Headers */,
- BC3B7AF40E919CA900D54065 /* JSEventTargetNode.h in Headers */,
BC00F0150E0A189500FD04E3 /* JSFile.h in Headers */,
BC00F0170E0A189500FD04E3 /* JSFileList.h in Headers */,
FE80DA640E9C4703000D6F75 /* JSGeolocation.h in Headers */,
@@ -15917,6 +16158,8 @@
498391640F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.h in Headers */,
498391640F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.h in Headers */,
31611E5B0E1C4DE000F6A579 /* JSWebKitCSSTransformValue.h in Headers */,
+ 494BD79E0F55C94C00747828 /* JSWebKitPoint.h in Headers */,
+ 494BD79A0F55C90E00747828 /* JSWebKitPointConstructor.h in Headers */,
31C0FF400E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.h in Headers */,
65DF320609D1CC60000BE325 /* JSWheelEvent.h in Headers */,
E1CAA5C60E8BD23600A73ECA /* JSWorker.h in Headers */,
@@ -15973,6 +16216,7 @@
1A8F6BC60DB55CDC001DB794 /* ManifestParser.h in Headers */,
A8C4A80509D563270003AC8D /* MappedAttribute.h in Headers */,
A8C4A84C09D5649D0003AC8D /* MappedAttributeEntry.h in Headers */,
+ 49D5DC2C0F423A73008F20FD /* Matrix3DTransformOperation.h in Headers */,
49E911C70EF86D47009D0CAF /* MatrixTransformOperation.h in Headers */,
ABFE7E130D32FAF60066F4D2 /* MediaControlElements.h in Headers */,
AB40484E0E083FA8007D6920 /* MediaDocument.h in Headers */,
@@ -15981,6 +16225,7 @@
A8EA800E0A19516E00A8EF5F /* MediaList.h in Headers */,
E44613E40CD681A200FADA75 /* MediaPlayer.h in Headers */,
E44613E60CD681A900FADA75 /* MediaPlayerPrivateQTKit.h in Headers */,
+ 0735EE6A0F40C5E4004A2604 /* MediaPlayerProxy.h in Headers */,
4E19592A0A39DACC00220FE5 /* MediaQuery.h in Headers */,
4E19592C0A39DACC00220FE5 /* MediaQueryEvaluator.h in Headers */,
4E19592E0A39DACC00220FE5 /* MediaQueryExp.h in Headers */,
@@ -16039,6 +16284,7 @@
A8FA6E5D0E4CFDED00D5CF49 /* Pattern.h in Headers */,
B22279710D00BF220071B782 /* PatternAttributes.h in Headers */,
B27535820B053814002CE64F /* Pen.h in Headers */,
+ 49D5DC2E0F423A73008F20FD /* PerspectiveTransformOperation.h in Headers */,
935C476809AC4D4300A6AAB4 /* PlatformKeyboardEvent.h in Headers */,
932871C00B20DEB70049035A /* PlatformMenuDescription.h in Headers */,
935C476909AC4D4300A6AAB4 /* PlatformMouseEvent.h in Headers */,
@@ -16084,13 +16330,12 @@
BCEA4864097D93020094C9E4 /* RenderBR.h in Headers */,
BCEA4860097D93020094C9E4 /* RenderBlock.h in Headers */,
BCEA4862097D93020094C9E4 /* RenderBox.h in Headers */,
+ BC96DB430F3A880E00573CB3 /* RenderBoxModelObject.h in Headers */,
BCEA4866097D93020094C9E4 /* RenderButton.h in Headers */,
- BCEA486C097D93020094C9E4 /* RenderContainer.h in Headers */,
9392F1420AD185F400691BD4 /* RenderCounter.h in Headers */,
A8EA73C40A1900E300A8EF5F /* RenderFieldset.h in Headers */,
066C77310AB603FD00238CC4 /* RenderFileUploadControl.h in Headers */,
BCEA486E097D93020094C9E4 /* RenderFlexibleBox.h in Headers */,
- BCEA4870097D93020094C9E4 /* RenderFlow.h in Headers */,
853CA9ED0AEEC63C002372DC /* RenderForeignObject.h in Headers */,
A871DED30A1530C700B12A68 /* RenderFrame.h in Headers */,
A871DED10A1530C700B12A68 /* RenderFrameSet.h in Headers */,
@@ -16099,7 +16344,9 @@
BCB4F8900DB28DD60039139B /* RenderImageGeneratedContent.h in Headers */,
BCEA4878097D93020094C9E4 /* RenderInline.h in Headers */,
BCEA487A097D93020094C9E4 /* RenderLayer.h in Headers */,
- A8EA73D10A1900E300A8EF5F /* RenderLegend.h in Headers */,
+ 0F580CFF0F12DE9B0051D689 /* RenderLayerBacking.h in Headers */,
+ 0F580CFD0F12DE9B0051D689 /* RenderLayerCompositor.h in Headers */,
+ 0BE030A20F3112FB003C1A46 /* RenderLineBoxList.h in Headers */,
ABB5419F0ACDDFE4002820EB /* RenderListBox.h in Headers */,
A8EA7A520A191A5200A8EF5F /* RenderListItem.h in Headers */,
A8EA7A500A191A5200A8EF5F /* RenderListMarker.h in Headers */,
@@ -16107,6 +16354,7 @@
E4C279590CF9741900E97B98 /* RenderMedia.h in Headers */,
ABDDFE7A0A5C6E7000A3E11D /* RenderMenuList.h in Headers */,
BCEA4880097D93020094C9E4 /* RenderObject.h in Headers */,
+ BC2CC8DF0F32881000A9DF26 /* RenderObjectChildList.h in Headers */,
A871DED70A1530C700B12A68 /* RenderPart.h in Headers */,
A871DED50A1530C700B12A68 /* RenderPartObject.h in Headers */,
853CA9F10AEEC657002372DC /* RenderPath.h in Headers */,
@@ -16128,6 +16376,7 @@
BC3BE9940E9C1C7C00835588 /* RenderScrollbar.h in Headers */,
BC3BE9950E9C1C7C00835588 /* RenderScrollbarPart.h in Headers */,
BC3BE9990E9C1E5D00835588 /* RenderScrollbarTheme.h in Headers */,
+ 0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */,
AB247A6D0AFD6383003FA5FD /* RenderSlider.h in Headers */,
BC8C8FAE0DDCD31B00B592F4 /* RenderStyle.h in Headers */,
BC5EB6680E81CB7100B25965 /* RenderStyleConstants.h in Headers */,
@@ -16368,7 +16617,10 @@
93B70D7009EB0C7C009D8468 /* ScriptController.h in Headers */,
08A484780E5272C500C3FE76 /* ScriptElement.h in Headers */,
E11C9D9B0EB3681200E409DB /* ScriptExecutionContext.h in Headers */,
+ 41002CCD0F66EDEF009E660D /* ScriptFunctionCall.h in Headers */,
934CC1170EDCAC7300A658F2 /* ScriptInstance.h in Headers */,
+ 41F066E40F64BCF600A07EAC /* ScriptObject.h in Headers */,
+ 419536510F68222400D0C679 /* ScriptObjectQuarantine.h in Headers */,
934CC10A0EDB223900A658F2 /* ScriptSourceCode.h in Headers */,
41C760B10EDE03D300C1655F /* ScriptState.h in Headers */,
416F45F00ED7B311008215B6 /* ScriptString.h in Headers */,
@@ -16385,7 +16637,6 @@
BCD0E0FC0E972C3500265DEA /* SecurityOriginHash.h in Headers */,
371F4FFC0D25E7F300ECE0D5 /* SegmentedFontData.h in Headers */,
B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */,
- 93309E0C099E64920056E581 /* Selection.h in Headers */,
93309E0E099E64920056E581 /* SelectionController.h in Headers */,
BC7FA6810D1F167900DB22A9 /* SelectorNodeList.h in Headers */,
51E0BB230DA572A600A9E417 /* SessionStorage.h in Headers */,
@@ -16460,10 +16711,10 @@
B2C3DA420D006C1D00EF6F26 /* TextCodecUTF16.h in Headers */,
B2C3DA400D006C1D00EF6F26 /* TextCodecUserDefined.h in Headers */,
AB014DE40E689A4300E10445 /* TextControlInnerElements.h in Headers */,
- B2C3DA440D006C1D00EF6F26 /* TextDecoder.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 */,
933A14300B7D188600A53FFD /* TextEvent.h in Headers */,
93309E18099E64920056E581 /* TextGranularity.h in Headers */,
@@ -16477,6 +16728,7 @@
BCE659A90EA927B9007E4533 /* ThemeTypes.h in Headers */,
51DF6D7E0B92A16D00C2DC85 /* ThreadCheck.h in Headers */,
E1FF57A30F01255B00891EBB /* ThreadGlobalData.h in Headers */,
+ 185BCF290F3279CE000EA262 /* ThreadTimers.h in Headers */,
0B90561B0F2578BF0095FF6A /* ThreadableLoader.h in Headers */,
0B90561C0F2578BF0095FF6A /* ThreadableLoaderClient.h in Headers */,
E44613B00CD6331000FADA75 /* TimeRanges.h in Headers */,
@@ -16485,6 +16737,7 @@
BCCFBAE80B5152ED0001F1D7 /* Tokenizer.h in Headers */,
49E911CE0EF86D47009D0CAF /* TransformOperation.h in Headers */,
49E911D00EF86D47009D0CAF /* TransformOperations.h in Headers */,
+ 0F500AAF0F54DB1B00EEF928 /* TransformState.h in Headers */,
49E911C40EF86D47009D0CAF /* TransformationMatrix.h in Headers */,
49E911D20EF86D47009D0CAF /* TranslateTransformOperation.h in Headers */,
854FE7370A2297BE0058D7AD /* Traversal.h in Headers */,
@@ -16499,6 +16752,7 @@
656581B209D14EE6000E61D7 /* UserAgentStyleSheets.h in Headers */,
7284ADDE0E6FEB31002EEFBD /* UserStyleSheetLoader.h in Headers */,
93309E20099E64920056E581 /* VisiblePosition.h in Headers */,
+ A883DF280F3D045D00F19BF6 /* VisibleSelection.h in Headers */,
E44613B60CD6344E00FADA75 /* VoidCallback.h in Headers */,
B25599490D00D8BA00BB825C /* WKArithmeticFilter.h in Headers */,
B255994C0D00D8BA00BB825C /* WKComponentMergeFilter.h in Headers */,
@@ -16570,22 +16824,28 @@
498391590F1E776900C23782 /* WebKitCSSMatrix.h in Headers */,
498391590F1E776900C23782 /* WebKitCSSMatrix.h in Headers */,
BC9ADD230CC4032600098C4C /* WebKitCSSTransformValue.h in Headers */,
+ 494BD7950F55C8EE00747828 /* WebKitPoint.h in Headers */,
31C0FF250E4CEB6E007D6FE5 /* WebKitTransitionEvent.h in Headers */,
+ 0FCF332F0F2B9A25004B6795 /* WebLayer.h in Headers */,
1CAF34810A6C405200ABE06E /* WebScriptObject.h in Headers */,
1A569D1B0D7E2B82007C3983 /* WebScriptObject.h in Headers */,
1CAF34830A6C405200ABE06E /* WebScriptObjectPrivate.h in Headers */,
+ 0FCF332D0F2B9A25004B6795 /* WebTiledLayer.h in Headers */,
85031B510A44EFC700F992E0 /* WheelEvent.h in Headers */,
9380F47409A11AB4001FDB34 /* Widget.h in Headers */,
939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */,
- E1CA5CA00E8CD73B00E8EF90 /* Worker.h in Headers */,
- E1C2C43E0EAD0133007E61FB /* WorkerContext.h in Headers */,
- E1C363010EAF2CC6007410BC /* WorkerLocation.h in Headers */,
- E14799A70ECDE3A400292BF3 /* WorkerMessagingProxy.h in Headers */,
+ 2E4346460F546A8200B0F1BA /* Worker.h in Headers */,
+ 2E4346490F546A8200B0F1BA /* WorkerContext.h in Headers */,
+ 2E43464B0F546A8200B0F1BA /* WorkerContextProxy.h in Headers */,
+ 2E43464D0F546A8200B0F1BA /* WorkerLocation.h in Headers */,
+ 2E4346500F546A8200B0F1BA /* WorkerMessagingProxy.h in Headers */,
E1271A0B0EEEC77A00F61213 /* WorkerNavigator.h in Headers */,
+ 2E4346510F546A8200B0F1BA /* WorkerObjectProxy.h in Headers */,
+ 2E4346530F546A8200B0F1BA /* WorkerRunLoop.h in Headers */,
E1A643F20EC0972500779668 /* WorkerScriptController.h in Headers */,
- E108224B0EC3153A00E93953 /* WorkerTask.h in Headers */,
- E1C2C4240EACE0BC007E61FB /* WorkerThread.h in Headers */,
+ 2E4346550F546A8200B0F1BA /* WorkerThread.h in Headers */,
+ 0B9056F90F2685F30095FF6A /* WorkerThreadableLoader.h in Headers */,
93309E24099E64920056E581 /* WrapContentsInDummySpanCommand.h in Headers */,
6565820209D1508D000E61D7 /* XLinkNames.h in Headers */,
BC772C470C4EB2C60083285F /* XMLHttpRequest.h in Headers */,
@@ -16649,9 +16909,20 @@
1A569D230D7E2B82007C3983 /* runtime_object.h in Headers */,
1A569D250D7E2B82007C3983 /* runtime_root.h in Headers */,
93309E1E099E64920056E581 /* visible_units.h in Headers */,
- 18A0537D0F26859C00A51705 /* WorkerRunLoop.h in Headers */,
- 51C0AA390F2AA10A001648C2 /* CachedFrame.h in Headers */,
- 188604B40F2E654A000B6443 /* DOMTimer.h in Headers */,
+ BCE494AB0F4F5E9E0084E319 /* GeolocationServiceMac.h in Headers */,
+ 41F060CE0F5EEB2B00A07EAC /* JSInspectorController.h in Headers */,
+ 41F061740F5F00AC00A07EAC /* InspectorDOMStorageResource.h in Headers */,
+ 41F0618E0F5F069800A07EAC /* ConsoleMessage.h in Headers */,
+ 41F062010F5F0B6600A07EAC /* InspectorResource.h in Headers */,
+ 41F062140F5F192600A07EAC /* InspectorDatabaseResource.h in Headers */,
+ 5D925B680F64D4DD00B847F0 /* ScrollBehavior.h in Headers */,
+ E1C415DA0F655D6F0092D2FB /* CrossOriginPreflightResultCache.h in Headers */,
+ E1C416120F6562FD0092D2FB /* CrossOriginAccessControl.h in Headers */,
+ A7D6B3490F61104500B79FD1 /* WorkerImportScriptsClient.h in Headers */,
+ FE6FD4880F676E5700092873 /* Coordinates.h in Headers */,
+ FE6FD48E0F676E9300092873 /* JSCoordinates.h in Headers */,
+ 1C63A2480F71646600C09D5A /* RunLoopTimer.h in Headers */,
+ 935F45430F7C3B5F00D7C1FB /* JSLazyEventListener.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -16720,7 +16991,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- A7094AFC0F27AEE300596CEC /* CanvasPixelArray.idl in Resources */,
B25599480D00D8BA00BB825C /* WKArithmeticFilter.cikernel in Resources */,
B255994B0D00D8BA00BB825C /* WKComponentMergeFilter.cikernel in Resources */,
B255994E0D00D8BA00BB825C /* WKDiffuseLightingFilter.cikernel in Resources */,
@@ -16767,6 +17037,7 @@
85136CA80AED665900F90A3D /* westResizeCursor.png in Resources */,
1AB1AE7A0C051FDE00139F4F /* zoomInCursor.png in Resources */,
1AB1AE7B0C051FDE00139F4F /* zoomOutCursor.png in Resources */,
+ FE6FD4890F676E5700092873 /* Coordinates.idl in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -16850,7 +17121,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -f ../WebKitTools/Scripts/check-for-weak-vtables ]; then\n ../WebKitTools/Scripts/check-for-weak-vtables || exit $?\nfi";
+ shellScript = "if [ \"${ACTION}\" = \"installhdrs\" ]; then\n exit 0;\nfi\n\nif [ -f ../WebKitTools/Scripts/check-for-weak-vtables ]; then\n ../WebKitTools/Scripts/check-for-weak-vtables || exit $?\nfi";
};
5D2F7DA00C6879C600B5B72B /* Update Info.plist with version information */ = {
isa = PBXShellScriptBuildPhase;
@@ -16880,7 +17151,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -f ../WebKitTools/Scripts/check-for-exit-time-destructors ]; then\n ../WebKitTools/Scripts/check-for-exit-time-destructors || exit $?\nfi";
+ shellScript = "if [ \"${ACTION}\" = \"installhdrs\" ]; then\n exit 0;\nfi\n\nif [ -f ../WebKitTools/Scripts/check-for-exit-time-destructors ]; then\n ../WebKitTools/Scripts/check-for-exit-time-destructors || exit $?\nfi";
};
939D050109D9FF6B00984996 /* Check For Global Initializers */ = {
isa = PBXShellScriptBuildPhase;
@@ -16894,7 +17165,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -f ../WebKitTools/Scripts/check-for-global-initializers ]; then\n ../WebKitTools/Scripts/check-for-global-initializers || exit $?\nfi";
+ shellScript = "if [ \"${ACTION}\" = \"installhdrs\" ]; then\n exit 0;\nfi\n\nif [ -f ../WebKitTools/Scripts/check-for-global-initializers ]; then\n ../WebKitTools/Scripts/check-for-global-initializers || exit $?\nfi";
};
DD041FBD09D9DDBE0010AF2A /* Generate Derived Sources */ = {
isa = PBXShellScriptBuildPhase;
@@ -16908,7 +17179,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\n\nif [ \"${BUILD_STYLE}\" = \"Release\" -o \"${BUILD_STYLE}\" = \"Debug\" ] ; then\n export CREATE_HASH_TABLE=\"${BUILT_PRODUCTS_DIR}/JavaScriptCore.framework/PrivateHeaders/create_hash_table\"\nelse\n export CREATE_HASH_TABLE=\"${NEXT_ROOT}${SYSTEM_LIBRARY_DIR}/Frameworks/JavaScriptCore.framework/PrivateHeaders/create_hash_table\"\nfi\n\nln -sfh \"${SRCROOT}\" WebCore\nexport WebCore=\"WebCore\"\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" ]; then\n make -f \"WebCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.availcpu`\nfi\n";
+ shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\ncd \"${BUILT_PRODUCTS_DIR}/DerivedSources/WebCore\"\n\nexport CREATE_HASH_TABLE=\"${JAVASCRIPTCORE_PRIVATE_HEADERS_DIR}/create_hash_table\"\n\nln -sfh \"${SRCROOT}\" WebCore\nexport WebCore=\"WebCore\"\n\nif [ \"${ACTION}\" = \"build\" -o \"${ACTION}\" = \"install\" -o \"${ACTION}\" = \"installhdrs\" ]; then\n make -f \"WebCore/DerivedSources.make\" -j `/usr/sbin/sysctl -n hw.availcpu`\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -17013,6 +17284,7 @@
BCB16C170979C3BD00467741 /* Cache.cpp in Sources */,
BCB16C190979C3BD00467741 /* CachedCSSStyleSheet.cpp in Sources */,
BC64B4CB0CB4295D005F2B62 /* CachedFont.cpp in Sources */,
+ 51C0AA410F2AA15E001648C2 /* CachedFrame.cpp in Sources */,
BCB16C1B0979C3BD00467741 /* CachedImage.cpp in Sources */,
5101846A0B08602A004A825F /* CachedPage.cpp in Sources */,
BCB16C1F0979C3BD00467741 /* CachedResource.cpp in Sources */,
@@ -17034,10 +17306,13 @@
ABAF22080C03B1C700B0BCF0 /* ChromeMac.mm in Sources */,
BC4BF9E40D11E133007D247F /* ClassNames.cpp in Sources */,
BC904B760D10998F00680D32 /* ClassNodeList.cpp in Sources */,
+ BCC0657D0F3CE1B700CD2D87 /* ClientRect.cpp in Sources */,
+ BCC065800F3CE1B700CD2D87 /* ClientRectList.cpp in Sources */,
A784941B0B5FE507001E237A /* Clipboard.cpp in Sources */,
85031B3F0A44EFC700F992E0 /* ClipboardEvent.cpp in Sources */,
93F19AFF08245E59001E9ABC /* ClipboardMac.mm in Sources */,
B27535660B053814002CE64F /* Color.cpp in Sources */,
+ 0FCF33240F2B9715004B6795 /* ColorCG.cpp in Sources */,
B22279620D00BF220071B782 /* ColorDistance.cpp in Sources */,
B27535770B053814002CE64F /* ColorMac.mm in Sources */,
6550B6A1099DF0270090D781 /* Comment.cpp in Sources */,
@@ -17046,6 +17321,7 @@
BC0B36A40CD3C67C00AC7EB5 /* Console.cpp in Sources */,
A818721F0977D3C0005826D9 /* ContainerNode.cpp in Sources */,
BC5EB9800E82072500B25965 /* ContentData.cpp in Sources */,
+ 41D015CB0F4B5C71004A662F /* ContentType.cpp in Sources */,
93B6A0E80B0BCA6700F5027A /* ContextMenu.cpp in Sources */,
065AD4F60B0C2EDA005A2B1D /* ContextMenuController.cpp in Sources */,
06027CB30B1CC03D00884B2D /* ContextMenuItemMac.mm in Sources */,
@@ -17056,6 +17332,7 @@
9392F1500AD1862300691BD4 /* CounterNode.cpp in Sources */,
D0B0556909C6700100307E43 /* CreateLinkCommand.cpp in Sources */,
514C766D0CE923A1007EF3CD /* Credential.cpp in Sources */,
+ 2E4346580F546A9900B0F1BA /* CrossThreadCopier.cpp in Sources */,
93F19A2608245E59001E9ABC /* CursorMac.mm in Sources */,
B2F34FE90E82F82700F627CD /* DNSCFNet.cpp in Sources */,
BC1A37AE097C715F0019F3D8 /* DOM.mm in Sources */,
@@ -17315,6 +17592,7 @@
850657030AAB4763002D15C0 /* DOMStyleSheetList.mm in Sources */,
85ACA99D0A9B575900671E90 /* DOMText.mm in Sources */,
933A14AA0B7D1D0900A53FFD /* DOMTextEvent.mm in Sources */,
+ 188604B30F2E654A000B6443 /* DOMTimer.cpp in Sources */,
85526CD30AB0B7DA000302EA /* DOMTreeWalker.mm in Sources */,
85C7F4920AAF79DC004014DD /* DOMUIEvent.mm in Sources */,
BC1A37BF097C715F0019F3D8 /* DOMUtility.mm in Sources */,
@@ -17368,7 +17646,6 @@
1CA19E050DC255950065A994 /* EventLoopMac.mm in Sources */,
939885C308B7E3D100E707C4 /* EventNames.cpp in Sources */,
E12EDBEA0B308E0B002704B6 /* EventTarget.cpp in Sources */,
- 14EC268009CA07E000E1EEEC /* EventTargetNode.cpp in Sources */,
BC60D8F20D2A11E000B9918F /* ExceptionBase.cpp in Sources */,
93831B570D087D6000E5C984 /* ExceptionCode.cpp in Sources */,
148AFDA60AF58360008CC700 /* ExceptionHandlers.mm in Sources */,
@@ -17426,7 +17703,6 @@
D05CED290A40BB2C00C5AF38 /* FormatBlockCommand.cpp in Sources */,
65BF022E0974816300C43196 /* Frame.cpp in Sources */,
932E16090AF578340025F408 /* FrameLoader.cpp in Sources */,
- E182504F0ED2F20200499A8F /* FrameLoaderClient.cpp in Sources */,
65BF02450974819000C43196 /* FrameMac.mm in Sources */,
65A21484097A3F5300B9050A /* FrameTree.cpp in Sources */,
65CBFEF90974F607001DAC25 /* FrameView.cpp in Sources */,
@@ -17443,6 +17719,8 @@
B2A015A80AF6CD53006BCE0E /* GraphicsContext.cpp in Sources */,
B2ED97710B1F55CE00257D0F /* GraphicsContextCG.cpp in Sources */,
B277B4040B22F37C0004BEC6 /* GraphicsContextMac.mm in Sources */,
+ 0F580B0C0F12A2690051D689 /* GraphicsLayer.cpp in Sources */,
+ 0F580B050F12A2550051D689 /* GraphicsLayerCA.mm in Sources */,
B2A015AA0AF6CD53006BCE0E /* GraphicsTypes.cpp in Sources */,
A8CFF7A40A156978000A4234 /* HTMLAnchorElement.cpp in Sources */,
A871D45E0A127CBC00B12A68 /* HTMLAppletElement.cpp in Sources */,
@@ -17461,7 +17739,7 @@
A8EA7CB10A192B9C00A8EF5F /* HTMLDivElement.cpp in Sources */,
93F19A9108245E59001E9ABC /* HTMLDocument.cpp in Sources */,
93F19A9208245E59001E9ABC /* HTMLElement.cpp in Sources */,
- BCEF3434087B563E00BBF833 /* HTMLElementFactory.cpp in Sources */,
+ A17C81220F2A5CF7005DAAEB /* HTMLElementFactory.cpp in Sources */,
A871D45F0A127CBC00B12A68 /* HTMLEmbedElement.cpp in Sources */,
A81369D5097374F600D74463 /* HTMLFieldSetElement.cpp in Sources */,
A8CFF7A20A156978000A4234 /* HTMLFontElement.cpp in Sources */,
@@ -17537,6 +17815,7 @@
513F14530AB634C400094DDF /* IconLoader.cpp in Sources */,
B275358E0B053A66002CE64F /* IconMac.mm in Sources */,
51E1ECC00C91C90400DC255B /* IconRecord.cpp in Sources */,
+ 1A71D57B0F33819000F9CE4E /* IdentifierRep.cpp in Sources */,
B275356F0B053814002CE64F /* Image.cpp in Sources */,
B2A10B940B3818D700099AA4 /* ImageBufferCG.cpp in Sources */,
B275355E0B053814002CE64F /* ImageCG.cpp in Sources */,
@@ -17571,6 +17850,7 @@
E4EEFFC80D34550C00469A58 /* JSAudioConstructor.cpp in Sources */,
BC124EFF0C26447A009E2349 /* JSBarInfo.cpp in Sources */,
93F9B7A00BA6032600854064 /* JSCDATASection.cpp in Sources */,
+ 93BA59B20F2AA5FE008E8E99 /* JSCDATASectionCustom.cpp in Sources */,
BC46C1FA0C0DDC8F0020CFC3 /* JSCSSCharsetRule.cpp in Sources */,
BC46C1FC0C0DDC8F0020CFC3 /* JSCSSFontFaceRule.cpp in Sources */,
BC46C1FE0C0DDC8F0020CFC3 /* JSCSSImportRule.cpp in Sources */,
@@ -17594,6 +17874,8 @@
65DF323D09D1DE65000BE325 /* JSCanvasRenderingContext2D.cpp in Sources */,
1A9EF4570A1B957D00332B63 /* JSCanvasRenderingContext2DCustom.cpp in Sources */,
65DF31F309D1CC60000BE325 /* JSCharacterData.cpp in Sources */,
+ BCC065870F3CE2A700CD2D87 /* JSClientRect.cpp in Sources */,
+ BCC065890F3CE2A700CD2D87 /* JSClientRectList.cpp in Sources */,
BCA83E4F0D7CE1E9003421A8 /* JSClipboard.cpp in Sources */,
BCA83E520D7CE205003421A8 /* JSClipboardCustom.cpp in Sources */,
93F9B6E00BA0FB7200854064 /* JSComment.cpp in Sources */,
@@ -17638,8 +17920,6 @@
BC60D9BF0D2A269A00B9918F /* JSEventException.cpp in Sources */,
93B70D6909EB0C7C009D8468 /* JSEventListener.cpp in Sources */,
BC6090200E91B8EC000C68B5 /* JSEventTarget.cpp in Sources */,
- BC3B7AF30E919CA900D54065 /* JSEventTargetNode.cpp in Sources */,
- BC3B7B210E91AAF400D54065 /* JSEventTargetNodeCustom.cpp in Sources */,
BC00F0140E0A189500FD04E3 /* JSFile.cpp in Sources */,
BC00F0160E0A189500FD04E3 /* JSFileList.cpp in Sources */,
FE80DA630E9C4703000D6F75 /* JSGeolocation.cpp in Sources */,
@@ -17731,6 +18011,8 @@
A7D0318E0E93540300E24ACD /* JSImageDataCustom.cpp in Sources */,
C091588A0DB4209200E55AF4 /* JSInspectedObjectWrapper.cpp in Sources */,
C091588C0DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp in Sources */,
+ 41F060CD0F5EEB2B00A07EAC /* JSInspectorController.cpp in Sources */,
+ 41F0616A0F5EFBDD00A07EAC /* JSInspectorControllerCustom.cpp in Sources */,
1C5FAED10DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp in Sources */,
1C5FAEE70DCFDA6800D58F78 /* JSJavaScriptCallFrameCustom.cpp in Sources */,
A86629D409DA2B48009633A5 /* JSKeyboardEvent.cpp in Sources */,
@@ -17948,6 +18230,8 @@
4983913F0F1E767500C23782 /* JSWebKitCSSMatrix.cpp in Sources */,
498391630F1E8EE100C23782 /* JSWebKitCSSMatrixConstructor.cpp in Sources */,
31611E5A0E1C4DE000F6A579 /* JSWebKitCSSTransformValue.cpp in Sources */,
+ 494BD79D0F55C94C00747828 /* JSWebKitPoint.cpp in Sources */,
+ 494BD7990F55C90E00747828 /* JSWebKitPointConstructor.cpp in Sources */,
31C0FF3F0E4CEFAC007D6FE5 /* JSWebKitTransitionEvent.cpp in Sources */,
65DF320509D1CC60000BE325 /* JSWheelEvent.cpp in Sources */,
E1C8BE5D0E8BD15A0064CB7D /* JSWorker.cpp in Sources */,
@@ -18008,6 +18292,7 @@
93E227E10AF589AD00D48324 /* MainResourceLoader.cpp in Sources */,
1A8F6BC50DB55CDC001DB794 /* ManifestParser.cpp in Sources */,
A8C4A80609D563270003AC8D /* MappedAttribute.cpp in Sources */,
+ 49D5DC2B0F423A73008F20FD /* Matrix3DTransformOperation.cpp in Sources */,
49E911C60EF86D47009D0CAF /* MatrixTransformOperation.cpp in Sources */,
ABFE7E120D32FAF60066F4D2 /* MediaControlElements.cpp in Sources */,
AB40484D0E083FA8007D6920 /* MediaDocument.cpp in Sources */,
@@ -18067,6 +18352,7 @@
A8FA6E5E0E4CFDED00D5CF49 /* Pattern.cpp in Sources */,
A80A38FE0E50CC8200A25EBC /* PatternCG.cpp in Sources */,
B27535810B053814002CE64F /* Pen.cpp in Sources */,
+ 49D5DC2D0F423A73008F20FD /* PerspectiveTransformOperation.cpp in Sources */,
935C477109AC4D7300A6AAB4 /* PlatformMouseEventMac.mm in Sources */,
BC94D1080C274F88006BC617 /* PlatformScreenMac.mm in Sources */,
A9C6E4EB0D745E2B006442E9 /* Plugin.cpp in Sources */,
@@ -18098,13 +18384,12 @@
BCEA4863097D93020094C9E4 /* RenderBR.cpp in Sources */,
BCEA485F097D93020094C9E4 /* RenderBlock.cpp in Sources */,
BCEA4861097D93020094C9E4 /* RenderBox.cpp in Sources */,
+ BC96DB460F3A882200573CB3 /* RenderBoxModelObject.cpp in Sources */,
BCEA4865097D93020094C9E4 /* RenderButton.cpp in Sources */,
- BCEA486B097D93020094C9E4 /* RenderContainer.cpp in Sources */,
9392F1440AD185FE00691BD4 /* RenderCounter.cpp in Sources */,
A8EA73C30A1900E300A8EF5F /* RenderFieldset.cpp in Sources */,
066C77300AB603FD00238CC4 /* RenderFileUploadControl.cpp in Sources */,
BCEA486D097D93020094C9E4 /* RenderFlexibleBox.cpp in Sources */,
- BCEA486F097D93020094C9E4 /* RenderFlow.cpp in Sources */,
853CA9EC0AEEC63C002372DC /* RenderForeignObject.cpp in Sources */,
A871DED40A1530C700B12A68 /* RenderFrame.cpp in Sources */,
A871DED20A1530C700B12A68 /* RenderFrameSet.cpp in Sources */,
@@ -18113,7 +18398,9 @@
BCB4F8930DB28E530039139B /* RenderImageGeneratedContent.cpp in Sources */,
BCEA4877097D93020094C9E4 /* RenderInline.cpp in Sources */,
BCEA4879097D93020094C9E4 /* RenderLayer.cpp in Sources */,
- A8EA73CA0A1900E300A8EF5F /* RenderLegend.cpp in Sources */,
+ 0F580D000F12DE9B0051D689 /* RenderLayerBacking.cpp in Sources */,
+ 0F580CFE0F12DE9B0051D689 /* RenderLayerCompositor.cpp in Sources */,
+ BC33FB1B0F30EE85002CDD7C /* RenderLineBoxList.cpp in Sources */,
ABB5419E0ACDDFE4002820EB /* RenderListBox.cpp in Sources */,
A8EA7A4E0A191A5200A8EF5F /* RenderListItem.cpp in Sources */,
A8EA7A510A191A5200A8EF5F /* RenderListMarker.cpp in Sources */,
@@ -18121,6 +18408,7 @@
E4C279580CF9741900E97B98 /* RenderMedia.cpp in Sources */,
ABDDFE790A5C6E7000A3E11D /* RenderMenuList.cpp in Sources */,
BCEA487F097D93020094C9E4 /* RenderObject.cpp in Sources */,
+ BC60EFB70F33A0E700812A93 /* RenderObjectChildList.cpp in Sources */,
A871DED00A1530C700B12A68 /* RenderPart.cpp in Sources */,
A871DED60A1530C700B12A68 /* RenderPartObject.cpp in Sources */,
853CA9F00AEEC657002372DC /* RenderPath.cpp in Sources */,
@@ -18329,7 +18617,6 @@
B25599980D00D8BA00BB825C /* SVGResourceFilterPlatformDataMac.mm in Sources */,
B25599B90D00D8BA00BB825C /* SVGResourceMarker.cpp in Sources */,
B25599BB0D00D8BA00BB825C /* SVGResourceMasker.cpp in Sources */,
- B25599370D00D8BA00BB825C /* SVGResourceMaskerCg.mm in Sources */,
853CA9E80AEEC608002372DC /* SVGRootInlineBox.cpp in Sources */,
E4AFD00F0DAF335500F5F55C /* SVGSMILElement.cpp in Sources */,
B2227ABA0D00BF220071B782 /* SVGSVGElement.cpp in Sources */,
@@ -18374,6 +18661,9 @@
A83E1C740E49042C00140B9C /* ScriptControllerMac.mm in Sources */,
08A484770E5272C500C3FE76 /* ScriptElement.cpp in Sources */,
E11C9DB00EB3699500E409DB /* ScriptExecutionContext.cpp in Sources */,
+ 41002CCE0F66EDEF009E660D /* ScriptFunctionCall.cpp in Sources */,
+ 41F066E50F64BCF600A07EAC /* ScriptObject.cpp in Sources */,
+ 412A68470F6B03DD000EA66E /* ScriptObjectQuarantine.cpp in Sources */,
934CC0E10ED39D6F00A658F2 /* ScriptValue.cpp in Sources */,
BC2441C40E8B65D00055320F /* ScrollView.cpp in Sources */,
9353676B09AED88B00D35CD6 /* ScrollViewMac.mm in Sources */,
@@ -18384,7 +18674,6 @@
BCD0E0FA0E972C3500265DEA /* SecurityOrigin.cpp in Sources */,
371F4FFD0D25E7F300ECE0D5 /* SegmentedFontData.cpp in Sources */,
B2C3DA2E0D006C1D00EF6F26 /* SegmentedString.cpp in Sources */,
- 93309E0B099E64920056E581 /* Selection.cpp in Sources */,
93309E0D099E64920056E581 /* SelectionController.cpp in Sources */,
4A8C96EB0BE69032004EEFF0 /* SelectionControllerMac.mm in Sources */,
BC7FA6820D1F167900DB22A9 /* SelectorNodeList.cpp in Sources */,
@@ -18455,9 +18744,9 @@
B2C3DA410D006C1D00EF6F26 /* TextCodecUTF16.cpp in Sources */,
B2C3DA3F0D006C1D00EF6F26 /* TextCodecUserDefined.cpp in Sources */,
AB014DE30E689A4300E10445 /* TextControlInnerElements.cpp in Sources */,
- B2C3DA430D006C1D00EF6F26 /* TextDecoder.cpp in Sources */,
1A6938010A11100A00C127FE /* TextDocument.cpp in Sources */,
B2C3DA460D006C1D00EF6F26 /* TextEncoding.cpp in Sources */,
+ C105DA620F3AA68F001DD44F /* TextEncodingDetectorICU.cpp in Sources */,
B2C3DA480D006C1D00EF6F26 /* TextEncodingRegistry.cpp in Sources */,
933A142E0B7D188600A53FFD /* TextEvent.cpp in Sources */,
93309E1B099E64920056E581 /* TextIterator.cpp in Sources */,
@@ -18467,10 +18756,12 @@
BCE659E90EA92FFA007E4533 /* ThemeMac.mm in Sources */,
51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */,
E1FF57A60F01256B00891EBB /* ThreadGlobalData.cpp in Sources */,
+ 185BCF280F3279CE000EA262 /* ThreadTimers.cpp in Sources */,
0B90561E0F257E930095FF6A /* ThreadableLoader.cpp in Sources */,
E44613AF0CD6331000FADA75 /* TimeRanges.cpp in Sources */,
93309EA4099EB78C0056E581 /* Timer.cpp in Sources */,
49E911CF0EF86D47009D0CAF /* TransformOperations.cpp in Sources */,
+ 0F500AB10F54DB3100EEF928 /* TransformState.cpp in Sources */,
49E911C30EF86D47009D0CAF /* TransformationMatrix.cpp in Sources */,
B27535580B053814002CE64F /* TransformationMatrixCG.cpp in Sources */,
49E911D10EF86D47009D0CAF /* TranslateTransformOperation.cpp in Sources */,
@@ -18484,6 +18775,7 @@
65DF326109D1E199000BE325 /* UserAgentStyleSheetsData.cpp in Sources */,
7284ADDD0E6FEB31002EEFBD /* UserStyleSheetLoader.cpp in Sources */,
93309E1F099E64920056E581 /* VisiblePosition.cpp in Sources */,
+ A883DF270F3D045D00F19BF6 /* VisibleSelection.cpp in Sources */,
B255994A0D00D8BA00BB825C /* WKArithmeticFilter.m in Sources */,
B255994D0D00D8BA00BB825C /* WKComponentMergeFilter.m in Sources */,
B25599500D00D8BA00BB825C /* WKDiffuseLightingFilter.m in Sources */,
@@ -18551,22 +18843,24 @@
498391580F1E776900C23782 /* WebKitCSSMatrix.cpp in Sources */,
BC9ADD800CC4092200098C4C /* WebKitCSSTransformValue.cpp in Sources */,
31C0FF240E4CEB6E007D6FE5 /* WebKitTransitionEvent.cpp in Sources */,
+ 0FCF332E0F2B9A25004B6795 /* WebLayer.mm in Sources */,
1CAF34820A6C405200ABE06E /* WebScriptObject.mm in Sources */,
+ 0FCF332C0F2B9A25004B6795 /* WebTiledLayer.mm in Sources */,
85031B500A44EFC700F992E0 /* WheelEvent.cpp in Sources */,
935C477309AC4D7700A6AAB4 /* WheelEventMac.mm in Sources */,
9380F47309A11AB4001FDB34 /* Widget.cpp in Sources */,
9380F47809A11ACC001FDB34 /* WidgetMac.mm in Sources */,
939B02EE0EA2DBC400C54570 /* WidthIterator.cpp in Sources */,
BC8243E80D0CFD7500460C8F /* WindowFeatures.cpp in Sources */,
- E1CA5CA50E8CD78500E8EF90 /* Worker.cpp in Sources */,
- E1C2C4420EAD017B007E61FB /* WorkerContext.cpp in Sources */,
- E1C363060EAF2D07007410BC /* WorkerLocation.cpp in Sources */,
- E14799B40ECDE9D800292BF3 /* WorkerMessagingProxy.cpp in Sources */,
+ 2E4346450F546A8200B0F1BA /* Worker.cpp in Sources */,
+ 2E4346480F546A8200B0F1BA /* WorkerContext.cpp in Sources */,
+ 2E43464C0F546A8200B0F1BA /* WorkerLocation.cpp in Sources */,
+ 2E43464F0F546A8200B0F1BA /* WorkerMessagingProxy.cpp in Sources */,
E1271A140EEEC80400F61213 /* WorkerNavigator.cpp in Sources */,
- 18A0537C0F26859C00A51705 /* WorkerRunLoop.cpp in Sources */,
+ 2E4346520F546A8200B0F1BA /* WorkerRunLoop.cpp in Sources */,
E1A643FD0EC097A000779668 /* WorkerScriptController.cpp in Sources */,
- E108224F0EC3156700E93953 /* WorkerTask.cpp in Sources */,
- E1C2C4290EACE0E0007E61FB /* WorkerThread.cpp in Sources */,
+ 2E4346540F546A8200B0F1BA /* WorkerThread.cpp in Sources */,
+ 0B9056F80F2685F30095FF6A /* WorkerThreadableLoader.cpp in Sources */,
93309E23099E64920056E581 /* WrapContentsInDummySpanCommand.cpp in Sources */,
A833C7CC0A2CF07400D57664 /* XLinkNames.cpp in Sources */,
BC772C460C4EB2C60083285F /* XMLHttpRequest.cpp in Sources */,
@@ -18622,9 +18916,19 @@
1A569D220D7E2B82007C3983 /* runtime_object.cpp in Sources */,
1A569D240D7E2B82007C3983 /* runtime_root.cpp in Sources */,
93309E1D099E64920056E581 /* visible_units.cpp in Sources */,
- 51C0AA410F2AA15E001648C2 /* CachedFrame.cpp in Sources */,
- 93BA59B20F2AA5FE008E8E99 /* JSCDATASectionCustom.cpp in Sources */,
- 188604B30F2E654A000B6443 /* DOMTimer.cpp in Sources */,
+ BCE494AC0F4F5E9E0084E319 /* GeolocationServiceMac.mm in Sources */,
+ 41F061750F5F00AC00A07EAC /* InspectorDOMStorageResource.cpp in Sources */,
+ 41F0618F0F5F069800A07EAC /* ConsoleMessage.cpp in Sources */,
+ 41F062020F5F0B6600A07EAC /* InspectorResource.cpp in Sources */,
+ 41F062150F5F192600A07EAC /* InspectorDatabaseResource.cpp in Sources */,
+ 5D925B670F64D4DD00B847F0 /* ScrollBehavior.cpp in Sources */,
+ E1C415DE0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp in Sources */,
+ E1C416170F6563180092D2FB /* CrossOriginAccessControl.cpp in Sources */,
+ A7D6B34A0F61104500B79FD1 /* WorkerImportScriptsClient.cpp in Sources */,
+ FE6FD4870F676E5700092873 /* Coordinates.cpp in Sources */,
+ FE6FD48D0F676E9300092873 /* JSCoordinates.cpp in Sources */,
+ 1C63A2490F71646600C09D5A /* RunLoopTimerCF.cpp in Sources */,
+ 935F45420F7C3B5F00D7C1FB /* JSLazyEventListener.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebCore/WebCorePrefix.h b/WebCore/WebCorePrefix.h
index aaa6a0f..e857ecc 100644
--- a/WebCore/WebCorePrefix.h
+++ b/WebCore/WebCorePrefix.h
@@ -100,16 +100,6 @@
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
-#include <AvailabilityMacros.h>
-
-#if defined(__APPLE__)
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
-#define BUILDING_ON_TIGER 1
-#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-#define BUILDING_ON_LEOPARD 1
-#endif
-#endif
-
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
diff --git a/WebCore/WebCoreSources.bkl b/WebCore/WebCoreSources.bkl
index 6c53e84..dfc3094 100644
--- a/WebCore/WebCoreSources.bkl
+++ b/WebCore/WebCoreSources.bkl
@@ -63,7 +63,6 @@ This file contains the list of files needed to build WebCore.
bindings/js/JSElementCustom.cpp
bindings/js/JSEventCustom.cpp
bindings/js/JSEventTarget.cpp
- bindings/js/JSEventTargetNodeCustom.cpp
bindings/js/JSGeolocationCustom.cpp
bindings/js/JSHTMLAllCollection.cpp
bindings/js/JSHistoryCustom.cpp
@@ -84,6 +83,7 @@ This file contains the list of files needed to build WebCore.
bindings/js/JSImageDataCustom.cpp
bindings/js/JSInspectedObjectWrapper.cpp
bindings/js/JSInspectorCallbackWrapper.cpp
+ bindings/js/JSInspectorControllerCustom.cpp
bindings/js/JSJavaScriptCallFrameCustom.cpp
bindings/js/JSLocationCustom.cpp
bindings/js/JSMessageChannelConstructor.cpp
@@ -117,22 +117,28 @@ This file contains the list of files needed to build WebCore.
bindings/js/JSXSLTProcessorCustom.cpp
bindings/js/JSDOMBinding.cpp
bindings/js/JSEventListener.cpp
+ bindings/js/JSLazyEventListener.cpp
bindings/js/JSPluginElementFunctions.cpp
bindings/js/ScriptCachedFrameData.cpp
bindings/js/ScriptCallFrame.cpp
bindings/js/ScriptCallStack.cpp
bindings/js/ScriptController.cpp
+ bindings/js/ScriptFunctionCall.cpp
+ bindings/js/ScriptObject.cpp
+ bindings/js/ScriptObjectQuarantine.cpp
bindings/js/ScriptValue.cpp
bindings/js/ScheduledAction.cpp
bindings/js/JSWebKitCSSMatrixConstructor.cpp
+ bindings/js/JSWebKitPointConstructor.cpp
</set>
<set append="1" var="WEBCORE_SOURCES_BRIDGE">
+ bridge/IdentifierRep.cpp
+ bridge/NP_jsobject.cpp
bridge/c/c_class.cpp
bridge/c/c_instance.cpp
bridge/c/c_runtime.cpp
bridge/c/c_utility.cpp
- bridge/NP_jsobject.cpp
bridge/npruntime.cpp
bridge/runtime.cpp
bridge/runtime_array.cpp
@@ -205,6 +211,7 @@ This file contains the list of files needed to build WebCore.
<set append="1" var="WEBCORE_SOURCES_DERIVEDSOURCES">
DerivedSources/WebCore/CSSGrammar.cpp
DerivedSources/WebCore/ColorData.c
+ DerivedSources/WebCore/HTMLElementFactory.cpp
DerivedSources/WebCore/HTMLEntityNames.c
DerivedSources/WebCore/HTMLNames.cpp
DerivedSources/WebCore/JSAttr.cpp
@@ -229,9 +236,12 @@ This file contains the list of files needed to build WebCore.
DerivedSources/WebCore/JSCanvasPattern.cpp
DerivedSources/WebCore/JSCanvasRenderingContext2D.cpp
DerivedSources/WebCore/JSCharacterData.cpp
+ DerivedSources/WebCore/JSClientRect.cpp
+ DerivedSources/WebCore/JSClientRectList.cpp
DerivedSources/WebCore/JSClipboard.cpp
DerivedSources/WebCore/JSComment.cpp
DerivedSources/WebCore/JSConsole.cpp
+ DerivedSources/WebCore/JSCoordinates.cpp
DerivedSources/WebCore/JSCounter.cpp
DerivedSources/WebCore/JSDatabase.cpp
DerivedSources/WebCore/JSDocument.cpp
@@ -248,7 +258,6 @@ This file contains the list of files needed to build WebCore.
DerivedSources/WebCore/JSEntityReference.cpp
DerivedSources/WebCore/JSEvent.cpp
DerivedSources/WebCore/JSEventException.cpp
- DerivedSources/WebCore/JSEventTargetNode.cpp
DerivedSources/WebCore/JSFile.cpp
DerivedSources/WebCore/JSFileList.cpp
DerivedSources/WebCore/JSGeolocation.cpp
@@ -316,6 +325,7 @@ This file contains the list of files needed to build WebCore.
DerivedSources/WebCore/JSHTMLUListElement.cpp
DerivedSources/WebCore/JSHistory.cpp
DerivedSources/WebCore/JSImageData.cpp
+ DerivedSources/WebCore/JSInspectorController.cpp
DerivedSources/WebCore/JSJavaScriptCallFrame.cpp
DerivedSources/WebCore/JSKeyboardEvent.cpp
DerivedSources/WebCore/JSLocation.cpp
@@ -362,6 +372,7 @@ This file contains the list of files needed to build WebCore.
DerivedSources/WebCore/JSWebKitCSSKeyframesRule.cpp
DerivedSources/WebCore/JSWebKitCSSMatrix.cpp
DerivedSources/WebCore/JSWebKitCSSTransformValue.cpp
+ DerivedSources/WebCore/JSWebKitPoint.cpp
DerivedSources/WebCore/JSWebKitTransitionEvent.cpp
DerivedSources/WebCore/JSWheelEvent.cpp
DerivedSources/WebCore/JSXMLHttpRequest.cpp
@@ -393,6 +404,8 @@ This file contains the list of files needed to build WebCore.
dom/ChildNodeList.cpp
dom/ClassNames.cpp
dom/ClassNodeList.cpp
+ dom/ClientRect.cpp
+ dom/ClientRectList.cpp
dom/Clipboard.cpp
dom/ClipboardEvent.cpp
dom/Comment.cpp
@@ -410,7 +423,6 @@ This file contains the list of files needed to build WebCore.
dom/Event.cpp
dom/EventNames.cpp
dom/EventTarget.cpp
- dom/EventTargetNode.cpp
dom/ExceptionBase.cpp
dom/ExceptionCode.cpp
dom/FormControlElementWithState.cpp
@@ -494,7 +506,6 @@ This file contains the list of files needed to build WebCore.
editing/RemoveNodeCommand.cpp
editing/RemoveNodePreservingChildrenCommand.cpp
editing/ReplaceSelectionCommand.cpp
- editing/Selection.cpp
editing/SelectionController.cpp
editing/SmartReplace.cpp
editing/SmartReplaceICU.cpp
@@ -506,6 +517,7 @@ This file contains the list of files needed to build WebCore.
editing/TypingCommand.cpp
editing/UnlinkCommand.cpp
editing/VisiblePosition.cpp
+ editing/VisibleSelection.cpp
editing/WrapContentsInDummySpanCommand.cpp
editing/htmlediting.cpp
editing/markup.cpp
@@ -545,7 +557,6 @@ This file contains the list of files needed to build WebCore.
html/HTMLDivElement.cpp
html/HTMLDocument.cpp
html/HTMLElement.cpp
- html/HTMLElementFactory.cpp
html/HTMLEmbedElement.cpp
html/HTMLFieldSetElement.cpp
html/HTMLFontElement.cpp
@@ -610,7 +621,11 @@ This file contains the list of files needed to build WebCore.
</set>
<set append="1" var="WEBCORE_SOURCES_INSPECTOR">
+ inspector/ConsoleMessage.cpp
+ inspector/InspectorDatabaseResource.cpp
+ inspector/InspectorDOMStorageResource.cpp
inspector/InspectorController.cpp
+ inspector/InspectorResource.cpp
inspector/JavaScriptCallFrame.cpp
inspector/JavaScriptDebugServer.cpp
inspector/JavaScriptProfile.cpp
@@ -635,12 +650,13 @@ This file contains the list of files needed to build WebCore.
loader/CachedResourceClientWalker.cpp
loader/CachedScript.cpp
loader/CachedXSLStyleSheet.cpp
+ loader/CrossOriginAccessControl.cpp
+ loader/CrossOriginPreflightResultCache.cpp
loader/DocLoader.cpp
loader/DocumentLoader.cpp
loader/DocumentThreadableLoader.cpp
loader/FormState.cpp
loader/FrameLoader.cpp
- loader/FrameLoaderClient.cpp
loader/FTPDirectoryDocument.cpp
loader/FTPDirectoryParser.cpp
loader/ImageDocument.cpp
@@ -657,6 +673,7 @@ This file contains the list of files needed to build WebCore.
loader/TextDocument.cpp
loader/TextResourceDecoder.cpp
loader/ThreadableLoader.cpp
+ loader/WorkerThreadableLoader.cpp
loader/loader.cpp
</set>
@@ -689,6 +706,7 @@ This file contains the list of files needed to build WebCore.
page/Chrome.cpp
page/Console.cpp
page/ContextMenuController.cpp
+ page/Coordinates.cpp
page/DOMSelection.cpp
page/DOMTimer.cpp
page/DOMWindow.cpp
@@ -721,11 +739,14 @@ This file contains the list of files needed to build WebCore.
platform/text/Base64.cpp
platform/text/BidiContext.cpp
platform/text/CString.cpp
+ platform/ContentType.cpp
platform/ContextMenu.cpp
+ platform/CrossThreadCopier.cpp
platform/DeprecatedPtrListImpl.cpp
platform/DragImage.cpp
platform/FileChooser.cpp
platform/GeolocationService.cpp
+ platform/graphics/FloatPoint3D.cpp
platform/graphics/Font.cpp
platform/graphics/FontCache.cpp
platform/graphics/FontData.cpp
@@ -758,11 +779,12 @@ This file contains the list of files needed to build WebCore.
platform/text/TextCodecLatin1.cpp
platform/text/TextCodecUTF16.cpp
platform/text/TextCodecUserDefined.cpp
- platform/text/TextDecoder.cpp
platform/text/TextEncoding.cpp
+ platform/text/TextEncodingDetectorICU.cpp
platform/text/TextEncodingRegistry.cpp
platform/text/TextStream.cpp
platform/ThreadGlobalData.cpp
+ platform/ThreadTimers.cpp
platform/Timer.cpp
platform/Widget.cpp
platform/graphics/BitmapImage.cpp
@@ -783,6 +805,8 @@ This file contains the list of files needed to build WebCore.
platform/graphics/Pen.cpp
platform/graphics/transforms/TransformationMatrix.cpp
platform/graphics/transforms/MatrixTransformOperation.cpp
+ platform/graphics/transforms/Matrix3DTransformOperation.cpp
+ platform/graphics/transforms/PerspectiveTransformOperation.cpp
platform/graphics/transforms/RotateTransformOperation.cpp
platform/graphics/transforms/ScaleTransformOperation.cpp
platform/graphics/transforms/SkewTransformOperation.cpp
@@ -881,13 +905,12 @@ This file contains the list of files needed to build WebCore.
rendering/RenderBR.cpp
rendering/RenderBlock.cpp
rendering/RenderBox.cpp
+ rendering/RenderBoxModelObject.cpp
rendering/RenderButton.cpp
- rendering/RenderContainer.cpp
rendering/RenderCounter.cpp
rendering/RenderFieldset.cpp
rendering/RenderFileUploadControl.cpp
rendering/RenderFlexibleBox.cpp
- rendering/RenderFlow.cpp
rendering/RenderFrame.cpp
rendering/RenderFrameSet.cpp
rendering/RenderHTMLCanvas.cpp
@@ -895,13 +918,14 @@ This file contains the list of files needed to build WebCore.
rendering/RenderImageGeneratedContent.cpp
rendering/RenderInline.cpp
rendering/RenderLayer.cpp
- rendering/RenderLegend.cpp
+ rendering/RenderLineBoxList.cpp
rendering/RenderListBox.cpp
rendering/RenderListItem.cpp
rendering/RenderListMarker.cpp
rendering/RenderMarquee.cpp
rendering/RenderMenuList.cpp
rendering/RenderObject.cpp
+ rendering/RenderObjectChildList.cpp
rendering/RenderPart.cpp
rendering/RenderPartObject.cpp
rendering/RenderReplaced.cpp
@@ -926,7 +950,9 @@ This file contains the list of files needed to build WebCore.
rendering/RenderWidget.cpp
rendering/RenderWordBreak.cpp
rendering/RootInlineBox.cpp
+ rendering/ScrollBehavior.cpp
rendering/TextControlInnerElements.cpp
+ rendering/TransformState.cpp
rendering/style/BindingURI.cpp
rendering/style/ContentData.cpp
rendering/style/CounterDirectives.cpp
diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp
index f0bdbe8..3fd53fe 100644
--- a/WebCore/bindings/js/JSAudioConstructor.cpp
+++ b/WebCore/bindings/js/JSAudioConstructor.cpp
@@ -43,13 +43,19 @@ const ClassInfo JSAudioConstructor::s_info = { "AudioConstructor", 0, 0, 0 };
JSAudioConstructor::JSAudioConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSAudioConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+ , m_globalObject(toJSDOMGlobalObject(context))
{
ASSERT(context->isDocument());
- m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
+ putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
+Document* JSAudioConstructor::document() const
+{
+ return static_cast<Document*>(m_globalObject->scriptExecutionContext());
+}
+
static JSObject* constructAudio(ExecState* exec, JSObject* constructor, const ArgList& args)
{
// FIXME: Why doesn't this need the call toJS on the document like JSImageConstructor?
@@ -71,8 +77,8 @@ ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData)
void JSAudioConstructor::mark()
{
DOMObject::mark();
- if (!m_document->marked())
- m_document->mark();
+ if (!m_globalObject->marked())
+ m_globalObject->mark();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSAudioConstructor.h b/WebCore/bindings/js/JSAudioConstructor.h
index cdff10f..1078b0f 100644
--- a/WebCore/bindings/js/JSAudioConstructor.h
+++ b/WebCore/bindings/js/JSAudioConstructor.h
@@ -38,7 +38,7 @@ namespace WebCore {
public:
JSAudioConstructor(JSC::ExecState*, ScriptExecutionContext*);
- Document* document() const { return m_document->impl(); }
+ Document* document() const;
static const JSC::ClassInfo s_info;
@@ -48,7 +48,7 @@ namespace WebCore {
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
- JSDocument* m_document;
+ JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
index 6c46ae4..22154ce 100644
--- a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
+++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
@@ -77,7 +77,7 @@ static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPo
return String();
Vector<UChar> name;
- name.reserveCapacity(length);
+ name.reserveInitialCapacity(length);
unsigned i = 0;
diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp
index cae1e1e..6b0bb43 100644
--- a/WebCore/bindings/js/JSCustomPositionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp
@@ -26,10 +26,8 @@
#include "config.h"
#include "JSCustomPositionCallback.h"
-#include "CString.h"
#include "Frame.h"
#include "JSGeoposition.h"
-#include "Page.h"
#include "ScriptController.h"
#include <runtime/JSLock.h>
@@ -73,14 +71,16 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition, bool& raise
ArgList args;
args.append(toJS(exec, geoposition));
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException()) {
reportCurrentException(exec);
raisedException = true;
}
+
+ Document::updateDocumentsRendering();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
index 766f698..ecc67dd 100644
--- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
@@ -26,10 +26,8 @@
#include "config.h"
#include "JSCustomPositionErrorCallback.h"
-#include "CString.h"
#include "Frame.h"
#include "JSPositionError.h"
-#include "Page.h"
#include "ScriptController.h"
#include <runtime/JSLock.h>
@@ -73,12 +71,14 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError)
ArgList args;
args.append(toJS(exec, positionError));
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException())
reportCurrentException(exec);
+
+ Document::updateDocumentsRendering();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
index f61306c..8733696 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
@@ -29,8 +29,6 @@
#include "config.h"
#include "JSCustomSQLStatementCallback.h"
-#include "CString.h"
-#include "DOMWindow.h"
#include "Frame.h"
#include "ScriptController.h"
#include "JSSQLResultSet.h"
@@ -78,9 +76,9 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
args.append(toJS(exec, transaction));
args.append(toJS(exec, resultSet));
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException()) {
reportCurrentException(exec);
diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
index 0d27de7..dd23889 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
@@ -29,8 +29,6 @@
#include "config.h"
#include "JSCustomSQLStatementErrorCallback.h"
-#include "CString.h"
-#include "DOMWindow.h"
#include "Frame.h"
#include "ScriptController.h"
#include "JSSQLError.h"
@@ -81,12 +79,12 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
args.append(toJS(exec, error));
JSValuePtr result;
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
if (handleEventCallType != CallTypeNone)
result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args);
else
result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException()) {
reportCurrentException(exec);
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
index d6187bc..9960a0e 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
@@ -29,10 +29,7 @@
#include "config.h"
#include "JSCustomSQLTransactionCallback.h"
-#include "CString.h"
-#include "DOMWindow.h"
#include "Frame.h"
-#include "Logging.h"
#include "ScriptController.h"
#include "JSSQLTransaction.h"
#include "Page.h"
@@ -120,12 +117,12 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
ArgList args;
args.append(toJS(exec, transaction));
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
if (handleEventCallType != CallTypeNone)
call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_data->callback(), args);
else
call(exec, m_data->callback(), callbackCallType, callbackCallData, m_data->callback(), args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException()) {
reportCurrentException(exec);
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
index 5c8b8d4..2324d04 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
@@ -29,8 +29,6 @@
#include "config.h"
#include "JSCustomSQLTransactionErrorCallback.h"
-#include "CString.h"
-#include "DOMWindow.h"
#include "Frame.h"
#include "ScriptController.h"
#include "JSSQLError.h"
@@ -77,9 +75,9 @@ bool JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
args.append(toJS(exec, error));
JSValuePtr result;
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
result = call(exec, function, callType, callData, m_callback, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException())
reportCurrentException(exec);
diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp
index 60b3777..23e9fa6 100644
--- a/WebCore/bindings/js/JSCustomVoidCallback.cpp
+++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp
@@ -29,11 +29,8 @@
#include "config.h"
#include "JSCustomVoidCallback.h"
-#include "CString.h"
-#include "DOMWindow.h"
#include "Frame.h"
#include "JSDOMWindowCustom.h"
-#include "JSDOMBinding.h"
#include "ScriptController.h"
#include <runtime/JSLock.h>
@@ -76,9 +73,9 @@ void JSCustomVoidCallback::handleEvent()
ArgList args;
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException())
reportCurrentException(exec);
diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
index 6796af6..5187411 100644
--- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
+++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
@@ -28,14 +28,10 @@
#if ENABLE(XPATH)
-#include "CString.h"
-#include "Console.h"
-#include "DOMWindow.h"
#include "Document.h"
#include "ExceptionCode.h"
#include "Frame.h"
#include "JSDOMWindowCustom.h"
-#include "JSDOMBinding.h"
#include "ScriptController.h"
#include <runtime/JSLock.h>
@@ -99,9 +95,9 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
ArgList args;
args.append(jsString(exec, prefix));
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr retval = call(exec, function, callType, callData, m_customResolver, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
String result;
if (exec->hadException())
diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
index 980d795..20d09dd 100644
--- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,38 +46,21 @@ void JSDOMApplicationCache::mark()
{
DOMObject::mark();
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onchecking()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onnoupdate()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->ondownloading()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onprogress()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onupdateready()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->oncached()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onobsolete()))
- listener->mark();
+ markIfNotNull(m_impl->onchecking());
+ markIfNotNull(m_impl->onerror());
+ markIfNotNull(m_impl->onnoupdate());
+ markIfNotNull(m_impl->ondownloading());
+ markIfNotNull(m_impl->onprogress());
+ markIfNotNull(m_impl->onupdateready());
+ markIfNotNull(m_impl->oncached());
+ markIfNotNull(m_impl->onobsolete());
typedef DOMApplicationCache::EventListenersMap EventListenersMap;
typedef DOMApplicationCache::ListenerVector ListenerVector;
EventListenersMap& eventListeners = m_impl->eventListeners();
for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
- for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
- JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
- listener->mark();
- }
+ for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+ (*vecIter)->mark();
}
}
@@ -129,7 +112,7 @@ JSValuePtr JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgLis
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- RefPtr<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1));
+ RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
@@ -141,7 +124,7 @@ JSValuePtr JSDOMApplicationCache::removeEventListener(ExecState* exec, const Arg
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1));
+ JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
diff --git a/WebCore/bindings/js/JSDOMGlobalObject.cpp b/WebCore/bindings/js/JSDOMGlobalObject.cpp
index 27dbf84..849c470 100644
--- a/WebCore/bindings/js/JSDOMGlobalObject.cpp
+++ b/WebCore/bindings/js/JSDOMGlobalObject.cpp
@@ -54,23 +54,23 @@ JSDOMGlobalObject::JSDOMGlobalObject(PassRefPtr<Structure> structure, JSDOMGloba
JSDOMGlobalObject::~JSDOMGlobalObject()
{
// Clear any backpointers to the window
- ListenersMap::iterator i1 = d()->jsEventListeners.begin();
- ListenersMap::iterator e1 = d()->jsEventListeners.end();
+ ProtectedListenersMap::iterator i1 = d()->jsProtectedEventListeners.begin();
+ ProtectedListenersMap::iterator e1 = d()->jsProtectedEventListeners.end();
for (; i1 != e1; ++i1)
i1->second->clearGlobalObject();
- i1 = d()->jsInlineEventListeners.begin();
- e1 = d()->jsInlineEventListeners.end();
+ i1 = d()->jsProtectedInlineEventListeners.begin();
+ e1 = d()->jsProtectedInlineEventListeners.end();
for (; i1 != e1; ++i1)
i1->second->clearGlobalObject();
- UnprotectedListenersMap::iterator i2 = d()->jsUnprotectedEventListeners.begin();
- UnprotectedListenersMap::iterator e2 = d()->jsUnprotectedEventListeners.end();
+ JSListenersMap::iterator i2 = d()->jsEventListeners.begin();
+ JSListenersMap::iterator e2 = d()->jsEventListeners.end();
for (; i2 != e2; ++i2)
i2->second->clearGlobalObject();
- i2 = d()->jsUnprotectedInlineEventListeners.begin();
- e2 = d()->jsUnprotectedInlineEventListeners.end();
+ i2 = d()->jsInlineEventListeners.begin();
+ e2 = d()->jsInlineEventListeners.end();
for (; i2 != e2; ++i2)
i2->second->clearGlobalObject();
}
@@ -90,66 +90,66 @@ void JSDOMGlobalObject::mark()
}
}
-JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValuePtr val, bool isInline)
+JSProtectedEventListener* JSDOMGlobalObject::findJSProtectedEventListener(JSValuePtr val, bool isInline)
{
if (!val.isObject())
return 0;
JSObject* object = asObject(val);
- ListenersMap& listeners = isInline ? d()->jsInlineEventListeners : d()->jsEventListeners;
+ ProtectedListenersMap& listeners = isInline ? d()->jsProtectedInlineEventListeners : d()->jsProtectedEventListeners;
return listeners.get(object);
}
-PassRefPtr<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(ExecState*, JSValuePtr val, bool isInline)
+PassRefPtr<JSProtectedEventListener> JSDOMGlobalObject::findOrCreateJSProtectedEventListener(ExecState*, JSValuePtr val, bool isInline)
{
- if (JSEventListener* listener = findJSEventListener(val, isInline))
+ if (JSProtectedEventListener* listener = findJSProtectedEventListener(val, isInline))
return listener;
if (!val.isObject())
return 0;
- // The JSEventListener constructor adds it to our jsEventListeners map.
- return JSEventListener::create(asObject(val), this, isInline).get();
+ // The JSProtectedEventListener constructor adds it to our jsProtectedEventListeners map.
+ return JSProtectedEventListener::create(asObject(val), this, isInline).get();
}
-JSUnprotectedEventListener* JSDOMGlobalObject::findJSUnprotectedEventListener(ExecState*, JSValuePtr val, bool isInline)
+JSEventListener* JSDOMGlobalObject::findJSEventListener(ExecState*, JSValuePtr val, bool isInline)
{
if (!val.isObject())
return 0;
- UnprotectedListenersMap& listeners = isInline ? d()->jsUnprotectedInlineEventListeners : d()->jsUnprotectedEventListeners;
+ JSListenersMap& listeners = isInline ? d()->jsInlineEventListeners : d()->jsEventListeners;
return listeners.get(asObject(val));
}
-PassRefPtr<JSUnprotectedEventListener> JSDOMGlobalObject::findOrCreateJSUnprotectedEventListener(ExecState* exec, JSValuePtr val, bool isInline)
+PassRefPtr<JSEventListener> JSDOMGlobalObject::findOrCreateJSEventListener(ExecState* exec, JSValuePtr val, bool isInline)
{
- if (JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(exec, val, isInline))
+ if (JSEventListener* listener = findJSEventListener(exec, val, isInline))
return listener;
if (!val.isObject())
return 0;
- // The JSUnprotectedEventListener constructor adds it to our jsUnprotectedEventListeners map.
- return JSUnprotectedEventListener::create(asObject(val), this, isInline).get();
+ // The JSEventListener constructor adds it to our jsEventListeners map.
+ return JSEventListener::create(asObject(val), this, isInline).get();
}
-JSDOMGlobalObject::ListenersMap& JSDOMGlobalObject::jsEventListeners()
+JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedEventListeners()
{
- return d()->jsEventListeners;
+ return d()->jsProtectedEventListeners;
}
-JSDOMGlobalObject::ListenersMap& JSDOMGlobalObject::jsInlineEventListeners()
+JSDOMGlobalObject::ProtectedListenersMap& JSDOMGlobalObject::jsProtectedInlineEventListeners()
{
- return d()->jsInlineEventListeners;
+ return d()->jsProtectedInlineEventListeners;
}
-JSDOMGlobalObject::UnprotectedListenersMap& JSDOMGlobalObject::jsUnprotectedEventListeners()
+JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsEventListeners()
{
- return d()->jsUnprotectedEventListeners;
+ return d()->jsEventListeners;
}
-JSDOMGlobalObject::UnprotectedListenersMap& JSDOMGlobalObject::jsUnprotectedInlineEventListeners()
+JSDOMGlobalObject::JSListenersMap& JSDOMGlobalObject::jsInlineEventListeners()
{
- return d()->jsUnprotectedInlineEventListeners;
+ return d()->jsInlineEventListeners;
}
void JSDOMGlobalObject::setCurrentEvent(Event* evt)
diff --git a/WebCore/bindings/js/JSDOMGlobalObject.h b/WebCore/bindings/js/JSDOMGlobalObject.h
index fbb3eb9..6ca3797 100644
--- a/WebCore/bindings/js/JSDOMGlobalObject.h
+++ b/WebCore/bindings/js/JSDOMGlobalObject.h
@@ -32,8 +32,8 @@
namespace WebCore {
class Event;
+ class JSProtectedEventListener;
class JSEventListener;
- class JSUnprotectedEventListener;
class ScriptExecutionContext;
typedef HashMap<const JSC::ClassInfo*, RefPtr<JSC::Structure> > JSDOMStructureMap;
@@ -54,24 +54,24 @@ namespace WebCore {
virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
// Finds a wrapper of a JS EventListener, returns 0 if no existing one.
- JSEventListener* findJSEventListener(JSC::JSValuePtr, bool isInline = false);
+ JSProtectedEventListener* findJSProtectedEventListener(JSC::JSValuePtr, bool isInline = false);
// Finds or creates a wrapper of a JS EventListener. JS EventListener object is GC-protected.
- PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false);
+ PassRefPtr<JSProtectedEventListener> findOrCreateJSProtectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false);
// Finds a wrapper of a GC-unprotected JS EventListener, returns 0 if no existing one.
- JSUnprotectedEventListener* findJSUnprotectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false);
+ JSEventListener* findJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false);
// Finds or creates a wrapper of a JS EventListener. JS EventListener object is *NOT* GC-protected.
- PassRefPtr<JSUnprotectedEventListener> findOrCreateJSUnprotectedEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false);
+ PassRefPtr<JSEventListener> findOrCreateJSEventListener(JSC::ExecState*, JSC::JSValuePtr, bool isInline = false);
- typedef HashMap<JSC::JSObject*, JSEventListener*> ListenersMap;
- typedef HashMap<JSC::JSObject*, JSUnprotectedEventListener*> UnprotectedListenersMap;
+ typedef HashMap<JSC::JSObject*, JSProtectedEventListener*> ProtectedListenersMap;
+ typedef HashMap<JSC::JSObject*, JSEventListener*> JSListenersMap;
- ListenersMap& jsEventListeners();
- ListenersMap& jsInlineEventListeners();
- UnprotectedListenersMap& jsUnprotectedEventListeners();
- UnprotectedListenersMap& jsUnprotectedInlineEventListeners();
+ ProtectedListenersMap& jsProtectedEventListeners();
+ ProtectedListenersMap& jsProtectedInlineEventListeners();
+ JSListenersMap& jsEventListeners();
+ JSListenersMap& jsInlineEventListeners();
void setCurrentEvent(Event*);
Event* currentEvent();
@@ -85,10 +85,10 @@ namespace WebCore {
JSDOMStructureMap structures;
JSDOMConstructorMap constructors;
- JSDOMGlobalObject::ListenersMap jsEventListeners;
- JSDOMGlobalObject::ListenersMap jsInlineEventListeners;
- JSDOMGlobalObject::UnprotectedListenersMap jsUnprotectedEventListeners;
- JSDOMGlobalObject::UnprotectedListenersMap jsUnprotectedInlineEventListeners;
+ JSDOMGlobalObject::ProtectedListenersMap jsProtectedEventListeners;
+ JSDOMGlobalObject::ProtectedListenersMap jsProtectedInlineEventListeners;
+ JSDOMGlobalObject::JSListenersMap jsEventListeners;
+ JSDOMGlobalObject::JSListenersMap jsInlineEventListeners;
Event* evt;
};
diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp
index 83bc202..5e5ac2f 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.cpp
+++ b/WebCore/bindings/js/JSDOMWindowBase.cpp
@@ -28,26 +28,21 @@
#include "DOMTimer.h"
#include "DOMWindow.h"
#include "Element.h"
-#include "EventListener.h"
-#include "ExceptionCode.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameLoadRequest.h"
-#include "FrameLoader.h"
-#include "FrameTree.h"
-#include "GCController.h"
#include "HTMLDocument.h"
#include "InspectorController.h"
#include "JSAudioConstructor.h"
#include "JSDOMWindowCustom.h"
#include "JSEvent.h"
-#include "JSEventListener.h"
#include "JSHTMLCollection.h"
#include "JSImageConstructor.h"
#include "JSMessageChannelConstructor.h"
#include "JSNode.h"
#include "JSWebKitCSSMatrixConstructor.h"
#include "JSOptionConstructor.h"
+#include "JSWebKitPointConstructor.h"
#include "JSWorkerConstructor.h"
#include "JSXMLHttpRequestConstructor.h"
#include "JSXSLTProcessorConstructor.h"
@@ -62,10 +57,7 @@
#include "SecurityOrigin.h"
#include "Settings.h"
#include "WindowFeatures.h"
-#include "htmlediting.h"
-#include <runtime/Error.h>
#include <runtime/JSLock.h>
-#include <wtf/AlwaysInline.h>
#include <wtf/MathExtras.h>
using namespace JSC;
@@ -91,6 +83,8 @@ static JSValuePtr jsDOMWindowBaseOption(ExecState*, const Identifier&, const Pro
static void setJSDOMWindowBaseOption(ExecState*, JSObject*, JSValuePtr);
static JSValuePtr jsDOMWindowBaseWebKitCSSMatrix(ExecState*, const Identifier&, const PropertySlot&);
static void setJSDOMWindowBaseWebKitCSSMatrix(ExecState*, JSObject*, JSValuePtr);
+static JSValuePtr jsDOMWindowBaseWebKitPoint(ExecState*, const Identifier&, const PropertySlot&);
+static void setJSDOMWindowBaseWebKitPoint(ExecState*, JSObject*, JSValuePtr);
static JSValuePtr jsDOMWindowBaseXMLHttpRequest(ExecState*, const Identifier&, const PropertySlot&);
static void setJSDOMWindowBaseXMLHttpRequest(ExecState*, JSObject*, JSValuePtr);
static JSValuePtr jsDOMWindowBaseXSLTProcessor(ExecState*, const Identifier&, const PropertySlot&);
@@ -121,6 +115,7 @@ const ClassInfo JSDOMWindowBase::s_info = { "Window", 0, &JSDOMWindowBaseTable,
MessageChannel jsDOMWindowBaseMessageChannel DontDelete
Option jsDOMWindowBaseOption DontDelete
WebKitCSSMatrix jsDOMWindowBaseWebKitCSSMatrix DontDelete
+ WebKitPoint jsDOMWindowBaseWebKitPoint DontDelete
Worker jsDOMWindowBaseWorker DontDelete
XMLHttpRequest jsDOMWindowBaseXMLHttpRequest DontDelete
XSLTProcessor jsDOMWindowBaseXSLTProcessor DontDelete
@@ -137,9 +132,6 @@ JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow>
JSDOMWindowBase::JSDOMWindowBase(PassRefPtr<Structure> structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
: JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell)
{
- // Time in milliseconds before the script timeout handler kicks in.
- setTimeoutTime(10000);
-
GlobalPropertyInfo staticGlobals[] = {
GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
GlobalPropertyInfo(Identifier(globalExec(), "window"), d()->shell, DontDelete | ReadOnly)
@@ -409,7 +401,7 @@ JSValuePtr jsDOMWindowBaseWebKitCSSMatrix(ExecState* exec, const Identifier&, co
{
if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec))
return jsUndefined();
- return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase())));
+ return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec);
}
JSValuePtr jsDOMWindowBaseXMLHttpRequest(ExecState* exec, const Identifier&, const PropertySlot& slot)
@@ -428,10 +420,19 @@ JSValuePtr jsDOMWindowBaseAudio(ExecState* exec, const Identifier&, const Proper
return jsUndefined();
return getDOMConstructor<JSAudioConstructor>(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase())));
#else
+ UNUSED_PARAM(exec);
+ UNUSED_PARAM(slot);
return jsUndefined();
#endif
}
+JSValuePtr jsDOMWindowBaseWebKitPoint(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+ if (!static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->allowsAccessFrom(exec))
+ return jsUndefined();
+ return getDOMConstructor<JSWebKitPointConstructor>(exec);
+}
+
JSValuePtr jsDOMWindowBaseWorker(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
#if ENABLE(WORKERS)
@@ -439,6 +440,8 @@ JSValuePtr jsDOMWindowBaseWorker(ExecState* exec, const Identifier&, const Prope
return jsUndefined();
return getDOMConstructor<JSWorkerConstructor>(exec);
#else
+ UNUSED_PARAM(exec);
+ UNUSED_PARAM(slot);
return jsUndefined();
#endif
}
@@ -450,6 +453,8 @@ JSValuePtr jsDOMWindowBaseXSLTProcessor(ExecState* exec, const Identifier&, cons
return jsUndefined();
return getDOMConstructor<JSXSLTProcessorConstructor>(exec);
#else
+ UNUSED_PARAM(exec);
+ UNUSED_PARAM(slot);
return jsUndefined();
#endif
}
@@ -510,6 +515,14 @@ void setJSDOMWindowBaseWebKitCSSMatrix(ExecState* exec, JSObject* thisObject, JS
static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "WebKitCSSMatrix"), value);
}
+void setJSDOMWindowBaseWebKitPoint(ExecState* exec, JSObject* thisObject, JSValuePtr value)
+{
+ if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec))
+ return;
+ // Shadowing a built-in constructor
+ static_cast<JSDOMWindowBase*>(thisObject)->putDirect(Identifier(exec, "WebKitPoint"), value);
+}
+
void setJSDOMWindowBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value)
{
if (!static_cast<JSDOMWindowBase*>(thisObject)->allowsAccessFrom(exec))
@@ -609,7 +622,7 @@ bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& prop
// Allow shortcuts like 'Image1' instead of document.images.Image1
Document* document = impl()->frame()->document();
- if (document && document->isHTMLDocument()) {
+ if (document->isHTMLDocument()) {
AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName);
if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
slot.setCustom(this, namedItemGetter);
@@ -735,7 +748,12 @@ JSDOMWindowShell* JSDOMWindowBase::shell() const
JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
{
- static JSGlobalData* globalData = JSGlobalData::createLeaked().releaseRef();
+ static JSGlobalData* globalData;
+ if (!globalData) {
+ globalData = JSGlobalData::createLeaked().releaseRef();
+ globalData->timeoutChecker.setTimeoutInterval(10000); // 10 seconds
+ }
+
return globalData;
}
diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h
index 2398172..ef87f20 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.h
+++ b/WebCore/bindings/js/JSDOMWindowBase.h
@@ -34,9 +34,9 @@ namespace WebCore {
class Frame;
class JSDOMWindow;
class JSDOMWindowShell;
- class JSEventListener;
+ class JSProtectedEventListener;
class JSLocation;
- class JSUnprotectedEventListener;
+ class JSEventListener;
class ScheduledAction;
class SecurityOrigin;
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index 562e661..703ad8a 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -268,10 +268,8 @@ JSValuePtr JSDOMWindow::addEventListener(ExecState* exec, const ArgList& args)
if (!frame)
return jsUndefined();
- if (RefPtr<JSEventListener> listener = findOrCreateJSEventListener(exec, args.at(exec, 1))) {
- if (Document* doc = frame->document())
- doc->addWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener.release(), args.at(exec, 2).toBoolean(exec));
- }
+ if (RefPtr<JSProtectedEventListener> listener = findOrCreateJSProtectedEventListener(exec, args.at(exec, 1)))
+ frame->document()->addWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener.release(), args.at(exec, 2).toBoolean(exec));
return jsUndefined();
}
@@ -282,10 +280,8 @@ JSValuePtr JSDOMWindow::removeEventListener(ExecState* exec, const ArgList& args
if (!frame)
return jsUndefined();
- if (JSEventListener* listener = findJSEventListener(args.at(exec, 1))) {
- if (Document* doc = frame->document())
- doc->removeWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener, args.at(exec, 2).toBoolean(exec));
- }
+ if (JSProtectedEventListener* listener = findJSProtectedEventListener(args.at(exec, 1)))
+ frame->document()->removeWindowEventListener(AtomicString(args.at(exec, 0).toString(exec)), listener, args.at(exec, 2).toBoolean(exec));
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.h b/WebCore/bindings/js/JSDOMWindowCustom.h
index 838abab..73a9656 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.h
+++ b/WebCore/bindings/js/JSDOMWindowCustom.h
@@ -74,12 +74,10 @@ ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, c
// is allowed.
bool allowsAccess = allowsAccessFromNoErrorMessage(exec);
- // Look for overrides before looking at any of our own properties.
- if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) {
- // But ignore overrides completely if this is cross-domain access.
- if (allowsAccess)
- return true;
- }
+ // Look for overrides before looking at any of our own properties, but ignore overrides completely
+ // if this is cross-domain access.
+ if (allowsAccess && JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot))
+ return true;
// We need this code here because otherwise JSC::Window will stop the search before we even get to the
// prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot.
@@ -128,7 +126,7 @@ inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier&
if (!impl()->frame())
return true;
- // We have a local override (e.g. "var location"), save time and jump directly to JSGlobalObject.
+ // Optimization: access JavaScript global variables directly before involving the DOM.
JSC::PropertySlot getSlot;
bool slotIsWriteable;
if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, getSlot, slotIsWriteable)) {
diff --git a/WebCore/bindings/js/JSDOMWindowShell.cpp b/WebCore/bindings/js/JSDOMWindowShell.cpp
index d54611e..f14c2f7 100644
--- a/WebCore/bindings/js/JSDOMWindowShell.cpp
+++ b/WebCore/bindings/js/JSDOMWindowShell.cpp
@@ -39,7 +39,7 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSDOMWindowShell)
+ASSERT_CLASS_FITS_IN_CELL(JSDOMWindowShell);
const ClassInfo JSDOMWindowShell::s_info = { "JSDOMWindowShell", 0, 0, 0 };
@@ -54,11 +54,17 @@ JSDOMWindowShell::~JSDOMWindowShell()
{
}
-void JSDOMWindowShell::setWindow(PassRefPtr<DOMWindow> window)
+void JSDOMWindowShell::setWindow(PassRefPtr<DOMWindow> domWindow)
{
+ // Explicitly protect the global object's prototype so it isn't collected
+ // when we allocate the global object. (Once the global object is fully
+ // constructed, it can mark its own prototype.)
RefPtr<Structure> prototypeStructure = JSDOMWindowPrototype::createStructure(jsNull());
- RefPtr<Structure> structure = JSDOMWindow::createStructure(new JSDOMWindowPrototype(prototypeStructure.release()));
- setWindow(new (JSDOMWindow::commonJSGlobalData()) JSDOMWindow(structure.release(), window, this));
+ ProtectedPtr<JSDOMWindowPrototype> prototype = new JSDOMWindowPrototype(prototypeStructure.release());
+
+ RefPtr<Structure> structure = JSDOMWindow::createStructure(prototype);
+ JSDOMWindow* jsDOMWindow = new (JSDOMWindow::commonJSGlobalData()) JSDOMWindow(structure.release(), domWindow, this);
+ setWindow(jsDOMWindow);
}
// ----
diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp
index fff0ea5..c432aea 100644
--- a/WebCore/bindings/js/JSDocumentCustom.cpp
+++ b/WebCore/bindings/js/JSDocumentCustom.cpp
@@ -20,7 +20,6 @@
#include "config.h"
#include "JSDocument.h"
-#include "DOMWindow.h"
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -28,9 +27,6 @@
#include "JSDOMWindowCustom.h"
#include "JSHTMLDocument.h"
#include "JSLocation.h"
-#include "JSNodeList.h"
-#include "Location.h"
-#include "NodeList.h"
#include "ScriptController.h"
#if ENABLE(SVG)
@@ -44,7 +40,7 @@ namespace WebCore {
void JSDocument::mark()
{
- JSEventTargetNode::mark();
+ JSNode::mark();
markDOMNodesForDocument(impl());
markActiveObjectsForContext(*Heap::heap(this)->globalData(), impl());
}
diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp
index 4eb00fa..4c9cf0d 100644
--- a/WebCore/bindings/js/JSEventListener.cpp
+++ b/WebCore/bindings/js/JSEventListener.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,19 +20,10 @@
#include "config.h"
#include "JSEventListener.h"
-#include "CString.h"
-#include "Console.h"
-#include "DOMWindow.h"
-#include "Document.h"
#include "Event.h"
#include "Frame.h"
-#include "FrameLoader.h"
-#include "JSDOMWindow.h"
#include "JSEvent.h"
#include "JSEventTarget.h"
-#include "JSEventTargetNode.h"
-#include "ScriptController.h"
-#include <runtime/FunctionConstructor.h>
#include <runtime/JSLock.h>
#include <wtf/RefCountedLeakCounter.h>
@@ -40,13 +31,11 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSAbstractEventListener)
-
void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
{
JSLock lock(false);
- JSObject* listener = listenerObj();
+ JSObject* listener = function();
if (!listener)
return;
@@ -103,7 +92,7 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
JSValuePtr retval;
if (handleEventFunction) {
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
retval = call(exec, handleEventFunction, callType, callData, listener, args);
} else {
JSValuePtr thisValue;
@@ -111,10 +100,10 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
thisValue = globalObject->toThisObject(exec);
else
thisValue = toJS(exec, event->currentTarget());
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
retval = call(exec, listener, callType, callData, thisValue, args);
}
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
globalObject->setCurrentEvent(savedEvent);
@@ -136,50 +125,50 @@ void JSAbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
}
}
-bool JSAbstractEventListener::isInline() const
+bool JSAbstractEventListener::virtualIsInline() const
{
return m_isInline;
}
// -------------------------------------------------------------------------
-JSUnprotectedEventListener::JSUnprotectedEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
+JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
: JSAbstractEventListener(isInline)
, m_listener(listener)
, m_globalObject(globalObject)
{
if (m_listener) {
- JSDOMWindow::UnprotectedListenersMap& listeners = isInline
- ? globalObject->jsUnprotectedInlineEventListeners() : globalObject->jsUnprotectedEventListeners();
+ JSDOMWindow::JSListenersMap& listeners = isInline
+ ? globalObject->jsInlineEventListeners() : globalObject->jsEventListeners();
listeners.set(m_listener, this);
}
}
-JSUnprotectedEventListener::~JSUnprotectedEventListener()
+JSEventListener::~JSEventListener()
{
if (m_listener && m_globalObject) {
- JSDOMWindow::UnprotectedListenersMap& listeners = isInline()
- ? m_globalObject->jsUnprotectedInlineEventListeners() : m_globalObject->jsUnprotectedEventListeners();
+ JSDOMWindow::JSListenersMap& listeners = isInline()
+ ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners();
listeners.remove(m_listener);
}
}
-JSObject* JSUnprotectedEventListener::listenerObj() const
+JSObject* JSEventListener::function() const
{
return m_listener;
}
-JSDOMGlobalObject* JSUnprotectedEventListener::globalObject() const
+JSDOMGlobalObject* JSEventListener::globalObject() const
{
return m_globalObject;
}
-void JSUnprotectedEventListener::clearGlobalObject()
+void JSEventListener::clearGlobalObject()
{
m_globalObject = 0;
}
-void JSUnprotectedEventListener::mark()
+void JSEventListener::mark()
{
if (m_listener && !m_listener->marked())
m_listener->mark();
@@ -191,14 +180,14 @@ static WTF::RefCountedLeakCounter eventListenerCounter("EventListener");
// -------------------------------------------------------------------------
-JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
+JSProtectedEventListener::JSProtectedEventListener(JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
: JSAbstractEventListener(isInline)
, m_listener(listener)
, m_globalObject(globalObject)
{
if (m_listener) {
- JSDOMWindow::ListenersMap& listeners = isInline
- ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners();
+ JSDOMWindow::ProtectedListenersMap& listeners = isInline
+ ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners();
listeners.set(m_listener, this);
}
#ifndef NDEBUG
@@ -206,11 +195,11 @@ JSEventListener::JSEventListener(JSObject* listener, JSDOMGlobalObject* globalOb
#endif
}
-JSEventListener::~JSEventListener()
+JSProtectedEventListener::~JSProtectedEventListener()
{
if (m_listener && m_globalObject) {
- JSDOMWindow::ListenersMap& listeners = isInline()
- ? m_globalObject->jsInlineEventListeners() : m_globalObject->jsEventListeners();
+ JSDOMWindow::ProtectedListenersMap& listeners = isInline()
+ ? m_globalObject->jsProtectedInlineEventListeners() : m_globalObject->jsProtectedEventListeners();
listeners.remove(m_listener);
}
#ifndef NDEBUG
@@ -218,123 +207,19 @@ JSEventListener::~JSEventListener()
#endif
}
-JSObject* JSEventListener::listenerObj() const
+JSObject* JSProtectedEventListener::function() const
{
return m_listener;
}
-JSDOMGlobalObject* JSEventListener::globalObject() const
+JSDOMGlobalObject* JSProtectedEventListener::globalObject() const
{
return m_globalObject;
}
-void JSEventListener::clearGlobalObject()
+void JSProtectedEventListener::clearGlobalObject()
{
m_globalObject = 0;
}
-// -------------------------------------------------------------------------
-
-JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
- : JSEventListener(0, globalObject, true)
- , m_functionName(functionName)
- , m_code(code)
- , m_parsed(false)
- , m_lineNumber(lineNumber)
- , m_originalNode(node)
- , m_type(type)
-{
- // We don't retain the original node because we assume it
- // will stay alive as long as this handler object is around
- // and we need to avoid a reference cycle. If JS transfers
- // this handler to another node, parseCode will be called and
- // then originalNode is no longer needed.
-
- // A JSLazyEventListener can be created with a line number of zero when it is created with
- // a setAttribute call from JavaScript, so make the line number 1 in that case.
- if (m_lineNumber == 0)
- m_lineNumber = 1;
-}
-
-JSObject* JSLazyEventListener::listenerObj() const
-{
- parseCode();
- return m_listener;
-}
-
-// Helper function
-inline JSValuePtr eventParameterName(JSLazyEventListener::LazyEventListenerType type, ExecState* exec)
-{
- switch (type) {
- case JSLazyEventListener::HTMLLazyEventListener:
- return jsNontrivialString(exec, "event");
-#if ENABLE(SVG)
- case JSLazyEventListener::SVGLazyEventListener:
- return jsNontrivialString(exec, "evt");
-#endif
- default:
- ASSERT_NOT_REACHED();
- return jsUndefined();
- }
-}
-
-void JSLazyEventListener::parseCode() const
-{
- if (m_parsed)
- return;
-
- if (globalObject()->scriptExecutionContext()->isDocument()) {
- JSDOMWindow* window = static_cast<JSDOMWindow*>(globalObject());
- Frame* frame = window->impl()->frame();
- if (!frame)
- return;
- // FIXME: Is this check needed for non-Document contexts?
- ScriptController* script = frame->script();
- if (!script->isEnabled() || script->isPaused())
- return;
- }
-
- m_parsed = true;
-
- ExecState* exec = globalObject()->globalExec();
-
- ArgList args;
- UString sourceURL(globalObject()->scriptExecutionContext()->url().string());
- args.append(eventParameterName(m_type, exec));
- args.append(jsString(exec, m_code));
-
- // FIXME: Passing the document's URL to construct is not always correct, since this event listener might
- // have been added with setAttribute from a script, and we should pass String() in that case.
- m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok?
-
- JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_listener.get());
-
- if (exec->hadException()) {
- exec->clearException();
-
- // failed to parse, so let's just make this listener a no-op
- m_listener = 0;
- } else if (m_originalNode) {
- // Add the event's home element to the scope
- // (and the document, and the form - see JSHTMLElement::eventHandlerScope)
- ScopeChain scope = listenerAsFunction->scope();
-
- JSValuePtr thisObj = toJS(exec, m_originalNode);
- if (thisObj.isObject()) {
- static_cast<JSEventTargetNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope);
- listenerAsFunction->setScope(scope);
- }
- }
-
- // no more need to keep the unparsed code around
- m_functionName = String();
- m_code = String();
-
- if (m_listener) {
- ASSERT(isInline());
- JSDOMWindow::ListenersMap& listeners = globalObject()->jsInlineEventListeners();
- listeners.set(m_listener, const_cast<JSLazyEventListener*>(this));
- }
-}
-
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h
index 859d5d4..9589001 100644
--- a/WebCore/bindings/js/JSEventListener.h
+++ b/WebCore/bindings/js/JSEventListener.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,21 +21,15 @@
#define JSEventListener_h
#include "EventListener.h"
-#include "PlatformString.h"
#include <runtime/Protect.h>
namespace WebCore {
- class Event;
class JSDOMGlobalObject;
- class Node;
class JSAbstractEventListener : public EventListener {
public:
- virtual void handleEvent(Event*, bool isWindowEvent);
- virtual bool isInline() const;
- virtual JSC::JSObject* listenerObj() const = 0;
- virtual JSDOMGlobalObject* globalObject() const = 0;
+ bool isInline() const { return m_isInline; }
protected:
JSAbstractEventListener(bool isInline)
@@ -44,80 +38,53 @@ namespace WebCore {
}
private:
+ virtual void handleEvent(Event*, bool isWindowEvent);
+ virtual JSDOMGlobalObject* globalObject() const = 0;
+ virtual bool virtualIsInline() const;
+
bool m_isInline;
};
- class JSUnprotectedEventListener : public JSAbstractEventListener {
+ class JSEventListener : public JSAbstractEventListener {
public:
- static PassRefPtr<JSUnprotectedEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
+ static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
{
- return adoptRef(new JSUnprotectedEventListener(listener, globalObject, isInline));
+ return adoptRef(new JSEventListener(listener, globalObject, isInline));
}
- virtual ~JSUnprotectedEventListener();
+ virtual ~JSEventListener();
- virtual JSC::JSObject* listenerObj() const;
- virtual JSDOMGlobalObject* globalObject() const;
void clearGlobalObject();
- void mark();
private:
- JSUnprotectedEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline);
+ JSEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline);
+
+ virtual JSC::JSObject* function() const;
+ virtual void mark();
+ virtual JSDOMGlobalObject* globalObject() const;
JSC::JSObject* m_listener;
JSDOMGlobalObject* m_globalObject;
};
- class JSEventListener : public JSAbstractEventListener {
+ class JSProtectedEventListener : public JSAbstractEventListener {
public:
- static PassRefPtr<JSEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
+ static PassRefPtr<JSProtectedEventListener> create(JSC::JSObject* listener, JSDOMGlobalObject* globalObject, bool isInline)
{
- return adoptRef(new JSEventListener(listener, globalObject, isInline));
+ return adoptRef(new JSProtectedEventListener(listener, globalObject, isInline));
}
- virtual ~JSEventListener();
+ virtual ~JSProtectedEventListener();
- virtual JSC::JSObject* listenerObj() const;
- virtual JSDOMGlobalObject* globalObject() const;
void clearGlobalObject();
protected:
- JSEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline);
+ JSProtectedEventListener(JSC::JSObject* listener, JSDOMGlobalObject*, bool isInline);
mutable JSC::ProtectedPtr<JSC::JSObject> m_listener;
-
- private:
JSC::ProtectedPtr<JSDOMGlobalObject> m_globalObject;
- };
-
- class JSLazyEventListener : public JSEventListener {
- public:
- enum LazyEventListenerType {
- HTMLLazyEventListener
-#if ENABLE(SVG)
- , SVGLazyEventListener
-#endif
- };
-
- virtual bool wasCreatedFromMarkup() const { return true; }
-
- static PassRefPtr<JSLazyEventListener> create(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
- {
- return adoptRef(new JSLazyEventListener(type, functionName, code, globalObject, node, lineNumber));
- }
- virtual JSC::JSObject* listenerObj() const;
-
- protected:
- JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber);
private:
- void parseCode() const;
-
- mutable String m_functionName;
- mutable String m_code;
- mutable bool m_parsed;
- int m_lineNumber;
- Node* m_originalNode;
-
- LazyEventListenerType m_type;
+ virtual JSC::JSObject* function() const;
+ virtual JSDOMGlobalObject* globalObject() const;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSEventTarget.cpp b/WebCore/bindings/js/JSEventTarget.cpp
index fb72ce7..d9cff4a 100644
--- a/WebCore/bindings/js/JSEventTarget.cpp
+++ b/WebCore/bindings/js/JSEventTarget.cpp
@@ -28,23 +28,31 @@
#include "Document.h"
#include "JSEventListener.h"
-#include "JSEventTargetNode.h"
#include "JSMessagePort.h"
-#ifdef ANDROID_FIX // these are generated files, need to check ENABLE(WORKERS)
-#if ENABLE(WORKERS)
-#include "JSWorker.h"
-#include "JSWorkerContext.h"
-#endif
-#endif
+#include "JSNode.h"
+#include "JSXMLHttpRequest.h"
#include "JSXMLHttpRequestUpload.h"
-#include "Worker.h"
-#include "WorkerContext.h"
+#include "MessagePort.h"
+#include "XMLHttpRequest.h"
+#include "XMLHttpRequestUpload.h"
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "DOMApplicationCache.h"
+#include "JSDOMApplicationCache.h"
+#endif
#if ENABLE(SVG)
#include "SVGElementInstance.h"
#include "JSSVGElementInstance.h"
#endif
+#if ENABLE(WORKERS)
+#include "JSWorker.h"
+#include "JSWorkerContext.h"
+#include "Worker.h"
+#include "WorkerContext.h"
+#endif
+
using namespace JSC;
namespace WebCore {
@@ -91,4 +99,31 @@ JSValuePtr toJS(ExecState* exec, EventTarget* target)
return jsNull();
}
+EventTarget* toEventTarget(JSC::JSValuePtr value)
+{
+ #define CONVERT_TO_EVENT_TARGET(type) \
+ if (value.isObject(&JS##type::s_info)) \
+ return static_cast<JS##type*>(asObject(value))->impl();
+
+ CONVERT_TO_EVENT_TARGET(Node)
+ CONVERT_TO_EVENT_TARGET(XMLHttpRequest)
+ CONVERT_TO_EVENT_TARGET(XMLHttpRequestUpload)
+ CONVERT_TO_EVENT_TARGET(MessagePort)
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ CONVERT_TO_EVENT_TARGET(DOMApplicationCache)
+#endif
+
+#if ENABLE(SVG)
+ CONVERT_TO_EVENT_TARGET(SVGElementInstance)
+#endif
+
+#if ENABLE(WORKERS)
+ CONVERT_TO_EVENT_TARGET(Worker)
+ CONVERT_TO_EVENT_TARGET(WorkerContext)
+#endif
+
+ return 0;
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSEventTarget.h b/WebCore/bindings/js/JSEventTarget.h
index 00dd848..02f3734 100644
--- a/WebCore/bindings/js/JSEventTarget.h
+++ b/WebCore/bindings/js/JSEventTarget.h
@@ -37,6 +37,7 @@ namespace WebCore {
class EventTarget;
JSC::JSValuePtr toJS(JSC::ExecState*, EventTarget*);
+ EventTarget* toEventTarget(JSC::JSValuePtr);
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSEventTargetNodeCustom.cpp b/WebCore/bindings/js/JSEventTargetNodeCustom.cpp
deleted file mode 100644
index 3193272..0000000
--- a/WebCore/bindings/js/JSEventTargetNodeCustom.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "JSEventTargetNode.h"
-
-#include "AtomicString.h"
-#include "Document.h"
-#include "Event.h"
-#include "EventTargetNode.h"
-#include "ExceptionCode.h"
-#include "Frame.h"
-#include "JSDOMWindow.h"
-#include "JSEvent.h"
-#include "JSEventListener.h"
-
-using namespace JSC;
-
-namespace WebCore {
-
-JSValuePtr JSEventTargetNode::addEventListener(ExecState* exec, const ArgList& args)
-{
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
- if (!globalObject)
- return jsUndefined();
-
- if (RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)))
- impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
-
- return jsUndefined();
-}
-
-JSValuePtr JSEventTargetNode::removeEventListener(ExecState* exec, const ArgList& args)
-{
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
- if (!globalObject)
- return jsUndefined();
-
- if (JSEventListener* listener = globalObject->findJSEventListener(args.at(exec, 1)))
- impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
-
- return jsUndefined();
-}
-
-void JSEventTargetNode::pushEventHandlerScope(ExecState*, ScopeChain&) const
-{
-}
-
-} // namespace WebCore
diff --git a/WebCore/bindings/js/JSGeolocationCustom.cpp b/WebCore/bindings/js/JSGeolocationCustom.cpp
index 1b9bce8..c818dd9 100644
--- a/WebCore/bindings/js/JSGeolocationCustom.cpp
+++ b/WebCore/bindings/js/JSGeolocationCustom.cpp
@@ -60,7 +60,14 @@ static PassRefPtr<PositionOptions> createPositionOptions(ExecState* exec, JSValu
if (exec->hadException())
return 0;
- return PositionOptions::create(enableHighAccuracy, timeout);
+ JSValuePtr maximumAgeValue = object->get(exec, Identifier(exec, "maximumAge"));
+ if (exec->hadException())
+ return 0;
+ unsigned maximumAge = maximumAgeValue.toUInt32(exec);
+ if (exec->hadException())
+ return 0;
+
+ return PositionOptions::create(enableHighAccuracy, timeout, maximumAge);
}
JSValuePtr JSGeolocation::getCurrentPosition(ExecState* exec, const ArgList& args)
diff --git a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
index be2d158..1bc40ff 100644
--- a/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSHTMLDocument.h"
+#include "CharacterNames.h"
#include "Frame.h"
#include "HTMLBodyElement.h"
#include "HTMLCollection.h"
@@ -37,6 +38,8 @@
#include "JSDOMWindowCustom.h"
#include "JSDOMWindowShell.h"
#include "JSHTMLCollection.h"
+#include "SegmentedString.h"
+#include "Tokenizer.h"
#include <runtime/Error.h>
using namespace JSC;
@@ -124,32 +127,42 @@ JSValuePtr JSHTMLDocument::open(ExecState* exec, const ArgList& args)
return this;
}
-static String writeHelper(ExecState* exec, const ArgList& args)
-{
- // DOM only specifies single string argument, but NS & IE allow multiple
- // or no arguments.
+enum NewlineRequirement { DoNotAddNewline, DoAddNewline };
- unsigned size = args.size();
- if (size == 1)
- return args.at(exec, 0).toString(exec);
+static inline void documentWrite(ExecState* exec, const ArgList& args, HTMLDocument* document, NewlineRequirement addNewline)
+{
+ // DOM only specifies single string argument, but browsers allow multiple or no arguments.
+
+ size_t size = args.size();
+
+ UString firstString = args.at(exec, 0).toString(exec);
+ SegmentedString segmentedString = String(firstString);
+ if (size != 1) {
+ if (!size)
+ segmentedString.clear();
+ else {
+ for (size_t i = 1; i < size; ++i) {
+ UString subsequentString = args.at(exec, i).toString(exec);
+ segmentedString.append(SegmentedString(String(subsequentString)));
+ }
+ }
+ }
+ if (addNewline)
+ segmentedString.append(SegmentedString(&newlineCharacter, 1));
- Vector<UChar> result;
- for (unsigned i = 0; i < size; ++i)
- append(result, args.at(exec, i).toString(exec));
- return String::adopt(result);
+ Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document();
+ document->write(segmentedString, activeDocument);
}
JSValuePtr JSHTMLDocument::write(ExecState* exec, const ArgList& args)
{
- Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document();
- static_cast<HTMLDocument*>(impl())->write(writeHelper(exec, args), activeDocument);
+ documentWrite(exec, args, static_cast<HTMLDocument*>(impl()), DoNotAddNewline);
return jsUndefined();
}
JSValuePtr JSHTMLDocument::writeln(ExecState* exec, const ArgList& args)
{
- Document* activeDocument = asJSDOMWindow(exec->lexicalGlobalObject())->impl()->document();
- static_cast<HTMLDocument*>(impl())->write(writeHelper(exec, args) + "\n", activeDocument);
+ documentWrite(exec, args, static_cast<HTMLDocument*>(impl()), DoAddNewline);
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSHTMLInputElementCustom.cpp b/WebCore/bindings/js/JSHTMLInputElementCustom.cpp
index d59ef92..aa52007 100644
--- a/WebCore/bindings/js/JSHTMLInputElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLInputElementCustom.cpp
@@ -32,41 +32,53 @@ using namespace JSC;
namespace WebCore {
-bool JSHTMLInputElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+JSValuePtr JSHTMLInputElement::selectionStart(ExecState* exec) const
{
HTMLInputElement* input = static_cast<HTMLInputElement*>(impl());
- if (input->canHaveSelection())
- return false;
-
- const HashEntry* entry = JSHTMLInputElementPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
- if (entry) {
- if (entry->attributes() & Function) {
- if (entry->function() == jsHTMLInputElementPrototypeFunctionSetSelectionRange) {
- slot.setUndefined();
- return true;
- }
- }
- }
+ if (!input->canHaveSelection())
+ return throwError(exec, TypeError);
- return false;
+ return jsNumber(exec, input->selectionStart());
}
-JSValuePtr JSHTMLInputElement::selectionStart(ExecState* exec) const
+void JSHTMLInputElement::setSelectionStart(ExecState* exec, JSValuePtr value)
{
HTMLInputElement* input = static_cast<HTMLInputElement*>(impl());
if (!input->canHaveSelection())
- return jsUndefined();
+ throwError(exec, TypeError);
- return jsNumber(exec, input->selectionStart());
+ input->setSelectionStart(value.toInt32(exec));
}
JSValuePtr JSHTMLInputElement::selectionEnd(ExecState* exec) const
{
HTMLInputElement* input = static_cast<HTMLInputElement*>(impl());
if (!input->canHaveSelection())
- return jsUndefined();
+ return throwError(exec, TypeError);
return jsNumber(exec, input->selectionEnd());
}
+void JSHTMLInputElement::setSelectionEnd(ExecState* exec, JSValuePtr value)
+{
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(impl());
+ if (!input->canHaveSelection())
+ throwError(exec, TypeError);
+
+ input->setSelectionEnd(value.toInt32(exec));
+}
+
+JSValuePtr JSHTMLInputElement::setSelectionRange(ExecState* exec, const ArgList& args)
+{
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(impl());
+ if (!input->canHaveSelection())
+ return throwError(exec, TypeError);
+
+ int start = args.at(exec, 0).toInt32(exec);
+ int end = args.at(exec, 1).toInt32(exec);
+
+ input->setSelectionRange(start, end);
+ return jsUndefined();
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSImageConstructor.cpp b/WebCore/bindings/js/JSImageConstructor.cpp
index 0dc55b4..aa44c73 100644
--- a/WebCore/bindings/js/JSImageConstructor.cpp
+++ b/WebCore/bindings/js/JSImageConstructor.cpp
@@ -22,6 +22,7 @@
#include "HTMLImageElement.h"
#include "HTMLNames.h"
+#include "JSHTMLImageElement.h"
#include "JSNode.h"
#include "ScriptExecutionContext.h"
@@ -29,15 +30,22 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor)
+ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor);
const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", 0, 0, 0 };
JSImageConstructor::JSImageConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSImageConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+ , m_globalObject(toJSDOMGlobalObject(context))
{
ASSERT(context->isDocument());
- m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
+
+ putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec), None);
+}
+
+Document* JSImageConstructor::document() const
+{
+ return static_cast<Document*>(m_globalObject->scriptExecutionContext());
}
static JSObject* constructImage(ExecState* exec, JSObject* constructor, const ArgList& args)
@@ -79,8 +87,8 @@ ConstructType JSImageConstructor::getConstructData(ConstructData& constructData)
void JSImageConstructor::mark()
{
DOMObject::mark();
- if (!m_document->marked())
- m_document->mark();
+ if (!m_globalObject->marked())
+ m_globalObject->mark();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSImageConstructor.h b/WebCore/bindings/js/JSImageConstructor.h
index 13cce26..578d1cf 100644
--- a/WebCore/bindings/js/JSImageConstructor.h
+++ b/WebCore/bindings/js/JSImageConstructor.h
@@ -28,7 +28,7 @@ namespace WebCore {
class JSImageConstructor : public DOMObject {
public:
JSImageConstructor(JSC::ExecState*, ScriptExecutionContext*);
- Document* document() const { return m_document->impl(); }
+ Document* document() const;
static const JSC::ClassInfo s_info;
@@ -37,7 +37,7 @@ namespace WebCore {
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
- JSDocument* m_document;
+ JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp
index 09ad9f4..09007c1 100644
--- a/WebCore/bindings/js/JSInspectedObjectWrapper.cpp
+++ b/WebCore/bindings/js/JSInspectedObjectWrapper.cpp
@@ -34,7 +34,7 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSInspectedObjectWrapper)
+ASSERT_CLASS_FITS_IN_CELL(JSInspectedObjectWrapper);
typedef HashMap<JSObject*, JSInspectedObjectWrapper*> WrapperMap;
typedef HashMap<JSGlobalObject*, WrapperMap*> GlobalObjectWrapperMap;
@@ -57,7 +57,7 @@ JSValuePtr JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValuePtr u
if (unwrappedObject->inherits(&JSInspectedObjectWrapper::s_info))
return unwrappedObject;
- if (WrapperMap* wrapperMap = wrappers().get(unwrappedExec->dynamicGlobalObject()))
+ if (WrapperMap* wrapperMap = wrappers().get(unwrappedExec->lexicalGlobalObject()))
if (JSInspectedObjectWrapper* wrapper = wrapperMap->get(unwrappedObject))
return wrapper;
diff --git a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp
index 7ccf312..1fb5eae 100644
--- a/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp
+++ b/WebCore/bindings/js/JSInspectorCallbackWrapper.cpp
@@ -33,7 +33,7 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSInspectorCallbackWrapper)
+ASSERT_CLASS_FITS_IN_CELL(JSInspectorCallbackWrapper);
typedef HashMap<JSObject*, JSInspectorCallbackWrapper*> WrapperMap;
diff --git a/WebCore/bindings/js/JSInspectorControllerCustom.cpp b/WebCore/bindings/js/JSInspectorControllerCustom.cpp
new file mode 100644
index 0000000..79c69c8
--- /dev/null
+++ b/WebCore/bindings/js/JSInspectorControllerCustom.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSInspectorController.h"
+
+#include "Console.h"
+#if ENABLE(DATABASE)
+#include "Database.h"
+#include "JSDatabase.h"
+#endif
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "InspectorController.h"
+#include "InspectorResource.h"
+#include "JavaScriptProfile.h"
+#include "JSDOMWindow.h"
+#include "JSInspectedObjectWrapper.h"
+#include "JSInspectorCallbackWrapper.h"
+#include "JSNode.h"
+#include "JSRange.h"
+#include "Node.h"
+#include "Page.h"
+#include "TextIterator.h"
+#include "VisiblePosition.h"
+#include <profiler/Profile.h>
+#include <profiler/Profiler.h>
+#include <runtime/JSArray.h>
+#include <runtime/JSLock.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "JavaScriptCallFrame.h"
+#include "JavaScriptDebugServer.h"
+#include "JSJavaScriptCallFrame.h"
+#endif
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSValuePtr JSInspectorController::profiles(JSC::ExecState* exec, const JSC::ArgList&)
+{
+ JSLock lock(false);
+ ArgList result;
+ const Vector<RefPtr<Profile> >& profiles = impl()->profiles();
+
+ for (size_t i = 0; i < profiles.size(); ++i)
+ result.append(toJS(exec, profiles[i].get()));
+
+ return constructArray(exec, result);
+}
+
+JSValuePtr JSInspectorController::highlightDOMNode(JSC::ExecState* exec, const JSC::ArgList& args)
+{
+ if (args.size() < 1)
+ return jsUndefined();
+
+ JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(exec, 0));
+ if (!wrapper)
+ return jsUndefined();
+
+ Node* node = toNode(wrapper->unwrappedObject());
+ if (!node)
+ return jsUndefined();
+
+ impl()->highlight(node);
+
+ return jsUndefined();
+}
+
+JSValuePtr JSInspectorController::addResourceSourceToFrame(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 2)
+ return jsUndefined();
+
+ bool ok = false;
+ unsigned identifier = args.at(exec, 0).toUInt32(exec, ok);
+ if (!ok)
+ return jsUndefined();
+
+ RefPtr<InspectorResource> resource = impl()->resources().get(identifier);
+ ASSERT(resource);
+ if (!resource)
+ return jsUndefined();
+
+ String sourceString = resource->sourceString();
+ if (sourceString.isEmpty())
+ return jsUndefined();
+
+ return jsBoolean(impl()->addSourceToFrame(resource->mimeType, sourceString, toNode(args.at(exec, 1))));
+}
+
+JSValuePtr JSInspectorController::addSourceToFrame(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 3)
+ return jsUndefined();
+
+ String mimeType = args.at(exec, 0).toString(exec);
+ if (exec->hadException())
+ return jsUndefined();
+
+ String sourceString = args.at(exec, 1).toString(exec);
+ if (exec->hadException())
+ return jsUndefined();
+
+ return jsBoolean(impl()->addSourceToFrame(mimeType, sourceString, toNode(args.at(exec, 1))));
+}
+
+JSValuePtr JSInspectorController::getResourceDocumentNode(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 1)
+ return jsUndefined();
+
+ bool ok = false;
+ unsigned identifier = args.at(exec, 0).toUInt32(exec, ok);
+ if (!ok)
+ return jsUndefined();
+
+ RefPtr<InspectorResource> resource = impl()->resources().get(identifier);
+ ASSERT(resource);
+ if (!resource)
+ return jsUndefined();
+
+ Frame* frame = resource->frame.get();
+ Document* document = frame->document();
+
+ if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument())
+ return jsUndefined();
+
+ // FIXME: I am not sure if this is actually needed. Can we just use exec?
+ ExecState* resourceExec = toJSDOMWindowShell(resource->frame.get())->window()->globalExec();
+
+ JSLock lock(false);
+ return JSInspectedObjectWrapper::wrap(resourceExec, toJS(resourceExec, document));
+}
+
+JSValuePtr JSInspectorController::search(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 2)
+ return jsUndefined();
+
+ Node* node = toNode(args.at(exec, 0));
+ if (!node)
+ return jsUndefined();
+
+ String target = args.at(exec, 1).toString(exec);
+ if (exec->hadException())
+ return jsUndefined();
+
+ ArgList result;
+ RefPtr<Range> searchRange(rangeOfContents(node));
+
+ ExceptionCode ec = 0;
+ do {
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
+ if (resultRange->collapsed(ec))
+ break;
+
+ // A non-collapsed result range can in some funky whitespace cases still not
+ // advance the range's start position (4509328). Break to avoid infinite loop.
+ VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
+ if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
+ break;
+
+ result.append(toJS(exec, resultRange.get()));
+
+ setStart(searchRange.get(), newStart);
+ } while (true);
+
+ return constructArray(exec, result);
+}
+
+#if ENABLE(DATABASE)
+JSValuePtr JSInspectorController::databaseTableNames(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 1)
+ return jsUndefined();
+
+ JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(args.at(exec, 0));
+ if (!wrapper)
+ return jsUndefined();
+
+ Database* database = toDatabase(wrapper->unwrappedObject());
+ if (!database)
+ return jsUndefined();
+
+ ArgList result;
+
+ Vector<String> tableNames = database->tableNames();
+ unsigned length = tableNames.size();
+ for (unsigned i = 0; i < length; ++i)
+ result.append(jsString(exec, tableNames[i]));
+
+ return constructArray(exec, result);
+}
+#endif
+
+JSValuePtr JSInspectorController::inspectedWindow(ExecState*, const ArgList&)
+{
+ JSDOMWindow* inspectedWindow = toJSDOMWindow(impl()->inspectedPage()->mainFrame());
+ return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow);
+}
+
+JSValuePtr JSInspectorController::setting(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 1)
+ return jsUndefined();
+
+ String key = args.at(exec, 0).toString(exec);
+ if (exec->hadException())
+ return jsUndefined();
+
+ const InspectorController::Setting& setting = impl()->setting(key);
+
+ switch (setting.type()) {
+ default:
+ case InspectorController::Setting::NoType:
+ return jsUndefined();
+ case InspectorController::Setting::StringType:
+ return jsString(exec, setting.string());
+ case InspectorController::Setting::DoubleType:
+ return jsNumber(exec, setting.doubleValue());
+ case InspectorController::Setting::IntegerType:
+ return jsNumber(exec, setting.integerValue());
+ case InspectorController::Setting::BooleanType:
+ return jsBoolean(setting.booleanValue());
+ case InspectorController::Setting::StringVectorType: {
+ ArgList stringsArray;
+ const Vector<String>& strings = setting.stringVector();
+ const unsigned length = strings.size();
+ for (unsigned i = 0; i < length; ++i)
+ stringsArray.append(jsString(exec, strings[i]));
+ return constructArray(exec, stringsArray);
+ }
+ }
+}
+
+JSValuePtr JSInspectorController::setSetting(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 2)
+ return jsUndefined();
+
+ String key = args.at(exec, 0).toString(exec);
+ if (exec->hadException())
+ return jsUndefined();
+
+ InspectorController::Setting setting;
+
+ JSValuePtr value = args.at(exec, 0);
+ if (value.isUndefined() || value.isNull()) {
+ // Do nothing. The setting is already NoType.
+ ASSERT(setting.type() == InspectorController::Setting::NoType);
+ } else if (value.isString())
+ setting.set(value.toString(exec));
+ else if (value.isNumber())
+ setting.set(value.toNumber(exec));
+ else if (value.isBoolean())
+ setting.set(value.toBoolean(exec));
+ else {
+ JSArray* jsArray = asArray(value);
+ if (!jsArray)
+ return jsUndefined();
+ Vector<String> strings;
+ for (unsigned i = 0; i < jsArray->length(); ++i) {
+ String item = jsArray->get(exec, i).toString(exec);
+ if (exec->hadException())
+ return jsUndefined();
+ strings.append(item);
+ }
+ setting.set(strings);
+ }
+
+ if (exec->hadException())
+ return jsUndefined();
+
+ impl()->setSetting(key, setting);
+
+ return jsUndefined();
+}
+
+JSValuePtr JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 1)
+ return jsUndefined();
+
+ return JSInspectorCallbackWrapper::wrap(exec, args.at(exec, 0));
+}
+
+JSValuePtr JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&)
+{
+ JavaScriptCallFrame* callFrame = impl()->currentCallFrame();
+ if (!callFrame || !callFrame->isValid())
+ return jsUndefined();
+
+ // FIXME: I am not sure if this is actually needed. Can we just use exec?
+ ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec();
+
+ JSLock lock(false);
+ return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp
new file mode 100644
index 0000000..3c80efe
--- /dev/null
+++ b/WebCore/bindings/js/JSLazyEventListener.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 "JSLazyEventListener.h"
+
+#include "Frame.h"
+#include "JSNode.h"
+#include <runtime/FunctionConstructor.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSLazyEventListener::JSLazyEventListener(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
+ : JSProtectedEventListener(0, globalObject, true)
+ , m_functionName(functionName)
+ , m_code(code)
+ , m_parsed(false)
+ , m_lineNumber(lineNumber)
+ , m_originalNode(node)
+ , m_type(type)
+{
+ // We don't retain the original node because we assume it
+ // will stay alive as long as this handler object is around
+ // and we need to avoid a reference cycle. If JS transfers
+ // this handler to another node, parseCode will be called and
+ // then originalNode is no longer needed.
+
+ // A JSLazyEventListener can be created with a line number of zero when it is created with
+ // a setAttribute call from JavaScript, so make the line number 1 in that case.
+ if (m_lineNumber == 0)
+ m_lineNumber = 1;
+}
+
+JSObject* JSLazyEventListener::function() const
+{
+ parseCode();
+ return m_listener;
+}
+
+static inline JSValuePtr eventParameterName(JSLazyEventListener::LazyEventListenerType type, ExecState* exec)
+{
+ switch (type) {
+ case JSLazyEventListener::HTMLLazyEventListener:
+ return jsNontrivialString(exec, "event");
+#if ENABLE(SVG)
+ case JSLazyEventListener::SVGLazyEventListener:
+ return jsNontrivialString(exec, "evt");
+#endif
+ }
+ ASSERT_NOT_REACHED();
+ return jsUndefined();
+}
+
+void JSLazyEventListener::parseCode() const
+{
+ if (m_parsed)
+ return;
+
+ if (m_globalObject->scriptExecutionContext()->isDocument()) {
+ JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject.get());
+ Frame* frame = window->impl()->frame();
+ if (!frame)
+ return;
+ // FIXME: Is this check needed for non-Document contexts?
+ ScriptController* script = frame->script();
+ if (!script->isEnabled() || script->isPaused())
+ return;
+ }
+
+ m_parsed = true;
+
+ ExecState* exec = m_globalObject->globalExec();
+
+ ArgList args;
+ UString sourceURL(m_globalObject->scriptExecutionContext()->url().string());
+ args.append(eventParameterName(m_type, exec));
+ args.append(jsString(exec, m_code));
+
+ // FIXME: Passing the document's URL to construct is not always correct, since this event listener might
+ // have been added with setAttribute from a script, and we should pass String() in that case.
+ m_listener = constructFunction(exec, args, Identifier(exec, m_functionName), sourceURL, m_lineNumber); // FIXME: is globalExec ok?
+
+ JSFunction* listenerAsFunction = static_cast<JSFunction*>(m_listener.get());
+
+ if (exec->hadException()) {
+ exec->clearException();
+
+ // failed to parse, so let's just make this listener a no-op
+ m_listener = 0;
+ } else if (m_originalNode) {
+ // Add the event's home element to the scope
+ // (and the document, and the form - see JSHTMLElement::eventHandlerScope)
+ ScopeChain scope = listenerAsFunction->scope();
+
+ JSValuePtr thisObj = toJS(exec, m_originalNode);
+ if (thisObj.isObject()) {
+ static_cast<JSNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope);
+ listenerAsFunction->setScope(scope);
+ }
+ }
+
+ // no more need to keep the unparsed code around
+ m_functionName = String();
+ m_code = String();
+
+ if (m_listener) {
+ ASSERT(isInline());
+ JSDOMWindow::ProtectedListenersMap& listeners = m_globalObject->jsProtectedInlineEventListeners();
+ listeners.set(m_listener, const_cast<JSLazyEventListener*>(this));
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSLazyEventListener.h b/WebCore/bindings/js/JSLazyEventListener.h
new file mode 100644
index 0000000..5424883
--- /dev/null
+++ b/WebCore/bindings/js/JSLazyEventListener.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 JSLazyEventListener_h
+#define JSLazyEventListener_h
+
+#include "JSEventListener.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+ class Node;
+
+ class JSLazyEventListener : public JSProtectedEventListener {
+ public:
+ enum LazyEventListenerType {
+ HTMLLazyEventListener
+#if ENABLE(SVG)
+ , SVGLazyEventListener
+#endif
+ };
+
+ static PassRefPtr<JSLazyEventListener> create(LazyEventListenerType type, const String& functionName, const String& code, JSDOMGlobalObject* globalObject, Node* node, int lineNumber)
+ {
+ return adoptRef(new JSLazyEventListener(type, functionName, code, globalObject, node, lineNumber));
+ }
+
+ private:
+ JSLazyEventListener(LazyEventListenerType, const String& functionName, const String& code, JSDOMGlobalObject*, Node*, int lineNumber);
+
+ virtual JSC::JSObject* function() const;
+ virtual bool wasCreatedFromMarkup() const { return true; }
+
+ void parseCode() const;
+
+ mutable String m_functionName;
+ mutable String m_code;
+ mutable bool m_parsed;
+ int m_lineNumber;
+ Node* m_originalNode;
+
+ LazyEventListenerType m_type;
+ };
+
+} // namespace WebCore
+
+#endif // JSEventListener_h
diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.cpp b/WebCore/bindings/js/JSMessageChannelConstructor.cpp
index 8da9f6d..f5b73df 100644
--- a/WebCore/bindings/js/JSMessageChannelConstructor.cpp
+++ b/WebCore/bindings/js/JSMessageChannelConstructor.cpp
@@ -44,17 +44,8 @@ const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstruct
JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext)
: DOMObject(JSMessageChannelConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
- , m_scriptExecutionContext(scriptExecutionContext)
+ , m_globalObject(toJSDOMGlobalObject(scriptExecutionContext))
{
- if (m_scriptExecutionContext->isDocument())
- m_contextWrapper = toJS(exec, static_cast<Document*>(scriptExecutionContext));
-#if ENABLE(WORKERS)
- else if (m_scriptExecutionContext->isWorkerContext())
- m_contextWrapper = toJSDOMGlobalObject(scriptExecutionContext);
-#endif
- else
- ASSERT_NOT_REACHED();
-
putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec), None);
}
@@ -62,6 +53,11 @@ JSMessageChannelConstructor::~JSMessageChannelConstructor()
{
}
+ScriptExecutionContext* JSMessageChannelConstructor::scriptExecutionContext() const
+{
+ return m_globalObject->scriptExecutionContext();
+}
+
ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& constructData)
{
constructData.native.function = construct;
@@ -76,8 +72,8 @@ JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* cons
void JSMessageChannelConstructor::mark()
{
DOMObject::mark();
- if (!m_contextWrapper.marked())
- m_contextWrapper.mark();
+ if (!m_globalObject->marked())
+ m_globalObject->mark();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.h b/WebCore/bindings/js/JSMessageChannelConstructor.h
index 614f6ae..2691777 100644
--- a/WebCore/bindings/js/JSMessageChannelConstructor.h
+++ b/WebCore/bindings/js/JSMessageChannelConstructor.h
@@ -37,7 +37,7 @@ namespace WebCore {
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
static const JSC::ClassInfo s_info;
- ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; }
+ ScriptExecutionContext* scriptExecutionContext() const;
virtual bool implementsHasInstance() const { return true; }
static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&);
@@ -46,8 +46,7 @@ namespace WebCore {
virtual void mark();
private:
- ScriptExecutionContext* m_scriptExecutionContext;
- JSC::JSValuePtr m_contextWrapper;
+ JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp
index d30b14c..394f9b1 100644
--- a/WebCore/bindings/js/JSMessagePortCustom.cpp
+++ b/WebCore/bindings/js/JSMessagePortCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,11 +42,8 @@ void JSMessagePort::mark()
{
DOMObject::mark();
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onmessage()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onclose()))
- listener->mark();
+ markIfNotNull(m_impl->onmessage());
+ markIfNotNull(m_impl->onclose());
if (MessagePort* entangledPort = m_impl->entangledPort()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort);
@@ -58,10 +55,8 @@ void JSMessagePort::mark()
typedef MessagePort::ListenerVector ListenerVector;
EventListenersMap& eventListeners = m_impl->eventListeners();
for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
- for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
- JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
- listener->mark();
- }
+ for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+ (*vecIter)->mark();
}
}
@@ -78,7 +73,7 @@ JSValuePtr JSMessagePort::addEventListener(ExecState* exec, const ArgList& args)
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- RefPtr<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1));
+ RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
@@ -90,7 +85,7 @@ JSValuePtr JSMessagePort::removeEventListener(ExecState* exec, const ArgList& ar
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1));
+ JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
diff --git a/WebCore/bindings/js/JSNamedNodesCollection.cpp b/WebCore/bindings/js/JSNamedNodesCollection.cpp
index 8a7ee0e..8068a1d 100644
--- a/WebCore/bindings/js/JSNamedNodesCollection.cpp
+++ b/WebCore/bindings/js/JSNamedNodesCollection.cpp
@@ -35,7 +35,7 @@ namespace WebCore {
using namespace JSC;
-ASSERT_CLASS_FITS_IN_CELL(JSNamedNodesCollection)
+ASSERT_CLASS_FITS_IN_CELL(JSNamedNodesCollection);
const ClassInfo JSNamedNodesCollection::s_info = { "Collection", 0, 0, 0 };
diff --git a/WebCore/bindings/js/JSNavigatorCustom.cpp b/WebCore/bindings/js/JSNavigatorCustom.cpp
index 2287426..a7b6194 100644
--- a/WebCore/bindings/js/JSNavigatorCustom.cpp
+++ b/WebCore/bindings/js/JSNavigatorCustom.cpp
@@ -76,10 +76,6 @@ static bool needsYouTubeQuirk(ExecState* exec, Frame* frame)
return false;
Document* document = frame->document();
- // FIXME: The document is never null, so we should remove this check along with the
- // other similar ones in this file when we are absolutely sure it's safe.
- if (!document)
- return false;
// Do the quirk only on the front page of the global version of YouTube.
const KURL& url = document->url();
diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp
index 2b4d6d4..8f4d2c1 100644
--- a/WebCore/bindings/js/JSNodeCustom.cpp
+++ b/WebCore/bindings/js/JSNodeCustom.cpp
@@ -43,6 +43,7 @@
#include "JSDocumentType.h"
#include "JSEntity.h"
#include "JSEntityReference.h"
+#include "JSEventListener.h"
#include "JSHTMLElement.h"
#include "JSHTMLElementWrapperFactory.h"
#include "JSNotation.h"
@@ -106,6 +107,34 @@ JSValuePtr JSNode::appendChild(ExecState* exec, const ArgList& args)
return jsNull();
}
+JSValuePtr JSNode::addEventListener(ExecState* exec, const ArgList& args)
+{
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
+ if (!globalObject)
+ return jsUndefined();
+
+ if (RefPtr<JSProtectedEventListener> listener = globalObject->findOrCreateJSProtectedEventListener(exec, args.at(exec, 1)))
+ impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
+
+ return jsUndefined();
+}
+
+JSValuePtr JSNode::removeEventListener(ExecState* exec, const ArgList& args)
+{
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
+ if (!globalObject)
+ return jsUndefined();
+
+ if (JSProtectedEventListener* listener = globalObject->findJSProtectedEventListener(args.at(exec, 1)))
+ impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
+
+ return jsUndefined();
+}
+
+void JSNode::pushEventHandlerScope(ExecState*, ScopeChain&) const
+{
+}
+
void JSNode::mark()
{
ASSERT(!marked());
diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp
index 1e4151b..f4b9e0c 100644
--- a/WebCore/bindings/js/JSNodeFilterCondition.cpp
+++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp
@@ -29,7 +29,7 @@ namespace WebCore {
using namespace JSC;
-ASSERT_CLASS_FITS_IN_CELL(JSNodeFilterCondition)
+ASSERT_CLASS_FITS_IN_CELL(JSNodeFilterCondition);
JSNodeFilterCondition::JSNodeFilterCondition(JSValuePtr filter)
: m_filter(filter)
diff --git a/WebCore/bindings/js/JSOptionConstructor.cpp b/WebCore/bindings/js/JSOptionConstructor.cpp
index 0030594..e1d5cfe 100644
--- a/WebCore/bindings/js/JSOptionConstructor.cpp
+++ b/WebCore/bindings/js/JSOptionConstructor.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "JSOptionConstructor.h"
+#include "HTMLNames.h"
#include "HTMLOptionElement.h"
#include "JSHTMLOptionElement.h"
#include "ScriptExecutionContext.h"
@@ -29,30 +30,34 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor)
+ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor);
const ClassInfo JSOptionConstructor::s_info = { "OptionConstructor", 0, 0, 0 };
JSOptionConstructor::JSOptionConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSOptionConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+ , m_globalObject(toJSDOMGlobalObject(context))
{
ASSERT(context->isDocument());
- m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
+ putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 4), ReadOnly|DontDelete|DontEnum);
}
+Document* JSOptionConstructor::document() const
+{
+ return static_cast<Document*>(m_globalObject->scriptExecutionContext());
+}
+
static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* constructor, const ArgList& args)
{
Document* document = static_cast<JSOptionConstructor*>(constructor)->document();
- ExceptionCode ec = 0;
+ RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(document->createElement(HTMLNames::optionTag, false));
- RefPtr<HTMLOptionElement> element = static_pointer_cast<HTMLOptionElement>(document->createElement("option", ec));
- RefPtr<Text> text;
- if (ec == 0)
- text = document->createTextNode("");
- if (ec == 0 && !args.at(exec, 0).isUndefined())
+ ExceptionCode ec = 0;
+ RefPtr<Text> text = document->createTextNode("");
+ if (!args.at(exec, 0).isUndefined())
text->setData(args.at(exec, 0).toString(exec), ec);
if (ec == 0)
element->appendChild(text.release(), ec);
@@ -80,8 +85,8 @@ ConstructType JSOptionConstructor::getConstructData(ConstructData& constructData
void JSOptionConstructor::mark()
{
DOMObject::mark();
- if (!m_document->marked())
- m_document->mark();
+ if (!m_globalObject->marked())
+ m_globalObject->mark();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSOptionConstructor.h b/WebCore/bindings/js/JSOptionConstructor.h
index 5234c49..60f6873 100644
--- a/WebCore/bindings/js/JSOptionConstructor.h
+++ b/WebCore/bindings/js/JSOptionConstructor.h
@@ -29,7 +29,7 @@ namespace WebCore {
class JSOptionConstructor : public DOMObject {
public:
JSOptionConstructor(JSC::ExecState*, ScriptExecutionContext*);
- Document* document() const { return m_document->impl(); }
+ Document* document() const;
static const JSC::ClassInfo s_info;
@@ -38,7 +38,7 @@ namespace WebCore {
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
- JSDocument* m_document;
+ JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSPluginElementFunctions.cpp b/WebCore/bindings/js/JSPluginElementFunctions.cpp
index 4003efb..eeaa394 100644
--- a/WebCore/bindings/js/JSPluginElementFunctions.cpp
+++ b/WebCore/bindings/js/JSPluginElementFunctions.cpp
@@ -20,13 +20,9 @@
#include "config.h"
#include "JSPluginElementFunctions.h"
-#include "Frame.h"
-#include "FrameLoader.h"
-#include "HTMLDocument.h"
#include "HTMLNames.h"
#include "HTMLPlugInElement.h"
#include "JSHTMLElement.h"
-#include "ScriptController.h"
#include "runtime.h"
#include "runtime_object.h"
diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
index b1b0c92..c3fc41f 100644
--- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
+++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
@@ -32,7 +32,7 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSQuarantinedObjectWrapper)
+ASSERT_CLASS_FITS_IN_CELL(JSQuarantinedObjectWrapper);
const ClassInfo JSQuarantinedObjectWrapper::s_info = { "JSQuarantinedObjectWrapper", 0, 0, 0 };
@@ -58,7 +58,7 @@ JSValuePtr JSQuarantinedObjectWrapper::cachedValueGetter(ExecState*, const Ident
JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, PassRefPtr<Structure> structure)
: JSObject(structure)
- , m_unwrappedGlobalObject(unwrappedExec->dynamicGlobalObject())
+ , m_unwrappedGlobalObject(unwrappedExec->lexicalGlobalObject())
, m_unwrappedObject(unwrappedObject)
{
ASSERT_ARG(unwrappedExec, unwrappedExec);
@@ -72,7 +72,7 @@ JSQuarantinedObjectWrapper::~JSQuarantinedObjectWrapper()
bool JSQuarantinedObjectWrapper::allowsUnwrappedAccessFrom(ExecState* exec) const
{
- return m_unwrappedGlobalObject->profileGroup() == exec->dynamicGlobalObject()->profileGroup();
+ return m_unwrappedGlobalObject->profileGroup() == exec->lexicalGlobalObject()->profileGroup();
}
ExecState* JSQuarantinedObjectWrapper::unwrappedExecState() const
@@ -87,8 +87,9 @@ void JSQuarantinedObjectWrapper::transferExceptionToExecState(ExecState* exec) c
if (!unwrappedExecState()->hadException())
return;
- exec->setException(wrapOutgoingValue(unwrappedExecState(), unwrappedExecState()->exception()));
+ JSValuePtr exception = unwrappedExecState()->exception();
unwrappedExecState()->clearException();
+ exec->setException(wrapOutgoingValue(unwrappedExecState(), exception));
}
void JSQuarantinedObjectWrapper::mark()
diff --git a/WebCore/bindings/js/JSRGBColor.cpp b/WebCore/bindings/js/JSRGBColor.cpp
index 91fe4b3..90f8037 100644
--- a/WebCore/bindings/js/JSRGBColor.cpp
+++ b/WebCore/bindings/js/JSRGBColor.cpp
@@ -44,7 +44,7 @@ static JSValuePtr jsRGBColorBlue(ExecState*, const Identifier&, const PropertySl
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSRGBColor)
+ASSERT_CLASS_FITS_IN_CELL(JSRGBColor);
const ClassInfo JSRGBColor::s_info = { "RGBColor", 0, &JSRGBColorTable, 0 };
diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
index 6309f4a..56ceb7c 100644
--- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
+++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
@@ -42,7 +42,7 @@ JSValuePtr JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList
if (!globalObject)
return jsUndefined();
- if (RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1)))
+ if (RefPtr<JSProtectedEventListener> listener = globalObject->findOrCreateJSProtectedEventListener(exec, args.at(exec, 1)))
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
return jsUndefined();
@@ -54,7 +54,7 @@ JSValuePtr JSSVGElementInstance::removeEventListener(ExecState* exec, const ArgL
if (!globalObject)
return jsUndefined();
- if (JSEventListener* listener = globalObject->findJSEventListener(args.at(exec, 1)))
+ if (JSProtectedEventListener* listener = globalObject->findJSProtectedEventListener(args.at(exec, 1)))
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
return jsUndefined();
diff --git a/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/WebCore/bindings/js/JSSVGPODTypeWrapper.h
index c30f97f..51e4e9e 100644
--- a/WebCore/bindings/js/JSSVGPODTypeWrapper.h
+++ b/WebCore/bindings/js/JSSVGPODTypeWrapper.h
@@ -28,7 +28,6 @@
#define JSSVGPODTypeWrapper_h
#if ENABLE(SVG)
-#include "Frame.h"
#include "SVGElement.h"
#include <wtf/StdLibExtras.h>
diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp
index 04dabf0..2cadcb4 100644
--- a/WebCore/bindings/js/JSStyleSheetCustom.cpp
+++ b/WebCore/bindings/js/JSStyleSheetCustom.cpp
@@ -27,6 +27,7 @@
#include "JSStyleSheet.h"
#include "CSSStyleSheet.h"
+#include "Node.h"
#include "JSCSSStyleSheet.h"
#include "JSNode.h"
diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
index ba864ea..3b97eb1 100644
--- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
+++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
@@ -35,10 +35,10 @@ namespace WebCore {
const ClassInfo JSWebKitCSSMatrixConstructor::s_info = { "WebKitCSSMatrixConstructor", 0, 0, 0 };
-JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec, ScriptExecutionContext* context)
+JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec)
: DOMObject(JSWebKitCSSMatrixConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
{
- ASSERT_UNUSED(context, context->isDocument());
+ putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h
index b280241..d0e0bd1 100644
--- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h
+++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h
@@ -33,7 +33,7 @@ namespace WebCore {
class JSWebKitCSSMatrixConstructor : public DOMObject {
public:
- JSWebKitCSSMatrixConstructor(JSC::ExecState*, ScriptExecutionContext*);
+ JSWebKitCSSMatrixConstructor(JSC::ExecState*);
static const JSC::ClassInfo s_info;
private:
diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.cpp b/WebCore/bindings/js/JSWebKitPointConstructor.cpp
new file mode 100644
index 0000000..c3a8ea6
--- /dev/null
+++ b/WebCore/bindings/js/JSWebKitPointConstructor.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSWebKitPointConstructor.h"
+
+#include "Document.h"
+#include "WebKitPoint.h"
+#include "JSWebKitPoint.h"
+
+namespace WebCore {
+
+using namespace JSC;
+
+const ClassInfo JSWebKitPointConstructor::s_info = { "WebKitPointConstructor", 0, 0, 0 };
+
+JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec)
+ : DOMObject(JSWebKitPointConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+{
+ putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec), None);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum);
+}
+
+static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList& args)
+{
+ float x = 0;
+ float y = 0;
+ if (args.size() >= 2) {
+ x = (float)args.at(exec, 0).toNumber(exec);
+ y = (float)args.at(exec, 1).toNumber(exec);
+ if (isnan(x))
+ x = 0;
+ if (isnan(y))
+ y = 0;
+ }
+ return asObject(toJS(exec, WebKitPoint::create(x, y)));
+}
+
+JSC::ConstructType JSWebKitPointConstructor::getConstructData(JSC::ConstructData& constructData)
+{
+ constructData.native.function = constructWebKitPoint;
+ return ConstructTypeHost;
+}
+
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.h b/WebCore/bindings/js/JSWebKitPointConstructor.h
new file mode 100644
index 0000000..a5bb5c1
--- /dev/null
+++ b/WebCore/bindings/js/JSWebKitPointConstructor.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSWebKitPointConstructor_h
+#define JSWebKitPointConstructor_h
+
+#include "JSDOMBinding.h"
+#include "JSDocument.h"
+
+namespace WebCore {
+
+class JSWebKitPointConstructor : public DOMObject {
+public:
+ JSWebKitPointConstructor(JSC::ExecState*);
+ static const JSC::ClassInfo s_info;
+
+private:
+ virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
+ virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
+};
+
+}
+
+#endif // JSWebKitPointConstructor_h
diff --git a/WebCore/bindings/js/JSWorkerConstructor.cpp b/WebCore/bindings/js/JSWorkerConstructor.cpp
index 52147a2..a9f2f74 100644
--- a/WebCore/bindings/js/JSWorkerConstructor.cpp
+++ b/WebCore/bindings/js/JSWorkerConstructor.cpp
@@ -44,6 +44,7 @@ const ClassInfo JSWorkerConstructor::s_info = { "WorkerConstructor", 0, 0, 0 };
JSWorkerConstructor::JSWorkerConstructor(ExecState* exec)
: DOMObject(JSWorkerConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
{
+ putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
diff --git a/WebCore/bindings/js/JSWorkerContextBase.cpp b/WebCore/bindings/js/JSWorkerContextBase.cpp
index 24dd50f..c948b85 100644
--- a/WebCore/bindings/js/JSWorkerContextBase.cpp
+++ b/WebCore/bindings/js/JSWorkerContextBase.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -38,6 +39,7 @@
#include "JSMessagePort.h"
#include "JSWorkerLocation.h"
#include "JSWorkerNavigator.h"
+#include "JSXMLHttpRequestConstructor.h"
#include "WorkerContext.h"
#include "WorkerLocation.h"
@@ -45,14 +47,19 @@ using namespace JSC;
/*
@begin JSWorkerContextBaseTable
+# -- Constructors --
+ XMLHttpRequest jsWorkerContextBaseXMLHttpRequest DontDelete
@end
*/
+static JSValuePtr jsWorkerContextBaseXMLHttpRequest(ExecState*, const Identifier&, const PropertySlot&);
+static void setJSWorkerContextBaseXMLHttpRequest(ExecState*, JSObject*, JSValuePtr);
+
#include "JSWorkerContextBase.lut.h"
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase)
+ASSERT_CLASS_FITS_IN_CELL(JSWorkerContextBase);
JSWorkerContextBase::JSWorkerContextBase(PassRefPtr<JSC::Structure> structure, PassRefPtr<WorkerContext> impl)
: JSDOMGlobalObject(structure, new JSDOMGlobalObjectData, this)
@@ -81,6 +88,33 @@ void JSWorkerContextBase::put(ExecState* exec, const Identifier& propertyName, J
lookupPut<JSWorkerContextBase, Base>(exec, propertyName, value, getJSWorkerContextBaseTable(exec), this, slot);
}
+bool JSWorkerContextBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ const HashEntry* entry = getJSWorkerContextBaseTable(exec)->entry(exec, propertyName);
+ if (entry) {
+ if (entry->attributes() & Function)
+ setUpStaticFunctionSlot(exec, entry, this, propertyName, slot);
+ else
+ slot.setCustom(this, entry->propertyGetter());
+ return true;
+ }
+
+ return Base::getOwnPropertySlot(exec, propertyName, slot);
+}
+
} // namespace WebCore
+using namespace WebCore;
+
+JSValuePtr jsWorkerContextBaseXMLHttpRequest(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+ return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, static_cast<JSWorkerContextBase*>(asObject(slot.slotBase())));
+}
+
+void setJSWorkerContextBaseXMLHttpRequest(ExecState* exec, JSObject* thisObject, JSValuePtr value)
+{
+ // Shadowing a built-in constructor
+ static_cast<JSWorkerContextBase*>(thisObject)->putDirect(Identifier(exec, "XMLHttpRequest"), value);
+}
+
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSWorkerContextBase.h b/WebCore/bindings/js/JSWorkerContextBase.h
index d2d5bd2..5dc1921 100644
--- a/WebCore/bindings/js/JSWorkerContextBase.h
+++ b/WebCore/bindings/js/JSWorkerContextBase.h
@@ -48,6 +48,8 @@ namespace WebCore {
WorkerContext* impl() const { return m_impl.get(); }
virtual ScriptExecutionContext* scriptExecutionContext() const;
+ bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);
+
private:
RefPtr<WorkerContext> m_impl;
};
diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp
index 3a6dca0..a28cb75 100644
--- a/WebCore/bindings/js/JSWorkerContextCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,7 +31,9 @@
#include "JSDOMBinding.h"
#include "JSEventListener.h"
+#include "ScheduledAction.h"
#include "WorkerContext.h"
+#include <interpreter/Interpreter.h>
using namespace JSC;
@@ -51,17 +53,14 @@ void JSWorkerContext::mark()
markActiveObjectsForContext(*globalData(), scriptExecutionContext());
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(impl()->onmessage()))
- listener->mark();
+ markIfNotNull(impl()->onmessage());
typedef WorkerContext::EventListenersMap EventListenersMap;
typedef WorkerContext::ListenerVector ListenerVector;
EventListenersMap& eventListeners = impl()->eventListeners();
for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
- for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
- JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
- listener->mark();
- }
+ for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+ (*vecIter)->mark();
}
}
@@ -75,9 +74,32 @@ void JSWorkerContext::setSelf(ExecState* exec, JSValuePtr value)
putDirect(Identifier(exec, "self"), value);
}
+JSValuePtr JSWorkerContext::importScripts(ExecState* exec, const ArgList& args)
+{
+ if (!args.size())
+ return jsUndefined();
+
+ Vector<String> urls;
+ for (unsigned i = 0; i < args.size(); i++) {
+ urls.append(args.at(exec, i).toString(exec));
+ if (exec->hadException())
+ return jsUndefined();
+ }
+ ExceptionCode ec = 0;
+ int signedLineNumber;
+ intptr_t sourceID;
+ UString sourceURL;
+ JSValuePtr function;
+ exec->interpreter()->retrieveLastCaller(exec, signedLineNumber, sourceID, sourceURL, function);
+
+ impl()->importScripts(urls, sourceURL, signedLineNumber >= 0 ? signedLineNumber : 0, ec);
+ setDOMException(exec, ec);
+ return jsUndefined();
+}
+
JSValuePtr JSWorkerContext::addEventListener(ExecState* exec, const ArgList& args)
{
- RefPtr<JSUnprotectedEventListener> listener = findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1));
+ RefPtr<JSEventListener> listener = findOrCreateJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
@@ -86,13 +108,49 @@ JSValuePtr JSWorkerContext::addEventListener(ExecState* exec, const ArgList& arg
JSValuePtr JSWorkerContext::removeEventListener(ExecState* exec, const ArgList& args)
{
- JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(exec, args.at(exec, 1));
+ JSEventListener* listener = findJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
return jsUndefined();
}
+static JSValuePtr setTimeoutOrInterval(ExecState* exec, WorkerContext* workerContext, const ArgList& args, bool singleShot)
+{
+ JSValuePtr v = args.at(exec, 0);
+ int delay = args.at(exec, 1).toInt32(exec);
+ if (v.isString())
+ return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(asString(v)->value()), delay, singleShot));
+ CallData callData;
+ if (v.getCallData(callData) == CallTypeNone)
+ return jsUndefined();
+ ArgList argsTail;
+ args.getSlice(2, argsTail);
+ return jsNumber(exec, workerContext->installTimeout(new ScheduledAction(exec, v, argsTail), delay, singleShot));
+}
+
+JSValuePtr JSWorkerContext::setTimeout(ExecState* exec, const ArgList& args)
+{
+ return setTimeoutOrInterval(exec, impl(), args, true);
+}
+
+JSValuePtr JSWorkerContext::clearTimeout(ExecState* exec, const ArgList& args)
+{
+ impl()->removeTimeout(args.at(exec, 0).toInt32(exec));
+ return jsUndefined();
+}
+
+JSValuePtr JSWorkerContext::setInterval(ExecState* exec, const ArgList& args)
+{
+ return setTimeoutOrInterval(exec, impl(), args, false);
+}
+
+JSValuePtr JSWorkerContext::clearInterval(ExecState* exec, const ArgList& args)
+{
+ impl()->removeTimeout(args.at(exec, 0).toInt32(exec));
+ return jsUndefined();
+}
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSWorkerCustom.cpp b/WebCore/bindings/js/JSWorkerCustom.cpp
index 2ede0da..12103d3 100644
--- a/WebCore/bindings/js/JSWorkerCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,20 +41,15 @@ void JSWorker::mark()
{
DOMObject::mark();
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onmessage()))
- listener->mark();
-
- if (JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror()))
- listener->mark();
+ markIfNotNull(m_impl->onmessage());
+ markIfNotNull(m_impl->onerror());
typedef Worker::EventListenersMap EventListenersMap;
typedef Worker::ListenerVector ListenerVector;
EventListenersMap& eventListeners = m_impl->eventListeners();
for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
- for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
- JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
- listener->mark();
- }
+ for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+ (*vecIter)->mark();
}
}
@@ -63,7 +58,7 @@ JSValuePtr JSWorker::addEventListener(ExecState* exec, const ArgList& args)
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- RefPtr<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1));
+ RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
@@ -75,7 +70,7 @@ JSValuePtr JSWorker::removeEventListener(ExecState* exec, const ArgList& args)
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1));
+ JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
index d7f54de..a7f8ab0 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
@@ -28,22 +28,25 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor)
+ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor);
const ClassInfo JSXMLHttpRequestConstructor::s_info = { "XMLHttpRequestConstructor", 0, 0, 0 };
-JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, ScriptExecutionContext* context)
+JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext)
: DOMObject(JSXMLHttpRequestConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+ , m_globalObject(toJSDOMGlobalObject(scriptExecutionContext))
{
- ASSERT(context->isDocument());
- m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
-
putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec), None);
}
+ScriptExecutionContext* JSXMLHttpRequestConstructor::scriptExecutionContext() const
+{
+ return m_globalObject->scriptExecutionContext();
+}
+
static JSObject* constructXMLHttpRequest(ExecState* exec, JSObject* constructor, const ArgList&)
{
- RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(static_cast<JSXMLHttpRequestConstructor*>(constructor)->document());
+ RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(static_cast<JSXMLHttpRequestConstructor*>(constructor)->scriptExecutionContext());
return CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequest, xmlHttpRequest.get());
}
@@ -56,8 +59,8 @@ ConstructType JSXMLHttpRequestConstructor::getConstructData(ConstructData& const
void JSXMLHttpRequestConstructor::mark()
{
DOMObject::mark();
- if (!m_document->marked())
- m_document->mark();
+ if (!m_globalObject->marked())
+ m_globalObject->mark();
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h
index f235af6..01d1f85 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h
+++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h
@@ -21,14 +21,13 @@
#define JSXMLHttpRequestConstructor_h
#include "JSDOMBinding.h"
-#include "JSDocument.h"
namespace WebCore {
class JSXMLHttpRequestConstructor : public DOMObject {
public:
JSXMLHttpRequestConstructor(JSC::ExecState*, ScriptExecutionContext*);
- Document* document() const { return m_document->impl(); }
+ ScriptExecutionContext* scriptExecutionContext() const;
static const JSC::ClassInfo s_info;
virtual void mark();
@@ -36,7 +35,7 @@ private:
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
- JSDocument* m_document;
+ JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
index 5122ba3..a7f78b7 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -59,32 +59,19 @@ void JSXMLHttpRequest::mark()
wrapper->mark();
}
- if (JSUnprotectedEventListener* onReadyStateChangeListener = static_cast<JSUnprotectedEventListener*>(m_impl->onreadystatechange()))
- onReadyStateChangeListener->mark();
-
- if (JSUnprotectedEventListener* onAbortListener = static_cast<JSUnprotectedEventListener*>(m_impl->onabort()))
- onAbortListener->mark();
-
- if (JSUnprotectedEventListener* onErrorListener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror()))
- onErrorListener->mark();
-
- if (JSUnprotectedEventListener* onLoadListener = static_cast<JSUnprotectedEventListener*>(m_impl->onload()))
- onLoadListener->mark();
-
- if (JSUnprotectedEventListener* onLoadStartListener = static_cast<JSUnprotectedEventListener*>(m_impl->onloadstart()))
- onLoadStartListener->mark();
-
- if (JSUnprotectedEventListener* onProgressListener = static_cast<JSUnprotectedEventListener*>(m_impl->onprogress()))
- onProgressListener->mark();
+ markIfNotNull(m_impl->onreadystatechange());
+ markIfNotNull(m_impl->onabort());
+ markIfNotNull(m_impl->onerror());
+ markIfNotNull(m_impl->onload());
+ markIfNotNull(m_impl->onloadstart());
+ markIfNotNull(m_impl->onprogress());
typedef XMLHttpRequest::EventListenersMap EventListenersMap;
typedef XMLHttpRequest::ListenerVector ListenerVector;
EventListenersMap& eventListeners = m_impl->eventListeners();
for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
- for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
- JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
- listener->mark();
- }
+ for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+ (*vecIter)->mark();
}
}
@@ -181,7 +168,7 @@ JSValuePtr JSXMLHttpRequest::addEventListener(ExecState* exec, const ArgList& ar
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- RefPtr<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1));
+ RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
@@ -193,7 +180,7 @@ JSValuePtr JSXMLHttpRequest::removeEventListener(ExecState* exec, const ArgList&
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1));
+ JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
index f456c87..26342e0 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,29 +51,18 @@ void JSXMLHttpRequestUpload::mark()
wrapper->mark();
}
- if (JSUnprotectedEventListener* onAbortListener = static_cast<JSUnprotectedEventListener*>(m_impl->onabort()))
- onAbortListener->mark();
-
- if (JSUnprotectedEventListener* onErrorListener = static_cast<JSUnprotectedEventListener*>(m_impl->onerror()))
- onErrorListener->mark();
-
- if (JSUnprotectedEventListener* onLoadListener = static_cast<JSUnprotectedEventListener*>(m_impl->onload()))
- onLoadListener->mark();
-
- if (JSUnprotectedEventListener* onLoadStartListener = static_cast<JSUnprotectedEventListener*>(m_impl->onloadstart()))
- onLoadStartListener->mark();
-
- if (JSUnprotectedEventListener* onProgressListener = static_cast<JSUnprotectedEventListener*>(m_impl->onprogress()))
- onProgressListener->mark();
+ markIfNotNull(m_impl->onabort());
+ markIfNotNull(m_impl->onerror());
+ markIfNotNull(m_impl->onload());
+ markIfNotNull(m_impl->onloadstart());
+ markIfNotNull(m_impl->onprogress());
typedef XMLHttpRequestUpload::EventListenersMap EventListenersMap;
typedef XMLHttpRequestUpload::ListenerVector ListenerVector;
EventListenersMap& eventListeners = m_impl->eventListeners();
for (EventListenersMap::iterator mapIter = eventListeners.begin(); mapIter != eventListeners.end(); ++mapIter) {
- for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter) {
- JSUnprotectedEventListener* listener = static_cast<JSUnprotectedEventListener*>(vecIter->get());
- listener->mark();
- }
+ for (ListenerVector::iterator vecIter = mapIter->second.begin(); vecIter != mapIter->second.end(); ++vecIter)
+ (*vecIter)->mark();
}
}
@@ -82,7 +71,7 @@ JSValuePtr JSXMLHttpRequestUpload::addEventListener(ExecState* exec, const ArgLi
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- RefPtr<JSUnprotectedEventListener> listener = globalObject->findOrCreateJSUnprotectedEventListener(exec, args.at(exec, 1));
+ RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->addEventListener(args.at(exec, 0).toString(exec), listener.release(), args.at(exec, 2).toBoolean(exec));
@@ -94,7 +83,7 @@ JSValuePtr JSXMLHttpRequestUpload::removeEventListener(ExecState* exec, const Ar
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
if (!globalObject)
return jsUndefined();
- JSUnprotectedEventListener* listener = globalObject->findJSUnprotectedEventListener(exec, args.at(exec, 1));
+ JSEventListener* listener = globalObject->findJSEventListener(exec, args.at(exec, 1));
if (!listener)
return jsUndefined();
impl()->removeEventListener(args.at(exec, 0).toString(exec), listener, args.at(exec, 2).toBoolean(exec));
diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
index ed456e1..448c832 100644
--- a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
+++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
@@ -37,7 +37,7 @@ using namespace JSC;
namespace WebCore {
-ASSERT_CLASS_FITS_IN_CELL(JSXSLTProcessorConstructor)
+ASSERT_CLASS_FITS_IN_CELL(JSXSLTProcessorConstructor);
const ClassInfo JSXSLTProcessorConstructor::s_info = { "XSLTProcessorConsructor", 0, 0, 0 };
diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp
index 8627474..986a96e 100644
--- a/WebCore/bindings/js/ScheduledAction.cpp
+++ b/WebCore/bindings/js/ScheduledAction.cpp
@@ -88,9 +88,9 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV
for (size_t i = 0; i < size; ++i)
args.append(m_args[i]);
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
call(exec, m_function, callType, callData, thisValue, args);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
if (exec->hadException())
reportCurrentException(exec);
@@ -136,8 +136,7 @@ void ScheduledAction::execute(Document* document)
// FIXME: Is this really the right point to do the update? We need a place that works
// for all possible entry points that might possibly execute script, but this seems
// to be a bit too low-level.
- if (Document* document = frame->document())
- document->updateRendering();
+ frame->document()->updateRendering();
frame->script()->setProcessingTimerCallback(false);
}
diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp
index efd3a70..fbca680 100644
--- a/WebCore/bindings/js/ScriptController.cpp
+++ b/WebCore/bindings/js/ScriptController.cpp
@@ -21,34 +21,24 @@
#include "config.h"
#include "ScriptController.h"
-#include "Console.h"
-#include "DOMWindow.h"
-#include "Document.h"
#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
-#include "FrameLoader.h"
#include "GCController.h"
-#include "JSDOMWindow.h"
+#include "HTMLPlugInElement.h"
#include "JSDocument.h"
-#include "JSEventListener.h"
-#include "npruntime_impl.h"
+#include "JSLazyEventListener.h"
#include "NP_jsobject.h"
#include "Page.h"
#include "PageGroup.h"
-#include "runtime_root.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "Settings.h"
-
-#include <runtime/Completion.h>
+#include "npruntime_impl.h"
+#include "runtime_root.h"
#include <debugger/Debugger.h>
#include <runtime/JSLock.h>
-#if ENABLE(NETSCAPE_PLUGIN_API)
-#include "HTMLPlugInElement.h"
-#endif
-
using namespace JSC;
namespace WebCore {
@@ -110,16 +100,16 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
// so we start the keep alive timer here.
m_frame->keepAlive();
- m_windowShell->window()->startTimeoutCheck();
+ m_windowShell->window()->globalData()->timeoutChecker.start();
Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), jsSourceCode, m_windowShell);
- m_windowShell->window()->stopTimeoutCheck();
+ m_windowShell->window()->globalData()->timeoutChecker.stop();
if (comp.complType() == Normal || comp.complType() == ReturnValue) {
m_sourceURL = savedSourceURL;
return comp.value();
}
- if (comp.complType() == Throw)
+ if (comp.complType() == Throw || comp.complType() == Interrupted)
reportException(exec, comp.value());
m_sourceURL = savedSourceURL;
@@ -152,12 +142,14 @@ PassRefPtr<EventListener> ScriptController::createInlineEventListener(const Stri
}
#if ENABLE(SVG)
+
PassRefPtr<EventListener> ScriptController::createSVGEventHandler(const String& functionName, const String& code, Node* node)
{
initScriptIfNeeded();
JSLock lock(false);
return JSLazyEventListener::create(JSLazyEventListener::SVGLazyEventListener, functionName, code, m_windowShell->window(), node, m_handlerLineno);
}
+
#endif
void ScriptController::initScript()
@@ -300,6 +292,7 @@ PassRefPtr<Bindings::RootObject> ScriptController::createRootObject(void* native
}
#if ENABLE(NETSCAPE_PLUGIN_API)
+
NPObject* ScriptController::windowScriptNPObject()
{
if (!m_windowScriptNPObject) {
@@ -323,23 +316,34 @@ NPObject* ScriptController::windowScriptNPObject()
NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement* plugin)
{
- // Can't create NPObjects when JavaScript is disabled
- if (!isEnabled())
+ JSObject* object = jsObjectForPluginElement(plugin);
+ if (!object)
return _NPN_CreateNoScriptObject();
+ // Wrap the JSObject in an NPObject
+ return _NPN_CreateScriptObject(0, object, bindingRootObject());
+}
+
+#endif
+
+JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin)
+{
+ // Can't create JSObjects when JavaScript is disabled
+ if (!isEnabled())
+ return 0;
+
// Create a JSObject bound to this element
JSLock lock(false);
ExecState* exec = globalObject()->globalExec();
JSValuePtr jsElementValue = toJS(exec, plugin);
if (!jsElementValue || !jsElementValue.isObject())
- return _NPN_CreateNoScriptObject();
-
- // Wrap the JSObject in an NPObject
- return _NPN_CreateScriptObject(0, jsElementValue.getObject(), bindingRootObject());
+ return 0;
+
+ return jsElementValue.getObject();
}
-#endif
#if !PLATFORM(MAC)
+
void ScriptController::updatePlatformScriptObjects()
{
}
@@ -347,6 +351,7 @@ void ScriptController::updatePlatformScriptObjects()
void ScriptController::disconnectPlatformScriptObjects()
{
}
+
#endif
void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h
index 28fd7e9..6f1781e 100644
--- a/WebCore/bindings/js/ScriptController.h
+++ b/WebCore/bindings/js/ScriptController.h
@@ -127,6 +127,8 @@ public:
WebScriptObject* windowScriptObject();
#endif
+ JSC::JSObject* jsObjectForPluginElement(HTMLPlugInElement*);
+
#if ENABLE(NETSCAPE_PLUGIN_API)
NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*);
NPObject* windowScriptNPObject();
diff --git a/WebCore/bindings/js/ScriptControllerMac.mm b/WebCore/bindings/js/ScriptControllerMac.mm
index 17ad0b2..6554e11 100644
--- a/WebCore/bindings/js/ScriptControllerMac.mm
+++ b/WebCore/bindings/js/ScriptControllerMac.mm
@@ -157,11 +157,7 @@ static void updateRenderingForBindings(JSC::ExecState*, JSC::JSObject* rootObjec
if (!frame)
return;
- Document* document = frame->document();
- if (!document)
- return;
-
- document->updateRendering();
+ frame->document()->updateRendering();
}
void ScriptController::initJavaJSBindings()
diff --git a/WebCore/bindings/js/ScriptControllerQt.cpp b/WebCore/bindings/js/ScriptControllerQt.cpp
index 8e9dfad..6b14190 100644
--- a/WebCore/bindings/js/ScriptControllerQt.cpp
+++ b/WebCore/bindings/js/ScriptControllerQt.cpp
@@ -50,15 +50,13 @@ PassRefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWid
{
if (widget->isPluginView()) {
PluginView* pluginView = static_cast<PluginView*>(widget);
- if (pluginView->isNPAPIPlugin())
- return pluginView->bindingInstance();
- return 0;
+ return pluginView->bindingInstance();
}
QWidget* platformWidget = widget->platformWidget();
if (!platformWidget)
return 0;
- return JSC::Bindings::QtInstance::getQtInstance(platformWidget, bindingRootObject());
+ return JSC::Bindings::QtInstance::getQtInstance(platformWidget, bindingRootObject(), QScriptEngine::QtOwnership);
}
}
diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp
new file mode 100644
index 0000000..5d928c1
--- /dev/null
+++ b/WebCore/bindings/js/ScriptFunctionCall.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptFunctionCall.h"
+
+#include "JSDOMBinding.h"
+#include "ScriptString.h"
+#include "ScriptValue.h"
+#include <runtime/JSLock.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+ScriptFunctionCall::ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const char* name)
+ : m_exec(exec)
+ , m_thisObject(thisObject)
+ , m_name(name)
+{
+}
+
+void ScriptFunctionCall::appendArgument(const ScriptObject& argument)
+{
+ m_arguments.append(argument.jsObject());
+}
+
+void ScriptFunctionCall::appendArgument(const ScriptString& argument)
+{
+ m_arguments.append(jsString(m_exec, argument));
+}
+
+void ScriptFunctionCall::appendArgument(const ScriptValue& argument)
+{
+ m_arguments.append(argument.jsValue());
+}
+
+void ScriptFunctionCall::appendArgument(const String& argument)
+{
+ JSLock lock(false);
+ m_arguments.append(jsString(m_exec, argument));
+}
+
+void ScriptFunctionCall::appendArgument(unsigned int argument)
+{
+ JSLock lock(false);
+ m_arguments.append(jsNumber(m_exec, argument));
+}
+
+void ScriptFunctionCall::appendArgument(bool argument)
+{
+ m_arguments.append(jsBoolean(argument));
+}
+
+ScriptValue ScriptFunctionCall::call(bool& hadException)
+{
+ JSObject* thisObject = m_thisObject.jsObject();
+
+ JSLock lock(false);
+
+ JSValuePtr function = thisObject->get(m_exec, Identifier(m_exec, m_name));
+ if (m_exec->hadException()) {
+ reportException(m_exec, m_exec->exception());
+ hadException = true;
+ return ScriptValue();
+ }
+
+ CallData callData;
+ CallType callType = function.getCallData(callData);
+ if (callType == CallTypeNone)
+ return ScriptValue();
+
+ JSValuePtr result = JSC::call(m_exec, function, callType, callData, thisObject, m_arguments);
+ if (m_exec->hadException()) {
+ reportException(m_exec, m_exec->exception());
+ hadException = true;
+ return ScriptValue();
+ }
+
+ return ScriptValue(result);
+}
+
+ScriptObject ScriptFunctionCall::construct(bool& hadException)
+{
+ JSObject* thisObject = m_thisObject.jsObject();
+
+ JSLock lock(false);
+
+ JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, m_name)));
+ if (m_exec->hadException()) {
+ reportException(m_exec, m_exec->exception());
+ hadException = true;
+ return ScriptObject();
+ }
+
+ ConstructData constructData;
+ ConstructType constructType = constructor->getConstructData(constructData);
+ if (constructType == ConstructTypeNone)
+ return ScriptObject();
+
+ JSValuePtr result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments);
+ if (m_exec->hadException()) {
+ reportException(m_exec, m_exec->exception());
+ hadException = true;
+ return ScriptObject();
+ }
+
+ return ScriptObject(asObject(result));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptFunctionCall.h b/WebCore/bindings/js/ScriptFunctionCall.h
new file mode 100644
index 0000000..0b01717
--- /dev/null
+++ b/WebCore/bindings/js/ScriptFunctionCall.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptFunctionCall_h
+#define ScriptFunctionCall_h
+
+#include "PlatformString.h"
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <runtime/ArgList.h>
+
+namespace WebCore {
+ class ScriptValue;
+ class ScriptString;
+
+ class ScriptFunctionCall {
+ public:
+ ScriptFunctionCall(ScriptState* exec, const ScriptObject& thisObject, const char* name);
+ virtual ~ScriptFunctionCall() {};
+
+ void appendArgument(const ScriptObject&);
+ void appendArgument(const ScriptString&);
+ void appendArgument(const ScriptValue&);
+ void appendArgument(const String&);
+ void appendArgument(unsigned int);
+ void appendArgument(bool);
+ ScriptValue call(bool& hadException);
+ ScriptObject construct(bool& hadException);
+
+ protected:
+ ScriptState* m_exec;
+ ScriptObject m_thisObject;
+ String m_name;
+ JSC::ArgList m_arguments;
+ bool m_quarantineObjects;
+ };
+
+} // namespace WebCore
+
+#endif // ScriptFunctionCall
diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp
new file mode 100644
index 0000000..148dac5
--- /dev/null
+++ b/WebCore/bindings/js/ScriptObject.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptObject.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+ScriptObject::ScriptObject(JSObject* object)
+ : ScriptValue(object)
+{
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptObject.h b/WebCore/bindings/js/ScriptObject.h
new file mode 100644
index 0000000..08fa323
--- /dev/null
+++ b/WebCore/bindings/js/ScriptObject.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptObject_h
+#define ScriptObject_h
+
+#include "ScriptValue.h"
+
+#include <runtime/JSObject.h>
+#include <runtime/Protect.h>
+
+namespace WebCore {
+
+ class ScriptObject : public ScriptValue {
+ public:
+ ScriptObject(JSC::JSObject*);
+ ScriptObject() {}
+ JSC::JSObject* jsObject() const { return asObject(jsValue()); }
+ };
+
+}
+
+#endif // ScriptObject_h
diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/WebCore/bindings/js/ScriptObjectQuarantine.cpp
new file mode 100644
index 0000000..9311737
--- /dev/null
+++ b/WebCore/bindings/js/ScriptObjectQuarantine.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptObjectQuarantine.h"
+
+#include "Database.h"
+#include "Document.h"
+#include "Frame.h"
+#include "JSDatabase.h"
+#include "JSStorage.h"
+#include "JSDOMBinding.h"
+#include "JSInspectedObjectWrapper.h"
+#include "ScriptObject.h"
+#include "ScriptValue.h"
+
+#include <runtime/JSLock.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value)
+{
+ JSLock lock(false);
+ return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue()));
+}
+
+bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject)
+{
+ ASSERT(database);
+
+ Frame* frame = database->document()->frame();
+ if (!frame)
+ return false;
+
+ ExecState* exec = toJSDOMWindow(frame)->globalExec();
+
+ JSLock lock(false);
+ quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, database))));
+
+ return true;
+}
+
+bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject)
+{
+ ASSERT(frame);
+ ASSERT(storage);
+
+ ExecState* exec = toJSDOMWindow(frame)->globalExec();
+
+ JSLock lock(false);
+ quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, storage))));
+
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.h b/WebCore/bindings/js/ScriptObjectQuarantine.h
new file mode 100644
index 0000000..a3ac7f1
--- /dev/null
+++ b/WebCore/bindings/js/ScriptObjectQuarantine.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptObjectQuarantine_h
+#define ScriptObjectQuarantine_h
+
+#include "ScriptState.h"
+
+namespace WebCore {
+
+ class Database;
+ class Frame;
+ class ScriptObject;
+ class ScriptValue;
+ class Storage;
+
+ ScriptValue quarantineValue(ScriptState*, const ScriptValue&);
+
+ bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject);
+ bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject);
+
+}
+
+#endif // ScriptObjectQuarantine_h
diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp
index 37e3f67..c4a7579 100644
--- a/WebCore/bindings/js/ScriptValue.cpp
+++ b/WebCore/bindings/js/ScriptValue.cpp
@@ -29,7 +29,9 @@
#include "config.h"
#include "ScriptValue.h"
-#include "PlatformString.h"
+#include <JavaScriptCore/APICast.h>
+#include <JavaScriptCore/JSValueRef.h>
+
#include <runtime/JSLock.h>
#include <runtime/Protect.h>
#include <runtime/UString.h>
@@ -50,6 +52,14 @@ bool ScriptValue::getString(String& result) const
return true;
}
+bool ScriptValue::isEqual(ScriptState* scriptState, const ScriptValue& anotherValue) const
+{
+ if (hasNoValue())
+ return anotherValue.hasNoValue();
+
+ return JSValueIsEqual(toRef(scriptState), toRef(jsValue()), toRef(anotherValue.jsValue()), 0);
+}
+
bool ScriptValue::isNull() const
{
if (!m_value)
diff --git a/WebCore/bindings/js/ScriptValue.h b/WebCore/bindings/js/ScriptValue.h
index 855509a..e6e7cb1 100644
--- a/WebCore/bindings/js/ScriptValue.h
+++ b/WebCore/bindings/js/ScriptValue.h
@@ -31,6 +31,8 @@
#ifndef ScriptValue_h
#define ScriptValue_h
+#include "PlatformString.h"
+#include "ScriptState.h"
#include <runtime/Protect.h>
namespace WebCore {
@@ -40,11 +42,15 @@ class String;
class ScriptValue {
public:
ScriptValue(JSC::JSValuePtr value = JSC::noValue()) : m_value(value) {}
+ virtual ~ScriptValue() {}
JSC::JSValuePtr jsValue() const { return m_value.get(); }
bool getString(String& result) const;
+ String toString(ScriptState* scriptState) const { return m_value.get().toString(scriptState); }
+ bool isEqual(ScriptState*, const ScriptValue&) const;
bool isNull() const;
bool isUndefined() const;
+ bool hasNoValue() const { return m_value == JSC::noValue(); }
private:
JSC::ProtectedJSValuePtr m_value;
diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp
index 0727510..25d7eb9 100644
--- a/WebCore/bindings/js/WorkerScriptController.cpp
+++ b/WebCore/bindings/js/WorkerScriptController.cpp
@@ -35,7 +35,7 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "WorkerContext.h"
-#include "WorkerMessagingProxy.h"
+#include "WorkerObjectProxy.h"
#include "WorkerThread.h"
#include <interpreter/Interpreter.h>
#include <runtime/Completion.h>
@@ -68,8 +68,13 @@ void WorkerScriptController::initScript()
JSLock lock(false);
+ // Explicitly protect the global object's prototype so it isn't collected
+ // when we allocate the global object. (Once the global object is fully
+ // constructed, it can mark its own prototype.)
RefPtr<Structure> prototypeStructure = JSWorkerContextPrototype::createStructure(jsNull());
- RefPtr<Structure> structure = JSWorkerContext::createStructure(new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release()));
+ ProtectedPtr<JSWorkerContextPrototype> prototype = new (m_globalData.get()) JSWorkerContextPrototype(prototypeStructure.release());
+
+ RefPtr<Structure> structure = JSWorkerContext::createStructure(prototype);
m_workerContextWrapper = new (m_globalData.get()) JSWorkerContext(structure.release(), m_workerContext);
}
@@ -80,25 +85,46 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
if (m_executionForbidden)
return noValue();
}
+ ScriptValue exception;
+ ScriptValue result = evaluate(sourceCode, &exception);
+ if (exception.jsValue()) {
+ JSLock lock(false);
+ reportException(m_workerContextWrapper->globalExec(), exception.jsValue());
+ }
+ return result;
+}
+
+ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception)
+{
+ {
+ MutexLocker lock(m_sharedDataMutex);
+ if (m_executionForbidden)
+ return noValue();
+ }
initScriptIfNeeded();
JSLock lock(false);
ExecState* exec = m_workerContextWrapper->globalExec();
- m_workerContextWrapper->startTimeoutCheck();
+ m_workerContextWrapper->globalData()->timeoutChecker.start();
Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper);
- m_workerContextWrapper->stopTimeoutCheck();
+ m_workerContextWrapper->globalData()->timeoutChecker.stop();
- m_workerContext->thread()->messagingProxy()->reportWorkerThreadActivity(m_workerContext->hasPendingActivity());
+ m_workerContext->thread()->workerObjectProxy()->reportPendingActivity(m_workerContext->hasPendingActivity());
if (comp.complType() == Normal || comp.complType() == ReturnValue)
return comp.value();
if (comp.complType() == Throw)
- reportException(exec, comp.value());
+ *exception = comp.value();
return noValue();
}
+void WorkerScriptController::setException(ScriptValue exception)
+{
+ m_workerContextWrapper->globalExec()->setException(exception.jsValue());
+}
+
void WorkerScriptController::forbidExecution()
{
// This function is called from another thread.
@@ -107,7 +133,7 @@ void WorkerScriptController::forbidExecution()
// It is not critical for Interpreter::m_timeoutTime to be synchronized, we just rely on it reaching the worker thread's processor sooner or later.
MutexLocker lock(m_sharedDataMutex);
m_executionForbidden = true;
- m_globalData->interpreter->setTimeoutTime(1); // 1 ms is the smallest timeout that can be set.
+ m_globalData->timeoutChecker.setTimeoutInterval(1); // 1ms is the smallest timeout that can be set.
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/WorkerScriptController.h b/WebCore/bindings/js/WorkerScriptController.h
index 1dda5da..0454721 100644
--- a/WebCore/bindings/js/WorkerScriptController.h
+++ b/WebCore/bindings/js/WorkerScriptController.h
@@ -57,9 +57,11 @@ namespace WebCore {
}
ScriptValue evaluate(const ScriptSourceCode&);
+ ScriptValue evaluate(const ScriptSourceCode&, ScriptValue* exception);
- void forbidExecution();
+ void setException(ScriptValue);
+ void forbidExecution();
private:
void initScriptIfNeeded()
{
diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm
index 485d011..53be4ff 100644
--- a/WebCore/bindings/objc/DOM.mm
+++ b/WebCore/bindings/objc/DOM.mm
@@ -31,6 +31,7 @@
#import "DOMHTMLCanvasElement.h"
#import "DOMInternal.h"
#import "ExceptionHandlers.h"
+#import "Frame.h"
#import "HTMLNames.h"
#import "HTMLPlugInElement.h"
#import "NodeIterator.h"
@@ -400,7 +401,7 @@ static NSArray *kit(const Vector<IntRect>& rects)
WebCore::RenderObject *renderer = [self _node]->renderer();
if (renderer) {
Vector<WebCore::IntRect> rects;
- renderer->addLineBoxRects(rects);
+ renderer->absoluteRectsForRange(rects);
return kit(rects);
}
return nil;
@@ -524,18 +525,6 @@ static NSArray *kit(const Vector<IntRect>& rects)
return nil;
}
-- (NSRect)_windowClipRect
-{
- WebCore::RenderObject* renderer = [self _element]->renderer();
- if (renderer && renderer->view()) {
- WebCore::FrameView* frameView = renderer->view()->frameView();
- if (!frameView)
- return WebCore::IntRect();
- return frameView->windowClipRectForLayer(renderer->enclosingLayer(), true);
- }
- return WebCore::IntRect();
-}
-
// FIXME: this should be implemented in the implementation
- (NSURL *)_getURLAttribute:(NSString *)name
{
@@ -546,17 +535,6 @@ static NSArray *kit(const Vector<IntRect>& rects)
}
// FIXME: this should be implemented in the implementation
-- (void *)_NPObject
-{
-#if ENABLE(NETSCAPE_PLUGIN_API)
- WebCore::Element* element = [self _element];
- if (element->hasTagName(WebCore::HTMLNames::appletTag) || element->hasTagName(WebCore::HTMLNames::embedTag) || element->hasTagName(WebCore::HTMLNames::objectTag))
- return static_cast<WebCore::HTMLPlugInElement*>(element)->getNPObject();
-#endif
- return 0;
-}
-
-// FIXME: this should be implemented in the implementation
- (BOOL)isFocused
{
WebCore::Element* impl = [self _element];
diff --git a/WebCore/bindings/objc/DOMAbstractView.mm b/WebCore/bindings/objc/DOMAbstractView.mm
index 728a39a..7bfe7f1 100644
--- a/WebCore/bindings/objc/DOMAbstractView.mm
+++ b/WebCore/bindings/objc/DOMAbstractView.mm
@@ -44,7 +44,7 @@
- (void)dealloc
{
- { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); }
+ { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }
[super dealloc];
}
@@ -79,7 +79,7 @@
- (id)_initWithFrame:(WebCore::Frame *)impl
{
- { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); };
+ { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); };
[super _init];
_internal = reinterpret_cast<DOMObjectInternal*>(impl);
WebCore::addDOMWrapper(self, impl);
@@ -88,7 +88,7 @@
+ (DOMAbstractView *)_wrapAbstractView:(WebCore::DOMWindow *)impl
{
- { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); };
+ { DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); };
if (!impl)
return nil;
diff --git a/WebCore/bindings/objc/DOMPrivate.h b/WebCore/bindings/objc/DOMPrivate.h
index 0ee5979..ba95ce3 100644
--- a/WebCore/bindings/objc/DOMPrivate.h
+++ b/WebCore/bindings/objc/DOMPrivate.h
@@ -86,8 +86,6 @@
- (NSFont *)_font;
- (NSData *)_imageTIFFRepresentation;
- (NSURL *)_getURLAttribute:(NSString *)name;
-- (void *)_NPObject; // For subclasses to implement; we only allow NPObjects to be created for certain element types
-- (NSRect)_windowClipRect; // Clip rect in NSWindow coords (used by plugins)
- (BOOL)isFocused;
@end
diff --git a/WebCore/bindings/objc/WebScriptObject.mm b/WebCore/bindings/objc/WebScriptObject.mm
index f08d61b..3cdae86 100644
--- a/WebCore/bindings/objc/WebScriptObject.mm
+++ b/WebCore/bindings/objc/WebScriptObject.mm
@@ -298,9 +298,9 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
if (![self _isSafeScript])
return nil;
- [self _rootObject]->globalObject()->startTimeoutCheck();
+ [self _rootObject]->globalObject()->globalData()->timeoutChecker.start();
JSValuePtr result = call(exec, function, callType, callData, [self _imp], argList);
- [self _rootObject]->globalObject()->stopTimeoutCheck();
+ [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop();
if (exec->hadException()) {
addExceptionToConsole(exec);
@@ -327,9 +327,9 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
JSValuePtr result;
JSLock lock(false);
- [self _rootObject]->globalObject()->startTimeoutCheck();
+ [self _rootObject]->globalObject()->globalData()->timeoutChecker.start();
Completion completion = JSC::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)));
- [self _rootObject]->globalObject()->stopTimeoutCheck();
+ [self _rootObject]->globalObject()->globalData()->timeoutChecker.stop();
ComplType type = completion.complType();
if (type == Normal) {
diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm
index 7a4d095..4f899be 100644
--- a/WebCore/bindings/scripts/CodeGenerator.pm
+++ b/WebCore/bindings/scripts/CodeGenerator.pm
@@ -131,9 +131,6 @@ sub AddMethodsConstantsAndAttributesFromParentClasses
my $functionsRef = $dataNode->functions;
my $attributesRef = $dataNode->attributes;
- # Exception: For the DOM 'Node' is our topmost baseclass, not EventTargetNode.
- return if $parentsMax eq 1 and $parents[0] eq "EventTargetNode";
-
foreach (@{$dataNode->parents}) {
if ($ignoreParent) {
# Ignore first parent class, already handled by the generation itself.
@@ -196,9 +193,6 @@ sub GetMethodsAndAttributesFromParentClasses
foreach (@{$dataNode->parents}) {
my $interface = $object->StripModule($_);
- if ($interface eq "EventTargetNode") {
- $interface = "Node";
- }
# Step #1: Find the IDL file associated with 'interface'
$endCondition = 0;
diff --git a/WebCore/bindings/scripts/CodeGeneratorCOM.pm b/WebCore/bindings/scripts/CodeGeneratorCOM.pm
index 0c86ef2..4e363aa 100644
--- a/WebCore/bindings/scripts/CodeGeneratorCOM.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorCOM.pm
@@ -236,7 +236,6 @@ sub GetParentInterface
{
my ($dataNode) = @_;
return "I" . $TEMP_PREFIX . "DOMObject" if (@{$dataNode->parents} == 0);
- return "I" . $TEMP_PREFIX . "DOMNode" if $codeGenerator->StripModule($dataNode->parents(0)) eq "EventTargetNode";
return GetInterfaceName($codeGenerator->StripModule($dataNode->parents(0)));
}
@@ -244,7 +243,6 @@ sub GetParentClass
{
my ($dataNode) = @_;
return $TEMP_PREFIX . "DOMObject" if (@{$dataNode->parents} == 0);
- return $TEMP_PREFIX . "DOMNode" if $codeGenerator->StripModule($dataNode->parents(0)) eq "EventTargetNode";
return GetClassName($codeGenerator->StripModule($dataNode->parents(0)));
}
@@ -316,7 +314,6 @@ sub AddIncludesForTypeInCPPImplementation
}
# Special casing
- $CPPImplementationWebCoreIncludes{"EventTargetNode.h"} = 1 if $type eq "Node";
$CPPImplementationWebCoreIncludes{"NameNodeList.h"} = 1 if $type eq "NodeList";
$CPPImplementationWebCoreIncludes{"CSSMutableStyleDeclaration.h"} = 1 if $type eq "CSSStyleDeclaration";
@@ -706,7 +703,6 @@ sub GenerateCPPFunction
my $functionName = $function->signature->name;
my $returnIDLType = $function->signature->type;
my $noReturn = ($returnIDLType eq "void");
- my $requiresEventTargetNodeCast = $function->signature->extendedAttributes->{"EventTargetNodeCast"};
my $raisesExceptions = @{$function->raisesExceptions};
AddIncludesForTypeInCPPImplementation($returnIDLType);
@@ -756,9 +752,6 @@ sub GenerateCPPFunction
push(@parameterList, "ec") if $raisesExceptions;
my $implementationGetter = "impl${implementationClassWithoutNamespace}()";
- if ($requiresEventTargetNodeCast) {
- $implementationGetter = "WebCore::EventTargetNodeCast(${implementationGetter})";
- }
my $callSigBegin = " ";
my $callSigMiddle = "${implementationGetter}->" . $codeGenerator->WK_lcfirst($functionName) . "(" . join(", ", @parameterList) . ")";
@@ -801,10 +794,6 @@ sub GenerateCPPFunction
}
push(@functionImplementation, " WebCore::ExceptionCode ec = 0;\n") if $raisesExceptions; # FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT
push(@functionImplementation, join("\n", @parameterInitialization) . (@parameterInitialization > 0 ? "\n" : ""));
- if ($requiresEventTargetNodeCast) {
- push(@functionImplementation, " if (!impl${implementationClassWithoutNamespace}()->isEventTargetNode())\n");
- push(@functionImplementation, " return E_FAIL;\n");
- }
push(@functionImplementation, $callSigBegin . $callSigMiddle . $callSigEnd . "\n");
push(@functionImplementation, " return S_OK;\n");
push(@functionImplementation, "}\n\n");
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 2af88e2..08ef971 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -174,7 +174,7 @@ sub AddIncludesForType
# When we're finished with the one-file-per-class
# reorganization, we won't need these special cases.
if ($codeGenerator->IsPrimitiveType($type) or AvoidInclusionOfType($type)
- or $type eq "DOMString" or $type eq "DOMObject" or $type eq "RGBColor") {
+ or $type eq "DOMString" or $type eq "DOMObject" or $type eq "RGBColor" or $type eq "Array") {
} elsif ($type =~ /SVGPathSeg/) {
$joinedName = $type;
$joinedName =~ s/Abs|Rel//;
@@ -284,29 +284,19 @@ sub GenerateGetOwnPropertySlotBody
push(@getOwnPropertySlotImpl, " return false;\n\n");
}
- my $hasNameGetterGeneration = sub {
- push(@getOwnPropertySlotImpl, " if (canGetItemsForName(exec, static_cast<$implClassName*>(impl()), propertyName)) {\n");
- push(@getOwnPropertySlotImpl, " slot.setCustom(this, nameGetter);\n");
- push(@getOwnPropertySlotImpl, " return true;\n");
- push(@getOwnPropertySlotImpl, " }\n");
- if ($inlined) {
- $headerIncludes{"AtomicString.h"} = 1;
- } else {
- $implIncludes{"AtomicString.h"} = 1;
+ my $manualLookupGetterGeneration = sub {
+ my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"};
+ if ($requiresManualLookup) {
+ push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n");
+ push(@getOwnPropertySlotImpl, " if (entry) {\n");
+ push(@getOwnPropertySlotImpl, " slot.setCustom(this, entry->propertyGetter());\n");
+ push(@getOwnPropertySlotImpl, " return true;\n");
+ push(@getOwnPropertySlotImpl, " }\n");
}
};
- if ($dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
- &$hasNameGetterGeneration();
- }
-
- my $requiresManualLookup = $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasNameGetter"};
- if ($requiresManualLookup) {
- push(@getOwnPropertySlotImpl, " const ${namespaceMaybe}HashEntry* entry = ${className}Table.entry(exec, propertyName);\n");
- push(@getOwnPropertySlotImpl, " if (entry) {\n");
- push(@getOwnPropertySlotImpl, " slot.setCustom(this, entry->propertyGetter());\n");
- push(@getOwnPropertySlotImpl, " return true;\n");
- push(@getOwnPropertySlotImpl, " }\n");
+ if (!$dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
+ &$manualLookupGetterGeneration();
}
if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
@@ -322,8 +312,20 @@ sub GenerateGetOwnPropertySlotBody
push(@getOwnPropertySlotImpl, " }\n");
}
- if ($dataNode->extendedAttributes->{"HasNameGetter"}) {
- &$hasNameGetterGeneration();
+ if ($dataNode->extendedAttributes->{"HasNameGetter"} || $dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
+ push(@getOwnPropertySlotImpl, " if (canGetItemsForName(exec, static_cast<$implClassName*>(impl()), propertyName)) {\n");
+ push(@getOwnPropertySlotImpl, " slot.setCustom(this, nameGetter);\n");
+ push(@getOwnPropertySlotImpl, " return true;\n");
+ push(@getOwnPropertySlotImpl, " }\n");
+ if ($inlined) {
+ $headerIncludes{"AtomicString.h"} = 1;
+ } else {
+ $implIncludes{"AtomicString.h"} = 1;
+ }
+ }
+
+ if ($dataNode->extendedAttributes->{"HasOverridingNameGetter"}) {
+ &$manualLookupGetterGeneration();
}
if ($dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) {
@@ -386,9 +388,6 @@ sub GenerateHeader
push(@headerContentHeader, "#include <runtime/JSGlobalObject.h>\n");
push(@headerContentHeader, "#include <runtime/ObjectPrototype.h>\n");
}
- if ($interfaceName eq "Node") {
- push(@headerContentHeader, "#include \"EventTargetNode.h\"\n");
- }
if ($dataNode->extendedAttributes->{"CustomCall"}) {
push(@headerContentHeader, "#include <runtime/CallData.h>\n");
@@ -536,7 +535,7 @@ sub GenerateHeader
if ($numAttributes > 0) {
foreach (@{$dataNode->attributes}) {
my $attribute = $_;
- $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"Custom"};
+ $numCustomAttributes++ if $attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"};
$numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomGetter"};
$numCustomAttributes++ if $attribute->signature->extendedAttributes->{"CustomSetter"};
}
@@ -546,7 +545,7 @@ sub GenerateHeader
push(@headerContent, "\n // Custom attributes\n");
foreach my $attribute (@{$dataNode->attributes}) {
- if ($attribute->signature->extendedAttributes->{"Custom"}) {
+ if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"}) {
push(@headerContent, " JSC::JSValuePtr " . $codeGenerator->WK_lcfirst($attribute->signature->name) . "(JSC::ExecState*) const;\n");
if ($attribute->type !~ /^readonly/) {
push(@headerContent, " void set" . $codeGenerator->WK_ucfirst($attribute->signature->name) . "(JSC::ExecState*, JSC::JSValuePtr);\n");
@@ -562,13 +561,13 @@ sub GenerateHeader
}
foreach my $function (@{$dataNode->functions}) {
- $numCustomFunctions++ if $function->signature->extendedAttributes->{"Custom"};
+ $numCustomFunctions++ if $function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"};
}
if ($numCustomFunctions > 0) {
push(@headerContent, "\n // Custom functions\n");
foreach my $function (@{$dataNode->functions}) {
- if ($function->signature->extendedAttributes->{"Custom"}) {
+ if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}) {
my $functionImplementationName = $function->signature->extendedAttributes->{"ImplementationFunction"} || $codeGenerator->WK_lcfirst($function->signature->name);
push(@headerContent, " JSC::JSValuePtr " . $functionImplementationName . "(JSC::ExecState*, const JSC::ArgList&);\n");
}
@@ -636,11 +635,6 @@ sub GenerateHeader
} else {
push(@headerContent, "JSC::JSValuePtr toJS(JSC::ExecState*, $implType*);\n");
}
-
- # Resolve ambiguity with EventTarget that otherwise exists.
- if ($interfaceName eq "Node") {
- push(@headerContent, "inline JSC::JSValuePtr toJS(JSC::ExecState* exec, EventTargetNode* node) { return toJS(exec, static_cast<Node*>(node)); }\n");
- }
}
if (!$hasParent || $dataNode->extendedAttributes->{"GenerateNativeConverter"}) {
if ($podType) {
@@ -763,7 +757,7 @@ sub GenerateImplementation
push(@implContent, "\nusing namespace JSC;\n\n");
push(@implContent, "namespace WebCore {\n\n");
- push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className)\n\n");
+ push(@implContent, "ASSERT_CLASS_FITS_IN_CELL($className);\n\n");
# - Add all attributes in a hashtable definition
my $numAttributes = @{$dataNode->attributes};
@@ -1080,7 +1074,7 @@ sub GenerateImplementation
push(@implContent, " return jsUndefined();\n");
}
- if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) {
+ if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"}) {
push(@implContent, " return static_cast<$className*>(asObject(slot.slotBase()))->$implGetterFunctionName(exec);\n");
} elsif ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
$implIncludes{"JSDOMBinding.h"} = 1;
@@ -1092,19 +1086,12 @@ sub GenerateImplementation
push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
push(@implContent, " return checkNodeSecurity(exec, imp->contentDocument()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "static_cast<$className*>(asObject(slot.slotBase()))") . " : jsUndefined();\n");
} elsif ($type eq "EventListener") {
- $implIncludes{"JSEventListener.h"} = 1;
$implIncludes{"EventListener.h"} = 1;
- my $listenerType;
- if ($attribute->signature->extendedAttributes->{"ProtectedListener"}) {
- $listenerType = "JSEventListener";
- } else {
- $listenerType = "JSUnprotectedEventListener";
- }
push(@implContent, " UNUSED_PARAM(exec);\n");
push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
- push(@implContent, " if (${listenerType}* listener = static_cast<${listenerType}*>(imp->$implGetterFunctionName())) {\n");
- push(@implContent, " if (JSObject* listenerObj = listener->listenerObj())\n");
- push(@implContent, " return listenerObj;\n");
+ push(@implContent, " if (EventListener* listener = imp->$implGetterFunctionName()) {\n");
+ push(@implContent, " if (JSObject* function = listener->function())\n");
+ push(@implContent, " return function;\n");
push(@implContent, " }\n");
push(@implContent, " return jsNull();\n");
} elsif ($attribute->signature->type =~ /Constructor$/) {
@@ -1220,16 +1207,16 @@ sub GenerateImplementation
push(@implContent, " return;\n");
}
- if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"CustomSetter"}) {
+ if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomSetter"}) {
push(@implContent, " static_cast<$className*>(thisObject)->set$implSetterFunctionName(exec, value);\n");
} elsif ($type eq "EventListener") {
$implIncludes{"JSEventListener.h"} = 1;
push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n");
my $listenerType;
if ($attribute->signature->extendedAttributes->{"ProtectedListener"}) {
- $listenerType = "JSEventListener";
+ $listenerType = "JSProtectedEventListener";
} else {
- $listenerType = "JSUnprotectedEventListener";
+ $listenerType = "JSEventListener";
}
if ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"}) {
push(@implContent, " JSDOMGlobalObject* globalObject = static_cast<$className*>(thisObject);\n");
@@ -1248,6 +1235,7 @@ sub GenerateImplementation
push(@implContent, " // Shadowing a built-in constructor\n");
push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n");
} elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
+ push(@implContent, " // Shadowing a built-in object\n");
push(@implContent, " static_cast<$className*>(thisObject)->putDirect(Identifier(exec, \"$name\"), value);\n");
} else {
if ($podType) {
@@ -1331,7 +1319,7 @@ sub GenerateImplementation
push(@implContent, " return jsUndefined();\n");
}
- if ($function->signature->extendedAttributes->{"Custom"}) {
+ if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"JSCCustom"}) {
push(@implContent, " return castedThisObj->" . $functionImplementationName . "(exec, args);\n");
} else {
if ($podType) {
@@ -1557,7 +1545,6 @@ sub GetNativeTypeFromSignature
my %nativeType = (
"CompareHow" => "Range::CompareHow",
"DOMString" => "const UString&",
- "EventTarget" => "EventTargetNode*",
"NodeFilter" => "RefPtr<NodeFilter>",
"SVGLength" => "SVGLength",
"SVGMatrix" => "TransformationMatrix",
@@ -1605,11 +1592,6 @@ sub JSValueToNative
return "$value.toString(exec)";
}
- if ($type eq "EventTarget") {
- $implIncludes{"JSEventTargetNode.h"} = 1;
- return "toEventTargetNode($value)";
- }
-
$implIncludes{"FloatPoint.h"} = 1 if $type eq "SVGPoint";
$implIncludes{"FloatRect.h"} = 1 if $type eq "SVGRect";
$implIncludes{"HTMLOptionElement.h"} = 1 if $type eq "HTMLOptionElement";
diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
index 68fce3d..5ec960e 100644
--- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
@@ -79,7 +79,7 @@ my $buildingForTigerOrEarlier = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"
my $buildingForLeopardOrLater = 1 if $ENV{"MACOSX_DEPLOYMENT_TARGET"} and $ENV{"MACOSX_DEPLOYMENT_TARGET"} >= 10.5;
my $exceptionInit = "WebCore::ExceptionCode ec = 0;";
my $exceptionRaiseOnError = "WebCore::raiseOnDOMError(ec);";
-my $assertMainThread = "{ DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheck(); }";
+my $assertMainThread = "{ DOM_ASSERT_MAIN_THREAD(); WebCoreThreadViolationCheckRoundOne(); }";
my %conflictMethod = (
# FIXME: Add C language keywords?
@@ -345,7 +345,6 @@ sub GetParentImplClassName
my $parent = $codeGenerator->StripModule($dataNode->parents(0));
# special cases
- return "Node" if $parent eq "EventTargetNode";
return "Object" if $parent eq "HTMLCollection";
return $parent;
@@ -373,8 +372,6 @@ sub GetParentAndProtocols
} else {
if (IsProtocolType($parentName)) {
push(@protocols, "DOM" . $parentName);
- } elsif ($parentName eq "EventTargetNode") {
- $parent = "DOMNode";
} elsif ($parentName eq "HTMLCollection") {
$parent = "DOMObject";
} else {
@@ -507,7 +504,7 @@ sub GetObjCTypeGetter
my $type = $codeGenerator->StripModule(shift);
return $argName if $codeGenerator->IsPrimitiveType($type) or $codeGenerator->IsStringType($type) or IsNativeObjCType($type);
- return $argName . "EventTarget" if $type eq "EventTarget";
+ return $argName . "Node" if $type eq "EventTarget";
return "static_cast<WebCore::Range::CompareHow>($argName)" if $type eq "CompareHow";
return "static_cast<WebCore::SVGPaint::SVGPaintType>($argName)" if $type eq "SVGPaintType";
@@ -623,7 +620,7 @@ sub AddIncludesForType
}
if ($type eq "EventTarget") {
- $implIncludes{"EventTargetNode.h"} = 1;
+ $implIncludes{"Node.h"} = 1;
$implIncludes{"DOM$type.h"} = 1;
return;
}
@@ -1406,7 +1403,6 @@ sub GenerateImplementation
my $paramName = $needsCustom{"EventTarget"};
push(@functionContent, " DOMNode* ${paramName}ObjC = $paramName;\n");
push(@functionContent, " WebCore::Node* ${paramName}Node = [${paramName}ObjC _node];\n");
- push(@functionContent, " WebCore::EventTargetNode* ${paramName}EventTarget = (${paramName}Node && ${paramName}Node->isEventTargetNode()) ? static_cast<WebCore::EventTargetNode*>(${paramName}Node) : 0;\n\n");
$implIncludes{"DOMNode.h"} = 1;
$implIncludes{"Node.h"} = 1;
}
@@ -1419,16 +1415,6 @@ sub GenerateImplementation
$caller = "dv";
}
- if ($function->signature->extendedAttributes->{"EventTargetNodeCast"}) {
- if ($dataNode->name =~ /^SVG/) {
- $caller = "static_cast<WebCore::SVGElementInstance*>($caller)";
- } else {
- push(@functionContent, " if (!$caller->isEventTargetNode())\n");
- $caller = "WebCore::EventTargetNodeCast($caller)";
- push(@functionContent, " WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);\n");
- }
- }
-
# special case the EventListener
if (defined $needsCustom{"EventListener"}) {
my $paramName = $needsCustom{"EventListener"};
diff --git a/WebCore/bindings/v8/ScheduledAction.cpp b/WebCore/bindings/v8/ScheduledAction.cpp
new file mode 100644
index 0000000..7c71d00
--- /dev/null
+++ b/WebCore/bindings/v8/ScheduledAction.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScheduledAction.h"
+
+#include "Document.h"
+#include "ScriptExecutionContext.h"
+#include "ScriptSourceCode.h"
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ScheduledAction::ScheduledAction(v8::Handle<v8::Function> func, int argc, v8::Handle<v8::Value> argv[])
+ : m_code(String(), KURL(), 0)
+{
+ m_function = v8::Persistent<v8::Function>::New(func);
+
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_function);
+#endif
+
+ m_argc = argc;
+ if (argc > 0) {
+ m_argv = new v8::Persistent<v8::Value>[argc];
+ for (int i = 0; i < argc; i++) {
+ m_argv[i] = v8::Persistent<v8::Value>::New(argv[i]);
+
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_argv[i]);
+#endif
+ }
+ } else
+ m_argv = 0;
+}
+
+ScheduledAction::~ScheduledAction()
+{
+ if (m_function.IsEmpty())
+ return;
+
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_function);
+#endif
+ m_function.Dispose();
+
+ for (int i = 0; i < m_argc; i++) {
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_argv[i]);
+#endif
+ m_argv[i].Dispose();
+ }
+
+ if (m_argc > 0)
+ delete[] m_argv;
+}
+
+void ScheduledAction::execute(ScriptExecutionContext* context)
+{
+ // FIXME: Timeouts for running the javascript code are not set.
+ V8Proxy* proxy = V8Proxy::retrieve(context);
+ if (!proxy)
+ return;
+
+ v8::HandleScope handleScope;
+ v8::Local<v8::Context> v8Context = proxy->GetContext();
+ if (v8Context.IsEmpty())
+ return; // JS may not be enabled.
+
+ v8::Context::Scope scope(v8Context);
+
+ proxy->setTimerCallback(true);
+
+ if (!m_function.IsEmpty() && m_function->IsFunction())
+ proxy->CallFunction(v8::Persistent<v8::Function>::Cast(m_function), v8Context->Global(), m_argc, m_argv);
+ else
+ proxy->evaluate(m_code, 0);
+
+ if (context->isDocument())
+ static_cast<Document*>(context)->updateRendering();
+
+ proxy->setTimerCallback(false);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScheduledAction.h b/WebCore/bindings/v8/ScheduledAction.h
new file mode 100644
index 0000000..da6cb02
--- /dev/null
+++ b/WebCore/bindings/v8/ScheduledAction.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScheduledAction_h
+#define ScheduledAction_h
+
+#include "ScriptSourceCode.h"
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class String;
+ class ScriptExecutionContext;
+
+ class ScheduledAction {
+ public:
+ ScheduledAction(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
+ explicit ScheduledAction(const WebCore::String& code)
+ : m_argc(0)
+ , m_argv(0)
+ , m_code(code)
+ {
+ }
+
+ virtual ~ScheduledAction();
+ virtual void execute(ScriptExecutionContext*);
+
+ private:
+ v8::Persistent<v8::Function> m_function;
+ int m_argc;
+ v8::Persistent<v8::Value>* m_argv;
+ ScriptSourceCode m_code;
+ };
+
+} // namespace WebCore
+
+#endif // ScheduledAction
diff --git a/WebCore/bindings/v8/ScriptCachedFrameData.h b/WebCore/bindings/v8/ScriptCachedFrameData.h
new file mode 100644
index 0000000..e6530f4
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptCachedFrameData.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptCachedPageData_h
+#define ScriptCachedPageData_h
+
+// We don't use WebKit's page caching, so this implementation is just a stub.
+
+namespace WebCore {
+ class Frame;
+ class DOMWindow;
+
+ class ScriptCachedFrameData {
+ public:
+ ScriptCachedFrameData(Frame*) { }
+ ~ScriptCachedFrameData() { }
+
+ void restore(Frame*) { }
+ void clear() { }
+ DOMWindow* domWindow() const { return 0; }
+ };
+
+} // namespace WebCore
+
+#endif // ScriptCachedPageData_h
diff --git a/WebCore/bindings/v8/ScriptCallFrame.cpp b/WebCore/bindings/v8/ScriptCallFrame.cpp
new file mode 100644
index 0000000..ab30862
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptCallFrame.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptCallFrame.h"
+
+#include <v8.h>
+
+#include "PlatformString.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+#include "ScriptValue.h"
+
+namespace WebCore {
+
+ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments& arguments, unsigned skipArgumentCount)
+ : m_functionName(functionName)
+ , m_sourceURL(urlString)
+ , m_lineNumber(lineNumber)
+{
+ for (int i = 0; i < arguments.Length(); ++i)
+ m_arguments.append(ScriptValue(arguments[i]));
+}
+
+ScriptCallFrame::~ScriptCallFrame()
+{
+}
+
+const ScriptValue& ScriptCallFrame::argumentAt(unsigned index) const
+{
+ ASSERT(m_arguments.size() > index);
+ return m_arguments[index];
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptCallFrame.h b/WebCore/bindings/v8/ScriptCallFrame.h
new file mode 100644
index 0000000..50357cf
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptCallFrame.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptCallFrame_h
+#define ScriptCallFrame_h
+
+#include "KURL.h"
+#include "ScriptString.h"
+
+#include <wtf/Vector.h>
+
+namespace v8 {
+ class Arguments;
+}
+
+namespace WebCore {
+ class ScriptValue;
+
+ // FIXME: Implement retrieving line number and source URL and storing here
+ // for all call frames, not just the first one.
+ // See <https://bugs.webkit.org/show_bug.cgi?id=22556> and
+ // <https://bugs.webkit.org/show_bug.cgi?id=21180>
+ class ScriptCallFrame {
+ public:
+ ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments&, unsigned skipArgumentCount);
+ ~ScriptCallFrame();
+
+ const ScriptString& functionName() const { return m_functionName; }
+ const KURL& sourceURL() const { return m_sourceURL; }
+ unsigned lineNumber() const { return m_lineNumber; }
+
+ // argument retrieval methods
+ const ScriptValue& argumentAt(unsigned) const;
+ unsigned argumentCount() const { return m_arguments.size(); }
+
+ private:
+ ScriptString m_functionName;
+ KURL m_sourceURL;
+ unsigned m_lineNumber;
+
+ Vector<ScriptValue> m_arguments;
+ };
+
+} // namespace WebCore
+
+#endif // ScriptCallFrame_h
diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp
new file mode 100644
index 0000000..9188dcf
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptCallStack.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptCallStack.h"
+
+#include <v8.h>
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount)
+ : m_lastCaller(String(), V8Proxy::GetSourceName(), V8Proxy::GetSourceLineNumber() + 1, arguments, skipArgumentCount)
+{
+}
+
+ScriptCallStack::~ScriptCallStack()
+{
+}
+
+const ScriptCallFrame& ScriptCallStack::at(unsigned index) const
+{
+ // Currently, only one ScriptCallFrame is supported. When we can get
+ // a full stack trace from V8, we can do this right.
+ ASSERT(index == 0);
+ return m_lastCaller;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h
new file mode 100644
index 0000000..2dfd484
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptCallStack.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptCallStack_h
+#define ScriptCallStack_h
+
+#include "ScriptCallFrame.h"
+#include "ScriptState.h"
+#include "ScriptValue.h"
+#include <wtf/Noncopyable.h>
+
+namespace v8 {
+ class Arguments;
+}
+
+namespace WebCore {
+
+ class ScriptCallStack : public Noncopyable {
+ public:
+ ScriptCallStack(const v8::Arguments&, unsigned skipArgumentCount = 0);
+ ~ScriptCallStack();
+
+ const ScriptCallFrame& at(unsigned) const;
+ // FIXME: implement retrieving and storing call stack trace
+ unsigned size() const { return 1; }
+
+ // FIXME: This method is obviously not implemented.
+ ScriptState* state() const { return 0; }
+
+ private:
+ ScriptCallFrame m_lastCaller;
+ };
+
+} // namespace WebCore
+
+#endif // ScriptCallStack_h
diff --git a/WebCore/bindings/v8/ScriptInstance.cpp b/WebCore/bindings/v8/ScriptInstance.cpp
new file mode 100644
index 0000000..aa4a396
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptInstance.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptInstance.h"
+
+#ifndef NDEBUG
+#include "V8Proxy.h"
+#endif
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+V8ScriptInstance::V8ScriptInstance()
+{
+}
+
+V8ScriptInstance::V8ScriptInstance(v8::Handle<v8::Object> instance)
+{
+ set(instance);
+}
+
+V8ScriptInstance::~V8ScriptInstance()
+{
+ clear();
+}
+
+v8::Persistent<v8::Object> V8ScriptInstance::instance()
+{
+ return m_instance;
+}
+
+void V8ScriptInstance::clear()
+{
+ if (m_instance.IsEmpty())
+ return;
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_instance);
+#endif
+ m_instance.Dispose();
+ m_instance.Clear();
+}
+
+void V8ScriptInstance::set(v8::Handle<v8::Object> instance)
+{
+ clear();
+ if (instance.IsEmpty())
+ return;
+
+ m_instance = v8::Persistent<v8::Object>::New(instance);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(SCRIPTINSTANCE, this, m_instance);
+#endif
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptInstance.h b/WebCore/bindings/v8/ScriptInstance.h
new file mode 100644
index 0000000..2fe3736
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptInstance.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptInstance_h
+#define ScriptInstance_h
+
+#include <v8.h>
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class V8ScriptInstance : public RefCounted<V8ScriptInstance> {
+public:
+ static PassRefPtr<V8ScriptInstance> create(v8::Handle<v8::Object> instance)
+ {
+ return adoptRef(new V8ScriptInstance(instance));
+ }
+ V8ScriptInstance();
+ V8ScriptInstance(v8::Handle<v8::Object>);
+ ~V8ScriptInstance();
+ v8::Persistent<v8::Object> instance();
+
+private:
+ void clear();
+ void set(v8::Handle<v8::Object>);
+ mutable v8::Persistent<v8::Object> m_instance;
+};
+
+typedef RefPtr<V8ScriptInstance> ScriptInstance;
+typedef PassRefPtr<V8ScriptInstance> PassScriptInstance;
+
+} // namespace WebCore
+
+#endif // ScriptInstance_h
diff --git a/WebCore/bindings/v8/ScriptSourceCode.h b/WebCore/bindings/v8/ScriptSourceCode.h
new file mode 100644
index 0000000..fea387a
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptSourceCode.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptSourceCode_h
+#define ScriptSourceCode_h
+
+#include "CachedScript.h"
+#include "KURL.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class ScriptSourceCode {
+public:
+ ScriptSourceCode(const String& source, const KURL& url = KURL(), int startLine = 1)
+ : m_source(source)
+ , m_url(url)
+ , m_startLine(startLine)
+ {
+ }
+
+ // We lose the encoding information from CachedScript.
+ // Not sure if that matters.
+ ScriptSourceCode(CachedScript* cs)
+ : m_source(cs->script())
+ , m_url(cs->url())
+ , m_startLine(1)
+ {
+ }
+
+ bool isEmpty() const { return m_source.isEmpty(); }
+
+ const String& source() const { return m_source; }
+ const KURL& url() const { return m_url; }
+ int startLine() const { return m_startLine; }
+
+private:
+ String m_source;
+ KURL m_url;
+ int m_startLine;
+};
+
+} // namespace WebCore
+
+#endif // ScriptSourceCode_h
diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h
new file mode 100644
index 0000000..b5a9578
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptState.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptState_h
+#define ScriptState_h
+
+#include <v8.h>
+
+namespace WebCore {
+ class ScriptState {
+ public:
+ bool hadException() { return !m_exception.IsEmpty(); }
+ void setException(v8::Local<v8::Value> exception)
+ {
+ m_exception = exception;
+ }
+ v8::Local<v8::Value> exception() { return m_exception; }
+
+ private:
+ v8::Local<v8::Value> m_exception;
+ };
+}
+
+#endif // ScriptState_h
diff --git a/WebCore/bindings/v8/ScriptString.h b/WebCore/bindings/v8/ScriptString.h
new file mode 100644
index 0000000..66a575f
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptString.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptString_h
+#define ScriptString_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class ScriptString {
+public:
+ ScriptString(const String& s) : m_str(s) {}
+ ScriptString(const char* s) : m_str(s) {}
+
+ operator String() const { return m_str; }
+
+ bool isNull() const { return m_str.isNull(); }
+ size_t size() const { return m_str.length(); }
+
+ ScriptString& operator=(const char* s)
+ {
+ m_str = s;
+ return *this;
+ }
+
+ ScriptString& operator+=(const String& s)
+ {
+ m_str += s;
+ return *this;
+ }
+
+private:
+ String m_str;
+};
+
+} // namespace WebCore
+
+#endif // ScriptString_h
diff --git a/WebCore/bindings/v8/ScriptValue.cpp b/WebCore/bindings/v8/ScriptValue.cpp
new file mode 100644
index 0000000..af84e99
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptValue.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptValue.h"
+
+#include "V8Binding.h"
+
+namespace WebCore {
+
+bool ScriptValue::getString(String& result) const
+{
+ if (m_value.IsEmpty())
+ return false;
+
+ if (!m_value->IsString())
+ return false;
+
+ result = toWebCoreString(m_value);
+ return true;
+}
+
+String ScriptValue::toString(ScriptState*) const
+{
+ return toWebCoreStringWithNullCheck(m_value);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h
new file mode 100644
index 0000000..bfb11c2
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptValue.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptValue_h
+#define ScriptValue_h
+
+#include "PlatformString.h"
+#include "ScriptState.h"
+
+#include <v8.h>
+
+#ifndef NDEBUG
+#include "V8Proxy.h" // for register and unregister global handles.
+#endif
+
+namespace WebCore {
+
+class ScriptValue {
+public:
+ ScriptValue() {}
+
+ ScriptValue(v8::Handle<v8::Value> value)
+ {
+ if (value.IsEmpty())
+ return;
+
+ m_value = v8::Persistent<v8::Value>::New(value);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value);
+#endif
+ }
+
+ ScriptValue(const ScriptValue& value)
+ {
+ if (value.m_value.IsEmpty())
+ return;
+
+ m_value = v8::Persistent<v8::Value>::New(value.m_value);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value);
+#endif
+ }
+
+ ScriptValue& operator=(const ScriptValue& value)
+ {
+ if (this == &value)
+ return *this;
+
+ clear();
+
+ if (value.m_value.IsEmpty())
+ return *this;
+
+ m_value = v8::Persistent<v8::Value>::New(value.m_value);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value);
+#endif
+
+ return *this;
+ }
+
+ bool operator==(const ScriptValue value) const
+ {
+ return m_value == value.m_value;
+ }
+
+ bool operator!=(const ScriptValue value) const
+ {
+ return !operator==(value);
+ }
+
+ bool isNull() const
+ {
+ return m_value->IsNull();
+ }
+
+ bool isUndefined() const
+ {
+ return m_value->IsUndefined();
+ }
+
+ bool hasNoValue() const
+ {
+ return m_value.IsEmpty();
+ }
+
+ void clear()
+ {
+ if (m_value.IsEmpty())
+ return;
+
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_value);
+#endif
+ m_value.Dispose();
+ m_value.Clear();
+ }
+
+ ~ScriptValue()
+ {
+ clear();
+ }
+
+ v8::Handle<v8::Value> v8Value() const { return m_value; }
+ bool getString(String& result) const;
+ String toString(ScriptState*) const;
+
+private:
+ mutable v8::Persistent<v8::Value> m_value;
+};
+
+} // namespace WebCore
+
+#endif // ScriptValue_h
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
new file mode 100644
index 0000000..83ab856
--- /dev/null
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8AbstractEventListener.h"
+
+#include "Document.h"
+#include "Event.h"
+#include "Frame.h"
+#include "Tokenizer.h"
+#include "V8Binding.h"
+
+namespace WebCore {
+
+V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isInline)
+ : m_isInline(isInline)
+ , m_frame(frame)
+ , m_lineNumber(0)
+ , m_columnNumber(0)
+{
+ if (!m_frame)
+ return;
+
+ // Get the position in the source if any.
+ if (m_isInline && m_frame->document()->tokenizer()) {
+ m_lineNumber = m_frame->document()->tokenizer()->lineNumber();
+ m_columnNumber = m_frame->document()->tokenizer()->columnNumber();
+ }
+}
+
+void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context, Event* event, v8::Handle<v8::Value> jsEvent, bool isWindowEvent)
+{
+ // For compatibility, we store the event object as a property on the window called "event". Because this is the global namespace, we save away any
+ // existing "event" property, and then restore it after executing the javascript handler.
+ v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event");
+ v8::Local<v8::Value> returnValue;
+
+ {
+ // Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire.
+ // Setting and getting the 'event' property on the global object can throw exceptions as well (for instance if accessors that
+ // throw exceptions are defined for 'event' using __defineGetter__ and __defineSetter__ on the global object).
+ v8::TryCatch tryCatch;
+ tryCatch.SetVerbose(true);
+
+ // Save the old 'event' property so we can restore it later.
+ v8::Local<v8::Value> savedEvent = context->Global()->Get(eventSymbol);
+ tryCatch.Reset();
+
+ // Make the event available in the window object.
+ //
+ // FIXME: This does not work as it does with jsc bindings if the window.event property is already set. We need to make sure that property
+ // access is intercepted correctly.
+ context->Global()->Set(eventSymbol, jsEvent);
+ tryCatch.Reset();
+
+ // Call the event handler.
+ returnValue = callListenerFunction(jsEvent, event, isWindowEvent);
+ tryCatch.Reset();
+
+ // Restore the old event. This must be done for all exit paths through this method.
+ if (savedEvent.IsEmpty())
+ context->Global()->Set(eventSymbol, v8::Undefined());
+ else
+ context->Global()->Set(eventSymbol, savedEvent);
+ tryCatch.Reset();
+ }
+
+ ASSERT(!V8Proxy::HandleOutOfMemory() || returnValue.IsEmpty());
+
+ if (returnValue.IsEmpty())
+ return;
+
+ if (!returnValue->IsNull() && !returnValue->IsUndefined() && event->storesResultAsString())
+ event->storeResult(toWebCoreString(returnValue));
+
+ // Prevent default action if the return value is false;
+ // FIXME: Add example, and reference to bug entry.
+ if (m_isInline && returnValue->IsBoolean() && !returnValue->BooleanValue())
+ event->preventDefault();
+}
+
+void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
+{
+ // EventListener could be disconnected from the frame.
+ if (disconnected())
+ return;
+
+ // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
+ // See issue 889829.
+ RefPtr<V8AbstractEventListener> protect(this);
+
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
+ if (context.IsEmpty())
+ return;
+
+ // m_frame can removed by the callback function, protect it until the callback function returns.
+ RefPtr<Frame> protectFrame(m_frame);
+
+ // Enter the V8 context in which to perform the event handling.
+ v8::Context::Scope scope(context);
+
+ // Get the V8 wrapper for the event object.
+ v8::Handle<v8::Value> jsEvent = V8Proxy::EventToV8Object(event);
+
+ invokeEventHandler(context, event, jsEvent, isWindowEvent);
+
+ Document::updateDocumentsRendering();
+}
+
+void V8AbstractEventListener::disposeListenerObject()
+{
+ if (!m_listener.IsEmpty()) {
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_listener);
+#endif
+ m_listener.Dispose();
+ m_listener.Clear();
+ }
+}
+
+v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event, bool isWindowEvent)
+{
+ if (!m_listener.IsEmpty() && !m_listener->IsFunction())
+ return v8::Local<v8::Object>::New(m_listener);
+
+ if (isWindowEvent)
+ return v8::Context::GetCurrent()->Global();
+
+ EventTarget* target = event->currentTarget();
+ v8::Handle<v8::Value> value = V8Proxy::EventTargetToV8Object(target);
+ if (value.IsEmpty())
+ return v8::Local<v8::Object>();
+ return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h
new file mode 100644
index 0000000..0c34a86
--- /dev/null
+++ b/WebCore/bindings/v8/V8AbstractEventListener.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8AbstractEventListener_h
+#define V8AbstractEventListener_h
+
+#include "EventListener.h"
+#include <v8.h>
+
+namespace WebCore {
+
+ class Event;
+ class Frame;
+
+ // There are two kinds of event listeners: HTML or non-HMTL. onload, onfocus, etc (attributes) are always HTML event handler type;
+ // Event listeners added by Window.addEventListener or EventTargetNode::addEventListener are non-HTML type.
+ //
+ // Why does this matter?
+ // WebKit does not allow duplicated HTML event handlers of the same type, but ALLOWs duplicated non-HTML event handlers.
+ class V8AbstractEventListener : public EventListener {
+ public:
+ virtual ~V8AbstractEventListener() { }
+
+ // Returns the owner frame of the listener.
+ Frame* frame() { return m_frame; }
+
+ virtual void handleEvent(Event*, bool isWindowEvent);
+ void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent, bool isWindowEvent);
+
+ // Returns the listener object, either a function or an object.
+ virtual v8::Local<v8::Object> getListenerObject()
+ {
+ return v8::Local<v8::Object>::New(m_listener);
+ }
+
+ // Dispose listener object and clear the handle.
+ void disposeListenerObject();
+
+ virtual bool disconnected() const { return !m_frame; }
+
+ protected:
+ v8::Persistent<v8::Object> m_listener;
+
+ // Indicates if this is an HTML type listener.
+ bool m_isInline;
+
+ private:
+ V8AbstractEventListener(Frame*, bool isInline);
+
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*, bool isWindowEvent) = 0;
+
+ // Get the receiver object to use for event listener call.
+ v8::Local<v8::Object> getReceiverObject(Event*, bool isWindowEvent);
+
+ // Frame to which the event listener is attached to. An event listener must be destroyed before its owner frame is
+ // deleted. See fast/dom/replaceChild.html
+ // FIXME: this could hold m_frame live until the event listener is deleted.
+ Frame* m_frame;
+
+ // Position in the HTML source for HTML event listeners.
+ int m_lineNumber;
+ int m_columnNumber;
+
+ friend class V8EventListener;
+ friend class V8ObjectEventListener;
+ friend class V8LazyEventListener;
+ };
+
+} // namespace WebCore
+
+#endif // V8AbstractEventListener_h
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
new file mode 100644
index 0000000..9fce3f2
--- /dev/null
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -0,0 +1,81 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef V8Binding_h
+#define V8Binding_h
+
+// FIXME: This is a temporary forwarding header until all bindings have migrated
+// over and v8_binding actually becomes V8Binding.
+#include "v8_binding.h"
+
+namespace WebCore {
+
+ // FIXME: Remove once migration is complete.
+ inline int toInt32(v8::Handle<v8::Value> value)
+ {
+ return ToInt32(value);
+ }
+
+ inline float toFloat(v8::Local<v8::Value> value)
+ {
+ return static_cast<float>(value->NumberValue());
+ }
+
+ // FIXME: Remove once migration is complete.
+ inline String toWebCoreString(v8::Handle<v8::Value> obj)
+ {
+ return ToWebCoreString(obj);
+ }
+
+ // FIXME: Remove once migration is complete.
+ inline const uint16_t* fromWebCoreString(const String& str)
+ {
+ return FromWebCoreString(str);
+ }
+
+ // FIXME: Rename valueToStringWithNullCheck once migration is complete.
+ inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
+ {
+ return valueToStringWithNullCheck(value);
+ }
+
+ inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
+ {
+ return value->IsNull() || value->IsUndefined();
+ }
+
+ inline v8::Handle<v8::Boolean> v8Boolean(bool value)
+ {
+ return value ? v8::True() : v8::False();
+ }
+
+}
+
+#endif // V8Binding_h
diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h
new file mode 100644
index 0000000..247c108
--- /dev/null
+++ b/WebCore/bindings/v8/V8Collection.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8Collection_h
+#define V8Collection_h
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+#include <v8.h>
+
+namespace WebCore {
+ // FIXME: These functions should be named using to* since they return the item (get* is used for method that take a ref param).
+ // See https://bugs.webkit.org/show_bug.cgi?id=24664.
+
+ static v8::Handle<v8::Value> getV8Object(void* implementation, v8::Local<v8::Value> implementationType)
+ {
+ if (!implementation)
+ return v8::Handle<v8::Value>();
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(implementationType->Int32Value());
+ if (type == V8ClassIndex::NODE)
+ return V8Proxy::NodeToV8Object(static_cast<Node*>(implementation));
+ return V8Proxy::ToV8Object(type, implementation);
+ }
+
+ template<class T> static v8::Handle<v8::Value> getV8Object(PassRefPtr<T> implementation, v8::Local<v8::Value> implementationType)
+ {
+ return getV8Object(implementation.get(), implementationType);
+ }
+
+ // Returns named property of a collection.
+ template<class Collection, class ItemType> static v8::Handle<v8::Value> getNamedPropertyOfCollection(v8::Local<v8::String> name, v8::Local<v8::Object> object,
+ v8::Local<v8::Value> implementationType)
+ {
+ // FIXME: assert object is a collection type
+ ASSERT(V8Proxy::MaybeDOMWrapper(object));
+ V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(object);
+ ASSERT(wrapperType != V8ClassIndex::NODE);
+ Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, object);
+ String propertyName = toWebCoreString(name);
+ return getV8Object<ItemType>(collection->namedItem(propertyName), implementationType);
+ }
+
+ // A template of named property accessor of collections.
+ template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+ {
+ return getNamedPropertyOfCollection<Collection, ItemType>(name, info.Holder(), info.Data());
+ }
+
+ // A template of named property accessor of HTMLSelectElement and HTMLFormElement.
+ template<class Collection> static v8::Handle<v8::Value> nodeCollectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+ {
+ ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder()));
+ ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE);
+ Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder());
+ String propertyName = toWebCoreString(name);
+ void* implementation = collection->namedItem(propertyName);
+ return getV8Object(implementation, info.Data());
+ }
+
+ // Returns the property at the index of a collection.
+ template<class Collection, class ItemType> static v8::Handle<v8::Value> getIndexedPropertyOfCollection(uint32_t index, v8::Local<v8::Object> object,
+ v8::Local<v8::Value> implementationType)
+ {
+ // FIXME: Assert that object must be a collection type.
+ ASSERT(V8Proxy::MaybeDOMWrapper(object));
+ V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(object);
+ ASSERT(wrapperType != V8ClassIndex::NODE);
+ Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, object);
+ return getV8Object<ItemType>(collection->item(index), implementationType);
+ }
+
+ // A template of index interceptor of collections.
+ template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
+ {
+ return getIndexedPropertyOfCollection<Collection, ItemType>(index, info.Holder(), info.Data());
+ }
+
+ // A template of index interceptor of HTMLSelectElement and HTMLFormElement.
+ template<class Collection> static v8::Handle<v8::Value> nodeCollectionIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
+ {
+ ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder()));
+ ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE);
+ Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder());
+ void* implementation = collection->item(index);
+ return getV8Object(implementation, info.Data());
+ }
+
+ // Get an array containing the names of indexed properties of HTMLSelectElement and HTMLFormElement.
+ template<class Collection> static v8::Handle<v8::Array> nodeCollectionIndexedPropertyEnumerator(const v8::AccessorInfo& info)
+ {
+ ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder()));
+ ASSERT(V8Proxy::GetDOMWrapperType(info.Holder()) == V8ClassIndex::NODE);
+ Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder());
+ int length = collection->length();
+ v8::Handle<v8::Array> properties = v8::Array::New(length);
+ for (int i = 0; i < length; ++i) {
+ // FIXME: Do we need to check that the item function returns a non-null value for this index?
+ v8::Handle<v8::Integer> integer = v8::Integer::New(i);
+ properties->Set(integer, integer);
+ }
+ return properties;
+ }
+
+ // Get an array containing the names of indexed properties in a collection.
+ template<class Collection> static v8::Handle<v8::Array> collectionIndexedPropertyEnumerator(const v8::AccessorInfo& info)
+ {
+ ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder()));
+ V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(info.Holder());
+ Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, info.Holder());
+ int length = collection->length();
+ v8::Handle<v8::Array> properties = v8::Array::New(length);
+ for (int i = 0; i < length; ++i) {
+ // FIXME: Do we need to check that the item function returns a non-null value for this index?
+ v8::Handle<v8::Integer> integer = v8::Integer::New(i);
+ properties->Set(integer, integer);
+ }
+ return properties;
+ }
+
+
+ // A template for indexed getters on collections of strings that should return null if the resulting string is a null string.
+ template<class Collection> static v8::Handle<v8::Value> collectionStringOrNullIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
+ {
+ // FIXME: assert that object must be a collection type
+ ASSERT(V8Proxy::MaybeDOMWrapper(info.Holder()));
+ V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(info.Holder());
+ Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, info.Holder());
+ String result = collection->item(index);
+ return v8StringOrNull(result);
+ }
+
+
+ // Add indexed getter to the function template for a collection.
+ template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
+ {
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>,
+ v8::Integer::New(V8ClassIndex::ToInt(type)));
+ }
+
+
+ // Add named getter to the function template for a collection.
+ template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
+ {
+ desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0, v8::Integer::New(V8ClassIndex::ToInt(type)));
+ }
+
+
+ // Add named and indexed getters to the function template for a collection.
+ template<class Collection, class ItemType> static void setCollectionIndexedAndNamedGetters(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
+ {
+ // If we interceptor before object, accessing 'length' can trigger a webkit assertion error (see fast/dom/HTMLDocument/document-special-properties.html).
+ desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0, v8::Integer::New(V8ClassIndex::ToInt(type)));
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>,
+ v8::Integer::New(V8ClassIndex::ToInt(type)));
+ }
+
+
+ // Add indexed getter returning a string or null to a function template for a collection.
+ template<class Collection> static void setCollectionStringOrNullIndexedGetter(v8::Handle<v8::FunctionTemplate> desc)
+ {
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>);
+ }
+
+} // namespace WebCore
+
+#endif // V8Collection_h
diff --git a/WebCore/bindings/v8/V8Index.h b/WebCore/bindings/v8/V8Index.h
new file mode 100644
index 0000000..58af42e
--- /dev/null
+++ b/WebCore/bindings/v8/V8Index.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8Index_h
+#define V8Index_h
+
+// FIXME: This is a temporary forwarding header until all bindings have migrated
+// over and v8_index actually becomes V8Index.
+#include "v8_index.h"
+
+#endif // V8Index_h
diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp
new file mode 100644
index 0000000..f53370d
--- /dev/null
+++ b/WebCore/bindings/v8/V8LazyEventListener.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8LazyEventListener.h"
+
+#include "Frame.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, const String& functionName)
+ : V8AbstractEventListener(frame, true)
+ , m_code(code)
+ , m_functionName(functionName)
+ , m_compiled(false)
+ , m_wrappedFunctionCompiled(false)
+{
+}
+
+V8LazyEventListener::~V8LazyEventListener()
+{
+ disposeListenerObject();
+
+ // Dispose wrapped function
+ if (!m_wrappedFunction.IsEmpty()) {
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_wrappedFunction);
+#endif
+ m_wrappedFunction.Dispose();
+ m_wrappedFunction.Clear();
+ }
+}
+
+v8::Local<v8::Function> V8LazyEventListener::getListenerFunction()
+{
+ if (m_compiled) {
+ ASSERT(m_listener.IsEmpty() || m_listener->IsFunction());
+ return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+ }
+
+ m_compiled = true;
+
+ ASSERT(m_frame);
+
+ {
+ // Switch to the context of m_frame.
+ v8::HandleScope handleScope;
+
+ // Use the outer scope to hold context.
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
+ // Bail out if we could not get the context.
+ if (context.IsEmpty())
+ return v8::Local<v8::Function>();
+
+ v8::Context::Scope scope(context);
+
+ // Wrap function around the event code. The parenthesis around the function are needed so that evaluating the code yields
+ // the function value. Without the parenthesis the function value is thrown away.
+
+ // Make it an anonymous function to avoid name conflict for cases like
+ // <body onload='onload()'>
+ // <script> function onload() { alert('hi'); } </script>.
+ // Set function name to function object instead.
+ // See issue 944690.
+ //
+ // The ECMAScript spec says (very obliquely) that the parameter to an event handler is named "evt".
+ String code = "(function (evt) {\n";
+ code.append(m_code);
+ code.append("\n})");
+
+ v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
+ v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 1);
+ if (!script.IsEmpty()) {
+ V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+ ASSERT(proxy);
+ v8::Local<v8::Value> value = proxy->RunScript(script, false);
+ if (!value.IsEmpty()) {
+ ASSERT(value->IsFunction());
+ v8::Local<v8::Function> listenerFunction = v8::Local<v8::Function>::Cast(value);
+ listenerFunction->SetName(v8::String::New(FromWebCoreString(m_functionName), m_functionName.length()));
+
+ m_listener = v8::Persistent<v8::Function>::New(listenerFunction);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener);
+#endif
+ }
+ }
+ }
+
+ ASSERT(m_listener.IsEmpty() || m_listener->IsFunction());
+ return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+}
+
+v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
+{
+ v8::Local<v8::Function> handlerFunction = getWrappedListenerFunction();
+ v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent);
+ if (handlerFunction.IsEmpty() || receiver.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::Handle<v8::Value> parameters[1] = { jsEvent };
+
+ V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+ return proxy->CallFunction(handlerFunction, receiver, 1, parameters);
+}
+
+v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction()
+{
+ if (m_wrappedFunctionCompiled) {
+ ASSERT(m_wrappedFunction.IsEmpty() || m_wrappedFunction->IsFunction());
+ return m_wrappedFunction.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(m_wrappedFunction);
+ }
+
+ m_wrappedFunctionCompiled = true;
+
+ {
+ // Switch to the context of m_frame.
+ v8::HandleScope handleScope;
+
+ // Use the outer scope to hold context.
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
+ // Bail out if we cannot get the context.
+ if (context.IsEmpty())
+ return v8::Local<v8::Function>();
+
+ v8::Context::Scope scope(context);
+
+ // FIXME: cache the wrapper function.
+
+ // Nodes other than the document object, when executing inline event handlers push document, form, and the target node on the scope chain.
+ // We do this by using 'with' statement.
+ // See chrome/fast/forms/form-action.html
+ // chrome/fast/forms/selected-index-value.html
+ // base/fast/overflow/onscroll-layer-self-destruct.html
+ String code = "(function (evt) {\n" \
+ " with (this.ownerDocument ? this.ownerDocument : {}) {\n" \
+ " with (this.form ? this.form : {}) {\n" \
+ " with (this) {\n" \
+ " return (function(evt){\n";
+ code.append(m_code);
+ code.append( "\n" \
+ "}).call(this, evt);\n" \
+ " }\n" \
+ " }\n" \
+ " }\n" \
+ "})");
+ v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
+ v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 4);
+ if (!script.IsEmpty()) {
+ V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+ ASSERT(proxy);
+ v8::Local<v8::Value> value = proxy->RunScript(script, false);
+ if (!value.IsEmpty()) {
+ ASSERT(value->IsFunction());
+
+ m_wrappedFunction = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(value));
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction);
+#endif
+ m_wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
+ }
+ }
+ }
+
+ return v8::Local<v8::Function>::New(m_wrappedFunction);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
new file mode 100644
index 0000000..7c7be34
--- /dev/null
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8LazyEventListener_h
+#define V8LazyEventListener_h
+
+#include "PlatformString.h"
+#include "V8AbstractEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+ class Event;
+ class Frame;
+
+ // V8LazyEventListener is a wrapper for a JavaScript code string that is compiled and evaluated when an event is fired.
+ // A V8LazyEventListener is always a HTML event handler.
+ class V8LazyEventListener : public V8AbstractEventListener {
+ public:
+ static PassRefPtr<V8LazyEventListener> create(Frame* frame, const String& code, const String& functionName)
+ {
+ return adoptRef(new V8LazyEventListener(frame, code, functionName));
+ }
+
+ virtual bool isInline() const { return true; }
+
+ // For lazy event listener, the listener object is the same as its listener
+ // function without additional scope chains.
+ virtual v8::Local<v8::Object> getListenerObject() { return getWrappedListenerFunction(); }
+
+ private:
+ V8LazyEventListener(Frame*, const String& code, const String& functionName);
+ virtual ~V8LazyEventListener();
+
+ String m_code;
+ String m_functionName;
+ bool m_compiled;
+
+ // If the event listener is on a non-document dom node, we compile the function with some implicit scope chains before it.
+ bool m_wrappedFunctionCompiled;
+ v8::Persistent<v8::Function> m_wrappedFunction;
+
+ v8::Local<v8::Function> getWrappedListenerFunction();
+
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent);
+
+ v8::Local<v8::Function> getListenerFunction();
+ };
+
+} // namespace WebCore
+
+#endif // V8LazyEventListener_h
diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
new file mode 100644
index 0000000..b5ae30c
--- /dev/null
+++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8NodeFilterCondition.h"
+
+#include "Node.h"
+#include "NodeFilter.h"
+#include "ScriptState.h"
+#include "V8Proxy.h"
+
+#include <wtf/OwnArrayPtr.h>
+
+namespace WebCore {
+
+V8NodeFilterCondition::V8NodeFilterCondition(v8::Handle<v8::Value> filter)
+ : m_filter(v8::Persistent<v8::Value>::New(filter))
+{
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(NODE_FILTER, this, m_filter);
+#endif
+}
+
+V8NodeFilterCondition::~V8NodeFilterCondition()
+{
+#ifndef NDEBUG
+ V8Proxy::UnregisterGlobalHandle(this, m_filter);
+#endif
+ m_filter.Dispose();
+ m_filter.Clear();
+}
+
+short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
+{
+ ASSERT(v8::Context::InContext());
+
+ if (!m_filter->IsFunction())
+ return NodeFilter::FILTER_ACCEPT;
+
+ v8::TryCatch exceptionCatcher;
+
+ v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global();
+ v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(m_filter);
+ OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]);
+ args[0] = V8Proxy::ToV8Object(V8ClassIndex::NODE, node);
+
+ V8Proxy* proxy = V8Proxy::retrieve();
+ ASSERT(proxy);
+
+ v8::Handle<v8::Value> result = proxy->CallFunction(callback, object, 1, args.get());
+
+ if (exceptionCatcher.HasCaught()) {
+ state->setException(exceptionCatcher.Exception());
+ return NodeFilter::FILTER_REJECT;
+ }
+
+ ASSERT(!result.IsEmpty());
+
+ return result->Int32Value();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.h b/WebCore/bindings/v8/V8NodeFilterCondition.h
new file mode 100644
index 0000000..5850b69
--- /dev/null
+++ b/WebCore/bindings/v8/V8NodeFilterCondition.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8NodeFilterCondition_h
+#define V8NodeFilterCondition_h
+
+#include "NodeFilterCondition.h"
+#include <v8.h>
+
+// NodeFilter is a JavaScript function that takes a Node as parameter and returns a short (ACCEPT, SKIP, REJECT) as the result.
+namespace WebCore {
+
+ class Node;
+ class ScriptState;
+
+ // NodeFilterCondition is a wrapper around a NodeFilter JS function.
+ class V8NodeFilterCondition : public NodeFilterCondition {
+ public:
+ explicit V8NodeFilterCondition(v8::Handle<v8::Value> filter);
+ virtual ~V8NodeFilterCondition();
+
+ virtual short acceptNode(ScriptState*, Node*) const;
+
+ private:
+ mutable v8::Persistent<v8::Value> m_filter;
+ };
+
+} // namespace WebCore
+
+#endif // V8NodeFilterCondition_h
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.cpp b/WebCore/bindings/v8/V8ObjectEventListener.cpp
new file mode 100644
index 0000000..584962a
--- /dev/null
+++ b/WebCore/bindings/v8/V8ObjectEventListener.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8ObjectEventListener.h"
+
+#include "Frame.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
+{
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(parameter);
+
+ // Remove the wrapper
+ Frame* frame = listener->frame();
+ if (frame) {
+ V8Proxy* proxy = V8Proxy::retrieve(frame);
+ if (proxy)
+ proxy->RemoveObjectEventListener(listener);
+
+ // Because the listener is no longer in the list, it must be disconnected from the frame to avoid dangling frame pointer
+ // in the destructor.
+ listener->disconnectFrame();
+ }
+ listener->disposeListenerObject();
+}
+
+V8ObjectEventListener::V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
+ : V8EventListener(frame, listener, isInline)
+{
+ m_listener.MakeWeak(this, weakObjectEventListenerCallback);
+}
+
+V8ObjectEventListener::~V8ObjectEventListener()
+{
+ if (m_frame) {
+ ASSERT(!m_listener.IsEmpty());
+ V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+ if (proxy)
+ proxy->RemoveObjectEventListener(this);
+ }
+
+ disposeListenerObject();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.h b/WebCore/bindings/v8/V8ObjectEventListener.h
new file mode 100644
index 0000000..730b96c
--- /dev/null
+++ b/WebCore/bindings/v8/V8ObjectEventListener.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8ObjectEventListener_h
+#define V8ObjectEventListener_h
+
+#include "V8CustomEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+ class Frame;
+
+ // V8ObjectEventListener is a special listener wrapper for objects not in the DOM. It keeps the JS listener as a weak pointer.
+ class V8ObjectEventListener : public V8EventListener {
+ public:
+ static PassRefPtr<V8ObjectEventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
+ {
+ return adoptRef(new V8ObjectEventListener(frame, listener, isInline));
+ }
+
+ protected:
+ V8ObjectEventListener(Frame*, v8::Local<v8::Object> listener, bool isInline);
+ virtual ~V8ObjectEventListener();
+ };
+
+} // namespace WebCore
+
+#endif // V8ObjectEventListener_h
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
new file mode 100644
index 0000000..c21e0dd
--- /dev/null
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8Proxy_h
+#define V8Proxy_h
+
+// FIXME: This is a temporary forwarding header until all bindings have migrated
+// over and v8_proxy actually becomes V8Proxy.
+#include "v8_proxy.h"
+
+namespace WebCore {
+
+ // Used by an interceptor callback that it hasn't found anything to
+ // intercept.
+ inline static v8::Local<v8::Object> notHandledByInterceptor()
+ {
+ return v8::Local<v8::Object>();
+ }
+
+ inline static v8::Local<v8::Boolean> deletionNotHandledByInterceptor()
+ {
+ return v8::Local<v8::Boolean>();
+ }
+
+ // FIXME: Remove once migration is complete.
+ inline static DOMWrapperMap<void>& domObjectMap()
+ {
+ return GetDOMObjectMap();
+ }
+
+ inline v8::Handle<v8::Primitive> throwError(const char* message, V8Proxy::ErrorType type = V8Proxy::TYPE_ERROR)
+ {
+ V8Proxy::ThrowError(type, message);
+ return v8::Undefined();
+ }
+
+ inline v8::Handle<v8::Primitive> throwError(ExceptionCode ec)
+ {
+ V8Proxy::SetDOMException(ec);
+ return v8::Undefined();
+ }
+
+ inline v8::Handle<v8::Primitive> throwError(v8::Local<v8::Value> exception)
+ {
+ v8::ThrowException(exception);
+ return v8::Undefined();
+ }
+
+ template <class T> inline v8::Handle<v8::Object> toV8(PassRefPtr<T> object, v8::Local<v8::Object> holder)
+ {
+ object->ref();
+ V8Proxy::SetJSWrapperForDOMObject(object.get(), v8::Persistent<v8::Object>::New(holder));
+ return holder;
+ }
+
+}
+
+#endif // V8Proxy_h
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
new file mode 100644
index 0000000..ba7a2c0
--- /dev/null
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "V8WorkerContextEventListener.h"
+
+#include "Event.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
+ : V8ObjectEventListener(0, listener, isInline)
+ , m_proxy(proxy)
+{
+}
+
+V8WorkerContextEventListener::~V8WorkerContextEventListener()
+{
+ if (m_proxy)
+ m_proxy->RemoveEventListener(this);
+ disposeListenerObject();
+}
+
+void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent)
+{
+ // Is the EventListener disconnected from the frame?
+ if (disconnected())
+ return;
+
+ // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
+ // See issue 889829.
+ RefPtr<V8AbstractEventListener> protect(this);
+
+ v8::Locker locker;
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = m_proxy->GetContext();
+ if (context.IsEmpty())
+ return;
+
+ // Enter the V8 context in which to perform the event handling.
+ v8::Context::Scope scope(context);
+
+ // Get the V8 wrapper for the event object.
+ v8::Handle<v8::Value> jsEvent = WorkerContextExecutionProxy::EventToV8Object(event);
+
+ invokeEventHandler(context, event, jsEvent, isWindowEvent);
+}
+
+v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
+{
+ v8::Local<v8::Function> handlerFunction = getListenerFunction();
+ if (handlerFunction.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent);
+ v8::Handle<v8::Value> parameters[1] = { jsEvent };
+ v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters);
+
+ m_proxy->trackEvent(event);
+
+ return result;
+}
+
+v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* event, bool isWindowEvent)
+{
+ if (!m_listener.IsEmpty() && !m_listener->IsFunction())
+ return v8::Local<v8::Object>::New(m_listener);
+
+ if (isWindowEvent)
+ return v8::Context::GetCurrent()->Global();
+
+ EventTarget* target = event->currentTarget();
+ v8::Handle<v8::Value> value = WorkerContextExecutionProxy::EventTargetToV8Object(target);
+ if (value.IsEmpty())
+ return v8::Local<v8::Object>();
+ return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
+}
+
+} // namespace WebCore
+
+#endif // WORKERS
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
new file mode 100644
index 0000000..85dae41
--- /dev/null
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8WorkerContextEventListener_h
+#define V8WorkerContextEventListener_h
+
+#if ENABLE(WORKERS)
+
+#include "V8ObjectEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+ class Event;
+ class WorkerContextExecutionProxy;
+
+ class V8WorkerContextEventListener : public V8ObjectEventListener {
+ public:
+ static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
+ {
+ return adoptRef(new V8WorkerContextEventListener(proxy, listener, isInline));
+ }
+ V8WorkerContextEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline);
+
+ virtual ~V8WorkerContextEventListener();
+ virtual void handleEvent(Event*, bool isWindowEvent);
+ virtual bool disconnected() const { return !m_proxy; }
+
+ void disconnect() { m_proxy = 0; }
+
+ private:
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent);
+ v8::Local<v8::Object> getReceiverObject(Event*, bool isWindowEvent);
+ WorkerContextExecutionProxy* m_proxy;
+ };
+
+} // namespace WebCore
+
+#endif // WORKERS
+
+#endif // V8WorkerContextEventListener_h
diff --git a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp
new file mode 100644
index 0000000..dfd5e45
--- /dev/null
+++ b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8XMLHttpRequestUtilities.h"
+
+#include <v8.h>
+
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xmlHttpRequest object.
+void createHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value> value)
+{
+ ASSERT(V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUEST || V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUESTUPLOAD);
+ v8::Local<v8::Value> cache = xmlHttpRequest->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ xmlHttpRequest->SetInternalField(V8Custom::kXMLHttpRequestCacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
+ cacheArray->Set(v8::Integer::New(cacheArray->Length()), value);
+}
+
+void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value> value)
+{
+ ASSERT(V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUEST || V8Proxy::GetDOMWrapperType(xmlHttpRequest) == V8ClassIndex::XMLHTTPREQUESTUPLOAD);
+ v8::Local<v8::Value> cache = xmlHttpRequest->GetInternalField(V8Custom::kXMLHttpRequestCacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cacheArray = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cacheArray->Length() - 1; i >= 0; --i) {
+ v8::Local<v8::Value> cached = cacheArray->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cacheArray->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was never added.
+ ASSERT_NOT_REACHED();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h
new file mode 100644
index 0000000..5a55974
--- /dev/null
+++ b/WebCore/bindings/v8/V8XMLHttpRequestUtilities.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8XMLHttpRequestUtilities_h
+#define V8XMLHttpRequestUtilities_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xmlHttpRequest object.
+void createHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value>);
+void removeHiddenXHRDependency(v8::Local<v8::Object> xmlHttpRequest, v8::Local<v8::Value>);
+
+} // namespace WebCore
+
+#endif // V8XMLHttpRequestUtilities_h
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
new file mode 100644
index 0000000..a46aa24
--- /dev/null
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerContextExecutionProxy.h"
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+#include "Event.h"
+#include "V8WorkerContextEventListener.h"
+#include "WorkerContext.h"
+#include "WorkerLocation.h"
+#include "WorkerNavigator.h"
+#include "WorkerScriptController.h"
+
+namespace WebCore {
+
+static bool isWorkersEnabled = false;
+
+bool WorkerContextExecutionProxy::isWebWorkersEnabled()
+{
+ return isWorkersEnabled;
+}
+
+void WorkerContextExecutionProxy::setIsWebWorkersEnabled(bool value)
+{
+ isWorkersEnabled = value;
+}
+
+WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext)
+ : m_workerContext(workerContext)
+ , m_recursion(0)
+{
+}
+
+WorkerContextExecutionProxy::~WorkerContextExecutionProxy()
+{
+ dispose();
+}
+
+void WorkerContextExecutionProxy::dispose()
+{
+ // Disconnect all event listeners.
+ for (size_t listenerIndex = 0; listenerIndex < m_listeners.size(); ++listenerIndex)
+ m_listeners[listenerIndex]->disconnect();
+
+ m_listeners.clear();
+
+ // Detach all events from their JS wrappers.
+ for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) {
+ Event* event = m_events[eventIndex];
+ if (forgetV8EventObject(event))
+ event->deref();
+ }
+ m_events.clear();
+
+ // Dispose the context.
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
+ }
+
+ // Remove the wrapping between JS object and DOM object. This is because
+ // the worker context object is going to be disposed immediately when a
+ // worker thread is tearing down. We do not want to re-delete the real object
+ // when JS object is garbage collected.
+ v8::Locker locker;
+ v8::HandleScope scope;
+ v8::Persistent<v8::Object> wrapper = domObjectMap().get(m_workerContext);
+ if (!wrapper.IsEmpty())
+ V8Proxy::SetDOMWrapper(wrapper, V8ClassIndex::INVALID_CLASS_INDEX, NULL);
+ domObjectMap().forget(m_workerContext);
+}
+
+WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve()
+{
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ v8::Handle<v8::Object> global = context->Global();
+ global = V8Proxy::LookupDOMWrapper(V8ClassIndex::WORKERCONTEXT, global);
+ ASSERT(!global.IsEmpty());
+ WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, global);
+ return workerContext->script()->proxy();
+}
+
+void WorkerContextExecutionProxy::initContextIfNeeded()
+{
+ // Bail out if the context has already been initialized.
+ if (!m_context.IsEmpty())
+ return;
+
+ // Create a new environment
+ v8::Persistent<v8::ObjectTemplate> globalTemplate;
+ m_context = v8::Context::New(NULL, globalTemplate);
+
+ // Starting from now, use local context only.
+ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context);
+ v8::Context::Scope scope(context);
+
+ // Allocate strings used during initialization.
+ v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
+
+ // Create a new JS object and use it as the prototype for the shadow global object.
+ v8::Handle<v8::Function> workerContextConstructor = GetConstructor(V8ClassIndex::WORKERCONTEXT);
+ v8::Local<v8::Object> jsWorkerContext = SafeAllocation::NewInstance(workerContextConstructor);
+ // Bail out if allocation failed.
+ if (jsWorkerContext.IsEmpty()) {
+ dispose();
+ return;
+ }
+
+ // Wrap the object.
+ V8Proxy::SetDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::WORKERCONTEXT), m_workerContext);
+
+ V8Proxy::SetJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
+
+ // Insert the object instance as the prototype of the shadow object.
+ v8::Handle<v8::Object> globalObject = m_context->Global();
+ globalObject->Set(implicitProtoString, jsWorkerContext);
+}
+
+v8::Local<v8::Function> WorkerContextExecutionProxy::GetConstructor(V8ClassIndex::V8WrapperType type)
+{
+ // Enter the context of the proxy to make sure that the function is
+ // constructed in the context corresponding to this proxy.
+ v8::Context::Scope scope(m_context);
+ v8::Handle<v8::FunctionTemplate> functionTemplate = V8Proxy::GetTemplate(type);
+
+ // Getting the function might fail if we're running out of stack or memory.
+ v8::TryCatch tryCatch;
+ v8::Local<v8::Function> value = functionTemplate->GetFunction();
+ if (value.IsEmpty())
+ return v8::Local<v8::Function>();
+
+ return value;
+}
+
+v8::Handle<v8::Value> WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::V8WrapperType type, void* impl)
+{
+ if (!impl)
+ return v8::Null();
+
+ if (type == V8ClassIndex::WORKERCONTEXT)
+ return WorkerContextToV8Object(static_cast<WorkerContext*>(impl));
+
+ // Non DOM node
+ v8::Persistent<v8::Object> result = domObjectMap().get(impl);
+ if (result.IsEmpty()) {
+ v8::Local<v8::Object> object = toV8(type, type, impl);
+ if (!object.IsEmpty()) {
+ switch (type) {
+ case V8ClassIndex::WORKERLOCATION:
+ static_cast<WorkerLocation*>(impl)->ref();
+ break;
+ case V8ClassIndex::WORKERNAVIGATOR:
+ static_cast<WorkerNavigator*>(impl)->ref();
+ break;
+ default:
+ ASSERT(false);
+ }
+ result = v8::Persistent<v8::Object>::New(object);
+ V8Proxy::SetJSWrapperForDOMObject(impl, result);
+ }
+ }
+ return result;
+}
+
+v8::Handle<v8::Value> WorkerContextExecutionProxy::EventToV8Object(Event* event)
+{
+ if (!event)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = domObjectMap().get(event);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::EVENT;
+
+ if (event->isMessageEvent())
+ type = V8ClassIndex::MESSAGEEVENT;
+
+ v8::Handle<v8::Object> result = toV8(type, V8ClassIndex::EVENT, event);
+ if (result.IsEmpty()) {
+ // Instantiation failed. Avoid updating the DOM object map and return null which
+ // is already handled by callers of this function in case the event is NULL.
+ return v8::Null();
+ }
+
+ event->ref(); // fast ref
+ V8Proxy::SetJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result));
+
+ return result;
+}
+
+// A JS object of type EventTarget in the worker context can only be WorkerContext.
+v8::Handle<v8::Value> WorkerContextExecutionProxy::EventTargetToV8Object(EventTarget* target)
+{
+ if (!target)
+ return v8::Null();
+
+ WorkerContext* workerContext = target->toWorkerContext();
+ if (workerContext)
+ return WorkerContextToV8Object(workerContext);
+
+ ASSERT_NOT_REACHED();
+ return v8::Handle<v8::Value>();
+}
+
+v8::Handle<v8::Value> WorkerContextExecutionProxy::WorkerContextToV8Object(WorkerContext* workerContext)
+{
+ if (!workerContext)
+ return v8::Null();
+
+ v8::Handle<v8::Context> context = workerContext->script()->proxy()->GetContext();
+
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ return global;
+}
+
+v8::Local<v8::Object> WorkerContextExecutionProxy::toV8(V8ClassIndex::V8WrapperType descType, V8ClassIndex::V8WrapperType cptrType, void* impl)
+{
+ v8::Local<v8::Function> function;
+ WorkerContextExecutionProxy* proxy = retrieve();
+ if (proxy)
+ function = proxy->GetConstructor(descType);
+ else
+ function = V8Proxy::GetTemplate(descType)->GetFunction();
+
+ v8::Local<v8::Object> instance = SafeAllocation::NewInstance(function);
+ if (!instance.IsEmpty()) {
+ // Avoid setting the DOM wrapper for failed allocations.
+ V8Proxy::SetDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl);
+ }
+ return instance;
+}
+
+bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
+{
+ if (domObjectMap().contains(event)) {
+ domObjectMap().forget(event);
+ return true;
+ } else
+ return false;
+}
+
+v8::Local<v8::Value> WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine)
+{
+ v8::Locker locker;
+ v8::HandleScope hs;
+
+ initContextIfNeeded();
+ v8::Context::Scope scope(m_context);
+
+ v8::Local<v8::String> scriptString = v8ExternalString(script);
+ v8::Handle<v8::Script> compiledScript = V8Proxy::CompileScript(scriptString, fileName, baseLine);
+ return runScript(compiledScript);
+}
+
+v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Script> script)
+{
+ if (script.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ // Compute the source string and prevent against infinite recursion.
+ if (m_recursion >= kMaxRecursionDepth) {
+ v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')");
+ script = V8Proxy::CompileScript(code, "", 0);
+ }
+
+ if (V8Proxy::HandleOutOfMemory())
+ ASSERT(script.IsEmpty());
+
+ if (script.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ // Run the script and keep track of the current recursion depth.
+ v8::Local<v8::Value> result;
+ {
+ m_recursion++;
+ result = script->Run();
+ m_recursion--;
+ }
+
+ // Handle V8 internal error situation (Out-of-memory).
+ if (result.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ return result;
+}
+
+PassRefPtr<V8EventListener> WorkerContextExecutionProxy::FindOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
+{
+ if (!object->IsObject())
+ return 0;
+
+ for (size_t index = 0; index < m_listeners.size(); ++index) {
+ V8EventListener* el = m_listeners[index];
+ if (el->isInline() == isInline && el->getListenerObject() == object)
+ return el;
+ }
+ if (findOnly)
+ return NULL;
+
+ // Create a new one, and add to cache.
+ RefPtr<V8WorkerContextEventListener> listener = V8WorkerContextEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline);
+ m_listeners.append(listener.get());
+
+ return listener.release();
+}
+
+void WorkerContextExecutionProxy::RemoveEventListener(V8EventListener* listener)
+{
+ for (size_t index = 0; index < m_listeners.size(); ++index) {
+ if (m_listeners[index] == listener) {
+ m_listeners.remove(index);
+ return;
+ }
+ }
+}
+
+void WorkerContextExecutionProxy::trackEvent(Event* event)
+{
+ m_events.append(event);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
new file mode 100644
index 0000000..3023666
--- /dev/null
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef WorkerContextExecutionProxy_h
+#define WorkerContextExecutionProxy_h
+
+#if ENABLE(WORKERS)
+
+#include <v8.h>
+#include "V8Index.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class Event;
+ class EventTarget;
+ class V8EventListener;
+ class V8WorkerContextEventListener;
+ class WorkerContext;
+
+ class WorkerContextExecutionProxy {
+ public:
+ WorkerContextExecutionProxy(WorkerContext*);
+ ~WorkerContextExecutionProxy();
+
+ // FIXME: following function sshould have camelCased names once V8 code-generating script is migrated.
+ v8::Local<v8::Context> GetContext() { return v8::Local<v8::Context>::New(m_context); }
+ v8::Local<v8::Function> GetConstructor(V8ClassIndex::V8WrapperType);
+ PassRefPtr<V8EventListener> FindOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly);
+ void RemoveEventListener(V8EventListener*);
+
+ static v8::Handle<v8::Value> ToV8Object(V8ClassIndex::V8WrapperType type, void* impl);
+ static v8::Handle<v8::Value> EventToV8Object(Event* event);
+ static v8::Handle<v8::Value> EventTargetToV8Object(EventTarget* target);
+ static v8::Handle<v8::Value> WorkerContextToV8Object(WorkerContext* wc);
+
+ // Track the event so that we can detach it from the JS wrapper when a worker
+ // terminates. This is needed because we need to be able to dispose these
+ // events and releases references to their event targets: WorkerContext.
+ void trackEvent(Event*);
+
+ // Evaluate a script file in the current execution environment.
+ v8::Local<v8::Value> evaluate(const String& script, const String& fileName, int baseLine);
+
+ // Returns WorkerContext object.
+ WorkerContext* workerContext() { return m_workerContext; }
+
+ // Returns WorkerContextExecutionProxy object of the currently executing context.
+ static WorkerContextExecutionProxy* retrieve();
+
+ // Enables HTML5 worker support.
+ static bool isWebWorkersEnabled();
+ static void setIsWebWorkersEnabled(bool);
+
+ private:
+ void initContextIfNeeded();
+ void dispose();
+
+ // Run an already compiled script.
+ v8::Local<v8::Value> runScript(v8::Handle<v8::Script>);
+
+ static v8::Local<v8::Object> toV8(V8ClassIndex::V8WrapperType descType, V8ClassIndex::V8WrapperType cptrType, void* impl);
+
+ static bool forgetV8EventObject(Event*);
+
+ WorkerContext* m_workerContext;
+ v8::Persistent<v8::Context> m_context;
+ int m_recursion;
+
+ Vector<V8WorkerContextEventListener*> m_listeners;
+ Vector<Event*> m_events;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerContextExecutionProxy_h
diff --git a/WebCore/bindings/v8/WorkerScriptController.cpp b/WebCore/bindings/v8/WorkerScriptController.cpp
new file mode 100644
index 0000000..85bee0a
--- /dev/null
+++ b/WebCore/bindings/v8/WorkerScriptController.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerScriptController.h"
+
+#include <v8.h>
+
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "DOMTimer.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+#include "WorkerObjectProxy.h"
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+WorkerScriptController::WorkerScriptController(WorkerContext* workerContext)
+ : m_workerContext(workerContext)
+ , m_proxy(new WorkerContextExecutionProxy(workerContext))
+ , m_executionForbidden(false)
+{
+}
+
+WorkerScriptController::~WorkerScriptController()
+{
+}
+
+ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
+{
+ {
+ MutexLocker lock(m_sharedDataMutex);
+ if (m_executionForbidden)
+ return ScriptValue();
+ }
+
+ v8::Local<v8::Value> result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startLine() - 1);
+ m_workerContext->thread()->workerObjectProxy()->reportPendingActivity(m_workerContext->hasPendingActivity());
+ return ScriptValue();
+}
+
+ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* /* exception */)
+{
+ // FIXME: Need to return an exception.
+ return evaluate(sourceCode);
+}
+
+void WorkerScriptController::forbidExecution()
+{
+ // This function is called from another thread.
+ MutexLocker lock(m_sharedDataMutex);
+ m_executionForbidden = true;
+}
+
+void WorkerScriptController::setException(ScriptValue /* exception */)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/WorkerScriptController.h b/WebCore/bindings/v8/WorkerScriptController.h
new file mode 100644
index 0000000..07e224c
--- /dev/null
+++ b/WebCore/bindings/v8/WorkerScriptController.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerScriptController_h
+#define WorkerScriptController_h
+
+#if ENABLE(WORKERS)
+
+#include <wtf/OwnPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+ class ScriptSourceCode;
+ class ScriptValue;
+ class WorkerContext;
+ class WorkerContextExecutionProxy;
+
+ class WorkerScriptController {
+ public:
+ WorkerScriptController(WorkerContext*);
+ ~WorkerScriptController();
+
+ WorkerContextExecutionProxy* proxy() { return m_proxy.get(); }
+
+ ScriptValue evaluate(const ScriptSourceCode&);
+ ScriptValue evaluate(const ScriptSourceCode&, ScriptValue* exception);
+
+ void setException(ScriptValue);
+
+ void forbidExecution();
+
+ private:
+ WorkerContext* m_workerContext;
+ OwnPtr<WorkerContextExecutionProxy> m_proxy;
+
+ Mutex m_sharedDataMutex;
+ bool m_executionForbidden;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerScriptController_h
diff --git a/WebCore/bindings/v8/custom/V8AttrCustom.cpp b/WebCore/bindings/v8/custom/V8AttrCustom.cpp
new file mode 100644
index 0000000..f34a441
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8AttrCustom.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Attr.h"
+
+#include "Element.h"
+#include "ExceptionCode.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_SETTER(AttrValue)
+{
+ Attr* imp = V8Proxy::DOMWrapperToNode<Attr>(info.Holder());
+ String attrValue = toWebCoreStringWithNullCheck(value);
+ Element* ownerElement = imp->ownerElement();
+
+ if (ownerElement && !allowSettingSrcToJavascriptURL(ownerElement, imp->name(), attrValue))
+ return;
+
+ ExceptionCode ec = 0;
+ imp->setValue(attrValue, ec);
+ if (ec)
+ throwError(ec);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
new file mode 100644
index 0000000..c86f924
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CSSStyleDeclaration.h"
+
+#include "CSSValue.h"
+#include "CSSPrimitiveValue.h"
+#include "EventTarget.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/ASCIICType.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+// FIXME: Next two functions look lifted verbatim from JSCSSStyleDeclarationCustom. Please remove duplication.
+
+// Check for a CSS prefix.
+// Passed prefix is all lowercase.
+// First character of the prefix within the property name may be upper or lowercase.
+// Other characters in the prefix within the property name must be lowercase.
+// The prefix within the property name must be followed by a capital letter.
+static bool hasCSSPropertyNamePrefix(const String& propertyName, const char* prefix)
+{
+#ifndef NDEBUG
+ ASSERT(*prefix);
+ for (const char* p = prefix; *p; ++p)
+ ASSERT(WTF::isASCIILower(*p));
+ ASSERT(propertyName.length());
+#endif
+
+ if (WTF::toASCIILower(propertyName[0]) != prefix[0])
+ return false;
+
+ unsigned length = propertyName.length();
+ for (unsigned i = 1; i < length; ++i) {
+ if (!prefix[i])
+ return WTF::isASCIIUpper(propertyName[i]);
+ if (propertyName[i] != prefix[i])
+ return false;
+ }
+ return false;
+}
+
+// When getting properties on CSSStyleDeclarations, the name used from
+// Javascript and the actual name of the property are not the same, so
+// we have to do the following translation. The translation turns upper
+// case characters into lower case characters and inserts dashes to
+// separate words.
+//
+// Example: 'backgroundPositionY' -> 'background-position-y'
+//
+// Also, certain prefixes such as 'pos', 'css-' and 'pixel-' are stripped
+// and the hadPixelOrPosPrefix out parameter is used to indicate whether or
+// not the property name was prefixed with 'pos-' or 'pixel-'.
+static String cssPropertyName(const String& propertyName, bool& hadPixelOrPosPrefix)
+{
+ hadPixelOrPosPrefix = false;
+
+ unsigned length = propertyName.length();
+ if (!length)
+ return String();
+
+ Vector<UChar> name;
+ name.reserveCapacity(length);
+
+ unsigned i = 0;
+
+ if (hasCSSPropertyNamePrefix(propertyName, "css"))
+ i += 3;
+ else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
+ i += 5;
+ hadPixelOrPosPrefix = true;
+ } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
+ i += 3;
+ hadPixelOrPosPrefix = true;
+ } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
+ || hasCSSPropertyNamePrefix(propertyName, "khtml")
+ || hasCSSPropertyNamePrefix(propertyName, "apple"))
+ name.append('-');
+ else if (WTF::isASCIIUpper(propertyName[0]))
+ return String();
+
+ name.append(WTF::toASCIILower(propertyName[i++]));
+
+ for (; i < length; ++i) {
+ UChar c = propertyName[i];
+ if (!WTF::isASCIIUpper(c))
+ name.append(c);
+ else {
+ name.append('-');
+ name.append(WTF::toASCIILower(c));
+ }
+ }
+
+ return String::adopt(name);
+}
+
+NAMED_PROPERTY_GETTER(CSSStyleDeclaration)
+{
+ INC_STATS("DOM.CSSStyleDeclaration.NamedPropertyGetter");
+ // First look for API defined attributes on the style declaration object.
+ if (info.Holder()->HasRealNamedCallbackProperty(name))
+ return notHandledByInterceptor();
+
+ // Search the style declaration.
+ CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder());
+
+ bool hadPixelOrPosPrefix = false;
+ String propertyName = cssPropertyName(toWebCoreString(name), hadPixelOrPosPrefix);
+
+ // Do not handle non-property names.
+ if (!CSSStyleDeclaration::isPropertyName(propertyName))
+ return notHandledByInterceptor();
+
+
+ RefPtr<CSSValue> cssValue = imp->getPropertyCSSValue(propertyName);
+ if (cssValue) {
+ if (hadPixelOrPosPrefix && cssValue->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
+ return v8::Number::New(static_cast<CSSPrimitiveValue*>(cssValue.get())->getFloatValue(CSSPrimitiveValue::CSS_PX));
+ return v8StringOrNull(cssValue->cssText());
+ }
+
+ String result = imp->getPropertyValue(propertyName);
+ if (result.isNull())
+ result = ""; // convert null to empty string.
+
+ // The 'filter' attribute is made undetectable in KJS/WebKit
+ // to avoid confusion with IE's filter extension.
+ if (propertyName == "filter")
+ return v8UndetectableString(result);
+
+ return v8String(result);
+}
+
+NAMED_PROPERTY_SETTER(CSSStyleDeclaration)
+{
+ INC_STATS("DOM.CSSStyleDeclaration.NamedPropertySetter");
+ CSSStyleDeclaration* imp = V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder());
+
+ bool hadPixelOrPosPrefix = false;
+ String prop = cssPropertyName(toWebCoreString(name), hadPixelOrPosPrefix);
+ if (!CSSStyleDeclaration::isPropertyName(prop))
+ return notHandledByInterceptor();
+
+ String propertyValue = valueToStringWithNullCheck(value);
+ if (hadPixelOrPosPrefix)
+ propertyValue.append("px");
+
+ ExceptionCode ec = 0;
+ imp->setProperty(prop, propertyValue, ec);
+
+ if (ec)
+ throwError(ec);
+
+ return value;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
new file mode 100644
index 0000000..0570e0e
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CanvasRenderingContext2D.h"
+
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasStyle.h"
+
+#include "V8Binding.h"
+#include "V8CanvasGradient.h"
+#include "V8CanvasPattern.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+static v8::Handle<v8::Value> toV8(CanvasStyle* style)
+{
+ if (style->canvasGradient())
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASGRADIENT, style->canvasGradient());
+
+ if (style->canvasPattern())
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, style->canvasPattern());
+
+ return v8String(style->color());
+}
+
+static PassRefPtr<CanvasStyle> toCanvasStyle(v8::Handle<v8::Value> value)
+{
+ if (value->IsString())
+ return CanvasStyle::create(toWebCoreString(value));
+
+ if (V8CanvasGradient::HasInstance(value))
+ return CanvasStyle::create(V8Proxy::DOMWrapperToNative<CanvasGradient>(value));
+
+ if (V8CanvasPattern::HasInstance(value))
+ return CanvasStyle::create(V8Proxy::DOMWrapperToNative<CanvasPattern>(value));
+
+ return 0;
+}
+
+ACCESSOR_GETTER(CanvasRenderingContext2DStrokeStyle)
+{
+ CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ return toV8(impl->strokeStyle());
+}
+
+ACCESSOR_SETTER(CanvasRenderingContext2DStrokeStyle)
+{
+ CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ impl->setStrokeStyle(toCanvasStyle(value));
+}
+
+ACCESSOR_GETTER(CanvasRenderingContext2DFillStyle)
+{
+ CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ return toV8(impl->fillStyle());
+}
+
+ACCESSOR_SETTER(CanvasRenderingContext2DFillStyle)
+{
+ CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ impl->setFillStyle(toCanvasStyle(value));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp b/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp
new file mode 100644
index 0000000..eff5511
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Clipboard.h"
+
+#include "HTMLImageElement.h"
+#include "HTMLNames.h"
+#include "IntPoint.h"
+#include "Node.h"
+#include "Element.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Node.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(ClipboardTypes)
+{
+ INC_STATS("DOM.Clipboard.types()");
+ Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, info.Holder());
+
+ HashSet<String> types = clipboard->types();
+ if (types.isEmpty())
+ return v8::Null();
+
+ v8::Local<v8::Array> result = v8::Array::New(types.size());
+ HashSet<String>::const_iterator end = types.end();
+ int index = 0;
+ for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it, ++index)
+ result->Set(v8::Integer::New(index), v8String(*it));
+
+ return result;
+}
+
+CALLBACK_FUNC_DECL(ClipboardClearData)
+{
+ INC_STATS("DOM.Clipboard.clearData()");
+ Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+
+ if (!args.Length()) {
+ clipboard->clearAllData();
+ return v8::Undefined();
+ }
+
+ if (args.Length() != 1)
+ return throwError("clearData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+
+ String type = toWebCoreString(args[0]);
+ clipboard->clearData(type);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ClipboardGetData)
+{
+ INC_STATS("DOM.Clipboard.getData()");
+ Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+
+ if (args.Length() != 1)
+ return throwError("getData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+
+ bool success;
+ String result = clipboard->getData(toWebCoreString(args[0]), success);
+ if (success)
+ return v8String(result);
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ClipboardSetData)
+{
+ INC_STATS("DOM.Clipboard.setData()");
+ Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+
+ if (args.Length() != 2)
+ return throwError("setData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+
+ String type = toWebCoreString(args[0]);
+ String data = toWebCoreString(args[1]);
+ return v8Boolean(clipboard->setData(type, data));
+}
+
+CALLBACK_FUNC_DECL(ClipboardSetDragImage)
+{
+ INC_STATS("DOM.Clipboard.setDragImage()");
+ Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+
+ if (!clipboard->isForDragging())
+ return v8::Undefined();
+
+ if (args.Length() != 3)
+ return throwError("setDragImage: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+
+ int x = toInt32(args[1]);
+ int y = toInt32(args[2]);
+
+ Node* node = 0;
+ if (V8Node::HasInstance(args[0]))
+ node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+
+ if (!node || !node->isElementNode())
+ return throwError("setDragImageFromElement: Invalid first argument");
+
+ if (static_cast<Element*>(node)->hasLocalName(HTMLNames::imgTag) && !node->inDocument())
+ clipboard->setDragImage(static_cast<HTMLImageElement*>(node)->cachedImage(), IntPoint(x, y));
+ else
+ clipboard->setDragImageElement(node, IntPoint(x, y));
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.cpp b/WebCore/bindings/v8/custom/V8CustomBinding.cpp
new file mode 100644
index 0000000..841382b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomBinding.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomBinding.h"
+
+#include "Element.h"
+#include "Document.h"
+#include "HTMLNames.h"
+#include "HTMLFrameElementBase.h"
+#include "CSSHelper.h"
+
+namespace WebCore {
+
+bool allowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase* frame, String value)
+{
+ if (protocolIs(parseURL(value), "javascript")) {
+ Node* contentDoc = frame->contentDocument();
+ if (contentDoc && !V8Proxy::CheckNodeSecurity(contentDoc))
+ return false;
+ }
+ return true;
+}
+
+bool allowSettingSrcToJavascriptURL(Element* element, String name, String value)
+{
+ if ((element->hasTagName(HTMLNames::iframeTag) || element->hasTagName(HTMLNames::frameTag)) && equalIgnoringCase(name, "src"))
+ return allowSettingFrameSrcToJavascriptUrl(static_cast<HTMLFrameElementBase*>(element), value);
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h
new file mode 100644
index 0000000..20fa6a1
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomBinding.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomBinding_h
+#define V8CustomBinding_h
+
+// FIXME: This is a temporary forwarding header until all bindings have migrated
+// over and v8_custom actually becomes V8CustomBinding.
+#include "v8_custom.h"
+
+namespace WebCore {
+
+ class HTMLFrameElementBase;
+ class Element;
+ class String;
+
+ bool allowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase*, String value);
+ bool allowSettingSrcToJavascriptURL(Element*, String name, String value);
+
+} // namespace WebCore
+
+#endif // V8CustomBinding_h
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
new file mode 100644
index 0000000..68c8328
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomEventListener.h"
+
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
+ : V8AbstractEventListener(frame, isInline)
+{
+ m_listener = v8::Persistent<v8::Object>::New(listener);
+#ifndef NDEBUG
+ V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener);
+#endif
+}
+
+V8EventListener::~V8EventListener()
+{
+ if (m_frame) {
+ V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+ if (proxy)
+ proxy->RemoveV8EventListener(this);
+ }
+
+ disposeListenerObject();
+}
+
+v8::Local<v8::Function> V8EventListener::getListenerFunction()
+{
+ // Has the listener been disposed?
+ if (m_listener.IsEmpty())
+ return v8::Local<v8::Function>();
+
+ if (m_listener->IsFunction())
+ return v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+
+ if (m_listener->IsObject()) {
+ v8::Local<v8::Value> property = m_listener->Get(v8::String::NewSymbol("handleEvent"));
+ if (property->IsFunction())
+ return v8::Local<v8::Function>::Cast(property);
+ }
+
+ return v8::Local<v8::Function>();
+}
+
+v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
+{
+ v8::Local<v8::Function> handlerFunction = getListenerFunction();
+ v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent);
+ if (handlerFunction.IsEmpty() || receiver.IsEmpty())
+ return v8::Local<v8::Value>();
+
+ v8::Handle<v8::Value> parameters[1] = { jsEvent };
+
+ V8Proxy* proxy = V8Proxy::retrieve(m_frame);
+ return proxy->CallFunction(handlerFunction, receiver, 1, parameters);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h
new file mode 100644
index 0000000..1e613d0
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomEventListener_h
+#define V8CustomEventListener_h
+
+#include "V8AbstractEventListener.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+ class Event;
+ class Frame;
+
+ // V8EventListener is a wrapper of a JS object implements EventListener interface (has handleEvent(event) method), or a JS function
+ // that can handle the event.
+ class V8EventListener : public V8AbstractEventListener {
+ public:
+ static PassRefPtr<V8EventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
+ {
+ return adoptRef(new V8EventListener(frame, listener, isInline));
+ }
+
+ virtual bool isInline() const { return m_isInline; }
+
+ // Detach the listener from its owner frame.
+ void disconnectFrame() { m_frame = 0; }
+
+ protected:
+ V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isInline);
+ virtual ~V8EventListener();
+ v8::Local<v8::Function> getListenerFunction();
+
+ private:
+ virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent);
+ };
+
+} // namespace WebCore
+
+#endif // V8CustomEventListener_h
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
new file mode 100644
index 0000000..bf07416
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomSQLStatementCallback.h"
+
+#include "Frame.h"
+#include "V8CustomVoidCallback.h"
+
+namespace WebCore {
+
+V8CustomSQLStatementCallback::V8CustomSQLStatementCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+{
+}
+
+V8CustomSQLStatementCallback::~V8CustomSQLStatementCallback()
+{
+ m_callback.Dispose();
+}
+
+void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Value> argv[] = {
+ V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction),
+ V8Proxy::ToV8Object(V8ClassIndex::SQLRESULTSET, resultSet)
+ };
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ bool callbackReturnValue = false;
+ raisedException = invokeCallback(m_callback, 2, argv, callbackReturnValue);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
new file mode 100644
index 0000000..5c4b368
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomSQLStatementCallback_h
+#define V8CustomSQLStatementCallback_h
+
+#include "SQLStatementCallback.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8CustomSQLStatementCallback : public SQLStatementCallback {
+public:
+ static PassRefPtr<V8CustomSQLStatementCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8CustomSQLStatementCallback(value->ToObject(), frame));
+ }
+ virtual ~V8CustomSQLStatementCallback();
+
+ virtual void handleEvent(SQLTransaction*, SQLResultSet*, bool& raisedException);
+private:
+ V8CustomSQLStatementCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+};
+
+} // namespace WebCore
+
+#endif // V8CustomSQLStatementCallback_h
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
new file mode 100644
index 0000000..908d21c
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomSQLStatementErrorCallback.h"
+
+#include "Frame.h"
+#include "V8CustomVoidCallback.h"
+
+namespace WebCore {
+
+V8CustomSQLStatementErrorCallback::V8CustomSQLStatementErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+{
+}
+
+V8CustomSQLStatementErrorCallback::~V8CustomSQLStatementErrorCallback()
+{
+ m_callback.Dispose();
+}
+
+bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ if (context.IsEmpty())
+ return true;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Value> argv[] = {
+ V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction),
+ V8Proxy::ToV8Object(V8ClassIndex::SQLERROR, error)
+ };
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ bool callbackReturnValue = false;
+ // Step 6: If the error callback returns false, then move on to the next
+ // statement, if any, or onto the next overall step otherwise. Otherwise,
+ // the error callback did not return false, or there was no error callback.
+ // Jump to the last step in the overall steps.
+ return invokeCallback(m_callback, 2, argv, callbackReturnValue) && !callbackReturnValue;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
new file mode 100644
index 0000000..7dc8114
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomSQLStatementErrorCallback_h
+#define V8CustomSQLStatementErrorCallback_h
+
+#include "SQLStatementErrorCallback.h"
+
+#include "SQLStatementErrorCallback.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8CustomSQLStatementErrorCallback : public SQLStatementErrorCallback {
+public:
+ static PassRefPtr<V8CustomSQLStatementErrorCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8CustomSQLStatementErrorCallback(value->ToObject(), frame));
+ }
+ virtual ~V8CustomSQLStatementErrorCallback();
+
+ virtual bool handleEvent(SQLTransaction*, SQLError*);
+private:
+ V8CustomSQLStatementErrorCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+};
+
+} // namespace WebCore
+
+#endif // V8CustomSQLStatementErrorCallback_h
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
new file mode 100644
index 0000000..a45f3c9
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomSQLTransactionCallback.h"
+
+#include "Frame.h"
+#include "V8CustomVoidCallback.h"
+
+namespace WebCore {
+
+V8CustomSQLTransactionCallback::V8CustomSQLTransactionCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+{
+}
+
+V8CustomSQLTransactionCallback::~V8CustomSQLTransactionCallback()
+{
+ m_callback.Dispose();
+}
+
+
+void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Value> argv[] = {
+ V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction)
+ };
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ // Step 5: If the callback couldn't be called (e.g. it was null) or if
+ // the callback was invoked and raised an exception, jump to the last
+ // step (rollback transaction).
+ bool callbackReturnValue = false;
+ raisedException = invokeCallback(m_callback, 1, argv, callbackReturnValue);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
new file mode 100644
index 0000000..35497e0
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomSQLTransactionCallback_h
+#define V8CustomSQLTransactionCallback_h
+
+#include "SQLTransactionCallback.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8CustomSQLTransactionCallback : public SQLTransactionCallback {
+public:
+ static PassRefPtr<V8CustomSQLTransactionCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8CustomSQLTransactionCallback(value->ToObject(), frame));
+ }
+ virtual ~V8CustomSQLTransactionCallback();
+
+ virtual void handleEvent(SQLTransaction*, bool& raisedException);
+private:
+ V8CustomSQLTransactionCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+};
+
+} // namespace WebCore
+
+#endif // V8CustomSQLTransactionCallback_h
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
new file mode 100644
index 0000000..f1ad740
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomSQLTransactionErrorCallback.h"
+
+#include "Frame.h"
+#include "V8CustomVoidCallback.h"
+
+namespace WebCore {
+
+V8CustomSQLTransactionErrorCallback::V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+{
+}
+
+V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback()
+{
+ m_callback.Dispose();
+}
+
+bool V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ if (context.IsEmpty())
+ return true;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Value> argv[] = {
+ V8Proxy::ToV8Object(V8ClassIndex::SQLERROR, error)
+ };
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ bool callbackReturnValue = false;
+ invokeCallback(m_callback, 1, argv, callbackReturnValue);
+
+ // FIXME: Eliminate return value once SQLTransactionErrorCallback is changed
+ // to match the spec.
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
new file mode 100644
index 0000000..bbf5a749
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomSQLTransactionErrorCallback_h
+#define V8CustomSQLTransactionErrorCallback_h
+
+#include "SQLTransactionErrorCallback.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8CustomSQLTransactionErrorCallback : public SQLTransactionErrorCallback {
+public:
+ static PassRefPtr<V8CustomSQLTransactionErrorCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8CustomSQLTransactionErrorCallback(value->ToObject(), frame));
+ }
+ virtual ~V8CustomSQLTransactionErrorCallback();
+
+ virtual bool handleEvent(SQLError*);
+
+private:
+ V8CustomSQLTransactionErrorCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+};
+
+} // namespace WebCore
+
+#endif // V8CustomSQLTransactionErrorCallback_h
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
new file mode 100644
index 0000000..b4daebd
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8CustomVoidCallback.h"
+
+#include "Frame.h"
+
+namespace WebCore {
+
+V8CustomVoidCallback::V8CustomVoidCallback(v8::Local<v8::Object> callback, Frame* frame)
+ : m_callback(v8::Persistent<v8::Object>::New(callback))
+ , m_frame(frame)
+{
+}
+
+V8CustomVoidCallback::~V8CustomVoidCallback()
+{
+ m_callback.Dispose();
+}
+
+void V8CustomVoidCallback::handleEvent()
+{
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+
+ // Protect the frame until the callback returns.
+ RefPtr<Frame> protector(m_frame);
+
+ bool callbackReturnValue = false;
+ invokeCallback(m_callback, 0, 0, callbackReturnValue);
+}
+
+bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue)
+{
+ // FIXME: If an exception was thrown by the callback, we should report it
+ v8::TryCatch exceptionCatcher;
+
+ v8::Local<v8::Function> callbackFunction;
+ if (callback->IsFunction()) {
+ callbackFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(callback));
+ } else if (callback->IsObject()) {
+ v8::Local<v8::Value> handleEventFunction = callback->Get(v8::String::NewSymbol("handleEvent"));
+ if (handleEventFunction->IsFunction()) {
+ callbackFunction = v8::Local<v8::Function>::Cast(handleEventFunction);
+ }
+ } else
+ return false;
+
+ if (callbackFunction.IsEmpty())
+ return false;
+
+ v8::Handle<v8::Object> thisObject = v8::Context::GetCurrent()->Global();
+
+ V8Proxy* proxy = V8Proxy::retrieve();
+ ASSERT(proxy);
+
+ v8::Handle<v8::Value> result = proxy->CallFunction(callbackFunction, thisObject, argc, argv);
+
+ callbackReturnValue = result.IsEmpty() && result->IsBoolean() && result->BooleanValue();
+
+ return exceptionCatcher.HasCaught();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.h b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
new file mode 100644
index 0000000..586296b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8CustomVoidCallback_h
+#define V8CustomVoidCallback_h
+
+#include "VoidCallback.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+
+class V8CustomVoidCallback : public VoidCallback {
+public:
+ static PassRefPtr<V8CustomVoidCallback> create(v8::Local<v8::Value> value, Frame* frame)
+ {
+ ASSERT(value->IsObject());
+ return adoptRef(new V8CustomVoidCallback(value->ToObject(), frame));
+ }
+ virtual ~V8CustomVoidCallback();
+
+ virtual void handleEvent();
+
+private:
+ V8CustomVoidCallback(v8::Local<v8::Object>, Frame*);
+
+ v8::Persistent<v8::Object> m_callback;
+ RefPtr<Frame> m_frame;
+};
+
+// Returns false if callback failed (null, wrong type, or threw exception).
+bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8::Value> argv[], bool& callbackReturnValue);
+
+} // namespace WebCore
+
+#endif // V8CustomVoidCallback_h
diff --git a/WebCore/svg/graphics/skia/SVGResourceMaskerSkia.cpp b/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp
index 06e6833..f96b889 100644
--- a/WebCore/svg/graphics/skia/SVGResourceMaskerSkia.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2008, Google Inc. All rights reserved.
- *
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * 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
@@ -29,21 +29,17 @@
*/
#include "config.h"
+#include "DOMParser.h"
-#if ENABLE(SVG)
-#include "SVGResourceMasker.h"
-#include "ImageBuffer.h"
-#include "GraphicsContext.h"
-
-#include "NotImplemented.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
namespace WebCore {
-void SVGResourceMasker::applyMask(GraphicsContext*, const FloatRect& boundingBox)
+CALLBACK_FUNC_DECL(DOMParserConstructor)
{
- notImplemented();
+ INC_STATS("DOM.DOMParser.Contructor");
+ return V8Proxy::ConstructDOMObject<V8ClassIndex::DOMPARSER, DOMParser>(args);
}
} // namespace WebCore
-
-#endif
diff --git a/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp b/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp
new file mode 100644
index 0000000..52d4399
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DOMStringList.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+INDEXED_PROPERTY_GETTER(DOMStringList)
+{
+ INC_STATS("DOM.DOMStringList.IndexedPropertyGetter");
+ DOMStringList* imp = V8Proxy::DOMWrapperToNative<DOMStringList>(info.Holder());
+ return v8String(imp->item(index));
+}
+
+CALLBACK_FUNC_DECL(DOMStringListItem)
+{
+ INC_STATS("DOM.DOMStringListItem()");
+ if (!args.Length())
+ return v8::Null();
+
+ uint32_t index = args[0]->Uint32Value();
+
+ DOMStringList* imp = V8Proxy::DOMWrapperToNative<DOMStringList>(args.Holder());
+ if (index >= imp->length())
+ return v8::Null();
+
+ return v8String(imp->item(index));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
new file mode 100644
index 0000000..5962ea3
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+
+#include "Database.h"
+#include "V8CustomSQLTransactionCallback.h"
+#include "V8CustomSQLTransactionErrorCallback.h"
+#include "V8CustomVoidCallback.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(DatabaseChangeVersion)
+{
+ INC_STATS("DOM.Database.changeVersion()");
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(DatabaseTransaction)
+{
+ INC_STATS("DOM.Database.transaction()");
+
+ if (args.Length() == 0) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Transaction callback is required.");
+ return v8::Undefined();
+ }
+
+ if (!args[0]->IsObject()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction callback must be of valid type.");
+ return v8::Undefined();
+ }
+
+ Database* database = V8Proxy::ToNativeObject<Database>(V8ClassIndex::DATABASE, args.Holder());
+
+ Frame* frame = V8Proxy::retrieveFrame();
+
+ RefPtr<V8CustomSQLTransactionCallback> callback = V8CustomSQLTransactionCallback::create(args[0], frame);
+
+ RefPtr<V8CustomSQLTransactionErrorCallback> errorCallback;
+ if (args.Length() > 1) {
+ if (!args[1]->IsObject()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction error callback must be of valid type.");
+ return v8::Undefined();
+ }
+ errorCallback = V8CustomSQLTransactionErrorCallback::create(args[1], frame);
+ }
+
+ RefPtr<V8CustomVoidCallback> successCallback;
+ if (args.Length() > 2) {
+ if (!args[1]->IsObject()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction success callback must be of valid type.");
+ return v8::Undefined();
+ }
+ successCallback = V8CustomVoidCallback::create(args[2], frame);
+ }
+
+ database->transaction(callback.release(), errorCallback.release(), successCallback.release());
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
new file mode 100644
index 0000000..7f868f1
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Document.h"
+
+#include "ExceptionCode.h"
+#include "JSXPathNSResolver.h"
+#include "Node.h"
+#include "XPathNSResolver.h"
+#include "XPathResult.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Node.h"
+#include "V8Proxy.h"
+#include "V8XPathNSResolver.h"
+#include "V8XPathResult.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(DocumentEvaluate)
+{
+ INC_STATS("DOM.Document.evaluate()");
+
+ Document* document = V8Proxy::DOMWrapperToNode<Document>(args.Holder());
+ ExceptionCode ec = 0;
+ String expression = toWebCoreString(args[0]);
+ Node* contextNode = 0;
+ if (V8Node::HasInstance(args[1]))
+ contextNode = V8Proxy::DOMWrapperToNode<Node>(args[1]);
+
+ XPathNSResolver* resolver = 0;
+ if (V8XPathNSResolver::HasInstance(args[2]))
+ resolver = V8Proxy::ToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, args[2]);
+ else if (args[2]->IsObject())
+ resolver = new JSXPathNSResolver(args[2]->ToObject());
+ else if (!args[2]->IsNull() && !args[2]->IsUndefined())
+ return throwError(TYPE_MISMATCH_ERR);
+
+ int type = toInt32(args[3]);
+ XPathResult* inResult = 0;
+ if (V8XPathResult::HasInstance(args[4]))
+ inResult = V8Proxy::ToNativeObject<XPathResult>(V8ClassIndex::XPATHRESULT, args[4]);
+
+ v8::TryCatch exceptionCatcher;
+ RefPtr<XPathResult> result = document->evaluate(expression, contextNode, resolver, type, inResult, ec);
+ if (exceptionCatcher.HasCaught())
+ return throwError(exceptionCatcher.Exception());
+
+ if (ec)
+ return throwError(ec);
+
+ return V8Proxy::ToV8Object(V8ClassIndex::XPATHRESULT, result.get());
+}
+
+CALLBACK_FUNC_DECL(DocumentGetCSSCanvasContext)
+{
+ INC_STATS("DOM.Document.getCSSCanvasContext");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Document* imp = V8Proxy::DOMWrapperToNode<Document>(holder);
+ String contextId = toWebCoreString(args[0]);
+ String name = toWebCoreString(args[1]);
+ int width = toInt32(args[2]);
+ int height = toInt32(args[3]);
+ CanvasRenderingContext2D* result = imp->getCSSCanvasContext(contextId, name, width, height);
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
new file mode 100644
index 0000000..131f401
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Element.h"
+
+#include "Attr.h"
+#include "CSSHelper.h"
+#include "Document.h"
+#include "EventListener.h"
+#include "ExceptionCode.h"
+#include "HTMLFrameElementBase.h"
+#include "HTMLNames.h"
+#include "Node.h"
+
+#include "V8Attr.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(ElementSetAttribute)
+{
+ INC_STATS("DOM.Element.setAttribute()");
+ Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ String name = toWebCoreString(args[0]);
+ String value = toWebCoreString(args[1]);
+
+ if (!allowSettingSrcToJavascriptURL(element, name, value))
+ return v8::Undefined();
+
+ ExceptionCode ec = 0;
+ element->setAttribute(name, value, ec);
+ if (ec)
+ return throwError(ec);
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ElementSetAttributeNode)
+{
+ INC_STATS("DOM.Element.setAttributeNode()");
+ if (!V8Attr::HasInstance(args[0]))
+ throwError(TYPE_MISMATCH_ERR);
+
+ Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]);
+ Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+
+ if (!allowSettingSrcToJavascriptURL(element, newAttr->name(), newAttr->value()))
+ return v8::Undefined();
+
+ ExceptionCode ec = 0;
+ RefPtr<Attr> result = element->setAttributeNode(newAttr, ec);
+ if (ec)
+ throwError(ec);
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+CALLBACK_FUNC_DECL(ElementSetAttributeNS)
+{
+ INC_STATS("DOM.Element.setAttributeNS()");
+ Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ String namespaceURI = toWebCoreStringWithNullCheck(args[0]);
+ String qualifiedName = toWebCoreString(args[1]);
+ String value = toWebCoreString(args[2]);
+
+ if (!allowSettingSrcToJavascriptURL(element, qualifiedName, value))
+ return v8::Undefined();
+
+ ExceptionCode ec = 0;
+ element->setAttributeNS(namespaceURI, qualifiedName, value, ec);
+ if (ec)
+ throwError(ec);
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ElementSetAttributeNodeNS)
+{
+ INC_STATS("DOM.Element.setAttributeNodeNS()");
+ if (!V8Attr::HasInstance(args[0]))
+ return throwError(TYPE_MISMATCH_ERR);
+
+ Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]);
+ Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+
+ if (!allowSettingSrcToJavascriptURL(element, newAttr->name(), newAttr->value()))
+ return v8::Undefined();
+
+ ExceptionCode ec = 0;
+ RefPtr<Attr> result = element->setAttributeNodeNS(newAttr, ec);
+ if (ec)
+ throwError(ec);
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+static inline String toEventType(v8::Local<v8::String> value)
+{
+ String key = toWebCoreString(value);
+ ASSERT(key.startsWith("on"));
+ return key.substring(2);
+}
+
+ACCESSOR_SETTER(ElementEventHandler)
+{
+ Node* node = V8Proxy::DOMWrapperToNode<Node>(info.Holder());
+
+ String eventType = toEventType(name);
+
+ // Set handler if the value is a function. Otherwise, clear the
+ // event handler.
+ if (value->IsFunction()) {
+ V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
+ // the document might be created using createDocument,
+ // which does not have a frame, use the active frame
+ if (!proxy)
+ proxy = V8Proxy::retrieve(V8Proxy::retrieveActiveFrame());
+ if (!proxy)
+ return;
+
+ if (RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(value, true))
+ node->setInlineEventListenerForType(eventType, listener);
+ } else
+ node->removeInlineEventListenerForType(eventType);
+}
+
+ACCESSOR_GETTER(ElementEventHandler)
+{
+ Node* node = V8Proxy::DOMWrapperToNode<Node>(info.Holder());
+
+ EventListener* listener = node->inlineEventListenerForType(toEventType(name));
+ return V8Proxy::EventListenerToV8Object(listener);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8EventCustom.cpp b/WebCore/bindings/v8/custom/V8EventCustom.cpp
new file mode 100644
index 0000000..1dae845
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8EventCustom.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Event.h"
+
+#include "Clipboard.h"
+#include "ClipboardEvent.h"
+#include "MouseEvent.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_SETTER(EventReturnValue)
+{
+ Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ event->setDefaultPrevented(!value->BooleanValue());
+}
+
+ACCESSOR_GETTER(EventDataTransfer)
+{
+ Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+
+ if (event->isDragEvent())
+ return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, static_cast<MouseEvent*>(event)->clipboard());
+
+ return v8::Undefined();
+}
+
+ACCESSOR_GETTER(EventClipboardData)
+{
+ Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+
+ if (event->isClipboardEvent())
+ return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, static_cast<ClipboardEvent*>(event)->clipboard());
+
+ return v8::Undefined();
+}
+
+ACCESSOR_GETTER(EventSrcElement)
+{
+ Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ return V8Proxy::EventTargetToV8Object(event->target());
+}
+
+ACCESSOR_GETTER(EventReturnValue)
+{
+ Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ return event->defaultPrevented() ? v8::False() : v8::True();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
new file mode 100644
index 0000000..cf66e39
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLCanvasElement.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Node.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(HTMLCanvasElementGetContext)
+{
+ INC_STATS("DOM.HTMLCanvasElement.getContext");
+ v8::Handle<v8::Value> holder = args.Holder();
+ HTMLCanvasElement* imp = V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(holder);
+ String contextId = ToWebCoreString(args[0]);
+ CanvasRenderingContext2D* result = imp->getContext(contextId);
+ return V8Proxy::ToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
new file mode 100644
index 0000000..97a3b4f
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLCollection.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8NamedNodesCollection.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, String name)
+{
+ Vector<RefPtr<Node> > namedItems;
+ collection->namedItems(name, namedItems);
+
+ if (!namedItems.size())
+ return v8::Handle<v8::Value>();
+
+ if (namedItems.size() == 1)
+ return V8Proxy::NodeToV8Object(namedItems.at(0).get());
+
+ NodeList* list = new V8NamedNodesCollection(namedItems);
+ return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, list);
+}
+
+static v8::Handle<v8::Value> getItem(HTMLCollection* collection, v8::Handle<v8::Value> argument)
+{
+ v8::Local<v8::Uint32> index = argument->ToArrayIndex();
+ if (index.IsEmpty()) {
+ v8::Handle<v8::Value> result = getNamedItems(collection, toWebCoreString(argument->ToString()));
+
+ if (result.IsEmpty())
+ return v8::Undefined();
+
+ return result;
+ }
+
+ RefPtr<Node> result = collection->item(index->Uint32Value());
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+NAMED_PROPERTY_GETTER(HTMLCollection)
+{
+ INC_STATS("DOM.HTMLCollection.NamedPropertyGetter");
+ // Search the prototype chain first.
+ v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name);
+
+ if (!value.IsEmpty())
+ return value;
+
+ // Search local callback properties next to find IDL defined
+ // properties.
+ if (info.Holder()->HasRealNamedCallbackProperty(name))
+ return v8::Handle<v8::Value>();
+
+ // Finally, search the DOM structure.
+ HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, info.Holder());
+ return getNamedItems(imp, toWebCoreString(name));
+}
+
+CALLBACK_FUNC_DECL(HTMLCollectionItem)
+{
+ INC_STATS("DOM.HTMLCollection.item()");
+ HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
+ return getItem(imp, args[0]);
+}
+
+CALLBACK_FUNC_DECL(HTMLCollectionNamedItem)
+{
+ INC_STATS("DOM.HTMLCollection.namedItem()");
+ HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
+ v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0]));
+
+ if (result.IsEmpty())
+ return v8::Undefined();
+
+ return result;
+}
+
+CALLBACK_FUNC_DECL(HTMLCollectionCallAsFunction)
+{
+ INC_STATS("DOM.HTMLCollection.callAsFunction()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
+
+ if (args.Length() == 1)
+ return getItem(imp, args[0]);
+
+ // If there is a second argument it is the index of the item we want.
+ String name = toWebCoreString(args[0]);
+ v8::Local<v8::Uint32> index = args[1]->ToArrayIndex();
+ if (index.IsEmpty())
+ return v8::Undefined();
+
+ unsigned current = index->Uint32Value();
+ Node* node = imp->namedItem(name);
+ while (node) {
+ if (!current)
+ return V8Proxy::NodeToV8Object(node);
+
+ node = imp->nextNamedItem(name);
+ current--;
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
new file mode 100644
index 0000000..bc04f7e
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLDocument.h"
+
+#include "Frame.h"
+#include "HTMLIFrameElement.h"
+#include "HTMLNames.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+NAMED_PROPERTY_DELETER(HTMLDocument)
+{
+ // Only handle document.all. Insert the marker object into the
+ // shadow internal field to signal that document.all is no longer
+ // shadowed.
+ String key = toWebCoreString(name);
+ if (key != "all")
+ return deletionNotHandledByInterceptor();
+
+ ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount);
+ v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex);
+ info.Holder()->SetInternalField(kHTMLDocumentShadowIndex, marker);
+ return v8::True();
+}
+
+NAMED_PROPERTY_SETTER(HTMLDocument)
+{
+ INC_STATS("DOM.HTMLDocument.NamedPropertySetter");
+ // Only handle document.all. We insert the value into the shadow
+ // internal field from which the getter will retrieve it.
+ String key = toWebCoreString(name);
+ if (key == "all") {
+ ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount);
+ info.Holder()->SetInternalField(kHTMLDocumentShadowIndex, value);
+ }
+ return notHandledByInterceptor();
+}
+
+NAMED_PROPERTY_GETTER(HTMLDocument)
+{
+ INC_STATS("DOM.HTMLDocument.NamedPropertyGetter");
+ AtomicString key = toWebCoreString(name);
+
+ // Special case for document.all. If the value in the shadow
+ // internal field is not the marker object, then document.all has
+ // been temporarily shadowed and we return the value.
+ if (key == "all") {
+ ASSERT(info.Holder()->InternalFieldCount() == kHTMLDocumentInternalFieldCount);
+ v8::Local<v8::Value> marker = info.Holder()->GetInternalField(kHTMLDocumentMarkerIndex);
+ v8::Local<v8::Value> value = info.Holder()->GetInternalField(kHTMLDocumentShadowIndex);
+ if (marker != value)
+ return value;
+ }
+
+ HTMLDocument* imp = V8Proxy::DOMWrapperToNode<HTMLDocument>(info.Holder());
+
+ // Fast case for named elements that are not there.
+ if (!imp->hasNamedItem(key.impl()) && !imp->hasExtraNamedItem(key.impl()))
+ return v8::Handle<v8::Value>();
+
+ RefPtr<HTMLCollection> items = imp->documentNamedItems(key);
+ if (!items->length())
+ return notHandledByInterceptor();
+
+ if (items->length() == 1) {
+ Node* node = items->firstItem();
+ Frame* frame = 0;
+ if (node->hasTagName(HTMLNames::iframeTag) && (frame = static_cast<HTMLIFrameElement*>(node)->contentFrame()))
+ return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
+
+ return V8Proxy::NodeToV8Object(node);
+ }
+
+ return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, items.get());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp
new file mode 100644
index 0000000..454bbc0
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLFormElement.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8NamedNodesCollection.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+NAMED_PROPERTY_GETTER(HTMLFormElement)
+{
+ INC_STATS("DOM.HTMLFormElement.NamedPropertyGetter");
+ HTMLFormElement* imp = V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder());
+ String v = toWebCoreString(name);
+
+ // Call getNamedElements twice, first time check if it has a value
+ // and let HTMLFormElement update its cache.
+ // See issue: 867404
+ {
+ Vector<RefPtr<Node> > elements;
+ imp->getNamedElements(v, elements);
+ if (elements.isEmpty())
+ return v8::Handle<v8::Value>();
+ }
+
+ // Second call may return different results from the first call,
+ // but if the first the size cannot be zero.
+ Vector<RefPtr<Node> > elements;
+ imp->getNamedElements(v, elements);
+ ASSERT(!elements.isEmpty());
+
+ if (elements.size() == 1)
+ return V8Proxy::NodeToV8Object(elements.at(0).get());
+
+ NodeList* collection = new V8NamedNodesCollection(elements);
+ return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, collection);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
new file mode 100644
index 0000000..bfc4c28
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLFrameElement.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_SETTER(HTMLFrameElementSrc)
+{
+ HTMLFrameElement* frame = V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder());
+ String srcValue = toWebCoreStringWithNullCheck(value);
+
+ if (!allowSettingFrameSrcToJavascriptUrl(frame, srcValue))
+ return;
+
+ frame->setSrc(srcValue);
+}
+
+ACCESSOR_SETTER(HTMLFrameElementLocation)
+{
+ HTMLFrameElement* frame = V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder());
+ String locationValue = toWebCoreStringWithNullCheck(value);
+
+ if (!allowSettingFrameSrcToJavascriptUrl(frame, locationValue))
+ return;
+
+ frame->setLocation(locationValue);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp
new file mode 100644
index 0000000..df08542
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLFrameSetElement.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "HTMLCollection.h"
+#include "HTMLFrameElement.h"
+#include "HTMLNames.h"
+#include "Node.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+NAMED_PROPERTY_GETTER(HTMLFrameSetElement)
+{
+ INC_STATS("DOM.HTMLFrameSetElement.NamedPropertyGetter");
+ HTMLFrameSetElement* imp = V8Proxy::DOMWrapperToNode<HTMLFrameSetElement>(info.Holder());
+ Node* frameNode = imp->children()->namedItem(toWebCoreString(name));
+ if (frameNode && frameNode->hasTagName(HTMLNames::frameTag)) {
+ Document* doc = static_cast<HTMLFrameElement*>(frameNode)->contentDocument();
+ if (!doc)
+ return v8::Undefined();
+ if (Frame* frame = doc->frame())
+ return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
+ }
+ return notHandledByInterceptor();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
new file mode 100644
index 0000000..3739a4e
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLIFrameElement.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_SETTER(HTMLIFrameElementSrc)
+{
+ HTMLIFrameElement* iframe = V8Proxy::DOMWrapperToNode<HTMLIFrameElement>(info.Holder());
+ String v = valueToStringWithNullCheck(value);
+
+ if (!allowSettingFrameSrcToJavascriptUrl(iframe, v))
+ return;
+
+ iframe->setSrc(v);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp
new file mode 100644
index 0000000..628634d
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLInputElement.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(HTMLInputElementSelectionStart)
+{
+ INC_STATS("DOM.HTMLInputElement.selectionStart._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+
+ if (!imp->canHaveSelection())
+ return throwError("Accessing selectionStart on an input element that cannot have a selection.");
+
+ int v = imp->selectionStart();
+ return v8::Integer::New(v);
+}
+
+ACCESSOR_SETTER(HTMLInputElementSelectionStart)
+{
+ INC_STATS("DOM.HTMLInputElement.selectionStart._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+
+ if (!imp->canHaveSelection()) {
+ throwError("Accessing selectionStart on an input element that cannot have a selection.");
+ return;
+ }
+ imp->setSelectionStart(value->Int32Value());
+}
+
+ACCESSOR_GETTER(HTMLInputElementSelectionEnd)
+{
+ INC_STATS("DOM.HTMLInputElement.selectionEnd._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+
+ if (!imp->canHaveSelection())
+ return throwError("Accessing selectionEnd on an input element that cannot have a selection.");
+
+ int v = imp->selectionEnd();
+ return v8::Integer::New(v);
+}
+
+ACCESSOR_SETTER(HTMLInputElementSelectionEnd)
+{
+ INC_STATS("DOM.HTMLInputElement.selectionEnd._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+
+ if (!imp->canHaveSelection()) {
+ throwError("Accessing selectionEnd on an input element that cannot have a selection.");
+ return;
+ }
+
+ imp->setSelectionEnd(value->Int32Value());
+}
+
+CALLBACK_FUNC_DECL(HTMLInputElementSetSelectionRange)
+{
+ INC_STATS("DOM.HTMLInputElement.setSelectionRange");
+ v8::Handle<v8::Object> holder = args.Holder();
+ HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+
+ if (!imp->canHaveSelection())
+ return throwError("Calling setSelectionRange on an input element that cannot have a selection.");
+
+ int start = args[0]->Int32Value();
+ int end = args[1]->Int32Value();
+
+ imp->setSelectionRange(start, end);
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
new file mode 100644
index 0000000..c8f7f6e
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLOptionsCollection.h"
+
+#include "HTMLOptionElement.h"
+#include "HTMLSelectElement.h"
+#include "ExceptionCode.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8HTMLOptionElement.h"
+#include "V8HTMLSelectElementCustom.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(HTMLOptionsCollectionRemove)
+{
+ INC_STATS("DOM.HTMLOptionsCollection.remove()");
+ HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder());
+ HTMLSelectElement* base = static_cast<HTMLSelectElement*>(imp->base());
+ return removeElement(base, args);
+}
+
+CALLBACK_FUNC_DECL(HTMLOptionsCollectionAdd)
+{
+ INC_STATS("DOM.HTMLOptionsCollection.add()");
+ if (!V8HTMLOptionElement::HasInstance(args[0])) {
+ V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ return v8::Undefined();
+ }
+ HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder());
+ HTMLOptionElement* option = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(args[0]);
+
+ ExceptionCode ec = 0;
+ if (args.Length() < 2)
+ imp->add(option, ec);
+ else {
+ bool ok;
+ v8::TryCatch try_catch;
+ int index = ToInt32(args[1], ok);
+
+ if (try_catch.HasCaught())
+ return v8::Undefined();
+
+ if (!ok)
+ ec = TYPE_MISMATCH_ERR;
+ else
+ imp->add(option, index, ec);
+ }
+
+ if (ec != 0)
+ V8Proxy::SetDOMException(ec);
+
+ return v8::Undefined();
+}
+
+ACCESSOR_GETTER(HTMLOptionsCollectionLength)
+{
+ INC_STATS("DOM.HTMLOptionsCollection.length._get");
+ HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ int v = imp->length();
+ return v8::Integer::New(v);
+}
+
+ACCESSOR_SETTER(HTMLOptionsCollectionLength)
+{
+ INC_STATS("DOM.HTMLOptionsCollection.length._set");
+ HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ double v = value->NumberValue();
+ unsigned newLength = 0;
+ ExceptionCode ec = 0;
+ if (!isnan(v) && !isinf(v)) {
+ if (v < 0.0)
+ ec = INDEX_SIZE_ERR;
+ else if (v > static_cast<double>(UINT_MAX))
+ newLength = UINT_MAX;
+ else
+ newLength = static_cast<unsigned>(v);
+ }
+ if (!ec)
+ imp->setLength(value->Uint32Value(), ec);
+
+ V8Proxy::SetDOMException(ec);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
new file mode 100644
index 0000000..a6e41a1
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
@@ -0,0 +1,111 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+#include "HTMLPlugInElement.h"
+
+#include "ScriptInstance.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+// FIXME: The name of this file will change once refactoring is complete
+#include "v8_npobject.h"
+
+namespace WebCore {
+
+NAMED_PROPERTY_GETTER(HTMLPlugInElement)
+{
+ INC_STATS("DOM.HTMLPlugInElement.NamedPropertyGetter");
+ HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ ScriptInstance scriptInstance = imp->getInstance();
+ if (!scriptInstance)
+ return notHandledByInterceptor();
+
+ v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance());
+ if (instance.IsEmpty())
+ return notHandledByInterceptor();
+
+ return NPObjectGetNamedProperty(instance, name);
+}
+
+NAMED_PROPERTY_SETTER(HTMLPlugInElement)
+{
+ INC_STATS("DOM.HTMLPlugInElement.NamedPropertySetter");
+ HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ ScriptInstance scriptInstance = imp->getInstance();
+ if (!scriptInstance)
+ return notHandledByInterceptor();
+
+ v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance());
+ if (instance.IsEmpty())
+ return notHandledByInterceptor();
+
+ return NPObjectSetNamedProperty(instance, name, value);
+}
+
+CALLBACK_FUNC_DECL(HTMLPlugInElement)
+{
+ INC_STATS("DOM.HTMLPluginElement()");
+ return NPObjectInvokeDefaultHandler(args);
+}
+
+INDEXED_PROPERTY_GETTER(HTMLPlugInElement)
+{
+ INC_STATS("DOM.HTMLPlugInElement.IndexedPropertyGetter");
+ HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ ScriptInstance scriptInstance = imp->getInstance();
+ if (!scriptInstance)
+ return notHandledByInterceptor();
+
+ v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance());
+ if (instance.IsEmpty())
+ return notHandledByInterceptor();
+
+ return NPObjectGetIndexedProperty(instance, index);
+}
+
+INDEXED_PROPERTY_SETTER(HTMLPlugInElement)
+{
+ INC_STATS("DOM.HTMLPlugInElement.IndexedPropertySetter");
+ HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ ScriptInstance scriptInstance = imp->getInstance();
+ if (!scriptInstance)
+ return notHandledByInterceptor();
+
+ v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance());
+ if (instance.IsEmpty())
+ return notHandledByInterceptor();
+
+ return NPObjectSetIndexedProperty(instance, index, value);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp
new file mode 100644
index 0000000..97f7726
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "V8HTMLSelectElementCustom.h"
+
+#include "HTMLSelectElement.h"
+#include "HTMLOptionElement.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8HTMLOptionElement.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(HTMLSelectElementRemove)
+{
+ INC_STATS("DOM.HTMLSelectElement.remove");
+ HTMLSelectElement* imp = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(args.Holder());
+ return removeElement(imp, args);
+}
+
+v8::Handle<v8::Value> removeElement(HTMLSelectElement* imp, const v8::Arguments& args)
+{
+ if (V8HTMLOptionElement::HasInstance(args[0])) {
+ HTMLOptionElement* element = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(args[0]);
+ imp->remove(element->index());
+ return v8::Undefined();
+ }
+
+ imp->remove(ToInt32(args[0]));
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h
new file mode 100644
index 0000000..b956ed8
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008, 2009 Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef V8HTMLSelectElementCustom_h
+#define V8HTMLSelectElementCustom_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class HTMLSelectElement;
+
+ v8::Handle<v8::Value> removeElement(HTMLSelectElement*, const v8::Arguments&);
+
+} // namespace WebCore
+
+#endif // V8HTMLSelectElementCustom_h
diff --git a/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp
new file mode 100644
index 0000000..387806f
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorController.h"
+
+#include "ExceptionCode.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(InspectorControllerDebuggerEnabled)
+{
+ INC_STATS("InspectorController.debuggerEnabled()");
+ return v8::False();
+}
+
+CALLBACK_FUNC_DECL(InspectorControllerPauseOnExceptions)
+{
+ INC_STATS("InspectorController.pauseOnExceptions()");
+ return v8::False();
+}
+
+CALLBACK_FUNC_DECL(InspectorControllerProfilerEnabled)
+{
+ INC_STATS("InspectorController.profilerEnabled()");
+ return v8::False();
+}
+
+#if ENABLE(DATABASE)
+CALLBACK_FUNC_DECL(InspectorControllerDatabaseTableNames)
+{
+ INC_STATS("InspectorController.databaseTableNames()");
+ v8::Local<v8::Array> result = v8::Array::New(0);
+ return result;
+}
+#endif
+
+CALLBACK_FUNC_DECL(InspectorControllerWrapCallback)
+{
+ INC_STATS("InspectorController.wrapCallback()");
+ return args[0];
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
new file mode 100644
index 0000000..6dc2652
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Location.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
+#include "V8Location.h"
+#include "V8Proxy.h"
+
+#include "PlatformString.h"
+#include "KURL.h"
+#include "Document.h"
+#include "FrameLoader.h"
+#include "ScriptController.h"
+#include "CSSHelper.h"
+#include "Frame.h"
+
+namespace WebCore {
+
+// Notes about V8/JSC porting of this file.
+// This class is not very JS-engine specific. If we can move a couple of
+// methods to the scriptController, we should be able to unify the code
+// between JSC and V8:
+// retrieveActiveFrame() - in JSC, this needs an ExecState.
+// isSafeScript()
+// Since JSC and V8 have different mechanisms for getting at the ActiveFrame,
+// we're just making all these custom for now. The functionality is simple
+// and mirrors JSLocationCustom.cpp.
+
+static void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool lockBackForwardList)
+{
+ if (url.isEmpty())
+ return;
+
+ Frame* activeFrame = ScriptController::retrieveActiveFrame();
+ if (!activeFrame)
+ return;
+
+ if (!url.protocolIs("javascript") || ScriptController::isSafeScript(frame)) {
+ bool userGesture = activeFrame->script()->processingUserGesture();
+ frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, userGesture);
+ }
+}
+
+ACCESSOR_SETTER(LocationHash)
+{
+ INC_STATS("DOM.Location.hash._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String hash = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ String oldRef = url.ref();
+
+ if (hash.startsWith("#"))
+ hash = hash.substring(1);
+ if (oldRef == hash || (oldRef.isNull() && hash.isEmpty()))
+ return;
+ url.setRef(hash);
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_SETTER(LocationHost)
+{
+ INC_STATS("DOM.Location.host._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String host = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ String newHost = host.left(host.find(":"));
+ String newPort = host.substring(host.find(":") + 1);
+ url.setHost(newHost);
+ url.setPort(newPort.toUInt());
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_SETTER(LocationHostname)
+{
+ INC_STATS("DOM.Location.hostname._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String hostname = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ url.setHost(hostname);
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_SETTER(LocationHref)
+{
+ INC_STATS("DOM.Location.href._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String href = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ Frame* activeFrame = ScriptController::retrieveActiveFrame();
+ if (!activeFrame)
+ return;
+
+ if (!activeFrame->loader()->shouldAllowNavigation(frame))
+ return;
+
+ navigateIfAllowed(frame, activeFrame->loader()->completeURL(href), false, false);
+}
+
+ACCESSOR_SETTER(LocationPathname)
+{
+ INC_STATS("DOM.Location.pathname._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String pathname = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ url.setPath(pathname);
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_SETTER(LocationPort)
+{
+ INC_STATS("DOM.Location.port._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String port = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ url.setPort(port.toUInt());
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_SETTER(LocationProtocol)
+{
+ INC_STATS("DOM.Location.protocol._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String protocol = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ url.setProtocol(protocol);
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_SETTER(LocationSearch)
+{
+ INC_STATS("DOM.Location.search._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String query = toWebCoreString(value);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return;
+
+ KURL url = frame->loader()->url();
+ url.setQuery(query);
+
+ navigateIfAllowed(frame, url, false, false);
+}
+
+ACCESSOR_GETTER(LocationReload)
+{
+ INC_STATS("DOM.Location.reload._get");
+ static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReloadCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate())));
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::LOCATION, info.This());
+ if (holder.IsEmpty()) {
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+ return privateTemplate->GetFunction();
+ }
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ if (!V8Proxy::CanAccessFrame(imp->frame(), false)) {
+ static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReloadCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate())));
+ return sharedTemplate->GetFunction();
+ } else
+ return privateTemplate->GetFunction();
+}
+
+ACCESSOR_GETTER(LocationReplace)
+{
+ INC_STATS("DOM.Location.replace._get");
+ static v8::Persistent<v8::FunctionTemplate> privateTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReplaceCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate())));
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::LOCATION, info.This());
+ if (holder.IsEmpty()) {
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+ return privateTemplate->GetFunction();
+ }
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ if (!V8Proxy::CanAccessFrame(imp->frame(), false)) {
+ static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationReplaceCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate())));
+ return sharedTemplate->GetFunction();
+ } else
+ return privateTemplate->GetFunction();
+}
+
+ACCESSOR_GETTER(LocationAssign)
+{
+ INC_STATS("DOM.Location.assign._get");
+ static v8::Persistent<v8::FunctionTemplate> privateTemplate =
+ v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationAssignCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate())));
+ v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::LOCATION, info.This());
+ if (holder.IsEmpty()) {
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+ return privateTemplate->GetFunction();
+ }
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ if (!V8Proxy::CanAccessFrame(imp->frame(), false)) {
+ static v8::Persistent<v8::FunctionTemplate> sharedTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(v8LocationAssignCallback, v8::Handle<v8::Value>(), v8::Signature::New(V8Location::GetRawTemplate())));
+ return sharedTemplate->GetFunction();
+ } else
+ return privateTemplate->GetFunction();
+}
+
+CALLBACK_FUNC_DECL(LocationReload)
+{
+ // FIXME: we ignore the "forceget" parameter.
+
+ INC_STATS("DOM.Location.reload");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return v8::Undefined();
+
+ Frame* activeFrame = ScriptController::retrieveActiveFrame();
+ if (!activeFrame)
+ return v8::Undefined();
+
+ if (!ScriptController::isSafeScript(frame))
+ return v8::Undefined();
+
+ bool userGesture = activeFrame->script()->processingUserGesture();
+ frame->loader()->scheduleRefresh(userGesture);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(LocationReplace)
+{
+ INC_STATS("DOM.Location.replace");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String url = toWebCoreString(args[0]);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return v8::Undefined();
+
+ Frame* activeFrame = ScriptController::retrieveActiveFrame();
+ if (!activeFrame)
+ return v8::Undefined();
+
+ if (!activeFrame->loader()->shouldAllowNavigation(frame))
+ return v8::Undefined();
+
+ navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), true, true);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(LocationAssign)
+{
+ INC_STATS("DOM.Location.assign");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ String url = toWebCoreString(args[0]);
+
+ Frame* frame = imp->frame();
+ if (!frame)
+ return v8::Undefined();
+
+ Frame* activeFrame = ScriptController::retrieveActiveFrame();
+ if (!activeFrame)
+ return v8::Undefined();
+
+ if (!activeFrame->loader()->shouldAllowNavigation(frame))
+ return v8::Undefined();
+
+ navigateIfAllowed(frame, activeFrame->loader()->completeURL(url), false, false);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(LocationValueOf)
+{
+ // Just return the this object the way the normal valueOf function
+ // on the Object prototype would. The valueOf function is only
+ // added to make sure that it cannot be overwritten on location
+ // objects, since that would provide a hook to change the string
+ // conversion behavior of location objects.
+ return args.This();
+}
+
+CALLBACK_FUNC_DECL(LocationToString)
+{
+ INC_STATS("DOM.Location.toString");
+ v8::Handle<v8::Value> holder = args.Holder();
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ return v8::Undefined();
+ String result = imp->href();
+ return v8String(result);
+}
+
+INDEXED_ACCESS_CHECK(Location)
+{
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION);
+ // Only allow same origin access
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, host);
+ return V8Proxy::CanAccessFrame(imp->frame(), false);
+}
+
+NAMED_ACCESS_CHECK(Location)
+{
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::LOCATION);
+ // Only allow same origin access
+ Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, host);
+ return V8Proxy::CanAccessFrame(imp->frame(), false);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
new file mode 100644
index 0000000..3a41467
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MessageChannel.h"
+
+#include "Document.h"
+#include "Frame.h"
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(MessageChannelConstructor)
+{
+ INC_STATS("DOM.MessageChannel.Constructor");
+ // FIXME: The logic here is almost exact duplicate of V8::ConstructDOMObject.
+ // Consider refactoring to reduce duplication.
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.");
+
+ // Get the document.
+ Frame* frame = V8Proxy::retrieveFrame();
+ if (!frame)
+ return v8::Undefined();
+
+ Document* document = frame->document();
+
+ // Note: it's OK to let this RefPtr go out of scope because we also call
+ // SetDOMWrapper(), which effectively holds a reference to obj.
+ RefPtr<MessageChannel> obj = MessageChannel::create(document);
+
+ v8::Local<v8::Object> messageChannel = args.Holder();
+
+ // Create references from the MessageChannel wrapper to the two
+ // MessagePort wrappers to make sure that the MessagePort wrappers
+ // stay alive as long as the MessageChannel wrapper is around.
+ messageChannel->SetInternalField(kMessageChannelPort1Index, V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, obj->port1()));
+ messageChannel->SetInternalField(kMessageChannelPort2Index, V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, obj->port2()));
+
+ // Setup the standard wrapper object internal fields.
+ V8Proxy::SetDOMWrapper(messageChannel, V8ClassIndex::MESSAGECHANNEL, obj.get());
+ return toV8(obj.release(), messageChannel);
+}
+
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
new file mode 100644
index 0000000..8e529cc
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NamedNodeMap.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+INDEXED_PROPERTY_GETTER(NamedNodeMap)
+{
+ INC_STATS("DOM.NamedNodeMap.IndexedPropertyGetter");
+ NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder());
+ RefPtr<Node> result = imp->item(index);
+ if (!result)
+ return notHandledByInterceptor();
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+NAMED_PROPERTY_GETTER(NamedNodeMap)
+{
+ INC_STATS("DOM.NamedNodeMap.NamedPropertyGetter");
+ // Search the prototype chain first.
+ v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name);
+ if (!value.IsEmpty())
+ return value;
+
+ // Then look for IDL defined properties on the object itself.
+ if (info.Holder()->HasRealNamedCallbackProperty(name))
+ return notHandledByInterceptor();
+
+ // Finally, search the DOM.
+ NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder());
+ RefPtr<Node> result = imp->getNamedItem(toWebCoreString(name));
+ if (!result)
+ return notHandledByInterceptor();
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp b/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp
new file mode 100644
index 0000000..0723498
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NamedNodesCollection.cpp
@@ -0,0 +1,55 @@
+// 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
+// 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 "V8NamedNodesCollection.h"
+
+#include "Element.h"
+#include "NamedAttrMap.h"
+
+namespace WebCore {
+
+Node* V8NamedNodesCollection::item(unsigned index) const
+{
+ if (index < m_nodes.size())
+ return m_nodes[index].get();
+ return 0;
+}
+
+Node* V8NamedNodesCollection::itemWithName(const AtomicString& id) const
+{
+ for (unsigned i = 0; i < m_nodes.size(); ++i) {
+ Node* node = m_nodes[i].get();
+ if (node->hasAttributes() && node->attributes()->id() == id)
+ return node;
+ }
+ return 0;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NamedNodesCollection.h b/WebCore/bindings/v8/custom/V8NamedNodesCollection.h
new file mode 100644
index 0000000..d13b7a8
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NamedNodesCollection.h
@@ -0,0 +1,55 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+* * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef V8NamedNodesCollection_h
+#define V8NamedNodesCollection_h
+
+#include "Node.h"
+#include "NodeList.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class V8NamedNodesCollection : public NodeList {
+ public:
+ explicit V8NamedNodesCollection(const Vector<RefPtr<Node> >& nodes)
+ : m_nodes(nodes) { }
+ virtual unsigned length() const { return m_nodes.size(); }
+ virtual Node* item(unsigned) const;
+ virtual Node* itemWithName(const AtomicString&) const;
+
+ private:
+ Vector<RefPtr<Node> > m_nodes;
+ };
+
+} // namespace WebCore
+
+#endif // V8NamedNodesCollection_h
diff --git a/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
new file mode 100644
index 0000000..9adfe25
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Navigator.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(NavigatorAppVersion)
+{
+ INC_STATS("DOM.Navigator.appVersion");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Navigator* navigator = V8Proxy::ToNativeObject<Navigator>(V8ClassIndex::NAVIGATOR, holder);
+ return v8StringOrUndefined(navigator->appVersion());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
new file mode 100644
index 0000000..bf30414
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Node.h"
+
+#include "Document.h"
+#include "EventListener.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(NodeAddEventListener)
+{
+ INC_STATS("DOM.Node.addEventListener()");
+ Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ node->addEventListener(type, listener, useCapture);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(NodeRemoveEventListener)
+{
+ INC_STATS("DOM.Node.removeEventListener()");
+ Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
+ // It is possbile that the owner document of the node is detached
+ // from the frame, return immediately in this case.
+ // See issue http://b/878909
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ node->removeEventListener(type, listener.get(), useCapture);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp b/WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp
new file mode 100644
index 0000000..8839420
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NodeFilterCustom.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NodeFilter.h"
+
+#include "ExceptionCode.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(NodeFilterAcceptNode)
+{
+ INC_STATS("DOM.NodeFilter.acceptNode()");
+ return throwError(NOT_SUPPORTED_ERR);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp b/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp
new file mode 100644
index 0000000..48e6b8f
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NodeIterator.h"
+
+#include "ScriptState.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+static inline v8::Handle<v8::Value> toV8(PassRefPtr<Node> object, ExceptionCode ec, ScriptState* state)
+{
+ if (ec)
+ return throwError(ec);
+
+ if (state->hadException())
+ return throwError(state->exception());
+
+ if (!object)
+ return v8::Null();
+
+ return V8Proxy::NodeToV8Object(object.get());
+}
+
+CALLBACK_FUNC_DECL(NodeIteratorNextNode)
+{
+ INC_STATS("DOM.NodeIterator.nextNode()");
+ NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder());
+
+ ExceptionCode ec = 0;
+ ScriptState state;
+ RefPtr<Node> result = nodeIterator->nextNode(&state, ec);
+ return toV8(result.release(), ec, &state);
+}
+
+CALLBACK_FUNC_DECL(NodeIteratorPreviousNode)
+{
+ INC_STATS("DOM.NodeIterator.previousNode()");
+ NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder());
+
+ ExceptionCode ec = 0;
+ ScriptState state;
+ RefPtr<Node> result = nodeIterator->previousNode(&state, ec);
+ return toV8(result.release(), ec, &state);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NodeListCustom.cpp b/WebCore/bindings/v8/custom/V8NodeListCustom.cpp
new file mode 100644
index 0000000..27a47f5
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NodeListCustom.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NodeList.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+NAMED_PROPERTY_GETTER(NodeList)
+{
+ INC_STATS("DOM.NodeList.NamedPropertyGetter");
+ NodeList* list = V8Proxy::ToNativeObject<NodeList>(V8ClassIndex::NODELIST, info.Holder());
+ String key = toWebCoreString(name);
+
+ // Length property cannot be overridden.
+ if (key == "length")
+ return v8::Number::New(list->length());
+
+ RefPtr<Node> result = list->itemWithName(key);
+ if (!result)
+ return notHandledByInterceptor();
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp b/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
new file mode 100644
index 0000000..66585be
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+
+#include "SQLResultSetRowList.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(SQLResultSetRowListItem)
+{
+ INC_STATS("DOM.SQLResultSetRowList.item()");
+
+ if (args.Length() == 0) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Item index is required.");
+ return v8::Undefined();
+ }
+
+ if (!args[0]->IsNumber()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Item index must be a number.");
+ return v8::Undefined();
+ }
+
+ SQLResultSetRowList* rowList = V8Proxy::ToNativeObject<SQLResultSetRowList>(V8ClassIndex::SQLRESULTSETROWLIST, args.Holder());
+
+ unsigned long index = args[0]->IntegerValue();
+ if (index < 0 || index >= rowList->length()) {
+ V8Proxy::ThrowError(V8Proxy::RANGE_ERROR, "Item index is out of range.");
+ return v8::Undefined();
+ }
+
+ v8::Local<v8::Object> item = v8::Object::New();
+ unsigned numColumns = rowList->columnNames().size();
+ unsigned valuesIndex = index * numColumns;
+
+ for (unsigned i = 0; i < numColumns; ++i) {
+ const SQLValue& sqlValue = rowList->values()[valuesIndex + i];
+ v8::Handle<v8::Value> value;
+ switch(sqlValue.type()) {
+ case SQLValue::StringValue:
+ value = v8String(sqlValue.string());
+ break;
+ case SQLValue::NullValue:
+ value = v8::Null();
+ break;
+ case SQLValue::NumberValue:
+ value = v8::Number::New(sqlValue.number());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ item->Set(v8String(rowList->columnNames()[i]), value, static_cast<v8::PropertyAttribute>(v8::DontDelete|v8::ReadOnly));
+ }
+
+ return item;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp b/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp
new file mode 100644
index 0000000..3ca797c
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_proxy.h"
+
+#include "Database.h"
+#include "SQLValue.h"
+#include "V8CustomSQLStatementCallback.h"
+#include "V8CustomSQLStatementErrorCallback.h"
+#include <wtf/Vector.h>
+
+using namespace WTF;
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
+{
+ INC_STATS("DOM.SQLTransaction.executeSql()");
+
+ if (args.Length() == 0) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "SQL statement is required.");
+ return v8::Undefined();
+ }
+
+ String statement = ToWebCoreString(args[0]);
+
+ Vector<SQLValue> sqlValues;
+
+ if (args.Length() > 1) {
+ // FIXME: Make this work for v8::Arrayish objects, as well
+ if (!args[1]->IsArray()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement arguments must be an v8::Array.");
+ return v8::Undefined();
+ }
+
+ v8::Local<v8::Array> arguments = v8::Local<v8::Array>::Cast(args[1]);
+ uint32_t length = arguments->Length();
+
+ for (unsigned int i = 0; i < length; ++i) {
+ v8::Local<v8::Value> value = arguments->Get(v8::Integer::New(i));
+ if (value.IsEmpty() || value->IsNull())
+ sqlValues.append(SQLValue());
+ else if (value->IsNumber())
+ sqlValues.append(SQLValue(value->NumberValue()));
+ else
+ sqlValues.append(SQLValue(ToWebCoreString(value)));
+ }
+ }
+
+ SQLTransaction* transaction = V8Proxy::ToNativeObject<SQLTransaction>(V8ClassIndex::SQLTRANSACTION, args.Holder());
+
+ Frame* frame = V8Proxy::retrieveFrame();
+
+ RefPtr<SQLStatementCallback> callback;
+ if (args.Length() > 2) {
+ if (!args[2]->IsObject()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement callback must be of valid type.");
+ return v8::Undefined();
+ }
+
+ if (frame)
+ callback = V8CustomSQLStatementCallback::create(args[2], frame);
+ }
+
+ RefPtr<SQLStatementErrorCallback> errorCallback;
+ if (args.Length() > 3) {
+ if (!args[2]->IsObject()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement error callback must be of valid type.");
+ return v8::Undefined();
+ }
+
+ if (frame)
+ errorCallback = V8CustomSQLStatementErrorCallback::create(args[3], frame);
+ }
+
+ ExceptionCode ec = 0;
+ transaction->executeSQL(statement, sqlValues, callback, errorCallback, ec);
+ V8Proxy::SetDOMException(ec);
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
new file mode 100644
index 0000000..351b030
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#if ENABLE(SVG)
+
+#include "SVGElementInstance.h"
+
+#include "EventListener.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
+#include "V8SVGPODTypeWrapper.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener)
+{
+ INC_STATS("DOM.SVGElementInstance.AddEventListener()");
+ SVGElementInstance* instance = V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ instance->addEventListener(type, listener, useCapture);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(SVGElementInstanceRemoveEventListener)
+{
+ INC_STATS("DOM.SVGElementInstance.RemoveEventListener()");
+ SVGElementInstance* instance = V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ instance->removeEventListener(type, listener.get(), useCapture);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp
new file mode 100644
index 0000000..a2a4d49
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#if ENABLE(SVG)
+
+#include "SVGLength.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8SVGPODTypeWrapper.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(SVGLengthValue)
+{
+ INC_STATS("DOM.SVGLength.value");
+ V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, info.Holder());
+ SVGLength imp = *wrapper;
+ return v8::Number::New(imp.value(V8Proxy::GetSVGContext(wrapper)));
+}
+
+CALLBACK_FUNC_DECL(SVGLengthConvertToSpecifiedUnits)
+{
+ INC_STATS("DOM.SVGLength.convertToSpecifiedUnits");
+ V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, args.Holder());
+ SVGLength imp = *wrapper;
+ SVGElement* context = V8Proxy::GetSVGContext(wrapper);
+ imp.convertToSpecifiedUnits(toInt32(args[0]), context);
+ wrapper->commitChange(imp, context);
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
new file mode 100644
index 0000000..b69202b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#if ENABLE(SVG)
+
+#include "TransformationMatrix.h"
+
+#include "SVGException.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8SVGPODTypeWrapper.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(SVGMatrixInverse)
+{
+ INC_STATS("DOM.SVGMatrix.inverse()");
+ TransformationMatrix matrix = *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
+ ExceptionCode ec = 0;
+ TransformationMatrix result = matrix.inverse();
+
+ if (!matrix.isInvertible())
+ ec = SVGException::SVG_MATRIX_NOT_INVERTABLE;
+
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, new V8SVGStaticPODTypeWrapper<TransformationMatrix>(result));
+}
+
+CALLBACK_FUNC_DECL(SVGMatrixRotateFromVector)
+{
+ INC_STATS("DOM.SVGMatrix.rotateFromVector()");
+ TransformationMatrix matrix = *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
+ ExceptionCode ec = 0;
+ float x = toFloat(args[0]);
+ float y = toFloat(args[1]);
+ TransformationMatrix result = matrix;
+ result.rotateFromVector(x, y);
+ if (x == 0.0 || y == 0.0)
+ ec = SVGException::SVG_INVALID_VALUE_ERR;
+
+ if (ec != 0) {
+ V8Proxy::SetDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+
+ return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, new V8SVGStaticPODTypeWrapper<TransformationMatrix>(result));
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
new file mode 100644
index 0000000..a362ce5
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StyleSheetList.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+NAMED_PROPERTY_GETTER(StyleSheetList)
+{
+ INC_STATS("DOM.StyleSheetList.NamedPropertyGetter");
+
+ if (info.Holder()->HasRealNamedProperty(name))
+ return notHandledByInterceptor();
+
+ // Search style sheet.
+ StyleSheetList* imp = V8Proxy::ToNativeObject<StyleSheetList>(V8ClassIndex::STYLESHEETLIST, info.Holder());
+ HTMLStyleElement* item = imp->getNamedItem(toWebCoreString(name));
+ if (!item)
+ return notHandledByInterceptor();
+
+ return V8Proxy::ToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp b/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp
new file mode 100644
index 0000000..baf49c0
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TreeWalker.h"
+
+#include "Node.h"
+#include "ScriptState.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+static inline v8::Handle<v8::Value> toV8(PassRefPtr<Node> object, ScriptState* state)
+{
+ if (state->hadException())
+ return throwError(state->exception());
+
+ if (!object)
+ return v8::Null();
+
+ return V8Proxy::NodeToV8Object(object.get());
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerParentNode)
+{
+ INC_STATS("DOM.TreeWalker.parentNode()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->parentNode(&state);
+ return toV8(result.release(), &state);
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerFirstChild)
+{
+ INC_STATS("DOM.TreeWalker.firstChild()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->firstChild(&state);
+ return toV8(result.release(), &state);
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerLastChild)
+{
+ INC_STATS("DOM.TreeWalker.lastChild()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->lastChild(&state);
+ return toV8(result.release(), &state);
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerNextNode)
+{
+ INC_STATS("DOM.TreeWalker.nextNode()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->nextNode(&state);
+ return toV8(result.release(), &state);
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerPreviousNode)
+{
+ INC_STATS("DOM.TreeWalker.previousNode()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->previousNode(&state);
+ return toV8(result.release(), &state);
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerNextSibling)
+{
+ INC_STATS("DOM.TreeWalker.nextSibling()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->nextSibling(&state);
+ return toV8(result.release(), &state);
+}
+
+CALLBACK_FUNC_DECL(TreeWalkerPreviousSibling)
+{
+ INC_STATS("DOM.TreeWalker.previousSibling()");
+ TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+
+ ScriptState state;
+ RefPtr<Node> result = treeWalker->previousSibling(&state);
+ return toV8(result.release(), &state);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
new file mode 100644
index 0000000..b07d288
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitCSSMatrix.h"
+
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Node.h"
+
+#include "V8Binding.h"
+#include "V8Document.h"
+#include "V8Node.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebKitCSSMatrixConstructor)
+{
+ INC_STATS("DOM.WebKitCSSMatrix.Constructor");
+ // FIXME: The logic here is almost exact duplicate of V8::ConstructDOMObject.
+ // Consider refactoring to reduce duplication.
+ String cssValue;
+ if (args.Length() >= 1)
+ cssValue = toWebCoreString(args[0]);
+
+ ExceptionCode ec = 0;
+ RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(cssValue, ec);
+ if (ec)
+ throwError(ec);
+
+ // Transform the holder into a wrapper object for the matrix.
+ V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), matrix.get());
+ return toV8(matrix.release(), args.Holder());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
new file mode 100644
index 0000000..6b55238
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "Frame.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8ObjectEventListener.h"
+#include "V8Proxy.h"
+#include "XMLHttpRequest.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(XMLHttpRequestConstructor)
+{
+ INC_STATS("DOM.XMLHttpRequest.Constructor");
+
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TYPE_ERROR);
+
+ // Expect no parameters.
+ // Allocate a XMLHttpRequest object as its internal field.
+ Document* doc = V8Proxy::retrieveFrame()->document();
+ RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(doc);
+ V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());
+
+ // Add object to the wrapper map.
+ xmlHttpRequest->ref();
+ V8Proxy::SetJSWrapperForActiveDOMObject(xmlHttpRequest.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+ return args.Holder();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
new file mode 100644
index 0000000..ea69f0b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -0,0 +1,444 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "XMLHttpRequest.h"
+
+#include "Frame.h"
+#include "V8Binding.h"
+#include "V8Document.h"
+#include "V8CustomBinding.h"
+#include "V8HTMLDocument.h"
+#include "V8ObjectEventListener.h"
+#include "V8Proxy.h"
+#include "V8XMLHttpRequestUtilities.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(XMLHttpRequestOnabort)
+{
+ INC_STATS("DOM.XMLHttpRequest.onabort._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (xmlHttpRequest->onabort()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnabort)
+{
+ INC_STATS("DOM.XMLHttpRequest.onabort._set");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequest->onabort()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequest->setOnabort(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequest->setOnabort(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnerror)
+{
+ INC_STATS("DOM.XMLHttpRequest.onerror._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (xmlHttpRequest->onerror()) {
+ RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnerror)
+{
+ INC_STATS("DOM.XMLHttpRequest.onerror._set");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequest->onerror()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequest->setOnerror(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequest->setOnerror(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnload)
+{
+ INC_STATS("DOM.XMLHttpRequest.onload._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (xmlHttpRequest->onload()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnload)
+{
+ INC_STATS("DOM.XMLHttpRequest.onload._set");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequest->onload()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ xmlHttpRequest->setOnload(0);
+
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequest->setOnload(listener.get());
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnloadstart)
+{
+ INC_STATS("DOM.XMLHttpRequest.onloadstart._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (xmlHttpRequest->onloadstart()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnloadstart)
+{
+ INC_STATS("DOM.XMLHttpRequest.onloadstart._set");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequest->onloadstart()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequest->setOnloadstart(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequest->setOnloadstart(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnprogress)
+{
+ INC_STATS("DOM.XMLHttpRequest.onprogress._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (xmlHttpRequest->onprogress()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnprogress)
+{
+ INC_STATS("DOM.XMLHttpRequest.onprogress._set");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequest->onprogress()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequest->setOnprogress(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequest->setOnprogress(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange)
+{
+ INC_STATS("DOM.XMLHttpRequest.onreadystatechange._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (xmlHttpRequest->onreadystatechange()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange)
+{
+ INC_STATS("DOM.XMLHttpRequest.onreadystatechange._set");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequest->onreadystatechange()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequest->setOnreadystatechange(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequest->setOnreadystatechange(listener.get());
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestResponseText)
+{
+ // FIXME: This is only needed because webkit set this getter as custom.
+ // So we need a custom method to avoid forking the IDL file.
+ INC_STATS("DOM.XMLHttpRequest.responsetext._get");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ return v8StringOrNull(xmlHttpRequest->responseText());
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener)
+{
+ INC_STATS("DOM.XMLHttpRequest.addEventListener()");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ xmlHttpRequest->addEventListener(type, listener, useCapture);
+
+ createHiddenXHRDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener)
+{
+ INC_STATS("DOM.XMLHttpRequest.removeEventListener()");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined(); // Probably leaked.
+
+ RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false);
+
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ xmlHttpRequest->removeEventListener(type, listener.get(), useCapture);
+
+ removeHiddenXHRDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestOpen)
+{
+ INC_STATS("DOM.XMLHttpRequest.open()");
+ // Four cases:
+ // open(method, url)
+ // open(method, url, async)
+ // open(method, url, async, user)
+ // open(method, url, async, user, passwd)
+
+ if (args.Length() < 2)
+ return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ String method = toWebCoreString(args[0]);
+ String urlstring = toWebCoreString(args[1]);
+ V8Proxy* proxy = V8Proxy::retrieve();
+ KURL url = proxy->frame()->document()->completeURL(urlstring);
+
+ bool async = (args.Length() < 3) ? true : args[2]->BooleanValue();
+
+ ExceptionCode ec = 0;
+ String user, passwd;
+ if (args.Length() >= 4 && !args[3]->IsUndefined()) {
+ user = valueToStringWithNullCheck(args[3]);
+
+ if (args.Length() >= 5 && !args[4]->IsUndefined()) {
+ passwd = valueToStringWithNullCheck(args[4]);
+ xmlHttpRequest->open(method, url, async, user, passwd, ec);
+ } else
+ xmlHttpRequest->open(method, url, async, user, ec);
+ } else
+ xmlHttpRequest->open(method, url, async, ec);
+
+ if (ec)
+ return throwError(ec);
+
+ return v8::Undefined();
+}
+
+static bool IsDocumentType(v8::Handle<v8::Value> value)
+{
+ // FIXME: add other document types.
+ return V8Document::HasInstance(value) || V8HTMLDocument::HasInstance(value);
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestSend)
+{
+ INC_STATS("DOM.XMLHttpRequest.send()");
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+
+ ExceptionCode ec = 0;
+ if (args.Length() < 1)
+ xmlHttpRequest->send(ec);
+ else {
+ v8::Handle<v8::Value> arg = args[0];
+ // FIXME: upstream handles "File" objects too.
+ if (IsDocumentType(arg)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
+ Document* document = V8Proxy::DOMWrapperToNode<Document>(object);
+ ASSERT(document);
+ xmlHttpRequest->send(document, ec);
+ } else
+ xmlHttpRequest->send(valueToStringWithNullCheck(arg), ec);
+ }
+
+ if (ec)
+ return throwError(ec);
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestSetRequestHeader) {
+ INC_STATS("DOM.XMLHttpRequest.setRequestHeader()");
+ if (args.Length() < 2)
+ return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ ExceptionCode ec = 0;
+ String header = toWebCoreString(args[0]);
+ String value = toWebCoreString(args[1]);
+ xmlHttpRequest->setRequestHeader(header, value, ec);
+ if (ec)
+ return throwError(ec);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestGetResponseHeader)
+{
+ INC_STATS("DOM.XMLHttpRequest.getResponseHeader()");
+ if (args.Length() < 1)
+ return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ ExceptionCode ec = 0;
+ String header = toWebCoreString(args[0]);
+ String result = xmlHttpRequest->getResponseHeader(header, ec);
+ if (ec)
+ return throwError(ec);
+ return v8StringOrNull(result);
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestOverrideMimeType)
+{
+ INC_STATS("DOM.XMLHttpRequest.overrideMimeType()");
+ if (args.Length() < 1)
+ return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+
+ XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ String value = toWebCoreString(args[0]);
+ xmlHttpRequest->overrideMimeType(value);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestDispatchEvent)
+{
+ INC_STATS("DOM.XMLHttpRequest.dispatchEvent()");
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
new file mode 100644
index 0000000..7ffad82
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "XMLHttpRequestUpload.h"
+
+#include "ExceptionCode.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8ObjectEventListener.h"
+#include "V8Proxy.h"
+#include "V8XMLHttpRequestUtilities.h"
+#include "XMLHttpRequest.h"
+
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onabort._get");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (xmlHttpRequestUpload->onabort()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onabort._set");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequestUpload->onabort()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequestUpload->setOnabort(0);
+ } else {
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequestUpload->setOnabort(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onerror._get");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (xmlHttpRequestUpload->onerror()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onerror._set");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequestUpload->onerror()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequestUpload->setOnerror(0);
+ } else {
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequestUpload->setOnerror(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnload)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onload._get");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (xmlHttpRequestUpload->onload()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onload._set");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequestUpload->onload()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequestUpload->setOnload(0);
+ } else {
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequestUpload->setOnload(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._get");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (xmlHttpRequestUpload->onloadstart()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._set");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequestUpload->onloadstart()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequestUpload->setOnloadstart(0);
+ } else {
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequestUpload->setOnloadstart(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onprogress._get");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (xmlHttpRequestUpload->onprogress()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.onprogress._set");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ if (value->IsNull()) {
+ if (xmlHttpRequestUpload->onprogress()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ removeHiddenXHRDependency(info.Holder(), v8Listener);
+ }
+
+ // Clear the listener.
+ xmlHttpRequestUpload->setOnprogress(0);
+ } else {
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ xmlHttpRequestUpload->setOnprogress(listener);
+ createHiddenXHRDependency(info.Holder(), value);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
+
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ xmlHttpRequestUpload->addEventListener(type, listener, useCapture);
+
+ createHiddenXHRDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.removeEventListener()");
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
+
+ XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
+ V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined(); // Probably leaked.
+
+ RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false);
+
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ xmlHttpRequestUpload->removeEventListener(type, listener.get(), useCapture);
+
+ removeHiddenXHRDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(XMLHttpRequestUploadDispatchEvent)
+{
+ INC_STATS("DOM.XMLHttpRequestUpload.dispatchEvent()");
+ return throwError(NOT_SUPPORTED_ERR);
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/WorkerRunLoop.cpp b/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp
index 98c2e8d..7b20293 100644
--- a/WebCore/dom/WorkerRunLoop.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -27,43 +27,19 @@
* (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(WORKERS)
+#include "config.h"
+#include "XMLSerializer.h"
-#include "WorkerRunLoop.h"
-#include "WorkerContext.h"
-#include "WorkerTask.h"
-#include "WorkerThread.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
namespace WebCore {
-void WorkerRunLoop::run(WorkerContext* context)
-{
- ASSERT(context);
- ASSERT(context->thread());
- ASSERT(context->thread()->threadID() == currentThread());
-
- while (true) {
- RefPtr<WorkerTask> task;
- if (!m_messageQueue.waitForMessage(task))
- break;
-
- task->performTask(context);
- }
-}
-
-void WorkerRunLoop::terminate()
-{
- m_messageQueue.kill();
-}
-
-void WorkerRunLoop::postTask(PassRefPtr<WorkerTask> task)
+CALLBACK_FUNC_DECL(XMLSerializerConstructor)
{
- m_messageQueue.append(task);
+ INC_STATS("DOM.XMLSerializer.Constructor");
+ return V8Proxy::ConstructDOMObject<V8ClassIndex::XMLSERIALIZER, XMLSerializer>(args);
}
} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp b/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp
new file mode 100644
index 0000000..84d75db
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "XPathEvaluator.h"
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(XPathEvaluatorConstructor)
+{
+ INC_STATS("DOM.XPathEvaluator.Constructor");
+ return V8Proxy::ConstructDOMObject<V8ClassIndex::XPATHEVALUATOR, XPathEvaluator>(args);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
new file mode 100644
index 0000000..d470f84
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "XSLTProcessor.h"
+
+#include "Document.h"
+#include "DocumentFragment.h"
+#include "Node.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Document.h"
+#include "V8Node.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(XSLTProcessorConstructor)
+{
+ INC_STATS("DOM.XSLTProcessor.Constructor");
+ return V8Proxy::ConstructDOMObject<V8ClassIndex::XSLTPROCESSOR, XSLTProcessor>(args);
+}
+
+
+CALLBACK_FUNC_DECL(XSLTProcessorImportStylesheet)
+{
+ INC_STATS("DOM.XSLTProcessor.importStylesheet");
+ if (!V8Node::HasInstance(args[0]))
+ return v8::Undefined();
+
+ XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+
+ Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ imp->importStylesheet(node);
+ return v8::Undefined();
+}
+
+
+CALLBACK_FUNC_DECL(XSLTProcessorTransformToFragment)
+{
+ INC_STATS("DOM.XSLTProcessor.transformToFragment");
+ if (!V8Node::HasInstance(args[0]) || !V8Document::HasInstance(args[1]))
+ return v8::Undefined();
+
+ XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+
+ Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ Document* owner = V8Proxy::DOMWrapperToNode<Document>(args[1]);
+ RefPtr<DocumentFragment> result = imp->transformToFragment(source, owner);
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+
+CALLBACK_FUNC_DECL(XSLTProcessorTransformToDocument)
+{
+ INC_STATS("DOM.XSLTProcessor.transformToDocument");
+
+ if (!V8Node::HasInstance(args[0]))
+ return v8::Undefined();
+
+ XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+
+ Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ if (!source)
+ return v8::Undefined();
+
+ RefPtr<Document> result = imp->transformToDocument(source);
+ if (!result)
+ return v8::Undefined();
+
+ return V8Proxy::NodeToV8Object(result.get());
+}
+
+
+CALLBACK_FUNC_DECL(XSLTProcessorSetParameter)
+{
+ INC_STATS("DOM.XSLTProcessor.setParameter");
+ if (isUndefinedOrNull(args[1]) || isUndefinedOrNull(args[2]))
+ return v8::Undefined();
+
+ XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+
+ String namespaceURI = toWebCoreString(args[0]);
+ String localName = toWebCoreString(args[1]);
+ String value = toWebCoreString(args[2]);
+ imp->setParameter(namespaceURI, localName, value);
+
+ return v8::Undefined();
+}
+
+
+CALLBACK_FUNC_DECL(XSLTProcessorGetParameter)
+{
+ INC_STATS("DOM.XSLTProcessor.getParameter");
+ if (isUndefinedOrNull(args[1]))
+ return v8::Undefined();
+
+ XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+
+ String namespaceURI = toWebCoreString(args[0]);
+ String localName = toWebCoreString(args[1]);
+ String result = imp->getParameter(namespaceURI, localName);
+ if (result.isNull())
+ return v8::Undefined();
+
+ return v8String(result);
+}
+
+CALLBACK_FUNC_DECL(XSLTProcessorRemoveParameter)
+{
+ INC_STATS("DOM.XSLTProcessor.removeParameter");
+ if (isUndefinedOrNull(args[1]))
+ return v8::Undefined();
+
+ XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+
+ String namespaceURI = toWebCoreString(args[0]);
+ String localName = toWebCoreString(args[1]);
+ imp->removeParameter(namespaceURI, localName);
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bridge/IdentifierRep.cpp b/WebCore/bridge/IdentifierRep.cpp
new file mode 100644
index 0000000..11560e3
--- /dev/null
+++ b/WebCore/bridge/IdentifierRep.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IdentifierRep.h"
+
+#include "PlatformString.h"
+#include <runtime/UString.h>
+#include <wtf/HashMap.h>
+#include <wtf/StdLibExtras.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+typedef HashSet<IdentifierRep*> IdentifierSet;
+
+static IdentifierSet& identifierSet()
+{
+ DEFINE_STATIC_LOCAL(IdentifierSet, identifierSet, ());
+ return identifierSet;
+}
+
+typedef HashMap<int, IdentifierRep*> IntIdentifierMap;
+
+static IntIdentifierMap& intIdentifierMap()
+{
+ DEFINE_STATIC_LOCAL(IntIdentifierMap, intIdentifierMap, ());
+ return intIdentifierMap;
+}
+
+IdentifierRep* IdentifierRep::get(int intID)
+{
+ if (intID == 0 || intID == -1) {
+ static IdentifierRep* negativeOneAndZeroIdentifiers[2];
+
+ IdentifierRep* identifier = negativeOneAndZeroIdentifiers[intID + 1];
+ if (!identifier) {
+ identifier = new IdentifierRep(intID);
+
+ negativeOneAndZeroIdentifiers[intID + 1] = identifier;
+ }
+
+ return identifier;
+ }
+
+ pair<IntIdentifierMap::iterator, bool> result = intIdentifierMap().add(intID, 0);
+ if (result.second) {
+ ASSERT(!result.first->second);
+ result.first->second = new IdentifierRep(intID);
+
+ identifierSet().add(result.first->second);
+ }
+
+ return result.first->second;
+}
+
+typedef HashMap<RefPtr<JSC::UString::Rep>, IdentifierRep*> StringIdentifierMap;
+
+static StringIdentifierMap& stringIdentifierMap()
+{
+ DEFINE_STATIC_LOCAL(StringIdentifierMap, stringIdentifierMap, ());
+ return stringIdentifierMap;
+}
+
+IdentifierRep* IdentifierRep::get(const char* name)
+{
+ ASSERT(name);
+ if (!name)
+ return 0;
+
+ UString string = String::fromUTF8WithLatin1Fallback(name, strlen(name));
+ pair<StringIdentifierMap::iterator, bool> result = stringIdentifierMap().add(string.rep(), 0);
+ if (result.second) {
+ ASSERT(!result.first->second);
+ result.first->second = new IdentifierRep(name);
+
+ identifierSet().add(result.first->second);
+ }
+
+ return result.first->second;
+}
+
+bool IdentifierRep::isValid(IdentifierRep* identifier)
+{
+ return identifierSet().contains(identifier);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bridge/IdentifierRep.h b/WebCore/bridge/IdentifierRep.h
new file mode 100644
index 0000000..8e0e0d9
--- /dev/null
+++ b/WebCore/bridge/IdentifierRep.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IdentifierRep_h
+#define IdentifierRep_h
+
+#include <wtf/Assertions.h>
+#include <string.h>
+
+namespace WebCore {
+
+class IdentifierRep {
+public:
+ static IdentifierRep* get(int);
+ static IdentifierRep* get(const char*);
+
+ static bool isValid(IdentifierRep*);
+
+ bool isString() const { return m_isString; }
+
+ int number() const { return m_isString ? 0 : m_value.m_number; }
+ const char* string() const { return m_isString ? m_value.m_string : 0; }
+
+private:
+ IdentifierRep(int number)
+ : m_isString(false)
+ {
+ m_value.m_number = number;
+ }
+
+ IdentifierRep(const char* name)
+ : m_isString(true)
+ {
+ m_value.m_string = strdup(name);
+ }
+
+ ~IdentifierRep()
+ {
+ // IdentifierReps should never be deleted.
+ ASSERT_NOT_REACHED();
+ }
+
+ union {
+ const char* m_string;
+ int m_number;
+ } m_value;
+ bool m_isString;
+};
+
+} // namespace WebCore
+
+#endif // IdentifierRep_h
diff --git a/WebCore/bridge/NP_jsobject.cpp b/WebCore/bridge/NP_jsobject.cpp
index 45f9f6d..9a9cfc3 100644
--- a/WebCore/bridge/NP_jsobject.cpp
+++ b/WebCore/bridge/NP_jsobject.cpp
@@ -36,6 +36,7 @@
#endif // ANDROID_NPN_SETEXCEPTION
#include "c_utility.h"
#include "c_instance.h"
+#include "IdentifierRep.h"
#include "npruntime_impl.h"
#include "npruntime_priv.h"
#include "runtime_root.h"
@@ -47,10 +48,9 @@
#include <runtime/Completion.h>
#include <runtime/Completion.h>
-using WebCore::String;
-using WebCore::StringSourceProvider;
using namespace JSC;
using namespace JSC::Bindings;
+using namespace WebCore;
static void getListFromVariantArgs(ExecState* exec, const NPVariant* args, unsigned argCount, RootObject* rootObject, ArgList& aList)
{
@@ -125,9 +125,9 @@ bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCou
ArgList argList;
getListFromVariantArgs(exec, args, argCount, rootObject, argList);
ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr resultV = call(exec, function, callType, callData, function, argList);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
// Convert and return the result of the function call.
convertValueToNPVariant(exec, resultV, result);
@@ -146,8 +146,8 @@ bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant*
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o);
- PrivateIdentifier* i = static_cast<PrivateIdentifier*>(methodName);
- if (!i->isString)
+ IdentifierRep* i = static_cast<IdentifierRep*>(methodName);
+ if (!i->isString())
return false;
// Special case the "eval" method.
@@ -165,7 +165,7 @@ bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant*
return false;
ExecState* exec = rootObject->globalObject()->globalExec();
JSLock lock(false);
- JSValuePtr function = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string));
+ JSValuePtr function = obj->imp->get(exec, identifierFromNPIdentifier(i->string()));
CallData callData;
CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
@@ -175,9 +175,9 @@ bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant*
ArgList argList;
getListFromVariantArgs(exec, args, argCount, rootObject, argList);
ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr resultV = call(exec, function, callType, callData, obj->imp, argList);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
// Convert and return the result of the function call.
convertValueToNPVariant(exec, resultV, result);
@@ -205,9 +205,9 @@ bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant)
JSLock lock(false);
String scriptString = convertNPStringToUTF16(s);
ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
Completion completion = JSC::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(scriptString));
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
ComplType type = completion.complType();
JSValuePtr result;
@@ -237,14 +237,14 @@ bool _NPN_GetProperty(NPP, NPObject* o, NPIdentifier propertyName, NPVariant* va
return false;
ExecState* exec = rootObject->globalObject()->globalExec();
- PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName);
+ IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
JSLock lock(false);
JSValuePtr result;
- if (i->isString)
- result = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string));
+ if (i->isString())
+ result = obj->imp->get(exec, identifierFromNPIdentifier(i->string()));
else
- result = obj->imp->get(exec, i->value.number);
+ result = obj->imp->get(exec, i->number());
convertValueToNPVariant(exec, result, variant);
exec->clearException();
@@ -272,13 +272,13 @@ bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVaria
ExecState* exec = rootObject->globalObject()->globalExec();
JSLock lock(false);
- PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName);
+ IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
- if (i->isString) {
+ if (i->isString()) {
PutPropertySlot slot;
- obj->imp->put(exec, identifierFromNPIdentifier(i->value.string), convertNPVariantToValue(exec, variant, rootObject), slot);
+ obj->imp->put(exec, identifierFromNPIdentifier(i->string()), convertNPVariantToValue(exec, variant, rootObject), slot);
} else
- obj->imp->put(exec, i->value.number, convertNPVariantToValue(exec, variant, rootObject));
+ obj->imp->put(exec, i->number(), convertNPVariantToValue(exec, variant, rootObject));
exec->clearException();
return true;
}
@@ -299,24 +299,24 @@ bool _NPN_RemoveProperty(NPP, NPObject* o, NPIdentifier propertyName)
return false;
ExecState* exec = rootObject->globalObject()->globalExec();
- PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName);
- if (i->isString) {
- if (!obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->value.string))) {
+ IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
+ if (i->isString()) {
+ if (!obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->string()))) {
exec->clearException();
return false;
}
} else {
- if (!obj->imp->hasProperty(exec, i->value.number)) {
+ if (!obj->imp->hasProperty(exec, i->number())) {
exec->clearException();
return false;
}
}
JSLock lock(false);
- if (i->isString)
- obj->imp->deleteProperty(exec, identifierFromNPIdentifier(i->value.string));
+ if (i->isString())
+ obj->imp->deleteProperty(exec, identifierFromNPIdentifier(i->string()));
else
- obj->imp->deleteProperty(exec, i->value.number);
+ obj->imp->deleteProperty(exec, i->number());
exec->clearException();
return true;
@@ -334,15 +334,15 @@ bool _NPN_HasProperty(NPP, NPObject* o, NPIdentifier propertyName)
return false;
ExecState* exec = rootObject->globalObject()->globalExec();
- PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName);
+ IdentifierRep* i = static_cast<IdentifierRep*>(propertyName);
JSLock lock(false);
- if (i->isString) {
- bool result = obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->value.string));
+ if (i->isString()) {
+ bool result = obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->string()));
exec->clearException();
return result;
}
- bool result = obj->imp->hasProperty(exec, i->value.number);
+ bool result = obj->imp->hasProperty(exec, i->number());
exec->clearException();
return result;
}
@@ -358,8 +358,8 @@ bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName)
if (o->_class == NPScriptObjectClass) {
JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o);
- PrivateIdentifier* i = static_cast<PrivateIdentifier*>(methodName);
- if (!i->isString)
+ IdentifierRep* i = static_cast<IdentifierRep*>(methodName);
+ if (!i->isString())
return false;
RootObject* rootObject = obj->rootObject;
@@ -368,7 +368,7 @@ bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName)
ExecState* exec = rootObject->globalObject()->globalExec();
JSLock lock(false);
- JSValuePtr func = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string));
+ JSValuePtr func = obj->imp->get(exec, identifierFromNPIdentifier(i->string()));
exec->clearException();
return !func.isUndefined();
}
@@ -451,9 +451,9 @@ bool _NPN_Construct(NPP, NPObject* o, const NPVariant* args, uint32_t argCount,
ArgList argList;
getListFromVariantArgs(exec, args, argCount, rootObject, argList);
ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject();
- globalObject->startTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.start();
JSValuePtr resultV = construct(exec, constructor, constructType, constructData, argList);
- globalObject->stopTimeoutCheck();
+ globalObject->globalData()->timeoutChecker.stop();
// Convert and return the result.
convertValueToNPVariant(exec, resultV, result);
diff --git a/WebCore/bridge/c/c_instance.cpp b/WebCore/bridge/c/c_instance.cpp
index 3e6f6d6..24b881f 100644
--- a/WebCore/bridge/c/c_instance.cpp
+++ b/WebCore/bridge/c/c_instance.cpp
@@ -32,6 +32,7 @@
#include "c_class.h"
#include "c_runtime.h"
#include "c_utility.h"
+#include "IdentifierRep.h"
#include "npruntime_impl.h"
#include "runtime_root.h"
#include <runtime/ArgList.h>
@@ -45,6 +46,8 @@
#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
+using namespace WebCore;
+
namespace JSC {
namespace Bindings {
@@ -265,12 +268,12 @@ void CInstance::getPropertyNames(ExecState* exec, PropertyNameArray& nameArray)
}
for (uint32_t i = 0; i < count; i++) {
- PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(identifiers[i]);
+ IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]);
- if (identifier->isString)
- nameArray.add(identifierFromNPIdentifier(identifier->value.string));
+ if (identifier->isString())
+ nameArray.add(identifierFromNPIdentifier(identifier->string()));
else
- nameArray.add(Identifier::from(exec, identifier->value.number));
+ nameArray.add(Identifier::from(exec, identifier->number()));
}
// FIXME: This should really call NPN_MemFree but that's in WebKit
diff --git a/WebCore/bridge/c/c_utility.cpp b/WebCore/bridge/c/c_utility.cpp
index 1f5ff6c..352163c 100644
--- a/WebCore/bridge/c/c_utility.cpp
+++ b/WebCore/bridge/c/c_utility.cpp
@@ -139,7 +139,7 @@ JSValuePtr convertNPVariantToValue(ExecState* exec, const NPVariant* variant, Ro
String convertNPStringToUTF16(const NPString* string)
{
- return convertUTF8ToUTF16WithLatin1Fallback(string->UTF8Characters, string->UTF8Length);
+ return String::fromUTF8WithLatin1Fallback(string->UTF8Characters, string->UTF8Length);
}
Identifier identifierFromNPIdentifier(const NPUTF8* name)
diff --git a/WebCore/bridge/c/c_utility.h b/WebCore/bridge/c/c_utility.h
index 2efc66c..bd25e80 100644
--- a/WebCore/bridge/c/c_utility.h
+++ b/WebCore/bridge/c/c_utility.h
@@ -46,29 +46,11 @@ class RootObject;
typedef uint16_t NPUTF16;
-enum NP_ValueType {
- NP_NumberValueType,
- NP_StringValueType,
- NP_BooleanValueType,
- NP_NullValueType,
- NP_UndefinedValueType,
- NP_ObjectValueType,
- NP_InvalidValueType
-};
-
WebCore::String convertNPStringToUTF16(const NPString *string);
void convertValueToNPVariant(ExecState*, JSValuePtr, NPVariant* result);
JSValuePtr convertNPVariantToValue(ExecState*, const NPVariant*, RootObject*);
Identifier identifierFromNPIdentifier(const NPUTF8* name);
-struct PrivateIdentifier {
- union {
- const NPUTF8* string;
- int32_t number;
- } value;
- bool isString;
-};
-
} }
#endif // ENABLE(NETSCAPE_PLUGIN_API)
diff --git a/WebCore/bridge/jni/jni_jsobject.mm b/WebCore/bridge/jni/jni_jsobject.mm
index 301d672..3689840 100644
--- a/WebCore/bridge/jni/jni_jsobject.mm
+++ b/WebCore/bridge/jni/jni_jsobject.mm
@@ -302,9 +302,9 @@ jobject JavaJSObject::call(jstring methodName, jobjectArray args) const
// Call the function object.
ArgList argList;
getListFromJArray(exec, args, argList);
- rootObject->globalObject()->startTimeoutCheck();
+ rootObject->globalObject()->globalData()->timeoutChecker.start();
JSValuePtr result = JSC::call(exec, function, callType, callData, _imp, argList);
- rootObject->globalObject()->stopTimeoutCheck();
+ rootObject->globalObject()->globalData()->timeoutChecker.stop();
return convertValueToJObject(result);
}
@@ -321,9 +321,9 @@ jobject JavaJSObject::eval(jstring script) const
if (!rootObject)
return 0;
- rootObject->globalObject()->startTimeoutCheck();
+ rootObject->globalObject()->globalData()->timeoutChecker.start();
Completion completion = JSC::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), makeSource(JavaString(script)));
- rootObject->globalObject()->stopTimeoutCheck();
+ rootObject->globalObject()->globalData()->timeoutChecker.stop();
ComplType type = completion.complType();
if (type == Normal) {
diff --git a/WebCore/bridge/npapi.h b/WebCore/bridge/npapi.h
index e098fe0..43b701b 100644
--- a/WebCore/bridge/npapi.h
+++ b/WebCore/bridge/npapi.h
@@ -108,9 +108,7 @@
/*----------------------------------------------------------------------*/
#define NP_VERSION_MAJOR 0
-#define NP_VERSION_MINOR 20
-
-
+#define NP_VERSION_MINOR 24
/*----------------------------------------------------------------------*/
/* Definition of Basic Types */
@@ -343,13 +341,16 @@ typedef enum {
*/
NPPVpluginWantsAllNetworkStreams = 18,
+ NPPVpluginPrivateModeBool = 19,
+
+ /* Checks to see if the plug-in would like the browser to load the "src" attribute. */
+ NPPVpluginCancelSrcStream = 20,
+
#ifdef XP_MACOSX
/* Used for negotiating drawing models */
NPPVpluginDrawingModel = 1000,
/* Used for negotiating event models */
NPPVpluginEventModel = 1001,
- /* The plug-in text input vtable */
- NPPVpluginTextInputFuncs = 1002,
/* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */
NPPVpluginCoreAnimationLayer = 1003
#endif
@@ -383,7 +384,9 @@ typedef enum {
/* Get the NPObject wrapper for the plugins DOM element. */
NPNVPluginElementNPObject = 16,
- NPNVSupportsWindowless = 17
+ NPNVSupportsWindowless = 17,
+
+ NPNVprivateModeBool = 18
#ifdef XP_MACOSX
, NPNVpluginDrawingModel = 1000 /* The NPDrawingModel specified by the plugin */
@@ -400,7 +403,6 @@ typedef enum {
#endif
, NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */
- , NPNVbrowserTextInputFuncs = 1002 /* The browser text input vtable */
#endif /* XP_MACOSX */
#ifdef ANDROID
@@ -408,6 +410,11 @@ typedef enum {
#endif
} NPNVariable;
+typedef enum {
+ NPNURLVCookie = 501,
+ NPNURLVProxy
+} NPNURLVariable;
+
/*
* The type of a NPWindow - it specifies the type of the data structure
* returned in the window field.
@@ -457,6 +464,7 @@ typedef enum {
NPCocoaEventFocusChanged,
NPCocoaEventWindowFocusChanged,
NPCocoaEventScrollWheel,
+ NPCocoaEventTextInput
} NPCocoaEventType;
typedef struct _NPNSString NPNSString;
@@ -493,7 +501,10 @@ typedef struct _NPCocoaEvent {
} draw;
struct {
NPBool hasFocus;
- } focus;
+ } focus;
+ struct {
+ NPNSString *text;
+ } text;
} data;
} NPCocoaEvent;
@@ -734,7 +745,11 @@ typedef struct NP_Port
#define NPVERS_HAS_RESPONSE_HEADERS 17
#define NPVERS_HAS_NPOBJECT_ENUM 18
#define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19
-#define NPVERS_MACOSX_HAS_EVENT_MODELS 20
+#define NPVERS_HAS_ALL_NETWORK_STREAMS 20
+#define NPVERS_HAS_URL_AND_AUTH_INFO 21
+#define NPVERS_HAS_PRIVATE_MODE 22
+#define NPVERS_MACOSX_HAS_EVENT_MODELS 23
+#define NPVERS_HAS_CANCEL_SRC_STREAM 24
/*----------------------------------------------------------------------*/
/* Function Prototypes */
diff --git a/WebCore/bridge/npruntime.cpp b/WebCore/bridge/npruntime.cpp
index bb31c6e..ab67076 100644
--- a/WebCore/bridge/npruntime.cpp
+++ b/WebCore/bridge/npruntime.cpp
@@ -27,6 +27,7 @@
#if ENABLE(NETSCAPE_PLUGIN_API)
+#include "IdentifierRep.h"
#include "npruntime_internal.h"
#include "npruntime_impl.h"
#include "npruntime_priv.h"
@@ -38,52 +39,11 @@
#include <wtf/HashMap.h>
using namespace JSC::Bindings;
-
-typedef HashMap<RefPtr<JSC::UString::Rep>, PrivateIdentifier*> StringIdentifierMap;
-
-static StringIdentifierMap* getStringIdentifierMap()
-{
- static StringIdentifierMap* stringIdentifierMap = 0;
- if (!stringIdentifierMap)
- stringIdentifierMap = new StringIdentifierMap;
- return stringIdentifierMap;
-}
-
-typedef HashMap<int, PrivateIdentifier*> IntIdentifierMap;
-
-static IntIdentifierMap* getIntIdentifierMap()
-{
- static IntIdentifierMap* intIdentifierMap = 0;
- if (!intIdentifierMap)
- intIdentifierMap = new IntIdentifierMap;
- return intIdentifierMap;
-}
+using namespace WebCore;
NPIdentifier _NPN_GetStringIdentifier(const NPUTF8* name)
{
- ASSERT(name);
-
- if (name) {
- PrivateIdentifier* identifier = 0;
-
- JSC::JSLock lock(false);
-
- identifier = getStringIdentifierMap()->get(identifierFromNPIdentifier(name).ustring().rep());
- if (identifier == 0) {
- identifier = (PrivateIdentifier*)malloc(sizeof(PrivateIdentifier));
- if (!identifier)
- CRASH();
- // We never release identifier names, so this dictionary will grow, as will
- // the memory for the identifier name strings.
- identifier->isString = true;
- identifier->value.string = strdup(name);
-
- getStringIdentifierMap()->set(identifierFromNPIdentifier(name).ustring().rep(), identifier);
- }
- return (NPIdentifier)identifier;
- }
-
- return 0;
+ return static_cast<NPIdentifier>(IdentifierRep::get(name));
}
void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers)
@@ -91,65 +51,34 @@ void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdenti
ASSERT(names);
ASSERT(identifiers);
- if (names && identifiers)
+ if (names && identifiers) {
for (int i = 0; i < nameCount; i++)
identifiers[i] = _NPN_GetStringIdentifier(names[i]);
+ }
}
NPIdentifier _NPN_GetIntIdentifier(int32_t intid)
{
- PrivateIdentifier* identifier;
-
- if (intid == 0 || intid == -1) {
- static PrivateIdentifier* negativeOneAndZeroIdentifiers[2];
-
- identifier = negativeOneAndZeroIdentifiers[intid + 1];
- if (!identifier) {
- identifier = (PrivateIdentifier*)malloc(sizeof(PrivateIdentifier));
- if (!identifier)
- CRASH();
- identifier->isString = false;
- identifier->value.number = intid;
-
- negativeOneAndZeroIdentifiers[intid + 1] = identifier;
- }
- } else {
- identifier = getIntIdentifierMap()->get(intid);
- if (!identifier) {
- identifier = (PrivateIdentifier*)malloc(sizeof(PrivateIdentifier));
- if (!identifier)
- CRASH();
- // We never release identifier names, so this dictionary will grow.
- identifier->isString = false;
- identifier->value.number = intid;
-
- getIntIdentifierMap()->set(intid, identifier);
- }
- }
- return (NPIdentifier)identifier;
+ return static_cast<NPIdentifier>(IdentifierRep::get(intid));
}
bool _NPN_IdentifierIsString(NPIdentifier identifier)
{
- PrivateIdentifier* i = (PrivateIdentifier*)identifier;
- return i->isString;
+ return static_cast<IdentifierRep*>(identifier)->isString();
}
NPUTF8 *_NPN_UTF8FromIdentifier(NPIdentifier identifier)
{
- PrivateIdentifier* i = (PrivateIdentifier*)identifier;
- if (!i->isString || !i->value.string)
- return NULL;
-
- return (NPUTF8 *)strdup(i->value.string);
+ const char* string = static_cast<IdentifierRep*>(identifier)->string();
+ if (!string)
+ return 0;
+
+ return strdup(string);
}
int32_t _NPN_IntFromIdentifier(NPIdentifier identifier)
{
- PrivateIdentifier* i = (PrivateIdentifier*)identifier;
- if (i->isString)
- return 0;
- return i->value.number;
+ return static_cast<IdentifierRep*>(identifier)->number();
}
void NPN_InitializeVariantWithStringCopy(NPVariant* variant, const NPString* value)
diff --git a/WebCore/bridge/npruntime_internal.h b/WebCore/bridge/npruntime_internal.h
index 5ccdecd..736a7f1 100644
--- a/WebCore/bridge/npruntime_internal.h
+++ b/WebCore/bridge/npruntime_internal.h
@@ -47,4 +47,5 @@
#undef Bool
#undef FontChange
#undef GrayScale
+ #undef NormalState
#endif
diff --git a/WebCore/bridge/qt/qt_instance.cpp b/WebCore/bridge/qt/qt_instance.cpp
index 0848463..d2a9cc6 100644
--- a/WebCore/bridge/qt/qt_instance.cpp
+++ b/WebCore/bridge/qt/qt_instance.cpp
@@ -98,12 +98,13 @@ void QtRuntimeObjectImp::removeFromCache()
}
// QtInstance
-QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject)
+QtInstance::QtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership)
: Instance(rootObject)
, m_class(0)
, m_object(o)
, m_hashkey(o)
, m_defaultMethod(0)
+ , m_ownership(ownership)
{
}
@@ -121,9 +122,23 @@ QtInstance::~QtInstance()
delete f;
}
m_fields.clear();
+
+ if (m_object) {
+ switch (m_ownership) {
+ case QScriptEngine::QtOwnership:
+ break;
+ case QScriptEngine::AutoOwnership:
+ if (m_object->parent())
+ break;
+ // fall through!
+ case QScriptEngine::ScriptOwnership:
+ delete m_object;
+ break;
+ }
+ }
}
-PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObject> rootObject)
+PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership)
{
JSLock lock(false);
@@ -132,7 +147,7 @@ PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObje
return instance;
}
- RefPtr<QtInstance> ret = QtInstance::create(o, rootObject);
+ RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership);
cachedInstances.insert(o, ret.get());
return ret.release();
diff --git a/WebCore/bridge/qt/qt_instance.h b/WebCore/bridge/qt/qt_instance.h
index 4cfaff8..526adb4 100644
--- a/WebCore/bridge/qt/qt_instance.h
+++ b/WebCore/bridge/qt/qt_instance.h
@@ -20,6 +20,7 @@
#ifndef BINDINGS_QT_INSTANCE_H_
#define BINDINGS_QT_INSTANCE_H_
+#include <QtScript/qscriptengine.h>
#include "runtime.h"
#include "runtime_root.h"
#include <qpointer.h>
@@ -59,7 +60,7 @@ public:
QObject* getObject() const { return m_object; }
- static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>);
+ static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>, QScriptEngine::ValueOwnership ownership);
virtual bool getOwnPropertySlot(JSObject*, ExecState*, const Identifier&, PropertySlot&);
virtual void put(JSObject*, ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
@@ -67,14 +68,14 @@ public:
static QtInstance* getInstance(JSObject*);
private:
- static PassRefPtr<QtInstance> create(QObject *instance, PassRefPtr<RootObject> rootObject)
+ static PassRefPtr<QtInstance> create(QObject *instance, PassRefPtr<RootObject> rootObject, QScriptEngine::ValueOwnership ownership)
{
- return adoptRef(new QtInstance(instance, rootObject));
+ return adoptRef(new QtInstance(instance, rootObject, ownership));
}
friend class QtClass;
friend class QtField;
- QtInstance(QObject*, PassRefPtr<RootObject>); // Factory produced only..
+ QtInstance(QObject*, PassRefPtr<RootObject>, QScriptEngine::ValueOwnership ownership); // Factory produced only..
mutable QtClass* m_class;
QPointer<QObject> m_object;
QObject* m_hashkey;
@@ -82,6 +83,7 @@ private:
mutable QHash<QString, QtField*> m_fields;
mutable QSet<JSValuePtr> m_children;
mutable QtRuntimeMetaMethod* m_defaultMethod;
+ QScriptEngine::ValueOwnership m_ownership;
};
} // namespace Bindings
diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp
index 282de42..31b343e 100644
--- a/WebCore/bridge/qt/qt_runtime.cpp
+++ b/WebCore/bridge/qt/qt_runtime.cpp
@@ -24,7 +24,9 @@
#include "DateMath.h"
#include "DatePrototype.h"
#include "FunctionPrototype.h"
+#include "Interpreter.h"
#include "JSArray.h"
+#include "JSByteArray.h"
#include "JSDOMBinding.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
@@ -95,7 +97,8 @@ typedef enum {
QObj,
Object,
Null,
- RTArray
+ RTArray,
+ JSByteArray
} JSRealType;
#if defined(QTWK_RUNTIME_CONVERSION_DEBUG) || defined(QTWK_RUNTIME_MATCH_DEBUG)
@@ -120,6 +123,8 @@ static JSRealType valueRealType(ExecState* exec, JSValuePtr val)
return Boolean;
else if (val.isNull())
return Null;
+ else if (isJSByteArray(&exec->globalData(), val))
+ return JSByteArray;
else if (val.isObject()) {
JSObject *object = val.toObject(exec);
if (object->inherits(&RuntimeArray::s_info)) // RuntimeArray 'inherits' from Array, but not in C++
@@ -190,6 +195,9 @@ QVariant convertValueToQVariant(ExecState* exec, JSValuePtr value, QMetaType::Ty
case QObj:
hint = QMetaType::QObjectStar;
break;
+ case JSByteArray:
+ hint = QMetaType::QByteArray;
+ break;
case Array:
case RTArray:
hint = QMetaType::QVariantList;
@@ -425,12 +433,18 @@ QVariant convertValueToQVariant(ExecState* exec, JSValuePtr value, QMetaType::Ty
}
case QMetaType::QByteArray: {
- UString ustring = value.toString(exec);
- ret = QVariant(QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()).toLatin1());
- if (type == String)
- dist = 5;
- else
- dist = 10;
+ if (type == JSByteArray) {
+ WTF::ByteArray* arr = asByteArray(value)->storage();
+ ret = QVariant(QByteArray(reinterpret_cast<const char*>(arr->data()), arr->length()));
+ dist = 0;
+ } else {
+ UString ustring = value.toString(exec);
+ ret = QVariant(QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()).toLatin1());
+ if (type == String)
+ dist = 5;
+ else
+ dist = 10;
+ }
break;
}
@@ -822,14 +836,15 @@ JSValuePtr convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root,
}
if (type == QMetaType::QByteArray) {
- QByteArray ba = variant.value<QByteArray>();
- UString ustring(ba.constData());
- return jsString(exec, ustring);
+ QByteArray qtByteArray = variant.value<QByteArray>();
+ WTF::RefPtr<WTF::ByteArray> wtfByteArray = WTF::ByteArray::create(qtByteArray.length());
+ qMemCopy(wtfByteArray->data(), qtByteArray.constData(), qtByteArray.length());
+ return new (exec) JSC::JSByteArray(exec, JSC::JSByteArray::createStructure(jsNull()), wtfByteArray.get());
}
if (type == QMetaType::QObjectStar || type == QMetaType::QWidgetStar) {
QObject* obj = variant.value<QObject*>();
- return QtInstance::getQtInstance(obj, root)->createRuntimeObject(exec);
+ return QtInstance::getQtInstance(obj, root, QScriptEngine::QtOwnership)->createRuntimeObject(exec);
}
if (type == QMetaType::QVariantMap) {
@@ -1678,7 +1693,7 @@ void QtConnectionObject::execute(void **argv)
if (m_funcObject->inherits(&JSFunction::info)) {
JSFunction* fimp = static_cast<JSFunction*>(m_funcObject.get());
- JSObject* qt_sender = QtInstance::getQtInstance(sender(), ro)->createRuntimeObject(exec);
+ 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);
diff --git a/WebCore/bridge/testbindings.mm b/WebCore/bridge/testbindings.mm
index 9215c48..ca70e17 100644
--- a/WebCore/bridge/testbindings.mm
+++ b/WebCore/bridge/testbindings.mm
@@ -103,7 +103,7 @@
}
/*
-- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args;
+- (id)invokeUndefinedMethodFromWebScript:(NSString *)name withArguments:(NSArray *)args
{
NSLog (@"Call to undefined method %@", name);
NSLog (@"%d args\n", [args count]);
diff --git a/WebCore/config.h b/WebCore/config.h
index ddb772b..4a882bf 100644
--- a/WebCore/config.h
+++ b/WebCore/config.h
@@ -131,6 +131,7 @@
#endif
#if PLATFORM(MAC)
+// ATSUI vs. CoreText
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
#define WTF_USE_ATSUI 0
#define WTF_USE_CORE_TEXT 1
@@ -138,8 +139,15 @@
#define WTF_USE_ATSUI 1
#define WTF_USE_CORE_TEXT 0
#endif
+
+// New theme
#define WTF_USE_NEW_THEME 1
+
+// Accelerated compositing
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#define WTF_USE_ACCELERATED_COMPOSITING 0
#endif
+#endif // PLATFORM(MAC)
#if PLATFORM(SYMBIAN)
#undef WIN32
diff --git a/WebCore/css/CSSComputedStyleDeclaration.cpp b/WebCore/css/CSSComputedStyleDeclaration.cpp
index 73e0165..6103b2c 100644
--- a/WebCore/css/CSSComputedStyleDeclaration.cpp
+++ b/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -23,6 +23,7 @@
#include "config.h"
#include "CSSComputedStyleDeclaration.h"
+#include "AnimationController.h"
#include "CSSBorderImageValue.h"
#include "CSSMutableStyleDeclaration.h"
#include "CSSPrimitiveValue.h"
@@ -37,6 +38,7 @@
#include "Pair.h"
#include "Rect.h"
#include "RenderBox.h"
+#include "RenderLayer.h"
#include "ShadowValue.h"
#ifdef ANDROID_LAYOUT
#include "Frame.h"
@@ -44,6 +46,7 @@
#endif
#include "WebKitCSSTransformValue.h"
+
#if ENABLE(DASHBOARD_SUPPORT)
#include "DashboardRegion.h"
#endif
@@ -141,9 +144,9 @@ static const int computedProperties[] = {
CSSPropertyWebkitAnimationDuration,
CSSPropertyWebkitAnimationIterationCount,
CSSPropertyWebkitAnimationName,
- CSSPropertyWebkitAnimationPlayState,
CSSPropertyWebkitAnimationTimingFunction,
CSSPropertyWebkitAppearance,
+ CSSPropertyWebkitBackfaceVisibility,
CSSPropertyWebkitBackgroundClip,
CSSPropertyWebkitBackgroundComposite,
CSSPropertyWebkitBackgroundOrigin,
@@ -191,6 +194,8 @@ static const int computedProperties[] = {
CSSPropertyWebkitMaskOrigin,
CSSPropertyWebkitMaskSize,
CSSPropertyWebkitNbspMode,
+ CSSPropertyWebkitPerspective,
+ CSSPropertyWebkitPerspectiveOrigin,
CSSPropertyWebkitRtlOrdering,
CSSPropertyWebkitTextDecorationsInEffect,
CSSPropertyWebkitTextFillColor,
@@ -199,6 +204,7 @@ static const int computedProperties[] = {
CSSPropertyWebkitTextStrokeWidth,
CSSPropertyWebkitTransform,
CSSPropertyWebkitTransformOrigin,
+ CSSPropertyWebkitTransformStyle,
CSSPropertyWebkitTransitionDelay,
CSSPropertyWebkitTransitionDuration,
CSSPropertyWebkitTransitionProperty,
@@ -410,24 +416,57 @@ static IntRect sizingBox(RenderObject* renderer)
return box->style()->boxSizing() == CONTENT_BOX ? box->contentBoxRect() : box->borderBoxRect();
}
-static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer)
+static inline bool hasCompositedLayer(RenderObject* renderer)
+{
+ return renderer && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->isComposited();
+}
+
+static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
{
- if (!renderer || renderer->style()->transform().operations().isEmpty())
+ if (!renderer || style->transform().operations().isEmpty())
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
IntRect box = sizingBox(renderer);
TransformationMatrix transform;
- renderer->style()->applyTransform(transform, box.size(), false);
+ style->applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
+ // Note that this does not flatten to an affine transform if ENABLE(3D_RENDERING) is off, by design.
- RefPtr<WebKitCSSTransformValue> transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
+ RefPtr<WebKitCSSTransformValue> transformVal;
- transformVal->append(CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
- transformVal->append(CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
- transformVal->append(CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
- transformVal->append(CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
- transformVal->append(CSSPrimitiveValue::create(transform.e(), CSSPrimitiveValue::CSS_NUMBER));
- transformVal->append(CSSPrimitiveValue::create(transform.f(), CSSPrimitiveValue::CSS_NUMBER));
+ // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
+ if (transform.isAffine()) {
+ transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
+
+ transformVal->append(CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.e(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.f(), CSSPrimitiveValue::CSS_NUMBER));
+ } else {
+ transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
+
+ transformVal->append(CSSPrimitiveValue::create(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
+
+ transformVal->append(CSSPrimitiveValue::create(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
+
+ transformVal->append(CSSPrimitiveValue::create(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
+
+ transformVal->append(CSSPrimitiveValue::create(transform.m41(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m42(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m43(), CSSPrimitiveValue::CSS_NUMBER));
+ transformVal->append(CSSPrimitiveValue::create(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
+ }
RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(transformVal);
@@ -524,7 +563,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
RenderObject* renderer = node->renderer();
- RenderStyle* style = node->computedStyle();
+ RefPtr<RenderStyle> style;
+ if (renderer && hasCompositedLayer(renderer) && AnimationController::supportsAcceleratedAnimationOfProperty(static_cast<CSSPropertyID>(propertyID)))
+ style = renderer->animation()->getAnimatedStyleForRenderer(renderer);
+ else
+ style = node->computedStyle();
if (!style)
return 0;
@@ -588,13 +631,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyWebkitBorderVerticalSpacing:
return CSSPrimitiveValue::create(style->verticalBorderSpacing(), CSSPrimitiveValue::CSS_PX);
case CSSPropertyBorderTopColor:
- return currentColorOrValidColor(style, style->borderTopColor());
+ return currentColorOrValidColor(style.get(), style->borderTopColor());
case CSSPropertyBorderRightColor:
- return currentColorOrValidColor(style, style->borderRightColor());
+ return currentColorOrValidColor(style.get(), style->borderRightColor());
case CSSPropertyBorderBottomColor:
- return currentColorOrValidColor(style, style->borderBottomColor());
+ return currentColorOrValidColor(style.get(), style->borderBottomColor());
case CSSPropertyBorderLeftColor:
- return currentColorOrValidColor(style, style->borderLeftColor());
+ return currentColorOrValidColor(style.get(), style->borderLeftColor());
case CSSPropertyBorderTopStyle:
return CSSPrimitiveValue::create(style->borderTopStyle());
case CSSPropertyBorderRightStyle:
@@ -612,7 +655,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyBorderLeftWidth:
return CSSPrimitiveValue::create(style->borderLeftWidth(), CSSPrimitiveValue::CSS_PX);
case CSSPropertyBottom:
- return getPositionOffsetValue(style, CSSPropertyBottom);
+ return getPositionOffsetValue(style.get(), CSSPropertyBottom);
case CSSPropertyWebkitBoxAlign:
return CSSPrimitiveValue::create(style->boxAlign());
case CSSPropertyWebkitBoxDirection:
@@ -654,7 +697,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyWebkitColumnRuleColor:
- return currentColorOrValidColor(style, style->columnRuleColor());
+ return currentColorOrValidColor(style.get(), style->columnRuleColor());
case CSSPropertyWebkitColumnRuleStyle:
return CSSPrimitiveValue::create(style->columnRuleStyle());
case CSSPropertyWebkitColumnRuleWidth:
@@ -747,7 +790,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return CSSPrimitiveValue::createIdentifier(CSSValueBorder);
return CSSPrimitiveValue::createIdentifier(CSSValueLines);
case CSSPropertyLeft:
- return getPositionOffsetValue(style, CSSPropertyLeft);
+ return getPositionOffsetValue(style.get(), CSSPropertyLeft);
case CSSPropertyLetterSpacing:
if (!style->letterSpacing())
return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
@@ -864,7 +907,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyOrphans:
return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyOutlineColor:
- return currentColorOrValidColor(style, style->outlineColor());
+ return currentColorOrValidColor(style.get(), style->outlineColor());
case CSSPropertyOutlineStyle:
if (style->outlineStyleIsAuto())
return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
@@ -915,7 +958,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
#endif
return CSSPrimitiveValue::create(style->position());
case CSSPropertyRight:
- return getPositionOffsetValue(style, CSSPropertyRight);
+ return getPositionOffsetValue(style.get(), CSSPropertyRight);
case CSSPropertyTableLayout:
return CSSPrimitiveValue::create(style->tableLayout());
case CSSPropertyTextAlign:
@@ -967,7 +1010,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return CSSPrimitiveValue::create(string, CSSPrimitiveValue::CSS_STRING);
}
case CSSPropertyWebkitTextFillColor:
- return currentColorOrValidColor(style, style->textFillColor());
+ return currentColorOrValidColor(style.get(), style->textFillColor());
case CSSPropertyTextIndent:
return CSSPrimitiveValue::create(style->textIndent());
case CSSPropertyTextShadow:
@@ -979,13 +1022,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyWebkitTextStrokeColor:
- return currentColorOrValidColor(style, style->textStrokeColor());
+ return currentColorOrValidColor(style.get(), style->textStrokeColor());
case CSSPropertyWebkitTextStrokeWidth:
return CSSPrimitiveValue::create(style->textStrokeWidth(), CSSPrimitiveValue::CSS_PX);
case CSSPropertyTextTransform:
return CSSPrimitiveValue::create(style->textTransform());
case CSSPropertyTop:
- return getPositionOffsetValue(style, CSSPropertyTop);
+ return getPositionOffsetValue(style.get(), CSSPropertyTop);
case CSSPropertyUnicodeBidi:
return CSSPrimitiveValue::create(style->unicodeBidi());
case CSSPropertyVerticalAlign:
@@ -1122,7 +1165,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
if (t) {
for (size_t i = 0; i < t->size(); ++i) {
int iterationCount = t->animation(i)->iterationCount();
- if (iterationCount < 0)
+ if (iterationCount == Animation::IterationCountInfinite)
list->append(CSSPrimitiveValue::createIdentifier(CSSValueInfinite));
else
list->append(CSSPrimitiveValue::create(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
@@ -1142,25 +1185,12 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
return list.release();
}
- case CSSPropertyWebkitAnimationPlayState: {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const AnimationList* t = style->animations();
- if (t) {
- for (size_t i = 0; i < t->size(); ++i) {
- int prop = t->animation(i)->playState();
- if (prop == AnimPlayStatePlaying)
- list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning));
- else
- list->append(CSSPrimitiveValue::createIdentifier(CSSValuePaused));
- }
- } else
- list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning));
- return list.release();
- }
case CSSPropertyWebkitAnimationTimingFunction:
return getTimingFunctionValue(style->animations());
case CSSPropertyWebkitAppearance:
return CSSPrimitiveValue::create(style->appearance());
+ case CSSPropertyWebkitBackfaceVisibility:
+ return CSSPrimitiveValue::createIdentifier((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
case CSSPropertyWebkitBorderImage:
return valueForNinePieceImage(style->borderImage());
case CSSPropertyWebkitMaskBoxImage:
@@ -1172,6 +1202,23 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return CSSPrimitiveValue::create(style->marginBottomCollapse());
case CSSPropertyWebkitMarginTopCollapse:
return CSSPrimitiveValue::create(style->marginTopCollapse());
+ case CSSPropertyWebkitPerspective:
+ if (!style->hasPerspective())
+ return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+ return CSSPrimitiveValue::create(style->perspective(), CSSPrimitiveValue::CSS_NUMBER);
+ case CSSPropertyWebkitPerspectiveOrigin: {
+ RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ if (renderer) {
+ IntRect box = sizingBox(renderer);
+ list->append(CSSPrimitiveValue::create(style->perspectiveOriginX().calcMinValue(box.width()), CSSPrimitiveValue::CSS_PX));
+ list->append(CSSPrimitiveValue::create(style->perspectiveOriginY().calcMinValue(box.height()), CSSPrimitiveValue::CSS_PX));
+ }
+ else {
+ list->append(CSSPrimitiveValue::create(style->perspectiveOriginX()));
+ list->append(CSSPrimitiveValue::create(style->perspectiveOriginY()));
+ }
+ return list.release();
+ }
case CSSPropertyWebkitRtlOrdering:
if (style->visuallyOrdered())
return CSSPrimitiveValue::createIdentifier(CSSValueVisual);
@@ -1201,19 +1248,25 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return 0;
}
case CSSPropertyWebkitTransform:
- return computedTransform(renderer);
+ return computedTransform(renderer, style.get());
case CSSPropertyWebkitTransformOrigin: {
RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (renderer) {
IntRect box = sizingBox(renderer);
list->append(CSSPrimitiveValue::create(style->transformOriginX().calcMinValue(box.width()), CSSPrimitiveValue::CSS_PX));
list->append(CSSPrimitiveValue::create(style->transformOriginY().calcMinValue(box.height()), CSSPrimitiveValue::CSS_PX));
+ if (style->transformOriginZ() != 0)
+ list->append(CSSPrimitiveValue::create(style->transformOriginZ(), CSSPrimitiveValue::CSS_PX));
} else {
list->append(CSSPrimitiveValue::create(style->transformOriginX()));
list->append(CSSPrimitiveValue::create(style->transformOriginY()));
+ if (style->transformOriginZ() != 0)
+ list->append(CSSPrimitiveValue::create(style->transformOriginZ(), CSSPrimitiveValue::CSS_PX));
}
return list.release();
}
+ case CSSPropertyWebkitTransformStyle:
+ return CSSPrimitiveValue::createIdentifier((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
case CSSPropertyWebkitTransitionDelay:
return getDelayValue(style->transitions());
case CSSPropertyWebkitTransitionDuration:
@@ -1241,6 +1294,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
return getTimingFunctionValue(style->transitions());
case CSSPropertyPointerEvents:
return CSSPrimitiveValue::create(style->pointerEvents());
+
+ /* Shorthand properties, currently not supported see bug 13658*/
case CSSPropertyBackground:
case CSSPropertyBorder:
case CSSPropertyBorderBottom:
@@ -1250,27 +1305,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyBorderStyle:
case CSSPropertyBorderTop:
case CSSPropertyBorderWidth:
- case CSSPropertyContent:
- case CSSPropertyCounterIncrement:
- case CSSPropertyCounterReset:
case CSSPropertyFont:
- case CSSPropertyFontStretch:
case CSSPropertyListStyle:
case CSSPropertyMargin:
- case CSSPropertyOutline:
- case CSSPropertyOutlineOffset:
case CSSPropertyPadding:
- case CSSPropertyPage:
- case CSSPropertyQuotes:
- case CSSPropertyScrollbar3dlightColor:
- case CSSPropertyScrollbarArrowColor:
- case CSSPropertyScrollbarDarkshadowColor:
- case CSSPropertyScrollbarFaceColor:
- case CSSPropertyScrollbarHighlightColor:
- case CSSPropertyScrollbarShadowColor:
- case CSSPropertyScrollbarTrackColor:
- case CSSPropertySrc: // Only used in @font-face rules.
- case CSSPropertySize:
+ break;
+
+ /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
case CSSPropertyTextLineThrough:
case CSSPropertyTextLineThroughColor:
case CSSPropertyTextLineThroughMode:
@@ -1287,7 +1328,26 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyTextUnderlineMode:
case CSSPropertyTextUnderlineStyle:
case CSSPropertyTextUnderlineWidth:
- case CSSPropertyUnicodeRange: // Only used in @font-face rules.
+ break;
+
+ /* Unimplemented @font-face properties */
+ case CSSPropertyFontStretch:
+ case CSSPropertySrc:
+ case CSSPropertyUnicodeRange:
+ break;
+
+ /* Other unimplemented properties */
+ case CSSPropertyContent: // FIXME: needs implementation, bug 23668
+ case CSSPropertyCounterIncrement:
+ case CSSPropertyCounterReset:
+ case CSSPropertyOutline: // FIXME: needs implementation
+ case CSSPropertyOutlineOffset: // FIXME: needs implementation
+ case CSSPropertyPage: // for @page
+ case CSSPropertyQuotes: // FIXME: needs implementation
+ case CSSPropertySize: // for @page
+ break;
+
+ /* Unimplemented -webkit- properties */
case CSSPropertyWebkitAnimation:
case CSSPropertyWebkitBorderRadius:
case CSSPropertyWebkitColumns:
@@ -1301,7 +1361,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
case CSSPropertyWebkitTextStroke:
case CSSPropertyWebkitTransition:
case CSSPropertyWebkitVariableDeclarationBlock:
- // FIXME: The above are unimplemented.
break;
#ifdef ANDROID_CSS_TAP_HIGHLIGHT_COLOR
case CSSPropertyWebkitTapHighlightColor:
diff --git a/WebCore/css/CSSFontSelector.cpp b/WebCore/css/CSSFontSelector.cpp
index 5005c39..0e26f4e 100644
--- a/WebCore/css/CSSFontSelector.cpp
+++ b/WebCore/css/CSSFontSelector.cpp
@@ -93,7 +93,7 @@ void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
RefPtr<CSSValue> fontFamily = style->getPropertyCSSValue(CSSPropertyFontFamily);
RefPtr<CSSValue> src = style->getPropertyCSSValue(CSSPropertySrc);
RefPtr<CSSValue> unicodeRange = style->getPropertyCSSValue(CSSPropertyUnicodeRange);
- if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || unicodeRange && !unicodeRange->isValueList())
+ if (!fontFamily || !src || !fontFamily->isValueList() || !src->isValueList() || (unicodeRange && !unicodeRange->isValueList()))
return;
CSSValueList* familyList = static_cast<CSSValueList*>(fontFamily.get());
@@ -433,7 +433,9 @@ static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second)
// or the next darker otherwise."
// For '400', we made up our own rule (which then '500' follows).
- static const FontTraitsMask weightFallbackRules[9][8] = {
+ static const unsigned fallbackRuleSets = 9;
+ static const unsigned rulesPerSet = 8;
+ static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
{ FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
{ FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
{ FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
@@ -445,14 +447,16 @@ static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second)
{ FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }
};
- const FontTraitsMask* weightFallbackRule = weightFallbackRules[0];
+ unsigned ruleSetIndex = 0;
unsigned w = FontWeight100Bit;
while (!(desiredTraitsMaskForComparison & (1 << w))) {
w++;
- weightFallbackRule += 8;
+ ruleSetIndex++;
}
- for (unsigned i = 0; i < 8; ++i) {
+ ASSERT(ruleSetIndex < fallbackRuleSets);
+ const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
+ for (unsigned i = 0; i < rulesPerSet; ++i) {
if (secondTraitsMask & weightFallbackRule[i])
return false;
if (firstTraitsMask & weightFallbackRule[i])
diff --git a/WebCore/css/CSSGrammar.y b/WebCore/css/CSSGrammar.y
index 1ff48bb..451591d 100644
--- a/WebCore/css/CSSGrammar.y
+++ b/WebCore/css/CSSGrammar.y
@@ -1180,7 +1180,7 @@ pseudo:
}
// used by :not
| ':' NOTFUNCTION maybe_space simple_selector maybe_space ')' {
- if (!$4)
+ if (!$4 || $4->simpleSelector() || $4->tagHistory())
$$ = 0;
else {
CSSParser* p = static_cast<CSSParser*>(parser);
diff --git a/WebCore/css/CSSMutableStyleDeclaration.cpp b/WebCore/css/CSSMutableStyleDeclaration.cpp
index 2e2064a..cf50306 100644
--- a/WebCore/css/CSSMutableStyleDeclaration.cpp
+++ b/WebCore/css/CSSMutableStyleDeclaration.cpp
@@ -81,7 +81,7 @@ CSSMutableStyleDeclaration::CSSMutableStyleDeclaration(CSSRule* parent, const CS
, m_iteratorCount(0)
#endif
{
- m_properties.reserveCapacity(numProperties);
+ m_properties.reserveInitialCapacity(numProperties);
for (int i = 0; i < numProperties; ++i) {
ASSERT(properties[i]);
m_properties.append(*properties[i]);
@@ -217,9 +217,10 @@ String CSSMutableStyleDeclaration::getPropertyValue(int propertyID) const
return getLayeredShorthandValue(properties, 6);
}
case CSSPropertyWebkitTransformOrigin: {
- const int properties[2] = { CSSPropertyWebkitTransformOriginX,
- CSSPropertyWebkitTransformOriginY };
- return getShorthandValue(properties, 2);
+ const int properties[3] = { CSSPropertyWebkitTransformOriginX,
+ CSSPropertyWebkitTransformOriginY,
+ CSSPropertyWebkitTransformOriginZ };
+ return getShorthandValue(properties, 3);
}
case CSSPropertyWebkitTransition: {
const int properties[4] = { CSSPropertyWebkitTransitionProperty, CSSPropertyWebkitTransitionDuration,
@@ -701,8 +702,8 @@ void CSSMutableStyleDeclaration::removePropertiesInSet(const int* set, unsigned
for (unsigned i = 0; i < length; ++i)
toRemove.add(set[i]);
- Vector<CSSProperty> newProperties;
- newProperties.reserveCapacity(m_properties.size());
+ Vector<CSSProperty, 4> newProperties;
+ newProperties.reserveInitialCapacity(m_properties.size());
unsigned size = m_properties.size();
for (unsigned n = 0; n < size; ++n) {
diff --git a/WebCore/css/CSSMutableStyleDeclaration.h b/WebCore/css/CSSMutableStyleDeclaration.h
index 9c84916..7951388 100644
--- a/WebCore/css/CSSMutableStyleDeclaration.h
+++ b/WebCore/css/CSSMutableStyleDeclaration.h
@@ -157,7 +157,7 @@ private:
Vector<CSSProperty>::const_iterator findPropertyWithId(int propertyId) const;
Vector<CSSProperty>::iterator findPropertyWithId(int propertyId);
- Vector<CSSProperty> m_properties;
+ Vector<CSSProperty, 4> m_properties;
Node* m_node;
unsigned m_variableDependentValueCount : 24;
diff --git a/WebCore/css/CSSParser.cpp b/WebCore/css/CSSParser.cpp
index e420a5f..98d670b 100644
--- a/WebCore/css/CSSParser.cpp
+++ b/WebCore/css/CSSParser.cpp
@@ -366,6 +366,8 @@ void CSSParser::addProperty(int propId, PassRefPtr<CSSValue> value, bool importa
CSSProperty* prop = new CSSProperty(propId, value, important, m_currentShorthand, m_implicitShorthand);
if (m_numParsedProperties >= m_maxParsedProperties) {
m_maxParsedProperties += 32;
+ if (m_maxParsedProperties > UINT_MAX / sizeof(CSSProperty*))
+ return;
m_parsedProperties = static_cast<CSSProperty**>(fastRealloc(m_parsedProperties,
m_maxParsedProperties * sizeof(CSSProperty*)));
}
@@ -375,7 +377,7 @@ void CSSParser::addProperty(int propId, PassRefPtr<CSSValue> value, bool importa
void CSSParser::rollbackLastProperties(int num)
{
ASSERT(num >= 0);
- ASSERT(m_numParsedProperties >= num);
+ ASSERT(m_numParsedProperties >= static_cast<unsigned>(num));
for (int i = 0; i < num; ++i)
delete m_parsedProperties[--m_numParsedProperties];
@@ -383,7 +385,7 @@ void CSSParser::rollbackLastProperties(int num)
void CSSParser::clearProperties()
{
- for (int i = 0; i < m_numParsedProperties; i++)
+ for (unsigned i = 0; i < m_numParsedProperties; i++)
delete m_parsedProperties[i];
m_numParsedProperties = 0;
m_hasFontFaceOnlyValues = false;
@@ -764,16 +766,6 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyWebkitBorderVerticalSpacing:
valid_primitive = validUnit(value, FLength|FNonNeg, m_strict);
break;
- case CSSPropertyScrollbarFaceColor: // IE5.5
- case CSSPropertyScrollbarShadowColor: // IE5.5
- case CSSPropertyScrollbarHighlightColor: // IE5.5
- case CSSPropertyScrollbar3dlightColor: // IE5.5
- case CSSPropertyScrollbarDarkshadowColor: // IE5.5
- case CSSPropertyScrollbarTrackColor: // IE5.5
- case CSSPropertyScrollbarArrowColor: // IE5.5
- if (m_strict)
- break;
- /* nobreak */
case CSSPropertyOutlineColor: // <color> | invert | inherit
// Outline color has "invert" as additional keyword.
// Also, we want to allow the special focus color even in strict parsing mode.
@@ -799,7 +791,7 @@ bool CSSParser::parseValue(int propId, bool important)
// since we use this in our UA sheets.
else if (id == CSSValueCurrentcolor)
valid_primitive = true;
- else if (id >= CSSValueAqua && id <= CSSValueWindowtext || id == CSSValueMenu ||
+ else if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu ||
(id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && !m_strict)) {
valid_primitive = true;
} else {
@@ -834,7 +826,7 @@ bool CSSParser::parseValue(int propId, bool important)
} else if (m_strict && nrcoords == 2)
hotspot = IntPoint(coords[0], coords[1]);
if (m_strict || coords.size() == 0) {
- if (!uri.isNull())
+ if (!uri.isNull() && m_styleSheet)
list->append(CSSCursorImageValue::create(m_styleSheet->completeURL(uri), hotspot));
}
if ((m_strict && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ',')))
@@ -900,7 +892,7 @@ bool CSSParser::parseValue(int propId, bool important)
} else if (value->unit == CSSPrimitiveValue::CSS_URI) {
// ### allow string in non strict mode?
String uri = parseURL(value->string);
- if (!uri.isNull()) {
+ if (!uri.isNull() && m_styleSheet) {
parsedValue = CSSImageValue::create(m_styleSheet->completeURL(uri));
m_valueList->next();
}
@@ -1112,7 +1104,7 @@ bool CSSParser::parseValue(int propId, bool important)
CSSParserValue* val;
RefPtr<CSSValue> parsedValue;
while ((val = m_valueList->current())) {
- if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
String value = parseURL(val->string);
parsedValue = CSSPrimitiveValue::create(m_styleSheet->completeURL(value), CSSPrimitiveValue::CSS_URI);
}
@@ -1298,11 +1290,51 @@ bool CSSParser::parseValue(int propId, bool important)
break;
case CSSPropertyWebkitTransformOrigin:
case CSSPropertyWebkitTransformOriginX:
- case CSSPropertyWebkitTransformOriginY: {
+ case CSSPropertyWebkitTransformOriginY:
+ case CSSPropertyWebkitTransformOriginZ: {
+ RefPtr<CSSValue> val1;
+ RefPtr<CSSValue> val2;
+ RefPtr<CSSValue> val3;
+ int propId1, propId2, propId3;
+ if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ if (val3)
+ addProperty(propId3, val3.release(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSSPropertyWebkitTransformStyle:
+ if (value->id == CSSValueFlat || value->id == CSSValuePreserve3d)
+ valid_primitive = true;
+ break;
+ case CSSPropertyWebkitBackfaceVisibility:
+ if (value->id == CSSValueVisible || value->id == CSSValueHidden)
+ valid_primitive = true;
+ break;
+ case CSSPropertyWebkitPerspective:
+ if (id == CSSValueNone)
+ valid_primitive = true;
+ else {
+ if (validUnit(value, FNumber|FNonNeg, m_strict)) {
+ RefPtr<CSSValue> val = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+ if (val) {
+ addProperty(propId, val.release(), important);
+ return true;
+ }
+ return false;
+ }
+ }
+ break;
+ case CSSPropertyWebkitPerspectiveOrigin:
+ case CSSPropertyWebkitPerspectiveOriginX:
+ case CSSPropertyWebkitPerspectiveOriginY: {
RefPtr<CSSValue> val1;
RefPtr<CSSValue> val2;
int propId1, propId2;
- if (parseTransformOrigin(propId, propId1, propId2, val1, val2)) {
+ if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
addProperty(propId1, val1.release(), important);
if (val2)
addProperty(propId2, val2.release(), important);
@@ -1314,7 +1346,6 @@ bool CSSParser::parseValue(int propId, bool important)
case CSSPropertyWebkitAnimationDirection:
case CSSPropertyWebkitAnimationDuration:
case CSSPropertyWebkitAnimationName:
- case CSSPropertyWebkitAnimationPlayState:
case CSSPropertyWebkitAnimationIterationCount:
case CSSPropertyWebkitAnimationTimingFunction:
case CSSPropertyWebkitTransitionDelay:
@@ -1974,7 +2005,7 @@ bool CSSParser::parseContent(int propId, bool important)
while (CSSParserValue* val = m_valueList->current()) {
RefPtr<CSSValue> parsedValue;
- if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
// url
String value = parseURL(val->string);
parsedValue = CSSImageValue::create(m_styleSheet->completeURL(value));
@@ -2047,7 +2078,7 @@ bool CSSParser::parseFillImage(RefPtr<CSSValue>& value)
}
if (m_valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
String uri = parseURL(m_valueList->current()->string);
- if (!uri.isNull())
+ if (!uri.isNull() && m_styleSheet)
value = CSSImageValue::create(m_styleSheet->completeURL(uri));
return true;
}
@@ -2216,7 +2247,10 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
case CSSPropertyWebkitBackgroundOrigin:
case CSSPropertyWebkitMaskClip:
case CSSPropertyWebkitMaskOrigin:
- if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent || val->id == CSSValueText) {
+ // The first three values here are deprecated and should not be allowed to apply when we drop the -webkit-
+ // from the property names.
+ if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent ||
+ val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox || val->id == CSSValueText) {
currValue = CSSPrimitiveValue::createIdentifier(val->id);
m_valueList->next();
}
@@ -2224,7 +2258,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
case CSSPropertyBackgroundPosition:
case CSSPropertyWebkitMaskPosition:
parseFillPosition(currValue, currValue2);
- // unlike the other functions, parseFillPosition advances the m_valueList pointer
+ // parseFillPosition advances the m_valueList pointer
break;
case CSSPropertyBackgroundPositionX:
case CSSPropertyWebkitMaskPositionX: {
@@ -2356,14 +2390,6 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationName()
return 0;
}
-PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueRunning || value->id == CSSValuePaused)
- return CSSPrimitiveValue::createIdentifier(value->id);
- return 0;
-}
-
PassRefPtr<CSSValue> CSSParser::parseAnimationProperty()
{
CSSParserValue* value = m_valueList->current();
@@ -2379,6 +2405,18 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationProperty()
return 0;
}
+void CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
+{
+ parseFillPosition(value1, value2);
+
+ // now get z
+ if (m_valueList->current() && validUnit(m_valueList->current(), FLength, m_strict))
+ value3 = CSSPrimitiveValue::create(m_valueList->current()->fValue,
+ (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
+ if (value3)
+ m_valueList->next();
+}
+
bool CSSParser::parseTimingFunctionValue(CSSParserValueList*& args, double& result)
{
CSSParserValue* v = args->current();
@@ -2473,11 +2511,6 @@ bool CSSParser::parseAnimationProperty(int propId, RefPtr<CSSValue>& result)
if (currValue)
m_valueList->next();
break;
- case CSSPropertyWebkitAnimationPlayState:
- currValue = parseAnimationPlayState();
- if (currValue)
- m_valueList->next();
- break;
case CSSPropertyWebkitTransitionProperty:
currValue = parseAnimationProperty();
if (currValue)
@@ -3096,7 +3129,7 @@ bool CSSParser::parseFontFaceSrc()
RefPtr<CSSFontFaceSrcValue> uriValue;
while ((val = m_valueList->current())) {
RefPtr<CSSFontFaceSrcValue> parsedValue;
- if (val->unit == CSSPrimitiveValue::CSS_URI && !expectComma) {
+ if (val->unit == CSSPrimitiveValue::CSS_URI && !expectComma && m_styleSheet) {
String value = parseURL(val->string);
parsedValue = CSSFontFaceSrcValue::create(m_styleSheet->completeURL(value));
uriValue = parsedValue;
@@ -3475,7 +3508,7 @@ bool CSSParser::parseShadow(int propId, bool important)
else {
// The only other type of value that's ok is a color value.
RefPtr<CSSPrimitiveValue> parsedColor;
- bool isColor = (val->id >= CSSValueAqua && val->id <= CSSValueWindowtext || val->id == CSSValueMenu ||
+ bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu ||
(val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && !m_strict));
if (isColor) {
if (!context.allowColor)
@@ -3697,7 +3730,7 @@ bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& r
// Look for an image initially. If the first value is not a URI, then we're done.
BorderImageParseContext context;
CSSParserValue* val = m_valueList->current();
- if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
String uri = parseURL(val->string);
if (uri.isNull())
return false;
@@ -4014,17 +4047,37 @@ public:
, m_allowSingleArgument(false)
, m_unit(CSSParser::FUnknown)
{
- if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "scalex(") || equalIgnoringCase(name, "scaley(")) {
+ if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "scalex(") || equalIgnoringCase(name, "scaley(") || equalIgnoringCase(name, "scalez(")) {
m_unit = CSSParser::FNumber;
if (equalIgnoringCase(name, "scale("))
m_type = WebKitCSSTransformValue::ScaleTransformOperation;
else if (equalIgnoringCase(name, "scalex("))
m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
- else
+ else if (equalIgnoringCase(name, "scaley("))
m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
+ else
+ m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
+ } else if (equalIgnoringCase(name, "scale3d(")) {
+ m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
+ m_argCount = 5;
+ m_unit = CSSParser::FNumber;
} else if (equalIgnoringCase(name, "rotate(")) {
m_type = WebKitCSSTransformValue::RotateTransformOperation;
m_unit = CSSParser::FAngle;
+ } else if (equalIgnoringCase(name, "rotatex(") ||
+ equalIgnoringCase(name, "rotatey(") ||
+ equalIgnoringCase(name, "rotatez(")) {
+ m_unit = CSSParser::FAngle;
+ if (equalIgnoringCase(name, "rotatex("))
+ m_type = WebKitCSSTransformValue::RotateXTransformOperation;
+ else if (equalIgnoringCase(name, "rotatey("))
+ m_type = WebKitCSSTransformValue::RotateYTransformOperation;
+ else
+ m_type = WebKitCSSTransformValue::RotateZTransformOperation;
+ } else if (equalIgnoringCase(name, "rotate3d(")) {
+ m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
+ m_argCount = 7;
+ m_unit = CSSParser::FNumber;
} else if (equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "skewx(") || equalIgnoringCase(name, "skewy(")) {
m_unit = CSSParser::FAngle;
if (equalIgnoringCase(name, "skew("))
@@ -4033,20 +4086,33 @@ public:
m_type = WebKitCSSTransformValue::SkewXTransformOperation;
else
m_type = WebKitCSSTransformValue::SkewYTransformOperation;
- } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translatex(") || equalIgnoringCase(name, "translatey(")) {
+ } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translatex(") || equalIgnoringCase(name, "translatey(") || equalIgnoringCase(name, "translatez(")) {
m_unit = CSSParser::FLength | CSSParser::FPercent;
if (equalIgnoringCase(name, "translate("))
m_type = WebKitCSSTransformValue::TranslateTransformOperation;
else if (equalIgnoringCase(name, "translatex("))
m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
- else
+ else if (equalIgnoringCase(name, "translatey("))
m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
+ else
+ m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
+ } else if (equalIgnoringCase(name, "translate3d(")) {
+ m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
+ m_argCount = 5;
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
} else if (equalIgnoringCase(name, "matrix(")) {
m_type = WebKitCSSTransformValue::MatrixTransformOperation;
m_argCount = 11;
m_unit = CSSParser::FNumber;
+ } else if (equalIgnoringCase(name, "matrix3d(")) {
+ m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
+ m_argCount = 31;
+ m_unit = CSSParser::FNumber;
+ } else if (equalIgnoringCase(name, "perspective(")) {
+ m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
+ m_unit = CSSParser::FNumber;
}
-
+
if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "translate(")) {
m_allowSingleArgument = true;
m_argCount = 3;
@@ -4102,7 +4168,11 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
while (a) {
CSSParser::Units unit = info.unit();
- if (!validUnit(a, unit, true))
+ // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
+ if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
+ if (!validUnit(a, FAngle, true))
+ return 0;
+ } else if (!validUnit(a, unit, true))
return 0;
// Add the value to the current transform operation.
@@ -4122,19 +4192,21 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
return list.release();
}
-bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2)
+bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
{
propId1 = propId;
propId2 = propId;
+ propId3 = propId;
if (propId == CSSPropertyWebkitTransformOrigin) {
propId1 = CSSPropertyWebkitTransformOriginX;
propId2 = CSSPropertyWebkitTransformOriginY;
+ propId3 = CSSPropertyWebkitTransformOriginZ;
}
switch (propId) {
case CSSPropertyWebkitTransformOrigin:
- parseFillPosition(value, value2);
- // Unlike the other functions, parseFillPosition advances the m_valueList pointer
+ parseTransformOriginShorthand(value, value2, value3);
+ // parseTransformOriginShorthand advances the m_valueList pointer
break;
case CSSPropertyWebkitTransformOriginX: {
bool xFound = false, yFound = true;
@@ -4150,6 +4222,45 @@ bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, Ref
m_valueList->next();
break;
}
+ case CSSPropertyWebkitTransformOriginZ: {
+ if (validUnit(m_valueList->current(), FLength, m_strict))
+ value = CSSPrimitiveValue::create(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ }
+
+ return value;
+}
+
+bool CSSParser::parsePerspectiveOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2)
+{
+ propId1 = propId;
+ propId2 = propId;
+ if (propId == CSSPropertyWebkitPerspectiveOrigin) {
+ propId1 = CSSPropertyWebkitPerspectiveOriginX;
+ propId2 = CSSPropertyWebkitPerspectiveOriginY;
+ }
+
+ switch (propId) {
+ case CSSPropertyWebkitPerspectiveOrigin:
+ parseFillPosition(value, value2);
+ break;
+ case CSSPropertyWebkitPerspectiveOriginX: {
+ bool xFound = false, yFound = true;
+ value = parseFillPositionXY(xFound, yFound);
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyWebkitPerspectiveOriginY: {
+ bool xFound = true, yFound = false;
+ value = parseFillPositionXY(xFound, yFound);
+ if (value)
+ m_valueList->next();
+ break;
+ }
}
return value;
@@ -4566,7 +4677,7 @@ CSSRule* CSSParser::createStyleRule(Vector<CSSSelector*>* selectors)
CSSRule* CSSParser::createFontFaceRule()
{
RefPtr<CSSFontFaceRule> rule = CSSFontFaceRule::create(m_styleSheet);
- for (int i = 0; i < m_numParsedProperties; ++i) {
+ for (unsigned i = 0; i < m_numParsedProperties; ++i) {
CSSProperty* property = m_parsedProperties[i];
int id = property->id();
if ((id == CSSPropertyFontWeight || id == CSSPropertyFontStyle || id == CSSPropertyFontVariant) && property->value()->isPrimitiveValue()) {
@@ -4707,7 +4818,7 @@ void CSSParser::deleteFontFaceOnlyValues()
ASSERT(m_hasFontFaceOnlyValues);
int deletedProperties = 0;
- for (int i = 0; i < m_numParsedProperties; ++i) {
+ for (unsigned i = 0; i < m_numParsedProperties; ++i) {
CSSProperty* property = m_parsedProperties[i];
int id = property->id();
if ((id == CSSPropertyFontWeight || id == CSSPropertyFontStyle || id == CSSPropertyFontVariant) && property->value()->isValueList()) {
diff --git a/WebCore/css/CSSParser.h b/WebCore/css/CSSParser.h
index 83aafa4..3b07ef9 100644
--- a/WebCore/css/CSSParser.h
+++ b/WebCore/css/CSSParser.h
@@ -94,10 +94,10 @@ namespace WebCore {
PassRefPtr<CSSValue> parseAnimationDuration();
PassRefPtr<CSSValue> parseAnimationIterationCount();
PassRefPtr<CSSValue> parseAnimationName();
- PassRefPtr<CSSValue> parseAnimationPlayState();
PassRefPtr<CSSValue> parseAnimationProperty();
PassRefPtr<CSSValue> parseAnimationTimingFunction();
+ void parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
bool parseTimingFunctionValue(CSSParserValueList*& args, double& result);
bool parseAnimationProperty(int propId, RefPtr<CSSValue>&);
bool parseTransitionShorthand(bool important);
@@ -145,8 +145,8 @@ namespace WebCore {
bool parseGradient(RefPtr<CSSValue>&);
PassRefPtr<CSSValueList> parseTransform();
- bool parseTransformOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-
+ bool parseTransformOrigin(int propId, int& propId1, int& propId2, int& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
+ bool parsePerspectiveOrigin(int propId, int& propId1, int& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
bool parseVariable(CSSVariablesDeclaration*, const String& variableName, const String& variableValue);
void parsePropertyWithResolvedVariables(int propId, bool important, CSSMutableStyleDeclaration*, CSSParserValueList*);
@@ -200,8 +200,8 @@ namespace WebCore {
CSSParserValueList* m_valueList;
CSSProperty** m_parsedProperties;
CSSSelectorList* m_selectorListForParseSelector;
- int m_numParsedProperties;
- int m_maxParsedProperties;
+ unsigned m_numParsedProperties;
+ unsigned m_maxParsedProperties;
int m_inParseShorthand;
int m_currentShorthand;
diff --git a/WebCore/css/CSSPrimitiveValue.cpp b/WebCore/css/CSSPrimitiveValue.cpp
index 43fb70b..4bf6005 100644
--- a/WebCore/css/CSSPrimitiveValue.cpp
+++ b/WebCore/css/CSSPrimitiveValue.cpp
@@ -768,7 +768,7 @@ String CSSPrimitiveValue::cssText() const
Rect* rectVal = getRectValue();
Vector<UChar> result;
- result.reserveCapacity(32);
+ result.reserveInitialCapacity(32);
append(result, rectParen);
append(result, rectVal->top()->cssText());
@@ -797,7 +797,7 @@ String CSSPrimitiveValue::cssText() const
Color color(rgbColor);
Vector<UChar> result;
- result.reserveCapacity(32);
+ result.reserveInitialCapacity(32);
if (color.hasAlpha())
append(result, rgbaParen);
else
diff --git a/WebCore/css/CSSPrimitiveValue.h b/WebCore/css/CSSPrimitiveValue.h
index d552ca0..ece9fc5 100644
--- a/WebCore/css/CSSPrimitiveValue.h
+++ b/WebCore/css/CSSPrimitiveValue.h
@@ -81,6 +81,8 @@ public:
// This unit is in CSS 3, but that isn't a finished standard yet
CSS_TURN = 108
};
+
+ static bool isUnitTypeLength(int type) { return type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG; }
static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident);
static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue);
diff --git a/WebCore/css/CSSPrimitiveValueMappings.h b/WebCore/css/CSSPrimitiveValueMappings.h
index 1712372..fd1d203 100644
--- a/WebCore/css/CSSPrimitiveValueMappings.h
+++ b/WebCore/css/CSSPrimitiveValueMappings.h
@@ -29,7 +29,12 @@
#include "CSSPrimitiveValue.h"
#include "CSSValueKeywords.h"
-#include "RenderStyle.h"
+#include "GraphicsTypes.h"
+#include "Path.h"
+#include "RenderStyleConstants.h"
+#include "SVGRenderStyleDefs.h"
+#include "TextDirection.h"
+#include "ThemeTypes.h"
namespace WebCore {
@@ -292,13 +297,13 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EFillBox e)
{
switch (e) {
case BorderFillBox:
- m_value.ident = CSSValueBorder;
+ m_value.ident = CSSValueBorderBox;
break;
case PaddingFillBox:
- m_value.ident = CSSValuePadding;
+ m_value.ident = CSSValuePaddingBox;
break;
case ContentFillBox:
- m_value.ident = CSSValueContent;
+ m_value.ident = CSSValueContentBox;
break;
case TextFillBox:
m_value.ident = CSSValueText;
@@ -310,10 +315,13 @@ template<> inline CSSPrimitiveValue::operator EFillBox() const
{
switch (m_value.ident) {
case CSSValueBorder:
+ case CSSValueBorderBox:
return BorderFillBox;
case CSSValuePadding:
+ case CSSValuePaddingBox:
return PaddingFillBox;
case CSSValueContent:
+ case CSSValueContentBox:
return ContentFillBox;
case CSSValueText:
return TextFillBox;
diff --git a/WebCore/css/CSSPropertyNames.in b/WebCore/css/CSSPropertyNames.in
index 3ad83dc..fd101e4 100644
--- a/WebCore/css/CSSPropertyNames.in
+++ b/WebCore/css/CSSPropertyNames.in
@@ -99,13 +99,6 @@ position
quotes
resize
right
-scrollbar-3dlight-color
-scrollbar-arrow-color
-scrollbar-darkshadow-color
-scrollbar-face-color
-scrollbar-highlight-color
-scrollbar-shadow-color
-scrollbar-track-color
size
src
table-layout
@@ -149,9 +142,9 @@ zoom
-webkit-animation-duration
-webkit-animation-iteration-count
-webkit-animation-name
--webkit-animation-play-state
-webkit-animation-timing-function
-webkit-appearance
+-webkit-backface-visibility
-webkit-background-clip
-webkit-background-composite
-webkit-background-origin
@@ -217,6 +210,10 @@ zoom
-webkit-match-nearest-mail-blockquote-color
-webkit-nbsp-mode
-webkit-padding-start
+-webkit-perspective
+-webkit-perspective-origin
+-webkit-perspective-origin-x
+-webkit-perspective-origin-y
-webkit-rtl-ordering
# ANDROID_CSS_TAP_HIGHLIGHT_COLOR: added CSS property (also in iPhone)
-webkit-tap-highlight-color
@@ -232,6 +229,8 @@ zoom
-webkit-transform-origin
-webkit-transform-origin-x
-webkit-transform-origin-y
+-webkit-transform-origin-z
+-webkit-transform-style
-webkit-transition
-webkit-transition-delay
-webkit-transition-duration
diff --git a/WebCore/css/CSSSelectorList.cpp b/WebCore/css/CSSSelectorList.cpp
index 7276141..5ad3809 100644
--- a/WebCore/css/CSSSelectorList.cpp
+++ b/WebCore/css/CSSSelectorList.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -54,7 +55,11 @@ void CSSSelectorList::adoptSelectorVector(Vector<CSSSelector*>& selectorVector)
m_selectorArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectorVector.size()));
for (size_t i = 0; i < size; ++i) {
memcpy(&m_selectorArray[i], selectorVector[i], sizeof(CSSSelector));
- fastFree(selectorVector[i]);
+ // We want to free the memory (which was allocated with new), but we
+ // don't want the destructor to run since it will affect the copy
+ // we've just made. In theory this is undefined, but operator delete
+ // is only defined taking a void*, so in practice it should be ok.
+ delete reinterpret_cast<char*>(selectorVector[i]);
ASSERT(!m_selectorArray[i].isLastInSelectorList());
}
m_selectorArray[size - 1].setLastInSelectorList();
@@ -65,15 +70,25 @@ void CSSSelectorList::deleteSelectors()
{
if (!m_selectorArray)
return;
+
+ // We had two cases in adoptSelectVector. The fast case of a 1 element
+ // vector took the CSSSelector directly, which was allocated with new.
+ // The second case we allocated a new fastMalloc buffer, which should be
+ // freed with fastFree, and the destructors called manually.
CSSSelector* s = m_selectorArray;
- while (1) {
- bool done = s->isLastInSelectorList();
- s->~CSSSelector();
- if (done)
- break;
- ++s;
+ bool done = s->isLastInSelectorList();
+ if (done)
+ delete s;
+ else {
+ while (1) {
+ s->~CSSSelector();
+ if (done)
+ break;
+ ++s;
+ done = s->isLastInSelectorList();
+ }
+ fastFree(m_selectorArray);
}
- fastFree(m_selectorArray);
}
}
diff --git a/WebCore/css/CSSStyleDeclaration.cpp b/WebCore/css/CSSStyleDeclaration.cpp
index b840e07..a35f817 100644
--- a/WebCore/css/CSSStyleDeclaration.cpp
+++ b/WebCore/css/CSSStyleDeclaration.cpp
@@ -142,7 +142,7 @@ void CSSStyleDeclaration::diff(CSSMutableStyleDeclaration* style) const
PassRefPtr<CSSMutableStyleDeclaration> CSSStyleDeclaration::copyPropertiesInSet(const int* set, unsigned length) const
{
Vector<CSSProperty> list;
- list.reserveCapacity(length);
+ list.reserveInitialCapacity(length);
unsigned variableDependentValueCount = 0;
for (unsigned i = 0; i < length; i++) {
RefPtr<CSSValue> value = getPropertyCSSValue(set[i]);
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index bfe0315..42b07ef 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -5,7 +5,7 @@
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
* Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -63,15 +63,18 @@
#include "HTMLTextAreaElement.h"
#include "LinkHash.h"
#include "MatrixTransformOperation.h"
+#include "Matrix3DTransformOperation.h"
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
#include "NodeRenderStyle.h"
#include "Page.h"
#include "PageGroup.h"
#include "Pair.h"
+#include "PerspectiveTransformOperation.h"
#include "Rect.h"
#include "RenderScrollbar.h"
#include "RenderScrollbarTheme.h"
+#include "RenderStyleConstants.h"
#include "RenderTheme.h"
#include "RotateTransformOperation.h"
#include "ScaleTransformOperation.h"
@@ -83,6 +86,7 @@
#include "StyleGeneratedImage.h"
#include "StyleSheetList.h"
#include "Text.h"
+#include "TransformationMatrix.h"
#include "TranslateTransformOperation.h"
#include "UserAgentStyleSheets.h"
#include "WebKitCSSKeyframeRule.h"
@@ -370,11 +374,11 @@ static PseudoState pseudoState;
static void loadFullDefaultStyle();
static void loadSimpleDefaultStyle();
// FIXME: It would be nice to use some mechanism that guarantees this is in sync with the real UA stylesheet.
-static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}";
+static const char* simpleUserAgentStyleSheet = "html,body,div{display:block}body{margin:8px}div:focus,span:focus{outline:auto 5px -webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}";
static bool elementCanUseSimpleDefaultStyle(Element* e)
{
- return e->hasTagName(htmlTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag);
+ return e->hasTagName(htmlTag) || e->hasTagName(bodyTag) || e->hasTagName(divTag) || e->hasTagName(spanTag) || e->hasTagName(brTag) || e->hasTagName(aTag);
}
static const MediaQueryEvaluator& screenEval()
@@ -683,10 +687,10 @@ void CSSStyleSelector::matchRulesForList(CSSRuleDataList* rules, int& firstRuleI
// If we're matching normal rules, set a pseudo bit if
// we really just matched a pseudo-element.
- if (m_dynamicPseudo != RenderStyle::NOPSEUDO && m_checker.m_pseudoStyle == RenderStyle::NOPSEUDO) {
+ if (m_dynamicPseudo != NOPSEUDO && m_checker.m_pseudoStyle == NOPSEUDO) {
if (m_checker.m_collectRulesOnly)
return;
- if (m_dynamicPseudo < RenderStyle::FIRST_INTERNAL_PSEUDOID)
+ if (m_dynamicPseudo < FIRST_INTERNAL_PSEUDOID)
m_style->setHasPseudoStyle(m_dynamicPseudo);
} else {
// Update our first/last rule indices in the matched rules array.
@@ -753,7 +757,7 @@ void CSSStyleSelector::sortMatchedRules(unsigned start, unsigned end)
// We have to merge sort. Ensure our merge buffer is big enough to hold
// all the items.
Vector<CSSRuleData*> rulesMergeBuffer;
- rulesMergeBuffer.reserveCapacity(end - start);
+ rulesMergeBuffer.reserveInitialCapacity(end - start);
unsigned i1 = start;
unsigned i2 = mid;
@@ -787,7 +791,7 @@ void CSSStyleSelector::initElementAndPseudoState(Element* e)
pseudoState = PseudoUnknown;
}
-void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, RenderStyle::PseudoId pseudoID)
+void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
{
m_checker.m_pseudoStyle = pseudoID;
@@ -845,7 +849,7 @@ CSSStyleSelector::SelectorChecker::SelectorChecker(Document* document, bool stri
: m_document(document)
, m_strictParsing(strictParsing)
, m_collectRulesOnly(false)
- , m_pseudoStyle(RenderStyle::NOPSEUDO)
+ , m_pseudoStyle(NOPSEUDO)
, m_documentIsHTML(document->isHTMLDocument())
{
}
@@ -878,7 +882,7 @@ PseudoState CSSStyleSelector::SelectorChecker::checkPseudoState(Element* element
bool CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* element) const
{
pseudoState = PseudoUnknown;
- RenderStyle::PseudoId dynamicPseudo = RenderStyle::NOPSEUDO;
+ PseudoId dynamicPseudo = NOPSEUDO;
return checkSelector(sel, element, 0, dynamicPseudo, true, false) == SelectorMatches;
}
@@ -933,21 +937,35 @@ bool CSSStyleSelector::canShareStyleWithElement(Node* n)
(s->hovered() == m_element->hovered()) &&
(s->active() == m_element->active()) &&
(s->focused() == m_element->focused()) &&
- (s != s->document()->getCSSTarget() && m_element != m_element->document()->getCSSTarget()) &&
+ (s != s->document()->cssTarget() && m_element != m_element->document()->cssTarget()) &&
(s->getAttribute(typeAttr) == m_element->getAttribute(typeAttr)) &&
(s->getAttribute(XMLNames::langAttr) == m_element->getAttribute(XMLNames::langAttr)) &&
(s->getAttribute(langAttr) == m_element->getAttribute(langAttr)) &&
(s->getAttribute(readonlyAttr) == m_element->getAttribute(readonlyAttr)) &&
(s->getAttribute(cellpaddingAttr) == m_element->getAttribute(cellpaddingAttr))) {
- bool isControl = s->isControl();
- if (isControl != m_element->isControl())
+ bool isControl = s->isFormControlElement();
+ if (isControl != m_element->isFormControlElement())
return false;
- if (isControl && (s->isEnabled() != m_element->isEnabled()) ||
- (s->isIndeterminate() != m_element->isIndeterminate()) ||
- (s->isChecked() != m_element->isChecked()) ||
- (s->isAutofilled() != m_element->isAutofilled()))
- return false;
-
+ if (isControl) {
+ InputElement* thisInputElement = toInputElement(s);
+ InputElement* otherInputElement = toInputElement(m_element);
+ if (thisInputElement && otherInputElement) {
+ if ((thisInputElement->isAutofilled() != otherInputElement->isAutofilled()) ||
+ (thisInputElement->isChecked() != otherInputElement->isChecked()) ||
+ (thisInputElement->isIndeterminate() != otherInputElement->isIndeterminate()))
+ return false;
+ } else
+ return false;
+
+ FormControlElement* thisFormControlElement = toFormControlElement(s);
+ FormControlElement* otherFormControlElement = toFormControlElement(m_element);
+ if (thisFormControlElement && otherFormControlElement) {
+ if (thisFormControlElement->isEnabled() != otherFormControlElement->isEnabled())
+ return false;
+ } else
+ return false;
+ }
+
if (style->transitions() || style->animations())
return false;
@@ -1211,7 +1229,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl
m_style->setPseudoState(pseudoState);
// If we have first-letter pseudo style, do not share this style
- if (m_style->hasPseudoStyle(RenderStyle::FIRST_LETTER))
+ if (m_style->hasPseudoStyle(FIRST_LETTER))
m_style->setUnique();
// Now return the style.
@@ -1293,7 +1311,7 @@ void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle*
list.clear();
}
-PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(RenderStyle::PseudoId pseudo, Element* e, RenderStyle* parentStyle)
+PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo, Element* e, RenderStyle* parentStyle)
{
if (!e)
return 0;
@@ -1427,7 +1445,10 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
// Table headers with a text-align of auto will change the text-align to center.
if (e && e->hasTagName(thTag) && style->textAlign() == TAAUTO)
style->setTextAlign(CENTER);
-
+
+ if (e && e->hasTagName(legendTag))
+ style->setDisplay(BLOCK);
+
// Mutate the display to BLOCK or TABLE for certain cases, e.g., if someone attempts to
// position or float an inline, compact, or run-in. Cache the original display, since it
// may be needed for positioned elements that have to compute their static normal flow
@@ -1466,7 +1487,7 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
// cases where objects that should be blended as a single unit end up with a non-transparent
// object wedged in between them. Auto z-index also becomes 0 for objects that specify transforms/masks/reflections.
if (style->hasAutoZIndex() && ((e && e->document()->documentElement() == e) || style->opacity() < 1.0f ||
- style->hasTransform() || style->hasMask() || style->boxReflect()))
+ style->hasTransformRelatedProperty() || style->hasMask() || style->boxReflect()))
style->setZIndex(0);
// Button, legend, input, select and textarea all consider width values of 'auto' to be 'intrinsic'.
@@ -1480,6 +1501,12 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
)) {
if (style->width().isAuto())
style->setWidth(Length(Intrinsic));
+
+ // Textarea considers overflow visible as auto.
+ if (e && e->hasTagName(textareaTag)) {
+ style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
+ style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
+ }
}
// Finally update our text decorations in effect, but don't allow text-decoration to percolate through
@@ -1526,7 +1553,7 @@ void CSSStyleSelector::adjustRenderStyle(RenderStyle* style, Element *e)
// Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
// alter fonts and heights/widths.
- if (e && e->isControl() && style->fontSize() >= 11) {
+ if (e && e->isFormControlElement() && style->fontSize() >= 11) {
// Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
// so we have to treat all image buttons as though they were explicitly sized.
if (!e->hasTagName(inputTag) || static_cast<HTMLInputElement*>(e)->inputType() != HTMLInputElement::IMAGE)
@@ -1617,14 +1644,14 @@ PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element*, c
bool CSSStyleSelector::checkSelector(CSSSelector* sel)
{
- m_dynamicPseudo = RenderStyle::NOPSEUDO;
+ m_dynamicPseudo = NOPSEUDO;
// Check the selector
SelectorMatch match = m_checker.checkSelector(sel, m_element, &m_selectorAttrs, m_dynamicPseudo, true, false, style(), m_parentStyle);
if (match != SelectorMatches)
return false;
- if (m_checker.m_pseudoStyle != RenderStyle::NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
+ if (m_checker.m_pseudoStyle != NOPSEUDO && m_checker.m_pseudoStyle != m_dynamicPseudo)
return false;
return true;
@@ -1635,7 +1662,7 @@ bool CSSStyleSelector::checkSelector(CSSSelector* sel)
// * SelectorMatches - the selector matches the element e
// * SelectorFailsLocally - the selector fails for the element e
// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
-CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
+CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
{
#if ENABLE(SVG)
// Spec: CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree
@@ -1658,7 +1685,7 @@ CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector
if (relation != CSSSelector::SubSelector)
// Bail-out if this selector is irrelevant for the pseudoStyle
- if (m_pseudoStyle != RenderStyle::NOPSEUDO && m_pseudoStyle != dynamicPseudo)
+ if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != dynamicPseudo)
return SelectorFailsCompletely;
switch (relation) {
@@ -1718,8 +1745,8 @@ CSSStyleSelector::SelectorMatch CSSStyleSelector::SelectorChecker::checkSelector
// a selector is invalid if something follows a pseudo-element
// We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
// to follow the pseudo elements.
- if (elementStyle && dynamicPseudo != RenderStyle::NOPSEUDO &&
- !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == RenderStyle::SCROLLBAR_CORNER || dynamicPseudo == RenderStyle::RESIZER) && sel->m_match == CSSSelector::PseudoClass))
+ if (elementStyle && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION &&
+ !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && sel->m_match == CSSSelector::PseudoClass))
return SelectorFailsCompletely;
return checkSelector(sel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle);
}
@@ -1794,7 +1821,7 @@ static bool htmlAttributeHasCaseInsensitiveValue(const QualifiedName& attr)
return isPossibleHTMLAttr && htmlCaseInsensitiveAttributesSet->contains(attr.localName().impl());
}
-bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
+bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Element* e, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* elementStyle, RenderStyle* elementParentStyle) const
{
if (!e)
return false;
@@ -1892,15 +1919,19 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
for (CSSSelector* subSel = sel->simpleSelector(); subSel; subSel = subSel->tagHistory()) {
// :not cannot nest. I don't really know why this is a
// restriction in CSS3, but it is, so let's honor it.
- if (subSel->simpleSelector())
- break;
+ // the parser enforces that this never occurs
+ ASSERT(!subSel->simpleSelector());
+
if (!checkOneSelector(subSel, e, selectorAttrs, dynamicPseudo, isAncestor, true, elementStyle, elementParentStyle))
return true;
}
- } else if (dynamicPseudo != RenderStyle::NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == RenderStyle::SCROLLBAR_CORNER || dynamicPseudo == RenderStyle::RESIZER)) {
+ } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) {
// CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
// (since there are no elements involved).
return checkScrollbarPseudoClass(sel, dynamicPseudo);
+ } else if (dynamicPseudo == SELECTION) {
+ if (sel->pseudoType() == CSSSelector::PseudoWindowInactive)
+ return !m_document->page()->focusController()->isActive();
}
// Normal element pseudo class checking.
@@ -2195,7 +2226,7 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
break;
}
case CSSSelector::PseudoTarget:
- if (e == e->document()->getCSSTarget())
+ if (e == e->document()->cssTarget())
return true;
break;
case CSSSelector::PseudoAnyLink:
@@ -2204,10 +2235,13 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
if (pseudoState == PseudoAnyLink || pseudoState == PseudoLink || pseudoState == PseudoVisited)
return true;
break;
- case CSSSelector::PseudoAutofill:
- if (e)
- return e->isAutofilled();
+ case CSSSelector::PseudoAutofill: {
+ if (!e || !e->isFormControlElement())
+ break;
+ if (InputElement* inputElement = toInputElement(e))
+ return inputElement->isAutofilled();
break;
+ }
case CSSSelector::PseudoLink:
if (pseudoState == PseudoUnknown || pseudoState == PseudoAnyLink)
pseudoState = checkPseudoState(e);
@@ -2259,37 +2293,62 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
}
break;
case CSSSelector::PseudoEnabled:
- if (e && e->isControl() && !e->isInputTypeHidden())
+ if (e && e->isFormControlElement()) {
+ InputElement* inputElement = toInputElement(e);
+ if (inputElement && inputElement->isInputTypeHidden())
+ break;
// The UI spec states that you can't match :enabled unless you are an object that can
// "receive focus and be activated." We will limit matching of this pseudo-class to elements
// that are non-"hidden" controls.
- return e->isEnabled();
+ return toFormControlElement(e)->isEnabled();
+ }
break;
case CSSSelector::PseudoFullPageMedia:
return e && e->document() && e->document()->isMediaDocument();
break;
case CSSSelector::PseudoDisabled:
- if (e && e->isControl() && !e->isInputTypeHidden())
+ if (e && e->isFormControlElement()) {
+ InputElement* inputElement = toInputElement(e);
+ if (inputElement && inputElement->isInputTypeHidden())
+ break;
+
// The UI spec states that you can't match :enabled unless you are an object that can
// "receive focus and be activated." We will limit matching of this pseudo-class to elements
// that are non-"hidden" controls.
- return !e->isEnabled();
+ return !toFormControlElement(e)->isEnabled();
+ }
break;
- case CSSSelector::PseudoReadOnly:
- return e && e->isTextControl() && e->isReadOnlyControl();
- case CSSSelector::PseudoReadWrite:
- return e && e->isTextControl() && !e->isReadOnlyControl();
- case CSSSelector::PseudoChecked:
+ case CSSSelector::PseudoReadOnly: {
+ if (!e || !e->isFormControlElement())
+ return false;
+ FormControlElement* formControlElement = toFormControlElement(e);
+ return formControlElement->isTextControl() && formControlElement->isReadOnlyControl();
+ }
+ case CSSSelector::PseudoReadWrite: {
+ if (!e || !e->isFormControlElement())
+ return false;
+ FormControlElement* formControlElement = toFormControlElement(e);
+ return formControlElement->isTextControl() && !formControlElement->isReadOnlyControl();
+ }
+ case CSSSelector::PseudoChecked: {
+ if (!e || !e->isFormControlElement())
+ break;
// Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
// you can't be both checked and indeterminate. We will behave like WinIE behind the scenes and just
// obey the CSS spec here in the test for matching the pseudo.
- if (e && e->isChecked() && !e->isIndeterminate())
+ InputElement* inputElement = toInputElement(e);
+ if (inputElement && inputElement->isChecked() && !inputElement->isIndeterminate())
return true;
break;
- case CSSSelector::PseudoIndeterminate:
- if (e && e->isIndeterminate())
+ }
+ case CSSSelector::PseudoIndeterminate: {
+ if (!e || !e->isFormControlElement())
+ break;
+ InputElement* inputElement = toInputElement(e);
+ if (inputElement && inputElement->isIndeterminate())
return true;
break;
+ }
case CSSSelector::PseudoRoot:
if (e == e->document()->documentElement())
return true;
@@ -2333,93 +2392,93 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
switch (sel->pseudoType()) {
// Pseudo-elements:
case CSSSelector::PseudoFirstLine:
- dynamicPseudo = RenderStyle::FIRST_LINE;
+ dynamicPseudo = FIRST_LINE;
return true;
case CSSSelector::PseudoFirstLetter:
- dynamicPseudo = RenderStyle::FIRST_LETTER;
+ dynamicPseudo = FIRST_LETTER;
if (Document* doc = e->document())
doc->setUsesFirstLetterRules(true);
return true;
case CSSSelector::PseudoSelection:
- dynamicPseudo = RenderStyle::SELECTION;
+ dynamicPseudo = SELECTION;
return true;
case CSSSelector::PseudoBefore:
- dynamicPseudo = RenderStyle::BEFORE;
+ dynamicPseudo = BEFORE;
return true;
case CSSSelector::PseudoAfter:
- dynamicPseudo = RenderStyle::AFTER;
+ dynamicPseudo = AFTER;
return true;
case CSSSelector::PseudoFileUploadButton:
- dynamicPseudo = RenderStyle::FILE_UPLOAD_BUTTON;
+ dynamicPseudo = FILE_UPLOAD_BUTTON;
return true;
case CSSSelector::PseudoInputPlaceholder:
- dynamicPseudo = RenderStyle::INPUT_PLACEHOLDER;
+ dynamicPseudo = INPUT_PLACEHOLDER;
return true;
case CSSSelector::PseudoSliderThumb:
- dynamicPseudo = RenderStyle::SLIDER_THUMB;
+ dynamicPseudo = SLIDER_THUMB;
return true;
case CSSSelector::PseudoSearchCancelButton:
- dynamicPseudo = RenderStyle::SEARCH_CANCEL_BUTTON;
+ dynamicPseudo = SEARCH_CANCEL_BUTTON;
return true;
case CSSSelector::PseudoSearchDecoration:
- dynamicPseudo = RenderStyle::SEARCH_DECORATION;
+ dynamicPseudo = SEARCH_DECORATION;
return true;
case CSSSelector::PseudoSearchResultsDecoration:
- dynamicPseudo = RenderStyle::SEARCH_RESULTS_DECORATION;
+ dynamicPseudo = SEARCH_RESULTS_DECORATION;
return true;
case CSSSelector::PseudoSearchResultsButton:
- dynamicPseudo = RenderStyle::SEARCH_RESULTS_BUTTON;
+ dynamicPseudo = SEARCH_RESULTS_BUTTON;
return true;
case CSSSelector::PseudoMediaControlsPanel:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_PANEL;
+ dynamicPseudo = MEDIA_CONTROLS_PANEL;
return true;
case CSSSelector::PseudoMediaControlsMuteButton:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_MUTE_BUTTON;
+ dynamicPseudo = MEDIA_CONTROLS_MUTE_BUTTON;
return true;
case CSSSelector::PseudoMediaControlsPlayButton:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_PLAY_BUTTON;
+ dynamicPseudo = MEDIA_CONTROLS_PLAY_BUTTON;
return true;
case CSSSelector::PseudoMediaControlsTimelineContainer:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_TIMELINE_CONTAINER;
+ dynamicPseudo = MEDIA_CONTROLS_TIMELINE_CONTAINER;
return true;
case CSSSelector::PseudoMediaControlsCurrentTimeDisplay:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_CURRENT_TIME_DISPLAY;
+ dynamicPseudo = MEDIA_CONTROLS_CURRENT_TIME_DISPLAY;
return true;
case CSSSelector::PseudoMediaControlsTimeRemainingDisplay:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_TIME_REMAINING_DISPLAY;
+ dynamicPseudo = MEDIA_CONTROLS_TIME_REMAINING_DISPLAY;
return true;
case CSSSelector::PseudoMediaControlsTimeline:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_TIMELINE;
+ dynamicPseudo = MEDIA_CONTROLS_TIMELINE;
return true;
case CSSSelector::PseudoMediaControlsSeekBackButton:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_SEEK_BACK_BUTTON;
+ dynamicPseudo = MEDIA_CONTROLS_SEEK_BACK_BUTTON;
return true;
case CSSSelector::PseudoMediaControlsSeekForwardButton:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_SEEK_FORWARD_BUTTON;
+ dynamicPseudo = MEDIA_CONTROLS_SEEK_FORWARD_BUTTON;
return true;
case CSSSelector::PseudoMediaControlsFullscreenButton:
- dynamicPseudo = RenderStyle::MEDIA_CONTROLS_FULLSCREEN_BUTTON;
+ dynamicPseudo = MEDIA_CONTROLS_FULLSCREEN_BUTTON;
return true;
case CSSSelector::PseudoScrollbar:
- dynamicPseudo = RenderStyle::SCROLLBAR;
+ dynamicPseudo = SCROLLBAR;
return true;
case CSSSelector::PseudoScrollbarButton:
- dynamicPseudo = RenderStyle::SCROLLBAR_BUTTON;
+ dynamicPseudo = SCROLLBAR_BUTTON;
return true;
case CSSSelector::PseudoScrollbarCorner:
- dynamicPseudo = RenderStyle::SCROLLBAR_CORNER;
+ dynamicPseudo = SCROLLBAR_CORNER;
return true;
case CSSSelector::PseudoScrollbarThumb:
- dynamicPseudo = RenderStyle::SCROLLBAR_THUMB;
+ dynamicPseudo = SCROLLBAR_THUMB;
return true;
case CSSSelector::PseudoScrollbarTrack:
- dynamicPseudo = RenderStyle::SCROLLBAR_TRACK;
+ dynamicPseudo = SCROLLBAR_TRACK;
return true;
case CSSSelector::PseudoScrollbarTrackPiece:
- dynamicPseudo = RenderStyle::SCROLLBAR_TRACK_PIECE;
+ dynamicPseudo = SCROLLBAR_TRACK_PIECE;
return true;
case CSSSelector::PseudoResizer:
- dynamicPseudo = RenderStyle::RESIZER;
+ dynamicPseudo = RESIZER;
return true;
case CSSSelector::PseudoUnknown:
case CSSSelector::PseudoNotParsed:
@@ -2433,7 +2492,7 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
return true;
}
-bool CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, RenderStyle::PseudoId&) const
+bool CSSStyleSelector::SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, PseudoId&) const
{
RenderScrollbar* scrollbar = RenderScrollbar::scrollbarForStyleResolve();
ScrollbarPart part = RenderScrollbar::partForStyleResolve();
@@ -2644,7 +2703,7 @@ void CSSRuleSet::addRulesFromSheet(CSSStyleSheet* sheet, const MediaQueryEvaluat
// -------------------------------------------------------------------------------------
// this is mostly boring stuff on how to apply a certain rule to the renderstyle...
-static Length convertToLength(CSSPrimitiveValue *primitiveValue, RenderStyle *style, bool *ok = 0)
+static Length convertToLength(CSSPrimitiveValue *primitiveValue, RenderStyle *style, double multiplier = 1, bool *ok = 0)
{
// This function is tolerant of a null style value. The only place style is used is in
// length measurements, like 'ems' and 'px'. And in those cases style is only used
@@ -2659,8 +2718,8 @@ static Length convertToLength(CSSPrimitiveValue *primitiveValue, RenderStyle *st
if (!style && (type == CSSPrimitiveValue::CSS_EMS || type == CSSPrimitiveValue::CSS_EXS)) {
if (ok)
*ok = false;
- } else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
- l = Length(primitiveValue->computeLengthIntForLength(style), Fixed);
+ } else if (CSSPrimitiveValue::isUnitTypeLength(type))
+ l = Length(primitiveValue->computeLengthIntForLength(style, multiplier), Fixed);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
else if (type == CSSPrimitiveValue::CSS_NUMBER)
@@ -2957,7 +3016,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
}
if (m_style->setFontDescription(fontDescription))
m_fontDirty = true;
- return;
+ return;
}
case CSSPropertyFontWeight:
@@ -3175,7 +3234,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
HANDLE_INHERIT_AND_INITIAL(horizontalBorderSpacing, HorizontalBorderSpacing)
if (!primitiveValue)
return;
- short spacing = primitiveValue->computeLengthShort(style(), zoomFactor);
+ short spacing = primitiveValue->computeLengthShort(style(), zoomFactor);
m_style->setHorizontalBorderSpacing(spacing);
return;
}
@@ -3183,7 +3242,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
HANDLE_INHERIT_AND_INITIAL(verticalBorderSpacing, VerticalBorderSpacing)
if (!primitiveValue)
return;
- short spacing = primitiveValue->computeLengthShort(style(), zoomFactor);
+ short spacing = primitiveValue->computeLengthShort(style(), zoomFactor);
m_style->setVerticalBorderSpacing(spacing);
return;
}
@@ -3553,7 +3612,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
if (primitiveValue && !apply) {
int type = primitiveValue->primitiveType();
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
// Handle our quirky margin units if we have them.
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed,
primitiveValue->isQuirkValue());
@@ -3654,7 +3713,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
if (primitiveValue && !apply) {
unsigned short type = primitiveValue->primitiveType();
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
@@ -3710,7 +3769,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
} else {
int type = primitiveValue->primitiveType();
Length l;
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
@@ -3774,7 +3833,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
(type != CSSPrimitiveValue::CSS_PERCENTAGE &&
type != CSSPrimitiveValue::CSS_EMS &&
type != CSSPrimitiveValue::CSS_EXS));
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
size = primitiveValue->computeLengthFloat(m_parentStyle, true);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
size = (primitiveValue->getFloatValue() * oldSize) / 100.0f;
@@ -3837,7 +3896,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
int type = primitiveValue->primitiveType();
if (primitiveValue->getIdent() == CSSValueNormal)
lineHeight = Length(-100.0, Percent);
- else if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) {
+ else if (CSSPrimitiveValue::isUnitTypeLength(type)) {
double multiplier = m_style->effectiveZoom();
if (m_style->textSizeAdjust() && m_checker.m_document->frame() && m_checker.m_document->frame()->shouldApplyTextZoom())
multiplier *= m_checker.m_document->frame()->textZoomFactor();
@@ -3882,8 +3941,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
right = m_parentStyle->clipRight();
bottom = m_parentStyle->clipBottom();
left = m_parentStyle->clipLeft();
- }
- else {
+ } else {
hasClip = false;
top = right = bottom = left = Length();
}
@@ -3896,11 +3954,10 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
Rect* rect = primitiveValue->getRectValue();
if (!rect)
return;
- top = convertToLength(rect->top(), style());
- right = convertToLength(rect->right(), style());
- bottom = convertToLength(rect->bottom(), style());
- left = convertToLength(rect->left(), style());
-
+ top = convertToLength(rect->top(), style(), zoomFactor);
+ right = convertToLength(rect->right(), style(), zoomFactor);
+ bottom = convertToLength(rect->bottom(), style(), zoomFactor);
+ left = convertToLength(rect->left(), style(), zoomFactor);
} else if (primitiveValue->getIdent() != CSSValueAuto) {
return;
}
@@ -3948,7 +4005,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
break;
case CSSPrimitiveValue::CSS_ATTR: {
// FIXME: Can a namespace be specified for an attr(foo)?
- if (m_style->styleType() == RenderStyle::NOPSEUDO)
+ if (m_style->styleType() == NOPSEUDO)
m_style->setUnique();
else
m_parentStyle->setUnique();
@@ -4281,6 +4338,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
m_fontDirty = true;
} else if (isInitial) {
Settings* settings = m_checker.m_document->settings();
+ ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
+ if (!settings)
+ return;
FontDescription fontDescription;
fontDescription.setGenericFamily(FontDescription::StandardFamily);
fontDescription.setRenderingMode(settings->fontRenderingMode());
@@ -4307,6 +4367,9 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
if (fontDescription.isAbsoluteSize()) {
// Make sure the rendering mode and printer font settings are updated.
Settings* settings = m_checker.m_document->settings();
+ ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
+ if (!settings)
+ return;
fontDescription.setRenderingMode(settings->fontRenderingMode());
fontDescription.setUsePrinterFont(m_checker.m_document->printing());
@@ -4566,21 +4629,26 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
return;
case CSSPropertyUnicodeRange: // Only used in @font-face rules.
return;
+ case CSSPropertyWebkitBackfaceVisibility:
+ HANDLE_INHERIT_AND_INITIAL(backfaceVisibility, BackfaceVisibility)
+ if (primitiveValue)
+ m_style->setBackfaceVisibility((primitiveValue->getIdent() == CSSValueVisible) ? BackfaceVisibilityVisible : BackfaceVisibilityHidden);
+ return;
case CSSPropertyWebkitBoxDirection:
HANDLE_INHERIT_AND_INITIAL(boxDirection, BoxDirection)
if (primitiveValue)
m_style->setBoxDirection(*primitiveValue);
- return;
+ return;
case CSSPropertyWebkitBoxLines:
HANDLE_INHERIT_AND_INITIAL(boxLines, BoxLines)
if (primitiveValue)
m_style->setBoxLines(*primitiveValue);
- return;
+ return;
case CSSPropertyWebkitBoxOrient:
HANDLE_INHERIT_AND_INITIAL(boxOrient, BoxOrient)
if (primitiveValue)
m_style->setBoxOrient(*primitiveValue);
- return;
+ return;
case CSSPropertyWebkitBoxPack:
{
HANDLE_INHERIT_AND_INITIAL(boxPack, BoxPack)
@@ -4602,7 +4670,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
return; // Error case.
m_style->setBoxFlexGroup((unsigned int)(primitiveValue->getDoubleValue()));
- return;
+ return;
case CSSPropertyWebkitBoxOrdinalGroup:
HANDLE_INHERIT_AND_INITIAL(boxOrdinalGroup, BoxOrdinalGroup)
if (!primitiveValue || primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
@@ -4764,7 +4832,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
}
else {
bool ok = true;
- Length l = convertToLength(primitiveValue, style(), &ok);
+ Length l = convertToLength(primitiveValue, style(), 1, &ok);
if (ok)
m_style->setMarqueeIncrement(l);
}
@@ -4941,13 +5009,14 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyWebkitTransformOrigin:
HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX)
HANDLE_INHERIT_AND_INITIAL(transformOriginY, TransformOriginY)
+ HANDLE_INHERIT_AND_INITIAL(transformOriginZ, TransformOriginZ)
return;
case CSSPropertyWebkitTransformOriginX: {
HANDLE_INHERIT_AND_INITIAL(transformOriginX, TransformOriginX)
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
int type = primitiveValue->primitiveType();
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
@@ -4961,7 +5030,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
int type = primitiveValue->primitiveType();
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
@@ -4970,6 +5039,69 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
m_style->setTransformOriginY(l);
break;
}
+ case CSSPropertyWebkitTransformOriginZ: {
+ HANDLE_INHERIT_AND_INITIAL(transformOriginZ, TransformOriginZ)
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ float f;
+ int type = primitiveValue->primitiveType();
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
+ f = static_cast<float>(primitiveValue->computeLengthIntForLength(style()));
+ else
+ return;
+ m_style->setTransformOriginZ(f);
+ break;
+ }
+ case CSSPropertyWebkitTransformStyle:
+ HANDLE_INHERIT_AND_INITIAL(transformStyle3D, TransformStyle3D)
+ if (primitiveValue)
+ m_style->setTransformStyle3D((primitiveValue->getIdent() == CSSValuePreserve3d) ? TransformStyle3DPreserve3D : TransformStyle3DFlat);
+ return;
+ case CSSPropertyWebkitPerspective: {
+ HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
+ if (primitiveValue && primitiveValue->getIdent() == CSSValueNone) {
+ m_style->setPerspective(0);
+ return;
+ }
+
+ if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
+ return;
+ float perspectiveValue = static_cast<float>(primitiveValue->getDoubleValue());
+ if (perspectiveValue >= 0.0f)
+ m_style->setPerspective(perspectiveValue);
+ return;
+ }
+ case CSSPropertyWebkitPerspectiveOrigin:
+ HANDLE_INHERIT_AND_INITIAL(perspectiveOriginX, PerspectiveOriginX)
+ HANDLE_INHERIT_AND_INITIAL(perspectiveOriginY, PerspectiveOriginY)
+ return;
+ case CSSPropertyWebkitPerspectiveOriginX: {
+ HANDLE_INHERIT_AND_INITIAL(perspectiveOriginX, PerspectiveOriginX)
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Length l;
+ int type = primitiveValue->primitiveType();
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
+ l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
+ else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ m_style->setPerspectiveOriginX(l);
+ return;
+ }
+ case CSSPropertyWebkitPerspectiveOriginY: {
+ HANDLE_INHERIT_AND_INITIAL(perspectiveOriginY, PerspectiveOriginY)
+ CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+ Length l;
+ int type = primitiveValue->primitiveType();
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
+ l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
+ else if(type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ l = Length(primitiveValue->getDoubleValue(), Percent);
+ else
+ return;
+ m_style->setPerspectiveOriginY(l);
+ return;
+ }
case CSSPropertyWebkitAnimation:
if (isInitial)
m_style->clearAnimations();
@@ -4991,9 +5123,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyWebkitAnimationName:
HANDLE_ANIMATION_VALUE(name, Name, value)
return;
- case CSSPropertyWebkitAnimationPlayState:
- HANDLE_ANIMATION_VALUE(playState, PlayState, value)
- return;
case CSSPropertyWebkitAnimationTimingFunction:
HANDLE_ANIMATION_VALUE(timingFunction, TimingFunction, value)
return;
@@ -5035,13 +5164,6 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyFontStretch:
case CSSPropertyPage:
case CSSPropertyQuotes:
- case CSSPropertyScrollbar3dlightColor:
- case CSSPropertyScrollbarArrowColor:
- case CSSPropertyScrollbarDarkshadowColor:
- case CSSPropertyScrollbarFaceColor:
- case CSSPropertyScrollbarHighlightColor:
- case CSSPropertyScrollbarShadowColor:
- case CSSPropertyScrollbarTrackColor:
case CSSPropertySize:
case CSSPropertyTextLineThrough:
case CSSPropertyTextLineThroughColor:
@@ -5212,7 +5334,7 @@ void CSSStyleSelector::mapFillSize(FillLayer* layer, CSSValue* value)
if (firstType == CSSPrimitiveValue::CSS_UNKNOWN)
firstLength = Length(Auto);
- else if (firstType > CSSPrimitiveValue::CSS_PERCENTAGE && firstType < CSSPrimitiveValue::CSS_DEG)
+ else if (CSSPrimitiveValue::isUnitTypeLength(firstType))
firstLength = Length(first->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (firstType == CSSPrimitiveValue::CSS_PERCENTAGE)
firstLength = Length(first->getDoubleValue(), Percent);
@@ -5221,7 +5343,7 @@ void CSSStyleSelector::mapFillSize(FillLayer* layer, CSSValue* value)
if (secondType == CSSPrimitiveValue::CSS_UNKNOWN)
secondLength = Length(Auto);
- else if (secondType > CSSPrimitiveValue::CSS_PERCENTAGE && secondType < CSSPrimitiveValue::CSS_DEG)
+ else if (CSSPrimitiveValue::isUnitTypeLength(secondType))
secondLength = Length(second->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (secondType == CSSPrimitiveValue::CSS_PERCENTAGE)
secondLength = Length(second->getDoubleValue(), Percent);
@@ -5248,7 +5370,7 @@ void CSSStyleSelector::mapFillXPosition(FillLayer* layer, CSSValue* value)
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
int type = primitiveValue->primitiveType();
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
@@ -5272,7 +5394,7 @@ void CSSStyleSelector::mapFillYPosition(FillLayer* layer, CSSValue* value)
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
int type = primitiveValue->primitiveType();
- if (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG)
+ if (CSSPrimitiveValue::isUnitTypeLength(type))
l = Length(primitiveValue->computeLengthIntForLength(style(), zoomFactor), Fixed);
else if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
l = Length(primitiveValue->getDoubleValue(), Percent);
@@ -5303,7 +5425,7 @@ void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value)
}
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- layer->setDirection(primitiveValue->getIdent() == CSSValueAlternate);
+ layer->setDirection(primitiveValue->getIdent() == CSSValueAlternate ? Animation::AnimationDirectionAlternate : Animation::AnimationDirectionNormal);
}
void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* value)
@@ -5355,17 +5477,6 @@ void CSSStyleSelector::mapAnimationName(Animation* layer, CSSValue* value)
layer->setName(primitiveValue->getStringValue());
}
-void CSSStyleSelector::mapAnimationPlayState(Animation* layer, CSSValue* value)
-{
- if (value->cssValueType() == CSSValue::CSS_INITIAL) {
- layer->setPlayState(Animation::initialAnimationPlayState());
- return;
- }
-
- CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- layer->setPlayState((primitiveValue->getIdent() == CSSValuePaused) ? AnimPlayStatePaused : AnimPlayStatePlaying);
-}
-
void CSSStyleSelector::mapAnimationProperty(Animation* animation, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
@@ -5775,21 +5886,33 @@ static TransformOperation::OperationType getTransformOperationType(WebKitCSSTran
case WebKitCSSTransformValue::ScaleTransformOperation: return TransformOperation::SCALE;
case WebKitCSSTransformValue::ScaleXTransformOperation: return TransformOperation::SCALE_X;
case WebKitCSSTransformValue::ScaleYTransformOperation: return TransformOperation::SCALE_Y;
+ case WebKitCSSTransformValue::ScaleZTransformOperation: return TransformOperation::SCALE_Z;
+ case WebKitCSSTransformValue::Scale3DTransformOperation: return TransformOperation::SCALE_3D;
case WebKitCSSTransformValue::TranslateTransformOperation: return TransformOperation::TRANSLATE;
case WebKitCSSTransformValue::TranslateXTransformOperation: return TransformOperation::TRANSLATE_X;
case WebKitCSSTransformValue::TranslateYTransformOperation: return TransformOperation::TRANSLATE_Y;
+ case WebKitCSSTransformValue::TranslateZTransformOperation: return TransformOperation::TRANSLATE_Z;
+ case WebKitCSSTransformValue::Translate3DTransformOperation: return TransformOperation::TRANSLATE_3D;
case WebKitCSSTransformValue::RotateTransformOperation: return TransformOperation::ROTATE;
+ case WebKitCSSTransformValue::RotateXTransformOperation: return TransformOperation::ROTATE_X;
+ case WebKitCSSTransformValue::RotateYTransformOperation: return TransformOperation::ROTATE_Y;
+ case WebKitCSSTransformValue::RotateZTransformOperation: return TransformOperation::ROTATE_Z;
+ case WebKitCSSTransformValue::Rotate3DTransformOperation: return TransformOperation::ROTATE_3D;
case WebKitCSSTransformValue::SkewTransformOperation: return TransformOperation::SKEW;
case WebKitCSSTransformValue::SkewXTransformOperation: return TransformOperation::SKEW_X;
case WebKitCSSTransformValue::SkewYTransformOperation: return TransformOperation::SKEW_Y;
case WebKitCSSTransformValue::MatrixTransformOperation: return TransformOperation::MATRIX;
+ case WebKitCSSTransformValue::Matrix3DTransformOperation: return TransformOperation::MATRIX_3D;
+ case WebKitCSSTransformValue::PerspectiveTransformOperation: return TransformOperation::PERSPECTIVE;
case WebKitCSSTransformValue::UnknownTransformOperation: return TransformOperation::NONE;
}
return TransformOperation::NONE;
}
-bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle* inStyle, TransformOperations& outOperations)
+bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle* style, TransformOperations& outOperations)
{
+ float zoomFactor = style ? style->effectiveZoom() : 1;
+
TransformOperations operations;
if (inValue && !inValue->isPrimitiveValue()) {
CSSValueList* list = static_cast<CSSValueList*>(inValue);
@@ -5817,7 +5940,33 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
sy = sx;
}
}
- operations.operations().append(ScaleTransformOperation::create(sx, sy, getTransformOperationType(val->operationType())));
+ operations.operations().append(ScaleTransformOperation::create(sx, sy, 1.0, getTransformOperationType(val->operationType())));
+ break;
+ }
+ case WebKitCSSTransformValue::ScaleZTransformOperation:
+ case WebKitCSSTransformValue::Scale3DTransformOperation: {
+ double sx = 1.0;
+ double sy = 1.0;
+ double sz = 1.0;
+ if (val->operationType() == WebKitCSSTransformValue::ScaleZTransformOperation)
+ sz = firstValue->getDoubleValue();
+ else if (val->operationType() == WebKitCSSTransformValue::ScaleYTransformOperation)
+ sy = firstValue->getDoubleValue();
+ else {
+ sx = firstValue->getDoubleValue();
+ if (val->operationType() != WebKitCSSTransformValue::ScaleXTransformOperation) {
+ if (val->length() > 2) {
+ CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2));
+ sz = thirdValue->getDoubleValue();
+ }
+ if (val->length() > 1) {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
+ sy = secondValue->getDoubleValue();
+ } else
+ sy = sx;
+ }
+ }
+ operations.operations().append(ScaleTransformOperation::create(sx, sy, sz, getTransformOperationType(val->operationType())));
break;
}
case WebKitCSSTransformValue::TranslateTransformOperation:
@@ -5827,13 +5976,43 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
Length tx = Length(0, Fixed);
Length ty = Length(0, Fixed);
if (val->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation)
- ty = convertToLength(firstValue, inStyle, &ok);
+ ty = convertToLength(firstValue, style, zoomFactor, &ok);
+ else {
+ tx = convertToLength(firstValue, style, zoomFactor, &ok);
+ if (val->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) {
+ if (val->length() > 1) {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
+ ty = convertToLength(secondValue, style, zoomFactor, &ok);
+ }
+ }
+ }
+
+ if (!ok)
+ return false;
+
+ operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(val->operationType())));
+ break;
+ }
+ case WebKitCSSTransformValue::TranslateZTransformOperation:
+ case WebKitCSSTransformValue::Translate3DTransformOperation: {
+ bool ok = true;
+ Length tx = Length(0, Fixed);
+ Length ty = Length(0, Fixed);
+ Length tz = Length(0, Fixed);
+ if (val->operationType() == WebKitCSSTransformValue::TranslateZTransformOperation)
+ tz = convertToLength(firstValue, style, zoomFactor, &ok);
+ else if (val->operationType() == WebKitCSSTransformValue::TranslateYTransformOperation)
+ ty = convertToLength(firstValue, style, zoomFactor, &ok);
else {
- tx = convertToLength(firstValue, inStyle, &ok);
+ tx = convertToLength(firstValue, style, zoomFactor, &ok);
if (val->operationType() != WebKitCSSTransformValue::TranslateXTransformOperation) {
+ if (val->length() > 2) {
+ CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2));
+ tz = convertToLength(thirdValue, style, zoomFactor, &ok);
+ }
if (val->length() > 1) {
CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
- ty = convertToLength(secondValue, inStyle, &ok);
+ ty = convertToLength(secondValue, style, zoomFactor, &ok);
}
}
}
@@ -5841,7 +6020,7 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
if (!ok)
return false;
- operations.operations().append(TranslateTransformOperation::create(tx, ty, getTransformOperationType(val->operationType())));
+ operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(val->operationType())));
break;
}
case WebKitCSSTransformValue::RotateTransformOperation: {
@@ -5853,7 +6032,43 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_TURN)
angle = turn2deg(angle);
- operations.operations().append(RotateTransformOperation::create(angle, getTransformOperationType(val->operationType())));
+ operations.operations().append(RotateTransformOperation::create(0, 0, 1, angle, getTransformOperationType(val->operationType())));
+ break;
+ }
+ case WebKitCSSTransformValue::RotateXTransformOperation:
+ case WebKitCSSTransformValue::RotateYTransformOperation:
+ case WebKitCSSTransformValue::RotateZTransformOperation: {
+ double x = 0;
+ double y = 0;
+ double z = 0;
+ double angle = firstValue->getDoubleValue();
+ if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
+ angle = rad2deg(angle);
+ else if (firstValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
+ angle = grad2deg(angle);
+
+ if (val->operationType() == WebKitCSSTransformValue::RotateXTransformOperation)
+ x = 1;
+ else if (val->operationType() == WebKitCSSTransformValue::RotateYTransformOperation)
+ y = 1;
+ else
+ z = 1;
+ operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(val->operationType())));
+ break;
+ }
+ case WebKitCSSTransformValue::Rotate3DTransformOperation: {
+ CSSPrimitiveValue* secondValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1));
+ CSSPrimitiveValue* thirdValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2));
+ CSSPrimitiveValue* fourthValue = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3));
+ double x = firstValue->getDoubleValue();
+ double y = secondValue->getDoubleValue();
+ double z = thirdValue->getDoubleValue();
+ double angle = fourthValue->getDoubleValue();
+ if (fourthValue->primitiveType() == CSSPrimitiveValue::CSS_RAD)
+ angle = rad2deg(angle);
+ else if (fourthValue->primitiveType() == CSSPrimitiveValue::CSS_GRAD)
+ angle = grad2deg(angle);
+ operations.operations().append(RotateTransformOperation::create(x, y, z, angle, getTransformOperationType(val->operationType())));
break;
}
case WebKitCSSTransformValue::SkewTransformOperation:
@@ -5889,15 +6104,42 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
break;
}
case WebKitCSSTransformValue::MatrixTransformOperation: {
- float a = firstValue->getFloatValue();
- float b = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1))->getFloatValue();
- float c = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2))->getFloatValue();
- float d = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3))->getFloatValue();
- float e = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(4))->getFloatValue();
- float f = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(5))->getFloatValue();
+ double a = firstValue->getDoubleValue();
+ double b = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1))->getDoubleValue();
+ double c = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2))->getDoubleValue();
+ double d = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3))->getDoubleValue();
+ double e = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(4))->getDoubleValue();
+ double f = static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(5))->getDoubleValue();
operations.operations().append(MatrixTransformOperation::create(a, b, c, d, e, f));
break;
}
+ case WebKitCSSTransformValue::Matrix3DTransformOperation: {
+ TransformationMatrix matrix(static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(0))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(1))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(2))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(3))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(4))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(5))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(6))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(7))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(8))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(9))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(10))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(11))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(12))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(13))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(14))->getDoubleValue(),
+ static_cast<CSSPrimitiveValue*>(val->itemWithoutBoundsCheck(15))->getDoubleValue());
+ operations.operations().append(Matrix3DTransformOperation::create(matrix));
+ break;
+ }
+ case WebKitCSSTransformValue::PerspectiveTransformOperation: {
+ double p = firstValue->getDoubleValue();
+ if (p < 0.0)
+ return false;
+ operations.operations().append(PerspectiveTransformOperation::create(p));
+ break;
+ }
case WebKitCSSTransformValue::UnknownTransformOperation:
ASSERT_NOT_REACHED();
break;
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
index b925efc..8dd36d7 100644
--- a/WebCore/css/CSSStyleSelector.h
+++ b/WebCore/css/CSSStyleSelector.h
@@ -83,11 +83,11 @@ public:
~CSSStyleSelector();
void initElementAndPseudoState(Element*);
- void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, RenderStyle::PseudoId = RenderStyle::NOPSEUDO);
+ void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, bool allowSharing = true, bool resolveForRootDefault = false);
void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList& list);
- PassRefPtr<RenderStyle> pseudoStyleForElement(RenderStyle::PseudoId, Element*, RenderStyle* parentStyle = 0);
+ PassRefPtr<RenderStyle> pseudoStyleForElement(PseudoId, Element*, RenderStyle* parentStyle = 0);
private:
RenderStyle* locateSharedStyle();
@@ -186,10 +186,10 @@ public:
SelectorChecker(Document*, bool strictParsing);
bool checkSelector(CSSSelector*, Element*) const;
- SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
- bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, RenderStyle::PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
+ SelectorMatch checkSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle* = 0, RenderStyle* elementParentStyle = 0) const;
+ bool checkOneSelector(CSSSelector*, Element*, HashSet<AtomicStringImpl*>* selectorAttrs, PseudoId& dynamicPseudo, bool isAncestor, bool isSubSelector, RenderStyle*, RenderStyle* elementParentStyle) const;
PseudoState checkPseudoState(Element*, bool checkVisited = true) const;
- bool checkScrollbarPseudoClass(CSSSelector*, RenderStyle::PseudoId& dynamicPseudo) const;
+ bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const;
void allVisitedStateChanged();
void visitedStateChanged(LinkHash visitedHash);
@@ -197,7 +197,7 @@ public:
Document* m_document;
bool m_strictParsing;
bool m_collectRulesOnly;
- RenderStyle::PseudoId m_pseudoStyle;
+ PseudoId m_pseudoStyle;
bool m_documentIsHTML;
mutable HashSet<LinkHash, LinkHashHash> m_linksCheckedForVisitedState;
};
@@ -226,7 +226,6 @@ public:
void mapAnimationDuration(Animation*, CSSValue*);
void mapAnimationIterationCount(Animation*, CSSValue*);
void mapAnimationName(Animation*, CSSValue*);
- void mapAnimationPlayState(Animation*, CSSValue*);
void mapAnimationProperty(Animation*, CSSValue*);
void mapAnimationTimingFunction(Animation*, CSSValue*);
@@ -254,7 +253,7 @@ public:
MediaQueryEvaluator* m_medium;
RefPtr<RenderStyle> m_rootDefaultStyle;
- RenderStyle::PseudoId m_dynamicPseudo;
+ PseudoId m_dynamicPseudo;
SelectorChecker m_checker;
diff --git a/WebCore/css/CSSStyleSheet.cpp b/WebCore/css/CSSStyleSheet.cpp
index 2e9255b..56305f3 100644
--- a/WebCore/css/CSSStyleSheet.cpp
+++ b/WebCore/css/CSSStyleSheet.cpp
@@ -192,6 +192,10 @@ void CSSStyleSheet::checkLoaded()
return;
if (parent())
parent()->checkLoaded();
+
+ // Avoid |this| being deleted by scripts that run via HTMLTokenizer::executeScriptsWaitingForStylesheets().
+ // See <rdar://problem/6622300>.
+ RefPtr<CSSStyleSheet> protector(this);
m_loadCompleted = ownerNode() ? ownerNode()->sheetLoaded() : true;
}
@@ -200,7 +204,7 @@ void CSSStyleSheet::styleSheetChanged()
StyleBase* root = this;
while (StyleBase* parent = root->parent())
root = parent;
- Document* documentToUpdate = (root && root->isCSSStyleSheet()) ? static_cast<CSSStyleSheet*>(root)->doc() : 0;
+ Document* documentToUpdate = root->isCSSStyleSheet() ? static_cast<CSSStyleSheet*>(root)->doc() : 0;
/* FIXME: We don't need to do everything updateStyleSelector does,
* basically we just need to recreate the document's selector with the
diff --git a/WebCore/css/CSSValueKeywords.in b/WebCore/css/CSSValueKeywords.in
index 936b635..698dffe 100644
--- a/WebCore/css/CSSValueKeywords.in
+++ b/WebCore/css/CSSValueKeywords.in
@@ -537,9 +537,13 @@ round
#
# CSS_PROP_BACKGROUND_CLIP/ORIGIN
#
+# border/content/padding are deprecated and ultimately will only apply to the -webkit- form of these properties.
+# border-box/content-box/padding-box should be used instead.
+#
border
content
padding
+padding-box
#
# CSS_PROP_BOX_SIZING
@@ -575,6 +579,12 @@ running
paused
#
+# CSS_PROP__WEBKIT_TRANSFORM_STYLE
+#
+flat
+preserve-3d
+
+#
# CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION
# CSS_PROP__WEBKIT_ANIMATION_TIMING_FUNCTION
#
@@ -601,4 +611,4 @@ painted
fill
stroke
#all
-#none \ No newline at end of file
+#none
diff --git a/WebCore/css/MediaQueryEvaluator.cpp b/WebCore/css/MediaQueryEvaluator.cpp
index fa5a3e9..4268d8c 100644
--- a/WebCore/css/MediaQueryEvaluator.cpp
+++ b/WebCore/css/MediaQueryEvaluator.cpp
@@ -417,11 +417,22 @@ static bool transform_2dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*,
static bool transform_3dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
{
+ bool returnValueIfNoParameter;
+ int have3dRendering;
+
+#if ENABLE(3D_RENDERING)
+ returnValueIfNoParameter = true;
+ have3dRendering = 1;
+#else
+ returnValueIfNoParameter = false;
+ have3dRendering = 0;
+#endif
+
if (value) {
float number;
- return numberValue(value, number) && compareValue(0, static_cast<int>(number), op);
+ return numberValue(value, number) && compareValue(have3dRendering, static_cast<int>(number), op);
}
- return false;
+ return returnValueIfNoParameter;
}
static void createFunctionMap()
diff --git a/WebCore/css/SVGCSSComputedStyleDeclaration.cpp b/WebCore/css/SVGCSSComputedStyleDeclaration.cpp
index 1375fc2..2cd90a9d 100644
--- a/WebCore/css/SVGCSSComputedStyleDeclaration.cpp
+++ b/WebCore/css/SVGCSSComputedStyleDeclaration.cpp
@@ -26,6 +26,7 @@
#include "CSSPrimitiveValueMappings.h"
#include "CSSPropertyNames.h"
#include "Document.h"
+#include "RenderStyle.h"
namespace WebCore {
diff --git a/WebCore/css/SVGCSSStyleSelector.cpp b/WebCore/css/SVGCSSStyleSelector.cpp
index 34d981c..d326dde 100644
--- a/WebCore/css/SVGCSSStyleSelector.cpp
+++ b/WebCore/css/SVGCSSStyleSelector.cpp
@@ -59,25 +59,6 @@ HANDLE_INHERIT(prop, Prop) \
else if (isInitial) \
svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
-#define HANDLE_INHERIT_COND(propID, prop, Prop) \
-if (id == propID) \
-{\
- svgstyle->set##Prop(m_parentStyle->svgStyle()->prop());\
- return;\
-}
-
-#define HANDLE_INITIAL_COND(propID, Prop) \
-if (id == propID) \
-{\
- svgstyle->set##Prop(SVGRenderStyle::initial##Prop());\
- return;\
-}
-
-#define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
-if (id == propID) { \
- svgstyle->set##Prop(SVGRenderStyle::initial##Value()); \
- return; \
-}
namespace WebCore {
@@ -111,8 +92,21 @@ static int angleToGlyphOrientation(float angle)
return -1;
}
+static Color colorFromSVGColorCSSValue(CSSValue* value, RenderStyle* style)
+{
+ ASSERT(value->isSVGColor());
+ SVGColor* c = static_cast<SVGColor*>(value);
+ Color color;
+ if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
+ color = style->color();
+ else
+ color = c->color();
+ return color;
+}
+
void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
{
+ ASSERT(value);
CSSPrimitiveValue* primitiveValue = 0;
if (value->isPrimitiveValue())
primitiveValue = static_cast<CSSPrimitiveValue*>(value);
@@ -168,15 +162,7 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
}
case CSSPropertyKerning:
{
- if (isInherit) {
- HANDLE_INHERIT_COND(CSSPropertyKerning, kerning, Kerning)
- return;
- }
- else if (isInitial) {
- HANDLE_INITIAL_COND_WITH_VALUE(CSSPropertyKerning, Kerning, Kerning)
- return;
- }
-
+ HANDLE_INHERIT_AND_INITIAL(kerning, Kerning);
svgstyle->setKerning(primitiveValue);
break;
}
@@ -254,52 +240,37 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
case CSSPropertyFill:
{
HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
- if (!primitiveValue && value) {
- SVGPaint *paint = static_cast<SVGPaint*>(value);
- if (paint)
- svgstyle->setFillPaint(paint);
- }
-
+ if (value->isSVGPaint())
+ svgstyle->setFillPaint(static_cast<SVGPaint*>(value));
break;
}
case CSSPropertyStroke:
{
HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
- if (!primitiveValue && value) {
- SVGPaint *paint = static_cast<SVGPaint*>(value);
- if (paint)
- svgstyle->setStrokePaint(paint);
- }
+ if (value->isSVGPaint())
+ svgstyle->setStrokePaint(static_cast<SVGPaint*>(value));
break;
}
case CSSPropertyStrokeWidth:
{
HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
- if (!primitiveValue)
- return;
-
- svgstyle->setStrokeWidth(primitiveValue);
+ if (primitiveValue)
+ svgstyle->setStrokeWidth(primitiveValue);
break;
}
case CSSPropertyStrokeDasharray:
{
HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
- if (!primitiveValue && value) {
- CSSValueList* dashes = static_cast<CSSValueList*>(value);
- if (dashes)
- svgstyle->setStrokeDashArray(dashes);
- }
-
+ if (value->isValueList())
+ svgstyle->setStrokeDashArray(static_cast<CSSValueList*>(value));
break;
}
case CSSPropertyStrokeDashoffset:
{
HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
- if (!primitiveValue)
- return;
-
- svgstyle->setStrokeDashOffset(primitiveValue);
+ if (primitiveValue)
+ svgstyle->setStrokeDashOffset(primitiveValue);
break;
}
case CSSPropertyFillOpacity:
@@ -491,35 +462,13 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
case CSSPropertyStopColor:
{
HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
-
- SVGColor* c = static_cast<SVGColor*>(value);
- if (!c)
- return CSSStyleSelector::applyProperty(id, value);
-
- Color col;
- if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
- col = m_style->color();
- else
- col = c->color();
-
- svgstyle->setStopColor(col);
+ svgstyle->setStopColor(colorFromSVGColorCSSValue(value, m_style.get()));
break;
}
case CSSPropertyLightingColor:
{
HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
-
- SVGColor* c = static_cast<SVGColor*>(value);
- if (!c)
- return CSSStyleSelector::applyProperty(id, value);
-
- Color col;
- if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
- col = m_style->color();
- else
- col = c->color();
-
- svgstyle->setLightingColor(col);
+ svgstyle->setLightingColor(colorFromSVGColorCSSValue(value, m_style.get()));
break;
}
case CSSPropertyFloodOpacity:
@@ -542,21 +491,11 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
}
case CSSPropertyFloodColor:
{
- Color col;
- if (isInitial)
- col = SVGRenderStyle::initialFloodColor();
- else {
- SVGColor *c = static_cast<SVGColor*>(value);
- if (!c)
- return CSSStyleSelector::applyProperty(id, value);
-
- if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
- col = m_style->color();
- else
- col = c->color();
+ if (isInitial) {
+ svgstyle->setFloodColor(SVGRenderStyle::initialFloodColor());
+ return;
}
-
- svgstyle->setFloodColor(col);
+ svgstyle->setFloodColor(colorFromSVGColorCSSValue(value, m_style.get()));
break;
}
case CSSPropertyGlyphOrientationHorizontal:
diff --git a/WebCore/css/WebKitCSSMatrix.cpp b/WebCore/css/WebKitCSSMatrix.cpp
index 2d97b85..574a01a 100644
--- a/WebCore/css/WebKitCSSMatrix.cpp
+++ b/WebCore/css/WebKitCSSMatrix.cpp
@@ -24,6 +24,7 @@
*/
#include "config.h"
+#include "WebKitCSSMatrix.h"
#include "CSSParser.h"
#include "CSSStyleSelector.h"
@@ -31,7 +32,7 @@
#include "CSSPropertyNames.h"
#include "ExceptionCode.h"
#include "RenderStyle.h"
-#include "WebKitCSSMatrix.h"
+#include <wtf/MathExtras.h>
namespace WebCore {
@@ -93,14 +94,17 @@ void WebKitCSSMatrix::setMatrixValue(const String& string, ExceptionCode& ec)
}
// This is a multRight (this = this * secondMatrix)
-PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::multiply(WebKitCSSMatrix* secondMatrix)
+PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::multiply(WebKitCSSMatrix* secondMatrix) const
{
+ if (!secondMatrix)
+ return 0;
+
TransformationMatrix tmp(m_matrix);
tmp.multiply(secondMatrix->m_matrix);
return WebKitCSSMatrix::create(tmp);
}
-PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::inverse(ExceptionCode& ec)
+PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::inverse(ExceptionCode& ec) const
{
if (!m_matrix.isInvertible()) {
ec = NOT_SUPPORTED_ERR;
@@ -110,35 +114,73 @@ PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::inverse(ExceptionCode& ec)
return WebKitCSSMatrix::create(m_matrix.inverse());
}
-PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::translate(float x, float y)
+PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::translate(double x, double y, double z) const
{
if (isnan(x))
- x = 0;
+ x = 0;
if (isnan(y))
- y = 0;
- return WebKitCSSMatrix::create(m_matrix.translate(x, y));
+ y = 0;
+ if (isnan(z))
+ z = 0;
+ return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).translate3d(x, y, z));
}
-PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::scale(float scaleX, float scaleY)
+PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const
{
if (isnan(scaleX))
- scaleX = 1;
+ scaleX = 1;
if (isnan(scaleY))
- scaleY = scaleX;
- return WebKitCSSMatrix::create(m_matrix.scale(scaleX,scaleY));
+ scaleY = scaleX;
+ if (isnan(scaleZ))
+ scaleZ = 1;
+ return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).scale3d(scaleX, scaleY, scaleZ));
}
-PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotate(float rot)
+PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotate(double rotX, double rotY, double rotZ) const
{
- if (isnan(rot))
- rot = 0;
- return WebKitCSSMatrix::create(m_matrix.rotate(rot));
+ if (isnan(rotX))
+ rotX = 0;
+
+ if (isnan(rotY) && isnan(rotZ)) {
+ rotZ = rotX;
+ rotX = 0;
+ rotY = 0;
+ }
+
+ if (isnan(rotY))
+ rotY = 0;
+ if (isnan(rotZ))
+ rotZ = 0;
+ return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(rotX, rotY, rotZ));
}
-String WebKitCSSMatrix::toString()
+PassRefPtr<WebKitCSSMatrix> WebKitCSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const
+{
+ if (isnan(x))
+ x = 0;
+ if (isnan(y))
+ y = 0;
+ if (isnan(z))
+ z = 0;
+ if (isnan(angle))
+ angle = 0;
+ if (x == 0 && y == 0 && z == 0)
+ z = 1;
+ return WebKitCSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(x, y, z, angle));
+}
+
+
+String WebKitCSSMatrix::toString() const
{
- return String::format("matrix(%f, %f, %f, %f, %f, %f)",
- m_matrix.a(), m_matrix.b(), m_matrix.c(), m_matrix.d(), m_matrix.e(), m_matrix.f());
+ // FIXME - Need to ensure valid CSS floating point values (https://bugs.webkit.org/show_bug.cgi?id=20674)
+ if (m_matrix.isAffine())
+ return String::format("matrix(%f, %f, %f, %f, %f, %f)",
+ m_matrix.a(), m_matrix.b(), m_matrix.c(), m_matrix.d(), m_matrix.e(), m_matrix.f());
+ return String::format("matrix3d(%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)",
+ m_matrix.m11(), m_matrix.m12(), m_matrix.m13(), m_matrix.m14(),
+ m_matrix.m21(), m_matrix.m22(), m_matrix.m23(), m_matrix.m24(),
+ m_matrix.m31(), m_matrix.m32(), m_matrix.m33(), m_matrix.m34(),
+ m_matrix.m41(), m_matrix.m42(), m_matrix.m43(), m_matrix.m44());
}
} // namespace WebCore
diff --git a/WebCore/css/WebKitCSSMatrix.h b/WebCore/css/WebKitCSSMatrix.h
index 1c660bf..67ba113 100644
--- a/WebCore/css/WebKitCSSMatrix.h
+++ b/WebCore/css/WebKitCSSMatrix.h
@@ -26,8 +26,9 @@
#ifndef WebKitCSSMatrix_h
#define WebKitCSSMatrix_h
-#include "StyleBase.h"
+#include "ExceptionCode.h"
#include "PlatformString.h"
+#include "StyleBase.h"
#include "TransformationMatrix.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -55,34 +56,94 @@ public:
virtual ~WebKitCSSMatrix();
- float a() const { return static_cast<float>(m_matrix.a()); }
- float b() const { return static_cast<float>(m_matrix.b()); }
- float c() const { return static_cast<float>(m_matrix.c()); }
- float d() const { return static_cast<float>(m_matrix.d()); }
- float e() const { return static_cast<float>(m_matrix.e()); }
- float f() const { return static_cast<float>(m_matrix.f()); }
+ double a() const { return m_matrix.a(); }
+ double b() const { return m_matrix.b(); }
+ double c() const { return m_matrix.c(); }
+ double d() const { return m_matrix.d(); }
+ double e() const { return m_matrix.e(); }
+ double f() const { return m_matrix.f(); }
- void setA(float f) { m_matrix.setA(f); }
- void setB(float f) { m_matrix.setB(f); }
- void setC(float f) { m_matrix.setC(f); }
- void setD(float f) { m_matrix.setD(f); }
- void setE(float f) { m_matrix.setE(f); }
- void setF(float f) { m_matrix.setF(f); }
+ void setA(double f) { m_matrix.setA(f); }
+ void setB(double f) { m_matrix.setB(f); }
+ void setC(double f) { m_matrix.setC(f); }
+ void setD(double f) { m_matrix.setD(f); }
+ void setE(double f) { m_matrix.setE(f); }
+ void setF(double f) { m_matrix.setF(f); }
+
+ double m11() const { return m_matrix.m11(); }
+ double m12() const { return m_matrix.m12(); }
+ double m13() const { return m_matrix.m13(); }
+ double m14() const { return m_matrix.m14(); }
+ double m21() const { return m_matrix.m21(); }
+ double m22() const { return m_matrix.m22(); }
+ double m23() const { return m_matrix.m23(); }
+ double m24() const { return m_matrix.m24(); }
+ double m31() const { return m_matrix.m31(); }
+ double m32() const { return m_matrix.m32(); }
+ double m33() const { return m_matrix.m33(); }
+ double m34() const { return m_matrix.m34(); }
+ double m41() const { return m_matrix.m41(); }
+ double m42() const { return m_matrix.m42(); }
+ double m43() const { return m_matrix.m43(); }
+ double m44() const { return m_matrix.m44(); }
+
+ void setM11(double f) { m_matrix.setM11(f); }
+ void setM12(double f) { m_matrix.setM12(f); }
+ void setM13(double f) { m_matrix.setM13(f); }
+ void setM14(double f) { m_matrix.setM14(f); }
+ void setM21(double f) { m_matrix.setM21(f); }
+ void setM22(double f) { m_matrix.setM22(f); }
+ void setM23(double f) { m_matrix.setM23(f); }
+ void setM24(double f) { m_matrix.setM24(f); }
+ void setM31(double f) { m_matrix.setM31(f); }
+ void setM32(double f) { m_matrix.setM32(f); }
+ void setM33(double f) { m_matrix.setM33(f); }
+ void setM34(double f) { m_matrix.setM34(f); }
+ void setM41(double f) { m_matrix.setM41(f); }
+ void setM42(double f) { m_matrix.setM42(f); }
+ void setM43(double f) { m_matrix.setM43(f); }
+ void setM44(double f) { m_matrix.setM44(f); }
void setMatrixValue(const String& string, ExceptionCode&);
- // this = this * secondMatrix
- PassRefPtr<WebKitCSSMatrix> multiply(WebKitCSSMatrix* secondMatrix);
+ // The following math function return a new matrix with the
+ // specified operation applied. The this value is not modified.
+
+ // Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix)
+ PassRefPtr<WebKitCSSMatrix> multiply(WebKitCSSMatrix* secondMatrix) const;
+
+ // Return the inverse of this matrix. Throw an exception if the matrix is not invertible
+ PassRefPtr<WebKitCSSMatrix> inverse(ExceptionCode&) const;
+
+ // Return this matrix translated by the passed values.
+ // Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations
+ // Operation is performed as though the this matrix is multiplied by a matrix with
+ // the translation values on the left (result = translation(x,y,z) * this)
+ PassRefPtr<WebKitCSSMatrix> translate(double x, double y, double z) const;
+
+ // Returns this matrix scaled by the passed values.
+ // Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN
+ // makes it the same as scaleX. This allows the 3D form to used for 2D operations
+ // Operation is performed as though the this matrix is multiplied by a matrix with
+ // the scale values on the left (result = scale(x,y,z) * this)
+ PassRefPtr<WebKitCSSMatrix> scale(double scaleX, double scaleY, double scaleZ) const;
+
+ // Returns this matrix rotated by the passed values.
+ // If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX).
+ // Otherwise use a rotation value of 0 for any passed NaN.
+ // Operation is performed as though the this matrix is multiplied by a matrix with
+ // the rotation values on the left (result = rotation(x,y,z) * this)
+ PassRefPtr<WebKitCSSMatrix> rotate(double rotX, double rotY, double rotZ) const;
- // FIXME: we really should have an exception here, for when matrix is not invertible
- PassRefPtr<WebKitCSSMatrix> inverse(ExceptionCode&);
- PassRefPtr<WebKitCSSMatrix> translate(float x, float y);
- PassRefPtr<WebKitCSSMatrix> scale(float scaleX, float scaleY);
- PassRefPtr<WebKitCSSMatrix> rotate(float rot);
+ // Returns this matrix rotated about the passed axis by the passed angle.
+ // Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value
+ // Operation is performed as though the this matrix is multiplied by a matrix with
+ // the rotation values on the left (result = rotation(x,y,z,angle) * this)
+ PassRefPtr<WebKitCSSMatrix> rotateAxisAngle(double x, double y, double z, double angle) const;
- const TransformationMatrix& transform() { return m_matrix; }
+ const TransformationMatrix& transform() const { return m_matrix; }
- String toString();
+ String toString() const;
protected:
WebKitCSSMatrix();
diff --git a/WebCore/css/WebKitCSSMatrix.idl b/WebCore/css/WebKitCSSMatrix.idl
index b1d5946..6b22da1 100644
--- a/WebCore/css/WebKitCSSMatrix.idl
+++ b/WebCore/css/WebKitCSSMatrix.idl
@@ -28,19 +28,57 @@ module css {
// Introduced in DOM Level ?:
interface WebKitCSSMatrix {
- attribute float a;
- attribute float b;
- attribute float c;
- attribute float d;
- attribute float e;
- attribute float f;
+ // These attributes are simple aliases for certain elements of the 4x4 matrix
+ attribute double a; // alias for m11
+ attribute double b; // alias for m12
+ attribute double c; // alias for m21
+ attribute double d; // alias for m22
+ attribute double e; // alias for m41
+ attribute double f; // alias for m42
- void setMatrixValue(in DOMString string) raises (DOMException);
- WebKitCSSMatrix multiply(in WebKitCSSMatrix secondMatrix);
- WebKitCSSMatrix inverse() raises (DOMException);
- WebKitCSSMatrix translate(in float x, in float y);
- WebKitCSSMatrix scale(in float scaleX, in float scaleY);
- WebKitCSSMatrix rotate(in float rot);
+ attribute double m11;
+ attribute double m12;
+ attribute double m13;
+ attribute double m14;
+ attribute double m21;
+ attribute double m22;
+ attribute double m23;
+ attribute double m24;
+ attribute double m31;
+ attribute double m32;
+ attribute double m33;
+ attribute double m34;
+ attribute double m41;
+ attribute double m42;
+ attribute double m43;
+ attribute double m44;
+
+ void setMatrixValue(in DOMString string) raises (DOMException);
+
+ // Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix)
+ [Immutable] WebKitCSSMatrix multiply(in WebKitCSSMatrix secondMatrix);
+
+ // Return the inverse of this matrix. Throw an exception if the matrix is not invertible
+ [Immutable] WebKitCSSMatrix inverse() raises (DOMException);
+
+ // Return this matrix translated by the passed values.
+ // Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations
+ [Immutable] WebKitCSSMatrix translate(in double x, in double y, in double z);
+
+ // Returns this matrix scaled by the passed values.
+ // Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN
+ // makes it the same as scaleX. This allows the 3D form to used for 2D operations
+ [Immutable] WebKitCSSMatrix scale(in double scaleX, in double scaleY, in double scaleZ);
+
+ // Returns this matrix rotated by the passed values.
+ // If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX).
+ // Otherwise use a rotation value of 0 for any passed NaN.
+ [Immutable] WebKitCSSMatrix rotate(in double rotX, in double rotY, in double rotZ);
+
+ // Returns this matrix rotated about the passed axis by the passed angle.
+ // Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value
+ // of (0,0,1).
+ [Immutable] WebKitCSSMatrix rotateAxisAngle(in double x, in double y, in double z, in double angle);
[DontEnum] DOMString toString();
};
diff --git a/WebCore/css/WebKitCSSTransformValue.cpp b/WebCore/css/WebKitCSSTransformValue.cpp
index e6af840..3b4286e 100644
--- a/WebCore/css/WebKitCSSTransformValue.cpp
+++ b/WebCore/css/WebKitCSSTransformValue.cpp
@@ -79,6 +79,36 @@ String WebKitCSSTransformValue::cssText() const
case MatrixTransformOperation:
result += "matrix(";
break;
+ case TranslateZTransformOperation:
+ result += "translateZ(";
+ break;
+ case Translate3DTransformOperation:
+ result += "translate3d(";
+ break;
+ case RotateXTransformOperation:
+ result += "rotateX(";
+ break;
+ case RotateYTransformOperation:
+ result += "rotateY(";
+ break;
+ case RotateZTransformOperation:
+ result += "rotateZ(";
+ break;
+ case Rotate3DTransformOperation:
+ result += "rotate3d(";
+ break;
+ case ScaleZTransformOperation:
+ result += "scaleZ(";
+ break;
+ case Scale3DTransformOperation:
+ result += "scale3d(";
+ break;
+ case PerspectiveTransformOperation:
+ result += "perspective(";
+ break;
+ case Matrix3DTransformOperation:
+ result += "matrix3d(";
+ break;
default:
break;
}
diff --git a/WebCore/css/WebKitCSSTransformValue.h b/WebCore/css/WebKitCSSTransformValue.h
index 2bb2631..0c3c038 100644
--- a/WebCore/css/WebKitCSSTransformValue.h
+++ b/WebCore/css/WebKitCSSTransformValue.h
@@ -47,7 +47,17 @@ public:
SkewTransformOperation,
SkewXTransformOperation,
SkewYTransformOperation,
- MatrixTransformOperation
+ MatrixTransformOperation,
+ TranslateZTransformOperation,
+ Translate3DTransformOperation,
+ RotateXTransformOperation,
+ RotateYTransformOperation,
+ RotateZTransformOperation,
+ Rotate3DTransformOperation,
+ ScaleZTransformOperation,
+ Scale3DTransformOperation,
+ PerspectiveTransformOperation,
+ Matrix3DTransformOperation
};
static PassRefPtr<WebKitCSSTransformValue> create(TransformOperationType type)
diff --git a/WebCore/css/WebKitCSSTransformValue.idl b/WebCore/css/WebKitCSSTransformValue.idl
index 39e97a3..14a373f 100644
--- a/WebCore/css/WebKitCSSTransformValue.idl
+++ b/WebCore/css/WebKitCSSTransformValue.idl
@@ -48,6 +48,16 @@ module css {
const unsigned short CSS_SKEWX = 9;
const unsigned short CSS_SKEWY = 10;
const unsigned short CSS_MATRIX = 11;
+ const unsigned short CSS_TRANSLATEZ = 12;
+ const unsigned short CSS_TRANSLATE3D = 13;
+ const unsigned short CSS_ROTATEX = 14;
+ const unsigned short CSS_ROTATEY = 15;
+ const unsigned short CSS_ROTATEZ = 16;
+ const unsigned short CSS_ROTATE3D = 17;
+ const unsigned short CSS_SCALEZ = 18;
+ const unsigned short CSS_SCALE3D = 19;
+ const unsigned short CSS_PERSPECTIVE = 20;
+ const unsigned short CSS_MATRIX3D = 21;
readonly attribute unsigned short operationType;
};
diff --git a/WebCore/css/html4.css b/WebCore/css/html4.css
index 704e216..2b6d3fe 100644
--- a/WebCore/css/html4.css
+++ b/WebCore/css/html4.css
@@ -599,4 +599,8 @@ iframe {
border: 2px inset
}
+img, input[type=image], video, iframe, object, embed, applet {
+ overflow: hidden; /* Default to overflow:hidden so that border-radius clipping works on the foreground of these elements. */
+}
+
/* noscript is handled internally, as it depends on settings */
diff --git a/WebCore/css/themeChromiumWin.css b/WebCore/css/themeChromiumWin.css
new file mode 100644
index 0000000..e829373
--- /dev/null
+++ b/WebCore/css/themeChromiumWin.css
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* These styles override the default styling for HTML elements as defined in
+ WebCore/css/themeWin.css. */
+#include "themeWin.css"
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-results-decoration,
+input[type="search"]::-webkit-search-results-button {
+ margin: 0 0 0 0;
+}
diff --git a/WebCore/css/themeWin.css b/WebCore/css/themeWin.css
index 8620536..6c582e9 100644
--- a/WebCore/css/themeWin.css
+++ b/WebCore/css/themeWin.css
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Google Inc. All rights reserved.
+ * 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
@@ -34,12 +34,16 @@
input:not([type]),
input[type="text"],
-input[type="password"],
-input[type="search"] {
+input[type="password"] {
margin:0;
padding:1px 0;
}
+input[type="search"] {
+ margin:0;
+ padding:1px;
+}
+
input[type="checkbox"] {
margin:3px 3px 3px 4px;
}
@@ -63,6 +67,10 @@ input[type="search"]:disabled {
background-color: #EBEBE4;
}
+input[type="search"] {
+ -webkit-appearance: textfield;
+}
+
input[type="search"]::-webkit-search-cancel-button {
margin-right: 3px;
}
@@ -89,6 +97,10 @@ select[size="1"] {
-webkit-border-radius: 0;
margin: 0;
}
+/* Options always use the selects' fonts */
+option {
+ font: inherit !important;
+}
textarea {
font-family: monospace;
diff --git a/WebCore/css/themeWinQuirks.css b/WebCore/css/themeWinQuirks.css
index 688eabc..c69b74c 100644
--- a/WebCore/css/themeWinQuirks.css
+++ b/WebCore/css/themeWinQuirks.css
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Google Inc. All rights reserved.
+ * 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
diff --git a/WebCore/dom/Attr.idl b/WebCore/dom/Attr.idl
index 42ac04c..ccbfada 100644
--- a/WebCore/dom/Attr.idl
+++ b/WebCore/dom/Attr.idl
@@ -25,7 +25,7 @@ module core {
GenerateNativeConverter,
InterfaceUUID=EEE8E22B-22C3-4e50-95F4-5E0B8AAD8231,
ImplementationUUID=41B16348-D8E7-4d21-BFDB-125705B7E91F
- ] Attr : EventTargetNode {
+ ] Attr : Node {
// DOM Level 1
diff --git a/WebCore/dom/CharacterData.cpp b/WebCore/dom/CharacterData.cpp
index 0ce4170..54e1888 100644
--- a/WebCore/dom/CharacterData.cpp
+++ b/WebCore/dom/CharacterData.cpp
@@ -31,13 +31,13 @@
namespace WebCore {
CharacterData::CharacterData(Document *doc, bool isText)
- : EventTargetNode(doc, false, false, isText)
+ : Node(doc, false, false, isText)
, m_data(StringImpl::empty())
{
}
CharacterData::CharacterData(Document* document, const String& text, bool isText)
- : EventTargetNode(document, false, false, isText)
+ : Node(document, false, false, isText)
{
m_data = text.impl() ? text.impl() : StringImpl::empty();
}
@@ -224,7 +224,7 @@ bool CharacterData::rendererIsNeeded(RenderStyle *style)
{
if (!m_data || !length())
return false;
- return EventTargetNode::rendererIsNeeded(style);
+ return Node::rendererIsNeeded(style);
}
bool CharacterData::offsetInCharacters() const
diff --git a/WebCore/dom/CharacterData.h b/WebCore/dom/CharacterData.h
index 412650e..d9e55c0 100644
--- a/WebCore/dom/CharacterData.h
+++ b/WebCore/dom/CharacterData.h
@@ -23,11 +23,11 @@
#ifndef CharacterData_h
#define CharacterData_h
-#include "EventTargetNode.h"
+#include "Node.h"
namespace WebCore {
-class CharacterData : public EventTargetNode {
+class CharacterData : public Node {
public:
CharacterData(Document*, const String& text, bool isText = false);
CharacterData(Document*, bool isText = false);
diff --git a/WebCore/dom/CharacterData.idl b/WebCore/dom/CharacterData.idl
index 74dc483..7c8c7ac 100644
--- a/WebCore/dom/CharacterData.idl
+++ b/WebCore/dom/CharacterData.idl
@@ -23,7 +23,7 @@ module core {
GenerateConstructor,
InterfaceUUID=149159F4-D2BA-4040-8137-6BF6424C972A,
ImplementationUUID=E2095280-B9BD-446a-8C03-79F78417CDFF
- ] CharacterData : EventTargetNode {
+ ] CharacterData : Node {
attribute [ConvertNullToNullString] DOMString data
setter raises(DOMException);
diff --git a/WebCore/dom/WorkerTask.cpp b/WebCore/dom/ClientRect.cpp
index 4a22c59..c69a2ab 100644
--- a/WebCore/dom/WorkerTask.cpp
+++ b/WebCore/dom/ClientRect.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,17 +25,17 @@
*/
#include "config.h"
-
-#if ENABLE(WORKERS)
-
-#include "WorkerTask.h"
+#include "ClientRect.h"
namespace WebCore {
-WorkerTask::~WorkerTask()
+ClientRect::ClientRect()
{
}
-} // namespace WebCore
+ClientRect::ClientRect(const IntRect& rect)
+ : m_rect(rect)
+{
+}
-#endif // ENABLE(WORKERS)
+} // namespace WebCore
diff --git a/WebCore/dom/ClientRect.h b/WebCore/dom/ClientRect.h
new file mode 100644
index 0000000..349ea85
--- /dev/null
+++ b/WebCore/dom/ClientRect.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef ClientRect_h
+#define ClientRect_h
+
+#include "FloatRect.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class IntRect;
+
+ class ClientRect : public RefCounted<ClientRect> {
+ public:
+ static PassRefPtr<ClientRect> create() { return adoptRef(new ClientRect); }
+ static PassRefPtr<ClientRect> create(const IntRect& rect) { return adoptRef(new ClientRect(rect)); }
+
+ float top() const { return m_rect.y(); }
+ float right() const { return m_rect.right(); }
+ float bottom() const { return m_rect.bottom(); }
+ float left() const { return m_rect.x(); }
+ float width() const { return m_rect.width(); }
+ float height() const { return m_rect.height(); }
+
+ private:
+ ClientRect();
+ ClientRect(const IntRect&);
+
+ FloatRect m_rect;
+ };
+
+} // namespace WebCore
+
+#endif // ClientRect_h
diff --git a/WebCore/dom/ClientRect.idl b/WebCore/dom/ClientRect.idl
new file mode 100644
index 0000000..6f0598f
--- /dev/null
+++ b/WebCore/dom/ClientRect.idl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+module view {
+
+ interface [
+ GenerateConstructor
+ ] ClientRect {
+ readonly attribute float top;
+ readonly attribute float right;
+ readonly attribute float bottom;
+ readonly attribute float left;
+ readonly attribute float width;
+ readonly attribute float height;
+ };
+
+}
diff --git a/WebCore/dom/ClientRectList.cpp b/WebCore/dom/ClientRectList.cpp
new file mode 100644
index 0000000..95ec758
--- /dev/null
+++ b/WebCore/dom/ClientRectList.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "ClientRectList.h"
+
+#include "ExceptionCode.h"
+#include "ClientRect.h"
+
+namespace WebCore {
+
+ClientRectList::ClientRectList()
+{
+}
+
+ClientRectList::ClientRectList(const Vector<FloatQuad>& quads)
+{
+ m_list.reserveInitialCapacity(quads.size());
+ for (size_t i = 0; i < quads.size(); ++i)
+ m_list.append(ClientRect::create(quads[i].enclosingBoundingBox()));
+}
+
+ClientRectList::~ClientRectList()
+{
+}
+
+unsigned ClientRectList::length() const
+{
+ return m_list.size();
+}
+
+ClientRect* ClientRectList::item(unsigned index)
+{
+ if (index >= m_list.size()) {
+ // FIXME: this should throw an exception.
+ // ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ return m_list[index].get();
+}
+
+} // namespace WebCore
diff --git a/WebCore/dom/ClientRectList.h b/WebCore/dom/ClientRectList.h
new file mode 100644
index 0000000..03915b1
--- /dev/null
+++ b/WebCore/dom/ClientRectList.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef ClientRectList_h
+#define ClientRectList_h
+
+#include "FloatQuad.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class ClientRect;
+
+ class ClientRectList : public RefCounted<ClientRectList> {
+ public:
+ static PassRefPtr<ClientRectList> create() { return adoptRef(new ClientRectList); }
+ static PassRefPtr<ClientRectList> create(const Vector<FloatQuad>& quads) { return adoptRef(new ClientRectList(quads)); }
+ ~ClientRectList();
+
+ unsigned length() const;
+ ClientRect* item(unsigned index);
+
+ private:
+ ClientRectList();
+ ClientRectList(const Vector<FloatQuad>&);
+
+ Vector<RefPtr<ClientRect> > m_list;
+ };
+
+} // namespace WebCore
+
+#endif // ClientRectList_h
diff --git a/WebCore/dom/ClientRectList.idl b/WebCore/dom/ClientRectList.idl
new file mode 100644
index 0000000..8230f6c
--- /dev/null
+++ b/WebCore/dom/ClientRectList.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+module view {
+
+ interface [
+ GenerateConstructor,
+ HasIndexGetter
+ ] ClientRectList {
+ readonly attribute unsigned long length;
+ ClientRect item(in [IsIndex] unsigned long index);
+ // FIXME: Fix list behavior to allow custom exceptions to be thrown.
+ };
+
+}
diff --git a/WebCore/dom/Clipboard.cpp b/WebCore/dom/Clipboard.cpp
index f7a52ef..6d1bc15 100644
--- a/WebCore/dom/Clipboard.cpp
+++ b/WebCore/dom/Clipboard.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "Clipboard.h"
+#include "CachedImage.h"
#include "DOMImplementation.h"
#include "Frame.h"
#include "FrameLoader.h"
diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index 958fc4e..91b633f 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,6 +32,7 @@
#include "FrameView.h"
#include "InlineTextBox.h"
#include "MutationEvent.h"
+#include "Page.h"
#include "RenderTheme.h"
#include "RootInlineBox.h"
#include <wtf/CurrentTime.h>
@@ -42,16 +43,10 @@ static void dispatchChildInsertionEvents(Node*, ExceptionCode&);
static void dispatchChildRemovalEvents(Node*, ExceptionCode&);
typedef Vector<std::pair<NodeCallback, RefPtr<Node> > > NodeCallbackQueue;
-static NodeCallbackQueue* s_postAttachCallbackQueue = 0;
+static NodeCallbackQueue* s_postAttachCallbackQueue;
-static size_t s_attachDepth = 0;
-
-ContainerNode::ContainerNode(Document* doc, bool isElement)
- : EventTargetNode(doc, isElement, true)
- , m_firstChild(0)
- , m_lastChild(0)
-{
-}
+static size_t s_attachDepth;
+static bool s_shouldReEnableMemoryCacheCallsAfterAttach;
void ContainerNode::removeAllChildren()
{
@@ -98,9 +93,8 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
return true;
RefPtr<Node> next = refChild;
- RefPtr<Node> prev = refChild->previousSibling();
+ RefPtr<Node> refChildPreviousSibling = refChild->previousSibling();
- int childCountDelta = 0;
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
RefPtr<Node> nextChild = isFragment ? child->nextSibling() : 0;
@@ -128,8 +122,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
ASSERT(!child->nextSibling());
ASSERT(!child->previousSibling());
- childCountDelta++;
-
// Add child before "next".
forbidEventDispatch();
Node* prev = next->previousSibling();
@@ -149,6 +141,7 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
allowEventDispatch();
// Dispatch the mutation events.
+ childrenChanged(false, refChildPreviousSibling.get(), next.get(), 1);
dispatchChildInsertionEvents(child.get(), ec);
// Add child to the rendering tree.
@@ -163,8 +156,6 @@ bool ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
}
document()->setDocumentChanged(true);
- if (childCountDelta)
- childrenChanged(false, prev.get(), next.get(), childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -222,7 +213,7 @@ bool ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
if (Node* oldParent = child->parentNode())
oldParent->removeChild(child.get(), ec);
if (ec)
- return 0;
+ return false;
// Due to arbitrary code running in response to a DOM mutation event it's
// possible that "prev" is no longer a child of "this".
@@ -288,7 +279,7 @@ void ContainerNode::willRemove()
{
for (Node *n = m_firstChild; n != 0; n = n->nextSibling())
n->willRemove();
- EventTargetNode::willRemove();
+ Node::willRemove();
}
static ExceptionCode willRemoveChild(Node *child)
@@ -392,25 +383,25 @@ bool ContainerNode::removeChildren()
if (!m_firstChild)
return false;
- Node* n;
+ // The container node can be removed from event handlers.
+ RefPtr<Node> protect(this);
- // do any prep work needed before actually starting to detach
- // and remove... e.g. stop loading frames, fire unload events
- for (n = m_firstChild; n; n = n->nextSibling())
- willRemoveChild(n);
+ // Do any prep work needed before actually starting to detach
+ // and remove... e.g. stop loading frames, fire unload events.
+ // FIXME: Adding new children from event handlers can cause an infinite loop here.
+ for (RefPtr<Node> n = m_firstChild; n; n = n->nextSibling())
+ willRemoveChild(n.get());
// exclude this node when looking for removed focusedNode since only children will be removed
document()->removeFocusedNodeOfSubtree(this, true);
forbidEventDispatch();
int childCountDelta = 0;
- while ((n = m_firstChild) != 0) {
+ while (RefPtr<Node> n = m_firstChild) {
childCountDelta--;
- Node *next = n->nextSibling();
+ Node* next = n->nextSibling();
- n->ref();
-
// Remove the node from the tree before calling detach or removedFromDocument (4427024, 4129744)
n->setPreviousSibling(0);
n->setNextSibling(0);
@@ -425,8 +416,6 @@ bool ContainerNode::removeChildren()
if (n->inDocument())
n->removedFromDocument();
-
- n->deref();
}
allowEventDispatch();
@@ -461,7 +450,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
return true;
// Now actually add the child(ren)
- int childCountDelta = 0;
RefPtr<Node> prev = lastChild();
RefPtr<Node> child = isFragment ? newChild->firstChild() : newChild;
while (child) {
@@ -482,7 +470,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
}
// Append child to the end of the list
- childCountDelta++;
forbidEventDispatch();
child->setParent(this);
if (m_lastChild) {
@@ -494,6 +481,7 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
allowEventDispatch();
// Dispatch the mutation events
+ childrenChanged(false, prev.get(), 0, 1);
dispatchChildInsertionEvents(child.get(), ec);
// Add child to the rendering tree
@@ -508,7 +496,6 @@ bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bo
}
document()->setDocumentChanged(true);
- childrenChanged(false, prev.get(), 0, childCountDelta);
dispatchSubtreeModifiedEvent();
return true;
}
@@ -539,13 +526,29 @@ ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild)
void ContainerNode::suspendPostAttachCallbacks()
{
+ if (!s_attachDepth) {
+ ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);
+ if (Page* page = document()->page()) {
+ if (page->areMemoryCacheClientCallsEnabled()) {
+ page->setMemoryCacheClientCallsEnabled(false);
+ s_shouldReEnableMemoryCacheCallsAfterAttach = true;
+ }
+ }
+ }
++s_attachDepth;
}
void ContainerNode::resumePostAttachCallbacks()
{
- if (s_attachDepth == 1 && s_postAttachCallbackQueue)
- dispatchPostAttachCallbacks();
+ if (s_attachDepth == 1) {
+ if (s_postAttachCallbackQueue)
+ dispatchPostAttachCallbacks();
+ if (s_shouldReEnableMemoryCacheCallsAfterAttach) {
+ s_shouldReEnableMemoryCacheCallsAfterAttach = false;
+ if (Page* page = document()->page())
+ page->setMemoryCacheClientCallsEnabled(true);
+ }
+ }
--s_attachDepth;
}
@@ -573,15 +576,13 @@ void ContainerNode::dispatchPostAttachCallbacks()
void ContainerNode::attach()
{
- ++s_attachDepth;
+ suspendPostAttachCallbacks();
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->attach();
- EventTargetNode::attach();
+ Node::attach();
- if (s_attachDepth == 1 && s_postAttachCallbackQueue)
- dispatchPostAttachCallbacks();
- --s_attachDepth;
+ resumePostAttachCallbacks();
}
void ContainerNode::detach()
@@ -589,39 +590,40 @@ void ContainerNode::detach()
for (Node* child = m_firstChild; child; child = child->nextSibling())
child->detach();
setHasChangedChild(false);
- EventTargetNode::detach();
+ Node::detach();
}
void ContainerNode::insertedIntoDocument()
{
- EventTargetNode::insertedIntoDocument();
- for (Node *child = m_firstChild; child; child = child->nextSibling())
+ Node::insertedIntoDocument();
+ insertedIntoTree(false);
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
child->insertedIntoDocument();
}
void ContainerNode::removedFromDocument()
{
- EventTargetNode::removedFromDocument();
- for (Node *child = m_firstChild; child; child = child->nextSibling())
+ Node::removedFromDocument();
+ setInDocument(false);
+ removedFromTree(false);
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
child->removedFromDocument();
}
void ContainerNode::insertedIntoTree(bool deep)
{
- EventTargetNode::insertedIntoTree(deep);
- if (deep) {
- for (Node *child = m_firstChild; child; child = child->nextSibling())
- child->insertedIntoTree(deep);
- }
+ if (!deep)
+ return;
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->insertedIntoTree(true);
}
void ContainerNode::removedFromTree(bool deep)
{
- EventTargetNode::removedFromTree(deep);
- if (deep) {
- for (Node *child = m_firstChild; child; child = child->nextSibling())
- child->removedFromTree(deep);
- }
+ if (!deep)
+ return;
+ for (Node* child = m_firstChild; child; child = child->nextSibling())
+ child->removedFromTree(true);
}
void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -677,13 +679,14 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
if (!o)
break;
}
+ ASSERT(o);
if (!o->isInline() || o->isReplaced()) {
point = o->localToAbsolute();
return true;
}
- if (p->element() && p->element() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
+ if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {
// do nothing - skip unrendered whitespace that is a child or next sibling of the anchor
} else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
point = o->container()->localToAbsolute();
@@ -713,9 +716,8 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
if (!renderer())
return false;
- RenderObject *o = renderer();
- if (!o->isInline() || o->isReplaced())
- {
+ RenderObject* o = renderer();
+ if (!o->isInline() || o->isReplaced()) {
RenderBox* box = toRenderBox(o);
point = o->localToAbsolute();
point.move(box->width(), box->height());
@@ -729,8 +731,8 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
else if (o->previousSibling())
o = o->previousSibling();
else {
- RenderObject *prev = 0;
- while(!prev) {
+ RenderObject* prev = 0;
+ while (!prev) {
o = o->parent();
if (!o)
return false;
@@ -738,12 +740,13 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
}
o = prev;
}
+ ASSERT(o);
if (o->isText() || o->isReplaced()) {
point = o->container()->localToAbsolute();
if (o->isText()) {
RenderText* text = toRenderText(o);
IntRect linesBox = text->linesBoundingBox();
- point.move(linesBox.x() + linesBox.width(), linesBox.height());
+ point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());
} else {
RenderBox* box = toRenderBox(o);
point.move(box->x() + box->width(), box->y() + box->height());
@@ -762,8 +765,7 @@ IntRect ContainerNode::getRect() const
// If we've found one corner, but not the other,
// then we should just return a point at the corner that we did find.
- if (foundUpperLeft != foundLowerRight)
- {
+ if (foundUpperLeft != foundLowerRight) {
if (foundUpperLeft)
lowerRight = upperLeft;
else
@@ -781,7 +783,7 @@ void ContainerNode::setFocus(bool received)
if (focused() == received)
return;
- EventTargetNode::setFocus(received);
+ Node::setFocus(received);
// note that we need to recalc the style
setChanged();
@@ -791,7 +793,7 @@ void ContainerNode::setActive(bool down, bool pause)
{
if (down == active()) return;
- EventTargetNode::setActive(down);
+ Node::setActive(down);
// note that we need to recalc the style
// FIXME: Move to Element
@@ -834,7 +836,7 @@ void ContainerNode::setHovered(bool over)
{
if (over == hovered()) return;
- EventTargetNode::setHovered(over);
+ Node::setHovered(over);
// note that we need to recalc the style
// FIXME: Move to Element
@@ -876,11 +878,11 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
else
c->insertedIntoTree(true);
- if (c->parentNode() &&
- doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER) &&
- c->isEventTargetNode()) {
+ doc->incDOMTreeVersion();
+
+ if (c->parentNode() && doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) {
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, false,
c->parentNode(), String(), String(), String(), 0), ec);
if (ec)
return;
@@ -889,11 +891,8 @@ static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec)
// dispatch the DOMNodeInsertedIntoDocument event to all descendants
if (c->inDocument() && doc->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER))
for (; c; c = c->traverseNextNode(child)) {
- if (!c->isEventTargetNode())
- continue;
-
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false, false,
0, String(), String(), String(), 0), ec);
if (ec)
return;
@@ -908,12 +907,12 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
// update auxiliary doc info (e.g. iterators) to note that node is being removed
doc->nodeWillBeRemoved(child);
+ doc->incDOMTreeVersion();
+
// dispatch pre-removal mutation events
- if (c->parentNode() &&
- doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER) &&
- c->isEventTargetNode()) {
+ if (c->parentNode() && doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, false,
c->parentNode(), String(), String(), String(), 0), ec);
if (ec)
return;
@@ -922,10 +921,8 @@ static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec)
// dispatch the DOMNodeRemovedFromDocument event to all descendants
if (c->inDocument() && doc->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER))
for (; c; c = c->traverseNextNode(child)) {
- if (!c->isEventTargetNode())
- continue;
ec = 0;
- EventTargetNodeCast(c.get())->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false, false,
+ c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false, false,
0, String(), String(), String(), 0), ec);
if (ec)
return;
diff --git a/WebCore/dom/ContainerNode.h b/WebCore/dom/ContainerNode.h
index 91ca49a..3ad932c 100644
--- a/WebCore/dom/ContainerNode.h
+++ b/WebCore/dom/ContainerNode.h
@@ -24,7 +24,7 @@
#ifndef ContainerNode_h
#define ContainerNode_h
-#include "EventTargetNode.h"
+#include "Node.h"
#include "FloatPoint.h"
namespace WebCore {
@@ -36,7 +36,7 @@ namespace Private {
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container);
};
-class ContainerNode : public EventTargetNode {
+class ContainerNode : public Node {
public:
ContainerNode(Document*, bool isElement = false);
virtual ~ContainerNode();
@@ -75,8 +75,8 @@ public:
protected:
static void queuePostAttachCallback(NodeCallback, Node*);
- static void suspendPostAttachCallbacks();
- static void resumePostAttachCallbacks();
+ void suspendPostAttachCallbacks();
+ void resumePostAttachCallbacks();
template<class GenericNode, class GenericNodeContainer>
friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
@@ -96,7 +96,14 @@ private:
Node* m_firstChild;
Node* m_lastChild;
};
-
+
+inline ContainerNode::ContainerNode(Document* document, bool isElement)
+ : Node(document, isElement, true)
+ , m_firstChild(0)
+ , m_lastChild(0)
+{
+}
+
inline unsigned Node::containerChildNodeCount() const
{
ASSERT(isContainerNode());
diff --git a/WebCore/dom/DOMImplementation.cpp b/WebCore/dom/DOMImplementation.cpp
index 738575f..4f29f96 100644
--- a/WebCore/dom/DOMImplementation.cpp
+++ b/WebCore/dom/DOMImplementation.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "DOMImplementation.h"
+#include "ContentType.h"
#include "CSSStyleSheet.h"
#include "DocumentType.h"
#include "Element.h"
@@ -347,7 +348,7 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame
#if ENABLE(VIDEO)
// Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument
- if (MediaPlayer::supportsType(type))
+ if (MediaPlayer::supportsType(ContentType(type)))
return MediaDocument::create(frame);
#endif
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index a687df8..2e2dd9a 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2008 David Levin (levin@chromium.org)
*
@@ -38,7 +38,6 @@
#include "Console.h"
#include "CookieJar.h"
#include "DOMImplementation.h"
-#include "DOMTimer.h"
#include "DOMWindow.h"
#include "DocLoader.h"
#include "DocumentFragment.h"
@@ -94,6 +93,7 @@
#include "ProgressEvent.h"
#include "RegisteredEventListener.h"
#include "RenderArena.h"
+#include "RenderTextControl.h"
#include "RenderView.h"
#include "RenderWidget.h"
#include "ScriptController.h"
@@ -294,6 +294,17 @@ static bool acceptsEditingFocus(Node *node)
return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
}
+static bool disableRangeMutation(Page* page)
+{
+#if PLATFORM(MAC)
+ // Disable Range mutation on document modifications in Tiger and Leopard Mail
+ // See <rdar://problem/5865171>
+ return page && (page->settings()->needsLeopardMailQuirks() || page->settings()->needsTigerMailQuirks());
+#else
+ return false;
+#endif
+}
+
static HashSet<Document*>* changedDocuments = 0;
Document::Document(Frame* frame, bool isXHTML)
@@ -303,7 +314,6 @@ Document::Document(Frame* frame, bool isXHTML)
, m_frameElementsShouldIgnoreScrolling(false)
, m_title("")
, m_titleSetExplicitly(false)
- , m_imageLoadEventTimer(this, &Document::imageLoadEventTimerFired)
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
#if ENABLE(XSLT)
, m_transformSource(0)
@@ -334,9 +344,6 @@ Document::Document(Frame* frame, bool isXHTML)
, m_hasOpenDatabases(false)
#endif
, m_usingGeolocation(false)
-#if USE(LOW_BANDWIDTH_DISPLAY)
- , m_inLowBandwidthDisplay(false)
-#endif
#ifdef ANDROID_MOBILE
, mExtraLayoutDelay(0)
#endif
@@ -555,7 +562,7 @@ PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionC
if (m_isXHTML)
return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), this, 0, false);
- return createElement(QualifiedName(nullAtom, name, nullAtom), false, ec);
+ return createElement(QualifiedName(nullAtom, name, nullAtom), false);
}
PassRefPtr<DocumentFragment> Document::createDocumentFragment()
@@ -772,7 +779,7 @@ bool Document::hasPrefixNamespaceMismatch(const QualifiedName& qName)
}
// FIXME: This should really be in a possible ElementFactory class
-PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser, ExceptionCode& ec)
+PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
{
RefPtr<Element> e;
@@ -790,19 +797,10 @@ PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool cre
if (!e)
e = new Element(qName, document());
-
- // FIXME: The element factories should be fixed to not ignore qName.prefix()
- // Instead they should pass the entire qName into element creation so we don't
- // need to manually set the prefix after creation.
- // Then this code can become ASSERT(qName == e.qname());
- // and Document::createElement can stop taking ExceptionCode& as well.
- if (e && !qName.prefix().isNull()) {
- ec = 0;
- e->setPrefix(qName.prefix(), ec);
- if (ec)
- return 0;
- }
-
+
+ // <image> uses imgTag so we need a special rule.
+ ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
+
return e.release();
}
@@ -818,7 +816,7 @@ PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const
return 0;
}
- return createElement(qName, false, ec);
+ return createElement(qName, false);
}
Element* Document::getElementById(const AtomicString& elementId) const
@@ -861,7 +859,7 @@ String Document::readyState() const
return String();
}
-String Document::inputEncoding() const
+String Document::encoding() const
{
if (TextResourceDecoder* d = decoder())
return d->encoding().name();
@@ -920,8 +918,12 @@ Element* Document::elementFromPoint(int x, int y) const
if (!renderer())
return 0;
- HitTestRequest request(true, true);
- HitTestResult result(IntPoint(x, y));
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
+
+ float zoomFactor = frame() ? frame()->pageZoomFactor() : 1.0f;
+
+ HitTestResult result(roundedIntPoint(FloatPoint(x * zoomFactor, y * zoomFactor)));
renderView()->layer()->hitTest(request, result);
Node* n = result.innerNode();
@@ -999,9 +1001,8 @@ void Document::setTitle(const String& title, Element* titleElement)
m_titleElement = 0;
else if (!m_titleElement) {
if (HTMLElement* headElement = head()) {
+ m_titleElement = createElement(titleTag, false);
ExceptionCode ec = 0;
- m_titleElement = createElement("title", ec);
- ASSERT(!ec);
headElement->appendChild(m_titleElement, ec);
ASSERT(!ec);
}
@@ -1120,8 +1121,8 @@ void Document::setDocumentChanged(bool b)
void Document::recalcStyle(StyleChange change)
{
// we should not enter style recalc while painting
- if (frame() && frame()->view() && frame()->view()->isPainting()) {
- ASSERT(!frame()->view()->isPainting());
+ if (view() && view()->isPainting()) {
+ ASSERT(!view()->isPainting());
return;
}
@@ -1130,6 +1131,8 @@ void Document::recalcStyle(StyleChange change)
m_inStyleRecalc = true;
suspendPostAttachCallbacks();
+ if (view())
+ view()->pauseScheduledEvents();
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::CalculateStyleTimeCounter);
@@ -1172,8 +1175,6 @@ void Document::recalcStyle(StyleChange change)
StyleChange ch = diff(documentStyle.get(), renderer()->style());
if (renderer() && ch != NoChange)
renderer()->setStyle(documentStyle.release());
- if (change != Force)
- change = ch;
}
for (Node* n = firstChild(); n; n = n->nextSibling())
@@ -1184,17 +1185,27 @@ void Document::recalcStyle(StyleChange change)
android::TimeCounter::record(android::TimeCounter::CalculateStyleTimeCounter, __FUNCTION__);
#endif
- if (changed() && view())
- view()->layout();
+ if (view()) {
+ if (changed())
+ view()->layout();
+#if USE(ACCELERATED_COMPOSITING)
+ else {
+ // If we didn't update compositing layers because of layout(), we need to do so here.
+ view()->updateCompositingLayers();
+ }
+#endif
+ }
bail_out:
setChanged(NoStyleChange);
setHasChangedChild(false);
setDocumentChanged(false);
-
+
+ if (view())
+ view()->resumeScheduledEvents();
resumePostAttachCallbacks();
m_inStyleRecalc = false;
-
+
// If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
if (m_closeAfterStyleRecalc) {
m_closeAfterStyleRecalc = false;
@@ -1237,7 +1248,6 @@ void Document::updateLayout()
if (Element* oe = ownerElement())
oe->document()->updateLayout();
- // FIXME: Dave Hyatt's pretty sure we can remove this because layout calls recalcStyle as needed.
updateRendering();
// Only do a layout if changes have occurred that make it necessary.
@@ -1290,6 +1300,9 @@ void Document::attach()
// Create the rendering tree
setRenderer(new (m_renderArena) RenderView(this, view()));
+#if USE(ACCELERATED_COMPOSITING)
+ renderView()->didMoveOnscreen();
+#endif
if (!m_styleSelector) {
bool matchAuthorAndUserStyles = true;
@@ -1318,15 +1331,13 @@ void Document::detach()
RenderObject* render = renderer();
+ // Send out documentWillBecomeInactive() notifications to registered elements,
+ // in order to stop media elements
+ documentWillBecomeInactive();
+
// indicate destruction mode, i.e. attached() but renderer == 0
setRenderer(0);
-
- // Empty out these lists as a performance optimization, since detaching
- // all the individual render objects will cause all the RenderImage
- // objects to remove themselves from the lists.
- m_imageLoadEventDispatchSoonList.clear();
- m_imageLoadEventDispatchingList.clear();
-
+
m_hoverNode = 0;
m_focusedNode = 0;
m_activeNode = 0;
@@ -1360,11 +1371,8 @@ void Document::removeAllEventListenersFromAllNodes()
m_windowEventListeners[i]->setRemoved(true);
m_windowEventListeners.clear();
removeAllDisconnectedNodeEventListeners();
- for (Node *n = this; n; n = n->traverseNextNode()) {
- if (!n->isEventTargetNode())
- continue;
- EventTargetNodeCast(n)->removeAllEventListeners();
- }
+ for (Node* node = this; node; node = node->traverseNextNode())
+ node->removeAllEventListeners();
}
void Document::registerDisconnectedNodeWithEventListeners(Node* node)
@@ -1381,13 +1389,13 @@ void Document::removeAllDisconnectedNodeEventListeners()
{
HashSet<Node*>::iterator end = m_disconnectedNodesWithEventListeners.end();
for (HashSet<Node*>::iterator i = m_disconnectedNodesWithEventListeners.begin(); i != end; ++i)
- EventTargetNodeCast(*i)->removeAllEventListeners();
+ (*i)->removeAllEventListeners();
m_disconnectedNodesWithEventListeners.clear();
}
RenderView* Document::renderView() const
{
- return static_cast<RenderView*>(renderer());
+ return toRenderView(renderer());
}
void Document::clearAXObjectCache()
@@ -1499,7 +1507,7 @@ void Document::implicitOpen()
setParsing(true);
}
-HTMLElement* Document::body()
+HTMLElement* Document::body() const
{
Node* de = documentElement();
if (!de)
@@ -1609,8 +1617,8 @@ void Document::implicitClose()
if (f)
f->animation()->resumeAnimations(this);
- dispatchImageLoadEventsNow();
- this->dispatchWindowEvent(eventNames().loadEvent, false, false);
+ ImageLoader::dispatchPendingLoadEvents();
+ dispatchWindowEvent(eventNames().loadEvent, false, false);
if (f)
f->loader()->handledOnloadEvents();
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
@@ -1692,8 +1700,8 @@ bool Document::shouldScheduleLayout()
// (a) Only schedule a layout once the stylesheets are loaded.
// (b) Only schedule layout once we have a body element.
- return haveStylesheetsLoaded()
- && body() || (documentElement() && !documentElement()->hasTagName(htmlTag));
+ return (haveStylesheetsLoaded() && body()) ||
+ (documentElement() && !documentElement()->hasTagName(htmlTag));
}
int Document::minimumLayoutDelay()
@@ -1713,28 +1721,30 @@ int Document::elapsedTime() const
return static_cast<int>((currentTime() - m_startTime) * 1000);
}
-void Document::write(const String& text, Document* ownerDocument)
+void Document::write(const SegmentedString& text, Document* ownerDocument)
{
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
printf("Beginning a document.write at %d\n", elapsedTime());
#endif
-
- if (!m_tokenizer) {
+
+ if (!m_tokenizer)
open(ownerDocument);
- ASSERT(m_tokenizer);
- if (!m_tokenizer)
- return;
- write("<html>", ownerDocument);
- }
+
+ ASSERT(m_tokenizer);
m_tokenizer->write(text, false);
-
+
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (!ownerElement())
printf("Ending a document.write at %d\n", elapsedTime());
#endif
}
+void Document::write(const String& text, Document* ownerDocument)
+{
+ write(SegmentedString(text), ownerDocument);
+}
+
void Document::writeln(const String& text, Document* ownerDocument)
{
write(text, ownerDocument);
@@ -1817,6 +1827,11 @@ void Document::updateBaseURL()
m_mappedElementSheet->setHref(m_baseURL.string());
}
+String Document::userAgent(const KURL& url) const
+{
+ return frame() ? frame()->loader()->userAgent(url) : String();
+}
+
void Document::setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet* sheet)
{
m_sheet = CSSStyleSheet::create(this, url, charset);
@@ -2097,7 +2112,7 @@ MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& r
HitTestResult result(documentPoint);
renderView()->layer()->hitTest(request, result);
- if (!request.readonly)
+ if (!request.readOnly())
updateRendering();
return MouseEventWithHitTestResults(event, result);
@@ -2553,21 +2568,23 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
// Dispatch a change event for text fields or textareas that have been edited
RenderObject* r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer());
- if (r && (r->isTextArea() || r->isTextField()) && r->isEdited()) {
- EventTargetNodeCast(oldFocusedNode.get())->dispatchEventForType(eventNames().changeEvent, true, false);
- if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer())))
- r->setEdited(false);
+ if (r && r->isTextControl() && toRenderTextControl(r)->isEdited()) {
+ oldFocusedNode->dispatchEventForType(eventNames().changeEvent, true, false);
+ if ((r = static_cast<RenderObject*>(oldFocusedNode.get()->renderer()))) {
+ if (r->isTextControl())
+ toRenderTextControl(r)->setEdited(false);
+ }
}
// Dispatch the blur event and let the node do any other blur related activities (important for text fields)
- EventTargetNodeCast(oldFocusedNode.get())->dispatchBlurEvent();
+ oldFocusedNode->dispatchBlurEvent();
if (m_focusedNode) {
// handler shifted focus
focusChangeBlocked = true;
newFocusedNode = 0;
}
- EventTargetNodeCast(oldFocusedNode.get())->dispatchUIEvent(eventNames().DOMFocusOutEvent);
+ oldFocusedNode->dispatchUIEvent(eventNames().DOMFocusOutEvent);
if (m_focusedNode) {
// handler shifted focus
focusChangeBlocked = true;
@@ -2590,14 +2607,14 @@ bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
m_focusedNode = newFocusedNode.get();
// Dispatch the focus event and let the node do any other focus related activities (important for text fields)
- EventTargetNodeCast(m_focusedNode.get())->dispatchFocusEvent();
+ m_focusedNode->dispatchFocusEvent();
if (m_focusedNode != newFocusedNode) {
// handler shifted focus
focusChangeBlocked = true;
goto SetFocusedNodeDone;
}
- EventTargetNodeCast(m_focusedNode.get())->dispatchUIEvent(eventNames().DOMFocusInEvent);
+ m_focusedNode->dispatchUIEvent(eventNames().DOMFocusInEvent);
if (m_focusedNode != newFocusedNode) {
// handler shifted focus
focusChangeBlocked = true;
@@ -2637,7 +2654,7 @@ SetFocusedNodeDone:
return !focusChangeBlocked;
}
-void Document::setCSSTarget(Node* n)
+void Document::setCSSTarget(Element* n)
{
if (m_cssTarget)
m_cssTarget->setChanged();
@@ -2646,11 +2663,6 @@ void Document::setCSSTarget(Node* n)
n->setChanged();
}
-Node* Document::getCSSTarget() const
-{
- return m_cssTarget;
-}
-
void Document::attachNodeIterator(NodeIterator *ni)
{
m_nodeIterators.add(ni);
@@ -2663,7 +2675,7 @@ void Document::detachNodeIterator(NodeIterator *ni)
void Document::nodeChildrenChanged(ContainerNode* container)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenChanged(container);
@@ -2676,7 +2688,7 @@ void Document::nodeWillBeRemoved(Node* n)
for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
(*it)->nodeWillBeRemoved(n);
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
(*it)->nodeWillBeRemoved(n);
@@ -2690,7 +2702,7 @@ void Document::nodeWillBeRemoved(Node* n)
void Document::textInserted(Node* text, unsigned offset, unsigned length)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textInserted(text, offset, length);
@@ -2702,7 +2714,7 @@ void Document::textInserted(Node* text, unsigned offset, unsigned length)
void Document::textRemoved(Node* text, unsigned offset, unsigned length)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textRemoved(text, offset, length);
@@ -2715,7 +2727,7 @@ void Document::textRemoved(Node* text, unsigned offset, unsigned length)
void Document::textNodesMerged(Text* oldNode, unsigned offset)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
NodeWithIndex oldNodeWithIndex(oldNode);
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
@@ -2727,7 +2739,7 @@ void Document::textNodesMerged(Text* oldNode, unsigned offset)
void Document::textNodeSplit(Text* oldNode)
{
- if (!page() || !page()->settings()->rangeMutationDisabledForOldAppleMail()) {
+ if (!disableRangeMutation(page())) {
HashSet<Range*>::const_iterator end = m_ranges.end();
for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->textNodeSplit(oldNode);
@@ -2956,66 +2968,6 @@ void Document::setWindowInlineEventListenerForTypeAndAttribute(const AtomicStrin
setWindowInlineEventListenerForType(eventType, createEventListener(attr->localName().string(), attr->value(), 0));
}
-void Document::dispatchImageLoadEventSoon(ImageLoader* image)
-{
- m_imageLoadEventDispatchSoonList.append(image);
- if (!m_imageLoadEventTimer.isActive())
- m_imageLoadEventTimer.startOneShot(0);
-}
-
-void Document::removeImage(ImageLoader* image)
-{
- // Remove instances of this image from both lists.
- // Use loops because we allow multiple instances to get into the lists.
- size_t size = m_imageLoadEventDispatchSoonList.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_imageLoadEventDispatchSoonList[i] == image)
- m_imageLoadEventDispatchSoonList[i] = 0;
- }
- size = m_imageLoadEventDispatchingList.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_imageLoadEventDispatchingList[i] == image)
- m_imageLoadEventDispatchingList[i] = 0;
- }
- if (m_imageLoadEventDispatchSoonList.isEmpty())
- m_imageLoadEventTimer.stop();
-}
-
-void Document::dispatchImageLoadEventsNow()
-{
- // Need to avoid re-entering this function; if new dispatches are
- // scheduled before the parent finishes processing the list, they
- // will set a timer and eventually be processed.
- if (!m_imageLoadEventDispatchingList.isEmpty())
- return;
-#ifdef BUILDING_ON_LEOPARD
- bool shouldReenableMemoryCacheClientCalls = false;
- if (settings() && settings()->needsIChatMemoryCacheCallsQuirk() && page()->areMemoryCacheClientCallsEnabled()) {
- shouldReenableMemoryCacheClientCalls = true;
- page()->setMemoryCacheClientCallsEnabled(false);
- }
-#endif
- m_imageLoadEventTimer.stop();
-
- m_imageLoadEventDispatchingList = m_imageLoadEventDispatchSoonList;
- m_imageLoadEventDispatchSoonList.clear();
- size_t size = m_imageLoadEventDispatchingList.size();
- for (size_t i = 0; i < size; ++i) {
- if (ImageLoader* image = m_imageLoadEventDispatchingList[i])
- image->dispatchLoadEvent();
- }
- m_imageLoadEventDispatchingList.clear();
-#ifdef BUILDING_ON_LEOPARD
- if (shouldReenableMemoryCacheClientCalls && page())
- page()->setMemoryCacheClientCallsEnabled(true);
-#endif
-}
-
-void Document::imageLoadEventTimerFired(Timer<Document>*)
-{
- dispatchImageLoadEventsNow();
-}
-
Element* Document::ownerElement() const
{
if (!frame())
@@ -3262,9 +3214,10 @@ KURL Document::completeURL(const String& url) const
// See also [CSS]StyleSheet::completeURL(const String&)
if (url.isNull())
return KURL();
+ const KURL& baseURL = ((m_baseURL.isEmpty() || m_baseURL == blankURL()) && parentDocument()) ? parentDocument()->baseURL() : m_baseURL;
if (!m_decoder)
- return KURL(m_baseURL, url);
- return KURL(m_baseURL, url, m_decoder->encoding());
+ return KURL(baseURL, url);
+ return KURL(baseURL, url, m_decoder->encoding());
}
void Document::setInPageCache(bool flag)
@@ -3288,6 +3241,11 @@ void Document::setInPageCache(bool flag)
void Document::documentWillBecomeInactive()
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (renderer())
+ renderView()->willMoveOffscreen();
+#endif
+
HashSet<Element*>::iterator end = m_documentActivationCallbackElements.end();
for (HashSet<Element*>::iterator i = m_documentActivationCallbackElements.begin(); i != end; ++i)
(*i)->documentWillBecomeInactive();
@@ -3298,6 +3256,11 @@ void Document::documentDidBecomeActive()
HashSet<Element*>::iterator end = m_documentActivationCallbackElements.end();
for (HashSet<Element*>::iterator i = m_documentActivationCallbackElements.begin(); i != end; ++i)
(*i)->documentDidBecomeActive();
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (renderer())
+ renderView()->didMoveOnscreen();
+#endif
}
void Document::registerForDocumentActivationCallbacks(Element* e)
@@ -4005,7 +3968,7 @@ void Document::finishedParsing()
Vector<String> Document::formElementsState() const
{
Vector<String> stateVector;
- stateVector.reserveCapacity(m_formElementsWithState.size() * 3);
+ stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 3);
typedef ListHashSet<FormControlElementWithState*>::const_iterator Iterator;
Iterator end = m_formElementsWithState.end();
for (Iterator it = m_formElementsWithState.begin(); it != end; ++it) {
@@ -4225,6 +4188,20 @@ void Document::initSecurityContext()
securityOrigin()->grantLoadLocalResources();
}
+ if (Settings* settings = this->settings()) {
+ if (!settings->isWebSecurityEnabled()) {
+ // Web security is turned off. We should let this document access every
+ // other document. This is used primary by testing harnesses for web
+ // sites.
+ securityOrigin()->grantUniversalAccess();
+
+ } else if (settings->allowUniversalAccessFromFileURLs() && securityOrigin()->isLocal()) {
+ // Some clients want file:// URLs to have universal access, but that
+ // setting is dangerous for other clients.
+ securityOrigin()->grantUniversalAccess();
+ }
+ }
+
if (!securityOrigin()->isEmpty())
return;
@@ -4235,7 +4212,7 @@ void Document::initSecurityContext()
if (!ownerFrame)
ownerFrame = m_frame->loader()->opener();
- if (ownerFrame && ownerFrame->document()) {
+ if (ownerFrame) {
m_cookieURL = ownerFrame->document()->cookieURL();
// We alias the SecurityOrigins to match Firefox, see Bug 15313
// https://bugs.webkit.org/show_bug.cgi?id=15313
@@ -4428,22 +4405,6 @@ void Document::removeTouchEventListener(Node* node)
#endif
-void Document::addTimeout(int timeoutId, DOMTimer* timer)
-{
- ASSERT(!m_timeouts.contains(timeoutId));
- m_timeouts.set(timeoutId, timer);
-}
-
-void Document::removeTimeout(int timeoutId)
-{
- m_timeouts.remove(timeoutId);
-}
-
-DOMTimer* Document::findTimeout(int timeoutId)
-{
- return m_timeouts.get(timeoutId);
-}
-
void Document::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
{
if (DOMWindow* window = domWindow())
@@ -4471,6 +4432,12 @@ void Document::resourceRetrievedByXMLHttpRequest(unsigned long identifier, const
page()->inspectorController()->resourceRetrievedByXMLHttpRequest(identifier, sourceString);
}
+void Document::scriptImported(unsigned long identifier, const String& sourceString)
+{
+ if (page())
+ page()->inspectorController()->scriptImported(identifier, sourceString);
+}
+
class ScriptExecutionContextTaskTimer : public TimerBase {
public:
ScriptExecutionContextTaskTimer(PassRefPtr<Document> context, PassRefPtr<ScriptExecutionContext::Task> task)
@@ -4541,4 +4508,24 @@ Element* Document::findAnchor(const String& name)
return 0;
}
+String Document::displayStringModifiedByEncoding(const String& str) const
+{
+ if (m_decoder)
+ return m_decoder->encoding().displayString(str.impl());
+ return str;
+}
+
+PassRefPtr<StringImpl> Document::displayStringModifiedByEncoding(PassRefPtr<StringImpl> str) const
+{
+ if (m_decoder)
+ return m_decoder->encoding().displayString(str);
+ return str;
+}
+
+void Document::displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const
+{
+ if (m_decoder)
+ m_decoder->encoding().displayBuffer(buffer, len);
+}
+
} // namespace WebCore
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index ce8116d..3d232ec 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -33,7 +33,6 @@
#include "HTMLFormElement.h"
#include "ScriptExecutionContext.h"
#include "StringHash.h"
-#include "TextResourceDecoder.h"
#include "Timer.h"
#include <wtf/HashCountedSet.h>
#include <wtf/ListHashSet.h>
@@ -63,7 +62,6 @@ namespace WebCore {
class Database;
class DOMImplementation;
class DOMSelection;
- class DOMTimer;
class DOMWindow;
class DatabaseThread;
class DocLoader;
@@ -77,6 +75,7 @@ namespace WebCore {
class FormControlElementWithState;
class Frame;
class FrameView;
+ class HitTestRequest;
class HTMLCanvasElement;
class HTMLDocument;
class HTMLElement;
@@ -84,7 +83,6 @@ namespace WebCore {
class HTMLHeadElement;
class HTMLInputElement;
class HTMLMapElement;
- class ImageLoader;
class IntPoint;
class JSNode;
class MouseEventWithHitTestResults;
@@ -98,6 +96,7 @@ namespace WebCore {
class RenderArena;
class RenderView;
class SecurityOrigin;
+ class SegmentedString;
class Settings;
class StyleSheet;
class StyleSheetList;
@@ -125,7 +124,6 @@ namespace WebCore {
#if ENABLE(DASHBOARD_SUPPORT)
struct DashboardRegionValue;
#endif
- struct HitTestRequest;
typedef int ExceptionCode;
@@ -235,18 +233,20 @@ public:
PassRefPtr<EntityReference> createEntityReference(const String& name, ExceptionCode&);
PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionCode&);
virtual PassRefPtr<Element> createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode&);
- PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser, ExceptionCode& ec);
+ PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
Element* getElementById(const AtomicString&) const;
bool hasElementWithId(AtomicStringImpl* id) const;
bool containsMultipleElementsWithId(const AtomicString& elementId) { return m_duplicateIds.contains(elementId.impl()); }
Element* elementFromPoint(int x, int y) const;
String readyState() const;
- String inputEncoding() const;
- String defaultCharset() const;
- String charset() const { return inputEncoding(); }
- String characterSet() const { return inputEncoding(); }
+ String defaultCharset() const;
+
+ // Synonyms backing similar DOM attributes. Use Document::encoding() to avoid virtual dispatch.
+ String inputEncoding() const { return Document::encoding(); }
+ String charset() const { return Document::encoding(); }
+ String characterSet() const { return Document::encoding(); }
void setCharset(const String&);
@@ -314,6 +314,7 @@ public:
#if ENABLE(WML)
virtual bool isWMLDocument() const { return false; }
#endif
+ virtual bool isFrameSet() const { return false; }
CSSStyleSelector* styleSelector() const { return m_styleSelector; }
@@ -330,11 +331,7 @@ public:
*/
bool haveStylesheetsLoaded() const
{
- return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets
-#if USE(LOW_BANDWIDTH_DISPLAY)
- || m_inLowBandwidthDisplay
-#endif
- ;
+ return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
}
/**
@@ -426,6 +423,7 @@ public:
void implicitClose();
void cancelParsing();
+ void write(const SegmentedString& text, Document* ownerDocument = 0);
void write(const String& text, Document* ownerDocument = 0);
void writeln(const String& text, Document* ownerDocument = 0);
void finishParsing();
@@ -446,6 +444,8 @@ public:
KURL completeURL(const String&) const;
+ virtual String userAgent(const KURL&) const;
+
// from cachedObjectClient
virtual void setCSSStyleSheet(const String& url, const String& charset, const CachedCSSStyleSheet*);
@@ -532,8 +532,8 @@ public:
void activeChainNodeDetached(Node*);
// Updates for :target (CSS3 selector).
- void setCSSTarget(Node*);
- Node* getCSSTarget() const;
+ void setCSSTarget(Element*);
+ Element* cssTarget() const { return m_cssTarget; }
void setDocumentChanged(bool);
@@ -644,11 +644,7 @@ public:
*/
void processMetadataSettings(const String& content);
#endif
-
- void dispatchImageLoadEventSoon(ImageLoader*);
- void dispatchImageLoadEventsNow();
- void removeImage(ImageLoader*);
-
+
// Returns the owning element in the parent document.
// Returns 0 if this is the top level document.
Element* ownerElement() const;
@@ -692,7 +688,7 @@ public:
void removeImageMap(HTMLMapElement*);
HTMLMapElement* getImageMap(const String& url) const;
- HTMLElement* body();
+ HTMLElement* body() const;
void setBody(PassRefPtr<HTMLElement>, ExceptionCode&);
HTMLHeadElement* head();
@@ -776,13 +772,7 @@ public:
void setUseSecureKeyboardEntryWhenActive(bool);
bool useSecureKeyboardEntryWhenActive() const;
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- void setDocLoader(DocLoader* loader) { m_docLoader = loader; }
- bool inLowBandwidthDisplay() const { return m_inLowBandwidthDisplay; }
- void setLowBandwidthDisplay(bool lowBandWidth) { m_inLowBandwidthDisplay = lowBandWidth; }
-#endif
-
+
void addNodeListCache() { ++m_numNodeListCaches; }
void removeNodeListCache() { ASSERT(m_numNodeListCaches > 0); --m_numNodeListCaches; }
bool hasNodeListCaches() const { return m_numNodeListCaches; }
@@ -809,12 +799,9 @@ public:
virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
+ virtual void scriptImported(unsigned long, const String&);
virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
- void addTimeout(int timeoutId, DOMTimer*);
- void removeTimeout(int timeoutId);
- DOMTimer* findTimeout(int timeoutId);
-
protected:
Document(Frame*, bool isXHTML);
@@ -837,6 +824,8 @@ private:
virtual const KURL& virtualURL() const; // Same as url(), but needed for ScriptExecutionContext to implement it without a performance loss for direct calls.
virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
+ String encoding() const;
+
CSSStyleSelector* m_styleSelector;
bool m_didCalculateStyleSelector;
@@ -953,13 +942,9 @@ private:
mutable AXObjectCache* m_axObjectCache;
- Vector<ImageLoader*> m_imageLoadEventDispatchSoonList;
- Vector<ImageLoader*> m_imageLoadEventDispatchingList;
- Timer<Document> m_imageLoadEventTimer;
-
Timer<Document> m_updateFocusAppearanceTimer;
- Node* m_cssTarget;
+ Element* m_cssTarget;
bool m_processingLoadEvent;
double m_startTime;
@@ -1008,20 +993,9 @@ public:
void setDecoder(PassRefPtr<TextResourceDecoder>);
TextResourceDecoder* decoder() const { return m_decoder.get(); }
- String displayStringModifiedByEncoding(const String& str) const {
- if (m_decoder)
- return m_decoder->encoding().displayString(str.impl());
- return str;
- }
- PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl> str) const {
- if (m_decoder)
- return m_decoder->encoding().displayString(str);
- return str;
- }
- void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const {
- if (m_decoder)
- m_decoder->encoding().displayBuffer(buffer, len);
- }
+ String displayStringModifiedByEncoding(const String&) const;
+ PassRefPtr<StringImpl> displayStringModifiedByEncoding(PassRefPtr<StringImpl>) const;
+ void displayBufferModifiedByEncoding(UChar* buffer, unsigned len) const;
// Quirk for the benefit of Apple's Dictionary application.
void setFrameElementsShouldIgnoreScrolling(bool ignore) { m_frameElementsShouldIgnoreScrolling = ignore; }
@@ -1079,7 +1053,6 @@ protected:
private:
void updateTitle();
void removeAllDisconnectedNodeEventListeners();
- void imageLoadEventTimerFired(Timer<Document>*);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
@@ -1152,16 +1125,9 @@ private:
#endif
bool m_usingGeolocation;
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- bool m_inLowBandwidthDisplay;
-#endif
#ifdef ANDROID_MOBILE
int mExtraLayoutDelay;
#endif
-
- typedef HashMap<int, DOMTimer*> TimeoutsMap;
- TimeoutsMap m_timeouts;
};
inline bool Document::hasElementWithId(AtomicStringImpl* id) const
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index dfdfe46..3543cc7 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -28,11 +28,11 @@ module core {
InlineGetOwnPropertySlot,
InterfaceUUID=48BB95FC-2D08-4c54-BE65-7558736A4CAE,
ImplementationUUID=FF5CBE81-F817-429c-A6C2-0CCCD2328062
- ] Document : EventTargetNode {
+ ] Document : Node {
// DOM Level 1 Core
readonly attribute DocumentType doctype;
- readonly attribute DOMImplementation implementation;
+ readonly attribute [V8Custom] DOMImplementation implementation;
readonly attribute Element documentElement;
[ReturnsNew] Element createElement(in [ConvertNullToNullString] DOMString tagName)
@@ -122,11 +122,11 @@ module core {
in XPathNSResolver resolver)
raises(DOMException);
XPathNSResolver createNSResolver(in Node nodeResolver);
- [OldStyleObjC] XPathResult evaluate(in DOMString expression,
- in Node contextNode,
- in XPathNSResolver resolver,
- in unsigned short type,
- in XPathResult inResult)
+ [OldStyleObjC, V8Custom] XPathResult evaluate(in DOMString expression,
+ in Node contextNode,
+ in XPathNSResolver resolver,
+ in unsigned short type,
+ in XPathResult inResult)
raises(DOMException);
#endif // ENABLE_XPATH
#endif // !defined(LANGUAGE_COM)
@@ -226,7 +226,7 @@ module core {
#if !defined(LANGUAGE_COM)
#if !defined(LANGUAGE_OBJECTIVE_C)
- DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
+ [V8Custom] DOMObject getCSSCanvasContext(in DOMString contextId, in DOMString name, in long width, in long height);
#endif
#endif
@@ -234,9 +234,9 @@ module core {
NodeList getElementsByClassName(in DOMString tagname);
// NodeSelector - Selector API
- Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ Element querySelector(in DOMString selectors)
raises(DOMException);
- NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ NodeList querySelectorAll(in DOMString selectors)
raises(DOMException);
#if ENABLE_WML
diff --git a/WebCore/dom/DocumentFragment.idl b/WebCore/dom/DocumentFragment.idl
index 2cdcdf8..ff6232f 100644
--- a/WebCore/dom/DocumentFragment.idl
+++ b/WebCore/dom/DocumentFragment.idl
@@ -23,12 +23,11 @@ module core {
GenerateConstructor,
InterfaceUUID=F5C8DAF0-D728-4b2b-9D9C-630621B07D35,
ImplementationUUID=E57BF71F-3FAA-495c-A307-E288F8E5B2EC
- ] DocumentFragment : EventTargetNode {
+ ] DocumentFragment : Node {
// NodeSelector - Selector API
- // FIXME: add support for NSResolver in languages other than JS
- Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ Element querySelector(in DOMString selectors)
raises(DOMException);
- NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ NodeList querySelectorAll(in DOMString selectors)
raises(DOMException);
};
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 781179d..dbec884 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -29,6 +29,8 @@
#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
#include "CString.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
#include "Document.h"
#include "Editor.h"
#include "ElementRareData.h"
@@ -44,6 +46,9 @@
#include "Page.h"
#include "PlatformString.h"
#include "RenderBlock.h"
+#if ENABLE(SVG)
+#include "SVGNames.h"
+#endif
#include "SelectionController.h"
#include "TextIterator.h"
#include "XMLNames.h"
@@ -83,27 +88,32 @@ NodeRareData* Element::createRareData()
PassRefPtr<Node> Element::cloneNode(bool deep)
{
- ExceptionCode ec = 0;
- RefPtr<Element> clone = document()->createElementNS(namespaceURI(), nodeName(), ec);
- ASSERT(!ec);
-
- // clone attributes
+ return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
+}
+
+PassRefPtr<Element> Element::cloneElementWithChildren()
+{
+ RefPtr<Element> clone = cloneElementWithoutChildren();
+ cloneChildNodes(clone.get());
+ return clone.release();
+}
+
+PassRefPtr<Element> Element::cloneElementWithoutChildren()
+{
+ RefPtr<Element> clone = document()->createElement(tagQName(), false);
+ // This will catch HTML elements in the wrong namespace that are not correctly copied.
+ // This is a sanity check as HTML overloads some of the DOM methods.
+ ASSERT(isHTMLElement() == clone->isHTMLElement());
+
+ // Clone attributes.
if (namedAttrMap)
clone->attributes()->setAttributes(*namedAttrMap);
clone->copyNonAttributeProperties(this);
- if (deep)
- cloneChildNodes(clone.get());
-
return clone.release();
}
-PassRefPtr<Element> Element::cloneElement()
-{
- return static_pointer_cast<Element>(cloneNode(false));
-}
-
void Element::removeAttribute(const QualifiedName& name, ExceptionCode& ec)
{
if (namedAttrMap) {
@@ -189,9 +199,9 @@ void Element::scrollIntoView(bool alignToTop)
if (renderer()) {
// Align to the top / bottom and to the closest edge.
if (alignToTop)
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
else
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignBottomAlways);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
}
}
@@ -201,9 +211,9 @@ void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
IntRect bounds = getRect();
if (renderer()) {
if (centerIfNeeded)
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignCenterIfNeeded, RenderLayer::gAlignCenterIfNeeded);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
else
- renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
+ renderer()->enclosingLayer()->scrollRectToVisible(bounds, false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
}
}
@@ -274,7 +284,7 @@ static int adjustForAbsoluteZoom(int value, RenderObject* renderer)
int Element::offsetLeft()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForLocalZoom(rend->offsetLeft(), rend);
return 0;
}
@@ -282,7 +292,7 @@ int Element::offsetLeft()
int Element::offsetTop()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForLocalZoom(rend->offsetTop(), rend);
return 0;
}
@@ -290,7 +300,7 @@ int Element::offsetTop()
int Element::offsetWidth()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForAbsoluteZoom(rend->offsetWidth(), rend);
return 0;
}
@@ -298,7 +308,7 @@ int Element::offsetWidth()
int Element::offsetHeight()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderBoxModelObject* rend = renderBoxModelObject())
return adjustForAbsoluteZoom(rend->offsetHeight(), rend);
return 0;
}
@@ -306,9 +316,9 @@ int Element::offsetHeight()
Element* Element::offsetParent()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox())
+ if (RenderObject* rend = renderer())
if (RenderObject* offsetParent = rend->offsetParent())
- return static_cast<Element*>(offsetParent->element());
+ return static_cast<Element*>(offsetParent->node());
return 0;
}
@@ -340,14 +350,11 @@ int Element::clientWidth()
if ((!inCompatMode && document()->documentElement() == this) ||
(inCompatMode && isHTMLElement() && document()->body() == this)) {
if (FrameView* view = document()->view())
- return view->layoutWidth();
+ return adjustForAbsoluteZoom(view->layoutWidth(), document()->renderer());
}
-
- if (RenderBox* rend = renderBox()) {
- if (!rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->clientWidth(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->clientWidth(), rend);
return 0;
}
@@ -362,13 +369,11 @@ int Element::clientHeight()
if ((!inCompatMode && document()->documentElement() == this) ||
(inCompatMode && isHTMLElement() && document()->body() == this)) {
if (FrameView* view = document()->view())
- return view->layoutHeight();
+ return adjustForAbsoluteZoom(view->layoutHeight(), document()->renderer());
}
- if (RenderBox* rend = renderBox()) {
- if (!rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->clientHeight(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->clientHeight(), rend);
return 0;
}
@@ -405,23 +410,67 @@ void Element::setScrollTop(int newTop)
int Element::scrollWidth()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox()) {
- if (rend->hasOverflowClip() || !rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
return 0;
}
int Element::scrollHeight()
{
document()->updateLayoutIgnorePendingStylesheets();
- if (RenderBox* rend = renderBox()) {
- if (rend->hasOverflowClip() || !rend->isRenderInline())
- return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
- }
+ if (RenderBox* rend = renderBox())
+ return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
return 0;
}
+PassRefPtr<ClientRectList> Element::getClientRects() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+
+ RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
+ if (!renderBoxModelObject)
+ return ClientRectList::create();
+
+ // FIXME: Handle SVG elements.
+ // FIXME: Handle table/inline-table with a caption.
+
+ Vector<FloatQuad> quads;
+ renderBoxModelObject->absoluteQuads(quads);
+
+ if (FrameView* view = document()->view()) {
+ IntRect visibleContentRect = view->visibleContentRect();
+ for (size_t i = 0; i < quads.size(); ++i)
+ quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
+ }
+
+ return ClientRectList::create(quads);
+}
+
+PassRefPtr<ClientRect> Element::getBoundingClientRect() const
+{
+ document()->updateLayoutIgnorePendingStylesheets();
+ RenderBoxModelObject* renderBoxModelObject = this->renderBoxModelObject();
+ if (!renderBoxModelObject)
+ return ClientRect::create();
+
+ Vector<FloatQuad> quads;
+ renderBoxModelObject->absoluteQuads(quads);
+
+ if (quads.isEmpty())
+ return ClientRect::create();
+
+ IntRect result = quads[0].enclosingBoundingBox();
+ for (size_t i = 1; i < quads.size(); ++i)
+ result.unite(quads[i].enclosingBoundingBox());
+
+ if (FrameView* view = document()->view()) {
+ IntRect visibleContentRect = view->visibleContentRect();
+ result.move(-visibleContentRect.x(), -visibleContentRect.y());
+ }
+
+ return ClientRect::create(result);
+}
+
static inline bool shouldIgnoreAttributeCase(const Element* e)
{
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
@@ -1105,18 +1154,17 @@ void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
return;
// FIXME: We should restore the previous selection if there is one.
- Selection newSelection = hasTagName(htmlTag) || hasTagName(bodyTag) ? Selection(Position(this, 0), DOWNSTREAM) : Selection::selectionFromContentsOfNode(this);
+ VisibleSelection newSelection = hasTagName(htmlTag) || hasTagName(bodyTag) ? VisibleSelection(Position(this, 0), DOWNSTREAM) : VisibleSelection::selectionFromContentsOfNode(this);
if (frame->shouldChangeSelection(newSelection)) {
frame->selection()->setSelection(newSelection);
frame->revealSelection();
}
-#ifdef ANDROID_SCROLL_FIX
- // We handle the scrolling the screen with our navigation code,
- // so ignore this call to put the rectangle on screen.
}
-#else
- } else if (renderer() && !renderer()->isWidget())
+ // FIXME: I'm not sure all devices will want this off, but this is
+ // currently turned off for Andriod.
+#if !ENABLE(DIRECTIONAL_PAD_NAVIGATION)
+ else if (renderer() && !renderer()->isWidget())
renderer()->enclosingLayer()->scrollRectToVisible(getRect());
#endif
}
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index e9bab28..b9b391a 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -36,6 +36,8 @@ class Attribute;
class CSSStyleDeclaration;
class ElementRareData;
class IntSize;
+class ClientRect;
+class ClientRectList;
class Element : public ContainerNode {
public:
@@ -82,6 +84,9 @@ public:
int scrollWidth();
int scrollHeight();
+ PassRefPtr<ClientRectList> getClientRects() const;
+ PassRefPtr<ClientRect> getBoundingClientRect() const;
+
void removeAttribute(const String& name, ExceptionCode&);
void removeAttributeNS(const String& namespaceURI, const String& localName, ExceptionCode&);
@@ -110,20 +115,18 @@ public:
// DOM methods overridden from parent classes
virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep);
virtual String nodeName() const;
virtual void insertedIntoDocument();
virtual void removedFromDocument();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
- PassRefPtr<Element> cloneElement();
+ PassRefPtr<Element> cloneElementWithChildren();
+ PassRefPtr<Element> cloneElementWithoutChildren();
void normalizeAttributes();
virtual bool isFormControlElement() const { return false; }
virtual bool isFormControlElementWithState() const { return false; }
- virtual bool isInputTypeHidden() const { return false; }
- virtual bool isPasswordField() const { return false; }
String nodeNamePreservingCase() const;
@@ -215,6 +218,10 @@ private:
virtual const AtomicString& virtualLocalName() const { return localName(); }
virtual const AtomicString& virtualNamespaceURI() const { return namespaceURI(); }
+ // cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
+ // are used instead.
+ virtual PassRefPtr<Node> cloneNode(bool deep);
+
QualifiedName m_tagName;
virtual NodeRareData* createRareData();
diff --git a/WebCore/dom/Element.idl b/WebCore/dom/Element.idl
index ae2c1b8..889eaf0 100644
--- a/WebCore/dom/Element.idl
+++ b/WebCore/dom/Element.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -26,7 +26,7 @@ module core {
InlineGetOwnPropertySlot,
InterfaceUUID=FEFE9C21-E58C-4b5b-821A-61A514613763,
ImplementationUUID=12E5B08E-A680-4baf-9D1E-108AEF7ABBFB
- ] Element : EventTargetNode {
+ ] Element : Node {
// DOM Level 1 Core
@@ -104,13 +104,13 @@ module core {
NodeList getElementsByClassName(in DOMString name);
// NodeSelector - Selector API
- Element querySelector(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ Element querySelector(in DOMString selectors)
raises(DOMException);
- NodeList querySelectorAll(in [ConvertUndefinedOrNullToNullString] DOMString selectors)
+ NodeList querySelectorAll(in DOMString selectors)
raises(DOMException);
- // ElementTraversal API
#if !defined(LANGUAGE_COM)
+ // ElementTraversal API
readonly attribute Element firstElementChild;
readonly attribute Element lastElementChild;
readonly attribute Element previousElementSibling;
@@ -118,6 +118,12 @@ module core {
readonly attribute unsigned long childElementCount;
#endif
+#if defined(LANGUAGE_JAVASCRIPT)
+ // CSSOM View Module API
+ ClientRectList getClientRects();
+ ClientRect getBoundingClientRect();
+#endif
+
#if defined(LANGUAGE_OBJECTIVE_C)
// Objective-C extensions
readonly attribute DOMString innerText;
diff --git a/WebCore/dom/EventException.idl b/WebCore/dom/EventException.idl
index 61cfd65..f948078 100644
--- a/WebCore/dom/EventException.idl
+++ b/WebCore/dom/EventException.idl
@@ -30,7 +30,8 @@ module events {
// Introduced in DOM Level 2:
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
] EventException {
readonly attribute unsigned short code;
diff --git a/WebCore/dom/EventListener.h b/WebCore/dom/EventListener.h
index 24fce86..b7daa6d 100644
--- a/WebCore/dom/EventListener.h
+++ b/WebCore/dom/EventListener.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,6 +23,10 @@
#include <wtf/RefCounted.h>
+namespace JSC {
+ class JSObject;
+}
+
namespace WebCore {
class Event;
@@ -31,10 +35,21 @@ namespace WebCore {
public:
virtual ~EventListener() { }
virtual void handleEvent(Event*, bool isWindowEvent = false) = 0;
- virtual bool isInline() const { return false; }
virtual bool wasCreatedFromMarkup() const { return false; }
+
+#if USE(JSC)
+ virtual JSC::JSObject* function() const { return 0; }
+ virtual void mark() { }
+#endif
+
+ bool isInline() const { return virtualIsInline(); }
+
+ private:
+ virtual bool virtualIsInline() const { return false; }
};
+ inline void markIfNotNull(EventListener* listener) { if (listener) listener->mark(); }
+
}
#endif
diff --git a/WebCore/dom/EventListener.idl b/WebCore/dom/EventListener.idl
index 9d28703..9dc2e0a 100644
--- a/WebCore/dom/EventListener.idl
+++ b/WebCore/dom/EventListener.idl
@@ -22,6 +22,7 @@ module events {
// Introduced in DOM Level 2:
interface [
+ NoStaticTables,
ObjCProtocol,
InterfaceUUID=B04F2AE3-71E2-4ebe-ABFE-EF4938354082,
ImplementationUUID=DDFDD342-A78B-4f19-8F32-A5DF51B56E08
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index d6f2314..28a66bc 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -108,24 +108,26 @@ namespace WebCore {
macro(webkitBeforeTextInserted) \
macro(webkitEditableContentChanged) \
\
- macro(canshowcurrentframe) \
macro(canplay) \
macro(canplaythrough) \
- macro(dataunavailable) \
macro(durationchange) \
macro(emptied) \
macro(ended) \
- macro(loadedfirstframe) \
+ macro(loadeddata) \
macro(loadedmetadata) \
macro(pause) \
macro(play) \
+ macro(playing) \
macro(ratechange) \
+ macro(seeked) \
+ macro(seeking) \
macro(timeupdate) \
macro(volumechange) \
macro(waiting) \
\
macro(progress) \
macro(stalled) \
+ macro(suspend) \
\
macro(webkitAnimationEnd) \
macro(webkitAnimationStart) \
diff --git a/WebCore/dom/EventTarget.cpp b/WebCore/dom/EventTarget.cpp
index dcebd64..6717a02 100644
--- a/WebCore/dom/EventTarget.cpp
+++ b/WebCore/dom/EventTarget.cpp
@@ -44,7 +44,7 @@ EventTarget::~EventTarget()
{
}
-EventTargetNode* EventTarget::toNode()
+Node* EventTarget::toNode()
{
return 0;
}
diff --git a/WebCore/dom/EventTarget.h b/WebCore/dom/EventTarget.h
index 3a3ec84..81d2c5a 100644
--- a/WebCore/dom/EventTarget.h
+++ b/WebCore/dom/EventTarget.h
@@ -40,8 +40,8 @@ namespace WebCore {
class DOMApplicationCache;
class Event;
class EventListener;
- class EventTargetNode;
class MessagePort;
+ class Node;
class ScriptExecutionContext;
class SVGElementInstance;
class Worker;
@@ -54,7 +54,7 @@ namespace WebCore {
class EventTarget {
public:
virtual MessagePort* toMessagePort();
- virtual EventTargetNode* toNode();
+ virtual Node* toNode();
virtual XMLHttpRequest* toXMLHttpRequest();
virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
diff --git a/WebCore/dom/EventTarget.idl b/WebCore/dom/EventTarget.idl
index d3f46f7..844dc32 100644
--- a/WebCore/dom/EventTarget.idl
+++ b/WebCore/dom/EventTarget.idl
@@ -26,13 +26,13 @@ module events {
PureInterface,
InterfaceUUID=1D71C7EC-0BA0-4044-BDFD-56B3E8F5F9D4
] EventTarget {
- [OldStyleObjC, EventTargetNodeCast] void addEventListener(in DOMString type,
+ [OldStyleObjC] void addEventListener(in DOMString type,
in EventListener listener,
in boolean useCapture);
- [OldStyleObjC, EventTargetNodeCast] void removeEventListener(in DOMString type,
+ [OldStyleObjC] void removeEventListener(in DOMString type,
in EventListener listener,
in boolean useCapture);
- [EventTargetNodeCast] boolean dispatchEvent(in Event event)
+ boolean dispatchEvent(in Event event)
raises(EventException);
};
diff --git a/WebCore/dom/EventTargetNode.cpp b/WebCore/dom/EventTargetNode.cpp
deleted file mode 100644
index d3d9a32..0000000
--- a/WebCore/dom/EventTargetNode.cpp
+++ /dev/null
@@ -1,1241 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "EventTargetNode.h"
-
-#include "Document.h"
-#include "EventException.h"
-#include "EventHandler.h"
-#include "EventListener.h"
-#include "EventNames.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "KeyboardEvent.h"
-#include "MouseEvent.h"
-#include "MutationEvent.h"
-#include "NodeRareData.h"
-#include "Page.h"
-#include "PlatformMouseEvent.h"
-#include "PlatformWheelEvent.h"
-#include "ProgressEvent.h"
-#include "RegisteredEventListener.h"
-#include "ScriptController.h"
-#include "TextEvent.h"
-#include "WebKitAnimationEvent.h"
-#include "WebKitTransitionEvent.h"
-#include "WheelEvent.h"
-#include <wtf/HashSet.h>
-
-#if ENABLE(DOM_STORAGE)
-#include "StorageEvent.h"
-#endif
-
-#if ENABLE(SVG)
-#include "SVGElementInstance.h"
-#include "SVGUseElement.h"
-#endif
-
-namespace WebCore {
-
-static HashSet<EventTargetNode*>* gNodesDispatchingSimulatedClicks = 0;
-
-EventTargetNode::EventTargetNode(Document* doc, bool isElement, bool isContainer, bool isText)
- : Node(doc, isElement, isContainer, isText)
-{
-}
-
-EventTargetNode::~EventTargetNode()
-{
- if (!eventListeners().isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-}
-
-ScriptExecutionContext* EventTargetNode::scriptExecutionContext() const
-{
- return document();
-}
-
-const RegisteredEventListenerVector& EventTargetNode::eventListeners() const
-{
- if (hasRareData()) {
- if (RegisteredEventListenerVector* listeners = rareData()->listeners())
- return *listeners;
- }
- static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector;
- return *emptyListenersVector;
-}
-
-void EventTargetNode::insertedIntoDocument()
-{
- if (!eventListeners().isEmpty())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- Node::insertedIntoDocument();
-}
-
-void EventTargetNode::removedFromDocument()
-{
- if (!eventListeners().isEmpty())
- document()->registerDisconnectedNodeWithEventListeners(this);
-
- Node::removedFromDocument();
-}
-
-void EventTargetNode::willMoveToNewOwnerDocument()
-{
- if (!eventListeners().isEmpty())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- Node::willMoveToNewOwnerDocument();
-}
-
-void EventTargetNode::didMoveToNewOwnerDocument()
-{
- if (!eventListeners().isEmpty())
- document()->registerDisconnectedNodeWithEventListeners(this);
-
- Node::didMoveToNewOwnerDocument();
-}
-
-static inline void updateSVGElementInstancesAfterEventListenerChange(EventTargetNode* referenceNode)
-{
- ASSERT(referenceNode);
-
-#if ENABLE(SVG)
- if (!referenceNode->isSVGElement())
- return;
-
- // Elements living inside a <use> shadow tree, never cause any updates!
- if (referenceNode->shadowTreeRootNode())
- return;
-
- // We're possibly (a child of) an element that is referenced by a <use> client
- // If an event listeners changes on a referenced element, update all instances.
- for (Node* node = referenceNode; node; node = node->parentNode()) {
- if (!node->hasID() || !node->isSVGElement())
- continue;
-
- SVGElementInstance::invalidateAllInstancesOfElement(static_cast<SVGElement*>(node));
- break;
- }
-#endif
-}
-
-void EventTargetNode::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
- Document* document = this->document();
- if (!document->attached())
- return;
-
- document->addListenerTypeIfNeeded(eventType);
-
- RegisteredEventListenerVector& listeners = ensureRareData()->ensureListeners();
-
- // Remove existing identical listener set with identical arguments.
- // The DOM2 spec says that "duplicate instances are discarded" in this case.
- removeEventListener(eventType, listener.get(), useCapture);
-
- // adding the first one
- if (listeners.isEmpty() && !inDocument())
- document->registerDisconnectedNodeWithEventListeners(this);
-
- listeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
- updateSVGElementInstancesAfterEventListenerChange(this);
-
-#if ENABLE(TOUCH_EVENTS) // Android
- if (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent)
- document->addTouchEventListener(this);
-#endif
-}
-
-void EventTargetNode::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *listeners->at(i);
- if (r.eventType() == eventType && r.listener() == listener && r.useCapture() == useCapture) {
- r.setRemoved(true);
- listeners->remove(i);
-
- // removed last
- if (listeners->isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- updateSVGElementInstancesAfterEventListenerChange(this);
-
-#if ENABLE(TOUCH_EVENTS) // Android
- if (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent)
- document()->removeTouchEventListener(this);
-#endif
- return;
- }
- }
-}
-
-void EventTargetNode::removeAllEventListeners()
-{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
-#if ENABLE(TOUCH_EVENTS) // Android
- document()->removeTouchEventListener(this);
-#endif
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i)
- listeners->at(i)->setRemoved(true);
- listeners->clear();
-}
-
-void EventTargetNode::handleLocalEvents(Event* event, bool useCapture)
-{
- if (disabled() && event->isMouseEvent())
- return;
-
- RegisteredEventListenerVector listenersCopy = eventListeners();
- size_t size = listenersCopy.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listenersCopy[i];
- if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
- r.listener()->handleEvent(event, false);
- }
-}
-
-#if ENABLE(SVG)
-static inline SVGElementInstance* eventTargetAsSVGElementInstance(EventTargetNode* referenceNode)
-{
- ASSERT(referenceNode);
- if (!referenceNode->isSVGElement())
- return 0;
-
- // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
- // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
- for (Node* n = referenceNode; n; n = n->parentNode()) {
- if (!n->isShadowNode() || !n->isSVGElement())
- continue;
-
- Node* shadowTreeParentElement = n->shadowParentNode();
- ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
-
- if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
- return instance;
- }
-
- return 0;
-}
-#endif
-
-static inline EventTarget* eventTargetRespectingSVGTargetRules(EventTargetNode* referenceNode)
-{
- ASSERT(referenceNode);
-
-#if ENABLE(SVG)
- if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) {
- ASSERT(instance->shadowTreeElement() == referenceNode);
- return instance;
- }
-#endif
-
- return referenceNode;
-}
-
-bool EventTargetNode::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
-{
- RefPtr<Event> evt(e);
- ASSERT(!eventDispatchForbidden());
- if (!evt || evt->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return false;
- }
-
- evt->setTarget(eventTargetRespectingSVGTargetRules(this));
-
- RefPtr<FrameView> view = document()->view();
- return dispatchGenericEvent(evt.release());
-}
-
-bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
-{
- RefPtr<Event> event(prpEvent);
-
- ASSERT(!eventDispatchForbidden());
- ASSERT(event->target());
- ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
-
- // Make a vector of ancestors to send the event to.
- // If the node is not in a document just send the event to it.
- // Be sure to ref all of nodes since event handlers could result in the last reference going away.
- RefPtr<EventTargetNode> thisNode(this);
- Vector<RefPtr<ContainerNode> > ancestors;
- if (inDocument()) {
- for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
-#if ENABLE(SVG)
- // Skip <use> shadow tree elements.
- if (ancestor->isSVGElement() && ancestor->isShadowNode())
- continue;
-#endif
- ancestors.append(ancestor);
- }
- }
-
- // Set up a pointer to indicate whether to dispatch window events.
- // We don't dispatch load events to the window. That quirk was originally
- // added because Mozilla doesn't propagate load events to the window object.
- Document* documentForWindowEvents = 0;
- if (event->type() != eventNames().loadEvent) {
- EventTargetNode* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get();
- if (topLevelContainer->isDocumentNode())
- documentForWindowEvents = static_cast<Document*>(topLevelContainer);
- }
-
- // Give the target node a chance to do some work before DOM event handlers get a crack.
- void* data = preDispatchEventHandler(event.get());
- if (event->propagationStopped())
- goto doneDispatching;
-
- // Trigger capturing event handlers, starting at the top and working our way down.
- event->setEventPhase(Event::CAPTURING_PHASE);
-
- if (documentForWindowEvents) {
- event->setCurrentTarget(documentForWindowEvents);
- documentForWindowEvents->handleWindowEvent(event.get(), true);
- if (event->propagationStopped())
- goto doneDispatching;
- }
- for (size_t i = ancestors.size(); i; --i) {
- ContainerNode* ancestor = ancestors[i - 1].get();
- event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
- ancestor->handleLocalEvents(event.get(), true);
- if (event->propagationStopped())
- goto doneDispatching;
- }
-
- event->setEventPhase(Event::AT_TARGET);
-
- // We do want capturing event listeners to be invoked here, even though
- // that violates some versions of the DOM specification; Mozilla does it.
- event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this));
- handleLocalEvents(event.get(), true);
- if (event->propagationStopped())
- goto doneDispatching;
- handleLocalEvents(event.get(), false);
- if (event->propagationStopped())
- goto doneDispatching;
-
- if (event->bubbles() && !event->cancelBubble()) {
- // Trigger bubbling event handlers, starting at the bottom and working our way up.
- event->setEventPhase(Event::BUBBLING_PHASE);
-
- size_t size = ancestors.size();
- for (size_t i = 0; i < size; ++i) {
- ContainerNode* ancestor = ancestors[i].get();
- event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
- ancestor->handleLocalEvents(event.get(), false);
- if (event->propagationStopped() || event->cancelBubble())
- goto doneDispatching;
- }
- if (documentForWindowEvents) {
- event->setCurrentTarget(documentForWindowEvents);
- documentForWindowEvents->handleWindowEvent(event.get(), false);
- if (event->propagationStopped() || event->cancelBubble())
- goto doneDispatching;
- }
- }
-
-doneDispatching:
- event->setCurrentTarget(0);
- event->setEventPhase(0);
-
- // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
- postDispatchEventHandler(event.get(), data);
-
- // Call default event handlers. While the DOM does have a concept of preventing
- // default handling, the detail of which handlers are called is an internal
- // implementation detail and not part of the DOM.
- if (!event->defaultPrevented() && !event->defaultHandled()) {
- // Non-bubbling events call only one default event handler, the one for the target.
- defaultEventHandler(event.get());
- ASSERT(!event->defaultPrevented());
- if (event->defaultHandled())
- goto doneWithDefault;
- // For bubbling events, call default event handlers on the same targets in the
- // same order as the bubbling phase.
- if (event->bubbles()) {
- size_t size = ancestors.size();
- for (size_t i = 0; i < size; ++i) {
- ContainerNode* ancestor = ancestors[i].get();
- ancestor->defaultEventHandler(event.get());
- ASSERT(!event->defaultPrevented());
- if (event->defaultHandled())
- goto doneWithDefault;
- }
- }
- }
-
-doneWithDefault:
- Document::updateDocumentsRendering();
-
- return !event->defaultPrevented();
-}
-
-bool EventTargetNode::dispatchSubtreeModifiedEvent()
-{
- ASSERT(!eventDispatchForbidden());
-
- document()->incDOMTreeVersion();
-
- notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
-
- if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
- return false;
- ExceptionCode ec = 0;
- return dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true, false, 0, String(), String(), String(), 0), ec);
-}
-
-void EventTargetNode::dispatchWindowEvent(PassRefPtr<Event> e)
-{
- ASSERT(!eventDispatchForbidden());
- RefPtr<Event> evt(e);
- RefPtr<Document> doc = document();
- evt->setTarget(doc);
- doc->handleWindowEvent(evt.get(), true);
- doc->handleWindowEvent(evt.get(), false);
-}
-
-void EventTargetNode::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
- ASSERT(!eventDispatchForbidden());
- RefPtr<Document> doc = document();
- dispatchWindowEvent(Event::create(eventType, canBubbleArg, cancelableArg));
-
- if (eventType == eventNames().loadEvent) {
- // For onload events, send a separate load event to the enclosing frame only.
- // This is a DOM extension and is independent of bubbling/capturing rules of
- // the DOM.
- Element* ownerElement = doc->ownerElement();
- if (ownerElement) {
- RefPtr<Event> ownerEvent = Event::create(eventType, false, cancelableArg);
- ownerEvent->setTarget(ownerElement);
- ownerElement->dispatchGenericEvent(ownerEvent.release());
- }
- }
-}
-
-bool EventTargetNode::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
-{
- ASSERT(!eventDispatchForbidden());
- ASSERT(eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent);
-
- bool cancelable = eventType == eventNames().DOMActivateEvent;
-
- ExceptionCode ec = 0;
- RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
- evt->setUnderlyingEvent(underlyingEvent);
- return dispatchEvent(evt.release(), ec);
-}
-
-bool EventTargetNode::dispatchKeyEvent(const PlatformKeyboardEvent& key)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
- bool r = dispatchEvent(keyboardEvent, ec);
-
- // we want to return false if default is prevented (already taken care of)
- // or if the element is default-handled by the DOM. Otherwise we let it just
- // let it get handled by AppKit
- if (keyboardEvent->defaultHandled())
- r = false;
-
- return r;
-}
-
-bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
- int detail, Node* relatedTarget)
-{
- ASSERT(!eventDispatchForbidden());
-
- IntPoint contentsPos;
- if (FrameView* view = document()->view())
- contentsPos = view->windowToContents(event.pos());
-
- short button = event.button();
-
- ASSERT(event.eventType() == MouseEventMoved || button != NoButton);
-
- return dispatchMouseEvent(eventType, button, detail,
- contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(),
- event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
- false, relatedTarget);
-}
-
-void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType,
- PassRefPtr<Event> underlyingEvent)
-{
- ASSERT(!eventDispatchForbidden());
-
- bool ctrlKey = false;
- bool altKey = false;
- bool shiftKey = false;
- bool metaKey = false;
- if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
- ctrlKey = keyStateEvent->ctrlKey();
- altKey = keyStateEvent->altKey();
- shiftKey = keyStateEvent->shiftKey();
- metaKey = keyStateEvent->metaKey();
- }
-
- // Like Gecko, we just pass 0 for everything when we make a fake mouse event.
- // Internet Explorer instead gives the current mouse position and state.
- dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
- ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent);
-}
-
-void EventTargetNode::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
-{
- if (!gNodesDispatchingSimulatedClicks)
- gNodesDispatchingSimulatedClicks = new HashSet<EventTargetNode*>;
- else if (gNodesDispatchingSimulatedClicks->contains(this))
- return;
-
- gNodesDispatchingSimulatedClicks->add(this);
-
- // send mousedown and mouseup before the click, if requested
- if (sendMouseEvents)
- dispatchSimulatedMouseEvent(eventNames().mousedownEvent, event.get());
- setActive(true, showPressedLook);
- if (sendMouseEvents)
- dispatchSimulatedMouseEvent(eventNames().mouseupEvent, event.get());
- setActive(false);
-
- // always send click
- dispatchSimulatedMouseEvent(eventNames().clickEvent, event);
-
- gNodesDispatchingSimulatedClicks->remove(this);
-}
-
-bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int button, int detail,
- int pageX, int pageY, int screenX, int screenY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent)
-{
- ASSERT(!eventDispatchForbidden());
- if (disabled()) // Don't even send DOM events for disabled controls..
- return true;
-
- if (eventType.isEmpty())
- return false; // Shouldn't happen.
-
- // Dispatching the first event can easily result in this node being destroyed.
- // Since we dispatch up to three events here, we need to make sure we're referenced
- // so the pointer will be good for the two subsequent ones.
- RefPtr<Node> protect(this);
-
- bool cancelable = eventType != eventNames().mousemoveEvent;
-
- ExceptionCode ec = 0;
-
- bool swallowEvent = false;
-
- // Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored.
- RefPtr<EventTargetNode> relatedTarget = (relatedTargetArg && relatedTargetArg->isEventTargetNode())
- ? static_cast<EventTargetNode*>(relatedTargetArg) : 0;
-
- if (Frame* frame = document()->frame()) {
- float pageZoom = frame->pageZoomFactor();
- if (pageZoom != 1.0f) {
- // Adjust our pageX and pageY to account for the page zoom.
- pageX = lroundf(pageX / pageZoom);
- pageY = lroundf(pageY / pageZoom);
- }
- }
-
- RefPtr<Event> mouseEvent = MouseEvent::create(eventType,
- true, cancelable, document()->defaultView(),
- detail, screenX, screenY, pageX, pageY,
- ctrlKey, altKey, shiftKey, metaKey, button,
- relatedTarget, 0, isSimulated);
- mouseEvent->setUnderlyingEvent(underlyingEvent.get());
-
- dispatchEvent(mouseEvent, ec);
- bool defaultHandled = mouseEvent->defaultHandled();
- bool defaultPrevented = mouseEvent->defaultPrevented();
- if (defaultHandled || defaultPrevented)
- swallowEvent = true;
-
- // Special case: If it's a double click event, we also send the dblclick event. This is not part
- // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
- // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
- if (eventType == eventNames().clickEvent && detail == 2) {
- RefPtr<Event> doubleClickEvent = MouseEvent::create(eventNames().dblclickEvent,
- true, cancelable, document()->defaultView(),
- detail, screenX, screenY, pageX, pageY,
- ctrlKey, altKey, shiftKey, metaKey, button,
- relatedTarget, 0, isSimulated);
- doubleClickEvent->setUnderlyingEvent(underlyingEvent.get());
- if (defaultHandled)
- doubleClickEvent->setDefaultHandled();
- dispatchEvent(doubleClickEvent, ec);
- if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
- swallowEvent = true;
- }
-
- return swallowEvent;
-}
-
-void EventTargetNode::dispatchWheelEvent(PlatformWheelEvent& e)
-{
- ASSERT(!eventDispatchForbidden());
- if (e.deltaX() == 0 && e.deltaY() == 0)
- return;
-
- FrameView* view = document()->view();
- if (!view)
- return;
-
- IntPoint pos = view->windowToContents(e.pos());
-
- // Convert the deltas from pixels to lines if we have a pixel scroll event.
- float deltaX = e.deltaX();
- float deltaY = e.deltaY();
-
- // FIXME: Should we do anything with a ScrollByPageWheelEvent here?
- // It will be treated like a line scroll of 1 right now.
- if (e.granularity() == ScrollByPixelWheelEvent) {
- deltaX /= cMouseWheelPixelsPerLineStep;
- deltaY /= cMouseWheelPixelsPerLineStep;
- }
-
- RefPtr<WheelEvent> we = WheelEvent::create(e.deltaX(), e.deltaY(),
- document()->defaultView(), e.globalX(), e.globalY(), pos.x(), pos.y(),
- e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
- ExceptionCode ec = 0;
- if (!dispatchEvent(we.release(), ec))
- e.accept();
-}
-
-bool EventTargetNode::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
-{
- ASSERT(!eventDispatchForbidden());
-
- ExceptionCode ec = 0;
- return dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
-}
-
-bool EventTargetNode::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
-{
- ASSERT(!eventDispatchForbidden());
-
- ExceptionCode ec = 0;
- return dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
-}
-
-void EventTargetNode::dispatchFocusEvent()
-{
- dispatchEventForType(eventNames().focusEvent, false, false);
-}
-
-void EventTargetNode::dispatchBlurEvent()
-{
- dispatchEventForType(eventNames().blurEvent, false, false);
-}
-
-bool EventTargetNode::dispatchEventForType(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
-}
-
-bool EventTargetNode::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- return dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
-}
-
-void EventTargetNode::dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source)
-{
-#if ENABLE(DOM_STORAGE)
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- dispatchEvent(StorageEvent::create(eventType, key, oldValue, newValue, source->document()->documentURI(), source->domWindow()), ec);
-#endif
-}
-
-void EventTargetNode::removeInlineEventListenerForType(const AtomicString& eventType)
-{
- if (!hasRareData())
- return;
-
- RegisteredEventListenerVector* listeners = rareData()->listeners();
- if (!listeners)
- return;
-
- size_t size = listeners->size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *listeners->at(i);
- if (r.eventType() != eventType || !r.listener()->isInline())
- continue;
-
- r.setRemoved(true);
- listeners->remove(i);
-
- // removed last
- if (listeners->isEmpty() && !inDocument())
- document()->unregisterDisconnectedNodeWithEventListeners(this);
-
- updateSVGElementInstancesAfterEventListenerChange(this);
- return;
- }
-}
-
-void EventTargetNode::setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
- // In case we are the only one holding a reference to it, we don't want removeInlineEventListenerForType to destroy it.
- removeInlineEventListenerForType(eventType);
- if (listener)
- addEventListener(eventType, listener, false);
-}
-
-void EventTargetNode::setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute* attr)
-{
- setInlineEventListenerForType(eventType, document()->createEventListener(attr->localName().string(), attr->value(), this));
-}
-
-EventListener* EventTargetNode::inlineEventListenerForType(const AtomicString& eventType) const
-{
- const RegisteredEventListenerVector& listeners = eventListeners();
- size_t size = listeners.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listeners[i];
- if (r.eventType() == eventType && r.listener()->isInline())
- return r.listener();
- }
- return 0;
-}
-
-#ifdef ANDROID
-EventListener *EventTargetNode::getEventListener(const AtomicString &eventType)
-{
- const RegisteredEventListenerVector& listeners = eventListeners();
- size_t size = listeners.size();
- for (size_t i = 0; i < size; ++i) {
- const RegisteredEventListener& r = *listeners[i];
- if (r.eventType() == eventType)
- return r.listener();
- }
- return 0;
-}
-#endif
-
-bool EventTargetNode::disabled() const
-{
- return false;
-}
-
-void EventTargetNode::defaultEventHandler(Event* event)
-{
- if (event->target() != this)
- return;
- const AtomicString& eventType = event->type();
- if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
- if (event->isKeyboardEvent())
- if (Frame* frame = document()->frame())
- frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event));
- } else if (eventType == eventNames().clickEvent) {
- int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
- dispatchUIEvent(eventNames().DOMActivateEvent, detail, event);
- } else if (eventType == eventNames().contextmenuEvent) {
- if (Frame* frame = document()->frame())
- if (Page* page = frame->page())
- page->contextMenuController()->handleContextMenuEvent(event);
- } else if (eventType == eventNames().textInputEvent) {
- if (event->isTextEvent())
- if (Frame* frame = document()->frame())
- frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
- }
-}
-
-EventListener* EventTargetNode::onabort() const
-{
- return inlineEventListenerForType(eventNames().abortEvent);
-}
-
-void EventTargetNode::setOnabort(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().abortEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onblur() const
-{
- return inlineEventListenerForType(eventNames().blurEvent);
-}
-
-void EventTargetNode::setOnblur(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().blurEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onchange() const
-{
- return inlineEventListenerForType(eventNames().changeEvent);
-}
-
-void EventTargetNode::setOnchange(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().changeEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onclick() const
-{
- return inlineEventListenerForType(eventNames().clickEvent);
-}
-
-void EventTargetNode::setOnclick(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().clickEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oncontextmenu() const
-{
- return inlineEventListenerForType(eventNames().contextmenuEvent);
-}
-
-void EventTargetNode::setOncontextmenu(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondblclick() const
-{
- return inlineEventListenerForType(eventNames().dblclickEvent);
-}
-
-void EventTargetNode::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onerror() const
-{
- return inlineEventListenerForType(eventNames().errorEvent);
-}
-
-void EventTargetNode::setOnerror(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().errorEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onfocus() const
-{
- return inlineEventListenerForType(eventNames().focusEvent);
-}
-
-void EventTargetNode::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().focusEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oninput() const
-{
- return inlineEventListenerForType(eventNames().inputEvent);
-}
-
-void EventTargetNode::setOninput(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().inputEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onkeydown() const
-{
- return inlineEventListenerForType(eventNames().keydownEvent);
-}
-
-void EventTargetNode::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onkeypress() const
-{
- return inlineEventListenerForType(eventNames().keypressEvent);
-}
-
-void EventTargetNode::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onkeyup() const
-{
- return inlineEventListenerForType(eventNames().keyupEvent);
-}
-
-void EventTargetNode::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onload() const
-{
- return inlineEventListenerForType(eventNames().loadEvent);
-}
-
-void EventTargetNode::setOnload(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().loadEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmousedown() const
-{
- return inlineEventListenerForType(eventNames().mousedownEvent);
-}
-
-void EventTargetNode::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmousemove() const
-{
- return inlineEventListenerForType(eventNames().mousemoveEvent);
-}
-
-void EventTargetNode::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmouseout() const
-{
- return inlineEventListenerForType(eventNames().mouseoutEvent);
-}
-
-void EventTargetNode::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmouseover() const
-{
- return inlineEventListenerForType(eventNames().mouseoverEvent);
-}
-
-void EventTargetNode::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmouseup() const
-{
- return inlineEventListenerForType(eventNames().mouseupEvent);
-}
-
-void EventTargetNode::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onmousewheel() const
-{
- return inlineEventListenerForType(eventNames().mousewheelEvent);
-}
-
-void EventTargetNode::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onbeforecut() const
-{
- return inlineEventListenerForType(eventNames().beforecutEvent);
-}
-
-void EventTargetNode::setOnbeforecut(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().beforecutEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oncut() const
-{
- return inlineEventListenerForType(eventNames().cutEvent);
-}
-
-void EventTargetNode::setOncut(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().cutEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onbeforecopy() const
-{
- return inlineEventListenerForType(eventNames().beforecopyEvent);
-}
-
-void EventTargetNode::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener);
-}
-
-EventListener* EventTargetNode::oncopy() const
-{
- return inlineEventListenerForType(eventNames().copyEvent);
-}
-
-void EventTargetNode::setOncopy(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().copyEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onbeforepaste() const
-{
- return inlineEventListenerForType(eventNames().beforepasteEvent);
-}
-
-void EventTargetNode::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onpaste() const
-{
- return inlineEventListenerForType(eventNames().pasteEvent);
-}
-
-void EventTargetNode::setOnpaste(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().pasteEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragenter() const
-{
- return inlineEventListenerForType(eventNames().dragenterEvent);
-}
-
-void EventTargetNode::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragover() const
-{
- return inlineEventListenerForType(eventNames().dragoverEvent);
-}
-
-void EventTargetNode::setOndragover(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragleave() const
-{
- return inlineEventListenerForType(eventNames().dragleaveEvent);
-}
-
-void EventTargetNode::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondrop() const
-{
- return inlineEventListenerForType(eventNames().dropEvent);
-}
-
-void EventTargetNode::setOndrop(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dropEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragstart() const
-{
- return inlineEventListenerForType(eventNames().dragstartEvent);
-}
-
-void EventTargetNode::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondrag() const
-{
- return inlineEventListenerForType(eventNames().dragEvent);
-}
-
-void EventTargetNode::setOndrag(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ondragend() const
-{
- return inlineEventListenerForType(eventNames().dragendEvent);
-}
-
-void EventTargetNode::setOndragend(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onreset() const
-{
- return inlineEventListenerForType(eventNames().resetEvent);
-}
-
-void EventTargetNode::setOnreset(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().resetEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onresize() const
-{
- return inlineEventListenerForType(eventNames().resizeEvent);
-}
-
-void EventTargetNode::setOnresize(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onscroll() const
-{
- return inlineEventListenerForType(eventNames().scrollEvent);
-}
-
-void EventTargetNode::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onsearch() const
-{
- return inlineEventListenerForType(eventNames().searchEvent);
-}
-
-void EventTargetNode::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().searchEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onselect() const
-{
- return inlineEventListenerForType(eventNames().selectEvent);
-}
-
-void EventTargetNode::setOnselect(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().selectEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onselectstart() const
-{
- return inlineEventListenerForType(eventNames().selectstartEvent);
-}
-
-void EventTargetNode::setOnselectstart(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().selectstartEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onsubmit() const
-{
- return inlineEventListenerForType(eventNames().submitEvent);
-}
-
-void EventTargetNode::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().submitEvent, eventListener);
-}
-
-EventListener* EventTargetNode::onunload() const
-{
- return inlineEventListenerForType(eventNames().unloadEvent);
-}
-
-void EventTargetNode::setOnunload(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().unloadEvent, eventListener);
-}
-
-#if ENABLE(TOUCH_EVENTS) // Android
-EventListener* EventTargetNode::ontouchstart() const
-{
- return inlineEventListenerForType(eventNames().touchstartEvent);
-}
-
-void EventTargetNode::setOntouchstart(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchstartEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ontouchend() const
-{
- return inlineEventListenerForType(eventNames().touchendEvent);
-}
-
-void EventTargetNode::setOntouchend(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchendEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ontouchmove() const
-{
- return inlineEventListenerForType(eventNames().touchmoveEvent);
-}
-
-void EventTargetNode::setOntouchmove(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchmoveEvent, eventListener);
-}
-
-EventListener* EventTargetNode::ontouchcancel() const
-{
- return inlineEventListenerForType(eventNames().touchcancelEvent);
-}
-
-void EventTargetNode::setOntouchcancel(PassRefPtr<EventListener> eventListener)
-{
- setInlineEventListenerForType(eventNames().touchcancelEvent, eventListener);
-}
-
-#endif
-
-} // namespace WebCore
diff --git a/WebCore/dom/EventTargetNode.h b/WebCore/dom/EventTargetNode.h
deleted file mode 100644
index 1814b7b..0000000
--- a/WebCore/dom/EventTargetNode.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef EventTargetNode_h
-#define EventTargetNode_h
-
-#include "EventTarget.h"
-#include "Node.h"
-
-namespace WebCore {
-
-class Attribute;
-class Frame;
-class RegisteredEventListener;
-
-typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
-
-class EventTargetNode : public Node, public EventTarget {
-public:
- EventTargetNode(Document*, bool isElement = false, bool isContainer = false, bool isText = false);
- virtual ~EventTargetNode();
-
- virtual bool isEventTargetNode() const { return true; }
- virtual EventTargetNode* toNode() { return this; }
-
- virtual ScriptExecutionContext* scriptExecutionContext() const;
-
- virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
- void removeAllEventListeners();
-
-#ifdef ANDROID
- EventListener* getEventListener(const AtomicString& eventType);
-#endif
- void setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
- void setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
- void removeInlineEventListenerForType(const AtomicString& eventType);
- bool dispatchEventForType(const AtomicString& eventType, bool canBubble, bool cancelable);
- EventListener* inlineEventListenerForType(const AtomicString& eventType) const;
-
- bool dispatchSubtreeModifiedEvent();
- void dispatchWindowEvent(PassRefPtr<Event>);
- void dispatchWindowEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
- bool dispatchUIEvent(const AtomicString& eventType, int detail = 0, PassRefPtr<Event> underlyingEvent = 0);
- bool dispatchKeyEvent(const PlatformKeyboardEvent&);
- void dispatchWheelEvent(PlatformWheelEvent&);
- bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
- int clickCount = 0, Node* relatedTarget = 0);
- bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
- int pageX, int pageY, int screenX, int screenY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- bool isSimulated = false, Node* relatedTarget = 0, PassRefPtr<Event> underlyingEvent = 0);
- void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent = 0);
- void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
- bool dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
- void dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source);
- bool dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
- bool dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
- bool dispatchGenericEvent(PassRefPtr<Event>);
-
- virtual void handleLocalEvents(Event*, bool useCapture);
-
- virtual void dispatchFocusEvent();
- virtual void dispatchBlurEvent();
-
- virtual void insertedIntoDocument();
- virtual void removedFromDocument();
- virtual void willMoveToNewOwnerDocument();
- virtual void didMoveToNewOwnerDocument();
-
- /**
- * Perform the default action for an event e.g. submitting a form
- */
- virtual void defaultEventHandler(Event*);
-
- /**
- * Used for disabled form elements; if true, prevents mouse events from being dispatched
- * to event listeners, and prevents DOMActivate events from being sent at all.
- */
- virtual bool disabled() const;
-
- const RegisteredEventListenerVector& eventListeners() const;
-
- EventListener* onabort() const;
- void setOnabort(PassRefPtr<EventListener>);
- EventListener* onblur() const;
- void setOnblur(PassRefPtr<EventListener>);
- EventListener* onchange() const;
- void setOnchange(PassRefPtr<EventListener>);
- EventListener* onclick() const;
- void setOnclick(PassRefPtr<EventListener>);
- EventListener* oncontextmenu() const;
- void setOncontextmenu(PassRefPtr<EventListener>);
- EventListener* ondblclick() const;
- void setOndblclick(PassRefPtr<EventListener>);
- EventListener* onerror() const;
- void setOnerror(PassRefPtr<EventListener>);
- EventListener* onfocus() const;
- void setOnfocus(PassRefPtr<EventListener>);
- EventListener* oninput() const;
- void setOninput(PassRefPtr<EventListener>);
- EventListener* onkeydown() const;
- void setOnkeydown(PassRefPtr<EventListener>);
- EventListener* onkeypress() const;
- void setOnkeypress(PassRefPtr<EventListener>);
- EventListener* onkeyup() const;
- void setOnkeyup(PassRefPtr<EventListener>);
- EventListener* onload() const;
- void setOnload(PassRefPtr<EventListener>);
- EventListener* onmousedown() const;
- void setOnmousedown(PassRefPtr<EventListener>);
- EventListener* onmousemove() const;
- void setOnmousemove(PassRefPtr<EventListener>);
- EventListener* onmouseout() const;
- void setOnmouseout(PassRefPtr<EventListener>);
- EventListener* onmouseover() const;
- void setOnmouseover(PassRefPtr<EventListener>);
- EventListener* onmouseup() const;
- void setOnmouseup(PassRefPtr<EventListener>);
- EventListener* onmousewheel() const;
- void setOnmousewheel(PassRefPtr<EventListener>);
- EventListener* onbeforecut() const;
- void setOnbeforecut(PassRefPtr<EventListener>);
- EventListener* oncut() const;
- void setOncut(PassRefPtr<EventListener>);
- EventListener* onbeforecopy() const;
- void setOnbeforecopy(PassRefPtr<EventListener>);
- EventListener* oncopy() const;
- void setOncopy(PassRefPtr<EventListener>);
- EventListener* onbeforepaste() const;
- void setOnbeforepaste(PassRefPtr<EventListener>);
- EventListener* onpaste() const;
- void setOnpaste(PassRefPtr<EventListener>);
- EventListener* ondragenter() const;
- void setOndragenter(PassRefPtr<EventListener>);
- EventListener* ondragover() const;
- void setOndragover(PassRefPtr<EventListener>);
- EventListener* ondragleave() const;
- void setOndragleave(PassRefPtr<EventListener>);
- EventListener* ondrop() const;
- void setOndrop(PassRefPtr<EventListener>);
- EventListener* ondragstart() const;
- void setOndragstart(PassRefPtr<EventListener>);
- EventListener* ondrag() const;
- void setOndrag(PassRefPtr<EventListener>);
- EventListener* ondragend() const;
- void setOndragend(PassRefPtr<EventListener>);
- EventListener* onreset() const;
- void setOnreset(PassRefPtr<EventListener>);
- EventListener* onresize() const;
- void setOnresize(PassRefPtr<EventListener>);
- EventListener* onscroll() const;
- void setOnscroll(PassRefPtr<EventListener>);
- EventListener* onsearch() const;
- void setOnsearch(PassRefPtr<EventListener>);
- EventListener* onselect() const;
- void setOnselect(PassRefPtr<EventListener>);
- EventListener* onselectstart() const;
- void setOnselectstart(PassRefPtr<EventListener>);
- EventListener* onsubmit() const;
- void setOnsubmit(PassRefPtr<EventListener>);
- EventListener* onunload() const;
- void setOnunload(PassRefPtr<EventListener>);
-#if ENABLE(TOUCH_EVENTS) // Android
- EventListener* ontouchstart() const;
- void setOntouchstart(PassRefPtr<EventListener>);
- EventListener* ontouchend() const;
- void setOntouchend(PassRefPtr<EventListener>);
- EventListener* ontouchmove() const;
- void setOntouchmove(PassRefPtr<EventListener>);
- EventListener* ontouchcancel() const;
- void setOntouchcancel(PassRefPtr<EventListener>);
-#endif
-
- using Node::ref;
- using Node::deref;
-
-private:
- virtual void refEventTarget() { ref(); }
- virtual void derefEventTarget() { deref(); }
-};
-
-inline EventTargetNode* EventTargetNodeCast(Node* n)
-{
- ASSERT(n->isEventTargetNode());
- return static_cast<EventTargetNode*>(n);
-}
-
-inline const EventTargetNode* EventTargetNodeCast(const Node* n)
-{
- ASSERT(n->isEventTargetNode());
- return static_cast<const EventTargetNode*>(n);
-}
-
-} // namespace WebCore
-
-#endif // EventTargetNode_h
diff --git a/WebCore/dom/EventTargetNode.idl b/WebCore/dom/EventTargetNode.idl
deleted file mode 100644
index acb2e95..0000000
--- a/WebCore/dom/EventTargetNode.idl
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-module core {
-
- interface [
- CustomPushEventHandlerScope,
- GenerateNativeConverter
- ] EventTargetNode : Node {
- // EventTarget
- attribute [DontEnum, ProtectedListener] EventListener onabort;
- attribute [DontEnum, ProtectedListener] EventListener onblur;
- attribute [DontEnum, ProtectedListener] EventListener onchange;
- attribute [DontEnum, ProtectedListener] EventListener onclick;
- attribute [DontEnum, ProtectedListener] EventListener oncontextmenu;
- attribute [DontEnum, ProtectedListener] EventListener ondblclick;
- attribute [DontEnum, ProtectedListener] EventListener onerror;
- attribute [DontEnum, ProtectedListener] EventListener onfocus;
- attribute [DontEnum, ProtectedListener] EventListener oninput;
- attribute [DontEnum, ProtectedListener] EventListener onkeydown;
- attribute [DontEnum, ProtectedListener] EventListener onkeypress;
- attribute [DontEnum, ProtectedListener] EventListener onkeyup;
- attribute [DontEnum, ProtectedListener] EventListener onload;
- attribute [DontEnum, ProtectedListener] EventListener onmousedown;
- attribute [DontEnum, ProtectedListener] EventListener onmousemove;
- attribute [DontEnum, ProtectedListener] EventListener onmouseout;
- attribute [DontEnum, ProtectedListener] EventListener onmouseover;
- attribute [DontEnum, ProtectedListener] EventListener onmouseup;
- attribute [DontEnum, ProtectedListener] EventListener onmousewheel;
- attribute [DontEnum, ProtectedListener] EventListener onbeforecut;
- attribute [DontEnum, ProtectedListener] EventListener oncut;
- attribute [DontEnum, ProtectedListener] EventListener onbeforecopy;
- attribute [DontEnum, ProtectedListener] EventListener oncopy;
- attribute [DontEnum, ProtectedListener] EventListener onbeforepaste;
- attribute [DontEnum, ProtectedListener] EventListener onpaste;
- attribute [DontEnum, ProtectedListener] EventListener ondragenter;
- attribute [DontEnum, ProtectedListener] EventListener ondragover;
- attribute [DontEnum, ProtectedListener] EventListener ondragleave;
- attribute [DontEnum, ProtectedListener] EventListener ondrop;
- attribute [DontEnum, ProtectedListener] EventListener ondragstart;
- attribute [DontEnum, ProtectedListener] EventListener ondrag;
- attribute [DontEnum, ProtectedListener] EventListener ondragend;
- attribute [DontEnum, ProtectedListener] EventListener onreset;
- attribute [DontEnum, ProtectedListener] EventListener onresize;
- attribute [DontEnum, ProtectedListener] EventListener onscroll;
- attribute [DontEnum, ProtectedListener] EventListener onsearch;
- attribute [DontEnum, ProtectedListener] EventListener onselect;
- attribute [DontEnum, ProtectedListener] EventListener onselectstart;
- attribute [DontEnum, ProtectedListener] EventListener onsubmit;
- attribute [DontEnum, ProtectedListener] EventListener onunload;
-#if ENABLE_TOUCH_EVENTS
- attribute [DontEnum, ProtectedListener] EventListener ontouchstart;
- attribute [DontEnum, ProtectedListener] EventListener ontouchend;
- attribute [DontEnum, ProtectedListener] EventListener ontouchmove;
- attribute [DontEnum, ProtectedListener] EventListener ontouchcancel;
-#endif
-
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- boolean dispatchEvent(in Event event)
- raises(EventException);
- };
-
-}
diff --git a/WebCore/dom/ExceptionCode.cpp b/WebCore/dom/ExceptionCode.cpp
index fa0a7a7..8ce1643 100644
--- a/WebCore/dom/ExceptionCode.cpp
+++ b/WebCore/dom/ExceptionCode.cpp
@@ -71,7 +71,8 @@ static const char* const eventExceptionNames[] = {
};
static const char* const xmlHttpRequestExceptionNames[] = {
- "NETWORK_ERR"
+ "NETWORK_ERR",
+ "ABORT_ERR"
};
#if ENABLE(XPATH)
diff --git a/WebCore/dom/FormControlElement.h b/WebCore/dom/FormControlElement.h
index 881c9fd..dc77ada 100644
--- a/WebCore/dom/FormControlElement.h
+++ b/WebCore/dom/FormControlElement.h
@@ -30,6 +30,10 @@ class FormControlElement {
public:
virtual ~FormControlElement() { }
+ virtual bool isEnabled() const = 0;
+ virtual bool isReadOnlyControl() const = 0;
+ virtual bool isTextControl() const = 0;
+
virtual bool valueMatchesRenderer() const = 0;
virtual void setValueMatchesRenderer(bool value = true) = 0;
diff --git a/WebCore/dom/GenericWorkerTask.h b/WebCore/dom/GenericWorkerTask.h
deleted file mode 100644
index 79fd148..0000000
--- a/WebCore/dom/GenericWorkerTask.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GenericWorkerTask_h
-#define GenericWorkerTask_h
-
-#if ENABLE(WORKERS)
-
-#include "WorkerMessagingProxy.h"
-#include "ScriptExecutionContext.h"
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
- class GenericWorkerTaskBase : public ScriptExecutionContext::Task {
- protected:
- GenericWorkerTaskBase(WorkerMessagingProxy* messagingProxy) : m_messagingProxy(messagingProxy)
- {
- }
-
- bool canPerformTask()
- {
- return !m_messagingProxy->askedToTerminate();
- }
-
- WorkerMessagingProxy* m_messagingProxy;
- };
-
- template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
- class GenericWorkerTask6 : public GenericWorkerTaskBase {
- public:
- typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6);
- typedef GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> GenericWorkerTask;
-
- static PassRefPtr<GenericWorkerTask> create(WorkerMessagingProxy* messagingProxy, Method method, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
- {
- return adoptRef(new GenericWorkerTask(messagingProxy, method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6));
- }
-
- private:
- GenericWorkerTask6(WorkerMessagingProxy* messagingProxy, Method method, const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
- : GenericWorkerTaskBase(messagingProxy)
- , m_method(method)
- , m_parameter1(parameter1)
- , m_parameter2(parameter2)
- , m_parameter3(parameter3)
- , m_parameter4(parameter4)
- , m_parameter5(parameter5)
- , m_parameter6(parameter6)
- {
- }
-
- virtual void performTask(ScriptExecutionContext* context)
- {
- if (!canPerformTask())
- return;
- (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6);
- }
-
- private:
- Method m_method;
- P1 m_parameter1;
- P2 m_parameter2;
- P3 m_parameter3;
- P4 m_parameter4;
- P5 m_parameter5;
- P6 m_parameter6;
- };
-
- template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
- PassRefPtr<GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> > createCallbackTask(
- WorkerMessagingProxy* messagingProxy,
- void (*method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6),
- const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
- {
- return GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6>::create(messagingProxy, method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6);
- }
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
-
-#endif // GenericWorkerTask_h
diff --git a/WebCore/dom/InputElement.cpp b/WebCore/dom/InputElement.cpp
index 47c1a28..6b733cb 100644
--- a/WebCore/dom/InputElement.cpp
+++ b/WebCore/dom/InputElement.cpp
@@ -114,7 +114,7 @@ void InputElement::updateSelectionRange(InputElementData& data, int start, int e
if (!data.inputElement()->isTextField())
return;
- if (RenderTextControl* renderer = static_cast<RenderTextControl*>(data.element()->renderer()))
+ if (RenderTextControl* renderer = toRenderTextControl(data.element()->renderer()))
renderer->setSelectionRange(start, end);
}
@@ -218,7 +218,7 @@ void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, Documen
// Make sure that the text to be inserted will not violate the maxLength.
int oldLength = numGraphemeClusters(data.inputElement()->value().impl());
ASSERT(oldLength <= data.maxLength());
- int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toRange().get()).impl());
+ int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toNormalizedRange().get()).impl());
ASSERT(oldLength >= selectionLength);
int maxNewLength = data.maxLength() - (oldLength - selectionLength);
diff --git a/WebCore/dom/InputElement.h b/WebCore/dom/InputElement.h
index c64f131..40c972f 100644
--- a/WebCore/dom/InputElement.h
+++ b/WebCore/dom/InputElement.h
@@ -36,6 +36,10 @@ class InputElement {
public:
virtual ~InputElement() { }
+ virtual bool isAutofilled() const = 0;
+ virtual bool isChecked() const = 0;
+ virtual bool isIndeterminate() const = 0;
+ virtual bool isInputTypeHidden() const = 0;
virtual bool isPasswordField() const = 0;
virtual bool isSearchField() const = 0;
virtual bool isTextField() const = 0;
diff --git a/WebCore/dom/MessagePort.cpp b/WebCore/dom/MessagePort.cpp
index 0607bea..312a1f3 100644
--- a/WebCore/dom/MessagePort.cpp
+++ b/WebCore/dom/MessagePort.cpp
@@ -137,6 +137,7 @@ void MessagePort::postMessage(const String& message, MessagePort* dataPort, Exce
ec = INVALID_ACCESS_ERR;
return;
}
+ ec = 0;
newMessagePort = dataPort->clone(ec);
if (ec)
return;
diff --git a/WebCore/dom/MouseEvent.cpp b/WebCore/dom/MouseEvent.cpp
index 1c97522..bdd39d3 100644
--- a/WebCore/dom/MouseEvent.cpp
+++ b/WebCore/dom/MouseEvent.cpp
@@ -36,7 +36,7 @@ MouseEvent::MouseEvent()
MouseEvent::MouseEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
int detail, int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTargetNode> relatedTarget,
+ unsigned short button, PassRefPtr<EventTarget> relatedTarget,
PassRefPtr<Clipboard> clipboard, bool isSimulated)
: MouseRelatedEvent(eventType, canBubble, cancelable, view, detail, screenX, screenY,
pageX, pageY, ctrlKey, altKey, shiftKey, metaKey, isSimulated)
@@ -54,7 +54,7 @@ MouseEvent::~MouseEvent()
void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
int detail, int screenX, int screenY, int clientX, int clientY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTargetNode> relatedTarget)
+ unsigned short button, PassRefPtr<EventTarget> relatedTarget)
{
if (dispatched())
return;
@@ -101,7 +101,7 @@ Node* MouseEvent::toElement() const
{
// MSIE extension - "the object toward which the user is moving the mouse pointer"
if (type() == eventNames().mouseoutEvent)
- return relatedTarget();
+ return relatedTarget() ? relatedTarget()->toNode() : 0;
return target() ? target()->toNode() : 0;
}
@@ -110,7 +110,7 @@ Node* MouseEvent::fromElement() const
{
// MSIE extension - "object from which activation or the mouse pointer is exiting during the event" (huh?)
if (type() != eventNames().mouseoutEvent)
- return relatedTarget();
+ return relatedTarget() ? relatedTarget()->toNode() : 0;
return target() ? target()->toNode() : 0;
}
diff --git a/WebCore/dom/MouseEvent.h b/WebCore/dom/MouseEvent.h
index aa3eee5..7454b04 100644
--- a/WebCore/dom/MouseEvent.h
+++ b/WebCore/dom/MouseEvent.h
@@ -25,7 +25,6 @@
#define MouseEvent_h
#include "Clipboard.h"
-#include "EventTargetNode.h"
#include "MouseRelatedEvent.h"
namespace WebCore {
@@ -40,7 +39,7 @@ namespace WebCore {
static PassRefPtr<MouseEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
int detail, int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTargetNode> relatedTarget, PassRefPtr<Clipboard> clipboard = 0, bool isSimulated = false)
+ PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard = 0, bool isSimulated = false)
{
return adoptRef(new MouseEvent(type, canBubble, cancelable, view, detail, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, clipboard, isSimulated));
@@ -50,13 +49,13 @@ namespace WebCore {
void initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
int detail, int screenX, int screenY, int clientX, int clientY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTargetNode> relatedTarget);
+ unsigned short button, PassRefPtr<EventTarget> relatedTarget);
// WinIE uses 1,4,2 for left/middle/right but not for click (just for mousedown/up, maybe others),
// but we will match the standard DOM.
unsigned short button() const { return m_button; }
bool buttonDown() const { return m_buttonDown; }
- EventTargetNode* relatedTarget() const { return m_relatedTarget.get(); }
+ EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
Clipboard* clipboard() const { return m_clipboard.get(); }
@@ -74,11 +73,11 @@ namespace WebCore {
MouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
int detail, int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTargetNode> relatedTarget, PassRefPtr<Clipboard> clipboard, bool isSimulated);
+ PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard, bool isSimulated);
unsigned short m_button;
bool m_buttonDown;
- RefPtr<EventTargetNode> m_relatedTarget;
+ RefPtr<EventTarget> m_relatedTarget;
RefPtr<Clipboard> m_clipboard;
};
diff --git a/WebCore/dom/MouseRelatedEvent.cpp b/WebCore/dom/MouseRelatedEvent.cpp
index a69c8a7..c66b0a8 100644
--- a/WebCore/dom/MouseRelatedEvent.cpp
+++ b/WebCore/dom/MouseRelatedEvent.cpp
@@ -97,6 +97,8 @@ void MouseRelatedEvent::initCoordinates()
m_layerY = m_pageY;
m_offsetX = m_pageX;
m_offsetY = m_pageY;
+
+ computePageLocation();
}
void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
@@ -112,6 +114,14 @@ void MouseRelatedEvent::initCoordinates(int clientX, int clientY)
m_layerY = m_pageY;
m_offsetX = m_pageX;
m_offsetY = m_pageY;
+
+ computePageLocation();
+}
+
+void MouseRelatedEvent::computePageLocation()
+{
+ float zoomFactor = (view() && view()->frame()) ? view()->frame()->pageZoomFactor() : 1.0f;
+ setAbsoluteLocation(roundedIntPoint(FloatPoint(pageX() * zoomFactor, pageY() * zoomFactor)));
}
void MouseRelatedEvent::receivedTarget()
@@ -133,9 +143,10 @@ void MouseRelatedEvent::receivedTarget()
// Adjust offsetX/Y to be relative to the target's position.
if (!isSimulated()) {
if (RenderObject* r = targ->renderer()) {
- FloatPoint absPos = r->absoluteToLocal(FloatPoint(m_pageX, m_pageY), false, true);
- m_offsetX = absPos.x();
- m_offsetY = absPos.y();
+ FloatPoint localPos = r->absoluteToLocal(absoluteLocation(), false, true);
+ float zoomFactor = (view() && view()->frame()) ? view()->frame()->pageZoomFactor() : 1.0f;
+ m_offsetX = lroundf(localPos.x() / zoomFactor);
+ m_offsetY = lroundf(localPos.y() / zoomFactor);
}
}
@@ -151,8 +162,8 @@ void MouseRelatedEvent::receivedTarget()
RenderLayer* layer = n->renderer()->enclosingLayer();
layer->updateLayerPosition();
for (; layer; layer = layer->parent()) {
- m_layerX -= layer->xPos();
- m_layerY -= layer->yPos();
+ m_layerX -= layer->x();
+ m_layerY -= layer->y();
}
}
}
diff --git a/WebCore/dom/MouseRelatedEvent.h b/WebCore/dom/MouseRelatedEvent.h
index 35c65dd..7649aa9 100644
--- a/WebCore/dom/MouseRelatedEvent.h
+++ b/WebCore/dom/MouseRelatedEvent.h
@@ -26,6 +26,7 @@
#ifndef MouseRelatedEvent_h
#define MouseRelatedEvent_h
+#include "IntPoint.h"
#include "UIEventWithKeyState.h"
namespace WebCore {
@@ -33,6 +34,8 @@ namespace WebCore {
// Internal only: Helper class for what's common between mouse and wheel events.
class MouseRelatedEvent : public UIEventWithKeyState {
public:
+ // Note that these values are adjusted to counter the effects of zoom, so that values
+ // exposed via DOM APIs are invariant under zooming.
int screenX() const { return m_screenX; }
int screenY() const { return m_screenY; }
int clientX() const { return m_clientX; }
@@ -46,6 +49,11 @@ namespace WebCore {
virtual int pageY() const;
int x() const;
int y() const;
+
+ // Page point in "absolute" coordinates (i.e. post-zoomed, page-relative coords,
+ // usable with RenderObject::absoluteToLocal).
+ IntPoint absoluteLocation() const { return m_absoluteLocation; }
+ void setAbsoluteLocation(const IntPoint& p) { m_absoluteLocation = p; }
protected:
MouseRelatedEvent();
@@ -56,6 +64,8 @@ namespace WebCore {
void initCoordinates();
void initCoordinates(int clientX, int clientY);
virtual void receivedTarget();
+
+ void computePageLocation();
// Expose these so MouseEvent::initMouseEvent can set them.
int m_screenX;
@@ -70,6 +80,7 @@ namespace WebCore {
int m_layerY;
int m_offsetX;
int m_offsetY;
+ IntPoint m_absoluteLocation;
bool m_isSimulated;
};
diff --git a/WebCore/dom/NamedAttrMap.cpp b/WebCore/dom/NamedAttrMap.cpp
index 8944b79..33c60d3 100644
--- a/WebCore/dom/NamedAttrMap.cpp
+++ b/WebCore/dom/NamedAttrMap.cpp
@@ -3,7 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* (C) 2007 Eric Seidel (eric@webkit.org)
*
* This library is free software; you can redistribute it and/or
@@ -39,9 +39,18 @@ static inline bool shouldIgnoreAttributeCase(const Element* e)
return e && e->document()->isHTMLDocument() && e->isHTMLElement();
}
+inline void NamedAttrMap::detachAttributesFromElement()
+{
+ size_t size = m_attributes.size();
+ for (size_t i = 0; i < size; i++) {
+ if (Attr* attr = m_attributes[i]->attr())
+ attr->m_element = 0;
+ }
+}
+
NamedAttrMap::~NamedAttrMap()
{
- NamedAttrMap::clearAttributes(); // virtual function, qualify to be explicit and slightly faster
+ detachAttributesFromElement();
}
bool NamedAttrMap::isMappedAttributeMap() const
@@ -190,11 +199,7 @@ Attribute* NamedAttrMap::getAttributeItem(const QualifiedName& name) const
void NamedAttrMap::clearAttributes()
{
- unsigned len = length();
- for (unsigned i = 0; i < len; i++)
- if (Attr* attr = m_attributes[i]->attr())
- attr->m_element = 0;
-
+ detachAttributesFromElement();
m_attributes.clear();
}
@@ -203,7 +208,7 @@ void NamedAttrMap::detachFromElement()
// we allow a NamedAttrMap w/o an element in case someone still has a reference
// to if after the element gets deleted - but the map is now invalid
m_element = 0;
- clearAttributes();
+ detachAttributesFromElement();
}
void NamedAttrMap::setAttributes(const NamedAttrMap& other)
@@ -310,4 +315,9 @@ bool NamedAttrMap::mapsEquivalent(const NamedAttrMap* otherMap) const
return true;
}
+size_t NamedAttrMap::virtualLength() const
+{
+ return length();
+}
+
}
diff --git a/WebCore/dom/NamedAttrMap.h b/WebCore/dom/NamedAttrMap.h
index 693a9e5..61628e4 100644
--- a/WebCore/dom/NamedAttrMap.h
+++ b/WebCore/dom/NamedAttrMap.h
@@ -1,11 +1,9 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,7 +27,6 @@
#include "Attribute.h"
#include "NamedNodeMap.h"
-#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#ifdef __OBJC__
@@ -50,28 +47,12 @@ public:
void setAttributes(const NamedAttrMap&);
- // DOM methods & attributes for NamedNodeMap
-
- virtual PassRefPtr<Node> getNamedItem(const String& name) const;
- virtual PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
-
- virtual PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
- virtual PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
-
- virtual PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
- virtual PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
- virtual PassRefPtr<Node> setNamedItem(Node* arg, ExceptionCode&);
-
- virtual PassRefPtr<Node> item(unsigned index) const;
size_t length() const { return m_attributes.size(); }
-
- // Other methods (not part of DOM)
Attribute* attributeItem(unsigned index) const { return m_attributes[index].get(); }
- Attribute* getAttributeItem(const QualifiedName& name) const;
- Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
-
+ Attribute* getAttributeItem(const QualifiedName&) const;
+
void shrinkToLength() { m_attributes.shrinkCapacity(length()); }
- void reserveCapacity(unsigned capacity) { m_attributes.reserveCapacity(capacity); }
+ void reserveInitialCapacity(unsigned capacity) { m_attributes.reserveInitialCapacity(capacity); }
// used during parsing: only inserts if not already there
// no error checking!
@@ -83,20 +64,38 @@ public:
}
virtual bool isMappedAttributeMap() const;
-
- const AtomicString& id() const { return m_id; }
- void setID(const AtomicString& _id) { m_id = _id; }
+ const AtomicString& id() const { return m_id; }
+ void setID(const AtomicString& newId) { m_id = newId; }
+
bool mapsEquivalent(const NamedAttrMap* otherMap) const;
- // These functions are internal, and do no error checking.
+ // These functions do no error checking.
void addAttribute(PassRefPtr<Attribute>);
- void removeAttribute(const QualifiedName& name);
+ void removeAttribute(const QualifiedName&);
protected:
virtual void clearAttributes();
+ Element* element() const { return m_element; }
+
+private:
+ void detachAttributesFromElement();
void detachFromElement();
+ Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
+
+ virtual PassRefPtr<Node> getNamedItem(const String& name) const;
+ virtual PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
+
+ virtual PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
+ virtual PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
+
+ virtual PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
+ virtual PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
+ virtual PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&);
+
+ virtual PassRefPtr<Node> item(unsigned index) const;
+ virtual size_t virtualLength() const;
Element* m_element;
Vector<RefPtr<Attribute> > m_attributes;
diff --git a/WebCore/dom/NamedMappedAttrMap.cpp b/WebCore/dom/NamedMappedAttrMap.cpp
index bc2d999..cff4997 100644
--- a/WebCore/dom/NamedMappedAttrMap.cpp
+++ b/WebCore/dom/NamedMappedAttrMap.cpp
@@ -75,12 +75,12 @@ bool NamedMappedAttrMap::mapsEquivalent(const NamedMappedAttrMap* otherMap) cons
void NamedMappedAttrMap::setClass(const String& classStr)
{
- if (!m_element->hasClass()) {
+ if (!element()->hasClass()) {
m_classNames.clear();
return;
}
- m_classNames.set(classStr, m_element->document()->inCompatMode());
+ m_classNames.set(classStr, element()->document()->inCompatMode());
}
}
diff --git a/WebCore/dom/NamedMappedAttrMap.h b/WebCore/dom/NamedMappedAttrMap.h
index c4deddc..9267f89 100644
--- a/WebCore/dom/NamedMappedAttrMap.h
+++ b/WebCore/dom/NamedMappedAttrMap.h
@@ -4,7 +4,7 @@
* (C) 2001 Peter Kelly (pmk@post.com)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* (C) 2007 David Smith (catfish.man@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,32 +27,33 @@
#define NamedMappedAttrMap_h
#include "ClassNames.h"
-#include "MappedAttribute.h"
+#include "MappedAttribute.h" // This header is not required for the NamedMappedAttrMap definition. Should remove it.
#include "NamedAttrMap.h"
namespace WebCore {
class NamedMappedAttrMap : public NamedAttrMap {
-private:
- NamedMappedAttrMap(Element* element) : NamedAttrMap(element), m_mappedAttributeCount(0) { }
public:
static PassRefPtr<NamedMappedAttrMap> create(Element* element = 0) { return adoptRef(new NamedMappedAttrMap(element)); }
- virtual void clearAttributes();
- virtual bool isMappedAttributeMap() const;
-
void clearClass() { m_classNames.clear(); }
void setClass(const String&);
const ClassNames& classNames() const { return m_classNames; }
- virtual bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
+ bool hasMappedAttributes() const { return m_mappedAttributeCount > 0; }
void declRemoved() { m_mappedAttributeCount--; }
void declAdded() { m_mappedAttributeCount++; }
-
+
bool mapsEquivalent(const NamedMappedAttrMap*) const;
- int declCount() const;
private:
+ NamedMappedAttrMap(Element* element) : NamedAttrMap(element), m_mappedAttributeCount(0) { }
+
+ virtual void clearAttributes();
+ virtual bool isMappedAttributeMap() const;
+
+ int declCount() const;
+
ClassNames m_classNames;
int m_mappedAttributeCount;
};
diff --git a/WebCore/dom/NamedNodeMap.h b/WebCore/dom/NamedNodeMap.h
index 504af69..08e6efb 100644
--- a/WebCore/dom/NamedNodeMap.h
+++ b/WebCore/dom/NamedNodeMap.h
@@ -56,7 +56,10 @@ public:
virtual PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&) = 0;
virtual PassRefPtr<Node> item(unsigned index) const = 0;
- virtual size_t length() const = 0;
+ size_t length() const { return virtualLength(); }
+
+private:
+ virtual size_t virtualLength() const = 0;
};
} //namespace
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index eb591a7..bd8f497 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
@@ -44,25 +44,55 @@
#include "Document.h"
#include "DynamicNodeList.h"
#include "Element.h"
+#include "Event.h"
+#include "EventException.h"
+#include "EventHandler.h"
+#include "EventListener.h"
+#include "EventNames.h"
#include "ExceptionCode.h"
#include "Frame.h"
+#include "FrameView.h"
#include "HTMLNames.h"
#include "JSDOMBinding.h"
+#include "KeyboardEvent.h"
#include "Logging.h"
+#include "MouseEvent.h"
+#include "MutationEvent.h"
#include "NameNodeList.h"
#include "NamedAttrMap.h"
#include "NodeRareData.h"
+#include "Page.h"
+#include "PlatformMouseEvent.h"
+#include "PlatformWheelEvent.h"
#include "ProcessingInstruction.h"
+#include "ProgressEvent.h"
+#include "RegisteredEventListener.h"
#include "RenderObject.h"
#include "ScriptController.h"
#include "SelectorNodeList.h"
#include "StringBuilder.h"
#include "TagNodeList.h"
#include "Text.h"
+#include "TextEvent.h"
+#include "UIEvent.h"
+#include "UIEventWithKeyState.h"
+#include "WebKitAnimationEvent.h"
+#include "WebKitTransitionEvent.h"
+#include "WheelEvent.h"
#include "XMLNames.h"
#include "htmlediting.h"
+#include <wtf/HashSet.h>
#include <wtf/RefCountedLeakCounter.h>
+#if ENABLE(DOM_STORAGE)
+#include "StorageEvent.h"
+#endif
+
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+#include "SVGUseElement.h"
+#endif
+
#define DUMP_NODE_STATISTICS 0
using namespace std;
@@ -71,6 +101,8 @@ namespace WebCore {
using namespace HTMLNames;
+static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
+
bool Node::isSupported(const String& feature, const String& version)
{
return DOMImplementation::hasFeature(feature, version);
@@ -255,9 +287,9 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
// style in cases where you need to.
StyleChange ch = NoInherit;
EDisplay display1 = s1 ? s1->display() : NONE;
- bool fl1 = s1 && s1->hasPseudoStyle(RenderStyle::FIRST_LETTER);
+ bool fl1 = s1 && s1->hasPseudoStyle(FIRST_LETTER);
EDisplay display2 = s2 ? s2->display() : NONE;
- bool fl2 = s2 && s2->hasPseudoStyle(RenderStyle::FIRST_LETTER);
+ bool fl2 = s2 && s2->hasPseudoStyle(FIRST_LETTER);
if (display1 != display2 || fl1 != fl2 || (s1 && s2 && !s1->contentDataEquivalent(s2)))
ch = Detach;
@@ -270,21 +302,21 @@ Node::StyleChange Node::diff( RenderStyle *s1, RenderStyle *s2 )
// If the pseudoStyles have changed, we want any StyleChange that is not NoChange
// because setStyle will do the right thing with anything else.
- if (ch == NoChange && s1->hasPseudoStyle(RenderStyle::BEFORE)) {
- RenderStyle* ps2 = s2->getCachedPseudoStyle(RenderStyle::BEFORE);
+ if (ch == NoChange && s1->hasPseudoStyle(BEFORE)) {
+ RenderStyle* ps2 = s2->getCachedPseudoStyle(BEFORE);
if (!ps2)
ch = NoInherit;
else {
- RenderStyle* ps1 = s1->getCachedPseudoStyle(RenderStyle::BEFORE);
+ RenderStyle* ps1 = s1->getCachedPseudoStyle(BEFORE);
ch = ps1 && *ps1 == *ps2 ? NoChange : NoInherit;
}
}
- if (ch == NoChange && s1->hasPseudoStyle(RenderStyle::AFTER)) {
- RenderStyle* ps2 = s2->getCachedPseudoStyle(RenderStyle::AFTER);
+ if (ch == NoChange && s1->hasPseudoStyle(AFTER)) {
+ RenderStyle* ps2 = s2->getCachedPseudoStyle(AFTER);
if (!ps2)
ch = NoInherit;
else {
- RenderStyle* ps1 = s1->getCachedPseudoStyle(RenderStyle::AFTER);
+ RenderStyle* ps1 = s1->getCachedPseudoStyle(AFTER);
ch = ps2 && *ps1 == *ps2 ? NoChange : NoInherit;
}
}
@@ -348,6 +380,9 @@ Node::~Node()
liveNodeSet.remove(this);
#endif
+ if (!eventListeners().isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
if (!hasRareData())
ASSERT(!NodeRareData::rareDataMap().contains(this));
else {
@@ -583,7 +618,12 @@ bool Node::shouldUseInputMethod() const
RenderBox* Node::renderBox() const
{
- return m_renderer && m_renderer->isBox() ? static_cast<RenderBox*>(m_renderer) : 0;
+ return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0;
+}
+
+RenderBoxModelObject* Node::renderBoxModelObject() const
+{
+ return m_renderer && m_renderer->isBoxModelObject() ? toRenderBoxModelObject(m_renderer) : 0;
}
IntRect Node::getRect() const
@@ -1081,21 +1121,6 @@ void Node::detach()
m_inDetach = false;
}
-void Node::insertedIntoDocument()
-{
- setInDocument(true);
- insertedIntoTree(false);
-}
-
-void Node::removedFromDocument()
-{
- if (m_document && m_document->getCSSTarget() == this)
- m_document->setCSSTarget(0);
-
- setInDocument(false);
- removedFromTree(false);
-}
-
Node *Node::previousEditable() const
{
Node *node = previousLeafNode();
@@ -1317,7 +1342,7 @@ bool Node::isBlockFlow() const
bool Node::isBlockFlowOrBlockTable() const
{
- return renderer() && (renderer()->isBlockFlow() || renderer()->isTable() && !renderer()->isInline());
+ return renderer() && (renderer()->isBlockFlow() || (renderer()->isTable() && !renderer()->isInline()));
}
bool Node::isEditableBlock() const
@@ -1984,6 +2009,36 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS;
}
+FloatPoint Node::convertToPage(const FloatPoint& p) const
+{
+ // If there is a renderer, just ask it to do the conversion
+ if (renderer())
+ return renderer()->localToAbsolute(p, false, true);
+
+ // Otherwise go up the tree looking for a renderer
+ Element *parent = ancestorElement();
+ if (parent)
+ return parent->convertToPage(p);
+
+ // No parent - no conversion needed
+ return p;
+}
+
+FloatPoint Node::convertFromPage(const FloatPoint& p) const
+{
+ // If there is a renderer, just ask it to do the conversion
+ if (renderer())
+ return renderer()->absoluteToLocal(p, false, true);
+
+ // Otherwise go up the tree looking for a renderer
+ Element *parent = ancestorElement();
+ if (parent)
+ return parent->convertFromPage(p);
+
+ // No parent - no conversion needed
+ return p;
+}
+
#if !defined(NDEBUG) || defined(ANDROID_DOM_LOGGING)
static void appendAttributeDesc(const Node* node, String& string, const QualifiedName& name, const char* attrDesc)
@@ -2177,6 +2232,1157 @@ size_t Node::reportDOMNodesSize()
// --------
+ScriptExecutionContext* Node::scriptExecutionContext() const
+{
+ return document();
+}
+
+const RegisteredEventListenerVector& Node::eventListeners() const
+{
+ if (hasRareData()) {
+ if (RegisteredEventListenerVector* listeners = rareData()->listeners())
+ return *listeners;
+ }
+ static const RegisteredEventListenerVector* emptyListenersVector = new RegisteredEventListenerVector;
+ return *emptyListenersVector;
+}
+
+void Node::insertedIntoDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ setInDocument(true);
+}
+
+void Node::removedFromDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->registerDisconnectedNodeWithEventListeners(this);
+
+ setInDocument(false);
+}
+
+void Node::willMoveToNewOwnerDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+}
+
+void Node::didMoveToNewOwnerDocument()
+{
+ if (!eventListeners().isEmpty())
+ document()->registerDisconnectedNodeWithEventListeners(this);
+}
+
+static inline void updateSVGElementInstancesAfterEventListenerChange(Node* referenceNode)
+{
+ ASSERT(referenceNode);
+
+#if ENABLE(SVG)
+ if (!referenceNode->isSVGElement())
+ return;
+
+ // Elements living inside a <use> shadow tree, never cause any updates!
+ if (referenceNode->shadowTreeRootNode())
+ return;
+
+ // We're possibly (a child of) an element that is referenced by a <use> client
+ // If an event listeners changes on a referenced element, update all instances.
+ for (Node* node = referenceNode; node; node = node->parentNode()) {
+ if (!node->hasID() || !node->isSVGElement())
+ continue;
+
+ SVGElementInstance::invalidateAllInstancesOfElement(static_cast<SVGElement*>(node));
+ break;
+ }
+#endif
+}
+
+void Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+ Document* document = this->document();
+ if (!document->attached())
+ return;
+
+ document->addListenerTypeIfNeeded(eventType);
+
+ RegisteredEventListenerVector& listeners = ensureRareData()->ensureListeners();
+
+ // Remove existing identical listener set with identical arguments.
+ // The DOM2 spec says that "duplicate instances are discarded" in this case.
+ removeEventListener(eventType, listener.get(), useCapture);
+
+ // adding the first one
+ if (listeners.isEmpty() && !inDocument())
+ document->registerDisconnectedNodeWithEventListeners(this);
+
+ listeners.append(RegisteredEventListener::create(eventType, listener, useCapture));
+ updateSVGElementInstancesAfterEventListenerChange(this);
+
+#if ENABLE(TOUCH_EVENTS) // Android
+ if (eventType == eventNames().touchstartEvent ||
+ eventType == eventNames().touchendEvent ||
+ eventType == eventNames().touchmoveEvent ||
+ eventType == eventNames().touchcancelEvent)
+ document->addTouchEventListener(this);
+#endif
+}
+
+void Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+{
+ if (!hasRareData())
+ return;
+
+ RegisteredEventListenerVector* listeners = rareData()->listeners();
+ if (!listeners)
+ return;
+
+ size_t size = listeners->size();
+ for (size_t i = 0; i < size; ++i) {
+ RegisteredEventListener& r = *listeners->at(i);
+ if (r.eventType() == eventType && r.listener() == listener && r.useCapture() == useCapture) {
+ r.setRemoved(true);
+ listeners->remove(i);
+
+ // removed last
+ if (listeners->isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ updateSVGElementInstancesAfterEventListenerChange(this);
+#if ENABLE(TOUCH_EVENTS) // Android
+ if (eventType == eventNames().touchstartEvent ||
+ eventType == eventNames().touchendEvent ||
+ eventType == eventNames().touchmoveEvent ||
+ eventType == eventNames().touchcancelEvent)
+ document()->removeTouchEventListener(this);
+#endif
+ return;
+ }
+ }
+}
+
+void Node::removeAllEventListenersSlowCase()
+{
+ ASSERT(hasRareData());
+
+ RegisteredEventListenerVector* listeners = rareData()->listeners();
+ if (!listeners)
+ return;
+
+#if ENABLE(TOUCH_EVENTS) // Android
+ document()->removeTouchEventListener(this);
+#endif
+
+ size_t size = listeners->size();
+ for (size_t i = 0; i < size; ++i)
+ listeners->at(i)->setRemoved(true);
+ listeners->clear();
+}
+
+void Node::handleLocalEvents(Event* event, bool useCapture)
+{
+ if (disabled() && event->isMouseEvent())
+ return;
+
+ RegisteredEventListenerVector listenersCopy = eventListeners();
+ size_t size = listenersCopy.size();
+ for (size_t i = 0; i < size; ++i) {
+ const RegisteredEventListener& r = *listenersCopy[i];
+ if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
+ r.listener()->handleEvent(event, false);
+ }
+}
+
+#if ENABLE(SVG)
+static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenceNode)
+{
+ ASSERT(referenceNode);
+ if (!referenceNode->isSVGElement())
+ return 0;
+
+ // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
+ // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
+ for (Node* n = referenceNode; n; n = n->parentNode()) {
+ if (!n->isShadowNode() || !n->isSVGElement())
+ continue;
+
+ Node* shadowTreeParentElement = n->shadowParentNode();
+ ASSERT(shadowTreeParentElement->hasTagName(SVGNames::useTag));
+
+ if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
+ return instance;
+ }
+
+ return 0;
+}
+#endif
+
+static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode)
+{
+ ASSERT(referenceNode);
+
+#if ENABLE(SVG)
+ if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) {
+ ASSERT(instance->shadowTreeElement() == referenceNode);
+ return instance;
+ }
+#endif
+
+ return referenceNode;
+}
+
+bool Node::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
+{
+ RefPtr<Event> evt(e);
+ ASSERT(!eventDispatchForbidden());
+ if (!evt || evt->type().isEmpty()) {
+ ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
+ return false;
+ }
+
+ evt->setTarget(eventTargetRespectingSVGTargetRules(this));
+
+ RefPtr<FrameView> view = document()->view();
+ return dispatchGenericEvent(evt.release());
+}
+
+bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
+{
+ RefPtr<Event> event(prpEvent);
+
+ ASSERT(!eventDispatchForbidden());
+ ASSERT(event->target());
+ ASSERT(!event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
+
+ // Make a vector of ancestors to send the event to.
+ // If the node is not in a document just send the event to it.
+ // Be sure to ref all of nodes since event handlers could result in the last reference going away.
+ RefPtr<Node> thisNode(this);
+ Vector<RefPtr<ContainerNode> > ancestors;
+ if (inDocument()) {
+ for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
+#if ENABLE(SVG)
+ // Skip <use> shadow tree elements.
+ if (ancestor->isSVGElement() && ancestor->isShadowNode())
+ continue;
+#endif
+ ancestors.append(ancestor);
+ }
+ }
+
+ // Set up a pointer to indicate whether to dispatch window events.
+ // We don't dispatch load events to the window. That quirk was originally
+ // added because Mozilla doesn't propagate load events to the window object.
+ Document* documentForWindowEvents = 0;
+ if (event->type() != eventNames().loadEvent) {
+ Node* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get();
+ if (topLevelContainer->isDocumentNode())
+ documentForWindowEvents = static_cast<Document*>(topLevelContainer);
+ }
+
+ // Give the target node a chance to do some work before DOM event handlers get a crack.
+ void* data = preDispatchEventHandler(event.get());
+ if (event->propagationStopped())
+ goto doneDispatching;
+
+ // Trigger capturing event handlers, starting at the top and working our way down.
+ event->setEventPhase(Event::CAPTURING_PHASE);
+
+ if (documentForWindowEvents) {
+ event->setCurrentTarget(documentForWindowEvents);
+ documentForWindowEvents->handleWindowEvent(event.get(), true);
+ if (event->propagationStopped())
+ goto doneDispatching;
+ }
+ for (size_t i = ancestors.size(); i; --i) {
+ ContainerNode* ancestor = ancestors[i - 1].get();
+ event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
+ ancestor->handleLocalEvents(event.get(), true);
+ if (event->propagationStopped())
+ goto doneDispatching;
+ }
+
+ event->setEventPhase(Event::AT_TARGET);
+
+ // We do want capturing event listeners to be invoked here, even though
+ // that violates some versions of the DOM specification; Mozilla does it.
+ event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this));
+ handleLocalEvents(event.get(), true);
+ if (event->propagationStopped())
+ goto doneDispatching;
+ handleLocalEvents(event.get(), false);
+ if (event->propagationStopped())
+ goto doneDispatching;
+
+ if (event->bubbles() && !event->cancelBubble()) {
+ // Trigger bubbling event handlers, starting at the bottom and working our way up.
+ event->setEventPhase(Event::BUBBLING_PHASE);
+
+ size_t size = ancestors.size();
+ for (size_t i = 0; i < size; ++i) {
+ ContainerNode* ancestor = ancestors[i].get();
+ event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
+ ancestor->handleLocalEvents(event.get(), false);
+ if (event->propagationStopped() || event->cancelBubble())
+ goto doneDispatching;
+ }
+ if (documentForWindowEvents) {
+ event->setCurrentTarget(documentForWindowEvents);
+ documentForWindowEvents->handleWindowEvent(event.get(), false);
+ if (event->propagationStopped() || event->cancelBubble())
+ goto doneDispatching;
+ }
+ }
+
+doneDispatching:
+ event->setCurrentTarget(0);
+ event->setEventPhase(0);
+
+ // Pass the data from the preDispatchEventHandler to the postDispatchEventHandler.
+ postDispatchEventHandler(event.get(), data);
+
+ // Call default event handlers. While the DOM does have a concept of preventing
+ // default handling, the detail of which handlers are called is an internal
+ // implementation detail and not part of the DOM.
+ if (!event->defaultPrevented() && !event->defaultHandled()) {
+ // Non-bubbling events call only one default event handler, the one for the target.
+ defaultEventHandler(event.get());
+ ASSERT(!event->defaultPrevented());
+ if (event->defaultHandled())
+ goto doneWithDefault;
+ // For bubbling events, call default event handlers on the same targets in the
+ // same order as the bubbling phase.
+ if (event->bubbles()) {
+ size_t size = ancestors.size();
+ for (size_t i = 0; i < size; ++i) {
+ ContainerNode* ancestor = ancestors[i].get();
+ ancestor->defaultEventHandler(event.get());
+ ASSERT(!event->defaultPrevented());
+ if (event->defaultHandled())
+ goto doneWithDefault;
+ }
+ }
+ }
+
+doneWithDefault:
+ Document::updateDocumentsRendering();
+
+ return !event->defaultPrevented();
+}
+
+bool Node::dispatchSubtreeModifiedEvent()
+{
+ ASSERT(!eventDispatchForbidden());
+
+ document()->incDOMTreeVersion();
+
+ notifyNodeListsAttributeChanged(); // FIXME: Can do better some day. Really only care about the name attribute changing.
+
+ if (!document()->hasListenerType(Document::DOMSUBTREEMODIFIED_LISTENER))
+ return false;
+ ExceptionCode ec = 0;
+ return dispatchEvent(MutationEvent::create(eventNames().DOMSubtreeModifiedEvent, true, false, 0, String(), String(), String(), 0), ec);
+}
+
+void Node::dispatchWindowEvent(PassRefPtr<Event> e)
+{
+ ASSERT(!eventDispatchForbidden());
+ RefPtr<Event> evt(e);
+ RefPtr<Document> doc = document();
+ evt->setTarget(doc);
+ doc->handleWindowEvent(evt.get(), true);
+ doc->handleWindowEvent(evt.get(), false);
+}
+
+void Node::dispatchWindowEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ RefPtr<Document> doc = document();
+ dispatchWindowEvent(Event::create(eventType, canBubbleArg, cancelableArg));
+
+ if (eventType == eventNames().loadEvent) {
+ // For onload events, send a separate load event to the enclosing frame only.
+ // This is a DOM extension and is independent of bubbling/capturing rules of
+ // the DOM.
+ Element* ownerElement = doc->ownerElement();
+ if (ownerElement) {
+ RefPtr<Event> ownerEvent = Event::create(eventType, false, cancelableArg);
+ ownerEvent->setTarget(ownerElement);
+ ownerElement->dispatchGenericEvent(ownerEvent.release());
+ }
+ }
+}
+
+bool Node::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
+{
+ ASSERT(!eventDispatchForbidden());
+ ASSERT(eventType == eventNames().DOMFocusInEvent || eventType == eventNames().DOMFocusOutEvent || eventType == eventNames().DOMActivateEvent);
+
+ bool cancelable = eventType == eventNames().DOMActivateEvent;
+
+ ExceptionCode ec = 0;
+ RefPtr<UIEvent> evt = UIEvent::create(eventType, true, cancelable, document()->defaultView(), detail);
+ evt->setUnderlyingEvent(underlyingEvent);
+ return dispatchEvent(evt.release(), ec);
+}
+
+bool Node::dispatchKeyEvent(const PlatformKeyboardEvent& key)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ RefPtr<KeyboardEvent> keyboardEvent = KeyboardEvent::create(key, document()->defaultView());
+ bool r = dispatchEvent(keyboardEvent, ec);
+
+ // we want to return false if default is prevented (already taken care of)
+ // or if the element is default-handled by the DOM. Otherwise we let it just
+ // let it get handled by AppKit
+ if (keyboardEvent->defaultHandled())
+ r = false;
+
+ return r;
+}
+
+bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
+ int detail, Node* relatedTarget)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ IntPoint contentsPos;
+ if (FrameView* view = document()->view())
+ contentsPos = view->windowToContents(event.pos());
+
+ short button = event.button();
+
+ ASSERT(event.eventType() == MouseEventMoved || button != NoButton);
+
+ return dispatchMouseEvent(eventType, button, detail,
+ contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
+ false, relatedTarget);
+}
+
+void Node::dispatchSimulatedMouseEvent(const AtomicString& eventType,
+ PassRefPtr<Event> underlyingEvent)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ bool ctrlKey = false;
+ bool altKey = false;
+ bool shiftKey = false;
+ bool metaKey = false;
+ if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
+ ctrlKey = keyStateEvent->ctrlKey();
+ altKey = keyStateEvent->altKey();
+ shiftKey = keyStateEvent->shiftKey();
+ metaKey = keyStateEvent->metaKey();
+ }
+
+ // Like Gecko, we just pass 0 for everything when we make a fake mouse event.
+ // Internet Explorer instead gives the current mouse position and state.
+ dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
+ ctrlKey, altKey, shiftKey, metaKey, true, 0, underlyingEvent);
+}
+
+void Node::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
+{
+ if (!gNodesDispatchingSimulatedClicks)
+ gNodesDispatchingSimulatedClicks = new HashSet<Node*>;
+ else if (gNodesDispatchingSimulatedClicks->contains(this))
+ return;
+
+ gNodesDispatchingSimulatedClicks->add(this);
+
+ // send mousedown and mouseup before the click, if requested
+ if (sendMouseEvents)
+ dispatchSimulatedMouseEvent(eventNames().mousedownEvent, event.get());
+ setActive(true, showPressedLook);
+ if (sendMouseEvents)
+ dispatchSimulatedMouseEvent(eventNames().mouseupEvent, event.get());
+ setActive(false);
+
+ // always send click
+ dispatchSimulatedMouseEvent(eventNames().clickEvent, event);
+
+ gNodesDispatchingSimulatedClicks->remove(this);
+}
+
+bool Node::dispatchMouseEvent(const AtomicString& eventType, int button, int detail,
+ int pageX, int pageY, int screenX, int screenY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+ bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent)
+{
+ ASSERT(!eventDispatchForbidden());
+ if (disabled()) // Don't even send DOM events for disabled controls..
+ return true;
+
+ if (eventType.isEmpty())
+ return false; // Shouldn't happen.
+
+ // Dispatching the first event can easily result in this node being destroyed.
+ // Since we dispatch up to three events here, we need to make sure we're referenced
+ // so the pointer will be good for the two subsequent ones.
+ RefPtr<Node> protect(this);
+
+ bool cancelable = eventType != eventNames().mousemoveEvent;
+
+ ExceptionCode ec = 0;
+
+ bool swallowEvent = false;
+
+ // Attempting to dispatch with a non-EventTarget relatedTarget causes the relatedTarget to be silently ignored.
+ RefPtr<Node> relatedTarget = relatedTargetArg;
+
+ int adjustedPageX = pageX;
+ int adjustedPageY = pageY;
+ if (Frame* frame = document()->frame()) {
+ float pageZoom = frame->pageZoomFactor();
+ if (pageZoom != 1.0f) {
+ // Adjust our pageX and pageY to account for the page zoom.
+ adjustedPageX = lroundf(pageX / pageZoom);
+ adjustedPageY = lroundf(pageY / pageZoom);
+ }
+ }
+
+ RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventType,
+ true, cancelable, document()->defaultView(),
+ detail, screenX, screenY, adjustedPageX, adjustedPageY,
+ ctrlKey, altKey, shiftKey, metaKey, button,
+ relatedTarget, 0, isSimulated);
+ mouseEvent->setUnderlyingEvent(underlyingEvent.get());
+ mouseEvent->setAbsoluteLocation(IntPoint(pageX, pageY));
+
+ dispatchEvent(mouseEvent, ec);
+ bool defaultHandled = mouseEvent->defaultHandled();
+ bool defaultPrevented = mouseEvent->defaultPrevented();
+ if (defaultHandled || defaultPrevented)
+ swallowEvent = true;
+
+ // Special case: If it's a double click event, we also send the dblclick event. This is not part
+ // of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
+ // as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
+ if (eventType == eventNames().clickEvent && detail == 2) {
+ RefPtr<Event> doubleClickEvent = MouseEvent::create(eventNames().dblclickEvent,
+ true, cancelable, document()->defaultView(),
+ detail, screenX, screenY, pageX, pageY,
+ ctrlKey, altKey, shiftKey, metaKey, button,
+ relatedTarget, 0, isSimulated);
+ doubleClickEvent->setUnderlyingEvent(underlyingEvent.get());
+ if (defaultHandled)
+ doubleClickEvent->setDefaultHandled();
+ dispatchEvent(doubleClickEvent, ec);
+ if (doubleClickEvent->defaultHandled() || doubleClickEvent->defaultPrevented())
+ swallowEvent = true;
+ }
+
+ return swallowEvent;
+}
+
+void Node::dispatchWheelEvent(PlatformWheelEvent& e)
+{
+ ASSERT(!eventDispatchForbidden());
+ if (e.deltaX() == 0 && e.deltaY() == 0)
+ return;
+
+ FrameView* view = document()->view();
+ if (!view)
+ return;
+
+ IntPoint pos = view->windowToContents(e.pos());
+
+ int adjustedPageX = pos.x();
+ int adjustedPageY = pos.y();
+ if (Frame* frame = document()->frame()) {
+ float pageZoom = frame->pageZoomFactor();
+ if (pageZoom != 1.0f) {
+ // Adjust our pageX and pageY to account for the page zoom.
+ adjustedPageX = lroundf(pos.x() / pageZoom);
+ adjustedPageY = lroundf(pos.y() / pageZoom);
+ }
+ }
+
+ RefPtr<WheelEvent> we = WheelEvent::create(e.wheelTicksX(), e.wheelTicksY(),
+ document()->defaultView(), e.globalX(), e.globalY(), adjustedPageX, adjustedPageY,
+ e.ctrlKey(), e.altKey(), e.shiftKey(), e.metaKey());
+
+ we->setAbsoluteLocation(IntPoint(pos.x(), pos.y()));
+
+ ExceptionCode ec = 0;
+ if (!dispatchEvent(we.release(), ec))
+ e.accept();
+}
+
+bool Node::dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ ExceptionCode ec = 0;
+ return dispatchEvent(WebKitAnimationEvent::create(eventType, animationName, elapsedTime), ec);
+}
+
+bool Node::dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime)
+{
+ ASSERT(!eventDispatchForbidden());
+
+ ExceptionCode ec = 0;
+ return dispatchEvent(WebKitTransitionEvent::create(eventType, propertyName, elapsedTime), ec);
+}
+
+void Node::dispatchFocusEvent()
+{
+ dispatchEventForType(eventNames().focusEvent, false, false);
+}
+
+void Node::dispatchBlurEvent()
+{
+ dispatchEventForType(eventNames().blurEvent, false, false);
+}
+
+bool Node::dispatchEventForType(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ return dispatchEvent(Event::create(eventType, canBubbleArg, cancelableArg), ec);
+}
+
+bool Node::dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg)
+{
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ return dispatchEvent(ProgressEvent::create(eventType, lengthComputableArg, loadedArg, totalArg), ec);
+}
+
+void Node::dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source)
+{
+#if ENABLE(DOM_STORAGE)
+ ASSERT(!eventDispatchForbidden());
+ ExceptionCode ec = 0;
+ dispatchEvent(StorageEvent::create(eventType, key, oldValue, newValue, source->document()->documentURI(), source->domWindow()), ec);
+#endif
+}
+
+void Node::removeInlineEventListenerForType(const AtomicString& eventType)
+{
+ if (!hasRareData())
+ return;
+
+ RegisteredEventListenerVector* listeners = rareData()->listeners();
+ if (!listeners)
+ return;
+
+ size_t size = listeners->size();
+ for (size_t i = 0; i < size; ++i) {
+ RegisteredEventListener& r = *listeners->at(i);
+ if (r.eventType() != eventType || !r.listener()->isInline())
+ continue;
+
+ r.setRemoved(true);
+ listeners->remove(i);
+
+ // removed last
+ if (listeners->isEmpty() && !inDocument())
+ document()->unregisterDisconnectedNodeWithEventListeners(this);
+
+ updateSVGElementInstancesAfterEventListenerChange(this);
+ return;
+ }
+}
+
+void Node::setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+{
+ // In case we are the only one holding a reference to it, we don't want removeInlineEventListenerForType to destroy it.
+ removeInlineEventListenerForType(eventType);
+ if (listener)
+ addEventListener(eventType, listener, false);
+}
+
+void Node::setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute* attr)
+{
+ setInlineEventListenerForType(eventType, document()->createEventListener(attr->localName().string(), attr->value(), this));
+}
+
+EventListener* Node::inlineEventListenerForType(const AtomicString& eventType) const
+{
+ const RegisteredEventListenerVector& listeners = eventListeners();
+ size_t size = listeners.size();
+ for (size_t i = 0; i < size; ++i) {
+ const RegisteredEventListener& r = *listeners[i];
+ if (r.eventType() == eventType && r.listener()->isInline())
+ return r.listener();
+ }
+ return 0;
+}
+
+bool Node::disabled() const
+{
+ return false;
+}
+
+void Node::defaultEventHandler(Event* event)
+{
+ if (event->target() != this)
+ return;
+ const AtomicString& eventType = event->type();
+ if (eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent) {
+ if (event->isKeyboardEvent())
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->defaultKeyboardEventHandler(static_cast<KeyboardEvent*>(event));
+ } else if (eventType == eventNames().clickEvent) {
+ int detail = event->isUIEvent() ? static_cast<UIEvent*>(event)->detail() : 0;
+ dispatchUIEvent(eventNames().DOMActivateEvent, detail, event);
+ } else if (eventType == eventNames().contextmenuEvent) {
+ if (Frame* frame = document()->frame())
+ if (Page* page = frame->page())
+ page->contextMenuController()->handleContextMenuEvent(event);
+ } else if (eventType == eventNames().textInputEvent) {
+ if (event->isTextEvent())
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->defaultTextInputEventHandler(static_cast<TextEvent*>(event));
+ }
+}
+
+EventListener* Node::onabort() const
+{
+ return inlineEventListenerForType(eventNames().abortEvent);
+}
+
+void Node::setOnabort(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().abortEvent, eventListener);
+}
+
+EventListener* Node::onblur() const
+{
+ return inlineEventListenerForType(eventNames().blurEvent);
+}
+
+void Node::setOnblur(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().blurEvent, eventListener);
+}
+
+EventListener* Node::onchange() const
+{
+ return inlineEventListenerForType(eventNames().changeEvent);
+}
+
+void Node::setOnchange(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().changeEvent, eventListener);
+}
+
+EventListener* Node::onclick() const
+{
+ return inlineEventListenerForType(eventNames().clickEvent);
+}
+
+void Node::setOnclick(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().clickEvent, eventListener);
+}
+
+EventListener* Node::oncontextmenu() const
+{
+ return inlineEventListenerForType(eventNames().contextmenuEvent);
+}
+
+void Node::setOncontextmenu(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener);
+}
+
+EventListener* Node::ondblclick() const
+{
+ return inlineEventListenerForType(eventNames().dblclickEvent);
+}
+
+void Node::setOndblclick(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dblclickEvent, eventListener);
+}
+
+EventListener* Node::onerror() const
+{
+ return inlineEventListenerForType(eventNames().errorEvent);
+}
+
+void Node::setOnerror(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().errorEvent, eventListener);
+}
+
+EventListener* Node::onfocus() const
+{
+ return inlineEventListenerForType(eventNames().focusEvent);
+}
+
+void Node::setOnfocus(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().focusEvent, eventListener);
+}
+
+EventListener* Node::oninput() const
+{
+ return inlineEventListenerForType(eventNames().inputEvent);
+}
+
+void Node::setOninput(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().inputEvent, eventListener);
+}
+
+EventListener* Node::onkeydown() const
+{
+ return inlineEventListenerForType(eventNames().keydownEvent);
+}
+
+void Node::setOnkeydown(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keydownEvent, eventListener);
+}
+
+EventListener* Node::onkeypress() const
+{
+ return inlineEventListenerForType(eventNames().keypressEvent);
+}
+
+void Node::setOnkeypress(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keypressEvent, eventListener);
+}
+
+EventListener* Node::onkeyup() const
+{
+ return inlineEventListenerForType(eventNames().keyupEvent);
+}
+
+void Node::setOnkeyup(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().keyupEvent, eventListener);
+}
+
+EventListener* Node::onload() const
+{
+ return inlineEventListenerForType(eventNames().loadEvent);
+}
+
+void Node::setOnload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().loadEvent, eventListener);
+}
+
+EventListener* Node::onmousedown() const
+{
+ return inlineEventListenerForType(eventNames().mousedownEvent);
+}
+
+void Node::setOnmousedown(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousedownEvent, eventListener);
+}
+
+EventListener* Node::onmousemove() const
+{
+ return inlineEventListenerForType(eventNames().mousemoveEvent);
+}
+
+void Node::setOnmousemove(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener);
+}
+
+EventListener* Node::onmouseout() const
+{
+ return inlineEventListenerForType(eventNames().mouseoutEvent);
+}
+
+void Node::setOnmouseout(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener);
+}
+
+EventListener* Node::onmouseover() const
+{
+ return inlineEventListenerForType(eventNames().mouseoverEvent);
+}
+
+void Node::setOnmouseover(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener);
+}
+
+EventListener* Node::onmouseup() const
+{
+ return inlineEventListenerForType(eventNames().mouseupEvent);
+}
+
+void Node::setOnmouseup(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mouseupEvent, eventListener);
+}
+
+EventListener* Node::onmousewheel() const
+{
+ return inlineEventListenerForType(eventNames().mousewheelEvent);
+}
+
+void Node::setOnmousewheel(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener);
+}
+
+EventListener* Node::onbeforecut() const
+{
+ return inlineEventListenerForType(eventNames().beforecutEvent);
+}
+
+void Node::setOnbeforecut(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforecutEvent, eventListener);
+}
+
+EventListener* Node::oncut() const
+{
+ return inlineEventListenerForType(eventNames().cutEvent);
+}
+
+void Node::setOncut(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().cutEvent, eventListener);
+}
+
+EventListener* Node::onbeforecopy() const
+{
+ return inlineEventListenerForType(eventNames().beforecopyEvent);
+}
+
+void Node::setOnbeforecopy(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener);
+}
+
+EventListener* Node::oncopy() const
+{
+ return inlineEventListenerForType(eventNames().copyEvent);
+}
+
+void Node::setOncopy(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().copyEvent, eventListener);
+}
+
+EventListener* Node::onbeforepaste() const
+{
+ return inlineEventListenerForType(eventNames().beforepasteEvent);
+}
+
+void Node::setOnbeforepaste(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener);
+}
+
+EventListener* Node::onpaste() const
+{
+ return inlineEventListenerForType(eventNames().pasteEvent);
+}
+
+void Node::setOnpaste(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().pasteEvent, eventListener);
+}
+
+EventListener* Node::ondragenter() const
+{
+ return inlineEventListenerForType(eventNames().dragenterEvent);
+}
+
+void Node::setOndragenter(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragenterEvent, eventListener);
+}
+
+EventListener* Node::ondragover() const
+{
+ return inlineEventListenerForType(eventNames().dragoverEvent);
+}
+
+void Node::setOndragover(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragoverEvent, eventListener);
+}
+
+EventListener* Node::ondragleave() const
+{
+ return inlineEventListenerForType(eventNames().dragleaveEvent);
+}
+
+void Node::setOndragleave(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener);
+}
+
+EventListener* Node::ondrop() const
+{
+ return inlineEventListenerForType(eventNames().dropEvent);
+}
+
+void Node::setOndrop(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dropEvent, eventListener);
+}
+
+EventListener* Node::ondragstart() const
+{
+ return inlineEventListenerForType(eventNames().dragstartEvent);
+}
+
+void Node::setOndragstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragstartEvent, eventListener);
+}
+
+EventListener* Node::ondrag() const
+{
+ return inlineEventListenerForType(eventNames().dragEvent);
+}
+
+void Node::setOndrag(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragEvent, eventListener);
+}
+
+EventListener* Node::ondragend() const
+{
+ return inlineEventListenerForType(eventNames().dragendEvent);
+}
+
+void Node::setOndragend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().dragendEvent, eventListener);
+}
+
+EventListener* Node::onreset() const
+{
+ return inlineEventListenerForType(eventNames().resetEvent);
+}
+
+void Node::setOnreset(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().resetEvent, eventListener);
+}
+
+EventListener* Node::onresize() const
+{
+ return inlineEventListenerForType(eventNames().resizeEvent);
+}
+
+void Node::setOnresize(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().resizeEvent, eventListener);
+}
+
+EventListener* Node::onscroll() const
+{
+ return inlineEventListenerForType(eventNames().scrollEvent);
+}
+
+void Node::setOnscroll(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().scrollEvent, eventListener);
+}
+
+EventListener* Node::onsearch() const
+{
+ return inlineEventListenerForType(eventNames().searchEvent);
+}
+
+void Node::setOnsearch(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().searchEvent, eventListener);
+}
+
+EventListener* Node::onselect() const
+{
+ return inlineEventListenerForType(eventNames().selectEvent);
+}
+
+void Node::setOnselect(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().selectEvent, eventListener);
+}
+
+EventListener* Node::onselectstart() const
+{
+ return inlineEventListenerForType(eventNames().selectstartEvent);
+}
+
+void Node::setOnselectstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().selectstartEvent, eventListener);
+}
+
+EventListener* Node::onsubmit() const
+{
+ return inlineEventListenerForType(eventNames().submitEvent);
+}
+
+void Node::setOnsubmit(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().submitEvent, eventListener);
+}
+
+EventListener* Node::onunload() const
+{
+ return inlineEventListenerForType(eventNames().unloadEvent);
+}
+
+void Node::setOnunload(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().unloadEvent, eventListener);
+}
+
+#if ENABLE(TOUCH_EVENTS) // Android
+EventListener* Node::ontouchstart() const
+{
+ return inlineEventListenerForType(eventNames().touchstartEvent);
+}
+
+void Node::setOntouchstart(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchstartEvent, eventListener);
+}
+
+EventListener* Node::ontouchend() const
+{
+ return inlineEventListenerForType(eventNames().touchendEvent);
+}
+
+void Node::setOntouchend(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchendEvent, eventListener);
+}
+
+EventListener* Node::ontouchmove() const
+{
+ return inlineEventListenerForType(eventNames().touchmoveEvent);
+}
+
+void Node::setOntouchmove(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchmoveEvent, eventListener);
+}
+
+EventListener* Node::ontouchcancel() const
+{
+ return inlineEventListenerForType(eventNames().touchcancelEvent);
+}
+
+void Node::setOntouchcancel(PassRefPtr<EventListener> eventListener)
+{
+ setInlineEventListenerForType(eventNames().touchcancelEvent, eventListener);
+}
+#endif // ENABLE(TOUCH_EVENT)
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index fa9995d..01f2736 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,9 +25,11 @@
#define Node_h
#include "DocPtr.h"
+#include "EventTarget.h"
#include "KURLHash.h"
#include "PlatformString.h"
#include "TreeShared.h"
+#include "FloatPoint.h"
#include <wtf/Assertions.h>
#include <wtf/ListHashSet.h>
#include <wtf/OwnPtr.h>
@@ -36,30 +38,36 @@
namespace WebCore {
class AtomicString;
+class Attribute;
class ContainerNode;
class Document;
class DynamicNodeList;
class Element;
class Event;
class EventListener;
+class Frame;
class IntRect;
class KeyboardEvent;
class NSResolver;
class NamedAttrMap;
class NodeList;
+class NodeRareData;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
class PlatformWheelEvent;
class QualifiedName;
+class RegisteredEventListener;
class RenderArena;
class RenderBox;
+class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
class StringBuilder;
-class NodeRareData;
typedef int ExceptionCode;
+typedef Vector<RefPtr<RegisteredEventListener> > RegisteredEventListenerVector;
+
enum StyleChangeType { NoStyleChange, InlineStyleChange, FullStyleChange, AnimationStyleChange };
const unsigned short DOCUMENT_POSITION_EQUIVALENT = 0x00;
@@ -71,7 +79,7 @@ const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
// this class implements nodes, which can have a parent but no children:
-class Node : public TreeShared<Node> {
+class Node : public EventTarget, public TreeShared<Node> {
friend class Document;
public:
enum NodeType {
@@ -180,7 +188,6 @@ public:
virtual bool isCommentNode() const { return false; }
virtual bool isCharacterDataNode() const { return false; }
bool isDocumentNode() const;
- virtual bool isEventTargetNode() const { return false; }
virtual bool isShadowNode() const { return false; }
virtual Node* shadowParentNode() { return 0; }
Node* shadowAncestorNode();
@@ -290,14 +297,6 @@ public:
virtual bool isKeyboardFocusable(KeyboardEvent*) const;
virtual bool isMouseFocusable() const;
- virtual bool isAutofilled() const { return false; }
- virtual bool isControl() const { return false; } // Eventually the notion of what is a control will be extensible.
- virtual bool isEnabled() const { return true; }
- virtual bool isChecked() const { return false; }
- virtual bool isIndeterminate() const { return false; }
- virtual bool isReadOnlyControl() const { return false; }
- virtual bool isTextControl() const { return false; }
-
virtual bool isContentEditable() const;
virtual bool isContentRichlyEditable() const;
virtual bool shouldUseInputMethod() const;
@@ -316,7 +315,7 @@ public:
Document* document() const
{
ASSERT(this);
- ASSERT(m_document || nodeType() == DOCUMENT_TYPE_NODE && !inDocument());
+ ASSERT(m_document || (nodeType() == DOCUMENT_TYPE_NODE && !inDocument()));
return m_document.get();
}
void setDocument(Document*);
@@ -375,10 +374,10 @@ public:
RenderObject* previousRenderer();
void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
- // Use with caution. Does no type checking. Mostly a convenience method for shadow nodes of form controls, where we know exactly
- // what kind of renderer we made.
+ // Use these two methods with caution.
RenderBox* renderBox() const;
-
+ RenderBoxModelObject* renderBoxModelObject() const;
+
void checkSetPrefix(const AtomicString& prefix, ExceptionCode&);
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
@@ -405,6 +404,10 @@ public:
// Whether or not a selection can be started in this object
virtual bool canStartSelection() const;
+ // Getting points into and out of screen space
+ FloatPoint convertToPage(const FloatPoint& p) const;
+ FloatPoint convertFromPage(const FloatPoint& p) const;
+
// -----------------------------------------------------------------------------
// Integration with rendering tree
@@ -507,8 +510,8 @@ public:
#endif
protected:
- virtual void willMoveToNewOwnerDocument() { }
- virtual void didMoveToNewOwnerDocument() { }
+ virtual void willMoveToNewOwnerDocument();
+ virtual void didMoveToNewOwnerDocument();
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
void setTabIndexExplicitly(short);
@@ -518,6 +521,160 @@ protected:
NodeRareData* rareData() const;
NodeRareData* ensureRareData();
+public:
+ virtual Node* toNode() { return this; }
+
+ virtual ScriptExecutionContext* scriptExecutionContext() const;
+
+ virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+ virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
+ void removeAllEventListeners() { if (hasRareData()) removeAllEventListenersSlowCase(); }
+
+ void setInlineEventListenerForType(const AtomicString& eventType, PassRefPtr<EventListener>);
+ void setInlineEventListenerForTypeAndAttribute(const AtomicString& eventType, Attribute*);
+ void removeInlineEventListenerForType(const AtomicString& eventType);
+ bool dispatchEventForType(const AtomicString& eventType, bool canBubble, bool cancelable);
+ EventListener* inlineEventListenerForType(const AtomicString& eventType) const;
+
+ bool dispatchSubtreeModifiedEvent();
+ void dispatchWindowEvent(PassRefPtr<Event>);
+ void dispatchWindowEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+ bool dispatchUIEvent(const AtomicString& eventType, int detail = 0, PassRefPtr<Event> underlyingEvent = 0);
+ bool dispatchKeyEvent(const PlatformKeyboardEvent&);
+ void dispatchWheelEvent(PlatformWheelEvent&);
+ bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
+ int clickCount = 0, Node* relatedTarget = 0);
+ bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
+ int pageX, int pageY, int screenX, int screenY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+ bool isSimulated = false, Node* relatedTarget = 0, PassRefPtr<Event> underlyingEvent = 0);
+ void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent = 0);
+ void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
+ bool dispatchProgressEvent(const AtomicString &eventType, bool lengthComputableArg, unsigned loadedArg, unsigned totalArg);
+ void dispatchStorageEvent(const AtomicString &eventType, const String& key, const String& oldValue, const String& newValue, Frame* source);
+ bool dispatchWebKitAnimationEvent(const AtomicString& eventType, const String& animationName, double elapsedTime);
+ bool dispatchWebKitTransitionEvent(const AtomicString& eventType, const String& propertyName, double elapsedTime);
+ bool dispatchGenericEvent(PassRefPtr<Event>);
+
+ virtual void handleLocalEvents(Event*, bool useCapture);
+
+ virtual void dispatchFocusEvent();
+ virtual void dispatchBlurEvent();
+
+ /**
+ * Perform the default action for an event e.g. submitting a form
+ */
+ virtual void defaultEventHandler(Event*);
+
+ /**
+ * Used for disabled form elements; if true, prevents mouse events from being dispatched
+ * to event listeners, and prevents DOMActivate events from being sent at all.
+ */
+ virtual bool disabled() const;
+
+ const RegisteredEventListenerVector& eventListeners() const;
+
+ EventListener* onabort() const;
+ void setOnabort(PassRefPtr<EventListener>);
+ EventListener* onblur() const;
+ void setOnblur(PassRefPtr<EventListener>);
+ EventListener* onchange() const;
+ void setOnchange(PassRefPtr<EventListener>);
+ EventListener* onclick() const;
+ void setOnclick(PassRefPtr<EventListener>);
+ EventListener* oncontextmenu() const;
+ void setOncontextmenu(PassRefPtr<EventListener>);
+ EventListener* ondblclick() const;
+ void setOndblclick(PassRefPtr<EventListener>);
+ EventListener* onerror() const;
+ void setOnerror(PassRefPtr<EventListener>);
+ EventListener* onfocus() const;
+ void setOnfocus(PassRefPtr<EventListener>);
+ EventListener* oninput() const;
+ void setOninput(PassRefPtr<EventListener>);
+ EventListener* onkeydown() const;
+ void setOnkeydown(PassRefPtr<EventListener>);
+ EventListener* onkeypress() const;
+ void setOnkeypress(PassRefPtr<EventListener>);
+ EventListener* onkeyup() const;
+ void setOnkeyup(PassRefPtr<EventListener>);
+ EventListener* onload() const;
+ void setOnload(PassRefPtr<EventListener>);
+ EventListener* onmousedown() const;
+ void setOnmousedown(PassRefPtr<EventListener>);
+ EventListener* onmousemove() const;
+ void setOnmousemove(PassRefPtr<EventListener>);
+ EventListener* onmouseout() const;
+ void setOnmouseout(PassRefPtr<EventListener>);
+ EventListener* onmouseover() const;
+ void setOnmouseover(PassRefPtr<EventListener>);
+ EventListener* onmouseup() const;
+ void setOnmouseup(PassRefPtr<EventListener>);
+ EventListener* onmousewheel() const;
+ void setOnmousewheel(PassRefPtr<EventListener>);
+ EventListener* onbeforecut() const;
+ void setOnbeforecut(PassRefPtr<EventListener>);
+ EventListener* oncut() const;
+ void setOncut(PassRefPtr<EventListener>);
+ EventListener* onbeforecopy() const;
+ void setOnbeforecopy(PassRefPtr<EventListener>);
+ EventListener* oncopy() const;
+ void setOncopy(PassRefPtr<EventListener>);
+ EventListener* onbeforepaste() const;
+ void setOnbeforepaste(PassRefPtr<EventListener>);
+ EventListener* onpaste() const;
+ void setOnpaste(PassRefPtr<EventListener>);
+ EventListener* ondragenter() const;
+ void setOndragenter(PassRefPtr<EventListener>);
+ EventListener* ondragover() const;
+ void setOndragover(PassRefPtr<EventListener>);
+ EventListener* ondragleave() const;
+ void setOndragleave(PassRefPtr<EventListener>);
+ EventListener* ondrop() const;
+ void setOndrop(PassRefPtr<EventListener>);
+ EventListener* ondragstart() const;
+ void setOndragstart(PassRefPtr<EventListener>);
+ EventListener* ondrag() const;
+ void setOndrag(PassRefPtr<EventListener>);
+ EventListener* ondragend() const;
+ void setOndragend(PassRefPtr<EventListener>);
+ EventListener* onreset() const;
+ void setOnreset(PassRefPtr<EventListener>);
+ EventListener* onresize() const;
+ void setOnresize(PassRefPtr<EventListener>);
+ EventListener* onscroll() const;
+ void setOnscroll(PassRefPtr<EventListener>);
+ EventListener* onsearch() const;
+ void setOnsearch(PassRefPtr<EventListener>);
+ EventListener* onselect() const;
+ void setOnselect(PassRefPtr<EventListener>);
+ EventListener* onselectstart() const;
+ void setOnselectstart(PassRefPtr<EventListener>);
+ EventListener* onsubmit() const;
+ void setOnsubmit(PassRefPtr<EventListener>);
+ EventListener* onunload() const;
+ void setOnunload(PassRefPtr<EventListener>);
+#if ENABLE(TOUCH_EVENTS) // Android
+ EventListener* ontouchstart() const;
+ void setOntouchstart(PassRefPtr<EventListener>);
+ EventListener* ontouchend() const;
+ void setOntouchend(PassRefPtr<EventListener>);
+ EventListener* ontouchmove() const;
+ void setOntouchmove(PassRefPtr<EventListener>);
+ EventListener* ontouchcancel() const;
+ void setOntouchcancel(PassRefPtr<EventListener>);
+#endif
+
+ using TreeShared<Node>::ref;
+ using TreeShared<Node>::deref;
+
+private:
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+
+ void removeAllEventListenersSlowCase();
+
private:
virtual NodeRareData* createRareData();
Node* containerChildNode(unsigned index) const;
diff --git a/WebCore/dom/Node.idl b/WebCore/dom/Node.idl
index f45eaa6..0e1848d 100644
--- a/WebCore/dom/Node.idl
+++ b/WebCore/dom/Node.idl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
*
* This library is free software; you can redistribute it and/or
@@ -22,6 +22,7 @@ module core {
interface [
CustomMarkFunction,
+ CustomPushEventHandlerScope,
GenerateConstructor,
GenerateNativeConverter,
GenerateToJS,
@@ -64,15 +65,15 @@ module core {
readonly attribute NamedNodeMap attributes;
readonly attribute Document ownerDocument;
- [OldStyleObjC, Custom] Node insertBefore(in [Return] Node newChild,
+ [OldStyleObjC, JSCCustom] Node insertBefore(in [Return] Node newChild,
in Node refChild)
raises(DOMException);
- [OldStyleObjC, Custom] Node replaceChild(in Node newChild,
+ [OldStyleObjC, JSCCustom] Node replaceChild(in Node newChild,
in [Return] Node oldChild)
+ raises(DOMExceptionJSC);
+ [JSCCustom] Node removeChild(in [Return] Node oldChild)
raises(DOMException);
- [Custom] Node removeChild(in [Return] Node oldChild)
- raises(DOMException);
- [Custom] Node appendChild(in [Return] Node newChild)
+ [JSCCustom] Node appendChild(in [Return] Node newChild)
raises(DOMException);
boolean hasChildNodes();
@@ -131,6 +132,66 @@ module core {
// Objective-C extensions
readonly attribute boolean isContentEditable;
#endif /* defined(LANGUAGE_OBJECTIVE_C) */
+
+#if !defined(LANGUAGE_OBJECTIVE_C)
+#if !defined(LANGUAGE_COM)
+ attribute [DontEnum, ProtectedListener] EventListener onabort;
+ attribute [DontEnum, ProtectedListener] EventListener onblur;
+ attribute [DontEnum, ProtectedListener] EventListener onchange;
+ attribute [DontEnum, ProtectedListener] EventListener onclick;
+ attribute [DontEnum, ProtectedListener] EventListener oncontextmenu;
+ attribute [DontEnum, ProtectedListener] EventListener ondblclick;
+ attribute [DontEnum, ProtectedListener] EventListener onerror;
+ attribute [DontEnum, ProtectedListener] EventListener onfocus;
+ attribute [DontEnum, ProtectedListener] EventListener oninput;
+ attribute [DontEnum, ProtectedListener] EventListener onkeydown;
+ attribute [DontEnum, ProtectedListener] EventListener onkeypress;
+ attribute [DontEnum, ProtectedListener] EventListener onkeyup;
+ attribute [DontEnum, ProtectedListener] EventListener onload;
+ attribute [DontEnum, ProtectedListener] EventListener onmousedown;
+ attribute [DontEnum, ProtectedListener] EventListener onmousemove;
+ attribute [DontEnum, ProtectedListener] EventListener onmouseout;
+ attribute [DontEnum, ProtectedListener] EventListener onmouseover;
+ attribute [DontEnum, ProtectedListener] EventListener onmouseup;
+ attribute [DontEnum, ProtectedListener] EventListener onmousewheel;
+ attribute [DontEnum, ProtectedListener] EventListener onbeforecut;
+ attribute [DontEnum, ProtectedListener] EventListener oncut;
+ attribute [DontEnum, ProtectedListener] EventListener onbeforecopy;
+ attribute [DontEnum, ProtectedListener] EventListener oncopy;
+ attribute [DontEnum, ProtectedListener] EventListener onbeforepaste;
+ attribute [DontEnum, ProtectedListener] EventListener onpaste;
+ attribute [DontEnum, ProtectedListener] EventListener ondragenter;
+ attribute [DontEnum, ProtectedListener] EventListener ondragover;
+ attribute [DontEnum, ProtectedListener] EventListener ondragleave;
+ attribute [DontEnum, ProtectedListener] EventListener ondrop;
+ attribute [DontEnum, ProtectedListener] EventListener ondragstart;
+ attribute [DontEnum, ProtectedListener] EventListener ondrag;
+ attribute [DontEnum, ProtectedListener] EventListener ondragend;
+ attribute [DontEnum, ProtectedListener] EventListener onreset;
+ attribute [DontEnum, ProtectedListener] EventListener onresize;
+ attribute [DontEnum, ProtectedListener] EventListener onscroll;
+ attribute [DontEnum, ProtectedListener] EventListener onsearch;
+ attribute [DontEnum, ProtectedListener] EventListener onselect;
+ attribute [DontEnum, ProtectedListener] EventListener onselectstart;
+ attribute [DontEnum, ProtectedListener] EventListener onsubmit;
+ attribute [DontEnum, ProtectedListener] EventListener onunload;
+#if ENABLE_TOUCH_EVENTS
+ attribute [DontEnum, ProtectedListener] EventListener ontouchstart;
+ attribute [DontEnum, ProtectedListener] EventListener ontouchend;
+ attribute [DontEnum, ProtectedListener] EventListener ontouchmove;
+ attribute [DontEnum, ProtectedListener] EventListener ontouchcancel;
+#endif
+
+ [Custom] void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ [Custom] void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ boolean dispatchEvent(in Event event)
+ raises(EventException);
+#endif
+#endif
};
}
diff --git a/WebCore/dom/Position.cpp b/WebCore/dom/Position.cpp
index faa4a13..a2591ba 100644
--- a/WebCore/dom/Position.cpp
+++ b/WebCore/dom/Position.cpp
@@ -43,7 +43,7 @@ namespace WebCore {
using namespace HTMLNames;
-static Node *nextRenderedEditable(Node *node)
+static Node* nextRenderedEditable(Node* node)
{
while (1) {
node = node->nextEditable();
@@ -52,13 +52,13 @@ static Node *nextRenderedEditable(Node *node)
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
- if (renderer->inlineBoxWrapper() || renderer->isText() && toRenderText(renderer)->firstTextBox())
+ if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
return node;
}
return 0;
}
-static Node *previousRenderedEditable(Node *node)
+static Node* previousRenderedEditable(Node* node)
{
while (1) {
node = node->previousEditable();
@@ -67,7 +67,7 @@ static Node *previousRenderedEditable(Node *node)
RenderObject* renderer = node->renderer();
if (!renderer)
continue;
- if (renderer->inlineBoxWrapper() || renderer->isText() && toRenderText(renderer)->firstTextBox())
+ if ((renderer->isBox() && toRenderBox(renderer)->inlineBoxWrapper()) || (renderer->isText() && toRenderText(renderer)->firstTextBox()))
return node;
}
return 0;
@@ -97,60 +97,69 @@ PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
return WebCore::computedStyle(elem);
}
-Position Position::previous(EUsingComposedCharacters usingComposedCharacters) const
+Position Position::previous(PositionMoveType moveType) const
{
- Node *n = node();
+ Node* n = node();
if (!n)
return *this;
- int o = offset();
+ int o = m_offset;
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(o >= 0);
if (o > 0) {
- Node *child = n->childNode(o - 1);
- if (child) {
- return Position(child, maxDeepOffset(child));
- }
+ Node* child = n->childNode(o - 1);
+ if (child)
+ return lastDeepEditingPositionForNode(child);
+
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
// Going backward one character at a time is correct.
// 2) The old offset was a bogus offset like (<br>, 1), and there is no child.
// Going from 1 to 0 is correct.
- return Position(n, usingComposedCharacters ? uncheckedPreviousOffset(n, o) : o - 1);
+ switch (moveType) {
+ case CodePoint:
+ return Position(n, o - 1);
+ case Character:
+ return Position(n, uncheckedPreviousOffset(n, o));
+ case BackwardDeletion:
+ return Position(n, uncheckedPreviousOffsetForBackwardDeletion(n, o));
+ }
}
- Node *parent = n->parentNode();
+ Node* parent = n->parentNode();
if (!parent)
return *this;
return Position(parent, n->nodeIndex());
}
-Position Position::next(EUsingComposedCharacters usingComposedCharacters) const
+Position Position::next(PositionMoveType moveType) const
{
- Node *n = node();
+ ASSERT(moveType != BackwardDeletion);
+
+ Node* n = node();
if (!n)
return *this;
- int o = offset();
+ int o = m_offset;
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(o >= 0);
Node* child = n->childNode(o);
- if (child || !n->hasChildNodes() && o < maxDeepOffset(n)) {
+ if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n))) {
if (child)
- return Position(child, 0);
-
+ return firstDeepEditingPositionForNode(child);
+
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
// Going forward one character at a time is correct.
// 2) The new offset is a bogus offset like (<br>, 1), and there is no child.
// Going from 0 to 1 is correct.
- return Position(n, usingComposedCharacters ? uncheckedNextOffset(n, o) : o + 1);
+ return Position(n, (moveType == Character) ? uncheckedNextOffset(n, o) : o + 1);
}
- Node *parent = n->parentNode();
+ Node* parent = n->parentNode();
if (!parent)
return *this;
@@ -162,46 +171,61 @@ int Position::uncheckedPreviousOffset(const Node* n, int current)
return n->renderer() ? n->renderer()->previousOffset(current) : current - 1;
}
+int Position::uncheckedPreviousOffsetForBackwardDeletion(const Node* n, int current)
+{
+ return n->renderer() ? n->renderer()->previousOffsetForBackwardDeletion(current) : current - 1;
+}
+
int Position::uncheckedNextOffset(const Node* n, int current)
{
return n->renderer() ? n->renderer()->nextOffset(current) : current + 1;
}
-bool Position::atStart() const
+bool Position::atFirstEditingPositionForNode() const
{
- Node *n = node();
- if (!n)
+ if (isNull())
return true;
-
- return offset() <= 0 && n->parent() == 0;
+ return m_offset <= 0;
}
-bool Position::atEnd() const
+bool Position::atLastEditingPositionForNode() const
{
- Node *n = node();
- if (!n)
+ if (isNull())
return true;
-
- return n->parent() == 0 && offset() >= maxDeepOffset(n);
+ return m_offset >= lastOffsetForEditing(node());
+}
+
+bool Position::atStartOfTree() const
+{
+ if (isNull())
+ return true;
+ return !node()->parentNode() && m_offset <= 0;
+}
+
+bool Position::atEndOfTree() const
+{
+ if (isNull())
+ return true;
+ return !node()->parentNode() && m_offset >= lastOffsetForEditing(node());
}
int Position::renderedOffset() const
{
if (!node()->isTextNode())
- return offset();
+ return m_offset;
if (!node()->renderer())
- return offset();
+ return m_offset;
int result = 0;
RenderText *textRenderer = toRenderText(node()->renderer());
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
int start = box->start();
int end = box->start() + box->len();
- if (offset() < start)
+ if (m_offset < start)
return result;
- if (offset() <= end) {
- result += offset() - start;
+ if (m_offset <= end) {
+ result += m_offset - start;
return result;
}
result += box->len();
@@ -221,7 +245,7 @@ Position Position::previousCharacterPosition(EAffinity affinity) const
bool rendered = isCandidate();
Position currentPos = *this;
- while (!currentPos.atStart()) {
+ while (!currentPos.atStartOfTree()) {
currentPos = currentPos.previous();
if (currentPos.node()->rootEditableElement() != fromRootEditableElement)
@@ -249,7 +273,7 @@ Position Position::nextCharacterPosition(EAffinity affinity) const
bool rendered = isCandidate();
Position currentPos = *this;
- while (!currentPos.atEnd()) {
+ while (!currentPos.atEndOfTree()) {
currentPos = currentPos.next();
if (currentPos.node()->rootEditableElement() != fromRootEditableElement)
@@ -265,7 +289,7 @@ Position Position::nextCharacterPosition(EAffinity affinity) const
return *this;
}
-// Whether or not [node, 0] and [node, maxDeepOffset(node)] are their own VisiblePositions.
+// Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
// If true, adjacent candidates are visually distinct.
// FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
// FIXME: Share code with isCandidate, if possible.
@@ -359,7 +383,7 @@ Position Position::upstream() const
// Return position after tables and nodes which have content that can be ignored.
if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
if (currentPos.atEndOfNode())
- return Position(currentNode, maxDeepOffset(currentNode));
+ return lastDeepEditingPositionForNode(currentNode);
continue;
}
@@ -396,7 +420,7 @@ Position Position::upstream() const
otherBox = otherBox->nextLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))
continuesOnNextLine = false;
}
@@ -405,7 +429,7 @@ Position Position::upstream() const
otherBox = otherBox->prevLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() > textOffset))
continuesOnNextLine = false;
}
@@ -508,7 +532,7 @@ Position Position::downstream() const
otherBox = otherBox->nextLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))
continuesOnNextLine = false;
}
@@ -517,7 +541,7 @@ Position Position::downstream() const
otherBox = otherBox->prevLeafChild();
if (!otherBox)
break;
- if (otherBox == lastTextBox || otherBox->object() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset)
+ if (otherBox == lastTextBox || (otherBox->renderer() == textRenderer && static_cast<InlineTextBox*>(otherBox)->start() >= textOffset))
continuesOnNextLine = false;
}
@@ -534,7 +558,7 @@ bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* render
{
RenderObject* stop = renderer->nextInPreOrderAfterChildren();
for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
- if (o->element()) {
+ if (o->node()) {
if ((o->isText() && toRenderText(o)->linesBoundingBox().height()) ||
(o->isBox() && toRenderBox(o)->borderBoundingBox().height()))
return true;
@@ -560,17 +584,17 @@ bool Position::isCandidate() const
return false;
if (renderer->isBR())
- return offset() == 0 && !nodeIsUserSelectNone(node()->parent());
+ return m_offset == 0 && !nodeIsUserSelectNone(node()->parent());
if (renderer->isText())
return inRenderedText() && !nodeIsUserSelectNone(node());
if (isTableElement(node()) || editingIgnoresContent(node()))
- return (offset() == 0 || offset() == maxDeepOffset(node())) && !nodeIsUserSelectNone(node()->parent());
+ return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(node()->parent());
if (!node()->hasTagName(htmlTag) && renderer->isBlockFlow() && !hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
(toRenderBox(renderer)->height() || node()->hasTagName(bodyTag)))
- return offset() == 0 && !nodeIsUserSelectNone(node());
+ return atFirstEditingPositionForNode() && !nodeIsUserSelectNone(node());
return false;
}
@@ -586,15 +610,15 @@ bool Position::inRenderedText() const
RenderText *textRenderer = toRenderText(renderer);
for (InlineTextBox *box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offset() < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
+ if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
// The offset we're looking for is before this node
// this means the offset must be in content that is
// not rendered. Return false.
return false;
}
- if (box->containsCaretOffset(offset()))
+ if (box->containsCaretOffset(m_offset))
// Return false for offsets inside composed characters.
- return offset() == 0 || offset() == textRenderer->nextOffset(textRenderer->previousOffset(offset()));
+ return m_offset == 0 || m_offset == textRenderer->nextOffset(textRenderer->previousOffset(m_offset));
}
return false;
@@ -622,13 +646,13 @@ bool Position::isRenderedCharacter() const
RenderText* textRenderer = toRenderText(renderer);
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offset() < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
+ if (m_offset < static_cast<int>(box->start()) && !textRenderer->containsReversedText()) {
// The offset we're looking for is before this node
// this means the offset must be in content that is
// not rendered. Return false.
return false;
}
- if (offset() >= static_cast<int>(box->start()) && offset() < static_cast<int>(box->start() + box->len()))
+ if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast<int>(box->start() + box->len()))
return true;
}
@@ -656,11 +680,11 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
if (node()->hasTagName(brTag))
return false;
- if (offset() == pos.offset())
+ if (m_offset == pos.m_offset)
return false;
if (!node()->isTextNode() && !pos.node()->isTextNode()) {
- if (offset() != pos.offset())
+ if (m_offset != pos.m_offset)
return true;
}
}
@@ -734,7 +758,7 @@ Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
Position prev = previousCharacterPosition(affinity);
if (prev != *this && prev.node()->inSameContainingBlockFlowElement(node()) && prev.node()->isTextNode()) {
String string = static_cast<Text *>(prev.node())->data();
- UChar c = string[prev.offset()];
+ UChar c = string[prev.m_offset];
if (considerNonCollapsibleWhitespace ? (isSpaceOrNewline(c) || c == noBreakSpace) : isCollapsibleWhitespace(c))
if (isEditablePosition(prev))
return prev;
@@ -809,11 +833,11 @@ static InlineTextBox* searchAheadForBetterMatch(RenderObject* renderer)
void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
{
- caretOffset = offset();
+ caretOffset = m_offset;
RenderObject* renderer = node()->renderer();
if (!renderer->isText()) {
- inlineBox = renderer->inlineBoxWrapper();
- if (!inlineBox || caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset())
+ inlineBox = renderer->isBox() ? toRenderBox(renderer)->inlineBoxWrapper() : 0;
+ if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && caretOffset < inlineBox->caretMaxOffset()))
return;
} else {
RenderText* textRenderer = toRenderText(renderer);
@@ -825,7 +849,7 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi
int caretMinOffset = box->caretMinOffset();
int caretMaxOffset = box->caretMaxOffset();
- if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || caretOffset == caretMaxOffset && box->isLineBreak())
+ if (caretOffset < caretMinOffset || caretOffset > caretMaxOffset || (caretOffset == caretMaxOffset && box->isLineBreak()))
continue;
if (caretOffset > caretMinOffset && caretOffset < caretMaxOffset) {
@@ -943,7 +967,7 @@ void Position::debugPosition(const char* msg) const
if (isNull())
fprintf(stderr, "Position [%s]: null\n", msg);
else
- fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, node()->nodeName().utf8().data(), node(), offset());
+ fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, node()->nodeName().utf8().data(), node(), m_offset);
}
#ifndef NDEBUG
@@ -957,7 +981,7 @@ void Position::formatForDebugger(char* buffer, unsigned length) const
else {
char s[1024];
result += "offset ";
- result += String::number(offset());
+ result += String::number(m_offset);
result += " of ";
node()->formatForDebugger(s, sizeof(s));
result += s;
@@ -984,6 +1008,19 @@ Position endPosition(const Range* r)
return r ? r->endPosition() : Position();
}
+// NOTE: first/lastDeepEditingPositionForNode can return "editing positions" (like [img, 0])
+// for elements which editing "ignores". the rest of the editing code will treat [img, 0]
+// as "the last position before the img"
+Position firstDeepEditingPositionForNode(Node* node)
+{
+ return Position(node, 0);
+}
+
+Position lastDeepEditingPositionForNode(Node* node)
+{
+ return Position(node, lastOffsetForEditing(node));
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/dom/Position.h b/WebCore/dom/Position.h
index 2624238..8efb10f 100644
--- a/WebCore/dom/Position.h
+++ b/WebCore/dom/Position.h
@@ -40,7 +40,11 @@ class Node;
class Range;
class RenderObject;
-enum EUsingComposedCharacters { NotUsingComposedCharacters = false, UsingComposedCharacters = true };
+enum PositionMoveType {
+ CodePoint, // Move by a single code point.
+ Character, // Move to the next Unicode character break.
+ BackwardDeletion // Subject to platform conventions.
+};
// FIXME: Reduce the number of operations we have on a Position.
// This should be more like a humble struct, without so many different
@@ -48,20 +52,36 @@ enum EUsingComposedCharacters { NotUsingComposedCharacters = false, UsingCompose
class Position {
public:
- RefPtr<Node> container;
- int posOffset; // to be renamed to offset when we get rid of offset()
+ Position() : m_offset(0) { }
+
+ // This constructor should be private
+ Position(PassRefPtr<Node> anchorNode, int offset)
+ : m_anchorNode(anchorNode)
+ , m_offset(offset)
+ {}
- Position() : posOffset(0) { }
- Position(PassRefPtr<Node> c, int o) : container(c), posOffset(o) { }
+ void clear() { m_anchorNode.clear(); m_offset = 0; }
- void clear() { container.clear(); posOffset = 0; }
+ Node* anchorNode() const { return m_anchorNode.get(); }
- Node* node() const { return container.get(); }
- int offset() const { return posOffset; }
+ // FIXME: Callers should be moved off of node(), node() is not always the container for this position.
+ // For nodes which editingIgnoresContent(node()) returns true, positions like [ignoredNode, 0]
+ // will be treated as before ignoredNode (thus node() is really after the position, not containing it).
+ Node* node() const { return m_anchorNode.get(); }
Element* documentElement() const;
- bool isNull() const { return !container; }
- bool isNotNull() const { return container; }
+ void moveToPosition(PassRefPtr<Node> node, int offset)
+ {
+ m_anchorNode = node;
+ m_offset = offset;
+ }
+ void moveToOffset(int offset)
+ {
+ m_offset = offset;
+ }
+
+ bool isNull() const { return !m_anchorNode; }
+ bool isNotNull() const { return m_anchorNode; }
Element* element() const;
PassRefPtr<CSSComputedStyleDeclaration> computedStyle() const;
@@ -69,13 +89,19 @@ public:
// Move up or down the DOM by one position.
// Offsets are computed using render text for nodes that have renderers - but note that even when
// using composed characters, the result may be inside a single user-visible character if a ligature is formed.
- Position previous(EUsingComposedCharacters usingComposedCharacters=NotUsingComposedCharacters) const;
- Position next(EUsingComposedCharacters usingComposedCharacters=NotUsingComposedCharacters) const;
+ Position previous(PositionMoveType = CodePoint) const;
+ Position next(PositionMoveType = CodePoint) const;
static int uncheckedPreviousOffset(const Node*, int current);
+ static int uncheckedPreviousOffsetForBackwardDeletion(const Node*, int current);
static int uncheckedNextOffset(const Node*, int current);
- bool atStart() const;
- bool atEnd() const;
+ // These can be either inside or just before/after the node, depending on
+ // if the node is ignored by editing or not.
+ bool atFirstEditingPositionForNode() const;
+ bool atLastEditingPositionForNode() const;
+
+ bool atStartOfTree() const;
+ bool atEndOfTree() const;
// FIXME: Make these non-member functions and put them somewhere in the editing directory.
// These aren't really basic "position" operations. More high level editing helper functions.
@@ -109,11 +135,20 @@ private:
Position previousCharacterPosition(EAffinity) const;
Position nextCharacterPosition(EAffinity) const;
+
+ RefPtr<Node> m_anchorNode;
+public:
+ // m_offset can be the offset inside m_anchorNode, or if editingIgnoresContent(m_anchorNode)
+ // returns true, then other places in editing will treat m_offset == 0 as "before the anchor"
+ // and m_offset > 0 as "after the anchor node". See rangeCompliantEquivalent for more info.
+ int m_offset; // FIXME: This should be made private.
};
inline bool operator==(const Position& a, const Position& b)
{
- return a.container == b.container && a.posOffset == b.posOffset;
+ // FIXME: In <div><img></div> [div, 0] != [img, 0] even though most of the
+ // editing code will treat them as identical.
+ return a.anchorNode() == b.anchorNode() && a.m_offset == b.m_offset;
}
inline bool operator!=(const Position& a, const Position& b)
@@ -124,6 +159,12 @@ inline bool operator!=(const Position& a, const Position& b)
Position startPosition(const Range*);
Position endPosition(const Range*);
+// NOTE: first/lastDeepEditingPositionForNode can return "editing positions" (like [img, 0])
+// for elements which editing "ignores". the rest of the editing code will treat [img, 0]
+// as "the last position before the img"
+Position firstDeepEditingPositionForNode(Node*);
+Position lastDeepEditingPositionForNode(Node*);
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/dom/PositionIterator.cpp b/WebCore/dom/PositionIterator.cpp
index 06e1e32..781d352 100644
--- a/WebCore/dom/PositionIterator.cpp
+++ b/WebCore/dom/PositionIterator.cpp
@@ -36,7 +36,13 @@ using namespace HTMLNames;
PositionIterator::operator Position() const
{
- return Position(m_parent, m_child ? m_child->nodeIndex() : (m_parent->hasChildNodes() ? maxDeepOffset(m_parent) : m_offset));
+ if (m_child) {
+ ASSERT(m_child->parentNode() == m_parent);
+ return positionBeforeNode(m_child);
+ }
+ if (m_parent->hasChildNodes())
+ return lastDeepEditingPositionForNode(m_parent);
+ return Position(m_parent, m_offset);
}
void PositionIterator::increment()
@@ -51,7 +57,7 @@ void PositionIterator::increment()
return;
}
- if (!m_parent->hasChildNodes() && m_offset < maxDeepOffset(m_parent))
+ if (!m_parent->hasChildNodes() && m_offset < lastOffsetForEditing(m_parent))
m_offset = Position::uncheckedNextOffset(m_parent, m_offset);
else {
m_child = m_parent;
@@ -70,7 +76,7 @@ void PositionIterator::decrement()
m_parent = m_child->previousSibling();
if (m_parent) {
m_child = 0;
- m_offset = m_parent->hasChildNodes() ? 0 : maxDeepOffset(m_parent);
+ m_offset = m_parent->hasChildNodes() ? 0 : lastOffsetForEditing(m_parent);
} else {
m_child = m_child->parentNode();
m_parent = m_child->parentNode();
@@ -85,7 +91,7 @@ void PositionIterator::decrement()
if (m_parent->hasChildNodes()) {
m_parent = m_parent->lastChild();
if (!m_parent->hasChildNodes())
- m_offset = maxDeepOffset(m_parent);
+ m_offset = lastOffsetForEditing(m_parent);
} else {
m_child = m_parent;
m_parent = m_parent->parentNode();
@@ -99,7 +105,7 @@ bool PositionIterator::atStart() const
return true;
if (m_parent->parentNode())
return false;
- return !m_parent->hasChildNodes() && !m_offset || m_child && !m_child->previousSibling();
+ return (!m_parent->hasChildNodes() && !m_offset) || (m_child && !m_child->previousSibling());
}
bool PositionIterator::atEnd() const
@@ -108,7 +114,7 @@ bool PositionIterator::atEnd() const
return true;
if (m_child)
return false;
- return !m_parent->parentNode() && (m_parent->hasChildNodes() || m_offset >= maxDeepOffset(m_parent));
+ return !m_parent->parentNode() && (m_parent->hasChildNodes() || m_offset >= lastOffsetForEditing(m_parent));
}
bool PositionIterator::atStartOfNode() const
@@ -126,7 +132,7 @@ bool PositionIterator::atEndOfNode() const
return true;
if (m_child)
return false;
- return m_parent->hasChildNodes() || m_offset >= maxDeepOffset(m_parent);
+ return m_parent->hasChildNodes() || m_offset >= lastOffsetForEditing(m_parent);
}
bool PositionIterator::isCandidate() const
@@ -151,7 +157,7 @@ bool PositionIterator::isCandidate() const
return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_parent->parent());
if (!m_parent->hasTagName(htmlTag) && renderer->isBlockFlow() && !Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer) &&
- (static_cast<RenderBlock*>(renderer)->height() || m_parent->hasTagName(bodyTag)))
+ (toRenderBlock(renderer)->height() || m_parent->hasTagName(bodyTag)))
return atStartOfNode() && !Position::nodeIsUserSelectNone(m_parent);
return false;
diff --git a/WebCore/dom/PositionIterator.h b/WebCore/dom/PositionIterator.h
index 54f5020..98a2ccb 100644
--- a/WebCore/dom/PositionIterator.h
+++ b/WebCore/dom/PositionIterator.h
@@ -45,8 +45,8 @@ public:
PositionIterator(const Position& pos)
: m_parent(pos.node())
- , m_child(m_parent->childNode(pos.offset()))
- , m_offset(m_child ? 0 : pos.offset())
+ , m_child(m_parent->childNode(pos.m_offset))
+ , m_offset(m_child ? 0 : pos.m_offset)
{
}
operator Position() const;
diff --git a/WebCore/dom/QualifiedName.cpp b/WebCore/dom/QualifiedName.cpp
index f40f398..5953b97 100644
--- a/WebCore/dom/QualifiedName.cpp
+++ b/WebCore/dom/QualifiedName.cpp
@@ -1,7 +1,5 @@
-/**
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 2005, 2006 Apple Computer, Inc.
+/*
+ * Copyright (C) 2005, 2006, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -54,7 +52,6 @@ struct QNameComponentsTranslator {
static QNameSet* gNameCache;
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- : m_impl(0)
{
if (!gNameCache)
gNameCache = new QNameSet;
@@ -65,28 +62,6 @@ QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const
m_impl->ref();
}
-QualifiedName::~QualifiedName()
-{
- deref();
-}
-
-QualifiedName::QualifiedName(const QualifiedName& other)
-{
- m_impl = other.m_impl;
- ref();
-}
-
-const QualifiedName& QualifiedName::operator=(const QualifiedName& other)
-{
- if (m_impl != other.m_impl) {
- deref();
- m_impl = other.m_impl;
- ref();
- }
-
- return *this;
-}
-
void QualifiedName::deref()
{
#ifdef QNAME_DEFAULT_CONSTRUCTOR
@@ -99,12 +74,6 @@ void QualifiedName::deref()
m_impl->deref();
}
-void QualifiedName::setPrefix(const AtomicString& prefix)
-{
- QualifiedName other(prefix, localName(), namespaceURI());
- *this = other;
-}
-
String QualifiedName::toString() const
{
String local = localName();
diff --git a/WebCore/dom/QualifiedName.h b/WebCore/dom/QualifiedName.h
index d09cdea..13747a9 100644
--- a/WebCore/dom/QualifiedName.h
+++ b/WebCore/dom/QualifiedName.h
@@ -1,7 +1,5 @@
/*
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 2005 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,6 +17,7 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#ifndef QualifiedName_h
#define QualifiedName_h
@@ -26,7 +25,7 @@
#include <wtf/HashFunctions.h>
namespace WebCore {
-
+
struct QualifiedNameComponents {
StringImpl* m_prefix;
StringImpl* m_localName;
@@ -37,32 +36,32 @@ class QualifiedName {
public:
class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
public:
- static PassRefPtr<QualifiedNameImpl> create(const AtomicString& p, const AtomicString& l, const AtomicString& n)
+ static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
{
- return adoptRef(new QualifiedNameImpl(p, l, n));
+ return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI));
}
-
+
AtomicString m_prefix;
AtomicString m_localName;
AtomicString m_namespace;
private:
- QualifiedNameImpl(const AtomicString& p, const AtomicString& l, const AtomicString& n)
- : m_prefix(p)
- , m_localName(l)
- , m_namespace(n)
+ QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
+ : m_prefix(prefix)
+ , m_localName(localName)
+ , m_namespace(namespaceURI.isEmpty() ? nullAtom : namespaceURI)
{
}
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
- ~QualifiedName();
+ ~QualifiedName() { deref(); }
#ifdef QNAME_DEFAULT_CONSTRUCTOR
QualifiedName() : m_impl(0) { }
#endif
- QualifiedName(const QualifiedName&);
- const QualifiedName& operator=(const QualifiedName&);
+ QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); }
+ const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; }
bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; }
bool operator!=(const QualifiedName& other) const { return !(*this == other); }
@@ -70,7 +69,7 @@ public:
bool matches(const QualifiedName& other) const { return m_impl == other.m_impl || (localName() == other.localName() && namespaceURI() == other.namespaceURI()); }
bool hasPrefix() const { return m_impl->m_prefix != nullAtom; }
- void setPrefix(const AtomicString& prefix);
+ void setPrefix(const AtomicString& prefix) { *this = QualifiedName(prefix, localName(), namespaceURI()); }
const AtomicString& prefix() const { return m_impl->m_prefix; }
const AtomicString& localName() const { return m_impl->m_localName; }
@@ -84,7 +83,7 @@ public:
static void init();
private:
- void ref() { m_impl->ref(); }
+ void ref() const { m_impl->ref(); }
void deref();
QualifiedNameImpl* m_impl;
@@ -100,7 +99,6 @@ inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a
inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
inline bool operator!=(const QualifiedName& q, const AtomicString& a) { return a != q.localName(); }
-
inline unsigned hashComponents(const QualifiedNameComponents& buf)
{
ASSERT(sizeof(QualifiedNameComponents) % (sizeof(uint16_t) * 2) == 0);
@@ -154,6 +152,7 @@ struct QualifiedNameHash {
namespace WTF {
template<typename T> struct DefaultHash;
+
template<> struct DefaultHash<WebCore::QualifiedName> {
typedef WebCore::QualifiedNameHash Hash;
};
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index b5afdd1..34b1d21 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -89,7 +89,7 @@ PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, PassRefPtr<N
PassRefPtr<Range> Range::create(PassRefPtr<Document> ownerDocument, const Position& start, const Position& end)
{
- return adoptRef(new Range(ownerDocument, start.container.get(), start.posOffset, end.container.get(), end.posOffset));
+ return adoptRef(new Range(ownerDocument, start.node(), start.m_offset, end.node(), end.m_offset));
}
Range::~Range()
@@ -264,17 +264,17 @@ void Range::collapse(bool toStart, ExceptionCode& ec)
bool Range::isPointInRange(Node* refNode, int offset, ExceptionCode& ec)
{
- if (!refNode) {
- ec = NOT_FOUND_ERR;
+ if (!m_start.container()) {
+ ec = INVALID_STATE_ERR;
return false;
}
- if (!m_start.container() && refNode->attached()) {
- ec = INVALID_STATE_ERR;
+ if (!refNode) {
+ ec = HIERARCHY_REQUEST_ERR;
return false;
}
- if (m_start.container() && !refNode->attached()) {
+ if (!refNode->attached()) {
// Firefox doesn't throw an exception for this case; it returns false.
return false;
}
@@ -299,22 +299,17 @@ short Range::comparePoint(Node* refNode, int offset, ExceptionCode& ec)
// This method returns -1, 0 or 1 depending on if the point described by the
// refNode node and an offset within the node is before, same as, or after the range respectively.
- if (!refNode) {
- ec = NOT_FOUND_ERR;
- return 0;
- }
-
- if (!m_start.container() && refNode->attached()) {
+ if (!m_start.container()) {
ec = INVALID_STATE_ERR;
return 0;
}
- if (m_start.container() && !refNode->attached()) {
- // Firefox doesn't throw an exception for this case; it returns -1.
- return -1;
+ if (!refNode) {
+ ec = HIERARCHY_REQUEST_ERR;
+ return 0;
}
- if (refNode->document() != m_ownerDocument) {
+ if (!refNode->attached() || refNode->document() != m_ownerDocument) {
ec = WRONG_DOCUMENT_ERR;
return 0;
}
@@ -441,11 +436,14 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containerB, int offsetB)
{
- ASSERT(containerA && containerB);
+ ASSERT(containerA);
+ ASSERT(containerB);
+
if (!containerA)
return -1;
if (!containerB)
return 1;
+
// see DOM2 traversal & range section 2.5
// case 1: both points have the same container
@@ -529,7 +527,7 @@ short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containe
short Range::compareBoundaryPoints(const Position& a, const Position& b)
{
- return compareBoundaryPoints(a.container.get(), a.posOffset, b.container.get(), b.posOffset);
+ return compareBoundaryPoints(a.node(), a.m_offset, b.node(), b.m_offset);
}
bool Range::boundaryPointsValid() const
@@ -556,8 +554,8 @@ bool Range::intersectsNode(Node* refNode, ExceptionCode& ec)
return false;
}
- if (!m_start.container() && refNode->attached()
- || m_start.container() && !refNode->attached()
+ if ((!m_start.container() && refNode->attached())
+ || (m_start.container() && !refNode->attached())
|| refNode->document() != m_ownerDocument) {
// Firefox doesn't throw an exception for these cases; it returns false.
return false;
@@ -842,6 +840,17 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
processEnd = processEnd->parentNode();
}
+ // Collapse the range, making sure that the result is not within a node that was partially selected.
+ if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
+ if (partialStart)
+ setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec);
+ else if (partialEnd)
+ setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec);
+ if (ec)
+ return 0;
+ m_end = m_start;
+ }
+
// Now add leftContents, stuff in between, and rightContents to the fragment
// (or just delete the stuff in between)
@@ -1592,13 +1601,16 @@ void Range::addLineBoxRects(Vector<IntRect>& rects, bool useSelectionHeight)
if (!start || !end)
return;
- RenderObject* stop = end->nextInPreOrderAfterChildren();
+ RenderObject* stop = end->childAt(m_end.offset());
+ if (!stop)
+ stop = end->nextInPreOrderAfterChildren();
+
for (RenderObject* r = start; r && r != stop; r = r->nextInPreOrder()) {
// only ask leaf render objects for their line box rects
if (!r->firstChild()) {
int startOffset = r == start ? m_start.offset() : 0;
int endOffset = r == end ? m_end.offset() : INT_MAX;
- r->addLineBoxRects(rects, startOffset, endOffset, useSelectionHeight);
+ r->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight);
}
}
}
diff --git a/WebCore/dom/RangeBoundaryPoint.h b/WebCore/dom/RangeBoundaryPoint.h
index 4cb7bf5..e39454e 100644
--- a/WebCore/dom/RangeBoundaryPoint.h
+++ b/WebCore/dom/RangeBoundaryPoint.h
@@ -55,6 +55,10 @@ public:
private:
static const int invalidOffset = -1;
+ // FIXME: RangeBoundaryPoint is the only file to ever use -1 as am expected offset for Position
+ // RangeBoundaryPoint currently needs to store a Position object to make the
+ // position() function be able to return a const& (and thus avoid ref-churn).
+
mutable Position m_position;
Node* m_childBefore;
};
@@ -72,7 +76,7 @@ inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
inline Node* RangeBoundaryPoint::container() const
{
- return m_position.container.get();
+ return m_position.node();
}
inline Node* RangeBoundaryPoint::childBefore() const
@@ -82,16 +86,16 @@ inline Node* RangeBoundaryPoint::childBefore() const
inline const Position& RangeBoundaryPoint::position() const
{
- if (m_position.posOffset >= 0)
+ if (m_position.m_offset >= 0)
return m_position;
ASSERT(m_childBefore);
- m_position.posOffset = m_childBefore->nodeIndex() + 1;
+ m_position.m_offset = m_childBefore->nodeIndex() + 1;
return m_position;
}
inline int RangeBoundaryPoint::offset() const
{
- return position().posOffset;
+ return position().m_offset;
}
inline void RangeBoundaryPoint::clear()
@@ -104,63 +108,59 @@ inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node
{
ASSERT(offset >= 0);
ASSERT(childBefore == (offset ? container->childNode(offset - 1) : 0));
- m_position.container = container;
- m_position.posOffset = offset;
+ m_position.moveToPosition(container, offset);
m_childBefore = childBefore;
}
inline void RangeBoundaryPoint::setOffset(int offset)
{
- ASSERT(m_position.container);
- ASSERT(m_position.container->offsetInCharacters());
- ASSERT(m_position.posOffset >= 0);
+ ASSERT(m_position.node());
+ ASSERT(m_position.node()->offsetInCharacters());
+ ASSERT(m_position.m_offset >= 0);
ASSERT(!m_childBefore);
- m_position.posOffset = offset;
+ m_position.moveToOffset(offset);
}
inline void RangeBoundaryPoint::setToChild(Node* child)
{
ASSERT(child);
ASSERT(child->parentNode());
- m_position.container = child->parentNode();
m_childBefore = child->previousSibling();
- m_position.posOffset = m_childBefore ? invalidOffset : 0;
+ m_position.moveToPosition(child->parentNode(), m_childBefore ? invalidOffset : 0);
}
inline void RangeBoundaryPoint::setToStart(PassRefPtr<Node> container)
{
ASSERT(container);
- m_position.container = container;
- m_position.posOffset = 0;
+ m_position.moveToPosition(container, 0);
m_childBefore = 0;
}
inline void RangeBoundaryPoint::setToEnd(PassRefPtr<Node> container)
{
ASSERT(container);
- m_position.container = container;
- if (m_position.container->offsetInCharacters()) {
- m_position.posOffset = m_position.container->maxCharacterOffset();
+ if (container->offsetInCharacters()) {
+ m_position.moveToPosition(container, container->maxCharacterOffset());
m_childBefore = 0;
} else {
- m_childBefore = m_position.container->lastChild();
- m_position.posOffset = m_childBefore ? invalidOffset : 0;
+ m_childBefore = container->lastChild();
+ m_position.moveToPosition(container, m_childBefore ? invalidOffset : 0);
}
}
inline void RangeBoundaryPoint::childBeforeWillBeRemoved()
{
- ASSERT(m_position.posOffset);
+ ASSERT(m_position.m_offset);
m_childBefore = m_childBefore->previousSibling();
if (!m_childBefore)
- m_position.posOffset = 0;
- else if (m_position.posOffset > 0)
- --m_position.posOffset;
+ m_position.m_offset = 0;
+ else if (m_position.m_offset > 0)
+ --m_position.m_offset;
}
inline void RangeBoundaryPoint::invalidateOffset() const
{
- m_position.posOffset = invalidOffset;
+ m_position.m_offset = invalidOffset;
}
inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
diff --git a/WebCore/dom/ScriptExecutionContext.cpp b/WebCore/dom/ScriptExecutionContext.cpp
index 1d1aaec..c518734 100644
--- a/WebCore/dom/ScriptExecutionContext.cpp
+++ b/WebCore/dom/ScriptExecutionContext.cpp
@@ -175,6 +175,22 @@ void ScriptExecutionContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securi
m_securityOrigin = securityOrigin;
}
+void ScriptExecutionContext::addTimeout(int timeoutId, DOMTimer* timer)
+{
+ ASSERT(!m_timeouts.contains(timeoutId));
+ m_timeouts.set(timeoutId, timer);
+}
+
+void ScriptExecutionContext::removeTimeout(int timeoutId)
+{
+ m_timeouts.remove(timeoutId);
+}
+
+DOMTimer* ScriptExecutionContext::findTimeout(int timeoutId)
+{
+ return m_timeouts.get(timeoutId);
+}
+
ScriptExecutionContext::Task::~Task()
{
}
diff --git a/WebCore/dom/ScriptExecutionContext.h b/WebCore/dom/ScriptExecutionContext.h
index 6f09e1a..7b2f36a 100644
--- a/WebCore/dom/ScriptExecutionContext.h
+++ b/WebCore/dom/ScriptExecutionContext.h
@@ -37,6 +37,7 @@
namespace WebCore {
class ActiveDOMObject;
+ class DOMTimer;
class MessagePort;
class SecurityOrigin;
class ScriptString;
@@ -58,12 +59,15 @@ namespace WebCore {
const KURL& url() const { return virtualURL(); }
KURL completeURL(const String& url) const { return virtualCompleteURL(url); }
+ virtual String userAgent(const KURL&) const = 0;
+
SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL) = 0;
virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL) = 0;
virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString) = 0;
-
+ virtual void scriptImported(unsigned long, const String&) = 0;
+
// Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
bool canSuspendActiveDOMObjects();
// Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
@@ -94,6 +98,10 @@ namespace WebCore {
virtual void postTask(PassRefPtr<Task>) = 0; // Executes the task on context's thread asynchronously.
+ void addTimeout(int timeoutId, DOMTimer*);
+ void removeTimeout(int timeoutId);
+ DOMTimer* findTimeout(int timeoutId);
+
protected:
// Explicitly override the security origin for this script context.
// Note: It is dangerous to change the security origin of a script context
@@ -110,6 +118,8 @@ namespace WebCore {
HashMap<ActiveDOMObject*, void*> m_activeDOMObjects;
+ HashMap<int, DOMTimer*> m_timeouts;
+
virtual void refScriptExecutionContext() = 0;
virtual void derefScriptExecutionContext() = 0;
};
diff --git a/WebCore/dom/Text.cpp b/WebCore/dom/Text.cpp
index 6277ff6..5cb1af5 100644
--- a/WebCore/dom/Text.cpp
+++ b/WebCore/dom/Text.cpp
@@ -29,6 +29,7 @@
#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
+#include "SVGNames.h"
#endif
#if ENABLE(WML)
@@ -233,7 +234,11 @@ bool Text::rendererIsNeeded(RenderStyle *style)
RenderObject *Text::createRenderer(RenderArena* arena, RenderStyle*)
{
#if ENABLE(SVG)
- if (parentNode()->isSVGElement())
+ if (parentNode()->isSVGElement()
+#if ENABLE(SVG_FOREIGN_OBJECT)
+ && !parentNode()->hasTagName(SVGNames::foreignObjectTag)
+#endif
+ )
return new (arena) RenderSVGInlineText(this, m_data);
#endif
diff --git a/WebCore/dom/Tokenizer.h b/WebCore/dom/Tokenizer.h
index 1ed9484..f9c6dc4 100644
--- a/WebCore/dom/Tokenizer.h
+++ b/WebCore/dom/Tokenizer.h
@@ -37,7 +37,7 @@ namespace WebCore {
// received during executing a script must be appended, hence the
// extra bool to be able to distinguish between both cases.
// document.write() always uses false, while the loader uses true.
- virtual bool write(const SegmentedString&, bool appendData) = 0;
+ virtual void write(const SegmentedString&, bool appendData) = 0;
virtual void finish() = 0;
virtual bool isWaitingForScripts() const = 0;
virtual void stopParsing() { m_parserStopped = true; }
diff --git a/WebCore/dom/WheelEvent.cpp b/WebCore/dom/WheelEvent.cpp
index a3c806e..2039541 100644
--- a/WebCore/dom/WheelEvent.cpp
+++ b/WebCore/dom/WheelEvent.cpp
@@ -34,20 +34,15 @@ WheelEvent::WheelEvent()
{
}
-WheelEvent::WheelEvent(float wheelDeltaX, float wheelDeltaY, PassRefPtr<AbstractView> view,
+WheelEvent::WheelEvent(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView> view,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
: MouseRelatedEvent(eventNames().mousewheelEvent,
true, true, view, 0, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey)
- , m_wheelDeltaX(lroundf(wheelDeltaX) * 120)
- , m_wheelDeltaY(lroundf(wheelDeltaY) * 120) // Normalize to the Windows 120 multiple
+ , m_wheelDeltaX(lroundf(wheelTicksX * 120))
+ , m_wheelDeltaY(lroundf(wheelTicksY * 120)) // Normalize to the Windows 120 multiple
{
- // Rounding delta to zero makes no sense and breaks Google Maps, <http://bugs.webkit.org/show_bug.cgi?id=16078>.
- if (wheelDeltaX && !m_wheelDeltaX)
- m_wheelDeltaX = (wheelDeltaX > 0) ? 120 : -120;
- if (wheelDeltaY && !m_wheelDeltaY)
- m_wheelDeltaY = (wheelDeltaY > 0) ? 120 : -120;
}
void WheelEvent::initWheelEvent(int wheelDeltaX, int wheelDeltaY, PassRefPtr<AbstractView> view,
diff --git a/WebCore/dom/WheelEvent.h b/WebCore/dom/WheelEvent.h
index 015796e..04d5421 100644
--- a/WebCore/dom/WheelEvent.h
+++ b/WebCore/dom/WheelEvent.h
@@ -35,11 +35,11 @@ namespace WebCore {
{
return adoptRef(new WheelEvent);
}
- static PassRefPtr<WheelEvent> create(float wheelDeltaX, float wheelDeltaY, PassRefPtr<AbstractView> view,
+ static PassRefPtr<WheelEvent> create(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView> view,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
- return adoptRef(new WheelEvent(wheelDeltaX, wheelDeltaY, view, screenX, screenY, pageX, pageY,
+ return adoptRef(new WheelEvent(wheelTicksX, wheelTicksY, view, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey));
}
@@ -56,7 +56,7 @@ namespace WebCore {
private:
WheelEvent();
- WheelEvent(float wheelDeltaX, float wheelDeltaY, PassRefPtr<AbstractView>,
+ WheelEvent(float wheelTicksX, float wheelTicksY, PassRefPtr<AbstractView>,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
diff --git a/WebCore/dom/XMLTokenizer.cpp b/WebCore/dom/XMLTokenizer.cpp
index 6f57a46..1415922 100644
--- a/WebCore/dom/XMLTokenizer.cpp
+++ b/WebCore/dom/XMLTokenizer.cpp
@@ -64,6 +64,8 @@ using namespace std;
namespace WebCore {
+using namespace HTMLNames;
+
const int maxErrors = 25;
#if ENABLE(WML)
@@ -87,7 +89,7 @@ void XMLTokenizer::setCurrentNode(Node* n)
m_currentNodeIsReferenced = nodeNeedsReference;
}
-bool XMLTokenizer::write(const SegmentedString& s, bool /*appendData*/)
+void XMLTokenizer::write(const SegmentedString& s, bool /*appendData*/)
{
String parseString = s.toString();
@@ -95,15 +97,14 @@ bool XMLTokenizer::write(const SegmentedString& s, bool /*appendData*/)
m_originalSourceForTransform += parseString;
if (m_parserStopped || m_sawXSLTransform)
- return false;
+ return;
if (m_parserPaused) {
m_pendingSrc.append(s);
- return false;
+ return;
}
doWrite(s.toString());
- return false;
}
void XMLTokenizer::handleError(ErrorType type, const char* m, int lineNumber, int columnNumber)
@@ -200,20 +201,20 @@ void XMLTokenizer::finish()
static inline RefPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
{
- ExceptionCode ec = 0;
- RefPtr<Element> reportElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "parsererror", ec);
- reportElement->setAttribute(HTMLNames::styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
+ RefPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), false);
+ reportElement->setAttribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
- RefPtr<Element> h3 = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "h3", ec);
+ ExceptionCode ec = 0;
+ RefPtr<Element> h3 = doc->createElement(h3Tag, false);
reportElement->appendChild(h3.get(), ec);
h3->appendChild(doc->createTextNode("This page contains the following errors:"), ec);
-
- RefPtr<Element> fixed = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "div", ec);
+
+ RefPtr<Element> fixed = doc->createElement(divTag, false);
reportElement->appendChild(fixed.get(), ec);
- fixed->setAttribute(HTMLNames::styleAttr, "font-family:monospace;font-size:12px");
+ fixed->setAttribute(styleAttr, "font-family:monospace;font-size:12px");
fixed->appendChild(doc->createTextNode(errorMessages), ec);
-
- h3 = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "h3", ec);
+
+ h3 = doc->createElement(h3Tag, false);
reportElement->appendChild(h3.get(), ec);
h3->appendChild(doc->createTextNode("Below is a rendering of the page up to the first error."), ec);
@@ -235,16 +236,16 @@ void XMLTokenizer::insertErrorMessageBlock()
Document* doc = m_doc;
Node* documentElement = doc->documentElement();
if (!documentElement) {
- RefPtr<Node> rootElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "html", ec);
+ RefPtr<Node> rootElement = doc->createElement(htmlTag, false);
doc->appendChild(rootElement, ec);
- RefPtr<Node> body = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "body", ec);
+ RefPtr<Node> body = doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
documentElement = body.get();
}
#if ENABLE(SVG)
else if (documentElement->namespaceURI() == SVGNames::svgNamespaceURI) {
- RefPtr<Node> rootElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "html", ec);
- RefPtr<Node> body = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "body", ec);
+ RefPtr<Node> rootElement = doc->createElement(htmlTag, false);
+ RefPtr<Node> body = doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
body->appendChild(documentElement, ec);
doc->appendChild(rootElement.get(), ec);
@@ -253,8 +254,8 @@ void XMLTokenizer::insertErrorMessageBlock()
#endif
#if ENABLE(WML)
else if (isWMLDocument()) {
- RefPtr<Node> rootElement = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "html", ec);
- RefPtr<Node> body = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "body", ec);
+ RefPtr<Node> rootElement = doc->createElement(htmlTag, false);
+ RefPtr<Node> body = doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
body->appendChild(documentElement, ec);
doc->appendChild(rootElement.get(), ec);
@@ -266,9 +267,9 @@ void XMLTokenizer::insertErrorMessageBlock()
documentElement->insertBefore(reportElement, documentElement->firstChild(), ec);
#if ENABLE(XSLT)
if (doc->transformSourceDocument()) {
- RefPtr<Element> par = doc->createElementNS(HTMLNames::xhtmlNamespaceURI, "p", ec);
+ RefPtr<Element> par = doc->createElement(pTag, false);
reportElement->appendChild(par, ec);
- par->setAttribute(HTMLNames::styleAttr, "white-space: normal");
+ par->setAttribute(styleAttr, "white-space: normal");
par->appendChild(doc->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."), ec);
}
#endif
diff --git a/WebCore/dom/XMLTokenizer.h b/WebCore/dom/XMLTokenizer.h
index c5c0847..8f35c63 100644
--- a/WebCore/dom/XMLTokenizer.h
+++ b/WebCore/dom/XMLTokenizer.h
@@ -169,7 +169,7 @@ namespace WebCore {
enum ErrorType { warning, nonFatal, fatal };
// from Tokenizer
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
virtual bool isWaitingForScripts() const;
virtual void stopParsing();
diff --git a/WebCore/dom/XMLTokenizerLibxml2.cpp b/WebCore/dom/XMLTokenizerLibxml2.cpp
index 24ea6e8..77a1afd 100644
--- a/WebCore/dom/XMLTokenizerLibxml2.cpp
+++ b/WebCore/dom/XMLTokenizerLibxml2.cpp
@@ -395,7 +395,7 @@ static void* openFunc(const char* uri)
ASSERT(globalDocLoader);
ASSERT(currentThread() == libxmlLoaderThread);
- KURL url(uri);
+ KURL url(KURL(), uri);
if (!shouldAllowExternalLoad(url))
return &globalDescriptor;
@@ -706,7 +706,8 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
nb_attributes, nb_defaulted, libxmlAttributes);
return;
}
-
+
+ bool isFirstElement = !m_sawFirstElement;
m_sawFirstElement = true;
exitText();
@@ -722,14 +723,14 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
uri = m_defaultNamespaceURI;
}
- ExceptionCode ec = 0;
QualifiedName qName(prefix, localName, uri);
- RefPtr<Element> newElement = m_doc->createElement(qName, true, ec);
+ RefPtr<Element> newElement = m_doc->createElement(qName, true);
if (!newElement) {
stopParsing();
return;
}
+ ExceptionCode ec = 0;
handleElementNamespaces(newElement.get(), libxmlNamespaces, nb_namespaces, ec);
if (ec) {
stopParsing();
@@ -763,6 +764,9 @@ void XMLTokenizer::startElementNs(const xmlChar* xmlLocalName, const xmlChar* xm
setCurrentNode(newElement.get());
if (m_view && !newElement->attached())
newElement->attach();
+
+ if (isFirstElement && m_doc->frame())
+ m_doc->frame()->loader()->dispatchDocumentElementAvailable();
}
void XMLTokenizer::endElementNs()
diff --git a/WebCore/dom/XMLTokenizerQt.cpp b/WebCore/dom/XMLTokenizerQt.cpp
index ce50126..68bc17b 100644
--- a/WebCore/dom/XMLTokenizerQt.cpp
+++ b/WebCore/dom/XMLTokenizerQt.cpp
@@ -507,6 +507,8 @@ void XMLTokenizer::parseStartElement()
m_sawFirstElement = true;
return;
}
+
+ bool isFirstElement = !m_sawFirstElement;
m_sawFirstElement = true;
exitText();
@@ -520,14 +522,14 @@ void XMLTokenizer::parseStartElement()
uri = m_defaultNamespaceURI;
}
- ExceptionCode ec = 0;
QualifiedName qName(prefix, localName, uri);
- RefPtr<Element> newElement = m_doc->createElement(qName, true, ec);
+ RefPtr<Element> newElement = m_doc->createElement(qName, true);
if (!newElement) {
stopParsing();
return;
}
+ ExceptionCode ec = 0;
handleElementNamespaces(newElement.get(), m_stream.namespaceDeclarations(), ec);
if (ec) {
stopParsing();
@@ -552,6 +554,9 @@ void XMLTokenizer::parseStartElement()
setCurrentNode(newElement.get());
if (m_view && !newElement->attached())
newElement->attach();
+
+ if (isFirstElement && m_doc->frame())
+ m_doc->frame()->loader()->dispatchDocumentElementAvailable();
}
void XMLTokenizer::parseEndElement()
diff --git a/WebCore/dom/make_names.pl b/WebCore/dom/make_names.pl
index f9eba88..f2a7a76 100755
--- a/WebCore/dom/make_names.pl
+++ b/WebCore/dom/make_names.pl
@@ -93,6 +93,7 @@ sub initializeTagPropertyHash
'interfaceName' => defaultInterfaceName($_[0]),
# By default, the JSInterfaceName is the same as the interfaceName.
'JSInterfaceName' => defaultInterfaceName($_[0]),
+ 'mapToTagName' => '',
'wrapperOnlyIfMediaIsAvailable' => 0);
}
@@ -217,47 +218,126 @@ sub printMacros
}
}
-sub printConstructors
+sub usesDefaultWrapper
{
- my $F = shift;
+ my $tagName = shift;
+ return $tagName eq $parameters{'namespace'} . "Element";
+}
- print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
- for my $name (sort keys %tags) {
- my $ucName = $tags{$name}{'interfaceName'};
-
- # Print the method signature avoiding unused arguments' name.
- print F "static PassRefPtr<$parameters{'namespace'}Element> ${name}Constructor(Document* doc";
- if ($parameters{'namespace'} eq "HTML") {
- print F ", HTMLFormElement* formElement";
- if ($tags{$name}{'constructorNeedsFormElement'}) {
- print F " formElement";
- }
- }
- print F ", bool";
- if ($tags{$name}{'constructorNeedsCreatedByParser'}) {
- print F " createdByParser";
+# Build a direct mapping from the tags to the Element to create, excluding
+# Element that have not constructor.
+sub buildConstructorMap
+{
+ my %tagConstructorMap = ();
+ for my $tagName (keys %tags) {
+ my $interfaceName = $tags{$tagName}{'interfaceName'};
+ next if (usesDefaultWrapper($interfaceName));
+
+ if ($tags{$tagName}{'mapToTagName'}) {
+ die "Cannot handle multiple mapToTagName for $tagName\n" if $tags{$tags{$tagName}{'mapToTagName'}}{'mapToTagName'};
+ $interfaceName = $tags{ $tags{$tagName}{'mapToTagName'} }{'interfaceName'};
}
- print F ")\n{\n";
- # Now call the constructor with the right parameters.
- print F " return new ${ucName}($parameters{'namespace'}Names::${name}Tag, doc";
- if ($tags{$name}{'constructorNeedsFormElement'}) {
- print F ", formElement";
+ # Chop the string to keep the interesting part.
+ $interfaceName =~ s/$parameters{'namespace'}(.*)Element/$1/;
+ $tagConstructorMap{$tagName} = lc($interfaceName);
+ }
+
+ return %tagConstructorMap;
+}
+
+# Helper method that print the constructor's signature avoiding
+# unneeded arguments.
+sub printConstructorSignature
+{
+ my ($F, $tagName, $constructorName, $constructorTagName) = @_;
+
+ print F "static PassRefPtr<$parameters{'namespace'}Element> ${constructorName}Constructor(const QualifiedName& $constructorTagName, Document* doc";
+ if ($parameters{'namespace'} eq "HTML") {
+ print F ", HTMLFormElement*";
+ if ($tags{$tagName}{'constructorNeedsFormElement'}) {
+ print F " formElement";
}
- if ($tags{$name}{'constructorNeedsCreatedByParser'}) {
- print F ", createdByParser";
+ }
+ print F ", bool";
+ if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {
+ print F " createdByParser";
+ }
+ print F ")\n{\n";
+}
+
+# Helper method to dump the constructor interior and call the
+# Element constructor with the right arguments.
+# The variable names should be kept in sync with the previous method.
+sub printConstructorInterior
+{
+ my ($F, $tagName, $interfaceName, $constructorTagName) = @_;
+
+ # Handle media elements.
+ if ($tags{$tagName}{'wrapperOnlyIfMediaIsAvailable'}) {
+ print F <<END
+ if (!MediaPlayer::isAvailable())
+ return new HTMLElement($constructorTagName, doc);
+END
+;
+ }
+
+ # Now call the constructor with the right parameters.
+ print F " return new ${interfaceName}($constructorTagName, doc";
+ if ($tags{$tagName}{'constructorNeedsFormElement'}) {
+ print F ", formElement";
+ }
+ if ($tags{$tagName}{'constructorNeedsCreatedByParser'}) {
+ print F ", createdByParser";
+ }
+ print F ");\n}\n\n";
+}
+
+sub printConstructors
+{
+ my ($F, $tagConstructorMapRef) = @_;
+ my %tagConstructorMap = %$tagConstructorMapRef;
+
+ print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
+
+ # This is to avoid generating the same constructor several times.
+ my %uniqueTags = ();
+ for my $tagName (sort keys %tagConstructorMap) {
+ my $interfaceName = $tags{$tagName}{'interfaceName'};
+
+ # Ignore the mapped tag
+ # FIXME: It could be moved inside this loop but was split for readibility.
+ next if (defined($uniqueTags{$interfaceName}) || $tags{$tagName}{'mapToTagName'});
+
+ $uniqueTags{$interfaceName} = '1';
+
+ printConstructorSignature($F, $tagName, $tagConstructorMap{$tagName}, "tagName");
+ printConstructorInterior($F, $tagName, $interfaceName, "tagName");
+ }
+
+ # Mapped tag name uses a special wrapper to keep their prefix and namespaceURI while using the mapped localname.
+ for my $tagName (sort keys %tagConstructorMap) {
+ if ($tags{$tagName}{'mapToTagName'}) {
+ my $mappedName = $tags{$tagName}{'mapToTagName'};
+ printConstructorSignature($F, $mappedName, $mappedName . "To" . $tagName, "tagName");
+ printConstructorInterior($F, $mappedName, $tags{$mappedName}{'interfaceName'}, "QualifiedName(tagName.prefix(), ${mappedName}Tag.localName(), tagName.namespaceURI())");
}
- print F ");\n}\n\n";
}
+
print F "#endif\n" if $parameters{'guardFactoryWith'};
}
sub printFunctionInits
{
- my $F = shift;
+ my ($F, $tagConstructorMap) = @_;
+ my %tagConstructorMap = %$tagConstructorMap;
- for my $name (sort keys %tags) {
- print F " gFunctionMap->set($parameters{'namespace'}Names::${name}Tag.localName().impl(), ${name}Constructor);\n";
+ for my $tagName (sort keys %tagConstructorMap) {
+ if ($tags{$tagName}{'mapToTagName'}) {
+ print F " addTag(${tagName}Tag, $tags{$tagName}{'mapToTagName'}To${tagName}Constructor);\n";
+ } else {
+ print F " addTag(${tagName}Tag, $tagConstructorMap{$tagName}Constructor);\n";
+ }
}
}
@@ -568,34 +648,40 @@ printElementIncludes($F);
print F <<END
#include <wtf/HashMap.h>
-using namespace WebCore;
+namespace WebCore {
+
+using namespace $parameters{'namespace'}Names;
END
;
-print F "typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(Document*";
+print F "typedef PassRefPtr<$parameters{'namespace'}Element> (*ConstructorFunction)(const QualifiedName&, Document*";
if ($parameters{'namespace'} eq "HTML") {
- print F ", HTMLFormElement* formElement";
+ print F ", HTMLFormElement*";
}
print F ", bool createdByParser);\n";
-
print F <<END
-typedef WTF::HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
+typedef HashMap<AtomicStringImpl*, ConstructorFunction> FunctionMap;
static FunctionMap* gFunctionMap = 0;
-namespace WebCore {
-
END
;
-printConstructors($F);
+my %tagConstructorMap = buildConstructorMap();
+
+printConstructors($F, \%tagConstructorMap);
print F "#if $parameters{'guardFactoryWith'}\n" if $parameters{'guardFactoryWith'};
print F <<END
+static void addTag(const QualifiedName& tag, ConstructorFunction func)
+{
+ gFunctionMap->set(tag.localName().impl(), func);
+}
+
static inline void createFunctionMapIfNecessary()
{
if (gFunctionMap)
@@ -607,7 +693,7 @@ static inline void createFunctionMapIfNecessary()
END
;
-printFunctionInits($F);
+printFunctionInits($F, \%tagConstructorMap);
print F "}\n";
print F "#endif\n" if $parameters{'guardFactoryWith'};
@@ -627,12 +713,22 @@ print F <<END
if (!doc)
return 0;
+END
+;
+
+if ($parameters{'namespace'} ne "HTML") {
+print F <<END
#if ENABLE(DASHBOARD_SUPPORT)
Settings* settings = doc->settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode())
return 0;
#endif
+END
+;
+}
+
+print F <<END
createFunctionMapIfNecessary();
ConstructorFunction func = gFunctionMap->get(qName.localName().impl());
if (func)
@@ -640,9 +736,9 @@ END
;
if ($parameters{"namespace"} eq "HTML") {
- print F " return func(doc, formElement, createdByParser);\n";
+ print F " return func(qName, doc, formElement, createdByParser);\n";
} else {
- print F " return func(doc, createdByParser);\n";
+ print F " return func(qName, doc, createdByParser);\n";
}
print F " return new $parameters{'namespace'}Element(qName, doc);\n";
diff --git a/WebCore/editing/ApplyStyleCommand.cpp b/WebCore/editing/ApplyStyleCommand.cpp
index eca2999..d43cc81 100644
--- a/WebCore/editing/ApplyStyleCommand.cpp
+++ b/WebCore/editing/ApplyStyleCommand.cpp
@@ -32,6 +32,8 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "Document.h"
+#include "Editor.h"
+#include "Frame.h"
#include "HTMLElement.h"
#include "HTMLInterchange.h"
#include "HTMLNames.h"
@@ -50,12 +52,7 @@ using namespace HTMLNames;
class StyleChange {
public:
- enum ELegacyHTMLStyles { DoNotUseLegacyHTMLStyles, UseLegacyHTMLStyles };
-
- explicit StyleChange(CSSStyleDeclaration*, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
- StyleChange(CSSStyleDeclaration*, const Position&, ELegacyHTMLStyles usesLegacyStyles=UseLegacyHTMLStyles);
-
- static ELegacyHTMLStyles styleModeForParseMode(bool);
+ explicit StyleChange(CSSStyleDeclaration*, const Position&);
String cssStyle() const { return m_cssStyle; }
bool applyBold() const { return m_applyBold; }
@@ -70,8 +67,6 @@ public:
String fontFace() { return m_applyFontFace; }
String fontSize() { return m_applyFontSize; }
- bool usesLegacyStyles() const { return m_usesLegacyStyles; }
-
private:
void init(PassRefPtr<CSSStyleDeclaration>, const Position&);
bool checkForLegacyHTMLStyleChange(const CSSProperty*);
@@ -85,33 +80,26 @@ private:
String m_applyFontColor;
String m_applyFontFace;
String m_applyFontSize;
- bool m_usesLegacyStyles;
};
-
-StyleChange::StyleChange(CSSStyleDeclaration* style, ELegacyHTMLStyles usesLegacyStyles)
+StyleChange::StyleChange(CSSStyleDeclaration* style, const Position& position)
: m_applyBold(false)
, m_applyItalic(false)
, m_applySubscript(false)
, m_applySuperscript(false)
- , m_usesLegacyStyles(usesLegacyStyles)
-{
- init(style, Position());
-}
-
-StyleChange::StyleChange(CSSStyleDeclaration* style, const Position& position, ELegacyHTMLStyles usesLegacyStyles)
- : m_applyBold(false)
- , m_applyItalic(false)
- , m_applySubscript(false)
- , m_applySuperscript(false)
- , m_usesLegacyStyles(usesLegacyStyles)
{
init(style, position);
}
-void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position &position)
+void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position& position)
{
+ Document* document = position.node() ? position.node()->document() : 0;
+ if (!document || !document->frame())
+ return;
+
+ bool useHTMLFormattingTags = !document->frame()->editor()->shouldStyleWithCSS();
+
RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
String styleText("");
@@ -131,7 +119,7 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position &po
continue;
// If needed, figure out if this change is a legacy HTML style change.
- if (m_usesLegacyStyles && checkForLegacyHTMLStyleChange(property))
+ if (useHTMLFormattingTags && checkForLegacyHTMLStyleChange(property))
continue;
if (property->id() == CSSPropertyDirection) {
@@ -160,11 +148,6 @@ void StyleChange::init(PassRefPtr<CSSStyleDeclaration> style, const Position &po
m_cssStyle = styleText.stripWhiteSpace();
}
-StyleChange::ELegacyHTMLStyles StyleChange::styleModeForParseMode(bool isQuirksMode)
-{
- return isQuirksMode ? UseLegacyHTMLStyles : DoNotUseLegacyHTMLStyles;
-}
-
// This function is the mapping from CSS styles to styling tags (like font-weight: bold to <b>)
bool StyleChange::checkForLegacyHTMLStyleChange(const CSSProperty* property)
{
@@ -359,7 +342,7 @@ void ApplyStyleCommand::updateStartEnd(const Position& newStart, const Position&
if (!m_useEndingSelection && (newStart != m_start || newEnd != m_end))
m_useEndingSelection = true;
- setEndingSelection(Selection(newStart, newEnd, VP_DEFAULT_AFFINITY));
+ setEndingSelection(VisibleSelection(newStart, newEnd, VP_DEFAULT_AFFINITY));
m_start = newStart;
m_end = newEnd;
}
@@ -442,7 +425,7 @@ void ApplyStyleCommand::applyBlockStyle(CSSMutableStyleDeclaration *style)
VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next());
VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next());
while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) {
- StyleChange styleChange(style, paragraphStart.deepEquivalent(), StyleChange::styleModeForParseMode(document()->inCompatMode()));
+ StyleChange styleChange(style, paragraphStart.deepEquivalent());
if (styleChange.cssStyle().length() > 0 || m_removeOnly) {
RefPtr<Node> block = enclosingBlock(paragraphStart.deepEquivalent().node());
RefPtr<Node> newBlock = moveParagraphContentsToNewBlockIfNecessary(paragraphStart.deepEquivalent());
@@ -537,7 +520,7 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(CSSMutableStyleDeclaration
start = start.upstream(); // Move upstream to ensure we do not add redundant spans.
Node *startNode = start.node();
- if (startNode->isTextNode() && start.offset() >= caretMaxOffset(startNode)) // Move out of text node if range does not include its characters.
+ if (startNode->isTextNode() && start.m_offset >= caretMaxOffset(startNode)) // Move out of text node if range does not include its characters.
startNode = startNode->traverseNextNode();
// Store away font size before making any changes to the document.
@@ -885,17 +868,17 @@ void ApplyStyleCommand::applyInlineStyleToRange(CSSMutableStyleDeclaration* styl
bool rangeIsEmpty = false;
- if (start.offset() >= caretMaxOffset(start.node())) {
+ if (start.m_offset >= caretMaxOffset(start.node())) {
node = node->traverseNextNode();
Position newStart = Position(node, 0);
- if (Range::compareBoundaryPoints(end, newStart) < 0)
+ if (!node || Range::compareBoundaryPoints(end, newStart) < 0)
rangeIsEmpty = true;
}
if (!rangeIsEmpty) {
// pastEndNode is the node after the last fully selected node.
Node* pastEndNode = end.node();
- if (end.offset() >= caretMaxOffset(end.node()))
+ if (end.m_offset >= 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.
@@ -958,7 +941,8 @@ bool ApplyStyleCommand::isHTMLStyleNode(CSSMutableStyleDeclaration* style, HTMLE
for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {
switch ((*it).id()) {
case CSSPropertyFontWeight:
- if (elem->hasLocalName(bTag))
+ // IE inserts "strong" tags for execCommand("bold"), so we remove them, even though they're not strictly presentational
+ if (elem->hasLocalName(bTag) || elem->hasLocalName(strongTag))
return true;
break;
case CSSPropertyVerticalAlign:
@@ -966,7 +950,8 @@ bool ApplyStyleCommand::isHTMLStyleNode(CSSMutableStyleDeclaration* style, HTMLE
return true;
break;
case CSSPropertyFontStyle:
- if (elem->hasLocalName(iTag))
+ // IE inserts "em" tags for execCommand("italic"), so we remove them, even though they're not strictly presentational
+ if (elem->hasLocalName(iTag) || elem->hasLocalName(emTag))
return true;
}
}
@@ -1145,7 +1130,7 @@ void ApplyStyleCommand::applyTextDecorationStyle(Node *node, CSSMutableStyleDecl
HTMLElement *element = static_cast<HTMLElement *>(node);
- StyleChange styleChange(style, Position(element, 0), StyleChange::styleModeForParseMode(document()->inCompatMode()));
+ StyleChange styleChange(style, Position(element, 0));
if (styleChange.cssStyle().length() > 0) {
String cssText = styleChange.cssStyle();
CSSMutableStyleDeclaration *decl = element->inlineStyleDecl();
@@ -1234,13 +1219,13 @@ void ApplyStyleCommand::removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration>
Position s = start;
Position e = end;
- Node *node = start.node();
+ Node* node = start.node();
while (node) {
- Node *next = node->traverseNextNode();
+ Node* next = node->traverseNextNode();
if (node->isHTMLElement() && nodeFullySelected(node, start, end)) {
- HTMLElement *elem = static_cast<HTMLElement *>(node);
- Node *prev = elem->traversePreviousNodePostOrder();
- Node *next = elem->traverseNextNode();
+ HTMLElement* elem = static_cast<HTMLElement*>(node);
+ Node* prev = elem->traversePreviousNodePostOrder();
+ Node* next = elem->traverseNextNode();
if (m_styledInlineElement && elem->hasTagName(m_styledInlineElement->tagQName()))
removeNodePreservingChildren(elem);
if (isHTMLStyleNode(style.get(), elem))
@@ -1254,14 +1239,14 @@ void ApplyStyleCommand::removeInlineStyle(PassRefPtr<CSSMutableStyleDeclaration>
if (s.node() == elem) {
// Since elem must have been fully selected, and it is at the start
// of the selection, it is clear we can set the new s offset to 0.
- ASSERT(s.offset() <= caretMinOffset(s.node()));
+ ASSERT(s.m_offset <= caretMinOffset(s.node()));
s = Position(next, 0);
}
if (e.node() == elem) {
// Since elem must have been fully selected, and it is at the end
// of the selection, it is clear we can set the new e offset to
// the max range offset of prev.
- ASSERT(e.offset() >= maxRangeOffset(e.node()));
+ ASSERT(e.m_offset >= maxRangeOffset(e.node()));
e = Position(prev, maxRangeOffset(prev));
}
}
@@ -1282,7 +1267,7 @@ bool ApplyStyleCommand::nodeFullySelected(Node *node, const Position &start, con
ASSERT(node->isElementNode());
Position pos = Position(node, node->childNodeCount()).upstream();
- return Range::compareBoundaryPoints(node, 0, start.node(), start.offset()) >= 0 &&
+ return Range::compareBoundaryPoints(node, 0, start.node(), start.m_offset) >= 0 &&
Range::compareBoundaryPoints(pos, end) <= 0;
}
@@ -1293,7 +1278,7 @@ bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, c
Position pos = Position(node, node->childNodeCount()).upstream();
bool isFullyBeforeStart = Range::compareBoundaryPoints(pos, start) < 0;
- bool isFullyAfterEnd = Range::compareBoundaryPoints(node, 0, end.node(), end.offset()) > 0;
+ bool isFullyAfterEnd = Range::compareBoundaryPoints(node, 0, end.node(), end.m_offset) > 0;
return isFullyBeforeStart || isFullyAfterEnd;
}
@@ -1301,11 +1286,11 @@ bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, c
bool ApplyStyleCommand::splitTextAtStartIfNeeded(const Position &start, const Position &end)
{
- if (start.node()->isTextNode() && start.offset() > caretMinOffset(start.node()) && start.offset() < caretMaxOffset(start.node())) {
- int endOffsetAdjustment = start.node() == end.node() ? start.offset() : 0;
+ if (start.node()->isTextNode() && start.m_offset > caretMinOffset(start.node()) && start.m_offset < caretMaxOffset(start.node())) {
+ int endOffsetAdjustment = start.node() == end.node() ? start.m_offset : 0;
Text *text = static_cast<Text *>(start.node());
- splitTextNode(text, start.offset());
- updateStartEnd(Position(start.node(), 0), Position(end.node(), end.offset() - endOffsetAdjustment));
+ splitTextNode(text, start.m_offset);
+ updateStartEnd(Position(start.node(), 0), Position(end.node(), end.m_offset - endOffsetAdjustment));
return true;
}
return false;
@@ -1313,15 +1298,15 @@ bool ApplyStyleCommand::splitTextAtStartIfNeeded(const Position &start, const Po
bool ApplyStyleCommand::splitTextAtEndIfNeeded(const Position &start, const Position &end)
{
- if (end.node()->isTextNode() && end.offset() > caretMinOffset(end.node()) && end.offset() < caretMaxOffset(end.node())) {
+ if (end.node()->isTextNode() && end.m_offset > caretMinOffset(end.node()) && end.m_offset < caretMaxOffset(end.node())) {
Text *text = static_cast<Text *>(end.node());
- splitTextNode(text, end.offset());
+ splitTextNode(text, end.m_offset);
Node *prevNode = text->previousSibling();
ASSERT(prevNode);
Node *startNode = start.node() == end.node() ? prevNode : start.node();
ASSERT(startNode);
- updateStartEnd(Position(startNode, start.offset()), Position(prevNode, caretMaxOffset(prevNode)));
+ updateStartEnd(Position(startNode, start.m_offset), Position(prevNode, caretMaxOffset(prevNode)));
return true;
}
return false;
@@ -1329,12 +1314,12 @@ bool ApplyStyleCommand::splitTextAtEndIfNeeded(const Position &start, const Posi
bool ApplyStyleCommand::splitTextElementAtStartIfNeeded(const Position &start, const Position &end)
{
- if (start.node()->isTextNode() && start.offset() > caretMinOffset(start.node()) && start.offset() < caretMaxOffset(start.node())) {
- int endOffsetAdjustment = start.node() == end.node() ? start.offset() : 0;
+ if (start.node()->isTextNode() && start.m_offset > caretMinOffset(start.node()) && start.m_offset < caretMaxOffset(start.node())) {
+ int endOffsetAdjustment = start.node() == end.node() ? start.m_offset : 0;
Text *text = static_cast<Text *>(start.node());
- splitTextNodeContainingElement(text, start.offset());
+ splitTextNodeContainingElement(text, start.m_offset);
- updateStartEnd(Position(start.node()->parentNode(), start.node()->nodeIndex()), Position(end.node(), end.offset() - endOffsetAdjustment));
+ updateStartEnd(Position(start.node()->parentNode(), start.node()->nodeIndex()), Position(end.node(), end.m_offset - endOffsetAdjustment));
return true;
}
return false;
@@ -1342,15 +1327,15 @@ bool ApplyStyleCommand::splitTextElementAtStartIfNeeded(const Position &start, c
bool ApplyStyleCommand::splitTextElementAtEndIfNeeded(const Position &start, const Position &end)
{
- if (end.node()->isTextNode() && end.offset() > caretMinOffset(end.node()) && end.offset() < caretMaxOffset(end.node())) {
+ if (end.node()->isTextNode() && end.m_offset > caretMinOffset(end.node()) && end.m_offset < caretMaxOffset(end.node())) {
Text *text = static_cast<Text *>(end.node());
- splitTextNodeContainingElement(text, end.offset());
+ splitTextNodeContainingElement(text, end.m_offset);
Node *prevNode = text->parent()->previousSibling()->lastChild();
ASSERT(prevNode);
Node *startNode = start.node() == end.node() ? prevNode : start.node();
ASSERT(startNode);
- updateStartEnd(Position(startNode, start.offset()), Position(prevNode->parent(), prevNode->nodeIndex() + 1));
+ updateStartEnd(Position(startNode, start.m_offset), Position(prevNode->parent(), prevNode->nodeIndex() + 1));
return true;
}
return false;
@@ -1394,10 +1379,10 @@ static bool areIdenticalElements(Node *first, Node *second)
bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position &start, const Position &end)
{
Node *startNode = start.node();
- int startOffset = start.offset();
+ int startOffset = start.m_offset;
if (isAtomicNode(start.node())) {
- if (start.offset() != 0)
+ if (start.m_offset != 0)
return false;
// note: prior siblings could be unrendered elements. it's silly to miss the
@@ -1426,7 +1411,7 @@ bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position &start,
int startOffsetAdjustment = startChild->nodeIndex();
int endOffsetAdjustment = startNode == end.node() ? startOffsetAdjustment : 0;
- updateStartEnd(Position(startNode, startOffsetAdjustment), Position(end.node(), end.offset() + endOffsetAdjustment));
+ updateStartEnd(Position(startNode, startOffsetAdjustment), Position(end.node(), end.m_offset + endOffsetAdjustment));
return true;
}
@@ -1436,7 +1421,7 @@ bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position &start,
bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const Position &end)
{
Node *endNode = end.node();
- int endOffset = end.offset();
+ int endOffset = end.m_offset;
if (isAtomicNode(endNode)) {
if (endOffset < caretMaxOffset(endNode))
@@ -1466,7 +1451,7 @@ bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position &start, const
ASSERT(startNode);
int endOffset = nextChild ? nextChild->nodeIndex() : nextElement->childNodes()->length();
- updateStartEnd(Position(startNode, start.offset()), Position(nextElement, endOffset));
+ updateStartEnd(Position(startNode, start.m_offset), Position(nextElement, endOffset));
return true;
}
@@ -1495,7 +1480,7 @@ void ApplyStyleCommand::surroundNodeRangeWithElement(Node* startNode, Node* endN
}
// FIXME: We should probably call updateStartEnd if the start or end was in the node
// range so that the endingSelection() is canonicalized. See the comments at the end of
- // Selection::validate().
+ // VisibleSelection::validate().
}
void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElement* block)
@@ -1544,7 +1529,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style
if (m_removeOnly)
return;
- StyleChange styleChange(style, Position(startNode, 0), StyleChange::styleModeForParseMode(document()->inCompatMode()));
+ StyleChange styleChange(style, Position(startNode, 0));
//
// Font tags need to go outside of CSS so that CSS font sizes override leagcy font sizes.
@@ -1587,7 +1572,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclaration *style
surroundNodeRangeWithElement(startNode, endNode, createHTMLElement(document(), supTag));
if (m_styledInlineElement)
- surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElement());
+ surroundNodeRangeWithElement(startNode, endNode, m_styledInlineElement->cloneElementWithoutChildren());
}
float ApplyStyleCommand::computedFontSize(const Node *node)
@@ -1622,9 +1607,9 @@ void ApplyStyleCommand::joinChildTextNodes(Node *node, const Position &start, co
Text *childText = static_cast<Text *>(child);
Text *nextText = static_cast<Text *>(next);
if (next == start.node())
- newStart = Position(childText, childText->length() + start.offset());
+ newStart = Position(childText, childText->length() + start.m_offset);
if (next == end.node())
- newEnd = Position(childText, childText->length() + end.offset());
+ newEnd = Position(childText, childText->length() + end.m_offset);
String textToMove = nextText->data();
insertTextIntoNode(childText, childText->length(), textToMove);
removeNode(next);
diff --git a/WebCore/editing/BreakBlockquoteCommand.cpp b/WebCore/editing/BreakBlockquoteCommand.cpp
index 76a0890..2a513a5 100644
--- a/WebCore/editing/BreakBlockquoteCommand.cpp
+++ b/WebCore/editing/BreakBlockquoteCommand.cpp
@@ -72,7 +72,7 @@ void BreakBlockquoteCommand::doApply()
insertNodeAfter(breakNode.get(), topBlockquote);
if (isLastVisiblePositionInNode(visiblePos, topBlockquote)) {
- setEndingSelection(Selection(Position(breakNode.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(breakNode.get(), 0), DOWNSTREAM));
rebalanceWhitespace();
return;
}
@@ -85,19 +85,19 @@ void BreakBlockquoteCommand::doApply()
// Split at pos if in the middle of a text node.
if (startNode->isTextNode()) {
Text* textNode = static_cast<Text*>(startNode);
- if ((unsigned)pos.offset() >= textNode->length()) {
+ if ((unsigned)pos.m_offset >= textNode->length()) {
startNode = startNode->traverseNextNode();
ASSERT(startNode);
- } else if (pos.offset() > 0)
- splitTextNode(textNode, pos.offset());
- } else if (pos.offset() > 0) {
+ } else if (pos.m_offset > 0)
+ splitTextNode(textNode, pos.m_offset);
+ } else if (pos.m_offset > 0) {
startNode = startNode->traverseNextNode();
ASSERT(startNode);
}
// If there's nothing inside topBlockquote to move, we're finished.
if (!startNode->isDescendantOf(topBlockquote)) {
- setEndingSelection(Selection(VisiblePosition(Position(startNode, 0))));
+ setEndingSelection(VisibleSelection(VisiblePosition(Position(startNode, 0))));
return;
}
@@ -107,7 +107,7 @@ void BreakBlockquoteCommand::doApply()
ancestors.append(node);
// Insert a clone of the top blockquote after the break.
- RefPtr<Element> clonedBlockquote = topBlockquote->cloneElement();
+ RefPtr<Element> clonedBlockquote = topBlockquote->cloneElementWithoutChildren();
insertNodeAfter(clonedBlockquote.get(), breakNode.get());
// Clone startNode's ancestors into the cloned blockquote.
@@ -116,7 +116,7 @@ void BreakBlockquoteCommand::doApply()
// or clonedBlockquote if ancestors is empty).
RefPtr<Element> clonedAncestor = clonedBlockquote;
for (size_t i = ancestors.size(); i != 0; --i) {
- RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElement(); // shallow clone
+ RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren();
// Preserve list item numbering in cloned lists.
if (clonedChild->isElementNode() && clonedChild->hasTagName(olTag)) {
Node* listChildNode = i > 1 ? ancestors[i - 2] : startNode;
@@ -168,7 +168,7 @@ void BreakBlockquoteCommand::doApply()
addBlockPlaceholderIfNeeded(clonedBlockquote.get());
// Put the selection right before the break.
- setEndingSelection(Selection(Position(breakNode.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(breakNode.get(), 0), DOWNSTREAM));
rebalanceWhitespace();
}
diff --git a/WebCore/editing/CompositeEditCommand.cpp b/WebCore/editing/CompositeEditCommand.cpp
index 335f77e..9052582 100644
--- a/WebCore/editing/CompositeEditCommand.cpp
+++ b/WebCore/editing/CompositeEditCommand.cpp
@@ -157,7 +157,7 @@ void CompositeEditCommand::insertNodeAt(PassRefPtr<Node> insertChild, const Posi
// likewise for replaced elements, brs, etc.
Position p = rangeCompliantEquivalent(editingPosition);
Node* refChild = p.node();
- int offset = p.offset();
+ int offset = p.m_offset;
if (canHaveChildrenForEditing(refChild)) {
Node* child = refChild->firstChild();
@@ -171,6 +171,10 @@ void CompositeEditCommand::insertNodeAt(PassRefPtr<Node> insertChild, const Posi
insertNodeBefore(insertChild, refChild);
else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) {
splitTextNode(static_cast<Text *>(refChild), offset);
+
+ // Mutation events (bug 22634) from the text node insertion may have removed the refChild
+ if (!refChild->inDocument())
+ return;
insertNodeBefore(insertChild, refChild);
} else
insertNodeAfter(insertChild, refChild);
@@ -296,7 +300,7 @@ void CompositeEditCommand::inputText(const String& text, bool selectInsertedText
if (selectInsertedText) {
RefPtr<Range> selectedRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), startIndex, length);
- setEndingSelection(Selection(selectedRange.get()));
+ setEndingSelection(VisibleSelection(selectedRange.get()));
}
}
@@ -323,13 +327,13 @@ Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
Node* tabSpan = tabSpanNode(pos.node());
- if (pos.offset() <= caretMinOffset(pos.node()))
+ if (pos.m_offset <= caretMinOffset(pos.node()))
return positionBeforeNode(tabSpan);
- if (pos.offset() >= caretMaxOffset(pos.node()))
+ if (pos.m_offset >= caretMaxOffset(pos.node()))
return positionAfterNode(tabSpan);
- splitTextNodeContainingElement(static_cast<Text *>(pos.node()), pos.offset());
+ splitTextNodeContainingElement(static_cast<Text *>(pos.node()), pos.m_offset);
return positionBeforeNode(tabSpan);
}
@@ -345,7 +349,7 @@ void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
applyCommandToComposite(DeleteSelectionCommand::create(document(), smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements));
}
-void CompositeEditCommand::deleteSelection(const Selection &selection, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements)
+void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements)
{
if (selection.isRange())
applyCommandToComposite(DeleteSelectionCommand::create(selection, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements));
@@ -388,7 +392,7 @@ void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position)
String text = textNode->data();
ASSERT(!text.isEmpty());
- int offset = position.offset();
+ int offset = position.m_offset;
// If neither text[offset] nor text[offset - 1] are some form of whitespace, do nothing.
if (!isWhitespace(text[offset])) {
offset--;
@@ -445,14 +449,14 @@ void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& positio
Position previous(previousVisiblePos.deepEquivalent());
if (isCollapsibleWhitespace(previousVisiblePos.characterAfter()) && previous.node()->isTextNode() && !previous.node()->hasTagName(brTag))
- replaceTextInNode(static_cast<Text*>(previous.node()), previous.offset(), 1, nonBreakingSpaceString());
+ replaceTextInNode(static_cast<Text*>(previous.node()), previous.m_offset, 1, nonBreakingSpaceString());
if (isCollapsibleWhitespace(visiblePos.characterAfter()) && position.node()->isTextNode() && !position.node()->hasTagName(brTag))
- replaceTextInNode(static_cast<Text*>(position.node()), position.offset(), 1, nonBreakingSpaceString());
+ replaceTextInNode(static_cast<Text*>(position.node()), position.m_offset, 1, nonBreakingSpaceString());
}
void CompositeEditCommand::rebalanceWhitespace()
{
- Selection selection = endingSelection();
+ VisibleSelection selection = endingSelection();
if (selection.isNone())
return;
@@ -538,8 +542,8 @@ void CompositeEditCommand::deleteInsignificantText(const Position& start, const
next = node->traverseNextNode();
if (node->isTextNode()) {
Text* textNode = static_cast<Text*>(node);
- int startOffset = node == start.node() ? start.offset() : 0;
- int endOffset = node == end.node() ? end.offset() : textNode->length();
+ int startOffset = node == start.node() ? start.m_offset : 0;
+ int endOffset = node == end.node() ? end.m_offset : textNode->length();
deleteInsignificantText(textNode, startOffset, endOffset);
}
if (node == end.node())
@@ -592,7 +596,7 @@ PassRefPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* cont
// append the placeholder to make sure it follows
// any unrendered blocks
- RenderBlock* block = static_cast<RenderBlock*>(renderer);
+ RenderBlock* block = toRenderBlock(renderer);
if (block->height() == 0 || (block->isListItem() && block->isEmpty()))
return appendBlockPlaceholder(container);
@@ -612,10 +616,10 @@ void CompositeEditCommand::removePlaceholderAt(const VisiblePosition& visiblePos
// the start of a paragraph will render it superfluous.
// FIXME: This doesn't remove placeholders at the end of anonymous blocks.
if (isEndOfBlock(visiblePosition) && isStartOfParagraph(visiblePosition)) {
- if (p.node()->hasTagName(brTag) && p.offset() == 0)
+ if (p.node()->hasTagName(brTag) && p.m_offset == 0)
removeNode(p.node());
else if (lineBreakExistsAtPosition(visiblePosition))
- deleteTextFromNode(static_cast<Text*>(p.node()), p.offset(), 1);
+ deleteTextFromNode(static_cast<Text*>(p.node()), p.m_offset, 1);
}
}
@@ -655,11 +659,10 @@ PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar
// Perform some checks to see if we need to perform work in this function.
if (isBlock(upstreamStart.node())) {
- // If the block is the body element, always move content to a new block, so that
- // we avoid adding styles to the body element, since Mail's Make Plain Text feature
- // can't handle those.
- if (upstreamStart.node()->hasTagName(bodyTag)) {
- // If the block is the body element and there is nothing insde of it, create a new
+ // If the block is the root editable element, always move content to a new block,
+ // since it is illegal to modify attributes on the root editable element for editing.
+ if (upstreamStart.node() == editableRootForPosition(upstreamStart)) {
+ // If the block is the root editable element and there is nothing insde of it, create a new
// block but don't try and move content into it, since there's nothing to move.
if (upstreamStart == upstreamEnd)
return insertNewDefaultParagraphElementAt(upstreamStart);
@@ -696,7 +699,7 @@ void CompositeEditCommand::pushAnchorElementDown(Node* anchorNode)
ASSERT(anchorNode->isLink());
- setEndingSelection(Selection::selectionFromContentsOfNode(anchorNode));
+ setEndingSelection(VisibleSelection::selectionFromContentsOfNode(anchorNode));
applyStyledElement(static_cast<Element*>(anchorNode));
// Clones of anchorNode have been pushed down, now remove it.
if (anchorNode->inDocument())
@@ -709,7 +712,7 @@ void CompositeEditCommand::pushAnchorElementDown(Node* anchorNode)
// Anchors cannot be nested.
void CompositeEditCommand::pushPartiallySelectedAnchorElementsDown()
{
- Selection originalSelection = endingSelection();
+ VisibleSelection originalSelection = endingSelection();
VisiblePosition visibleStart(originalSelection.start());
VisiblePosition visibleEnd(originalSelection.end());
@@ -779,7 +782,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
// start and end can't be used directly to create a Range; they are "editing positions"
Position startRangeCompliant = rangeCompliantEquivalent(start);
Position endRangeCompliant = rangeCompliantEquivalent(end);
- RefPtr<Range> range = Range::create(document(), startRangeCompliant.node(), startRangeCompliant.offset(), endRangeCompliant.node(), endRangeCompliant.offset());
+ RefPtr<Range> range = Range::create(document(), startRangeCompliant.node(), startRangeCompliant.m_offset, endRangeCompliant.node(), endRangeCompliant.m_offset);
// FIXME: This is an inefficient way to preserve style on nodes in the paragraph to move. It
// shouldn't matter though, since moved paragraphs will usually be quite small.
@@ -797,7 +800,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
// FIXME (5098931): We should add a new insert action "WebViewInsertActionMoved" and call shouldInsertFragment here.
- setEndingSelection(Selection(start, end, DOWNSTREAM));
+ setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
deleteSelection(false, false, false, false);
ASSERT(destination.deepEquivalent().node()->inDocument());
@@ -828,7 +831,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
if (textNode->length() == 1)
removeNodeAndPruneAncestors(node);
else
- deleteTextFromNode(textNode, position.offset(), 1);
+ deleteTextFromNode(textNode, position.m_offset, 1);
}
}
@@ -866,7 +869,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
RefPtr<Range> start = TextIterator::rangeFromLocationAndLength(document()->documentElement(), destinationIndex + startIndex, 0, true);
RefPtr<Range> end = TextIterator::rangeFromLocationAndLength(document()->documentElement(), destinationIndex + endIndex, 0, true);
if (start && end)
- setEndingSelection(Selection(start->startPosition(), end->startPosition(), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(start->startPosition(), end->startPosition(), DOWNSTREAM));
}
}
@@ -897,7 +900,7 @@ bool CompositeEditCommand::breakOutOfEmptyListItem()
}
appendBlockPlaceholder(newBlock);
- setEndingSelection(Selection(Position(newBlock.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(newBlock.get(), 0), DOWNSTREAM));
computedStyle(endingSelection().start().node())->diff(style.get());
if (style->length() > 0)
@@ -935,7 +938,7 @@ bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph()
// a second one.
if (!isStartOfParagraph(atBR))
insertNodeBefore(createBreakElement(document()), br);
- setEndingSelection(Selection(atBR));
+ setEndingSelection(VisibleSelection(atBR));
// If this is an empty paragraph there must be a line break here.
if (!lineBreakExistsAtPosition(caret))
@@ -950,7 +953,7 @@ bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph()
removeNode(caretPos.node());
prune(beforeBR.node());
} else {
- ASSERT(caretPos.offset() == 0);
+ ASSERT(caretPos.m_offset == 0);
Text* textNode = static_cast<Text*>(caretPos.node());
Node* parentNode = textNode->parentNode();
// The preserved newline must be the first thing in the node, since otherwise the previous
@@ -976,8 +979,8 @@ Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(const Posi
Position result = original;
// Don't avoid block level anchors, because that would insert content into the wrong paragraph.
if (enclosingAnchor && !isBlock(enclosingAnchor)) {
- VisiblePosition firstInAnchor(Position(enclosingAnchor, 0));
- VisiblePosition lastInAnchor(Position(enclosingAnchor, maxDeepOffset(enclosingAnchor)));
+ VisiblePosition firstInAnchor(firstDeepEditingPositionForNode(enclosingAnchor));
+ VisiblePosition lastInAnchor(lastDeepEditingPositionForNode(enclosingAnchor));
// If visually just after the anchor, insert *inside* the anchor unless it's the last
// VisiblePosition in the document, to match NSTextView.
if (visiblePos == lastInAnchor) {
@@ -1034,9 +1037,7 @@ PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, b
PassRefPtr<Element> createBlockPlaceholderElement(Document* document)
{
- ExceptionCode ec = 0;
- RefPtr<Element> breakNode = document->createElementNS(xhtmlNamespaceURI, "br", ec);
- ASSERT(ec == 0);
+ RefPtr<Element> breakNode = document->createElement(brTag, false);
return breakNode.release();
}
diff --git a/WebCore/editing/CompositeEditCommand.h b/WebCore/editing/CompositeEditCommand.h
index 6bb142b..4a3defd 100644
--- a/WebCore/editing/CompositeEditCommand.h
+++ b/WebCore/editing/CompositeEditCommand.h
@@ -52,7 +52,7 @@ protected:
void applyStyledElement(PassRefPtr<Element>);
void removeStyledElement(PassRefPtr<Element>);
void deleteSelection(bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true);
- void deleteSelection(const Selection&, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true);
+ void deleteSelection(const VisibleSelection&, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true);
virtual void deleteTextFromNode(PassRefPtr<Text>, unsigned offset, unsigned count);
void inputText(const String&, bool selectInsertedText = false);
void insertNodeAfter(PassRefPtr<Node>, PassRefPtr<Node> refChild);
diff --git a/WebCore/editing/CreateLinkCommand.cpp b/WebCore/editing/CreateLinkCommand.cpp
index c5d68dd..263feab 100644
--- a/WebCore/editing/CreateLinkCommand.cpp
+++ b/WebCore/editing/CreateLinkCommand.cpp
@@ -53,7 +53,7 @@ void CreateLinkCommand::doApply()
insertNodeAt(anchorElement.get(), endingSelection().start());
RefPtr<Text> textNode = new Text(document(), m_url);
appendNode(textNode.get(), anchorElement.get());
- setEndingSelection(Selection(positionBeforeNode(anchorElement.get()), positionAfterNode(anchorElement.get()), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(positionBeforeNode(anchorElement.get()), positionAfterNode(anchorElement.get()), DOWNSTREAM));
}
}
diff --git a/WebCore/editing/DeleteButtonController.cpp b/WebCore/editing/DeleteButtonController.cpp
index 0516e0c..c0775e3 100644
--- a/WebCore/editing/DeleteButtonController.cpp
+++ b/WebCore/editing/DeleteButtonController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -101,12 +101,12 @@ static bool isDeletableElement(const Node* node)
return false;
}
-static HTMLElement* enclosingDeletableElement(const Selection& selection)
+static HTMLElement* enclosingDeletableElement(const VisibleSelection& selection)
{
if (!selection.isContentEditable())
return 0;
- RefPtr<Range> range = selection.toRange();
+ RefPtr<Range> range = selection.toNormalizedRange();
if (!range)
return 0;
@@ -128,7 +128,7 @@ static HTMLElement* enclosingDeletableElement(const Selection& selection)
return static_cast<HTMLElement*>(element);
}
-void DeleteButtonController::respondToChangedSelection(const Selection& oldSelection)
+void DeleteButtonController::respondToChangedSelection(const VisibleSelection& oldSelection)
{
if (!enabled())
return;
@@ -154,6 +154,13 @@ void DeleteButtonController::createDeletionUI()
style->setProperty(CSSPropertyWebkitUserDrag, CSSValueNone);
style->setProperty(CSSPropertyWebkitUserSelect, CSSValueNone);
style->setProperty(CSSPropertyWebkitUserModify, CSSValueNone);
+ style->setProperty(CSSPropertyVisibility, CSSValueHidden);
+ style->setProperty(CSSPropertyPosition, CSSValueAbsolute);
+ style->setProperty(CSSPropertyCursor, CSSValueDefault);
+ style->setProperty(CSSPropertyTop, "0");
+ style->setProperty(CSSPropertyRight, "0");
+ style->setProperty(CSSPropertyBottom, "0");
+ style->setProperty(CSSPropertyLeft, "0");
RefPtr<HTMLDivElement> outline = new HTMLDivElement(divTag, m_target->document());
outline->setId(outlineElementIdentifier);
@@ -163,10 +170,6 @@ void DeleteButtonController::createDeletionUI()
style = outline->getInlineStyleDecl();
style->setProperty(CSSPropertyPosition, CSSValueAbsolute);
- style->setProperty(CSSPropertyCursor, CSSValueDefault);
- style->setProperty(CSSPropertyWebkitUserDrag, CSSValueNone);
- style->setProperty(CSSPropertyWebkitUserSelect, CSSValueNone);
- style->setProperty(CSSPropertyWebkitUserModify, CSSValueNone);
style->setProperty(CSSPropertyZIndex, String::number(-1000000));
style->setProperty(CSSPropertyTop, String::number(-borderWidth - m_target->renderBox()->borderTop()) + "px");
style->setProperty(CSSPropertyRight, String::number(-borderWidth - m_target->renderBox()->borderRight()) + "px");
@@ -174,6 +177,7 @@ void DeleteButtonController::createDeletionUI()
style->setProperty(CSSPropertyLeft, String::number(-borderWidth - m_target->renderBox()->borderLeft()) + "px");
style->setProperty(CSSPropertyBorder, String::number(borderWidth) + "px solid rgba(0, 0, 0, 0.6)");
style->setProperty(CSSPropertyWebkitBorderRadius, String::number(borderRadius) + "px");
+ style->setProperty(CSSPropertyVisibility, CSSValueVisible);
ExceptionCode ec = 0;
container->appendChild(outline.get(), ec);
@@ -190,15 +194,12 @@ void DeleteButtonController::createDeletionUI()
style = button->getInlineStyleDecl();
style->setProperty(CSSPropertyPosition, CSSValueAbsolute);
- style->setProperty(CSSPropertyCursor, CSSValueDefault);
- style->setProperty(CSSPropertyWebkitUserDrag, CSSValueNone);
- style->setProperty(CSSPropertyWebkitUserSelect, CSSValueNone);
- style->setProperty(CSSPropertyWebkitUserModify, CSSValueNone);
style->setProperty(CSSPropertyZIndex, String::number(1000000));
style->setProperty(CSSPropertyTop, String::number((-buttonHeight / 2) - m_target->renderBox()->borderTop() - (borderWidth / 2) + buttonBottomShadowOffset) + "px");
style->setProperty(CSSPropertyLeft, String::number((-buttonWidth / 2) - m_target->renderBox()->borderLeft() - (borderWidth / 2)) + "px");
style->setProperty(CSSPropertyWidth, String::number(buttonWidth) + "px");
style->setProperty(CSSPropertyHeight, String::number(buttonHeight) + "px");
+ style->setProperty(CSSPropertyVisibility, CSSValueVisible);
RefPtr<Image> buttonImage = Image::loadPlatformResource("deleteButton");
if (buttonImage->isNull())
@@ -283,8 +284,13 @@ void DeleteButtonController::enable()
ASSERT(m_disableStack > 0);
if (m_disableStack > 0)
m_disableStack--;
- if (enabled())
+ if (enabled()) {
+ // Determining if the element is deletable currently depends on style
+ // because whether something is editable depends on style, so we need
+ // to recalculate style before calling enclosingDeletableElement.
+ m_frame->document()->updateRendering();
show(enclosingDeletableElement(m_frame->selection()->selection()));
+ }
}
void DeleteButtonController::disable()
diff --git a/WebCore/editing/DeleteButtonController.h b/WebCore/editing/DeleteButtonController.h
index ab2d0b0..713ae8b 100644
--- a/WebCore/editing/DeleteButtonController.h
+++ b/WebCore/editing/DeleteButtonController.h
@@ -34,7 +34,7 @@ class DeleteButton;
class Frame;
class HTMLElement;
class RenderObject;
-class Selection;
+class VisibleSelection;
class DeleteButtonController {
public:
@@ -45,7 +45,7 @@ public:
HTMLElement* target() const { return m_target.get(); }
HTMLElement* containerElement() const { return m_containerElement.get(); }
- void respondToChangedSelection(const Selection& oldSelection);
+ void respondToChangedSelection(const VisibleSelection& oldSelection);
void show(HTMLElement*);
void hide();
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp
index 21b597e..09288ee 100644
--- a/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/WebCore/editing/DeleteSelectionCommand.cpp
@@ -56,9 +56,7 @@ static bool isTableRow(const Node* node)
static bool isTableCellEmpty(Node* cell)
{
ASSERT(isTableCell(cell));
- VisiblePosition firstInCell(Position(cell, 0));
- VisiblePosition lastInCell(Position(cell, maxDeepOffset(cell)));
- return firstInCell == lastInCell;
+ return VisiblePosition(firstDeepEditingPositionForNode(cell)) == VisiblePosition(lastDeepEditingPositionForNode(cell));
}
static bool isTableRowEmpty(Node* row)
@@ -88,7 +86,7 @@ DeleteSelectionCommand::DeleteSelectionCommand(Document *document, bool smartDel
{
}
-DeleteSelectionCommand::DeleteSelectionCommand(const Selection& selection, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements)
+DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements)
: CompositeEditCommand(selection.start().node()->document()),
m_hasSelectionToDelete(true),
m_smartDelete(smartDelete),
@@ -312,8 +310,8 @@ static void updatePositionForNodeRemoval(Node* node, Position& position)
{
if (position.isNull())
return;
- if (node->parent() == position.node() && node->nodeIndex() < (unsigned)position.offset())
- position = Position(position.node(), position.offset() - 1);
+ if (node->parent() == position.node() && node->nodeIndex() < (unsigned)position.m_offset)
+ position = Position(position.node(), position.m_offset - 1);
if (position.node() == node || position.node()->isDescendantOf(node))
position = positionBeforeNode(node);
}
@@ -363,9 +361,9 @@ void DeleteSelectionCommand::removeNode(PassRefPtr<Node> node)
return;
}
- if (node == m_startBlock && !isEndOfBlock(VisiblePosition(m_startBlock.get(), 0, DOWNSTREAM).previous()))
+ if (node == m_startBlock && !isEndOfBlock(VisiblePosition(firstDeepEditingPositionForNode(m_startBlock.get())).previous()))
m_needPlaceholder = true;
- else if (node == m_endBlock && !isStartOfBlock(VisiblePosition(m_endBlock.get(), maxDeepOffset(m_endBlock.get()), DOWNSTREAM).next()))
+ else if (node == m_endBlock && !isStartOfBlock(VisiblePosition(lastDeepEditingPositionForNode(m_startBlock.get())).next()))
m_needPlaceholder = true;
// FIXME: Update the endpoints of the range being deleted.
@@ -379,9 +377,9 @@ void DeleteSelectionCommand::removeNode(PassRefPtr<Node> node)
static void updatePositionForTextRemoval(Node* node, int offset, int count, Position& position)
{
if (position.node() == node) {
- if (position.offset() > offset + count)
- position = Position(position.node(), position.offset() - count);
- else if (position.offset() > offset)
+ if (position.m_offset > offset + count)
+ position = Position(position.node(), position.m_offset - count);
+ else if (position.m_offset > offset)
position = Position(position.node(), offset);
}
}
@@ -398,7 +396,7 @@ void DeleteSelectionCommand::deleteTextFromNode(PassRefPtr<Text> node, unsigned
void DeleteSelectionCommand::handleGeneralDelete()
{
- int startOffset = m_upstreamStart.offset();
+ int startOffset = m_upstreamStart.m_offset;
Node* startNode = m_upstreamStart.node();
// Never remove the start block unless it's a table, in which case we won't merge content in.
@@ -413,7 +411,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
deleteTextFromNode(text, caretMaxOffset(startNode), text->length() - caretMaxOffset(startNode));
}
- if (startOffset >= maxDeepOffset(startNode)) {
+ if (startOffset >= lastOffsetForEditing(startNode)) {
startNode = startNode->traverseNextSibling();
startOffset = 0;
}
@@ -424,17 +422,16 @@ void DeleteSelectionCommand::handleGeneralDelete()
if (startNode == m_downstreamEnd.node()) {
// The selection to delete is all in one node.
- if (!startNode->renderer() ||
- (startOffset == 0 && m_downstreamEnd.offset() >= maxDeepOffset(startNode))) {
+ if (!startNode->renderer() || (startOffset == 0 && m_downstreamEnd.atLastEditingPositionForNode())) {
// just delete
removeNode(startNode);
- } else if (m_downstreamEnd.offset() - startOffset > 0) {
+ } else if (m_downstreamEnd.m_offset - startOffset > 0) {
if (startNode->isTextNode()) {
// in a text node that needs to be trimmed
- Text *text = static_cast<Text *>(startNode);
- deleteTextFromNode(text, startOffset, m_downstreamEnd.offset() - startOffset);
+ Text* text = static_cast<Text*>(startNode);
+ deleteTextFromNode(text, startOffset, m_downstreamEnd.m_offset - startOffset);
} else {
- removeChildrenInRange(startNode, startOffset, m_downstreamEnd.offset());
+ removeChildrenInRange(startNode, startOffset, m_downstreamEnd.m_offset);
m_endingPosition = m_upstreamStart;
}
}
@@ -465,14 +462,14 @@ void DeleteSelectionCommand::handleGeneralDelete()
// if we just removed a node from the end container, update end position so the
// check above will work
if (node->parentNode() == m_downstreamEnd.node()) {
- ASSERT(node->nodeIndex() < (unsigned)m_downstreamEnd.offset());
- m_downstreamEnd = Position(m_downstreamEnd.node(), m_downstreamEnd.offset() - 1);
+ ASSERT(node->nodeIndex() < (unsigned)m_downstreamEnd.m_offset);
+ m_downstreamEnd = Position(m_downstreamEnd.node(), m_downstreamEnd.m_offset - 1);
}
removeNode(node.get());
node = nextNode.get();
} else {
Node* n = node->lastDescendant();
- if (m_downstreamEnd.node() == n && m_downstreamEnd.offset() >= caretMaxOffset(n)) {
+ if (m_downstreamEnd.node() == n && m_downstreamEnd.m_offset >= caretMaxOffset(n)) {
removeNode(node.get());
node = 0;
} else
@@ -480,16 +477,16 @@ void DeleteSelectionCommand::handleGeneralDelete()
}
}
- if (m_downstreamEnd.node() != startNode && !m_upstreamStart.node()->isDescendantOf(m_downstreamEnd.node()) && m_downstreamEnd.node()->inDocument() && m_downstreamEnd.offset() >= caretMinOffset(m_downstreamEnd.node())) {
- if (m_downstreamEnd.offset() >= maxDeepOffset(m_downstreamEnd.node()) && !canHaveChildrenForEditing(m_downstreamEnd.node())) {
+ if (m_downstreamEnd.node() != startNode && !m_upstreamStart.node()->isDescendantOf(m_downstreamEnd.node()) && m_downstreamEnd.node()->inDocument() && m_downstreamEnd.m_offset >= caretMinOffset(m_downstreamEnd.node())) {
+ if (m_downstreamEnd.atLastEditingPositionForNode() && !canHaveChildrenForEditing(m_downstreamEnd.node())) {
// The node itself is fully selected, not just its contents. Delete it.
removeNode(m_downstreamEnd.node());
} else {
if (m_downstreamEnd.node()->isTextNode()) {
// in a text node that needs to be trimmed
Text *text = static_cast<Text *>(m_downstreamEnd.node());
- if (m_downstreamEnd.offset() > 0) {
- deleteTextFromNode(text, 0, m_downstreamEnd.offset());
+ if (m_downstreamEnd.m_offset > 0) {
+ deleteTextFromNode(text, 0, m_downstreamEnd.m_offset);
m_downstreamEnd = Position(text, 0);
}
// Remove children of m_downstreamEnd.node() that come after m_upstreamStart.
@@ -507,7 +504,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
if (n)
offset = n->nodeIndex() + 1;
}
- removeChildrenInRange(m_downstreamEnd.node(), offset, m_downstreamEnd.offset());
+ removeChildrenInRange(m_downstreamEnd.node(), offset, m_downstreamEnd.m_offset);
m_downstreamEnd = Position(m_downstreamEnd.node(), offset);
}
}
@@ -522,12 +519,12 @@ void DeleteSelectionCommand::fixupWhitespace()
if (m_leadingWhitespace.isNotNull() && !m_leadingWhitespace.isRenderedCharacter()) {
Text* textNode = static_cast<Text*>(m_leadingWhitespace.node());
ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace());
- replaceTextInNode(textNode, m_leadingWhitespace.offset(), 1, nonBreakingSpaceString());
+ replaceTextInNode(textNode, m_leadingWhitespace.m_offset, 1, nonBreakingSpaceString());
}
if (m_trailingWhitespace.isNotNull() && !m_trailingWhitespace.isRenderedCharacter()) {
Text* textNode = static_cast<Text*>(m_trailingWhitespace.node());
ASSERT(!textNode->renderer() ||textNode->renderer()->style()->collapseWhiteSpace());
- replaceTextInNode(textNode, m_trailingWhitespace.offset(), 1, nonBreakingSpaceString());
+ replaceTextInNode(textNode, m_trailingWhitespace.m_offset, 1, nonBreakingSpaceString());
}
}
@@ -696,7 +693,7 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete()
void DeleteSelectionCommand::clearTransientState()
{
- m_selectionToDelete = Selection();
+ m_selectionToDelete = VisibleSelection();
m_upstreamStart.clear();
m_downstreamStart.clear();
m_upstreamEnd.clear();
@@ -755,7 +752,7 @@ void DeleteSelectionCommand::doApply()
// want to replace it with a placeholder BR!
if (handleSpecialCaseBRDelete()) {
calculateTypingStyleAfterDelete();
- setEndingSelection(Selection(m_endingPosition, affinity));
+ setEndingSelection(VisibleSelection(m_endingPosition, affinity));
clearTransientState();
rebalanceWhitespace();
return;
@@ -778,7 +775,7 @@ void DeleteSelectionCommand::doApply()
calculateTypingStyleAfterDelete();
- setEndingSelection(Selection(m_endingPosition, affinity));
+ setEndingSelection(VisibleSelection(m_endingPosition, affinity));
clearTransientState();
}
diff --git a/WebCore/editing/DeleteSelectionCommand.h b/WebCore/editing/DeleteSelectionCommand.h
index 0f9f2f7..640c549 100644
--- a/WebCore/editing/DeleteSelectionCommand.h
+++ b/WebCore/editing/DeleteSelectionCommand.h
@@ -36,14 +36,14 @@ public:
{
return adoptRef(new DeleteSelectionCommand(document, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements));
}
- static PassRefPtr<DeleteSelectionCommand> create(const Selection& selection, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = false)
+ static PassRefPtr<DeleteSelectionCommand> create(const VisibleSelection& selection, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = false)
{
return adoptRef(new DeleteSelectionCommand(selection, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements));
}
private:
DeleteSelectionCommand(Document*, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements);
- DeleteSelectionCommand(const Selection&, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements);
+ DeleteSelectionCommand(const VisibleSelection&, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements);
virtual void doApply();
virtual EditAction editingAction() const;
@@ -74,7 +74,7 @@ private:
bool m_pruneStartBlockIfNecessary;
// This data is transient and should be cleared at the end of the doApply function.
- Selection m_selectionToDelete;
+ VisibleSelection m_selectionToDelete;
Position m_upstreamStart;
Position m_downstreamStart;
Position m_upstreamEnd;
diff --git a/WebCore/editing/EditCommand.cpp b/WebCore/editing/EditCommand.cpp
index 7ec0c19..fefe658 100644
--- a/WebCore/editing/EditCommand.cpp
+++ b/WebCore/editing/EditCommand.cpp
@@ -47,8 +47,7 @@ EditCommand::EditCommand(Document* document)
{
ASSERT(m_document);
ASSERT(m_document->frame());
- DeleteButtonController* deleteButton = m_document->frame()->editor()->deleteButtonController();
- setStartingSelection(avoidIntersectionWithNode(m_document->frame()->selection()->selection(), deleteButton ? deleteButton->containerElement() : 0));
+ setStartingSelection(avoidIntersectionWithNode(m_document->frame()->selection()->selection(), m_document->frame()->editor()->deleteButtonController()->containerElement()));
setEndingSelection(m_startingSelection);
}
@@ -94,7 +93,10 @@ void EditCommand::apply()
if (!m_parent) {
updateLayout();
- frame->editor()->appliedEditing(this);
+ // Only need to call appliedEditing for top-level commands, and TypingCommands do it on their
+ // own (see TypingCommand::typingAddedToOpenCommand).
+ if (!isTypingCommand())
+ frame->editor()->appliedEditing(this);
}
}
@@ -158,7 +160,7 @@ EditAction EditCommand::editingAction() const
return EditActionUnspecified;
}
-void EditCommand::setStartingSelection(const Selection& s)
+void EditCommand::setStartingSelection(const VisibleSelection& s)
{
Element* root = s.rootEditableElement();
for (EditCommand* cmd = this; ; cmd = cmd->m_parent) {
@@ -169,7 +171,7 @@ void EditCommand::setStartingSelection(const Selection& s)
}
}
-void EditCommand::setEndingSelection(const Selection &s)
+void EditCommand::setEndingSelection(const VisibleSelection &s)
{
Element* root = s.rootEditableElement();
for (EditCommand* cmd = this; cmd; cmd = cmd->m_parent) {
diff --git a/WebCore/editing/EditCommand.h b/WebCore/editing/EditCommand.h
index 78490f8..c4969f6 100644
--- a/WebCore/editing/EditCommand.h
+++ b/WebCore/editing/EditCommand.h
@@ -28,7 +28,7 @@
#include "EditAction.h"
#include "Element.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
namespace WebCore {
@@ -47,8 +47,8 @@ public:
virtual EditAction editingAction() const;
- const Selection& startingSelection() const { return m_startingSelection; }
- const Selection& endingSelection() const { return m_endingSelection; }
+ const VisibleSelection& startingSelection() const { return m_startingSelection; }
+ const VisibleSelection& endingSelection() const { return m_endingSelection; }
Element* startingRootEditableElement() const { return m_startingRootEditableElement.get(); }
Element* endingRootEditableElement() const { return m_endingRootEditableElement.get(); }
@@ -63,8 +63,8 @@ protected:
Document* document() const { return m_document.get(); }
- void setStartingSelection(const Selection&);
- void setEndingSelection(const Selection&);
+ void setStartingSelection(const VisibleSelection&);
+ void setEndingSelection(const VisibleSelection&);
PassRefPtr<CSSMutableStyleDeclaration> styleAtPosition(const Position&);
void updateLayout() const;
@@ -75,8 +75,8 @@ private:
virtual void doReapply(); // calls doApply()
RefPtr<Document> m_document;
- Selection m_startingSelection;
- Selection m_endingSelection;
+ VisibleSelection m_startingSelection;
+ VisibleSelection m_endingSelection;
RefPtr<Element> m_startingRootEditableElement;
RefPtr<Element> m_endingRootEditableElement;
CompositeEditCommand* m_parent;
diff --git a/WebCore/editing/Editor.cpp b/WebCore/editing/Editor.cpp
index 510b910..f44449b 100644
--- a/WebCore/editing/Editor.cpp
+++ b/WebCore/editing/Editor.cpp
@@ -74,9 +74,9 @@ using namespace HTMLNames;
// When an event handler has moved the selection outside of a text control
// we should use the target control's selection for this editing operation.
-Selection Editor::selectionForCommand(Event* event)
+VisibleSelection Editor::selectionForCommand(Event* event)
{
- Selection selection = m_frame->selection()->selection();
+ VisibleSelection selection = m_frame->selection()->selection();
if (!event)
return selection;
// If the target is a text control, and the current selection is outside of its shadow tree,
@@ -222,7 +222,7 @@ bool Editor::isSelectTrailingWhitespaceEnabled()
bool Editor::deleteWithDirection(SelectionController::EDirection direction, TextGranularity granularity, bool killRing, bool isTypingAction)
{
- if (!canEdit() || !m_frame->document())
+ if (!canEdit())
return false;
if (m_frame->selection()->isRange()) {
@@ -317,7 +317,7 @@ PassRefPtr<Range> Editor::selectedRange()
{
if (!m_frame)
return 0;
- return m_frame->selection()->toRange();
+ return m_frame->selection()->toNormalizedRange();
}
bool Editor::shouldDeleteRange(Range* range) const
@@ -376,14 +376,14 @@ bool Editor::shouldShowDeleteInterface(HTMLElement* element) const
return client() && client()->shouldShowDeleteInterface(element);
}
-void Editor::respondToChangedSelection(const Selection& oldSelection)
+void Editor::respondToChangedSelection(const VisibleSelection& oldSelection)
{
if (client())
client()->respondToChangedSelection();
m_deleteButtonController->respondToChangedSelection(oldSelection);
}
-void Editor::respondToChangedContents(const Selection& endingSelection)
+void Editor::respondToChangedContents(const VisibleSelection& endingSelection)
{
if (AXObjectCache::accessibilityEnabled()) {
Node* node = endingSelection.start().node();
@@ -419,7 +419,7 @@ const SimpleFontData* Editor::fontForSelection(bool& hasMultipleFonts) const
const SimpleFontData* font = 0;
- RefPtr<Range> range = m_frame->selection()->toRange();
+ RefPtr<Range> range = m_frame->selection()->toNormalizedRange();
Node* startNode = range->editingStartPosition().node();
if (startNode) {
Node* pastEnd = range->pastLastNode();
@@ -572,7 +572,7 @@ bool Editor::hasBidiSelection() const
if (style->direction() == RTL)
return true;
- return static_cast<RenderBlock*>(renderer)->containsNonZeroBidiLevel();
+ return toRenderBlock(renderer)->containsNonZeroBidiLevel();
}
TriState Editor::selectionUnorderedListState() const
@@ -689,7 +689,7 @@ void Editor::clearLastEditCommand()
bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPolicy policy)
{
Node* target = m_frame->selection()->start().element();
- if (!target && m_frame->document())
+ if (!target)
target = m_frame->document()->body();
if (!target)
return true;
@@ -699,7 +699,7 @@ bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPoli
ExceptionCode ec = 0;
RefPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard);
- EventTargetNodeCast(target)->dispatchEvent(evt, ec);
+ target->dispatchEvent(evt, ec);
bool noDefaultProcessing = evt->defaultPrevented();
// invalidate clipboard here for security
@@ -710,15 +710,15 @@ bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPoli
void Editor::applyStyle(CSSStyleDeclaration* style, EditAction editingAction)
{
- switch (m_frame->selection()->state()) {
- case Selection::NONE:
+ switch (m_frame->selection()->selectionType()) {
+ case VisibleSelection::NoSelection:
// do nothing
break;
- case Selection::CARET:
+ case VisibleSelection::CaretSelection:
m_frame->computeAndSetTypingStyle(style, editingAction);
break;
- case Selection::RANGE:
- if (m_frame->document() && style)
+ case VisibleSelection::RangeSelection:
+ if (style)
applyCommand(ApplyStyleCommand::create(m_frame->document(), style, editingAction));
break;
}
@@ -731,13 +731,13 @@ bool Editor::shouldApplyStyle(CSSStyleDeclaration* style, Range* range)
void Editor::applyParagraphStyle(CSSStyleDeclaration* style, EditAction editingAction)
{
- switch (m_frame->selection()->state()) {
- case Selection::NONE:
+ switch (m_frame->selection()->selectionType()) {
+ case VisibleSelection::NoSelection:
// do nothing
break;
- case Selection::CARET:
- case Selection::RANGE:
- if (m_frame->document() && style)
+ case VisibleSelection::CaretSelection:
+ case VisibleSelection::RangeSelection:
+ if (style)
applyCommand(ApplyStyleCommand::create(m_frame->document(), style, editingAction, ApplyStyleCommand::ForceBlockProperties));
break;
}
@@ -748,7 +748,7 @@ void Editor::applyStyleToSelection(CSSStyleDeclaration* style, EditAction editin
if (!style || style->length() == 0 || !canEditRichly())
return;
- if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toRange().get()))
+ if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toNormalizedRange().get()))
applyStyle(style, editingAction);
}
@@ -757,7 +757,7 @@ void Editor::applyParagraphStyleToSelection(CSSStyleDeclaration* style, EditActi
if (!style || style->length() == 0 || !canEditRichly())
return;
- if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toRange().get()))
+ if (client() && client()->shouldApplyStyle(style, m_frame->selection()->toNormalizedRange().get()))
applyParagraphStyle(style, editingAction);
}
@@ -870,14 +870,9 @@ void Editor::appliedEditing(PassRefPtr<EditCommand> cmd)
{
dispatchEditableContentChangedEvents(*cmd);
- Selection newSelection(cmd->endingSelection());
- // If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
- // because there is work that it must do in this situation.
- // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
- // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
+ VisibleSelection newSelection(cmd->endingSelection());
// Don't clear the typing style with this selection change. We do those things elsewhere if necessary.
- if (newSelection == m_frame->selection()->selection() || m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, false, false);
+ changeSelectionAfterCommand(newSelection, false, false, cmd.get());
if (!cmd->preservesTypingStyle())
m_frame->setTypingStyle(0);
@@ -899,13 +894,8 @@ void Editor::unappliedEditing(PassRefPtr<EditCommand> cmd)
{
dispatchEditableContentChangedEvents(*cmd);
- Selection newSelection(cmd->startingSelection());
- // If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
- // because there is work that it must do in this situation.
- // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
- // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
- if (newSelection == m_frame->selection()->selection() || m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, true);
+ VisibleSelection newSelection(cmd->startingSelection());
+ changeSelectionAfterCommand(newSelection, true, true, cmd.get());
m_lastEditCommand = 0;
if (client())
@@ -917,13 +907,8 @@ void Editor::reappliedEditing(PassRefPtr<EditCommand> cmd)
{
dispatchEditableContentChangedEvents(*cmd);
- Selection newSelection(cmd->endingSelection());
- // If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
- // because there is work that it must do in this situation.
- // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
- // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
- if (newSelection == m_frame->selection()->selection() || m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection, true);
+ VisibleSelection newSelection(cmd->endingSelection());
+ changeSelectionAfterCommand(newSelection, true, true, cmd.get());
m_lastEditCommand = 0;
if (client())
@@ -936,6 +921,8 @@ Editor::Editor(Frame* frame)
, m_deleteButtonController(new DeleteButtonController(frame))
, m_ignoreCompositionSelectionChange(false)
, m_shouldStartNewKillRingSequence(false)
+ // This is off by default, since most editors want this behavior (this matches IE but not FF).
+ , m_shouldStyleWithCSS(false)
{
}
@@ -947,6 +934,7 @@ void Editor::clear()
{
m_compositionNode = 0;
m_customCompositionUnderlines.clear();
+ m_shouldStyleWithCSS = false;
}
bool Editor::insertText(const String& text, Event* triggeringEvent)
@@ -959,10 +947,10 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
if (text.isEmpty())
return false;
- Selection selection = selectionForCommand(triggeringEvent);
+ VisibleSelection selection = selectionForCommand(triggeringEvent);
if (!selection.isContentEditable())
return false;
- RefPtr<Range> range = selection.toRange();
+ RefPtr<Range> range = selection.toNormalizedRange();
if (!shouldInsertText(text, range.get(), EditorInsertActionTyped))
return true;
@@ -981,7 +969,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
// Reveal the current selection
if (Frame* editedFrame = document->frame())
if (Page* page = editedFrame->page())
- page->focusController()->focusedOrMainFrame()->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
+ page->focusController()->focusedOrMainFrame()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
}
}
@@ -993,7 +981,7 @@ bool Editor::insertLineBreak()
if (!canEdit())
return false;
- if (!shouldInsertText("\n", m_frame->selection()->toRange().get(), EditorInsertActionTyped))
+ if (!shouldInsertText("\n", m_frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
return true;
TypingCommand::insertLineBreak(m_frame->document());
@@ -1009,7 +997,7 @@ bool Editor::insertParagraphSeparator()
if (!canEditRichly())
return insertLineBreak();
- if (!shouldInsertText("\n", m_frame->selection()->toRange().get(), EditorInsertActionTyped))
+ if (!shouldInsertText("\n", m_frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
return true;
TypingCommand::insertParagraphSeparator(m_frame->document());
@@ -1204,8 +1192,8 @@ void Editor::setBaseWritingDirection(WritingDirection direction)
{
Node* focusedNode = frame()->document()->focusedNode();
if (focusedNode && (focusedNode->hasTagName(textareaTag)
- || focusedNode->hasTagName(inputTag) && (static_cast<HTMLInputElement*>(focusedNode)->inputType() == HTMLInputElement::TEXT
- || static_cast<HTMLInputElement*>(focusedNode)->inputType() == HTMLInputElement::SEARCH))) {
+ || (focusedNode->hasTagName(inputTag) && (static_cast<HTMLInputElement*>(focusedNode)->inputType() == HTMLInputElement::TEXT
+ || static_cast<HTMLInputElement*>(focusedNode)->inputType() == HTMLInputElement::SEARCH)))) {
if (direction == NaturalWritingDirection)
return;
static_cast<HTMLElement*>(focusedNode)->setAttribute(dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl");
@@ -1226,7 +1214,7 @@ void Editor::selectComposition()
// The composition can start inside a composed character sequence, so we have to override checks.
// See <http://bugs.webkit.org/show_bug.cgi?id=15781>
- Selection selection;
+ VisibleSelection selection;
selection.setWithoutValidation(range->startPosition(), range->endPosition());
m_frame->selection()->setSelection(selection, false, false);
}
@@ -1254,7 +1242,7 @@ void Editor::confirmComposition(const String& text, bool preserveSelection)
{
setIgnoreCompositionSelectionChange(true);
- Selection oldSelection = m_frame->selection()->selection();
+ VisibleSelection oldSelection = m_frame->selection()->selection();
selectComposition();
@@ -1302,9 +1290,9 @@ void Editor::setComposition(const String& text, const Vector<CompositionUnderlin
TypingCommand::insertText(m_frame->document(), text, true, true);
Node* baseNode = m_frame->selection()->base().node();
- unsigned baseOffset = m_frame->selection()->base().offset();
+ unsigned baseOffset = m_frame->selection()->base().m_offset;
Node* extentNode = m_frame->selection()->extent().node();
- unsigned extentOffset = m_frame->selection()->extent().offset();
+ unsigned extentOffset = m_frame->selection()->extent().m_offset;
if (baseNode && baseNode == extentNode && baseNode->isTextNode() && baseOffset + text.length() == extentOffset) {
m_compositionNode = static_cast<Text*>(baseNode);
@@ -1334,7 +1322,7 @@ void Editor::ignoreSpelling()
if (!client())
return;
- RefPtr<Range> selectedRange = frame()->selection()->toRange();
+ RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange();
if (selectedRange)
frame()->document()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
@@ -1548,6 +1536,130 @@ static String findFirstBadGrammarInRange(EditorClient* client, Range* searchRang
#endif /* not BUILDING_ON_TIGER */
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
+static String findFirstMisspellingOrBadGrammarInRange(EditorClient* client, Range* searchRange, bool checkGrammar, bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail)
+{
+ ASSERT_ARG(client, client);
+ ASSERT_ARG(searchRange, searchRange);
+
+ String firstFoundItem;
+ String misspelledWord;
+ String badGrammarPhrase;
+ ExceptionCode ec = 0;
+
+ // Initialize out parameters; these will be updated if we find something to return.
+ outIsSpelling = true;
+ outFirstFoundOffset = 0;
+ outGrammarDetail.location = -1;
+ outGrammarDetail.length = 0;
+ outGrammarDetail.guesses.clear();
+ outGrammarDetail.userDescription = "";
+
+ // Expand the search range to encompass entire paragraphs, since text checking needs that much context.
+ // Determine the character offset from the start of the paragraph to the start of the original search range,
+ // since we will want to ignore results in this area.
+ RefPtr<Range> paragraphRange = searchRange->cloneRange(ec);
+ setStart(paragraphRange.get(), startOfParagraph(searchRange->startPosition()));
+ int totalRangeLength = TextIterator::rangeLength(paragraphRange.get());
+ setEnd(paragraphRange.get(), endOfParagraph(searchRange->startPosition()));
+
+ RefPtr<Range> offsetAsRange = Range::create(paragraphRange->startContainer(ec)->document(), paragraphRange->startPosition(), searchRange->startPosition());
+ int searchRangeStartOffset = TextIterator::rangeLength(offsetAsRange.get());
+ int totalLengthProcessed = 0;
+
+ bool firstIteration = true;
+ bool lastIteration = false;
+ while (totalLengthProcessed < totalRangeLength) {
+ // Iterate through the search range by paragraphs, checking each one for spelling and grammar.
+ int currentLength = TextIterator::rangeLength(paragraphRange.get());
+ int currentStartOffset = firstIteration ? searchRangeStartOffset : 0;
+ int currentEndOffset = currentLength;
+ if (inSameParagraph(paragraphRange->startPosition(), searchRange->endPosition())) {
+ // Determine the character offset from the end of the original search range to the end of the paragraph,
+ // since we will want to ignore results in this area.
+ RefPtr<Range> endOffsetAsRange = Range::create(paragraphRange->startContainer(ec)->document(), paragraphRange->startPosition(), searchRange->endPosition());
+ currentEndOffset = TextIterator::rangeLength(endOffsetAsRange.get());
+ lastIteration = true;
+ }
+ if (currentStartOffset < currentEndOffset) {
+ String paragraphString = plainText(paragraphRange.get());
+ if (paragraphString.length() > 0) {
+ bool foundGrammar = false;
+ int spellingLocation = 0;
+ int grammarPhraseLocation = 0;
+ int grammarDetailLocation = 0;
+ unsigned grammarDetailIndex = 0;
+
+ Vector<TextCheckingResult> results;
+ client->checkSpellingAndGrammarOfParagraph(paragraphString.characters(), paragraphString.length(), checkGrammar, results);
+
+ for (unsigned i = 0; i < results.size(); i++) {
+ const TextCheckingResult* result = &results[i];
+ if (result->resultType == 1 && result->location >= currentStartOffset && result->location + result->length <= currentEndOffset) {
+ ASSERT(result->length > 0 && result->location >= 0);
+ spellingLocation = result->location;
+ misspelledWord = paragraphString.substring(result->location, result->length);
+ ASSERT(misspelledWord.length() != 0);
+ break;
+ } else if (checkGrammar && result->resultType == 2 && result->location < currentEndOffset && result->location + result->length > currentStartOffset) {
+ ASSERT(result->length > 0 && result->location >= 0);
+ // We can't stop after the first grammar result, since there might still be a spelling result after
+ // it begins but before the first detail in it, but we can stop if we find a second grammar result.
+ if (foundGrammar) break;
+ for (unsigned j = 0; j < result->details.size(); j++) {
+ const GrammarDetail* detail = &result->details[j];
+ ASSERT(detail->length > 0 && detail->location >= 0);
+ if (result->location + detail->location >= currentStartOffset && result->location + detail->location + detail->length <= currentEndOffset && (!foundGrammar || result->location + detail->location < grammarDetailLocation)) {
+ grammarDetailIndex = j;
+ grammarDetailLocation = result->location + detail->location;
+ foundGrammar = true;
+ }
+ }
+ if (foundGrammar) {
+ grammarPhraseLocation = result->location;
+ outGrammarDetail = result->details[grammarDetailIndex];
+ badGrammarPhrase = paragraphString.substring(result->location, result->length);
+ ASSERT(badGrammarPhrase.length() != 0);
+ }
+ }
+ }
+
+ if (!misspelledWord.isEmpty() && (!checkGrammar || badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) {
+ int spellingOffset = spellingLocation - currentStartOffset;
+ if (!firstIteration) {
+ RefPtr<Range> paragraphOffsetAsRange = Range::create(paragraphRange->startContainer(ec)->document(), searchRange->startPosition(), paragraphRange->startPosition());
+ spellingOffset += TextIterator::rangeLength(paragraphOffsetAsRange.get());
+ }
+ outIsSpelling = true;
+ outFirstFoundOffset = spellingOffset;
+ firstFoundItem = misspelledWord;
+ break;
+ } else if (checkGrammar && !badGrammarPhrase.isEmpty()) {
+ int grammarPhraseOffset = grammarPhraseLocation - currentStartOffset;
+ if (!firstIteration) {
+ RefPtr<Range> paragraphOffsetAsRange = Range::create(paragraphRange->startContainer(ec)->document(), searchRange->startPosition(), paragraphRange->startPosition());
+ grammarPhraseOffset += TextIterator::rangeLength(paragraphOffsetAsRange.get());
+ }
+ outIsSpelling = false;
+ outFirstFoundOffset = grammarPhraseOffset;
+ firstFoundItem = badGrammarPhrase;
+ break;
+ }
+ }
+ }
+ if (lastIteration || totalLengthProcessed + currentLength >= totalRangeLength)
+ break;
+ setStart(paragraphRange.get(), startOfNextParagraph(paragraphRange->endPosition()));
+ setEnd(paragraphRange.get(), endOfParagraph(paragraphRange->startPosition()));
+ firstIteration = false;
+ totalLengthProcessed += currentLength;
+ }
+ return firstFoundItem;
+}
+
+#endif
+
void Editor::advanceToNextMisspelling(bool startBeforeSelection)
{
ExceptionCode ec = 0;
@@ -1557,7 +1669,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
// Start at the end of the selection, search to edge of document. Starting at the selection end makes
// repeated "check spelling" commands work.
- Selection selection(frame()->selection()->selection());
+ VisibleSelection selection(frame()->selection()->selection());
RefPtr<Range> spellingSearchRange(rangeOfContents(frame()->document()));
bool startedWithSelection = false;
if (selection.start().node()) {
@@ -1584,13 +1696,14 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
return;
Position rangeCompliantPosition = rangeCompliantEquivalent(position);
- spellingSearchRange->setStart(rangeCompliantPosition.node(), rangeCompliantPosition.offset(), ec);
+ spellingSearchRange->setStart(rangeCompliantPosition.node(), rangeCompliantPosition.m_offset, ec);
startedWithSelection = false; // won't need to wrap
}
// topNode defines the whole range we want to operate on
Node* topNode = highestEditableRoot(position);
- spellingSearchRange->setEnd(topNode, maxDeepOffset(topNode), ec);
+ // FIXME: lastOffsetForEditing() is wrong here if editingIgnoresContent(highestEditableRoot()) returns true (e.g. a <table>)
+ spellingSearchRange->setEnd(topNode, lastOffsetForEditing(topNode), ec);
// If spellingSearchRange starts in the middle of a word, advance to the next word so we start checking
// at a word boundary. Going back by one char and then forward by a word does the trick.
@@ -1614,7 +1727,24 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
Node *searchEndNodeAfterWrap = spellingSearchRange->endContainer(ec);
int searchEndOffsetAfterWrap = spellingSearchRange->endOffset(ec);
- int misspellingOffset;
+ int misspellingOffset = 0;
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ RefPtr<Range> grammarSearchRange = spellingSearchRange->cloneRange(ec);
+ String misspelledWord;
+ String badGrammarPhrase;
+ int grammarPhraseOffset = 0;
+ bool isSpelling = true;
+ int foundOffset = 0;
+ GrammarDetail grammarDetail;
+ String foundItem = findFirstMisspellingOrBadGrammarInRange(client(), spellingSearchRange.get(), isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
+ if (isSpelling) {
+ misspelledWord = foundItem;
+ misspellingOffset = foundOffset;
+ } else {
+ badGrammarPhrase = foundItem;
+ grammarPhraseOffset = foundOffset;
+ }
+#else
String misspelledWord = findFirstMisspellingInRange(client(), spellingSearchRange.get(), misspellingOffset, false);
String badGrammarPhrase;
@@ -1635,6 +1765,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
if (isGrammarCheckingEnabled())
badGrammarPhrase = findFirstBadGrammarInRange(client(), grammarSearchRange.get(), grammarDetail, grammarPhraseOffset, false);
#endif
+#endif
// If we found neither bad grammar nor a misspelled word, wrap and try again (but don't bother if we started at the beginning of the
// block rather than at a selection).
@@ -1643,6 +1774,17 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
// going until the end of the very first chunk we tested is far enough
spellingSearchRange->setEnd(searchEndNodeAfterWrap, searchEndOffsetAfterWrap, ec);
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ grammarSearchRange = spellingSearchRange->cloneRange(ec);
+ foundItem = findFirstMisspellingOrBadGrammarInRange(client(), spellingSearchRange.get(), isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
+ if (isSpelling) {
+ misspelledWord = foundItem;
+ misspellingOffset = foundOffset;
+ } else {
+ badGrammarPhrase = foundItem;
+ grammarPhraseOffset = foundOffset;
+ }
+#else
misspelledWord = findFirstMisspellingInRange(client(), spellingSearchRange.get(), misspellingOffset, false);
#ifndef BUILDING_ON_TIGER
@@ -1656,6 +1798,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
if (isGrammarCheckingEnabled())
badGrammarPhrase = findFirstBadGrammarInRange(client(), grammarSearchRange.get(), grammarDetail, grammarPhraseOffset, false);
#endif
+#endif
}
if (!badGrammarPhrase.isEmpty()) {
@@ -1671,7 +1814,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
// FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
- frame()->selection()->setSelection(Selection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY));
+ frame()->selection()->setSelection(VisibleSelection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY));
frame()->revealSelection();
client()->updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail);
@@ -1682,7 +1825,7 @@ void Editor::advanceToNextMisspelling(bool startBeforeSelection)
// a marker so we draw the red squiggle later.
RefPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRange.get(), misspellingOffset, misspelledWord.length());
- frame()->selection()->setSelection(Selection(misspellingRange.get(), DOWNSTREAM));
+ frame()->selection()->setSelection(VisibleSelection(misspellingRange.get(), DOWNSTREAM));
frame()->revealSelection();
client()->updateSpellingUIWithMisspelledWord(misspelledWord);
@@ -1770,7 +1913,7 @@ bool Editor::isSelectionUngrammatical()
return false;
#else
Vector<String> ignoredGuesses;
- return isRangeUngrammatical(client(), frame()->selection()->toRange().get(), ignoredGuesses);
+ return isRangeUngrammatical(client(), frame()->selection()->toNormalizedRange().get(), ignoredGuesses);
#endif
}
@@ -1781,7 +1924,7 @@ Vector<String> Editor::guessesForUngrammaticalSelection()
#else
Vector<String> guesses;
// Ignore the result of isRangeUngrammatical; we just want the guesses, whether or not there are any
- isRangeUngrammatical(client(), frame()->selection()->toRange().get(), guesses);
+ isRangeUngrammatical(client(), frame()->selection()->toNormalizedRange().get(), guesses);
return guesses;
#endif
}
@@ -1797,6 +1940,86 @@ Vector<String> Editor::guessesForMisspelledSelection()
return guesses;
}
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
+static Vector<String> guessesForMisspelledOrUngrammaticalRange(EditorClient* client, Range *range, bool checkGrammar, bool& misspelled, bool& ungrammatical)
+{
+ Vector<String> guesses;
+ ExceptionCode ec;
+ misspelled = false;
+ ungrammatical = false;
+
+ if (!client || !range || range->collapsed(ec))
+ return guesses;
+
+ // Expand the range to encompass entire paragraphs, since text checking needs that much context.
+ int rangeStartOffset;
+ String paragraphString;
+ RefPtr<Range> paragraphRange = paragraphAlignedRangeForRange(range, rangeStartOffset, paragraphString);
+ int rangeLength = TextIterator::rangeLength(range);
+ if (rangeLength == 0 || paragraphString.length() == 0)
+ return guesses;
+
+ Vector<TextCheckingResult> results;
+ client->checkSpellingAndGrammarOfParagraph(paragraphString.characters(), paragraphString.length(), checkGrammar, results);
+
+ for (unsigned i = 0; i < results.size(); i++) {
+ const TextCheckingResult* result = &results[i];
+ if (result->resultType == 1 && result->location == rangeStartOffset && result->length == rangeLength) {
+ String misspelledWord = paragraphString.substring(rangeStartOffset, rangeLength);
+ ASSERT(misspelledWord.length() != 0);
+ client->getGuessesForWord(misspelledWord, guesses);
+ client->updateSpellingUIWithMisspelledWord(misspelledWord);
+ misspelled = true;
+ return guesses;
+ }
+ }
+
+ if (!checkGrammar)
+ return guesses;
+
+ for (unsigned i = 0; i < results.size(); i++) {
+ const TextCheckingResult* result = &results[i];
+ if (result->resultType == 2 && result->location <= rangeStartOffset && result->location + result->length >= rangeStartOffset + rangeLength) {
+ for (unsigned j = 0; j < result->details.size(); j++) {
+ const GrammarDetail* detail = &result->details[j];
+ ASSERT(detail->length > 0 && detail->location >= 0);
+ if (result->location + detail->location == rangeStartOffset && detail->length == rangeLength) {
+ String badGrammarPhrase = paragraphString.substring(result->location, result->length);
+ ASSERT(badGrammarPhrase.length() != 0);
+ for (unsigned k = 0; k < detail->guesses.size(); k++)
+ guesses.append(detail->guesses[k]);
+ client->updateSpellingUIWithGrammarString(badGrammarPhrase, *detail);
+ ungrammatical = true;
+ return guesses;
+ }
+ }
+ }
+ }
+ return guesses;
+}
+
+#endif
+
+Vector<String> Editor::guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical)
+{
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ return guessesForMisspelledOrUngrammaticalRange(client(), frame()->selection()->toNormalizedRange().get(), isGrammarCheckingEnabled(), misspelled, ungrammatical);
+#else
+ misspelled = isSelectionMisspelled();
+ if (misspelled) {
+ ungrammatical = false;
+ return guessesForMisspelledSelection();
+ }
+ if (isGrammarCheckingEnabled() && isSelectionUngrammatical()) {
+ ungrammatical = true;
+ return guessesForUngrammaticalSelection();
+ }
+ ungrammatical = false;
+ return Vector<String>();
+#endif
+}
+
void Editor::showSpellingGuessPanel()
{
if (!client()) {
@@ -1829,14 +2052,24 @@ void Editor::markMisspellingsAfterTypingToPosition(const VisiblePosition &p)
if (!isContinuousSpellCheckingEnabled())
return;
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ VisibleSelection adjacentWords = VisibleSelection(startOfWord(p, LeftWordIfOnBoundary), endOfWord(p, RightWordIfOnBoundary));
+ if (isGrammarCheckingEnabled()) {
+ VisibleSelection selectedSentence = VisibleSelection(startOfSentence(p), endOfSentence(p));
+ markMisspellingsAndBadGrammar(adjacentWords, true, selectedSentence);
+ } else {
+ markMisspellingsAndBadGrammar(adjacentWords, false, adjacentWords);
+ }
+#else
// Check spelling of one word
- markMisspellings(Selection(startOfWord(p, LeftWordIfOnBoundary), endOfWord(p, RightWordIfOnBoundary)));
+ markMisspellings(VisibleSelection(startOfWord(p, LeftWordIfOnBoundary), endOfWord(p, RightWordIfOnBoundary)));
if (!isGrammarCheckingEnabled())
return;
// Check grammar of entire sentence
- markBadGrammar(Selection(startOfSentence(p), endOfSentence(p)));
+ markBadGrammar(VisibleSelection(startOfSentence(p), endOfSentence(p)));
+#endif
}
static void markAllMisspellingsInRange(EditorClient* client, Range* searchRange)
@@ -1858,7 +2091,7 @@ static void markAllBadGrammarInRange(EditorClient* client, Range* searchRange)
}
#endif
-static void markMisspellingsOrBadGrammar(Editor* editor, const Selection& selection, bool checkSpelling)
+static void markMisspellingsOrBadGrammar(Editor* editor, const VisibleSelection& selection, bool checkSpelling)
{
// This function is called with a selection already expanded to word boundaries.
// Might be nice to assert that here.
@@ -1868,7 +2101,7 @@ static void markMisspellingsOrBadGrammar(Editor* editor, const Selection& select
if (!editor->isContinuousSpellCheckingEnabled())
return;
- RefPtr<Range> searchRange(selection.toRange());
+ RefPtr<Range> searchRange(selection.toNormalizedRange());
if (!searchRange)
return;
@@ -1893,12 +2126,12 @@ static void markMisspellingsOrBadGrammar(Editor* editor, const Selection& select
}
}
-void Editor::markMisspellings(const Selection& selection)
+void Editor::markMisspellings(const VisibleSelection& selection)
{
markMisspellingsOrBadGrammar(this, selection, true);
}
-void Editor::markBadGrammar(const Selection& selection)
+void Editor::markBadGrammar(const VisibleSelection& selection)
{
#ifndef BUILDING_ON_TIGER
markMisspellingsOrBadGrammar(this, selection, false);
@@ -1907,6 +2140,78 @@ void Editor::markBadGrammar(const Selection& selection)
#endif
}
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+
+static void markAllMisspellingsAndBadGrammarInRanges(EditorClient* client, Range *spellingRange, bool markGrammar, Range *grammarRange)
+{
+ // This function is called with selections already expanded to word boundaries.
+ ExceptionCode ec;
+ if (!client || !spellingRange || (markGrammar && !grammarRange))
+ return;
+
+ // If we're not in an editable node, bail.
+ Node* editableNode = spellingRange->startContainer();
+ if (!editableNode || !editableNode->isContentEditable())
+ return;
+
+ // Expand the range to encompass entire paragraphs, since text checking needs that much context.
+ int spellingRangeStartOffset = 0;
+ int spellingRangeEndOffset = 0;
+ int grammarRangeStartOffset = 0;
+ int grammarRangeEndOffset = 0;
+ String paragraphString;
+
+ if (markGrammar) {
+ // The spelling range should be contained in the paragraph-aligned extension of the grammar range.
+ RefPtr<Range> paragraphRange = paragraphAlignedRangeForRange(grammarRange, grammarRangeStartOffset, paragraphString);
+ RefPtr<Range> offsetAsRange = Range::create(paragraphRange->startContainer(ec)->document(), paragraphRange->startPosition(), spellingRange->startPosition());
+ spellingRangeStartOffset = TextIterator::rangeLength(offsetAsRange.get());
+ grammarRangeEndOffset = grammarRangeStartOffset + TextIterator::rangeLength(grammarRange);
+ } else {
+ RefPtr<Range> paragraphRange = paragraphAlignedRangeForRange(spellingRange, spellingRangeStartOffset, paragraphString);
+ }
+ spellingRangeEndOffset = spellingRangeStartOffset + TextIterator::rangeLength(spellingRange);
+ if (paragraphString.length() == 0 || (spellingRangeStartOffset >= spellingRangeEndOffset && (!markGrammar || grammarRangeStartOffset >= grammarRangeEndOffset)))
+ return;
+
+ Vector<TextCheckingResult> results;
+ client->checkSpellingAndGrammarOfParagraph(paragraphString.characters(), paragraphString.length(), markGrammar, results);
+
+ for (unsigned i = 0; i < results.size(); i++) {
+ const TextCheckingResult* result = &results[i];
+ if (result->resultType == 1 && result->location >= spellingRangeStartOffset && result->location + result->length <= spellingRangeEndOffset) {
+ ASSERT(result->length > 0 && result->location >= 0);
+ RefPtr<Range> misspellingRange = TextIterator::subrange(spellingRange, result->location - spellingRangeStartOffset, result->length);
+ misspellingRange->startContainer(ec)->document()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+ } else if (markGrammar && result->resultType == 2 && result->location < grammarRangeEndOffset && result->location + result->length > grammarRangeStartOffset) {
+ ASSERT(result->length > 0 && result->location >= 0);
+ for (unsigned j = 0; j < result->details.size(); j++) {
+ const GrammarDetail* detail = &result->details[j];
+ ASSERT(detail->length > 0 && detail->location >= 0);
+ if (result->location + detail->location >= grammarRangeStartOffset && result->location + detail->location + detail->length <= grammarRangeEndOffset) {
+ RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarRange, result->location + detail->location - grammarRangeStartOffset, detail->length);
+ grammarRange->startContainer(ec)->document()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+void Editor::markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection)
+{
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ if (!isContinuousSpellCheckingEnabled())
+ return;
+ markAllMisspellingsAndBadGrammarInRanges(client(), spellingSelection.toNormalizedRange().get(), markGrammar && isGrammarCheckingEnabled(), grammarSelection.toNormalizedRange().get());
+#else
+ markMisspellings(spellingSelection);
+ if (markGrammar)
+ markBadGrammar(grammarSelection);
+#endif
+}
+
PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
{
Document* document = m_frame->documentAtPoint(windowPoint);
@@ -1919,8 +2224,8 @@ PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
if (!frameView)
return 0;
IntPoint framePoint = frameView->windowToContents(windowPoint);
- Selection selection(frame->visiblePositionForPoint(framePoint));
- return avoidIntersectionWithNode(selection.toRange().get(), deleteButtonController() ? deleteButtonController()->containerElement() : 0);
+ VisibleSelection selection(frame->visiblePositionForPoint(framePoint));
+ return avoidIntersectionWithNode(selection.toNormalizedRange().get(), m_deleteButtonController->containerElement());
}
void Editor::revealSelectionAfterEditingOperation()
@@ -1928,7 +2233,7 @@ void Editor::revealSelectionAfterEditingOperation()
if (m_ignoreCompositionSelectionChange)
return;
- m_frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
+ m_frame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
}
void Editor::setIgnoreCompositionSelectionChange(bool ignore)
@@ -1964,13 +2269,13 @@ bool Editor::getCompositionSelection(unsigned& selectionStart, unsigned& selecti
if (end.node() != m_compositionNode)
return false;
- if (static_cast<unsigned>(start.offset()) < m_compositionStart)
+ if (static_cast<unsigned>(start.m_offset) < m_compositionStart)
return false;
- if (static_cast<unsigned>(end.offset()) > m_compositionEnd)
+ if (static_cast<unsigned>(end.m_offset) > m_compositionEnd)
return false;
- selectionStart = start.offset() - m_compositionStart;
- selectionEnd = start.offset() - m_compositionEnd;
+ selectionStart = start.m_offset - m_compositionStart;
+ selectionEnd = start.m_offset - m_compositionEnd;
return true;
}
@@ -1979,7 +2284,7 @@ void Editor::transpose()
if (!canEdit())
return;
- Selection selection = m_frame->selection()->selection();
+ VisibleSelection selection = m_frame->selection()->selection();
if (!selection.isCaret())
return;
@@ -1995,7 +2300,7 @@ void Editor::transpose()
RefPtr<Range> range = makeRange(previous, next);
if (!range)
return;
- Selection newSelection(range.get(), DOWNSTREAM);
+ VisibleSelection newSelection(range.get(), DOWNSTREAM);
// Transpose the two characters.
String text = plainText(range.get());
@@ -2070,7 +2375,7 @@ bool Editor::insideVisibleArea(const IntPoint& point) const
if (!(container->style()->overflowX() == OHIDDEN || container->style()->overflowY() == OHIDDEN))
return true;
- IntRect rectInPageCoords = container->getOverflowClipRect(0, 0);
+ IntRect rectInPageCoords = container->overflowClipRect(0, 0);
IntRect rectInFrameCoords = IntRect(renderer->x() * -1, renderer->y() * -1,
rectInPageCoords.width(), rectInPageCoords.height());
@@ -2096,7 +2401,7 @@ bool Editor::insideVisibleArea(Range* range) const
if (!(container->style()->overflowX() == OHIDDEN || container->style()->overflowY() == OHIDDEN))
return true;
- IntRect rectInPageCoords = container->getOverflowClipRect(0, 0);
+ IntRect rectInPageCoords = container->overflowClipRect(0, 0);
IntRect rectInFrameCoords = IntRect(renderer->x() * -1, renderer->y() * -1,
rectInPageCoords.width(), rectInPageCoords.height());
IntRect resultRect = range->boundingBox();
@@ -2186,4 +2491,25 @@ PassRefPtr<Range> Editor::nextVisibleRange(Range* currentRange, const String& ta
return lastVisibleRange(target, caseFlag);
}
+void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle, EditCommand* cmd)
+{
+ // If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
+ // because there is work that it must do in this situation.
+ // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
+ // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
+ bool selectionDidNotChangeDOMPosition = newSelection == m_frame->selection()->selection();
+ if (selectionDidNotChangeDOMPosition || m_frame->shouldChangeSelection(newSelection))
+ m_frame->selection()->setSelection(newSelection, closeTyping, clearTypingStyle);
+
+ // Some kinds of deletes and line break insertions change the selection's position within the document without
+ // changing its position within the DOM. For example when you press return in the following (the caret is marked by ^):
+ // <div contentEditable="true"><div>^Hello</div></div>
+ // WebCore inserts <div><br></div> *before* the current block, which correctly moves the paragraph down but which doesn't
+ // change the caret's DOM position (["hello", 0]). In these situations the above SelectionController::setSelection call
+ // does not call EditorClient::respondToChangedSelection(), which, on the Mac, sends selection change notifications and
+ // starts a new kill ring sequence, but we want to do these things (matches AppKit).
+ if (selectionDidNotChangeDOMPosition && cmd->isTypingCommand())
+ client()->respondToChangedSelection();
+}
+
} // namespace WebCore
diff --git a/WebCore/editing/Editor.h b/WebCore/editing/Editor.h
index d97f670..ce8fa0f 100644
--- a/WebCore/editing/Editor.h
+++ b/WebCore/editing/Editor.h
@@ -110,8 +110,8 @@ public:
bool shouldDeleteRange(Range*) const;
bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
- void respondToChangedSelection(const Selection& oldSelection);
- void respondToChangedContents(const Selection& endingSelection);
+ void respondToChangedSelection(const VisibleSelection& oldSelection);
+ void respondToChangedContents(const VisibleSelection& endingSelection);
TriState selectionHasStyle(CSSStyleDeclaration*) const;
const SimpleFontData* fontForSelection(bool&) const;
@@ -151,6 +151,9 @@ public:
bool selectionStartHasStyle(CSSStyleDeclaration*) const;
bool clientIsEditable() const;
+
+ void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
+ bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
class Command {
public:
@@ -192,9 +195,11 @@ public:
bool isSelectionMisspelled();
Vector<String> guessesForMisspelledSelection();
Vector<String> guessesForUngrammaticalSelection();
+ Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical);
void markMisspellingsAfterTypingToPosition(const VisiblePosition&);
- void markMisspellings(const Selection&);
- void markBadGrammar(const Selection&);
+ void markMisspellings(const VisibleSelection&);
+ void markBadGrammar(const VisibleSelection&);
+ void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
void advanceToNextMisspelling(bool startBeforeSelection = false);
void showSpellingGuessPanel();
bool spellingPanelIsShowing();
@@ -250,7 +255,7 @@ public:
void clear();
- Selection selectionForCommand(Event*);
+ VisibleSelection selectionForCommand(Event*);
void appendToKillRing(const String&);
void prependToKillRing(const String&);
@@ -278,6 +283,7 @@ private:
Vector<CompositionUnderline> m_customCompositionUnderlines;
bool m_ignoreCompositionSelectionChange;
bool m_shouldStartNewKillRingSequence;
+ bool m_shouldStyleWithCSS;
bool canDeleteRange(Range*) const;
bool canSmartReplaceWithPasteboard(Pasteboard*);
@@ -295,6 +301,8 @@ private:
PassRefPtr<Range> firstVisibleRange(const String&, bool caseFlag);
PassRefPtr<Range> lastVisibleRange(const String&, bool caseFlag);
+
+ void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle, EditCommand*);
};
inline void Editor::setStartNewKillRingSequence(bool flag)
diff --git a/WebCore/editing/EditorCommand.cpp b/WebCore/editing/EditorCommand.cpp
index 54c73b9..0090df7 100644
--- a/WebCore/editing/EditorCommand.cpp
+++ b/WebCore/editing/EditorCommand.cpp
@@ -35,13 +35,14 @@
#include "EditorClient.h"
#include "Event.h"
#include "EventHandler.h"
-#include "Frame.h"
#include "FormatBlockCommand.h"
+#include "Frame.h"
#include "HTMLFontElement.h"
#include "HTMLImageElement.h"
#include "IndentOutdentCommand.h"
#include "InsertListCommand.h"
#include "Page.h"
+#include "RenderBox.h"
#include "ReplaceSelectionCommand.h"
#include "Scrollbar.h"
#include "Settings.h"
@@ -184,15 +185,15 @@ static bool executeInsertNode(Frame* frame, PassRefPtr<Node> content)
static bool expandSelectionToGranularity(Frame* frame, TextGranularity granularity)
{
- Selection selection = frame->selection()->selection();
+ VisibleSelection selection = frame->selection()->selection();
selection.expandUsingGranularity(granularity);
- RefPtr<Range> newRange = selection.toRange();
+ RefPtr<Range> newRange = selection.toNormalizedRange();
if (!newRange)
return false;
ExceptionCode ec = 0;
if (newRange->collapsed(ec))
return false;
- RefPtr<Range> oldRange = frame->selection()->selection().toRange();
+ RefPtr<Range> oldRange = frame->selection()->selection().toNormalizedRange();
EAffinity affinity = frame->selection()->affinity();
if (!frame->editor()->client()->shouldChangeSelectedRange(oldRange.get(), newRange.get(), affinity, false))
return false;
@@ -342,7 +343,7 @@ static bool executeDeleteToEndOfParagraph(Frame* frame, Event*, EditorCommandSou
static bool executeDeleteToMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<Range> mark = frame->mark().toRange();
+ RefPtr<Range> mark = frame->mark().toNormalizedRange();
if (mark) {
SelectionController* selection = frame->selection();
bool selected = selection->setSelectedRange(unionDOMRanges(mark.get(), frame->editor()->selectedRange().get()).get(), DOWNSTREAM, true);
@@ -491,9 +492,9 @@ static bool executeInsertNewlineInQuotedContent(Frame* frame, Event*, EditorComm
return true;
}
-static bool executeInsertOrderedList(Frame* frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertOrderedList(Frame* frame, Event*, EditorCommandSource, const String&)
{
- applyCommand(InsertListCommand::create(frame->document(), InsertListCommand::OrderedList, value));
+ applyCommand(InsertListCommand::create(frame->document(), InsertListCommand::OrderedList));
return true;
}
@@ -514,9 +515,9 @@ static bool executeInsertText(Frame* frame, Event*, EditorCommandSource, const S
return true;
}
-static bool executeInsertUnorderedList(Frame* frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertUnorderedList(Frame* frame, Event*, EditorCommandSource, const String&)
{
- applyCommand(InsertListCommand::create(frame->document(), InsertListCommand::UnorderedList, value));
+ applyCommand(InsertListCommand::create(frame->document(), InsertListCommand::UnorderedList));
return true;
}
@@ -826,6 +827,30 @@ static bool executeMoveWordRightAndModifySelection(Frame* frame, Event*, EditorC
return true;
}
+static bool executeMoveToLeftEndOfLine(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+ frame->selection()->modify(SelectionController::MOVE, SelectionController::LEFT, LineBoundary, true);
+ return true;
+}
+
+static bool executeMoveToLeftEndOfLineAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+ frame->selection()->modify(SelectionController::EXTEND, SelectionController::LEFT, LineBoundary, true);
+ return true;
+}
+
+static bool executeMoveToRightEndOfLine(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+ frame->selection()->modify(SelectionController::MOVE, SelectionController::RIGHT, LineBoundary, true);
+ return true;
+}
+
+static bool executeMoveToRightEndOfLineAndModifySelection(Frame* frame, Event*, EditorCommandSource, const String&)
+{
+ frame->selection()->modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary, true);
+ return true;
+}
+
static bool executeOutdent(Frame* frame, Event*, EditorCommandSource, const String&)
{
applyCommand(IndentOutdentCommand::create(frame->document(), IndentOutdentCommand::Outdent));
@@ -888,7 +913,7 @@ static bool executeSelectSentence(Frame* frame, Event*, EditorCommandSource, con
static bool executeSelectToMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<Range> mark = frame->mark().toRange();
+ RefPtr<Range> mark = frame->mark().toNormalizedRange();
RefPtr<Range> selection = frame->editor()->selectedRange();
if (!mark || !selection) {
systemBeep();
@@ -914,6 +939,15 @@ static bool executeStrikethrough(Frame* frame, Event*, EditorCommandSource sourc
return executeToggleStyle(frame, source, EditActionChangeAttributes, CSSPropertyWebkitTextDecorationsInEffect, "none", "line-through");
}
+static bool executeStyleWithCSS(Frame* frame, Event*, EditorCommandSource, const String& value)
+{
+ if (value != "false" && value != "true")
+ return false;
+
+ frame->editor()->setShouldStyleWithCSS(value == "true" ? true : false);
+ return true;
+}
+
static bool executeSubscript(Frame* frame, Event*, EditorCommandSource source, const String&)
{
return executeToggleStyle(frame, source, EditActionSubscript, CSSPropertyVerticalAlign, "baseline", "sub");
@@ -926,8 +960,8 @@ static bool executeSuperscript(Frame* frame, Event*, EditorCommandSource source,
static bool executeSwapWithMark(Frame* frame, Event*, EditorCommandSource, const String&)
{
- const Selection& mark = frame->mark();
- const Selection& selection = frame->selection()->selection();
+ const VisibleSelection& mark = frame->mark();
+ const VisibleSelection& selection = frame->selection()->selection();
if (mark.isNone() || selection.isNone()) {
systemBeep();
return false;
@@ -1033,20 +1067,20 @@ static bool enabled(Frame*, Event*, EditorCommandSource)
static bool enabledVisibleSelection(Frame* frame, Event* event, EditorCommandSource)
{
// The term "visible" here includes a caret in editable text or a range in any text.
- const Selection& selection = frame->editor()->selectionForCommand(event);
+ const VisibleSelection& selection = frame->editor()->selectionForCommand(event);
return (selection.isCaret() && selection.isContentEditable()) || selection.isRange();
}
static bool enabledVisibleSelectionAndMark(Frame* frame, Event* event, EditorCommandSource)
{
- const Selection& selection = frame->editor()->selectionForCommand(event);
+ const VisibleSelection& selection = frame->editor()->selectionForCommand(event);
return ((selection.isCaret() && selection.isContentEditable()) || selection.isRange())
&& frame->mark().isCaretOrRange();
}
static bool enableCaretInEditableText(Frame* frame, Event* event, EditorCommandSource)
{
- const Selection& selection = frame->editor()->selectionForCommand(event);
+ const VisibleSelection& selection = frame->editor()->selectionForCommand(event);
return selection.isCaret() && selection.isContentEditable();
}
@@ -1138,6 +1172,11 @@ static TriState stateStrikethrough(Frame* frame, Event*)
return stateStyle(frame, CSSPropertyTextDecoration, "line-through");
}
+static TriState stateStyleWithCSS(Frame* frame, Event*)
+{
+ return frame->editor()->shouldStyleWithCSS() ? TrueTriState : FalseTriState;
+}
+
static TriState stateSubscript(Frame* frame, Event*)
{
return stateStyle(frame, CSSPropertyVerticalAlign, "sub");
@@ -1244,8 +1283,8 @@ static const CommandMap& createCommandMap()
{ "IgnoreSpelling", { executeIgnoreSpelling, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "Indent", { executeIndent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertBacktab", { executeInsertBacktab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertHorizontalRule", { executeInsertHorizontalRule, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertHTML", { executeInsertHTML, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertHorizontalRule", { executeInsertHorizontalRule, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertImage", { executeInsertImage, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertLineBreak", { executeInsertLineBreak, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "InsertNewline", { executeInsertNewline, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
@@ -1296,6 +1335,10 @@ static const CommandMap& createCommandMap()
{ "MoveToEndOfParagraphAndModifySelection", { executeMoveToEndOfParagraphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "MoveToEndOfSentence", { executeMoveToEndOfSentence, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "MoveToEndOfSentenceAndModifySelection", { executeMoveToEndOfSentenceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToLeftEndOfLine", { executeMoveToLeftEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToLeftEndOfLineAndModifySelection", { executeMoveToLeftEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToRightEndOfLine", { executeMoveToRightEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToRightEndOfLineAndModifySelection", { executeMoveToRightEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "MoveUp", { executeMoveUp, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "MoveUpAndModifySelection", { executeMoveUpAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "MoveWordBackward", { executeMoveWordBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
@@ -1320,6 +1363,7 @@ static const CommandMap& createCommandMap()
{ "SelectWord", { executeSelectWord, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "SetMark", { executeSetMark, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "Strikethrough", { executeStrikethrough, supported, enabledInRichlyEditableText, stateStrikethrough, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "StyleWithCSS", { executeStyleWithCSS, supported, enabledInRichlyEditableText, stateStyleWithCSS, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "Subscript", { executeSubscript, supported, enabledInRichlyEditableText, stateSubscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "Superscript", { executeSuperscript, supported, enabledInRichlyEditableText, stateSuperscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
{ "SwapWithMark", { executeSwapWithMark, supportedFromMenuOrKeyBinding, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
@@ -1428,7 +1472,7 @@ bool Editor::Command::execute(const String& parameter, Event* triggeringEvent) c
{
if (!isEnabled(triggeringEvent)) {
// Let certain commands be executed when performed explicitly even if they are disabled.
- if (!isSupported() || !m_frame || !m_frame->document() || !m_command->allowExecutionWhenDisabled)
+ if (!isSupported() || !m_frame || !m_command->allowExecutionWhenDisabled)
return false;
}
m_frame->document()->updateLayoutIgnorePendingStylesheets();
@@ -1447,21 +1491,21 @@ bool Editor::Command::isSupported() const
bool Editor::Command::isEnabled(Event* triggeringEvent) const
{
- if (!isSupported() || !m_frame || !m_frame->document())
+ if (!isSupported() || !m_frame)
return false;
return m_command->isEnabled(m_frame.get(), triggeringEvent, m_source);
}
TriState Editor::Command::state(Event* triggeringEvent) const
{
- if (!isSupported() || !m_frame || !m_frame->document())
+ if (!isSupported() || !m_frame)
return FalseTriState;
return m_command->state(m_frame.get(), triggeringEvent);
}
String Editor::Command::value(Event* triggeringEvent) const
{
- if (!isSupported() || !m_frame || !m_frame->document())
+ if (!isSupported() || !m_frame)
return String();
return m_command->value(m_frame.get(), triggeringEvent);
}
diff --git a/WebCore/editing/FormatBlockCommand.cpp b/WebCore/editing/FormatBlockCommand.cpp
index 6a4ee7e..88169be 100644
--- a/WebCore/editing/FormatBlockCommand.cpp
+++ b/WebCore/editing/FormatBlockCommand.cpp
@@ -63,7 +63,7 @@ bool FormatBlockCommand::modifyRange()
setEndingSelection(visibleEnd);
doApply();
visibleEnd = endingSelection().visibleEnd();
- setEndingSelection(Selection(visibleStart.deepEquivalent(), visibleEnd.deepEquivalent(), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(visibleStart.deepEquivalent(), visibleEnd.deepEquivalent(), DOWNSTREAM));
return true;
}
@@ -87,7 +87,7 @@ void FormatBlockCommand::doApply()
// margin/padding, but not others. We should make the gap painting more consistent and
// then use a left margin/padding rule here.
if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
- setEndingSelection(Selection(visibleStart, visibleEnd.previous(true)));
+ setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(true)));
if (endingSelection().isRange() && modifyRange())
return;
diff --git a/WebCore/editing/IndentOutdentCommand.cpp b/WebCore/editing/IndentOutdentCommand.cpp
index 242aeb0..9444b11 100644
--- a/WebCore/editing/IndentOutdentCommand.cpp
+++ b/WebCore/editing/IndentOutdentCommand.cpp
@@ -109,7 +109,7 @@ PassRefPtr<Element> IndentOutdentCommand::prepareBlockquoteLevelForInsertion(Vis
void IndentOutdentCommand::indentRegion()
{
- Selection selection = selectionForParagraphIteration(endingSelection());
+ VisibleSelection selection = selectionForParagraphIteration(endingSelection());
VisiblePosition startOfSelection = selection.visibleStart();
VisiblePosition endOfSelection = selection.visibleEnd();
int startIndex = indexForVisiblePosition(startOfSelection);
@@ -126,7 +126,7 @@ void IndentOutdentCommand::indentRegion()
insertNodeAt(blockquote, start);
RefPtr<Element> placeholder = createBreakElement(document());
appendNode(placeholder, blockquote);
- setEndingSelection(Selection(Position(placeholder.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(placeholder.get(), 0), DOWNSTREAM));
return;
}
@@ -151,7 +151,7 @@ void IndentOutdentCommand::indentRegion()
appendNode(placeholder, listItem);
} else {
// Clone the list element, insert it before the current paragraph, and move the paragraph into it.
- RefPtr<Element> clonedList = listNode->cloneElement();
+ RefPtr<Element> clonedList = listNode->cloneElementWithoutChildren();
insertNodeBefore(clonedList, enclosingListChild(endOfCurrentParagraph.deepEquivalent().node()));
appendNode(listItem, clonedList);
appendNode(placeholder, listItem);
@@ -191,7 +191,7 @@ void IndentOutdentCommand::indentRegion()
RefPtr<Range> startRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), startIndex, 0, true);
RefPtr<Range> endRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), endIndex, 0, true);
if (startRange && endRange)
- setEndingSelection(Selection(startRange->startPosition(), endRange->startPosition(), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(startRange->startPosition(), endRange->startPosition(), DOWNSTREAM));
}
void IndentOutdentCommand::outdentParagraph()
@@ -205,11 +205,11 @@ void IndentOutdentCommand::outdentParagraph()
// Use InsertListCommand to remove the selection from the list
if (enclosingNode->hasTagName(olTag)) {
- applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList, ""));
+ applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList));
return;
}
if (enclosingNode->hasTagName(ulTag)) {
- applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList, ""));
+ applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList));
return;
}
@@ -262,13 +262,13 @@ void IndentOutdentCommand::outdentRegion()
while (endOfCurrentParagraph != endAfterSelection) {
VisiblePosition endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next());
if (endOfCurrentParagraph == endOfLastParagraph)
- setEndingSelection(Selection(originalSelectionEnd, DOWNSTREAM));
+ setEndingSelection(VisibleSelection(originalSelectionEnd, DOWNSTREAM));
else
setEndingSelection(endOfCurrentParagraph);
outdentParagraph();
endOfCurrentParagraph = endOfNextParagraph;
}
- setEndingSelection(Selection(originalSelectionStart, endingSelection().end(), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(originalSelectionStart, endingSelection().end(), DOWNSTREAM));
}
void IndentOutdentCommand::doApply()
@@ -290,7 +290,7 @@ void IndentOutdentCommand::doApply()
// margin/padding, but not others. We should make the gap painting more consistent and
// then use a left margin/padding rule here.
if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
- setEndingSelection(Selection(visibleStart, visibleEnd.previous(true)));
+ setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(true)));
if (m_typeOfAction == Indent)
indentRegion();
diff --git a/WebCore/editing/InsertLineBreakCommand.cpp b/WebCore/editing/InsertLineBreakCommand.cpp
index 2ec71af..a5c588d 100644
--- a/WebCore/editing/InsertLineBreakCommand.cpp
+++ b/WebCore/editing/InsertLineBreakCommand.cpp
@@ -30,11 +30,12 @@
#include "Document.h"
#include "Element.h"
#include "Frame.h"
+#include "HTMLNames.h"
+#include "Range.h"
+#include "RenderObject.h"
#include "Text.h"
#include "VisiblePosition.h"
-#include "Range.h"
#include "htmlediting.h"
-#include "HTMLNames.h"
#include "visible_units.h"
namespace WebCore {
@@ -88,7 +89,7 @@ bool InsertLineBreakCommand::shouldUseBreakElement(const Position& insertionPos)
void InsertLineBreakCommand::doApply()
{
deleteSelection();
- Selection selection = endingSelection();
+ VisibleSelection selection = endingSelection();
if (selection.isNone())
return;
@@ -116,30 +117,27 @@ void InsertLineBreakCommand::doApply()
insertNodeBefore(nodeToInsert->cloneNode(false), nodeToInsert);
VisiblePosition endingPosition(Position(nodeToInsert.get(), 0));
- setEndingSelection(Selection(endingPosition));
- } else if (pos.offset() <= caretMinOffset(pos.node())) {
+ setEndingSelection(VisibleSelection(endingPosition));
+ } else if (pos.m_offset <= caretMinOffset(pos.node())) {
insertNodeAt(nodeToInsert.get(), pos);
// Insert an extra br or '\n' if the just inserted one collapsed.
if (!isStartOfParagraph(VisiblePosition(Position(nodeToInsert.get(), 0))))
insertNodeBefore(nodeToInsert->cloneNode(false).get(), nodeToInsert.get());
- setEndingSelection(Selection(positionAfterNode(nodeToInsert.get()), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(positionAfterNode(nodeToInsert.get()), DOWNSTREAM));
// If we're inserting after all of the rendered text in a text node, or into a non-text node,
// a simple insertion is sufficient.
- } else if (pos.offset() >= caretMaxOffset(pos.node()) || !pos.node()->isTextNode()) {
+ } else if (pos.m_offset >= caretMaxOffset(pos.node()) || !pos.node()->isTextNode()) {
insertNodeAt(nodeToInsert.get(), pos);
- setEndingSelection(Selection(positionAfterNode(nodeToInsert.get()), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(positionAfterNode(nodeToInsert.get()), DOWNSTREAM));
} else {
// Split a text node
ASSERT(pos.node()->isTextNode());
// Do the split
- ExceptionCode ec = 0;
Text* textNode = static_cast<Text*>(pos.node());
- RefPtr<Text> textBeforeNode = document()->createTextNode(textNode->substringData(0, selection.start().offset(), ec));
- deleteTextFromNode(textNode, 0, pos.offset());
- insertNodeBefore(textBeforeNode, textNode);
+ splitTextNode(textNode, pos.m_offset);
insertNodeBefore(nodeToInsert, textNode);
Position endingPosition = Position(textNode, 0);
@@ -160,7 +158,7 @@ void InsertLineBreakCommand::doApply()
}
}
- setEndingSelection(Selection(endingPosition, DOWNSTREAM));
+ setEndingSelection(VisibleSelection(endingPosition, DOWNSTREAM));
}
// Handle the case where there is a typing style.
@@ -172,10 +170,9 @@ void InsertLineBreakCommand::doApply()
// leaves and then comes back, new input will have the right style.
// FIXME: We shouldn't always apply the typing style to the line break here,
// see <rdar://problem/5794462>.
- applyStyle(typingStyle, Position(nodeToInsert.get(), 0),
- Position(nodeToInsert.get(), maxDeepOffset(nodeToInsert.get())));
+ applyStyle(typingStyle, firstDeepEditingPositionForNode(nodeToInsert.get()), lastDeepEditingPositionForNode(nodeToInsert.get()));
// Even though this applyStyle operates on a Range, it still sets an endingSelection().
- // It tries to set a Selection around the content it operated on. So, that Selection
+ // It tries to set a VisibleSelection around the content it operated on. So, that VisibleSelection
// will either (a) select the line break we inserted, or it will (b) be a caret just
// before the line break (if the line break is at the end of a block it isn't selectable).
// So, this next call sets the endingSelection() to a caret just after the line break
diff --git a/WebCore/editing/InsertListCommand.cpp b/WebCore/editing/InsertListCommand.cpp
index 20c63b8..aa48761 100644
--- a/WebCore/editing/InsertListCommand.cpp
+++ b/WebCore/editing/InsertListCommand.cpp
@@ -39,7 +39,7 @@ using namespace HTMLNames;
PassRefPtr<HTMLElement> InsertListCommand::insertList(Document* document, Type type)
{
- RefPtr<InsertListCommand> insertCommand = new InsertListCommand(document, type, "");
+ RefPtr<InsertListCommand> insertCommand = new InsertListCommand(document, type);
insertCommand->apply();
return insertCommand->m_listElement;
}
@@ -54,14 +54,14 @@ HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node)
return listElement.get();
}
-InsertListCommand::InsertListCommand(Document* document, Type type, const String& id)
- : CompositeEditCommand(document), m_type(type), m_id(id), m_forceCreateList(false)
+InsertListCommand::InsertListCommand(Document* document, Type type)
+ : CompositeEditCommand(document), m_type(type), m_forceCreateList(false)
{
}
bool InsertListCommand::modifyRange()
{
- Selection selection = selectionForParagraphIteration(endingSelection());
+ VisibleSelection selection = selectionForParagraphIteration(endingSelection());
ASSERT(selection.isRange());
VisiblePosition startOfSelection = selection.visibleStart();
VisiblePosition endOfSelection = selection.visibleEnd();
@@ -99,7 +99,7 @@ bool InsertListCommand::modifyRange()
doApply();
// Fetch the end of the selection, for the reason mentioned above.
endOfSelection = endingSelection().visibleEnd();
- setEndingSelection(Selection(startOfSelection, endOfSelection));
+ setEndingSelection(VisibleSelection(startOfSelection, endOfSelection));
m_forceCreateList = false;
return true;
}
@@ -123,7 +123,7 @@ void InsertListCommand::doApply()
// margin/padding, but not others. We should make the gap painting more consistent and
// then use a left margin/padding rule here.
if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
- setEndingSelection(Selection(visibleStart, visibleEnd.previous(true)));
+ setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(true)));
if (endingSelection().isRange() && modifyRange())
return;
@@ -148,8 +148,8 @@ void InsertListCommand::doApply()
VisiblePosition start;
VisiblePosition end;
if (listChildNode->hasTagName(liTag)) {
- start = VisiblePosition(Position(listChildNode, 0));
- end = VisiblePosition(Position(listChildNode, maxDeepOffset(listChildNode)));
+ start = firstDeepEditingPositionForNode(listChildNode);
+ end = lastDeepEditingPositionForNode(listChildNode);
nextListChild = listChildNode->nextSibling();
previousListChild = listChildNode->previousSibling();
} else {
@@ -230,8 +230,6 @@ void InsertListCommand::doApply()
// Create the list.
RefPtr<HTMLElement> listElement = m_type == OrderedList ? createOrderedListElement(document()) : createUnorderedListElement(document());
m_listElement = listElement;
- if (!m_id.isEmpty())
- listElement->setId(m_id);
appendNode(listItemElement, listElement);
if (start == end && isBlock(start.deepEquivalent().node())) {
diff --git a/WebCore/editing/InsertListCommand.h b/WebCore/editing/InsertListCommand.h
index b39f2b5..ecdd2cf 100644
--- a/WebCore/editing/InsertListCommand.h
+++ b/WebCore/editing/InsertListCommand.h
@@ -36,9 +36,9 @@ class InsertListCommand : public CompositeEditCommand {
public:
enum Type { OrderedList, UnorderedList };
- static PassRefPtr<InsertListCommand> create(Document* document, Type listType, const String& listID)
+ static PassRefPtr<InsertListCommand> create(Document* document, Type listType)
{
- return adoptRef(new InsertListCommand(document, listType, listID));
+ return adoptRef(new InsertListCommand(document, listType));
}
static PassRefPtr<HTMLElement> insertList(Document*, Type);
@@ -46,7 +46,7 @@ public:
virtual bool preservesTypingStyle() const { return true; }
private:
- InsertListCommand(Document*, Type, const String&);
+ InsertListCommand(Document*, Type);
virtual void doApply();
virtual EditAction editingAction() const { return EditActionInsertList; }
@@ -55,7 +55,6 @@ private:
bool modifyRange();
RefPtr<HTMLElement> m_listElement;
Type m_type;
- String m_id;
bool m_forceCreateList;
};
diff --git a/WebCore/editing/InsertParagraphSeparatorCommand.cpp b/WebCore/editing/InsertParagraphSeparatorCommand.cpp
index 30e006e..0e9c291 100644
--- a/WebCore/editing/InsertParagraphSeparatorCommand.cpp
+++ b/WebCore/editing/InsertParagraphSeparatorCommand.cpp
@@ -106,42 +106,42 @@ void InsertParagraphSeparatorCommand::doApply()
if (endingSelection().isNone())
return;
- Position pos = endingSelection().start();
+ Position insertionPosition = endingSelection().start();
EAffinity affinity = endingSelection().affinity();
// Delete the current selection.
if (endingSelection().isRange()) {
- calculateStyleBeforeInsertion(pos);
+ calculateStyleBeforeInsertion(insertionPosition);
deleteSelection(false, true);
- pos = endingSelection().start();
+ insertionPosition = endingSelection().start();
affinity = endingSelection().affinity();
}
// FIXME: The rangeCompliantEquivalent conversion needs to be moved into enclosingBlock.
- Node* startBlockNode = enclosingBlock(rangeCompliantEquivalent(pos).node());
- Position canonicalPos = VisiblePosition(pos).deepEquivalent();
+ Node* startBlockNode = enclosingBlock(rangeCompliantEquivalent(insertionPosition).node());
+ Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent();
Element* startBlock = static_cast<Element*>(startBlockNode);
if (!startBlockNode
|| !startBlockNode->isElementNode()
|| !startBlock->parentNode()
|| isTableCell(startBlock)
|| startBlock->hasTagName(formTag)
- || canonicalPos.node()->renderer() && canonicalPos.node()->renderer()->isTable()
+ || (canonicalPos.node()->renderer() && canonicalPos.node()->renderer()->isTable())
|| canonicalPos.node()->hasTagName(hrTag)) {
applyCommandToComposite(InsertLineBreakCommand::create(document()));
return;
}
// Use the leftmost candidate.
- pos = pos.upstream();
- if (!pos.isCandidate())
- pos = pos.downstream();
+ insertionPosition = insertionPosition.upstream();
+ if (!insertionPosition.isCandidate())
+ insertionPosition = insertionPosition.downstream();
// Adjust the insertion position after the delete
- pos = positionAvoidingSpecialElementBoundary(pos);
- VisiblePosition visiblePos(pos, affinity);
- calculateStyleBeforeInsertion(pos);
+ insertionPosition = positionAvoidingSpecialElementBoundary(insertionPosition);
+ VisiblePosition visiblePos(insertionPosition, affinity);
+ calculateStyleBeforeInsertion(insertionPosition);
//---------------------------------------------------------------------
// Handle special case of typing return on an empty list item
@@ -150,10 +150,6 @@ void InsertParagraphSeparatorCommand::doApply()
//---------------------------------------------------------------------
// Prepare for more general cases.
- // FIXME: We shouldn't peel off the node here because then we lose track of
- // the fact that it's the node that belongs to an editing position and
- // not a rangeCompliantEquivalent.
- Node *startNode = pos.node();
bool isFirstInBlock = isStartOfBlock(visiblePos);
bool isLastInBlock = isEndOfBlock(visiblePos);
@@ -167,7 +163,7 @@ void InsertParagraphSeparatorCommand::doApply()
} else if (shouldUseDefaultParagraphElement(startBlock))
blockToInsert = createDefaultParagraphElement(document());
else
- blockToInsert = startBlock->cloneElement();
+ blockToInsert = startBlock->cloneElementWithoutChildren();
//---------------------------------------------------------------------
// Handle case when position is in the last visible position in its block,
@@ -186,7 +182,7 @@ void InsertParagraphSeparatorCommand::doApply()
insertNodeAfter(blockToInsert, startBlock);
appendBlockPlaceholder(blockToInsert);
- setEndingSelection(Selection(Position(blockToInsert.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(blockToInsert.get(), 0), DOWNSTREAM));
applyStyleAfterInsertion(startBlock);
return;
}
@@ -198,20 +194,20 @@ void InsertParagraphSeparatorCommand::doApply()
Node *refNode;
if (isFirstInBlock && !nestNewBlock)
refNode = startBlock;
- else if (pos.node() == startBlock && nestNewBlock) {
- refNode = startBlock->childNode(pos.offset());
+ else if (insertionPosition.node() == startBlock && nestNewBlock) {
+ refNode = startBlock->childNode(insertionPosition.m_offset);
ASSERT(refNode); // must be true or we'd be in the end of block case
} else
- refNode = pos.node();
+ refNode = insertionPosition.node();
// find ending selection position easily before inserting the paragraph
- pos = pos.downstream();
+ insertionPosition = insertionPosition.downstream();
insertNodeBefore(blockToInsert, refNode);
appendBlockPlaceholder(blockToInsert.get());
- setEndingSelection(Selection(Position(blockToInsert.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(blockToInsert.get(), 0), DOWNSTREAM));
applyStyleAfterInsertion(startBlock);
- setEndingSelection(Selection(pos, DOWNSTREAM));
+ setEndingSelection(VisibleSelection(insertionPosition, DOWNSTREAM));
return;
}
@@ -224,41 +220,45 @@ void InsertParagraphSeparatorCommand::doApply()
// content will move down a line.
if (isStartOfParagraph(visiblePos)) {
RefPtr<Element> br = createBreakElement(document());
- insertNodeAt(br.get(), pos);
- pos = positionAfterNode(br.get());
+ insertNodeAt(br.get(), insertionPosition);
+ insertionPosition = positionAfterNode(br.get());
}
// Move downstream. Typing style code will take care of carrying along the
// style of the upstream position.
- pos = pos.downstream();
- startNode = pos.node();
+ insertionPosition = insertionPosition.downstream();
+
+ // At this point, the insertionPosition's node could be a container, and we want to make sure we include
+ // all of the correct nodes when building the ancestor list. So this needs to be the deepest representation of the position
+ // before we walk the DOM tree.
+ insertionPosition = VisiblePosition(insertionPosition).deepEquivalent();
// Build up list of ancestors in between the start node and the start block.
Vector<Element*> ancestors;
- if (startNode != startBlock) {
- for (Element* n = startNode->parentElement(); n && n != startBlock; n = n->parentElement())
+ if (insertionPosition.node() != startBlock) {
+ for (Element* n = insertionPosition.node()->parentElement(); n && n != startBlock; n = n->parentElement())
ancestors.append(n);
}
// Make sure we do not cause a rendered space to become unrendered.
// FIXME: We need the affinity for pos, but pos.downstream() does not give it
- Position leadingWhitespace = pos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY);
+ Position leadingWhitespace = insertionPosition.leadingWhitespacePosition(VP_DEFAULT_AFFINITY);
// FIXME: leadingWhitespacePosition is returning the position before preserved newlines for positions
// after the preserved newline, causing the newline to be turned into a nbsp.
if (leadingWhitespace.isNotNull()) {
Text* textNode = static_cast<Text*>(leadingWhitespace.node());
ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace());
- replaceTextInNode(textNode, leadingWhitespace.offset(), 1, nonBreakingSpaceString());
+ replaceTextInNode(textNode, leadingWhitespace.m_offset, 1, nonBreakingSpaceString());
}
// Split at pos if in the middle of a text node.
- if (startNode->isTextNode()) {
- Text *textNode = static_cast<Text *>(startNode);
- bool atEnd = (unsigned)pos.offset() >= textNode->length();
- if (pos.offset() > 0 && !atEnd) {
- splitTextNode(textNode, pos.offset());
- pos = Position(startNode, 0);
- visiblePos = VisiblePosition(pos);
+ if (insertionPosition.node()->isTextNode()) {
+ Text* textNode = static_cast<Text*>(insertionPosition.node());
+ bool atEnd = (unsigned)insertionPosition.m_offset >= textNode->length();
+ if (insertionPosition.m_offset > 0 && !atEnd) {
+ splitTextNode(textNode, insertionPosition.m_offset);
+ insertionPosition.m_offset = 0;
+ visiblePos = VisiblePosition(insertionPosition);
splitText = true;
}
}
@@ -274,7 +274,7 @@ void InsertParagraphSeparatorCommand::doApply()
// Make clones of ancestors in between the start node and the start block.
RefPtr<Element> parent = blockToInsert;
for (size_t i = ancestors.size(); i != 0; --i) {
- RefPtr<Element> child = ancestors[i - 1]->cloneElement(); // shallow clone
+ RefPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren();
appendNode(child, parent);
parent = child.release();
}
@@ -286,10 +286,10 @@ void InsertParagraphSeparatorCommand::doApply()
appendNode(createBreakElement(document()).get(), blockToInsert.get());
// Move the start node and the siblings of the start node.
- if (startNode != startBlock) {
- Node *n = startNode;
- if (pos.offset() >= caretMaxOffset(startNode))
- n = startNode->nextSibling();
+ if (insertionPosition.node() != startBlock) {
+ Node* n = insertionPosition.node();
+ if (insertionPosition.m_offset >= caretMaxOffset(n))
+ n = n->nextSibling();
while (n && n != blockToInsert) {
Node *next = n->nextSibling();
@@ -320,18 +320,17 @@ void InsertParagraphSeparatorCommand::doApply()
// Handle whitespace that occurs after the split
if (splitText) {
updateLayout();
- pos = Position(startNode, 0);
- if (!pos.isRenderedCharacter()) {
+ insertionPosition = Position(insertionPosition.node(), 0);
+ if (!insertionPosition.isRenderedCharacter()) {
// Clear out all whitespace and insert one non-breaking space
- ASSERT(startNode);
- ASSERT(startNode->isTextNode());
- ASSERT(!startNode->renderer() || startNode->renderer()->style()->collapseWhiteSpace());
- deleteInsignificantTextDownstream(pos);
- insertTextIntoNode(static_cast<Text*>(startNode), 0, nonBreakingSpaceString());
+ ASSERT(insertionPosition.node()->isTextNode());
+ ASSERT(!insertionPosition.node()->renderer() || insertionPosition.node()->renderer()->style()->collapseWhiteSpace());
+ deleteInsignificantTextDownstream(insertionPosition);
+ insertTextIntoNode(static_cast<Text*>(insertionPosition.node()), 0, nonBreakingSpaceString());
}
}
- setEndingSelection(Selection(Position(blockToInsert.get(), 0), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(blockToInsert.get(), 0), DOWNSTREAM));
applyStyleAfterInsertion(startBlock);
}
diff --git a/WebCore/editing/InsertTextCommand.cpp b/WebCore/editing/InsertTextCommand.cpp
index 46e9a94..52da5d0 100644
--- a/WebCore/editing/InsertTextCommand.cpp
+++ b/WebCore/editing/InsertTextCommand.cpp
@@ -89,19 +89,19 @@ bool InsertTextCommand::performTrivialReplace(const String& text, bool selectIns
if (start.node() != end.node() || !start.node()->isTextNode() || isTabSpanTextNode(start.node()))
return false;
- replaceTextInNode(static_cast<Text*>(start.node()), start.offset(), end.offset() - start.offset(), text);
+ replaceTextInNode(static_cast<Text*>(start.node()), start.m_offset, end.m_offset - start.m_offset, text);
- Position endPosition(start.node(), start.offset() + text.length());
+ Position endPosition(start.node(), start.m_offset + text.length());
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
- Selection forcedEndingSelection;
+ VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(start, endPosition);
setEndingSelection(forcedEndingSelection);
if (!selectInsertedText)
- setEndingSelection(Selection(endingSelection().visibleEnd()));
+ setEndingSelection(VisibleSelection(endingSelection().visibleEnd()));
return true;
}
@@ -155,7 +155,7 @@ void InsertTextCommand::input(const String& originalText, bool selectInsertedTex
startPosition = prepareForTextInsertion(startPosition);
removePlaceholderAt(VisiblePosition(startPosition));
Text *textNode = static_cast<Text *>(startPosition.node());
- int offset = startPosition.offset();
+ int offset = startPosition.m_offset;
insertTextIntoNode(textNode, offset, text);
endPosition = Position(textNode, offset + text.length());
@@ -172,7 +172,7 @@ void InsertTextCommand::input(const String& originalText, bool selectInsertedTex
// We could have inserted a part of composed character sequence,
// so we are basically treating ending selection as a range to avoid validation.
// <http://bugs.webkit.org/show_bug.cgi?id=15781>
- Selection forcedEndingSelection;
+ VisibleSelection forcedEndingSelection;
forcedEndingSelection.setWithoutValidation(startPosition, endPosition);
setEndingSelection(forcedEndingSelection);
@@ -199,7 +199,7 @@ void InsertTextCommand::input(const String& originalText, bool selectInsertedTex
applyStyle(typingStyle);
if (!selectInsertedText)
- setEndingSelection(Selection(endingSelection().end(), endingSelection().affinity()));
+ setEndingSelection(VisibleSelection(endingSelection().end(), endingSelection().affinity()));
}
Position InsertTextCommand::insertTab(const Position& pos)
@@ -207,7 +207,7 @@ Position InsertTextCommand::insertTab(const Position& pos)
Position insertPos = VisiblePosition(pos, DOWNSTREAM).deepEquivalent();
Node *node = insertPos.node();
- unsigned int offset = insertPos.offset();
+ unsigned int offset = insertPos.m_offset;
// keep tabs coalesced in tab span
if (isTabSpanTextNode(node)) {
diff --git a/WebCore/editing/ModifySelectionListLevel.cpp b/WebCore/editing/ModifySelectionListLevel.cpp
index 9bc73c6..5ea658c 100644
--- a/WebCore/editing/ModifySelectionListLevel.cpp
+++ b/WebCore/editing/ModifySelectionListLevel.cpp
@@ -46,7 +46,7 @@ bool ModifySelectionListLevelCommand::preservesTypingStyle() const
}
// This needs to be static so it can be called by canIncreaseSelectionListLevel and canDecreaseSelectionListLevel
-static bool getStartEndListChildren(const Selection& selection, Node*& start, Node*& end)
+static bool getStartEndListChildren(const VisibleSelection& selection, Node*& start, Node*& end)
{
if (selection.isNone())
return false;
@@ -79,8 +79,8 @@ static bool getStartEndListChildren(const Selection& selection, Node*& start, No
// if the selection ends on a list item with a sublist, include the entire sublist
if (endListChild->renderer()->isListItem()) {
RenderObject* r = endListChild->renderer()->nextSibling();
- if (r && isListElement(r->element()))
- endListChild = r->element();
+ if (r && isListElement(r->node()))
+ endListChild = r->node();
}
start = startListChild;
@@ -141,7 +141,7 @@ IncreaseSelectionListLevelCommand::IncreaseSelectionListLevelCommand(Document* d
}
// This needs to be static so it can be called by canIncreaseSelectionListLevel
-static bool canIncreaseListLevel(const Selection& selection, Node*& start, Node*& end)
+static bool canIncreaseListLevel(const VisibleSelection& selection, Node*& start, Node*& end)
{
if (!getStartEndListChildren(selection, start, end))
return false;
@@ -175,7 +175,7 @@ void IncreaseSelectionListLevelCommand::doApply()
if (!canIncreaseListLevel(endingSelection(), startListChild, endListChild))
return;
- Node* previousItem = startListChild->renderer()->previousSibling()->element();
+ Node* previousItem = startListChild->renderer()->previousSibling()->node();
if (isListElement(previousItem)) {
// move nodes up into preceding list
appendSiblingNodeRange(startListChild, endListChild, static_cast<Element*>(previousItem));
@@ -187,7 +187,7 @@ void IncreaseSelectionListLevelCommand::doApply()
case InheritedListType:
newParent = startListChild->parentElement();
if (newParent)
- newParent = newParent->cloneElement();
+ newParent = newParent->cloneElementWithoutChildren();
break;
case OrderedList:
newParent = createOrderedListElement(document());
@@ -239,7 +239,7 @@ DecreaseSelectionListLevelCommand::DecreaseSelectionListLevelCommand(Document* d
}
// This needs to be static so it can be called by canDecreaseSelectionListLevel
-static bool canDecreaseListLevel(const Selection& selection, Node*& start, Node*& end)
+static bool canDecreaseListLevel(const VisibleSelection& selection, Node*& start, Node*& end)
{
if (!getStartEndListChildren(selection, start, end))
return false;
@@ -258,8 +258,8 @@ void DecreaseSelectionListLevelCommand::doApply()
if (!canDecreaseListLevel(endingSelection(), startListChild, endListChild))
return;
- Node* previousItem = startListChild->renderer()->previousSibling() ? startListChild->renderer()->previousSibling()->element() : 0;
- Node* nextItem = endListChild->renderer()->nextSibling() ? endListChild->renderer()->nextSibling()->element() : 0;
+ Node* previousItem = startListChild->renderer()->previousSibling() ? startListChild->renderer()->previousSibling()->node() : 0;
+ Node* nextItem = endListChild->renderer()->nextSibling() ? endListChild->renderer()->nextSibling()->node() : 0;
Element* listNode = startListChild->parentElement();
if (!previousItem) {
diff --git a/WebCore/editing/MoveSelectionCommand.cpp b/WebCore/editing/MoveSelectionCommand.cpp
index 08587cb..2c656e7 100644
--- a/WebCore/editing/MoveSelectionCommand.cpp
+++ b/WebCore/editing/MoveSelectionCommand.cpp
@@ -39,7 +39,7 @@ MoveSelectionCommand::MoveSelectionCommand(PassRefPtr<DocumentFragment> fragment
void MoveSelectionCommand::doApply()
{
- Selection selection = endingSelection();
+ VisibleSelection selection = endingSelection();
ASSERT(selection.isRange());
Position pos = m_position;
@@ -48,14 +48,14 @@ void MoveSelectionCommand::doApply()
// Update the position otherwise it may become invalid after the selection is deleted.
Node *positionNode = m_position.node();
- int positionOffset = m_position.offset();
+ int positionOffset = m_position.m_offset;
Position selectionEnd = selection.end();
- int selectionEndOffset = selectionEnd.offset();
+ int selectionEndOffset = selectionEnd.m_offset;
if (selectionEnd.node() == positionNode && selectionEndOffset < positionOffset) {
positionOffset -= selectionEndOffset;
Position selectionStart = selection.start();
if (selectionStart.node() == positionNode) {
- positionOffset += selectionStart.offset();
+ positionOffset += selectionStart.m_offset;
}
pos = Position(positionNode, positionOffset);
}
@@ -69,7 +69,11 @@ void MoveSelectionCommand::doApply()
if (!pos.node()->inDocument())
pos = endingSelection().start();
- setEndingSelection(Selection(pos, endingSelection().affinity()));
+ setEndingSelection(VisibleSelection(pos, endingSelection().affinity()));
+ if (!positionNode->inDocument()) {
+ // Document was modified out from under us.
+ return;
+ }
applyCommandToComposite(ReplaceSelectionCommand::create(positionNode->document(), m_fragment, true, m_smartMove));
}
diff --git a/WebCore/editing/RemoveFormatCommand.cpp b/WebCore/editing/RemoveFormatCommand.cpp
index 80e0ee7..609ab0e 100644
--- a/WebCore/editing/RemoveFormatCommand.cpp
+++ b/WebCore/editing/RemoveFormatCommand.cpp
@@ -30,7 +30,7 @@
#include "Editor.h"
#include "Frame.h"
#include "HTMLNames.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
#include "SelectionController.h"
#include "TextIterator.h"
#include "TypingCommand.h"
@@ -49,7 +49,7 @@ void RemoveFormatCommand::doApply()
Frame* frame = document()->frame();
// Make a plain text string from the selection to remove formatting like tables and lists.
- String string = plainText(frame->selection()->selection().toRange().get());
+ String string = plainText(frame->selection()->selection().toNormalizedRange().get());
// Get the default style for this editable root, it's the style that we'll give the
// content that we're operating on.
diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
index 15fc736..09ad985 100644
--- a/WebCore/editing/ReplaceSelectionCommand.cpp
+++ b/WebCore/editing/ReplaceSelectionCommand.cpp
@@ -61,7 +61,7 @@ enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
class ReplacementFragment : Noncopyable {
public:
- ReplacementFragment(Document*, DocumentFragment*, bool matchStyle, const Selection&);
+ ReplacementFragment(Document*, DocumentFragment*, bool matchStyle, const VisibleSelection&);
Node* firstChild() const;
Node* lastChild() const;
@@ -103,7 +103,7 @@ static bool isInterchangeConvertedSpaceSpan(const Node *node)
static_cast<const HTMLElement *>(node)->getAttribute(classAttr) == convertedSpaceSpanClassString;
}
-ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* fragment, bool matchStyle, const Selection& selection)
+ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* fragment, bool matchStyle, const VisibleSelection& selection)
: m_document(document),
m_fragment(fragment),
m_matchStyle(matchStyle),
@@ -126,8 +126,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
if (!editableRoot->inlineEventListenerForType(eventNames().webkitBeforeTextInsertedEvent) &&
// FIXME: Remove these checks once textareas and textfields actually register an event handler.
- !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestorNode->renderer()->isTextField()) &&
- !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestorNode->renderer()->isTextArea()) &&
+ !(shadowAncestorNode && shadowAncestorNode->renderer() && shadowAncestorNode->renderer()->isTextControl()) &&
editableRoot->isContentRichlyEditable()) {
removeInterchangeNodes(m_fragment.get());
return;
@@ -136,7 +135,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
Node* styleNode = selection.base().node();
RefPtr<Node> holder = insertFragmentForTestRendering(styleNode);
- RefPtr<Range> range = Selection::selectionFromContentsOfNode(holder.get()).toRange();
+ RefPtr<Range> range = VisibleSelection::selectionFromContentsOfNode(holder.get()).toNormalizedRange();
String text = plainText(range.get());
// Give the root a chance to change the text.
RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
@@ -147,7 +146,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
restoreTestRenderingNodesToFragment(holder.get());
removeNode(holder);
- m_fragment = createFragmentFromText(selection.toRange().get(), evt->text());
+ m_fragment = createFragmentFromText(selection.toNormalizedRange().get(), evt->text());
if (!m_fragment->firstChild())
return;
holder = insertFragmentForTestRendering(styleNode);
@@ -406,6 +405,23 @@ void ReplaceSelectionCommand::removeNodeAndPruneAncestors(Node* node)
m_firstNodeInserted = m_lastLeafInserted && m_lastLeafInserted->inDocument() ? afterFirst : 0;
}
+static bool isHeaderElement(Node* a)
+{
+ if (!a)
+ return false;
+
+ return a->hasTagName(h1Tag) ||
+ a->hasTagName(h2Tag) ||
+ a->hasTagName(h3Tag) ||
+ a->hasTagName(h4Tag) ||
+ a->hasTagName(h5Tag);
+}
+
+static bool haveSameTagName(Node* a, Node* b)
+{
+ return a && b && a->isElementNode() && b->isElementNode() && static_cast<Element*>(a)->tagName() == static_cast<Element*>(b)->tagName();
+}
+
bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const VisiblePosition& destination)
{
if (source.isNull() || destination.isNull())
@@ -414,10 +430,12 @@ bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V
Node* sourceNode = source.deepEquivalent().node();
Node* destinationNode = destination.deepEquivalent().node();
Node* sourceBlock = enclosingBlock(sourceNode);
+ Node* destinationBlock = enclosingBlock(destinationNode);
return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotationNode) &&
sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailBlockquote(sourceBlock)) &&
enclosingListChild(sourceBlock) == enclosingListChild(destinationNode) &&
enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(destination.deepEquivalent()) &&
+ (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destinationBlock)) &&
// Don't merge to or from a position before or after a block because it would
// be a no-op and cause infinite recursion.
!isBlock(sourceNode) && !isBlock(destinationNode);
@@ -491,10 +509,11 @@ void ReplaceSelectionCommand::handlePasteAsQuotationNode()
VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent()
{
Node* lastNode = m_lastLeafInserted.get();
- Node* enclosingSelect = enclosingNodeWithTag(Position(lastNode, 0), selectTag);
+ // FIXME: Why is this hack here? What's special about <select> tags?
+ Node* enclosingSelect = enclosingNodeWithTag(firstDeepEditingPositionForNode(lastNode), selectTag);
if (enclosingSelect)
lastNode = enclosingSelect;
- return VisiblePosition(Position(lastNode, maxDeepOffset(lastNode)));
+ return lastDeepEditingPositionForNode(lastNode);
}
VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent()
@@ -509,8 +528,9 @@ static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const
{
Node* topNode = fragment.firstChild();
- // Handling this case is more complicated (see handleStyleSpans) and doesn't receive the optimization.
- if (isMailPasteAsQuotationNode(topNode))
+ // Handling the case where we are doing Paste as Quotation or pasting into quoted content is more complicated (see handleStyleSpans)
+ // and doesn't receive the optimization.
+ if (isMailPasteAsQuotationNode(topNode) || nearestMailBlockquote(topNode))
return false;
// Either there are no style spans in the fragment or a WebKit client has added content to the fragment
@@ -573,11 +593,12 @@ void ReplaceSelectionCommand::handleStyleSpans()
RefPtr<CSSMutableStyleDeclaration> sourceDocumentStyle = static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl()->copy();
Node* context = sourceDocumentStyleSpan->parentNode();
- // If Mail wraps the fragment with a Paste as Quotation blockquote, styles from that element are
- // allowed to override those from the source document, see <rdar://problem/4930986>.
- if (isMailPasteAsQuotationNode(context)) {
- RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = computedStyle(context)->copyInheritableProperties();
- RefPtr<CSSMutableStyleDeclaration> parentStyle = computedStyle(context->parentNode())->copyInheritableProperties();
+ // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region,
+ // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
+ Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : nearestMailBlockquote(context);
+ if (blockquoteNode) {
+ RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = computedStyle(blockquoteNode)->copyInheritableProperties();
+ RefPtr<CSSMutableStyleDeclaration> parentStyle = computedStyle(blockquoteNode->parentNode())->copyInheritableProperties();
parentStyle->diff(blockquoteStyle.get());
CSSMutableStyleDeclaration::const_iterator end = blockquoteStyle->end();
@@ -586,7 +607,7 @@ void ReplaceSelectionCommand::handleStyleSpans()
sourceDocumentStyle->removeProperty(property.id());
}
- context = context->parentNode();
+ context = blockquoteNode->parentNode();
}
RefPtr<CSSMutableStyleDeclaration> contextStyle = computedStyle(context)->copyInheritableProperties();
@@ -679,7 +700,7 @@ void ReplaceSelectionCommand::mergeEndIfNeeded()
void ReplaceSelectionCommand::doApply()
{
- Selection selection = endingSelection();
+ VisibleSelection selection = endingSelection();
ASSERT(selection.isCaretOrRange());
ASSERT(selection.start().node());
if (selection.isNone() || !selection.start().node())
@@ -704,9 +725,9 @@ void ReplaceSelectionCommand::doApply()
Position insertionPos = selection.start();
bool startIsInsideMailBlockquote = nearestMailBlockquote(insertionPos.node());
- if (selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !startIsInsideMailBlockquote ||
+ if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !startIsInsideMailBlockquote) ||
startBlock == currentRoot ||
- startBlock && startBlock->renderer() && startBlock->renderer()->isListItem() ||
+ (startBlock && startBlock->renderer() && startBlock->renderer()->isListItem()) ||
selectionIsPlainText)
m_preventNesting = false;
@@ -821,11 +842,20 @@ void ReplaceSelectionCommand::doApply()
fragment.removeNode(refNode);
insertNodeAtAndUpdateNodesInserted(refNode, insertionPos);
-
+
+ // Mutation events (bug 22634) may have already removed the inserted content
+ if (!refNode->inDocument())
+ return;
+
while (node) {
Node* next = node->nextSibling();
fragment.removeNode(node);
insertNodeAfterAndUpdateNodesInserted(node, refNode.get());
+
+ // Mutation events (bug 22634) may have already removed the inserted content
+ if (!node->inDocument())
+ return;
+
refNode = node;
node = next;
}
@@ -846,7 +876,7 @@ void ReplaceSelectionCommand::doApply()
// We inserted before the startBlock to prevent nesting, and the content before the startBlock wasn't in its own block and
// didn't have a br after it, so the inserted content ended up in the same paragraph.
- if (startBlock && insertionPos.node() == startBlock->parentNode() && (unsigned)insertionPos.offset() < startBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
+ if (startBlock && insertionPos.node() == startBlock->parentNode() && (unsigned)insertionPos.m_offset < startBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
insertNodeAt(createBreakElement(document()).get(), startOfInsertedContent.deepEquivalent());
Position lastPositionToSelect;
@@ -878,9 +908,13 @@ void ReplaceSelectionCommand::doApply()
// Insert a line break just after the inserted content to separate it from what
// comes after and prevent that from happening.
VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
- if (startOfParagraph(endOfInsertedContent) == startOfParagraphToMove)
+ if (startOfParagraph(endOfInsertedContent) == startOfParagraphToMove) {
insertNodeAt(createBreakElement(document()).get(), endOfInsertedContent.deepEquivalent());
-
+ // Mutation events (bug 22634) triggered by inserting the <br> might have removed the content we're about to move
+ if (!startOfParagraphToMove.deepEquivalent().node()->inDocument())
+ return;
+ }
+
// FIXME: Maintain positions for the start and end of inserted content instead of keeping nodes. The nodes are
// only ever used to create positions where inserted content starts/ends.
moveParagraph(startOfParagraphToMove, endOfParagraph(startOfParagraphToMove), destination);
@@ -1013,9 +1047,9 @@ void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi
return;
if (m_selectReplacement)
- setEndingSelection(Selection(start, end, SEL_DEFAULT_AFFINITY));
+ setEndingSelection(VisibleSelection(start, end, SEL_DEFAULT_AFFINITY));
else
- setEndingSelection(Selection(end, SEL_DEFAULT_AFFINITY));
+ setEndingSelection(VisibleSelection(end, SEL_DEFAULT_AFFINITY));
}
EditAction ReplaceSelectionCommand::editingAction() const
diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp
index 67f675e..d606891 100644
--- a/WebCore/editing/SelectionController.cpp
+++ b/WebCore/editing/SelectionController.cpp
@@ -76,30 +76,30 @@ SelectionController::SelectionController(Frame* frame, bool isDragCaretControlle
void SelectionController::moveTo(const VisiblePosition &pos, bool userTriggered)
{
- setSelection(Selection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered);
+ setSelection(VisibleSelection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered);
}
void SelectionController::moveTo(const VisiblePosition &base, const VisiblePosition &extent, bool userTriggered)
{
- setSelection(Selection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()), true, true, userTriggered);
+ setSelection(VisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()), true, true, userTriggered);
}
void SelectionController::moveTo(const Position &pos, EAffinity affinity, bool userTriggered)
{
- setSelection(Selection(pos, affinity), true, true, userTriggered);
+ setSelection(VisibleSelection(pos, affinity), true, true, userTriggered);
}
void SelectionController::moveTo(const Range *r, EAffinity affinity, bool userTriggered)
{
- setSelection(Selection(startPosition(r), endPosition(r), affinity), true, true, userTriggered);
+ setSelection(VisibleSelection(startPosition(r), endPosition(r), affinity), true, true, userTriggered);
}
void SelectionController::moveTo(const Position &base, const Position &extent, EAffinity affinity, bool userTriggered)
{
- setSelection(Selection(base, extent, affinity), true, true, userTriggered);
+ setSelection(VisibleSelection(base, extent, affinity), true, true, userTriggered);
}
-void SelectionController::setSelection(const Selection& s, bool closeTyping, bool clearTypingStyle, bool userTriggered)
+void SelectionController::setSelection(const VisibleSelection& s, bool closeTyping, bool clearTypingStyle, bool userTriggered)
{
if (m_isDragCaretController) {
invalidateCaretRect();
@@ -134,7 +134,7 @@ void SelectionController::setSelection(const Selection& s, bool closeTyping, boo
if (m_sel == s)
return;
- Selection oldSelection = m_sel;
+ VisibleSelection oldSelection = m_sel;
m_sel = s;
@@ -151,7 +151,7 @@ void SelectionController::setSelection(const Selection& s, bool closeTyping, boo
m_frame->notifyRendererOfSelectionChange(userTriggered);
m_frame->respondToChangedSelection(oldSelection, closeTyping);
if (userTriggered)
- m_frame->revealCaret(RenderLayer::gAlignToEdgeIfNeeded);
+ m_frame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded, true);
notifyAccessibilityForSelectionChange();
}
@@ -215,12 +215,12 @@ void SelectionController::nodeWillBeRemoved(Node *node)
if (clearRenderTreeSelection) {
RefPtr<Document> document = m_sel.start().node()->document();
document->updateRendering();
- if (RenderView* view = static_cast<RenderView*>(document->renderer()))
+ if (RenderView* view = toRenderView(document->renderer()))
view->clearSelection();
}
if (clearDOMTreeSelection)
- setSelection(Selection(), false, false);
+ setSelection(VisibleSelection(), false, false);
}
void SelectionController::willBeModified(EAlteration alter, EDirection direction)
@@ -700,27 +700,27 @@ int SelectionController::xPosForVerticalArrowNavigation(EPositionType type)
void SelectionController::clear()
{
- setSelection(Selection());
+ setSelection(VisibleSelection());
}
void SelectionController::setBase(const VisiblePosition &pos, bool userTriggered)
{
- setSelection(Selection(pos.deepEquivalent(), m_sel.extent(), pos.affinity()), true, true, userTriggered);
+ setSelection(VisibleSelection(pos.deepEquivalent(), m_sel.extent(), pos.affinity()), true, true, userTriggered);
}
void SelectionController::setExtent(const VisiblePosition &pos, bool userTriggered)
{
- setSelection(Selection(m_sel.base(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered);
+ setSelection(VisibleSelection(m_sel.base(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered);
}
void SelectionController::setBase(const Position &pos, EAffinity affinity, bool userTriggered)
{
- setSelection(Selection(pos, m_sel.extent(), affinity), true, true, userTriggered);
+ setSelection(VisibleSelection(pos, m_sel.extent(), affinity), true, true, userTriggered);
}
void SelectionController::setExtent(const Position &pos, EAffinity affinity, bool userTriggered)
{
- setSelection(Selection(m_sel.base(), pos, affinity), true, true, userTriggered);
+ setSelection(VisibleSelection(m_sel.base(), pos, affinity), true, true, userTriggered);
}
void SelectionController::setNeedsLayout(bool flag)
@@ -830,7 +830,7 @@ IntRect SelectionController::caretRepaintRect() const
bool SelectionController::recomputeCaretRect()
{
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return false;
FrameView* v = m_frame->document()->view();
@@ -853,9 +853,10 @@ bool SelectionController::recomputeCaretRect()
if (oldAbsRepaintRect == m_absCaretBounds)
return false;
- if (RenderView* view = static_cast<RenderView*>(m_frame->document()->renderer())) {
- view->repaintViewRectangle(oldAbsRepaintRect, false);
- view->repaintViewRectangle(m_absCaretBounds, false);
+ if (RenderView* view = toRenderView(m_frame->document()->renderer())) {
+ // FIXME: make caret repainting container-aware.
+ view->repaintRectangleInViewAndCompositedLayers(oldAbsRepaintRect, false);
+ view->repaintRectangleInViewAndCompositedLayers(m_absCaretBounds, false);
}
return true;
@@ -886,8 +887,8 @@ void SelectionController::invalidateCaretRect()
m_needsLayout = true;
if (!caretRectChanged) {
- if (RenderView* view = static_cast<RenderView*>(d->renderer()))
- view->repaintViewRectangle(caretRepaintRect(), false);
+ if (RenderView* view = toRenderView(d->renderer()))
+ view->repaintRectangleInViewAndCompositedLayers(caretRepaintRect(), false);
}
}
@@ -931,9 +932,9 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
if (selected) {
int offset = 0;
if (r->node() == m_sel.start().node())
- offset = m_sel.start().offset();
+ offset = m_sel.start().m_offset;
else if (r->node() == m_sel.end().node())
- offset = m_sel.end().offset();
+ offset = m_sel.end().m_offset;
int pos;
InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos);
@@ -995,7 +996,8 @@ bool SelectionController::contains(const IntPoint& point)
if (!document->renderer())
return false;
- HitTestRequest request(true, true);
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
HitTestResult result(point);
document->renderView()->layer()->hitTest(request, result);
Node* innerNode = result.innerNode();
@@ -1041,8 +1043,6 @@ void SelectionController::selectFrameElementInParentIfFullySelected()
// Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
Document* doc = m_frame->document();
- if (!doc)
- return;
Element* ownerElement = doc->ownerElement();
if (!ownerElement)
return;
@@ -1060,7 +1060,7 @@ void SelectionController::selectFrameElementInParentIfFullySelected()
VisiblePosition afterOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex + 1, VP_UPSTREAM_IF_POSSIBLE));
// Focus on the parent frame, and then select from before this element to after.
- Selection newSelection(beforeOwnerElement, afterOwnerElement);
+ VisibleSelection newSelection(beforeOwnerElement, afterOwnerElement);
if (parent->shouldChangeSelection(newSelection)) {
page->focusController()->setFocusedFrame(parent);
parent->selection()->setSelection(newSelection);
@@ -1070,8 +1070,6 @@ void SelectionController::selectFrameElementInParentIfFullySelected()
void SelectionController::selectAll()
{
Document* document = m_frame->document();
- if (!document)
- return;
if (document->focusedNode() && document->focusedNode()->canSelectAll()) {
document->focusedNode()->selectAll();
@@ -1088,7 +1086,7 @@ void SelectionController::selectAll()
}
if (!root)
return;
- Selection newSelection(Selection::selectionFromContentsOfNode(root));
+ VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode(root));
if (m_frame->shouldChangeSelection(newSelection))
setSelection(newSelection);
selectFrameElementInParentIfFullySelected();
@@ -1132,7 +1130,7 @@ bool SelectionController::setSelectedRange(Range* range, EAffinity affinity, boo
// FIXME: Can we provide extentAffinity?
VisiblePosition visibleStart(startContainer, startOffset, collapsed ? affinity : DOWNSTREAM);
VisiblePosition visibleEnd(endContainer, endOffset, SEL_DEFAULT_AFFINITY);
- setSelection(Selection(visibleStart, visibleEnd), closeTyping);
+ setSelection(VisibleSelection(visibleStart, visibleEnd), closeTyping);
return true;
}
@@ -1166,8 +1164,8 @@ void SelectionController::focusedOrActiveStateChanged()
// Because RenderObject::selectionBackgroundColor() and
// RenderObject::selectionForegroundColor() check if the frame is active,
// we have to update places those colors were painted.
- if (RenderView* view = static_cast<RenderView*>(m_frame->document()->renderer()))
- view->repaintViewRectangle(enclosingIntRect(m_frame->selectionBounds()));
+ if (RenderView* view = toRenderView(m_frame->document()->renderer()))
+ view->repaintRectangleInViewAndCompositedLayers(enclosingIntRect(m_frame->selectionBounds()));
// Caret appears in the active frame.
if (activeAndFocused)
@@ -1205,8 +1203,7 @@ void SelectionController::setFocused(bool flag)
focusedOrActiveStateChanged();
- if (Document* doc = m_frame->document())
- doc->dispatchWindowEvent(flag ? eventNames().focusEvent : eventNames().blurEvent, false, false);
+ m_frame->document()->dispatchWindowEvent(flag ? eventNames().focusEvent : eventNames().blurEvent, false, false);
}
bool SelectionController::isFocusedAndActive() const
diff --git a/WebCore/editing/SelectionController.h b/WebCore/editing/SelectionController.h
index fe5e90d..21e849d 100644
--- a/WebCore/editing/SelectionController.h
+++ b/WebCore/editing/SelectionController.h
@@ -27,8 +27,8 @@
#define SelectionController_h
#include "IntRect.h"
-#include "Selection.h"
#include "Range.h"
+#include "VisibleSelection.h"
#include <wtf/Noncopyable.h>
namespace WebCore {
@@ -56,8 +56,8 @@ public:
void moveTo(const Position&, EAffinity, bool userTriggered = false);
void moveTo(const Position&, const Position&, EAffinity, bool userTriggered = false);
- const Selection& selection() const { return m_sel; }
- void setSelection(const Selection&, bool closeTyping = true, bool clearTypingStyle = true, bool userTriggered = false);
+ const VisibleSelection& selection() const { return m_sel; }
+ void setSelection(const VisibleSelection&, bool closeTyping = true, bool clearTypingStyle = true, bool userTriggered = false);
bool setSelectedRange(Range*, EAffinity, bool closeTyping);
void selectAll();
void clear();
@@ -67,7 +67,7 @@ public:
bool contains(const IntPoint&);
- Selection::EState state() const { return m_sel.state(); }
+ VisibleSelection::SelectionType selectionType() const { return m_sel.selectionType(); }
EAffinity affinity() const { return m_sel.affinity(); }
@@ -103,7 +103,7 @@ public:
bool isCaretOrRange() const { return m_sel.isCaretOrRange(); }
bool isInPasswordField() const;
- PassRefPtr<Range> toRange() const { return m_sel.toRange(); }
+ PassRefPtr<Range> toNormalizedRange() const { return m_sel.toNormalizedRange(); }
void debugRenderer(RenderObject*, bool selected) const;
@@ -154,7 +154,7 @@ private:
Frame* m_frame;
int m_xPosForVerticalArrowNavigation;
- Selection m_sel;
+ VisibleSelection m_sel;
IntRect m_caretRect; // caret rect in coords local to the renderer responsible for painting the caret
IntRect m_absCaretBounds; // absolute bounding rect for the caret
diff --git a/WebCore/editing/SmartReplaceCF.cpp b/WebCore/editing/SmartReplaceCF.cpp
index f2fd985..c5fa9a8 100644
--- a/WebCore/editing/SmartReplaceCF.cpp
+++ b/WebCore/editing/SmartReplaceCF.cpp
@@ -30,6 +30,7 @@
#include "SmartReplace.h"
#include <CoreFoundation/CFCharacterSet.h>
+#include <CoreFoundation/CFString.h>
namespace WebCore {
diff --git a/WebCore/editing/SplitElementCommand.cpp b/WebCore/editing/SplitElementCommand.cpp
index 69447d4..35dfc6f 100644
--- a/WebCore/editing/SplitElementCommand.cpp
+++ b/WebCore/editing/SplitElementCommand.cpp
@@ -43,7 +43,7 @@ SplitElementCommand::SplitElementCommand(PassRefPtr<Element> element, PassRefPtr
void SplitElementCommand::doApply()
{
- RefPtr<Element> prefixElement = m_element2->cloneElement();
+ RefPtr<Element> prefixElement = m_element2->cloneElementWithoutChildren();
if (m_atChild->parentNode() != m_element2)
return;
diff --git a/WebCore/editing/TextIterator.cpp b/WebCore/editing/TextIterator.cpp
index f617889..2d7e641 100644
--- a/WebCore/editing/TextIterator.cpp
+++ b/WebCore/editing/TextIterator.cpp
@@ -224,7 +224,9 @@ void TextIterator::advance()
if (!m_handledNode) {
if (renderer->isText() && m_node->nodeType() == Node::TEXT_NODE) // FIXME: What about CDATA_SECTION_NODE?
m_handledNode = handleTextNode();
- else if (renderer && (renderer->isImage() || renderer->isWidget() || (renderer->element() && renderer->element()->isControl())))
+ else if (renderer && (renderer->isImage() || renderer->isWidget() ||
+ (renderer->node() && renderer->node()->isElementNode() &&
+ static_cast<Element*>(renderer->node())->isFormControlElement())))
m_handledNode = handleReplacedElement();
else
m_handledNode = handleNonTextNode();
@@ -247,7 +249,7 @@ void TextIterator::advance()
parentNode = m_node->shadowParentNode();
}
while (!next && parentNode) {
- if (pastEnd && parentNode == m_endContainer || m_endContainer->isDescendantOf(parentNode))
+ if ((pastEnd && parentNode == m_endContainer) || m_endContainer->isDescendantOf(parentNode))
return;
bool haveRenderer = m_node->renderer();
m_node = parentNode;
@@ -414,8 +416,8 @@ bool TextIterator::handleReplacedElement()
return false;
}
- if (m_enterTextControls && (renderer->isTextArea() || renderer->isTextField())) {
- m_node = static_cast<RenderTextControl*>(renderer)->innerTextElement();
+ if (m_enterTextControls && renderer->isTextControl()) {
+ m_node = toRenderTextControl(renderer)->innerTextElement();
m_offset = 0;
m_inShadowContent = true;
return false;
@@ -858,7 +860,7 @@ void SimplifiedBackwardsTextIterator::advance()
if (!m_handledNode &&
canHaveChildrenForEditing(m_node) &&
m_node->parentNode() &&
- (!m_node->lastChild() || m_node == m_endNode && m_endOffset == 0)) {
+ (!m_node->lastChild() || (m_node == m_endNode && m_endOffset == 0))) {
exitNode();
if (m_positionNode) {
m_handledNode = true;
@@ -1057,7 +1059,7 @@ void CharacterIterator::advance(int count)
String CharacterIterator::string(int numChars)
{
Vector<UChar> result;
- result.reserveCapacity(numChars);
+ result.reserveInitialCapacity(numChars);
while (numChars > 0 && !atEnd()) {
int runSize = min(numChars, length());
result.append(characters(), runSize);
@@ -1081,6 +1083,81 @@ static PassRefPtr<Range> characterSubrange(CharacterIterator& it, int offset, in
end->endContainer(), end->endOffset());
}
+BackwardsCharacterIterator::BackwardsCharacterIterator()
+ : m_offset(0)
+ , m_runOffset(0)
+ , m_atBreak(true)
+{
+}
+
+BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range)
+ : m_offset(0)
+ , m_runOffset(0)
+ , m_atBreak(true)
+ , m_textIterator(range)
+{
+ while (!atEnd() && !m_textIterator.length())
+ m_textIterator.advance();
+}
+
+PassRefPtr<Range> BackwardsCharacterIterator::range() const
+{
+ RefPtr<Range> r = m_textIterator.range();
+ if (!m_textIterator.atEnd()) {
+ if (m_textIterator.length() <= 1)
+ ASSERT(m_runOffset == 0);
+ else {
+ Node* n = r->startContainer();
+ ASSERT(n == r->endContainer());
+ int offset = r->endOffset() - m_runOffset;
+ ExceptionCode ec = 0;
+ r->setStart(n, offset - 1, ec);
+ r->setEnd(n, offset, ec);
+ ASSERT(!ec);
+ }
+ }
+ return r.release();
+}
+
+void BackwardsCharacterIterator::advance(int count)
+{
+ if (count <= 0) {
+ ASSERT(!count);
+ return;
+ }
+
+ m_atBreak = false;
+
+ int remaining = m_textIterator.length() - m_runOffset;
+ if (count < remaining) {
+ m_runOffset += count;
+ m_offset += count;
+ return;
+ }
+
+ count -= remaining;
+ m_offset += remaining;
+
+ for (m_textIterator.advance(); !atEnd(); m_textIterator.advance()) {
+ int runLength = m_textIterator.length();
+ if (runLength == 0)
+ m_atBreak = true;
+ else {
+ if (count < runLength) {
+ m_runOffset = count;
+ m_offset += count;
+ return;
+ }
+
+ count -= runLength;
+ m_offset += runLength;
+ }
+ }
+
+ m_atBreak = true;
+ m_runOffset = 0;
+}
+
// --------
WordAwareIterator::WordAwareIterator()
@@ -1225,7 +1302,7 @@ inline SearchBuffer::SearchBuffer(const String& target, bool isCaseSensitive)
ASSERT(!m_target.isEmpty());
size_t targetLength = target.length();
- m_buffer.reserveCapacity(max(targetLength * 8, minimumSearchBufferSize));
+ m_buffer.reserveInitialCapacity(max(targetLength * 8, minimumSearchBufferSize));
m_overlap = m_buffer.capacity() / 4;
// Grab the single global searcher.
@@ -1481,7 +1558,7 @@ PassRefPtr<Range> TextIterator::rangeFromLocationAndLength(Element *scope, int r
Position runEnd = VisiblePosition(runStart).next().deepEquivalent();
if (runEnd.isNotNull()) {
ExceptionCode ec = 0;
- textRunRange->setEnd(runEnd.node(), runEnd.offset(), ec);
+ textRunRange->setEnd(runEnd.node(), runEnd.m_offset, ec);
ASSERT(!ec);
}
}
@@ -1542,7 +1619,7 @@ UChar* plainTextToMallocAllocatedBuffer(const Range* r, unsigned& bufferLength,
typedef pair<UChar*, unsigned> TextSegment;
Vector<TextSegment>* textSegments = 0;
Vector<UChar> textBuffer;
- textBuffer.reserveCapacity(cMaxSegmentSize);
+ textBuffer.reserveInitialCapacity(cMaxSegmentSize);
for (TextIterator it(r); !it.atEnd(); it.advance()) {
if (textBuffer.size() && textBuffer.size() + it.length() > cMaxSegmentSize) {
UChar* newSegmentBuffer = static_cast<UChar*>(malloc(textBuffer.size() * sizeof(UChar)));
diff --git a/WebCore/editing/TextIterator.h b/WebCore/editing/TextIterator.h
index 308ffc9..f00bea4 100644
--- a/WebCore/editing/TextIterator.h
+++ b/WebCore/editing/TextIterator.h
@@ -216,6 +216,25 @@ private:
TextIterator m_textIterator;
};
+class BackwardsCharacterIterator {
+public:
+ BackwardsCharacterIterator();
+ explicit BackwardsCharacterIterator(const Range*);
+
+ void advance(int);
+
+ bool atEnd() const { return m_textIterator.atEnd(); }
+
+ PassRefPtr<Range> range() const;
+
+private:
+ int m_offset;
+ int m_runOffset;
+ bool m_atBreak;
+
+ SimplifiedBackwardsTextIterator m_textIterator;
+};
+
// Very similar to the TextIterator, except that the chunks of text returned are "well behaved",
// meaning they never end split up a word. This is useful for spellcheck or (perhaps one day) searching.
class WordAwareIterator {
diff --git a/WebCore/editing/TypingCommand.cpp b/WebCore/editing/TypingCommand.cpp
index 414680f..6235f7a 100644
--- a/WebCore/editing/TypingCommand.cpp
+++ b/WebCore/editing/TypingCommand.cpp
@@ -36,6 +36,7 @@
#include "InsertLineBreakCommand.h"
#include "InsertParagraphSeparatorCommand.h"
#include "InsertTextCommand.h"
+#include "RenderObject.h"
#include "SelectionController.h"
#include "VisiblePosition.h"
#include "htmlediting.h"
@@ -48,7 +49,6 @@ TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, con
m_commandType(commandType),
m_textToInsert(textToInsert),
m_openForMoreTyping(true),
- m_applyEditing(false),
m_selectInsertedText(selectInsertedText),
m_smartDelete(false),
m_granularity(granularity),
@@ -125,14 +125,14 @@ void TypingCommand::insertText(Document* document, const String& text, bool sele
insertText(document, text, frame->selection()->selection(), selectInsertedText, insertedTextIsComposition);
}
-void TypingCommand::insertText(Document* document, const String& text, const Selection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
+void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
{
ASSERT(document);
RefPtr<Frame> frame = document->frame();
ASSERT(frame);
- Selection currentSelection = frame->selection()->selection();
+ VisibleSelection currentSelection = frame->selection()->selection();
bool changeSelection = currentSelection != selectionForInsertion;
String newText = text;
@@ -300,13 +300,7 @@ void TypingCommand::markMisspellingsAfterTyping()
void TypingCommand::typingAddedToOpenCommand()
{
markMisspellingsAfterTyping();
- // Do not apply editing to the frame on the first time through.
- // The frame will get told in the same way as all other commands.
- // But since this command stays open and is used for additional typing,
- // we need to tell the frame here as other commands are added.
- if (m_applyEditing)
- document()->frame()->editor()->appliedEditing(this);
- m_applyEditing = true;
+ document()->frame()->editor()->appliedEditing(this);
}
void TypingCommand::insertText(const String &text, bool selectInsertedText)
@@ -370,19 +364,19 @@ void TypingCommand::insertParagraphSeparatorInQuotedContent()
void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
{
- Selection selectionToDelete;
- Selection selectionAfterUndo;
+ VisibleSelection selectionToDelete;
+ VisibleSelection selectionAfterUndo;
- switch (endingSelection().state()) {
- case Selection::RANGE:
+ switch (endingSelection().selectionType()) {
+ case VisibleSelection::RangeSelection:
selectionToDelete = endingSelection();
selectionAfterUndo = selectionToDelete;
break;
- case Selection::CARET: {
- if (breakOutOfEmptyMailBlockquotedParagraph()) {
+ case VisibleSelection::CaretSelection: {
+ // After breaking out of an empty mail blockquote, we still want continue with the deletion
+ // so actual content will get deleted, and not just the quote style.
+ if (breakOutOfEmptyMailBlockquotedParagraph())
typingAddedToOpenCommand();
- return;
- }
m_smartDelete = false;
@@ -410,63 +404,62 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
selection.modify(SelectionController::EXTEND, SelectionController::BACKWARD, granularity);
// If the caret is just after a table, select the table and don't delete anything.
} else if (Node* table = isFirstPositionAfterTable(visibleStart)) {
- setEndingSelection(Selection(Position(table, 0), endingSelection().start(), DOWNSTREAM));
+ setEndingSelection(VisibleSelection(Position(table, 0), endingSelection().start(), DOWNSTREAM));
typingAddedToOpenCommand();
return;
}
selectionToDelete = selection.selection();
- if (granularity == CharacterGranularity && selectionToDelete.end().offset() - selectionToDelete.start().offset() > 1) {
- // When we delete a ligature consisting of multiple Unicode characters with a backspace key,
- // we should not delete the ligature but delete only its last characeter. To check we are deleting
- // a ligature, we retrieve the previous position of the caret and count the number of
- // characters to be deleted.
- // To prevent from calculating the previous position every time when pressing a backspace key,
- // we retrieve the previous position only when the given selection consists of two or more characters.
- if (selectionToDelete.end().offset() - selectionToDelete.end().previous(UsingComposedCharacters).offset() > 1)
- selectionToDelete.setWithoutValidation(selectionToDelete.end(), selectionToDelete.end().previous(NotUsingComposedCharacters));
+ if (granularity == CharacterGranularity && selectionToDelete.end().node() == selectionToDelete.start().node() && selectionToDelete.end().m_offset - selectionToDelete.start().m_offset > 1) {
+ // If there are multiple Unicode code points to be deleted, adjust the range to match platform conventions.
+ selectionToDelete.setWithoutValidation(selectionToDelete.end(), selectionToDelete.end().previous(BackwardDeletion));
}
if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
selectionAfterUndo = selectionToDelete;
else
// It's a little tricky to compute what the starting selection would have been in the original document.
- // We can't let the Selection class's validation kick in or it'll adjust for us based on
+ // We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
// the current state of the document and we'll get the wrong result.
selectionAfterUndo.setWithoutValidation(startingSelection().end(), selectionToDelete.extent());
break;
}
- case Selection::NONE:
+ case VisibleSelection::NoSelection:
ASSERT_NOT_REACHED();
break;
}
- if (selectionToDelete.isCaretOrRange() && document()->frame()->shouldDeleteSelection(selectionToDelete)) {
- if (killRing)
- document()->frame()->editor()->addToKillRing(selectionToDelete.toRange().get(), false);
- // Make undo select everything that has been deleted, unless an undo will undo more than just this deletion.
- // FIXME: This behaves like TextEdit except for the case where you open with text insertion and then delete
- // more text than you insert. In that case all of the text that was around originally should be selected.
- if (m_openedByBackwardDelete)
- setStartingSelection(selectionAfterUndo);
- CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
- setSmartDelete(false);
- typingAddedToOpenCommand();
- }
+ ASSERT(!selectionToDelete.isNone());
+ if (selectionToDelete.isNone())
+ return;
+
+ if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
+ return;
+
+ if (killRing)
+ document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
+ // Make undo select everything that has been deleted, unless an undo will undo more than just this deletion.
+ // FIXME: This behaves like TextEdit except for the case where you open with text insertion and then delete
+ // more text than you insert. In that case all of the text that was around originally should be selected.
+ if (m_openedByBackwardDelete)
+ setStartingSelection(selectionAfterUndo);
+ CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
+ setSmartDelete(false);
+ typingAddedToOpenCommand();
}
void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
{
- Selection selectionToDelete;
- Selection selectionAfterUndo;
+ VisibleSelection selectionToDelete;
+ VisibleSelection selectionAfterUndo;
- switch (endingSelection().state()) {
- case Selection::RANGE:
+ switch (endingSelection().selectionType()) {
+ case VisibleSelection::RangeSelection:
selectionToDelete = endingSelection();
selectionAfterUndo = selectionToDelete;
break;
- case Selection::CARET: {
+ case VisibleSelection::CaretSelection: {
m_smartDelete = false;
// Handle delete at beginning-of-block case.
@@ -483,8 +476,8 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
if (visibleEnd == endOfParagraph(visibleEnd))
downstreamEnd = visibleEnd.next(true).deepEquivalent().downstream();
// When deleting tables: Select the table first, then perform the deletion
- if (downstreamEnd.node() && downstreamEnd.node()->renderer() && downstreamEnd.node()->renderer()->isTable() && downstreamEnd.offset() == 0) {
- setEndingSelection(Selection(endingSelection().end(), Position(downstreamEnd.node(), maxDeepOffset(downstreamEnd.node())), DOWNSTREAM));
+ if (downstreamEnd.node() && downstreamEnd.node()->renderer() && downstreamEnd.node()->renderer()->isTable() && downstreamEnd.m_offset == 0) {
+ setEndingSelection(VisibleSelection(endingSelection().end(), lastDeepEditingPositionForNode(downstreamEnd.node()), DOWNSTREAM));
typingAddedToOpenCommand();
return;
}
@@ -498,7 +491,7 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
selectionAfterUndo = selectionToDelete;
else {
// It's a little tricky to compute what the starting selection would have been in the original document.
- // We can't let the Selection class's validation kick in or it'll adjust for us based on
+ // We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
// the current state of the document and we'll get the wrong result.
Position extent = startingSelection().end();
if (extent.node() != selectionToDelete.end().node())
@@ -506,29 +499,34 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
else {
int extraCharacters;
if (selectionToDelete.start().node() == selectionToDelete.end().node())
- extraCharacters = selectionToDelete.end().offset() - selectionToDelete.start().offset();
+ extraCharacters = selectionToDelete.end().m_offset - selectionToDelete.start().m_offset;
else
- extraCharacters = selectionToDelete.end().offset();
- extent = Position(extent.node(), extent.offset() + extraCharacters);
+ extraCharacters = selectionToDelete.end().m_offset;
+ extent = Position(extent.node(), extent.m_offset + extraCharacters);
}
selectionAfterUndo.setWithoutValidation(startingSelection().start(), extent);
}
break;
}
- case Selection::NONE:
+ case VisibleSelection::NoSelection:
ASSERT_NOT_REACHED();
break;
}
- if (selectionToDelete.isCaretOrRange() && document()->frame()->shouldDeleteSelection(selectionToDelete)) {
- if (killRing)
- document()->frame()->editor()->addToKillRing(selectionToDelete.toRange().get(), false);
- // make undo select what was deleted
- setStartingSelection(selectionAfterUndo);
- CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
- setSmartDelete(false);
- typingAddedToOpenCommand();
- }
+ ASSERT(!selectionToDelete.isNone());
+ if (selectionToDelete.isNone())
+ return;
+
+ if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
+ return;
+
+ if (killRing)
+ document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
+ // make undo select what was deleted
+ setStartingSelection(selectionAfterUndo);
+ CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
+ setSmartDelete(false);
+ typingAddedToOpenCommand();
}
void TypingCommand::deleteSelection(bool smartDelete)
diff --git a/WebCore/editing/TypingCommand.h b/WebCore/editing/TypingCommand.h
index b4e1091..bf588be 100644
--- a/WebCore/editing/TypingCommand.h
+++ b/WebCore/editing/TypingCommand.h
@@ -46,7 +46,7 @@ public:
static void deleteKeyPressed(Document*, bool smartDelete = false, TextGranularity = CharacterGranularity, bool killRing = false);
static void forwardDeleteKeyPressed(Document*, bool smartDelete = false, TextGranularity = CharacterGranularity, bool killRing = false);
static void insertText(Document*, const String&, bool selectInsertedText = false, bool insertedTextIsComposition = false);
- static void insertText(Document*, const String&, const Selection&, bool selectInsertedText = false, bool insertedTextIsComposition = false);
+ static void insertText(Document*, const String&, const VisibleSelection&, bool selectInsertedText = false, bool insertedTextIsComposition = false);
static void insertLineBreak(Document*);
static void insertParagraphSeparator(Document*);
static void insertParagraphSeparatorInQuotedContent(Document*);
@@ -87,7 +87,6 @@ private:
ETypingCommand m_commandType;
String m_textToInsert;
bool m_openForMoreTyping;
- bool m_applyEditing;
bool m_selectInsertedText;
bool m_smartDelete;
TextGranularity m_granularity;
diff --git a/WebCore/editing/VisiblePosition.cpp b/WebCore/editing/VisiblePosition.cpp
index 3d771c6..27ee146 100644
--- a/WebCore/editing/VisiblePosition.cpp
+++ b/WebCore/editing/VisiblePosition.cpp
@@ -81,7 +81,7 @@ VisiblePosition VisiblePosition::previous(bool stayInEditableContent) const
Position pos = previousVisuallyDistinctCandidate(m_deepPosition);
// return null visible position if there is no previous visible position
- if (pos.atStart())
+ if (pos.atStartOfTree())
return VisiblePosition();
VisiblePosition prev = VisiblePosition(pos, DOWNSTREAM);
@@ -125,7 +125,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
if (!box)
return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
- RenderObject* renderer = box->object();
+ RenderObject* renderer = box->renderer();
while (true) {
if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretRightmostOffset())
@@ -147,7 +147,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
// Reposition at the other logical position corresponding to our edge's visual position and go for another round.
box = prevBox;
- renderer = box->object();
+ renderer = box->renderer();
offset = prevBox->caretRightmostOffset();
continue;
}
@@ -176,7 +176,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
break;
box = prevBox;
}
- renderer = box->object();
+ renderer = box->renderer();
offset = box->caretRightmostOffset();
if (box->direction() == primaryDirection)
break;
@@ -185,7 +185,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
if (prevBox) {
box = prevBox;
- renderer = box->object();
+ renderer = box->renderer();
offset = box->caretRightmostOffset();
if (box->bidiLevel() > level) {
do {
@@ -215,15 +215,15 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
break;
level = box->bidiLevel();
}
- renderer = box->object();
+ renderer = box->renderer();
offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
}
break;
}
- p = Position(renderer->element(), offset);
+ p = Position(renderer->node(), offset);
- if (p.isCandidate() && p.downstream() != downstreamStart || p.atStart() || p.atEnd())
+ if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
return p;
}
}
@@ -231,7 +231,8 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
VisiblePosition VisiblePosition::left(bool stayInEditableContent) const
{
Position pos = leftVisuallyDistinctCandidate();
- if (pos.atStart() || pos.atEnd())
+ // FIXME: Why can't we move left from the last position in a tree?
+ if (pos.atStartOfTree() || pos.atEndOfTree())
return VisiblePosition();
VisiblePosition left = VisiblePosition(pos, DOWNSTREAM);
@@ -266,7 +267,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
if (!box)
return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
- RenderObject* renderer = box->object();
+ RenderObject* renderer = box->renderer();
while (true) {
if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretLeftmostOffset())
@@ -288,7 +289,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
// Reposition at the other logical position corresponding to our edge's visual position and go for another round.
box = nextBox;
- renderer = box->object();
+ renderer = box->renderer();
offset = nextBox->caretLeftmostOffset();
continue;
}
@@ -318,7 +319,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
break;
box = nextBox;
}
- renderer = box->object();
+ renderer = box->renderer();
offset = box->caretLeftmostOffset();
if (box->direction() == primaryDirection)
break;
@@ -327,7 +328,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
if (nextBox) {
box = nextBox;
- renderer = box->object();
+ renderer = box->renderer();
offset = box->caretLeftmostOffset();
if (box->bidiLevel() > level) {
do {
@@ -357,15 +358,15 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
break;
level = box->bidiLevel();
}
- renderer = box->object();
+ renderer = box->renderer();
offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
}
break;
}
- p = Position(renderer->element(), offset);
+ p = Position(renderer->node(), offset);
- if (p.isCandidate() && p.downstream() != downstreamStart || p.atStart() || p.atEnd())
+ if ((p.isCandidate() && p.downstream() != downstreamStart) || p.atStartOfTree() || p.atEndOfTree())
return p;
}
}
@@ -373,7 +374,8 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
VisiblePosition VisiblePosition::right(bool stayInEditableContent) const
{
Position pos = rightVisuallyDistinctCandidate();
- if (pos.atStart() || pos.atEnd())
+ // FIXME: Why can't we move left from the last position in a tree?
+ if (pos.atStartOfTree() || pos.atEndOfTree())
return VisiblePosition();
VisiblePosition right = VisiblePosition(pos, DOWNSTREAM);
@@ -399,7 +401,7 @@ VisiblePosition VisiblePosition::honorEditableBoundaryAtOrBefore(const VisiblePo
// Return pos itself if the two are from the very same editable region, or both are non-editable
// FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
- // to it is allowed. Selection::adjustForEditableContent has this problem too.
+ // to it is allowed. VisibleSelection::adjustForEditableContent has this problem too.
if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)
return pos;
@@ -425,7 +427,7 @@ VisiblePosition VisiblePosition::honorEditableBoundaryAtOrAfter(const VisiblePos
// Return pos itself if the two are from the very same editable region, or both are non-editable
// FIXME: In the non-editable case, just because the new position is non-editable doesn't mean movement
- // to it is allowed. Selection::adjustForEditableContent has this problem too.
+ // to it is allowed. VisibleSelection::adjustForEditableContent has this problem too.
if (highestEditableRoot(pos.deepEquivalent()) == highestRoot)
return pos;
@@ -478,24 +480,24 @@ Position VisiblePosition::canonicalPosition(const Position& position)
// The new position must be in the same editable element. Enforce that first.
// Unless the descent is from a non-editable html element to an editable body.
- if (node->hasTagName(htmlTag) && !node->isContentEditable())
+ if (node->hasTagName(htmlTag) && !node->isContentEditable() && node->document()->body() && node->document()->body()->isContentEditable())
return next.isNotNull() ? next : prev;
Node* editingRoot = editableRootForPosition(position);
// If the html element is editable, descending into its body will look like a descent
// from non-editable to editable content since rootEditableElement() always stops at the body.
- if (editingRoot && editingRoot->hasTagName(htmlTag) || position.node()->isDocumentNode())
+ if ((editingRoot && editingRoot->hasTagName(htmlTag)) || position.node()->isDocumentNode())
return next.isNotNull() ? next : prev;
bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot;
if (prevIsInSameEditableElement && !nextIsInSameEditableElement)
return prev;
-
+
if (nextIsInSameEditableElement && !prevIsInSameEditableElement)
return next;
-
+
if (!nextIsInSameEditableElement && !prevIsInSameEditableElement)
return Position();
@@ -518,7 +520,7 @@ UChar VisiblePosition::characterAfter() const
if (!node || !node->isTextNode())
return 0;
Text* textNode = static_cast<Text*>(pos.node());
- int offset = pos.offset();
+ int offset = pos.m_offset;
if ((unsigned)offset >= textNode->length())
return 0;
return textNode->data()[offset];
@@ -541,7 +543,7 @@ IntRect VisiblePosition::localCaretRect(RenderObject*& renderer) const
getInlineBoxAndOffset(inlineBox, caretOffset);
if (inlineBox)
- renderer = inlineBox->object();
+ renderer = inlineBox->renderer();
return renderer->localCaretRect(inlineBox, caretOffset);
}
@@ -574,7 +576,7 @@ void VisiblePosition::debugPosition(const char* msg) const
if (isNull())
fprintf(stderr, "Position [%s]: null\n", msg);
else
- fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, m_deepPosition.node()->nodeName().utf8().data(), m_deepPosition.node(), m_deepPosition.offset());
+ fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, m_deepPosition.node()->nodeName().utf8().data(), m_deepPosition.node(), m_deepPosition.m_offset);
}
#ifndef NDEBUG
@@ -598,7 +600,7 @@ PassRefPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition
Position s = rangeCompliantEquivalent(start);
Position e = rangeCompliantEquivalent(end);
- return Range::create(s.node()->document(), s.node(), s.offset(), e.node(), e.offset());
+ return Range::create(s.node()->document(), s.node(), s.m_offset, e.node(), e.m_offset);
}
VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
@@ -619,7 +621,7 @@ bool setStart(Range *r, const VisiblePosition &visiblePosition)
return false;
Position p = rangeCompliantEquivalent(visiblePosition);
int code = 0;
- r->setStart(p.node(), p.offset(), code);
+ r->setStart(p.node(), p.m_offset, code);
return code == 0;
}
@@ -629,7 +631,7 @@ bool setEnd(Range *r, const VisiblePosition &visiblePosition)
return false;
Position p = rangeCompliantEquivalent(visiblePosition);
int code = 0;
- r->setEnd(p.node(), p.offset(), code);
+ r->setEnd(p.node(), p.m_offset, code);
return code == 0;
}
diff --git a/WebCore/editing/Selection.cpp b/WebCore/editing/VisibleSelection.cpp
index 4fb3a54..279adf2 100644
--- a/WebCore/editing/Selection.cpp
+++ b/WebCore/editing/VisibleSelection.cpp
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
#include "CharacterNames.h"
#include "CString.h"
@@ -35,20 +35,21 @@
#include "VisiblePosition.h"
#include "visible_units.h"
#include "Range.h"
+
#include <wtf/Assertions.h>
#include <stdio.h>
namespace WebCore {
-Selection::Selection()
+VisibleSelection::VisibleSelection()
: m_affinity(DOWNSTREAM)
, m_granularity(CharacterGranularity)
- , m_state(NONE)
+ , m_selectionType(NoSelection)
, m_baseIsFirst(true)
{
}
-Selection::Selection(const Position& pos, EAffinity affinity)
+VisibleSelection::VisibleSelection(const Position& pos, EAffinity affinity)
: m_base(pos)
, m_extent(pos)
, m_affinity(affinity)
@@ -57,7 +58,7 @@ Selection::Selection(const Position& pos, EAffinity affinity)
validate();
}
-Selection::Selection(const Position& base, const Position& extent, EAffinity affinity)
+VisibleSelection::VisibleSelection(const Position& base, const Position& extent, EAffinity affinity)
: m_base(base)
, m_extent(extent)
, m_affinity(affinity)
@@ -66,7 +67,7 @@ Selection::Selection(const Position& base, const Position& extent, EAffinity aff
validate();
}
-Selection::Selection(const VisiblePosition& pos)
+VisibleSelection::VisibleSelection(const VisiblePosition& pos)
: m_base(pos.deepEquivalent())
, m_extent(pos.deepEquivalent())
, m_affinity(pos.affinity())
@@ -75,7 +76,7 @@ Selection::Selection(const VisiblePosition& pos)
validate();
}
-Selection::Selection(const VisiblePosition& base, const VisiblePosition& extent)
+VisibleSelection::VisibleSelection(const VisiblePosition& base, const VisiblePosition& extent)
: m_base(base.deepEquivalent())
, m_extent(extent.deepEquivalent())
, m_affinity(base.affinity())
@@ -84,7 +85,7 @@ Selection::Selection(const VisiblePosition& base, const VisiblePosition& extent)
validate();
}
-Selection::Selection(const Range* range, EAffinity affinity)
+VisibleSelection::VisibleSelection(const Range* range, EAffinity affinity)
: m_base(range->startPosition())
, m_extent(range->endPosition())
, m_affinity(affinity)
@@ -93,36 +94,45 @@ Selection::Selection(const Range* range, EAffinity affinity)
validate();
}
-Selection Selection::selectionFromContentsOfNode(Node* node)
+VisibleSelection VisibleSelection::selectionFromContentsOfNode(Node* node)
{
- return Selection(Position(node, 0), Position(node, maxDeepOffset(node)), DOWNSTREAM);
+ return VisibleSelection(firstDeepEditingPositionForNode(node), lastDeepEditingPositionForNode(node), DOWNSTREAM);
}
-void Selection::setBase(const Position& position)
+void VisibleSelection::setBase(const Position& position)
{
m_base = position;
validate();
}
-void Selection::setBase(const VisiblePosition& visiblePosition)
+void VisibleSelection::setBase(const VisiblePosition& visiblePosition)
{
m_base = visiblePosition.deepEquivalent();
validate();
}
-void Selection::setExtent(const Position& position)
+void VisibleSelection::setExtent(const Position& position)
{
m_extent = position;
validate();
}
-void Selection::setExtent(const VisiblePosition& visiblePosition)
+void VisibleSelection::setExtent(const VisiblePosition& visiblePosition)
{
m_extent = visiblePosition.deepEquivalent();
validate();
}
-PassRefPtr<Range> Selection::toRange() const
+PassRefPtr<Range> VisibleSelection::firstRange() const
+{
+ if (isNone())
+ return 0;
+ Position start = rangeCompliantEquivalent(m_start);
+ Position end = rangeCompliantEquivalent(m_end);
+ return Range::create(start.node()->document(), start, end);
+}
+
+PassRefPtr<Range> VisibleSelection::toNormalizedRange() const
{
if (isNone())
return 0;
@@ -159,7 +169,7 @@ PassRefPtr<Range> Selection::toRange() const
ASSERT(isRange());
s = m_start.downstream();
e = m_end.upstream();
- if (Range::compareBoundaryPoints(s.node(), s.offset(), e.node(), e.offset()) > 0) {
+ if (Range::compareBoundaryPoints(s.node(), s.m_offset, e.node(), e.m_offset) > 0) {
// Make sure the start is before the end.
// The end can wind up before the start if collapsed whitespace is the only thing selected.
Position tmp = s;
@@ -170,22 +180,12 @@ PassRefPtr<Range> Selection::toRange() const
e = rangeCompliantEquivalent(e);
}
- ExceptionCode ec = 0;
- RefPtr<Range> result(Range::create(s.node()->document()));
- result->setStart(s.node(), s.offset(), ec);
- if (ec) {
- LOG_ERROR("Exception setting Range start from Selection: %d", ec);
- return 0;
- }
- result->setEnd(e.node(), e.offset(), ec);
- if (ec) {
- LOG_ERROR("Exception setting Range end from Selection: %d", ec);
- return 0;
- }
- return result.release();
+ // VisibleSelections are supposed to always be valid. This constructor will ASSERT
+ // if a valid range could not be created, which is fine for this callsite.
+ return Range::create(s.node()->document(), s, e);
}
-bool Selection::expandUsingGranularity(TextGranularity granularity)
+bool VisibleSelection::expandUsingGranularity(TextGranularity granularity)
{
if (isNone())
return false;
@@ -213,7 +213,7 @@ static PassRefPtr<Range> makeSearchRange(const Position& pos)
Position start(rangeCompliantEquivalent(pos));
searchRange->selectNodeContents(boundary, ec);
- searchRange->setStart(start.node(), start.offset(), ec);
+ searchRange->setStart(start.node(), start.m_offset, ec);
ASSERT(!ec);
if (ec)
@@ -222,7 +222,7 @@ static PassRefPtr<Range> makeSearchRange(const Position& pos)
return searchRange.release();
}
-void Selection::appendTrailingWhitespace()
+void VisibleSelection::appendTrailingWhitespace()
{
RefPtr<Range> searchRange = makeSearchRange(m_end);
if (!searchRange)
@@ -238,7 +238,7 @@ void Selection::appendTrailingWhitespace()
}
}
-void Selection::validate()
+void VisibleSelection::setBaseAndExtentToDeepEquivalents()
{
// Move the selection to rendered positions, if possible.
bool baseAndExtentEqual = m_base == m_extent;
@@ -259,10 +259,12 @@ void Selection::validate()
} else if (m_extent.isNull()) {
m_extent = m_base;
m_baseIsFirst = true;
- } else {
+ } else
m_baseIsFirst = comparePositions(m_base, m_extent) <= 0;
- }
+}
+void VisibleSelection::setStartAndEndFromBaseAndExtentRespectingGranularity()
+{
if (m_baseIsFirst) {
m_start = m_base;
m_end = m_extent;
@@ -271,7 +273,6 @@ void Selection::validate()
m_end = m_base;
}
- // Expand the selection if requested.
switch (m_granularity) {
case CharacterGranularity:
// Don't do any expansion.
@@ -385,26 +386,31 @@ void Selection::validate()
m_start = m_end;
if (m_end.isNull())
m_end = m_start;
-
- adjustForEditableContent();
+}
- // adjust the state
+void VisibleSelection::updateSelectionType()
+{
if (m_start.isNull()) {
ASSERT(m_end.isNull());
- m_state = NONE;
-
- // enforce downstream affinity if not caret, as affinity only
- // makes sense for caret
- m_affinity = DOWNSTREAM;
+ m_selectionType = NoSelection;
} else if (m_start == m_end || m_start.upstream() == m_end.upstream()) {
- m_state = CARET;
- } else {
- m_state = RANGE;
+ m_selectionType = CaretSelection;
+ } else
+ m_selectionType = RangeSelection;
- // enforce downstream affinity if not caret, as affinity only
- // makes sense for caret
+ // Affinity only makes sense for a caret
+ if (m_selectionType != CaretSelection)
m_affinity = DOWNSTREAM;
+}
+
+void VisibleSelection::validate()
+{
+ setBaseAndExtentToDeepEquivalents();
+ setStartAndEndFromBaseAndExtentRespectingGranularity();
+ adjustSelectionToAvoidCrossingEditingBoundaries();
+ updateSelectionType();
+ if (selectionType() == RangeSelection) {
// "Constrain" the selection to be the smallest equivalent range of nodes.
// This is a somewhat arbitrary choice, but experience shows that it is
// useful to make to make the selection "canonical" (if only for
@@ -419,12 +425,12 @@ void Selection::validate()
}
// FIXME: This function breaks the invariant of this class.
-// But because we use Selection to store values in editing commands for use when
+// But because we use VisibleSelection to store values in editing commands for use when
// undoing the command, we need to be able to create a selection that while currently
// invalid, will be valid once the changes are undone. This is a design problem.
-// To fix it we either need to change the invariants of Selection or create a new
+// To fix it we either need to change the invariants of VisibleSelection or create a new
// class for editing to use that can manipulate selections that are not currently valid.
-void Selection::setWithoutValidation(const Position& base, const Position& extent)
+void VisibleSelection::setWithoutValidation(const Position& base, const Position& extent)
{
ASSERT(!base.isNull());
ASSERT(!extent.isNull());
@@ -441,10 +447,10 @@ void Selection::setWithoutValidation(const Position& base, const Position& exten
m_start = extent;
m_end = base;
}
- m_state = RANGE;
+ m_selectionType = RangeSelection;
}
-void Selection::adjustForEditableContent()
+void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
{
if (m_base.isNull() || m_start.isNull() || m_end.isNull())
return;
@@ -496,17 +502,19 @@ void Selection::adjustForEditableContent()
Position p = previousVisuallyDistinctCandidate(m_end);
Node* shadowAncestor = endRoot ? endRoot->shadowAncestorNode() : 0;
if (p.isNull() && endRoot && (shadowAncestor != endRoot))
- p = Position(shadowAncestor, maxDeepOffset(shadowAncestor));
+ p = lastDeepEditingPositionForNode(shadowAncestor);
while (p.isNotNull() && !(lowestEditableAncestor(p.node()) == baseEditableAncestor && !isEditablePosition(p))) {
Node* root = editableRootForPosition(p);
shadowAncestor = root ? root->shadowAncestorNode() : 0;
p = isAtomicNode(p.node()) ? positionBeforeNode(p.node()) : previousVisuallyDistinctCandidate(p);
if (p.isNull() && (shadowAncestor != root))
- p = Position(shadowAncestor, maxDeepOffset(shadowAncestor));
+ p = lastDeepEditingPositionForNode(shadowAncestor);
}
VisiblePosition previous(p);
-
+
if (previous.isNull()) {
+ // The selection crosses an Editing boundary. This is a
+ // programmer error in the editing code. Happy debugging!
ASSERT_NOT_REACHED();
m_base = Position();
m_extent = Position();
@@ -534,6 +542,8 @@ void Selection::adjustForEditableContent()
VisiblePosition next(p);
if (next.isNull()) {
+ // The selection crosses an Editing boundary. This is a
+ // programmer error in the editing code. Happy debugging!
ASSERT_NOT_REACHED();
m_base = Position();
m_extent = Position();
@@ -549,42 +559,42 @@ void Selection::adjustForEditableContent()
m_extent = m_baseIsFirst ? m_end : m_start;
}
-bool Selection::isContentEditable() const
+bool VisibleSelection::isContentEditable() const
{
return isEditablePosition(start());
}
-bool Selection::isContentRichlyEditable() const
+bool VisibleSelection::isContentRichlyEditable() const
{
return isRichlyEditablePosition(start());
}
-Element* Selection::rootEditableElement() const
+Element* VisibleSelection::rootEditableElement() const
{
return editableRootForPosition(start());
}
-Node* Selection::shadowTreeRootNode() const
+Node* VisibleSelection::shadowTreeRootNode() const
{
return start().node() ? start().node()->shadowTreeRootNode() : 0;
}
-void Selection::debugPosition() const
+void VisibleSelection::debugPosition() const
{
if (!m_start.node())
return;
- fprintf(stderr, "Selection =================\n");
+ fprintf(stderr, "VisibleSelection =================\n");
if (m_start == m_end) {
Position pos = m_start;
- fprintf(stderr, "pos: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.offset());
+ fprintf(stderr, "pos: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.m_offset);
} else {
Position pos = m_start;
- fprintf(stderr, "start: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.offset());
+ fprintf(stderr, "start: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.m_offset);
fprintf(stderr, "-----------------------------------\n");
pos = m_end;
- fprintf(stderr, "end: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.offset());
+ fprintf(stderr, "end: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.m_offset);
fprintf(stderr, "-----------------------------------\n");
}
@@ -593,7 +603,7 @@ void Selection::debugPosition() const
#ifndef NDEBUG
-void Selection::formatForDebugger(char* buffer, unsigned length) const
+void VisibleSelection::formatForDebugger(char* buffer, unsigned length) const
{
String result;
String s;
@@ -614,11 +624,11 @@ void Selection::formatForDebugger(char* buffer, unsigned length) const
strncpy(buffer, result.utf8().data(), length - 1);
}
-void Selection::showTreeForThis() const
+void VisibleSelection::showTreeForThis() const
{
if (start().node()) {
start().node()->showTreeAndMark(start().node(), "S", end().node(), "E");
- fprintf(stderr, "start offset: %d, end offset: %d\n", start().offset(), end().offset());
+ fprintf(stderr, "start offset: %d, end offset: %d\n", start().m_offset, end().m_offset);
}
}
@@ -628,12 +638,12 @@ void Selection::showTreeForThis() const
#ifndef NDEBUG
-void showTree(const WebCore::Selection& sel)
+void showTree(const WebCore::VisibleSelection& sel)
{
sel.showTreeForThis();
}
-void showTree(const WebCore::Selection* sel)
+void showTree(const WebCore::VisibleSelection* sel)
{
if (sel)
sel->showTreeForThis();
diff --git a/WebCore/editing/Selection.h b/WebCore/editing/VisibleSelection.h
index 5e21701..ae2142d 100644
--- a/WebCore/editing/Selection.h
+++ b/WebCore/editing/VisibleSelection.h
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef Selection_h
-#define Selection_h
+#ifndef VisibleSelection_h
+#define VisibleSelection_h
#include "TextGranularity.h"
#include "VisiblePosition.h"
@@ -35,24 +35,23 @@ class Position;
const EAffinity SEL_DEFAULT_AFFINITY = DOWNSTREAM;
-class Selection {
+class VisibleSelection {
public:
- enum EState { NONE, CARET, RANGE };
- enum EDirection { FORWARD, BACKWARD, RIGHT, LEFT };
+ enum SelectionType { NoSelection, CaretSelection, RangeSelection };
- Selection();
+ VisibleSelection();
- Selection(const Position&, EAffinity);
- Selection(const Position&, const Position&, EAffinity);
+ VisibleSelection(const Position&, EAffinity);
+ VisibleSelection(const Position&, const Position&, EAffinity);
- Selection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY);
+ VisibleSelection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY);
- Selection(const VisiblePosition&);
- Selection(const VisiblePosition&, const VisiblePosition&);
+ VisibleSelection(const VisiblePosition&);
+ VisibleSelection(const VisiblePosition&, const VisiblePosition&);
- static Selection selectionFromContentsOfNode(Node*);
+ static VisibleSelection selectionFromContentsOfNode(Node*);
- EState state() const { return m_state; }
+ SelectionType selectionType() const { return m_selectionType; }
void setAffinity(EAffinity affinity) { m_affinity = affinity; }
EAffinity affinity() const { return m_affinity; }
@@ -63,17 +62,17 @@ public:
void setExtent(const VisiblePosition&);
Position base() const { return m_base; }
- Position extent() const { return m_extent; }
+ Position extent() const { return m_extent; }
Position start() const { return m_start; }
Position end() const { return m_end; }
VisiblePosition visibleStart() const { return VisiblePosition(m_start, isRange() ? DOWNSTREAM : affinity()); }
VisiblePosition visibleEnd() const { return VisiblePosition(m_end, isRange() ? UPSTREAM : affinity()); }
- bool isNone() const { return state() == NONE; }
- bool isCaret() const { return state() == CARET; }
- bool isRange() const { return state() == RANGE; }
- bool isCaretOrRange() const { return state() != NONE; }
+ bool isNone() const { return selectionType() == NoSelection; }
+ bool isCaret() const { return selectionType() == CaretSelection; }
+ bool isRange() const { return selectionType() == RangeSelection; }
+ bool isCaretOrRange() const { return selectionType() != NoSelection; }
bool isBaseFirst() const { return m_baseIsFirst; }
@@ -82,7 +81,13 @@ public:
bool expandUsingGranularity(TextGranularity granularity);
TextGranularity granularity() const { return m_granularity; }
- PassRefPtr<Range> toRange() const;
+ // We don't yet support multi-range selections, so we only ever have one range to return.
+ PassRefPtr<Range> firstRange() const;
+
+ // FIXME: Most callers probably don't want this function, but are using it
+ // for historical reasons. toNormalizedRange contracts the range around
+ // text, and moves the caret upstream before returning the range.
+ PassRefPtr<Range> toNormalizedRange() const;
Element* rootEditableElement() const;
bool isContentEditable() const;
@@ -100,27 +105,33 @@ public:
private:
void validate();
- void adjustForEditableContent();
- Position m_base; // base position for the selection
- Position m_extent; // extent position for the selection
- Position m_start; // start position for the selection
- Position m_end; // end position for the selection
+ // Support methods for validate()
+ void setBaseAndExtentToDeepEquivalents();
+ void setStartAndEndFromBaseAndExtentRespectingGranularity();
+ void adjustSelectionToAvoidCrossingEditingBoundaries();
+ void updateSelectionType();
+
+ // FIXME: These should all be VisiblePositions
+ Position m_base; // Where the first click happened
+ Position m_extent; // Where the end click happened
+ Position m_start; // Leftmost position when expanded to respect granularity
+ Position m_end; // Rightmost position when expanded to respect granularity
- EAffinity m_affinity; // the upstream/downstream affinity of the caret
- TextGranularity m_granularity; // granularity of start/end selection
+ EAffinity m_affinity; // the upstream/downstream affinity of the caret
+ TextGranularity m_granularity; // granularity of start/end selection
// these are cached, can be recalculated by validate()
- EState m_state; // the state of the selection
+ SelectionType m_selectionType; // None, Caret, Range
bool m_baseIsFirst; // true if base is before the extent
};
-inline bool operator==(const Selection& a, const Selection& b)
+inline bool operator==(const VisibleSelection& a, const VisibleSelection& b)
{
return a.start() == b.start() && a.end() == b.end() && a.affinity() == b.affinity() && a.granularity() == b.granularity() && a.isBaseFirst() == b.isBaseFirst();
}
-inline bool operator!=(const Selection& a, const Selection& b)
+inline bool operator!=(const VisibleSelection& a, const VisibleSelection& b)
{
return !(a == b);
}
@@ -129,8 +140,8 @@ inline bool operator!=(const Selection& a, const Selection& b)
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
-void showTree(const WebCore::Selection&);
-void showTree(const WebCore::Selection*);
+void showTree(const WebCore::VisibleSelection&);
+void showTree(const WebCore::VisibleSelection*);
#endif
-#endif // Selection_h
+#endif // VisibleSelection_h
diff --git a/WebCore/editing/htmlediting.cpp b/WebCore/editing/htmlediting.cpp
index ee41e69..055c3a7 100644
--- a/WebCore/editing/htmlediting.cpp
+++ b/WebCore/editing/htmlediting.cpp
@@ -40,7 +40,7 @@
#include "PositionIterator.h"
#include "RenderObject.h"
#include "Range.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
#include "Text.h"
#include "TextIterator.h"
#include "VisiblePosition.h"
@@ -98,8 +98,8 @@ int comparePositions(const Position& a, const Position& b)
ASSERT(nodeA);
Node* nodeB = b.node();
ASSERT(nodeB);
- int offsetA = a.offset();
- int offsetB = b.offset();
+ int offsetA = a.m_offset;
+ int offsetB = b.m_offset;
Node* shadowAncestorA = nodeA->shadowAncestorNode();
if (shadowAncestorA == nodeA)
@@ -221,8 +221,8 @@ Position nextVisuallyDistinctCandidate(const Position& position)
{
Position p = position;
Position downstreamStart = p.downstream();
- while (!p.atEnd()) {
- p = p.next(UsingComposedCharacters);
+ while (!p.atEndOfTree()) {
+ p = p.next(Character);
if (p.isCandidate() && p.downstream() != downstreamStart)
return p;
}
@@ -244,8 +244,8 @@ Position previousVisuallyDistinctCandidate(const Position& position)
{
Position p = position;
Position downstreamStart = p.downstream();
- while (!p.atStart()) {
- p = p.previous(UsingComposedCharacters);
+ while (!p.atStartOfTree()) {
+ p = p.previous(Character);
if (p.isCandidate() && p.downstream() != downstreamStart)
return p;
}
@@ -255,14 +255,14 @@ Position previousVisuallyDistinctCandidate(const Position& position)
VisiblePosition firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
{
// position falls before highestRoot.
- if (comparePositions(position, Position(highestRoot, 0)) == -1 && highestRoot->isContentEditable())
- return VisiblePosition(Position(highestRoot, 0));
-
+ if (comparePositions(position, firstDeepEditingPositionForNode(highestRoot)) == -1 && highestRoot->isContentEditable())
+ return firstDeepEditingPositionForNode(highestRoot);
+
Position p = position;
if (Node* shadowAncestor = p.node()->shadowAncestorNode())
if (shadowAncestor != p.node())
- p = Position(shadowAncestor, maxDeepOffset(shadowAncestor));
+ p = lastDeepEditingPositionForNode(shadowAncestor);
while (p.node() && !isEditablePosition(p) && p.node()->isDescendantOf(highestRoot))
p = isAtomicNode(p.node()) ? positionAfterNode(p.node()) : nextVisuallyDistinctCandidate(p);
@@ -276,14 +276,14 @@ VisiblePosition firstEditablePositionAfterPositionInRoot(const Position& positio
VisiblePosition lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
{
// When position falls after highestRoot, the result is easy to compute.
- if (comparePositions(position, Position(highestRoot, maxDeepOffset(highestRoot))) == 1)
- return VisiblePosition(Position(highestRoot, maxDeepOffset(highestRoot)));
-
+ if (comparePositions(position, lastDeepEditingPositionForNode(highestRoot)) == 1)
+ return lastDeepEditingPositionForNode(highestRoot);
+
Position p = position;
if (Node* shadowAncestor = p.node()->shadowAncestorNode())
if (shadowAncestor != p.node())
- p = Position(shadowAncestor, 0);
+ p = firstDeepEditingPositionForNode(shadowAncestor);
while (p.node() && !isEditablePosition(p) && p.node()->isDescendantOf(highestRoot))
p = isAtomicNode(p.node()) ? positionBeforeNode(p.node()) : previousVisuallyDistinctCandidate(p);
@@ -294,6 +294,7 @@ VisiblePosition lastEditablePositionBeforePositionInRoot(const Position& positio
return VisiblePosition(p);
}
+// FIXME: The method name, comment, and code say three different things here!
// Whether or not content before and after this node will collapse onto the same line as it.
bool isBlock(const Node* node)
{
@@ -309,39 +310,44 @@ Node* enclosingBlock(Node* node)
return static_cast<Element*>(enclosingNodeOfType(Position(node, 0), isBlock));
}
+// Internally editing uses "invalid" positions for historical reasons. For
+// example, in <div><img /></div>, Editing might use (img, 1) for the position
+// after <img>, but we have to convert that to (div, 1) before handing the
+// position to a Range object. Ideally all internal positions should
+// be "range compliant" for simplicity.
Position rangeCompliantEquivalent(const Position& pos)
{
if (pos.isNull())
return Position();
- Node *node = pos.node();
-
- if (pos.offset() <= 0) {
+ Node* node = pos.node();
+
+ if (pos.m_offset <= 0) {
if (node->parentNode() && (editingIgnoresContent(node) || isTableElement(node)))
return positionBeforeNode(node);
return Position(node, 0);
}
-
+
if (node->offsetInCharacters())
- return Position(node, min(node->maxCharacterOffset(), pos.offset()));
-
+ return Position(node, min(node->maxCharacterOffset(), pos.m_offset));
+
int maxCompliantOffset = node->childNodeCount();
- if (pos.offset() > maxCompliantOffset) {
+ if (pos.m_offset > maxCompliantOffset) {
if (node->parentNode())
return positionAfterNode(node);
-
+
// there is no other option at this point than to
// use the highest allowed position in the node
return Position(node, maxCompliantOffset);
}
// Editing should never generate positions like this.
- if ((pos.offset() < maxCompliantOffset) && editingIgnoresContent(node)) {
+ if ((pos.m_offset < maxCompliantOffset) && editingIgnoresContent(node)) {
ASSERT_NOT_REACHED();
return node->parentNode() ? positionBeforeNode(node) : Position(node, 0);
}
- if (pos.offset() == maxCompliantOffset && (editingIgnoresContent(node) || isTableElement(node)))
+ if (pos.m_offset == maxCompliantOffset && (editingIgnoresContent(node) || isTableElement(node)))
return positionAfterNode(node);
return Position(pos);
@@ -356,7 +362,7 @@ Position rangeCompliantEquivalent(const VisiblePosition& vpos)
// in a node. It returns 1 for some elements even though they do not have children, which
// creates technically invalid DOM Positions. Be sure to call rangeCompliantEquivalent
// on a Position before using it to create a DOM Range, or an exception will be thrown.
-int maxDeepOffset(const Node *node)
+int lastOffsetForEditing(const Node* node)
{
ASSERT(node);
if (!node)
@@ -536,7 +542,7 @@ Position positionOutsideContainingSpecialElement(const Position &pos, Node **con
Node* isFirstPositionAfterTable(const VisiblePosition& visiblePosition)
{
Position upstream(visiblePosition.deepEquivalent().upstream());
- if (upstream.node() && upstream.node()->renderer() && upstream.node()->renderer()->isTable() && upstream.offset() == maxDeepOffset(upstream.node()))
+ if (upstream.node() && upstream.node()->renderer() && upstream.node()->renderer()->isTable() && upstream.atLastEditingPositionForNode())
return upstream.node();
return 0;
@@ -545,19 +551,21 @@ Node* isFirstPositionAfterTable(const VisiblePosition& visiblePosition)
Node* isLastPositionBeforeTable(const VisiblePosition& visiblePosition)
{
Position downstream(visiblePosition.deepEquivalent().downstream());
- if (downstream.node() && downstream.node()->renderer() && downstream.node()->renderer()->isTable() && downstream.offset() == 0)
+ if (downstream.node() && downstream.node()->renderer() && downstream.node()->renderer()->isTable() && downstream.atFirstEditingPositionForNode())
return downstream.node();
return 0;
}
-Position positionBeforeNode(const Node *node)
+Position positionBeforeNode(const Node* node)
{
+ // FIXME: This should ASSERT(node->parentNode())
return Position(node->parentNode(), node->nodeIndex());
}
-Position positionAfterNode(const Node *node)
+Position positionAfterNode(const Node* node)
{
+ // FIXME: This should ASSERT(node->parentNode())
return Position(node->parentNode(), node->nodeIndex() + 1);
}
@@ -694,16 +702,17 @@ static Node* appendedSublist(Node* listItem)
return 0;
}
+// FIXME: This method should not need to call isStartOfParagraph/isEndOfParagraph
Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
{
// Check that position is on a line by itself inside a list item
Node* listChildNode = enclosingListChild(visiblePos.deepEquivalent().node());
if (!listChildNode || !isStartOfParagraph(visiblePos) || !isEndOfParagraph(visiblePos))
return 0;
-
- VisiblePosition firstInListChild(Position(listChildNode, 0));
- VisiblePosition lastInListChild(Position(listChildNode, maxDeepOffset(listChildNode)));
-
+
+ VisiblePosition firstInListChild(firstDeepEditingPositionForNode(listChildNode));
+ VisiblePosition lastInListChild(lastDeepEditingPositionForNode(listChildNode));
+
if (firstInListChild != visiblePos || lastInListChild != visiblePos)
return 0;
@@ -814,16 +823,16 @@ Position positionBeforeTabSpan(const Position& pos)
PassRefPtr<Element> createTabSpanElement(Document* document, PassRefPtr<Node> tabTextNode)
{
- // make the span to hold the tab
- ExceptionCode ec = 0;
- RefPtr<Element> spanElement = document->createElementNS(xhtmlNamespaceURI, "span", ec);
- ASSERT(ec == 0);
+ // Make the span to hold the tab.
+ RefPtr<Element> spanElement = document->createElement(spanTag, false);
spanElement->setAttribute(classAttr, AppleTabSpanClass);
spanElement->setAttribute(styleAttr, "white-space:pre");
- // add tab text to that span
+ // Add tab text to that span.
if (!tabTextNode)
tabTextNode = document->createEditingTextNode("\t");
+
+ ExceptionCode ec = 0;
spanElement->appendChild(tabTextNode, ec);
ASSERT(ec == 0);
@@ -873,7 +882,7 @@ unsigned numEnclosingMailBlockquotes(const Position& p)
bool isMailBlockquote(const Node *node)
{
- if (!node || !node->isElementNode() && !node->hasTagName(blockquoteTag))
+ if (!node || (!node->isElementNode() && !node->hasTagName(blockquoteTag)))
return false;
return static_cast<const Element *>(node)->getAttribute("type") == "cite";
@@ -894,7 +903,7 @@ int caretMaxOffset(const Node* n)
if (n->isTextNode() && n->renderer())
return n->renderer()->caretMaxOffset();
// For containers return the number of children. For others do the same as above.
- return maxDeepOffset(n);
+ return lastOffsetForEditing(n);
}
bool lineBreakExistsAtPosition(const VisiblePosition& visiblePosition)
@@ -904,15 +913,15 @@ bool lineBreakExistsAtPosition(const VisiblePosition& visiblePosition)
Position downstream(visiblePosition.deepEquivalent().downstream());
return downstream.node()->hasTagName(brTag) ||
- downstream.node()->isTextNode() && downstream.node()->renderer()->style()->preserveNewline() && visiblePosition.characterAfter() == '\n';
+ (downstream.node()->isTextNode() && downstream.node()->renderer()->style()->preserveNewline() && visiblePosition.characterAfter() == '\n');
}
// Modifies selections that have an end point at the edge of a table
// that contains the other endpoint so that they don't confuse
// code that iterates over selected paragraphs.
-Selection selectionForParagraphIteration(const Selection& original)
+VisibleSelection selectionForParagraphIteration(const VisibleSelection& original)
{
- Selection newSelection(original);
+ VisibleSelection newSelection(original);
VisiblePosition startOfSelection(newSelection.visibleStart());
VisiblePosition endOfSelection(newSelection.visibleEnd());
@@ -922,7 +931,7 @@ Selection selectionForParagraphIteration(const Selection& original)
// (a table is itself a paragraph).
if (Node* table = isFirstPositionAfterTable(endOfSelection))
if (startOfSelection.deepEquivalent().node()->isDescendantOf(table))
- newSelection = Selection(startOfSelection, endOfSelection.previous(true));
+ newSelection = VisibleSelection(startOfSelection, endOfSelection.previous(true));
// If the start of the selection to modify is just before a table,
// and if the end of the selection is inside that table, then the first paragraph
@@ -930,7 +939,7 @@ Selection selectionForParagraphIteration(const Selection& original)
// containing the table itself.
if (Node* table = isLastPositionBeforeTable(startOfSelection))
if (endOfSelection.deepEquivalent().node()->isDescendantOf(table))
- newSelection = Selection(startOfSelection.next(true), endOfSelection);
+ newSelection = VisibleSelection(startOfSelection.next(true), endOfSelection);
return newSelection;
}
@@ -976,12 +985,12 @@ PassRefPtr<Range> avoidIntersectionWithNode(const Range* range, Node* node)
return Range::create(document, startContainer, startOffset, endContainer, endOffset);
}
-Selection avoidIntersectionWithNode(const Selection& selection, Node* node)
+VisibleSelection avoidIntersectionWithNode(const VisibleSelection& selection, Node* node)
{
if (selection.isNone())
- return Selection(selection);
+ return VisibleSelection(selection);
- Selection updatedSelection(selection);
+ VisibleSelection updatedSelection(selection);
Node* base = selection.base().node();
Node* extent = selection.extent().node();
ASSERT(base);
diff --git a/WebCore/editing/htmlediting.h b/WebCore/editing/htmlediting.h
index a8bc0b4..ece5e29 100644
--- a/WebCore/editing/htmlediting.h
+++ b/WebCore/editing/htmlediting.h
@@ -37,13 +37,13 @@ class HTMLElement;
class Node;
class Position;
class Range;
-class Selection;
+class VisibleSelection;
class String;
class VisiblePosition;
Position rangeCompliantEquivalent(const Position&);
Position rangeCompliantEquivalent(const VisiblePosition&);
-int maxDeepOffset(const Node*);
+int lastOffsetForEditing(const Node*);
bool isAtomicNode(const Node*);
bool editingIgnoresContent(const Node*);
bool canHaveChildrenForEditing(const Node*);
@@ -72,7 +72,7 @@ Position positionBeforeNode(const Node*);
Position positionAfterNode(const Node*);
PassRefPtr<Range> avoidIntersectionWithNode(const Range*, Node*);
-Selection avoidIntersectionWithNode(const Selection&, Node*);
+VisibleSelection avoidIntersectionWithNode(const VisibleSelection&, Node*);
bool isSpecialElement(const Node*);
bool validBlockTag(const String&);
@@ -129,7 +129,7 @@ bool isTableCell(const Node*);
bool lineBreakExistsAtPosition(const VisiblePosition&);
-Selection selectionForParagraphIteration(const Selection&);
+VisibleSelection selectionForParagraphIteration(const VisibleSelection&);
int indexForVisiblePosition(VisiblePosition&);
diff --git a/WebCore/editing/mac/SelectionControllerMac.mm b/WebCore/editing/mac/SelectionControllerMac.mm
index 4125c3a..03e1051 100644
--- a/WebCore/editing/mac/SelectionControllerMac.mm
+++ b/WebCore/editing/mac/SelectionControllerMac.mm
@@ -27,42 +27,41 @@
#import "SelectionController.h"
#import "AXObjectCache.h"
-#import "Document.h"
#import "Frame.h"
-#import "FrameView.h"
#import "RenderView.h"
-#import "Selection.h"
#import "WebCoreViewFactory.h"
-#import <ApplicationServices/ApplicationServices.h>
-
namespace WebCore {
void SelectionController::notifyAccessibilityForSelectionChange()
{
+ Document* document = m_frame->document();
+
if (AXObjectCache::accessibilityEnabled() && m_sel.start().isNotNull() && m_sel.end().isNotNull())
- m_frame->document()->axObjectCache()->postNotification(m_sel.start().node()->renderer(), "AXSelectedTextChanged");
-
+ document->axObjectCache()->postNotification(m_sel.start().node()->renderer(), "AXSelectedTextChanged");
+
// if zoom feature is enabled, insertion point changes should update the zoom
- if (UAZoomEnabled() && m_sel.isCaret() && m_sel.start().node()) {
- RenderView *renderView = static_cast<RenderView*>(m_sel.start().node()->renderer());
- if (renderView) {
- IntRect selectionRect = absoluteCaretBounds();
- IntRect viewRect = renderView->viewRect();
- FrameView* frameView = renderView->view()->frameView();
- if (frameView) {
- selectionRect = frameView->contentsToScreen(selectionRect);
- viewRect = frameView->contentsToScreen(viewRect);
- CGRect cgCaretRect = CGRectMake(selectionRect.x(), selectionRect.y(), selectionRect.width(), selectionRect.height());
- CGRect cgViewRect = CGRectMake(viewRect.x(), viewRect.y(), viewRect.width(), viewRect.height());
- cgCaretRect = [[WebCoreViewFactory sharedFactory] accessibilityConvertScreenRect:cgCaretRect];
- cgViewRect = [[WebCoreViewFactory sharedFactory] accessibilityConvertScreenRect:cgViewRect];
+ if (!UAZoomEnabled() || !m_sel.isCaret())
+ return;
- (void)UAZoomChangeFocus(&cgViewRect, &cgCaretRect, kUAZoomFocusTypeInsertionPoint);
- }
- }
- }
-}
+ RenderView* renderView = document->renderView();
+ if (!renderView)
+ return;
+ FrameView* frameView = m_frame->view();
+ if (!frameView)
+ return;
+ IntRect selectionRect = absoluteCaretBounds();
+ IntRect viewRect = renderView->viewRect();
+
+ selectionRect = frameView->contentsToScreen(selectionRect);
+ viewRect = frameView->contentsToScreen(viewRect);
+ CGRect cgCaretRect = CGRectMake(selectionRect.x(), selectionRect.y(), selectionRect.width(), selectionRect.height());
+ CGRect cgViewRect = CGRectMake(viewRect.x(), viewRect.y(), viewRect.width(), viewRect.height());
+ cgCaretRect = [[WebCoreViewFactory sharedFactory] accessibilityConvertScreenRect:cgCaretRect];
+ cgViewRect = [[WebCoreViewFactory sharedFactory] accessibilityConvertScreenRect:cgViewRect];
+
+ UAZoomChangeFocus(&cgViewRect, &cgCaretRect, kUAZoomFocusTypeInsertionPoint);
+}
} // namespace WebCore
diff --git a/WebCore/editing/markup.cpp b/WebCore/editing/markup.cpp
index 1352457..7de5287 100644
--- a/WebCore/editing/markup.cpp
+++ b/WebCore/editing/markup.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,7 +52,7 @@
#include "ProcessingInstruction.h"
#include "QualifiedName.h"
#include "Range.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
#include "TextIterator.h"
#include "htmlediting.h"
#include "visible_units.h"
@@ -408,8 +408,7 @@ static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Ran
bool useRenderedText = !enclosingNodeWithTag(Position(const_cast<Node*>(node), 0), selectTag);
String markup = escapeContentText(useRenderedText ? renderedText(node, range) : stringValueForRange(node, range), false);
- if (annotate)
- markup = convertHTMLTextToInterchangeFormat(markup, static_cast<const Text*>(node));
+ markup = convertHTMLTextToInterchangeFormat(markup, static_cast<const Text*>(node));
append(result, markup);
break;
}
@@ -438,7 +437,7 @@ static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Ran
case Node::ELEMENT_NODE: {
result.append('<');
const Element* el = static_cast<const Element*>(node);
- bool convert = convertBlocksToInlines & isBlock(const_cast<Node*>(node));
+ bool convert = convertBlocksToInlines && isBlock(const_cast<Node*>(node));
append(result, el->nodeNamePreservingCase());
NamedAttrMap *attrs = el->attributes();
unsigned length = attrs->length();
@@ -587,26 +586,50 @@ static String getEndMarkup(const Node *node)
return String::adopt(result);
}
-static void appendMarkup(Vector<UChar>& result, Node* startNode, bool onlyIncludeChildren, Vector<Node*>* nodes, const HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0)
+class MarkupAccumulator {
+public:
+ MarkupAccumulator(Node* nodeToSkip, Vector<Node*>* nodes)
+ : m_nodeToSkip(nodeToSkip)
+ , m_nodes(nodes)
+ {
+ }
+
+ void appendMarkup(Node* startNode, EChildrenOnly, const HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0);
+
+ String takeResult() { return String::adopt(m_result); }
+
+private:
+ Vector<UChar> m_result;
+ Node* m_nodeToSkip;
+ Vector<Node*>* m_nodes;
+};
+
+// FIXME: Would be nice to do this in a non-recursive way.
+void MarkupAccumulator::appendMarkup(Node* startNode, EChildrenOnly childrenOnly, const HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces)
{
+ if (startNode == m_nodeToSkip)
+ return;
+
HashMap<AtomicStringImpl*, AtomicStringImpl*> namespaceHash;
if (namespaces)
namespaceHash = *namespaces;
-
- if (!onlyIncludeChildren) {
- if (nodes)
- nodes->append(startNode);
-
- appendStartMarkup(result,startNode, 0, DoNotAnnotateForInterchange, false, &namespaceHash);
+
+ // start tag
+ if (!childrenOnly) {
+ if (m_nodes)
+ m_nodes->append(startNode);
+ appendStartMarkup(m_result, startNode, 0, DoNotAnnotateForInterchange, false, &namespaceHash);
}
- // print children
- if (!(startNode->document()->isHTMLDocument() && doesHTMLForbidEndTag(startNode)))
+
+ // children
+ if (!(startNode->document()->isHTMLDocument() && doesHTMLForbidEndTag(startNode))) {
for (Node* current = startNode->firstChild(); current; current = current->nextSibling())
- appendMarkup(result, current, false, nodes, &namespaceHash);
-
- // Print my ending tag
- if (!onlyIncludeChildren)
- appendEndMarkup(result, startNode);
+ appendMarkup(current, IncludeNode, &namespaceHash);
+ }
+
+ // end tag
+ if (!childrenOnly)
+ appendEndMarkup(m_result, startNode);
}
static void completeURLs(Node* node, const String& baseURL)
@@ -690,7 +713,7 @@ static String joinMarkups(const Vector<String>& preMarkups, const Vector<String>
length += postMarkups[i].length();
Vector<UChar> result;
- result.reserveCapacity(length);
+ result.reserveInitialCapacity(length);
for (size_t i = preCount; i > 0; --i)
append(result, preMarkups[i - 1]);
@@ -701,6 +724,24 @@ static String joinMarkups(const Vector<String>& preMarkups, const Vector<String>
return String::adopt(result);
}
+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);
+}
+
// 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 annotate, bool convertBlocksToInlines)
@@ -849,12 +890,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
table = table->parentNode();
if (table)
specialCommonAncestor = table;
- } else if (commonAncestorBlock->hasTagName(listingTag)
- || commonAncestorBlock->hasTagName(olTag)
- || commonAncestorBlock->hasTagName(preTag)
- || commonAncestorBlock->hasTagName(tableTag)
- || commonAncestorBlock->hasTagName(ulTag)
- || commonAncestorBlock->hasTagName(xmpTag))
+ } else if (isSpecialAncestorBlock(commonAncestorBlock))
specialCommonAncestor = commonAncestorBlock;
}
@@ -888,7 +924,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
// FIXME: Only include markup for a fully selected root (and ancestors of lastClosed up to that root) if
// there are styles/attributes on those nodes that need to be included to preserve the appearance of the copied markup.
// FIXME: Do this for all fully selected blocks, not just the body.
- Node* fullySelectedRoot = body && *Selection::selectionFromContentsOfNode(body).toRange() == *updatedRange ? body : 0;
+ Node* fullySelectedRoot = body && *VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange() == *updatedRange ? body : 0;
if (annotate && fullySelectedRoot)
specialCommonAncestor = fullySelectedRoot;
@@ -1004,30 +1040,21 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const
return fragment.release();
}
-String createMarkup(const Node* node, EChildrenOnly includeChildren, Vector<Node*>* nodes)
+String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes)
{
- Vector<UChar> result;
-
if (!node)
return "";
- Document* document = node->document();
- Frame* frame = document->frame();
- DeleteButtonController* deleteButton = frame ? frame->editor()->deleteButtonController() : 0;
-
- // disable the delete button so it's elements are not serialized into the markup
- if (deleteButton) {
- if (node->isDescendantOf(deleteButton->containerElement()))
+ HTMLElement* deleteButtonContainerElement = 0;
+ if (Frame* frame = node->document()->frame()) {
+ deleteButtonContainerElement = frame->editor()->deleteButtonController()->containerElement();
+ if (node->isDescendantOf(deleteButtonContainerElement))
return "";
- deleteButton->disable();
}
- appendMarkup(result, const_cast<Node*>(node), includeChildren, nodes);
-
- if (deleteButton)
- deleteButton->enable();
-
- return String::adopt(result);
+ MarkupAccumulator accumulator(deleteButtonContainerElement, nodes);
+ accumulator.appendMarkup(const_cast<Node*>(node), childrenOnly);
+ return accumulator.takeResult();
}
static void fillContainerFromString(ContainerNode* paragraph, const String& string)
@@ -1140,7 +1167,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
element->setAttribute(classAttr, AppleInterchangeNewline);
} else {
if (useClonesOfEnclosingBlock)
- element = block->cloneElement();
+ element = block->cloneElementWithoutChildren();
else
element = createDefaultParagraphElement(document);
fillContainerFromString(element.get(), s);
diff --git a/WebCore/editing/qt/EditorQt.cpp b/WebCore/editing/qt/EditorQt.cpp
index 89ee78e..e74e2f3 100644
--- a/WebCore/editing/qt/EditorQt.cpp
+++ b/WebCore/editing/qt/EditorQt.cpp
@@ -31,7 +31,7 @@
#include "ClipboardQt.h"
#include "Document.h"
#include "Element.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
#include "SelectionController.h"
#include "TextIterator.h"
#include "htmlediting.h"
diff --git a/WebCore/editing/visible_units.cpp b/WebCore/editing/visible_units.cpp
index a50503d..1e8b05b 100644
--- a/WebCore/editing/visible_units.cpp
+++ b/WebCore/editing/visible_units.cpp
@@ -36,12 +36,32 @@
#include "TextIterator.h"
#include "VisiblePosition.h"
#include "htmlediting.h"
+#include <wtf/unicode/Unicode.h>
namespace WebCore {
using namespace HTMLNames;
+using namespace WTF::Unicode;
-static VisiblePosition previousBoundary(const VisiblePosition &c, unsigned (*searchFunction)(const UChar *, unsigned))
+static int firstNonComplexContextLineBreak(const UChar* characters, int length)
+{
+ for (int i = 0; i < length; ++i) {
+ if (!hasLineBreakingPropertyComplexContext(characters[i]))
+ return i;
+ }
+ return length;
+}
+
+static int lastNonComplexContextLineBreak(const UChar* characters, int length)
+{
+ for (int i = length - 1; i >= 0; --i) {
+ if (!hasLineBreakingPropertyComplexContext(characters[i]))
+ return i;
+ }
+ return -1;
+}
+
+static VisiblePosition previousBoundary(const VisiblePosition &c, unsigned (*searchFunction)(const UChar *, unsigned, unsigned))
{
Position pos = c.deepEquivalent();
Node *n = pos.node();
@@ -62,16 +82,35 @@ static VisiblePosition previousBoundary(const VisiblePosition &c, unsigned (*sea
Position end = rangeCompliantEquivalent(pos);
RefPtr<Range> searchRange = Range::create(d);
- int exception = 0;
- searchRange->setStart(start.node(), start.offset(), exception);
- searchRange->setEnd(end.node(), end.offset(), exception);
+ Vector<UChar, 1024> string;
+ unsigned suffixLength = 0;
+
+ ExceptionCode ec = 0;
+ if (hasLineBreakingPropertyComplexContext(c.characterBefore())) {
+ RefPtr<Range> forwardsScanRange(d->createRange());
+ forwardsScanRange->setEndAfter(boundary, ec);
+ forwardsScanRange->setStart(end.node(), end.m_offset, ec);
+ TextIterator forwardsIterator(forwardsScanRange.get());
+ while (!forwardsIterator.atEnd()) {
+ const UChar* characters = forwardsIterator.characters();
+ int length = forwardsIterator.length();
+ int i = firstNonComplexContextLineBreak(characters, length);
+ string.append(characters, i);
+ suffixLength += i;
+ if (i < length)
+ break;
+ forwardsIterator.advance();
+ }
+ }
+
+ searchRange->setStart(start.node(), start.m_offset, ec);
+ searchRange->setEnd(end.node(), end.m_offset, ec);
- ASSERT(!exception);
- if (exception)
+ ASSERT(!ec);
+ if (ec)
return VisiblePosition();
-
+
SimplifiedBackwardsTextIterator it(searchRange.get());
- Vector<UChar, 1024> string;
unsigned next = 0;
bool inTextSecurityMode = start.node() && start.node()->renderer() && start.node()->renderer()->style()->textSecurity() != TSNONE;
while (!it.atEnd()) {
@@ -85,7 +124,7 @@ static VisiblePosition previousBoundary(const VisiblePosition &c, unsigned (*sea
string.prepend(iteratorString.characters(), iteratorString.length());
}
- next = searchFunction(string.data(), string.size());
+ next = searchFunction(string.data(), string.size(), string.size() - suffixLength);
if (next != 0)
break;
it.advance();
@@ -94,26 +133,22 @@ static VisiblePosition previousBoundary(const VisiblePosition &c, unsigned (*sea
if (it.atEnd() && next == 0) {
pos = it.range()->startPosition();
} else if (next != 0) {
- Node *node = it.range()->startContainer(exception);
- if (node->isTextNode() || (node->renderer() && node->renderer()->isBR()))
+ Node *node = it.range()->startContainer(ec);
+ if ((node->isTextNode() && static_cast<int>(next) <= node->maxCharacterOffset()) || (node->renderer() && node->renderer()->isBR() && !next))
// The next variable contains a usable index into a text node
pos = Position(node, next);
else {
- // Use the end of the found range, the start is not guaranteed to
- // be correct.
- Position end = it.range()->endPosition();
- VisiblePosition boundary(end);
- unsigned i = it.length() - next;
- while (i--)
- boundary = boundary.previous();
- return boundary;
+ // Use the character iterator to translate the next value into a DOM position.
+ BackwardsCharacterIterator charIt(searchRange.get());
+ charIt.advance(string.size() - suffixLength - next);
+ pos = charIt.range()->endPosition();
}
}
return VisiblePosition(pos, DOWNSTREAM);
}
-static VisiblePosition nextBoundary(const VisiblePosition &c, unsigned (*searchFunction)(const UChar *, unsigned))
+static VisiblePosition nextBoundary(const VisiblePosition &c, unsigned (*searchFunction)(const UChar *, unsigned, unsigned))
{
Position pos = c.deepEquivalent();
Node *n = pos.node();
@@ -132,11 +167,30 @@ static VisiblePosition nextBoundary(const VisiblePosition &c, unsigned (*searchF
RefPtr<Range> searchRange(d->createRange());
Position start(rangeCompliantEquivalent(pos));
+
+ Vector<UChar, 1024> string;
+ unsigned prefixLength = 0;
+
ExceptionCode ec = 0;
+ if (hasLineBreakingPropertyComplexContext(c.characterAfter())) {
+ RefPtr<Range> backwardsScanRange(d->createRange());
+ backwardsScanRange->setEnd(start.node(), start.m_offset, ec);
+ SimplifiedBackwardsTextIterator backwardsIterator(backwardsScanRange.get());
+ while (!backwardsIterator.atEnd()) {
+ const UChar* characters = backwardsIterator.characters();
+ int length = backwardsIterator.length();
+ int i = lastNonComplexContextLineBreak(characters, length);
+ string.prepend(characters + i + 1, length - i - 1);
+ prefixLength += length - i - 1;
+ if (i > -1)
+ break;
+ backwardsIterator.advance();
+ }
+ }
+
searchRange->selectNodeContents(boundary, ec);
- searchRange->setStart(start.node(), start.offset(), ec);
+ searchRange->setStart(start.node(), start.m_offset, ec);
TextIterator it(searchRange.get(), true);
- Vector<UChar, 1024> string;
unsigned next = 0;
bool inTextSecurityMode = start.node() && start.node()->renderer() && start.node()->renderer()->style()->textSecurity() != TSNONE;
while (!it.atEnd()) {
@@ -151,7 +205,7 @@ static VisiblePosition nextBoundary(const VisiblePosition &c, unsigned (*searchF
string.append(iteratorString.characters(), iteratorString.length());
}
- next = searchFunction(string.data(), string.size());
+ next = searchFunction(string.data(), string.size(), prefixLength);
if (next != string.size())
break;
it.advance();
@@ -159,16 +213,18 @@ static VisiblePosition nextBoundary(const VisiblePosition &c, unsigned (*searchF
if (it.atEnd() && next == string.size()) {
pos = it.range()->startPosition();
- } else if (next != 0) {
+ } else if (next != prefixLength) {
// Use the character iterator to translate the next value into a DOM position.
CharacterIterator charIt(searchRange.get(), true);
- charIt.advance(next - 1);
+ charIt.advance(next - prefixLength - 1);
pos = charIt.range()->endPosition();
- // FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593)
- VisiblePosition visPos = VisiblePosition(pos);
- if (visPos == VisiblePosition(charIt.range()->startPosition()))
- pos = visPos.next(true).deepEquivalent();
+ if (*charIt.characters() == '\n') {
+ // FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593)
+ VisiblePosition visPos = VisiblePosition(pos);
+ if (visPos == VisiblePosition(charIt.range()->startPosition()))
+ pos = visPos.next(true).deepEquivalent();
+ }
}
// generate VisiblePosition, use UPSTREAM affinity if possible
@@ -177,10 +233,13 @@ static VisiblePosition nextBoundary(const VisiblePosition &c, unsigned (*searchF
// ---------
-static unsigned startWordBoundary(const UChar* characters, unsigned length)
+static unsigned startWordBoundary(const UChar* characters, unsigned length, unsigned offset)
{
+ ASSERT(offset);
+ if (lastNonComplexContextLineBreak(characters, offset) == -1)
+ return 0;
int start, end;
- findWordBoundary(characters, length, length, &start, &end);
+ findWordBoundary(characters, length, offset - 1, &start, &end);
return start;
}
@@ -201,10 +260,13 @@ VisiblePosition startOfWord(const VisiblePosition &c, EWordSide side)
return previousBoundary(p, startWordBoundary);
}
-static unsigned endWordBoundary(const UChar* characters, unsigned length)
+static unsigned endWordBoundary(const UChar* characters, unsigned length, unsigned offset)
{
+ ASSERT(offset <= length);
+ if (firstNonComplexContextLineBreak(characters + offset, length - offset) == static_cast<int>(length - offset))
+ return length;
int start, end;
- findWordBoundary(characters, length, 0, &start, &end);
+ findWordBoundary(characters, length, offset, &start, &end);
return end;
}
@@ -224,9 +286,11 @@ VisiblePosition endOfWord(const VisiblePosition &c, EWordSide side)
return nextBoundary(p, endWordBoundary);
}
-static unsigned previousWordPositionBoundary(const UChar* characters, unsigned length)
+static unsigned previousWordPositionBoundary(const UChar* characters, unsigned length, unsigned offset)
{
- return findNextWordFromIndex(characters, length, length, false);
+ if (lastNonComplexContextLineBreak(characters, offset) == -1)
+ return 0;
+ return findNextWordFromIndex(characters, length, offset, false);
}
VisiblePosition previousWordPosition(const VisiblePosition &c)
@@ -235,9 +299,11 @@ VisiblePosition previousWordPosition(const VisiblePosition &c)
return c.honorEditableBoundaryAtOrAfter(prev);
}
-static unsigned nextWordPositionBoundary(const UChar* characters, unsigned length)
+static unsigned nextWordPositionBoundary(const UChar* characters, unsigned length, unsigned offset)
{
- return findNextWordFromIndex(characters, length, 0, true);
+ if (firstNonComplexContextLineBreak(characters + offset, length - offset) == static_cast<int>(length - offset))
+ return length;
+ return findNextWordFromIndex(characters, length, offset, true);
}
VisiblePosition nextWordPosition(const VisiblePosition &c)
@@ -286,7 +352,7 @@ static VisiblePosition startPositionForLine(const VisiblePosition& c)
// There are VisiblePositions at offset 0 in blocks without
// RootInlineBoxes, like empty editable blocks and bordered blocks.
Position p = c.deepEquivalent();
- if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.offset() == 0)
+ if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.m_offset == 0)
return positionAvoidingFirstPositionInTable(c);
return VisiblePosition();
@@ -301,11 +367,11 @@ static VisiblePosition startPositionForLine(const VisiblePosition& c)
if (!startBox)
return VisiblePosition();
- RenderObject *startRenderer = startBox->object();
+ RenderObject *startRenderer = startBox->renderer();
if (!startRenderer)
return VisiblePosition();
- startNode = startRenderer->element();
+ startNode = startRenderer->node();
if (startNode)
break;
@@ -333,7 +399,7 @@ VisiblePosition startOfLine(const VisiblePosition& c)
// greater than the input position. This fix is to account for the discrepancy between lines with webkit-line-break:after-white-space
// style versus lines without that style, which would break before a space by default.
Position p = visPos.deepEquivalent();
- if (p.offset() > c.deepEquivalent().offset() && p.node()->isSameNode(c.deepEquivalent().node())) {
+ if (p.m_offset > c.deepEquivalent().m_offset && p.node()->isSameNode(c.deepEquivalent().node())) {
visPos = c.previous();
if (visPos.isNull())
return VisiblePosition();
@@ -354,7 +420,7 @@ static VisiblePosition endPositionForLine(const VisiblePosition& c)
// There are VisiblePositions at offset 0 in blocks without
// RootInlineBoxes, like empty editable blocks and bordered blocks.
Position p = c.deepEquivalent();
- if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.offset() == 0)
+ if (p.node()->renderer() && p.node()->renderer()->isRenderBlock() && p.m_offset == 0)
return c;
return VisiblePosition();
}
@@ -368,11 +434,11 @@ static VisiblePosition endPositionForLine(const VisiblePosition& c)
if (!endBox)
return VisiblePosition();
- RenderObject *endRenderer = endBox->object();
+ RenderObject *endRenderer = endBox->renderer();
if (!endRenderer)
return VisiblePosition();
- endNode = endRenderer->element();
+ endNode = endRenderer->node();
if (endNode)
break;
@@ -498,7 +564,7 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
FloatPoint absPos = containingBlock->localToAbsolute(FloatPoint());
if (containingBlock->hasOverflowClip())
absPos -= containingBlock->layer()->scrolledContentOffset();
- RenderObject *renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->object();
+ RenderObject* renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->renderer();
Node* node = renderer->node();
if (editingIgnoresContent(node))
return Position(node->parent(), node->nodeIndex());
@@ -571,7 +637,7 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int x)
// Need to move forward to next containing editable block in this root editable
// block and find the first root line box in that block.
Node* startBlock = enclosingBlock(node);
- Node* n = nextLeafWithSameEditability(node, p.offset());
+ Node* n = nextLeafWithSameEditability(node, p.m_offset);
while (n && startBlock == enclosingBlock(n))
n = nextLeafWithSameEditability(n);
while (n) {
@@ -599,7 +665,7 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int x)
FloatPoint absPos = containingBlock->localToAbsolute(FloatPoint());
if (containingBlock->hasOverflowClip())
absPos -= containingBlock->layer()->scrolledContentOffset();
- RenderObject *renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->object();
+ RenderObject* renderer = root->closestLeafChildForXPos(x - absPos.x(), isEditablePosition(p))->renderer();
Node* node = renderer->node();
if (editingIgnoresContent(node))
return Position(node->parent(), node->nodeIndex());
@@ -615,7 +681,7 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int x)
// ---------
-static unsigned startSentenceBoundary(const UChar* characters, unsigned length)
+static unsigned startSentenceBoundary(const UChar* characters, unsigned length, unsigned)
{
TextBreakIterator* iterator = sentenceBreakIterator(characters, length);
// FIXME: The following function can return -1; we don't handle that.
@@ -627,7 +693,7 @@ VisiblePosition startOfSentence(const VisiblePosition &c)
return previousBoundary(c, startSentenceBoundary);
}
-static unsigned endSentenceBoundary(const UChar* characters, unsigned length)
+static unsigned endSentenceBoundary(const UChar* characters, unsigned length, unsigned)
{
TextBreakIterator* iterator = sentenceBreakIterator(characters, length);
return textBreakNext(iterator);
@@ -639,7 +705,7 @@ VisiblePosition endOfSentence(const VisiblePosition &c)
return nextBoundary(c, endSentenceBoundary);
}
-static unsigned previousSentencePositionBoundary(const UChar* characters, unsigned length)
+static unsigned previousSentencePositionBoundary(const UChar* characters, unsigned length, unsigned)
{
// FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's not right.
TextBreakIterator* iterator = sentenceBreakIterator(characters, length);
@@ -653,7 +719,7 @@ VisiblePosition previousSentencePosition(const VisiblePosition &c)
return c.honorEditableBoundaryAtOrAfter(prev);
}
-static unsigned nextSentencePositionBoundary(const UChar* characters, unsigned length)
+static unsigned nextSentencePositionBoundary(const UChar* characters, unsigned length, unsigned)
{
// FIXME: This is identical to endSentenceBoundary. This isn't right, it needs to
// move to the equivlant position in the following sentence.
@@ -667,8 +733,13 @@ VisiblePosition nextSentencePosition(const VisiblePosition &c)
return c.honorEditableBoundaryAtOrBefore(next);
}
+static bool renderedAsNonInlineTableOrHR(RenderObject* renderer)
+{
+ return renderer && ((renderer->isTable() && !renderer->isInline()) || renderer->isHR());
+}
+
// FIXME: Broken for positions before/after images that aren't inline (5027702)
-VisiblePosition startOfParagraph(const VisiblePosition &c)
+VisiblePosition startOfParagraph(const VisiblePosition& c)
{
Position p = c.deepEquivalent();
Node *startNode = p.node();
@@ -676,16 +747,13 @@ VisiblePosition startOfParagraph(const VisiblePosition &c)
if (!startNode)
return VisiblePosition();
- if (startNode->renderer()
- && ((startNode->renderer()->isTable() && !startNode->renderer()->isInline())
- || startNode->renderer()->isHR())
- && p.offset() == maxDeepOffset(startNode))
- return VisiblePosition(Position(startNode, 0));
+ if (renderedAsNonInlineTableOrHR(startNode->renderer()) && p.atLastEditingPositionForNode())
+ return firstDeepEditingPositionForNode(startNode);
Node* startBlock = enclosingBlock(startNode);
Node *node = startNode;
- int offset = p.offset();
+ int offset = p.m_offset;
Node *n = startNode;
while (n) {
@@ -739,17 +807,14 @@ VisiblePosition endOfParagraph(const VisiblePosition &c)
Position p = c.deepEquivalent();
Node* startNode = p.node();
- if (startNode->renderer()
- && ((startNode->renderer()->isTable() && !startNode->renderer()->isInline())
- || startNode->renderer()->isHR())
- && p.offset() == 0)
- return VisiblePosition(Position(startNode, maxDeepOffset(startNode)));
+ if (renderedAsNonInlineTableOrHR(startNode->renderer()) && p.atFirstEditingPositionForNode())
+ return lastDeepEditingPositionForNode(startNode);
Node* startBlock = enclosingBlock(startNode);
Node *stayInsideBlock = startBlock;
Node *node = startNode;
- int offset = p.offset();
+ int offset = p.m_offset;
Node *n = startNode;
while (n) {
@@ -785,7 +850,7 @@ VisiblePosition endOfParagraph(const VisiblePosition &c)
n = n->traverseNextNode(stayInsideBlock);
} else if (editingIgnoresContent(n) || isTableElement(n)) {
node = n;
- offset = maxDeepOffset(n);
+ offset = lastOffsetForEditing(n);
n = n->traverseNextSibling(stayInsideBlock);
} else
n = n->traverseNextNode(stayInsideBlock);
@@ -820,25 +885,25 @@ bool isEndOfParagraph(const VisiblePosition &pos)
return pos.isNotNull() && pos == endOfParagraph(pos);
}
-VisiblePosition previousParagraphPosition(const VisiblePosition &p, int x)
+VisiblePosition previousParagraphPosition(const VisiblePosition& p, int x)
{
VisiblePosition pos = p;
do {
VisiblePosition n = previousLinePosition(pos, x);
if (n.isNull() || n == pos)
- return p;
+ break;
pos = n;
} while (inSameParagraph(p, pos));
return pos;
}
-VisiblePosition nextParagraphPosition(const VisiblePosition &p, int x)
+VisiblePosition nextParagraphPosition(const VisiblePosition& p, int x)
{
VisiblePosition pos = p;
do {
VisiblePosition n = nextLinePosition(pos, x);
if (n.isNull() || n == pos)
- return p;
+ break;
pos = n;
} while (inSameParagraph(p, pos));
return pos;
@@ -944,7 +1009,7 @@ VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition)
if (!highestRoot)
return VisiblePosition();
- return VisiblePosition(highestRoot, 0, DOWNSTREAM);
+ return firstDeepEditingPositionForNode(highestRoot);
}
VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
@@ -953,7 +1018,7 @@ VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
if (!highestRoot)
return VisiblePosition();
- return VisiblePosition(highestRoot, maxDeepOffset(highestRoot), DOWNSTREAM);
+ return lastDeepEditingPositionForNode(highestRoot);
}
}
diff --git a/WebCore/history/BackForwardListChromium.cpp b/WebCore/history/BackForwardListChromium.cpp
index 011f987..34f294c 100644
--- a/WebCore/history/BackForwardListChromium.cpp
+++ b/WebCore/history/BackForwardListChromium.cpp
@@ -38,6 +38,7 @@ static const unsigned NoCurrentItemIndex = UINT_MAX;
BackForwardList::BackForwardList(Page* page)
: m_page(page)
+ , m_client(0)
, m_capacity(DefaultCapacity)
, m_closed(true)
, m_enabled(true)
@@ -128,7 +129,8 @@ HistoryItemVector& BackForwardList::entries()
void BackForwardList::close()
{
- m_client->close();
+ if (m_client)
+ m_client->close();
m_page = 0;
m_closed = true;
}
diff --git a/WebCore/history/CachedFrame.cpp b/WebCore/history/CachedFrame.cpp
index ed7e9eb..db18903 100644
--- a/WebCore/history/CachedFrame.cpp
+++ b/WebCore/history/CachedFrame.cpp
@@ -27,9 +27,12 @@
#include "CachedPage.h"
#include "CachedFramePlatformData.h"
+#include "CString.h"
#include "DocumentLoader.h"
#include "Frame.h"
+#include "FrameLoaderClient.h"
#include "FrameView.h"
+#include "Logging.h"
#include <wtf/RefCountedLeakCounter.h>
#if ENABLE(SVG)
@@ -51,15 +54,29 @@ CachedFrame::CachedFrame(Frame* frame)
, m_documentLoader(frame->loader()->documentLoader())
, m_view(frame->view())
, m_mousePressNode(frame->eventHandler()->mousePressNode())
- , m_URL(frame->loader()->url())
- , m_cachedFrameScriptData(frame)
+ , m_url(frame->loader()->url())
{
#ifndef NDEBUG
cachedFrameCounter().increment();
#endif
+ ASSERT(m_document);
+ ASSERT(m_documentLoader);
+ ASSERT(m_view);
+
+ // Active DOM objects must be suspended before we cached the frame script data
+ m_document->suspendActiveDOMObjects();
+ m_cachedFrameScriptData.set(new ScriptCachedFrameData(frame));
+
m_document->documentWillBecomeInactive();
frame->clearTimers();
m_document->setInPageCache(true);
+
+ frame->loader()->client()->savePlatformDataToCachedFrame(this);
+
+ for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
+ m_childFrames.append(CachedFrame::create(child));
+
+ LOG(PageCache, "Finished creating CachedFrame with url %s and documentloader %p\n", m_url.string().utf8().data(), m_documentLoader.get());
}
CachedFrame::~CachedFrame()
@@ -71,19 +88,25 @@ CachedFrame::~CachedFrame()
clear();
}
-void CachedFrame::restore(Frame* frame)
+void CachedFrame::restore()
{
ASSERT(m_document->view() == m_view);
- m_cachedFrameScriptData.restore(frame);
+ Frame* frame = m_view->frame();
+ m_cachedFrameScriptData->restore(frame);
#if ENABLE(SVG)
- if (m_document && m_document->svgExtensions())
+ if (m_document->svgExtensions())
m_document->accessSVGExtensions()->unpauseAnimations();
#endif
frame->animation()->resumeAnimations(m_document.get());
frame->eventHandler()->setMousePressNode(mousePressNode());
+ m_document->resumeActiveDOMObjects();
+
+ // It is necessary to update any platform script objects after restoring the
+ // cached page.
+ frame->script()->updatePlatformScriptObjects();
}
void CachedFrame::clear()
@@ -113,7 +136,7 @@ void CachedFrame::clear()
m_document = 0;
m_view = 0;
m_mousePressNode = 0;
- m_URL = KURL();
+ m_url = KURL();
m_cachedFramePlatformData.clear();
diff --git a/WebCore/history/CachedFrame.h b/WebCore/history/CachedFrame.h
index c7beb15..83c3c3c 100644
--- a/WebCore/history/CachedFrame.h
+++ b/WebCore/history/CachedFrame.h
@@ -28,10 +28,11 @@
#include "KURL.h"
#include "ScriptCachedFrameData.h"
-#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
+ class CachedFrame;
class CachedFramePlatformData;
class DOMWindow;
class Document;
@@ -40,32 +41,38 @@ namespace WebCore {
class FrameView;
class Node;
-class CachedFrame : public Noncopyable {
+typedef Vector<RefPtr<CachedFrame> > CachedFrameVector;
+
+class CachedFrame : public RefCounted<CachedFrame> {
public:
- CachedFrame(Frame*);
+ static PassRefPtr<CachedFrame> create(Frame* frame) { return adoptRef(new CachedFrame(frame)); }
~CachedFrame();
- void restore(Frame*);
+ void restore();
void clear();
Document* document() const { return m_document.get(); }
DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
FrameView* view() const { return m_view.get(); }
Node* mousePressNode() const { return m_mousePressNode.get(); }
- const KURL& url() const { return m_URL; }
- DOMWindow* domWindow() const { return m_cachedFrameScriptData.domWindow(); }
+ const KURL& url() const { return m_url; }
+ DOMWindow* domWindow() const { return m_cachedFrameScriptData->domWindow(); }
void setCachedFramePlatformData(CachedFramePlatformData*);
CachedFramePlatformData* cachedFramePlatformData();
private:
+ CachedFrame(Frame*);
+
RefPtr<Document> m_document;
RefPtr<DocumentLoader> m_documentLoader;
RefPtr<FrameView> m_view;
RefPtr<Node> m_mousePressNode;
- KURL m_URL;
- ScriptCachedFrameData m_cachedFrameScriptData;
+ KURL m_url;
+ OwnPtr<ScriptCachedFrameData> m_cachedFrameScriptData;
OwnPtr<CachedFramePlatformData> m_cachedFramePlatformData;
+
+ CachedFrameVector m_childFrames;
};
} // namespace WebCore
diff --git a/WebCore/history/CachedPage.cpp b/WebCore/history/CachedPage.cpp
index 7167275..d6b66db 100644
--- a/WebCore/history/CachedPage.cpp
+++ b/WebCore/history/CachedPage.cpp
@@ -29,6 +29,9 @@
#include "CachedFrame.h"
#include "FocusController.h"
#include "Frame.h"
+#ifndef NDEBUG
+#include "FrameView.h"
+#endif
#include "Page.h"
#include <wtf/CurrentTime.h>
#include <wtf/RefCountedLeakCounter.h>
@@ -48,7 +51,7 @@ PassRefPtr<CachedPage> CachedPage::create(Page* page)
CachedPage::CachedPage(Page* page)
: m_timeStamp(currentTime())
- , m_cachedMainFrame(page->mainFrame())
+ , m_cachedMainFrame(CachedFrame::create(page->mainFrame()))
{
#ifndef NDEBUG
cachedPageCounter.increment();
@@ -66,8 +69,8 @@ CachedPage::~CachedPage()
void CachedPage::restore(Page* page)
{
- ASSERT(page && page->mainFrame());
- m_cachedMainFrame.restore(page->mainFrame());
+ ASSERT(page && page->mainFrame() && page->mainFrame() == m_cachedMainFrame->view()->frame());
+ m_cachedMainFrame->restore();
// Restore the focus appearance for the focused element.
// FIXME: Right now we don't support pages w/ frames in the b/f cache. This may need to be tweaked when we add support for that.
diff --git a/WebCore/history/CachedPage.h b/WebCore/history/CachedPage.h
index a9cf71c..430cf3a 100644
--- a/WebCore/history/CachedPage.h
+++ b/WebCore/history/CachedPage.h
@@ -30,7 +30,6 @@
namespace WebCore {
- class CachedFrame;
class CachedFramePlatformData;
class DOMWindow;
class Document;
@@ -48,22 +47,21 @@ public:
void restore(Page*);
void clear();
- Document* document() const { return m_cachedMainFrame.document(); }
- DocumentLoader* documentLoader() const { return m_cachedMainFrame.documentLoader(); }
- FrameView* view() const { return m_cachedMainFrame.view(); }
- Node* mousePressNode() const { return m_cachedMainFrame.mousePressNode(); }
- const KURL& url() const { return m_cachedMainFrame.url(); }
- DOMWindow* domWindow() const { return m_cachedMainFrame.domWindow(); }
+ Document* document() const { return m_cachedMainFrame->document(); }
+ DocumentLoader* documentLoader() const { return m_cachedMainFrame->documentLoader(); }
+ FrameView* mainFrameView() const { return m_cachedMainFrame->view(); }
+ const KURL& url() const { return m_cachedMainFrame->url(); }
+ DOMWindow* domWindow() const { return m_cachedMainFrame->domWindow(); }
double timeStamp() const { return m_timeStamp; }
- CachedFrame* cachedMainFrame() { return &m_cachedMainFrame; }
+ CachedFrame* cachedMainFrame() { return m_cachedMainFrame.get(); }
private:
CachedPage(Page*);
double m_timeStamp;
- CachedFrame m_cachedMainFrame;
+ RefPtr<CachedFrame> m_cachedMainFrame;
};
} // namespace WebCore
diff --git a/WebCore/history/HistoryItem.cpp b/WebCore/history/HistoryItem.cpp
index 5a059b2..1d05042f 100644
--- a/WebCore/history/HistoryItem.cpp
+++ b/WebCore/history/HistoryItem.cpp
@@ -50,7 +50,6 @@ HistoryItem::HistoryItem()
: m_lastVisitedTime(0)
, m_lastVisitWasHTTPNonGet(false)
, m_lastVisitWasFailure(false)
- , m_isInPageCache(false)
, m_isTargetItem(false)
, m_visitCount(0)
{
@@ -63,7 +62,6 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, double ti
, m_lastVisitedTime(time)
, m_lastVisitWasHTTPNonGet(false)
, m_lastVisitWasFailure(false)
- , m_isInPageCache(false)
, m_isTargetItem(false)
, m_visitCount(0)
{
@@ -78,7 +76,6 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, const Str
, m_lastVisitedTime(time)
, m_lastVisitWasHTTPNonGet(false)
, m_lastVisitWasFailure(false)
- , m_isInPageCache(false)
, m_isTargetItem(false)
, m_visitCount(0)
{
@@ -94,7 +91,6 @@ HistoryItem::HistoryItem(const KURL& url, const String& target, const String& pa
, m_lastVisitedTime(0)
, m_lastVisitWasHTTPNonGet(false)
, m_lastVisitWasFailure(false)
- , m_isInPageCache(false)
, m_isTargetItem(false)
, m_visitCount(0)
{
@@ -103,7 +99,7 @@ HistoryItem::HistoryItem(const KURL& url, const String& target, const String& pa
HistoryItem::~HistoryItem()
{
- ASSERT(!m_isInPageCache);
+ ASSERT(!m_cachedPage);
iconDatabase()->releaseIconForPageURL(m_urlString);
}
@@ -120,18 +116,19 @@ inline HistoryItem::HistoryItem(const HistoryItem& item)
, m_lastVisitWasHTTPNonGet(item.m_lastVisitWasHTTPNonGet)
, m_scrollPoint(item.m_scrollPoint)
, m_lastVisitWasFailure(item.m_lastVisitWasFailure)
- , m_isInPageCache(item.m_isInPageCache)
, m_isTargetItem(item.m_isTargetItem)
, m_visitCount(item.m_visitCount)
, m_dailyVisitCounts(item.m_dailyVisitCounts)
, m_weeklyVisitCounts(item.m_weeklyVisitCounts)
, m_formContentType(item.m_formContentType)
{
+ ASSERT(!item.m_cachedPage);
+
if (item.m_formData)
m_formData = item.m_formData->copy();
unsigned size = item.m_subItems.size();
- m_subItems.reserveCapacity(size);
+ m_subItems.reserveInitialCapacity(size);
for (unsigned i = 0; i < size; ++i)
m_subItems.append(item.m_subItems[i]->copy());
diff --git a/WebCore/history/HistoryItem.h b/WebCore/history/HistoryItem.h
index cd23c9e..d35352e 100644
--- a/WebCore/history/HistoryItem.h
+++ b/WebCore/history/HistoryItem.h
@@ -28,6 +28,7 @@
#include "IntPoint.h"
#include "PlatformString.h"
+#include <wtf/OwnPtr.h>
#if PLATFORM(MAC)
#import <wtf/RetainPtr.h>
@@ -50,7 +51,7 @@ class FormData;
class HistoryItem;
class Image;
class KURL;
-class ResourceRequest;
+struct ResourceRequest;
typedef Vector<RefPtr<HistoryItem> > HistoryItemVector;
@@ -86,8 +87,7 @@ public:
const String& urlString() const;
const String& title() const;
- void setInPageCache(bool inPageCache) { m_isInPageCache = inPageCache; }
- bool isInPageCache() const { return m_isInPageCache; }
+ bool isInPageCache() const { return m_cachedPage; }
double lastVisitedTime() const;
@@ -212,7 +212,6 @@ private:
HistoryItemVector m_subItems;
bool m_lastVisitWasFailure;
- bool m_isInPageCache;
bool m_isTargetItem;
int m_visitCount;
Vector<int> m_dailyVisitCounts;
diff --git a/WebCore/html/CanvasGradient.cpp b/WebCore/html/CanvasGradient.cpp
index 693d8f7..fd48194 100644
--- a/WebCore/html/CanvasGradient.cpp
+++ b/WebCore/html/CanvasGradient.cpp
@@ -34,11 +34,13 @@ namespace WebCore {
CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1)
: m_gradient(Gradient::create(p0, p1))
+ , m_dashbardCompatibilityMode(false)
{
}
CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1)
: m_gradient(Gradient::create(p0, r0, p1, r1))
+ , m_dashbardCompatibilityMode(false)
{
}
@@ -51,7 +53,8 @@ void CanvasGradient::addColorStop(float value, const String& color, ExceptionCod
RGBA32 rgba = 0;
if (!CSSParser::parseColor(rgba, color)) {
- ec = SYNTAX_ERR;
+ if (!m_dashbardCompatibilityMode)
+ ec = SYNTAX_ERR;
return;
}
diff --git a/WebCore/html/CanvasGradient.h b/WebCore/html/CanvasGradient.h
index 3b81dbd..0a77652 100644
--- a/WebCore/html/CanvasGradient.h
+++ b/WebCore/html/CanvasGradient.h
@@ -54,11 +54,16 @@ namespace WebCore {
void getColor(float value, float* r, float* g, float* b, float* a) const { m_gradient->getColor(value, r, g, b, a); }
+#if ENABLE(DASHBOARD_SUPPORT)
+ void setDashboardCompatibilityMode() { m_dashbardCompatibilityMode = true; }
+#endif
+
private:
CanvasGradient(const FloatPoint& p0, const FloatPoint& p1);
CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1);
RefPtr<Gradient> m_gradient;
+ bool m_dashbardCompatibilityMode;
};
} //namespace
diff --git a/WebCore/html/CanvasRenderingContext2D.cpp b/WebCore/html/CanvasRenderingContext2D.cpp
index 373301a..82680bd 100644
--- a/WebCore/html/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/CanvasRenderingContext2D.cpp
@@ -357,7 +357,7 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
return;
TransformationMatrix newTransform = state().m_transform;
- newTransform.scale(sx, sy);
+ newTransform.scaleNonUniform(sx, sy);
if (!newTransform.isInvertible()) {
state().m_invertibleCTM = false;
return;
@@ -365,7 +365,7 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
state().m_transform = newTransform;
c->scale(FloatSize(sx, sy));
- m_path.transform(TransformationMatrix().scale(1.0/sx, 1.0/sy));
+ m_path.transform(TransformationMatrix().scaleNonUniform(1.0/sx, 1.0/sy));
}
void CanvasRenderingContext2D::rotate(float angleInRadians)
@@ -867,7 +867,6 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
GraphicsContext* dc = drawingContext();
if (!dc)
return;
- // FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
const CGFloat components[5] = { c, m, y, k, a };
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceCMYK();
@@ -875,6 +874,8 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGColorSpaceRelease(colorSpace);
CGContextSetShadowWithColor(dc->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
CGColorRelease(shadowColor);
+#else
+ dc->setShadow(IntSize(width, -height), blur, Color(c, m, y, k, a));
#endif
}
@@ -1078,6 +1079,15 @@ void CanvasRenderingContext2D::setCompositeOperation(const String& operation)
setGlobalCompositeOperation(operation);
}
+void CanvasRenderingContext2D::prepareGradientForDashboard(CanvasGradient* gradient) const
+{
+#if ENABLE(DASHBOARD_SUPPORT)
+ if (Settings* settings = m_canvas->document()->settings())
+ if (settings->usesDashboardBackwardCompatibilityMode())
+ gradient->setDashboardCompatibilityMode();
+#endif
+}
+
PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionCode& ec)
{
if (!isfinite(x0) || !isfinite(y0) || !isfinite(x1) || !isfinite(y1)) {
@@ -1085,7 +1095,9 @@ PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float
return 0;
}
- return CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ PassRefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
+ prepareGradientForDashboard(gradient.get());
+ return gradient;
}
PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionCode& ec)
@@ -1095,7 +1107,9 @@ PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float
ec = NOT_SUPPORTED_ERR;
return 0;
}
- return CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ PassRefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
+ prepareGradientForDashboard(gradient.get());
+ return gradient;
}
PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
@@ -1422,6 +1436,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
m_canvas->willDraw(FloatRect(0, 0, m_canvas->width(), m_canvas->height()));
}
+#if PLATFORM(CG)
CanvasStyle* drawStyle = fill ? state().m_fillStyle.get() : state().m_strokeStyle.get();
if (drawStyle->canvasGradient() || drawStyle->canvasPattern()) {
// FIXME: The rect is not big enough for miters on stroked text.
@@ -1451,6 +1466,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
return;
}
+#endif
c->setTextDrawingMode(fill ? cTextFill : cTextStroke);
c->drawBidiText(font, textRun, location);
diff --git a/WebCore/html/CanvasRenderingContext2D.h b/WebCore/html/CanvasRenderingContext2D.h
index 8d05b92..d74659e 100644
--- a/WebCore/html/CanvasRenderingContext2D.h
+++ b/WebCore/html/CanvasRenderingContext2D.h
@@ -251,7 +251,8 @@ namespace WebCore {
#if ENABLE(DASHBOARD_SUPPORT)
void clearPathForDashboardBackwardCompatibilityMode();
#endif
-
+
+ void prepareGradientForDashboard(CanvasGradient* gradient) const;
void checkOrigin(const KURL&);
HTMLCanvasElement* m_canvas;
diff --git a/WebCore/html/CanvasStyle.cpp b/WebCore/html/CanvasStyle.cpp
index d82643f..0aaaab2 100644
--- a/WebCore/html/CanvasStyle.cpp
+++ b/WebCore/html/CanvasStyle.cpp
@@ -78,12 +78,21 @@ CanvasStyle::CanvasStyle(float grayLevel, float alpha)
}
CanvasStyle::CanvasStyle(float r, float g, float b, float a)
- : m_type(RGBA), m_alpha(a), m_red(r), m_green(g), m_blue(b)
+ : m_type(RGBA)
+ , m_alpha(a)
+ , m_red(r)
+ , m_green(g)
+ , m_blue(b)
{
}
CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
- : m_type(CMYKA), m_alpha(a), m_cyan(c), m_magenta(m), m_yellow(y), m_black(k)
+ : m_type(CMYKA)
+ , m_alpha(a)
+ , m_cyan(c)
+ , m_magenta(m)
+ , m_yellow(y)
+ , m_black(k)
{
}
@@ -146,10 +155,10 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
currentPen.setColor(clr);
context->platformContext()->setPen(currentPen);
-#elif PLATFORM(CAIRO)
- notImplemented();
#elif PLATFORM(SGL)
context->setCMYKAStrokeColor(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
+#else
+ context->setStrokeColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha));
#endif
break;
}
@@ -211,6 +220,8 @@ void CanvasStyle::applyFillColor(GraphicsContext* context)
context->platformContext()->setBrush(currentBrush);
#elif PLATFORM(SGL)
context->setCMYKAFillColor(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
+#else
+ context->setFillColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha));
#endif
break;
}
diff --git a/WebCore/html/HTMLAnchorElement.cpp b/WebCore/html/HTMLAnchorElement.cpp
index 4122168..c6b2a95 100644
--- a/WebCore/html/HTMLAnchorElement.cpp
+++ b/WebCore/html/HTMLAnchorElement.cpp
@@ -38,7 +38,8 @@
#include "KeyboardEvent.h"
#include "MouseEvent.h"
#include "MutationEvent.h"
-#include "RenderFlow.h"
+#include "Page.h"
+#include "RenderBox.h"
#include "RenderImage.h"
#include "ResourceRequest.h"
#include "SelectionController.h"
@@ -107,18 +108,14 @@ bool HTMLAnchorElement::isKeyboardFocusable(KeyboardEvent* event) const
if (!document()->frame()->eventHandler()->tabsToLinks(event))
return false;
- if (!renderer() || !renderer()->isBox())
+ if (!renderer() || !renderer()->isBoxModelObject())
return false;
// Before calling absoluteRects, check for the common case where the renderer
- // or one of the continuations is non-empty, since this is a faster check and
- // almost always returns true.
- RenderBox* box = toRenderBox(renderer());
+ // is non-empty, since this is a faster check and almost always returns true.
+ RenderBoxModelObject* box = toRenderBoxModelObject(renderer());
if (!box->borderBoundingBox().isEmpty())
return true;
- for (RenderFlow* r = box->virtualContinuation(); r; r = r->continuation())
- if (!r->borderBoundingBox().isEmpty())
- return true;
Vector<IntRect> rects;
FloatPoint absPos = renderer()->localToAbsolute();
@@ -203,7 +200,7 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
if (evt->target()->toNode()->hasTagName(imgTag)) {
HTMLImageElement* img = static_cast<HTMLImageElement*>(evt->target()->toNode());
if (img && img->isServerMap()) {
- RenderImage* r = static_cast<RenderImage*>(img->renderer());
+ RenderImage* r = toRenderImage(img->renderer());
if (r && e) {
// FIXME: broken with transforms
FloatPoint absPos = r->localToAbsolute();
@@ -434,7 +431,8 @@ void HTMLAnchorElement::setType(const AtomicString& value)
String HTMLAnchorElement::hash() const
{
- return "#" + href().ref();
+ String ref = href().ref();
+ return ref.isEmpty() ? "" : "#" + ref;
}
String HTMLAnchorElement::host() const
@@ -467,7 +465,8 @@ String HTMLAnchorElement::protocol() const
String HTMLAnchorElement::search() const
{
- return href().query();
+ String query = href().query();
+ return query.isEmpty() ? "" : "?" + query;
}
String HTMLAnchorElement::text() const
diff --git a/WebCore/html/HTMLAppletElement.cpp b/WebCore/html/HTMLAppletElement.cpp
index 9d7ab6a..de8e1cf 100644
--- a/WebCore/html/HTMLAppletElement.cpp
+++ b/WebCore/html/HTMLAppletElement.cpp
@@ -99,9 +99,12 @@ void HTMLAppletElement::removedFromDocument()
HTMLPlugInElement::removedFromDocument();
}
-bool HTMLAppletElement::rendererIsNeeded(RenderStyle*)
+bool HTMLAppletElement::rendererIsNeeded(RenderStyle* style)
{
- return !getAttribute(codeAttr).isNull();
+ if (getAttribute(codeAttr).isNull())
+ return false;
+
+ return HTMLPlugInElement::rendererIsNeeded(style);
}
RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style)
@@ -112,9 +115,13 @@ RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style
HashMap<String, String> args;
args.set("code", getAttribute(codeAttr));
+
const AtomicString& codeBase = getAttribute(codebaseAttr);
- if(!codeBase.isNull())
+ if (!codeBase.isNull())
args.set("codeBase", codeBase);
+ else
+ args.set("codeBase", document()->baseURL().baseAsString());
+
const AtomicString& name = getAttribute(document()->isHTMLDocument() ? nameAttr : idAttr);
if (!name.isNull())
args.set("name", name);
diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp
index 7a3c9e0..9db50b7 100644
--- a/WebCore/html/HTMLAreaElement.cpp
+++ b/WebCore/html/HTMLAreaElement.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -27,6 +27,7 @@
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "Length.h"
+#include "Path.h"
#include "RenderObject.h"
using namespace std;
@@ -35,8 +36,8 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLAreaElement::HTMLAreaElement(const QualifiedName& tagName, Document *doc)
- : HTMLAnchorElement(tagName, doc)
+HTMLAreaElement::HTMLAreaElement(const QualifiedName& tagName, Document* document)
+ : HTMLAnchorElement(tagName, document)
, m_coords(0)
, m_coordsLen(0)
, m_lastSize(-1, -1)
@@ -73,11 +74,11 @@ void HTMLAreaElement::parseMappedAttribute(MappedAttribute *attr)
bool HTMLAreaElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result)
{
if (m_lastSize != size) {
- region = getRegion(size);
+ m_region.set(new Path(getRegion(size)));
m_lastSize = size;
}
- if (!region.contains(IntPoint(x, y)))
+ if (!m_region->contains(IntPoint(x, y)))
return false;
result.setInnerNode(this);
@@ -150,32 +151,32 @@ Path HTMLAreaElement::getRegion(const IntSize& size) const
return path;
}
-String HTMLAreaElement::accessKey() const
+const AtomicString& HTMLAreaElement::accessKey() const
{
return getAttribute(accesskeyAttr);
}
-void HTMLAreaElement::setAccessKey(const String& value)
+void HTMLAreaElement::setAccessKey(const AtomicString& value)
{
setAttribute(accesskeyAttr, value);
}
-String HTMLAreaElement::alt() const
+const AtomicString& HTMLAreaElement::alt() const
{
return getAttribute(altAttr);
}
-void HTMLAreaElement::setAlt(const String& value)
+void HTMLAreaElement::setAlt(const AtomicString& value)
{
setAttribute(altAttr, value);
}
-String HTMLAreaElement::coords() const
+const AtomicString& HTMLAreaElement::coords() const
{
return getAttribute(coordsAttr);
}
-void HTMLAreaElement::setCoords(const String& value)
+void HTMLAreaElement::setCoords(const AtomicString& value)
{
setAttribute(coordsAttr, value);
}
@@ -185,7 +186,7 @@ KURL HTMLAreaElement::href() const
return document()->completeURL(getAttribute(hrefAttr));
}
-void HTMLAreaElement::setHref(const String& value)
+void HTMLAreaElement::setHref(const AtomicString& value)
{
setAttribute(hrefAttr, value);
}
@@ -200,12 +201,12 @@ void HTMLAreaElement::setNoHref(bool noHref)
setAttribute(nohrefAttr, noHref ? "" : 0);
}
-String HTMLAreaElement::shape() const
+const AtomicString& HTMLAreaElement::shape() const
{
return getAttribute(shapeAttr);
}
-void HTMLAreaElement::setShape(const String& value)
+void HTMLAreaElement::setShape(const AtomicString& value)
{
setAttribute(shapeAttr, value);
}
@@ -220,7 +221,7 @@ String HTMLAreaElement::target() const
return getAttribute(targetAttr);
}
-void HTMLAreaElement::setTarget(const String& value)
+void HTMLAreaElement::setTarget(const AtomicString& value)
{
setAttribute(targetAttr, value);
}
diff --git a/WebCore/html/HTMLAreaElement.h b/WebCore/html/HTMLAreaElement.h
index 7de5832..19533b1 100644
--- a/WebCore/html/HTMLAreaElement.h
+++ b/WebCore/html/HTMLAreaElement.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,11 +25,11 @@
#include "HTMLAnchorElement.h"
#include "IntSize.h"
-#include "Path.h"
namespace WebCore {
class HitTestResult;
+class Path;
class HTMLAreaElement : public HTMLAnchorElement {
public:
@@ -47,33 +47,34 @@ public:
virtual IntRect getRect(RenderObject*) const;
- String accessKey() const;
- void setAccessKey(const String&);
+ const AtomicString& accessKey() const;
+ void setAccessKey(const AtomicString&);
- String alt() const;
- void setAlt(const String&);
+ const AtomicString& alt() const;
+ void setAlt(const AtomicString&);
- String coords() const;
- void setCoords(const String&);
+ const AtomicString& coords() const;
+ void setCoords(const AtomicString&);
KURL href() const;
- void setHref(const String&);
+ void setHref(const AtomicString&);
bool noHref() const;
void setNoHref(bool);
- String shape() const;
- void setShape(const String&);
+ const AtomicString& shape() const;
+ void setShape(const AtomicString&);
virtual bool isFocusable() const;
virtual String target() const;
- void setTarget(const String&);
+ void setTarget(const AtomicString&);
private:
enum Shape { Default, Poly, Rect, Circle, Unknown };
Path getRegion(const IntSize&) const;
- Path region;
+
+ OwnPtr<Path> m_region;
Length* m_coords;
int m_coordsLen;
IntSize m_lastSize;
diff --git a/WebCore/html/HTMLCanvasElement.cpp b/WebCore/html/HTMLCanvasElement.cpp
index 7481d96..1cd2796 100644
--- a/WebCore/html/HTMLCanvasElement.cpp
+++ b/WebCore/html/HTMLCanvasElement.cpp
@@ -280,7 +280,7 @@ TransformationMatrix HTMLCanvasElement::baseTransform() const
IntSize size = convertLogicalToDevice(unscaledSize);
TransformationMatrix transform;
if (size.width() && size.height())
- transform.scale(size.width() / unscaledSize.width(), size.height() / unscaledSize.height());
+ transform.scaleNonUniform(size.width() / unscaledSize.width(), size.height() / unscaledSize.height());
transform.multiply(m_imageBuffer->baseTransform());
return transform;
}
diff --git a/WebCore/html/HTMLCanvasElement.idl b/WebCore/html/HTMLCanvasElement.idl
index e457c15..bf69ac0 100644
--- a/WebCore/html/HTMLCanvasElement.idl
+++ b/WebCore/html/HTMLCanvasElement.idl
@@ -38,7 +38,7 @@ module html {
raises(DOMException);
#if !defined(LANGUAGE_OBJECTIVE_C)
- DOMObject getContext(in DOMString contextId);
+ [V8Custom] DOMObject getContext(in DOMString contextId);
#endif
};
diff --git a/WebCore/html/HTMLDocument.cpp b/WebCore/html/HTMLDocument.cpp
index a987c76..01f151c 100644
--- a/WebCore/html/HTMLDocument.cpp
+++ b/WebCore/html/HTMLDocument.cpp
@@ -433,5 +433,11 @@ void HTMLDocument::clear()
// We've long had a comment saying that IE doesn't support this.
// But I do see it in the documentation for Mozilla.
}
-
+
+bool HTMLDocument::isFrameSet() const
+{
+ HTMLElement* bodyElement = body();
+ return bodyElement && bodyElement->renderer() && bodyElement->hasTagName(framesetTag);
+}
+
}
diff --git a/WebCore/html/HTMLDocument.h b/WebCore/html/HTMLDocument.h
index de84c70..ab5da50 100644
--- a/WebCore/html/HTMLDocument.h
+++ b/WebCore/html/HTMLDocument.h
@@ -88,6 +88,7 @@ protected:
private:
virtual bool isHTMLDocument() const { return true; }
+ virtual bool isFrameSet() const;
virtual Tokenizer* createTokenizer();
virtual void determineParseMode();
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index 4394bc8..906f847 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -96,23 +96,6 @@ int HTMLElement::tagPriority() const
return 1;
}
-PassRefPtr<Node> HTMLElement::cloneNode(bool deep)
-{
- RefPtr<HTMLElement> clone = HTMLElementFactory::createHTMLElement(tagQName(), document(), 0, false);
- if (!clone)
- return 0;
-
- if (namedAttrMap)
- clone->attributes()->setAttributes(*namedAttrMap);
-
- clone->copyNonAttributeProperties(this);
-
- if (deep)
- cloneChildNodes(clone.get());
-
- return clone.release();
-}
-
bool HTMLElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
if (attrName == alignAttr ||
@@ -947,8 +930,18 @@ bool HTMLElement::inEitherTagList(const Node* newChild)
if (newChild->isHTMLElement()) {
const HTMLElement* child = static_cast<const HTMLElement*>(newChild);
- if (inlineTagList()->contains(child->tagQName().localName().impl()))
+ if (inlineTagList()->contains(child->tagQName().localName().impl())) {
+#if PLATFORM(MAC)
+ if (child->tagQName().localName() == styleTag) {
+ // Leopard Mail doesn't expect <style> to be in the body of the document, so don't allow it in that case.
+ // See <rdar://problem/6621310>
+ Settings* settings = newChild->document() ? newChild->document()->settings() : 0;
+ if (settings && settings->needsLeopardMailQuirks())
+ return false;
+ }
+#endif
return true;
+ }
if (blockTagList()->contains(child->tagQName().localName().impl()))
return true;
return !isRecognizedTagName(child->tagQName()); // Accept custom html tags
@@ -999,7 +992,7 @@ bool HTMLElement::rendererIsNeeded(RenderStyle *style)
if (settings && settings->isJavaScriptEnabled())
return false;
}
- return (document()->documentElement() == this) || (style->display() != NONE);
+ return StyledElement::rendererIsNeeded(style);
}
RenderObject* HTMLElement::createRenderer(RenderArena* arena, RenderStyle* style)
diff --git a/WebCore/html/HTMLElement.h b/WebCore/html/HTMLElement.h
index 3d84e8b..60152cd 100644
--- a/WebCore/html/HTMLElement.h
+++ b/WebCore/html/HTMLElement.h
@@ -45,8 +45,6 @@ public:
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
virtual void parseMappedAttribute(MappedAttribute*);
- virtual PassRefPtr<Node> cloneNode(bool deep);
-
PassRefPtr<HTMLCollection> children();
String id() const;
diff --git a/WebCore/html/HTMLElementFactory.cpp b/WebCore/html/HTMLElementFactory.cpp
deleted file mode 100644
index 16c2b99..0000000
--- a/WebCore/html/HTMLElementFactory.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * This file is part of the HTML DOM implementation for KDE.
- *
- * Copyright (C) 2005 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "HTMLElementFactory.h"
-
-#include "HTMLAnchorElement.h"
-#include "HTMLAppletElement.h"
-#include "HTMLAreaElement.h"
-#include "HTMLAudioElement.h"
-#include "HTMLBRElement.h"
-#include "HTMLBaseElement.h"
-#include "HTMLBaseFontElement.h"
-#include "HTMLBlockquoteElement.h"
-#include "HTMLBodyElement.h"
-#include "HTMLButtonElement.h"
-#include "HTMLCanvasElement.h"
-#include "HTMLDListElement.h"
-#include "HTMLDirectoryElement.h"
-#include "HTMLDivElement.h"
-#include "HTMLDocument.h"
-#include "HTMLEmbedElement.h"
-#include "HTMLFieldSetElement.h"
-#include "HTMLFontElement.h"
-#include "HTMLFormElement.h"
-#include "HTMLFrameElement.h"
-#include "HTMLFrameSetElement.h"
-#include "HTMLHRElement.h"
-#include "HTMLHeadElement.h"
-#include "HTMLHeadingElement.h"
-#include "HTMLHtmlElement.h"
-#include "HTMLIFrameElement.h"
-#include "HTMLImageElement.h"
-#include "HTMLIsIndexElement.h"
-#include "HTMLKeygenElement.h"
-#include "HTMLLIElement.h"
-#include "HTMLLabelElement.h"
-#include "HTMLLegendElement.h"
-#include "HTMLLinkElement.h"
-#include "HTMLMapElement.h"
-#include "HTMLMarqueeElement.h"
-#include "HTMLMenuElement.h"
-#include "HTMLMetaElement.h"
-#include "HTMLModElement.h"
-#include "HTMLNames.h"
-#include "HTMLOListElement.h"
-#include "HTMLObjectElement.h"
-#include "HTMLOptGroupElement.h"
-#include "HTMLOptionElement.h"
-#include "HTMLParagraphElement.h"
-#include "HTMLParamElement.h"
-#include "HTMLPreElement.h"
-#include "HTMLQuoteElement.h"
-#include "HTMLScriptElement.h"
-#include "HTMLSelectElement.h"
-#include "HTMLSourceElement.h"
-#include "HTMLStyleElement.h"
-#include "HTMLTableCaptionElement.h"
-#include "HTMLTableCellElement.h"
-#include "HTMLTableColElement.h"
-#include "HTMLTableElement.h"
-#include "HTMLTableRowElement.h"
-#include "HTMLTableSectionElement.h"
-#include "HTMLTextAreaElement.h"
-#include "HTMLTitleElement.h"
-#include "HTMLUListElement.h"
-#include "HTMLVideoElement.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-typedef PassRefPtr<HTMLElement> (*ConstructorFunc)(const QualifiedName& tagName, Document*, HTMLFormElement*, bool createdByParser);
-typedef HashMap<AtomicStringImpl*, ConstructorFunc> FunctionMap;
-static FunctionMap* gFunctionMap;
-
-static PassRefPtr<HTMLElement> htmlConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLHtmlElement(htmlTag, doc);
-}
-
-static PassRefPtr<HTMLElement> headConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLHeadElement(headTag, doc);
-}
-
-static PassRefPtr<HTMLElement> bodyConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLBodyElement(bodyTag, doc);
-}
-
-static PassRefPtr<HTMLElement> baseConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLBaseElement(baseTag, doc);
-}
-
-static PassRefPtr<HTMLElement> linkConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool createdByParser)
-{
- return new HTMLLinkElement(linkTag, doc, createdByParser);
-}
-
-static PassRefPtr<HTMLElement> metaConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLMetaElement(metaTag, doc);
-}
-
-static PassRefPtr<HTMLElement> styleConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool createdByParser)
-{
- return new HTMLStyleElement(styleTag, doc, createdByParser);
-}
-
-static PassRefPtr<HTMLElement> titleConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTitleElement(titleTag, doc);
-}
-
-static PassRefPtr<HTMLElement> frameConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool createdByParser)
-{
- return new HTMLFrameElement(frameTag, doc, createdByParser);
-}
-
-static PassRefPtr<HTMLElement> framesetConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLFrameSetElement(framesetTag, doc);
-}
-
-static PassRefPtr<HTMLElement> iframeConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool createdByParser)
-{
- return new HTMLIFrameElement(iframeTag, doc, createdByParser);
-}
-
-static PassRefPtr<HTMLElement> formConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLFormElement(formTag, doc);
-}
-
-static PassRefPtr<HTMLElement> buttonConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLButtonElement(buttonTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> inputConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLInputElement(inputTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> isindexConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLIsIndexElement(isindexTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> fieldsetConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLFieldSetElement(fieldsetTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> keygenConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLKeygenElement(keygenTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> labelConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLLabelElement(labelTag, doc);
-}
-
-static PassRefPtr<HTMLElement> legendConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLLegendElement(legendTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> optgroupConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLOptGroupElement(optgroupTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> optionConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLOptionElement(optionTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> selectConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLSelectElement(selectTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> textareaConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLTextAreaElement(textareaTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> dlConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLDListElement(dlTag, doc);
-}
-
-static PassRefPtr<HTMLElement> ulConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLUListElement(ulTag, doc);
-}
-
-static PassRefPtr<HTMLElement> olConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLOListElement(olTag, doc);
-}
-
-static PassRefPtr<HTMLElement> dirConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLDirectoryElement(dirTag, doc);
-}
-
-static PassRefPtr<HTMLElement> menuConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLMenuElement(menuTag, doc);
-}
-
-static PassRefPtr<HTMLElement> liConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLLIElement(liTag, doc);
-}
-
-static PassRefPtr<HTMLElement> blockquoteConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLBlockquoteElement(blockquoteTag, doc);
-}
-
-static PassRefPtr<HTMLElement> divConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLDivElement(divTag, doc);
-}
-
-static PassRefPtr<HTMLElement> headingConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLHeadingElement(tagName, doc);
-}
-
-static PassRefPtr<HTMLElement> hrConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLHRElement(hrTag, doc);
-}
-
-static PassRefPtr<HTMLElement> paragraphConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLParagraphElement(pTag, doc);
-}
-
-static PassRefPtr<HTMLElement> preConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLPreElement(tagName, doc);
-}
-
-static PassRefPtr<HTMLElement> basefontConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLBaseFontElement(basefontTag, doc);
-}
-
-static PassRefPtr<HTMLElement> fontConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLFontElement(fontTag, doc);
-}
-
-static PassRefPtr<HTMLElement> modConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLModElement(tagName, doc);
-}
-
-static PassRefPtr<HTMLElement> anchorConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLAnchorElement(aTag, doc);
-}
-
-static PassRefPtr<HTMLElement> imageConstructor(const QualifiedName&, Document* doc, HTMLFormElement* form, bool)
-{
- return new HTMLImageElement(imgTag, doc, form);
-}
-
-static PassRefPtr<HTMLElement> mapConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLMapElement(mapTag, doc);
-}
-
-static PassRefPtr<HTMLElement> areaConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLAreaElement(areaTag, doc);
-}
-
-static PassRefPtr<HTMLElement> canvasConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLCanvasElement(canvasTag, doc);
-}
-
-static PassRefPtr<HTMLElement> appletConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLAppletElement(appletTag, doc);
-}
-
-static PassRefPtr<HTMLElement> embedConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLEmbedElement(embedTag, doc);
-}
-
-static PassRefPtr<HTMLElement> objectConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool createdByParser)
-{
- return new HTMLObjectElement(objectTag, doc, createdByParser);
-}
-
-static PassRefPtr<HTMLElement> paramConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLParamElement(paramTag, doc);
-}
-
-static PassRefPtr<HTMLElement> scriptConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool createdByParser)
-{
- return new HTMLScriptElement(scriptTag, doc, createdByParser);
-}
-
-static PassRefPtr<HTMLElement> tableConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTableElement(tableTag, doc);
-}
-
-static PassRefPtr<HTMLElement> tableCaptionConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTableCaptionElement(captionTag, doc);
-}
-
-static PassRefPtr<HTMLElement> tableColConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTableColElement(tagName, doc);
-}
-
-static PassRefPtr<HTMLElement> tableRowConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTableRowElement(trTag, doc);
-}
-
-static PassRefPtr<HTMLElement> tableCellConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTableCellElement(tagName, doc);
-}
-
-static PassRefPtr<HTMLElement> tableSectionConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLTableSectionElement(tagName, doc);
-}
-
-static PassRefPtr<HTMLElement> brConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLBRElement(brTag, doc);
-}
-
-static PassRefPtr<HTMLElement> quoteConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- doc->setUsesBeforeAfterRules(true);
- return new HTMLQuoteElement(qTag, doc);
-}
-
-static PassRefPtr<HTMLElement> marqueeConstructor(const QualifiedName&, Document* doc, HTMLFormElement*, bool)
-{
- return new HTMLMarqueeElement(marqueeTag, doc);
-}
-
-#if ENABLE(VIDEO)
-static PassRefPtr<HTMLElement> audioConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- if (!MediaPlayer::isAvailable())
- return new HTMLElement(tagName, doc);
- return new HTMLAudioElement(audioTag, doc);
-}
-
-static PassRefPtr<HTMLElement> videoConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- if (!MediaPlayer::isAvailable())
- return new HTMLElement(tagName, doc);
- return new HTMLVideoElement(videoTag, doc);
-}
-
-static PassRefPtr<HTMLElement> sourceConstructor(const QualifiedName& tagName, Document* doc, HTMLFormElement*, bool)
-{
- if (!MediaPlayer::isAvailable())
- return new HTMLElement(tagName, doc);
- return new HTMLSourceElement(sourceTag, doc);
-}
-#endif
-
-static void addTag(const QualifiedName& tag, ConstructorFunc func)
-{
- gFunctionMap->set(tag.localName().impl(), func);
-}
-
-static void createFunctionMap()
-{
- // Create the table.
- gFunctionMap = new FunctionMap;
-
- // Populate it with constructor functions.
- addTag(aTag, anchorConstructor);
- addTag(appletTag, appletConstructor);
- addTag(areaTag, areaConstructor);
- addTag(baseTag, baseConstructor);
- addTag(basefontTag, basefontConstructor);
- addTag(blockquoteTag, blockquoteConstructor);
- addTag(bodyTag, bodyConstructor);
- addTag(brTag, brConstructor);
- addTag(buttonTag, buttonConstructor);
- addTag(canvasTag, canvasConstructor);
- addTag(captionTag, tableCaptionConstructor);
- addTag(colTag, tableColConstructor);
- addTag(colgroupTag, tableColConstructor);
- addTag(delTag, modConstructor);
- addTag(dirTag, dirConstructor);
- addTag(divTag, divConstructor);
- addTag(dlTag, dlConstructor);
- addTag(embedTag, embedConstructor);
- addTag(fieldsetTag, fieldsetConstructor);
- addTag(fontTag, fontConstructor);
- addTag(formTag, formConstructor);
- addTag(frameTag, frameConstructor);
- addTag(framesetTag, framesetConstructor);
- addTag(h1Tag, headingConstructor);
- addTag(h2Tag, headingConstructor);
- addTag(h3Tag, headingConstructor);
- addTag(h4Tag, headingConstructor);
- addTag(h5Tag, headingConstructor);
- addTag(h6Tag, headingConstructor);
- addTag(headTag, headConstructor);
- addTag(hrTag, hrConstructor);
- addTag(htmlTag, htmlConstructor);
- addTag(iframeTag, iframeConstructor);
- addTag(imageTag, imageConstructor);
- addTag(imgTag, imageConstructor);
- addTag(inputTag, inputConstructor);
- addTag(insTag, modConstructor);
- addTag(isindexTag, isindexConstructor);
- addTag(keygenTag, keygenConstructor);
- addTag(labelTag, labelConstructor);
- addTag(legendTag, legendConstructor);
- addTag(liTag, liConstructor);
- addTag(linkTag, linkConstructor);
- addTag(listingTag, preConstructor);
- addTag(mapTag, mapConstructor);
- addTag(marqueeTag, marqueeConstructor);
- addTag(menuTag, menuConstructor);
- addTag(metaTag, metaConstructor);
- addTag(objectTag, objectConstructor);
- addTag(olTag, olConstructor);
- addTag(optgroupTag, optgroupConstructor);
- addTag(optionTag, optionConstructor);
- addTag(pTag, paragraphConstructor);
- addTag(paramTag, paramConstructor);
- addTag(preTag, preConstructor);
- addTag(qTag, quoteConstructor);
- addTag(scriptTag, scriptConstructor);
- addTag(selectTag, selectConstructor);
- addTag(styleTag, styleConstructor);
- addTag(tableTag, tableConstructor);
- addTag(tbodyTag, tableSectionConstructor);
- addTag(tdTag, tableCellConstructor);
- addTag(textareaTag, textareaConstructor);
- addTag(tfootTag, tableSectionConstructor);
- addTag(thTag, tableCellConstructor);
- addTag(theadTag, tableSectionConstructor);
- addTag(titleTag, titleConstructor);
- addTag(trTag, tableRowConstructor);
- addTag(ulTag, ulConstructor);
- addTag(xmpTag, preConstructor);
-#if ENABLE(VIDEO)
- addTag(audioTag, audioConstructor);
- addTag(sourceTag, sourceConstructor);
- addTag(videoTag, videoConstructor);
-#endif
-}
-
-PassRefPtr<HTMLElement> HTMLElementFactory::createHTMLElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* form, bool createdByParser)
-{
- if (!doc)
- return 0; // Don't allow elements to ever be made without having a doc.
-
- if (!gFunctionMap)
- createFunctionMap();
-
- ConstructorFunc func = gFunctionMap->get(tagName.localName().impl());
- if (func)
- return func(tagName, doc, form, createdByParser);
-
- // elements with no special representation in the DOM
- return new HTMLElement(tagName, doc);
-}
-
-}
-
diff --git a/WebCore/html/HTMLElementFactory.h b/WebCore/html/HTMLElementFactory.h
deleted file mode 100644
index 539d070..0000000
--- a/WebCore/html/HTMLElementFactory.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file is part of the HTML DOM implementation for KDE.
- *
- * Copyright (C) 2005, 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef HTMLElementFactory_h
-#define HTMLElementFactory_h
-
-#include <wtf/Forward.h>
-
-namespace WebCore {
-
-class AtomicString;
-class Document;
-class Element;
-class HTMLElement;
-class HTMLFormElement;
-class QualifiedName;
-
-// The idea behind this class is that there will eventually be a mapping from namespace URIs to ElementFactories that can dispense elements.
-// In a compound document world, the generic createElement function (will end up being virtual) will be called.
-class HTMLElementFactory {
-public:
- PassRefPtr<Element> createElement(const QualifiedName&, Document*, bool createdByParser = true);
- static PassRefPtr<HTMLElement> createHTMLElement(const QualifiedName& tagName, Document*, HTMLFormElement* = 0, bool createdByParser = true);
-};
-
-}
-
-#endif
diff --git a/WebCore/html/HTMLEmbedElement.cpp b/WebCore/html/HTMLEmbedElement.cpp
index 1af7147..f467849 100644
--- a/WebCore/html/HTMLEmbedElement.cpp
+++ b/WebCore/html/HTMLEmbedElement.cpp
@@ -137,7 +137,7 @@ bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style)
return false;
}
- return true;
+ return HTMLPlugInElement::rendererIsNeeded(style);
}
RenderObject* HTMLEmbedElement::createRenderer(RenderArena* arena, RenderStyle*)
@@ -164,7 +164,7 @@ void HTMLEmbedElement::attach()
m_imageLoader->updateFromElement();
if (renderer())
- static_cast<RenderImage*>(renderer())->setCachedImage(m_imageLoader->image());
+ toRenderImage(renderer())->setCachedImage(m_imageLoader->image());
}
}
diff --git a/WebCore/html/HTMLFormControlElement.cpp b/WebCore/html/HTMLFormControlElement.cpp
index 0295f39..5238ad5 100644
--- a/WebCore/html/HTMLFormControlElement.cpp
+++ b/WebCore/html/HTMLFormControlElement.cpp
@@ -34,6 +34,7 @@
#include "HTMLNames.h"
#include "HTMLParser.h"
#include "HTMLTokenizer.h"
+#include "RenderBox.h"
#include "RenderTheme.h"
namespace WebCore {
@@ -98,8 +99,12 @@ void HTMLFormControlElement::attach()
// Focus the element if it should honour its autofocus attribute.
// We have to determine if the element is a TextArea/Input/Button/Select,
// if input type hidden ignore autofocus. So if disabled or readonly.
+ bool isInputTypeHidden = false;
+ if (hasTagName(inputTag))
+ isInputTypeHidden = static_cast<HTMLInputElement*>(this)->isInputTypeHidden();
+
if (autofocus() && renderer() && !document()->ignoreAutofocus() && !isReadOnlyControl() &&
- ((hasTagName(inputTag) && !isInputTypeHidden()) || hasTagName(selectTag) ||
+ ((hasTagName(inputTag) && !isInputTypeHidden) || hasTagName(selectTag) ||
hasTagName(buttonTag) || hasTagName(textareaTag)))
focus();
}
diff --git a/WebCore/html/HTMLFormControlElement.h b/WebCore/html/HTMLFormControlElement.h
index 0d1b31a..7430df7 100644
--- a/WebCore/html/HTMLFormControlElement.h
+++ b/WebCore/html/HTMLFormControlElement.h
@@ -45,7 +45,7 @@ public:
virtual const AtomicString& type() const = 0;
- virtual bool isControl() const { return true; }
+ virtual bool isTextControl() const { return false; }
virtual bool isEnabled() const { return !disabled(); }
virtual void parseMappedAttribute(MappedAttribute*);
diff --git a/WebCore/html/HTMLFormElement.cpp b/WebCore/html/HTMLFormElement.cpp
index afc9c1e..df4e541 100644
--- a/WebCore/html/HTMLFormElement.cpp
+++ b/WebCore/html/HTMLFormElement.cpp
@@ -44,6 +44,7 @@
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "RenderTextControl.h"
+#include <wtf/CurrentTime.h>
#include <wtf/RandomNumber.h>
#include <limits>
@@ -61,6 +62,14 @@ namespace WebCore {
using namespace HTMLNames;
+static int64_t generateFormDataIdentifier()
+{
+ // Initialize to the current time to reduce the likelihood of generating
+ // identifiers that overlap with those from past/future browser sessions.
+ static int64_t nextIdentifier = static_cast<int64_t>(currentTime() * 1000000.0);
+ return ++nextIdentifier;
+}
+
HTMLFormElement::HTMLFormElement(const QualifiedName& tagName, Document* doc)
: HTMLElement(tagName, doc)
, m_elementAliases(0)
@@ -116,7 +125,7 @@ void HTMLFormElement::removedFromDocument()
void HTMLFormElement::handleLocalEvents(Event* event, bool useCapture)
{
- EventTargetNode* targetNode = event->target()->toNode();
+ Node* targetNode = event->target()->toNode();
if (!useCapture && targetNode && targetNode != this && (event->type() == eventNames().submitEvent || event->type() == eventNames().resetEvent)) {
event->stopPropagation();
return;
@@ -202,7 +211,8 @@ PassRefPtr<FormData> HTMLFormElement::createFormData(const CString& boundary)
if (!path.isEmpty()) {
if (Page* page = document()->page()) {
String generatedFileName;
- if (shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName))
+ shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
+ if (shouldGenerateFile)
fileName = generatedFileName;
}
}
@@ -240,6 +250,8 @@ PassRefPtr<FormData> HTMLFormElement::createFormData(const CString& boundary)
m_formDataBuilder.addBoundaryToMultiPartHeader(encodedData, boundary, true);
result->appendData(encodedData.data(), encodedData.size());
+
+ result->setIdentifier(generateFormDataIdentifier());
return result;
}
@@ -625,9 +637,11 @@ void HTMLFormElement::CheckedRadioButtons::removeButton(HTMLFormControlElement*
if (it == m_nameToCheckedRadioButtonMap->end() || it->second != element)
return;
+ InputElement* inputElement = toInputElement(element);
+ ASSERT_UNUSED(inputElement, inputElement);
+ ASSERT(inputElement->isChecked());
ASSERT(element->isRadioButton());
- ASSERT(element->isChecked());
-
+
m_nameToCheckedRadioButtonMap->remove(it);
if (m_nameToCheckedRadioButtonMap->isEmpty())
m_nameToCheckedRadioButtonMap.clear();
diff --git a/WebCore/html/HTMLImageElement.cpp b/WebCore/html/HTMLImageElement.cpp
index 599cbee..c4e7608 100644
--- a/WebCore/html/HTMLImageElement.cpp
+++ b/WebCore/html/HTMLImageElement.cpp
@@ -80,7 +80,7 @@ void HTMLImageElement::parseMappedAttribute(MappedAttribute* attr)
const QualifiedName& attrName = attr->name();
if (attrName == altAttr) {
if (renderer() && renderer()->isImage())
- static_cast<RenderImage*>(renderer())->updateAltText();
+ toRenderImage(renderer())->updateAltText();
} else if (attrName == srcAttr)
m_imageLoader.updateFromElementIgnoringPreviousError();
else if (attrName == widthAttr)
@@ -166,7 +166,7 @@ void HTMLImageElement::attach()
HTMLElement::attach();
if (renderer() && renderer()->isImage()) {
- RenderImage* imageObj = static_cast<RenderImage*>(renderer());
+ RenderImage* imageObj = toRenderImage(renderer());
if (imageObj->hasImage())
return;
imageObj->setCachedImage(m_imageLoader.image());
diff --git a/WebCore/html/HTMLImageLoader.cpp b/WebCore/html/HTMLImageLoader.cpp
index 22e3abc..5dac8bf 100644
--- a/WebCore/html/HTMLImageLoader.cpp
+++ b/WebCore/html/HTMLImageLoader.cpp
@@ -42,10 +42,7 @@ HTMLImageLoader::~HTMLImageLoader()
void HTMLImageLoader::dispatchLoadEvent()
{
- if (!haveFiredLoadEvent() && image()) {
- setHaveFiredLoadEvent(true);
- element()->dispatchEventForType(image()->errorOccurred() ? eventNames().errorEvent : eventNames().loadEvent, false, false);
- }
+ element()->dispatchEventForType(image()->errorOccurred() ? eventNames().errorEvent : eventNames().loadEvent, false, false);
}
String HTMLImageLoader::sourceURI(const AtomicString& attr) const
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index c451680..103b740 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -53,9 +53,6 @@
#include "RenderTextControlSingleLine.h"
#include "RenderTheme.h"
#include "TextEvent.h"
-#if USE(LOW_BANDWIDTH_DISPLAY)
-#include "FrameLoader.h"
-#endif
#ifdef ANDROID_ACCEPT_CHANGES_TO_FOCUSED_TEXTFIELDS
#include "WebViewCore.h"
#endif
@@ -447,7 +444,7 @@ int HTMLInputElement::selectionStart() const
return m_data.cachedSelectionStart();
if (!renderer())
return 0;
- return static_cast<RenderTextControl*>(renderer())->selectionStart();
+ return toRenderTextControl(renderer())->selectionStart();
}
int HTMLInputElement::selectionEnd() const
@@ -458,7 +455,7 @@ int HTMLInputElement::selectionEnd() const
return m_data.cachedSelectionEnd();
if (!renderer())
return 0;
- return static_cast<RenderTextControl*>(renderer())->selectionEnd();
+ return toRenderTextControl(renderer())->selectionEnd();
}
void HTMLInputElement::setSelectionStart(int start)
@@ -467,7 +464,7 @@ void HTMLInputElement::setSelectionStart(int start)
return;
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->setSelectionStart(start);
+ toRenderTextControl(renderer())->setSelectionStart(start);
}
void HTMLInputElement::setSelectionEnd(int end)
@@ -476,7 +473,7 @@ void HTMLInputElement::setSelectionEnd(int end)
return;
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->setSelectionEnd(end);
+ toRenderTextControl(renderer())->setSelectionEnd(end);
}
void HTMLInputElement::select()
@@ -485,7 +482,7 @@ void HTMLInputElement::select()
return;
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->select();
+ toRenderTextControl(renderer())->select();
}
void HTMLInputElement::setSelectionRange(int start, int end)
@@ -578,7 +575,7 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
InputElement::parseSizeAttribute(m_data, attr);
else if (attr->name() == altAttr) {
if (renderer() && inputType() == IMAGE)
- static_cast<RenderImage*>(renderer())->updateAltText();
+ toRenderImage(renderer())->updateAltText();
} else if (attr->name() == srcAttr) {
if (renderer() && inputType() == IMAGE) {
if (!m_imageLoader)
@@ -644,13 +641,6 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
bool HTMLInputElement::rendererIsNeeded(RenderStyle *style)
{
-#if USE(LOW_BANDWIDTH_DISPLAY)
- if (document()->inLowBandwidthDisplay()) {
- document()->frame()->loader()->needToSwitchOutLowBandwidthDisplay();
- return false;
- }
-#endif
-
switch (inputType()) {
case BUTTON:
case CHECKBOX:
@@ -715,7 +705,7 @@ void HTMLInputElement::attach()
m_imageLoader.set(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
if (renderer()) {
- RenderImage* imageObj = static_cast<RenderImage*>(renderer());
+ RenderImage* imageObj = toRenderImage(renderer());
imageObj->setCachedImage(m_imageLoader->image());
// If we have no image at all because we have no src attribute, set
@@ -956,17 +946,17 @@ void HTMLInputElement::setValue(const String& value)
if (inputType() == FILE && !value.isEmpty())
return;
- if (isTextField())
- InputElement::updatePlaceholderVisibility(m_data, document());
-
setValueMatchesRenderer(false);
if (storesValueSeparateFromAttribute()) {
if (inputType() == FILE)
m_fileList->clear();
else {
m_data.setValue(constrainValue(value));
- if (isTextField() && inDocument())
- document()->updateRendering();
+ if (isTextField()) {
+ InputElement::updatePlaceholderVisibility(m_data, document());
+ if (inDocument())
+ document()->updateRendering();
+ }
}
if (renderer())
renderer()->updateFromElement();
@@ -1113,6 +1103,9 @@ void HTMLInputElement::postDispatchEventHandler(Event *evt, void* data)
void HTMLInputElement::defaultEventHandler(Event* evt)
{
+ // FIXME: It would be better to refactor this for the different types of input element.
+ // Having them all in one giant function makes this hard to read, and almost all the handling is type-specific.
+
bool clickDefaultFormButton = false;
if (isTextField() && evt->type() == eventNames().textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
@@ -1128,26 +1121,36 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
m_yPos = 0;
} else {
// FIXME: This doesn't work correctly with transforms.
+ // FIXME: pageX/pageY need adjusting for pageZoomFactor(). Use actualPageLocation()?
IntPoint absOffset = roundedIntPoint(renderer()->localToAbsolute());
m_xPos = me->pageX() - absOffset.x();
m_yPos = me->pageY() - absOffset.y();
}
}
- if (isTextField() && evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
- && document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
+ if (isTextField()
+ && evt->type() == eventNames().keydownEvent
+ && evt->isKeyboardEvent()
+ && focused()
+ && document()->frame()
+ && document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
evt->setDefaultHandled();
return;
}
- if (inputType() == RADIO && evt->isMouseEvent()
- && evt->type() == eventNames().clickEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
+ if (inputType() == RADIO
+ && evt->isMouseEvent()
+ && evt->type() == eventNames().clickEvent
+ && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
evt->setDefaultHandled();
return;
}
- // Let the key handling done in EventTargetNode take precedence over the event handling here for editable text fields
- if (!clickDefaultFormButton) {
+ // Call the base event handler before any of our own event handling for almost all events in text fields.
+ // Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
+ bool callBaseClassEarly = isTextField() && !clickDefaultFormButton
+ && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
+ if (callBaseClassEarly) {
HTMLFormControlElementWithState::defaultEventHandler(evt);
if (evt->defaultHandled())
return;
@@ -1246,7 +1249,8 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
case SUBMIT:
case RADIO:
setActive(true, true);
- // No setDefaultHandled() - IE dispatches a keypress in this case.
+ // No setDefaultHandled(), because IE dispatches a keypress in this case
+ // and the caller will only dispatch a keypress if we don't call setDefaultHandled.
return;
default:
break;
@@ -1337,12 +1341,12 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
}
// Fire onChange for text fields.
RenderObject* r = renderer();
- if (r && r->isTextField() && r->isEdited()) {
+ if (r && r->isTextField() && toRenderTextControl(r)->isEdited()) {
onChange();
// Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it.
r = renderer();
- if (r)
- r->setEdited(false);
+ if (r && r->isTextField())
+ toRenderTextControl(r)->setEdited(false);
}
// Form may never have been present, or may have been destroyed by the change event.
if (form())
@@ -1357,20 +1361,11 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
if (isTextField() && renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == eventNames().blurEvent || evt->type() == eventNames().focusEvent))
static_cast<RenderTextControlSingleLine*>(renderer())->forwardEvent(evt);
- if (inputType() == RANGE && renderer()) {
- RenderSlider* slider = static_cast<RenderSlider*>(renderer());
- if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
- MouseEvent* mEvt = static_cast<MouseEvent*>(evt);
- if (!slider->mouseEventIsInThumb(mEvt)) {
- IntPoint eventOffset(mEvt->offsetX(), mEvt->offsetY());
- if (mEvt->target() != this) // Does this ever happen now? Was added for <video> controls
- eventOffset = roundedIntPoint(renderer()->absoluteToLocal(FloatPoint(mEvt->pageX(), mEvt->pageY()), false, true));
- slider->setValueForPosition(slider->positionForOffset(eventOffset));
- }
- }
- if (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent())
- slider->forwardEvent(evt);
- }
+ if (inputType() == RANGE && renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent()))
+ static_cast<RenderSlider*>(renderer())->forwardEvent(evt);
+
+ if (!callBaseClassEarly && !evt->defaultHandled())
+ HTMLFormControlElementWithState::defaultEventHandler(evt);
}
bool HTMLInputElement::isURLAttribute(Attribute *attr) const
@@ -1453,6 +1448,16 @@ void HTMLInputElement::setMaxLength(int _maxLength)
setAttribute(maxlengthAttr, String::number(_maxLength));
}
+bool HTMLInputElement::multiple() const
+{
+ return !getAttribute(multipleAttr).isNull();
+}
+
+void HTMLInputElement::setMultiple(bool multiple)
+{
+ setAttribute(multipleAttr, multiple ? "" : 0);
+}
+
void HTMLInputElement::setSize(unsigned _size)
{
setAttribute(sizeAttr, String::number(_size));
@@ -1537,11 +1542,11 @@ void HTMLInputElement::onSearch()
dispatchEventForType(eventNames().searchEvent, true, false);
}
-Selection HTMLInputElement::selection() const
+VisibleSelection HTMLInputElement::selection() const
{
if (!renderer() || !isTextField() || m_data.cachedSelectionStart() == -1 || m_data.cachedSelectionEnd() == -1)
- return Selection();
- return static_cast<RenderTextControl*>(renderer())->selection(m_data.cachedSelectionStart(), m_data.cachedSelectionEnd());
+ return VisibleSelection();
+ return toRenderTextControl(renderer())->selection(m_data.cachedSelectionStart(), m_data.cachedSelectionEnd());
}
void HTMLInputElement::documentDidBecomeActive()
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index fd7ce03..5b6a5d6 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -33,7 +33,7 @@ namespace WebCore {
class FileList;
class HTMLImageLoader;
class KURL;
-class Selection;
+class VisibleSelection;
class HTMLInputElement : public HTMLFormControlElementWithState, public InputElement {
public:
@@ -188,10 +188,13 @@ public:
int maxLength() const;
void setMaxLength(int);
+ bool multiple() const;
+ void setMultiple(bool);
+
String useMap() const;
void setUseMap(const String&);
- bool isAutofilled() const { return m_autofilled; }
+ virtual bool isAutofilled() const { return m_autofilled; }
void setAutofilled(bool value = true);
FileList* files();
@@ -200,7 +203,7 @@ public:
void addSearchResult();
void onSearch();
- Selection selection() const;
+ VisibleSelection selection() const;
virtual String constrainValue(const String& proposedValue) const;
diff --git a/WebCore/html/HTMLInputElement.idl b/WebCore/html/HTMLInputElement.idl
index a9b6d2c..0734e6a 100644
--- a/WebCore/html/HTMLInputElement.idl
+++ b/WebCore/html/HTMLInputElement.idl
@@ -21,7 +21,6 @@
module html {
interface [
- CustomGetOwnPropertySlot,
GenerateConstructor,
InterfaceUUID=8f388ea3-1c31-4cca-8edd-449d14e222e1,
ImplementationUUID=aeb56b87-a90e-4d9d-a4d5-7eec3687c338
@@ -37,6 +36,7 @@ module html {
attribute boolean disabled;
attribute boolean autofocus;
attribute long maxLength;
+ attribute boolean multiple;
attribute [ConvertNullToNullString] DOMString name;
attribute boolean readOnly;
#if defined(LANGUAGE_OBJECTIVE_C)
@@ -58,9 +58,9 @@ module html {
// WinIE & FireFox extension:
- attribute [CustomGetter] long selectionStart;
- attribute [CustomGetter] long selectionEnd;
- void setSelectionRange(in long start, in long end);
+ attribute [Custom] long selectionStart;
+ attribute [Custom] long selectionEnd;
+ [Custom] void setSelectionRange(in long start, in long end);
#if defined(LANGUAGE_OBJECTIVE_C)
// Objective-C extension:
diff --git a/WebCore/html/HTMLLegendElement.cpp b/WebCore/html/HTMLLegendElement.cpp
index 9f7e645..4092643 100644
--- a/WebCore/html/HTMLLegendElement.cpp
+++ b/WebCore/html/HTMLLegendElement.cpp
@@ -26,7 +26,6 @@
#include "HTMLLegendElement.h"
#include "HTMLNames.h"
-#include "RenderLegend.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -48,14 +47,6 @@ bool HTMLLegendElement::isFocusable() const
return HTMLElement::isFocusable();
}
-RenderObject* HTMLLegendElement::createRenderer(RenderArena* arena, RenderStyle* style)
-{
- if (style->contentData())
- return RenderObject::createObject(this, style);
-
- return new (arena) RenderLegend(this);
-}
-
const AtomicString& HTMLLegendElement::type() const
{
DEFINE_STATIC_LOCAL(const AtomicString, legend, ("legend"));
diff --git a/WebCore/html/HTMLLegendElement.h b/WebCore/html/HTMLLegendElement.h
index b2ee51a..6d01dce 100644
--- a/WebCore/html/HTMLLegendElement.h
+++ b/WebCore/html/HTMLLegendElement.h
@@ -34,7 +34,6 @@ public:
virtual ~HTMLLegendElement();
virtual bool isFocusable() const;
- virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual const AtomicString& type() const;
virtual void accessKeyAction(bool sendToAnyElement);
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index 8d9cabb..df0ed04 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,12 +28,15 @@
#if ENABLE(VIDEO)
#include "HTMLMediaElement.h"
+#include "ContentType.h"
#include "CSSHelper.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "Event.h"
#include "EventNames.h"
#include "ExceptionCode.h"
+#include "Frame.h"
+#include "FrameLoader.h"
#include "HTMLDocument.h"
#include "HTMLNames.h"
#include "HTMLSourceElement.h"
@@ -45,10 +48,18 @@
#include "MIMETypeRegistry.h"
#include "MediaPlayer.h"
#include "Page.h"
+#include "ProgressEvent.h"
#include "RenderVideo.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "RenderPartObject.h"
+#endif
#include "TimeRanges.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "Widget.h"
+#endif
#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
+#include <limits>
using namespace std;
@@ -61,27 +72,37 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
, m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
+ , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
+ , m_playbackRate(1.0f)
, m_defaultPlaybackRate(1.0f)
- , m_networkState(EMPTY)
- , m_readyState(DATA_UNAVAILABLE)
- , m_begun(false)
- , m_loadedFirstFrame(false)
- , m_autoplaying(true)
- , m_currentLoop(0)
+ , m_networkState(NETWORK_EMPTY)
+ , m_readyState(HAVE_NOTHING)
, m_volume(1.0f)
- , m_muted(false)
- , m_paused(true)
- , m_seeking(false)
, m_currentTimeDuringSeek(0)
, m_previousProgress(0)
, m_previousProgressTime(numeric_limits<double>::max())
+ , m_lastTimeUpdateEventWallTime(0)
+ , m_lastTimeUpdateEventMovieTime(numeric_limits<float>::max())
+ , m_loadState(WaitingForSource)
+ , m_currentSourceNode(0)
+ , m_player(0)
+ , m_restrictions(NoRestrictions)
+ , m_processingMediaPlayerCallback(0)
+ , m_processingLoad(false)
+ , m_delayingTheLoadEvent(false)
+ , m_haveFiredLoadedData(false)
+ , m_inActiveDocument(true)
+ , m_autoplaying(true)
+ , m_muted(false)
+ , m_paused(true)
+ , m_seeking(false)
, m_sentStalledEvent(false)
- , m_bufferingRate(0)
- , m_loadNestingLevel(0)
- , m_terminateLoadBelowNestingLevel(0)
+ , m_sentEndEvent(false)
, m_pausedInternal(false)
- , m_inActiveDocument(true)
- , m_player(0)
+ , m_sendProgressEvents(true)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ , m_needWidgetUpdate(false)
+#endif
{
document()->registerForDocumentActivationCallbacks(this);
document()->registerForMediaVolumeCallbacks(this);
@@ -104,11 +125,12 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
const QualifiedName& attrName = attr->name();
if (attrName == srcAttr) {
- // 3.14.9.2.
- // change to src attribute triggers load()
- if (inDocument() && m_networkState == EMPTY)
+ // don't have a src or any <source> children, trigger load
+ if (inDocument() && m_loadState == WaitingForSource)
scheduleLoad();
- } if (attrName == controlsAttr) {
+ }
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (attrName == controlsAttr) {
if (!isVideo() && attached() && (controls() != (renderer() != 0))) {
detach();
attach();
@@ -116,16 +138,30 @@ void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
if (renderer())
renderer()->updateFromElement();
}
+#endif
}
bool HTMLMediaElement::rendererIsNeeded(RenderStyle* style)
{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ UNUSED_PARAM(style);
+ Frame* frame = document()->frame();
+ if (!frame)
+ return false;
+
+ return true;
+#else
return controls() ? HTMLElement::rendererIsNeeded(style) : false;
+#endif
}
RenderObject* HTMLMediaElement::createRenderer(RenderArena* arena, RenderStyle*)
{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ return new (arena) RenderPartObject(this);
+#else
return new (arena) RenderMedia(this);
+#endif
}
void HTMLMediaElement::insertedIntoDocument()
@@ -137,10 +173,8 @@ void HTMLMediaElement::insertedIntoDocument()
void HTMLMediaElement::removedFromDocument()
{
- // FIXME: pause() may invoke load() which seem like a strange thing to do as a side effect
- // of removing an element. This might need to be fixed in the spec.
- ExceptionCode ec;
- pause(ec);
+ if (m_networkState > NETWORK_EMPTY)
+ pause();
HTMLElement::removedFromDocument();
}
@@ -148,6 +182,10 @@ void HTMLMediaElement::attach()
{
ASSERT(!attached());
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ m_needWidgetUpdate = true;
+#endif
+
HTMLElement::attach();
if (renderer())
@@ -167,36 +205,53 @@ void HTMLMediaElement::scheduleLoad()
m_loadTimer.startOneShot(0);
}
-void HTMLMediaElement::initAndDispatchProgressEvent(const AtomicString& eventName)
+void HTMLMediaElement::scheduleProgressEvent(const AtomicString& eventName)
{
+ if (!m_sendProgressEvents)
+ return;
+
+ // FIXME: don't schedule timeupdate or progress events unless there are registered listeners
+
bool totalKnown = m_player && m_player->totalBytesKnown();
unsigned loaded = m_player ? m_player->bytesLoaded() : 0;
unsigned total = m_player ? m_player->totalBytes() : 0;
- dispatchProgressEvent(eventName, totalKnown, loaded, total);
+
+ RefPtr<ProgressEvent> evt = ProgressEvent::create(eventName, totalKnown, loaded, total);
+ enqueueEvent(evt);
+
if (renderer())
renderer()->updateFromElement();
}
-void HTMLMediaElement::dispatchEventAsync(const AtomicString& eventName)
+void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
+{
+ enqueueEvent(Event::create(eventName, false, true));
+}
+
+void HTMLMediaElement::enqueueEvent(RefPtr<Event> event)
{
- m_asyncEventsToDispatch.append(eventName);
+ m_pendingEvents.append(event);
if (!m_asyncEventTimer.isActive())
m_asyncEventTimer.startOneShot(0);
}
-void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
+void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
{
- ExceptionCode ec;
- load(ec);
+ Vector<RefPtr<Event> > pendingEvents;
+ ExceptionCode ec = 0;
+
+ m_pendingEvents.swap(pendingEvents);
+ unsigned count = pendingEvents.size();
+ for (unsigned ndx = 0; ndx < count; ++ndx)
+ dispatchEvent(pendingEvents[ndx].release(), ec);
}
-void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
+void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
{
- Vector<AtomicString> asyncEventsToDispatch;
- m_asyncEventsToDispatch.swap(asyncEventsToDispatch);
- unsigned count = asyncEventsToDispatch.size();
- for (unsigned n = 0; n < count; ++n)
- dispatchEventForType(asyncEventsToDispatch[n], false, true);
+ if (m_loadState == LoadingFromSourceElement)
+ loadNextSourceChild();
+ else
+ loadInternal();
}
static String serializeTimeOffset(float time)
@@ -260,252 +315,420 @@ HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
return m_networkState;
}
-float HTMLMediaElement::bufferingRate()
+String HTMLMediaElement::canPlayType(const String& mimeType) const
{
- if (!m_player)
- return 0;
- return m_bufferingRate;
- //return m_player->dataRate();
+ MediaPlayer::SupportsType support = MediaPlayer::supportsType(ContentType(mimeType));
+ String canPlay;
+
+ // 4.8.10.3
+ switch (support)
+ {
+ case MediaPlayer::IsNotSupported:
+ canPlay = "no";
+ break;
+ case MediaPlayer::MayBeSupported:
+ canPlay = "maybe";
+ break;
+ case MediaPlayer::IsSupported:
+ canPlay = "probably";
+ break;
+ }
+
+ return canPlay;
}
void HTMLMediaElement::load(ExceptionCode& ec)
{
- String mediaSrc;
-
- // 3.14.9.4. Loading the media resource
- // 1
- // if an event generated during load() ends up re-entering load(), terminate previous instances
- m_loadNestingLevel++;
- m_terminateLoadBelowNestingLevel = m_loadNestingLevel;
-
- m_progressEventTimer.stop();
- m_sentStalledEvent = false;
- m_bufferingRate = 0;
+ if (m_restrictions & RequireUserGestureForLoadRestriction && !processingUserGesture())
+ ec = INVALID_STATE_ERR;
+ else
+ loadInternal();
+}
+
+void HTMLMediaElement::loadInternal()
+{
+ // 1 - If the load() method for this element is already being invoked, then abort these steps.
+ if (m_processingLoad)
+ return;
+ m_processingLoad = true;
+ stopPeriodicTimers();
m_loadTimer.stop();
+ m_sentStalledEvent = false;
+ m_haveFiredLoadedData = false;
+
+ // 2 - Abort any already-running instance of the resource selection algorithm for this element.
+ m_currentSourceNode = 0;
+
+ // 3 - If there are any tasks from the media element's media element event task source in
+ // one of the task queues, then remove those tasks.
+ m_pendingEvents.clear();
- // 2
- if (m_begun) {
- m_begun = false;
+ // 4 - If the media element's networkState is set to NETWORK_LOADING or NETWORK_IDLE, set the
+ // error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORTED,
+ // and fire a progress event called abort at the media element.
+ if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE) {
m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
- initAndDispatchProgressEvent(eventNames().abortEvent);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- goto end;
+
+ // fire synchronous 'abort'
+ bool totalKnown = m_player && m_player->totalBytesKnown();
+ unsigned loaded = m_player ? m_player->bytesLoaded() : 0;
+ unsigned total = m_player ? m_player->totalBytes() : 0;
+ dispatchProgressEvent(eventNames().abortEvent, totalKnown, loaded, total);
}
- // 3
+ // 5
m_error = 0;
- m_loadedFirstFrame = false;
m_autoplaying = true;
+
+ // 6
+ setPlaybackRate(defaultPlaybackRate());
- // 4
- setPlaybackRate(defaultPlaybackRate(), ec);
-
- // 5
- if (networkState() != EMPTY) {
- m_networkState = EMPTY;
- m_readyState = DATA_UNAVAILABLE;
+ // 7
+ if (m_networkState != NETWORK_EMPTY) {
+ m_networkState = NETWORK_EMPTY;
+ m_readyState = HAVE_NOTHING;
m_paused = true;
m_seeking = false;
if (m_player) {
m_player->pause();
m_player->seek(0);
}
- m_currentLoop = 0;
dispatchEventForType(eventNames().emptiedEvent, false, true);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- goto end;
}
- // 6
- mediaSrc = pickMedia();
+ selectMediaResource();
+ m_processingLoad = false;
+}
+
+void HTMLMediaElement::selectMediaResource()
+{
+ // 1 - If the media element has neither a src attribute nor any source element children, run these substeps
+ String mediaSrc = getAttribute(srcAttr);
+ if (!mediaSrc && !havePotentialSourceChild()) {
+ m_loadState = WaitingForSource;
+
+ // 1 - Set the networkState to NETWORK_NO_SOURCE
+ m_networkState = NETWORK_NO_SOURCE;
+
+ // 2 - While the media element has neither a src attribute nor any source element children,
+ // wait. (This steps might wait forever.)
+
+ m_delayingTheLoadEvent = false;
+ return;
+ }
+
+ // 2
+ m_delayingTheLoadEvent = true;
+
+ // 3
+ m_networkState = NETWORK_LOADING;
+
+ // 4
+ scheduleProgressEvent(eventNames().loadstartEvent);
+
+ // 5 - If the media element has a src attribute, then run these substeps
+ ContentType contentType("");
+ if (!mediaSrc.isEmpty()) {
+ mediaSrc = document()->completeURL(mediaSrc).string();
+ m_loadState = LoadingFromSrcAttr;
+ loadResource(mediaSrc, contentType);
+ return;
+ }
+
+ // Otherwise, the source elements will be used
+ m_currentSourceNode = 0;
+ loadNextSourceChild();
+}
+
+void HTMLMediaElement::loadNextSourceChild()
+{
+ ContentType contentType("");
+ String mediaSrc;
+
+ mediaSrc = nextSourceChild(&contentType);
if (mediaSrc.isEmpty()) {
- ec = INVALID_STATE_ERR;
- goto end;
+ noneSupported();
+ return;
}
-
- // 7
- m_networkState = LOADING;
-
- // 8
- m_currentSrc = mediaSrc;
-
- // 9
- m_begun = true;
- dispatchProgressEvent(eventNames().loadstartEvent, false, 0, 0);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- goto end;
-
- // 10, 11, 12, 13
+
+ m_loadState = LoadingFromSourceElement;
+ loadResource(mediaSrc, contentType);
+}
+
+void HTMLMediaElement::loadResource(String url, ContentType& contentType)
+{
+ // The resource fetch algorithm
+
+ m_networkState = NETWORK_LOADING;
+
+ m_currentSrc = url;
+
+ if (m_sendProgressEvents)
+ startProgressEventTimer();
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
m_player.clear();
m_player.set(new MediaPlayer(this));
+#else
+ if (!m_player)
+ m_player.set(new MediaPlayer(this));
+#endif
+
updateVolume();
- m_player->load(m_currentSrc);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- goto end;
+
+ m_player->load(m_currentSrc, contentType);
if (renderer())
renderer()->updateFromElement();
-
- // 14
+}
+
+void HTMLMediaElement::startProgressEventTimer()
+{
+ if (m_progressEventTimer.isActive())
+ return;
+
m_previousProgressTime = WTF::currentTime();
m_previousProgress = 0;
- if (m_begun)
- // 350ms is not magic, it is in the spec!
- m_progressEventTimer.startRepeating(0.350);
-end:
- ASSERT(m_loadNestingLevel);
- m_loadNestingLevel--;
+ // 350ms is not magic, it is in the spec!
+ m_progressEventTimer.startRepeating(0.350);
+}
+
+void HTMLMediaElement::noneSupported()
+{
+ stopPeriodicTimers();
+ m_loadState = WaitingForSource;
+ m_currentSourceNode = 0;
+
+ // 3 - Reaching this step indicates that either the URL failed to resolve, or the media
+ // resource failed to load. Set the error attribute to a new MediaError object whose
+ // code attribute is set to MEDIA_ERR_NONE_SUPPORTED.
+ m_error = MediaError::create(MediaError::MEDIA_ERR_NONE_SUPPORTED);
+
+ // 4- Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
+ m_networkState = NETWORK_NO_SOURCE;
+
+ // 5 - Queue a task to fire a progress event called error at the media element.
+ scheduleProgressEvent(eventNames().errorEvent);
+
+ // 6 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ m_delayingTheLoadEvent = false;
+
+ // Abort these steps. Until the load() method is invoked, the element won't attempt to load another resource.
+
+ if (isVideo())
+ static_cast<HTMLVideoElement*>(this)->updatePosterImage();
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
+void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
+{
+ // 1 - The user agent should cancel the fetching process.
+ stopPeriodicTimers();
+ m_loadState = WaitingForSource;
+
+ // 2 - Set the error attribute to a new MediaError object whose code attribute is
+ // set to MEDIA_ERR_NETWORK/MEDIA_ERR_DECODE.
+ m_error = err;
+
+ // 3 - Queue a task to fire a progress event called error at the media element.
+ scheduleProgressEvent(eventNames().errorEvent);
+
+ // 3 - Set the element's networkState attribute to the NETWORK_EMPTY value and queue a
+ // task to fire a simple event called emptied at the element.
+ m_networkState = NETWORK_EMPTY;
+ scheduleEvent(eventNames().emptiedEvent);
+
+ // 4 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ m_delayingTheLoadEvent = false;
+
+ // 5 - Abort the overall resource selection algorithm.
+ m_currentSourceNode = 0;
+
}
void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
{
- if (!m_begun || m_networkState == EMPTY)
+ beginProcessingMediaPlayerCallback();
+ setNetworkState(m_player->networkState());
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
+{
+ if (state == MediaPlayer::Empty) {
+ // just update the cached state and leave, we can't do anything
+ m_networkState = NETWORK_EMPTY;
return;
-
- m_terminateLoadBelowNestingLevel = m_loadNestingLevel;
+ }
- MediaPlayer::NetworkState state = m_player->networkState();
-
- // 3.14.9.4. Loading the media resource
- // 14
- if (state == MediaPlayer::LoadFailed) {
- //delete m_player;
- //m_player = 0;
- // FIXME better error handling
- m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK);
- m_begun = false;
- m_progressEventTimer.stop();
- m_bufferingRate = 0;
-
- initAndDispatchProgressEvent(eventNames().errorEvent);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
+ if (state == MediaPlayer::FormatError || state == MediaPlayer::NetworkError || state == MediaPlayer::DecodeError) {
+ stopPeriodicTimers();
+
+ // If we failed while trying to load a <source> element, the movie was never parsed, and there are more
+ // <source> children, schedule the next one without reporting an error
+ if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement && havePotentialSourceChild()) {
+ scheduleLoad();
return;
-
- m_networkState = EMPTY;
-
+ }
+
+ if (state == MediaPlayer::NetworkError)
+ mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_NETWORK));
+ else if (state == MediaPlayer::DecodeError)
+ mediaEngineError(MediaError::create(MediaError::MEDIA_ERR_DECODE));
+ else if (state == MediaPlayer::FormatError)
+ noneSupported();
+
if (isVideo())
static_cast<HTMLVideoElement*>(this)->updatePosterImage();
- dispatchEventForType(eventNames().emptiedEvent, false, true);
return;
}
-
- if (state >= MediaPlayer::Loading && m_networkState < LOADING)
- m_networkState = LOADING;
-
- if (state >= MediaPlayer::LoadedMetaData && m_networkState < LOADED_METADATA) {
- m_player->seek(effectiveStart());
- m_networkState = LOADED_METADATA;
-
- dispatchEventForType(eventNames().durationchangeEvent, false, true);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- return;
-
- dispatchEventForType(eventNames().loadedmetadataEvent, false, true);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- return;
+
+ if (state == MediaPlayer::Idle && m_networkState > NETWORK_IDLE) {
+ ASSERT(static_cast<ReadyState>(m_player->readyState()) < HAVE_ENOUGH_DATA);
+ m_networkState = NETWORK_IDLE;
+ stopPeriodicTimers();
+ scheduleProgressEvent(eventNames().suspendEvent);
}
-
- if (state >= MediaPlayer::LoadedFirstFrame && m_networkState < LOADED_FIRST_FRAME) {
- m_networkState = LOADED_FIRST_FRAME;
-
- setReadyState(CAN_SHOW_CURRENT_FRAME);
-
- if (isVideo())
- static_cast<HTMLVideoElement*>(this)->updatePosterImage();
-
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- return;
-
- m_loadedFirstFrame = true;
- if (renderer()) {
- ASSERT(!renderer()->isImage());
- static_cast<RenderVideo*>(renderer())->videoSizeChanged();
- }
-
- dispatchEventForType(eventNames().loadedfirstframeEvent, false, true);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- return;
-
- dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true);
- if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
- return;
+
+ if (state == MediaPlayer::Loading && (m_networkState < NETWORK_LOADING || m_networkState == NETWORK_NO_SOURCE)) {
+ ASSERT(static_cast<ReadyState>(m_player->readyState()) < HAVE_ENOUGH_DATA);
+ m_networkState = NETWORK_LOADING;
+ startProgressEventTimer();
}
-
- // 15
- if (state == MediaPlayer::Loaded && m_networkState < LOADED) {
- m_begun = false;
- m_networkState = LOADED;
+
+ if (state == MediaPlayer::Loaded && (m_networkState < NETWORK_LOADED || m_networkState == NETWORK_NO_SOURCE)) {
+ m_networkState = NETWORK_LOADED;
m_progressEventTimer.stop();
- m_bufferingRate = 0;
- initAndDispatchProgressEvent(eventNames().loadEvent);
+
+ // Check to see if readyState changes need to be dealt with before sending the
+ // 'load' event so we report 'canplaythrough' first. This is necessary because a
+ // media engine reports readyState and networkState changes separately
+ MediaPlayer::ReadyState currentState = m_player->readyState();
+ if (static_cast<ReadyState>(currentState) != m_readyState)
+ setReadyState(currentState);
+
+ scheduleProgressEvent(eventNames().loadEvent);
}
}
void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
{
- MediaPlayer::ReadyState state = m_player->readyState();
- setReadyState((ReadyState)state);
+ beginProcessingMediaPlayerCallback();
+
+ setReadyState(m_player->readyState());
+
+ endProcessingMediaPlayerCallback();
}
-void HTMLMediaElement::setReadyState(ReadyState state)
+void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
{
- // 3.14.9.6. The ready states
- if (m_readyState == state)
+ // Set "wasPotentiallyPlaying" BEFORE updating m_readyState, potentiallyPlaying() uses it
+ bool wasPotentiallyPlaying = potentiallyPlaying();
+
+ ReadyState oldState = m_readyState;
+ m_readyState = static_cast<ReadyState>(state);
+
+ if (m_readyState == oldState)
return;
- bool wasActivelyPlaying = activelyPlaying();
- m_readyState = state;
-
- if (state >= CAN_PLAY)
+ if (m_readyState >= HAVE_CURRENT_DATA)
m_seeking = false;
- if (networkState() == EMPTY)
+ if (m_networkState == NETWORK_EMPTY)
return;
-
- if (state == DATA_UNAVAILABLE) {
- dispatchEventForType(eventNames().dataunavailableEvent, false, true);
- if (wasActivelyPlaying) {
- dispatchEventForType(eventNames().timeupdateEvent, false, true);
- dispatchEventForType(eventNames().waitingEvent, false, true);
- }
- } else if (state == CAN_SHOW_CURRENT_FRAME) {
- if (m_loadedFirstFrame)
- dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true);
- if (wasActivelyPlaying) {
- dispatchEventForType(eventNames().timeupdateEvent, false, true);
- dispatchEventForType(eventNames().waitingEvent, false, true);
+
+ if (m_seeking && m_readyState < HAVE_CURRENT_DATA) {
+ // 4.8.10.10, step 9
+ scheduleEvent(eventNames().seekingEvent);
+ m_seeking = false;
+ }
+
+ if (wasPotentiallyPlaying && m_readyState < HAVE_FUTURE_DATA) {
+ // 4.8.10.9
+ scheduleTimeupdateEvent(false);
+ scheduleEvent(eventNames().waitingEvent);
+ }
+
+ if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
+ scheduleEvent(eventNames().durationchangeEvent);
+ scheduleEvent(eventNames().loadedmetadataEvent);
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (renderer() && !renderer()->isImage()) {
+ static_cast<RenderVideo*>(renderer())->videoSizeChanged();
}
- } else if (state == CAN_PLAY) {
- dispatchEventForType(eventNames().canplayEvent, false, true);
- } else if (state == CAN_PLAY_THROUGH) {
- dispatchEventForType(eventNames().canplaythroughEvent, false, true);
+#endif
+ m_delayingTheLoadEvent = false;
+ m_player->seek(0);
+ }
+
+ // 4.8.10.7 says loadeddata is sent only when the new state *is* HAVE_CURRENT_DATA: "If the
+ // previous ready state was HAVE_METADATA and the new ready state is HAVE_CURRENT_DATA",
+ // but the event table at the end of the spec says it is sent when: "readyState newly
+ // increased to HAVE_CURRENT_DATA or greater for the first time"
+ // We go with the later because it seems useful to count on getting this event
+ if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) {
+ m_haveFiredLoadedData = true;
+ scheduleEvent(eventNames().loadeddataEvent);
+ }
+
+ bool isPotentiallyPlaying = potentiallyPlaying();
+ if (m_readyState <= HAVE_CURRENT_DATA && oldState >= HAVE_FUTURE_DATA) {
+ if (isPotentiallyPlaying)
+ scheduleEvent(eventNames().waitingEvent);
+ }
+
+ if (m_readyState == HAVE_FUTURE_DATA && oldState <= HAVE_CURRENT_DATA) {
+ scheduleEvent(eventNames().canplayEvent);
+ if (isPotentiallyPlaying)
+ scheduleEvent(eventNames().playingEvent);
+
+ if (isVideo())
+ static_cast<HTMLVideoElement*>(this)->updatePosterImage();
+ }
+
+ if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA) {
+ if (oldState <= HAVE_CURRENT_DATA)
+ scheduleEvent(eventNames().canplayEvent);
+
+ scheduleEvent(eventNames().canplaythroughEvent);
+
+ if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
+ scheduleEvent(eventNames().playingEvent);
+
if (m_autoplaying && m_paused && autoplay()) {
m_paused = false;
- dispatchEventForType(eventNames().playEvent, false, true);
+ scheduleEvent(eventNames().playEvent);
+ scheduleEvent(eventNames().playingEvent);
}
+
+ if (isVideo())
+ static_cast<HTMLVideoElement*>(this)->updatePosterImage();
}
+
updatePlayState();
}
void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
{
ASSERT(m_player);
+ if (m_networkState == NETWORK_EMPTY || m_networkState >= NETWORK_LOADED)
+ return;
+
unsigned progress = m_player->bytesLoaded();
double time = WTF::currentTime();
double timedelta = time - m_previousProgressTime;
- if (timedelta)
- m_bufferingRate = (float)(0.8 * m_bufferingRate + 0.2 * ((float)(progress - m_previousProgress)) / timedelta);
-
+
if (progress == m_previousProgress) {
if (timedelta > 3.0 && !m_sentStalledEvent) {
- m_bufferingRate = 0;
- initAndDispatchProgressEvent(eventNames().stalledEvent);
+ scheduleProgressEvent(eventNames().stalledEvent);
m_sentStalledEvent = true;
}
} else {
- initAndDispatchProgressEvent(eventNames().progressEvent);
+ scheduleProgressEvent(eventNames().progressEvent);
m_previousProgress = progress;
m_previousProgressTime = time;
m_sentStalledEvent = false;
@@ -514,52 +737,45 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
void HTMLMediaElement::seek(float time, ExceptionCode& ec)
{
- // 3.14.9.8. Seeking
+ // 4.8.10.10. Seeking
// 1
- if (networkState() < LOADED_METADATA) {
+ if (m_readyState == HAVE_NOTHING || !m_player) {
ec = INVALID_STATE_ERR;
return;
}
-
+
// 2
- float minTime;
- if (currentLoop() == 0)
- minTime = effectiveStart();
- else
- minTime = effectiveLoopStart();
-
+ time = min(time, duration());
+
// 3
- float maxTime = currentLoop() == playCount() - 1 ? effectiveEnd() : effectiveLoopEnd();
-
+ time = max(time, 0.0f);
+
// 4
- time = min(time, maxTime);
-
- // 5
- time = max(time, minTime);
-
- // 6
RefPtr<TimeRanges> seekableRanges = seekable();
if (!seekableRanges->contain(time)) {
ec = INDEX_SIZE_ERR;
return;
}
- // 7
+ // avoid generating events when the time won't actually change
+ float now = currentTime();
+ if (time == now)
+ return;
+
+ // 5
m_currentTimeDuringSeek = time;
- // 8
+ // 6 - set the seeking flag, it will be cleared when the engine tells is the time has actually changed
m_seeking = true;
-
- // 9
- dispatchEventForType(eventNames().timeupdateEvent, false, true);
-
+
+ // 7
+ scheduleTimeupdateEvent(false);
+
+ // 8 - this is covered, if necessary, when the engine signals a readystate change
+
// 10
- // As soon as the user agent has established whether or not the media data for the new playback position is available,
- // and, if it is, decoded enough data to play back that position, the seeking DOM attribute must be set to false.
- if (m_player) {
- m_player->setEndTime(maxTime);
- m_player->seek(time);
- }
+ m_player->seek(time);
+ m_sentEndEvent = false;
}
HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
@@ -589,7 +805,10 @@ void HTMLMediaElement::setCurrentTime(float time, ExceptionCode& ec)
float HTMLMediaElement::duration() const
{
- return m_player ? m_player->duration() : 0;
+ if (m_readyState >= HAVE_METADATA)
+ return m_player->duration();
+
+ return numeric_limits<float>::quiet_NaN();
}
bool HTMLMediaElement::paused() const
@@ -602,15 +821,11 @@ float HTMLMediaElement::defaultPlaybackRate() const
return m_defaultPlaybackRate;
}
-void HTMLMediaElement::setDefaultPlaybackRate(float rate, ExceptionCode& ec)
+void HTMLMediaElement::setDefaultPlaybackRate(float rate)
{
- if (rate == 0.0f) {
- ec = NOT_SUPPORTED_ERR;
- return;
- }
if (m_defaultPlaybackRate != rate) {
m_defaultPlaybackRate = rate;
- dispatchEventAsync(eventNames().ratechangeEvent);
+ scheduleEvent(eventNames().ratechangeEvent);
}
}
@@ -619,16 +834,14 @@ float HTMLMediaElement::playbackRate() const
return m_player ? m_player->rate() : 0;
}
-void HTMLMediaElement::setPlaybackRate(float rate, ExceptionCode& ec)
+void HTMLMediaElement::setPlaybackRate(float rate)
{
- if (rate == 0.0f) {
- ec = NOT_SUPPORTED_ERR;
- return;
+ if (m_playbackRate != rate) {
+ m_playbackRate = rate;
+ scheduleEvent(eventNames().ratechangeEvent);
}
- if (m_player && m_player->rate() != rate) {
+ if (m_player && potentiallyPlaying() && m_player->rate() != rate)
m_player->setRate(rate);
- dispatchEventAsync(eventNames().ratechangeEvent);
- }
}
bool HTMLMediaElement::ended() const
@@ -646,126 +859,85 @@ void HTMLMediaElement::setAutoplay(bool b)
setBooleanAttribute(autoplayAttr, b);
}
-void HTMLMediaElement::play(ExceptionCode& ec)
+void HTMLMediaElement::play()
{
- // 3.14.9.7. Playing the media resource
- if (!m_player || networkState() == EMPTY) {
- ec = 0;
- load(ec);
- if (ec)
- return;
- }
- ExceptionCode unused;
- if (endedPlayback()) {
- m_currentLoop = 0;
- seek(effectiveStart(), unused);
- }
- setPlaybackRate(defaultPlaybackRate(), unused);
-
- if (m_paused) {
- m_paused = false;
- dispatchEventAsync(eventNames().playEvent);
- }
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
+ return;
- m_autoplaying = false;
-
- updatePlayState();
+ playInternal();
}
-void HTMLMediaElement::pause(ExceptionCode& ec)
+void HTMLMediaElement::playInternal()
{
- // 3.14.9.7. Playing the media resource
- if (!m_player || networkState() == EMPTY) {
- ec = 0;
- load(ec);
- if (ec)
- return;
- }
+ // 4.8.10.9. Playing the media resource
+ if (!m_player || m_networkState == NETWORK_EMPTY)
+ scheduleLoad();
- if (!m_paused) {
- m_paused = true;
- dispatchEventAsync(eventNames().timeupdateEvent);
- dispatchEventAsync(eventNames().pauseEvent);
+ if (endedPlayback()) {
+ ExceptionCode unused;
+ seek(0, unused);
}
+
+ setPlaybackRate(defaultPlaybackRate());
+
+ if (m_paused) {
+ m_paused = false;
+ scheduleEvent(eventNames().playEvent);
+ if (m_readyState <= HAVE_CURRENT_DATA)
+ scheduleEvent(eventNames().waitingEvent);
+ else if (m_readyState >= HAVE_FUTURE_DATA)
+ scheduleEvent(eventNames().playingEvent);
+ }
m_autoplaying = false;
-
- updatePlayState();
-}
-unsigned HTMLMediaElement::playCount() const
-{
- bool ok;
- unsigned count = getAttribute(playcountAttr).string().toUInt(&ok);
- return (count > 0 && ok) ? count : 1;
+ updatePlayState();
}
-void HTMLMediaElement::setPlayCount(unsigned count, ExceptionCode& ec)
+void HTMLMediaElement::pause()
{
- if (!count) {
- ec = INDEX_SIZE_ERR;
+ if (m_restrictions & RequireUserGestureForRateChangeRestriction && !processingUserGesture())
return;
- }
- setAttribute(playcountAttr, String::number(count));
- checkIfSeekNeeded();
-}
-float HTMLMediaElement::start() const
-{
- return getTimeOffsetAttribute(startAttr, 0);
+ pauseInternal();
}
-void HTMLMediaElement::setStart(float time)
-{
- setTimeOffsetAttribute(startAttr, time);
- checkIfSeekNeeded();
-}
-float HTMLMediaElement::end() const
-{
- return getTimeOffsetAttribute(endAttr, std::numeric_limits<float>::infinity());
-}
-
-void HTMLMediaElement::setEnd(float time)
-{
- setTimeOffsetAttribute(endAttr, time);
- checkIfSeekNeeded();
-}
-
-float HTMLMediaElement::loopStart() const
-{
- return getTimeOffsetAttribute(loopstartAttr, start());
-}
-
-void HTMLMediaElement::setLoopStart(float time)
+void HTMLMediaElement::pauseInternal()
{
- setTimeOffsetAttribute(loopstartAttr, time);
- checkIfSeekNeeded();
-}
+ // 4.8.10.9. Playing the media resource
+ if (!m_player || m_networkState == NETWORK_EMPTY)
+ scheduleLoad();
-float HTMLMediaElement::loopEnd() const
-{
- return getTimeOffsetAttribute(loopendAttr, end());
-}
+ m_autoplaying = false;
+
+ if (!m_paused) {
+ m_paused = true;
+ scheduleTimeupdateEvent(false);
+ scheduleEvent(eventNames().pauseEvent);
+ }
-void HTMLMediaElement::setLoopEnd(float time)
-{
- setTimeOffsetAttribute(loopendAttr, time);
- checkIfSeekNeeded();
+ updatePlayState();
}
-unsigned HTMLMediaElement::currentLoop() const
+bool HTMLMediaElement::loop() const
{
- return m_currentLoop;
+ return hasAttribute(loopAttr);
}
-void HTMLMediaElement::setCurrentLoop(unsigned currentLoop)
+void HTMLMediaElement::setLoop(bool b)
{
- m_currentLoop = currentLoop;
+ setBooleanAttribute(loopAttr, b);
}
bool HTMLMediaElement::controls() const
{
+ Frame* frame = document()->frame();
+
+ // always show controls when scripting is disabled
+ if (frame && !frame->script()->isEnabled())
+ return true;
+
return hasAttribute(controlsAttr);
}
@@ -789,7 +961,7 @@ void HTMLMediaElement::setVolume(float vol, ExceptionCode& ec)
if (m_volume != vol) {
m_volume = vol;
updateVolume();
- dispatchEventAsync(eventNames().volumechangeEvent);
+ scheduleEvent(eventNames().volumechangeEvent);
}
}
@@ -803,110 +975,224 @@ void HTMLMediaElement::setMuted(bool muted)
if (m_muted != muted) {
m_muted = muted;
updateVolume();
- dispatchEventAsync(eventNames().volumechangeEvent);
+ scheduleEvent(eventNames().volumechangeEvent);
}
}
-bool HTMLMediaElement::canPlay() const
+void HTMLMediaElement::togglePlayState()
{
- return paused() || ended() || networkState() < LOADED_METADATA;
+ // We can safely call the internal play/pause methods, which don't check restrictions, because
+ // this method is only called from the built-in media controller
+ if (canPlay())
+ playInternal();
+ else
+ pauseInternal();
}
-String HTMLMediaElement::pickMedia()
+void HTMLMediaElement::beginScrubbing()
{
- // 3.14.9.2. Location of the media resource
- String mediaSrc = getAttribute(srcAttr);
- if (mediaSrc.isEmpty()) {
- for (Node* n = firstChild(); n; n = n->nextSibling()) {
- if (n->hasTagName(sourceTag)) {
- HTMLSourceElement* source = static_cast<HTMLSourceElement*>(n);
- if (!source->hasAttribute(srcAttr))
- continue;
- if (source->hasAttribute(mediaAttr)) {
- MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
- RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
- if (!screenEval.eval(media.get()))
- continue;
- }
- if (source->hasAttribute(typeAttr)) {
- String type = source->type().stripWhiteSpace();
-
- // "type" can have parameters after a semi-colon, strip them before checking with the type registry
- int semi = type.find(';');
- if (semi != -1)
- type = type.left(semi).stripWhiteSpace();
-
- if (!MIMETypeRegistry::isSupportedMediaMIMEType(type))
- continue;
- }
- mediaSrc = source->src().string();
- break;
- }
+ if (!paused()) {
+ if (ended()) {
+ // Because a media element stays in non-paused state when it reaches end, playback resumes
+ // when the slider is dragged from the end to another position unless we pause first. Do
+ // a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes.
+ pause();
+ } else {
+ // Not at the end but we still want to pause playback so the media engine doesn't try to
+ // continue playing during scrubbing. Pause without generating an event as we will
+ // unpause after scrubbing finishes.
+ setPausedInternal(true);
}
}
- if (!mediaSrc.isEmpty())
- mediaSrc = document()->completeURL(mediaSrc).string();
- return mediaSrc;
}
-void HTMLMediaElement::checkIfSeekNeeded()
+void HTMLMediaElement::endScrubbing()
{
- // 3.14.9.5. Offsets into the media resource
- // 1
- if (playCount() <= m_currentLoop)
- m_currentLoop = playCount() - 1;
-
- // 2
- if (networkState() <= LOADING)
+ if (m_pausedInternal)
+ setPausedInternal(false);
+}
+
+// The spec says to fire periodic timeupdate events (those sent while playing) every
+// "15 to 250ms", we choose the slowest frequency
+static const double maxTimeupdateEventFrequency = 0.25;
+
+void HTMLMediaElement::startPlaybackProgressTimer()
+{
+ if (m_playbackProgressTimer.isActive())
+ return;
+
+ m_previousProgressTime = WTF::currentTime();
+ m_previousProgress = 0;
+ m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
+}
+
+void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
+{
+ ASSERT(m_player);
+ if (!m_playbackRate)
return;
+
+ scheduleTimeupdateEvent(true);
- // 3
- ExceptionCode ec;
- float time = currentTime();
- if (!m_currentLoop && time < effectiveStart())
- seek(effectiveStart(), ec);
+ // FIXME: deal with cue ranges here
+}
- // 4
- if (m_currentLoop && time < effectiveLoopStart())
- seek(effectiveLoopStart(), ec);
+void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
+{
+ double now = WTF::currentTime();
+ double timedelta = now - m_lastTimeUpdateEventWallTime;
+
+ // throttle the periodic events
+ if (periodicEvent && timedelta < maxTimeupdateEventFrequency)
+ return;
+
+ // Some media engines make multiple "time changed" callbacks at the same time, but we only want one
+ // event at a given time so filter here
+ float movieTime = m_player ? m_player->currentTime() : 0;
+ if (movieTime != m_lastTimeUpdateEventMovieTime) {
+ scheduleEvent(eventNames().timeupdateEvent);
+ m_lastTimeUpdateEventWallTime = now;
+ m_lastTimeUpdateEventMovieTime = movieTime;
+ }
+}
+
+bool HTMLMediaElement::canPlay() const
+{
+ return paused() || ended() || m_readyState < HAVE_METADATA;
+}
+
+bool HTMLMediaElement::havePotentialSourceChild()
+{
+ // Stash the current <source> node so we can restore it after checking
+ // to see there is another potential
+ Node* currentSourceNode = m_currentSourceNode;
+ String nextUrl = nextSourceChild();
+ m_currentSourceNode = currentSourceNode;
+
+ return !nextUrl.isEmpty();
+}
+
+String HTMLMediaElement::nextSourceChild(ContentType *contentType)
+{
+ String mediaSrc;
+ bool lookingForPreviousNode = m_currentSourceNode;
+
+ for (Node* node = firstChild(); node; node = node->nextSibling()) {
+ if (!node->hasTagName(sourceTag))
+ continue;
+
+ if (lookingForPreviousNode) {
+ if (m_currentSourceNode == node)
+ lookingForPreviousNode = false;
+ continue;
+ }
- // 5
- if (m_currentLoop < playCount() - 1 && time > effectiveLoopEnd()) {
- seek(effectiveLoopStart(), ec);
- m_currentLoop++;
+ HTMLSourceElement* source = static_cast<HTMLSourceElement*>(node);
+ if (!source->hasAttribute(srcAttr))
+ continue;
+ if (source->hasAttribute(mediaAttr)) {
+ MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
+ if (!screenEval.eval(media.get()))
+ continue;
+ }
+ if (source->hasAttribute(typeAttr)) {
+ ContentType type(source->type());
+ if (!MediaPlayer::supportsType(type))
+ continue;
+
+ // return type with all parameters in place so the media engine can use them
+ if (contentType)
+ *contentType = type;
+ }
+ mediaSrc = source->src().string();
+ m_currentSourceNode = node;
+ break;
}
-
- // 6
- if (m_currentLoop == playCount() - 1 && time > effectiveEnd())
- seek(effectiveEnd(), ec);
- updatePlayState();
+ if (!mediaSrc.isEmpty())
+ mediaSrc = document()->completeURL(mediaSrc).string();
+
+ return mediaSrc;
}
void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
{
- if (readyState() >= CAN_PLAY)
+ beginProcessingMediaPlayerCallback();
+
+ if (m_readyState >= HAVE_CURRENT_DATA && m_seeking) {
+ scheduleEvent(eventNames().seekedEvent);
m_seeking = false;
-
- if (m_currentLoop < playCount() - 1 && currentTime() >= effectiveLoopEnd()) {
- ExceptionCode ec;
- seek(effectiveLoopStart(), ec);
- m_currentLoop++;
- dispatchEventForType(eventNames().timeupdateEvent, false, true);
}
- if (m_currentLoop == playCount() - 1 && currentTime() >= effectiveEnd()) {
- dispatchEventForType(eventNames().timeupdateEvent, false, true);
- dispatchEventForType(eventNames().endedEvent, false, true);
+ float now = currentTime();
+ float dur = duration();
+ if (now >= dur) {
+ if (loop()) {
+ ExceptionCode ignoredException;
+ m_sentEndEvent = false;
+ seek(0, ignoredException);
+ } else {
+ if (!m_sentEndEvent) {
+ m_sentEndEvent = true;
+ scheduleTimeupdateEvent(false);
+ scheduleEvent(eventNames().endedEvent);
+ }
+ }
}
+ else
+ m_sentEndEvent = false;
updatePlayState();
+ endProcessingMediaPlayerCallback();
}
void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
{
+ beginProcessingMediaPlayerCallback();
if (renderer())
renderer()->repaint();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerVolumeChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ updateVolume();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerDurationChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ scheduleEvent(eventNames().durationchangeEvent);
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (renderer()) {
+ renderer()->updateFromElement();
+ if (!renderer()->isImage())
+ static_cast<RenderVideo*>(renderer())->videoSizeChanged();
+ }
+#endif
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerRateChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+ // Stash the rate in case the one we tried to set isn't what the engine is
+ // using (eg. it can't handle the rate we set)
+ m_playbackRate = m_player->rate();
+ endProcessingMediaPlayerCallback();
+}
+
+void HTMLMediaElement::mediaPlayerSizeChanged(MediaPlayer*)
+{
+ beginProcessingMediaPlayerCallback();
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ if (renderer() && !renderer()->isImage())
+ static_cast<RenderVideo*>(renderer())->videoSizeChanged();
+#endif
+ endProcessingMediaPlayerCallback();
}
PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
@@ -931,53 +1217,45 @@ PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
return TimeRanges::create(0, m_player->maxTimeSeekable());
}
-float HTMLMediaElement::effectiveStart() const
+bool HTMLMediaElement::potentiallyPlaying() const
{
- if (!m_player)
- return 0;
- return min(start(), m_player->duration());
+ return !paused() && m_readyState >= HAVE_FUTURE_DATA && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction();
}
-float HTMLMediaElement::effectiveEnd() const
-{
- if (!m_player)
- return 0;
- return min(max(end(), max(start(), loopStart())), m_player->duration());
-}
-
-float HTMLMediaElement::effectiveLoopStart() const
+bool HTMLMediaElement::endedPlayback() const
{
- if (!m_player)
- return 0;
- return min(loopStart(), m_player->duration());
+ return m_player && m_readyState >= HAVE_METADATA && currentTime() >= duration() && !loop();
}
-float HTMLMediaElement::effectiveLoopEnd() const
+bool HTMLMediaElement::stoppedDueToErrors() const
{
- if (!m_player)
- return 0;
- return min(max(start(), max(loopStart(), loopEnd())), m_player->duration());
+ if (m_readyState >= HAVE_METADATA && m_error) {
+ RefPtr<TimeRanges> seekableRanges = seekable();
+ if (!seekableRanges->contain(currentTime()))
+ return true;
+ }
+
+ return false;
}
-bool HTMLMediaElement::activelyPlaying() const
+bool HTMLMediaElement::pausedForUserInteraction() const
{
- return !paused() && readyState() >= CAN_PLAY && !endedPlayback(); // && !stoppedDueToErrors() && !pausedForUserInteraction();
+// return !paused() && m_readyState >= HAVE_FUTURE_DATA && [UA requires a decitions from the user]
+ return false;
}
-bool HTMLMediaElement::endedPlayback() const
-{
- return networkState() >= LOADED_METADATA && currentTime() >= effectiveEnd() && currentLoop() == playCount() - 1;
-}
-
void HTMLMediaElement::updateVolume()
{
if (!m_player)
return;
- Page* page = document()->page();
- float volumeMultiplier = page ? page->mediaVolume() : 1;
-
- m_player->setVolume(m_muted ? 0 : m_volume * volumeMultiplier);
+ // Avoid recursion when the player reports volume changes.
+ if (!processingMediaPlayerCallback()) {
+ Page* page = document()->page();
+ float volumeMultiplier = page ? page->mediaVolume() : 1;
+
+ m_player->setVolume(m_muted ? 0 : m_volume * volumeMultiplier);
+ }
if (renderer())
renderer()->updateFromElement();
@@ -987,20 +1265,26 @@ void HTMLMediaElement::updatePlayState()
{
if (!m_player)
return;
-
+
if (m_pausedInternal) {
if (!m_player->paused())
m_player->pause();
+ m_playbackProgressTimer.stop();
return;
}
- m_player->setEndTime(currentLoop() == playCount() - 1 ? effectiveEnd() : effectiveLoopEnd());
-
- bool shouldBePlaying = activelyPlaying() && currentTime() < effectiveEnd();
- if (shouldBePlaying && m_player->paused())
+ bool shouldBePlaying = potentiallyPlaying();
+ bool playerPaused = m_player->paused();
+ if (shouldBePlaying && playerPaused) {
+ // 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();
- else if (!shouldBePlaying && !m_player->paused())
+ startPlaybackProgressTimer();
+ } else if (!shouldBePlaying && !playerPaused) {
m_player->pause();
+ m_playbackProgressTimer.stop();
+ }
if (renderer())
renderer()->updateFromElement();
@@ -1012,25 +1296,50 @@ void HTMLMediaElement::setPausedInternal(bool b)
updatePlayState();
}
-void HTMLMediaElement::documentWillBecomeInactive()
+void HTMLMediaElement::stopPeriodicTimers()
+{
+ m_progressEventTimer.stop();
+ m_playbackProgressTimer.stop();
+}
+
+void HTMLMediaElement::userCancelledLoad()
{
- // 3.14.9.4. Loading the media resource
- // 14
- if (m_begun) {
- // For simplicity cancel the incomplete load by deleting the player
+ if (m_networkState != NETWORK_EMPTY) {
+
+ // If the media data fetching process is aborted by the user:
+
+ // 1 - The user agent should cancel the fetching process.
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
m_player.clear();
- m_progressEventTimer.stop();
+#endif
+ stopPeriodicTimers();
+ // 2 - Set the error attribute to a new MediaError object whose code attribute is set to MEDIA_ERR_ABORT.
m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
- m_begun = false;
- initAndDispatchProgressEvent(eventNames().abortEvent);
- if (m_networkState >= LOADING) {
- m_networkState = EMPTY;
- m_readyState = DATA_UNAVAILABLE;
- dispatchEventForType(eventNames().emptiedEvent, false, true);
+
+ // 3 - Queue a task to fire a progress event called abort at the media element.
+ scheduleProgressEvent(eventNames().abortEvent);
+
+ // 4 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the
+ // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a
+ // simple event called emptied at the element. Otherwise, set set the element's networkState
+ // attribute to the NETWORK_IDLE value.
+ if (m_networkState >= NETWORK_LOADING) {
+ m_networkState = NETWORK_EMPTY;
+ m_readyState = HAVE_NOTHING;
+ scheduleEvent(eventNames().emptiedEvent);
}
+
+ // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ m_delayingTheLoadEvent = false;
}
+}
+
+void HTMLMediaElement::documentWillBecomeInactive()
+{
m_inActiveDocument = false;
+ userCancelledLoad();
+
// Stop the playback without generating events
setPausedInternal(true);
@@ -1045,6 +1354,8 @@ void HTMLMediaElement::documentDidBecomeActive()
if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED) {
// Restart the load if it was aborted in the middle by moving the document to the page cache.
+ // m_error is only left at MEDIA_ERR_ABORTED when the document becomes inactive (it is set to
+ // MEDIA_ERR_ABORTED while the abortEvent is being sent, but cleared immediately afterwards).
// This behavior is not specified but it seems like a sensible thing to do.
ExceptionCode ec;
load(ec);
@@ -1061,13 +1372,78 @@ void HTMLMediaElement::mediaVolumeDidChange()
void HTMLMediaElement::defaultEventHandler(Event* event)
{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ RenderObject* r = renderer();
+ if (!r || !r->isWidget())
+ return;
+
+ Widget* widget = static_cast<RenderWidget*>(r)->widget();
+ if (widget)
+ widget->handleEvent(event);
+#else
if (renderer() && renderer()->isMedia())
static_cast<RenderMedia*>(renderer())->forwardEvent(event);
if (event->defaultHandled())
return;
HTMLElement::defaultEventHandler(event);
+#endif
}
+bool HTMLMediaElement::processingUserGesture() const
+{
+ Frame* frame = document()->frame();
+ FrameLoader* loader = frame ? frame->loader() : 0;
+
+ // return 'true' for safety if we don't know the answer
+ return loader ? loader->userGestureHint() : true;
+}
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+void HTMLMediaElement::deliverNotification(MediaPlayerProxyNotificationType notification)
+{
+ if (notification == MediaPlayerNotificationPlayPauseButtonPressed) {
+ ExceptionCode ec;
+ togglePlayState(ec);
+ return;
+ }
+
+ if (m_player)
+ m_player->deliverNotification(notification);
+}
+
+void HTMLMediaElement::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
+{
+ if (m_player)
+ m_player->setMediaPlayerProxy(proxy);
+}
+
+String HTMLMediaElement::initialURL()
+{
+ String initialSrc = mediaSrc = getAttribute(srcAttr);
+
+ if (initialSrc.isEmpty())
+ initialSrc = nextSourceChild();
+
+ if (!initialSrc.isEmpty())
+ initialSrc = document()->completeURL(initialSrc).string();
+
+ m_currentSrc = initialSrc;
+
+ return initialSrc;
+}
+
+void HTMLMediaElement::finishParsingChildren()
+{
+ HTMLElement::finishParsingChildren();
+ if (!m_player)
+ m_player.set(new MediaPlayer(this));
+
+ document()->updateRendering();
+ if (m_needWidgetUpdate && renderer())
+ static_cast<RenderPartObject*>(renderer())->updateWidget(true);
+}
+#endif
+
}
#endif
diff --git a/WebCore/html/HTMLMediaElement.h b/WebCore/html/HTMLMediaElement.h
index 6dd562c..ab0ab11 100644
--- a/WebCore/html/HTMLMediaElement.h
+++ b/WebCore/html/HTMLMediaElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,13 +31,17 @@
#include "HTMLElement.h"
#include "MediaPlayer.h"
#include "Timer.h"
-#include "VoidCallback.h"
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "MediaPlayerProxy.h"
+#endif
namespace WebCore {
+class Event;
class MediaError;
-class TimeRanges;
class KURL;
+class TimeRanges;
class HTMLMediaElement : public HTMLElement, public MediaPlayerClient {
public:
@@ -58,6 +62,7 @@ public:
MediaPlayer* player() const { return m_player.get(); }
virtual bool isVideo() const { return false; }
+ virtual bool hasVideo() const { return false; }
void scheduleLoad();
@@ -76,15 +81,16 @@ public:
KURL src() const;
void setSrc(const String&);
String currentSrc() const;
-
- enum NetworkState { EMPTY, LOADING, LOADED_METADATA, LOADED_FIRST_FRAME, LOADED };
+
+ enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_LOADED, NETWORK_NO_SOURCE };
NetworkState networkState() const;
- float bufferingRate();
PassRefPtr<TimeRanges> buffered() const;
void load(ExceptionCode&);
+
+ String canPlayType(const String& mimeType) const;
// ready state
- enum ReadyState { DATA_UNAVAILABLE, CAN_SHOW_CURRENT_FRAME, CAN_PLAY, CAN_PLAY_THROUGH };
+ enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
ReadyState readyState() const;
bool seeking() const;
@@ -94,31 +100,19 @@ public:
float duration() const;
bool paused() const;
float defaultPlaybackRate() const;
- void setDefaultPlaybackRate(float, ExceptionCode&);
+ void setDefaultPlaybackRate(float);
float playbackRate() const;
- void setPlaybackRate(float, ExceptionCode&);
+ void setPlaybackRate(float);
PassRefPtr<TimeRanges> played() const;
PassRefPtr<TimeRanges> seekable() const;
bool ended() const;
bool autoplay() const;
void setAutoplay(bool b);
- void play(ExceptionCode&);
- void pause(ExceptionCode&);
-
-// looping
- float start() const;
- void setStart(float time);
- float end() const;
- void setEnd(float time);
- float loopStart() const;
- void setLoopStart(float time);
- float loopEnd() const;
- void setLoopEnd(float time);
- unsigned playCount() const;
- void setPlayCount(unsigned, ExceptionCode&);
- unsigned currentLoop() const;
- void setCurrentLoop(unsigned);
-
+ bool loop() const;
+ void setLoop(bool b);
+ void play();
+ void pause();
+
// controls
bool controls() const;
void setControls(bool);
@@ -126,9 +120,20 @@ public:
void setVolume(float, ExceptionCode&);
bool muted() const;
void setMuted(bool);
+ void togglePlayState();
+ void beginScrubbing();
+ void endScrubbing();
bool canPlay() const;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
+ void deliverNotification(MediaPlayerProxyNotificationType notification);
+ void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
+ String initialURL();
+ virtual void finishParsingChildren();
+#endif
+
protected:
float getTimeOffsetAttribute(const QualifiedName&, float valueOnError) const;
void setTimeOffsetAttribute(const QualifiedName&, float value);
@@ -137,73 +142,136 @@ protected:
virtual void documentDidBecomeActive();
virtual void mediaVolumeDidChange();
- void initAndDispatchProgressEvent(const AtomicString& eventName);
- void dispatchEventAsync(const AtomicString& eventName);
-
- void setReadyState(ReadyState);
+ void setReadyState(MediaPlayer::ReadyState);
+ void setNetworkState(MediaPlayer::NetworkState);
private: // MediaPlayerObserver
virtual void mediaPlayerNetworkStateChanged(MediaPlayer*);
virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
virtual void mediaPlayerTimeChanged(MediaPlayer*);
virtual void mediaPlayerRepaint(MediaPlayer*);
+ virtual void mediaPlayerVolumeChanged(MediaPlayer*);
+ virtual void mediaPlayerDurationChanged(MediaPlayer*);
+ virtual void mediaPlayerRateChanged(MediaPlayer*);
+ virtual void mediaPlayerSizeChanged(MediaPlayer*);
private:
void loadTimerFired(Timer<HTMLMediaElement>*);
void asyncEventTimerFired(Timer<HTMLMediaElement>*);
void progressEventTimerFired(Timer<HTMLMediaElement>*);
- void seek(float time, ExceptionCode& ec);
+ void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
+ void startPlaybackProgressTimer();
+ void startProgressEventTimer();
+ void stopPeriodicTimers();
+
+ void seek(float time, ExceptionCode&);
void checkIfSeekNeeded();
- String pickMedia();
+ void scheduleTimeupdateEvent(bool periodicEvent);
+ void scheduleProgressEvent(const AtomicString& eventName);
+ void scheduleEvent(const AtomicString& eventName);
+ void enqueueEvent(RefPtr<Event> event);
+
+ // loading
+ void selectMediaResource();
+ void loadResource(String url, ContentType& contentType);
+ void loadNextSourceChild();
+ void userCancelledLoad();
+ String nextSourceChild(ContentType* contentType = 0);
+ bool havePotentialSourceChild();
+ void noneSupported();
+ void mediaEngineError(PassRefPtr<MediaError> err);
+
+ // These "internal" functions do not check user gesture restrictions.
+ void loadInternal();
+ void playInternal();
+ void pauseInternal();
+
+ bool processingUserGesture() const;
+ bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
+ void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
+ void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
+
void updateVolume();
void updatePlayState();
- float effectiveStart() const;
- float effectiveEnd() const;
- float effectiveLoopStart() const;
- float effectiveLoopEnd() const;
- bool activelyPlaying() const;
+ bool potentiallyPlaying() const;
bool endedPlayback() const;
-
+ bool stoppedDueToErrors() const;
+ bool pausedForUserInteraction() const;
+
+ // Restrictions to change default behaviors. This is a effectively a compile time choice at the moment
+ // because there are no accessor methods.
+ enum BehaviorRestrictions
+ {
+ NoRestrictions = 0,
+ RequireUserGestureForLoadRestriction = 1 << 0,
+ RequireUserGestureForRateChangeRestriction = 1 << 1,
+ };
+
protected:
Timer<HTMLMediaElement> m_loadTimer;
Timer<HTMLMediaElement> m_asyncEventTimer;
Timer<HTMLMediaElement> m_progressEventTimer;
- Vector<AtomicString> m_asyncEventsToDispatch;
+ Timer<HTMLMediaElement> m_playbackProgressTimer;
+ Vector<RefPtr<Event> > m_pendingEvents;
+ float m_playbackRate;
float m_defaultPlaybackRate;
NetworkState m_networkState;
ReadyState m_readyState;
String m_currentSrc;
RefPtr<MediaError> m_error;
-
- bool m_begun;
- bool m_loadedFirstFrame;
- bool m_autoplaying;
-
- unsigned m_currentLoop;
+
float m_volume;
- bool m_muted;
-
- bool m_paused;
- bool m_seeking;
-
float m_currentTimeDuringSeek;
unsigned m_previousProgress;
double m_previousProgressTime;
- bool m_sentStalledEvent;
-
- float m_bufferingRate;
+
+ // the last time a timeupdate event was sent (wall clock)
+ double m_lastTimeUpdateEventWallTime;
+
+ // the last time a timeupdate event was sent in movie time
+ float m_lastTimeUpdateEventMovieTime;
- unsigned m_loadNestingLevel;
- unsigned m_terminateLoadBelowNestingLevel;
+ // loading state
+ enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
+ LoadState m_loadState;
+ Node *m_currentSourceNode;
- bool m_pausedInternal;
- bool m_inActiveDocument;
-
OwnPtr<MediaPlayer> m_player;
+
+ BehaviorRestrictions m_restrictions;
+
+ // counter incremented while processing a callback from the media player, so we can avoid
+ // calling the media engine recursively
+ int m_processingMediaPlayerCallback;
+
+ bool m_processingLoad : 1;
+ bool m_delayingTheLoadEvent : 1;
+ bool m_haveFiredLoadedData : 1;
+ bool m_inActiveDocument : 1;
+ bool m_autoplaying : 1;
+ bool m_muted : 1;
+ bool m_paused : 1;
+ bool m_seeking : 1;
+
+ // data has not been loaded since sending a "stalled" event
+ bool m_sentStalledEvent : 1;
+
+ // time has not changed since sending an "ended" event
+ bool m_sentEndEvent : 1;
+
+ bool m_pausedInternal : 1;
+
+ // Not all media engines provide enough information about a file to be able to
+ // support progress events so setting m_sendProgressEvents disables them
+ bool m_sendProgressEvents : 1;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ bool m_needWidgetUpdate : 1;
+#endif
};
} //namespace
diff --git a/WebCore/html/HTMLMediaElement.idl b/WebCore/html/HTMLMediaElement.idl
index 1e3eb90..931980b 100644
--- a/WebCore/html/HTMLMediaElement.idl
+++ b/WebCore/html/HTMLMediaElement.idl
@@ -33,22 +33,24 @@ interface [GenerateConstructor, Conditional=VIDEO] HTMLMediaElement : HTMLElemen
attribute DOMString src;
readonly attribute DOMString currentSrc;
- const unsigned short EMPTY = 0;
- const unsigned short LOADING = 1;
- const unsigned short LOADED_METADATA = 2;
- const unsigned short LOADED_FIRST_FRAME = 3;
- const unsigned short LOADED = 4;
+ const unsigned short NETWORK_EMPTY = 0;
+ const unsigned short NETWORK_IDLE = 1;
+ const unsigned short NETWORK_LOADING = 2;
+ const unsigned short NETWORK_LOADED = 3;
+ const unsigned short NETWORK_NO_SOURCE = 4;
readonly attribute unsigned short networkState;
- readonly attribute float bufferingRate;
+
readonly attribute TimeRanges buffered;
void load()
raises (DOMException);
+ DOMString canPlayType(in DOMString type);
// ready state
- const unsigned short DATA_UNAVAILABLE = 0;
- const unsigned short CAN_SHOW_CURRENT_FRAME = 1;
- const unsigned short CAN_PLAY = 2;
- const unsigned short CAN_PLAY_THROUGH = 3;
+ const unsigned short HAVE_NOTHING = 0;
+ const unsigned short HAVE_METADATA = 1;
+ const unsigned short HAVE_CURRENT_DATA = 2;
+ const unsigned short HAVE_FUTURE_DATA = 3;
+ const unsigned short HAVE_ENOUGH_DATA = 4;
readonly attribute unsigned short readyState;
readonly attribute boolean seeking;
@@ -57,27 +59,15 @@ interface [GenerateConstructor, Conditional=VIDEO] HTMLMediaElement : HTMLElemen
setter raises (DOMException);
readonly attribute float duration;
readonly attribute boolean paused;
- attribute float defaultPlaybackRate
- setter raises (DOMException);
- attribute float playbackRate
- setter raises (DOMException);
+ attribute float defaultPlaybackRate;
+ attribute float playbackRate;
readonly attribute TimeRanges played;
readonly attribute TimeRanges seekable;
readonly attribute boolean ended;
attribute boolean autoplay;
- void play()
- raises (DOMException);
- void pause()
- raises (DOMException);
-
- // looping
- attribute float start;
- attribute float end;
- attribute float loopStart;
- attribute float loopEnd;
- attribute unsigned long playCount
- setter raises (DOMException);
- attribute unsigned long currentLoop;
+ attribute boolean loop;
+ void play();
+ void pause();
// controls
attribute boolean controls;
diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp
index 6f85d18..a41e037 100644
--- a/WebCore/html/HTMLObjectElement.cpp
+++ b/WebCore/html/HTMLObjectElement.cpp
@@ -119,14 +119,15 @@ void HTMLObjectElement::parseMappedAttribute(MappedAttribute *attr)
bool HTMLObjectElement::rendererIsNeeded(RenderStyle* style)
{
- if (m_useFallbackContent || isImageType())
- return HTMLPlugInElement::rendererIsNeeded(style);
-
Frame* frame = document()->frame();
if (!frame)
return false;
- return true;
+ // Temporary Workaround for Gears plugin - see bug 24215 for details and bug 24346 to track removal.
+ // Gears expects the plugin to be instantiated even if display:none is set
+ // for the object element.
+ bool isGearsPlugin = equalIgnoringCase(getAttribute(typeAttr), "application/x-googlegears");
+ return isGearsPlugin || HTMLPlugInElement::rendererIsNeeded(style);
}
RenderObject *HTMLObjectElement::createRenderer(RenderArena* arena, RenderStyle* style)
@@ -156,7 +157,7 @@ void HTMLObjectElement::attach()
return;
if (renderer())
- static_cast<RenderImage*>(renderer())->setCachedImage(m_imageLoader->image());
+ toRenderImage(renderer())->setCachedImage(m_imageLoader->image());
}
}
diff --git a/WebCore/html/HTMLOptGroupElement.cpp b/WebCore/html/HTMLOptGroupElement.cpp
index 294472b..5c79e74 100644
--- a/WebCore/html/HTMLOptGroupElement.cpp
+++ b/WebCore/html/HTMLOptGroupElement.cpp
@@ -58,40 +58,30 @@ const AtomicString& HTMLOptGroupElement::type() const
bool HTMLOptGroupElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
{
bool result = HTMLFormControlElement::insertBefore(newChild, refChild, ec, shouldLazyAttach);
- if (result)
- recalcSelectOptions();
return result;
}
bool HTMLOptGroupElement::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
{
bool result = HTMLFormControlElement::replaceChild(newChild, oldChild, ec, shouldLazyAttach);
- if (result)
- recalcSelectOptions();
return result;
}
bool HTMLOptGroupElement::removeChild(Node* oldChild, ExceptionCode& ec)
{
bool result = HTMLFormControlElement::removeChild(oldChild, ec);
- if (result)
- recalcSelectOptions();
return result;
}
bool HTMLOptGroupElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
{
bool result = HTMLFormControlElement::appendChild(newChild, ec, shouldLazyAttach);
- if (result)
- recalcSelectOptions();
return result;
}
bool HTMLOptGroupElement::removeChildren()
{
bool result = HTMLFormControlElement::removeChildren();
- if (result)
- recalcSelectOptions();
return result;
}
diff --git a/WebCore/html/HTMLOptionElement.cpp b/WebCore/html/HTMLOptionElement.cpp
index 085019f..982f578 100644
--- a/WebCore/html/HTMLOptionElement.cpp
+++ b/WebCore/html/HTMLOptionElement.cpp
@@ -225,13 +225,16 @@ bool HTMLOptionElement::disabled() const
return HTMLFormControlElement::disabled() || (parentNode() && static_cast<HTMLFormControlElement*>(parentNode())->disabled());
}
-void HTMLOptionElement::insertedIntoDocument()
+void HTMLOptionElement::insertedIntoTree(bool deep)
{
- HTMLSelectElement* select;
- if (selected() && (select = ownerSelectElement()))
+ if (HTMLSelectElement* select = ownerSelectElement()) {
+ select->setRecalcListItems();
+ if (selected())
+ select->setSelectedIndex(index(), false);
select->scrollToSelection();
+ }
- HTMLFormControlElement::insertedIntoDocument();
+ HTMLFormControlElement::insertedIntoTree(deep);
}
} // namespace
diff --git a/WebCore/html/HTMLOptionElement.h b/WebCore/html/HTMLOptionElement.h
index 39b857c..8c0f260 100644
--- a/WebCore/html/HTMLOptionElement.h
+++ b/WebCore/html/HTMLOptionElement.h
@@ -77,7 +77,7 @@ public:
virtual bool disabled() const;
- virtual void insertedIntoDocument();
+ virtual void insertedIntoTree(bool);
virtual void accessKeyAction(bool);
private:
diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp
index 0403dad..a4d4671 100644
--- a/WebCore/html/HTMLParser.cpp
+++ b/WebCore/html/HTMLParser.cpp
@@ -61,6 +61,13 @@ using namespace HTMLNames;
static const unsigned cMaxRedundantTagDepth = 20;
static const unsigned cResidualStyleMaxDepth = 200;
+static const int minBlockLevelTagPriority = 3;
+
+// A cap on the number of tags with priority minBlockLevelTagPriority or higher
+// allowed in m_blockStack. The cap is enforced by adding such new elements as
+// siblings instead of children once it is reached.
+static const size_t cMaxBlockDepth = 4096;
+
struct HTMLStackElem : Noncopyable {
HTMLStackElem(const AtomicString& t, int lvl, Node* n, bool r, HTMLStackElem* nx)
: tagName(t)
@@ -113,36 +120,38 @@ struct HTMLStackElem : Noncopyable {
*/
HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
- : document(doc)
- , current(doc)
- , didRefCurrent(false)
- , blockStack(0)
+ : m_document(doc)
+ , m_current(doc)
+ , m_didRefCurrent(false)
+ , m_blockStack(0)
+ , m_blocksInStack(0)
, m_hasPElementInScope(NotInScope)
- , head(0)
- , inBody(false)
- , haveContent(false)
- , haveFrameSet(false)
+ , m_head(0)
+ , m_inBody(false)
+ , m_haveContent(false)
+ , m_haveFrameSet(false)
, m_isParsingFragment(false)
, m_reportErrors(reportErrors)
, m_handlingResidualStyleAcrossBlocks(false)
- , inStrayTableContent(0)
+ , m_inStrayTableContent(0)
{
}
HTMLParser::HTMLParser(DocumentFragment* frag)
- : document(frag->document())
- , current(frag)
- , didRefCurrent(true)
- , blockStack(0)
+ : m_document(frag->document())
+ , m_current(frag)
+ , m_didRefCurrent(true)
+ , m_blockStack(0)
+ , m_blocksInStack(0)
, m_hasPElementInScope(NotInScope)
- , head(0)
- , inBody(true)
- , haveContent(false)
- , haveFrameSet(false)
+ , m_head(0)
+ , m_inBody(true)
+ , m_haveContent(false)
+ , m_haveFrameSet(false)
, m_isParsingFragment(true)
, m_reportErrors(false)
, m_handlingResidualStyleAcrossBlocks(false)
- , inStrayTableContent(0)
+ , m_inStrayTableContent(0)
{
if (frag)
frag->ref();
@@ -151,26 +160,26 @@ HTMLParser::HTMLParser(DocumentFragment* frag)
HTMLParser::~HTMLParser()
{
freeBlock();
- if (didRefCurrent)
- current->deref();
+ if (m_didRefCurrent)
+ m_current->deref();
}
void HTMLParser::reset()
{
ASSERT(!m_isParsingFragment);
- setCurrent(document);
+ setCurrent(m_document);
freeBlock();
- inBody = false;
- haveFrameSet = false;
- haveContent = false;
- inStrayTableContent = 0;
+ m_inBody = false;
+ m_haveFrameSet = false;
+ m_haveContent = false;
+ m_inStrayTableContent = 0;
m_currentFormElement = 0;
m_currentMapElement = 0;
- head = 0;
+ m_head = 0;
m_isindexElement = 0;
m_skipModeTag = nullAtom;
@@ -178,13 +187,13 @@ void HTMLParser::reset()
void HTMLParser::setCurrent(Node* newCurrent)
{
- bool didRefNewCurrent = newCurrent && newCurrent != document;
+ bool didRefNewCurrent = newCurrent && newCurrent != m_document;
if (didRefNewCurrent)
newCurrent->ref();
- if (didRefCurrent)
- current->deref();
- current = newCurrent;
- didRefCurrent = didRefNewCurrent;
+ if (m_didRefCurrent)
+ m_current->deref();
+ m_current = newCurrent;
+ m_didRefCurrent = didRefNewCurrent;
}
PassRefPtr<Node> HTMLParser::parseToken(Token* t)
@@ -193,7 +202,7 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
if (!t->beginTag && t->tagName == m_skipModeTag)
// Found the end tag for the current skip mode, so we're done skipping.
m_skipModeTag = nullAtom;
- else if (current->localName() == t->tagName)
+ else if (m_current->localName() == t->tagName)
// Do not skip </iframe>.
// FIXME: What does that comment mean? How can it be right to parse a token without clearing m_skipModeTag?
;
@@ -202,7 +211,7 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
}
// Apparently some sites use </br> instead of <br>. Be compatible with IE and Firefox and treat this like <br>.
- if (t->isCloseTag(brTag) && document->inCompatMode()) {
+ if (t->isCloseTag(brTag) && m_document->inCompatMode()) {
reportError(MalformedBRError);
t->beginTag = true;
}
@@ -214,17 +223,17 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
// Ignore spaces, if we're not inside a paragraph or other inline code.
// Do not alter the text if it is part of a scriptTag.
- if (t->tagName == textAtom && t->text && current->localName() != scriptTag) {
- if (inBody && !skipMode() && current->localName() != styleTag &&
- current->localName() != titleTag && !t->text->containsOnlyWhitespace())
- haveContent = true;
+ if (t->tagName == textAtom && t->text && m_current->localName() != scriptTag) {
+ if (m_inBody && !skipMode() && m_current->localName() != styleTag &&
+ m_current->localName() != titleTag && !t->text->containsOnlyWhitespace())
+ m_haveContent = true;
RefPtr<Node> n;
String text = t->text.get();
unsigned charsLeft = text.length();
while (charsLeft) {
// split large blocks of text to nodes of manageable size
- n = Text::createWithLengthLimit(document, text, charsLeft);
+ n = Text::createWithLengthLimit(m_document, text, charsLeft);
if (!insertNode(n.get(), t->selfClosingTag))
return 0;
}
@@ -269,8 +278,8 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
if (m_currentFormElement == n)
m_currentFormElement = 0;
- if (head == n)
- head = 0;
+ if (m_head == n)
+ m_head = 0;
return 0;
}
@@ -280,25 +289,25 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
void HTMLParser::parseDoctypeToken(DoctypeToken* t)
{
// Ignore any doctype after the first. Ignore doctypes in fragments.
- if (document->doctype() || m_isParsingFragment || current != document)
+ if (m_document->doctype() || m_isParsingFragment || m_current != m_document)
return;
// Make a new doctype node and set it as our doctype.
- document->addChild(DocumentType::create(document, String::adopt(t->m_name), String::adopt(t->m_publicID), String::adopt(t->m_systemID)));
+ m_document->addChild(DocumentType::create(m_document, String::adopt(t->m_name), String::adopt(t->m_publicID), String::adopt(t->m_systemID)));
}
-static bool isTableSection(Node* n)
+static bool isTableSection(const Node* n)
{
return n->hasTagName(tbodyTag) || n->hasTagName(tfootTag) || n->hasTagName(theadTag);
}
-static bool isTablePart(Node* n)
+static bool isTablePart(const Node* n)
{
return n->hasTagName(trTag) || n->hasTagName(tdTag) || n->hasTagName(thTag) ||
isTableSection(n);
}
-static bool isTableRelated(Node* n)
+static bool isTableRelated(const Node* n)
{
return n->hasTagName(tableTag) || isTablePart(n);
}
@@ -317,33 +326,38 @@ bool HTMLParser::insertNode(Node* n, bool flat)
// <table> is never allowed inside stray table content. Always pop out of the stray table content
// and close up the first table, and then start the second table as a sibling.
- if (inStrayTableContent && localName == tableTag)
+ if (m_inStrayTableContent && localName == tableTag)
popBlock(tableTag);
-
+
+ if (tagPriority >= minBlockLevelTagPriority) {
+ while (m_blocksInStack >= cMaxBlockDepth)
+ popBlock(m_blockStack->tagName);
+ }
+
// let's be stupid and just try to insert it.
// this should work if the document is well-formed
- Node* newNode = current->addChild(n);
+ Node* newNode = m_current->addChild(n);
if (!newNode)
return handleError(n, flat, localName, tagPriority); // Try to handle the error.
// don't push elements without end tags (e.g., <img>) on the stack
- bool parentAttached = current->attached();
+ bool parentAttached = m_current->attached();
if (tagPriority > 0 && !flat) {
- if (newNode == current) {
+ if (newNode == m_current) {
// This case should only be hit when a demoted <form> is placed inside a table.
ASSERT(localName == formTag);
- reportError(FormInsideTablePartError, &current->localName());
+ reportError(FormInsideTablePartError, &m_current->localName());
} else {
// The pushBlock function transfers ownership of current to the block stack
- // so we're guaranteed that didRefCurrent is false. The code below is an
+ // so we're guaranteed that m_didRefCurrent is false. The code below is an
// optimized version of setCurrent that takes advantage of that fact and also
// assumes that newNode is neither 0 nor a pointer to the document.
pushBlock(localName, tagPriority);
newNode->beginParsingChildren();
- ASSERT(!didRefCurrent);
+ ASSERT(!m_didRefCurrent);
newNode->ref();
- current = newNode;
- didRefCurrent = true;
+ m_current = newNode;
+ m_didRefCurrent = true;
}
if (parentAttached && !n->attached() && !m_isParsingFragment)
n->attach();
@@ -353,6 +367,9 @@ bool HTMLParser::insertNode(Node* n, bool flat)
n->finishParsingChildren();
}
+ if (localName == htmlTag && m_document->frame())
+ m_document->frame()->loader()->dispatchDocumentElementAvailable();
+
return true;
}
@@ -366,28 +383,28 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
if (n->isHTMLElement()) {
HTMLElement* h = static_cast<HTMLElement*>(n);
if (h->hasLocalName(trTag) || h->hasLocalName(thTag) || h->hasLocalName(tdTag)) {
- if (inStrayTableContent && !isTableRelated(current)) {
- reportError(MisplacedTablePartError, &localName, &current->localName());
+ if (m_inStrayTableContent && !isTableRelated(m_current)) {
+ reportError(MisplacedTablePartError, &localName, &m_current->localName());
// pop out to the nearest enclosing table-related tag.
- while (blockStack && !isTableRelated(current))
+ while (m_blockStack && !isTableRelated(m_current))
popOneBlock();
return insertNode(n);
}
} else if (h->hasLocalName(headTag)) {
- if (!current->isDocumentNode() && !current->hasTagName(htmlTag)) {
+ if (!m_current->isDocumentNode() && !m_current->hasTagName(htmlTag)) {
reportError(MisplacedHeadError);
return false;
}
} else if (h->hasLocalName(metaTag) || h->hasLocalName(linkTag) || h->hasLocalName(baseTag)) {
bool createdHead = false;
- if (!head) {
+ if (!m_head) {
createHead();
createdHead = true;
}
- if (head) {
+ if (m_head) {
if (!createdHead)
- reportError(MisplacedHeadContentError, &localName, &current->localName());
- if (head->addChild(n)) {
+ reportError(MisplacedHeadContentError, &localName, &m_current->localName());
+ if (m_head->addChild(n)) {
if (!n->attached() && !m_isParsingFragment)
n->attach();
return true;
@@ -395,13 +412,13 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
return false;
}
} else if (h->hasLocalName(htmlTag)) {
- if (!current->isDocumentNode() ) {
- if (document->documentElement() && document->documentElement()->hasTagName(htmlTag)) {
+ if (!m_current->isDocumentNode() ) {
+ if (m_document->documentElement() && m_document->documentElement()->hasTagName(htmlTag)) {
reportError(RedundantHTMLBodyError, &localName);
// we have another <HTML> element.... apply attributes to existing one
// make sure we don't overwrite already existing attributes
NamedAttrMap* map = static_cast<Element*>(n)->attributes(true);
- Element* existingHTML = static_cast<Element*>(document->documentElement());
+ Element* existingHTML = static_cast<Element*>(m_document->documentElement());
NamedAttrMap* bmap = existingHTML->attributes(false);
for (unsigned l = 0; map && l < map->length(); ++l) {
Attribute* it = map->attributeItem(l);
@@ -413,19 +430,19 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
}
} else if (h->hasLocalName(titleTag) || h->hasLocalName(styleTag)) {
bool createdHead = false;
- if (!head) {
+ if (!m_head) {
createHead();
createdHead = true;
}
- if (head) {
- Node* newNode = head->addChild(n);
+ if (m_head) {
+ Node* newNode = m_head->addChild(n);
if (!newNode) {
setSkipMode(h->tagQName());
return false;
}
if (!createdHead)
- reportError(MisplacedHeadContentError, &localName, &current->localName());
+ reportError(MisplacedHeadContentError, &localName, &m_current->localName());
pushBlock(localName, tagPriority);
newNode->beginParsingChildren();
@@ -434,18 +451,18 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
n->attach();
return true;
}
- if (inBody) {
+ if (m_inBody) {
setSkipMode(h->tagQName());
return false;
}
} else if (h->hasLocalName(bodyTag)) {
- if (inBody && document->body()) {
+ if (m_inBody && m_document->body()) {
// we have another <BODY> element.... apply attributes to existing one
// make sure we don't overwrite already existing attributes
// some sites use <body bgcolor=rightcolor>...<body bgcolor=wrongcolor>
reportError(RedundantHTMLBodyError, &localName);
NamedAttrMap* map = static_cast<Element*>(n)->attributes(true);
- Element* existingBody = document->body();
+ Element* existingBody = m_document->body();
NamedAttrMap* bmap = existingBody->attributes(false);
for (unsigned l = 0; map && l < map->length(); ++l) {
Attribute* it = map->attributeItem(l);
@@ -454,11 +471,11 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
}
return false;
}
- else if (!current->isDocumentNode())
+ else if (!m_current->isDocumentNode())
return false;
} else if (h->hasLocalName(areaTag)) {
if (m_currentMapElement) {
- reportError(MisplacedAreaError, &current->localName());
+ reportError(MisplacedAreaError, &m_current->localName());
m_currentMapElement->addChild(n);
if (!n->attached() && !m_isParsingFragment)
n->attach();
@@ -467,18 +484,18 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
}
return false;
} else if (h->hasLocalName(colgroupTag) || h->hasLocalName(captionTag)) {
- if (isTableRelated(current)) {
- while (blockStack && isTablePart(current))
+ if (isTableRelated(m_current)) {
+ while (m_blockStack && isTablePart(m_current))
popOneBlock();
return insertNode(n);
}
}
- } else if (n->isCommentNode() && !head)
+ } else if (n->isCommentNode() && !m_head)
return false;
// 2. Next we examine our currently active element to do some further error handling.
- if (current->isHTMLElement()) {
- HTMLElement* h = static_cast<HTMLElement*>(current);
+ if (m_current->isHTMLElement()) {
+ HTMLElement* h = static_cast<HTMLElement*>(m_current);
const AtomicString& currentTagName = h->localName();
if (h->hasLocalName(htmlTag)) {
HTMLElement* elt = n->isHTMLElement() ? static_cast<HTMLElement*>(n) : 0;
@@ -487,9 +504,9 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
elt->hasLocalName(objectTag) || elt->hasLocalName(embedTag) ||
elt->hasLocalName(titleTag) || elt->hasLocalName(isindexTag) ||
elt->hasLocalName(baseTag))) {
- if (!head) {
- head = new HTMLHeadElement(headTag, document);
- e = head;
+ if (!m_head) {
+ m_head = new HTMLHeadElement(headTag, m_document);
+ e = m_head;
insertNode(e);
handled = true;
}
@@ -499,8 +516,8 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
if (t->containsOnlyWhitespace())
return false;
}
- if (!haveFrameSet) {
- e = new HTMLBodyElement(bodyTag, document);
+ if (!m_haveFrameSet) {
+ e = new HTMLBodyElement(bodyTag, m_document);
startBody();
insertNode(e);
handled = true;
@@ -512,9 +529,9 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
return false;
else {
// This means the body starts here...
- if (!haveFrameSet) {
+ if (!m_haveFrameSet) {
popBlock(currentTagName);
- e = new HTMLBodyElement(bodyTag, document);
+ e = new HTMLBodyElement(bodyTag, m_document);
startBody();
insertNode(e);
handled = true;
@@ -542,7 +559,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
handled = true; // ...and start a new one
} else {
ExceptionCode ec = 0;
- Node* node = current;
+ Node* node = m_current;
Node* parent = node->parentNode();
// A script may have removed the current node's parent from the DOM
// http://bugs.webkit.org/show_bug.cgi?id=7137
@@ -574,24 +591,24 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
pushBlock(localName, tagPriority);
n->beginParsingChildren();
setCurrent(n);
- inStrayTableContent++;
- blockStack->strayTableContent = true;
+ m_inStrayTableContent++;
+ m_blockStack->strayTableContent = true;
}
return true;
}
}
if (!ec) {
- if (current->hasTagName(trTag)) {
+ if (m_current->hasTagName(trTag)) {
reportError(TablePartRequiredError, &localName, &tdTag.localName());
- e = new HTMLTableCellElement(tdTag, document);
- } else if (current->hasTagName(tableTag)) {
+ e = new HTMLTableCellElement(tdTag, m_document);
+ } else if (m_current->hasTagName(tableTag)) {
// Don't report an error in this case, since making a <tbody> happens all the time when you have <table><tr>,
// and it isn't really a parse error per se.
- e = new HTMLTableSectionElement(tbodyTag, document);
+ e = new HTMLTableSectionElement(tbodyTag, m_document);
} else {
reportError(TablePartRequiredError, &localName, &trTag.localName());
- e = new HTMLTableRowElement(trTag, document);
+ e = new HTMLTableRowElement(trTag, m_document);
}
insertNode(e);
@@ -625,20 +642,20 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
popBlock(currentTagName);
handled = true;
} else if (!h->hasLocalName(bodyTag)) {
- if (isInline(current)) {
+ if (isInline(m_current)) {
popInlineBlocks();
handled = true;
}
}
- } else if (current->isDocumentNode()) {
+ } else if (m_current->isDocumentNode()) {
if (n->isTextNode()) {
Text* t = static_cast<Text*>(n);
if (t->containsOnlyWhitespace())
return false;
}
- if (!document->documentElement()) {
- e = new HTMLHtmlElement(htmlTag, document);
+ if (!m_document->documentElement()) {
+ e = new HTMLHtmlElement(htmlTag, m_document);
insertNode(e);
handled = true;
}
@@ -646,7 +663,7 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
// 3. If we couldn't handle the error, just return false and attempt to error-correct again.
if (!handled) {
- reportError(IgnoredContentError, &localName, &current->localName());
+ reportError(IgnoredContentError, &localName, &m_current->localName());
return false;
}
return insertNode(n);
@@ -657,21 +674,21 @@ typedef HashMap<AtomicStringImpl*, CreateErrorCheckFunc> FunctionMap;
bool HTMLParser::textCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
- result = new Text(document, t->text.get());
+ result = new Text(m_document, t->text.get());
return false;
}
bool HTMLParser::commentCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
- result = new Comment(document, t->text.get());
+ result = new Comment(m_document, t->text.get());
return false;
}
bool HTMLParser::headCreateErrorCheck(Token*, RefPtr<Node>& result)
{
- if (!head || current->localName() == htmlTag) {
- head = new HTMLHeadElement(headTag, document);
- result = head;
+ if (!m_head || m_current->localName() == htmlTag) {
+ m_head = new HTMLHeadElement(headTag, m_document);
+ result = m_head;
} else
reportError(MisplacedHeadError);
return false;
@@ -680,7 +697,7 @@ bool HTMLParser::headCreateErrorCheck(Token*, RefPtr<Node>& result)
bool HTMLParser::bodyCreateErrorCheck(Token*, RefPtr<Node>&)
{
// body no longer allowed if we have a frameset
- if (haveFrameSet)
+ if (m_haveFrameSet)
return false;
popBlock(headTag);
startBody();
@@ -690,19 +707,19 @@ bool HTMLParser::bodyCreateErrorCheck(Token*, RefPtr<Node>&)
bool HTMLParser::framesetCreateErrorCheck(Token*, RefPtr<Node>&)
{
popBlock(headTag);
- if (inBody && !haveFrameSet && !haveContent) {
+ if (m_inBody && !m_haveFrameSet && !m_haveContent) {
popBlock(bodyTag);
// ### actually for IE document.body returns the now hidden "body" element
// we can't implement that behaviour now because it could cause too many
// regressions and the headaches are not worth the work as long as there is
// no site actually relying on that detail (Dirk)
- if (document->body())
- document->body()->setAttribute(styleAttr, "display:none");
- inBody = false;
+ if (m_document->body())
+ m_document->body()->setAttribute(styleAttr, "display:none");
+ m_inBody = false;
}
- if ((haveContent || haveFrameSet) && current->localName() == htmlTag)
+ if ((m_haveContent || m_haveFrameSet) && m_current->localName() == htmlTag)
return false;
- haveFrameSet = true;
+ m_haveFrameSet = true;
startBody();
return true;
}
@@ -712,7 +729,7 @@ bool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
// Only create a new form if we're not already inside one.
// This is consistent with other browsers' behavior.
if (!m_currentFormElement) {
- m_currentFormElement = new HTMLFormElement(formTag, document);
+ m_currentFormElement = new HTMLFormElement(formTag, m_document);
result = m_currentFormElement;
pCloserCreateErrorCheck(t, result);
}
@@ -722,7 +739,7 @@ bool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
bool HTMLParser::isindexCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
RefPtr<Node> n = handleIsindex(t);
- if (!inBody)
+ if (!m_inBody)
m_isindexElement = n.release();
else {
t->selfClosingTag = true;
@@ -800,7 +817,7 @@ bool HTMLParser::noframesCreateErrorCheck(Token*, RefPtr<Node>&)
bool HTMLParser::noscriptCreateErrorCheck(Token*, RefPtr<Node>&)
{
if (!m_isParsingFragment) {
- Settings* settings = document->settings();
+ Settings* settings = m_document->settings();
if (settings && settings->isJavaScriptEnabled())
setSkipMode(noscriptTag);
}
@@ -816,7 +833,7 @@ bool HTMLParser::pCloserCreateErrorCheck(Token*, RefPtr<Node>&)
bool HTMLParser::pCloserStrictCreateErrorCheck(Token*, RefPtr<Node>&)
{
- if (document->inCompatMode())
+ if (m_document->inCompatMode())
return true;
if (hasPElementInScope())
popBlock(pTag);
@@ -825,7 +842,7 @@ bool HTMLParser::pCloserStrictCreateErrorCheck(Token*, RefPtr<Node>&)
bool HTMLParser::mapCreateErrorCheck(Token*, RefPtr<Node>& result)
{
- m_currentMapElement = new HTMLMapElement(mapTag, document);
+ m_currentMapElement = new HTMLMapElement(mapTag, m_document);
result = m_currentMapElement;
return false;
}
@@ -896,7 +913,7 @@ PassRefPtr<Node> HTMLParser::getNode(Token* t)
if (CreateErrorCheckFunc errorCheckFunc = gFunctionMap.get(t->tagName.impl()))
proceed = (this->*errorCheckFunc)(t, result);
if (proceed)
- result = HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, t->tagName, xhtmlNamespaceURI), document, m_currentFormElement.get());
+ result = HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, t->tagName, xhtmlNamespaceURI), m_document, m_currentFormElement.get());
return result.release();
}
@@ -906,7 +923,7 @@ bool HTMLParser::allowNestedRedundantTag(const AtomicString& tagName)
// about 1500 tags, all from a bunch of <b>s. We will only allow at most 20
// nested tags of the same type before just ignoring them all together.
unsigned i = 0;
- for (HTMLStackElem* curr = blockStack;
+ for (HTMLStackElem* curr = m_blockStack;
i < cMaxRedundantTagDepth && curr && curr->tagName == tagName;
curr = curr->next, i++) { }
return i != cMaxRedundantTagDepth;
@@ -929,9 +946,9 @@ void HTMLParser::processCloseTag(Token* t)
else if (t->tagName == pTag)
checkForCloseTagErrors = false;
- HTMLStackElem* oldElem = blockStack;
+ HTMLStackElem* oldElem = m_blockStack;
popBlock(t->tagName, checkForCloseTagErrors);
- if (oldElem == blockStack && t->tagName == pTag) {
+ if (oldElem == m_blockStack && t->tagName == pTag) {
// We encountered a stray </p>. Amazingly Gecko, WinIE, and MacIE all treat
// this as a valid break, i.e., <p></p>. So go ahead and make the empty
// paragraph.
@@ -976,7 +993,7 @@ bool HTMLParser::isInline(Node* node) const
e->hasLocalName(noembedTag))
return true;
if (e->hasLocalName(noscriptTag) && !m_isParsingFragment) {
- Settings* settings = document->settings();
+ Settings* settings = m_document->settings();
if (settings && settings->isJavaScriptEnabled())
return true;
}
@@ -1047,7 +1064,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
// Find the outermost element that crosses over to a higher level. If there exists another higher-level
// element, we will do another pass, until we have corrected the innermost one.
ExceptionCode ec = 0;
- HTMLStackElem* curr = blockStack;
+ HTMLStackElem* curr = m_blockStack;
HTMLStackElem* prev = 0;
HTMLStackElem* prevMaxElem = 0;
maxElem = 0;
@@ -1071,7 +1088,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
return;
Node* residualElem = prev->node;
- Node* blockElem = prevMaxElem ? prevMaxElem->node : current;
+ Node* blockElem = prevMaxElem ? prevMaxElem->node : m_current;
Node* parentElem = elem->node;
// Check to see if the reparenting that is going to occur is allowed according to the DOM.
@@ -1220,13 +1237,13 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
// <table><b><i><form></b></form></i></table>
// Then this check will be too simplistic. Right now the <i><form> chain will end up inside the <tbody>, which is pretty crazy.
if (strayTableContent)
- inStrayTableContent--;
+ m_inStrayTableContent--;
// Step 7: Reopen intermediate inlines, e.g., <b><p><i>Foo</b>Goo</p>.
// In the above example, Goo should stay italic.
// We cap the number of tags we're willing to reopen based off cResidualStyleMaxDepth.
- HTMLStackElem* curr = blockStack;
+ HTMLStackElem* curr = m_blockStack;
HTMLStackElem* residualStyleStack = 0;
unsigned stackDepth = 1;
unsigned redundantStyleCount = 0;
@@ -1254,7 +1271,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
} else
popOneBlock();
- curr = blockStack;
+ curr = m_blockStack;
}
reopenResidualStyleTags(residualStyleStack, 0); // Stray table content can't be an issue here, since some element above will always become the root of new stray table content.
@@ -1276,7 +1293,7 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
if (malformedTableParent)
malformedTableParent->insertBefore(newNode, malformedTableParent->lastChild(), ec);
else
- current->appendChild(newNode, ec);
+ m_current->appendChild(newNode, ec);
// FIXME: Is it really OK to ignore the exceptions here?
// Now push a new stack element for this node we just created.
@@ -1285,9 +1302,9 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
// Set our strayTableContent boolean if needed, so that the reopened tag also knows
// that it is inside a malformed table.
- blockStack->strayTableContent = malformedTableParent != 0;
- if (blockStack->strayTableContent)
- inStrayTableContent++;
+ m_blockStack->strayTableContent = malformedTableParent != 0;
+ if (m_blockStack->strayTableContent)
+ m_inStrayTableContent++;
// Clear our malformed table parent variable.
malformedTableParent = 0;
@@ -1305,8 +1322,10 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
void HTMLParser::pushBlock(const AtomicString& tagName, int level)
{
- blockStack = new HTMLStackElem(tagName, level, current, didRefCurrent, blockStack);
- didRefCurrent = false;
+ m_blockStack = new HTMLStackElem(tagName, level, m_current, m_didRefCurrent, m_blockStack);
+ if (level >= minBlockLevelTagPriority)
+ m_blocksInStack++;
+ m_didRefCurrent = false;
if (tagName == pTag)
m_hasPElementInScope = InScope;
else if (isScopingTag(tagName))
@@ -1315,7 +1334,7 @@ void HTMLParser::pushBlock(const AtomicString& tagName, int level)
void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
{
- HTMLStackElem* elem = blockStack;
+ HTMLStackElem* elem = m_blockStack;
int maxLevel = 0;
@@ -1343,12 +1362,12 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
HTMLStackElem* residualStyleStack = 0;
Node* malformedTableParent = 0;
- elem = blockStack;
+ elem = m_blockStack;
unsigned stackDepth = 1;
unsigned redundantStyleCount = 0;
while (elem) {
if (elem->tagName == tagName) {
- int strayTable = inStrayTableContent;
+ int strayTable = m_inStrayTableContent;
popOneBlock();
elem = 0;
@@ -1356,8 +1375,8 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
// explicit <tbody> or <tr>.
// If we end up needing to reopen residual style tags, the root of the reopened chain
// must also know that it is the root of malformed content inside a <tbody>/<tr>.
- if (strayTable && (inStrayTableContent < strayTable) && residualStyleStack) {
- Node* curr = current;
+ if (strayTable && (m_inStrayTableContent < strayTable) && residualStyleStack) {
+ Node* curr = m_current;
while (curr && !curr->hasTagName(tableTag))
curr = curr->parentNode();
malformedTableParent = curr ? curr->parentNode() : 0;
@@ -1392,7 +1411,7 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
popOneBlock();
} else
popOneBlock();
- elem = blockStack;
+ elem = m_blockStack;
}
}
@@ -1401,19 +1420,23 @@ void HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
inline HTMLStackElem* HTMLParser::popOneBlockCommon()
{
- HTMLStackElem* elem = blockStack;
+ HTMLStackElem* elem = m_blockStack;
// Form elements restore their state during the parsing process.
// Also, a few elements (<applet>, <object>) need to know when all child elements (<param>s) are available.
- if (current && elem->node != current)
- current->finishParsingChildren();
+ if (m_current && elem->node != m_current)
+ m_current->finishParsingChildren();
- blockStack = elem->next;
- current = elem->node;
- didRefCurrent = elem->didRefNode;
+ if (m_blockStack->level >= minBlockLevelTagPriority) {
+ ASSERT(m_blocksInStack > 0);
+ m_blocksInStack--;
+ }
+ m_blockStack = elem->next;
+ m_current = elem->node;
+ m_didRefCurrent = elem->didRefNode;
if (elem->strayTableContent)
- inStrayTableContent--;
+ m_inStrayTableContent--;
if (elem->tagName == pTag)
m_hasPElementInScope = NotInScope;
@@ -1426,8 +1449,8 @@ inline HTMLStackElem* HTMLParser::popOneBlockCommon()
void HTMLParser::popOneBlock()
{
// Store the current node before popOneBlockCommon overwrites it.
- Node* lastCurrent = current;
- bool didRefLastCurrent = didRefCurrent;
+ Node* lastCurrent = m_current;
+ bool didRefLastCurrent = m_didRefCurrent;
delete popOneBlockCommon();
@@ -1441,8 +1464,8 @@ void HTMLParser::moveOneBlockToStack(HTMLStackElem*& head)
// See the two callers for details.
// Store the current node before popOneBlockCommon overwrites it.
- Node* lastCurrent = current;
- bool didRefLastCurrent = didRefCurrent;
+ Node* lastCurrent = m_current;
+ bool didRefLastCurrent = m_didRefCurrent;
// Pop the block, but don't deref the current node as popOneBlock does because
// we'll be using the pointer in the new stack element.
@@ -1450,7 +1473,7 @@ void HTMLParser::moveOneBlockToStack(HTMLStackElem*& head)
// Transfer the current node into the stack element.
// No need to deref the old elem->node because popOneBlockCommon transferred
- // it into the current/didRefCurrent fields.
+ // it into the m_current/m_didRefCurrent fields.
elem->node = lastCurrent;
elem->didRefNode = didRefLastCurrent;
elem->next = head;
@@ -1460,7 +1483,7 @@ void HTMLParser::moveOneBlockToStack(HTMLStackElem*& head)
void HTMLParser::checkIfHasPElementInScope()
{
m_hasPElementInScope = NotInScope;
- HTMLStackElem* elem = blockStack;
+ HTMLStackElem* elem = m_blockStack;
while (elem) {
const AtomicString& tagName = elem->tagName;
if (tagName == pTag) {
@@ -1474,42 +1497,43 @@ void HTMLParser::checkIfHasPElementInScope()
void HTMLParser::popInlineBlocks()
{
- while (blockStack && isInline(current))
+ while (m_blockStack && isInline(m_current))
popOneBlock();
}
void HTMLParser::freeBlock()
{
- while (blockStack)
+ while (m_blockStack)
popOneBlock();
+ ASSERT(!m_blocksInStack);
}
void HTMLParser::createHead()
{
- if (head || !document->documentElement())
+ if (m_head || !m_document->documentElement())
return;
- head = new HTMLHeadElement(headTag, document);
- HTMLElement* body = document->body();
+ m_head = new HTMLHeadElement(headTag, m_document);
+ HTMLElement* body = m_document->body();
ExceptionCode ec = 0;
- document->documentElement()->insertBefore(head, body, ec);
+ m_document->documentElement()->insertBefore(m_head, body, ec);
if (ec)
- head = 0;
+ m_head = 0;
// If the body does not exist yet, then the <head> should be pushed as the current block.
- if (head && !body) {
- pushBlock(head->localName(), head->tagPriority());
- setCurrent(head);
+ if (m_head && !body) {
+ pushBlock(m_head->localName(), m_head->tagPriority());
+ setCurrent(m_head);
}
}
PassRefPtr<Node> HTMLParser::handleIsindex(Token* t)
{
- RefPtr<Node> n = new HTMLDivElement(divTag, document);
+ RefPtr<Node> n = new HTMLDivElement(divTag, m_document);
NamedMappedAttrMap* attrs = t->attrs.get();
- RefPtr<HTMLIsIndexElement> isIndex = new HTMLIsIndexElement(isindexTag, document, m_currentFormElement.get());
+ RefPtr<HTMLIsIndexElement> isIndex = new HTMLIsIndexElement(isindexTag, m_document, m_currentFormElement.get());
isIndex->setAttributeMap(attrs);
isIndex->setAttribute(typeAttr, "khtml_isindex");
@@ -1520,20 +1544,20 @@ PassRefPtr<Node> HTMLParser::handleIsindex(Token* t)
t->attrs = 0;
}
- n->addChild(new HTMLHRElement(hrTag, document));
- n->addChild(new Text(document, text));
+ n->addChild(new HTMLHRElement(hrTag, m_document));
+ n->addChild(new Text(m_document, text));
n->addChild(isIndex.release());
- n->addChild(new HTMLHRElement(hrTag, document));
+ n->addChild(new HTMLHRElement(hrTag, m_document));
return n.release();
}
void HTMLParser::startBody()
{
- if (inBody)
+ if (m_inBody)
return;
- inBody = true;
+ m_inBody = true;
if (m_isindexElement) {
insertNode(m_isindexElement.get(), true /* don't descend into this node */);
@@ -1544,8 +1568,8 @@ void HTMLParser::startBody()
void HTMLParser::finished()
{
// In the case of a completely empty document, here's the place to create the HTML element.
- if (current && current->isDocumentNode() && !document->documentElement())
- insertNode(new HTMLHtmlElement(htmlTag, document));
+ if (m_current && m_current->isDocumentNode() && !m_document->documentElement())
+ insertNode(new HTMLHtmlElement(htmlTag, m_document));
// This ensures that "current" is not left pointing to a node when the document is destroyed.
freeBlock();
@@ -1553,16 +1577,16 @@ void HTMLParser::finished()
// Warning, this may delete the tokenizer and parser, so don't try to do anything else after this.
if (!m_isParsingFragment)
- document->finishedParsing();
+ m_document->finishedParsing();
}
void HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const AtomicString* tagName1, const AtomicString* tagName2, bool closeTags)
{
- Frame* frame = document->frame();
+ Frame* frame = m_document->frame();
if (!frame)
return;
- HTMLTokenizer* htmlTokenizer = static_cast<HTMLTokenizer*>(document->tokenizer());
+ HTMLTokenizer* htmlTokenizer = static_cast<HTMLTokenizer*>(m_document->tokenizer());
int lineNumber = htmlTokenizer->lineNumber() + 1;
AtomicString tag1;
@@ -1597,7 +1621,7 @@ void HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const Atomi
frame->domWindow()->console()->addMessage(HTMLMessageSource,
isWarning(errorCode) ? WarningMessageLevel : ErrorMessageLevel,
- message, lineNumber, document->url().string());
+ message, lineNumber, m_document->url().string());
}
}
diff --git a/WebCore/html/HTMLParser.h b/WebCore/html/HTMLParser.h
index 866835f..23fb980 100644
--- a/WebCore/html/HTMLParser.h
+++ b/WebCore/html/HTMLParser.h
@@ -150,33 +150,38 @@ private:
void reportErrorToConsole(HTMLParserErrorCode, const AtomicString* tagName1, const AtomicString* tagName2, bool closeTags);
- Document* document;
+ Document* m_document;
// The currently active element (the one new elements will be added to). Can be a document fragment, a document or an element.
- Node* current;
+ Node* m_current;
// We can't ref a document, but we don't want to constantly check if a node is a document just to decide whether to deref.
- bool didRefCurrent;
+ bool m_didRefCurrent;
- HTMLStackElem* blockStack;
+ HTMLStackElem* m_blockStack;
+
+ // The number of tags with priority minBlockLevelTagPriority or higher
+ // currently in m_blockStack. The parser enforces a cap on this value by
+ // adding such new elements as siblings instead of children once it is reached.
+ size_t m_blocksInStack;
enum ElementInScopeState { NotInScope, InScope, Unknown };
ElementInScopeState m_hasPElementInScope;
RefPtr<HTMLFormElement> m_currentFormElement; // currently active form
RefPtr<HTMLMapElement> m_currentMapElement; // current map
- HTMLHeadElement* head; // head element; needed for HTML which defines <base> after </head>
+ HTMLHeadElement* m_head; // head element; needed for HTML which defines <base> after </head>
RefPtr<Node> m_isindexElement; // a possible <isindex> element in the head
- bool inBody;
- bool haveContent;
- bool haveFrameSet;
+ bool m_inBody;
+ bool m_haveContent;
+ bool m_haveFrameSet;
AtomicString m_skipModeTag; // tells the parser to discard all tags until it reaches the one specified
bool m_isParsingFragment;
bool m_reportErrors;
bool m_handlingResidualStyleAcrossBlocks;
- int inStrayTableContent;
+ int m_inStrayTableContent;
};
}
diff --git a/WebCore/html/HTMLQuoteElement.cpp b/WebCore/html/HTMLQuoteElement.cpp
index 19164e2..e548215 100644
--- a/WebCore/html/HTMLQuoteElement.cpp
+++ b/WebCore/html/HTMLQuoteElement.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "HTMLQuoteElement.h"
+#include "Document.h"
#include "HTMLNames.h"
namespace WebCore {
@@ -34,6 +35,13 @@ HTMLQuoteElement::HTMLQuoteElement(const QualifiedName& tagName, Document* doc)
ASSERT(hasTagName(qTag));
}
+void HTMLQuoteElement::insertedIntoDocument()
+{
+ document()->setUsesBeforeAfterRules(true);
+
+ HTMLElement::insertedIntoDocument();
+}
+
String HTMLQuoteElement::cite() const
{
return getAttribute(citeAttr);
diff --git a/WebCore/html/HTMLQuoteElement.h b/WebCore/html/HTMLQuoteElement.h
index 1e35431..623c28f 100644
--- a/WebCore/html/HTMLQuoteElement.h
+++ b/WebCore/html/HTMLQuoteElement.h
@@ -36,6 +36,8 @@ public:
virtual HTMLTagStatus endTagRequirement() const { return TagStatusRequired; }
virtual int tagPriority() const { return 1; }
+ virtual void insertedIntoDocument();
+
String cite() const;
void setCite(const String&);
};
diff --git a/WebCore/html/HTMLSelectElement.cpp b/WebCore/html/HTMLSelectElement.cpp
index 7a0ee29..107fbd0 100644
--- a/WebCore/html/HTMLSelectElement.cpp
+++ b/WebCore/html/HTMLSelectElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -67,6 +67,9 @@ using namespace HTMLNames;
static const DOMTimeStamp typeAheadTimeout = 1000;
+// Upper limit agreed upon with representatives of Opera and Mozilla.
+static const unsigned maxSelectItems = 10000;
+
HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
: HTMLFormControlElementWithState(tagName, doc, f)
, m_minwidth(0)
@@ -218,10 +221,7 @@ void HTMLSelectElement::add(HTMLElement *element, HTMLElement *before, Exception
if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
return;
- ec = 0;
insertBefore(element, before, ec);
- if (!ec)
- setRecalcListItems();
}
void HTMLSelectElement::remove(int index)
@@ -236,8 +236,6 @@ void HTMLSelectElement::remove(int index)
Element *item = items[listIndex];
ASSERT(item->parentNode());
item->parentNode()->removeChild(item, ec);
- if (!ec)
- setRecalcListItems();
}
String HTMLSelectElement::value()
@@ -296,46 +294,6 @@ void HTMLSelectElement::restoreState(const String& state)
setChanged();
}
-bool HTMLSelectElement::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
-{
- bool result = HTMLFormControlElementWithState::insertBefore(newChild, refChild, ec, shouldLazyAttach);
- if (result)
- setRecalcListItems();
- return result;
-}
-
-bool HTMLSelectElement::replaceChild(PassRefPtr<Node> newChild, Node *oldChild, ExceptionCode& ec, bool shouldLazyAttach)
-{
- bool result = HTMLFormControlElementWithState::replaceChild(newChild, oldChild, ec, shouldLazyAttach);
- if (result)
- setRecalcListItems();
- return result;
-}
-
-bool HTMLSelectElement::removeChild(Node* oldChild, ExceptionCode& ec)
-{
- bool result = HTMLFormControlElementWithState::removeChild(oldChild, ec);
- if (result)
- setRecalcListItems();
- return result;
-}
-
-bool HTMLSelectElement::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
-{
- bool result = HTMLFormControlElementWithState::appendChild(newChild, ec, shouldLazyAttach);
- if (result)
- setRecalcListItems();
- return result;
-}
-
-bool HTMLSelectElement::removeChildren()
-{
- bool result = HTMLFormControlElementWithState::removeChildren();
- if (result)
- setRecalcListItems();
- return result;
-}
-
void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr)
{
bool oldUsesMenuList = usesMenuList();
@@ -349,7 +307,7 @@ void HTMLSelectElement::parseMappedAttribute(MappedAttribute *attr)
attr->setValue(attrSize);
m_size = max(size, 1);
- if ((oldUsesMenuList != usesMenuList() || !oldUsesMenuList && m_size != oldSize) && attached()) {
+ if ((oldUsesMenuList != usesMenuList() || (!oldUsesMenuList && m_size != oldSize)) && attached()) {
detach();
attach();
setRecalcListItems();
@@ -422,6 +380,9 @@ RenderObject* HTMLSelectElement::createRenderer(RenderArena* arena, RenderStyle*
bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
{
+ if (name().isEmpty())
+ return false;
+
bool successful = false;
const Vector<HTMLElement*>& items = listItems();
@@ -536,6 +497,7 @@ void HTMLSelectElement::childrenChanged(bool changedByParser, Node* beforeChange
void HTMLSelectElement::setRecalcListItems()
{
m_recalcListItems = true;
+ m_activeSelectionAnchorIndex = -1; // Manual selection anchor is reset when manipulating the select programmatically.
if (renderer()) {
if (usesMenuList())
static_cast<RenderMenuList*>(renderer())->setOptionsChanged(true);
@@ -617,8 +579,6 @@ void HTMLSelectElement::defaultEventHandler(Event* evt)
void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
{
- RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer());
-
if (evt->type() == eventNames().keydownEvent) {
if (!renderer() || !evt->isKeyboardEvent())
return;
@@ -630,7 +590,8 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
// Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
// which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
saveLastSelection();
- menuList->showPopup();
+ if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()))
+ menuList->showPopup();
handled = true;
}
#elif defined ANDROID_KEYBOARD_NAVIGATION
@@ -677,7 +638,8 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
// Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
// which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
saveLastSelection();
- menuList->showPopup();
+ if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer()))
+ menuList->showPopup();
handled = true;
}
if (keyCode == '\r') {
@@ -700,13 +662,15 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* evt)
if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
focus();
- if (menuList->popupIsVisible())
- menuList->hidePopup();
- else {
- // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
- // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
- saveLastSelection();
- menuList->showPopup();
+ if (RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer())) {
+ if (menuList->popupIsVisible())
+ menuList->hidePopup();
+ else {
+ // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
+ // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
+ saveLastSelection();
+ menuList->showPopup();
+ }
}
evt->setDefaultHandled();
}
@@ -716,9 +680,11 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt)
{
if (evt->type() == eventNames().mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
focus();
-
- MouseEvent* mEvt = static_cast<MouseEvent*>(evt);
- int listIndex = static_cast<RenderListBox*>(renderer())->listIndexAtOffset(mEvt->offsetX(), mEvt->offsetY());
+
+ // Convert to coords relative to the list box if needed.
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(evt);
+ IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
+ int listIndex = static_cast<RenderListBox*>(renderer())->listIndexAtOffset(localOffset.x(), localOffset.y());
if (listIndex >= 0) {
// Save the selection so it can be compared to the new selection when we call onChange during mouseup, or after autoscroll finishes.
saveLastSelection();
@@ -727,13 +693,13 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* evt)
bool multiSelectKeyPressed = false;
#if PLATFORM(MAC)
- multiSelectKeyPressed = mEvt->metaKey();
+ multiSelectKeyPressed = mouseEvent->metaKey();
#else
- multiSelectKeyPressed = mEvt->ctrlKey();
+ multiSelectKeyPressed = mouseEvent->ctrlKey();
#endif
- bool shiftSelect = multiple() && mEvt->shiftKey();
- bool multiSelect = multiple() && multiSelectKeyPressed && !mEvt->shiftKey();
+ bool shiftSelect = multiple() && mouseEvent->shiftKey();
+ bool multiSelect = multiple() && multiSelectKeyPressed && !mouseEvent->shiftKey();
HTMLElement* clickedElement = listItems()[listIndex];
HTMLOptionElement* option = 0;
@@ -1068,8 +1034,8 @@ Node* HTMLSelectElement::item(unsigned index)
void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, ExceptionCode& ec)
{
ec = 0;
- if (index > INT_MAX)
- index = INT_MAX;
+ if (index > maxSelectItems - 1)
+ index = maxSelectItems - 1;
int diff = index - length();
HTMLElement* before = 0;
// out of array bounds ? first insert empty dummies
@@ -1091,15 +1057,14 @@ void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
void HTMLSelectElement::setLength(unsigned newLen, ExceptionCode& ec)
{
ec = 0;
- if (newLen > INT_MAX)
- newLen = INT_MAX;
+ if (newLen > maxSelectItems)
+ newLen = maxSelectItems;
int diff = length() - newLen;
if (diff < 0) { // add dummy elements
do {
- RefPtr<Element> option = document()->createElement("option", ec);
- if (!option)
- break;
+ RefPtr<Element> option = document()->createElement(optionTag, false);
+ ASSERT(option);
add(static_cast<HTMLElement*>(option.get()), 0, ec);
if (ec)
break;
diff --git a/WebCore/html/HTMLSelectElement.h b/WebCore/html/HTMLSelectElement.h
index ec49a82..59e4a4b 100644
--- a/WebCore/html/HTMLSelectElement.h
+++ b/WebCore/html/HTMLSelectElement.h
@@ -81,11 +81,6 @@ public:
virtual bool saveState(String& value) const;
virtual void restoreState(const String&);
- virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
- virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
- virtual bool removeChild(Node* child, ExceptionCode&);
- virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
- virtual bool removeChildren();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void parseMappedAttribute(MappedAttribute*);
diff --git a/WebCore/html/HTMLSourceElement.cpp b/WebCore/html/HTMLSourceElement.cpp
index c8f814f..609bcbf 100644
--- a/WebCore/html/HTMLSourceElement.cpp
+++ b/WebCore/html/HTMLSourceElement.cpp
@@ -53,7 +53,7 @@ void HTMLSourceElement::insertedIntoDocument()
HTMLElement::insertedIntoDocument();
if (parentNode() && (parentNode()->hasTagName(audioTag) || parentNode()->hasTagName(videoTag))) {
HTMLMediaElement* media = static_cast<HTMLMediaElement*>(parentNode());
- if (media->networkState() == HTMLMediaElement::EMPTY)
+ if (media->networkState() == HTMLMediaElement::NETWORK_EMPTY)
media->scheduleLoad();
}
}
diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in
index 1697ebe..8b1fa2b 100644
--- a/WebCore/html/HTMLTagNames.in
+++ b/WebCore/html/HTMLTagNames.in
@@ -52,7 +52,7 @@ hr interfaceName=HTMLHRElement
html
i interfaceName=HTMLElement
iframe interfaceName=HTMLIFrameElement, constructorNeedsCreatedByParser
-image
+image mapToTagName=img
img interfaceName=HTMLImageElement, constructorNeedsFormElement
input constructorNeedsFormElement
ins interfaceName=HTMLModElement
diff --git a/WebCore/html/HTMLTextAreaElement.cpp b/WebCore/html/HTMLTextAreaElement.cpp
index 091718b..4eec088 100644
--- a/WebCore/html/HTMLTextAreaElement.cpp
+++ b/WebCore/html/HTMLTextAreaElement.cpp
@@ -37,7 +37,7 @@
#include "Page.h"
#include "RenderStyle.h"
#include "RenderTextControlMultiLine.h"
-#include "Selection.h"
+#include "VisibleSelection.h"
#include "Text.h"
#include <wtf/StdLibExtras.h>
@@ -96,7 +96,7 @@ int HTMLTextAreaElement::selectionStart()
return 0;
if (document()->focusedNode() != this && m_cachedSelectionStart >= 0)
return m_cachedSelectionStart;
- return static_cast<RenderTextControl*>(renderer())->selectionStart();
+ return toRenderTextControl(renderer())->selectionStart();
}
int HTMLTextAreaElement::selectionEnd()
@@ -105,35 +105,35 @@ int HTMLTextAreaElement::selectionEnd()
return 0;
if (document()->focusedNode() != this && m_cachedSelectionEnd >= 0)
return m_cachedSelectionEnd;
- return static_cast<RenderTextControl*>(renderer())->selectionEnd();
+ return toRenderTextControl(renderer())->selectionEnd();
}
void HTMLTextAreaElement::setSelectionStart(int start)
{
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->setSelectionStart(start);
+ toRenderTextControl(renderer())->setSelectionStart(start);
}
void HTMLTextAreaElement::setSelectionEnd(int end)
{
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->setSelectionEnd(end);
+ toRenderTextControl(renderer())->setSelectionEnd(end);
}
void HTMLTextAreaElement::select()
{
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->select();
+ toRenderTextControl(renderer())->select();
}
void HTMLTextAreaElement::setSelectionRange(int start, int end)
{
if (!renderer())
return;
- static_cast<RenderTextControl*>(renderer())->setSelectionRange(start, end);
+ toRenderTextControl(renderer())->setSelectionRange(start, end);
}
void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -206,7 +206,7 @@ bool HTMLTextAreaElement::appendFormData(FormDataList& encoding, bool)
// FIXME: It's not acceptable to ignore the HardWrap setting when there is no renderer.
// While we have no evidence this has ever been a practical problem, it would be best to fix it some day.
- RenderTextControl* control = static_cast<RenderTextControl*>(renderer());
+ RenderTextControl* control = toRenderTextControl(renderer());
const String& text = (m_wrap == HardWrap && control) ? control->textWithHardLineBreaks() : value();
encoding.appendData(name(), text);
return true;
@@ -233,10 +233,17 @@ void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
ASSERT(renderer());
if (!restorePreviousSelection || m_cachedSelectionStart < 0) {
+#if ENABLE(ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL)
+ // Devices with trackballs or d-pads may focus on a textarea in route
+ // to another focusable node. By selecting all text, the next movement
+ // can more readily be interpreted as moving to the next node.
+ select();
+#else
// If this is the first focus, set a caret at the beginning of the text.
// This matches some browsers' behavior; see bug 11746 Comment #15.
// http://bugs.webkit.org/show_bug.cgi?id=11746#c15
setSelectionRange(0, 0);
+#endif
} else {
// Restore the cached selection. This matches other browsers' behavior.
setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd);
@@ -265,7 +272,7 @@ void HTMLTextAreaElement::updateValue() const
return;
ASSERT(renderer());
- m_value = static_cast<RenderTextControl*>(renderer())->text();
+ m_value = toRenderTextControl(renderer())->text();
const_cast<HTMLTextAreaElement*>(this)->setValueMatchesRenderer();
notifyFormStateChanged(this);
}
@@ -382,11 +389,11 @@ void HTMLTextAreaElement::setRows(int rows)
setAttribute(rowsAttr, String::number(rows));
}
-Selection HTMLTextAreaElement::selection() const
+VisibleSelection HTMLTextAreaElement::selection() const
{
if (!renderer() || m_cachedSelectionStart < 0 || m_cachedSelectionEnd < 0)
- return Selection();
- return static_cast<RenderTextControl*>(renderer())->selection(m_cachedSelectionStart, m_cachedSelectionEnd);
+ return VisibleSelection();
+ return toRenderTextControl(renderer())->selection(m_cachedSelectionStart, m_cachedSelectionEnd);
}
bool HTMLTextAreaElement::shouldUseInputMethod() const
diff --git a/WebCore/html/HTMLTextAreaElement.h b/WebCore/html/HTMLTextAreaElement.h
index f02ad65..f78386c 100644
--- a/WebCore/html/HTMLTextAreaElement.h
+++ b/WebCore/html/HTMLTextAreaElement.h
@@ -28,7 +28,7 @@
namespace WebCore {
-class Selection;
+class VisibleSelection;
class HTMLTextAreaElement : public HTMLFormControlElementWithState {
public:
@@ -87,7 +87,7 @@ public:
void setRows(int);
void cacheSelection(int s, int e) { m_cachedSelectionStart = s; m_cachedSelectionEnd = e; };
- Selection selection() const;
+ VisibleSelection selection() const;
virtual bool shouldUseInputMethod() const;
diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp
index b01d4e4..e4952f7 100644
--- a/WebCore/html/HTMLTokenizer.cpp
+++ b/WebCore/html/HTMLTokenizer.cpp
@@ -143,7 +143,7 @@ inline void Token::addAttribute(AtomicString& attrName, const AtomicString& attr
RefPtr<MappedAttribute> a = MappedAttribute::create(attrName, attributeValue);
if (!attrs) {
attrs = NamedMappedAttrMap::create();
- attrs->reserveCapacity(10);
+ attrs->reserveInitialCapacity(10);
}
attrs->insertAttribute(a.release(), viewSourceMode);
}
@@ -448,15 +448,6 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
m_scriptTagSrcAttrValue = String();
} else {
// Parse m_scriptCode containing <script> info
-#if USE(LOW_BANDWIDTH_DISPLAY)
- if (m_doc->inLowBandwidthDisplay()) {
- // ideal solution is only skipping internal JavaScript if there is external JavaScript.
- // but internal JavaScript can use document.write() to create an external JavaScript,
- // so we have to skip internal JavaScript all the time.
- m_doc->frame()->loader()->needToSwitchOutLowBandwidthDisplay();
- doScriptExec = false;
- } else
-#endif
doScriptExec = m_scriptNode->shouldExecuteAsJavaScript();
m_scriptNode = 0;
}
@@ -1600,13 +1591,13 @@ inline bool HTMLTokenizer::continueProcessing(int& processedCount, double startT
return true;
}
-bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
+void HTMLTokenizer::write(const SegmentedString& str, bool appendData)
{
if (!m_buffer)
- return false;
+ return;
if (m_parserStopped)
- return false;
+ return;
SegmentedString source(str);
if (m_executingScript)
@@ -1623,7 +1614,7 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
m_preloadScanner->write(source);
#endif
}
- return false;
+ return;
}
@@ -1639,7 +1630,7 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
// Once a timer is set, it has control of when the tokenizer continues.
if (m_timer.isActive())
- return false;
+ return;
bool wasInWrite = m_inWrite;
m_inWrite = true;
@@ -1784,11 +1775,8 @@ bool HTMLTokenizer::write(const SegmentedString& str, bool appendData)
android::TimeCounter::record(android::TimeCounter::ParsingTimeCounter, __FUNCTION__);
#endif
- if (m_noMoreData && !m_inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive()) {
+ if (m_noMoreData && !m_inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive())
end(); // this actually causes us to be deleted
- return true;
- }
- return false;
}
void HTMLTokenizer::stopParsing()
@@ -2004,11 +1992,11 @@ void HTMLTokenizer::notifyFinished(CachedResource*)
#endif
if (errorOccurred)
- EventTargetNodeCast(n.get())->dispatchEventForType(eventNames().errorEvent, true, false);
+ n->dispatchEventForType(eventNames().errorEvent, true, false);
else {
if (static_cast<HTMLScriptElement*>(n.get())->shouldExecuteAsJavaScript())
m_state = scriptExecution(sourceCode, m_state);
- EventTargetNodeCast(n.get())->dispatchEventForType(eventNames().loadEvent, false, false);
+ n->dispatchEventForType(eventNames().loadEvent, false, false);
}
// The state of m_pendingScripts.isEmpty() can change inside the scriptExecution()
diff --git a/WebCore/html/HTMLTokenizer.h b/WebCore/html/HTMLTokenizer.h
index b4453af..2896974 100644
--- a/WebCore/html/HTMLTokenizer.h
+++ b/WebCore/html/HTMLTokenizer.h
@@ -138,7 +138,7 @@ public:
HTMLTokenizer(DocumentFragment*);
virtual ~HTMLTokenizer();
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
virtual void setForceSynchronous(bool force);
virtual bool isWaitingForScripts() const;
diff --git a/WebCore/html/HTMLVideoElement.cpp b/WebCore/html/HTMLVideoElement.cpp
index a67db71..b0aac3c 100644
--- a/WebCore/html/HTMLVideoElement.cpp
+++ b/WebCore/html/HTMLVideoElement.cpp
@@ -52,27 +52,30 @@ bool HTMLVideoElement::rendererIsNeeded(RenderStyle* style)
return HTMLElement::rendererIsNeeded(style);
}
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
RenderObject* HTMLVideoElement::createRenderer(RenderArena* arena, RenderStyle*)
{
if (m_shouldShowPosterImage)
return new (arena) RenderImage(this);
return new (arena) RenderVideo(this);
}
+#endif
void HTMLVideoElement::attach()
{
HTMLMediaElement::attach();
-
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
if (m_shouldShowPosterImage) {
if (!m_imageLoader)
m_imageLoader.set(new HTMLImageLoader(this));
m_imageLoader->updateFromElement();
if (renderer() && renderer()->isImage()) {
- RenderImage* imageRenderer = static_cast<RenderImage*>(renderer());
+ RenderImage* imageRenderer = toRenderImage(renderer());
imageRenderer->setCachedImage(m_imageLoader->image());
}
}
-
+#endif
}
void HTMLVideoElement::detach()
@@ -91,9 +94,14 @@ void HTMLVideoElement::parseMappedAttribute(MappedAttribute* attr)
if (attrName == posterAttr) {
updatePosterImage();
if (m_shouldShowPosterImage) {
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
if (!m_imageLoader)
m_imageLoader.set(new HTMLImageLoader(this));
m_imageLoader->updateFromElementIgnoringPreviousError();
+#else
+ if (m_player)
+ m_player->setPoster(poster());
+#endif
}
} else if (attrName == widthAttr)
addCSSLength(attr, CSSPropertyWidth, attr->value());
@@ -163,12 +171,18 @@ const QualifiedName& HTMLVideoElement::imageSourceAttributeName() const
void HTMLVideoElement::updatePosterImage()
{
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
bool oldShouldShowPosterImage = m_shouldShowPosterImage;
- m_shouldShowPosterImage = !poster().isEmpty() && m_networkState < LOADED_FIRST_FRAME;
+#endif
+
+ m_shouldShowPosterImage = !poster().isEmpty() && readyState() < HAVE_CURRENT_DATA;
+
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
if (attached() && oldShouldShowPosterImage != m_shouldShowPosterImage) {
detach();
attach();
}
+#endif
}
}
diff --git a/WebCore/html/HTMLVideoElement.h b/WebCore/html/HTMLVideoElement.h
index 8779c85..d35f3f8 100644
--- a/WebCore/html/HTMLVideoElement.h
+++ b/WebCore/html/HTMLVideoElement.h
@@ -42,11 +42,14 @@ public:
virtual int tagPriority() const { return 5; }
virtual bool rendererIsNeeded(RenderStyle*);
+#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
+#endif
virtual void attach();
virtual void detach();
virtual void parseMappedAttribute(MappedAttribute* attr);
virtual bool isVideo() const { return true; }
+ virtual bool hasVideo() const { return player() && player()->hasVideo(); }
virtual bool isURLAttribute(Attribute*) const;
virtual const QualifiedName& imageSourceAttributeName() const;
diff --git a/WebCore/html/HTMLViewSourceDocument.cpp b/WebCore/html/HTMLViewSourceDocument.cpp
index 163ee72..596f16e 100644
--- a/WebCore/html/HTMLViewSourceDocument.cpp
+++ b/WebCore/html/HTMLViewSourceDocument.cpp
@@ -73,7 +73,7 @@ void HTMLViewSourceDocument::createContainingTable()
// document.
RefPtr<Element> div = new HTMLDivElement(divTag, this);
RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
- attrs->insertAttribute(MappedAttribute::create(classAttr, "webkit-line-gutter-backdrop"), true);
+ attrs->addAttribute(MappedAttribute::create(classAttr, "webkit-line-gutter-backdrop"));
div->setAttributeMap(attrs.release());
body->addChild(div);
div->attach();
@@ -195,7 +195,7 @@ Element* HTMLViewSourceDocument::addSpanWithClassName(const String& className)
Element* span = new HTMLElement(spanTag, this);
RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
- attrs->insertAttribute(MappedAttribute::create(classAttr, className), true);
+ attrs->addAttribute(MappedAttribute::create(classAttr, className));
span->setAttributeMap(attrs.release());
m_current->addChild(span);
span->attach();
@@ -212,7 +212,7 @@ void HTMLViewSourceDocument::addLine(const String& className)
// Create a cell that will hold the line number (it is generated in the stylesheet using counters).
Element* td = new HTMLTableCellElement(tdTag, this);
RefPtr<NamedMappedAttrMap> attrs = NamedMappedAttrMap::create();
- attrs->insertAttribute(MappedAttribute::create(classAttr, "webkit-line-number"), true);
+ attrs->addAttribute(MappedAttribute::create(classAttr, "webkit-line-number"));
td->setAttributeMap(attrs.release());
trow->addChild(td);
td->attach();
@@ -220,7 +220,7 @@ void HTMLViewSourceDocument::addLine(const String& className)
// Create a second cell for the line contents
td = new HTMLTableCellElement(tdTag, this);
attrs = NamedMappedAttrMap::create();
- attrs->insertAttribute(MappedAttribute::create(classAttr, "webkit-line-content"), true);
+ attrs->addAttribute(MappedAttribute::create(classAttr, "webkit-line-content"));
td->setAttributeMap(attrs.release());
trow->addChild(td);
td->attach();
@@ -283,9 +283,9 @@ Element* HTMLViewSourceDocument::addLink(const String& url, bool isAnchor)
classValue = "webkit-html-attribute-value webkit-html-external-link";
else
classValue = "webkit-html-attribute-value webkit-html-resource-link";
- attrs->insertAttribute(MappedAttribute::create(classAttr, classValue), true);
- attrs->insertAttribute(MappedAttribute::create(targetAttr, "_blank"), true);
- attrs->insertAttribute(MappedAttribute::create(hrefAttr, url), true);
+ attrs->addAttribute(MappedAttribute::create(classAttr, classValue));
+ attrs->addAttribute(MappedAttribute::create(targetAttr, "_blank"));
+ attrs->addAttribute(MappedAttribute::create(hrefAttr, url));
anchor->setAttributeMap(attrs.release());
m_current->addChild(anchor);
anchor->attach();
diff --git a/WebCore/html/MediaError.h b/WebCore/html/MediaError.h
index fbf375f..7dcf72a 100644
--- a/WebCore/html/MediaError.h
+++ b/WebCore/html/MediaError.h
@@ -34,7 +34,7 @@ namespace WebCore {
class MediaError : public RefCounted<MediaError> {
public:
- enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE };
+ enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE, MEDIA_ERR_NONE_SUPPORTED };
static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
diff --git a/WebCore/html/MediaError.idl b/WebCore/html/MediaError.idl
index 5b4f0a2..162170f 100644
--- a/WebCore/html/MediaError.idl
+++ b/WebCore/html/MediaError.idl
@@ -28,6 +28,7 @@ module html {
const unsigned short MEDIA_ERR_ABORTED = 1;
const unsigned short MEDIA_ERR_NETWORK = 2;
const unsigned short MEDIA_ERR_DECODE = 3;
+ const unsigned short MEDIA_ERR_NONE_SUPPORTED = 4;
readonly attribute unsigned short code;
};
}
diff --git a/WebCore/html/PreloadScanner.cpp b/WebCore/html/PreloadScanner.cpp
index 7e95c65..782e9bd 100644
--- a/WebCore/html/PreloadScanner.cpp
+++ b/WebCore/html/PreloadScanner.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -43,7 +44,7 @@
#include <wtf/CurrentTime.h>
#include <wtf/unicode/Unicode.h>
-#ifdef __GNUC__
+#if COMPILER(GCC)
// The main tokenizer includes this too so we are getting two copies of the data. However, this way the code gets inlined.
#include "HTMLEntityNames.c"
#else
@@ -128,9 +129,13 @@ bool PreloadScanner::scanningBody() const
void PreloadScanner::write(const SegmentedString& source)
{
+#if PRELOAD_DEBUG
double startTime = currentTime();
+#endif
tokenize(source);
+#if PRELOAD_DEBUG
m_timeUsed += currentTime() - startTime;
+#endif
}
static inline bool isWhitespace(UChar c)
diff --git a/WebCore/icu/unicode/ucsdet.h b/WebCore/icu/unicode/ucsdet.h
new file mode 100644
index 0000000..27e2e34
--- /dev/null
+++ b/WebCore/icu/unicode/ucsdet.h
@@ -0,0 +1,350 @@
+/*
+ **********************************************************************
+ * Copyright (C) 2005-2006, International Business Machines
+ * Corporation and others. All Rights Reserved.
+ **********************************************************************
+ * file name: ucsdet.h
+ * encoding: US-ASCII
+ * indentation:4
+ *
+ * created on: 2005Aug04
+ * created by: Andy Heninger
+ *
+ * ICU Character Set Detection, API for C
+ *
+ * Draft version 18 Oct 2005
+ *
+ */
+
+#ifndef __UCSDET_H
+#define __UCSDET_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_CONVERSION
+#include "unicode/uenum.h"
+
+/**
+ * \file
+ * \brief C API: Charset Detection API
+ *
+ * This API provides a facility for detecting the
+ * charset or encoding of character data in an unknown text format.
+ * The input data can be from an array of bytes.
+ * <p>
+ * Character set detection is at best an imprecise operation. The detection
+ * process will attempt to identify the charset that best matches the characteristics
+ * of the byte data, but the process is partly statistical in nature, and
+ * the results can not be guaranteed to always be correct.
+ * <p>
+ * For best accuracy in charset detection, the input data should be primarily
+ * in a single language, and a minimum of a few hundred bytes worth of plain text
+ * in the language are needed. The detection process will attempt to
+ * ignore html or xml style markup that could otherwise obscure the content.
+ */
+
+
+struct UCharsetDetector;
+/**
+ * Structure representing a charset detector
+ * @draft ICU 3.6
+ */
+typedef struct UCharsetDetector UCharsetDetector;
+
+struct UCharsetMatch;
+/**
+ * Opaque structure representing a match that was identified
+ * from a charset detection operation.
+ * @draft ICU 3.6
+ */
+typedef struct UCharsetMatch UCharsetMatch;
+
+/**
+ * Open a charset detector.
+ *
+ * @param status Any error conditions occurring during the open
+ * operation are reported back in this variable.
+ * @return the newly opened charset detector.
+ * @draft ICU 3.6
+ */
+U_DRAFT UCharsetDetector * U_EXPORT2
+ucsdet_open(UErrorCode *status);
+
+/**
+ * Close a charset detector. All storage and any other resources
+ * owned by this charset detector will be released. Failure to
+ * close a charset detector when finished with it can result in
+ * memory leaks in the application.
+ *
+ * @param ucsd The charset detector to be closed.
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ucsdet_close(UCharsetDetector *ucsd);
+
+/**
+ * Set the input byte data whose charset is to detected.
+ *
+ * Ownership of the input text byte array remains with the caller.
+ * The input string must not be altered or deleted until the charset
+ * detector is either closed or reset to refer to different input text.
+ *
+ * @param ucsd the charset detector to be used.
+ * @param textIn the input text of unknown encoding. .
+ * @param len the length of the input text, or -1 if the text
+ * is NUL terminated.
+ * @param status any error conditions are reported back in this variable.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ucsdet_setText(UCharsetDetector *ucsd, const char *textIn, int32_t len, UErrorCode *status);
+
+
+/** Set the declared encoding for charset detection.
+ * The declared encoding of an input text is an encoding obtained
+ * by the user from an http header or xml declaration or similar source that
+ * can be provided as an additional hint to the charset detector.
+ *
+ * How and whether the declared encoding will be used during the
+ * detection process is TBD.
+ *
+ * @param ucsd the charset detector to be used.
+ * @param encoding an encoding for the current data obtained from
+ * a header or declaration or other source outside
+ * of the byte data itself.
+ * @param length the length of the encoding name, or -1 if the name string
+ * is NUL terminated.
+ * @param status any error conditions are reported back in this variable.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT void U_EXPORT2
+ucsdet_setDeclaredEncoding(UCharsetDetector *ucsd, const char *encoding, int32_t length, UErrorCode *status);
+
+
+/**
+ * Return the charset that best matches the supplied input data.
+ *
+ * Note though, that because the detection
+ * only looks at the start of the input data,
+ * there is a possibility that the returned charset will fail to handle
+ * the full set of input data.
+ * <p>
+ * The returned UCharsetMatch object is owned by the UCharsetDetector.
+ * It will remain valid until the detector input is reset, or until
+ * the detector is closed.
+ * <p>
+ * The function will fail if
+ * <ul>
+ * <li>no charset appears to match the data.</li>
+ * <li>no input text has been provided</li>
+ * </ul>
+ *
+ * @param ucsd the charset detector to be used.
+ * @param status any error conditions are reported back in this variable.
+ * @return a UCharsetMatch representing the best matching charset,
+ * or NULL if no charset matches the byte data.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT const UCharsetMatch * U_EXPORT2
+ucsdet_detect(UCharsetDetector *ucsd, UErrorCode *status);
+
+
+/**
+ * Find all charset matches that appear to be consistent with the input,
+ * returning an array of results. The results are ordered with the
+ * best quality match first.
+ *
+ * Because the detection only looks at a limited amount of the
+ * input byte data, some of the returned charsets may fail to handle
+ * the all of input data.
+ * <p>
+ * The returned UCharsetMatch objects are owned by the UCharsetDetector.
+ * They will remain valid until the detector is closed or modified
+ *
+ * <p>
+ * Return an error if
+ * <ul>
+ * <li>no charsets appear to match the input data.</li>
+ * <li>no input text has been provided</li>
+ * </ul>
+ *
+ * @param ucsd the charset detector to be used.
+ * @param matchesFound pointer to a variable that will be set to the
+ * number of charsets identified that are consistent with
+ * the input data. Output only.
+ * @param status any error conditions are reported back in this variable.
+ * @return A pointer to an array of pointers to UCharSetMatch objects.
+ * This array, and the UCharSetMatch instances to which it refers,
+ * are owned by the UCharsetDetector, and will remain valid until
+ * the detector is closed or modified.
+ * @draft ICU 3.4
+ */
+U_DRAFT const UCharsetMatch ** U_EXPORT2
+ucsdet_detectAll(UCharsetDetector *ucsd, int32_t *matchesFound, UErrorCode *status);
+
+
+
+/**
+ * Get the name of the charset represented by a UCharsetMatch.
+ *
+ * The storage for the returned name string is owned by the
+ * UCharsetMatch, and will remain valid while the UCharsetMatch
+ * is valid.
+ *
+ * The name returned is suitable for use with the ICU conversion APIs.
+ *
+ * @param ucsm The charset match object.
+ * @param status Any error conditions are reported back in this variable.
+ * @return The name of the matching charset.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT const char * U_EXPORT2
+ucsdet_getName(const UCharsetMatch *ucsm, UErrorCode *status);
+
+/**
+ * Get a confidence number for the quality of the match of the byte
+ * data with the charset. Confidence numbers range from zero to 100,
+ * with 100 representing complete confidence and zero representing
+ * no confidence.
+ *
+ * The confidence values are somewhat arbitrary. They define an
+ * an ordering within the results for any single detection operation
+ * but are not generally comparable between the results for different input.
+ *
+ * A confidence value of ten does have a general meaning - it is used
+ * for charsets that can represent the input data, but for which there
+ * is no other indication that suggests that the charset is the correct one.
+ * Pure 7 bit ASCII data, for example, is compatible with a
+ * great many charsets, most of which will appear as possible matches
+ * with a confidence of 10.
+ *
+ * @param ucsm The charset match object.
+ * @param status Any error conditions are reported back in this variable.
+ * @return A confidence number for the charset match.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT int32_t U_EXPORT2
+ucsdet_getConfidence(const UCharsetMatch *ucsm, UErrorCode *status);
+
+/**
+ * Get the RFC 3066 code for the language of the input data.
+ *
+ * The Charset Detection service is intended primarily for detecting
+ * charsets, not language. For some, but not all, charsets, a language is
+ * identified as a byproduct of the detection process, and that is what
+ * is returned by this function.
+ *
+ * CAUTION:
+ * 1. Language information is not available for input data encoded in
+ * all charsets. In particular, no language is identified
+ * for UTF-8 input data.
+ *
+ * 2. Closely related languages may sometimes be confused.
+ *
+ * If more accurate language detection is required, a linguistic
+ * analysis package should be used.
+ *
+ * The storage for the returned name string is owned by the
+ * UCharsetMatch, and will remain valid while the UCharsetMatch
+ * is valid.
+ *
+ * @param ucsm The charset match object.
+ * @param status Any error conditions are reported back in this variable.
+ * @return The RFC 3066 code for the language of the input data, or
+ * an empty string if the language could not be determined.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT const char * U_EXPORT2
+ucsdet_getLanguage(const UCharsetMatch *ucsm, UErrorCode *status);
+
+
+/**
+ * Get the entire input text as a UChar string, placing it into
+ * a caller-supplied buffer. A terminating
+ * NUL character will be appended to the buffer if space is available.
+ *
+ * The number of UChars in the output string, not including the terminating
+ * NUL, is returned.
+ *
+ * If the supplied buffer is smaller than required to hold the output,
+ * the contents of the buffer are undefined. The full output string length
+ * (in UChars) is returned as always, and can be used to allocate a buffer
+ * of the correct size.
+ *
+ *
+ * @param ucsm The charset match object.
+ * @param buf A UChar buffer to be filled with the converted text data.
+ * @param cap The capacity of the buffer in UChars.
+ * @param status Any error conditions are reported back in this variable.
+ * @return The number of UChars in the output string.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT int32_t U_EXPORT2
+ucsdet_getUChars(const UCharsetMatch *ucsm,
+ UChar *buf, int32_t cap, UErrorCode *status);
+
+
+
+/**
+ * Get an iterator over the set of all detectable charsets -
+ * over the charsets that are known to the charset detection
+ * service.
+ *
+ * The returned UEnumeration provides access to the names of
+ * the charsets.
+ *
+ * The state of the Charset detector that is passed in does not
+ * affect the result of this function, but requiring a valid, open
+ * charset detector as a parameter insures that the charset detection
+ * service has been safely initialized and that the required detection
+ * data is available.
+ *
+ * @param ucsd a Charset detector.
+ * @param status Any error conditions are reported back in this variable.
+ * @return an iterator providing access to the detectable charset names.
+ * @draft ICU 3.6
+ */
+
+U_DRAFT UEnumeration * U_EXPORT2
+ucsdet_getAllDetectableCharsets(const UCharsetDetector *ucsd, UErrorCode *status);
+
+
+/**
+ * Test whether input filtering is enabled for this charset detector.
+ * Input filtering removes text that appears to be HTML or xml
+ * markup from the input before applying the code page detection
+ * heuristics.
+ *
+ * @param ucsd The charset detector to check.
+ * @return TRUE if filtering is enabled.
+ * @draft ICU 3.4
+ */
+U_DRAFT UBool U_EXPORT2
+ucsdet_isInputFilterEnabled(const UCharsetDetector *ucsd);
+
+
+/**
+ * Enable filtering of input text. If filtering is enabled,
+ * text within angle brackets ("<" and ">") will be removed
+ * before detection, which will remove most HTML or xml markup.
+ *
+ * @param ucsd the charset detector to be modified.
+ * @param filter <code>true</code> to enable input text filtering.
+ * @return The previous setting.
+ *
+ * @draft ICU 3.6
+ */
+U_DRAFT UBool U_EXPORT2
+ucsdet_enableInputFilter(UCharsetDetector *ucsd, UBool filter);
+
+#endif
+#endif /* __UCSDET_H */
+
+
diff --git a/WebCore/inspector/ConsoleMessage.cpp b/WebCore/inspector/ConsoleMessage.cpp
new file mode 100644
index 0000000..b2bf390
--- /dev/null
+++ b/WebCore/inspector/ConsoleMessage.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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.
+ */
+
+#include "config.h"
+#include "ConsoleMessage.h"
+
+#include "JSInspectedObjectWrapper.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallFrame.h"
+#include "ScriptFunctionCall.h"
+#include "ScriptObjectQuarantine.h"
+#include "ScriptString.h"
+
+namespace WebCore {
+
+ConsoleMessage::ConsoleMessage(MessageSource s, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g)
+ : m_source(s)
+ , m_level(l)
+ , m_message(m)
+ , m_line(li)
+ , m_url(u)
+ , m_groupLevel(g)
+ , m_repeatCount(1)
+{
+}
+
+ConsoleMessage::ConsoleMessage(MessageSource s, MessageLevel l, ScriptCallStack* callStack, unsigned g, bool storeTrace)
+ : m_source(s)
+ , m_level(l)
+ , m_wrappedArguments(callStack->at(0).argumentCount())
+ , m_frames(storeTrace ? callStack->size() : 0)
+ , m_groupLevel(g)
+ , m_repeatCount(1)
+{
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ m_line = lastCaller.lineNumber();
+ m_url = lastCaller.sourceURL().string();
+
+ // FIXME: For now, just store function names as strings.
+ // As ScriptCallStack start storing line number and source URL for all
+ // frames, refactor to use that, as well.
+ if (storeTrace) {
+ for (unsigned i = 0; i < callStack->size(); ++i)
+ m_frames[i] = callStack->at(i).functionName();
+ }
+
+ for (unsigned i = 0; i < lastCaller.argumentCount(); ++i)
+ m_wrappedArguments[i] = quarantineValue(callStack->state(), lastCaller.argumentAt(i));
+}
+
+void ConsoleMessage::addToConsole(ScriptState* scriptState, const ScriptObject& webInspector)
+{
+ ScriptFunctionCall messageConstructor(scriptState, webInspector, "ConsoleMessage");
+ messageConstructor.appendArgument(static_cast<unsigned int>(m_source));
+ messageConstructor.appendArgument(static_cast<unsigned int>(m_level));
+ messageConstructor.appendArgument(m_line);
+ messageConstructor.appendArgument(m_url);
+ messageConstructor.appendArgument(m_groupLevel);
+ messageConstructor.appendArgument(m_repeatCount);
+
+ if (!m_frames.isEmpty()) {
+ for (unsigned i = 0; i < m_frames.size(); ++i)
+ messageConstructor.appendArgument(m_frames[i]);
+ } else if (!m_wrappedArguments.isEmpty()) {
+ for (unsigned i = 0; i < m_wrappedArguments.size(); ++i)
+ messageConstructor.appendArgument(m_wrappedArguments[i]);
+ } else
+ messageConstructor.appendArgument(m_message);
+
+ bool hadException = false;
+ ScriptObject message = messageConstructor.construct(hadException);
+ if (hadException)
+ return;
+
+ ScriptFunctionCall addMessageToConsole(scriptState, webInspector, "addMessageToConsole");
+ addMessageToConsole.appendArgument(message);
+ addMessageToConsole.call(hadException);
+}
+
+bool ConsoleMessage::isEqual(ScriptState* state, ConsoleMessage* msg) const
+{
+ if (msg->m_wrappedArguments.size() != m_wrappedArguments.size())
+ return false;
+ if (!state && msg->m_wrappedArguments.size())
+ return false;
+
+ ASSERT_ARG(state, state || msg->m_wrappedArguments.isEmpty());
+
+ for (size_t i = 0; i < msg->m_wrappedArguments.size(); ++i) {
+ if (!m_wrappedArguments[i].isEqual(state, msg->m_wrappedArguments[i]))
+ return false;
+ }
+
+ size_t frameCount = msg->m_frames.size();
+ if (frameCount != m_frames.size())
+ return false;
+
+ for (size_t i = 0; i < frameCount; ++i) {
+ if (m_frames[i] != msg->m_frames[i])
+ return false;
+ }
+
+ return msg->m_source == m_source
+ && msg->m_level == m_level
+ && msg->m_message == m_message
+ && msg->m_line == m_line
+ && msg->m_url == m_url
+ && msg->m_groupLevel == m_groupLevel;
+}
+
+} // namespace WebCore
diff --git a/WebCore/storage/SQLTransactionErrorCallback.idl b/WebCore/inspector/ConsoleMessage.h
index 9355d9a..d97cbb3 100644
--- a/WebCore/storage/SQLTransactionErrorCallback.idl
+++ b/WebCore/inspector/ConsoleMessage.h
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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
@@ -26,10 +28,42 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-module storage {
+#ifndef ConsoleMessage_h
+#define ConsoleMessage_h
- interface SQLTransactionErrorCallback {
- void handleEvent(in SQLError error);
+#include "Console.h"
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <runtime/Protect.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class ScriptCallStack;
+ class ScriptString;
+
+ class ConsoleMessage {
+ public:
+ ConsoleMessage(MessageSource, MessageLevel, const String& m, unsigned li, const String& u, unsigned g);
+ ConsoleMessage(MessageSource, MessageLevel, ScriptCallStack*, unsigned g, bool storeTrace = false);
+
+ void addToConsole(ScriptState*, const ScriptObject& webInspector);
+ void incrementCount() { ++m_repeatCount; };
+ bool isEqual(ScriptState*, ConsoleMessage* msg) const;
+
+ private:
+ MessageSource m_source;
+ MessageLevel m_level;
+ String m_message;
+ Vector<ScriptValue> m_wrappedArguments;
+ Vector<ScriptString> m_frames;
+ unsigned m_line;
+ String m_url;
+ unsigned m_groupLevel;
+ unsigned m_repeatCount;
};
-}
+} // namespace WebCore
+
+#endif // ConsoleMessage_h
diff --git a/WebCore/inspector/InspectorClient.h b/WebCore/inspector/InspectorClient.h
index fcbf79d..2508536 100644
--- a/WebCore/inspector/InspectorClient.h
+++ b/WebCore/inspector/InspectorClient.h
@@ -44,6 +44,8 @@ public:
virtual String localizedStringsURL() = 0;
+ virtual String hiddenPanels() = 0;
+
virtual void showWindow() = 0;
virtual void closeWindow() = 0;
diff --git a/WebCore/inspector/InspectorController.cpp b/WebCore/inspector/InspectorController.cpp
index 5cdc368..ae50769 100644
--- a/WebCore/inspector/InspectorController.cpp
+++ b/WebCore/inspector/InspectorController.cpp
@@ -33,6 +33,7 @@
#include "CString.h"
#include "CachedResource.h"
#include "Console.h"
+#include "ConsoleMessage.h"
#include "DOMWindow.h"
#include "DocLoader.h"
#include "Document.h"
@@ -46,34 +47,40 @@
#include "FrameTree.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "HitTestResult.h"
#include "HTMLFrameOwnerElement.h"
+#include "HitTestResult.h"
#include "InspectorClient.h"
+#include "InspectorDatabaseResource.h"
+#include "InspectorDOMStorageResource.h"
+#include "InspectorResource.h"
#include "JSDOMWindow.h"
#include "JSInspectedObjectWrapper.h"
#include "JSInspectorCallbackWrapper.h"
+#include "JSInspectorController.h"
#include "JSNode.h"
#include "JSRange.h"
#include "JavaScriptProfile.h"
#include "Page.h"
#include "Range.h"
+#include "RenderInline.h"
#include "ResourceRequest.h"
#include "ResourceResponse.h"
-#include "Settings.h"
#include "ScriptCallStack.h"
+#include "ScriptController.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
#include "SharedBuffer.h"
#include "TextEncoding.h"
#include "TextIterator.h"
-#include "ScriptController.h"
#include <JavaScriptCore/APICast.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <JavaScriptCore/JSStringRef.h>
#include <JavaScriptCore/OpaqueJSString.h>
-#include <runtime/JSLock.h>
-#include <runtime/UString.h>
-#include <runtime/CollectorHeapIterator.h>
#include <profiler/Profile.h>
#include <profiler/Profiler.h>
+#include <runtime/CollectorHeapIterator.h>
+#include <runtime/JSLock.h>
+#include <runtime/UString.h>
#include <wtf/CurrentTime.h>
#include <wtf/RefCounted.h>
#include <wtf/StdLibExtras.h>
@@ -83,6 +90,12 @@
#include "JSDatabase.h"
#endif
+#if ENABLE(DOM_STORAGE)
+#include "Storage.h"
+#include "StorageArea.h"
+#include "JSStorage.h"
+#endif
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
#include "JavaScriptCallFrame.h"
#include "JavaScriptDebugServer.h"
@@ -158,354 +171,7 @@ JSValueRef InspectorController::callFunction(JSContextRef context, JSObjectRef t
return result;
}
-// ConsoleMessage Struct
-
-struct ConsoleMessage {
- ConsoleMessage(MessageSource s, MessageLevel l, const String& m, unsigned li, const String& u, unsigned g)
- : source(s)
- , level(l)
- , message(m)
- , line(li)
- , url(u)
- , groupLevel(g)
- , repeatCount(1)
- {
- }
-
- ConsoleMessage(MessageSource s, MessageLevel l, ScriptCallStack* callStack, unsigned g, bool storeTrace = false)
- : source(s)
- , level(l)
- , wrappedArguments(callStack->at(0).argumentCount())
- , frames(storeTrace ? callStack->size() : 0)
- , groupLevel(g)
- , repeatCount(1)
- {
- const ScriptCallFrame& lastCaller = callStack->at(0);
- line = lastCaller.lineNumber();
- url = lastCaller.sourceURL().string();
-
- // FIXME: For now, just store function names as strings.
- // As ScriptCallStack start storing line number and source URL for all
- // frames, refactor to use that, as well.
- if (storeTrace) {
- unsigned stackSize = callStack->size();
- for (unsigned i = 0; i < stackSize; ++i)
- frames[i] = callStack->at(i).functionName();
- }
-
- JSLock lock(false);
-
- for (unsigned i = 0; i < lastCaller.argumentCount(); ++i)
- wrappedArguments[i] = JSInspectedObjectWrapper::wrap(callStack->state(), lastCaller.argumentAt(i).jsValue());
- }
-
- bool isEqual(ExecState* exec, ConsoleMessage* msg) const
- {
- if (msg->wrappedArguments.size() != this->wrappedArguments.size() ||
- (!exec && msg->wrappedArguments.size()))
- return false;
-
- for (size_t i = 0; i < msg->wrappedArguments.size(); ++i) {
- ASSERT_ARG(exec, exec);
- if (!JSValueIsEqual(toRef(exec), toRef(msg->wrappedArguments[i].get()), toRef(this->wrappedArguments[i].get()), 0))
- return false;
- }
-
- size_t frameCount = msg->frames.size();
- if (frameCount != this->frames.size())
- return false;
-
- for (size_t i = 0; i < frameCount; ++i) {
- const ScriptString& myFrameFunctionName = this->frames[i];
- if (myFrameFunctionName != msg->frames[i])
- return false;
- }
-
- return msg->source == this->source
- && msg->level == this->level
- && msg->message == this->message
- && msg->line == this->line
- && msg->url == this->url
- && msg->groupLevel == this->groupLevel;
- }
-
- MessageSource source;
- MessageLevel level;
- String message;
- Vector<ProtectedJSValuePtr> wrappedArguments;
- Vector<ScriptString> frames;
- unsigned line;
- String url;
- unsigned groupLevel;
- unsigned repeatCount;
-};
-
-// XMLHttpRequestResource Class
-
-struct XMLHttpRequestResource {
- XMLHttpRequestResource(const JSC::UString& sourceString)
- {
- JSC::JSLock lock(false);
- this->sourceString = sourceString.rep();
- }
-
- ~XMLHttpRequestResource()
- {
- JSC::JSLock lock(false);
- sourceString.clear();
- }
-
- RefPtr<JSC::UString::Rep> sourceString;
-};
-
-// InspectorResource Struct
-
-struct InspectorResource : public RefCounted<InspectorResource> {
- // Keep these in sync with WebInspector.Resource.Type
- enum Type {
- Doc,
- Stylesheet,
- Image,
- Font,
- Script,
- XHR,
- Media,
- Other
- };
-
- static PassRefPtr<InspectorResource> create(long long identifier, DocumentLoader* documentLoader, Frame* frame)
- {
- return adoptRef(new InspectorResource(identifier, documentLoader, frame));
- }
-
- ~InspectorResource()
- {
- setScriptObject(0, 0);
- }
-
- Type type() const
- {
- if (xmlHttpRequestResource)
- return XHR;
-
- if (requestURL == loader->requestURL())
- return Doc;
-
- if (loader->frameLoader() && requestURL == loader->frameLoader()->iconURL())
- return Image;
-
- CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
- if (!cachedResource)
- return Other;
-
- switch (cachedResource->type()) {
- case CachedResource::ImageResource:
- return Image;
- case CachedResource::FontResource:
- return Font;
- case CachedResource::CSSStyleSheet:
-#if ENABLE(XSLT)
- case CachedResource::XSLStyleSheet:
-#endif
- return Stylesheet;
- case CachedResource::Script:
- return Script;
- default:
- return Other;
- }
- }
-
- void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
- {
- if (scriptContext && scriptObject)
- JSValueUnprotect(scriptContext, scriptObject);
-
- scriptObject = newScriptObject;
- scriptContext = context;
-
- ASSERT((context && newScriptObject) || (!context && !newScriptObject));
- if (context && newScriptObject)
- JSValueProtect(context, newScriptObject);
- }
-
- void setXMLHttpRequestProperties(const JSC::UString& data)
- {
- xmlHttpRequestResource.set(new XMLHttpRequestResource(data));
- }
-
- String sourceString() const
- {
- if (xmlHttpRequestResource)
- return JSC::UString(xmlHttpRequestResource->sourceString);
-
- RefPtr<SharedBuffer> buffer;
- String textEncodingName;
-
- if (requestURL == loader->requestURL()) {
- buffer = loader->mainResourceData();
- textEncodingName = frame->document()->inputEncoding();
- } else {
- CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
- if (!cachedResource)
- return String();
-
- if (cachedResource->isPurgeable()) {
- // If the resource is purgeable then make it unpurgeable to get
- // get its data. This might fail, in which case we return an
- // empty String.
- // FIXME: should we do something else in the case of a purged
- // resource that informs the user why there is no data in the
- // inspector?
- if (!cachedResource->makePurgeable(false))
- return String();
- }
-
- buffer = cachedResource->data();
- textEncodingName = cachedResource->encoding();
- }
-
- if (!buffer)
- return String();
-
- TextEncoding encoding(textEncodingName);
- if (!encoding.isValid())
- encoding = WindowsLatin1Encoding();
- return encoding.decode(buffer->data(), buffer->size());
- }
-
- long long identifier;
- RefPtr<DocumentLoader> loader;
- RefPtr<Frame> frame;
- OwnPtr<XMLHttpRequestResource> xmlHttpRequestResource;
- KURL requestURL;
- HTTPHeaderMap requestHeaderFields;
- HTTPHeaderMap responseHeaderFields;
- String mimeType;
- String suggestedFilename;
- JSContextRef scriptContext;
- JSObjectRef scriptObject;
- long long expectedContentLength;
- bool cached;
- bool finished;
- bool failed;
- int length;
- int responseStatusCode;
- double startTime;
- double responseReceivedTime;
- double endTime;
-
-protected:
- InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame)
- : identifier(identifier)
- , loader(documentLoader)
- , frame(frame)
- , xmlHttpRequestResource(0)
- , scriptContext(0)
- , scriptObject(0)
- , expectedContentLength(0)
- , cached(false)
- , finished(false)
- , failed(false)
- , length(0)
- , responseStatusCode(0)
- , startTime(-1.0)
- , responseReceivedTime(-1.0)
- , endTime(-1.0)
- {
- }
-};
-
-// InspectorDatabaseResource Struct
-
-#if ENABLE(DATABASE)
-struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
- static PassRefPtr<InspectorDatabaseResource> create(Database* database, const String& domain, const String& name, const String& version)
- {
- return adoptRef(new InspectorDatabaseResource(database, domain, name, version));
- }
-
- void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
- {
- if (scriptContext && scriptObject)
- JSValueUnprotect(scriptContext, scriptObject);
-
- scriptObject = newScriptObject;
- scriptContext = context;
-
- ASSERT((context && newScriptObject) || (!context && !newScriptObject));
- if (context && newScriptObject)
- JSValueProtect(context, newScriptObject);
- }
-
- RefPtr<Database> database;
- String domain;
- String name;
- String version;
- JSContextRef scriptContext;
- JSObjectRef scriptObject;
-
-private:
- InspectorDatabaseResource(Database* database, const String& domain, const String& name, const String& version)
- : database(database)
- , domain(domain)
- , name(name)
- , version(version)
- , scriptContext(0)
- , scriptObject(0)
- {
- }
-};
-#endif
-
-// JavaScript Callbacks
-
-#define SIMPLE_INSPECTOR_CALLBACK(jsFunction, inspectorControllerMethod) \
-static JSValueRef jsFunction(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) \
-{ \
- if (InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject))) \
- controller->inspectorControllerMethod(); \
- return JSValueMakeUndefined(ctx); \
-}
-
-SIMPLE_INSPECTOR_CALLBACK(hideDOMNodeHighlight, hideHighlight);
-SIMPLE_INSPECTOR_CALLBACK(loaded, scriptObjectReady);
-SIMPLE_INSPECTOR_CALLBACK(unloading, close);
-SIMPLE_INSPECTOR_CALLBACK(attach, attachWindow);
-SIMPLE_INSPECTOR_CALLBACK(detach, detachWindow);
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-SIMPLE_INSPECTOR_CALLBACK(enableDebugger, enableDebugger);
-SIMPLE_INSPECTOR_CALLBACK(disableDebugger, disableDebugger);
-SIMPLE_INSPECTOR_CALLBACK(pauseInDebugger, pauseInDebugger);
-SIMPLE_INSPECTOR_CALLBACK(resumeDebugger, resumeDebugger);
-SIMPLE_INSPECTOR_CALLBACK(stepOverStatementInDebugger, stepOverStatementInDebugger);
-SIMPLE_INSPECTOR_CALLBACK(stepIntoStatementInDebugger, stepIntoStatementInDebugger);
-SIMPLE_INSPECTOR_CALLBACK(stepOutOfFunctionInDebugger, stepOutOfFunctionInDebugger);
-#endif
-SIMPLE_INSPECTOR_CALLBACK(closeWindow, closeWindow);
-SIMPLE_INSPECTOR_CALLBACK(clearMessages, clearConsoleMessages);
-SIMPLE_INSPECTOR_CALLBACK(startProfiling, startUserInitiatedProfilingSoon);
-SIMPLE_INSPECTOR_CALLBACK(stopProfiling, stopUserInitiatedProfiling);
-SIMPLE_INSPECTOR_CALLBACK(enableProfiler, enableProfiler);
-SIMPLE_INSPECTOR_CALLBACK(disableProfiler, disableProfiler);
-SIMPLE_INSPECTOR_CALLBACK(toggleNodeSearch, toggleSearchForNodeInPage);
-
-#define BOOL_INSPECTOR_CALLBACK(jsFunction, inspectorControllerMethod) \
-static JSValueRef jsFunction(JSContextRef ctx, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*) \
-{ \
- if (InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject))) \
- return JSValueMakeBoolean(ctx, controller->inspectorControllerMethod()); \
- return JSValueMakeUndefined(ctx); \
-}
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-BOOL_INSPECTOR_CALLBACK(debuggerEnabled, debuggerEnabled);
-BOOL_INSPECTOR_CALLBACK(pauseOnExceptions, pauseOnExceptions);
-#endif
-BOOL_INSPECTOR_CALLBACK(profilerEnabled, profilerEnabled);
-BOOL_INSPECTOR_CALLBACK(isWindowVisible, windowVisible);
-BOOL_INSPECTOR_CALLBACK(searchingForNode, searchingForNodeInPage);
-
-static bool addSourceToFrame(const String& mimeType, const String& source, Node* frameNode)
+bool InspectorController::addSourceToFrame(const String& mimeType, const String& source, Node* frameNode)
{
ASSERT_ARG(frameNode, frameNode);
@@ -541,362 +207,7 @@ static bool addSourceToFrame(const String& mimeType, const String& source, Node*
return true;
}
-static JSValueRef addResourceSourceToFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 2 || !controller)
- return undefined;
-
- JSValueRef identifierValue = arguments[0];
- if (!JSValueIsNumber(ctx, identifierValue))
- return undefined;
-
- long long identifier = static_cast<long long>(JSValueToNumber(ctx, identifierValue, exception));
- if (exception && *exception)
- return undefined;
-
- RefPtr<InspectorResource> resource = controller->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return undefined;
-
- String sourceString = resource->sourceString();
- if (sourceString.isEmpty())
- return undefined;
-
- bool successfullyAddedSource = addSourceToFrame(resource->mimeType, sourceString, toNode(toJS(arguments[1])));
- return JSValueMakeBoolean(ctx, successfullyAddedSource);
-}
-
-static JSValueRef addSourceToFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 3 || !controller)
- return undefined;
-
- JSValueRef mimeTypeValue = arguments[0];
- if (!JSValueIsString(ctx, mimeTypeValue))
- return undefined;
-
- JSValueRef sourceValue = arguments[1];
- if (!JSValueIsString(ctx, sourceValue))
- return undefined;
-
- String mimeType = toString(ctx, mimeTypeValue, exception);
- if (mimeType.isEmpty())
- return undefined;
-
- String source = toString(ctx, sourceValue, exception);
- if (source.isEmpty())
- return undefined;
-
- bool successfullyAddedSource = addSourceToFrame(mimeType, source, toNode(toJS(arguments[2])));
- return JSValueMakeBoolean(ctx, successfullyAddedSource);
-}
-
-static JSValueRef getResourceDocumentNode(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- JSValueRef undefined = JSValueMakeUndefined(ctx);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!argumentCount || argumentCount > 1 || !controller)
- return undefined;
-
- JSValueRef identifierValue = arguments[0];
- if (!JSValueIsNumber(ctx, identifierValue))
- return undefined;
-
- long long identifier = static_cast<long long>(JSValueToNumber(ctx, identifierValue, exception));
- if (exception && *exception)
- return undefined;
-
- RefPtr<InspectorResource> resource = controller->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return undefined;
-
- Frame* frame = resource->frame.get();
-
- Document* document = frame->document();
- if (!document)
- return undefined;
-
- if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument())
- return undefined;
-
- ExecState* exec = toJSDOMWindowShell(resource->frame.get())->window()->globalExec();
-
- JSC::JSLock lock(false);
- JSValueRef documentValue = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, document)));
- return documentValue;
-}
-
-static JSValueRef highlightDOMNode(JSContextRef context, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- JSValueRef undefined = JSValueMakeUndefined(context);
-
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (argumentCount < 1 || !controller)
- return undefined;
-
- JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(toJS(arguments[0]));
- if (!wrapper)
- return undefined;
- Node* node = toNode(wrapper->unwrappedObject());
- if (!node)
- return undefined;
-
- controller->highlight(node);
-
- return undefined;
-}
-
-static JSValueRef search(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2 || !JSValueIsString(ctx, arguments[1]))
- return JSValueMakeUndefined(ctx);
-
- Node* node = toNode(toJS(arguments[0]));
- if (!node)
- return JSValueMakeUndefined(ctx);
-
- String target = toString(ctx, arguments[1], exception);
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, jsStringRef("Array").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, jsStringRef("push").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- RefPtr<Range> searchRange(rangeOfContents(node));
-
- ExceptionCode ec = 0;
- do {
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
- if (resultRange->collapsed(ec))
- break;
-
- // A non-collapsed result range can in some funky whitespace cases still not
- // advance the range's start position (4509328). Break to avoid infinite loop.
- VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
- if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
- break;
-
- JSC::JSLock lock(false);
- JSValueRef arg0 = toRef(toJS(toJS(ctx), resultRange.get()));
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- setStart(searchRange.get(), newStart);
- } while (true);
-
- return result;
-}
-
-#if ENABLE(DATABASE)
-static JSValueRef databaseTableNames(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- JSQuarantinedObjectWrapper* wrapper = JSQuarantinedObjectWrapper::asWrapper(toJS(arguments[0]));
- if (!wrapper)
- return JSValueMakeUndefined(ctx);
-
- Database* database = toDatabase(wrapper->unwrappedObject());
- if (!database)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, jsStringRef("Array").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, jsStringRef("push").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- Vector<String> tableNames = database->tableNames();
- unsigned length = tableNames.size();
- for (unsigned i = 0; i < length; ++i) {
- String tableName = tableNames[i];
- JSValueRef tableNameValue = JSValueMakeString(ctx, jsStringRef(tableName).get());
-
- JSValueRef pushArguments[] = { tableNameValue };
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, pushArguments, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- return result;
-}
-#endif
-
-static JSValueRef inspectedWindow(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSDOMWindow* inspectedWindow = toJSDOMWindow(controller->inspectedPage()->mainFrame());
- JSLock lock(false);
- return toRef(JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow));
-}
-
-static JSValueRef setting(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef keyValue = arguments[0];
- if (!JSValueIsString(ctx, keyValue))
- return JSValueMakeUndefined(ctx);
-
- const InspectorController::Setting& setting = controller->setting(toString(ctx, keyValue, exception));
-
- switch (setting.type()) {
- default:
- case InspectorController::Setting::NoType:
- return JSValueMakeUndefined(ctx);
- case InspectorController::Setting::StringType:
- return JSValueMakeString(ctx, jsStringRef(setting.string()).get());
- case InspectorController::Setting::DoubleType:
- return JSValueMakeNumber(ctx, setting.doubleValue());
- case InspectorController::Setting::IntegerType:
- return JSValueMakeNumber(ctx, setting.integerValue());
- case InspectorController::Setting::BooleanType:
- return JSValueMakeBoolean(ctx, setting.booleanValue());
- case InspectorController::Setting::StringVectorType: {
- Vector<JSValueRef> stringValues;
- const Vector<String>& strings = setting.stringVector();
- const unsigned length = strings.size();
- for (unsigned i = 0; i < length; ++i)
- stringValues.append(JSValueMakeString(ctx, jsStringRef(strings[i]).get()));
-
- JSObjectRef stringsArray = JSObjectMakeArray(ctx, stringValues.size(), stringValues.data(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- return stringsArray;
- }
- }
-}
-
-static JSValueRef setSetting(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef keyValue = arguments[0];
- if (!JSValueIsString(ctx, keyValue))
- return JSValueMakeUndefined(ctx);
-
- InspectorController::Setting setting;
-
- JSValueRef value = arguments[1];
- switch (JSValueGetType(ctx, value)) {
- default:
- case kJSTypeUndefined:
- case kJSTypeNull:
- // Do nothing. The setting is already NoType.
- ASSERT(setting.type() == InspectorController::Setting::NoType);
- break;
- case kJSTypeString:
- setting.set(toString(ctx, value, exception));
- break;
- case kJSTypeNumber:
- setting.set(JSValueToNumber(ctx, value, exception));
- break;
- case kJSTypeBoolean:
- setting.set(JSValueToBoolean(ctx, value));
- break;
- case kJSTypeObject: {
- JSObjectRef object = JSValueToObject(ctx, value, 0);
- JSValueRef lengthValue = JSObjectGetProperty(ctx, object, jsStringRef("length").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- Vector<String> strings;
- const unsigned length = static_cast<unsigned>(JSValueToNumber(ctx, lengthValue, 0));
- for (unsigned i = 0; i < length; ++i) {
- JSValueRef itemValue = JSObjectGetPropertyAtIndex(ctx, object, i, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- strings.append(toString(ctx, itemValue, exception));
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- setting.set(strings);
- break;
- }
- }
-
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->setSetting(toString(ctx, keyValue, exception), setting);
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef localizedStrings(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- String url = controller->localizedStringsURL();
- if (url.isNull())
- return JSValueMakeNull(ctx);
-
- return JSValueMakeString(ctx, jsStringRef(url).get());
-}
-
-static JSValueRef platform(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef /*thisObject*/, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
+const String& InspectorController::platform() const
{
#if PLATFORM(MAC)
#ifdef BUILDING_ON_TIGER
@@ -916,184 +227,9 @@ static JSValueRef platform(JSContextRef ctx, JSObjectRef /*function*/, JSObjectR
DEFINE_STATIC_LOCAL(const String, platform, ("unknown"));
#endif
- JSValueRef platformValue = JSValueMakeString(ctx, jsStringRef(platform).get());
-
- return platformValue;
-}
-
-static JSValueRef moveByUnrestricted(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- double x = JSValueToNumber(ctx, arguments[0], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- double y = JSValueToNumber(ctx, arguments[1], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->moveWindowBy(narrowPrecisionToFloat(x), narrowPrecisionToFloat(y));
-
- return JSValueMakeUndefined(ctx);
+ return platform;
}
-static JSValueRef setAttachedWindowHeight(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- unsigned height = static_cast<unsigned>(JSValueToNumber(ctx, arguments[0], exception));
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->setAttachedWindowHeight(height);
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef wrapCallback(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- JSLock lock(false);
- return toRef(JSInspectorCallbackWrapper::wrap(toJS(ctx), toJS(arguments[0])));
-}
-
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-static JSValueRef currentCallFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JavaScriptCallFrame* callFrame = controller->currentCallFrame();
- if (!callFrame || !callFrame->isValid())
- return JSValueMakeNull(ctx);
-
- ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec();
-
- JSLock lock(false);
- return toRef(JSInspectedObjectWrapper::wrap(globalExec, toJS(toJS(ctx), callFrame)));
-}
-
-static JSValueRef setPauseOnExceptions(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 1)
- return JSValueMakeUndefined(ctx);
-
- controller->setPauseOnExceptions(JSValueToBoolean(ctx, arguments[0]));
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef addBreakpoint(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- double sourceID = JSValueToNumber(ctx, arguments[0], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- double lineNumber = JSValueToNumber(ctx, arguments[1], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->addBreakpoint(static_cast<int>(sourceID), static_cast<unsigned>(lineNumber));
-
- return JSValueMakeUndefined(ctx);
-}
-
-static JSValueRef removeBreakpoint(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- if (argumentCount < 2)
- return JSValueMakeUndefined(ctx);
-
- double sourceID = JSValueToNumber(ctx, arguments[0], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- double lineNumber = JSValueToNumber(ctx, arguments[1], exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- controller->removeBreakpoint(static_cast<int>(sourceID), static_cast<unsigned>(lineNumber));
-
- return JSValueMakeUndefined(ctx);
-}
-#endif
-
-static JSValueRef profiles(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments*/, JSValueRef* exception)
-{
- InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
- if (!controller)
- return JSValueMakeUndefined(ctx);
-
- JSLock lock(false);
-
- const Vector<RefPtr<Profile> >& profiles = controller->profiles();
-
- JSObjectRef global = JSContextGetGlobalObject(ctx);
-
- JSValueRef arrayProperty = JSObjectGetProperty(ctx, global, jsStringRef("Array").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef arrayConstructor = JSValueToObject(ctx, arrayProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSValueRef pushProperty = JSObjectGetProperty(ctx, result, jsStringRef("push").get(), exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- JSObjectRef pushFunction = JSValueToObject(ctx, pushProperty, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
-
- for (size_t i = 0; i < profiles.size(); ++i) {
- JSValueRef arg0 = toRef(toJS(toJS(ctx), profiles[i].get()));
- JSObjectCallAsFunction(ctx, pushFunction, result, 1, &arg0, exception);
- if (exception && *exception)
- return JSValueMakeUndefined(ctx);
- }
-
- return result;
-}
-
-// InspectorController Class
-
static unsigned s_inspectorControllerCount;
static HashMap<String, InspectorController::Setting*>* s_settingCache;
@@ -1225,6 +361,13 @@ String InspectorController::localizedStringsURL()
return m_client->localizedStringsURL();
}
+String InspectorController::hiddenPanels()
+{
+ if (!enabled())
+ return String();
+ return m_client->hiddenPanels();
+}
+
// Trying to inspect something in a frame with JavaScript disabled would later lead to
// crashes trying to create JavaScript wrappers. Some day we could fix this issue, but
// for now prevent crashes here by never targeting a node in such a frame.
@@ -1297,6 +440,7 @@ void InspectorController::hideHighlight()
{
if (!enabled())
return;
+ m_highlightedNode = 0;
m_client->hideHighlight();
}
@@ -1358,7 +502,7 @@ void InspectorController::addConsoleMessage(ExecState* exec, ConsoleMessage* con
ASSERT_ARG(consoleMessage, consoleMessage);
if (m_previousMessage && m_previousMessage->isEqual(exec, consoleMessage)) {
- ++m_previousMessage->repeatCount;
+ m_previousMessage->incrementCount();
delete consoleMessage;
} else {
m_previousMessage = consoleMessage;
@@ -1366,7 +510,7 @@ void InspectorController::addConsoleMessage(ExecState* exec, ConsoleMessage* con
}
if (windowVisible())
- addScriptConsoleMessage(m_previousMessage);
+ m_previousMessage->addToConsole(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
}
void InspectorController::clearConsoleMessages()
@@ -1520,83 +664,16 @@ void InspectorController::windowScriptObjectAvailable()
if (!m_page || !enabled())
return;
- m_scriptContext = toRef(m_page->mainFrame()->script()->globalObject()->globalExec());
+ // Grant the inspector the ability to script the inspected page.
+ m_page->mainFrame()->document()->securityOrigin()->grantUniversalAccess();
- JSObjectRef global = JSContextGetGlobalObject(m_scriptContext);
- ASSERT(global);
-
- static JSStaticFunction staticFunctions[] = {
- // SIMPLE_INSPECTOR_CALLBACK
- { "hideDOMNodeHighlight", WebCore::hideDOMNodeHighlight, kJSPropertyAttributeNone },
- { "loaded", WebCore::loaded, kJSPropertyAttributeNone },
- { "windowUnloading", WebCore::unloading, kJSPropertyAttributeNone },
- { "attach", WebCore::attach, kJSPropertyAttributeNone },
- { "detach", WebCore::detach, kJSPropertyAttributeNone },
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- { "enableDebugger", WebCore::enableDebugger, kJSPropertyAttributeNone },
- { "disableDebugger", WebCore::disableDebugger, kJSPropertyAttributeNone },
- { "pauseInDebugger", WebCore::pauseInDebugger, kJSPropertyAttributeNone },
- { "resumeDebugger", WebCore::resumeDebugger, kJSPropertyAttributeNone },
- { "stepOverStatementInDebugger", WebCore::stepOverStatementInDebugger, kJSPropertyAttributeNone },
- { "stepIntoStatementInDebugger", WebCore::stepIntoStatementInDebugger, kJSPropertyAttributeNone },
- { "stepOutOfFunctionInDebugger", WebCore::stepOutOfFunctionInDebugger, kJSPropertyAttributeNone },
-#endif
- { "closeWindow", WebCore::closeWindow, kJSPropertyAttributeNone },
- { "clearMessages", WebCore::clearMessages, kJSPropertyAttributeNone },
- { "startProfiling", WebCore::startProfiling, kJSPropertyAttributeNone },
- { "stopProfiling", WebCore::stopProfiling, kJSPropertyAttributeNone },
- { "enableProfiler", WebCore::enableProfiler, kJSPropertyAttributeNone },
- { "disableProfiler", WebCore::disableProfiler, kJSPropertyAttributeNone },
- { "toggleNodeSearch", WebCore::toggleNodeSearch, kJSPropertyAttributeNone },
-
- // BOOL_INSPECTOR_CALLBACK
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- { "debuggerEnabled", WebCore::debuggerEnabled, kJSPropertyAttributeNone },
- { "pauseOnExceptions", WebCore::pauseOnExceptions, kJSPropertyAttributeNone },
-#endif
- { "profilerEnabled", WebCore::profilerEnabled, kJSPropertyAttributeNone },
- { "isWindowVisible", WebCore::isWindowVisible, kJSPropertyAttributeNone },
- { "searchingForNode", WebCore::searchingForNode, kJSPropertyAttributeNone },
-
- // Custom callbacks
- { "addResourceSourceToFrame", WebCore::addResourceSourceToFrame, kJSPropertyAttributeNone },
- { "addSourceToFrame", WebCore::addSourceToFrame, kJSPropertyAttributeNone },
- { "getResourceDocumentNode", WebCore::getResourceDocumentNode, kJSPropertyAttributeNone },
- { "highlightDOMNode", WebCore::highlightDOMNode, kJSPropertyAttributeNone },
- { "search", WebCore::search, kJSPropertyAttributeNone },
-#if ENABLE(DATABASE)
- { "databaseTableNames", WebCore::databaseTableNames, kJSPropertyAttributeNone },
-#endif
- { "setting", WebCore::setting, kJSPropertyAttributeNone },
- { "setSetting", WebCore::setSetting, kJSPropertyAttributeNone },
- { "inspectedWindow", WebCore::inspectedWindow, kJSPropertyAttributeNone },
- { "localizedStringsURL", WebCore::localizedStrings, kJSPropertyAttributeNone },
- { "platform", WebCore::platform, kJSPropertyAttributeNone },
- { "moveByUnrestricted", WebCore::moveByUnrestricted, kJSPropertyAttributeNone },
- { "setAttachedWindowHeight", WebCore::setAttachedWindowHeight, kJSPropertyAttributeNone },
- { "wrapCallback", WebCore::wrapCallback, kJSPropertyAttributeNone },
-#if ENABLE(JAVASCRIPT_DEBUGGER)
- { "currentCallFrame", WebCore::currentCallFrame, kJSPropertyAttributeNone },
- { "setPauseOnExceptions", WebCore::setPauseOnExceptions, kJSPropertyAttributeNone },
- { "addBreakpoint", WebCore::addBreakpoint, kJSPropertyAttributeNone },
- { "removeBreakpoint", WebCore::removeBreakpoint, kJSPropertyAttributeNone },
-#endif
- { "profiles", WebCore::profiles, kJSPropertyAttributeNone },
- { 0, 0, 0 }
- };
-
- JSClassDefinition inspectorControllerDefinition = {
- 0, kJSClassAttributeNone, "InspectorController", 0, 0, staticFunctions,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- JSClassRef controllerClass = JSClassCreate(&inspectorControllerDefinition);
- ASSERT(controllerClass);
-
- m_controllerScriptObject = JSObjectMake(m_scriptContext, controllerClass, reinterpret_cast<void*>(this));
- ASSERT(m_controllerScriptObject);
-
- JSObjectSetProperty(m_scriptContext, global, jsStringRef("InspectorController").get(), m_controllerScriptObject, kJSPropertyAttributeNone, 0);
+ // FIXME: This should be cleaned up. API Mix-up.
+ JSGlobalObject* globalObject = m_page->mainFrame()->script()->globalObject();
+ ExecState* exec = globalObject->globalExec();
+ m_scriptContext = toRef(exec);
+ JSValuePtr jsInspector = toJS(exec, this);
+ m_controllerScriptObject = toRef(asObject(jsInspector));
+ globalObject->putDirect(Identifier(exec, "InspectorController"), jsInspector);
}
void InspectorController::scriptObjectReady()
@@ -2103,145 +1180,20 @@ void InspectorController::populateScriptObjects()
unsigned messageCount = m_consoleMessages.size();
for (unsigned i = 0; i < messageCount; ++i)
- addScriptConsoleMessage(m_consoleMessages[i]);
+ m_consoleMessages[i]->addToConsole(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
#if ENABLE(DATABASE)
DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
- addDatabaseScriptResource((*it).get());
+ (*it)->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
#endif
-
- callSimpleFunction(m_scriptContext, m_scriptObject, "populateInterface");
-}
-
-#if ENABLE(DATABASE)
-JSObjectRef InspectorController::addDatabaseScriptResource(InspectorDatabaseResource* resource)
-{
- ASSERT_ARG(resource, resource);
-
- if (resource->scriptObject)
- return resource->scriptObject;
-
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return 0;
-
- Frame* frame = resource->database->document()->frame();
- if (!frame)
- return 0;
-
- JSValueRef exception = 0;
-
- JSValueRef databaseProperty = JSObjectGetProperty(m_scriptContext, m_scriptObject, jsStringRef("Database").get(), &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return 0;
-
- JSObjectRef databaseConstructor = JSValueToObject(m_scriptContext, databaseProperty, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return 0;
-
- ExecState* exec = toJSDOMWindow(frame)->globalExec();
-
- JSValueRef database;
-
- {
- JSC::JSLock lock(false);
- database = toRef(JSInspectedObjectWrapper::wrap(exec, toJS(exec, resource->database.get())));
- }
-
- JSValueRef domainValue = JSValueMakeString(m_scriptContext, jsStringRef(resource->domain).get());
- JSValueRef nameValue = JSValueMakeString(m_scriptContext, jsStringRef(resource->name).get());
- JSValueRef versionValue = JSValueMakeString(m_scriptContext, jsStringRef(resource->version).get());
-
- JSValueRef arguments[] = { database, domainValue, nameValue, versionValue };
- JSObjectRef result = JSObjectCallAsConstructor(m_scriptContext, databaseConstructor, 4, arguments, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return 0;
-
- ASSERT(result);
-
- callFunction(m_scriptContext, m_scriptObject, "addDatabase", 1, &result, exception);
-
- if (exception)
- return 0;
-
- resource->setScriptObject(m_scriptContext, result);
-
- return result;
-}
-
-void InspectorController::removeDatabaseScriptResource(InspectorDatabaseResource* resource)
-{
- ASSERT(m_scriptContext);
- ASSERT(m_scriptObject);
- if (!m_scriptContext || !m_scriptObject)
- return;
-
- ASSERT(resource);
- ASSERT(resource->scriptObject);
- if (!resource || !resource->scriptObject)
- return;
-
- JSObjectRef scriptObject = resource->scriptObject;
- resource->setScriptObject(0, 0);
-
- JSValueRef exception = 0;
- callFunction(m_scriptContext, m_scriptObject, "removeDatabase", 1, &scriptObject, exception);
-}
+#if ENABLE(DOM_STORAGE)
+ DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
+ for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+ (*it)->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
#endif
-void InspectorController::addScriptConsoleMessage(const ConsoleMessage* message)
-{
- ASSERT_ARG(message, message);
-
- JSValueRef exception = 0;
-
- JSValueRef messageConstructorProperty = JSObjectGetProperty(m_scriptContext, m_scriptObject, jsStringRef("ConsoleMessage").get(), &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return;
-
- JSObjectRef messageConstructor = JSValueToObject(m_scriptContext, messageConstructorProperty, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return;
-
- JSValueRef sourceValue = JSValueMakeNumber(m_scriptContext, message->source);
- JSValueRef levelValue = JSValueMakeNumber(m_scriptContext, message->level);
- JSValueRef lineValue = JSValueMakeNumber(m_scriptContext, message->line);
- JSValueRef urlValue = JSValueMakeString(m_scriptContext, jsStringRef(message->url).get());
- JSValueRef groupLevelValue = JSValueMakeNumber(m_scriptContext, message->groupLevel);
- JSValueRef repeatCountValue = JSValueMakeNumber(m_scriptContext, message->repeatCount);
-
- static const unsigned maximumMessageArguments = 256;
- JSValueRef arguments[maximumMessageArguments];
- unsigned argumentCount = 0;
- arguments[argumentCount++] = sourceValue;
- arguments[argumentCount++] = levelValue;
- arguments[argumentCount++] = lineValue;
- arguments[argumentCount++] = urlValue;
- arguments[argumentCount++] = groupLevelValue;
- arguments[argumentCount++] = repeatCountValue;
-
- if (!message->frames.isEmpty()) {
- unsigned remainingSpaceInArguments = maximumMessageArguments - argumentCount;
- unsigned argumentsToAdd = min(remainingSpaceInArguments, static_cast<unsigned>(message->frames.size()));
- for (unsigned i = 0; i < argumentsToAdd; ++i)
- arguments[argumentCount++] = JSValueMakeString(m_scriptContext, jsStringRef(message->frames[i]).get());
- } else if (!message->wrappedArguments.isEmpty()) {
- unsigned remainingSpaceInArguments = maximumMessageArguments - argumentCount;
- unsigned argumentsToAdd = min(remainingSpaceInArguments, static_cast<unsigned>(message->wrappedArguments.size()));
- for (unsigned i = 0; i < argumentsToAdd; ++i)
- arguments[argumentCount++] = toRef(message->wrappedArguments[i]);
- } else {
- JSValueRef messageValue = JSValueMakeString(m_scriptContext, jsStringRef(message->message).get());
- arguments[argumentCount++] = messageValue;
- }
-
- JSObjectRef messageObject = JSObjectCallAsConstructor(m_scriptContext, messageConstructor, argumentCount, arguments, &exception);
- if (HANDLE_EXCEPTION(m_scriptContext, exception))
- return;
-
- callFunction(m_scriptContext, m_scriptObject, "addMessageToConsole", 1, &messageObject, exception);
+ callSimpleFunction(m_scriptContext, m_scriptObject, "populateInterface");
}
void InspectorController::addScriptProfile(Profile* profile)
@@ -2265,10 +1217,13 @@ void InspectorController::resetScriptObjects()
#if ENABLE(DATABASE)
DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
- for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) {
- InspectorDatabaseResource* resource = (*it).get();
- resource->setScriptObject(0, 0);
- }
+ for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
+ (*it)->unbind();
+#endif
+#if ENABLE(DOM_STORAGE)
+ DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
+ for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+ (*it)->unbind();
#endif
callSimpleFunction(m_scriptContext, m_scriptObject, "reset");
@@ -2312,6 +1267,9 @@ void InspectorController::didCommitLoad(DocumentLoader* loader)
#if ENABLE(DATABASE)
m_databaseResources.clear();
#endif
+#if ENABLE(DOM_STORAGE)
+ m_domStorageResources.clear();
+#endif
if (windowVisible()) {
resetScriptObjects();
@@ -2555,6 +1513,21 @@ void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identi
updateScriptResourceType(resource);
}
+void InspectorController::scriptImported(unsigned long identifier, const JSC::UString& sourceString)
+{
+ if (!enabled())
+ return;
+
+ InspectorResource* resource = m_resources.get(identifier).get();
+ if (!resource)
+ return;
+
+ resource->setXMLHttpRequestProperties(sourceString);
+
+ if (windowVisible() && resource->scriptObject)
+ updateScriptResourceType(resource);
+}
+
#if ENABLE(DATABASE)
void InspectorController::didOpenDatabase(Database* database, const String& domain, const String& name, const String& version)
@@ -2567,7 +1540,27 @@ void InspectorController::didOpenDatabase(Database* database, const String& doma
m_databaseResources.add(resource);
if (windowVisible())
- addDatabaseScriptResource(resource.get());
+ resource->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
+}
+#endif
+
+#if ENABLE(DOM_STORAGE)
+void InspectorController::didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame)
+{
+ if (!enabled())
+ return;
+
+ DOMStorageResourcesSet::iterator domStorageEnd = m_domStorageResources.end();
+ for (DOMStorageResourcesSet::iterator it = m_domStorageResources.begin(); it != domStorageEnd; ++it)
+ if ((*it)->isSameHostAndType(frame, isLocalStorage))
+ return;
+
+ RefPtr<Storage> domStorage = Storage::create(frame, storageArea);
+ RefPtr<InspectorDOMStorageResource> resource = InspectorDOMStorageResource::create(domStorage.get(), isLocalStorage, frame);
+
+ m_domStorageResources.add(resource);
+ if (windowVisible())
+ resource->bind(toJS(m_scriptContext), ScriptObject(toJS(m_scriptObject)));
}
#endif
@@ -2680,26 +1673,23 @@ void InspectorController::removeBreakpoint(intptr_t sourceID, unsigned lineNumbe
}
#endif
-static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, const Color& fillColor)
+static Path quadToPath(const FloatQuad& quad)
{
- static const int outlineThickness = 2;
- static const Color outlineColor(62, 86, 180, 228);
-
Path quadPath;
quadPath.moveTo(quad.p1());
quadPath.addLineTo(quad.p2());
quadPath.addLineTo(quad.p3());
quadPath.addLineTo(quad.p4());
quadPath.closeSubpath();
-
- // Clear the quad
- {
- context.save();
- context.setCompositeOperation(CompositeClear);
- context.addPath(quadPath);
- context.fillPath();
- context.restore();
- }
+ return quadPath;
+}
+
+static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, const Color& fillColor)
+{
+ static const int outlineThickness = 2;
+ static const Color outlineColor(62, 86, 180, 228);
+
+ Path quadPath = quadToPath(quad);
// Clip out the quad, then draw with a 2px stroke to get a pixel
// of outline (because inflating a quad is hard)
@@ -2722,29 +1712,40 @@ static void drawOutlinedQuad(GraphicsContext& context, const FloatQuad& quad, co
context.fillPath();
}
-static void drawHighlightForBoxes(GraphicsContext& context, const Vector<FloatQuad>& lineBoxQuads, const FloatQuad& contentQuad, const FloatQuad& paddingQuad, const FloatQuad& borderQuad, const FloatQuad& marginQuad)
+static void drawOutlinedQuadWithClip(GraphicsContext& context, const FloatQuad& quad, const FloatQuad& clipQuad, const Color& fillColor)
+{
+ context.save();
+ Path clipQuadPath = quadToPath(clipQuad);
+ context.clipOut(clipQuadPath);
+ drawOutlinedQuad(context, quad, fillColor);
+ context.restore();
+}
+
+static void drawHighlightForBox(GraphicsContext& context, const FloatQuad& contentQuad, const FloatQuad& paddingQuad, const FloatQuad& borderQuad, const FloatQuad& marginQuad)
{
static const Color contentBoxColor(125, 173, 217, 128);
static const Color paddingBoxColor(125, 173, 217, 160);
static const Color borderBoxColor(125, 173, 217, 192);
static const Color marginBoxColor(125, 173, 217, 228);
- if (!lineBoxQuads.isEmpty()) {
- for (size_t i = 0; i < lineBoxQuads.size(); ++i)
- drawOutlinedQuad(context, lineBoxQuads[i], contentBoxColor);
- return;
- }
-
if (marginQuad != borderQuad)
- drawOutlinedQuad(context, marginQuad, marginBoxColor);
+ drawOutlinedQuadWithClip(context, marginQuad, borderQuad, marginBoxColor);
if (borderQuad != paddingQuad)
- drawOutlinedQuad(context, borderQuad, borderBoxColor);
+ drawOutlinedQuadWithClip(context, borderQuad, paddingQuad, borderBoxColor);
if (paddingQuad != contentQuad)
- drawOutlinedQuad(context, paddingQuad, paddingBoxColor);
+ drawOutlinedQuadWithClip(context, paddingQuad, contentQuad, paddingBoxColor);
drawOutlinedQuad(context, contentQuad, contentBoxColor);
}
+static void drawHighlightForLineBoxes(GraphicsContext& context, const Vector<FloatQuad>& lineBoxQuads)
+{
+ static const Color lineBoxColor(125, 173, 217, 128);
+
+ for (size_t i = 0; i < lineBoxQuads.size(); ++i)
+ drawOutlinedQuad(context, lineBoxQuads[i], lineBoxColor);
+}
+
static inline void convertFromFrameToMainFrame(Frame* frame, IntRect& rect)
{
rect = frame->page()->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(rect));
@@ -2761,71 +1762,57 @@ void InspectorController::drawNodeHighlight(GraphicsContext& context) const
if (!m_highlightedNode)
return;
- RenderBox* renderer = m_highlightedNode->renderBox();
+ RenderObject* renderer = m_highlightedNode->renderer();
Frame* containingFrame = m_highlightedNode->document()->frame();
if (!renderer || !containingFrame)
return;
- IntRect contentBox = renderer->contentBoxRect();
-
- // FIXME: Should we add methods to RenderObject to obtain these rects?
- IntRect paddingBox(contentBox.x() - renderer->paddingLeft(), contentBox.y() - renderer->paddingTop(),
- contentBox.width() + renderer->paddingLeft() + renderer->paddingRight(), contentBox.height() + renderer->paddingTop() + renderer->paddingBottom());
- IntRect borderBox(paddingBox.x() - renderer->borderLeft(), paddingBox.y() - renderer->borderTop(),
- paddingBox.width() + renderer->borderLeft() + renderer->borderRight(), paddingBox.height() + renderer->borderTop() + renderer->borderBottom());
- IntRect marginBox(borderBox.x() - renderer->marginLeft(), borderBox.y() - renderer->marginTop(),
- borderBox.width() + renderer->marginLeft() + renderer->marginRight(), borderBox.height() + renderer->marginTop() + renderer->marginBottom());
-
-
IntSize mainFrameOffset = frameToMainFrameOffset(containingFrame);
-
- FloatQuad absContentQuad = renderer->localToAbsoluteQuad(FloatRect(contentBox));
- FloatQuad absPaddingQuad = renderer->localToAbsoluteQuad(FloatRect(paddingBox));
- FloatQuad absBorderQuad = renderer->localToAbsoluteQuad(FloatRect(borderBox));
- FloatQuad absMarginQuad = renderer->localToAbsoluteQuad(FloatRect(marginBox));
-
- absContentQuad.move(mainFrameOffset);
- absPaddingQuad.move(mainFrameOffset);
- absBorderQuad.move(mainFrameOffset);
- absMarginQuad.move(mainFrameOffset);
-
IntRect boundingBox = renderer->absoluteBoundingBoxRect(true);
boundingBox.move(mainFrameOffset);
- Vector<FloatQuad> lineBoxQuads;
- if (renderer->isInline() || (renderer->isText() && !m_highlightedNode->isSVGElement())) {
- // FIXME: We should show margins/padding/border for inlines.
- renderer->collectAbsoluteLineBoxQuads(lineBoxQuads);
- }
-
- for (unsigned i = 0; i < lineBoxQuads.size(); ++i)
- lineBoxQuads[i] += mainFrameOffset;
-
- if (lineBoxQuads.isEmpty() && contentBox.isEmpty()) {
- // If we have no line boxes and our content box is empty, we'll just draw our bounding box.
- // This can happen, e.g., with an <a> enclosing an <img style="float:right">.
- // FIXME: Can we make this better/more accurate? The <a> in the above case has no
- // width/height but the highlight makes it appear to be the size of the <img>.
- lineBoxQuads.append(FloatRect(boundingBox));
- }
-
ASSERT(m_inspectedPage);
FrameView* view = m_inspectedPage->mainFrame()->view();
FloatRect overlayRect = view->visibleContentRect();
-
- if (!overlayRect.contains(boundingBox) && !boundingBox.contains(enclosingIntRect(overlayRect))) {
- Element* element;
- if (m_highlightedNode->isElementNode())
- element = static_cast<Element*>(m_highlightedNode.get());
- else
- element = static_cast<Element*>(m_highlightedNode->parent());
+ if (!overlayRect.contains(boundingBox) && !boundingBox.contains(enclosingIntRect(overlayRect)))
overlayRect = view->visibleContentRect();
- }
-
context.translate(-overlayRect.x(), -overlayRect.y());
- drawHighlightForBoxes(context, lineBoxQuads, absContentQuad, absPaddingQuad, absBorderQuad, absMarginQuad);
+ if (renderer->isBox()) {
+ RenderBox* renderBox = toRenderBox(renderer);
+
+ IntRect contentBox = renderBox->contentBoxRect();
+
+ IntRect paddingBox(contentBox.x() - renderBox->paddingLeft(), contentBox.y() - renderBox->paddingTop(),
+ contentBox.width() + renderBox->paddingLeft() + renderBox->paddingRight(), contentBox.height() + renderBox->paddingTop() + renderBox->paddingBottom());
+ IntRect borderBox(paddingBox.x() - renderBox->borderLeft(), paddingBox.y() - renderBox->borderTop(),
+ paddingBox.width() + renderBox->borderLeft() + renderBox->borderRight(), paddingBox.height() + renderBox->borderTop() + renderBox->borderBottom());
+ IntRect marginBox(borderBox.x() - renderBox->marginLeft(), borderBox.y() - renderBox->marginTop(),
+ borderBox.width() + renderBox->marginLeft() + renderBox->marginRight(), borderBox.height() + renderBox->marginTop() + renderBox->marginBottom());
+
+ FloatQuad absContentQuad = renderBox->localToAbsoluteQuad(FloatRect(contentBox));
+ FloatQuad absPaddingQuad = renderBox->localToAbsoluteQuad(FloatRect(paddingBox));
+ FloatQuad absBorderQuad = renderBox->localToAbsoluteQuad(FloatRect(borderBox));
+ FloatQuad absMarginQuad = renderBox->localToAbsoluteQuad(FloatRect(marginBox));
+
+ absContentQuad.move(mainFrameOffset);
+ absPaddingQuad.move(mainFrameOffset);
+ absBorderQuad.move(mainFrameOffset);
+ absMarginQuad.move(mainFrameOffset);
+
+ drawHighlightForBox(context, absContentQuad, absPaddingQuad, absBorderQuad, absMarginQuad);
+ } else if (renderer->isRenderInline()) {
+ RenderInline* renderInline = toRenderInline(renderer);
+
+ // FIXME: We should show margins/padding/border for inlines.
+ Vector<FloatQuad> lineBoxQuads;
+ renderInline->absoluteQuadsForRange(lineBoxQuads);
+ for (unsigned i = 0; i < lineBoxQuads.size(); ++i)
+ lineBoxQuads[i] += mainFrameOffset;
+
+ drawHighlightForLineBoxes(context, lineBoxQuads);
+ }
}
void InspectorController::count(const String& title, unsigned lineNumber, const String& sourceID)
diff --git a/WebCore/inspector/InspectorController.h b/WebCore/inspector/InspectorController.h
index e52bee9..96b5e6f 100644
--- a/WebCore/inspector/InspectorController.h
+++ b/WebCore/inspector/InspectorController.h
@@ -36,6 +36,7 @@
#include <JavaScriptCore/JSContextRef.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -57,27 +58,30 @@ class GraphicsContext;
class HitTestResult;
class InspectorClient;
class JavaScriptCallFrame;
+class StorageArea;
class Node;
class Page;
-class ResourceRequest;
+struct ResourceRequest;
class ResourceResponse;
class ResourceError;
class ScriptCallStack;
class SharedBuffer;
-struct ConsoleMessage;
-struct InspectorDatabaseResource;
-struct InspectorResource;
+class ConsoleMessage;
+class InspectorDatabaseResource;
+class InspectorDOMStorageResource;
+class InspectorResource;
-class InspectorController
+class InspectorController : public RefCounted<InspectorController>
#if ENABLE(JAVASCRIPT_DEBUGGER)
- : JavaScriptDebugListener
+ , JavaScriptDebugListener
#endif
{
public:
typedef HashMap<long long, RefPtr<InspectorResource> > ResourcesMap;
typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
typedef HashSet<RefPtr<InspectorDatabaseResource> > DatabaseResourcesSet;
+ typedef HashSet<RefPtr<InspectorDOMStorageResource> > DOMStorageResourcesSet;
typedef enum {
CurrentPanel,
@@ -126,7 +130,11 @@ public:
} m_simpleContent;
};
- InspectorController(Page*, InspectorClient*);
+ static PassRefPtr<InspectorController> create(Page* page, InspectorClient* inspectorClient)
+ {
+ return adoptRef(new InspectorController(page, inspectorClient));
+ }
+
~InspectorController();
void inspectedPageDestroyed();
@@ -140,6 +148,7 @@ public:
void setSetting(const String& key, const Setting&);
String localizedStringsURL();
+ String hiddenPanels();
void inspect(Node*);
void highlight(Node*);
@@ -161,6 +170,7 @@ public:
bool windowVisible();
void setWindowVisible(bool visible = true, bool attached = false);
+ bool addSourceToFrame(const String& mimeType, const String& source, Node*);
void addMessageToConsole(MessageSource, MessageLevel, ScriptCallStack*);
void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID);
void clearConsoleMessages();
@@ -205,10 +215,14 @@ public:
void didFinishLoading(DocumentLoader*, unsigned long identifier);
void didFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const JSC::UString& sourceString);
+ void scriptImported(unsigned long identifier, const JSC::UString& sourceString);
#if ENABLE(DATABASE)
void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
#endif
+#if ENABLE(DOM_STORAGE)
+ void didUseDOMStorage(StorageArea* storageArea, bool isLocalStorage, Frame* frame);
+#endif
const ResourcesMap& resources() const { return m_resources; }
@@ -246,11 +260,13 @@ public:
void startGroup(MessageSource source, ScriptCallStack* callFrame);
void endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL);
+ const String& platform() const;
+
private:
+ InspectorController(Page*, InspectorClient*);
void focusNode();
void addConsoleMessage(JSC::ExecState*, ConsoleMessage*);
- void addScriptConsoleMessage(const ConsoleMessage*);
void addResource(InspectorResource*);
void removeResource(InspectorResource*);
@@ -269,11 +285,6 @@ private:
void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0);
void removeAllResources(ResourcesMap* map) { pruneResources(map); }
-#if ENABLE(DATABASE)
- JSObjectRef addDatabaseScriptResource(InspectorDatabaseResource*);
- void removeDatabaseScriptResource(InspectorDatabaseResource*);
-#endif
-
JSValueRef callSimpleFunction(JSContextRef, JSObjectRef thisObject, const char* functionName) const;
JSValueRef callFunction(JSContextRef, JSObjectRef thisObject, const char* functionName, size_t argumentCount, const JSValueRef arguments[], JSValueRef& exception) const;
@@ -302,6 +313,9 @@ private:
#if ENABLE(DATABASE)
DatabaseResourcesSet m_databaseResources;
#endif
+#if ENABLE(DOM_STORAGE)
+ DOMStorageResourcesSet m_domStorageResources;
+#endif
JSObjectRef m_scriptObject;
JSObjectRef m_controllerScriptObject;
JSContextRef m_scriptContext;
diff --git a/WebCore/inspector/InspectorController.idl b/WebCore/inspector/InspectorController.idl
new file mode 100644
index 0000000..0cb8041
--- /dev/null
+++ b/WebCore/inspector/InspectorController.idl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+ interface [
+ GenerateConstructor
+ ] InspectorController {
+ [ImplementationFunction=hideHighlight] void hideDOMNodeHighlight();
+ [Custom] void highlightDOMNode(in Node node);
+ [ImplementationFunction=scriptObjectReady] void loaded();
+ [ImplementationFunction=close] void windowUnloading();
+ [ImplementationFunction=attachWindow] void attach();
+ [ImplementationFunction=detachWindow] void detach();
+
+ void enableDebugger();
+ void disableDebugger();
+ void pauseInDebugger();
+ void resumeDebugger();
+ void stepOverStatementInDebugger();
+ void stepIntoStatementInDebugger();
+ void stepOutOfFunctionInDebugger();
+
+ void closeWindow();
+ [ImplementationFunction=clearConsoleMessages] void clearMessages();
+ [ImplementationFunction=startUserInitiatedProfiling] void startProfiling();
+ [ImplementationFunction=stopUserInitiatedProfiling] void stopProfiling();
+ void enableProfiler();
+ void disableProfiler();
+ [ImplementationFunction=toggleSearchForNodeInPage] void toggleNodeSearch();
+
+ boolean debuggerEnabled();
+ boolean pauseOnExceptions();
+
+ boolean profilerEnabled();
+ [ImplementationFunction=windowVisible] boolean isWindowVisible();
+ [ImplementationFunction=searchingForNodeInPage] boolean searchingForNode();
+
+ [Custom] void addResourceSourceToFrame(in unsigned long identifier, in Node frame);
+ [Custom] void addSourceToFrame(in DOMString mimeType, in DOMString sourceValue, in Node frame);
+ [Custom] Node getResourceDocumentNode(in unsigned long identifier);
+ [Custom] void search(in Node node, in DOMString query);
+#if ENABLE_DATABASE
+ [Custom] DOMObject databaseTableNames(in Database database);
+#endif
+ [Custom] DOMObject setting(in DOMString key);
+ [Custom] void setSetting(in DOMString key, in DOMObject value);
+ [Custom] DOMWindow inspectedWindow();
+ DOMString localizedStringsURL();
+ DOMString hiddenPanels();
+ DOMString platform();
+ [ImplementationFunction=moveWindowBy] void moveByUnrestricted(in float x, in float y);
+ void setAttachedWindowHeight(in unsigned long height);
+ [Custom] DOMObject wrapCallback(in DOMObject callback);
+
+ [Custom] DOMObject currentCallFrame();
+ void setPauseOnExceptions(in boolean pauseOnExceptions);
+ void addBreakpoint(in unsigned long sourceID, in unsigned long lineNumber);
+ void removeBreakpoint(in unsigned long sourceID, in unsigned long lineNumber);
+
+ [Custom] Array profiles();
+ };
+ }
diff --git a/WebCore/inspector/InspectorDOMStorageResource.cpp b/WebCore/inspector/InspectorDOMStorageResource.cpp
new file mode 100644
index 0000000..33d036e
--- /dev/null
+++ b/WebCore/inspector/InspectorDOMStorageResource.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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.
+ */
+
+#include "config.h"
+#if ENABLE(DOM_STORAGE)
+
+#include "InspectorDOMStorageResource.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptFunctionCall.h"
+#include "ScriptObjectQuarantine.h"
+#include "ScriptValue.h"
+#include "Storage.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+InspectorDOMStorageResource::InspectorDOMStorageResource(Storage* domStorage, bool isLocalStorage, Frame* frame)
+ : m_domStorage(domStorage)
+ , m_isLocalStorage(isLocalStorage)
+ , m_frame(frame)
+{
+}
+
+bool InspectorDOMStorageResource::isSameHostAndType(Frame* frame, bool isLocalStorage) const
+{
+ return equalIgnoringCase(m_frame->document()->securityOrigin()->host(), frame->document()->securityOrigin()->host()) && m_isLocalStorage == isLocalStorage;
+}
+
+void InspectorDOMStorageResource::bind(ScriptState* scriptState, const ScriptObject& webInspector)
+{
+ if (!m_scriptObject.hasNoValue())
+ return;
+
+ ASSERT(scriptState);
+ ASSERT(!webInspector.hasNoValue());
+ if (!scriptState || webInspector.hasNoValue())
+ return;
+
+ ScriptFunctionCall resourceConstructor(scriptState, webInspector, "DOMStorage");
+ ScriptObject domStorage;
+ if (!getQuarantinedScriptObject(m_frame.get(), m_domStorage.get(), domStorage))
+ return;
+
+ resourceConstructor.appendArgument(domStorage);
+ resourceConstructor.appendArgument(m_frame->document()->securityOrigin()->host());
+ resourceConstructor.appendArgument(m_isLocalStorage);
+
+ bool hadException = false;
+ m_scriptObject = resourceConstructor.construct(hadException);
+ if (hadException)
+ return;
+
+ ScriptFunctionCall addDOMStorage(scriptState, webInspector, "addDOMStorage");
+ addDOMStorage.appendArgument(m_scriptObject);
+ addDOMStorage.call(hadException);
+}
+
+void InspectorDOMStorageResource::unbind()
+{
+ m_scriptObject = ScriptObject();
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/inspector/InspectorDOMStorageResource.h b/WebCore/inspector/InspectorDOMStorageResource.h
new file mode 100644
index 0000000..ad3e196
--- /dev/null
+++ b/WebCore/inspector/InspectorDOMStorageResource.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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 InspectorDOMStorageResource_h
+#define InspectorDOMStorageResource_h
+
+#if ENABLE(DOM_STORAGE)
+
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class Storage;
+ class Frame;
+
+ class InspectorDOMStorageResource : public RefCounted<InspectorDOMStorageResource> {
+ public:
+ static PassRefPtr<InspectorDOMStorageResource> create(Storage* domStorage, bool isLocalStorage, Frame* frame)
+ {
+ return adoptRef(new InspectorDOMStorageResource(domStorage, isLocalStorage, frame));
+ }
+
+ void bind(ScriptState*, const ScriptObject& webInspector);
+ void unbind();
+
+ bool isSameHostAndType(Frame*, bool isLocalStorage) const;
+
+ private:
+
+ InspectorDOMStorageResource(Storage*, bool isLocalStorage, Frame*);
+
+ ScriptObject m_scriptObject;
+ RefPtr<Storage> m_domStorage;
+ bool m_isLocalStorage;
+ RefPtr<Frame> m_frame;
+
+ private:
+ };
+
+} // namespace WebCore
+
+#endif
+
+#endif // InspectorDOMStorageResource_h
diff --git a/WebCore/inspector/InspectorDatabaseResource.cpp b/WebCore/inspector/InspectorDatabaseResource.cpp
new file mode 100644
index 0000000..43cd8ef
--- /dev/null
+++ b/WebCore/inspector/InspectorDatabaseResource.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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.
+ */
+
+#include "config.h"
+#if ENABLE(DATABASE)
+#include "InspectorDatabaseResource.h"
+
+#include "Database.h"
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptFunctionCall.h"
+#include "ScriptObjectQuarantine.h"
+#include "ScriptValue.h"
+
+namespace WebCore {
+
+InspectorDatabaseResource::InspectorDatabaseResource(Database* database, const String& domain, const String& name, const String& version)
+ : m_database(database)
+ , m_domain(domain)
+ , m_name(name)
+ , m_version(version)
+{
+}
+
+void InspectorDatabaseResource::bind(ScriptState* scriptState, const ScriptObject& webInspector)
+{
+ if (!m_scriptObject.hasNoValue())
+ return;
+
+ ASSERT(scriptState);
+ ASSERT(!webInspector.hasNoValue());
+ if (!scriptState || webInspector.hasNoValue())
+ return;
+
+ ScriptFunctionCall resourceConstructor(scriptState, webInspector, "Database");
+ ScriptObject database;
+ if (!getQuarantinedScriptObject(m_database.get(), database))
+ return;
+
+ resourceConstructor.appendArgument(database);
+ resourceConstructor.appendArgument(m_domain);
+ resourceConstructor.appendArgument(m_name);
+ resourceConstructor.appendArgument(m_version);
+
+ bool hadException = false;
+ m_scriptObject = resourceConstructor.construct(hadException);
+ if (hadException)
+ return;
+
+ ScriptFunctionCall addDatabase(scriptState, webInspector, "addDatabase");
+ addDatabase.appendArgument(m_scriptObject);
+ addDatabase.call(hadException);
+}
+
+void InspectorDatabaseResource::unbind()
+{
+ m_scriptObject = ScriptObject();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
diff --git a/WebCore/inspector/InspectorDatabaseResource.h b/WebCore/inspector/InspectorDatabaseResource.h
new file mode 100644
index 0000000..1be2334
--- /dev/null
+++ b/WebCore/inspector/InspectorDatabaseResource.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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 InspectorDatabaseResource_h
+#define InspectorDatabaseResource_h
+
+#if ENABLE(DATABASE)
+
+#include "Database.h"
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+ class InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
+ public:
+ static PassRefPtr<InspectorDatabaseResource> create(Database* database, const String& domain, const String& name, const String& version)
+ {
+ return adoptRef(new InspectorDatabaseResource(database, domain, name, version));
+ }
+
+ void bind(ScriptState*, const ScriptObject& webInspector);
+ void unbind();
+
+ private:
+ InspectorDatabaseResource(Database*, const String& domain, const String& name, const String& version);
+ ScriptObject m_scriptObject;
+
+ RefPtr<Database> m_database;
+ String m_domain;
+ String m_name;
+ String m_version;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(DATABASE)
+
+#endif // InspectorDatabaseResource_h
diff --git a/WebCore/inspector/InspectorResource.cpp b/WebCore/inspector/InspectorResource.cpp
new file mode 100644
index 0000000..7db6cd1
--- /dev/null
+++ b/WebCore/inspector/InspectorResource.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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.
+ */
+
+#include "config.h"
+#include "InspectorResource.h"
+
+#include "CachedResource.h"
+#include "DocLoader.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "TextEncoding.h"
+
+#include <runtime/JSLock.h>
+
+namespace WebCore {
+
+// XMLHttpRequestResource Class
+
+struct XMLHttpRequestResource {
+ XMLHttpRequestResource(const JSC::UString& sourceString)
+ {
+ JSC::JSLock lock(false);
+ this->sourceString = sourceString.rep();
+ }
+
+ ~XMLHttpRequestResource()
+ {
+ JSC::JSLock lock(false);
+ sourceString.clear();
+ }
+
+ RefPtr<JSC::UString::Rep> sourceString;
+};
+
+ InspectorResource::InspectorResource(long long identifier, DocumentLoader* documentLoader, Frame* frame)
+ : identifier(identifier)
+ , loader(documentLoader)
+ , frame(frame)
+ , scriptContext(0)
+ , scriptObject(0)
+ , expectedContentLength(0)
+ , cached(false)
+ , finished(false)
+ , failed(false)
+ , length(0)
+ , responseStatusCode(0)
+ , startTime(-1.0)
+ , responseReceivedTime(-1.0)
+ , endTime(-1.0)
+ , xmlHttpRequestResource(0)
+ {
+ }
+
+InspectorResource::~InspectorResource()
+{
+ setScriptObject(0, 0);
+}
+
+InspectorResource::Type InspectorResource::type() const
+{
+ if (xmlHttpRequestResource)
+ return XHR;
+
+ if (requestURL == loader->requestURL())
+ return Doc;
+
+ if (loader->frameLoader() && requestURL == loader->frameLoader()->iconURL())
+ return Image;
+
+ CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
+ if (!cachedResource)
+ return Other;
+
+ switch (cachedResource->type()) {
+ case CachedResource::ImageResource:
+ return Image;
+ case CachedResource::FontResource:
+ return Font;
+ case CachedResource::CSSStyleSheet:
+#if ENABLE(XSLT)
+ case CachedResource::XSLStyleSheet:
+#endif
+ return Stylesheet;
+ case CachedResource::Script:
+ return Script;
+ default:
+ return Other;
+ }
+}
+
+void InspectorResource::setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
+{
+ if (scriptContext && scriptObject)
+ JSValueUnprotect(scriptContext, scriptObject);
+
+ scriptObject = newScriptObject;
+ scriptContext = context;
+
+ ASSERT((context && newScriptObject) || (!context && !newScriptObject));
+ if (context && newScriptObject)
+ JSValueProtect(context, newScriptObject);
+}
+
+void InspectorResource::setXMLHttpRequestProperties(const JSC::UString& data)
+{
+ xmlHttpRequestResource.set(new XMLHttpRequestResource(data));
+}
+
+void InspectorResource::setScriptProperties(const JSC::UString& data)
+{
+ xmlHttpRequestResource.set(new XMLHttpRequestResource(data));
+}
+
+String InspectorResource::sourceString() const
+{
+ if (xmlHttpRequestResource)
+ return JSC::UString(xmlHttpRequestResource->sourceString);
+
+ RefPtr<SharedBuffer> buffer;
+ String textEncodingName;
+
+ if (requestURL == loader->requestURL()) {
+ buffer = loader->mainResourceData();
+ textEncodingName = frame->document()->inputEncoding();
+ } else {
+ CachedResource* cachedResource = frame->document()->docLoader()->cachedResource(requestURL.string());
+ if (!cachedResource)
+ return String();
+
+ if (cachedResource->isPurgeable()) {
+ // If the resource is purgeable then make it unpurgeable to get
+ // get its data. This might fail, in which case we return an
+ // empty String.
+ // FIXME: should we do something else in the case of a purged
+ // resource that informs the user why there is no data in the
+ // inspector?
+ if (!cachedResource->makePurgeable(false))
+ return String();
+ }
+
+ buffer = cachedResource->data();
+ textEncodingName = cachedResource->encoding();
+ }
+
+ if (!buffer)
+ return String();
+
+ TextEncoding encoding(textEncodingName);
+ if (!encoding.isValid())
+ encoding = WindowsLatin1Encoding();
+ return encoding.decode(buffer->data(), buffer->size());
+}
+
+} // namespace WebCore
diff --git a/WebCore/inspector/InspectorResource.h b/WebCore/inspector/InspectorResource.h
new file mode 100644
index 0000000..46d7fed
--- /dev/null
+++ b/WebCore/inspector/InspectorResource.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * 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 InspectorResource_h
+#define InspectorResource_h
+
+#include <JavaScriptCore/JSContextRef.h>
+
+#include "HTTPHeaderMap.h"
+#include "KURL.h"
+
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+namespace JSC {
+ class UString;
+}
+
+namespace WebCore {
+ class DocumentLoader;
+ class Frame;
+ struct XMLHttpRequestResource;
+
+ class InspectorResource : public RefCounted<InspectorResource> {
+ public:
+
+ // Keep these in sync with WebInspector.Resource.Type
+ enum Type {
+ Doc,
+ Stylesheet,
+ Image,
+ Font,
+ Script,
+ XHR,
+ Media,
+ Other
+ };
+
+ static PassRefPtr<InspectorResource> create(long long identifier, DocumentLoader* documentLoader, Frame* frame)
+ {
+ return adoptRef(new InspectorResource(identifier, documentLoader, frame));
+ }
+
+ ~InspectorResource();
+ Type type() const;
+ void setScriptObject(JSContextRef, JSObjectRef);
+ void setXMLHttpRequestProperties(const JSC::UString& data);
+ void setScriptProperties(const JSC::UString& data);
+
+ String sourceString() const;
+
+ long long identifier;
+ RefPtr<DocumentLoader> loader;
+ RefPtr<Frame> frame;
+ KURL requestURL;
+ HTTPHeaderMap requestHeaderFields;
+ HTTPHeaderMap responseHeaderFields;
+ String mimeType;
+ String suggestedFilename;
+ JSContextRef scriptContext;
+ JSObjectRef scriptObject;
+ long long expectedContentLength;
+ bool cached;
+ bool finished;
+ bool failed;
+ int length;
+ int responseStatusCode;
+ double startTime;
+ double responseReceivedTime;
+ double endTime;
+
+ private:
+ InspectorResource(long long identifier, DocumentLoader*, Frame*);
+
+ OwnPtr<XMLHttpRequestResource> xmlHttpRequestResource;
+ };
+
+} // namespace WebCore
+
+#endif // InspectorResource_h
diff --git a/WebCore/inspector/JavaScriptDebugServer.cpp b/WebCore/inspector/JavaScriptDebugServer.cpp
index 05dca70..62ccad4 100644
--- a/WebCore/inspector/JavaScriptDebugServer.cpp
+++ b/WebCore/inspector/JavaScriptDebugServer.cpp
@@ -363,12 +363,11 @@ void JavaScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused)
frame->script()->setPaused(paused);
- if (Document* document = frame->document()) {
- if (paused)
- document->suspendActiveDOMObjects();
- else
- document->resumeActiveDOMObjects();
- }
+ Document* document = frame->document();
+ if (paused)
+ document->suspendActiveDOMObjects();
+ else
+ document->resumeActiveDOMObjects();
setJavaScriptPaused(frame->view(), paused);
}
diff --git a/WebCore/inspector/front-end/Console.js b/WebCore/inspector/front-end/Console.js
index 31e466c..ba879a0 100644
--- a/WebCore/inspector/front-end/Console.js
+++ b/WebCore/inspector/front-end/Console.js
@@ -141,7 +141,7 @@ WebInspector.Console.prototype = {
addMessage: function(msg)
{
- if (msg instanceof WebInspector.ConsoleMessage) {
+ if (msg instanceof WebInspector.ConsoleMessage && !(msg instanceof WebInspector.ConsoleCommandResult)) {
msg.totalRepeatCount = msg.repeatCount;
msg.repeatDelta = msg.repeatCount;
@@ -446,6 +446,9 @@ WebInspector.Console.prototype = {
if (!str.length)
return;
+ var commandMessage = new WebInspector.ConsoleCommand(str);
+ this.addMessage(commandMessage);
+
var result;
var exception = false;
try {
@@ -459,31 +462,12 @@ WebInspector.Console.prototype = {
this.prompt.historyOffset = 0;
this.prompt.text = "";
- var level = exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log;
- this.addMessage(new WebInspector.ConsoleCommand(str, result, this._format(result), level));
- },
-
- _mouseOverNode: function(event)
- {
- var anchorElement = event.target.enclosingNodeOrSelfWithNodeName("a");
- WebInspector.hoveredDOMNode = (anchorElement ? anchorElement.representedNode : null);
- },
-
- _mouseOutOfNode: function(event)
- {
- var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
- var anchorElement = nodeUnderMouse.enclosingNodeOrSelfWithNodeName("a");
- if (!anchorElement || !anchorElement.representedNode)
- WebInspector.hoveredDOMNode = null;
+ this.addMessage(new WebInspector.ConsoleCommandResult(result, exception, commandMessage));
},
- _format: function(output, inline)
+ _format: function(output, forceObjectFormat)
{
- var type = Object.type(output, InspectorController.inspectedWindow());
- if (type === "object") {
- if (output instanceof InspectorController.inspectedWindow().Node)
- type = "node";
- }
+ var type = (forceObjectFormat ? "object" : Object.type(output, InspectorController.inspectedWindow()));
// We don't perform any special formatting on these types, so we just
// pass them through the simple _formatvalue function.
@@ -497,7 +481,9 @@ WebInspector.Console.prototype = {
};
var formatter;
- if (type in undecoratedTypes)
+ if (forceObjectFormat)
+ formatter = "_formatobject";
+ else if (type in undecoratedTypes)
formatter = "_formatvalue";
else {
formatter = "_format" + type;
@@ -509,77 +495,74 @@ WebInspector.Console.prototype = {
var span = document.createElement("span");
span.addStyleClass("console-formatted-" + type);
- this[formatter](output, span, inline);
+ this[formatter](output, span);
return span;
},
- _formatvalue: function(val, elem, inline)
+ _formatvalue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},
- _formatstring: function(str, elem, inline)
+ _formatstring: function(str, elem)
{
elem.appendChild(document.createTextNode("\"" + str + "\""));
},
- _formatregexp: function(re, elem, inline)
+ _formatregexp: function(re, elem)
{
var formatted = String(re).replace(/([\\\/])/g, "\\$1").replace(/\\(\/[gim]*)$/, "$1").substring(1);
elem.appendChild(document.createTextNode(formatted));
},
- _formatarray: function(arr, elem, inline)
+ _formatarray: function(arr, elem)
{
elem.appendChild(document.createTextNode("["));
for (var i = 0; i < arr.length; ++i) {
- elem.appendChild(this._format(arr[i], true));
+ elem.appendChild(this._format(arr[i]));
if (i < arr.length - 1)
elem.appendChild(document.createTextNode(", "));
}
elem.appendChild(document.createTextNode("]"));
},
- _formatnode: function(node, elem, inline)
+ _formatnode: function(node, elem)
{
- var anchor = document.createElement("a");
- anchor.className = "inspectible-node";
- anchor.innerHTML = nodeTitleInfo.call(node).title;
- anchor.representedNode = node;
- anchor.addEventListener("mouseover", this._mouseOverNode.bind(this), false);
- anchor.addEventListener("mouseout", this._mouseOutOfNode.bind(this), false);
-
- if (inline)
- elem.appendChild(anchor);
- else
- elem.appendChild(new WebInspector.ObjectPropertiesSection(node, anchor, null, null, true).element);
+ var treeOutline = new WebInspector.ElementsTreeOutline();
+ treeOutline.rootDOMNode = node;
+ treeOutline.element.addStyleClass("outline-disclosure");
+ if (!treeOutline.children[0].hasChildren)
+ treeOutline.element.addStyleClass("single-node");
+ elem.appendChild(treeOutline.element);
},
- _formatobject: function(obj, elem, inline)
+ _formatobject: function(obj, elem)
{
- if (inline)
- elem.appendChild(document.createTextNode(Object.describe(obj)));
- else
- elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, null, null, null, true).element);
+ elem.appendChild(new WebInspector.ObjectPropertiesSection(obj, null, null, null, true).element);
},
- _formaterror: function(obj, elem, inline)
+ _formaterror: function(obj, elem)
{
- elem.appendChild(document.createTextNode(obj.name + ": " + obj.message + " "));
+ var messageElement = document.createElement("span");
+ messageElement.className = "error-message";
+ messageElement.textContent = obj.name + ": " + obj.message;
+ elem.appendChild(messageElement);
if (obj.sourceURL) {
var urlElement = document.createElement("a");
- urlElement.className = "console-message-url webkit-html-resource-link";
+ urlElement.className = "webkit-html-resource-link";
urlElement.href = obj.sourceURL;
urlElement.lineNumber = obj.line;
urlElement.preferredPanel = "scripts";
if (obj.line > 0)
- urlElement.textContent = WebInspector.UIString("%s (line %d)", obj.sourceURL, obj.line);
+ urlElement.textContent = WebInspector.displayNameForURL(obj.sourceURL) + ":" + obj.line;
else
- urlElement.textContent = obj.sourceURL;
+ urlElement.textContent = WebInspector.displayNameForURL(obj.sourceURL);
+ elem.appendChild(document.createTextNode(" ("));
elem.appendChild(urlElement);
+ elem.appendChild(document.createTextNode(")"));
}
},
}
@@ -596,18 +579,6 @@ WebInspector.ConsoleMessage = function(source, level, line, url, groupLevel, rep
this.repeatCount = repeatCount;
switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Object:
- var propertiesSection = new WebInspector.ObjectPropertiesSection(arguments[6], null, null, null, true);
- propertiesSection.element.addStyleClass("console-message");
- this.propertiesSection = propertiesSection;
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Node:
- var node = arguments[6];
- if (!(node instanceof InspectorController.inspectedWindow().Node))
- return;
- this.elementsTreeOutline = new WebInspector.ElementsTreeOutline();
- this.elementsTreeOutline.rootDOMNode = node;
- break;
case WebInspector.ConsoleMessage.MessageLevel.Trace:
var span = document.createElement("span");
span.addStyleClass("console-formatted-trace");
@@ -618,14 +589,16 @@ WebInspector.ConsoleMessage = function(source, level, line, url, groupLevel, rep
span.appendChild(document.createTextNode(funcNames.join("\n")));
this.formattedMessage = span;
break;
+ case WebInspector.ConsoleMessage.MessageLevel.Object:
+ this.formattedMessage = this._format(["%O", arguments[6]]);
+ break;
default:
- // The formatedMessage property is used for the rich and interactive console.
this.formattedMessage = this._format(Array.prototype.slice.call(arguments, 6));
-
- // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
- this.message = this.formattedMessage.textContent;
break;
}
+
+ // This is used for inline message bubbles in SourceFrames, or other plain-text representations.
+ this.message = this.formattedMessage.textContent;
}
WebInspector.ConsoleMessage.prototype = {
@@ -643,6 +616,11 @@ WebInspector.ConsoleMessage.prototype = {
function formatForConsole(obj)
{
+ return WebInspector.console._format(obj);
+ }
+
+ function formatAsObjectForConsole(obj)
+ {
return WebInspector.console._format(obj, true);
}
@@ -655,6 +633,8 @@ WebInspector.ConsoleMessage.prototype = {
formatters.o = formatForConsole;
// Firebug allows both %i and %d for formatting integers.
formatters.i = formatters.d;
+ // Support %O to force object formating, instead of the type-based %o formatting.
+ formatters.O = formatAsObjectForConsole;
function append(a, b)
{
@@ -675,10 +655,9 @@ WebInspector.ConsoleMessage.prototype = {
for (var i = 0; i < parameters.length; ++i) {
if (typeof parameters[i] === "string")
formattedResult.appendChild(WebInspector.linkifyStringAsFragment(parameters[i]));
- else if (parameters.length === 1)
- formattedResult.appendChild(WebInspector.console._format(parameters[0]));
else
formattedResult.appendChild(formatForConsole(parameters[i]));
+
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
@@ -758,7 +737,7 @@ WebInspector.ConsoleMessage.prototype = {
urlElement.preferredPanel = "scripts";
if (this.line > 0)
- urlElement.textContent = WebInspector.UIString("%s (line %d)", WebInspector.displayNameForURL(this.url), this.line);
+ urlElement.textContent = WebInspector.displayNameForURL(this.url) + ":" + this.line;
else
urlElement.textContent = WebInspector.displayNameForURL(this.url);
@@ -814,14 +793,20 @@ WebInspector.ConsoleMessage.prototype = {
case WebInspector.ConsoleMessage.MessageLevel.Object:
levelString = "Object";
break;
- case WebInspector.ConsoleMessage.MessageLevel.GroupTitle:
- levelString = "GroupTitle";
+ case WebInspector.ConsoleMessage.MessageLevel.Trace:
+ levelString = "Trace";
+ break;
+ case WebInspector.ConsoleMessage.MessageLevel.StartGroup:
+ levelString = "Start Group";
+ break;
+ case WebInspector.ConsoleMessage.MessageLevel.EndGroup:
+ levelString = "End Group";
break;
}
return sourceString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},
-
+
isEqual: function(msg, disreguardGroup)
{
if (!msg)
@@ -853,17 +838,14 @@ WebInspector.ConsoleMessage.MessageLevel = {
Warning: 2,
Error: 3,
Object: 4,
- Node: 5,
- Trace: 6,
- StartGroup: 7,
- EndGroup: 8
+ Trace: 5,
+ StartGroup: 6,
+ EndGroup: 7
}
-WebInspector.ConsoleCommand = function(command, result, formattedResultElement, level)
+WebInspector.ConsoleCommand = function(command)
{
this.command = command;
- this.formattedResultElement = formattedResultElement;
- this.level = level;
}
WebInspector.ConsoleCommand.prototype = {
@@ -878,30 +860,33 @@ WebInspector.ConsoleCommand.prototype = {
commandTextElement.textContent = this.command;
element.appendChild(commandTextElement);
- var resultElement = document.createElement("div");
- resultElement.className = "console-message";
- element.appendChild(resultElement);
+ return element;
+ }
+}
- switch (this.level) {
- case WebInspector.ConsoleMessage.MessageLevel.Log:
- resultElement.addStyleClass("console-log-level");
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Warning:
- resultElement.addStyleClass("console-warning-level");
- break;
- case WebInspector.ConsoleMessage.MessageLevel.Error:
- resultElement.addStyleClass("console-error-level");
- }
+WebInspector.ConsoleCommandResult = function(result, exception, originatingCommand)
+{
+ var level = (exception ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
+ var message = (exception ? String(result) : result);
+ var line = (exception ? result.line : -1);
+ var url = (exception ? result.sourceURL : null);
+
+ WebInspector.ConsoleMessage.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, line, url, null, 1, message);
- var resultTextElement = document.createElement("span");
- resultTextElement.className = "console-message-text";
- resultTextElement.appendChild(this.formattedResultElement);
- resultElement.appendChild(resultTextElement);
+ this.originatingCommand = originatingCommand;
+}
+WebInspector.ConsoleCommandResult.prototype = {
+ toMessageElement: function()
+ {
+ var element = WebInspector.ConsoleMessage.prototype.toMessageElement.call(this);
+ element.addStyleClass("console-user-command-result");
return element;
}
}
+WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;
+
WebInspector.ConsoleGroup = function(parentGroup, level)
{
this.parentGroup = parentGroup;
@@ -928,8 +913,11 @@ WebInspector.ConsoleGroup.prototype = {
element.addEventListener("click", this._titleClicked.bind(this), true);
} else
this.messagesElement.appendChild(element);
+
+ if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
+ element.previousSibling.addStyleClass("console-adjacent-user-command-result");
},
-
+
_titleClicked: function(event)
{
var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title-level");
diff --git a/WebCore/storage/SQLTransactionCallback.idl b/WebCore/inspector/front-end/DOMStorage.js
index cee726f..5207b69 100644
--- a/WebCore/storage/SQLTransactionCallback.idl
+++ b/WebCore/inspector/front-end/DOMStorage.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,7 +14,7 @@
* 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
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
* EXPRESS OR IMPLIED 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
@@ -26,10 +26,47 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-module storage {
+WebInspector.DOMStorage = function(domStorage, domain, isLocalStorage)
+{
+ this.domStorage = domStorage;
+ this.domain = domain;
+ this.isLocalStorage = isLocalStorage;
+}
+
+WebInspector.DOMStorage.prototype = {
+ get domStorage()
+ {
+ return this._domStorage;
+ },
+
+ set domStorage(x)
+ {
+ if (this._domStorage === x)
+ return;
+ this._domStorage = x;
+ },
- interface SQLTransactionCallback {
- void handleEvent(in SQLTransaction transaction);
- };
+ get domain()
+ {
+ return this._domain;
+ },
+ set domain(x)
+ {
+ if (this._domain === x)
+ return;
+ this._domain = x;
+ },
+
+ get isLocalStorage()
+ {
+ return this._isLocalStorage;
+ },
+
+ set isLocalStorage(x)
+ {
+ if (this._isLocalStorage === x)
+ return;
+ this._isLocalStorage = x;
+ }
}
diff --git a/WebCore/inspector/front-end/DOMStorageDataGrid.js b/WebCore/inspector/front-end/DOMStorageDataGrid.js
new file mode 100644
index 0000000..9946415
--- /dev/null
+++ b/WebCore/inspector/front-end/DOMStorageDataGrid.js
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009 Nokia Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list 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.
+ */
+
+WebInspector.DOMStorageDataGrid = function(columns)
+{
+ WebInspector.DataGrid.call(this, columns);
+ this.dataTableBody.addEventListener("dblclick", this._ondblclick.bind(this), false);
+}
+
+WebInspector.DOMStorageDataGrid.prototype = {
+ _ondblclick: function(event)
+ {
+ if (this._editing)
+ return;
+ if (this._editingNode)
+ return;
+ this._startEditing(event);
+ },
+
+ _startEditing: function(event)
+ {
+ var element = event.target.enclosingNodeOrSelfWithNodeName("td");
+ if (!element)
+ return;
+ this._editingNode = this.dataGridNodeFromEvent(event);
+ if (!this._editingNode)
+ return;
+ this._editing = true;
+
+ WebInspector.startEditing(element, this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
+ window.getSelection().setBaseAndExtent(element, 0, element, 1);
+ },
+
+ _editingCommitted: function(element, newText)
+ {
+ if (element.hasStyleClass("0-column"))
+ columnIdentifier = 0;
+ else
+ columnIdentifier = 1;
+ textBeforeEditing = this._editingNode.data[columnIdentifier];
+ if (textBeforeEditing == newText) {
+ this._editingCancelled(element);
+ return;
+ }
+
+ var domStorage = WebInspector.panels.databases.visibleView.domStorage.domStorage;
+ if (domStorage) {
+ if (columnIdentifier == 0) {
+ if (domStorage.getItem(newText) != null) {
+ element.textContent = this._editingNode.data[0];
+ this._editingCancelled(element);
+ return;
+ }
+ domStorage.removeItem(this._editingNode.data[0]);
+ domStorage.setItem(newText, this._editingNode.data[1]);
+ this._editingNode.data[0] = newText;
+ } else {
+ domStorage.setItem(this._editingNode.data[0], newText);
+ this._editingNode.data[1] = newText;
+ }
+ }
+
+ this._editingCancelled(element);
+ },
+
+ _editingCancelled: function(element, context)
+ {
+ delete this._editing;
+ this._editingNode = null;
+ },
+
+ deleteSelectedRow: function()
+ {
+ var node = this.selectedNode;
+ var domStorage = WebInspector.panels.databases.visibleView.domStorage.domStorage;
+ if (node && domStorage)
+ domStorage.removeItem(node.data[0]);
+ }
+}
+
+WebInspector.DOMStorageDataGrid.prototype.__proto__ = WebInspector.DataGrid.prototype;
diff --git a/WebCore/inspector/front-end/DOMStorageItemsView.js b/WebCore/inspector/front-end/DOMStorageItemsView.js
new file mode 100644
index 0000000..912573e
--- /dev/null
+++ b/WebCore/inspector/front-end/DOMStorageItemsView.js
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 Nokia Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 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.
+ */
+
+WebInspector.DOMStorageItemsView = function(domStorage)
+{
+ WebInspector.View.call(this);
+
+ this.domStorage = domStorage;
+
+ this.element.addStyleClass("storage-view");
+ this.element.addStyleClass("table");
+
+ this.deleteButton = document.createElement("button");
+ this.deleteButton.title = WebInspector.UIString("Delete");
+ this.deleteButton.className = "delete-storage-status-bar-item status-bar-item hidden";
+ this.deleteButton.addEventListener("click", this._deleteButtonClicked.bind(this), false);
+
+ this.refreshButton = document.createElement("button");
+ this.refreshButton.title = WebInspector.UIString("Refresh");
+ this.refreshButton.className = "refresh-storage-status-bar-item status-bar-item";
+ this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
+}
+
+WebInspector.DOMStorageItemsView.prototype = {
+ get statusBarItems()
+ {
+ return [this.refreshButton, this.deleteButton];
+ },
+
+ show: function(parentElement)
+ {
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this.update();
+ },
+
+ hide: function()
+ {
+ WebInspector.View.prototype.hide.call(this);
+ this.deleteButton.addStyleClass("hidden");
+ },
+
+ update: function()
+ {
+ this.element.removeChildren();
+ var hasDOMStorage = this.domStorage;
+ if (hasDOMStorage)
+ hasDOMStorage = this.domStorage.domStorage;
+
+ if (hasDOMStorage) {
+ var dataGrid = WebInspector.panels.databases.dataGridForDOMStorage(this.domStorage.domStorage);
+ if (!dataGrid)
+ hasDOMStorage = 0;
+ else {
+ this._dataGrid = dataGrid;
+ this.element.appendChild(dataGrid.element);
+ this.deleteButton.removeStyleClass("hidden");
+ }
+ }
+
+ if (!hasDOMStorage) {
+ var emptyMsgElement = document.createElement("div");
+ emptyMsgElement.className = "storage-table-empty";
+ if (this.domStorage)
+ emptyMsgElement.textContent = WebInspector.UIString("This storage is empty.");
+ this.element.appendChild(emptyMsgElement);
+ this._dataGrid = null;
+ this.deleteButton.addStyleClass("hidden");
+ }
+ },
+
+ _deleteButtonClicked: function(event)
+ {
+ if (this._dataGrid) {
+ this._dataGrid.deleteSelectedRow();
+
+ this.show();
+ }
+ },
+
+ _refreshButtonClicked: function(event)
+ {
+ this.update();
+ }
+}
+
+WebInspector.DOMStorageItemsView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/DatabaseQueryView.js b/WebCore/inspector/front-end/DatabaseQueryView.js
index 6a91625..122707f 100644
--- a/WebCore/inspector/front-end/DatabaseQueryView.js
+++ b/WebCore/inspector/front-end/DatabaseQueryView.js
@@ -29,7 +29,7 @@ WebInspector.DatabaseQueryView = function(database)
this.database = database;
- this.element.addStyleClass("database-view");
+ this.element.addStyleClass("storage-view");
this.element.addStyleClass("query");
this.element.tabIndex = 0;
diff --git a/WebCore/inspector/front-end/DatabaseTableView.js b/WebCore/inspector/front-end/DatabaseTableView.js
index 2e72240..bbca9d0 100644
--- a/WebCore/inspector/front-end/DatabaseTableView.js
+++ b/WebCore/inspector/front-end/DatabaseTableView.js
@@ -30,8 +30,13 @@ WebInspector.DatabaseTableView = function(database, tableName)
this.database = database;
this.tableName = tableName;
- this.element.addStyleClass("database-view");
+ this.element.addStyleClass("storage-view");
this.element.addStyleClass("table");
+
+ this.refreshButton = document.createElement("button");
+ this.refreshButton.title = WebInspector.UIString("Refresh");
+ this.refreshButton.className = "refresh-storage-status-bar-item status-bar-item";
+ this.refreshButton.addEventListener("click", this._refreshButtonClicked.bind(this), false);
}
WebInspector.DatabaseTableView.prototype = {
@@ -41,6 +46,11 @@ WebInspector.DatabaseTableView.prototype = {
this.update();
},
+ get statusBarItems()
+ {
+ return [this.refreshButton];
+ },
+
update: function()
{
function queryTransaction(tx)
@@ -58,7 +68,7 @@ WebInspector.DatabaseTableView.prototype = {
var dataGrid = WebInspector.panels.databases.dataGridForResult(result);
if (!dataGrid) {
var emptyMsgElement = document.createElement("div");
- emptyMsgElement.className = "database-table-empty";
+ emptyMsgElement.className = "storage-table-empty";
emptyMsgElement.textContent = WebInspector.UIString("The “%s”\ntable is empty.", this.tableName);
this.element.appendChild(emptyMsgElement);
return;
@@ -72,11 +82,15 @@ WebInspector.DatabaseTableView.prototype = {
this.element.removeChildren();
var errorMsgElement = document.createElement("div");
- errorMsgElement.className = "database-table-error";
+ errorMsgElement.className = "storage-table-error";
errorMsgElement.textContent = WebInspector.UIString("An error occurred trying to\nread the “%s” table.", this.tableName);
this.element.appendChild(errorMsgElement);
},
+ _refreshButtonClicked: function(event)
+ {
+ this.update();
+ }
}
WebInspector.DatabaseTableView.prototype.__proto__ = WebInspector.View.prototype;
diff --git a/WebCore/inspector/front-end/DatabasesPanel.js b/WebCore/inspector/front-end/DatabasesPanel.js
index df5bbb3..4644b3b 100644
--- a/WebCore/inspector/front-end/DatabasesPanel.js
+++ b/WebCore/inspector/front-end/DatabasesPanel.js
@@ -46,9 +46,24 @@ WebInspector.DatabasesPanel = function(database)
this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
- this.databaseViews = document.createElement("div");
- this.databaseViews.id = "database-views";
- this.element.appendChild(this.databaseViews);
+ this.databasesListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("DATABASES"), {}, true);
+ this.sidebarTree.appendChild(this.databasesListTreeElement);
+ this.databasesListTreeElement.expand();
+
+ this.localStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("LOCAL STORAGE"), {}, true);
+ this.sidebarTree.appendChild(this.localStorageListTreeElement);
+ this.localStorageListTreeElement.expand();
+
+ this.sessionStorageListTreeElement = new WebInspector.SidebarSectionTreeElement(WebInspector.UIString("SESSION STORAGE"), {}, true);
+ this.sidebarTree.appendChild(this.sessionStorageListTreeElement);
+ this.sessionStorageListTreeElement.expand();
+
+ this.storageViews = document.createElement("div");
+ this.storageViews.id = "storage-views";
+ this.element.appendChild(this.storageViews);
+
+ this.storageViewStatusBarItemsContainer = document.createElement("div");
+ this.storageViewStatusBarItemsContainer.id = "storage-view-status-bar-items";
this.reset();
}
@@ -61,6 +76,11 @@ WebInspector.DatabasesPanel.prototype = {
return WebInspector.UIString("Databases");
},
+ get statusBarItems()
+ {
+ return [this.storageViewStatusBarItemsContainer];
+ },
+
show: function()
{
WebInspector.Panel.prototype.show.call(this);
@@ -81,8 +101,23 @@ WebInspector.DatabasesPanel.prototype = {
this._databases = [];
- this.sidebarTree.removeChildren();
- this.databaseViews.removeChildren();
+ if (this._domStorage) {
+ var domStorageLength = this._domStorage.length;
+ for (var i = 0; i < domStorageLength; ++i) {
+ var domStorage = this._domStorage[i];
+
+ delete domStorage._domStorageView;
+ }
+ }
+
+ this._domStorage = [];
+
+ this.databasesListTreeElement.removeChildren();
+ this.localStorageListTreeElement.removeChildren();
+ this.sessionStorageListTreeElement.removeChildren();
+ this.storageViews.removeChildren();
+
+ this.storageViewStatusBarItemsContainer.removeChildren();
},
handleKeyEvent: function(event)
@@ -96,8 +131,18 @@ WebInspector.DatabasesPanel.prototype = {
var databaseTreeElement = new WebInspector.DatabaseSidebarTreeElement(database);
database._databasesTreeElement = databaseTreeElement;
+ this.databasesListTreeElement.appendChild(databaseTreeElement);
+ },
- this.sidebarTree.appendChild(databaseTreeElement);
+ addDOMStorage: function(domStorage)
+ {
+ this._domStorage.push(domStorage);
+ var domStorageTreeElement = new WebInspector.DOMStorageSidebarTreeElement(domStorage);
+ domStorage._domStorageTreeElement = domStorageTreeElement;
+ if (domStorage.isLocalStorage)
+ this.localStorageListTreeElement.appendChild(domStorageTreeElement);
+ else
+ this.sessionStorageListTreeElement.appendChild(domStorageTreeElement);
},
showDatabase: function(database, tableName)
@@ -105,8 +150,8 @@ WebInspector.DatabasesPanel.prototype = {
if (!database)
return;
- if (this.visibleDatabaseView)
- this.visibleDatabaseView.hide();
+ if (this.visibleView)
+ this.visibleView.hide();
var view;
if (tableName) {
@@ -125,16 +170,46 @@ WebInspector.DatabasesPanel.prototype = {
}
}
- view.show(this.databaseViews);
+ view.show(this.storageViews);
+
+ this.visibleView = view;
- this.visibleDatabaseView = view;
+ this.storageViewStatusBarItemsContainer.removeChildren();
+ var statusBarItems = view.statusBarItems;
+ for (var i = 0; i < statusBarItems.length; ++i)
+ this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
+ },
+
+ showDOMStorage: function(domStorage)
+ {
+ if (!domStorage)
+ return;
+
+ if (this.visibleView)
+ this.visibleView.hide();
+
+ var view;
+ view = domStorage._domStorageView;
+ if (!view) {
+ view = new WebInspector.DOMStorageItemsView(domStorage);
+ domStorage._domStorageView = view;
+ }
+
+ view.show(this.storageViews);
+
+ this.visibleView = view;
+
+ this.storageViewStatusBarItemsContainer.removeChildren();
+ var statusBarItems = view.statusBarItems;
+ for (var i = 0; i < statusBarItems.length; ++i)
+ this.storageViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
},
closeVisibleView: function()
{
- if (this.visibleDatabaseView)
- this.visibleDatabaseView.hide();
- delete this.visibleDatabaseView;
+ if (this.visibleView)
+ this.visibleView.hide();
+ delete this.visibleView;
},
updateDatabaseTables: function(database)
@@ -155,7 +230,7 @@ WebInspector.DatabasesPanel.prototype = {
for (var tableName in database._tableViews) {
if (!(tableName in tableNamesHash)) {
- if (this.visibleDatabaseView === database._tableViews[tableName])
+ if (this.visibleView === database._tableViews[tableName])
this.closeVisibleView();
delete database._tableViews[tableName];
}
@@ -241,6 +316,60 @@ WebInspector.DatabasesPanel.prototype = {
return dataGrid;
},
+ dataGridForDOMStorage: function(domStorage)
+ {
+ if (!domStorage.length)
+ return null;
+
+ var columns = {};
+ columns[0] = {};
+ columns[1] = {};
+ columns[0].title = WebInspector.UIString("Key");
+ columns[0].width = columns[0].title.length;
+ columns[1].title = WebInspector.UIString("Value");
+ columns[1].width = columns[0].title.length;
+
+ var nodes = [];
+
+ var length = domStorage.length;
+ for (index = 0; index < domStorage.length; index++) {
+ var data = {};
+
+ var key = String(domStorage.key(index));
+ data[0] = key;
+ if (key.length > columns[0].width)
+ columns[0].width = key.length;
+
+ var value = String(domStorage.getItem(key));
+ data[1] = value;
+ if (value.length > columns[1].width)
+ columns[1].width = value.length;
+ var node = new WebInspector.DataGridNode(data, false);
+ node.selectable = true;
+ nodes.push(node);
+ }
+
+ var totalColumnWidths = columns[0].width + columns[1].width;
+ width = Math.round((columns[0].width * 100) / totalColumnWidths);
+ const minimumPrecent = 10;
+ if (width < minimumPrecent)
+ width = minimumPrecent;
+ if (width > 100 - minimumPrecent)
+ width = 100 - minimumPrecent;
+ columns[0].width = width;
+ columns[1].width = 100 - width;
+ columns[0].width += "%";
+ columns[1].width += "%";
+
+ var dataGrid = new WebInspector.DOMStorageDataGrid(columns);
+ var length = nodes.length;
+ for (var i = 0; i < length; ++i)
+ dataGrid.appendChild(nodes[i]);
+ if (length > 0)
+ nodes[0].selected = true;
+ return dataGrid;
+ },
+
_startSidebarDragging: function(event)
{
WebInspector.elementDragStart(this.sidebarResizeElement, this._sidebarDragging.bind(this), this._endSidebarDragging.bind(this), event, "col-resize");
@@ -277,7 +406,8 @@ WebInspector.DatabasesPanel.prototype = {
this._currentSidebarWidth = width;
this.sidebarElement.style.width = width + "px";
- this.databaseViews.style.left = width + "px";
+ this.storageViews.style.left = width + "px";
+ this.storageViewStatusBarItemsContainer.style.left = width + "px";
this.sidebarResizeElement.style.left = (width - 3) + "px";
}
}
@@ -355,3 +485,42 @@ WebInspector.SidebarDatabaseTableTreeElement.prototype = {
}
WebInspector.SidebarDatabaseTableTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
+
+WebInspector.DOMStorageSidebarTreeElement = function(domStorage)
+{
+
+ this.domStorage = domStorage;
+
+ WebInspector.SidebarTreeElement.call(this, "domstorage-sidebar-tree-item", domStorage, "", null, false);
+
+ this.refreshTitles();
+}
+
+WebInspector.DOMStorageSidebarTreeElement.prototype = {
+ onselect: function()
+ {
+ WebInspector.panels.databases.showDOMStorage(this.domStorage);
+ },
+
+ get mainTitle()
+ {
+ return this.domStorage.domain;
+ },
+
+ set mainTitle(x)
+ {
+ // Do nothing.
+ },
+
+ get subtitle()
+ {
+ return ""; //this.database.displayDomain;
+ },
+
+ set subtitle(x)
+ {
+ // Do nothing.
+ }
+}
+
+WebInspector.DOMStorageSidebarTreeElement.prototype.__proto__ = WebInspector.SidebarTreeElement.prototype;
diff --git a/WebCore/inspector/front-end/Images/domStorage.png b/WebCore/inspector/front-end/Images/domStorage.png
new file mode 100644
index 0000000..028550c
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/domStorage.png
Binary files differ
diff --git a/WebCore/inspector/front-end/Images/userInputResultIcon.png b/WebCore/inspector/front-end/Images/userInputResultIcon.png
new file mode 100644
index 0000000..794a5ca
--- /dev/null
+++ b/WebCore/inspector/front-end/Images/userInputResultIcon.png
Binary files differ
diff --git a/WebCore/inspector/front-end/ScriptsPanel.js b/WebCore/inspector/front-end/ScriptsPanel.js
index 38a6a96..2792834 100644
--- a/WebCore/inspector/front-end/ScriptsPanel.js
+++ b/WebCore/inspector/front-end/ScriptsPanel.js
@@ -569,11 +569,29 @@ WebInspector.ScriptsPanel.prototype = {
var select = this.filesSelectElement;
- // FIXME: Append in some meaningful order.
var option = document.createElement("option");
option.representedObject = (script.resource || script);
option.text = (script.sourceURL ? WebInspector.displayNameForURL(script.sourceURL) : WebInspector.UIString("(program)"));
- select.appendChild(option);
+
+ var insertionIndex = -1;
+ if (select.childNodes) {
+ insertionIndex = insertionIndexForObjectInListSortedByFunction(option, select.childNodes, function(a, b) {
+ a = a.text.toLowerCase();
+ b = b.text.toLowerCase();
+
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+
+ return 0;
+ });
+ }
+
+ if (insertionIndex < 0)
+ select.appendChild(option);
+ else
+ select.insertBefore(option, select.childNodes.item(insertionIndex));
script.filesSelectOption = option;
diff --git a/WebCore/inspector/front-end/SourceFrame.js b/WebCore/inspector/front-end/SourceFrame.js
index 8d6d6d3..26c0626 100644
--- a/WebCore/inspector/front-end/SourceFrame.js
+++ b/WebCore/inspector/front-end/SourceFrame.js
@@ -225,8 +225,10 @@ WebInspector.SourceFrame.prototype = {
this.element.contentWindow.Element.prototype.addStyleClass = Element.prototype.addStyleClass;
this.element.contentWindow.Element.prototype.removeStyleClass = Element.prototype.removeStyleClass;
+ this.element.contentWindow.Element.prototype.removeMatchingStyleClasses = Element.prototype.removeMatchingStyleClasses;
this.element.contentWindow.Element.prototype.hasStyleClass = Element.prototype.hasStyleClass;
this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeName = Node.prototype.enclosingNodeOrSelfWithNodeName;
+ this.element.contentWindow.Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = Node.prototype.enclosingNodeOrSelfWithNodeNameInArray;
this._addExistingMessagesToSource();
this._addExistingBreakpointsToSource();
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 52a8578..997d4a7 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -10,6 +10,9 @@
<file>DatabasesPanel.js</file>
<file>DatabaseTableView.js</file>
<file>DataGrid.js</file>
+ <file>DOMStorage.js</file>
+ <file>DOMStorageDataGrid.js</file>
+ <file>DOMStorageItemsView.js</file>
<file>ElementsPanel.js</file>
<file>ElementsTreeOutline.js</file>
<file>FontView.js</file>
@@ -66,6 +69,7 @@
<file>Images/disclosureTriangleSmallRightDownWhite.png</file>
<file>Images/disclosureTriangleSmallRightWhite.png</file>
<file>Images/dockButtons.png</file>
+ <file>Images/domStorage.png</file>
<file>Images/elementsIcon.png</file>
<file>Images/enableButtons.png</file>
<file>Images/errorIcon.png</file>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 7e3c224..082955e 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -439,6 +439,7 @@ body.console-visible #console {
#console-messages {
position: absolute;
+ z-index: 0;
top: 0;
left: 0;
right: 0;
@@ -463,6 +464,10 @@ body.console-visible #console {
background-image: url(Images/userInputIcon.png);
}
+.console-user-command-result.console-log-level::before {
+ background-image: url(Images/userInputResultIcon.png);
+}
+
.console-message, .console-user-command {
position: relative;
border-bottom: 1px solid rgb(240, 240, 240);
@@ -470,6 +475,14 @@ body.console-visible #console {
min-height: 16px;
}
+.console-adjacent-user-command-result {
+ border-bottom: none;
+}
+
+.console-adjacent-user-command-result + .console-user-command-result.console-log-level::before {
+ background-image: none;
+}
+
.console-message::before, .console-user-command::before, #console-prompt::before, .console-group-title-level::before {
position: absolute;
display: block;
@@ -561,35 +574,34 @@ body.console-visible #console {
color: rgb(0, 128, 255);
}
-.console-message-url {
- color: rgb(33%, 33%, 33%) !important;
+#console-messages a {
+ color: rgb(33%, 33%, 33%);
cursor: pointer;
- float: right;
}
-.console-message-url:hover {
+#console-messages a:hover {
color: rgb(15%, 15%, 15%);
}
-.console-message-url:hover::after {
- opacity: 1;
+.console-message-url {
+ float: right;
}
.console-group-messages .section {
- margin: 0;
+ margin: 0 0 0 12px !important;
}
.console-group-messages .section .header {
padding: 0 8px 0 0;
background-image: none;
border: none;
- min-height: 16px;
+ min-height: 0;
}
.console-group-messages .section .header::before {
position: absolute;
top: 1px;
- left: 12px;
+ left: 1px;
width: 8px;
height: 8px;
content: url(Images/treeRightTriangleBlack.png);
@@ -601,6 +613,21 @@ body.console-visible #console {
.console-group-messages .section .header .title {
color: black;
+ font-weight: normal;
+}
+
+.console-group-messages .section .properties li .info {
+ padding-top: 0;
+ padding-bottom: 0;
+ color: rgb(60%, 60%, 60%);
+}
+
+.console-group-messages .outline-disclosure {
+ padding-left: 0;
+}
+
+.console-group-messages .outline-disclosure > ol {
+ padding: 0 0 0 12px !important;
}
.console-group-messages .outline-disclosure, .console-group-messages .outline-disclosure ol {
@@ -608,33 +635,39 @@ body.console-visible #console {
line-height: 1em;
}
-.console-group-messages .outline-disclosure li {
- padding-top: 2px;
- padding-bottom: 2px;
+.console-group-messages .outline-disclosure.single-node li {
+ padding-left: 2px;
}
.console-group-messages .outline-disclosure li .selection {
- z-index: 0;
- margin-top: -1px;
+ margin-left: -6px;
+ margin-right: -6px;
+}
+
+.console-formatted-object, .console-formatted-node {
+ position: relative;
+ display: inline-block;
+ vertical-align: top;
}
.console-formatted-object .section, .console-formatted-node .section {
position: static;
}
+.console-formatted-object .properties, .console-formatted-node .properties {
+ padding-left: 0 !important;
+}
+
+.error-message {
+ color: red;
+}
+
.auto-complete-text {
color: rgb(128, 128, 128);
-webkit-user-select: none;
-webkit-user-modify: read-only;
}
-.inspectible-node:hover {
- background-color: rgba(56, 121, 217, 0.1);
- -webkit-border-radius: 5px;
- padding: 0 5px 1px;
- margin: 0 -5px -1px;
-}
-
.panel {
display: none;
overflow: hidden;
@@ -1532,7 +1565,11 @@ body.inactive .sidebar {
content: url(Images/databaseTable.png);
}
-#database-views {
+.domstorage-sidebar-tree-item .icon {
+ content: url(Images/domStorage.png);
+}
+
+#storage-views {
position: absolute;
top: 0;
right: 0;
@@ -1540,7 +1577,7 @@ body.inactive .sidebar {
bottom: 0;
}
-.database-view {
+.storage-view {
display: none;
overflow: hidden;
position: absolute;
@@ -1550,20 +1587,20 @@ body.inactive .sidebar {
bottom: 0;
}
-.database-view.visible {
+.storage-view.visible {
display: block;
}
-.database-view.table {
+.storage-view.table {
overflow: hidden;
}
-.database-view.table .data-grid {
+.storage-view.table .data-grid {
border: none;
height: 100%;
}
-.database-view.table .database-table-empty, .database-view.table .database-table-error {
+.storage-view.table .storage-table-empty, .storage-view.table .storage-table-error {
position: absolute;
top: 0;
bottom: 25%;
@@ -1581,7 +1618,7 @@ body.inactive .sidebar {
white-space: pre-wrap;
}
-.database-view.table .database-table-error {
+.storage-view.table .storage-table-error {
color: rgb(66%, 33%, 33%);
}
@@ -1773,7 +1810,7 @@ body.inactive .data-grid th.sort-ascending, body.inactive .data-grid th.sort-des
text-indent: 10px;
}
-.database-view.query {
+.storage-view.query {
font-size: 10px;
font-family: Monaco, Lucida Console, monospace;
padding: 2px 0;
@@ -2498,6 +2535,10 @@ button.enable-toggle-status-bar-item.toggled-on:active {
padding-left: 37px;
}
+.sidebar-tree > .children > .children > .sidebar-tree-item {
+ padding-left: 37px;
+}
+
.sidebar-tree.hide-disclosure-buttons > .children {
display: none;
}
@@ -2994,3 +3035,39 @@ body.inactive .sidebar-tree-item.selected .bubble.search-matches {
.reset-profile-status-bar-item:active {
background-position: 32px 0;
}
+
+.delete-storage-status-bar-item {
+ background-image: url(Images/excludeButtons.png) !important;
+}
+
+.delete-storage-status-bar-item:active {
+ background-position: 32px 0;
+}
+
+#storage-view-status-bar-items {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 200px;
+ overflow: hidden;
+ border-left: 1px solid rgb(184, 184, 184);
+ margin-left: -1px;
+}
+
+.refresh-storage-status-bar-item {
+ background-image: url(Images/reloadButtons.png) !important;
+}
+
+.refresh-storage-status-bar-item:active {
+ background-position: 32px 0;
+}
+
+#storage-view-status-bar-items {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 200px;
+ overflow: hidden;
+ border-left: 1px solid rgb(184, 184, 184);
+ margin-left: -1px;
+}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index cb38886..77d720b 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -41,7 +41,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="Resource.js"></script>
<script type="text/javascript" src="ResourceCategory.js"></script>
<script type="text/javascript" src="Database.js"></script>
+ <script type="text/javascript" src="DOMStorage.js"></script>
+ <script type="text/javascript" src="DOMStorageItemsView.js"></script>
<script type="text/javascript" src="DataGrid.js"></script>
+ <script type="text/javascript" src="DOMStorageDataGrid.js"></script>
<script type="text/javascript" src="Script.js"></script>
<script type="text/javascript" src="Breakpoint.js"></script>
<script type="text/javascript" src="SidebarPane.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 07ae7db..90ffa2b 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -287,10 +287,14 @@ WebInspector.loaded = function()
databases: new WebInspector.DatabasesPanel()
};
+ var hiddenPanels = (InspectorController.hiddenPanels() || "").split(',');
+
var toolbarElement = document.getElementById("toolbar");
var previousToolbarItem = toolbarElement.children[0];
for (var panelName in this.panels) {
+ if (hiddenPanels.indexOf(panelName) !== -1)
+ continue;
var panel = this.panels[panelName];
var panelToolbarItem = panel.toolbarItem;
panelToolbarItem.addEventListener("click", this._toolbarItemClicked.bind(this));
@@ -795,6 +799,11 @@ WebInspector.addDatabase = function(database)
this.panels.databases.addDatabase(database);
}
+WebInspector.addDOMStorage = function(domStorage)
+{
+ this.panels.databases.addDOMStorage(domStorage);
+}
+
WebInspector.debuggerWasEnabled = function()
{
this.panels.scripts.debuggerWasEnabled();
diff --git a/WebCore/inspector/front-end/utilities.js b/WebCore/inspector/front-end/utilities.js
index 8f86504..7b0a20b 100644
--- a/WebCore/inspector/front-end/utilities.js
+++ b/WebCore/inspector/front-end/utilities.js
@@ -37,6 +37,8 @@ Object.type = function(obj, win)
win = win || window;
+ if (obj instanceof win.Node)
+ return "node";
if (obj instanceof win.String)
return "string";
if (obj instanceof win.Array)
@@ -70,6 +72,7 @@ Object.describe = function(obj, abbreviated)
switch (type1) {
case "object":
+ case "node":
return type2;
case "array":
return "[" + obj.toString() + "]";
@@ -937,6 +940,40 @@ Array.prototype.remove = function(value, onlyFirst)
}
}
+function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
+{
+ // indexOf returns (-lowerBound - 1). Taking (-result - 1) works out to lowerBound.
+ return (-indexOfObjectInListSortedByFunction(anObject, aList, aFunction) - 1);
+}
+
+function indexOfObjectInListSortedByFunction(anObject, aList, aFunction)
+{
+ var first = 0;
+ var last = aList.length - 1;
+ var floor = Math.floor;
+ var mid, c;
+
+ while (first <= last) {
+ mid = floor((first + last) / 2);
+ c = aFunction(anObject, aList[mid]);
+
+ if (c > 0)
+ first = mid + 1;
+ else if (c < 0)
+ last = mid - 1;
+ else {
+ //we return the first occurance of an item in the list.
+ while (mid > 0 && aFunction(anObject, aList[mid - 1]) === 0)
+ mid--;
+ return mid;
+ }
+ }
+
+ // By returning 1 less than the negative lower search bound, we can reuse this function
+ // for both indexOf and insertionIndexFor, with some simple arithmetic.
+ return (-first - 1);
+}
+
String.sprintf = function(format)
{
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
diff --git a/WebCore/loader/Cache.cpp b/WebCore/loader/Cache.cpp
index 212fca3..7f58bf2 100644
--- a/WebCore/loader/Cache.cpp
+++ b/WebCore/loader/Cache.cpp
@@ -145,13 +145,6 @@ CachedResource* Cache::requestResource(DocLoader* docLoader, CachedResource::Typ
if (resource->type() != type)
return 0;
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // addLowBandwidthDisplayRequest() returns true if requesting CSS or JS during low bandwidth display.
- // Here, return 0 to not block parsing or layout.
- if (docLoader->frame() && docLoader->frame()->loader()->addLowBandwidthDisplayRequest(resource))
- return 0;
-#endif
-
if (!disabled()) {
// This will move the resource to the front of its LRU list and increase its access count.
resourceAccessed(resource);
diff --git a/WebCore/loader/CachedCSSStyleSheet.cpp b/WebCore/loader/CachedCSSStyleSheet.cpp
index 10d566e..1fb1a9180 100644
--- a/WebCore/loader/CachedCSSStyleSheet.cpp
+++ b/WebCore/loader/CachedCSSStyleSheet.cpp
@@ -114,15 +114,6 @@ void CachedCSSStyleSheet::checkNotify()
CachedResourceClientWalker w(m_clients);
while (CachedResourceClient *c = w.next())
c->setCSSStyleSheet(m_response.url().string(), m_decoder->encoding().name(), this);
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // if checkNotify() is called from error(), client's setCSSStyleSheet(...)
- // can't find "this" from url, so they can't do clean up if needed.
- // call notifyFinished() to make sure they have a chance.
- CachedResourceClientWalker n(m_clients);
- while (CachedResourceClient* s = n.next())
- s->notifyFinished(this);
-#endif
}
void CachedCSSStyleSheet::error()
diff --git a/WebCore/loader/CachedFont.cpp b/WebCore/loader/CachedFont.cpp
index 0cbdc32..922fc91 100644
--- a/WebCore/loader/CachedFont.cpp
+++ b/WebCore/loader/CachedFont.cpp
@@ -31,7 +31,7 @@
#include "CachedResourceClientWalker.h"
#include "DOMImplementation.h"
#include "FontPlatformData.h"
-#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(SGL)
+#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && PLATFORM(WIN_OS)) || PLATFORM(SGL)
#include "FontCustomPlatformData.h"
#endif
#include "TextResourceDecoder.h"
@@ -60,7 +60,7 @@ CachedFont::CachedFont(const String &url)
CachedFont::~CachedFont()
{
-#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && PLATFORM(WIN_OS))
delete m_fontData;
#endif
}
@@ -100,7 +100,7 @@ void CachedFont::beginLoadIfNeeded(DocLoader* dl)
bool CachedFont::ensureCustomFontData()
{
-#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(SGL)
+#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && PLATFORM(WIN_OS)) || PLATFORM(SGL)
#if ENABLE(SVG_FONTS)
ASSERT(!m_isSVGFont);
#endif
@@ -119,7 +119,7 @@ FontPlatformData CachedFont::platformDataFromCustomData(float size, bool bold, b
if (m_externalSVGDocument)
return FontPlatformData(size, bold, italic);
#endif
-#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(SGL)
+#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && PLATFORM(WIN_OS)) || PLATFORM(SGL)
ASSERT(m_fontData);
return m_fontData->fontPlatformData(static_cast<int>(size), bold, italic, renderingMode);
#else
@@ -137,6 +137,7 @@ bool CachedFont::ensureSVGFontData()
RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
m_externalSVGDocument->write(decoder->decode(m_data->data(), m_data->size()));
+ m_externalSVGDocument->write(decoder->flush());
if (decoder->sawError()) {
m_externalSVGDocument.clear();
return 0;
@@ -174,7 +175,7 @@ SVGFontElement* CachedFont::getSVGFontById(const String& fontName) const
void CachedFont::allClientsRemoved()
{
-#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && PLATFORM(WIN_OS))
if (m_fontData) {
delete m_fontData;
m_fontData = 0;
diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp
index f5ce737..b4ee533 100644
--- a/WebCore/loader/CachedResource.cpp
+++ b/WebCore/loader/CachedResource.cpp
@@ -378,18 +378,10 @@ bool CachedResource::wasPurged() const
unsigned CachedResource::overheadSize() const
{
-
- // FIXME: Find some programmatic lighweight way to calculate response size, and size of the different CachedResource classes.
- // This is a rough estimate of resource overhead based on stats collected from the stress test.
- return sizeof(CachedResource) + 3648;
-
- /* sizeof(CachedResource) +
- 192 + // average size of m_url.
- 384 + // average size of m_clients hash map.
- 1280 * 2 + // average size of ResourceResponse. Doubled to account for the WebCore copy and the CF copy.
- // Mostly due to the size of the hash maps, the Header Map strings and the URL.
- 256 * 2 // Overhead from ResourceRequest, doubled to account for WebCore copy and CF copy.
- // Mostly due to the URL and Header Map.
+ return sizeof(CachedResource) + m_response.memoryUsage() + 576;
+ /*
+ 576 = 192 + // average size of m_url
+ 384; // average size of m_clients hash map
*/
}
diff --git a/WebCore/loader/CachedScript.cpp b/WebCore/loader/CachedScript.cpp
index 411521b..ebf0898 100644
--- a/WebCore/loader/CachedScript.cpp
+++ b/WebCore/loader/CachedScript.cpp
@@ -29,21 +29,20 @@
#include "CachedResourceClient.h"
#include "CachedResourceClientWalker.h"
+#include "TextResourceDecoder.h"
#include <wtf/Vector.h>
namespace WebCore {
CachedScript::CachedScript(const String& url, const String& charset)
: CachedResource(url, Script)
- , m_encoding(charset)
+ , m_decoder(TextResourceDecoder::create("application/javascript", charset))
, m_decodedDataDeletionTimer(this, &CachedScript::decodedDataDeletionTimerFired)
{
// It's javascript we want.
// But some websites think their scripts are <some wrong mimetype here>
// and refuse to serve them if we only accept application/x-javascript.
setAccept("*/*");
- if (!m_encoding.isValid())
- m_encoding = Latin1Encoding();
}
CachedScript::~CachedScript()
@@ -64,14 +63,12 @@ void CachedScript::allClientsRemoved()
void CachedScript::setEncoding(const String& chs)
{
- TextEncoding encoding(chs);
- if (encoding.isValid())
- m_encoding = encoding;
+ m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
}
String CachedScript::encoding() const
{
- return m_encoding.name();
+ return m_decoder->encoding().name();
}
const String& CachedScript::script()
@@ -79,7 +76,8 @@ const String& CachedScript::script()
ASSERT(!isPurgeable());
if (!m_script && m_data) {
- m_script = m_encoding.decode(m_data->data(), encodedSize());
+ m_script = m_decoder->decode(m_data->data(), encodedSize());
+ m_script += m_decoder->flush();
setDecodedSize(m_script.length() * sizeof(UChar));
}
diff --git a/WebCore/loader/CachedScript.h b/WebCore/loader/CachedScript.h
index 1715e06..e1c3ee0 100644
--- a/WebCore/loader/CachedScript.h
+++ b/WebCore/loader/CachedScript.h
@@ -27,12 +27,12 @@
#define CachedScript_h
#include "CachedResource.h"
-#include "TextEncoding.h"
#include "Timer.h"
namespace WebCore {
class DocLoader;
+ class TextResourceDecoder;
class CachedScript : public CachedResource {
public:
@@ -59,7 +59,7 @@ namespace WebCore {
void decodedDataDeletionTimerFired(Timer<CachedScript>*);
String m_script;
- TextEncoding m_encoding;
+ RefPtr<TextResourceDecoder> m_decoder;
Timer<CachedScript> m_decodedDataDeletionTimer;
};
}
diff --git a/WebCore/loader/CrossOriginAccessControl.cpp b/WebCore/loader/CrossOriginAccessControl.cpp
new file mode 100644
index 0000000..f0f8b6a
--- /dev/null
+++ b/WebCore/loader/CrossOriginAccessControl.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "CrossOriginAccessControl.h"
+
+#include "AtomicString.h"
+#include "HTTPParsers.h"
+#include "ResourceResponse.h"
+#include "SecurityOrigin.h"
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+bool isOnAccessControlSimpleRequestMethodWhitelist(const String& method)
+{
+ return method == "GET" || method == "HEAD" || method == "POST";
+}
+
+bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value)
+{
+ if (equalIgnoringCase(name, "accept") || equalIgnoringCase(name, "accept-language") || equalIgnoringCase(name, "content-language"))
+ return true;
+
+ // Preflight is required for MIME types that can not be sent via form submission.
+ if (equalIgnoringCase(name, "content-type")) {
+ String mimeType = extractMIMETypeFromMediaType(value);
+ return equalIgnoringCase(mimeType, "application/x-www-form-urlencoded")
+ || equalIgnoringCase(mimeType, "multipart/form-data")
+ || equalIgnoringCase(mimeType, "text/plain");
+ }
+
+ return false;
+}
+
+bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap& headerMap)
+{
+ if (!isOnAccessControlSimpleRequestMethodWhitelist(method))
+ return false;
+
+ HTTPHeaderMap::const_iterator end = headerMap.end();
+ for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
+ if (!isOnAccessControlSimpleRequestHeaderWhitelist(it->first, it->second))
+ return false;
+ }
+
+ return true;
+}
+
+typedef HashSet<String, CaseFoldingHash> HTTPHeaderSet;
+static HTTPHeaderSet* createAllowedCrossOriginResponseHeadersSet()
+{
+ HTTPHeaderSet* headerSet = new HashSet<String, CaseFoldingHash>;
+
+ headerSet->add("cache-control");
+ headerSet->add("content-language");
+ headerSet->add("content-type");
+ headerSet->add("expires");
+ headerSet->add("last-modified");
+ headerSet->add("pragma");
+
+ return headerSet;
+}
+
+bool isOnAccessControlResponseHeaderWhitelist(const String& name)
+{
+ AtomicallyInitializedStatic(HTTPHeaderSet*, allowedCrossOriginResponseHeaders = createAllowedCrossOriginResponseHeadersSet());
+
+ return allowedCrossOriginResponseHeaders->contains(name);
+}
+
+bool passesAccessControlCheck(const ResourceResponse& response, bool includeCredentials, SecurityOrigin* securityOrigin)
+{
+ // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
+ // even with Access-Control-Allow-Credentials set to true.
+ const String& accessControlOriginString = response.httpHeaderField("Access-Control-Allow-Origin");
+ if (accessControlOriginString == "*" && !includeCredentials)
+ return true;
+
+ RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);
+ if (!accessControlOrigin->isSameSchemeHostPort(securityOrigin))
+ return false;
+
+ if (includeCredentials) {
+ const String& accessControlCredentialsString = response.httpHeaderField("Access-Control-Allow-Credentials");
+ if (accessControlCredentialsString != "true")
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/loader/CrossOriginAccessControl.h b/WebCore/loader/CrossOriginAccessControl.h
new file mode 100644
index 0000000..267646f
--- /dev/null
+++ b/WebCore/loader/CrossOriginAccessControl.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED 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.
+ *
+ */
+
+namespace WebCore {
+
+ class HTTPHeaderMap;
+ class ResourceResponse;
+ class SecurityOrigin;
+ class String;
+
+ bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
+ bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
+ bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
+ bool isOnAccessControlResponseHeaderWhitelist(const String&);
+
+ bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*);
+
+} // namespace WebCore
diff --git a/WebCore/loader/CrossOriginPreflightResultCache.cpp b/WebCore/loader/CrossOriginPreflightResultCache.cpp
new file mode 100644
index 0000000..4bd05b2
--- /dev/null
+++ b/WebCore/loader/CrossOriginPreflightResultCache.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "CrossOriginPreflightResultCache.h"
+
+#include "CrossOriginAccessControl.h"
+#include "ResourceResponse.h"
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+// These values are at the discretion of the user agent.
+static const unsigned defaultPreflightCacheTimeoutSeconds = 5;
+static const unsigned maxPreflightCacheTimeoutSeconds = 600; // Should be short enough to minimize the risk of using a poisoned cache after switching to a secure network.
+
+static bool parseAccessControlMaxAge(const String& string, unsigned& expiryDelta)
+{
+ // FIXME: this will not do the correct thing for a number starting with a '+'
+ bool ok = false;
+ expiryDelta = string.toUIntStrict(&ok);
+ return ok;
+}
+
+template<class HashType>
+static void addToAccessControlAllowList(const String& string, unsigned start, unsigned end, HashSet<String, HashType>& set)
+{
+ StringImpl* stringImpl = string.impl();
+ if (!stringImpl)
+ return;
+
+ // Skip white space from start.
+ while (start <= end && isSpaceOrNewline((*stringImpl)[start]))
+ ++start;
+
+ // only white space
+ if (start > end)
+ return;
+
+ // Skip white space from end.
+ while (end && isSpaceOrNewline((*stringImpl)[end]))
+ --end;
+
+ // substringCopy() is called on the strings because the cache is accessed on multiple threads.
+ set.add(string.substringCopy(start, end - start + 1));
+}
+
+template<class HashType>
+static bool parseAccessControlAllowList(const String& string, HashSet<String, HashType>& set)
+{
+ int start = 0;
+ int end;
+ while ((end = string.find(',', start)) != -1) {
+ if (start == end)
+ return false;
+
+ addToAccessControlAllowList(string, start, end - 1, set);
+ start = end + 1;
+ }
+ if (start != static_cast<int>(string.length()))
+ addToAccessControlAllowList(string, start, string.length() - 1, set);
+
+ return true;
+}
+
+bool CrossOriginPreflightResultCacheItem::parse(const ResourceResponse& response)
+{
+ m_methods.clear();
+ if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Methods"), m_methods))
+ return false;
+
+ m_headers.clear();
+ if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Headers"), m_headers))
+ return false;
+
+ unsigned expiryDelta;
+ if (parseAccessControlMaxAge(response.httpHeaderField("Access-Control-Max-Age"), expiryDelta)) {
+ if (expiryDelta > maxPreflightCacheTimeoutSeconds)
+ expiryDelta = maxPreflightCacheTimeoutSeconds;
+ } else
+ expiryDelta = defaultPreflightCacheTimeoutSeconds;
+
+ m_absoluteExpiryTime = currentTime() + expiryDelta;
+ return true;
+}
+
+bool CrossOriginPreflightResultCacheItem::allowsCrossOriginMethod(const String& method) const
+{
+ return m_methods.contains(method) || isOnAccessControlSimpleRequestMethodWhitelist(method);
+}
+
+bool CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders(const HTTPHeaderMap& requestHeaders) const
+{
+ HTTPHeaderMap::const_iterator end = requestHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
+ if (!m_headers.contains(it->first) && !isOnAccessControlSimpleRequestHeaderWhitelist(it->first, it->second))
+ return false;
+ }
+ return true;
+}
+
+bool CrossOriginPreflightResultCacheItem::allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const
+{
+ if (m_absoluteExpiryTime < currentTime())
+ return false;
+ if (includeCredentials && !m_credentials)
+ return false;
+ if (!allowsCrossOriginMethod(method))
+ return false;
+ if (!allowsCrossOriginHeaders(requestHeaders))
+ return false;
+ return true;
+}
+
+CrossOriginPreflightResultCache& CrossOriginPreflightResultCache::shared()
+{
+ AtomicallyInitializedStatic(CrossOriginPreflightResultCache&, cache = *new CrossOriginPreflightResultCache);
+ return cache;
+}
+
+void CrossOriginPreflightResultCache::appendEntry(const String& origin, const KURL& url, CrossOriginPreflightResultCacheItem* preflightResult)
+{
+ MutexLocker lock(m_mutex);
+ // Note that the entry may already be present in the HashMap if another thread is accessing the same location.
+ m_preflightHashMap.set(std::make_pair(origin.copy(), url.copy()), preflightResult);
+}
+
+bool CrossOriginPreflightResultCache::canSkipPreflight(const String& origin, const KURL& url, bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders)
+{
+ MutexLocker lock(m_mutex);
+ CrossOriginPreflightResultHashMap::iterator cacheIt = m_preflightHashMap.find(std::make_pair(origin, url));
+ if (cacheIt == m_preflightHashMap.end())
+ return false;
+
+ if (cacheIt->second->allowsRequest(includeCredentials, method, requestHeaders))
+ return true;
+
+ delete cacheIt->second;
+ m_preflightHashMap.remove(cacheIt);
+ return false;
+}
+
+void CrossOriginPreflightResultCache::empty()
+{
+ MutexLocker lock(m_mutex);
+ deleteAllValues(m_preflightHashMap);
+ m_preflightHashMap.clear();
+}
+
+} // namespace WebCore
diff --git a/WebCore/loader/CrossOriginPreflightResultCache.h b/WebCore/loader/CrossOriginPreflightResultCache.h
new file mode 100644
index 0000000..39c3cd1
--- /dev/null
+++ b/WebCore/loader/CrossOriginPreflightResultCache.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED 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 "KURLHash.h"
+#include "StringHash.h"
+
+namespace WebCore {
+
+ class HTTPHeaderMap;
+ class ResourceResponse;
+
+ class CrossOriginPreflightResultCacheItem : Noncopyable {
+ public:
+ CrossOriginPreflightResultCacheItem(bool credentials)
+ : m_absoluteExpiryTime(0)
+ , m_credentials(credentials)
+ {
+ }
+
+ bool parse(const ResourceResponse&);
+ bool allowsCrossOriginMethod(const String&) const;
+ bool allowsCrossOriginHeaders(const HTTPHeaderMap&) const;
+ bool allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const;
+
+ private:
+ typedef HashSet<String, CaseFoldingHash> HeadersSet;
+
+ // FIXME: A better solution to holding onto the absolute expiration time might be
+ // to start a timer for the expiration delta that removes this from the cache when
+ // it fires.
+ double m_absoluteExpiryTime;
+ bool m_credentials;
+ HashSet<String> m_methods;
+ HeadersSet m_headers;
+ };
+
+ class CrossOriginPreflightResultCache : Noncopyable {
+ public:
+ static CrossOriginPreflightResultCache& shared();
+
+ void appendEntry(const String& origin, const KURL&, CrossOriginPreflightResultCacheItem*);
+ bool canSkipPreflight(const String& origin, const KURL&, bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
+
+ void empty();
+
+ private:
+ CrossOriginPreflightResultCache() { }
+
+ typedef HashMap<std::pair<String, KURL>, CrossOriginPreflightResultCacheItem*> CrossOriginPreflightResultHashMap;
+
+ CrossOriginPreflightResultHashMap m_preflightHashMap;
+ Mutex m_mutex;
+ };
+
+} // namespace WebCore
diff --git a/WebCore/loader/DocLoader.cpp b/WebCore/loader/DocLoader.cpp
index 28bbde7..c96348d 100644
--- a/WebCore/loader/DocLoader.cpp
+++ b/WebCore/loader/DocLoader.cpp
@@ -3,6 +3,7 @@
Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -67,6 +68,9 @@ DocLoader::~DocLoader()
for (DocumentResourceMap::iterator it = m_documentResources.begin(); it != end; ++it)
it->second->setDocLoader(0);
m_cache->removeDocLoader(this);
+
+ // Make sure no requests still point to this DocLoader
+ ASSERT(m_requestCount == 0);
}
Frame* DocLoader::frame() const
@@ -423,6 +427,11 @@ void DocLoader::clearPreloads()
m_preloads.clear();
}
+void DocLoader::clearPendingPreloads()
+{
+ m_pendingPreloads.clear();
+}
+
#if PRELOAD_DEBUG
void DocLoader::printPreloadStats()
{
diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/DocLoader.h
index b87b622..356349e 100644
--- a/WebCore/loader/DocLoader.h
+++ b/WebCore/loader/DocLoader.h
@@ -2,6 +2,7 @@
Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -97,15 +98,12 @@ public:
void setAllowStaleResources(bool allowStaleResources) { m_allowStaleResources = allowStaleResources; }
-#if USE(LOW_BANDWIDTH_DISPLAY)
- void replaceDocument(Document* doc) { m_doc = doc; }
-#endif
-
void incrementRequestCount();
void decrementRequestCount();
int requestCount();
void clearPreloads();
+ void clearPendingPreloads();
void preload(CachedResource::Type, const String& url, const String& charset, bool referencedFromBody);
void checkForPendingPreloads();
void printPreloadStats();
diff --git a/WebCore/loader/DocumentLoader.cpp b/WebCore/loader/DocumentLoader.cpp
index 12be864..bdf83a8 100644
--- a/WebCore/loader/DocumentLoader.cpp
+++ b/WebCore/loader/DocumentLoader.cpp
@@ -118,8 +118,7 @@ static inline String canonicalizedTitle(const String& title, Frame* frame)
buffer.shrink(builderIndex + 1);
// Replace the backslashes with currency symbols if the encoding requires it.
- if (frame->document())
- frame->document()->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
+ frame->document()->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
return String::adopt(buffer);
}
@@ -156,7 +155,7 @@ DocumentLoader::DocumentLoader(const ResourceRequest& req, const SubstituteData&
, m_loadingFromCachedPage(false)
, m_stopRecordingResponses(false)
, m_substituteResourceDeliveryTimer(this, &DocumentLoader::substituteResourceDeliveryTimerFired)
- , m_urlForHistoryReflectsClientRedirect(false)
+ , m_didCreateGlobalHistoryEntry(false)
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
, m_candidateApplicationCacheGroup(0)
#endif
@@ -296,7 +295,7 @@ void DocumentLoader::stopLoading()
// still parsing. Failure to do so can cause a world leak.
Document* doc = m_frame->document();
- if (loading || (doc && doc->parsing()))
+ if (loading || doc->parsing())
m_frame->loader()->stopLoading(false);
}
@@ -474,13 +473,12 @@ bool DocumentLoader::isLoadingInAPISense() const
return true;
if (!m_subresourceLoaders.isEmpty())
return true;
- if (Document* doc = m_frame->document()) {
- if (doc->docLoader()->requestCount())
+ Document* doc = m_frame->document();
+ if (doc->docLoader()->requestCount())
+ return true;
+ if (Tokenizer* tok = doc->tokenizer())
+ if (tok->processingData())
return true;
- if (Tokenizer* tok = doc->tokenizer())
- if (tok->processingData())
- return true;
- }
}
return frameLoader()->subframeIsLoading();
}
@@ -559,8 +557,6 @@ PassRefPtr<ArchiveResource> DocumentLoader::subresource(const KURL& url) const
return 0;
Document* doc = m_frame->document();
- if (!doc)
- return archiveResourceForURL(url);
CachedResource* resource = doc->docLoader()->cachedResource(url);
if (!resource || resource->preloadResult() == CachedResource::PreloadReferenced)
@@ -575,8 +571,6 @@ void DocumentLoader::getSubresources(Vector<PassRefPtr<ArchiveResource> >& subre
return;
Document* document = m_frame->document();
- if (!document)
- return;
const DocLoader::DocumentResourceMap& allResources = document->docLoader()->allCachedResources();
DocLoader::DocumentResourceMap::const_iterator end = allResources.end();
diff --git a/WebCore/loader/DocumentLoader.h b/WebCore/loader/DocumentLoader.h
index 85cceef..a861457 100644
--- a/WebCore/loader/DocumentLoader.h
+++ b/WebCore/loader/DocumentLoader.h
@@ -160,9 +160,21 @@ namespace WebCore {
KURL urlForHistory() const;
bool urlForHistoryReflectsFailure() const;
- bool urlForHistoryReflectsServerRedirect() const { return urlForHistory() != url(); }
- bool urlForHistoryReflectsClientRedirect() const { return m_urlForHistoryReflectsClientRedirect; }
- void setURLForHistoryReflectsClientRedirect(bool b) { m_urlForHistoryReflectsClientRedirect = b; }
+
+ // These accessors accomodate WebCore's somewhat fickle custom of creating history
+ // items for redirects, but only sometimes. For "source" and "destination",
+ // these accessors return the URL that would have been used if a history
+ // item were created. This allows WebKit to link history items reflecting
+ // redirects into a chain from start to finish.
+ String clientRedirectSourceForHistory() const { return m_clientRedirectSourceForHistory; } // null if no client redirect occurred.
+ String clientRedirectDestinationForHistory() const { return urlForHistory(); }
+ void setClientRedirectSourceForHistory(const String& clientedirectSourceForHistory) { m_clientRedirectSourceForHistory = clientedirectSourceForHistory; }
+
+ String serverRedirectSourceForHistory() const { return urlForHistory() == url() ? String() : urlForHistory(); } // null if no server redirect occurred.
+ String serverRedirectDestinationForHistory() const { return url(); }
+
+ bool didCreateGlobalHistoryEntry() const { return m_didCreateGlobalHistoryEntry; }
+ void setDidCreateGlobalHistoryEntry(bool didCreateGlobalHistoryEntry) { m_didCreateGlobalHistoryEntry = didCreateGlobalHistoryEntry; }
void loadFromCachedPage(PassRefPtr<CachedPage>);
void setLoadingFromCachedPage(bool loading) { m_loadingFromCachedPage = loading; }
@@ -297,7 +309,8 @@ namespace WebCore {
HashSet<String> m_resourcesClientKnowsAbout;
Vector<String> m_resourcesLoadedFromMemoryCacheForClientNotification;
- bool m_urlForHistoryReflectsClientRedirect;
+ String m_clientRedirectSourceForHistory;
+ bool m_didCreateGlobalHistoryEntry;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
// The application cache that the document loader is associated with (if any).
diff --git a/WebCore/loader/DocumentThreadableLoader.cpp b/WebCore/loader/DocumentThreadableLoader.cpp
index 05f8667..685db8c 100644
--- a/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/WebCore/loader/DocumentThreadableLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,9 @@
#include "AuthenticationChallenge.h"
#include "Document.h"
+#include "DocumentThreadableLoader.h"
+#include "Frame.h"
+#include "FrameLoader.h"
#include "ResourceRequest.h"
#include "SecurityOrigin.h"
#include "SubresourceLoader.h"
@@ -40,8 +43,43 @@
namespace WebCore {
+void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest& request, ThreadableLoaderClient& client)
+{
+ bool sameOriginRequest = document->securityOrigin()->canRequest(request.url());
+
+ Vector<char> data;
+ ResourceError error;
+ ResourceResponse response;
+ unsigned long identifier = std::numeric_limits<unsigned long>::max();
+ if (document->frame())
+ identifier = document->frame()->loader()->loadResourceSynchronously(request, error, response, data);
+
+ // No exception for file:/// resources, see <rdar://problem/4962298>.
+ // Also, if we have an HTTP response, then it wasn't a network error in fact.
+ if (!error.isNull() && !request.url().isLocalFile() && response.httpStatusCode() <= 0) {
+ client.didFail(error);
+ return;
+ }
+
+ // FIXME: This check along with the one in willSendRequest is specific to xhr and
+ // should be made more generic.
+ if (sameOriginRequest && !document->securityOrigin()->canRequest(response.url())) {
+ client.didFailRedirectCheck();
+ return;
+ }
+
+ client.didReceiveResponse(response);
+
+ const char* bytes = static_cast<const char*>(data.data());
+ int len = static_cast<int>(data.size());
+ client.didReceiveData(bytes, len);
+
+ client.didFinishLoading(identifier);
+}
+
PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
{
+ ASSERT(document);
RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, request, callbacksSetting, contentSniff));
if (!loader->m_loader)
loader = 0;
@@ -81,7 +119,7 @@ void DocumentThreadableLoader::willSendRequest(SubresourceLoader*, ResourceReque
// FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
if (!m_document->securityOrigin()->canRequest(request.url())) {
RefPtr<DocumentThreadableLoader> protect(this);
- m_client->didFail();
+ m_client->didFailRedirectCheck();
cancel();
}
}
@@ -114,10 +152,7 @@ void DocumentThreadableLoader::didFinishLoading(SubresourceLoader* loader)
void DocumentThreadableLoader::didFail(SubresourceLoader*, const ResourceError& error)
{
ASSERT(m_client);
- if (error.isCancellation())
- m_client->didGetCancelled();
- else
- m_client->didFail();
+ m_client->didFail(error);
}
void DocumentThreadableLoader::receivedCancellation(SubresourceLoader*, const AuthenticationChallenge& challenge)
diff --git a/WebCore/loader/DocumentThreadableLoader.h b/WebCore/loader/DocumentThreadableLoader.h
index d909091..ddf8570 100644
--- a/WebCore/loader/DocumentThreadableLoader.h
+++ b/WebCore/loader/DocumentThreadableLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -39,11 +39,12 @@
namespace WebCore {
class Document;
- class ResourceRequest;
+ struct ResourceRequest;
class ThreadableLoaderClient;
class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, public ThreadableLoader, private SubresourceLoaderClient {
public:
+ static void loadResourceSynchronously(Document*, const ResourceRequest&, ThreadableLoaderClient&);
static PassRefPtr<DocumentThreadableLoader> create(Document*, ThreadableLoaderClient*, const ResourceRequest&, LoadCallbacks, ContentSniff);
virtual ~DocumentThreadableLoader();
diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h
index 5871f9f..ace7e9e 100644
--- a/WebCore/loader/EmptyClients.h
+++ b/WebCore/loader/EmptyClients.h
@@ -211,14 +211,14 @@ public:
virtual void committedLoad(DocumentLoader*, const char*, int) { }
virtual void finishedLoading(DocumentLoader*) { }
- virtual ResourceError cancelledError(const ResourceRequest&) { return ResourceError(); }
- virtual ResourceError blockedError(const ResourceRequest&) { return ResourceError(); }
- virtual ResourceError cannotShowURLError(const ResourceRequest&) { return ResourceError(); }
- virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&) { return ResourceError(); }
+ virtual ResourceError cancelledError(const ResourceRequest&) { ResourceError error("", 0, "", ""); error.setIsCancellation(true); return error; }
+ virtual ResourceError blockedError(const ResourceRequest&) { return ResourceError("", 0, "", ""); }
+ virtual ResourceError cannotShowURLError(const ResourceRequest&) { return ResourceError("", 0, "", ""); }
+ virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&) { return ResourceError("", 0, "", ""); }
- virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&) { return ResourceError(); }
- virtual ResourceError fileDoesNotExistError(const ResourceResponse&) { return ResourceError(); }
- virtual ResourceError pluginWillHandleLoadError(const ResourceResponse&) { return ResourceError(); }
+ virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&) { return ResourceError("", 0, "", ""); }
+ virtual ResourceError fileDoesNotExistError(const ResourceResponse&) { return ResourceError("", 0, "", ""); }
+ virtual ResourceError pluginWillHandleLoadError(const ResourceResponse&) { return ResourceError("", 0, "", ""); }
virtual bool shouldFallBack(const ResourceError&) { return false; }
@@ -244,7 +244,7 @@ public:
virtual void transitionToCommittedForNewPage() { }
virtual void updateGlobalHistory() { }
- virtual void updateGlobalHistoryForRedirectWithoutHistoryItem() { }
+ virtual void updateGlobalHistoryRedirectLinks() { }
virtual bool shouldGoToHistoryItem(HistoryItem*) const { return false; }
#ifdef ANDROID_HISTORY_CLIENT
virtual void dispatchDidAddHistoryItem(HistoryItem*) const {}
@@ -255,14 +255,15 @@ public:
virtual bool canCachePage() const { return false; }
virtual PassRefPtr<Frame> createFrame(const KURL&, const String&, HTMLFrameOwnerElement*, const String&, bool, int, int) { return 0; }
- virtual Widget* createPlugin(const IntSize&, Element*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) { return 0; }
- virtual Widget* createJavaAppletWidget(const IntSize&, Element*, const KURL&, const Vector<String>&, const Vector<String>&) { return 0; }
+ virtual Widget* createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) { return 0; }
+ virtual Widget* createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) { return 0; }
virtual ObjectContentType objectContentType(const KURL&, const String&) { return ObjectContentType(); }
virtual String overrideMediaType() const { return String(); }
virtual void redirectDataToPlugin(Widget*) { }
virtual void windowObjectCleared() { }
+ virtual void documentElementAvailable() { }
virtual void didPerformFirstNavigation() const { }
virtual void registerForIconNotification(bool) { }
@@ -270,6 +271,9 @@ public:
#if PLATFORM(MAC)
virtual NSCachedURLResponse* willCacheResponse(DocumentLoader*, unsigned long, NSCachedURLResponse* response) const { return response; }
#endif
+#if USE(CFNETWORK)
+ virtual bool shouldCacheResponse(DocumentLoader*, unsigned long, const ResourceResponse&, const unsigned char*, unsigned long long) { return true; }
+#endif
};
@@ -345,6 +349,9 @@ public:
virtual void learnWord(const String&) { }
virtual void checkSpellingOfString(const UChar*, int, int*, int*) { }
virtual void checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*) { }
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ virtual void checkSpellingAndGrammarOfParagraph(const UChar*, int, bool, Vector<TextCheckingResult>&) { }
+#endif
virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) { }
virtual void updateSpellingUIWithMisspelledWord(const String&) { }
virtual void showSpellingUI(bool) { }
@@ -397,6 +404,8 @@ public:
virtual String localizedStringsURL() { return String(); }
+ virtual String hiddenPanels() { return String(); }
+
virtual void showWindow() { }
virtual void closeWindow() { }
diff --git a/WebCore/loader/FTPDirectoryDocument.cpp b/WebCore/loader/FTPDirectoryDocument.cpp
index 08ef896..188c84c 100644
--- a/WebCore/loader/FTPDirectoryDocument.cpp
+++ b/WebCore/loader/FTPDirectoryDocument.cpp
@@ -57,7 +57,7 @@ class FTPDirectoryTokenizer : public HTMLTokenizer {
public:
FTPDirectoryTokenizer(HTMLDocument*);
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
virtual bool isWaitingForScripts() const { return false; }
@@ -117,7 +117,7 @@ void FTPDirectoryTokenizer::appendEntry(const String& filename, const String& si
RefPtr<Element> rowElement = m_tableElement->insertRow(-1, ec);
rowElement->setAttribute("class", "ftpDirectoryEntryRow", ec);
- RefPtr<Element> element = m_doc->createElementNS(xhtmlNamespaceURI, "td", ec);
+ RefPtr<Element> element = m_doc->createElement(tdTag, false);
element->appendChild(new Text(m_doc, String(&noBreakSpace, 1)), ec);
if (isDirectory)
element->setAttribute("class", "ftpDirectoryIcon ftpDirectoryTypeDirectory", ec);
@@ -129,12 +129,12 @@ void FTPDirectoryTokenizer::appendEntry(const String& filename, const String& si
element->setAttribute("class", "ftpDirectoryFileName", ec);
rowElement->appendChild(element, ec);
- element = m_doc->createElementNS(xhtmlNamespaceURI, "td", ec);
+ element = m_doc->createElement(tdTag, false);
element->appendChild(new Text(m_doc, date), ec);
element->setAttribute("class", "ftpDirectoryFileDate", ec);
rowElement->appendChild(element, ec);
- element = m_doc->createElementNS(xhtmlNamespaceURI, "td", ec);
+ element = m_doc->createElement(tdTag, false);
element->appendChild(new Text(m_doc, size), ec);
element->setAttribute("class", "ftpDirectoryFileSize", ec);
rowElement->appendChild(element, ec);
@@ -150,11 +150,11 @@ PassRefPtr<Element> FTPDirectoryTokenizer::createTDForFilename(const String& fil
else
fullURL.append("/" + filename);
- RefPtr<Element> anchorElement = m_doc->createElementNS(xhtmlNamespaceURI, "a", ec);
+ RefPtr<Element> anchorElement = m_doc->createElement(aTag, false);
anchorElement->setAttribute("href", fullURL, ec);
anchorElement->appendChild(new Text(m_doc, filename), ec);
- RefPtr<Element> tdElement = m_doc->createElementNS(xhtmlNamespaceURI, "td", ec);
+ RefPtr<Element> tdElement = m_doc->createElement(tdTag, false);
tdElement->appendChild(anchorElement, ec);
return tdElement.release();
@@ -276,7 +276,7 @@ static String processFileDateString(const FTPTime& fileTime)
return "Yesterday" + timeOfDay;
}
- if (now.tm_mday == 1 && (now.tm_mon == fileTime.tm_mon + 1 || now.tm_mon == 0 && fileTime.tm_mon == 11) &&
+ if (now.tm_mday == 1 && (now.tm_mon == fileTime.tm_mon + 1 || (now.tm_mon == 0 && fileTime.tm_mon == 11)) &&
wasLastDayOfMonth(fileTime.tm_year, fileTime.tm_mon, fileTime.tm_mday))
return "Yesterday" + timeOfDay;
}
@@ -303,8 +303,9 @@ static String processFileDateString(const FTPTime& fileTime)
void FTPDirectoryTokenizer::parseAndAppendOneLine(const String& inputLine)
{
ListResult result;
+ CString latin1Input = inputLine.latin1();
- FTPEntryType typeResult = parseOneFTPLine(inputLine.latin1().data(), m_listState, result);
+ FTPEntryType typeResult = parseOneFTPLine(latin1Input.data(), m_listState, result);
// FTPMiscEntry is a comment or usage statistic which we don't care about, and junk is invalid data - bail in these 2 cases
if (typeResult == FTPMiscEntry || typeResult == FTPJunkEntry)
@@ -364,9 +365,9 @@ bool FTPDirectoryTokenizer::loadDocumentTemplate()
return true;
// Otherwise create one manually
- ExceptionCode ec;
- tableElement = m_doc->createElementNS(xhtmlNamespaceURI, "table", ec);
+ tableElement = m_doc->createElement(tableTag, false);
m_tableElement = static_cast<HTMLTableElement*>(tableElement.get());
+ ExceptionCode ec;
m_tableElement->setAttribute("id", "ftpDirectoryTable", ec);
// If we didn't find the table element, lets try to append our own to the body
@@ -386,20 +387,20 @@ void FTPDirectoryTokenizer::createBasicDocument()
// FIXME: Make this "basic document" more acceptable
- ExceptionCode ec;
- RefPtr<Element> bodyElement = m_doc->createElementNS(xhtmlNamespaceURI, "body", ec);
+ RefPtr<Element> bodyElement = m_doc->createElement(bodyTag, false);
+ ExceptionCode ec;
m_doc->appendChild(bodyElement, ec);
- RefPtr<Element> tableElement = m_doc->createElementNS(xhtmlNamespaceURI, "table", ec);
+ RefPtr<Element> tableElement = m_doc->createElement(tableTag, false);
m_tableElement = static_cast<HTMLTableElement*>(tableElement.get());
m_tableElement->setAttribute("id", "ftpDirectoryTable", ec);
bodyElement->appendChild(m_tableElement, ec);
}
-bool FTPDirectoryTokenizer::write(const SegmentedString& s, bool /*appendData*/)
+void FTPDirectoryTokenizer::write(const SegmentedString& s, bool /*appendData*/)
{
// Make sure we have the table element to append to by loading the template set in the pref, or
// creating a very basic document with the appropriate table
@@ -439,7 +440,7 @@ bool FTPDirectoryTokenizer::write(const SegmentedString& s, bool /*appendData*/)
if (!foundNewLine) {
m_dest = m_buffer;
- return false;
+ return;
}
UChar* start = m_buffer;
@@ -460,8 +461,6 @@ bool FTPDirectoryTokenizer::write(const SegmentedString& s, bool /*appendData*/)
// Copy the partial line we have left to the carryover buffer
if (cursor - start > 1)
m_carryOver.append(String(start, cursor - start - 1));
-
- return false;
}
void FTPDirectoryTokenizer::finish()
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index edcdbf0..bfc2686 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -57,6 +57,7 @@
#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLAnchorElement.h"
+#include "HTMLAppletElement.h"
#include "HTMLFormElement.h"
#include "HTMLFrameElement.h"
#include "HTMLNames.h"
@@ -124,11 +125,34 @@ using namespace SVGNames;
#endif
using namespace HTMLNames;
-#if USE(LOW_BANDWIDTH_DISPLAY)
-const unsigned int cMaxPendingSourceLengthInLowBandwidthDisplay = 128 * 1024;
+typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
+
+static URLSchemesMap& localSchemes()
+{
+ DEFINE_STATIC_LOCAL(URLSchemesMap, localSchemes, ());
+
+ if (localSchemes.isEmpty()) {
+ localSchemes.add("file");
+#if PLATFORM(MAC)
+ localSchemes.add("applewebdata");
+#endif
+#if PLATFORM(QT)
+ localSchemes.add("qrc");
#endif
+ }
+
+ return localSchemes;
+}
+
+static URLSchemesMap& noAccessSchemes()
+{
+ DEFINE_STATIC_LOCAL(URLSchemesMap, noAccessSchemes, ());
+
+ if (noAccessSchemes.isEmpty())
+ noAccessSchemes.add("data");
-typedef HashSet<String, CaseFoldingHash> LocalSchemesMap;
+ return noAccessSchemes;
+}
struct FormSubmission {
FormSubmission(const char* action, const String& url, PassRefPtr<FormData> formData,
@@ -159,15 +183,16 @@ struct FormSubmission {
struct ScheduledRedirection {
enum Type { redirection, locationChange, historyNavigation, locationChangeDuringLoad };
- Type type;
- double delay;
- String url;
- String referrer;
- int historySteps;
- bool lockHistory;
- bool lockBackForwardList;
- bool wasUserGesture;
- bool wasRefresh;
+
+ const Type type;
+ const double delay;
+ const String url;
+ const String referrer;
+ const int historySteps;
+ const bool lockHistory;
+ const bool lockBackForwardList;
+ const bool wasUserGesture;
+ const bool wasRefresh;
ScheduledRedirection(double delay, const String& url, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh)
: type(redirection)
@@ -179,6 +204,7 @@ struct ScheduledRedirection {
, wasUserGesture(wasUserGesture)
, wasRefresh(refresh)
{
+ ASSERT(!url.isEmpty());
}
ScheduledRedirection(Type locationChangeType, const String& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool wasUserGesture, bool refresh)
@@ -192,6 +218,8 @@ struct ScheduledRedirection {
, wasUserGesture(wasUserGesture)
, wasRefresh(refresh)
{
+ ASSERT(locationChangeType == locationChange || locationChangeType == locationChangeDuringLoad);
+ ASSERT(!url.isEmpty());
}
explicit ScheduledRedirection(int historyNavigationSteps)
@@ -199,6 +227,7 @@ struct ScheduledRedirection {
, delay(0)
, historySteps(historyNavigationSteps)
, lockHistory(false)
+ , lockBackForwardList(false)
, wasUserGesture(false)
, wasRefresh(false)
{
@@ -235,6 +264,11 @@ static int numRequests(Document* document)
return document->docLoader()->requestCount();
}
+static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame* parentFrame)
+{
+ return parentFrame && parentFrame->document()->securityOrigin()->canAccess(frame->document()->securityOrigin());
+}
+
FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
: m_frame(frame)
, m_client(client)
@@ -272,11 +306,6 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
#ifndef NDEBUG
, m_didDispatchDidCommitLoad(false)
#endif
-#if USE(LOW_BANDWIDTH_DISPLAY)
- , m_useLowBandwidthDisplay(true)
- , m_finishedParsingDuringLowBandwidthDisplay(false)
- , m_needToSwitchOutLowBandwidthDisplay(false)
-#endif
#if ENABLE(WML)
, m_forceReloadWmlDeck(false)
#endif
@@ -392,7 +421,6 @@ void FrameLoader::changeLocation(const String& url, const String& referrer, bool
changeLocation(completeURL(url), referrer, lockHistory, lockBackForwardList, userGesture, refresh);
}
-
void FrameLoader::changeLocation(const KURL& url, const String& referrer, bool lockHistory, bool lockBackForwardList, bool userGesture, bool refresh)
{
RefPtr<Frame> protect(m_frame);
@@ -424,7 +452,7 @@ void FrameLoader::urlSelected(const ResourceRequest& request, const String& _tar
return;
String target = _target;
- if (target.isEmpty() && m_frame->document())
+ if (target.isEmpty())
target = m_frame->document()->baseTarget();
FrameLoadRequest frameRequest(request, target);
@@ -437,14 +465,6 @@ void FrameLoader::urlSelected(const ResourceRequest& request, const String& _tar
bool FrameLoader::requestFrame(HTMLFrameOwnerElement* ownerElement, const String& urlString, const AtomicString& frameName)
{
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // don't create sub-frame during low bandwidth display
- if (frame()->document()->inLowBandwidthDisplay()) {
- m_needToSwitchOutLowBandwidthDisplay = true;
- return false;
- }
-#endif
-
// Support for <frame src="javascript:string">
KURL scriptURL;
KURL url;
@@ -649,14 +669,6 @@ void FrameLoader::stopLoading(bool sendUnload)
child->loader()->stopLoading(sendUnload);
cancelRedirection();
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- if (m_frame->document() && m_frame->document()->inLowBandwidthDisplay()) {
- // Since loading is forced to stop, reset the state without really switching.
- m_needToSwitchOutLowBandwidthDisplay = false;
- switchOutLowBandwidthDisplayIfReady();
- }
-#endif
}
void FrameLoader::stop()
@@ -665,16 +677,10 @@ void FrameLoader::stop()
// The frame's last ref may be removed and it will be deleted by checkCompleted().
RefPtr<Frame> protector(m_frame);
- if (m_frame->document()) {
- if (m_frame->document()->tokenizer())
- m_frame->document()->tokenizer()->stopParsing();
- m_frame->document()->finishParsing();
- } else
- // WebKit partially uses WebCore when loading non-HTML docs. In these cases doc==nil, but
- // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
- // become true. An example is when a subframe is a pure text doc, and that subframe is the
- // last one to complete.
- checkCompleted();
+ if (m_frame->document()->tokenizer())
+ m_frame->document()->tokenizer()->stopParsing();
+ m_frame->document()->finishParsing();
+
if (m_iconLoader)
m_iconLoader->stopLoading();
}
@@ -703,7 +709,7 @@ KURL FrameLoader::iconURL()
return KURL();
// If we have an iconURL from a Link element, return that
- if (m_frame->document() && !m_frame->document()->iconURL().isEmpty())
+ if (!m_frame->document()->iconURL().isEmpty())
return KURL(m_frame->document()->iconURL());
// Don't return a favicon iconURL unless we're http or https
@@ -777,13 +783,13 @@ bool FrameLoader::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool
return true;
SecurityOrigin* currentSecurityOrigin = 0;
- if (m_frame->document())
- currentSecurityOrigin = m_frame->document()->securityOrigin();
+ currentSecurityOrigin = m_frame->document()->securityOrigin();
// FIXME: We should always replace the document, but doing so
// synchronously can cause crashes:
// http://bugs.webkit.org/show_bug.cgi?id=16782
if (replaceDocument) {
+ stopAllLoaders();
begin(m_URL, true, currentSecurityOrigin);
write(scriptResult);
end();
@@ -835,7 +841,7 @@ void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects)
return;
m_needsClear = false;
- if (m_frame->document() && !m_frame->document()->inPageCache()) {
+ if (!m_frame->document()->inPageCache()) {
m_frame->document()->cancelParsing();
m_frame->document()->stopActiveDOMObjects();
if (m_frame->document()->attached()) {
@@ -932,12 +938,18 @@ void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin)
// might destroy the document that owns it.
RefPtr<SecurityOrigin> forcedSecurityOrigin = origin;
- bool resetScripting = !(m_isDisplayingInitialEmptyDocument && m_frame->document() && m_frame->document()->securityOrigin()->isSecureTransitionTo(url));
+ RefPtr<Document> document;
+
+ // Create a new document before clearing the frame, because it may need to inherit an aliased security context.
+ if (!m_isDisplayingInitialEmptyDocument && m_client->shouldUsePluginDocument(m_responseMIMEType))
+ document = PluginDocument::create(m_frame);
+ else
+ document = DOMImplementation::createDocument(m_responseMIMEType, m_frame, m_frame->inViewSourceMode());
+
+ bool resetScripting = !(m_isDisplayingInitialEmptyDocument && m_frame->document()->securityOrigin()->isSecureTransitionTo(url));
clear(resetScripting, resetScripting);
if (resetScripting)
m_frame->script()->updatePlatformScriptObjects();
- if (dispatch)
- dispatchWindowObjectAvailable();
m_needsClear = true;
m_isComplete = false;
@@ -952,14 +964,11 @@ void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin)
m_outgoingReferrer = ref.string();
m_URL = url;
- RefPtr<Document> document;
-
- if (!m_isDisplayingInitialEmptyDocument && m_client->shouldUsePluginDocument(m_responseMIMEType))
- document = PluginDocument::create(m_frame);
- else
- document = DOMImplementation::createDocument(m_responseMIMEType, m_frame, m_frame->inViewSourceMode());
m_frame->setDocument(document);
+ if (dispatch)
+ dispatchWindowObjectAvailable();
+
document->setURL(m_URL);
if (m_decoder)
document->setDecoder(m_decoder.get());
@@ -995,18 +1004,6 @@ void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin)
if (m_frame->view())
m_frame->view()->setContentsSize(IntSize());
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // Low bandwidth display is a first pass display without external resources
- // used to give an instant visual feedback. We currently only enable it for
- // HTML documents in the top frame.
- if (document->isHTMLDocument() && !m_frame->tree()->parent() && m_useLowBandwidthDisplay) {
- m_pendingSourceInLowBandwidthDisplay = String();
- m_finishedParsingDuringLowBandwidthDisplay = false;
- m_needToSwitchOutLowBandwidthDisplay = false;
- document->setLowBandwidthDisplay(true);
- }
-#endif
}
void FrameLoader::write(const char* str, int len, bool flush)
@@ -1025,12 +1022,28 @@ void FrameLoader::write(const char* str, int len, bool flush)
}
if (!m_decoder) {
- Settings* settings = m_frame->settings();
- m_decoder = TextResourceDecoder::create(m_responseMIMEType, settings ? settings->defaultTextEncodingName() : String());
- if (m_encoding.isEmpty()) {
+ if (Settings* settings = m_frame->settings()) {
+ m_decoder = TextResourceDecoder::create(m_responseMIMEType,
+ settings->defaultTextEncodingName(),
+ settings->usesEncodingDetector());
Frame* parentFrame = m_frame->tree()->parent();
- if (parentFrame && parentFrame->document()->securityOrigin()->canAccess(m_frame->document()->securityOrigin()))
- m_decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::DefaultEncoding);
+ // Set the hint encoding to the parent frame encoding only if
+ // the parent and the current frames share the security origin.
+ // We impose this condition because somebody can make a child frame
+ // containing a carefully crafted html/javascript in one encoding
+ // that can be mistaken for hintEncoding (or related encoding) by
+ // an auto detector. When interpreted in the latter, it could be
+ // an attack vector.
+ // FIXME: This might be too cautious for non-7bit-encodings and
+ // we may consider relaxing this later after testing.
+ if (canReferToParentFrameEncoding(m_frame, parentFrame))
+ m_decoder->setHintEncoding(parentFrame->document()->decoder());
+ } else
+ m_decoder = TextResourceDecoder::create(m_responseMIMEType, String());
+ Frame* parentFrame = m_frame->tree()->parent();
+ if (m_encoding.isEmpty()) {
+ if (canReferToParentFrameEncoding(m_frame, parentFrame))
+ m_decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::EncodingFromParentFrame);
} else {
m_decoder->setEncoding(m_encoding,
m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader);
@@ -1044,11 +1057,6 @@ void FrameLoader::write(const char* str, int len, bool flush)
if (decoded.isEmpty())
return;
-#if USE(LOW_BANDWIDTH_DISPLAY)
- if (m_frame->document()->inLowBandwidthDisplay())
- m_pendingSourceInLowBandwidthDisplay.append(decoded);
-#endif
-
if (!m_receivedData) {
m_receivedData = true;
if (m_decoder->encoding().usesVisualOrdering())
@@ -1084,7 +1092,7 @@ void FrameLoader::end()
void FrameLoader::endIfNotLoadingMainResource()
{
- if (m_isLoadingMainResource || !m_frame->page())
+ if (m_isLoadingMainResource || !m_frame->page() || !m_frame->document())
return;
// http://bugs.webkit.org/show_bug.cgi?id=10854
@@ -1093,21 +1101,8 @@ void FrameLoader::endIfNotLoadingMainResource()
RefPtr<Frame> protector(m_frame);
// make sure nothing's left in there
- if (m_frame->document()) {
- write(0, 0, true);
- m_frame->document()->finishParsing();
-#if USE(LOW_BANDWIDTH_DISPLAY)
- if (m_frame->document()->inLowBandwidthDisplay()) {
- m_finishedParsingDuringLowBandwidthDisplay = true;
- switchOutLowBandwidthDisplayIfReady();
- }
-#endif
- } else
- // WebKit partially uses WebCore when loading non-HTML docs. In these cases doc==nil, but
- // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
- // become true. An example is when a subframe is a pure text doc, and that subframe is the
- // last one to complete.
- checkCompleted();
+ write(0, 0, true);
+ m_frame->document()->finishParsing();
}
void FrameLoader::iconLoadDecisionAvailable()
@@ -1191,23 +1186,6 @@ bool FrameLoader::allowSubstituteDataAccessToLocal()
return localLoadPolicy != FrameLoader::AllowLocalLoadsForLocalOnly;
}
-static LocalSchemesMap& localSchemes()
-{
- DEFINE_STATIC_LOCAL(LocalSchemesMap, localSchemes, ());
-
- if (localSchemes.isEmpty()) {
- localSchemes.add("file");
-#if PLATFORM(MAC)
- localSchemes.add("applewebdata");
-#endif
-#if PLATFORM(QT)
- localSchemes.add("qrc");
-#endif
- }
-
- return localSchemes;
-}
-
void FrameLoader::commitIconURLToIconDatabase(const KURL& icon)
{
ASSERT(iconDatabase());
@@ -1219,8 +1197,6 @@ void FrameLoader::commitIconURLToIconDatabase(const KURL& icon)
void FrameLoader::restoreDocumentState()
{
Document* doc = m_frame->document();
- if (!doc)
- return;
HistoryItem* itemToRestore = 0;
@@ -1251,7 +1227,7 @@ void FrameLoader::gotoAnchor()
// OTOH If CSS target was set previously, we want to set it to 0, recalc
// and possibly repaint because :target pseudo class may have been
// set (see bug 11321).
- if (!m_URL.hasRef() && !(m_frame->document() && m_frame->document()->getCSSTarget()))
+ if (!m_URL.hasRef() && !m_frame->document()->cssTarget())
return;
String ref = m_URL.ref();
@@ -1289,12 +1265,14 @@ void FrameLoader::finishedParsing()
void FrameLoader::loadDone()
{
- if (m_frame->document())
- checkCompleted();
+ checkCompleted();
}
void FrameLoader::checkCompleted()
{
+ if (m_frame->view())
+ m_frame->view()->checkStopDelayingDeferredRepaints();
+
// Any frame that hasn't completed yet?
for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
if (!child->loader()->m_isComplete)
@@ -1305,19 +1283,12 @@ void FrameLoader::checkCompleted()
return;
// Are we still parsing?
- if (m_frame->document() && m_frame->document()->parsing())
+ if (m_frame->document()->parsing())
return;
// Still waiting for images/scripts?
- if (m_frame->document())
- if (numRequests(m_frame->document()))
- return;
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // as switch will be called, don't complete yet
- if (m_frame->document() && m_frame->document()->inLowBandwidthDisplay() && m_needToSwitchOutLowBandwidthDisplay)
+ if (numRequests(m_frame->document()))
return;
-#endif
// OK, completed.
m_isComplete = true;
@@ -1361,7 +1332,7 @@ void FrameLoader::scheduleCheckLoadComplete()
void FrameLoader::checkCallImplicitClose()
{
- if (m_didCallImplicitClose || !m_frame->document() || m_frame->document()->parsing())
+ if (m_didCallImplicitClose || m_frame->document()->parsing())
return;
for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
@@ -1370,8 +1341,7 @@ void FrameLoader::checkCallImplicitClose()
m_didCallImplicitClose = true;
m_wasUnloadEventEmitted = false;
- if (m_frame->document())
- m_frame->document()->implicitClose();
+ m_frame->document()->implicitClose();
}
KURL FrameLoader::baseURL() const
@@ -1400,6 +1370,9 @@ void FrameLoader::scheduleHTTPRedirection(double delay, const String& url)
if (!m_frame->page())
return;
+ if (url.isEmpty())
+ return;
+
// We want a new history item if the refresh timeout is > 1 second.
if (!m_scheduledRedirection || delay <= m_scheduledRedirection->delay)
#ifdef ANDROID_USER_GESTURE
@@ -1420,6 +1393,9 @@ void FrameLoader::scheduleLocationChange(const String& url, const String& referr
if (!m_frame->page())
return;
+ if (url.isEmpty())
+ return;
+
// If the URL we're going to navigate to is the same as the current one, except for the
// fragment part, we don't need to schedule the location change.
KURL parsedURL(url);
@@ -1451,18 +1427,10 @@ void FrameLoader::scheduleRefresh(bool wasUserGesture)
if (!m_frame->page())
return;
- // Handle a location change of a page with no document as a special case.
- // This may happen when a frame requests a refresh of another frame.
- bool duringLoad = !m_frame->document();
-
- // If a refresh was scheduled during a load, then stop the current load.
- // Otherwise when the current load transitions from a provisional to a
- // committed state, pending redirects may be cancelled.
- if (duringLoad)
- stopLoading(true);
+ if (m_URL.isEmpty())
+ return;
- ScheduledRedirection::Type type = duringLoad
- ? ScheduledRedirection::locationChangeDuringLoad : ScheduledRedirection::locationChange;
+ ScheduledRedirection::Type type = ScheduledRedirection::locationChange;
scheduleRedirection(new ScheduledRedirection(type, m_URL.string(), m_outgoingReferrer, true, true, wasUserGesture, true));
}
@@ -1573,13 +1541,14 @@ void FrameLoader::redirectionTimerFired(Timer<FrameLoader>*)
void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, Frame* childFrame)
{
ASSERT(childFrame);
+
HistoryItem* parentItem = currentHistoryItem();
FrameLoadType loadType = this->loadType();
FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedBackForwardList;
KURL workingURL = url;
- // If we're moving in the backforward list, we might want to replace the content
+ // If we're moving in the back/forward list, we might want to replace the content
// of this child frame with whatever was there at that point.
if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType)) {
HistoryItem* childItem = parentItem->childItemWithName(childFrame->tree()->name());
@@ -1684,12 +1653,10 @@ bool FrameLoader::gotoAnchor(const String& name)
// We need to update the layout before scrolling, otherwise we could
// really mess things up if an anchor scroll comes at a bad moment.
- if (m_frame->document()) {
- m_frame->document()->updateRendering();
- // Only do a layout if changes have occurred that make it necessary.
- if (m_frame->view() && m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout())
- m_frame->view()->layout();
- }
+ m_frame->document()->updateRendering();
+ // Only do a layout if changes have occurred that make it necessary.
+ if (m_frame->view() && m_frame->contentRenderer() && m_frame->contentRenderer()->needsLayout())
+ m_frame->view()->layout();
// Scroll nested layers and frames to reveal the anchor.
// Align to the top and to the closest side (this matches other browsers).
@@ -1705,10 +1672,11 @@ bool FrameLoader::gotoAnchor(const String& name)
android::WebFrame::getWebFrame(m_frame)->setUserInitiatedClick(true);
#endif
if (renderer)
- renderer->enclosingLayer()->scrollRectToVisible(rect, true, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
+ renderer->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
#ifdef ANDROID_SCROLL_ON_GOTO_ANCHOR
android::WebFrame::getWebFrame(m_frame)->setUserInitiatedClick(false);
#endif
+
return true;
}
@@ -1718,14 +1686,6 @@ bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const A
if (url.isEmpty() && mimeType.isEmpty())
return false;
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // don't care object during low bandwidth display
- if (frame()->document()->inLowBandwidthDisplay()) {
- m_needToSwitchOutLowBandwidthDisplay = true;
- return false;
- }
-#endif
-
KURL completedURL;
if (!url.isEmpty())
completedURL = completeURL(url);
@@ -1769,15 +1729,30 @@ bool FrameLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bool
return objectType == ObjectContentNone || objectType == ObjectContentNetscapePlugin || objectType == ObjectContentOtherPlugin;
}
+static HTMLPlugInElement* toPlugInElement(Node* node)
+{
+ if (!node)
+ return 0;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ ASSERT(node->hasTagName(objectTag) || node->hasTagName(embedTag)
+ || node->hasTagName(videoTag) || node->hasTagName(audioTag)
+ || node->hasTagName(appletTag));
+#else
+ ASSERT(node->hasTagName(objectTag) || node->hasTagName(embedTag)
+ || node->hasTagName(appletTag));
+#endif
+
+ return static_cast<HTMLPlugInElement*>(node);
+}
+
bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String& mimeType,
const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
{
Widget* widget = 0;
if (renderer && !useFallback) {
- Element* pluginElement = 0;
- if (renderer->node() && renderer->node()->isElementNode())
- pluginElement = static_cast<Element*>(renderer->node());
+ HTMLPlugInElement* element = toPlugInElement(renderer->node());
if (!canLoad(url, String(), frame()->document())) {
FrameLoader::reportLocalLoadFailed(m_frame, url.string());
@@ -1785,7 +1760,7 @@ bool FrameLoader::loadPlugin(RenderPart* renderer, const KURL& url, const String
}
widget = m_client->createPlugin(IntSize(renderer->contentWidth(), renderer->contentHeight()),
- pluginElement, url, paramNames, paramValues, mimeType,
+ element, url, paramNames, paramValues, mimeType,
m_frame->document()->isPluginDocument());
if (widget) {
renderer->setWidget(widget);
@@ -1825,10 +1800,7 @@ String FrameLoader::outgoingReferrer() const
String FrameLoader::outgoingOrigin() const
{
- if (m_frame->document())
- return m_frame->document()->securityOrigin()->toString();
-
- return SecurityOrigin::createEmpty()->toString();
+ return m_frame->document()->securityOrigin()->toString();
}
Frame* FrameLoader::opener()
@@ -1937,7 +1909,6 @@ bool FrameLoader::canCachePageContainingThisFrame()
// the right NPObjects. See <rdar://problem/5197041> for more information.
&& !m_containsPlugIns
&& !m_URL.protocolIs("https")
- && m_frame->document()
&& !m_frame->document()->hasWindowEventListener(eventNames().unloadEvent)
#if ENABLE(DATABASE)
&& !m_frame->document()->hasOpenDatabases()
@@ -2080,11 +2051,6 @@ bool FrameLoader::logCanCacheFrameDecision(int indentLevel)
{ PCLOG(" -Frame contains plugins"); cannotCache = true; }
if (m_URL.protocolIs("https"))
{ PCLOG(" -Frame is HTTPS"); cannotCache = true; }
- if (!m_frame->document()) {
- PCLOG(" -There is no Document object");
- cannotCache = true;
- break;
- }
if (m_frame->document()->hasWindowEventListener(eventNames().unloadEvent))
{ PCLOG(" -Frame has an unload event listener"); cannotCache = true; }
#if ENABLE(DATABASE)
@@ -2126,7 +2092,7 @@ bool FrameLoader::logCanCacheFrameDecision(int indentLevel)
void FrameLoader::updatePolicyBaseURL()
{
- if (m_frame->tree()->parent() && m_frame->tree()->parent()->document())
+ if (m_frame->tree()->parent())
setPolicyBaseURL(m_frame->tree()->parent()->document()->policyBaseURL());
else
setPolicyBaseURL(m_URL);
@@ -2134,8 +2100,7 @@ void FrameLoader::updatePolicyBaseURL()
void FrameLoader::setPolicyBaseURL(const KURL& url)
{
- if (m_frame->document())
- m_frame->document()->setPolicyBaseURL(url);
+ m_frame->document()->setPolicyBaseURL(url);
for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
child->loader()->setPolicyBaseURL(url);
}
@@ -2398,7 +2363,8 @@ void FrameLoader::load(const ResourceRequest& request, const SubstituteData& sub
// FIXME: is this the right place to reset loadType? Perhaps this should be done after loading is finished or aborted.
m_loadType = FrameLoadTypeStandard;
RefPtr<DocumentLoader> loader = m_client->createDocumentLoader(request, substituteData);
- loader->setURLForHistoryReflectsClientRedirect(lockHistory);
+ if (lockHistory && m_documentLoader)
+ loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory() : m_documentLoader->clientRedirectSourceForHistory());
load(loader.get());
}
@@ -2421,7 +2387,8 @@ void FrameLoader::load(const ResourceRequest& request, const String& frameName,
void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, bool lockHistory, FrameLoadType type, PassRefPtr<FormState> formState)
{
RefPtr<DocumentLoader> loader = m_client->createDocumentLoader(request, SubstituteData());
- loader->setURLForHistoryReflectsClientRedirect(lockHistory);
+ if (lockHistory && m_documentLoader)
+ loader->setClientRedirectSourceForHistory(m_documentLoader->didCreateGlobalHistoryEntry() ? m_documentLoader->urlForHistory() : m_documentLoader->clientRedirectSourceForHistory());
loader->setTriggeringAction(action);
if (m_documentLoader)
@@ -2818,11 +2785,6 @@ void FrameLoader::setDocumentLoader(DocumentLoader* loader)
m_documentLoader = loader;
}
-DocumentLoader* FrameLoader::documentLoader() const
-{
- return m_documentLoader.get();
-}
-
void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
{
if (m_policyDocumentLoader == loader)
@@ -2839,16 +2801,6 @@ void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
m_policyDocumentLoader = loader;
}
-DocumentLoader* FrameLoader::policyDocumentLoader() const
-{
- return m_policyDocumentLoader.get();
-}
-
-DocumentLoader* FrameLoader::provisionalDocumentLoader() const
-{
- return m_provisionalDocumentLoader.get();
-}
-
void FrameLoader::setProvisionalDocumentLoader(DocumentLoader* loader)
{
ASSERT(!loader || !m_provisionalDocumentLoader);
@@ -2860,11 +2812,6 @@ void FrameLoader::setProvisionalDocumentLoader(DocumentLoader* loader)
m_provisionalDocumentLoader = loader;
}
-FrameState FrameLoader::state() const
-{
- return m_state;
-}
-
double FrameLoader::timeOfLastCompletedLoad()
{
return storedTimeOfLastCompletedLoad;
@@ -2906,11 +2853,7 @@ void FrameLoader::commitProvisionalLoad(PassRefPtr<CachedPage> prpCachedPage)
// Check to see if we need to cache the page we are navigating away from into the back/forward cache.
// We are doing this here because we know for sure that a new page is about to be loaded.
- if (canCachePage() && !m_currentHistoryItem->isInPageCache()) {
- if (Document* document = m_frame->document())
- document->suspendActiveDOMObjects();
- cachePageForHistoryItem(m_currentHistoryItem.get());
- }
+ cachePageForHistoryItem(m_currentHistoryItem.get());
if (m_loadType != FrameLoadTypeReplace)
closeOldDataSources();
@@ -2944,7 +2887,37 @@ void FrameLoader::commitProvisionalLoad(PassRefPtr<CachedPage> prpCachedPage)
LOG(Loading, "WebCoreLoading %s: Finished committing provisional load to URL %s", m_frame->tree()->name().string().utf8().data(), m_URL.string().utf8().data());
- opened();
+ if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect())
+ updateHistoryForClientRedirect();
+
+ if (m_documentLoader->isLoadingFromCachedPage()) {
+ m_frame->document()->documentDidBecomeActive();
+
+ // Force a layout to update view size and thereby update scrollbars.
+ m_client->forceLayout();
+
+ const ResponseVector& responses = m_documentLoader->responses();
+ size_t count = responses.size();
+ for (size_t i = 0; i < count; i++) {
+ const ResourceResponse& response = responses[i];
+ // FIXME: If the WebKit client changes or cancels the request, this is not respected.
+ ResourceError error;
+ unsigned long identifier;
+ ResourceRequest request(response.url());
+ requestFromDelegate(request, identifier, error);
+ // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
+ // However, with today's computers and networking speeds, this won't happen in practice.
+ // Could be an issue with a giant local file.
+ sendRemainingDelegateMessages(identifier, response, static_cast<int>(response.expectedContentLength()), error);
+ }
+
+ pageCache()->remove(m_currentHistoryItem.get());
+
+ m_documentLoader->setPrimaryLoadComplete(true);
+
+ // FIXME: Why only this frame and not parent frames?
+ checkLoadCompleteForThisFrame();
+ }
}
void FrameLoader::transitionToCommitted(PassRefPtr<CachedPage> cachedPage)
@@ -3117,6 +3090,7 @@ void FrameLoader::closeOldDataSources()
void FrameLoader::open(CachedPage& cachedPage)
{
+ ASSERT(!m_frame->tree()->parent());
ASSERT(m_frame->page());
ASSERT(m_frame->page()->mainFrame() == m_frame);
@@ -3124,11 +3098,6 @@ void FrameLoader::open(CachedPage& cachedPage)
// We still have to close the previous part page.
closeURL();
-
- m_isComplete = false;
-
- // Don't re-emit the load event.
- m_didCallImplicitClose = true;
// Delete old status bar messages (if it _was_ activated on last URL).
if (m_frame->script()->isEnabled()) {
@@ -3136,7 +3105,19 @@ void FrameLoader::open(CachedPage& cachedPage)
m_frame->setJSDefaultStatusBarText(String());
}
- KURL url = cachedPage.url();
+ open(*cachedPage.cachedMainFrame());
+
+ checkCompleted();
+}
+
+void FrameLoader::open(CachedFrame& cachedFrame)
+{
+ m_isComplete = false;
+
+ // Don't re-emit the load event.
+ m_didCallImplicitClose = true;
+
+ KURL url = cachedFrame.url();
if ((url.protocolIs("http") || url.protocolIs("https")) && !url.host().isEmpty() && url.path().isEmpty())
url.setPath("/");
@@ -3148,7 +3129,7 @@ void FrameLoader::open(CachedPage& cachedPage)
clear();
- Document* document = cachedPage.document();
+ Document* document = cachedFrame.document();
ASSERT(document);
document->setInPageCache(false);
@@ -3157,13 +3138,16 @@ void FrameLoader::open(CachedPage& cachedPage)
m_didCallImplicitClose = false;
m_outgoingReferrer = url.string();
- FrameView* view = cachedPage.view();
+ FrameView* view = cachedFrame.view();
+
+ // When navigating to a CachedFrame its FrameView should never be null. If it is we'll crash in creative ways downstream.
+ ASSERT(view);
if (view)
view->setWasScrolledByUser(false);
m_frame->setView(view);
m_frame->setDocument(document);
- m_frame->setDOMWindow(cachedPage.domWindow());
+ m_frame->setDOMWindow(cachedFrame.domWindow());
m_frame->domWindow()->setURL(document->url());
m_frame->domWindow()->setSecurityOrigin(document->securityOrigin());
@@ -3171,14 +3155,7 @@ void FrameLoader::open(CachedPage& cachedPage)
updatePolicyBaseURL();
- cachedPage.restore(m_frame->page());
- document->resumeActiveDOMObjects();
-
- // It is necessary to update any platform script objects after restoring the
- // cached page.
- m_frame->script()->updatePlatformScriptObjects();
-
- checkCompleted();
+ cachedFrame.restore();
}
bool FrameLoader::isStopping() const
@@ -3323,7 +3300,7 @@ CachePolicy FrameLoader::cachePolicy() const
if (m_isComplete)
return CachePolicyVerify;
- if (m_loadType == FrameLoadTypeReloadFromOrigin)
+ if (m_loadType == FrameLoadTypeReloadFromOrigin || documentLoader()->request().cachePolicy() == ReloadIgnoringCacheData)
return CachePolicyReload;
if (Frame* parentFrame = m_frame->tree()->parent()) {
@@ -3443,9 +3420,7 @@ void FrameLoader::checkLoadCompleteForThisFrame()
}
case FrameStateComplete:
- // Even if already complete, we might have set a previous item on a frame that
- // didn't do any data loading on the past transaction. Make sure to clear these out.
- m_client->frameLoadCompleted();
+ frameLoadCompleted();
return;
}
@@ -3506,8 +3481,14 @@ void FrameLoader::didFirstVisuallyNonEmptyLayout()
void FrameLoader::frameLoadCompleted()
{
+ // Note: Can be called multiple times.
+
m_client->frameLoadCompleted();
+ // Even if already complete, we might have set a previous item on a frame that
+ // didn't do any data loading on the past transaction. Make sure to clear these out.
+ m_previousHistoryItem = 0;
+
// After a canceled provisional load, firstLayoutDone is false.
// Reset it to true if we're displaying a page.
if (m_documentLoader)
@@ -3534,6 +3515,18 @@ void FrameLoader::detachChildren()
}
}
+void FrameLoader::closeAndRemoveChild(Frame* child)
+{
+ child->tree()->detachFromParent();
+
+ child->setView(0);
+ if (child->ownerElement())
+ child->page()->decrementFrameCount();
+ child->pageDestroyed();
+
+ m_frame->tree()->removeChild(child);
+}
+
void FrameLoader::recursiveCheckLoadComplete()
{
Vector<RefPtr<Frame>, 10> frames;
@@ -3615,8 +3608,7 @@ void FrameLoader::handledOnloadEvents()
void FrameLoader::frameDetached()
{
stopAllLoaders();
- if (Document* document = m_frame->document())
- document->stopActiveDOMObjects();
+ m_frame->document()->stopActiveDOMObjects();
detachFromParent();
}
@@ -3636,7 +3628,7 @@ void FrameLoader::detachFromParent()
setDocumentLoader(0);
m_client->detachedFromParent3();
if (Frame* parent = m_frame->tree()->parent()) {
- parent->tree()->removeChild(m_frame);
+ parent->loader()->closeAndRemoveChild(m_frame);
parent->loader()->scheduleCheckCompleted();
} else {
m_frame->setView(0);
@@ -3656,6 +3648,19 @@ void FrameLoader::addExtraFieldsToMainResourceRequest(ResourceRequest& request)
void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadType loadType, bool mainResource, bool cookiePolicyURLFromRequest)
{
+ // Don't set the cookie policy URL if it's already been set.
+ // But make sure to set it on all requests, as it has significance beyond the cookie policy for all protocols (<rdar://problem/6616664>).
+ if (request.mainDocumentURL().isEmpty()) {
+ if (mainResource && (isLoadingMainFrame() || cookiePolicyURLFromRequest))
+ request.setMainDocumentURL(request.url());
+ else if (Page* page = m_frame->page())
+ request.setMainDocumentURL(page->mainFrame()->loader()->url());
+ }
+
+ // The remaining modifications are only necessary for HTTP and HTTPS.
+ if (!request.url().isEmpty() && !request.url().protocolInHTTPFamily())
+ return;
+
applyUserAgent(request);
if (loadType == FrameLoadTypeReload) {
@@ -3667,14 +3672,6 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request, FrameLoadTyp
request.setHTTPHeaderField("Pragma", "no-cache");
}
- // Don't set the cookie policy URL if it's already been set.
- if (request.mainDocumentURL().isEmpty()) {
- if (mainResource && (isLoadingMainFrame() || cookiePolicyURLFromRequest))
- request.setMainDocumentURL(request.url());
- else if (Page* page = m_frame->page())
- request.setMainDocumentURL(page->mainFrame()->loader()->url());
- }
-
if (mainResource)
request.setHTTPAccept("application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
@@ -3978,42 +3975,7 @@ bool FrameLoader::shouldScrollToAnchor(bool isFormSubmission, FrameLoadType load
&& !shouldReload(this->url(), url)
// We don't want to just scroll if a link from within a
// frameset is trying to reload the frameset into _top.
- && !m_frame->isFrameSet();
-}
-
-void FrameLoader::opened()
-{
- if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isClientRedirect())
- updateHistoryForClientRedirect();
-
- if (m_documentLoader->isLoadingFromCachedPage()) {
- m_frame->document()->documentDidBecomeActive();
-
- // Force a layout to update view size and thereby update scrollbars.
- m_client->forceLayout();
-
- const ResponseVector& responses = m_documentLoader->responses();
- size_t count = responses.size();
- for (size_t i = 0; i < count; i++) {
- const ResourceResponse& response = responses[i];
- // FIXME: If the WebKit client changes or cancels the request, this is not respected.
- ResourceError error;
- unsigned long identifier;
- ResourceRequest request(response.url());
- requestFromDelegate(request, identifier, error);
- // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
- // However, with today's computers and networking speeds, this won't happen in practice.
- // Could be an issue with a giant local file.
- sendRemainingDelegateMessages(identifier, response, static_cast<int>(response.expectedContentLength()), error);
- }
-
- pageCache()->remove(m_currentHistoryItem.get());
-
- m_documentLoader->setPrimaryLoadComplete(true);
-
- // FIXME: Why only this frame and not parent frames?
- checkLoadCompleteForThisFrame();
- }
+ && !m_frame->document()->isFrameSet();
}
void FrameLoader::checkNewWindowPolicy(const NavigationAction& action, const ResourceRequest& request,
@@ -4337,10 +4299,11 @@ bool FrameLoader::loadProvisionalItemFromCachedPage()
void FrameLoader::cachePageForHistoryItem(HistoryItem* item)
{
+ if (!canCachePage() || item->isInPageCache())
+ return;
+
if (Page* page = m_frame->page()) {
RefPtr<CachedPage> cachedPage = CachedPage::create(page);
- m_client->savePlatformDataToCachedFrame(cachedPage->cachedMainFrame());
-
pageCache()->add(item, cachedPage.release());
}
}
@@ -4552,7 +4515,7 @@ void FrameLoader::saveDocumentState()
Document* document = m_frame->document();
ASSERT(document);
- if (document && item->isCurrentDocument(document)) {
+ if (item->isCurrentDocument(document)) {
LOG(Loading, "WebCoreLoading %s: saving form state to %p", m_frame->tree()->name().string().utf8().data(), item);
item->setDocumentState(document->formElementsState());
}
@@ -4845,13 +4808,12 @@ void FrameLoader::updateHistoryForStandardLoad()
m_navigationDuringLoad = false;
}
- bool didUpdateGlobalHistory = false;
if (!frameNavigationDuringLoad && !documentLoader()->isClientRedirect()) {
if (!historyURL.isEmpty()) {
addBackForwardItemClippedAtTarget(true);
if (!needPrivacy) {
m_client->updateGlobalHistory();
- didUpdateGlobalHistory = true;
+ m_documentLoader->setDidCreateGlobalHistoryEntry(true);
}
if (Page* page = m_frame->page())
page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwardList()->currentItem());
@@ -4865,8 +4827,8 @@ void FrameLoader::updateHistoryForStandardLoad()
if (Page* page = m_frame->page())
page->group().addVisitedLink(historyURL);
- if (!didUpdateGlobalHistory && !url().isEmpty())
- m_client->updateGlobalHistoryForRedirectWithoutHistoryItem();
+ if (!m_documentLoader->didCreateGlobalHistoryEntry() && documentLoader()->unreachableURL().isEmpty() && !url().isEmpty())
+ m_client->updateGlobalHistoryRedirectLinks();
}
}
@@ -4935,14 +4897,13 @@ void FrameLoader::updateHistoryForRedirectWithLockedBackForwardList()
bool needPrivacy = !settings || settings->privateBrowsingEnabled();
const KURL& historyURL = documentLoader()->urlForHistory();
- bool didUpdateGlobalHistory = false;
if (documentLoader()->isClientRedirect()) {
if (!m_currentHistoryItem && !m_frame->tree()->parent()) {
if (!historyURL.isEmpty()) {
addBackForwardItemClippedAtTarget(true);
if (!needPrivacy) {
m_client->updateGlobalHistory();
- didUpdateGlobalHistory = true;
+ m_documentLoader->setDidCreateGlobalHistoryEntry(true);
}
if (Page* page = m_frame->page())
page->setGlobalHistoryItem(needPrivacy ? 0 : page->backForwardList()->currentItem());
@@ -4962,8 +4923,8 @@ void FrameLoader::updateHistoryForRedirectWithLockedBackForwardList()
if (Page* page = m_frame->page())
page->group().addVisitedLink(historyURL);
- if (!didUpdateGlobalHistory && !url().isEmpty())
- m_client->updateGlobalHistoryForRedirectWithoutHistoryItem();
+ if (!m_documentLoader->didCreateGlobalHistoryEntry() && documentLoader()->unreachableURL().isEmpty() && !url().isEmpty())
+ m_client->updateGlobalHistoryRedirectLinks();
}
}
@@ -5013,33 +4974,18 @@ void FrameLoader::saveDocumentAndScrollState()
}
}
-// FIXME: These 6 setter/getters are here for a dwindling number of users in WebKit, WebFrame
+// FIXME: These 3 setter/getters are here for a dwindling number of users in WebKit, WebFrame
// being the primary one. After they're no longer needed there, they can be removed!
HistoryItem* FrameLoader::currentHistoryItem()
{
return m_currentHistoryItem.get();
}
-HistoryItem* FrameLoader::previousHistoryItem()
-{
- return m_previousHistoryItem.get();
-}
-
-HistoryItem* FrameLoader::provisionalHistoryItem()
-{
- return m_provisionalHistoryItem.get();
-}
-
void FrameLoader::setCurrentHistoryItem(PassRefPtr<HistoryItem> item)
{
m_currentHistoryItem = item;
}
-void FrameLoader::setPreviousHistoryItem(PassRefPtr<HistoryItem> item)
-{
- m_previousHistoryItem = item;
-}
-
void FrameLoader::setProvisionalHistoryItem(PassRefPtr<HistoryItem> item)
{
m_provisionalHistoryItem = item;
@@ -5211,6 +5157,11 @@ String FrameLoader::referrer() const
return documentLoader()->request().httpReferrer();
}
+void FrameLoader::dispatchDocumentElementAvailable()
+{
+ m_client->documentElementAvailable();
+}
+
void FrameLoader::dispatchWindowObjectAvailable()
{
if (!m_frame->script()->isEnabled() || !m_frame->script()->haveWindowShell())
@@ -5226,15 +5177,18 @@ void FrameLoader::dispatchWindowObjectAvailable()
}
}
-Widget* FrameLoader::createJavaAppletWidget(const IntSize& size, Element* element, const HashMap<String, String>& args)
+Widget* FrameLoader::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const HashMap<String, String>& args)
{
String baseURLString;
+ String codeBaseURLString;
Vector<String> paramNames;
Vector<String> paramValues;
HashMap<String, String>::const_iterator end = args.end();
for (HashMap<String, String>::const_iterator it = args.begin(); it != end; ++it) {
if (equalIgnoringCase(it->first, "baseurl"))
baseURLString = it->second;
+ else if (equalIgnoringCase(it->first, "codebase"))
+ codeBaseURLString = it->second;
paramNames.append(it->first);
paramValues.append(it->second);
}
@@ -5243,10 +5197,14 @@ Widget* FrameLoader::createJavaAppletWidget(const IntSize& size, Element* elemen
baseURLString = m_frame->document()->baseURL().string();
KURL baseURL = completeURL(baseURLString);
- Widget* widget = m_client->createJavaAppletWidget(size, element, baseURL, paramNames, paramValues);
- if (widget)
- m_containsPlugIns = true;
-
+ Widget* widget = 0;
+ KURL codeBaseURL = completeURL(codeBaseURLString);
+ if (canLoad(codeBaseURL, String(), element->document())) {
+ widget = m_client->createJavaAppletWidget(size, element, baseURL, paramNames, paramValues);
+ if (widget)
+ m_containsPlugIns = true;
+ }
+
return widget;
}
@@ -5309,7 +5267,7 @@ bool FrameLoader::shouldTreatURLAsLocal(const String& url)
return localSchemes().contains(scheme);
}
-bool FrameLoader::shouldTreatSchemeAsLocal(const String& scheme)
+bool FrameLoader::shouldTreatURLSchemeAsLocal(const String& scheme)
{
// This avoids an allocation of another String and the HashSet contains()
// call for the file: and http: schemes.
@@ -5327,6 +5285,16 @@ bool FrameLoader::shouldTreatSchemeAsLocal(const String& scheme)
return localSchemes().contains(scheme);
}
+void FrameLoader::registerURLSchemeAsNoAccess(const String& scheme)
+{
+ noAccessSchemes().add(scheme);
+}
+
+bool FrameLoader::shouldTreatURLSchemeAsNoAccess(const String& scheme)
+{
+ return noAccessSchemes().contains(scheme);
+}
+
void FrameLoader::dispatchDidCommitLoad()
{
if (m_creatingInitialEmptyDocument)
@@ -5416,124 +5384,9 @@ void FrameLoader::tellClientAboutPastMemoryCacheLoads()
}
}
-#if USE(LOW_BANDWIDTH_DISPLAY)
-
-bool FrameLoader::addLowBandwidthDisplayRequest(CachedResource* cache)
-{
- if (m_frame->document()->inLowBandwidthDisplay() == false)
- return false;
-
- // if cache is loaded, don't add to the list, where notifyFinished() is expected.
- if (cache->isLoaded())
- return false;
-
- switch (cache->type()) {
- case CachedResource::CSSStyleSheet:
- case CachedResource::Script:
- m_needToSwitchOutLowBandwidthDisplay = true;
- m_externalRequestsInLowBandwidthDisplay.add(cache);
- cache->addClient(this);
- return true;
- case CachedResource::ImageResource:
- case CachedResource::FontResource:
-#if ENABLE(XSLT)
- case CachedResource::XSLStyleSheet:
-#endif
-#if ENABLE(XBL)
- case CachedResource::XBLStyleSheet:
-#endif
- return false;
- }
-
- ASSERT_NOT_REACHED();
- return false;
-}
-
-void FrameLoader::removeAllLowBandwidthDisplayRequests()
+bool FrameLoaderClient::hasHTMLView() const
{
- HashSet<CachedResource*>::iterator end = m_externalRequestsInLowBandwidthDisplay.end();
- for (HashSet<CachedResource*>::iterator it = m_externalRequestsInLowBandwidthDisplay.begin(); it != end; ++it)
- (*it)->removeClient(this);
- m_externalRequestsInLowBandwidthDisplay.clear();
-}
-
-void FrameLoader::notifyFinished(CachedResource* script)
-{
- HashSet<CachedResource*>::iterator it = m_externalRequestsInLowBandwidthDisplay.find(script);
- if (it != m_externalRequestsInLowBandwidthDisplay.end()) {
- (*it)->removeClient(this);
- m_externalRequestsInLowBandwidthDisplay.remove(it);
- switchOutLowBandwidthDisplayIfReady();
- }
-}
-
-void FrameLoader::switchOutLowBandwidthDisplayIfReady()
-{
- RefPtr<Document> oldDoc = m_frame->document();
- if (oldDoc->inLowBandwidthDisplay()) {
- if (!m_needToSwitchOutLowBandwidthDisplay) {
- // no need to switch, just reset state
- oldDoc->setLowBandwidthDisplay(false);
- removeAllLowBandwidthDisplayRequests();
- m_pendingSourceInLowBandwidthDisplay = String();
- m_finishedParsingDuringLowBandwidthDisplay = false;
- return;
- } else if (m_externalRequestsInLowBandwidthDisplay.isEmpty() ||
- m_pendingSourceInLowBandwidthDisplay.length() > cMaxPendingSourceLengthInLowBandwidthDisplay) {
- // clear the flag first
- oldDoc->setLowBandwidthDisplay(false);
-
- // similar to clear(), should be refactored to share more code
- oldDoc->cancelParsing();
- oldDoc->detach();
- if (m_frame->script()->isEnabled())
- m_frame->script()->clearWindowShell();
- if (m_frame->view())
- m_frame->view()->clear();
-
- // similar to begin(), should be refactored to share more code
- RefPtr<Document> newDoc = DOMImplementation::createDocument(m_responseMIMEType, m_frame, m_frame->inViewSourceMode());
- m_frame->setDocument(newDoc);
- newDoc->setURL(m_URL);
- if (m_decoder)
- newDoc->setDecoder(m_decoder.get());
- restoreDocumentState();
- dispatchWindowObjectAvailable();
- newDoc->implicitOpen();
-
- // swap DocLoader ownership
- DocLoader* docLoader = newDoc->docLoader();
- newDoc->setDocLoader(oldDoc->docLoader());
- newDoc->docLoader()->replaceDocument(newDoc.get());
- docLoader->replaceDocument(oldDoc.get());
- oldDoc->setDocLoader(docLoader);
-
- // drop the old doc
- oldDoc = 0;
-
- // write decoded data to the new doc, similar to write()
- if (m_pendingSourceInLowBandwidthDisplay.length()) {
- if (m_decoder->encoding().usesVisualOrdering())
- newDoc->setVisuallyOrdered();
- newDoc->recalcStyle(Node::Force);
- newDoc->tokenizer()->write(m_pendingSourceInLowBandwidthDisplay, true);
-
- if (m_finishedParsingDuringLowBandwidthDisplay)
- newDoc->finishParsing();
- }
-
- // update rendering
- newDoc->updateRendering();
-
- // reset states
- removeAllLowBandwidthDisplayRequests();
- m_pendingSourceInLowBandwidthDisplay = String();
- m_finishedParsingDuringLowBandwidthDisplay = false;
- m_needToSwitchOutLowBandwidthDisplay = false;
- }
- }
+ return true;
}
-#endif
-
} // namespace WebCore
diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h
index 4650b03..9b68601 100644
--- a/WebCore/loader/FrameLoader.h
+++ b/WebCore/loader/FrameLoader.h
@@ -36,16 +36,13 @@
#include "ResourceRequest.h"
#include "Timer.h"
-#if USE(LOW_BANDWIDTH_DISPLAY)
-#include "CachedResourceClient.h"
-#endif
-
namespace WebCore {
#if ENABLE(ARCHIVE) // ANDROID extension: disabled to reduce code size
class Archive;
#endif
class AuthenticationChallenge;
+ class CachedFrame;
class CachedPage;
class CachedResource;
class Document;
@@ -56,6 +53,7 @@ namespace WebCore {
class Frame;
class FrameLoaderClient;
class HistoryItem;
+ class HTMLAppletElement;
class HTMLFormElement;
class HTMLFrameOwnerElement;
class IconLoader;
@@ -115,11 +113,7 @@ namespace WebCore {
void* m_argument;
};
- class FrameLoader : Noncopyable
-#if USE(LOW_BANDWIDTH_DISPLAY)
- , private CachedResourceClient
-#endif
- {
+ class FrameLoader : Noncopyable {
public:
FrameLoader(Frame*, FrameLoaderClient*);
~FrameLoader();
@@ -196,10 +190,10 @@ namespace WebCore {
void loadEmptyDocumentSynchronously();
DocumentLoader* activeDocumentLoader() const;
- DocumentLoader* documentLoader() const;
- DocumentLoader* policyDocumentLoader() const;
- DocumentLoader* provisionalDocumentLoader() const;
- FrameState state() const;
+ DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
+ DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
+ DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
+ FrameState state() const { return m_state; }
static double timeOfLastCompletedLoad();
bool shouldUseCredentialStorage(ResourceLoader*);
@@ -283,6 +277,7 @@ namespace WebCore {
void checkLoadComplete();
void detachFromParent();
void detachChildren();
+ void closeAndRemoveChild(Frame*);
void addExtraFieldsToSubresourceRequest(ResourceRequest&);
void addExtraFieldsToMainResourceRequest(ResourceRequest&);
@@ -355,9 +350,10 @@ namespace WebCore {
void handledOnloadEvents();
String userAgent(const KURL&) const;
- Widget* createJavaAppletWidget(const IntSize&, Element*, const HashMap<String, String>& args);
+ Widget* createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const HashMap<String, String>& args);
void dispatchWindowObjectAvailable();
+ void dispatchDocumentElementAvailable();
void restoreDocumentState();
Frame* opener();
@@ -424,10 +420,7 @@ namespace WebCore {
// FIXME: These accessors are here for a dwindling number of users in WebKit, WebFrame
// being the primary one. After they're no longer needed there, they can be removed!
HistoryItem* currentHistoryItem();
- HistoryItem* previousHistoryItem();
- HistoryItem* provisionalHistoryItem();
void setCurrentHistoryItem(PassRefPtr<HistoryItem>);
- void setPreviousHistoryItem(PassRefPtr<HistoryItem>);
void setProvisionalHistoryItem(PassRefPtr<HistoryItem>);
void continueLoadWithData(SharedBuffer*, const String& mimeType, const String& textEncoding, const KURL&);
@@ -441,19 +434,12 @@ namespace WebCore {
static bool restrictAccessToLocal();
static bool allowSubstituteDataAccessToLocal();
- static void registerURLSchemeAsLocal(const String& scheme);
+ static void registerURLSchemeAsLocal(const String&);
static bool shouldTreatURLAsLocal(const String&);
- static bool shouldTreatSchemeAsLocal(const String&);
-
-#if USE(LOW_BANDWIDTH_DISPLAY)
- bool addLowBandwidthDisplayRequest(CachedResource*);
- void needToSwitchOutLowBandwidthDisplay() { m_needToSwitchOutLowBandwidthDisplay = true; }
+ static bool shouldTreatURLSchemeAsLocal(const String&);
- // Client can control whether to use low bandwidth display on a per frame basis.
- // However, this should only be used for the top frame, not sub-frame.
- void setUseLowBandwidthDisplay(bool lowBandwidth) { m_useLowBandwidthDisplay = lowBandwidth; }
- bool useLowBandwidthDisplay() const { return m_useLowBandwidthDisplay; }
-#endif
+ static void registerURLSchemeAsNoAccess(const String&);
+ static bool shouldTreatURLSchemeAsNoAccess(const String&);
bool committingFirstRealLoad() const { return !m_creatingInitialEmptyDocument && !m_committedFirstRealDocumentLoad; }
@@ -563,7 +549,8 @@ namespace WebCore {
void closeOldDataSources();
void open(CachedPage&);
- void opened();
+ void open(CachedFrame&);
+
void updateHistoryAfterClientRedirect();
void clear(bool clearWindowProperties = true, bool clearScriptObjects = true);
@@ -575,14 +562,6 @@ namespace WebCore {
void startRedirectionTimer();
void stopRedirectionTimer();
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // implementation of CachedResourceClient
- virtual void notifyFinished(CachedResource*);
-
- void removeAllLowBandwidthDisplayRequests();
- void switchOutLowBandwidthDisplayIfReady();
-#endif
-
void dispatchDidCommitLoad();
void dispatchAssignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
@@ -682,26 +661,11 @@ namespace WebCore {
bool m_didDispatchDidCommitLoad;
#endif
-#if USE(LOW_BANDWIDTH_DISPLAY)
- // whether to use low bandwidth dislay, set by client
- bool m_useLowBandwidthDisplay;
-
- // whether to call finishParsing() in switchOutLowBandwidthDisplayIfReady()
- bool m_finishedParsingDuringLowBandwidthDisplay;
-
- // whether to call switchOutLowBandwidthDisplayIfReady;
- // true if there is external css, javascript, or subframe/plugin
- bool m_needToSwitchOutLowBandwidthDisplay;
-
- String m_pendingSourceInLowBandwidthDisplay;
- HashSet<CachedResource*> m_externalRequestsInLowBandwidthDisplay;
-#endif
-
#if ENABLE(WML)
bool m_forceReloadWmlDeck;
#endif
};
-}
+} // namespace WebCore
-#endif
+#endif // FrameLoader_h
diff --git a/WebCore/loader/FrameLoaderClient.cpp b/WebCore/loader/FrameLoaderClient.cpp
deleted file mode 100644
index 9610fd1..0000000
--- a/WebCore/loader/FrameLoaderClient.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Holger Hans Peter Freyther
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "FrameLoaderClient.h"
-
-#include "Color.h"
-#include "Frame.h"
-#include "FrameView.h"
-#include "HTMLFrameOwnerElement.h"
-#include "Page.h"
-#include "RenderPart.h"
-
-namespace WebCore {
-
-FrameLoaderClient::~FrameLoaderClient()
-{}
-
-void FrameLoaderClient::transitionToCommittedForNewPage(Frame* frame,
- const IntSize& viewportSize,
- const Color& backgroundColor, bool transparent,
- const IntSize& fixedLayoutSize, bool useFixedLayout,
- ScrollbarMode horizontalScrollbarMode, ScrollbarMode verticalScrollbarMode)
-{
- ASSERT(frame);
-
- Page* page = frame->page();
- ASSERT(page);
-
- bool isMainFrame = frame == page->mainFrame();
-
- if (isMainFrame && frame->view())
- frame->view()->setParentVisible(false);
-
- frame->setView(0);
-
- FrameView* frameView;
- if (isMainFrame) {
- frameView = new FrameView(frame, viewportSize);
- frameView->setFixedLayoutSize(fixedLayoutSize);
- frameView->setUseFixedLayout(useFixedLayout);
- } else
- frameView = new FrameView(frame);
-
- frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode);
- frameView->updateDefaultScrollbarState();
-
- frame->setView(frameView);
- // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
- frameView->deref();
-
- if (backgroundColor.isValid())
- frameView->updateBackgroundRecursively(backgroundColor, transparent);
-
- if (isMainFrame)
- frameView->setParentVisible(true);
-
- if (frame->ownerRenderer())
- frame->ownerRenderer()->setWidget(frameView);
-
- if (HTMLFrameOwnerElement* owner = frame->ownerElement())
- frame->view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
-}
-
-}
-
diff --git a/WebCore/loader/FrameLoaderClient.h b/WebCore/loader/FrameLoaderClient.h
index 52dcfab..4f2b86e 100644
--- a/WebCore/loader/FrameLoaderClient.h
+++ b/WebCore/loader/FrameLoaderClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,21 +53,22 @@ namespace WebCore {
class Frame;
class FrameLoader;
class HistoryItem;
+ class HTMLAppletElement;
class HTMLFrameOwnerElement;
+ class HTMLPlugInElement;
class IntSize;
class KURL;
class NavigationAction;
class ResourceError;
class ResourceHandle;
class ResourceLoader;
+ struct ResourceRequest;
class ResourceResponse;
class SharedBuffer;
class SubstituteData;
class String;
class Widget;
- class ResourceRequest;
-
#ifdef ANDROID_HISTORY_CLIENT
class BackForwardList;
#endif
@@ -76,12 +77,17 @@ namespace WebCore {
class FrameLoaderClient {
public:
- virtual ~FrameLoaderClient();
+ // An inline function cannot be the first non-abstract virtual function declared
+ // in the class as it results in the vtable being generated as a weak symbol.
+ // This hurts performance (in Mac OS X at least, when loadig frameworks), so we
+ // don't want to do it in WebKit.
+ virtual bool hasHTMLView() const;
+
+ virtual ~FrameLoaderClient() { }
+
virtual void frameLoaderDestroyed() = 0;
-
- virtual bool hasWebView() const = 0; // mainly for assertions
- virtual bool hasHTMLView() const { return true; }
+ virtual bool hasWebView() const = 0; // mainly for assertions
virtual void makeRepresentation(DocumentLoader*) = 0;
virtual void forceLayout() = 0;
@@ -155,7 +161,7 @@ namespace WebCore {
virtual void finishedLoading(DocumentLoader*) = 0;
virtual void updateGlobalHistory() = 0;
- virtual void updateGlobalHistoryForRedirectWithoutHistoryItem() = 0;
+ virtual void updateGlobalHistoryRedirectLinks() = 0;
virtual bool shouldGoToHistoryItem(HistoryItem*) const = 0;
#ifdef ANDROID_HISTORY_CLIENT
@@ -201,15 +207,16 @@ namespace WebCore {
virtual PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) = 0;
- virtual Widget* createPlugin(const IntSize&, Element*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually) = 0;
+ virtual Widget* createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually) = 0;
virtual void redirectDataToPlugin(Widget* pluginWidget) = 0;
- virtual Widget* createJavaAppletWidget(const IntSize&, Element*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0;
+ virtual Widget* createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0;
virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType) = 0;
virtual String overrideMediaType() const = 0;
virtual void windowObjectCleared() = 0;
+ virtual void documentElementAvailable() = 0;
virtual void didPerformFirstNavigation() const = 0; // "Navigation" here means a transition from one page to another that ends up in the back/forward list.
virtual void registerForIconNotification(bool listen = true) = 0;
@@ -220,12 +227,11 @@ namespace WebCore {
#endif
virtual NSCachedURLResponse* willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse*) const = 0;
#endif
+#if USE(CFNETWORK)
+ virtual bool shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length) = 0;
+#endif
virtual bool shouldUsePluginDocument(const String& /*mimeType*/) const { return false; }
-
- protected:
- static void transitionToCommittedForNewPage(Frame*, const IntSize&, const Color&, bool, const IntSize &, bool,
- ScrollbarMode = ScrollbarAuto, ScrollbarMode = ScrollbarAuto);
};
} // namespace WebCore
diff --git a/WebCore/loader/ImageDocument.cpp b/WebCore/loader/ImageDocument.cpp
index 8f58179..ca3f785 100644
--- a/WebCore/loader/ImageDocument.cpp
+++ b/WebCore/loader/ImageDocument.cpp
@@ -63,7 +63,7 @@ class ImageTokenizer : public Tokenizer {
public:
ImageTokenizer(ImageDocument* doc) : m_doc(doc) {}
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
virtual bool isWaitingForScripts() const;
@@ -91,10 +91,9 @@ private:
// --------
-bool ImageTokenizer::write(const SegmentedString&, bool)
+void ImageTokenizer::write(const SegmentedString&, bool)
{
ASSERT_NOT_REACHED();
- return false;
}
bool ImageTokenizer::writeRawData(const char*, int)
@@ -166,10 +165,10 @@ void ImageDocument::createDocumentStructure()
{
ExceptionCode ec;
- RefPtr<Element> rootElement = createElementNS(xhtmlNamespaceURI, "html", ec);
+ RefPtr<Element> rootElement = Document::createElement(htmlTag, false);
appendChild(rootElement, ec);
- RefPtr<Element> body = createElementNS(xhtmlNamespaceURI, "body", ec);
+ RefPtr<Element> body = Document::createElement(bodyTag, false);
body->setAttribute(styleAttr, "margin: 0px;");
rootElement->appendChild(body, ec);
diff --git a/WebCore/loader/ImageLoader.cpp b/WebCore/loader/ImageLoader.cpp
index 43e08c0..b183a66 100644
--- a/WebCore/loader/ImageLoader.cpp
+++ b/WebCore/loader/ImageLoader.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -31,8 +31,33 @@
namespace WebCore {
-ImageLoader::ImageLoader(Element* elt)
- : m_element(elt)
+class ImageLoadEventSender {
+public:
+ ImageLoadEventSender();
+
+ void dispatchLoadEventSoon(ImageLoader*);
+ void cancelLoadEvent(ImageLoader*);
+
+ void dispatchPendingLoadEvents();
+
+private:
+ ~ImageLoadEventSender();
+
+ void timerFired(Timer<ImageLoadEventSender>*);
+
+ Timer<ImageLoadEventSender> m_timer;
+ Vector<ImageLoader*> m_dispatchSoonList;
+ Vector<ImageLoader*> m_dispatchingList;
+};
+
+static ImageLoadEventSender& loadEventSender()
+{
+ DEFINE_STATIC_LOCAL(ImageLoadEventSender, sender, ());
+ return sender;
+}
+
+ImageLoader::ImageLoader(Element* element)
+ : m_element(element)
, m_image(0)
, m_firedLoad(true)
, m_imageComplete(true)
@@ -44,7 +69,7 @@ ImageLoader::~ImageLoader()
{
if (m_image)
m_image->removeClient(this);
- m_element->document()->removeImage(this);
+ loadEventSender().cancelLoadEvent(this);
}
void ImageLoader::setImage(CachedImage* newImage)
@@ -61,11 +86,11 @@ void ImageLoader::setImage(CachedImage* newImage)
oldImage->removeClient(this);
}
- if (RenderObject* renderer = element()->renderer()) {
+ if (RenderObject* renderer = m_element->renderer()) {
if (!renderer->isImage())
return;
- static_cast<RenderImage*>(renderer)->resetAnimation();
+ toRenderImage(renderer)->resetAnimation();
}
}
@@ -80,12 +105,11 @@ void ImageLoader::updateFromElement()
{
// If we're not making renderers for the page, then don't load images. We don't want to slow
// down the raw HTML parsing case by loading images we don't intend to display.
- Element* elem = element();
- Document* doc = elem->document();
- if (!doc->renderer())
+ Document* document = m_element->document();
+ if (!document->renderer())
return;
- AtomicString attr = elem->getAttribute(elem->imageSourceAttributeName());
+ AtomicString attr = m_element->getAttribute(m_element->imageSourceAttributeName());
if (attr == m_failedLoadURL)
return;
@@ -95,15 +119,15 @@ void ImageLoader::updateFromElement()
// a quirk that preserves old behavior that Dashboard widgets
// need (<rdar://problem/5994621>).
CachedImage* newImage = 0;
- if (!(attr.isNull() || attr.isEmpty() && doc->baseURI().isLocalFile())) {
+ if (!(attr.isNull() || (attr.isEmpty() && document->baseURI().isLocalFile()))) {
if (m_loadManually) {
- doc->docLoader()->setAutoLoadImages(false);
+ document->docLoader()->setAutoLoadImages(false);
newImage = new CachedImage(sourceURI(attr));
newImage->setLoading(true);
- newImage->setDocLoader(doc->docLoader());
- doc->docLoader()->m_documentResources.set(newImage->url(), newImage);
+ newImage->setDocLoader(document->docLoader());
+ document->docLoader()->m_documentResources.set(newImage->url(), newImage);
} else
- newImage = doc->docLoader()->requestImage(sourceURI(attr));
+ newImage = document->docLoader()->requestImage(sourceURI(attr));
// If we do not have an image here, it means that a cross-site
// violation occurred.
@@ -119,11 +143,11 @@ void ImageLoader::updateFromElement()
oldImage->removeClient(this);
}
- if (RenderObject* renderer = elem->renderer()) {
+ if (RenderObject* renderer = m_element->renderer()) {
if (!renderer->isImage())
return;
- static_cast<RenderImage*>(renderer)->resetAnimation();
+ toRenderImage(renderer)->resetAnimation();
}
}
@@ -139,15 +163,85 @@ void ImageLoader::notifyFinished(CachedResource*)
ASSERT(m_failedLoadURL.isEmpty());
m_imageComplete = true;
- Element* elem = element();
- elem->document()->dispatchImageLoadEventSoon(this);
+ loadEventSender().dispatchLoadEventSoon(this);
- if (RenderObject* renderer = elem->renderer()) {
+ if (RenderObject* renderer = m_element->renderer()) {
if (!renderer->isImage())
return;
- static_cast<RenderImage*>(renderer)->setCachedImage(m_image.get());
+ toRenderImage(renderer)->setCachedImage(m_image.get());
}
}
+void ImageLoader::dispatchPendingLoadEvent()
+{
+ if (m_firedLoad)
+ return;
+ if (!m_image)
+ return;
+ if (!m_element->document()->attached())
+ return;
+ m_firedLoad = true;
+ dispatchLoadEvent();
+}
+
+void ImageLoader::dispatchPendingLoadEvents()
+{
+ loadEventSender().dispatchPendingLoadEvents();
+}
+
+ImageLoadEventSender::ImageLoadEventSender()
+ : m_timer(this, &ImageLoadEventSender::timerFired)
+{
+}
+
+void ImageLoadEventSender::dispatchLoadEventSoon(ImageLoader* loader)
+{
+ m_dispatchSoonList.append(loader);
+ if (!m_timer.isActive())
+ m_timer.startOneShot(0);
+}
+
+void ImageLoadEventSender::cancelLoadEvent(ImageLoader* loader)
+{
+ // Remove instances of this loader from both lists.
+ // Use loops because we allow multiple instances to get into the lists.
+ size_t size = m_dispatchSoonList.size();
+ for (size_t i = 0; i < size; ++i) {
+ if (m_dispatchSoonList[i] == loader)
+ m_dispatchSoonList[i] = 0;
+ }
+ size = m_dispatchingList.size();
+ for (size_t i = 0; i < size; ++i) {
+ if (m_dispatchingList[i] == loader)
+ m_dispatchingList[i] = 0;
+ }
+ if (m_dispatchSoonList.isEmpty())
+ m_timer.stop();
+}
+
+void ImageLoadEventSender::dispatchPendingLoadEvents()
+{
+ // Need to avoid re-entering this function; if new dispatches are
+ // scheduled before the parent finishes processing the list, they
+ // will set a timer and eventually be processed.
+ if (!m_dispatchingList.isEmpty())
+ return;
+
+ m_timer.stop();
+
+ m_dispatchingList.swap(m_dispatchSoonList);
+ size_t size = m_dispatchingList.size();
+ for (size_t i = 0; i < size; ++i) {
+ if (ImageLoader* loader = m_dispatchingList[i])
+ loader->dispatchPendingLoadEvent();
+ }
+ m_dispatchingList.clear();
+}
+
+void ImageLoadEventSender::timerFired(Timer<ImageLoadEventSender>*)
+{
+ dispatchPendingLoadEvents();
+}
+
}
diff --git a/WebCore/loader/ImageLoader.h b/WebCore/loader/ImageLoader.h
index fc3a58a..3496f75 100644
--- a/WebCore/loader/ImageLoader.h
+++ b/WebCore/loader/ImageLoader.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,22 +30,21 @@
namespace WebCore {
class Element;
+class ImageLoadEventSender;
class ImageLoader : public CachedResourceClient {
public:
ImageLoader(Element*);
virtual ~ImageLoader();
+ // This function should be called when the element is attached to a document; starts
+ // loading if a load hasn't already been started.
void updateFromElement();
- // This method should be called after the 'src' attribute
- // is set (even when it is not modified) to force the update
- // and match Firefox and Opera.
+ // This function should be called whenever the 'src' attribute is set, even if its value
+ // doesn't change; starts new load unconditionally (matches Firefox and Opera behavior).
void updateFromElementIgnoringPreviousError();
- virtual void dispatchLoadEvent() = 0;
- virtual String sourceURI(const AtomicString&) const = 0;
-
Element* element() const { return m_element; }
bool imageComplete() const { return m_imageComplete; }
@@ -54,16 +53,22 @@ public:
void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
- // CachedResourceClient API
- virtual void notifyFinished(CachedResource*);
-
bool haveFiredLoadEvent() const { return m_firedLoad; }
+
+ static void dispatchPendingLoadEvents();
+
protected:
- void setLoadingImage(CachedImage*);
-
- void setHaveFiredLoadEvent(bool firedLoad) { m_firedLoad = firedLoad; }
+ virtual void notifyFinished(CachedResource*);
private:
+ virtual void dispatchLoadEvent() = 0;
+ virtual String sourceURI(const AtomicString&) const = 0;
+
+ friend class ImageLoadEventSender;
+ void dispatchPendingLoadEvent();
+
+ void setLoadingImage(CachedImage*);
+
Element* m_element;
CachedResourceHandle<CachedImage> m_image;
AtomicString m_failedLoadURL;
diff --git a/WebCore/loader/MainResourceLoader.cpp b/WebCore/loader/MainResourceLoader.cpp
index 325809b..5aa1cde 100644
--- a/WebCore/loader/MainResourceLoader.cpp
+++ b/WebCore/loader/MainResourceLoader.cpp
@@ -186,7 +186,11 @@ void MainResourceLoader::willSendRequest(ResourceRequest& newRequest, const Reso
static bool shouldLoadAsEmptyDocument(const KURL& url)
{
- return url.isEmpty() || equalIgnoringCase(String(url.protocol()), "about");
+#if PLATFORM(TORCHMOBILE)
+ return url.isEmpty() || (url.protocolIs("about") && equalIgnoringRef(url, blankURL()));
+#else
+ return url.isEmpty() || url.protocolIs("about");
+#endif
}
void MainResourceLoader::continueAfterContentPolicy(PolicyAction contentPolicy, const ResourceResponse& r)
@@ -248,7 +252,7 @@ void MainResourceLoader::continueAfterContentPolicy(PolicyAction contentPolicy,
if (!reachedTerminalState())
ResourceLoader::didReceiveResponse(r);
- if (frameLoader() && !frameLoader()->isStopping())
+ if (frameLoader() && !frameLoader()->isStopping()) {
if (m_substituteData.isValid()) {
if (m_substituteData.content()->size())
didReceiveData(m_substituteData.content()->data(), m_substituteData.content()->size(), m_substituteData.content()->size(), true);
@@ -256,6 +260,7 @@ void MainResourceLoader::continueAfterContentPolicy(PolicyAction contentPolicy,
didFinishLoading();
} else if (shouldLoadAsEmptyDocument(url) || frameLoader()->representationExistsForURLScheme(url.protocol()))
didFinishLoading();
+ }
}
void MainResourceLoader::callContinueAfterContentPolicy(void* argument, PolicyAction policy)
@@ -319,6 +324,17 @@ void MainResourceLoader::didReceiveData(const char* data, int length, long long
ASSERT(data);
ASSERT(length != 0);
+ ASSERT(!m_response.isNull());
+
+#if USE(CFNETWORK) || (PLATFORM(MAC) && !defined(BUILDING_ON_TIGER))
+ // Workaround for <rdar://problem/6060782>
+ if (m_response.isNull()) {
+ m_response = ResourceResponse(KURL(), "text/html", 0, String(), String());
+ if (DocumentLoader* documentLoader = frameLoader()->activeDocumentLoader())
+ documentLoader->setResponse(m_response);
+ }
+#endif
+
// There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
// See <rdar://problem/6304600> for more details.
#if !PLATFORM(CF)
@@ -396,7 +412,7 @@ void MainResourceLoader::handleEmptyLoad(const KURL& url, bool forURLScheme)
didReceiveResponse(response);
}
-void MainResourceLoader::handleDataLoadNow(Timer<MainResourceLoader>*)
+void MainResourceLoader::handleDataLoadNow(MainResourceLoaderTimer*)
{
RefPtr<MainResourceLoader> protect(this);
@@ -408,12 +424,22 @@ void MainResourceLoader::handleDataLoadNow(Timer<MainResourceLoader>*)
didReceiveResponse(response);
}
+void MainResourceLoader::startDataLoadTimer()
+{
+ m_dataLoadTimer.startOneShot(0);
+
+#if HAVE(RUNLOOP_TIMER)
+ if (SchedulePairHashSet* scheduledPairs = m_frame->page()->scheduledRunLoopPairs())
+ m_dataLoadTimer.schedule(*scheduledPairs);
+#endif
+}
+
void MainResourceLoader::handleDataLoadSoon(ResourceRequest& r)
{
m_initialRequest = r;
if (m_documentLoader->deferMainResourceDataLoad())
- m_dataLoadTimer.startOneShot(0);
+ startDataLoadTimer();
else
handleDataLoadNow(0);
}
@@ -497,17 +523,16 @@ bool MainResourceLoader::load(const ResourceRequest& r, const SubstituteData& su
void MainResourceLoader::setDefersLoading(bool defers)
{
ResourceLoader::setDefersLoading(defers);
-
+
if (defers) {
if (m_dataLoadTimer.isActive())
m_dataLoadTimer.stop();
} else {
if (m_initialRequest.isNull())
return;
-
- if (m_substituteData.isValid() &&
- m_documentLoader->deferMainResourceDataLoad())
- m_dataLoadTimer.startOneShot(0);
+
+ if (m_substituteData.isValid() && m_documentLoader->deferMainResourceDataLoad())
+ startDataLoadTimer();
else {
ResourceRequest r(m_initialRequest);
m_initialRequest = ResourceRequest();
diff --git a/WebCore/loader/MainResourceLoader.h b/WebCore/loader/MainResourceLoader.h
index 6c69c1f..d9ce2f9 100644
--- a/WebCore/loader/MainResourceLoader.h
+++ b/WebCore/loader/MainResourceLoader.h
@@ -29,16 +29,21 @@
#include "FrameLoaderTypes.h"
#include "ResourceLoader.h"
#include "SubstituteData.h"
-#include "Timer.h"
#include <wtf/Forward.h>
+#if HAVE(RUNLOOP_TIMER)
+#include "RunLoopTimer.h"
+#else
+#include "Timer.h"
+#endif
+
namespace WebCore {
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
class ApplicationCache;
#endif
class FormState;
- class ResourceRequest;
+ struct ResourceRequest;
class MainResourceLoader : public ResourceLoader {
public:
@@ -56,7 +61,13 @@ namespace WebCore {
virtual void didFinishLoading();
virtual void didFail(const ResourceError&);
- void handleDataLoadNow(Timer<MainResourceLoader>*);
+#if HAVE(RUNLOOP_TIMER)
+ typedef RunLoopTimer<MainResourceLoader> MainResourceLoaderTimer;
+#else
+ typedef Timer<MainResourceLoader> MainResourceLoaderTimer;
+#endif
+
+ void handleDataLoadNow(MainResourceLoaderTimer*);
bool isLoadingMultipartContent() const { return m_loadingMultipartContent; }
@@ -74,6 +85,7 @@ namespace WebCore {
void handleEmptyLoad(const KURL&, bool forURLScheme);
void handleDataLoadSoon(ResourceRequest& r);
+ void startDataLoadTimer();
void handleDataLoad(ResourceRequest&);
void receivedError(const ResourceError&);
@@ -90,7 +102,8 @@ namespace WebCore {
ResourceRequest m_initialRequest;
SubstituteData m_substituteData;
- Timer<MainResourceLoader> m_dataLoadTimer;
+
+ MainResourceLoaderTimer m_dataLoadTimer;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
// The application cache that the main resource was loaded from (if any).
diff --git a/WebCore/loader/MediaDocument.cpp b/WebCore/loader/MediaDocument.cpp
index 8ed5b45..b89ac10 100644
--- a/WebCore/loader/MediaDocument.cpp
+++ b/WebCore/loader/MediaDocument.cpp
@@ -54,7 +54,7 @@ public:
MediaTokenizer(Document* doc) : m_doc(doc), m_mediaElement(0) {}
private:
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void stopParsing();
virtual void finish();
virtual bool isWaitingForScripts() const;
@@ -68,24 +68,23 @@ private:
HTMLMediaElement* m_mediaElement;
};
-bool MediaTokenizer::write(const SegmentedString&, bool)
+void MediaTokenizer::write(const SegmentedString&, bool)
{
ASSERT_NOT_REACHED();
- return false;
}
void MediaTokenizer::createDocumentStructure()
{
ExceptionCode ec;
- RefPtr<Element> rootElement = m_doc->createElementNS(xhtmlNamespaceURI, "html", ec);
+ RefPtr<Element> rootElement = m_doc->createElement(htmlTag, false);
m_doc->appendChild(rootElement, ec);
- RefPtr<Element> body = m_doc->createElementNS(xhtmlNamespaceURI, "body", ec);
+ RefPtr<Element> body = m_doc->createElement(bodyTag, false);
body->setAttribute(styleAttr, "background-color: rgb(38,38,38);");
rootElement->appendChild(body, ec);
- RefPtr<Element> mediaElement = m_doc->createElementNS(xhtmlNamespaceURI, "video", ec);
+ RefPtr<Element> mediaElement = m_doc->createElement(videoTag, false);
m_mediaElement = static_cast<HTMLVideoElement*>(mediaElement.get());
m_mediaElement->setAttribute(controlsAttr, "");
@@ -147,18 +146,17 @@ void MediaDocument::defaultEventHandler(Event* event)
{
// Match the default Quicktime plugin behavior to allow
// clicking and double-clicking to pause and play the media.
- EventTargetNode* targetNode = event->target()->toNode();
+ Node* targetNode = event->target()->toNode();
if (targetNode && targetNode->hasTagName(videoTag)) {
HTMLVideoElement* video = static_cast<HTMLVideoElement*>(targetNode);
- ExceptionCode ec;
if (event->type() == eventNames().clickEvent) {
if (!video->canPlay()) {
- video->pause(ec);
+ video->pause();
event->setDefaultHandled();
}
} else if (event->type() == eventNames().dblclickEvent) {
if (video->canPlay()) {
- video->play(ec);
+ video->play();
event->setDefaultHandled();
}
}
diff --git a/WebCore/loader/NetscapePlugInStreamLoader.cpp b/WebCore/loader/NetscapePlugInStreamLoader.cpp
index e12ed07..9d0e81b 100644
--- a/WebCore/loader/NetscapePlugInStreamLoader.cpp
+++ b/WebCore/loader/NetscapePlugInStreamLoader.cpp
@@ -119,6 +119,11 @@ void NetscapePlugInStreamLoader::didCancel(const ResourceError& error)
m_client->didFail(this, error);
+ // If calling didFail spins the run loop the stream loader can reach the terminal state.
+ // If that's the case we just return early.
+ if (reachedTerminalState())
+ return;
+
// We need to remove the stream loader after the call to didFail, since didFail can
// spawn a new run loop and if the loader has been removed it won't be deferred when
// the document loader is asked to defer loading.
diff --git a/WebCore/loader/PluginDocument.cpp b/WebCore/loader/PluginDocument.cpp
index 42c801c..373126f 100644
--- a/WebCore/loader/PluginDocument.cpp
+++ b/WebCore/loader/PluginDocument.cpp
@@ -49,7 +49,7 @@ public:
PluginTokenizer(Document* doc) : m_doc(doc), m_embedElement(0) {}
private:
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void stopParsing();
virtual void finish();
virtual bool isWaitingForScripts() const;
@@ -63,26 +63,25 @@ private:
HTMLEmbedElement* m_embedElement;
};
-bool PluginTokenizer::write(const SegmentedString&, bool)
+void PluginTokenizer::write(const SegmentedString&, bool)
{
ASSERT_NOT_REACHED();
- return false;
}
void PluginTokenizer::createDocumentStructure()
{
ExceptionCode ec;
- RefPtr<Element> rootElement = m_doc->createElementNS(xhtmlNamespaceURI, "html", ec);
+ RefPtr<Element> rootElement = m_doc->createElement(htmlTag, false);
m_doc->appendChild(rootElement, ec);
-
- RefPtr<Element> body = m_doc->createElementNS(xhtmlNamespaceURI, "body", ec);
+
+ RefPtr<Element> body = m_doc->createElement(bodyTag, false);
body->setAttribute(marginwidthAttr, "0");
body->setAttribute(marginheightAttr, "0");
body->setAttribute(bgcolorAttr, "rgb(38,38,38)");
rootElement->appendChild(body, ec);
- RefPtr<Element> embedElement = m_doc->createElementNS(xhtmlNamespaceURI, "embed", ec);
+ RefPtr<Element> embedElement = m_doc->createElement(embedTag, false);
m_embedElement = static_cast<HTMLEmbedElement*>(embedElement.get());
m_embedElement->setAttribute(widthAttr, "100%");
diff --git a/WebCore/loader/ResourceLoader.h b/WebCore/loader/ResourceLoader.h
index c8cc208..d3e7b80 100644
--- a/WebCore/loader/ResourceLoader.h
+++ b/WebCore/loader/ResourceLoader.h
@@ -106,6 +106,9 @@ namespace WebCore {
#if PLATFORM(MAC)
virtual NSCachedURLResponse* willCacheResponse(ResourceHandle*, NSCachedURLResponse*);
#endif
+#if USE(CFNETWORK)
+ virtual bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef);
+#endif
ResourceHandle* handle() const { return m_handle.get(); }
bool sendResourceLoadCallbacks() const { return m_sendResourceLoadCallbacks; }
diff --git a/WebCore/loader/SubresourceLoader.h b/WebCore/loader/SubresourceLoader.h
index 1a94c73..0fce930 100644
--- a/WebCore/loader/SubresourceLoader.h
+++ b/WebCore/loader/SubresourceLoader.h
@@ -33,7 +33,7 @@
namespace WebCore {
- class ResourceRequest;
+ struct ResourceRequest;
class SubresourceLoaderClient;
class SubresourceLoader : public ResourceLoader {
diff --git a/WebCore/loader/SubresourceLoaderClient.h b/WebCore/loader/SubresourceLoaderClient.h
index 76fde47..acf8e6a 100644
--- a/WebCore/loader/SubresourceLoaderClient.h
+++ b/WebCore/loader/SubresourceLoaderClient.h
@@ -33,7 +33,7 @@ namespace WebCore {
class AuthenticationChallenge;
class ResourceError;
-class ResourceRequest;
+struct ResourceRequest;
class ResourceResponse;
class SubresourceLoader;
diff --git a/WebCore/loader/TextDocument.cpp b/WebCore/loader/TextDocument.cpp
index bd2c446..0d86c1b 100644
--- a/WebCore/loader/TextDocument.cpp
+++ b/WebCore/loader/TextDocument.cpp
@@ -41,9 +41,10 @@ using namespace HTMLNames;
class TextTokenizer : public Tokenizer {
public:
TextTokenizer(Document*);
+ virtual ~TextTokenizer();
TextTokenizer(HTMLViewSourceDocument*);
- virtual bool write(const SegmentedString&, bool appendData);
+ virtual void write(const SegmentedString&, bool appendData);
virtual void finish();
virtual bool isWaitingForScripts() const;
@@ -91,9 +92,15 @@ TextTokenizer::TextTokenizer(HTMLViewSourceDocument* doc)
m_size = 254;
m_buffer = static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size));
m_dest = m_buffer;
-}
+}
+
+TextTokenizer::~TextTokenizer()
+{
+ // finish() should have been called to prevent any leaks
+ ASSERT(!m_buffer);
+}
-bool TextTokenizer::write(const SegmentedString& s, bool)
+void TextTokenizer::write(const SegmentedString& s, bool)
{
ExceptionCode ec;
@@ -125,13 +132,13 @@ bool TextTokenizer::write(const SegmentedString& s, bool)
}
if (!m_preElement && !inViewSourceMode()) {
- RefPtr<Element> rootElement = m_doc->createElementNS(xhtmlNamespaceURI, "html", ec);
+ RefPtr<Element> rootElement = m_doc->createElement(htmlTag, false);
m_doc->appendChild(rootElement, ec);
- RefPtr<Element> body = m_doc->createElementNS(xhtmlNamespaceURI, "body", ec);
+ RefPtr<Element> body = m_doc->createElement(bodyTag, false);
rootElement->appendChild(body, ec);
- RefPtr<Element> preElement = m_doc->createElementNS(xhtmlNamespaceURI, "pre", ec);
+ RefPtr<Element> preElement = m_doc->createElement(preTag, false);
preElement->setAttribute("style", "word-wrap: break-word; white-space: pre-wrap;", ec);
body->appendChild(preElement, ec);
@@ -142,7 +149,7 @@ bool TextTokenizer::write(const SegmentedString& s, bool)
String string = String(m_buffer, m_dest - m_buffer);
if (inViewSourceMode()) {
static_cast<HTMLViewSourceDocument*>(m_doc)->addViewSourceText(string);
- return false;
+ return;
}
unsigned charsLeft = string.length();
@@ -151,15 +158,15 @@ bool TextTokenizer::write(const SegmentedString& s, bool)
RefPtr<Text> text = Text::createWithLengthLimit(m_doc, string, charsLeft);
m_preElement->appendChild(text, ec);
}
-
- return false;
}
void TextTokenizer::finish()
{
m_preElement = 0;
fastFree(m_buffer);
-
+ m_buffer = 0;
+ m_dest = 0;
+
m_doc->finishedParsing();
}
diff --git a/WebCore/loader/TextResourceDecoder.cpp b/WebCore/loader/TextResourceDecoder.cpp
index f37d8f7..ee81326 100644
--- a/WebCore/loader/TextResourceDecoder.cpp
+++ b/WebCore/loader/TextResourceDecoder.cpp
@@ -1,6 +1,6 @@
/*
Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
Copyright (C) 2005, 2006, 2007 Alexey Proskuryakov (ap@nypop.com)
This library is free software; you can redistribute it and/or
@@ -26,6 +26,9 @@
#include "DOMImplementation.h"
#include "HTMLNames.h"
#include "TextCodec.h"
+#include "TextEncoding.h"
+#include "TextEncodingDetector.h"
+#include "TextEncodingRegistry.h"
#include <wtf/ASCIICType.h>
#include <wtf/StringExtras.h>
@@ -320,14 +323,17 @@ const TextEncoding& TextResourceDecoder::defaultEncoding(ContentType contentType
return specifiedDefaultEncoding;
}
-TextResourceDecoder::TextResourceDecoder(const String& mimeType, const TextEncoding& specifiedDefaultEncoding)
+TextResourceDecoder::TextResourceDecoder(const String& mimeType, const TextEncoding& specifiedDefaultEncoding, bool usesEncodingDetector)
: m_contentType(determineContentType(mimeType))
- , m_decoder(defaultEncoding(m_contentType, specifiedDefaultEncoding))
+ , m_encoding(defaultEncoding(m_contentType, specifiedDefaultEncoding))
, m_source(DefaultEncoding)
+ , m_hintEncoding(0)
, m_checkedForBOM(false)
, m_checkedForCSSCharset(false)
, m_checkedForHeadCharset(false)
+ , m_useLenientXMLDecoding(false)
, m_sawError(false)
+ , m_usesEncodingDetector(usesEncodingDetector)
{
}
@@ -344,12 +350,13 @@ void TextResourceDecoder::setEncoding(const TextEncoding& encoding, EncodingSour
// When encoding comes from meta tag (i.e. it cannot be XML files sent via XHR),
// treat x-user-defined as windows-1252 (bug 18270)
if (source == EncodingFromMetaTag && strcasecmp(encoding.name(), "x-user-defined") == 0)
- m_decoder.reset("windows-1252");
+ m_encoding = "windows-1252";
else if (source == EncodingFromMetaTag || source == EncodingFromXMLHeader || source == EncodingFromCSSCharset)
- m_decoder.reset(encoding.closestByteBasedEquivalent());
+ m_encoding = encoding.closestByteBasedEquivalent();
else
- m_decoder.reset(encoding);
+ m_encoding = encoding;
+ m_codec.clear();
m_source = source;
}
@@ -401,51 +408,54 @@ static inline bool skipWhitespace(const char*& pos, const char* dataEnd)
return pos != dataEnd;
}
-void TextResourceDecoder::checkForBOM(const char* data, size_t len)
+size_t TextResourceDecoder::checkForBOM(const char* data, size_t len)
{
// Check for UTF-16/32 or UTF-8 BOM mark at the beginning, which is a sure sign of a Unicode encoding.
+ // We let it override even a user-chosen encoding.
+ ASSERT(!m_checkedForBOM);
- if (m_source == UserChosenEncoding) {
- // FIXME: Maybe a BOM should override even a user-chosen encoding.
- m_checkedForBOM = true;
- return;
- }
+ size_t lengthOfBOM = 0;
- // Check if we have enough data.
size_t bufferLength = m_buffer.size();
- if (bufferLength + len < 4)
- return;
-
- m_checkedForBOM = true;
- // Extract the first four bytes.
- // Handle the case where some of bytes are already in the buffer.
- // The last byte is always guaranteed to not be in the buffer.
- const unsigned char* udata = reinterpret_cast<const unsigned char*>(data);
- unsigned char c1 = bufferLength >= 1 ? m_buffer[0] : *udata++;
- unsigned char c2 = bufferLength >= 2 ? m_buffer[1] : *udata++;
- unsigned char c3 = bufferLength >= 3 ? m_buffer[2] : *udata++;
- ASSERT(bufferLength < 4);
- unsigned char c4 = *udata;
+ size_t buf1Len = bufferLength;
+ size_t buf2Len = len;
+ const unsigned char* buf1 = reinterpret_cast<const unsigned char*>(m_buffer.data());
+ const unsigned char* buf2 = reinterpret_cast<const unsigned char*>(data);
+ unsigned char c1 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c2 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c3 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c4 = buf2Len ? (--buf2Len, *buf2++) : 0;
// Check for the BOM.
if (c1 == 0xFF && c2 == 0xFE) {
- if (c3 !=0 || c4 != 0)
+ if (c3 != 0 || c4 != 0) {
setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
- else
+ lengthOfBOM = 2;
+ } else {
setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
- }
- else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF)
+ lengthOfBOM = 4;
+ }
+ } else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) {
setEncoding(UTF8Encoding(), AutoDetectedEncoding);
- else if (c1 == 0xFE && c2 == 0xFF)
+ lengthOfBOM = 3;
+ } else if (c1 == 0xFE && c2 == 0xFF) {
setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
- else if (c1 == 0 && c2 == 0 && c3 == 0xFE && c4 == 0xFF)
+ lengthOfBOM = 2;
+ } else if (c1 == 0 && c2 == 0 && c3 == 0xFE && c4 == 0xFF) {
setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 4;
+ }
+
+ if (lengthOfBOM || bufferLength + len >= 4)
+ m_checkedForBOM = true;
+
+ return lengthOfBOM;
}
bool TextResourceDecoder::checkForCSSCharset(const char* data, size_t len, bool& movedDataToBuffer)
{
- if (m_source != DefaultEncoding) {
+ if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
m_checkedForCSSCharset = true;
return true;
}
@@ -526,7 +536,7 @@ const int bytesToCheckUnconditionally = 1024; // That many input bytes will be c
bool TextResourceDecoder::checkForHeadCharset(const char* data, size_t len, bool& movedDataToBuffer)
{
- if (m_source != DefaultEncoding) {
+ if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
m_checkedForHeadCharset = true;
return true;
}
@@ -636,7 +646,7 @@ bool TextResourceDecoder::checkForHeadCharset(const char* data, size_t len, bool
ptr++;
continue;
}
- if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9')
+ if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
;
else if (c >= 'A' && c <= 'Z')
c += 'a' - 'A';
@@ -695,8 +705,8 @@ bool TextResourceDecoder::checkForHeadCharset(const char* data, size_t len, bool
break;
if (str[pos++] != '=')
continue;
- while (pos < length &&
- (str[pos] <= ' ') || str[pos] == '=' || str[pos] == '"' || str[pos] == '\'')
+ while ((pos < length) &&
+ (str[pos] <= ' ' || str[pos] == '=' || str[pos] == '"' || str[pos] == '\''))
pos++;
// end ?
@@ -753,10 +763,28 @@ void TextResourceDecoder::detectJapaneseEncoding(const char* data, size_t len)
}
}
+// We use the encoding detector in two cases:
+// 1. Encoding detector is turned ON and no other encoding source is
+// available (that is, it's DefaultEncoding).
+// 2. Encoding detector is turned ON and the encoding is set to
+// the encoding of the parent frame, which is also auto-detected.
+// Note that condition #2 is NOT satisfied unless parent-child frame
+// relationship is compliant to the same-origin policy. If they're from
+// different domains, |m_source| would not be set to EncodingFromParentFrame
+// in the first place.
+bool TextResourceDecoder::shouldAutoDetect() const
+{
+ // Just checking m_hintEncoding suffices here because it's only set
+ // in setHintEncoding when the source is AutoDetectedEncoding.
+ return m_usesEncodingDetector
+ && (m_source == DefaultEncoding || (m_source == EncodingFromParentFrame && m_hintEncoding));
+}
+
String TextResourceDecoder::decode(const char* data, size_t len)
{
+ size_t lengthOfBOM = 0;
if (!m_checkedForBOM)
- checkForBOM(data, len);
+ lengthOfBOM = checkForBOM(data, len);
bool movedDataToBuffer = false;
@@ -768,15 +796,32 @@ String TextResourceDecoder::decode(const char* data, size_t len)
if (!checkForHeadCharset(data, len, movedDataToBuffer))
return "";
- // Do the auto-detect if our default encoding is one of the Japanese ones.
- // FIXME: It seems wrong to change our encoding downstream after we have already done some decoding.
- if (m_source != UserChosenEncoding && m_source != AutoDetectedEncoding && encoding().isJapanese())
+ // FIXME: It seems wrong to change our encoding downstream after
+ // we have already done some decoding. However, it's not possible
+ // to avoid in a sense in two cases below because triggering conditions
+ // for both cases depend on the information that won't be available
+ // until we do partial read.
+ // The first case had better be removed altogether (see bug 21990)
+ // or at least be made to be invoked only when the encoding detection
+ // is turned on.
+ // Do the auto-detect 1) using Japanese detector if our default encoding is
+ // one of the Japanese detector or 2) using detectTextEncoding if encoding
+ // detection is turned on.
+ if (m_source != UserChosenEncoding && m_source != AutoDetectedEncoding && m_encoding.isJapanese())
detectJapaneseEncoding(data, len);
+ else if (shouldAutoDetect()) {
+ TextEncoding detectedEncoding;
+ if (detectTextEncoding(data, len, m_hintEncoding, &detectedEncoding))
+ setEncoding(detectedEncoding, AutoDetectedEncoding);
+ }
+
+ ASSERT(m_encoding.isValid());
- ASSERT(encoding().isValid());
+ if (!m_codec)
+ m_codec.set(newTextCodec(m_encoding).release());
if (m_buffer.isEmpty())
- return m_decoder.decode(data, len, false, m_contentType == XML, m_sawError);
+ return m_codec->decode(data + lengthOfBOM, len - lengthOfBOM, false, m_contentType == XML, m_sawError);
if (!movedDataToBuffer) {
size_t oldSize = m_buffer.size();
@@ -784,16 +829,31 @@ String TextResourceDecoder::decode(const char* data, size_t len)
memcpy(m_buffer.data() + oldSize, data, len);
}
- String result = m_decoder.decode(m_buffer.data(), m_buffer.size(), false, m_contentType == XML, m_sawError);
+ String result = m_codec->decode(m_buffer.data() + lengthOfBOM, m_buffer.size() - lengthOfBOM, false, m_contentType == XML && !m_useLenientXMLDecoding, m_sawError);
m_buffer.clear();
return result;
}
String TextResourceDecoder::flush()
{
- String result = m_decoder.decode(m_buffer.data(), m_buffer.size(), true, m_contentType == XML, m_sawError);
+ // If we can not identify the encoding even after a document is completely
+ // loaded, we need to detect the encoding if other conditions for
+ // autodetection is satisfied.
+ if (m_buffer.size() && shouldAutoDetect()
+ && ((!m_checkedForHeadCharset && (m_contentType == HTML || m_contentType == XML)) || (!m_checkedForCSSCharset && (m_contentType == CSS)))) {
+ TextEncoding detectedEncoding;
+ if (detectTextEncoding(m_buffer.data(), m_buffer.size(),
+ m_hintEncoding, &detectedEncoding))
+ setEncoding(detectedEncoding, AutoDetectedEncoding);
+ }
+
+ if (!m_codec)
+ m_codec.set(newTextCodec(m_encoding).release());
+
+ String result = m_codec->decode(m_buffer.data(), m_buffer.size(), true, m_contentType == XML && !m_useLenientXMLDecoding, m_sawError);
m_buffer.clear();
- m_decoder.reset(m_decoder.encoding());
+ m_codec.clear();
+ m_checkedForBOM = false; // Skip BOM again when re-decoding.
return result;
}
diff --git a/WebCore/loader/TextResourceDecoder.h b/WebCore/loader/TextResourceDecoder.h
index 8bbe85e..fb755c9 100644
--- a/WebCore/loader/TextResourceDecoder.h
+++ b/WebCore/loader/TextResourceDecoder.h
@@ -23,7 +23,7 @@
#ifndef TextResourceDecoder_h
#define TextResourceDecoder_h
-#include "TextDecoder.h"
+#include "TextEncoding.h"
namespace WebCore {
@@ -36,43 +36,59 @@ public:
EncodingFromMetaTag,
EncodingFromCSSCharset,
EncodingFromHTTPHeader,
- UserChosenEncoding
+ UserChosenEncoding,
+ EncodingFromParentFrame
};
- static PassRefPtr<TextResourceDecoder> create(const String& mimeType, const TextEncoding& defaultEncoding = TextEncoding())
+ static PassRefPtr<TextResourceDecoder> create(const String& mimeType, const TextEncoding& defaultEncoding = TextEncoding(), bool usesEncodingDetector = false)
{
- return adoptRef(new TextResourceDecoder(mimeType, defaultEncoding));
+ return adoptRef(new TextResourceDecoder(mimeType, defaultEncoding, usesEncodingDetector));
}
~TextResourceDecoder();
void setEncoding(const TextEncoding&, EncodingSource);
- const TextEncoding& encoding() const { return m_decoder.encoding(); }
+ const TextEncoding& encoding() const { return m_encoding; }
String decode(const char* data, size_t length);
String flush();
-
+
+ void setHintEncoding(const TextResourceDecoder* hintDecoder)
+ {
+ // hintEncoding is for use with autodetection, which should be
+ // only invoked when hintEncoding comes from auto-detection.
+ if (hintDecoder && hintDecoder->m_source == AutoDetectedEncoding)
+ m_hintEncoding = hintDecoder->encoding().name();
+ }
+
+ void useLenientXMLDecoding() { m_useLenientXMLDecoding = true; }
bool sawError() const { return m_sawError; }
private:
- TextResourceDecoder(const String& mimeType, const TextEncoding& defaultEncoding);
+ TextResourceDecoder(const String& mimeType, const TextEncoding& defaultEncoding,
+ bool usesEncodingDetector);
- enum ContentType { PlainText, HTML, XML, CSS }; // PlainText is equivalent to directly using TextDecoder.
+ enum ContentType { PlainText, HTML, XML, CSS }; // PlainText only checks for BOM.
static ContentType determineContentType(const String& mimeType);
static const TextEncoding& defaultEncoding(ContentType, const TextEncoding& defaultEncoding);
- void checkForBOM(const char*, size_t);
+ size_t checkForBOM(const char*, size_t);
bool checkForCSSCharset(const char*, size_t, bool& movedDataToBuffer);
bool checkForHeadCharset(const char*, size_t, bool& movedDataToBuffer);
void detectJapaneseEncoding(const char*, size_t);
+ bool shouldAutoDetect() const;
ContentType m_contentType;
- TextDecoder m_decoder;
+ TextEncoding m_encoding;
+ OwnPtr<TextCodec> m_codec;
EncodingSource m_source;
+ const char* m_hintEncoding;
Vector<char> m_buffer;
bool m_checkedForBOM;
bool m_checkedForCSSCharset;
bool m_checkedForHeadCharset;
+ bool m_useLenientXMLDecoding; // Don't stop on XML decoding errors.
bool m_sawError;
+ bool m_usesEncodingDetector;
};
}
diff --git a/WebCore/loader/ThreadableLoader.cpp b/WebCore/loader/ThreadableLoader.cpp
index 0f22fbe..1b2cc88 100644
--- a/WebCore/loader/ThreadableLoader.cpp
+++ b/WebCore/loader/ThreadableLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,11 +31,12 @@
#include "config.h"
#include "ThreadableLoader.h"
-#include "DocumentThreadableLoader.h"
-#include "Document.h"
-#include "Frame.h"
-#include "FrameLoader.h"
#include "ScriptExecutionContext.h"
+#include "Document.h"
+#include "DocumentThreadableLoader.h"
+#include "WorkerContext.h"
+#include "WorkerRunLoop.h"
+#include "WorkerThreadableLoader.h"
namespace WebCore {
@@ -43,20 +44,29 @@ PassRefPtr<ThreadableLoader> ThreadableLoader::create(ScriptExecutionContext* co
{
ASSERT(client);
ASSERT(context);
- ASSERT(context->isDocument());
+#if ENABLE(WORKERS)
+ if (context->isWorkerContext())
+ return WorkerThreadableLoader::create(static_cast<WorkerContext*>(context), client, WorkerRunLoop::defaultMode(), request, callbacksSetting, contentSniff);
+#endif // ENABLE(WORKERS)
+
+ ASSERT(context->isDocument());
return DocumentThreadableLoader::create(static_cast<Document*>(context), client, request, callbacksSetting, contentSniff);
}
-unsigned long ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext* context, const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
+void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext* context, const ResourceRequest& request, ThreadableLoaderClient& client)
{
ASSERT(context);
- ASSERT(context->isDocument());
- Document* document = static_cast<Document*>(context);
- if (!document->frame())
- return std::numeric_limits<unsigned long>::max();
- return document->frame()->loader()->loadResourceSynchronously(request, error, response, data);
+#if ENABLE(WORKERS)
+ if (context->isWorkerContext()) {
+ WorkerThreadableLoader::loadResourceSynchronously(static_cast<WorkerContext*>(context), request, client);
+ return;
+ }
+#endif // ENABLE(WORKERS)
+
+ ASSERT(context->isDocument());
+ DocumentThreadableLoader::loadResourceSynchronously(static_cast<Document*>(context), request, client);
}
} // namespace WebCore
diff --git a/WebCore/loader/ThreadableLoader.h b/WebCore/loader/ThreadableLoader.h
index e8ff058..b051b32 100644
--- a/WebCore/loader/ThreadableLoader.h
+++ b/WebCore/loader/ThreadableLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -38,7 +38,7 @@
namespace WebCore {
class ResourceError;
- class ResourceRequest;
+ struct ResourceRequest;
class ResourceResponse;
class ScriptExecutionContext;
class ThreadableLoaderClient;
@@ -57,8 +57,8 @@ namespace WebCore {
// just able to run on threads other than the main thread).
class ThreadableLoader : Noncopyable {
public:
+ static void loadResourceSynchronously(ScriptExecutionContext*, const ResourceRequest&, ThreadableLoaderClient&);
static PassRefPtr<ThreadableLoader> create(ScriptExecutionContext*, ThreadableLoaderClient*, const ResourceRequest&, LoadCallbacks, ContentSniff);
- static unsigned long loadResourceSynchronously(ScriptExecutionContext*, const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data);
virtual void cancel() = 0;
void ref() { refThreadableLoader(); }
diff --git a/WebCore/loader/ThreadableLoaderClient.h b/WebCore/loader/ThreadableLoaderClient.h
index 4fde404..93a8e86 100644
--- a/WebCore/loader/ThreadableLoaderClient.h
+++ b/WebCore/loader/ThreadableLoaderClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +33,7 @@
namespace WebCore {
+ class ResourceError;
class ResourceResponse;
class ThreadableLoaderClient {
@@ -41,9 +42,9 @@ namespace WebCore {
virtual void didReceiveResponse(const ResourceResponse&) { }
virtual void didReceiveData(const char*, int /*lengthReceived*/) { }
- virtual void didFinishLoading(unsigned long /*identifer*/) { }
- virtual void didFail() { }
- virtual void didGetCancelled() { }
+ virtual void didFinishLoading(unsigned long /*identifier*/) { }
+ virtual void didFail(const ResourceError&) { }
+ virtual void didFailRedirectCheck() { }
virtual void didReceiveAuthenticationCancellation(const ResourceResponse&) { }
diff --git a/WebCore/loader/ThreadableLoaderClientWrapper.h b/WebCore/loader/ThreadableLoaderClientWrapper.h
new file mode 100644
index 0000000..d3c1a9f
--- /dev/null
+++ b/WebCore/loader/ThreadableLoaderClientWrapper.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ThreadableLoaderClientWrapper_h
+#define ThreadableLoaderClientWrapper_h
+
+#include "ThreadableLoaderClient.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+ class ThreadableLoaderClientWrapper : public ThreadSafeShared<ThreadableLoaderClientWrapper> {
+ public:
+ static PassRefPtr<ThreadableLoaderClientWrapper> create(ThreadableLoaderClient* client)
+ {
+ return adoptRef(new ThreadableLoaderClientWrapper(client));
+ }
+
+ void clearClient()
+ {
+ m_done = true;
+ m_client = 0;
+ }
+
+ bool done() const
+ {
+ return m_done;
+ }
+
+ void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+ {
+ if (m_client)
+ m_client->didSendData(bytesSent, totalBytesToBeSent);
+ }
+
+ void didReceiveResponse(const ResourceResponse& response)
+ {
+ if (m_client)
+ m_client->didReceiveResponse(response);
+ }
+
+ void didReceiveData(const char* data, int lengthReceived)
+ {
+ if (m_client)
+ m_client->didReceiveData(data, lengthReceived);
+ }
+
+ void didFinishLoading(unsigned long identifier)
+ {
+ m_done = true;
+ if (m_client)
+ m_client->didFinishLoading(identifier);
+ }
+
+ void didFail(const ResourceError& error)
+ {
+ m_done = true;
+ if (m_client)
+ m_client->didFail(error);
+ }
+
+ void didFailRedirectCheck()
+ {
+ m_done = true;
+ if (m_client)
+ m_client->didFailRedirectCheck();
+ }
+
+ void didReceiveAuthenticationCancellation(const ResourceResponse& response)
+ {
+ if (m_client)
+ m_client->didReceiveResponse(response);
+ }
+
+ protected:
+ ThreadableLoaderClientWrapper(ThreadableLoaderClient* client)
+ : m_client(client)
+ , m_done(false)
+ {
+ }
+
+ ThreadableLoaderClient* m_client;
+ bool m_done;
+ };
+
+} // namespace WebCore
+
+#endif // ThreadableLoaderClientWrapper_h
diff --git a/WebCore/loader/WorkerThreadableLoader.cpp b/WebCore/loader/WorkerThreadableLoader.cpp
new file mode 100644
index 0000000..731ffcb
--- /dev/null
+++ b/WebCore/loader/WorkerThreadableLoader.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerThreadableLoader.h"
+
+#include "GenericWorkerTask.h"
+#include "ResourceError.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+#include "ThreadableLoader.h"
+#include "WorkerContext.h"
+#include "WorkerMessagingProxy.h"
+#include "WorkerThread.h"
+#include <memory>
+#include <wtf/OwnPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
+
+using namespace std;
+
+namespace WebCore {
+
+static const char loadResourceSynchronouslyMode[] = "loadResourceSynchronouslyMode";
+
+// FIXME: The assumption that we can upcast worker object proxy to WorkerMessagingProxy will not be true in multi-process implementation.
+WorkerThreadableLoader::WorkerThreadableLoader(WorkerContext* workerContext, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, LoadCallbacks callbacksSetting,
+ ContentSniff contentSniff)
+ : m_workerContext(workerContext)
+ , m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client))
+ , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, *(static_cast<WorkerMessagingProxy*>(m_workerContext->thread()->workerObjectProxy())), taskMode, request, callbacksSetting,
+ contentSniff)))
+{
+}
+
+WorkerThreadableLoader::~WorkerThreadableLoader()
+{
+ m_bridge.destroy();
+}
+
+void WorkerThreadableLoader::loadResourceSynchronously(WorkerContext* workerContext, const ResourceRequest& request, ThreadableLoaderClient& client)
+{
+ WorkerRunLoop& runLoop = workerContext->thread()->runLoop();
+
+ // Create a unique mode just for this synchronous resource load.
+ String mode = loadResourceSynchronouslyMode;
+ mode.append(String::number(runLoop.createUniqueId()));
+
+ ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
+ RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerContext, &client, mode, request, DoNotSendLoadCallbacks, contentSniff);
+
+ MessageQueueWaitResult result = MessageQueueMessageReceived;
+ while (!loader->done() && result != MessageQueueTerminated)
+ result = runLoop.runInMode(workerContext, mode);
+
+ if (!loader->done() && result == MessageQueueTerminated)
+ loader->cancel();
+}
+
+void WorkerThreadableLoader::cancel()
+{
+ m_bridge.cancel();
+}
+
+WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, WorkerMessagingProxy& messagingProxy, const String& taskMode,
+ const ResourceRequest& request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
+ : m_workerClientWrapper(workerClientWrapper)
+ , m_messagingProxy(messagingProxy)
+ , m_taskMode(taskMode.copy())
+{
+ ASSERT(m_workerClientWrapper.get());
+ m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, this, request, callbacksSetting, contentSniff));
+}
+
+WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge()
+{
+}
+
+void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, auto_ptr<CrossThreadResourceRequestData> requestData, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
+{
+ // FIXME: This assert fails for nested workers. Removing the assert would allow it to work,
+ // but then there would be one WorkerThreadableLoader in every intermediate worker simply
+ // chaining the requests, which is not very good. Instead, the postTaskToWorkerObject should be a
+ // postTaskToDocumentContext.
+ ASSERT(isMainThread());
+ ASSERT(context->isDocument());
+
+ if (thisPtr->m_messagingProxy.askedToTerminate())
+ return;
+
+ // FIXME: the created loader has no knowledge of the origin of the worker doing the load request.
+ // Basically every setting done in SubresourceLoader::create (including the contents of addExtraFieldsToRequest)
+ // needs to be examined for how it should take into account a different originator.
+ OwnPtr<ResourceRequest> request(ResourceRequest::adopt(requestData));
+ // FIXME: If the a site requests a local resource, then this will return a non-zero value but the sync path
+ // will return a 0 value. Either this should return 0 or the other code path should do a callback with
+ // a failure.
+ thisPtr->m_mainThreadLoader = ThreadableLoader::create(context, thisPtr, *request, callbacksSetting, contentSniff);
+ ASSERT(thisPtr->m_mainThreadLoader);
+}
+
+void WorkerThreadableLoader::MainThreadBridge::mainThreadDestroy(ScriptExecutionContext* context, MainThreadBridge* thisPtr)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+ delete thisPtr;
+}
+
+void WorkerThreadableLoader::MainThreadBridge::destroy()
+{
+ // Ensure that no more client callbacks are done in the worker context's thread.
+ clearClientWrapper();
+
+ // "delete this" and m_mainThreadLoader::deref() on the worker object's thread.
+ m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&MainThreadBridge::mainThreadDestroy, this));
+}
+
+void WorkerThreadableLoader::MainThreadBridge::mainThreadCancel(ScriptExecutionContext* context, MainThreadBridge* thisPtr)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+
+ if (!thisPtr->m_mainThreadLoader)
+ return;
+ thisPtr->m_mainThreadLoader->cancel();
+ thisPtr->m_mainThreadLoader = 0;
+}
+
+void WorkerThreadableLoader::MainThreadBridge::cancel()
+{
+ m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&MainThreadBridge::mainThreadCancel, this));
+ ThreadableLoaderClientWrapper* clientWrapper = static_cast<ThreadableLoaderClientWrapper*>(m_workerClientWrapper.get());
+ if (!clientWrapper->done()) {
+ // If the client hasn't reached a termination state, then transition it by sending a cancellation error.
+ // Note: no more client callbacks will be done after this method -- the clearClientWrapper() call ensures that.
+ ResourceError error(String(), 0, String(), String());
+ error.setIsCancellation(true);
+ clientWrapper->didFail(error);
+ }
+ clearClientWrapper();
+}
+
+void WorkerThreadableLoader::MainThreadBridge::clearClientWrapper()
+{
+ static_cast<ThreadableLoaderClientWrapper*>(m_workerClientWrapper.get())->clearClient();
+}
+
+static void workerContextDidSendData(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ workerClientWrapper->didSendData(bytesSent, totalBytesToBeSent);
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent), m_taskMode);
+}
+
+static void workerContextDidReceiveResponse(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, auto_ptr<CrossThreadResourceResponseData> responseData)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData));
+ workerClientWrapper->didReceiveResponse(*response);
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didReceiveResponse(const ResourceResponse& response)
+{
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveResponse, m_workerClientWrapper, response), m_taskMode);
+}
+
+static void workerContextDidReceiveData(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, auto_ptr<Vector<char> > vectorData)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ workerClientWrapper->didReceiveData(vectorData->data(), vectorData->size());
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didReceiveData(const char* data, int lengthReceived)
+{
+ auto_ptr<Vector<char> > vector(new Vector<char>(lengthReceived)); // needs to be an auto_ptr for usage with createCallbackTask.
+ memcpy(vector->data(), data, lengthReceived);
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveData, m_workerClientWrapper, vector), m_taskMode);
+}
+
+static void workerContextDidFinishLoading(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ workerClientWrapper->didFinishLoading(identifier);
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didFinishLoading(unsigned long identifier)
+{
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidFinishLoading, m_workerClientWrapper, identifier), m_taskMode);
+}
+
+static void workerContextDidFail(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ workerClientWrapper->didFail(error);
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didFail(const ResourceError& error)
+{
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidFail, m_workerClientWrapper, error), m_taskMode);
+}
+
+static void workerContextDidFailRedirectCheck(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ workerClientWrapper->didFailRedirectCheck();
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didFailRedirectCheck()
+{
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidFailRedirectCheck, m_workerClientWrapper), m_taskMode);
+}
+
+static void workerContextDidReceiveAuthenticationCancellation(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, auto_ptr<CrossThreadResourceResponseData> responseData)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData));
+ workerClientWrapper->didReceiveAuthenticationCancellation(*response);
+}
+
+void WorkerThreadableLoader::MainThreadBridge::didReceiveAuthenticationCancellation(const ResourceResponse& response)
+{
+ m_messagingProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveAuthenticationCancellation, m_workerClientWrapper, response), m_taskMode);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/loader/WorkerThreadableLoader.h b/WebCore/loader/WorkerThreadableLoader.h
new file mode 100644
index 0000000..5462a97
--- /dev/null
+++ b/WebCore/loader/WorkerThreadableLoader.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerThreadableLoader_h
+#define WorkerThreadableLoader_h
+
+#if ENABLE(WORKERS)
+
+#include "PlatformString.h"
+#include "ThreadableLoader.h"
+#include "ThreadableLoaderClient.h"
+#include "ThreadableLoaderClientWrapper.h"
+
+#include <memory>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+ class ResourceError;
+ struct ResourceRequest;
+ class WorkerContext;
+ class WorkerMessagingProxy;
+ struct CrossThreadResourceResponseData;
+ struct CrossThreadResourceRequestData;
+
+ class WorkerThreadableLoader : public RefCounted<WorkerThreadableLoader>, public ThreadableLoader {
+ public:
+ static void loadResourceSynchronously(WorkerContext*, const ResourceRequest&, ThreadableLoaderClient&);
+ static PassRefPtr<WorkerThreadableLoader> create(WorkerContext* workerContext, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, LoadCallbacks callbacksSetting, ContentSniff contentSniff)
+ {
+ return adoptRef(new WorkerThreadableLoader(workerContext, client, taskMode, request, callbacksSetting, contentSniff));
+ }
+
+ ~WorkerThreadableLoader();
+
+ virtual void cancel();
+
+ bool done() const { return m_workerClientWrapper->done(); }
+
+ using RefCounted<WorkerThreadableLoader>::ref;
+ using RefCounted<WorkerThreadableLoader>::deref;
+
+ protected:
+ virtual void refThreadableLoader() { ref(); }
+ virtual void derefThreadableLoader() { deref(); }
+
+ private:
+ // Creates a loader on the main thread and bridges communication between
+ // the main thread and the worker context's thread where WorkerThreadableLoader runs.
+ //
+ // Regarding the bridge and lifetimes of items used in callbacks, there are a few cases:
+ //
+ // all cases. All tasks posted from the worker context's thread are ok because
+ // the last task posted always is "mainThreadDestroy", so MainThreadBridge is
+ // around for all tasks that use it on the mian thread.
+ //
+ // case 1. worker.terminate is called.
+ // In this case, no more tasks are posted from the worker object's thread to the worker
+ // context's thread -- WorkerMessagingProxy enforces this.
+ //
+ // case 2. xhr gets aborted and the worker context continues running.
+ // The ThreadableLoaderClientWrapper has the underlying client cleared, so no more calls
+ // go through it. All tasks posted from the worker object's thread to the worker context's
+ // thread do "ThreadableLoaderClientWrapper::ref" (automatically inside of the cross thread copy
+ // done in createCallbackTask), so the ThreadableLoaderClientWrapper instance is there until all
+ // tasks are executed.
+ class MainThreadBridge : ThreadableLoaderClient {
+ public:
+ // All executed on the worker context's thread.
+ MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerMessagingProxy&, const String& taskMode, const ResourceRequest&, LoadCallbacks, ContentSniff);
+ void cancel();
+ void destroy();
+
+ private:
+ // Executed on the worker context's thread.
+ void clearClientWrapper();
+
+ // All executed on the main thread.
+ static void mainThreadDestroy(ScriptExecutionContext*, MainThreadBridge*);
+ ~MainThreadBridge();
+
+ static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, std::auto_ptr<CrossThreadResourceRequestData>, LoadCallbacks, ContentSniff);
+ static void mainThreadCancel(ScriptExecutionContext*, MainThreadBridge*);
+ virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
+ virtual void didReceiveResponse(const ResourceResponse&);
+ virtual void didReceiveData(const char*, int lengthReceived);
+ virtual void didFinishLoading(unsigned long identifier);
+ virtual void didFail(const ResourceError&);
+ virtual void didFailRedirectCheck();
+ virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
+
+ // Only to be used on the main thread.
+ RefPtr<ThreadableLoader> m_mainThreadLoader;
+
+ // ThreadableLoaderClientWrapper is to be used on the worker context thread.
+ // The ref counting is done on either thread.
+ RefPtr<ThreadSafeShared<ThreadableLoaderClientWrapper> > m_workerClientWrapper;
+
+ // May be used on either thread.
+ WorkerMessagingProxy& m_messagingProxy;
+
+ // For use on the main thread.
+ String m_taskMode;
+ };
+
+ WorkerThreadableLoader(WorkerContext*, ThreadableLoaderClient*, const String& taskMode, const ResourceRequest&, LoadCallbacks, ContentSniff);
+
+ RefPtr<WorkerContext> m_workerContext;
+ RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
+ MainThreadBridge& m_bridge;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerThreadableLoader_h
diff --git a/WebCore/loader/appcache/ApplicationCache.cpp b/WebCore/loader/appcache/ApplicationCache.cpp
index abe8b22..e411852 100644
--- a/WebCore/loader/appcache/ApplicationCache.cpp
+++ b/WebCore/loader/appcache/ApplicationCache.cpp
@@ -81,7 +81,7 @@ void ApplicationCache::addResource(PassRefPtr<ApplicationCacheResource> resource
if (m_storageID) {
ASSERT(!resource->storageID());
- ASSERT(resource->type() & (ApplicationCacheResource::Dynamic | ApplicationCacheResource::Implicit));
+ ASSERT(resource->type() & (ApplicationCacheResource::Dynamic | ApplicationCacheResource::Master));
// Add the resource to the storage.
cacheStorage().store(resource.get(), this);
@@ -146,13 +146,13 @@ bool ApplicationCache::addDynamicEntry(const String& url)
if (!equalIgnoringCase(m_group->manifestURL().protocol(), KURL(url).protocol()))
return false;
- // FIXME: Implement
+ // FIXME: Implement (be sure to respect private browsing state).
return true;
}
void ApplicationCache::removeDynamicEntry(const String&)
{
- // FIXME: Implement
+ // FIXME: Implement (be sure to respect private browsing state).
}
void ApplicationCache::setOnlineWhitelist(const Vector<KURL>& onlineWhitelist)
diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
index 2367e79..1b16b50 100644
--- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp
@@ -154,7 +154,14 @@ void ApplicationCacheGroup::selectCache(Frame* frame, const KURL& manifestURL)
// Check that the resource URL has the same scheme/host/port as the manifest URL.
if (!protocolHostAndPortAreEqual(manifestURL, request.url()))
return;
-
+
+ // Don't change anything on disk if private browsing is enabled.
+ if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) {
+ postListenerTask(&DOMApplicationCache::callCheckingListener, documentLoader);
+ postListenerTask(&DOMApplicationCache::callErrorListener, documentLoader);
+ return;
+ }
+
ApplicationCacheGroup* group = cacheStorage().findOrCreateCacheGroup(manifestURL);
documentLoader->setCandidateApplicationCacheGroup(group);
@@ -184,7 +191,7 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
{
ASSERT(m_pendingMasterResourceLoaders.contains(loader));
ASSERT(m_completionType == None || m_pendingEntries.isEmpty());
- const KURL& url = loader->originalURL();
+ const KURL& url = loader->url();
switch (m_completionType) {
case None:
@@ -195,12 +202,12 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
associateDocumentLoaderWithCache(loader, m_newestCache.get());
if (ApplicationCacheResource* resource = m_newestCache->resourceForURL(url)) {
- if (!(resource->type() & ApplicationCacheResource::Implicit)) {
- resource->addType(ApplicationCacheResource::Implicit);
+ if (!(resource->type() & ApplicationCacheResource::Master)) {
+ resource->addType(ApplicationCacheResource::Master);
ASSERT(!resource->storageID());
}
} else
- m_newestCache->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Implicit, loader->mainResourceData()));
+ m_newestCache->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, loader->mainResourceData()));
break;
case Failure:
@@ -215,12 +222,12 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader)
ASSERT(m_associatedDocumentLoaders.contains(loader));
if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) {
- if (!(resource->type() & ApplicationCacheResource::Implicit)) {
- resource->addType(ApplicationCacheResource::Implicit);
+ if (!(resource->type() & ApplicationCacheResource::Master)) {
+ resource->addType(ApplicationCacheResource::Master);
ASSERT(!resource->storageID());
}
} else
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Implicit, loader->mainResourceData()));
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, loader->response(), ApplicationCacheResource::Master, loader->mainResourceData()));
// The "cached" event will be posted to all associated documents once update is complete.
break;
}
@@ -369,6 +376,16 @@ void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption up
return;
}
+ // Don't change anything on disk if private browsing is enabled.
+ if (!frame->settings() || frame->settings()->privateBrowsingEnabled()) {
+ ASSERT(m_pendingMasterResourceLoaders.isEmpty());
+ ASSERT(m_pendingEntries.isEmpty());
+ ASSERT(!m_cacheBeingUpdated);
+ postListenerTask(&DOMApplicationCache::callCheckingListener, frame->loader()->documentLoader());
+ postListenerTask(&DOMApplicationCache::callNoUpdateListener, frame->loader()->documentLoader());
+ return;
+ }
+
ASSERT(!m_frame);
m_frame = frame;
@@ -385,14 +402,29 @@ void ApplicationCacheGroup::update(Frame* frame, ApplicationCacheUpdateOption up
ASSERT(m_completionType == None);
// FIXME: Handle defer loading
-
- ResourceRequest request(m_manifestURL);
+ m_manifestHandle = createResourceHandle(m_manifestURL, m_newestCache ? m_newestCache->manifestResource() : 0);
+}
+
+PassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const KURL& url, ApplicationCacheResource* newestCachedResource)
+{
+ ResourceRequest request(url);
m_frame->loader()->applyUserAgent(request);
- // FIXME: Should ask to revalidate from origin.
+ request.setHTTPHeaderField("Cache-Control", "max-age=0");
+
+ if (newestCachedResource) {
+ const String& lastModified = newestCachedResource->response().httpHeaderField("Last-Modified");
+ const String& eTag = newestCachedResource->response().httpHeaderField("ETag");
+ if (!lastModified.isEmpty() || !eTag.isEmpty()) {
+ if (!lastModified.isEmpty())
+ request.setHTTPHeaderField("If-Modified-Since", lastModified);
+ if (!eTag.isEmpty())
+ request.setHTTPHeaderField("If-None-Match", eTag);
+ }
+ }
- m_manifestHandle = ResourceHandle::create(request, this, m_frame, false, true, false);
+ return ResourceHandle::create(request, this, m_frame, false, true, false);
}
-
+
void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const ResourceResponse& response)
{
if (handle == m_manifestHandle) {
@@ -409,11 +441,24 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
unsigned type = m_pendingEntries.get(url);
- // If this is an initial cache attempt, we should not get implicit resources delivered here.
+ // If this is an initial cache attempt, we should not get master resources delivered here.
if (!m_newestCache)
- ASSERT(!(type & ApplicationCacheResource::Implicit));
+ ASSERT(!(type & ApplicationCacheResource::Master));
+
+ if (m_newestCache && response.httpStatusCode() == 304) { // Not modified.
+ ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->request().url());
+ if (newestCachedResource) {
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data()));
+ m_currentHandle->cancel();
+ m_currentHandle = 0;
+ // Load the next resource, if any.
+ startLoadingEntry();
+ return;
+ }
+ // The server could return 304 for an unconditional request - in this case, we handle the response as a normal error.
+ }
- if (response.httpStatusCode() / 100 != 2 || response.url() != m_currentHandle->request().url()) {
+ if (response.httpStatusCode() / 100 != 2 || response.url() != m_currentHandle->request().url()) {
if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) {
// Note that cacheUpdateFailed() can cause the cache group to be deleted.
cacheUpdateFailed();
@@ -428,12 +473,12 @@ void ApplicationCacheGroup::didReceiveResponse(ResourceHandle* handle, const Res
// Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act
// as if that was the fetched resource, ignoring the resource obtained from the network.
ASSERT(m_newestCache);
- ApplicationCacheResource* resource = m_newestCache->resourceForURL(handle->request().url());
- ASSERT(resource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(handle->request().url(), resource->response(), resource->type(), resource->data()));
- // Load the next resource, if any.
+ ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(handle->request().url());
+ ASSERT(newestCachedResource);
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data()));
m_currentHandle->cancel();
m_currentHandle = 0;
+ // Load the next resource, if any.
startLoadingEntry();
}
return;
@@ -484,10 +529,11 @@ void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&
}
unsigned type = m_currentResource ? m_currentResource->type() : m_pendingEntries.get(handle->request().url());
+ const KURL& url = handle->request().url();
- ASSERT(!m_currentResource || !m_pendingEntries.contains(handle->request().url()));
+ ASSERT(!m_currentResource || !m_pendingEntries.contains(url));
m_currentResource = 0;
- m_pendingEntries.remove(handle->request().url());
+ m_pendingEntries.remove(url);
if ((type & ApplicationCacheResource::Explicit) || (type & ApplicationCacheResource::Fallback)) {
// Note that cacheUpdateFailed() can cause the cache group to be deleted.
@@ -496,9 +542,9 @@ void ApplicationCacheGroup::didFail(ResourceHandle* handle, const ResourceError&
// Copy the resource and its metadata from the newest application cache in cache group whose completeness flag is complete, and act
// as if that was the fetched resource, ignoring the resource obtained from the network.
ASSERT(m_newestCache);
- ApplicationCacheResource* resource = m_newestCache->resourceForURL(handle->request().url());
- ASSERT(resource);
- m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(handle->request().url(), resource->response(), resource->type(), resource->data()));
+ ApplicationCacheResource* newestCachedResource = m_newestCache->resourceForURL(url);
+ ASSERT(newestCachedResource);
+ m_cacheBeingUpdated->addResource(ApplicationCacheResource::create(url, newestCachedResource->response(), type, newestCachedResource->data()));
// Load the next resource, if any.
startLoadingEntry();
}
@@ -514,6 +560,9 @@ void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& r
return;
}
+ if (response.httpStatusCode() == 304)
+ return;
+
if (response.httpStatusCode() / 100 != 2 || response.url() != m_manifestHandle->request().url() || !equalIgnoringCase(response.mimeType(), "text/cache-manifest")) {
cacheUpdateFailed();
return;
@@ -525,28 +574,29 @@ void ApplicationCacheGroup::didReceiveManifestResponse(const ResourceResponse& r
void ApplicationCacheGroup::didReceiveManifestData(const char* data, int length)
{
- ASSERT(m_manifestResource);
- m_manifestResource->data()->append(data, length);
+ if (m_manifestResource)
+ m_manifestResource->data()->append(data, length);
}
void ApplicationCacheGroup::didFinishLoadingManifest()
{
- if (!m_manifestResource) {
+ bool isUpgradeAttempt = m_newestCache;
+
+ if (!isUpgradeAttempt && !m_manifestResource) {
+ // The server returned 304 Not Modified even though we didn't send a conditional request.
cacheUpdateFailed();
return;
}
- bool isUpgradeAttempt = m_newestCache;
-
m_manifestHandle = 0;
- // Check if the manifest is byte-for-byte identical.
+ // Check if the manifest was not modified.
if (isUpgradeAttempt) {
ApplicationCacheResource* newestManifest = m_newestCache->manifestResource();
ASSERT(newestManifest);
- if (newestManifest->data()->size() == m_manifestResource->data()->size() &&
- !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size())) {
+ if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified.
+ newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size())) {
m_completionType = NoUpdate;
m_manifestResource = 0;
@@ -581,7 +631,7 @@ void ApplicationCacheGroup::didFinishLoadingManifest()
ApplicationCache::ResourceMap::const_iterator end = m_newestCache->end();
for (ApplicationCache::ResourceMap::const_iterator it = m_newestCache->begin(); it != end; ++it) {
unsigned type = it->second->type();
- if (type & (ApplicationCacheResource::Implicit | ApplicationCacheResource::Dynamic))
+ if (type & (ApplicationCacheResource::Master | ApplicationCacheResource::Dynamic))
addEntry(it->first, type);
}
}
@@ -657,7 +707,11 @@ void ApplicationCacheGroup::checkIfLoadIsComplete()
case NoUpdate:
ASSERT(isUpgradeAttempt);
ASSERT(!m_cacheBeingUpdated);
- ASSERT(m_storageID);
+
+ // The storage could have been manually emptied by the user.
+ if (!m_storageID)
+ cacheStorage().storeNewestCache(this);
+
postListenerTask(&DOMApplicationCache::callNoUpdateListener, m_associatedDocumentLoaders);
break;
case Failure:
@@ -707,15 +761,9 @@ void ApplicationCacheGroup::startLoadingEntry()
postListenerTask(&DOMApplicationCache::callProgressListener, m_associatedDocumentLoaders);
- // FIXME: If this is an upgrade attempt, the newest cache should be used as an HTTP cache.
-
ASSERT(!m_currentHandle);
- ResourceRequest request(it->first);
- m_frame->loader()->applyUserAgent(request);
- // FIXME: Should ask to revalidate from origin.
-
- m_currentHandle = ResourceHandle::create(request, this, m_frame, false, true, false);
+ m_currentHandle = createResourceHandle(KURL(it->first), m_newestCache ? m_newestCache->resourceForURL(it->first) : 0);
}
void ApplicationCacheGroup::deliverDelayedMainResources()
@@ -743,10 +791,10 @@ void ApplicationCacheGroup::addEntry(const String& url, unsigned type)
{
ASSERT(m_cacheBeingUpdated);
- // Don't add the URL if we already have an implicit resource in the cache
+ // Don't add the URL if we already have an master resource in the cache
// (i.e., the main resource finished loading before the manifest).
if (ApplicationCacheResource* resource = m_cacheBeingUpdated->resourceForURL(url)) {
- ASSERT(resource->type() & ApplicationCacheResource::Implicit);
+ ASSERT(resource->type() & ApplicationCacheResource::Master);
ASSERT(!m_frame->loader()->documentLoader()->isLoadingMainResource());
resource->addType(type);
diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.h b/WebCore/loader/appcache/ApplicationCacheGroup.h
index e4b2d3e..aebf0ab 100644
--- a/WebCore/loader/appcache/ApplicationCacheGroup.h
+++ b/WebCore/loader/appcache/ApplicationCacheGroup.h
@@ -92,9 +92,11 @@ public:
private:
typedef void (DOMApplicationCache::*ListenerFunction)();
- void postListenerTask(ListenerFunction, const HashSet<DocumentLoader*>&);
- void postListenerTask(ListenerFunction, const Vector<RefPtr<DocumentLoader> >& loaders);
- void postListenerTask(ListenerFunction, DocumentLoader*);
+ static void postListenerTask(ListenerFunction, const HashSet<DocumentLoader*>&);
+ static void postListenerTask(ListenerFunction, const Vector<RefPtr<DocumentLoader> >& loaders);
+ static void postListenerTask(ListenerFunction, DocumentLoader*);
+
+ PassRefPtr<ResourceHandle> createResourceHandle(const KURL&, ApplicationCacheResource* newestCachedResource);
virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
diff --git a/WebCore/loader/appcache/ApplicationCacheResource.cpp b/WebCore/loader/appcache/ApplicationCacheResource.cpp
index d78cf7f..7c1241b 100644
--- a/WebCore/loader/appcache/ApplicationCacheResource.cpp
+++ b/WebCore/loader/appcache/ApplicationCacheResource.cpp
@@ -47,8 +47,8 @@ void ApplicationCacheResource::addType(unsigned type)
#ifndef NDEBUG
void ApplicationCacheResource::dumpType(unsigned type)
{
- if (type & Implicit)
- printf("implicit ");
+ if (type & Master)
+ printf("master ");
if (type & Manifest)
printf("manifest ");
if (type & Explicit)
diff --git a/WebCore/loader/appcache/ApplicationCacheResource.h b/WebCore/loader/appcache/ApplicationCacheResource.h
index 96f5a0e..28d8280 100644
--- a/WebCore/loader/appcache/ApplicationCacheResource.h
+++ b/WebCore/loader/appcache/ApplicationCacheResource.h
@@ -35,7 +35,7 @@ namespace WebCore {
class ApplicationCacheResource : public SubstituteResource {
public:
enum Type {
- Implicit = 1 << 0,
+ Master = 1 << 0,
Manifest = 1 << 1,
Explicit = 1 << 2,
Foreign = 1 << 3,
diff --git a/WebCore/loader/appcache/DOMApplicationCache.cpp b/WebCore/loader/appcache/DOMApplicationCache.cpp
index 5bc4420..90d2930 100644
--- a/WebCore/loader/appcache/DOMApplicationCache.cpp
+++ b/WebCore/loader/appcache/DOMApplicationCache.cpp
@@ -132,7 +132,7 @@ PassRefPtr<DOMStringList> DOMApplicationCache::items()
Vector<String> result;
if (ApplicationCache* cache = associatedCache()) {
unsigned numEntries = cache->numDynamicEntries();
- result.reserveCapacity(numEntries);
+ result.reserveInitialCapacity(numEntries);
for (unsigned i = 0; i < numEntries; ++i)
result.append(cache->dynamicEntry(i));
}
diff --git a/WebCore/loader/appcache/ManifestParser.cpp b/WebCore/loader/appcache/ManifestParser.cpp
index a83303a..4169313 100644
--- a/WebCore/loader/appcache/ManifestParser.cpp
+++ b/WebCore/loader/appcache/ManifestParser.cpp
@@ -30,7 +30,7 @@
#include "CharacterNames.h"
#include "KURL.h"
-#include "TextEncoding.h"
+#include "TextResourceDecoder.h"
using namespace std;
@@ -45,9 +45,12 @@ bool parseManifest(const KURL& manifestURL, const char* data, int length, Manife
ASSERT(manifest.fallbackURLs.isEmpty());
Mode mode = Explicit;
- String s = UTF8Encoding().decode(data, length);
+
+ RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/cache-manifest", "UTF-8");
+ String s = decoder->decode(data, length);
+ s += decoder->flush();
- // Look for the magic signature: "^\xFEFF?CACHE MANIFEST[ \t]?" (the BOM is removed by decode()).
+ // Look for the magic signature: "^\xFEFF?CACHE MANIFEST[ \t]?" (the BOM is removed by TextResourceDecoder).
// Example: "CACHE MANIFEST #comment" is a valid signature.
// Example: "CACHE MANIFEST;V2" is not.
if (!s.startsWith("CACHE MANIFEST"))
diff --git a/WebCore/loader/archive/cf/LegacyWebArchive.cpp b/WebCore/loader/archive/cf/LegacyWebArchive.cpp
index b00d93c..d1269cc 100644
--- a/WebCore/loader/archive/cf/LegacyWebArchive.cpp
+++ b/WebCore/loader/archive/cf/LegacyWebArchive.cpp
@@ -39,6 +39,7 @@
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
#include "IconDatabase.h"
+#include "Image.h"
#include "KURLHash.h"
#include "Logging.h"
#include "markup.h"
@@ -62,15 +63,16 @@ static const CFStringRef LegacyWebArchiveResourceTextEncodingNameKey = CFSTR("We
static const CFStringRef LegacyWebArchiveResourceResponseKey = CFSTR("WebResourceResponse");
static const CFStringRef LegacyWebArchiveResourceResponseVersionKey = CFSTR("WebResourceResponseVersion");
-static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(ArchiveResource* resource, bool mainResource)
+RetainPtr<CFDictionaryRef> LegacyWebArchive::createPropertyListRepresentation(ArchiveResource* resource, MainResourceStatus isMainResource)
{
if (!resource) {
- // The property list representation of a null/empty WebResource has the following 3 objects stored as nil
+ // The property list representation of a null/empty WebResource has the following 3 objects stored as nil.
+ // FIXME: 0 is not serializable. Presumably we need to use kCFNull here instead for compatibility.
+ // FIXME: But why do we need to support a resource of 0? Who relies on that?
RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, 0));
CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, 0);
CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, 0);
CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, 0);
-
return propertyList;
}
@@ -96,7 +98,7 @@ static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(A
// FrameName should be left out if empty for subresources, but always included for main resources
const String& frameName(resource->frameName());
- if (!frameName.isEmpty() || mainResource) {
+ if (!frameName.isEmpty() || isMainResource) {
RetainPtr<CFStringRef> cfFrameName(AdoptCF, frameName.createCFString());
CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceFrameNameKey, cfFrameName.get());
}
@@ -115,8 +117,8 @@ static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(A
}
// Don't include the resource response for the main resource
- if (!mainResource) {
- RetainPtr<CFDataRef> resourceResponseData = propertyListDataFromResourceResponse(resource->response());
+ if (!isMainResource) {
+ RetainPtr<CFDataRef> resourceResponseData = createPropertyListRepresentation(resource->response());
if (resourceResponseData)
CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceResponseKey, resourceResponseData.get());
}
@@ -124,19 +126,20 @@ static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(A
return propertyList;
}
-static RetainPtr<CFDictionaryRef> createPropertyListRep(Archive* archive)
+RetainPtr<CFDictionaryRef> LegacyWebArchive::createPropertyListRepresentation(Archive* archive)
{
RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, &kCFTypeDictionaryValueCallBacks));
- RetainPtr<CFDictionaryRef> mainResourceDict = createPropertyListRepresentationFromResource(archive->mainResource(), true);
+ RetainPtr<CFDictionaryRef> mainResourceDict = createPropertyListRepresentation(archive->mainResource(), MainResource);
+ ASSERT(mainResourceDict);
if (!mainResourceDict)
return 0;
CFDictionarySetValue(propertyList.get(), LegacyWebArchiveMainResourceKey, mainResourceDict.get());
-
+
RetainPtr<CFMutableArrayRef> subresourcesArray(AdoptCF, CFArrayCreateMutable(0, archive->subresources().size(), &kCFTypeArrayCallBacks));
const Vector<RefPtr<ArchiveResource> >& subresources(archive->subresources());
for (unsigned i = 0; i < subresources.size(); ++i) {
- RetainPtr<CFDictionaryRef> subresource = createPropertyListRepresentationFromResource(subresources[i].get(), false);
+ RetainPtr<CFDictionaryRef> subresource = createPropertyListRepresentation(subresources[i].get(), Subresource);
if (subresource)
CFArrayAppendValue(subresourcesArray.get(), subresource.get());
else
@@ -148,7 +151,7 @@ static RetainPtr<CFDictionaryRef> createPropertyListRep(Archive* archive)
RetainPtr<CFMutableArrayRef> subframesArray(AdoptCF, CFArrayCreateMutable(0, archive->subframeArchives().size(), &kCFTypeArrayCallBacks));
const Vector<RefPtr<Archive> >& subframeArchives(archive->subframeArchives());
for (unsigned i = 0; i < subframeArchives.size(); ++i) {
- RetainPtr<CFDictionaryRef> subframeArchive = createPropertyListRep(subframeArchives[i].get());
+ RetainPtr<CFDictionaryRef> subframeArchive = createPropertyListRepresentation(subframeArchives[i].get());
if (subframeArchive)
CFArrayAppendValue(subframesArray.get(), subframeArchive.get());
else
@@ -160,22 +163,23 @@ static RetainPtr<CFDictionaryRef> createPropertyListRep(Archive* archive)
return propertyList;
}
-static ResourceResponse createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType)
+ResourceResponse LegacyWebArchive::createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType)
{
ASSERT(data);
if (!data)
return ResourceResponse();
- // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" webarchive that we can parse well in a cross platform manner
- // If it doesn't exist, we will assume this is an "old" Cocoa-based WebArchive, and parse the ResourceResponse as such
+ // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" web archive that we
+ // can parse well in a cross platform manner If it doesn't exist, we will assume this is an "old" web archive with,
+ // NSURLResponse objects in it and parse the ResourceResponse as such.
if (!responseDataType)
return createResourceResponseFromMacArchivedData(data);
- // FIXME: Parse the "new" format that the above comment references here
+ // FIXME: Parse the "new" format that the above comment references here. This format doesn't exist yet.
return ResourceResponse();
}
-static PassRefPtr<ArchiveResource> createResource(CFDictionaryRef dictionary)
+PassRefPtr<ArchiveResource> LegacyWebArchive::createResource(CFDictionaryRef dictionary)
{
ASSERT(dictionary);
if (!dictionary)
@@ -237,17 +241,6 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create()
return adoptRef(new LegacyWebArchive);
}
-PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(SharedBuffer* data)
-{
- LOG(Archives, "LegacyWebArchive - Creating from raw data");
-
- RefPtr<LegacyWebArchive> archive = create();
- if (!archive->init(data))
- return 0;
-
- return archive.release();
-}
-
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives)
{
ASSERT(mainResource);
@@ -266,19 +259,19 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(PassRefPtr<ArchiveResource
return archive.release();
}
-LegacyWebArchive::LegacyWebArchive()
-{
-}
-
-bool LegacyWebArchive::init(SharedBuffer* data)
+PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(SharedBuffer* data)
{
+ LOG(Archives, "LegacyWebArchive - Creating from raw data");
+
+ RefPtr<LegacyWebArchive> archive = create();
+
ASSERT(data);
if (!data)
- return false;
+ return 0;
RetainPtr<CFDataRef> cfData(AdoptCF, data->createCFData());
if (!cfData)
- return false;
+ return 0;
CFStringRef errorString = 0;
@@ -290,15 +283,18 @@ bool LegacyWebArchive::init(SharedBuffer* data)
#endif
if (errorString)
CFRelease(errorString);
- return false;
+ return 0;
}
if (CFGetTypeID(plist.get()) != CFDictionaryGetTypeID()) {
LOG(Archives, "LegacyWebArchive - Archive property list is not the expected CFDictionary, aborting invalid WebArchive");
- return false;
+ return 0;
}
- return extract(plist.get());
+ if (!archive->extract(plist.get()))
+ return 0;
+
+ return archive.release();
}
bool LegacyWebArchive::extract(CFDictionaryRef dictionary)
@@ -371,7 +367,8 @@ bool LegacyWebArchive::extract(CFDictionaryRef dictionary)
RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation()
{
- RetainPtr<CFDictionaryRef> propertyList = createPropertyListRep(this);
+ RetainPtr<CFDictionaryRef> propertyList = createPropertyListRepresentation(this);
+ ASSERT(propertyList);
if (!propertyList) {
LOG(Archives, "LegacyWebArchive - Failed to create property list for archive, returning no data");
return 0;
@@ -383,6 +380,7 @@ RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation()
CFPropertyListWriteToStream(propertyList.get(), stream.get(), kCFPropertyListBinaryFormat_v1_0, 0);
RetainPtr<CFDataRef> plistData(AdoptCF, static_cast<CFDataRef>(CFWriteStreamCopyProperty(stream.get(), kCFStreamPropertyDataWritten)));
+ ASSERT(plistData);
CFWriteStreamClose(stream.get());
@@ -395,20 +393,21 @@ RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation()
}
#if !PLATFORM(MAC)
-// FIXME: Is it possible to parse in a Cocoa-style resource response manually,
-// without NSKeyed(Un)Archiver, manipulating plists directly?
-// If so, the code that does it will go here.
-// In the meantime, Mac will continue to NSKeyed(Un)Archive the response as it always has
-ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseData)
+
+ResourceResponse LegacyWebArchive::createResourceResponseFromMacArchivedData(CFDataRef responseData)
{
+ // FIXME: If is is possible to parse in a serialized NSURLResponse manually, without using
+ // NSKeyedUnarchiver, manipulating plists directly, then we want to do that here.
+ // Until then, this can be done on Mac only.
return ResourceResponse();
}
-RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse& response)
+RetainPtr<CFDataRef> LegacyWebArchive::createPropertyListRepresentation(const ResourceResponse& response)
{
- // FIXME: Write out the "new" format described in ::createResourceResponseFromPropertyListData() up above
+ // FIXME: Write out the "new" format described in createResourceResponseFromPropertyListData once we invent it.
return 0;
}
+
#endif
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(Node* node)
@@ -452,7 +451,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(Frame* frame)
Vector<PassRefPtr<ArchiveResource> > subresources;
documentLoader->getSubresources(subresources);
- return LegacyWebArchive::create(documentLoader->mainResource(), subresources, subframeArchives);
+ return create(documentLoader->mainResource(), subresources, subframeArchives);
}
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(Range* range)
@@ -480,7 +479,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(Range* range)
return create(markupString, frame, nodeList);
}
-PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString, Frame* frame, Vector<Node*>& nodes)
+PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString, Frame* frame, const Vector<Node*>& nodes)
{
ASSERT(frame);
@@ -497,19 +496,14 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString
Vector<PassRefPtr<LegacyWebArchive> > subframeArchives;
Vector<PassRefPtr<ArchiveResource> > subresources;
HashSet<KURL> uniqueSubresources;
-
- Vector<Node*>::iterator it = nodes.begin();
- Vector<Node*>::iterator end = nodes.end();
-
- for (; it != end; ++it) {
+
+ size_t nodesSize = nodes.size();
+ for (size_t i = 0; i < nodesSize; ++i) {
+ Node* node = nodes[i];
Frame* childFrame;
- if (((*it)->hasTagName(HTMLNames::frameTag) || (*it)->hasTagName(HTMLNames::iframeTag) || (*it)->hasTagName(HTMLNames::objectTag)) &&
- (childFrame = static_cast<HTMLFrameOwnerElement*>(*it)->contentFrame())) {
- RefPtr<LegacyWebArchive> subframeArchive;
- if (Document* document = childFrame->document())
- subframeArchive = LegacyWebArchive::create(document);
- else
- subframeArchive = create(childFrame);
+ if ((node->hasTagName(HTMLNames::frameTag) || node->hasTagName(HTMLNames::iframeTag) || node->hasTagName(HTMLNames::objectTag)) &&
+ (childFrame = static_cast<HTMLFrameOwnerElement*>(node)->contentFrame())) {
+ RefPtr<LegacyWebArchive> subframeArchive = create(childFrame->document());
if (subframeArchive)
subframeArchives.append(subframeArchive);
@@ -517,7 +511,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString
LOG_ERROR("Unabled to archive subframe %s", childFrame->tree()->name().string().utf8().data());
} else {
ListHashSet<KURL> subresourceURLs;
- (*it)->getSubresourceURLs(subresourceURLs);
+ node->getSubresourceURLs(subresourceURLs);
DocumentLoader* documentLoader = frame->loader()->documentLoader();
ListHashSet<KURL>::iterator iterEnd = subresourceURLs.end();
@@ -549,13 +543,13 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const String& markupString
}
}
- // Add favicon if one exists for this page
- if (iconDatabase() && iconDatabase()->isEnabled()) {
+ // Add favicon if one exists for this page, if we are archiving the entire page.
+ if (nodesSize && nodes[0]->isDocumentNode() && iconDatabase() && iconDatabase()->isEnabled()) {
const String& iconURL = iconDatabase()->iconURLForPageURL(responseURL);
if (!iconURL.isEmpty() && iconDatabase()->iconDataKnownForIconURL(iconURL)) {
if (Image* iconImage = iconDatabase()->iconForPageURL(responseURL, IntSize(16, 16))) {
- RefPtr<ArchiveResource> resource = ArchiveResource::create(iconImage->data(), KURL(iconURL), "image/x-icon", "", "");
- subresources.append(resource.release());
+ if (RefPtr<ArchiveResource> resource = ArchiveResource::create(iconImage->data(), KURL(iconURL), "image/x-icon", "", ""))
+ subresources.append(resource.release());
}
}
}
@@ -568,13 +562,13 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::createFromSelection(Frame* frame)
if (!frame)
return 0;
- RefPtr<Range> selectionRange = frame->selection()->toRange();
+ RefPtr<Range> selectionRange = frame->selection()->toNormalizedRange();
Vector<Node*> nodeList;
String markupString = frame->documentTypeString() + createMarkup(selectionRange.get(), &nodeList, AnnotateForInterchange);
RefPtr<LegacyWebArchive> archive = create(markupString, frame, nodeList);
- if (!frame->isFrameSet())
+ if (!frame->document() || !frame->document()->isFrameSet())
return archive.release();
// Wrap the frameset document in an iframe so it can be pasted into
@@ -588,7 +582,7 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::createFromSelection(Frame* frame)
Vector<PassRefPtr<LegacyWebArchive> > subframeArchives;
subframeArchives.append(archive);
- archive = LegacyWebArchive::create(iframeResource.release(), subresources, subframeArchives);
+ archive = create(iframeResource.release(), subresources, subframeArchives);
return archive.release();
}
diff --git a/WebCore/loader/archive/cf/LegacyWebArchive.h b/WebCore/loader/archive/cf/LegacyWebArchive.h
index 70faba5..8c8f2e4 100644
--- a/WebCore/loader/archive/cf/LegacyWebArchive.h
+++ b/WebCore/loader/archive/cf/LegacyWebArchive.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,8 +31,6 @@
#include "Archive.h"
-#include <wtf/PassRefPtr.h>
-
namespace WebCore {
class Frame;
@@ -40,28 +38,33 @@ class Node;
class Range;
class LegacyWebArchive : public Archive {
-public:
+public:
static PassRefPtr<LegacyWebArchive> create();
static PassRefPtr<LegacyWebArchive> create(SharedBuffer*);
static PassRefPtr<LegacyWebArchive> create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives);
static PassRefPtr<LegacyWebArchive> create(Node*);
static PassRefPtr<LegacyWebArchive> create(Frame*);
- static PassRefPtr<LegacyWebArchive> createFromSelection(Frame* frame);
+ static PassRefPtr<LegacyWebArchive> createFromSelection(Frame*);
static PassRefPtr<LegacyWebArchive> create(Range*);
- static PassRefPtr<LegacyWebArchive> create(const String& markupString, Frame*, Vector<Node*>& nodes);
RetainPtr<CFDataRef> rawDataRepresentation();
private:
- LegacyWebArchive();
- bool init(SharedBuffer*);
+ LegacyWebArchive() { }
+
+ enum MainResourceStatus { Subresource, MainResource };
+
+ static PassRefPtr<LegacyWebArchive> create(const String& markupString, Frame*, const Vector<Node*>& nodes);
+ static PassRefPtr<ArchiveResource> createResource(CFDictionaryRef);
+ static ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef);
+ static ResourceResponse createResourceResponseFromPropertyListData(CFDataRef, CFStringRef responseDataType);
+ static RetainPtr<CFDataRef> createPropertyListRepresentation(const ResourceResponse&);
+ static RetainPtr<CFDictionaryRef> createPropertyListRepresentation(Archive*);
+ static RetainPtr<CFDictionaryRef> createPropertyListRepresentation(ArchiveResource*, MainResourceStatus);
+
bool extract(CFDictionaryRef);
-
};
-ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef);
-RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse&);
-
}
#endif // Archive
diff --git a/WebCore/loader/archive/cf/LegacyWebArchiveMac.mm b/WebCore/loader/archive/cf/LegacyWebArchiveMac.mm
index b853a15..c474bba 100644
--- a/WebCore/loader/archive/cf/LegacyWebArchiveMac.mm
+++ b/WebCore/loader/archive/cf/LegacyWebArchiveMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,9 +33,9 @@ namespace WebCore {
static const NSString *LegacyWebArchiveResourceResponseKey = @"WebResourceResponse";
-// FIXME: Is it possible to parse in a Cocoa-style resource response manually,
-// without NSKeyed(Un)Archiver, manipulating plists directly?
-ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseData)
+// FIXME: If is is possible to parse in a serialized NSURLResponse manually, without using
+// NSKeyedUnarchiver, manipulating plists directly, we would prefer to do that instead.
+ResourceResponse LegacyWebArchive::createResourceResponseFromMacArchivedData(CFDataRef responseData)
{
ASSERT(responseData);
if (!responseData)
@@ -56,19 +56,21 @@ ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseDat
return ResourceResponse(response);
}
-RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse& response)
+RetainPtr<CFDataRef> LegacyWebArchive::createPropertyListRepresentation(const ResourceResponse& response)
{
NSURLResponse *nsResponse = response.nsURLResponse();
+ ASSERT(nsResponse);
if (!nsResponse)
return 0;
-
- NSMutableData *responseData = (NSMutableData *)CFDataCreateMutable(0, 0);
- NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];
+
+ CFMutableDataRef responseData = CFDataCreateMutable(0, 0);
+
+ NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:(NSMutableData *)responseData];
[archiver encodeObject:nsResponse forKey:LegacyWebArchiveResourceResponseKey];
[archiver finishEncoding];
[archiver release];
- return RetainPtr<CFDataRef>(AdoptCF, (CFDataRef)responseData);
+ return RetainPtr<CFDataRef>(AdoptCF, responseData);
}
}
diff --git a/WebCore/loader/cf/ResourceLoaderCFNet.cpp b/WebCore/loader/cf/ResourceLoaderCFNet.cpp
new file mode 100644
index 0000000..83642c6
--- /dev/null
+++ b/WebCore/loader/cf/ResourceLoaderCFNet.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ResourceLoader.h"
+
+#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+
+namespace WebCore {
+
+bool ResourceLoader::shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef cachedResponse)
+{
+ if (!m_sendResourceLoadCallbacks)
+ return 0;
+
+ CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse);
+ CFDataRef data = CFCachedURLResponseGetReceiverData(cachedResponse);
+ return frameLoader()->client()->shouldCacheResponse(documentLoader(), identifier(), response, CFDataGetBytePtr(data), CFDataGetLength(data));
+}
+
+} // namespace WebCore
diff --git a/WebCore/loader/icon/IconDatabase.cpp b/WebCore/loader/icon/IconDatabase.cpp
index 5705f7a..0521381 100644
--- a/WebCore/loader/icon/IconDatabase.cpp
+++ b/WebCore/loader/icon/IconDatabase.cpp
@@ -149,7 +149,7 @@ bool IconDatabase::open(const String& databasePath)
// Lock here as well as first thing in the thread so the thread doesn't actually commence until the createThread() call
// completes and m_syncThreadRunning is properly set
m_syncLock.lock();
- m_syncThread = createThread(IconDatabase::iconDatabaseSyncThreadStart, this, "WebCore::IconDatabase");
+ m_syncThread = createThread(IconDatabase::iconDatabaseSyncThreadStart, this, "WebCore: IconDatabase");
m_syncLock.unlock();
if (!m_syncThread)
return false;
diff --git a/WebCore/loader/icon/IconDatabaseNone.cpp b/WebCore/loader/icon/IconDatabaseNone.cpp
index c76a2c4..a7fb88d 100644
--- a/WebCore/loader/icon/IconDatabaseNone.cpp
+++ b/WebCore/loader/icon/IconDatabaseNone.cpp
@@ -25,7 +25,10 @@
#include "config.h"
#include "IconDatabase.h"
+
+#include "PlatformString.h"
#include "SharedBuffer.h"
+#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -47,8 +50,8 @@ const int updateTimerDelay = 5;
String IconDatabase::defaultDatabaseFilename()
{
- static String defaultDatabaseFilename = "Icons.db";
- return defaultDatabaseFilename;
+ DEFINE_STATIC_LOCAL(String, defaultDatabaseFilename, ("Icons.db"));
+ return defaultDatabaseFilename.copy();
}
IconDatabase* iconDatabase()
@@ -62,7 +65,7 @@ IconDatabase::IconDatabase()
{
}
-bool IconDatabase::open(const String& databasePath)
+bool IconDatabase::open(const String& /*databasePath*/)
{
return false;
}
@@ -85,7 +88,7 @@ void IconDatabase::removeAllIcons()
{
}
-void IconDatabase::setPrivateBrowsingEnabled(bool flag)
+void IconDatabase::setPrivateBrowsingEnabled(bool /*flag*/)
{
}
@@ -99,7 +102,7 @@ void IconDatabase::readIconForPageURLFromDisk(const String&)
}
-Image* IconDatabase::iconForPageURL(const String& pageURL, const IntSize& size)
+Image* IconDatabase::iconForPageURL(const String& /*pageURL*/, const IntSize& size)
{
return defaultIcon(size);
}
@@ -115,33 +118,33 @@ bool IconDatabase::iconDataKnownForIconURL(const String&)
return false;
}
-String IconDatabase::iconURLForPageURL(const String& pageURL)
+String IconDatabase::iconURLForPageURL(const String& /*pageURL*/)
{
return String();
}
-Image* IconDatabase::defaultIcon(const IntSize& size)
+Image* IconDatabase::defaultIcon(const IntSize& /*size*/)
{
return 0;
}
-void IconDatabase::retainIconForPageURL(const String& pageURL)
+void IconDatabase::retainIconForPageURL(const String& /*pageURL*/)
{
}
-void IconDatabase::releaseIconForPageURL(const String& pageURL)
+void IconDatabase::releaseIconForPageURL(const String& /*pageURL*/)
{
}
-void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> data, const String& iconURL)
+void IconDatabase::setIconDataForIconURL(PassRefPtr<SharedBuffer> /*data*/, const String& /*iconURL*/)
{
}
-void IconDatabase::setIconURLForPageURL(const String& iconURL, const String& pageURL)
+void IconDatabase::setIconURLForPageURL(const String& /*iconURL*/, const String& /*pageURL*/)
{
}
-void IconDatabase::setEnabled(bool enabled)
+void IconDatabase::setEnabled(bool /*enabled*/)
{
}
@@ -167,6 +170,26 @@ void IconDatabase::allowDatabaseCleanup()
{
}
+size_t IconDatabase::pageURLMappingCount()
+{
+ return 0;
+}
+
+size_t IconDatabase::retainedPageURLCount()
+{
+ return 0;
+}
+
+size_t IconDatabase::iconRecordCount()
+{
+ return 0;
+}
+
+size_t IconDatabase::iconRecordCountWithData()
+{
+ return 0;
+}
+
void IconDatabase::setClient(IconDatabaseClient*)
{
}
diff --git a/WebCore/loader/icon/IconFetcher.cpp b/WebCore/loader/icon/IconFetcher.cpp
index 69eeb7c..d1aa2f3 100644
--- a/WebCore/loader/icon/IconFetcher.cpp
+++ b/WebCore/loader/icon/IconFetcher.cpp
@@ -101,8 +101,6 @@ static void parseIconLink(HTMLLinkElement* link, Vector<IconLinkEntry>& entries)
PassRefPtr<IconFetcher> IconFetcher::create(Frame* frame, IconFetcherClient* client)
{
Document* document = frame->document();
- if (!document)
- return 0;
HTMLHeadElement* head = document->head();
if (!head)
diff --git a/WebCore/loader/icon/IconLoader.cpp b/WebCore/loader/icon/IconLoader.cpp
index b7bf115..5dd000e 100644
--- a/WebCore/loader/icon/IconLoader.cpp
+++ b/WebCore/loader/icon/IconLoader.cpp
@@ -35,6 +35,7 @@
#include "ResourceHandle.h"
#include "ResourceResponse.h"
#include "ResourceRequest.h"
+#include "SharedBuffer.h"
#include "SubresourceLoader.h"
#include <wtf/UnusedParam.h>
@@ -62,14 +63,6 @@ void IconLoader::startLoading()
if (m_resourceLoader)
return;
- // FIXME: http://bugs.webkit.org/show_bug.cgi?id=10902
- // Once ResourceHandle will load without a DocLoader, we can remove this check.
- // A frame may be documentless - one example is a frame containing only a PDF.
- if (!m_frame->document()) {
- LOG(IconDatabase, "Documentless-frame - icon won't be loaded");
- return;
- }
-
// Set flag so we can detect the case where the load completes before
// SubresourceLoader::create returns.
m_loadIsInProgress = true;
diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp
index 22fb158..b8d1ab7 100644
--- a/WebCore/loader/loader.cpp
+++ b/WebCore/loader/loader.cpp
@@ -159,6 +159,8 @@ void Loader::servePendingRequests(Priority minimumPriority)
void Loader::cancelRequests(DocLoader* docLoader)
{
+ docLoader->clearPendingPreloads();
+
if (m_nonHTTPProtocolHost.hasRequests())
m_nonHTTPProtocolHost.cancelRequests(docLoader);
@@ -172,10 +174,7 @@ void Loader::cancelRequests(DocLoader* docLoader)
scheduleServePendingRequests();
- if (docLoader->loadInProgress())
- ASSERT(docLoader->requestCount() == 1);
- else
- ASSERT(docLoader->requestCount() == 0);
+ ASSERT(docLoader->requestCount() == (docLoader->loadInProgress() ? 1 : 0));
}
Loader::Host::Host(const AtomicString& name, unsigned maxRequestsInFlight)
@@ -291,6 +290,9 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader)
Request* request = i->second;
m_requestsLoading.remove(i);
DocLoader* docLoader = request->docLoader();
+ // Prevent the document from being destroyed before we are done with
+ // the docLoader that it will delete when the document gets deleted.
+ DocPtr<Document> protector(docLoader->doc());
if (!request->isMultipart())
docLoader->decrementRequestCount();
@@ -336,6 +338,9 @@ void Loader::Host::didFail(SubresourceLoader* loader, bool cancelled)
Request* request = i->second;
m_requestsLoading.remove(i);
DocLoader* docLoader = request->docLoader();
+ // Prevent the document from being destroyed before we are done with
+ // the docLoader that it will delete when the document gets deleted.
+ DocPtr<Document> protector(docLoader->doc());
if (!request->isMultipart())
docLoader->decrementRequestCount();
diff --git a/WebCore/loader/mac/ResourceLoaderMac.mm b/WebCore/loader/mac/ResourceLoaderMac.mm
index d6ee923..25fe7bd 100644
--- a/WebCore/loader/mac/ResourceLoaderMac.mm
+++ b/WebCore/loader/mac/ResourceLoaderMac.mm
@@ -37,6 +37,8 @@ namespace WebCore {
NSCachedURLResponse* ResourceLoader::willCacheResponse(ResourceHandle*, NSCachedURLResponse* response)
{
+ if (!m_sendResourceLoadCallbacks)
+ return 0;
return frameLoader()->client()->willCacheResponse(documentLoader(), identifier(), response);
}
diff --git a/WebCore/make-generated-sources.sh b/WebCore/make-generated-sources.sh
index 9ccfff1..88173d5 100755
--- a/WebCore/make-generated-sources.sh
+++ b/WebCore/make-generated-sources.sh
@@ -5,4 +5,4 @@ export WebCore=$PWD
export CREATE_HASH_TABLE="$SRCROOT/../JavaScriptCore/create_hash_table"
mkdir -p DerivedSources/WebCore &&
-make -C DerivedSources/WebCore -f ../../DerivedSources.make
+make -C DerivedSources/WebCore -f ../../DerivedSources.make $@
diff --git a/WebCore/manual-tests/gtk/floatingdiv.html b/WebCore/manual-tests/gtk/floatingdiv.html
new file mode 100644
index 0000000..b7169c7
--- /dev/null
+++ b/WebCore/manual-tests/gtk/floatingdiv.html
@@ -0,0 +1,149 @@
+<html>
+<body>
+1<br />
+2<br />
+3<br />
+4<br />
+5<br />
+6<br />
+7<br />
+8<br />
+9<br />
+10<br />
+11<br />
+12<br />
+13<br />
+14<br />
+15<br />
+16<br />
+17<br />
+18<br />
+19<br />
+20<br />
+21<br />
+22<br />
+23<br />
+24<br />
+25<br />
+26<br />
+27<br />
+28<br />
+29<br />
+30<br />
+31<br />
+32<br />
+33<br />
+34<br />
+35<br />
+36<br />
+37<br />
+38<br />
+39<br />
+40<br />
+41<br />
+42<br />
+43<br />
+44<br />
+45<br />
+46<br />
+47<br />
+48<br />
+49<br />
+50<br />
+51<br />
+52<br />
+53<br />
+54<br />
+55<br />
+56<br />
+57<br />
+58<br />
+59<br />
+60<br />
+61<br />
+62<br />
+63<br />
+64<br />
+65<br />
+66<br />
+67<br />
+68<br />
+69<br />
+70<br />
+71<br />
+72<br />
+73<br />
+74<br />
+75<br />
+76<br />
+77<br />
+78<br />
+79<br />
+80<br />
+<div style="border : solid 2px #ff0000; position: absolute; float: right; background : #000000; color : #ffffff; padding : 4px; width : 200px; height : 100px; overflow : auto; ">
+1<br />
+2<br />
+3<br />
+4<br />
+5<br />
+6<br />
+7<br />
+8<br />
+9<br />
+10<br />
+61<br />
+62<br />
+63<br />
+64<br />
+65<br />
+66<br />
+67<br />
+68<br />
+69<br />
+70<br />
+</div>
+127<br />
+128<br />
+129<br />
+130<br />
+131<br />
+132<br />
+133<br />
+134<br />
+135<br />
+136<br />
+137<br />
+138<br />
+139<br />
+140<br />
+141<br />
+142<br />
+143<br />
+144<br />
+145<br />
+146<br />
+147<br />
+148<br />
+149<br />
+150<br />
+151<br />
+152<br />
+153<br />
+154<br />
+155<br />
+156<br />
+157<br />
+158<br />
+159<br />
+160<br />
+161<br />
+162<br />
+163<br />
+164<br />
+165<br />
+166<br />
+167<br />
+168<br />
+169<br />
+170<br />
+</body>
diff --git a/WebCore/manual-tests/gtk/plugin-resize-scroll.html b/WebCore/manual-tests/gtk/plugin-resize-scroll.html
new file mode 100644
index 0000000..d452b95
--- /dev/null
+++ b/WebCore/manual-tests/gtk/plugin-resize-scroll.html
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <style>
+ html, body {
+ background-color: blue;
+ color: white;
+ }
+ #spacer {
+ width: 100%;
+ height: 1000px;
+ background-color: yellow;
+ }
+ </style>
+ </script>
+ </head>
+ <body>
+ <p>
+ Resize the browser, ensure that the plugin resizes and does not produce a greyish border.
+ Scroll the view, ensure that plugin scrolls out of view.
+ </p>
+
+ <embed id="embed" height="100" style="width: 100%" pbgcolor="green"
+ src="http://www.tizag.com/pics/example.swf" type="application/x-shockwave-flash"/>
+
+ <div id="spacer"><p>content</p></div>
+ </body>
+</html>
+
diff --git a/WebCore/manual-tests/inspector/console-dir.html b/WebCore/manual-tests/inspector/console-dir.html
new file mode 100644
index 0000000..90f389d
--- /dev/null
+++ b/WebCore/manual-tests/inspector/console-dir.html
@@ -0,0 +1,31 @@
+<body>
+<p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=24329">Bug 24329: REGRESSION: console.dirxml() Console API broken</a>.</p>
+<p>To test, open the Inspector's Console and verify that all console messages have the correct output.</p>
+</body>
+<script>
+ console.log("Testing console.dir:");
+ console.dir(undefined);
+ console.dir(123);
+ console.dir(null);
+ console.dir({});
+ console.dir({test: 1, test1:{apple: "orange"}});
+ console.dir("Test");
+ console.dir(document);
+ console.dir(document.body);
+
+ console.log("\nTesting console.dirxml:");
+ console.dirxml(undefined);
+ console.dirxml(123);
+ console.dirxml(null);
+ console.dirxml({});
+ console.dirxml({test: 1, test1:{apple: "orange"}});
+ console.dirxml("Test");
+ console.dirxml(document);
+ console.dirxml(document.body);
+
+ console.log("\nTesting console.log's %o and %O formatters:");
+ console.log("%o %O", document.body, document.body);
+ console.log("%o %O", undefined, undefined);
+ console.log("%o %O", 123, 123);
+ console.log("%o %O", null, null);
+</script>
diff --git a/WebCore/manual-tests/inspector/debugger-step-on-do-while-statements.html b/WebCore/manual-tests/inspector/debugger-step-on-do-while-statements.html
new file mode 100644
index 0000000..190cbf8
--- /dev/null
+++ b/WebCore/manual-tests/inspector/debugger-step-on-do-while-statements.html
@@ -0,0 +1,29 @@
+<script src="resources/loop-statements.js"></script>
+<script>
+function runDoWhile()
+{
+ /* place breakpoint on next line and click continue */ debugger;
+ do {
+ statement();
+ increment();
+ } while (condition());
+}
+
+</script>
+Start a debugging session in the Web Inspector and open this file.
+<br><br>
+Before running the tests please perform the following:
+Make sure the execution is not paused in the debugger.<br>
+Click the button and when the debugger breaks, set a breakpoint on the first line in the loop
+(as indicated by the comment), and click continue.<br>
+The debugger should stop at the beggining of the loop.<br>
+The above actions should be performed before <b>each</b> of the following tests.
+<br><br>
+<input type="button" value="run do-while" onclick="initialize();runDoWhile()"/>
+<br><br>
+TEST 1: Click 'continue'. Execution should continue without stopping on the loop breakpoint again.<br>
+TEST 2: Click 'Step over'. Debugger should step inside the loop to the next statement line.
+'Step over' until the debugger reaches the 'while' line. Click 'Step into' - the debugger should
+enter the 'condition' function.<br>
+TEST 3: 'Step over' to the end of the loop (and 'while' statement) and step over again. Debugger
+should go to the beggining of the loop.<br>
diff --git a/WebCore/manual-tests/inspector/debugger-step-on-for-in-statements.html b/WebCore/manual-tests/inspector/debugger-step-on-for-in-statements.html
new file mode 100644
index 0000000..8d6de78
--- /dev/null
+++ b/WebCore/manual-tests/inspector/debugger-step-on-for-in-statements.html
@@ -0,0 +1,35 @@
+<script>
+var myObj = {test : 1};
+function getObject()
+{
+ return myObj;
+}
+
+function statement() {
+ ;
+}
+
+function runForIn()
+{
+ /* place breakpoint on next line and click continue */ debugger;
+ for (var property in getObject())
+ statement();
+}
+
+</script>
+Start a debugging session in the Web Inspector and open this file.
+<br><br>
+Before running the tests please perform the following:
+Make sure the execution is not paused in the debugger.<br>
+Click the button and when the debugger breaks, set a breakpoint on the first line in the loop
+(as indicated by the comment), and click continue.<br>
+The debugger should stop at the beggining of the loop.<br>
+The above actions should be performed before <b>each</b> of the following tests.
+<br><br>
+<input type="button" value="run for-in" onclick="runForIn()"/>
+<br><br>
+TEST 1: Click 'continue'. Execution should continue without stopping on the loop breakpoint again.<br>
+TEST 2: Click 'Step over'. Debugger should step inside the loop to the next statement line.<br>
+TEST 3: Click 'Step into'. Debugger should step into 'getObject' function.<br>
+TEST 4: 'Step over' to the statement line and then 'Step over' again. Debugger should pause on
+the for-in loop again.<br>
diff --git a/WebCore/manual-tests/inspector/debugger-step-on-for-statements.html b/WebCore/manual-tests/inspector/debugger-step-on-for-statements.html
new file mode 100644
index 0000000..d3a50c6
--- /dev/null
+++ b/WebCore/manual-tests/inspector/debugger-step-on-for-statements.html
@@ -0,0 +1,28 @@
+<script src="resources/loop-statements.js"></script>
+<script>
+function runFor()
+{
+ /* place breakpoint on next line and click continue */ debugger;
+ for (initialize(); condition(); increment())
+ statement();
+}
+</script>
+Start a debugging session in the Web Inspector and open this file.
+<br><br>
+Before running the tests please perform the following:
+Make sure the execution is not paused in the debugger.<br>
+Click the button and when the debugger breaks, set a breakpoint on the first line in the loop
+(as indicated by the comment), and click continue.<br>
+The debugger should stop at the beggining of the loop.<br>
+The above actions should be performed before <b>each</b> of the following tests.
+<br><br>
+<input type="button" value="run for" onclick="runFor()"/>
+<br><br>
+TEST 1: Click 'continue'. Execution should continue without stopping on the loop breakpoint again.<br>
+TEST 2: Click 'Step over'. Debugger should step inside the loop to the next statement line.<br>
+TEST 3: Click 'Step into'. Debugger should step into 'initialize' function. Click 'Step into' until
+outside of the 'initialize' function - debugger should enter the 'condition' function.<br>
+TEST 4: 'Step over' to the statement line and then 'Step over' again. Debugger should pause on
+the for loop again. Click 'Step into'. Debugger should step into the 'increment' function.
+Click 'Step into' until outside of the 'increment' function - debugger should enter the 'condition'
+function.<br>
diff --git a/WebCore/manual-tests/inspector/debugger-step-on-while-statements.html b/WebCore/manual-tests/inspector/debugger-step-on-while-statements.html
new file mode 100644
index 0000000..fd077bc
--- /dev/null
+++ b/WebCore/manual-tests/inspector/debugger-step-on-while-statements.html
@@ -0,0 +1,29 @@
+<script src="resources/loop-statements.js"></script>
+<script>
+function runWhile()
+{
+ /* place breakpoint on next line and click continue */ debugger;
+ while (condition()) {
+ statement();
+ increment();
+ }
+}
+
+</script>
+Start a debugging session in the Web Inspector and open this file.
+<br><br>
+Before running the tests please perform the following:
+Make sure the execution is not paused in the debugger.<br>
+Click the button and when the debugger breaks, set a breakpoint on the first line in the loop
+(as indicated by the comment), and click continue.<br>
+The debugger should stop at the beggining of the loop.<br>
+The above actions should be performed before <b>each</b> of the following tests.
+<br><br>
+<input type="button" value="run while" onclick="initialize();runWhile()"/>
+<br><br>
+TEST 1: Click 'continue'. Execution should continue without stopping on the loop breakpoint again.<br>
+TEST 2: Click 'Step over'. Debugger should step inside the loop to the next statement line.<br>
+TEST 3: Click 'Step into'. Debugger should step into 'condition' function.<br>
+TEST 4: 'Step over' the statements until reaching the end of the loop. Debugger should
+step over to the beggingin of the while loop again. Click 'Step into'. Debugger should step into
+the 'condition' function.<br>
diff --git a/WebCore/manual-tests/inspector/highlight-nodes.html b/WebCore/manual-tests/inspector/highlight-nodes.html
new file mode 100644
index 0000000..6712b3a
--- /dev/null
+++ b/WebCore/manual-tests/inspector/highlight-nodes.html
@@ -0,0 +1,23 @@
+<style>
+.skewed {
+ -webkit-transform:skew(-5deg,-5deg);
+}
+</style>
+<p>This page has basic tests of node highlighting in the inspected page. To tests, load this page, open the inspector and mouseover the nodes in the treeview of the inspector. You should see the highlights happen with the appropriate padding/border/margin/content highlights.</p>
+<div style="padding:10px; border: 10px solid; margin: 10px;">padding:10px; border: 10px; margin: 10px;</div>
+<div style="padding:10px; border: 10px solid;">padding:10px; border: 10px;</div>
+<div style="padding:10px; margin: 10px;">padding:10px; margin: 10px;</div>
+<div style="border: 10px solid; margin: 10px;">border: 10px; margin: 10px;</div>
+<div style="padding:10px">padding:10px;</div>
+<div style="border: 10px solid;">border: 10px;</div>
+<div style="margin: 10px;">margin: 10px;</div>
+<div>no padding, border, or margin</div>
+<div class=skewed style="padding:10px; border: 10px solid; margin: 10px;">-webkit-transform:skew(-5deg,-5deg); padding:10px; border: 10px; margin: 10px;</div>
+<div class=skewed style="padding:10px; border: 10px solid;">-webkit-transform:skew(-5deg,-5deg); padding:10px; border: 10px;</div>
+<div class=skewed style="padding:10px; margin: 10px;">-webkit-transform:skew(-5deg,-5deg); padding:10px; margin: 10px;</div>
+<div class=skewed style="border: 10px solid; margin: 10px;">-webkit-transform:skew(-5deg,-5deg); border: 10px; margin: 10px;</div>
+<div class=skewed style="padding:10px">-webkit-transform:skew(-5deg,-5deg); padding:10px;</div>
+<div class=skewed style="border: 10px solid;">-webkit-transform:skew(-5deg,-5deg); border: 10px;</div>
+<div class=skewed style="margin: 10px;">-webkit-transform:skew(-5deg,-5deg); margin: 10px;</div>
+<div class=skewed >-webkit-transform:skew(-5deg,-5deg); no padding, border, or margin</div>
+
diff --git a/WebCore/manual-tests/inspector/resources/loop-statements.js b/WebCore/manual-tests/inspector/resources/loop-statements.js
new file mode 100644
index 0000000..cbb4e0d
--- /dev/null
+++ b/WebCore/manual-tests/inspector/resources/loop-statements.js
@@ -0,0 +1,22 @@
+var i;
+var a;
+
+function initialize()
+{
+ i = false;
+}
+
+function condition()
+{
+ return !i;
+}
+
+function increment()
+{
+ i = !i;
+}
+
+function statement()
+{
+ a = i;
+}
diff --git a/WebCore/manual-tests/media-controls-when-javascript-disabled.html b/WebCore/manual-tests/media-controls-when-javascript-disabled.html
new file mode 100644
index 0000000..b7e52bc
--- /dev/null
+++ b/WebCore/manual-tests/media-controls-when-javascript-disabled.html
@@ -0,0 +1,26 @@
+<html>
+ <head>
+ <style> #error { display: none; } </style>
+ <script>
+ function showErrorMsg()
+ {
+ document.getElementById('error').style.display = 'block';
+ }
+ </script>
+ </head>
+
+<body onload="showErrorMsg()">
+
+ <p>TEST: Video should have controls when scripting is disabled.</p>
+
+ <video
+ src="http://movies.apple.com/movies/us/apple/ipoditunes/2007/touch/ads/apple_ipodtouch_touch_r640-9cie.mov">
+ </video>
+
+ <noscript><p>Scripting is DISABLED.</p></noscript>
+
+ <p id=error>ERROR: JavaScript must be disabled for this test.</p>
+
+
+</body>
+</html> \ No newline at end of file
diff --git a/WebCore/manual-tests/resources/simple_image.png b/WebCore/manual-tests/resources/simple_image.png
new file mode 100644
index 0000000..4685399
--- /dev/null
+++ b/WebCore/manual-tests/resources/simple_image.png
Binary files differ
diff --git a/WebCore/manual-tests/simple-image-compositing.html b/WebCore/manual-tests/simple-image-compositing.html
new file mode 100644
index 0000000..e44ffed
--- /dev/null
+++ b/WebCore/manual-tests/simple-image-compositing.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Checking for simple image layer optimisation</title>
+ <style type="text/css" media="screen">
+ img {
+ float: left;
+ width: 150px;
+ height: 150px;
+ }
+ p {
+ clear: both;
+ margin: 1em 2em;
+ height: 180px;
+ }
+ img {
+ -webkit-transform: rotate3d(0, 0, 1, 0);
+ }
+ </style>
+</head>
+<body>
+
+ <h1>Image optimisation in layers</h1>
+
+ <p style="height: auto">
+ In order to run this test you should enable the debugging options that indicate
+ what type of compositing layer is being used.
+ </p>
+
+<pre>
+defaults write com.apple.Safari WebCoreLayerRepaintCounter -bool yes
+defaults write com.apple.Safari WebCoreLayerBorders -bool yes
+</pre>
+
+ <p style="height: auto">
+ Directly composited image layers will have a yellow border and no repaint counter.
+ </p>
+
+ <p>
+ <img src="resources/simple_image.png">
+ Basic image - no style - can be directly composited
+ </p>
+
+ <p>
+ <img src="resources/simple_image.png" style="border: 5px solid blue;">
+ 5px blue border - can NOT be directly composited
+ </p>
+
+ <p>
+ <img src="resources/simple_image.png" style="margin: 10px 20px;">
+ margin - can NOT be directly composited
+ </p>
+
+ <p>
+ <img src="resources/simple_image.png" style="background-color: grey;">
+ solid background - can be directly composited
+ </p>
+
+ <p>
+ <img src="resources/simple_image.png" style="background: orange url(resources/simple_image.png) -50px -50px;">
+ background image - can NOT be directly composited
+ </p>
+
+ <p>
+ <img src="resources/simple_image.png" style="-webkit-transform: rotate3d(0, 0, 1, 10deg);">
+ rotated but otherwise no style - can be directly composited
+ </p>
+
+
+
+
+</body>
+</html>
diff --git a/WebCore/page/AXObjectCache.cpp b/WebCore/page/AXObjectCache.cpp
index d9c4c9a..f8167a5 100644
--- a/WebCore/page/AXObjectCache.cpp
+++ b/WebCore/page/AXObjectCache.cpp
@@ -58,6 +58,7 @@ AXObjectCache::~AXObjectCache()
AccessibilityObject* obj = (*it).second.get();
detachWrapper(obj);
obj->detach();
+ removeAXID(obj);
}
}
@@ -66,39 +67,52 @@ AccessibilityObject* AXObjectCache::get(RenderObject* renderer)
if (!renderer)
return 0;
- RefPtr<AccessibilityObject> obj = 0;
+ AccessibilityObject* obj = 0;
AXID axID = m_renderObjectMapping.get(renderer);
ASSERT(!HashTraits<AXID>::isDeletedValue(axID));
if (axID)
obj = m_objects.get(axID).get();
+
+ return obj;
+}
+
+AccessibilityObject* AXObjectCache::getOrCreate(RenderObject* renderer)
+{
+ if (!renderer)
+ return 0;
+
+ AccessibilityObject* obj = get(renderer);
- Node* element = renderer->element();
if (!obj) {
+ Node* node = renderer->node();
+ RefPtr<AccessibilityObject> newObj = 0;
if (renderer->isListBox())
- obj = AccessibilityListBox::create(renderer);
- else if (element && (element->hasTagName(ulTag) || element->hasTagName(olTag) || element->hasTagName(dlTag)))
- obj = AccessibilityList::create(renderer);
+ newObj = AccessibilityListBox::create(renderer);
+ else if (node && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(dlTag)))
+ newObj = AccessibilityList::create(renderer);
else if (renderer->isTable())
- obj = AccessibilityTable::create(renderer);
+ newObj = AccessibilityTable::create(renderer);
else if (renderer->isTableRow())
- obj = AccessibilityTableRow::create(renderer);
+ newObj = AccessibilityTableRow::create(renderer);
else if (renderer->isTableCell())
- obj = AccessibilityTableCell::create(renderer);
+ newObj = AccessibilityTableCell::create(renderer);
else
- obj = AccessibilityRenderObject::create(renderer);
+ newObj = AccessibilityRenderObject::create(renderer);
- getAXID(obj.get());
+ obj = newObj.get();
+
+ getAXID(obj);
- m_renderObjectMapping.set(renderer, obj.get()->axObjectID());
- m_objects.set(obj.get()->axObjectID(), obj);
- attachWrapper(obj.get());
+ m_renderObjectMapping.set(renderer, obj->axObjectID());
+ m_objects.set(obj->axObjectID(), obj);
+ attachWrapper(obj);
}
- return obj.get();
+ return obj;
}
-AccessibilityObject* AXObjectCache::get(AccessibilityRole role)
+AccessibilityObject* AXObjectCache::getOrCreate(AccessibilityRole role)
{
RefPtr<AccessibilityObject> obj = 0;
@@ -186,6 +200,9 @@ AXID AXObjectCache::getAXID(AccessibilityObject* obj)
void AXObjectCache::removeAXID(AccessibilityObject* obj)
{
+ if (!obj)
+ return;
+
AXID objID = obj->axObjectID();
if (objID == 0)
return;
@@ -221,7 +238,7 @@ void AXObjectCache::handleActiveDescendantChanged(RenderObject* renderer)
{
if (!renderer)
return;
- AccessibilityObject* obj = get(renderer);
+ AccessibilityObject* obj = getOrCreate(renderer);
if (obj)
obj->handleActiveDescendantChanged();
}
@@ -230,7 +247,7 @@ void AXObjectCache::handleAriaRoleChanged(RenderObject* renderer)
{
if (!renderer)
return;
- AccessibilityObject* obj = get(renderer);
+ AccessibilityObject* obj = getOrCreate(renderer);
if (obj && obj->isAccessibilityRenderObject())
static_cast<AccessibilityRenderObject*>(obj)->setAriaRole();
}
diff --git a/WebCore/page/AXObjectCache.h b/WebCore/page/AXObjectCache.h
index 5e95f74..4fd6dc3 100644
--- a/WebCore/page/AXObjectCache.h
+++ b/WebCore/page/AXObjectCache.h
@@ -60,10 +60,13 @@ namespace WebCore {
~AXObjectCache();
// to be used with render objects
- AccessibilityObject* get(RenderObject*);
+ AccessibilityObject* getOrCreate(RenderObject*);
// used for objects without backing elements
- AccessibilityObject* get(AccessibilityRole);
+ AccessibilityObject* getOrCreate(AccessibilityRole);
+
+ // will only return the AccessibilityObject if it already exists
+ AccessibilityObject* get(RenderObject*);
void remove(RenderObject*);
void remove(AXID);
diff --git a/WebCore/page/AccessibilityImageMapLink.cpp b/WebCore/page/AccessibilityImageMapLink.cpp
index 5557446..86ca623 100644
--- a/WebCore/page/AccessibilityImageMapLink.cpp
+++ b/WebCore/page/AccessibilityImageMapLink.cpp
@@ -65,7 +65,7 @@ AccessibilityObject* AccessibilityImageMapLink::parentObject() const
if (!m_mapElement || !m_mapElement->renderer())
return 0;
- return m_mapElement->document()->axObjectCache()->get(m_mapElement->renderer());
+ return m_mapElement->document()->axObjectCache()->getOrCreate(m_mapElement->renderer());
}
Element* AccessibilityImageMapLink::actionElement() const
diff --git a/WebCore/page/AccessibilityList.cpp b/WebCore/page/AccessibilityList.cpp
index ad71ff4..3097b3b 100644
--- a/WebCore/page/AccessibilityList.cpp
+++ b/WebCore/page/AccessibilityList.cpp
@@ -68,8 +68,8 @@ bool AccessibilityList::isUnorderedList() const
if (!m_renderer)
return false;
- Node* element = m_renderer->element();
- return element && element->hasTagName(ulTag);
+ Node* node = m_renderer->node();
+ return node && node->hasTagName(ulTag);
}
bool AccessibilityList::isOrderedList() const
@@ -77,8 +77,8 @@ bool AccessibilityList::isOrderedList() const
if (!m_renderer)
return false;
- Node* element = m_renderer->element();
- return element && element->hasTagName(olTag);
+ Node* node = m_renderer->node();
+ return node && node->hasTagName(olTag);
}
bool AccessibilityList::isDefinitionList() const
@@ -86,8 +86,8 @@ bool AccessibilityList::isDefinitionList() const
if (!m_renderer)
return false;
- Node* element = m_renderer->element();
- return element && element->hasTagName(dlTag);
+ Node* node = m_renderer->node();
+ return node && node->hasTagName(dlTag);
}
diff --git a/WebCore/page/AccessibilityListBox.cpp b/WebCore/page/AccessibilityListBox.cpp
index b94ccef..37baec9 100644
--- a/WebCore/page/AccessibilityListBox.cpp
+++ b/WebCore/page/AccessibilityListBox.cpp
@@ -144,7 +144,7 @@ AccessibilityObject* AccessibilityListBox::listBoxOptionAccessibilityObject(HTML
if (!element || element->hasTagName(hrTag))
return 0;
- AccessibilityObject* listBoxObject = m_renderer->document()->axObjectCache()->get(ListBoxOptionRole);
+ AccessibilityObject* listBoxObject = m_renderer->document()->axObjectCache()->getOrCreate(ListBoxOptionRole);
static_cast<AccessibilityListBoxOption*>(listBoxObject)->setHTMLElement(element);
return listBoxObject;
@@ -157,13 +157,13 @@ AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint
if (!m_renderer)
return 0;
- Node* element = m_renderer->element();
- if (!element)
+ Node* node = m_renderer->node();
+ if (!node)
return 0;
IntRect parentRect = boundingBoxRect();
- const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(element)->listItems();
+ const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(node)->listItems();
unsigned length = listItems.size();
for (unsigned i = 0; i < length; i++) {
IntRect rect = static_cast<RenderListBox*>(m_renderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), i);
@@ -171,7 +171,7 @@ AccessibilityObject* AccessibilityListBox::doAccessibilityHitTest(const IntPoint
return listBoxOptionAccessibilityObject(listItems[i]);
}
- return axObjectCache()->get(m_renderer);
+ return axObjectCache()->getOrCreate(m_renderer);
}
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityListBoxOption.cpp b/WebCore/page/AccessibilityListBoxOption.cpp
index fedfe91..088c556 100644
--- a/WebCore/page/AccessibilityListBoxOption.cpp
+++ b/WebCore/page/AccessibilityListBoxOption.cpp
@@ -97,7 +97,7 @@ IntRect AccessibilityListBoxOption::elementRect() const
if (!listBoxRenderer)
return rect;
- IntRect parentRect = listBoxRenderer->document()->axObjectCache()->get(listBoxRenderer)->boundingBoxRect();
+ IntRect parentRect = listBoxRenderer->document()->axObjectCache()->getOrCreate(listBoxRenderer)->boundingBoxRect();
int index = listBoxOptionIndex();
if (index != -1)
rect = static_cast<RenderListBox*>(listBoxRenderer)->itemBoundingBoxRect(parentRect.x(), parentRect.y(), index);
@@ -153,7 +153,7 @@ AccessibilityObject* AccessibilityListBoxOption::parentObject() const
if (!parentNode)
return 0;
- return m_optionElement->document()->axObjectCache()->get(parentNode->renderer());
+ return m_optionElement->document()->axObjectCache()->getOrCreate(parentNode->renderer());
}
void AccessibilityListBoxOption::setSelected(bool selected)
diff --git a/WebCore/page/AccessibilityObject.cpp b/WebCore/page/AccessibilityObject.cpp
index 6d441d0..d5b7ff5 100644
--- a/WebCore/page/AccessibilityObject.cpp
+++ b/WebCore/page/AccessibilityObject.cpp
@@ -75,7 +75,6 @@ AccessibilityObject::~AccessibilityObject()
void AccessibilityObject::detach()
{
- removeAXObjectID();
#if HAVE(ACCESSIBILITY)
setWrapper(0);
#endif
@@ -114,6 +113,11 @@ AccessibilityObject* AccessibilityObject::parentObjectUnignored() const
return parent;
}
+AccessibilityObject* AccessibilityObject::parentObjectIfExists() const
+{
+ return 0;
+}
+
int AccessibilityObject::layoutCount() const
{
return 0;
@@ -231,9 +235,9 @@ const AtomicString& AccessibilityObject::accessKey() const
return nullAtom;
}
-Selection AccessibilityObject::selection() const
+VisibleSelection AccessibilityObject::selection() const
{
- return Selection();
+ return VisibleSelection();
}
PlainTextRange AccessibilityObject::selectedTextRange() const
@@ -357,7 +361,7 @@ VisiblePositionRange AccessibilityObject::visiblePositionRangeForUnorderedPositi
// use selection order to see if the positions are in order
else
- alreadyInOrder = Selection(visiblePos1, visiblePos2).isBaseFirst();
+ alreadyInOrder = VisibleSelection(visiblePos1, visiblePos2).isBaseFirst();
if (alreadyInOrder) {
startPos = visiblePos1;
@@ -400,7 +404,7 @@ static VisiblePosition updateAXLineStartForVisiblePosition(const VisiblePosition
if (!p.node())
break;
renderer = p.node()->renderer();
- if (!renderer || renderer->isRenderBlock() && !p.offset())
+ if (!renderer || (renderer->isRenderBlock() && !p.m_offset))
break;
InlineBox* box;
int ignoredCaretOffset;
@@ -514,7 +518,7 @@ static VisiblePosition startOfStyleRange(const VisiblePosition visiblePos)
return VisiblePosition(startRenderer->node(), 0, VP_DEFAULT_AFFINITY);
}
-static VisiblePosition endOfStyleRange(const VisiblePosition visiblePos)
+static VisiblePosition endOfStyleRange(const VisiblePosition& visiblePos)
{
RenderObject* renderer = visiblePos.deepEquivalent().node()->renderer();
RenderObject* endRenderer = renderer;
@@ -534,7 +538,7 @@ static VisiblePosition endOfStyleRange(const VisiblePosition visiblePos)
endRenderer = r;
}
- return VisiblePosition(endRenderer->node(), maxDeepOffset(endRenderer->node()), VP_DEFAULT_AFFINITY);
+ return lastDeepEditingPositionForNode(endRenderer->node());
}
VisiblePositionRange AccessibilityObject::styleRangeForPosition(const VisiblePosition& visiblePos) const
@@ -566,7 +570,7 @@ static bool replacedNodeNeedsCharacter(Node* replacedNode)
}
// create an AX object, but skip it if it is not supposed to be seen
- AccessibilityObject* object = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer());
+ AccessibilityObject* object = replacedNode->renderer()->document()->axObjectCache()->getOrCreate(replacedNode->renderer());
if (object->accessibilityIsIgnored())
return false;
@@ -814,7 +818,7 @@ AccessibilityObject* AccessibilityObject::accessibilityObjectForPosition(const V
if (!obj)
return 0;
- return obj->document()->axObjectCache()->get(obj);
+ return obj->document()->axObjectCache()->getOrCreate(obj);
}
int AccessibilityObject::lineForPosition(const VisiblePosition& visiblePos) const
@@ -996,11 +1000,6 @@ void AccessibilityObject::setAXObjectID(unsigned axObjectID)
m_id = axObjectID;
}
-void AccessibilityObject::removeAXObjectID()
-{
- return;
-}
-
const String& AccessibilityObject::actionVerb() const
{
// FIXME: Need to add verbs for select elements.
diff --git a/WebCore/page/AccessibilityObject.h b/WebCore/page/AccessibilityObject.h
index a751003..9141b36 100644
--- a/WebCore/page/AccessibilityObject.h
+++ b/WebCore/page/AccessibilityObject.h
@@ -83,7 +83,7 @@ class IntPoint;
class IntSize;
class Node;
class RenderObject;
-class Selection;
+class VisibleSelection;
class String;
class Widget;
@@ -266,6 +266,7 @@ public:
virtual AccessibilityObject* nextSibling() const;
virtual AccessibilityObject* parentObject() const;
virtual AccessibilityObject* parentObjectUnignored() const;
+ virtual AccessibilityObject* parentObjectIfExists() const;
virtual AccessibilityObject* observableObject() const;
virtual void linkedUIElements(AccessibilityChildrenVector&) const;
virtual AccessibilityObject* titleUIElement() const;
@@ -285,7 +286,7 @@ public:
virtual KURL url() const;
virtual PlainTextRange selectedTextRange() const;
- virtual Selection selection() const;
+ virtual VisibleSelection selection() const;
unsigned selectionStart() const;
unsigned selectionEnd() const;
virtual String stringValue() const;
@@ -410,7 +411,6 @@ protected:
mutable bool m_haveChildren;
virtual void clearChildren();
- virtual void removeAXObjectID();
virtual bool isDetached() const { return true; }
#if PLATFORM(MAC)
diff --git a/WebCore/page/AccessibilityRenderObject.cpp b/WebCore/page/AccessibilityRenderObject.cpp
index 5cdc7b4..8ed352a 100644
--- a/WebCore/page/AccessibilityRenderObject.cpp
+++ b/WebCore/page/AccessibilityRenderObject.cpp
@@ -58,6 +58,7 @@
#include "RenderFieldset.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
+#include "RenderInline.h"
#include "RenderListBox.h"
#include "RenderListMarker.h"
#include "RenderMenuList.h"
@@ -120,7 +121,7 @@ AccessibilityObject* AccessibilityRenderObject::firstChild() const
if (!firstChild)
return 0;
- return m_renderer->document()->axObjectCache()->get(firstChild);
+ return m_renderer->document()->axObjectCache()->getOrCreate(firstChild);
}
AccessibilityObject* AccessibilityRenderObject::lastChild() const
@@ -132,7 +133,7 @@ AccessibilityObject* AccessibilityRenderObject::lastChild() const
if (!lastChild)
return 0;
- return m_renderer->document()->axObjectCache()->get(lastChild);
+ return m_renderer->document()->axObjectCache()->getOrCreate(lastChild);
}
AccessibilityObject* AccessibilityRenderObject::previousSibling() const
@@ -144,7 +145,7 @@ AccessibilityObject* AccessibilityRenderObject::previousSibling() const
if (!previousSibling)
return 0;
- return m_renderer->document()->axObjectCache()->get(previousSibling);
+ return m_renderer->document()->axObjectCache()->getOrCreate(previousSibling);
}
AccessibilityObject* AccessibilityRenderObject::nextSibling() const
@@ -156,9 +157,21 @@ AccessibilityObject* AccessibilityRenderObject::nextSibling() const
if (!nextSibling)
return 0;
- return m_renderer->document()->axObjectCache()->get(nextSibling);
+ return m_renderer->document()->axObjectCache()->getOrCreate(nextSibling);
}
+AccessibilityObject* AccessibilityRenderObject::parentObjectIfExists() const
+{
+ if (!m_renderer)
+ return 0;
+
+ RenderObject *parent = m_renderer->parent();
+ if (!parent)
+ return 0;
+
+ return m_renderer->document()->axObjectCache()->get(parent);
+}
+
AccessibilityObject* AccessibilityRenderObject::parentObject() const
{
if (!m_renderer)
@@ -169,7 +182,7 @@ AccessibilityObject* AccessibilityRenderObject::parentObject() const
return 0;
if (ariaRoleAttribute() == MenuBarRole)
- return m_renderer->document()->axObjectCache()->get(parent);
+ return m_renderer->document()->axObjectCache()->getOrCreate(parent);
// menuButton and its corresponding menu are DOM siblings, but Accessibility needs them to be parent/child
if (ariaRoleAttribute() == MenuRole) {
@@ -178,7 +191,7 @@ AccessibilityObject* AccessibilityRenderObject::parentObject() const
return parent;
}
- return m_renderer->document()->axObjectCache()->get(parent);
+ return m_renderer->document()->axObjectCache()->getOrCreate(parent);
}
bool AccessibilityRenderObject::isWebArea() const
@@ -198,7 +211,7 @@ bool AccessibilityRenderObject::isAnchor() const
bool AccessibilityRenderObject::isNativeTextControl() const
{
- return m_renderer->isTextField() || m_renderer->isTextArea();
+ return m_renderer->isTextControl();
}
bool AccessibilityRenderObject::isTextControl() const
@@ -219,6 +232,9 @@ bool AccessibilityRenderObject::isImage() const
bool AccessibilityRenderObject::isAttachment() const
{
+ if (!m_renderer)
+ return false;
+
// Widgets are the replaced elements that we represent to AX as attachments
bool isWidget = m_renderer && m_renderer->isWidget();
ASSERT(!isWidget || (m_renderer->isReplaced() && !isImage()));
@@ -228,9 +244,16 @@ bool AccessibilityRenderObject::isAttachment() const
bool AccessibilityRenderObject::isPasswordField() const
{
ASSERT(m_renderer);
- if (!m_renderer->element() || !m_renderer->element()->isHTMLElement())
+ if (!m_renderer->node() || !m_renderer->node()->isHTMLElement())
+ return false;
+ if (ariaRoleAttribute() != UnknownRole)
+ return false;
+
+ InputElement* inputElement = toInputElement(static_cast<Element*>(m_renderer->node()));
+ if (!inputElement)
return false;
- return static_cast<HTMLElement*>(m_renderer->element())->isPasswordField() && ariaRoleAttribute() == UnknownRole;
+
+ return inputElement->isPasswordField();
}
bool AccessibilityRenderObject::isCheckboxOrRadio() const
@@ -241,8 +264,8 @@ bool AccessibilityRenderObject::isCheckboxOrRadio() const
bool AccessibilityRenderObject::isFileUploadButton() const
{
- if (m_renderer && m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) {
- HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ if (m_renderer && m_renderer->node() && m_renderer->node()->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->node());
return input->inputType() == HTMLInputElement::FILE;
}
@@ -251,8 +274,8 @@ bool AccessibilityRenderObject::isFileUploadButton() const
bool AccessibilityRenderObject::isInputImage() const
{
- if (m_renderer && m_renderer->element() && m_renderer->element()->hasTagName(inputTag)) {
- HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ if (m_renderer && m_renderer->node() && m_renderer->node()->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->node());
return input->inputType() == HTMLInputElement::IMAGE;
}
@@ -321,13 +344,27 @@ bool AccessibilityRenderObject::isPressed() const
bool AccessibilityRenderObject::isIndeterminate() const
{
ASSERT(m_renderer);
- return m_renderer->node() && m_renderer->node()->isIndeterminate();
+ if (!m_renderer->node() || !m_renderer->node()->isElementNode())
+ return false;
+
+ InputElement* inputElement = toInputElement(static_cast<Element*>(m_renderer->node()));
+ if (!inputElement)
+ return false;
+
+ return inputElement->isIndeterminate();
}
bool AccessibilityRenderObject::isChecked() const
{
ASSERT(m_renderer);
- return m_renderer->node() && m_renderer->node()->isChecked();
+ if (!m_renderer->node() || !m_renderer->node()->isElementNode())
+ return false;
+
+ InputElement* inputElement = toInputElement(static_cast<Element*>(m_renderer->node()));
+ if (!inputElement)
+ return false;
+
+ return inputElement->isChecked();
}
bool AccessibilityRenderObject::isHovered() const
@@ -341,7 +378,7 @@ bool AccessibilityRenderObject::isMultiSelect() const
ASSERT(m_renderer);
if (!m_renderer->isListBox())
return false;
- return m_renderer->element() && static_cast<HTMLSelectElement*>(m_renderer->element())->multiple();
+ return m_renderer->node() && static_cast<HTMLSelectElement*>(m_renderer->node())->multiple();
}
bool AccessibilityRenderObject::isReadOnly() const
@@ -384,7 +421,7 @@ int AccessibilityRenderObject::headingLevel(Node* node)
return 0;
if (RenderObject* renderer = node->renderer()) {
- AccessibilityObject* axObjectForNode = node->document()->axObjectCache()->get(renderer);
+ AccessibilityObject* axObjectForNode = node->document()->axObjectCache()->getOrCreate(renderer);
if (axObjectForNode->ariaRoleAttribute() == HeadingRole) {
if (!node->isElementNode())
return 0;
@@ -430,8 +467,9 @@ bool AccessibilityRenderObject::isControl() const
if (!m_renderer)
return false;
- Node* node = m_renderer->element();
- return node && (node->isControl() || AccessibilityObject::isARIAControl(ariaRoleAttribute()));
+ Node* node = m_renderer->node();
+ return node && ((node->isElementNode() && static_cast<Element*>(node)->isFormControlElement())
+ || AccessibilityObject::isARIAControl(ariaRoleAttribute()));
}
bool AccessibilityRenderObject::isFieldset() const
@@ -449,7 +487,7 @@ bool AccessibilityRenderObject::isGroup() const
const AtomicString& AccessibilityRenderObject::getAttribute(const QualifiedName& attribute) const
{
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return nullAtom;
@@ -469,10 +507,12 @@ Element* AccessibilityRenderObject::anchorElement() const
RenderObject* currRenderer;
// Search up the render tree for a RenderObject with a DOM node. Defer to an earlier continuation, though.
- for (currRenderer = m_renderer; currRenderer && !currRenderer->element(); currRenderer = currRenderer->parent()) {
- RenderFlow* continuation = currRenderer->virtualContinuation();
- if (continuation)
- return cache->get(continuation)->anchorElement();
+ for (currRenderer = m_renderer; currRenderer && !currRenderer->node(); currRenderer = currRenderer->parent()) {
+ if (currRenderer->isRenderBlock()) {
+ RenderInline* continuation = toRenderBlock(currRenderer)->inlineContinuation();
+ if (continuation)
+ return cache->getOrCreate(continuation)->anchorElement();
+ }
}
// bail if none found
@@ -483,7 +523,7 @@ Element* AccessibilityRenderObject::anchorElement() const
// NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
Node* node = currRenderer->node();
for ( ; node; node = node->parentNode()) {
- if (node->hasTagName(aTag) || (node->renderer() && cache->get(node->renderer())->isAnchor()))
+ if (node->hasTagName(aTag) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
return static_cast<Element*>(node);
}
@@ -495,7 +535,7 @@ Element* AccessibilityRenderObject::actionElement() const
if (!m_renderer)
return 0;
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (node) {
if (node->hasTagName(inputTag)) {
HTMLInputElement* input = static_cast<HTMLInputElement*>(node);
@@ -506,13 +546,13 @@ Element* AccessibilityRenderObject::actionElement() const
}
if (isFileUploadButton())
- return static_cast<Element*>(m_renderer->element());
+ return static_cast<Element*>(m_renderer->node());
if (AccessibilityObject::isARIAInput(ariaRoleAttribute()))
- return static_cast<Element*>(m_renderer->element());
+ return static_cast<Element*>(m_renderer->node());
if (isImageButton())
- return static_cast<Element*>(m_renderer->element());
+ return static_cast<Element*>(m_renderer->node());
if (m_renderer->isMenuList())
return static_cast<RenderMenuList*>(m_renderer)->selectElement();
@@ -525,18 +565,18 @@ Element* AccessibilityRenderObject::actionElement() const
Element* AccessibilityRenderObject::mouseButtonListener() const
{
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return 0;
- if (!node->isEventTargetNode())
+ if (!node->isElementNode())
return 0;
-
+
// FIXME: Do the continuation search like anchorElement does
- for (EventTargetNode* elt = static_cast<EventTargetNode*>(node); elt; elt = static_cast<EventTargetNode*>(elt->parentNode())) {
- if (elt->inlineEventListenerForType(eventNames().clickEvent) || elt->inlineEventListenerForType(eventNames().mousedownEvent) || elt->inlineEventListenerForType(eventNames().mouseupEvent))
- return static_cast<Element*>(elt);
+ for (Element* element = static_cast<Element*>(node); element; element = element->parentElement()) {
+ if (element->inlineEventListenerForType(eventNames().clickEvent) || element->inlineEventListenerForType(eventNames().mousedownEvent) || element->inlineEventListenerForType(eventNames().mouseupEvent))
+ return element;
}
-
+
return 0;
}
@@ -567,7 +607,7 @@ AccessibilityObject* AccessibilityRenderObject::menuForMenuButton() const
{
Element* menu = menuElementForMenuButton();
if (menu && menu->renderer())
- return m_renderer->document()->axObjectCache()->get(menu->renderer());
+ return m_renderer->document()->axObjectCache()->getOrCreate(menu->renderer());
return 0;
}
@@ -585,7 +625,7 @@ AccessibilityObject* AccessibilityRenderObject::menuButtonForMenu() const
if (menuItem && menuItem->renderer()) {
// ARIA just has generic menu items. AppKit needs to know if this is a top level items like MenuBarButton or MenuBarItem
- AccessibilityObject* menuItemAX = m_renderer->document()->axObjectCache()->get(menuItem->renderer());
+ AccessibilityObject* menuItemAX = m_renderer->document()->axObjectCache()->getOrCreate(menuItem->renderer());
if (menuItemAX->isMenuButton())
return menuItemAX;
}
@@ -598,11 +638,11 @@ String AccessibilityRenderObject::helpText() const
return String();
for (RenderObject* curr = m_renderer; curr; curr = curr->parent()) {
- if (curr->element() && curr->element()->isHTMLElement()) {
- const AtomicString& summary = static_cast<Element*>(curr->element())->getAttribute(summaryAttr);
+ if (curr->node() && curr->node()->isHTMLElement()) {
+ const AtomicString& summary = static_cast<Element*>(curr->node())->getAttribute(summaryAttr);
if (!summary.isEmpty())
return summary;
- const AtomicString& title = static_cast<Element*>(curr->element())->getAttribute(titleAttr);
+ const AtomicString& title = static_cast<Element*>(curr->node())->getAttribute(titleAttr);
if (!title.isEmpty())
return title;
}
@@ -621,7 +661,7 @@ String AccessibilityRenderObject::textUnderElement() const
return uploadControl->buttonValue();
}
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (node) {
if (Frame* frame = node->document()->frame()) {
// catch stale WebCoreAXObject (see <rdar://problem/3960196>)
@@ -641,7 +681,7 @@ bool AccessibilityRenderObject::hasIntValue() const
if (isHeading())
return true;
- if (m_renderer->element() && isCheckboxOrRadio())
+ if (m_renderer->node() && isCheckboxOrRadio())
return true;
return false;
@@ -653,9 +693,9 @@ int AccessibilityRenderObject::intValue() const
return 0;
if (isHeading())
- return headingLevel(m_renderer->element());
+ return headingLevel(m_renderer->node());
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node || !isCheckboxOrRadio())
return 0;
@@ -830,7 +870,7 @@ HTMLLabelElement* AccessibilityRenderObject::labelElementContainer() const
return false;
// find if this has a parent that is a label
- for (Node* parentNode = m_renderer->element(); parentNode; parentNode = parentNode->parentNode()) {
+ for (Node* parentNode = m_renderer->node(); parentNode; parentNode = parentNode->parentNode()) {
if (parentNode->hasTagName(labelTag))
return static_cast<HTMLLabelElement*>(parentNode);
}
@@ -845,7 +885,7 @@ String AccessibilityRenderObject::title() const
if (!m_renderer)
return String();
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return String();
@@ -901,9 +941,10 @@ String AccessibilityRenderObject::accessibilityDescription() const
if (!ariaDescription.isEmpty())
return ariaDescription;
- if (isImage()) {
- if (m_renderer->element() && m_renderer->element()->isHTMLElement()) {
- const AtomicString& alt = static_cast<HTMLElement*>(m_renderer->element())->getAttribute(altAttr);
+ if (isImage() || isInputImage()) {
+ Node* node = m_renderer->node();
+ if (node && node->isHTMLElement()) {
+ const AtomicString& alt = static_cast<HTMLElement*>(node)->getAttribute(altAttr);
if (alt.isEmpty())
return String();
return alt;
@@ -944,8 +985,8 @@ IntRect AccessibilityRenderObject::boundingBoxRect() const
if (!obj)
return IntRect();
- if (obj->isInlineContinuation())
- obj = obj->element()->renderer();
+ if (obj->node()) // If we are a continuation, we want to make sure to use the primary renderer.
+ obj = obj->node()->renderer();
// FIXME: This doesn't work correctly with transforms.
Vector<IntRect> rects;
@@ -968,11 +1009,11 @@ IntRect AccessibilityRenderObject::checkboxOrRadioRect() const
if (!m_renderer)
return IntRect();
- HTMLLabelElement* label = labelForElement(static_cast<Element*>(m_renderer->element()));
+ HTMLLabelElement* label = labelForElement(static_cast<Element*>(m_renderer->node()));
if (!label || !label->renderer())
return boundingBoxRect();
- IntRect labelRect = axObjectCache()->get(label->renderer())->elementRect();
+ IntRect labelRect = axObjectCache()->getOrCreate(label->renderer())->elementRect();
labelRect.unite(boundingBoxRect());
return labelRect;
}
@@ -1018,7 +1059,7 @@ AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
return 0;
// the element we find may not be accessible, keep searching until we find a good one
- AccessibilityObject* linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer());
+ AccessibilityObject* linkedAXElement = m_renderer->document()->axObjectCache()->getOrCreate(linkedNode->renderer());
while (linkedAXElement && linkedAXElement->accessibilityIsIgnored()) {
linkedNode = linkedNode->traverseNextNode();
@@ -1027,7 +1068,7 @@ AccessibilityObject* AccessibilityRenderObject::internalLinkElement() const
if (!linkedNode)
return 0;
- linkedAXElement = m_renderer->document()->axObjectCache()->get(linkedNode->renderer());
+ linkedAXElement = m_renderer->document()->axObjectCache()->getOrCreate(linkedNode->renderer());
}
return linkedAXElement;
@@ -1051,7 +1092,7 @@ void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildren
unsigned len = formElements.size();
for (unsigned i = 0; i < len; ++i) {
Node* associateElement = formElements[i].get();
- if (AccessibilityObject* object = m_renderer->document()->axObjectCache()->get(associateElement->renderer()))
+ if (AccessibilityObject* object = m_renderer->document()->axObjectCache()->getOrCreate(associateElement->renderer()))
linkedUIElements.append(object);
}
} else {
@@ -1061,7 +1102,7 @@ void AccessibilityRenderObject::addRadioButtonGroupMembers(AccessibilityChildren
if (list->item(i)->hasTagName(inputTag)) {
HTMLInputElement* associateElement = static_cast<HTMLInputElement*>(list->item(i));
if (associateElement->isRadioButton() && associateElement->name() == input->name()) {
- if (AccessibilityObject* object = m_renderer->document()->axObjectCache()->get(associateElement->renderer()))
+ if (AccessibilityObject* object = m_renderer->document()->axObjectCache()->getOrCreate(associateElement->renderer()))
linkedUIElements.append(object);
}
}
@@ -1090,16 +1131,16 @@ AccessibilityObject* AccessibilityRenderObject::titleUIElement() const
// if isFieldset is true, the renderer is guaranteed to be a RenderFieldset
if (isFieldset())
- return axObjectCache()->get(static_cast<RenderFieldset*>(m_renderer)->findLegend());
+ return axObjectCache()->getOrCreate(static_cast<RenderFieldset*>(m_renderer)->findLegend());
// checkbox and radio hide their labels. Only controls get titleUIElements for now
if (isCheckboxOrRadio() || !isControl())
return 0;
- Node* element = m_renderer->element();
+ Node* element = m_renderer->node();
HTMLLabelElement* label = labelForElement(static_cast<Element*>(element));
if (label && label->renderer())
- return axObjectCache()->get(label->renderer());
+ return axObjectCache()->getOrCreate(label->renderer());
return 0;
}
@@ -1125,7 +1166,7 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
if (labelElement) {
HTMLElement* correspondingControl = labelElement->correspondingControl();
if (correspondingControl && correspondingControl->renderer()) {
- AccessibilityObject* controlObject = axObjectCache()->get(correspondingControl->renderer());
+ AccessibilityObject* controlObject = axObjectCache()->getOrCreate(correspondingControl->renderer());
if (controlObject->isCheckboxOrRadio())
return true;
}
@@ -1157,12 +1198,12 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
return false;
// don't ignore labels, because they serve as TitleUIElements
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (node && node->hasTagName(labelTag))
return false;
if (m_renderer->isBlockFlow() && m_renderer->childrenInline())
- return !static_cast<RenderBlock*>(m_renderer)->firstLineBox() && !mouseButtonListener();
+ return !toRenderBlock(m_renderer)->firstLineBox() && !mouseButtonListener();
// ignore images seemingly used as spacers
if (isImage()) {
@@ -1178,7 +1219,7 @@ bool AccessibilityRenderObject::accessibilityIsIgnored() const
}
// check for one-dimensional image
- RenderImage* image = static_cast<RenderImage*>(m_renderer);
+ RenderImage* image = toRenderImage(m_renderer);
if (image->height() <= 1 || image->width() <= 1)
return true;
@@ -1211,7 +1252,7 @@ int AccessibilityRenderObject::layoutCount() const
{
if (!m_renderer->isRenderView())
return 0;
- return static_cast<RenderView*>(m_renderer)->frameView()->layoutCount();
+ return toRenderView(m_renderer)->frameView()->layoutCount();
}
String AccessibilityRenderObject::text() const
@@ -1220,9 +1261,9 @@ String AccessibilityRenderObject::text() const
return String();
if (isNativeTextControl())
- return static_cast<RenderTextControl*>(m_renderer)->text();
+ return toRenderTextControl(m_renderer)->text();
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return String();
if (!node->isElementNode())
@@ -1243,11 +1284,11 @@ int AccessibilityRenderObject::textLength() const
PassRefPtr<Range> AccessibilityRenderObject::ariaSelectedTextDOMRange() const
{
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return 0;
- RefPtr<Range> currentSelectionRange = selection().toRange();
+ RefPtr<Range> currentSelectionRange = selection().toNormalizedRange();
if (!currentSelectionRange)
return 0;
@@ -1280,7 +1321,7 @@ String AccessibilityRenderObject::selectedText() const
return String(); // need to return something distinct from empty string
if (isNativeTextControl()) {
- RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer);
+ RenderTextControl* textControl = toRenderTextControl(m_renderer);
return textControl->text().substring(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
}
@@ -1295,7 +1336,7 @@ String AccessibilityRenderObject::selectedText() const
const AtomicString& AccessibilityRenderObject::accessKey() const
{
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return nullAtom;
if (!node->isElementNode())
@@ -1303,7 +1344,7 @@ const AtomicString& AccessibilityRenderObject::accessKey() const
return static_cast<Element*>(node)->getAttribute(accesskeyAttr);
}
-Selection AccessibilityRenderObject::selection() const
+VisibleSelection AccessibilityRenderObject::selection() const
{
return m_renderer->document()->frame()->selection()->selection();
}
@@ -1317,7 +1358,7 @@ PlainTextRange AccessibilityRenderObject::selectedTextRange() const
AccessibilityRole ariaRole = ariaRoleAttribute();
if (isNativeTextControl() && ariaRole == UnknownRole) {
- RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer);
+ RenderTextControl* textControl = toRenderTextControl(m_renderer);
return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
}
@@ -1333,7 +1374,7 @@ PlainTextRange AccessibilityRenderObject::selectedTextRange() const
void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
{
if (isNativeTextControl()) {
- RenderTextControl* textControl = static_cast<RenderTextControl*>(m_renderer);
+ RenderTextControl* textControl = toRenderTextControl(m_renderer);
textControl->setSelectionRange(range.start, range.start + range.length);
return;
}
@@ -1344,14 +1385,14 @@ void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range
Frame* frame = document->frame();
if (!frame)
return;
- Node* node = m_renderer->element();
- frame->selection()->setSelection(Selection(Position(node, range.start),
+ Node* node = m_renderer->node();
+ frame->selection()->setSelection(VisibleSelection(Position(node, range.start),
Position(node, range.start + range.length), DOWNSTREAM));
}
KURL AccessibilityRenderObject::url() const
{
- if (isAnchor() && m_renderer->element()->hasTagName(aTag)) {
+ if (isAnchor() && m_renderer->node()->hasTagName(aTag)) {
if (HTMLAnchorElement* anchor = static_cast<HTMLAnchorElement*>(anchorElement()))
return anchor->href();
}
@@ -1359,11 +1400,11 @@ KURL AccessibilityRenderObject::url() const
if (isWebArea())
return m_renderer->document()->url();
- if (isImage() && m_renderer->element() && m_renderer->element()->hasTagName(imgTag))
- return static_cast<HTMLImageElement*>(m_renderer->element())->src();
+ if (isImage() && m_renderer->node() && m_renderer->node()->hasTagName(imgTag))
+ return static_cast<HTMLImageElement*>(m_renderer->node())->src();
if (isInputImage())
- return static_cast<HTMLInputElement*>(m_renderer->element())->src();
+ return static_cast<HTMLInputElement*>(m_renderer->node())->src();
return KURL();
}
@@ -1400,7 +1441,7 @@ bool AccessibilityRenderObject::isFocused() const
// A web area is represented by the Document node in the DOM tree, which isn't focusable.
// Check instead if the frame's selection controller is focused
- if (focusedNode == m_renderer->element() ||
+ if (focusedNode == m_renderer->node() ||
(roleValue() == WebAreaRole && document->frame()->selection()->isFocusedAndActive()))
return true;
@@ -1415,10 +1456,10 @@ void AccessibilityRenderObject::setFocused(bool on)
if (!on)
m_renderer->document()->setFocusedNode(0);
else {
- if (m_renderer->element()->isElementNode())
- static_cast<Element*>(m_renderer->element())->focus();
+ if (m_renderer->node()->isElementNode())
+ static_cast<Element*>(m_renderer->node())->focus();
else
- m_renderer->document()->setFocusedNode(m_renderer->element());
+ m_renderer->document()->setFocusedNode(m_renderer->node());
}
}
@@ -1426,17 +1467,25 @@ void AccessibilityRenderObject::setValue(const String& string)
{
// FIXME: Do we want to do anything here for ARIA textboxes?
if (m_renderer->isTextField()) {
- HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->element());
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(m_renderer->node());
input->setValue(string);
} else if (m_renderer->isTextArea()) {
- HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(m_renderer->element());
+ HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(m_renderer->node());
textArea->setValue(string);
}
}
bool AccessibilityRenderObject::isEnabled() const
{
- return m_renderer->element() ? m_renderer->element()->isEnabled() : true;
+ ASSERT(m_renderer);
+ if (!m_renderer->node() || !m_renderer->node()->isElementNode())
+ return true;
+
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(m_renderer->node()));
+ if (!formControlElement)
+ return true;
+
+ return formControlElement->isEnabled();
}
RenderView* AccessibilityRenderObject::topRenderer() const
@@ -1482,7 +1531,7 @@ AccessibilityObject* AccessibilityRenderObject::accessibilityParentForImageMap(H
// The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
// which has to be stripped off
if (static_cast<HTMLImageElement*>(curr)->useMap().substring(1) == map->getName())
- return axObjectCache()->get(obj);
+ return axObjectCache()->getOrCreate(obj);
}
return 0;
@@ -1496,7 +1545,7 @@ void AccessibilityRenderObject::getDocumentLinks(AccessibilityChildrenVector& re
while (curr) {
RenderObject* obj = curr->renderer();
if (obj) {
- RefPtr<AccessibilityObject> axobj = document->axObjectCache()->get(obj);
+ RefPtr<AccessibilityObject> axobj = document->axObjectCache()->getOrCreate(obj);
ASSERT(axobj);
ASSERT(axobj->roleValue() == WebCoreLinkRole);
if (!axobj->accessibilityIsIgnored())
@@ -1504,7 +1553,7 @@ void AccessibilityRenderObject::getDocumentLinks(AccessibilityChildrenVector& re
} else {
Node* parent = curr->parent();
if (parent && curr->hasTagName(areaTag) && parent->hasTagName(mapTag)) {
- AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->get(ImageMapLinkRole));
+ AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(axObjectCache()->getOrCreate(ImageMapLinkRole));
areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(curr));
areaObject->setHTMLMapElement(static_cast<HTMLMapElement*>(parent));
areaObject->setParent(accessibilityParentForImageMap(static_cast<HTMLMapElement*>(parent)));
@@ -1548,20 +1597,23 @@ VisiblePositionRange AccessibilityRenderObject::visiblePositionRange() const
return VisiblePositionRange();
// construct VisiblePositions for start and end
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
if (!node)
return VisiblePositionRange();
-
- VisiblePosition startPos = VisiblePosition(node, 0, VP_DEFAULT_AFFINITY);
- VisiblePosition endPos = VisiblePosition(node, maxDeepOffset(node), VP_DEFAULT_AFFINITY);
-
+
+ VisiblePosition startPos = firstDeepEditingPositionForNode(node);
+ VisiblePosition endPos = lastDeepEditingPositionForNode(node);
+
// the VisiblePositions are equal for nodes like buttons, so adjust for that
+ // FIXME: Really? [button, 0] and [button, 1] are distinct (before and after the button)
+ // I expect this code is only hit for things like empty divs? In which case I don't think
+ // the behavior is correct here -- eseidel
if (startPos == endPos) {
endPos = endPos.next();
if (endPos.isNull())
endPos = startPos;
}
-
+
return VisiblePositionRange(startPos, endPos);
}
@@ -1587,7 +1639,7 @@ VisiblePositionRange AccessibilityRenderObject::visiblePositionRangeForLine(unsi
// starting at an empty line. The resulting selection in that case
// will be a caret at visiblePos.
SelectionController selection;
- selection.setSelection(Selection(visiblePos));
+ selection.setSelection(VisibleSelection(visiblePos));
selection.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary);
return VisiblePositionRange(selection.selection().visibleStart(), selection.selection().visibleEnd());
@@ -1599,7 +1651,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) co
return VisiblePosition();
if (isNativeTextControl())
- return static_cast<RenderTextControl*>(m_renderer)->visiblePositionForIndex(index);
+ return toRenderTextControl(m_renderer)->visiblePositionForIndex(index);
if (!isTextControl() && !m_renderer->isText())
return VisiblePosition();
@@ -1622,7 +1674,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) co
int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
{
if (isNativeTextControl())
- return static_cast<RenderTextControl*>(m_renderer)->indexForVisiblePosition(pos);
+ return toRenderTextControl(m_renderer)->indexForVisiblePosition(pos);
if (!isTextControl())
return 0;
@@ -1638,7 +1690,7 @@ int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& po
ExceptionCode ec = 0;
RefPtr<Range> range = Range::create(m_renderer->document());
range->setStart(node, 0, ec);
- range->setEnd(indexPosition.node(), indexPosition.offset(), ec);
+ range->setEnd(indexPosition.node(), indexPosition.m_offset, ec);
return TextIterator::rangeLength(range.get());
}
@@ -1694,7 +1746,7 @@ void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePos
m_renderer->document()->frame()->selection()->moveTo(range.start, true);
}
else {
- Selection newSelection = Selection(range.start, range.end);
+ VisibleSelection newSelection = VisibleSelection(range.start, range.end);
m_renderer->document()->frame()->selection()->setSelection(newSelection);
}
}
@@ -1715,7 +1767,8 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin
#else
ourpoint = point;
#endif
- HitTestRequest request(true, true);
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
HitTestResult result(ourpoint);
renderView->layer()->hitTest(request, result);
innerNode = result.innerNode();
@@ -1736,10 +1789,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoin
Frame* frame = static_cast<FrameView*>(widget)->frame();
if (!frame)
break;
- Document* document = frame->document();
- if (!document)
- break;
- renderView = document->renderView();
+ renderView = frame->document()->renderView();
frameView = static_cast<FrameView*>(widget);
}
@@ -1772,7 +1822,7 @@ int AccessibilityRenderObject::index(const VisiblePosition& position) const
if (!node)
return -1;
- for (RenderObject* renderer = node->renderer(); renderer && renderer->element(); renderer = renderer->parent()) {
+ for (RenderObject* renderer = node->renderer(); renderer && renderer->node(); renderer = renderer->parent()) {
if (renderer == m_renderer)
return indexForVisiblePosition(position);
}
@@ -1802,7 +1852,7 @@ PlainTextRange AccessibilityRenderObject::doAXRangeForLine(unsigned lineNumber)
// starting at an empty line. The resulting selection in that case
// will be a caret at visiblePos.
SelectionController selection;
- selection.setSelection(Selection(visiblePos));
+ selection.setSelection(VisibleSelection(visiblePos));
selection.modify(SelectionController::EXTEND, SelectionController::LEFT, LineBoundary);
selection.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary);
@@ -1875,7 +1925,8 @@ AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const Int
RenderLayer* layer = toRenderBox(m_renderer)->layer();
- HitTestRequest request(true, true);
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
HitTestResult hitTestResult = HitTestResult(point);
layer->hitTest(request, hitTestResult);
if (!hitTestResult.innerNode())
@@ -1885,7 +1936,7 @@ AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const Int
if (!obj)
return 0;
- AccessibilityObject *result = obj->document()->axObjectCache()->get(obj);
+ AccessibilityObject *result = obj->document()->axObjectCache()->getOrCreate(obj);
if (obj->isListBox())
return static_cast<AccessibilityListBox*>(result)->doAccessibilityHitTest(point);
@@ -1912,7 +1963,7 @@ AccessibilityObject* AccessibilityRenderObject::focusedUIElement() const
if (!focusedNodeRenderer)
return 0;
- AccessibilityObject* obj = focusedNodeRenderer->document()->axObjectCache()->get(focusedNodeRenderer);
+ AccessibilityObject* obj = focusedNodeRenderer->document()->axObjectCache()->getOrCreate(focusedNodeRenderer);
if (obj->shouldFocusActiveDescendant()) {
if (AccessibilityObject* descendant = obj->activeDescendant())
@@ -1957,9 +2008,9 @@ bool AccessibilityRenderObject::shouldFocusActiveDescendant() const
AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
{
- if (renderer()->element() && !renderer()->element()->isElementNode())
+ if (renderer()->node() && !renderer()->node()->isElementNode())
return 0;
- Element* element = static_cast<Element*>(renderer()->element());
+ Element* element = static_cast<Element*>(renderer()->node());
String activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr).string();
if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
@@ -1969,7 +2020,7 @@ AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
if (!target)
return 0;
- AccessibilityObject* obj = renderer()->document()->axObjectCache()->get(target->renderer());
+ AccessibilityObject* obj = renderer()->document()->axObjectCache()->getOrCreate(target->renderer());
if (obj->isAccessibilityRenderObject())
// an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification
return obj;
@@ -1979,7 +2030,7 @@ AccessibilityObject* AccessibilityRenderObject::activeDescendant() const
void AccessibilityRenderObject::handleActiveDescendantChanged()
{
- Element* element = static_cast<Element*>(renderer()->element());
+ Element* element = static_cast<Element*>(renderer()->node());
if (!element)
return;
Document* doc = renderer()->document();
@@ -1994,9 +2045,9 @@ void AccessibilityRenderObject::handleActiveDescendantChanged()
AccessibilityObject* AccessibilityRenderObject::observableObject() const
{
- for (RenderObject* renderer = m_renderer; renderer && renderer->element(); renderer = renderer->parent()) {
- if (renderer->isTextField() || renderer->isTextArea())
- return renderer->document()->axObjectCache()->get(renderer);
+ for (RenderObject* renderer = m_renderer; renderer && renderer->node(); renderer = renderer->parent()) {
+ if (renderer->isTextControl())
+ return renderer->document()->axObjectCache()->getOrCreate(renderer);
}
return 0;
@@ -2089,7 +2140,7 @@ AccessibilityRole AccessibilityRenderObject::roleValue() const
if (!m_renderer)
return UnknownRole;
- Node* node = m_renderer->element();
+ Node* node = m_renderer->node();
AccessibilityRole ariaRole = ariaRoleAttribute();
if (ariaRole != UnknownRole)
return ariaRole;
@@ -2138,7 +2189,7 @@ AccessibilityRole AccessibilityRenderObject::roleValue() const
if (m_renderer->isMenuList())
return PopUpButtonRole;
- if (headingLevel(m_renderer->element()) != 0)
+ if (headingLevel(m_renderer->node()) != 0)
return HeadingRole;
if (node && node->hasTagName(ddTag))
@@ -2178,12 +2229,18 @@ bool AccessibilityRenderObject::ariaRoleHasPresentationalChildren() const
bool AccessibilityRenderObject::canSetFocusAttribute() const
{
+ ASSERT(m_renderer);
+
// NOTE: It would be more accurate to ask the document whether setFocusedNode() would
// do anything. For example, it setFocusedNode() will do nothing if the current focused
// node will not relinquish the focus.
- if (!m_renderer->element() || !m_renderer->element()->isEnabled())
+ if (!m_renderer->node() || !m_renderer->node()->isElementNode())
return false;
-
+
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(m_renderer->node()));
+ if (formControlElement && !formControlElement->isEnabled())
+ return false;
+
switch (roleValue()) {
case WebCoreLinkRole:
case ImageMapLinkRole:
@@ -2219,13 +2276,15 @@ void AccessibilityRenderObject::childrenChanged()
markChildrenDirty();
- // this object may not be accessible (and thus may not appear
+ // This object may not be accessible (and thus may not appear
// in the hierarchy), which means we need to go up the parent
// chain and mark the parent's dirty. Ideally, we would want
// to only access the next object that is not ignored, but
// asking an element if it's ignored can lead to an examination of the
- // render tree which is dangerous.
- for (AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
+ // render tree which is dangerous.
+ // Only parents that already exist must be retrieved, otherwise objects can be created
+ // at bad times
+ for (AccessibilityObject* parent = parentObjectIfExists(); parent; parent = parent->parentObjectIfExists()) {
if (parent->isAccessibilityRenderObject())
static_cast<AccessibilityRenderObject *>(parent)->markChildrenDirty();
}
@@ -2291,13 +2350,13 @@ void AccessibilityRenderObject::addChildren()
// for a RenderImage, add the <area> elements as individual accessibility objects
if (m_renderer->isRenderImage()) {
- HTMLMapElement* map = static_cast<RenderImage*>(m_renderer)->imageMap();
+ HTMLMapElement* map = toRenderImage(m_renderer)->imageMap();
if (map) {
for (Node* current = map->firstChild(); current; current = current->traverseNextNode(map)) {
// add an <area> element for this child if it has a link
if (current->isLink()) {
- AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(m_renderer->document()->axObjectCache()->get(ImageMapLinkRole));
+ AccessibilityImageMapLink* areaObject = static_cast<AccessibilityImageMapLink*>(m_renderer->document()->axObjectCache()->getOrCreate(ImageMapLinkRole));
areaObject->setHTMLAreaElement(static_cast<HTMLAreaElement*>(current));
areaObject->setHTMLMapElement(map);
areaObject->setParent(this);
@@ -2314,7 +2373,7 @@ void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildre
AccessibilityObject* child = firstChild();
bool isMultiselectable = false;
- Element* element = static_cast<Element*>(renderer()->element());
+ Element* element = static_cast<Element*>(renderer()->node());
if (!element || !element->isElementNode()) // do this check to ensure safety of static_cast above
return;
@@ -2328,7 +2387,7 @@ void AccessibilityRenderObject::ariaListboxSelectedChildren(AccessibilityChildre
if (child->isAccessibilityRenderObject())
childRenderer = static_cast<AccessibilityRenderObject*>(child)->renderer();
if (childRenderer && ariaRole == ListBoxOptionRole) {
- Element* childElement = static_cast<Element*>(childRenderer->element());
+ Element* childElement = static_cast<Element*>(childRenderer->node());
if (childElement && childElement->isElementNode()) { // do this check to ensure safety of static_cast above
String selectedAttrString = childElement->getAttribute("aria-selected").string();
if (equalIgnoringCase(selectedAttrString, "true")) {
@@ -2378,15 +2437,6 @@ void AccessibilityRenderObject::visibleChildren(AccessibilityChildrenVector& res
return ariaListboxVisibleChildren(result);
}
-void AccessibilityRenderObject::removeAXObjectID()
-{
- if (!m_id)
- return;
-#if PLATFORM(MAC)
- m_renderer->document()->axObjectCache()->removeAXID(this);
-#endif
-}
-
const String& AccessibilityRenderObject::actionVerb() const
{
// FIXME: Need to add verbs for select elements.
diff --git a/WebCore/page/AccessibilityRenderObject.h b/WebCore/page/AccessibilityRenderObject.h
index 03ba1db..5370eac 100644
--- a/WebCore/page/AccessibilityRenderObject.h
+++ b/WebCore/page/AccessibilityRenderObject.h
@@ -51,7 +51,7 @@ class RenderObject;
class RenderListBox;
class RenderTextControl;
class RenderView;
-class Selection;
+class VisibleSelection;
class String;
class Widget;
@@ -125,6 +125,7 @@ public:
virtual AccessibilityObject* previousSibling() const;
virtual AccessibilityObject* nextSibling() const;
virtual AccessibilityObject* parentObject() const;
+ virtual AccessibilityObject* parentObjectIfExists() const;
virtual AccessibilityObject* observableObject() const;
virtual void linkedUIElements(AccessibilityChildrenVector&) const;
virtual AccessibilityObject* titleUIElement() const;
@@ -156,7 +157,7 @@ public:
virtual KURL url() const;
virtual PlainTextRange selectedTextRange() const;
- virtual Selection selection() const;
+ virtual VisibleSelection selection() const;
virtual String stringValue() const;
virtual String ariaAccessiblityName(const String&) const;
virtual String ariaLabeledByAttribute() const;
@@ -218,7 +219,6 @@ protected:
mutable bool m_childrenDirty;
void setRenderObject(RenderObject* renderer) { m_renderer = renderer; }
- virtual void removeAXObjectID();
virtual bool isDetached() const { return !m_renderer; }
diff --git a/WebCore/page/AccessibilityTable.cpp b/WebCore/page/AccessibilityTable.cpp
index 9409283..2b60d43 100644
--- a/WebCore/page/AccessibilityTable.cpp
+++ b/WebCore/page/AccessibilityTable.cpp
@@ -93,7 +93,7 @@ bool AccessibilityTable::isTableExposableThroughAccessibility()
// Unfortunately, there is no good way to determine the difference
// between a "layout" table and a "data" table
- Node* tableNode = table->element();
+ Node* tableNode = table->node();
if (!tableNode || !tableNode->hasTagName(tableTag))
return false;
@@ -139,7 +139,7 @@ bool AccessibilityTable::isTableExposableThroughAccessibility()
RenderTableCell* cell = firstBody->cellAt(row, col).cell;
if (!cell)
continue;
- Node* cellNode = cell->element();
+ Node* cellNode = cell->node();
if (!cellNode)
continue;
@@ -241,7 +241,7 @@ void AccessibilityTable::addChildren()
if (!cell)
continue;
- AccessibilityObject* rowObject = axCache->get(cell->parent());
+ AccessibilityObject* rowObject = axCache->getOrCreate(cell->parent());
if (!rowObject->isTableRow())
continue;
@@ -264,7 +264,7 @@ void AccessibilityTable::addChildren()
// make the columns based on the number of columns in the first body
unsigned length = initialTableSection->numColumns();
for (unsigned i = 0; i < length; ++i) {
- AccessibilityTableColumn* column = static_cast<AccessibilityTableColumn*>(axCache->get(ColumnRole));
+ AccessibilityTableColumn* column = static_cast<AccessibilityTableColumn*>(axCache->getOrCreate(ColumnRole));
column->setColumnIndex((int)i);
column->setParentTable(this);
m_columns.append(column);
@@ -281,7 +281,7 @@ AccessibilityObject* AccessibilityTable::headerContainer()
if (m_headerContainer)
return m_headerContainer;
- m_headerContainer = static_cast<AccessibilityTableHeaderContainer*>(axObjectCache()->get(TableHeaderContainerRole));
+ m_headerContainer = static_cast<AccessibilityTableHeaderContainer*>(axObjectCache()->getOrCreate(TableHeaderContainerRole));
m_headerContainer->setParentTable(this);
return m_headerContainer;
@@ -386,11 +386,13 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
unsigned rowOffset = 0;
while (tableSection) {
- rowCount += tableSection->numRows();
+ unsigned numRows = tableSection->numRows();
unsigned numCols = tableSection->numColumns();
- if (row < rowCount && column < numCols) {
- int sectionSpecificRow = row - rowOffset;
+ rowCount += numRows;
+
+ unsigned sectionSpecificRow = row - rowOffset;
+ if (row < rowCount && column < numCols && sectionSpecificRow < numRows) {
cell = tableSection->cellAt(sectionSpecificRow, column).cell;
// we didn't find the cell, which means there's spanning happening
@@ -422,9 +424,9 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
if (cell)
break;
- rowOffset += rowCount;
+ rowOffset += numRows;
// we didn't find anything between the rows we should have
- if (row < rowOffset)
+ if (row < rowCount)
break;
tableSection = table->sectionBelow(tableSection, true);
}
@@ -432,7 +434,7 @@ AccessibilityTableCell* AccessibilityTable::cellForColumnAndRow(unsigned column,
if (!cell)
return 0;
- AccessibilityObject* cellObject = axObjectCache()->get(cell);
+ AccessibilityObject* cellObject = axObjectCache()->getOrCreate(cell);
ASSERT(cellObject->isTableCell());
return static_cast<AccessibilityTableCell*>(cellObject);
@@ -464,7 +466,7 @@ String AccessibilityTable::title() const
return title;
// see if there is a caption
- Node *tableElement = m_renderer->element();
+ Node* tableElement = m_renderer->node();
if (tableElement) {
HTMLTableCaptionElement* caption = static_cast<HTMLTableElement*>(tableElement)->caption();
if (caption)
diff --git a/WebCore/page/AccessibilityTableCell.cpp b/WebCore/page/AccessibilityTableCell.cpp
index ff82811..f7cbe98 100644
--- a/WebCore/page/AccessibilityTableCell.cpp
+++ b/WebCore/page/AccessibilityTableCell.cpp
@@ -67,7 +67,7 @@ bool AccessibilityTableCell::isTableCell() const
if (!m_renderer)
return false;
- AccessibilityObject* renderTable = axObjectCache()->get(static_cast<RenderTableCell*>(m_renderer)->table());
+ AccessibilityObject* renderTable = axObjectCache()->getOrCreate(static_cast<RenderTableCell*>(m_renderer)->table());
if (!renderTable->isDataTable())
return false;
@@ -147,11 +147,11 @@ AccessibilityObject* AccessibilityTableCell::titleUIElement() const
if (!headerCell || headerCell == renderCell)
return 0;
- Node* cellElement = headerCell->element();
+ Node* cellElement = headerCell->node();
if (!cellElement || !cellElement->hasTagName(thTag))
return 0;
- return axObjectCache()->get(headerCell);
+ return axObjectCache()->getOrCreate(headerCell);
}
} // namespace WebCore
diff --git a/WebCore/page/AccessibilityTableColumn.cpp b/WebCore/page/AccessibilityTableColumn.cpp
index 6e03af9..ff330c0 100644
--- a/WebCore/page/AccessibilityTableColumn.cpp
+++ b/WebCore/page/AccessibilityTableColumn.cpp
@@ -124,7 +124,7 @@ AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTabl
if ((testCell->col() + (testCell->colSpan()-1)) < m_columnIndex)
break;
- Node* node = testCell->element();
+ Node* node = testCell->node();
if (!node)
continue;
@@ -137,7 +137,7 @@ AccessibilityObject* AccessibilityTableColumn::headerObjectForSection(RenderTabl
if (!cell)
return 0;
- return m_parentTable->axObjectCache()->get(cell);
+ return m_parentTable->axObjectCache()->getOrCreate(cell);
}
void AccessibilityTableColumn::addChildren()
diff --git a/WebCore/page/AccessibilityTableRow.cpp b/WebCore/page/AccessibilityTableRow.cpp
index caccff5..e67fcfe 100644
--- a/WebCore/page/AccessibilityTableRow.cpp
+++ b/WebCore/page/AccessibilityTableRow.cpp
@@ -70,7 +70,7 @@ bool AccessibilityTableRow::isTableRow() const
if (!m_renderer)
return true;
- AccessibilityObject* renderTable = axObjectCache()->get(static_cast<RenderTableRow*>(m_renderer)->table());
+ AccessibilityObject* renderTable = axObjectCache()->getOrCreate(static_cast<RenderTableRow*>(m_renderer)->table());
if (!renderTable->isDataTable())
return false;
@@ -100,7 +100,7 @@ AccessibilityObject* AccessibilityTableRow::headerObject()
if (!cellRenderer)
return 0;
- Node* cellNode = cellRenderer->element();
+ Node* cellNode = cellRenderer->node();
if (!cellNode || !cellNode->hasTagName(thTag))
return 0;
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp
index 4698aa5..b37ebc4 100644
--- a/WebCore/page/Chrome.cpp
+++ b/WebCore/page/Chrome.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
@@ -28,6 +28,7 @@
#include "FloatRect.h"
#include "Frame.h"
#include "FrameTree.h"
+#include "Geolocation.h"
#include "HTMLFormElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
@@ -387,6 +388,16 @@ void Chrome::enableSuddenTermination()
m_client->enableSuddenTermination();
}
+void Chrome::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
+{
+ // Defer loads in case the client method runs a new event loop that would
+ // otherwise cause the load to continue while we're in the middle of executing JavaScript.
+ PageGroupLoadDeferrer deferrer(m_page, true);
+
+ ASSERT(frame);
+ m_client->requestGeolocationPermissionForFrame(frame, geolocation);
+}
+
void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
{
m_client->runOpenPanel(frame, fileChooser);
@@ -457,10 +468,8 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
m_deferredFrames.append(otherPage->mainFrame());
#if !PLATFORM(MAC)
- for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (Document* document = frame->document())
- document->suspendActiveDOMObjects();
- }
+ for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->document()->suspendActiveDOMObjects();
#endif
}
}
@@ -478,10 +487,8 @@ PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
page->setDefersLoading(false);
#if !PLATFORM(MAC)
- for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (Document* document = frame->document())
- document->resumeActiveDOMObjects();
- }
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->document()->resumeActiveDOMObjects();
#endif
}
}
diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h
index 47b912d..ab0b42f 100644
--- a/WebCore/page/Chrome.h
+++ b/WebCore/page/Chrome.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -38,6 +38,7 @@ namespace WebCore {
class ContextMenu;
class FloatRect;
class Frame;
+ class Geolocation;
class HitTestResult;
class IntRect;
class Page;
@@ -119,6 +120,8 @@ namespace WebCore {
void enableSuddenTermination();
void disableSuddenTermination();
+ void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
+
void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
#if PLATFORM(MAC)
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 5d90b2f..6f82bc1 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -42,16 +42,21 @@ namespace WebCore {
class FileChooser;
class FloatRect;
class Frame;
+ class Geolocation;
class HitTestResult;
class IntRect;
class Node;
class Page;
class String;
class Widget;
-
+
struct FrameLoadRequest;
struct WindowFeatures;
+#if USE(ACCELERATED_COMPOSITING)
+ class GraphicsLayer;
+#endif
+
class ChromeClient {
public:
virtual void chromeDestroyed() = 0;
@@ -148,12 +153,24 @@ namespace WebCore {
float value, float proportion, ScrollbarControlPartMask);
virtual bool paintCustomScrollCorner(GraphicsContext*, const FloatRect&);
+ // This is an asynchronous call. The ChromeClient can display UI asking the user for permission
+ // to use Geolococation. The ChromeClient must call Geolocation::setShouldClearCache() appropriately.
+ virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) { }
+
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
// Notification that the given form element has changed. This function
// will be called frequently, so handling should be very fast.
virtual void formStateDidChange(const Node*) = 0;
+#if USE(ACCELERATED_COMPOSITING)
+ // Pass 0 as the GraphicsLayer to detatch the root layer.
+ virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) { }
+ // Sets a flag to specify that the next time content is drawn to the window,
+ // the changes appear on the screen in synchrony with updates to GraphicsLayers.
+ virtual void setNeedsOneShotDrawingSynchronization() { }
+#endif
+
#if PLATFORM(MAC)
virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; }
diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp
index 8755f0e..33128ea 100644
--- a/WebCore/page/Console.cpp
+++ b/WebCore/page/Console.cpp
@@ -68,7 +68,7 @@ static void printSourceURLAndLine(const String& sourceURL, unsigned lineNumber)
}
}
-static bool getFirstArgumentAsString(const ScriptCallFrame& callFrame, String& result, bool checkForNullOrUndefined = false)
+static bool getFirstArgumentAsString(ScriptState* scriptState, const ScriptCallFrame& callFrame, String& result, bool checkForNullOrUndefined = false)
{
if (!callFrame.argumentCount())
return false;
@@ -77,7 +77,8 @@ static bool getFirstArgumentAsString(const ScriptCallFrame& callFrame, String& r
if (checkForNullOrUndefined && (value.isNull() || value.isUndefined()))
return false;
- return value.getString(result);
+ result = value.toString(scriptState);
+ return true;
}
static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel level)
@@ -99,12 +100,13 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel
case CSSMessageSource:
sourceString = "CSS";
break;
- default:
- ASSERT_NOT_REACHED();
- // Fall thru.
case OtherMessageSource:
sourceString = "OTHER";
break;
+ default:
+ ASSERT_NOT_REACHED();
+ sourceString = "UNKNOWN";
+ break;
}
const char* levelString;
@@ -112,9 +114,6 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel
case TipMessageLevel:
levelString = "TIP";
break;
- default:
- ASSERT_NOT_REACHED();
- // Fall thru.
case LogMessageLevel:
levelString = "LOG";
break;
@@ -124,6 +123,22 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel
case ErrorMessageLevel:
levelString = "ERROR";
break;
+ case ObjectMessageLevel:
+ levelString = "OBJECT";
+ break;
+ case TraceMessageLevel:
+ levelString = "TRACE";
+ break;
+ case StartGroupMessageLevel:
+ levelString = "START GROUP";
+ break;
+ case EndGroupMessageLevel:
+ levelString = "END GROUP";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ levelString = "UNKNOWN";
+ break;
}
printf("%s %s:", sourceString, levelString);
@@ -160,7 +175,7 @@ void Console::addMessage(MessageLevel level, ScriptCallStack* callStack, bool ac
return;
String message;
- if (getFirstArgumentAsString(lastCaller, message))
+ if (getFirstArgumentAsString(callStack->state(), lastCaller, message))
page->chrome()->client()->addMessageToConsole(message, lastCaller.lineNumber(), lastCaller.sourceURL().prettyURL());
page->inspectorController()->addMessageToConsole(JSMessageSource, level, callStack);
@@ -207,7 +222,8 @@ void Console::dir(ScriptCallStack* callStack)
void Console::dirxml(ScriptCallStack* callStack)
{
- addMessage(NodeMessageLevel, callStack);
+ // The standard behavior of our console.log will print the DOM tree for nodes.
+ log(callStack);
}
void Console::trace(ScriptCallStack* callStack)
@@ -243,7 +259,7 @@ void Console::count(ScriptCallStack* callStack)
// Follow Firebug's behavior of counting with null and undefined title in
// the same bucket as no argument
String title;
- getFirstArgumentAsString(lastCaller, title);
+ getFirstArgumentAsString(callStack->state(), lastCaller, title);
page->inspectorController()->count(title, lastCaller.lineNumber(), lastCaller.sourceURL().string());
}
@@ -256,13 +272,15 @@ void Console::profile(const JSC::UString& title, ScriptCallStack* callStack)
if (!page)
return;
- if (title.isNull())
- return;
-
// FIXME: log a console message when profiling is disabled.
if (!page->inspectorController()->profilerEnabled())
return;
+ if (title.isNull()) { // no title so give it the next user initiated profile title.
+ page->inspectorController()->startUserInitiatedProfiling(0);
+ return;
+ }
+
JSC::Profiler::profiler()->startProfiling(callStack->state(), title);
}
diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h
index 7301fc9..2a24a2a 100644
--- a/WebCore/page/Console.h
+++ b/WebCore/page/Console.h
@@ -64,8 +64,8 @@ namespace WebCore {
LogMessageLevel,
WarningMessageLevel,
ErrorMessageLevel,
+ // FIXME: the remaining levels should become a new MessageType enum.
ObjectMessageLevel,
- NodeMessageLevel,
TraceMessageLevel,
StartGroupMessageLevel,
EndGroupMessageLevel
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index 47a0663..522e939 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -83,15 +83,10 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
if (!event->isMouseEvent())
return;
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
- IntPoint point = IntPoint(mouseEvent->pageX(), mouseEvent->pageY());
- HitTestResult result(point);
+ HitTestResult result(mouseEvent->absoluteLocation());
- if (Frame* frame = event->target()->toNode()->document()->frame()) {
- float zoomFactor = frame->pageZoomFactor();
- point.setX(static_cast<int>(point.x() * zoomFactor));
- point.setY(static_cast<int>(point.y() * zoomFactor));
- result = frame->eventHandler()->hitTestResultAtPoint(point, false);
- }
+ if (Frame* frame = event->target()->toNode()->document()->frame())
+ result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
if (!result.innerNonSharedNode())
return;
@@ -193,14 +188,14 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
#endif
case ContextMenuItemTagSpellingGuess:
ASSERT(frame->selectedText().length());
- if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toRange().get(),
+ 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);
applyCommand(command);
- frame->revealSelection(RenderLayer::gAlignToEdgeIfNeeded);
+ frame->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
}
break;
case ContextMenuItemTagIgnoreSpelling:
@@ -238,7 +233,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
break;
case ContextMenuItemTagStartSpeaking: {
ExceptionCode ec;
- RefPtr<Range> selectedRange = frame->selection()->toRange();
+ RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
if (!selectedRange || selectedRange->collapsed(ec)) {
Document* document = result.innerNonSharedNode()->document();
selectedRange = document->createRange();
diff --git a/WebCore/page/Coordinates.cpp b/WebCore/page/Coordinates.cpp
new file mode 100644
index 0000000..637a8c2
--- /dev/null
+++ b/WebCore/page/Coordinates.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 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 "Coordinates.h"
+
+namespace WebCore {
+
+String Coordinates::toString() const
+{
+ return String::format("coordinate(%.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.6lg)",
+ m_latitude, m_longitude, m_altitude, m_accuracy,
+ m_altitudeAccuracy, m_heading, m_speed);
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/Coordinates.h b/WebCore/page/Coordinates.h
new file mode 100644
index 0000000..743b04d
--- /dev/null
+++ b/WebCore/page/Coordinates.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Coordinates_h
+#define Coordinates_h
+
+#include "Event.h"
+#include "PlatformString.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+typedef int ExceptionCode;
+
+class Coordinates : public RefCounted<Coordinates> {
+public:
+ static PassRefPtr<Coordinates> create(double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy, double heading, double speed) { return adoptRef(new Coordinates(latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, speed)); }
+
+ double latitude() const { return m_latitude; }
+ double longitude() const { return m_longitude; }
+ double altitude() const { return m_altitude; }
+ double accuracy() const { return m_accuracy; }
+ double altitudeAccuracy() const { return m_altitudeAccuracy; }
+ double heading() const { return m_heading; }
+ double speed() const { return m_speed; }
+
+ String toString() const;
+
+private:
+ Coordinates(double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy, double heading, double speed)
+ : m_latitude(latitude)
+ , m_longitude(longitude)
+ , m_altitude(altitude)
+ , m_accuracy(accuracy)
+ , m_altitudeAccuracy(altitudeAccuracy)
+ , m_heading(heading)
+ , m_speed(speed)
+ {
+ }
+
+ double m_latitude;
+ double m_longitude;
+ double m_altitude;
+ double m_accuracy;
+ double m_altitudeAccuracy;
+ double m_heading;
+ double m_speed;
+};
+
+} // namespace WebCore
+
+#endif // Coordinates_h
diff --git a/WebCore/page/Coordinates.idl b/WebCore/page/Coordinates.idl
new file mode 100644
index 0000000..6318212
--- /dev/null
+++ b/WebCore/page/Coordinates.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module core {
+
+ interface Coordinates {
+ readonly attribute double latitude;
+ readonly attribute double longitude;
+ readonly attribute double altitude;
+ readonly attribute double accuracy;
+ readonly attribute double altitudeAccuracy;
+ readonly attribute double heading;
+ readonly attribute double speed;
+
+#if defined(LANGUAGE_JAVASCRIPT)
+ [DontEnum] DOMString toString();
+#endif
+ };
+}
diff --git a/WebCore/page/DOMSelection.cpp b/WebCore/page/DOMSelection.cpp
index 5dab325..86fe911 100644
--- a/WebCore/page/DOMSelection.cpp
+++ b/WebCore/page/DOMSelection.cpp
@@ -56,76 +56,89 @@ void DOMSelection::disconnectFrame()
m_frame = 0;
}
-Node* DOMSelection::anchorNode() const
+const VisibleSelection& DOMSelection::visibleSelection() const
{
- if (!m_frame)
- return 0;
+ ASSERT(m_frame);
+ return m_frame->selection()->selection();
+}
- const Selection& selection = m_frame->selection()->selection();
+static Position anchorPosition(const VisibleSelection& selection)
+{
Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
- anchor = rangeCompliantEquivalent(anchor);
- return anchor.node();
+ return rangeCompliantEquivalent(anchor);
}
-Node* DOMSelection::baseNode() const
+static Position focusPosition(const VisibleSelection& selection)
+{
+ Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
+ return rangeCompliantEquivalent(focus);
+}
+
+static Position basePosition(const VisibleSelection& selection)
+{
+ return rangeCompliantEquivalent(selection.base());
+}
+
+static Position extentPosition(const VisibleSelection& selection)
+{
+ return rangeCompliantEquivalent(selection.extent());
+}
+
+Node* DOMSelection::anchorNode() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selection()->selection().base()).node();
+ return anchorPosition(visibleSelection()).node();
}
int DOMSelection::anchorOffset() const
{
if (!m_frame)
return 0;
-
- const Selection& selection = m_frame->selection()->selection();
- Position anchor = selection.isBaseFirst() ? selection.start() : selection.end();
- anchor = rangeCompliantEquivalent(anchor);
- return anchor.offset();
+ return anchorPosition(visibleSelection()).m_offset;
}
-int DOMSelection::baseOffset() const
+Node* DOMSelection::focusNode() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selection()->selection().base()).offset();
+ return focusPosition(visibleSelection()).node();
}
-Node* DOMSelection::focusNode() const
+int DOMSelection::focusOffset() const
{
if (!m_frame)
return 0;
-
- const Selection& selection = m_frame->selection()->selection();
- Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
- focus = rangeCompliantEquivalent(focus);
- return focus.node();
+ return focusPosition(visibleSelection()).m_offset;
}
-Node* DOMSelection::extentNode() const
+Node* DOMSelection::baseNode() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selection()->selection().extent()).node();
+ return basePosition(visibleSelection()).node();
}
-int DOMSelection::focusOffset() const
+int DOMSelection::baseOffset() const
{
if (!m_frame)
return 0;
+ return basePosition(visibleSelection()).m_offset;
+}
- const Selection& selection = m_frame->selection()->selection();
- Position focus = selection.isBaseFirst() ? selection.end() : selection.start();
- focus = rangeCompliantEquivalent(focus);
- return focus.offset();
+
+Node* DOMSelection::extentNode() const
+{
+ if (!m_frame)
+ return 0;
+ return extentPosition(visibleSelection()).node();
}
int DOMSelection::extentOffset() const
{
if (!m_frame)
return 0;
- return rangeCompliantEquivalent(m_frame->selection()->selection().extent()).offset();
+ return extentPosition(visibleSelection()).m_offset;
}
bool DOMSelection::isCollapsed() const
@@ -142,6 +155,9 @@ String DOMSelection::type() const
SelectionController* selection = m_frame->selection();
+ // This is a WebKit DOM extension, incompatible with an IE extension
+ // IE has this same attribute, but returns "none", "text" and "control"
+ // http://msdn.microsoft.com/en-us/library/ms534692(VS.85).aspx
if (selection->isNone())
return "None";
if (selection->isCaret())
@@ -173,7 +189,7 @@ void DOMSelection::collapseToEnd()
if (!m_frame)
return;
- const Selection& selection = m_frame->selection()->selection();
+ const VisibleSelection& selection = m_frame->selection()->selection();
m_frame->selection()->moveTo(VisiblePosition(selection.end(), DOWNSTREAM));
}
@@ -182,7 +198,7 @@ void DOMSelection::collapseToStart()
if (!m_frame)
return;
- const Selection& selection = m_frame->selection()->selection();
+ const VisibleSelection& selection = m_frame->selection()->selection();
m_frame->selection()->moveTo(VisiblePosition(selection.start(), DOWNSTREAM));
}
@@ -298,8 +314,11 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
return 0;
}
- const Selection& selection = m_frame->selection()->selection();
- return selection.toRange();
+ // If you're hitting this, you've added broken multi-range selection support
+ ASSERT(rangeCount() == 1);
+
+ const VisibleSelection& selection = m_frame->selection()->selection();
+ return selection.firstRange();
}
void DOMSelection::removeAllRanges()
@@ -319,31 +338,31 @@ void DOMSelection::addRange(Range* r)
SelectionController* selection = m_frame->selection();
if (selection->isNone()) {
- selection->setSelection(Selection(r));
+ selection->setSelection(VisibleSelection(r));
return;
}
- RefPtr<Range> range = selection->selection().toRange();
+ RefPtr<Range> range = selection->selection().toNormalizedRange();
ExceptionCode ec = 0;
if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), ec) == -1) {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), ec) > -1) {
if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), ec) == -1)
// The original range and r intersect.
- selection->setSelection(Selection(r->startPosition(), range->endPosition(), DOWNSTREAM));
+ selection->setSelection(VisibleSelection(r->startPosition(), range->endPosition(), DOWNSTREAM));
else
// r contains the original range.
- selection->setSelection(Selection(r));
+ selection->setSelection(VisibleSelection(r));
}
} else {
// We don't support discontiguous selection. We don't do anything if r and range don't intersect.
if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), ec) < 1) {
if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), ec) == -1)
// The original range contains r.
- selection->setSelection(Selection(range.get()));
+ selection->setSelection(VisibleSelection(range.get()));
else
// The original range and r intersect.
- selection->setSelection(Selection(range->startPosition(), r->endPosition(), DOWNSTREAM));
+ selection->setSelection(VisibleSelection(range->startPosition(), r->endPosition(), DOWNSTREAM));
}
}
}
@@ -361,7 +380,7 @@ void DOMSelection::deleteFromDocument()
if (isCollapsed())
selection->modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity);
- RefPtr<Range> selectedRange = selection->selection().toRange();
+ RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
ExceptionCode ec = 0;
selectedRange->deleteContents(ec);
@@ -383,7 +402,7 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
Node* parentNode = n->parentNode();
unsigned nodeIndex = n->nodeIndex();
- RefPtr<Range> selectedRange = selection->selection().toRange();
+ RefPtr<Range> selectedRange = selection->selection().toNormalizedRange();
if (!parentNode)
return false;
@@ -418,7 +437,7 @@ String DOMSelection::toString()
if (!m_frame)
return String();
- return plainText(m_frame->selection()->selection().toRange().get());
+ return plainText(m_frame->selection()->selection().toNormalizedRange().get());
}
} // namespace WebCore
diff --git a/WebCore/page/DOMSelection.h b/WebCore/page/DOMSelection.h
index fd8d1fc..6a914d6 100644
--- a/WebCore/page/DOMSelection.h
+++ b/WebCore/page/DOMSelection.h
@@ -40,6 +40,7 @@ namespace WebCore {
class Range;
class Node;
class String;
+ class VisibleSelection;
typedef int ExceptionCode;
@@ -88,12 +89,13 @@ namespace WebCore {
// Microsoft Selection Object API
void empty();
- //void clear();
- //TextRange *createRange();
private:
DOMSelection(Frame*);
-
+
+ // Convenience method for accessors, does not NULL check m_frame.
+ const VisibleSelection& visibleSelection() const;
+
Frame* m_frame;
};
diff --git a/WebCore/page/DOMSelection.idl b/WebCore/page/DOMSelection.idl
index 85d23bf..a54f9e4 100644
--- a/WebCore/page/DOMSelection.idl
+++ b/WebCore/page/DOMSelection.idl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,35 +29,30 @@
module window {
+ // This is based off of Mozilla's Selection interface
+ // https://developer.mozilla.org/En/DOM/Selection
interface DOMSelection {
readonly attribute Node anchorNode;
readonly attribute long anchorOffset;
readonly attribute Node focusNode;
readonly attribute long focusOffset;
- readonly attribute Node baseNode;
- readonly attribute long baseOffset;
- readonly attribute Node extentNode;
- readonly attribute long extentOffset;
+
readonly attribute boolean isCollapsed;
- readonly attribute DOMString type;
readonly attribute long rangeCount;
void collapse(in Node node, in long index)
raises(DOMException);
void collapseToEnd();
void collapseToStart();
+
void deleteFromDocument();
boolean containsNode(in Node node, in boolean allowPartial);
void selectAllChildren(in Node node)
raises(DOMException);
- void empty();
- void setBaseAndExtent(in Node baseNode, in long baseOffset, in Node extentNode, in long extentOffset)
- raises(DOMException);
- void setPosition(in Node node, in long offset)
- raises(DOMException);
- void modify(in DOMString alter, in DOMString direction, in DOMString granularity);
+
void extend(in Node node, in long offset)
raises(DOMException);
+
Range getRangeAt(in long index)
raises(DOMException);
void removeAllRanges();
@@ -65,6 +61,26 @@ module window {
#if defined(LANGUAGE_JAVASCRIPT)
[DontEnum] DOMString toString();
#endif
+
+ // WebKit extensions
+ readonly attribute Node baseNode;
+ readonly attribute long baseOffset;
+ readonly attribute Node extentNode;
+ readonly attribute long extentOffset;
+
+ // WebKit's "type" accessor returns "None", "Range" and "Caret"
+ // IE's type accessor returns "none", "text" and "control"
+ readonly attribute DOMString type;
+
+ void modify(in DOMString alter, in DOMString direction, in DOMString granularity);
+ void setBaseAndExtent(in Node baseNode, in long baseOffset, in Node extentNode, in long extentOffset)
+ raises(DOMException);
+ void setPosition(in Node node, in long offset)
+ raises(DOMException);
+
+ // IE extentions
+ // http://msdn.microsoft.com/en-us/library/ms535869(VS.85).aspx
+ void empty();
};
}
diff --git a/WebCore/page/DOMTimer.cpp b/WebCore/page/DOMTimer.cpp
index 911da71..1cc7730 100644
--- a/WebCore/page/DOMTimer.cpp
+++ b/WebCore/page/DOMTimer.cpp
@@ -27,7 +27,6 @@
#include "config.h"
#include "DOMTimer.h"
-#include "Document.h"
#include "ScheduledAction.h"
#include "ScriptExecutionContext.h"
#include <wtf/HashSet.h>
@@ -39,7 +38,7 @@ namespace WebCore {
static const int maxTimerNestingLevel = 5;
static const double oneMillisecond = 0.001;
-static const double minTimerInterval = 0.010; // 10 milliseconds
+double DOMTimer::s_minTimerInterval = 0.010; // 10 milliseconds
static int timerNestingLevel = 0;
@@ -58,18 +57,15 @@ DOMTimer::DOMTimer(ScriptExecutionContext* context, ScheduledAction* action, int
m_nestingLevel = timerNestingLevel + 1;
- // FIXME: Move the timeout map and API to ScriptExecutionContext to be able
- // to create timeouts from Workers.
- ASSERT(scriptExecutionContext() && scriptExecutionContext()->isDocument());
- static_cast<Document*>(scriptExecutionContext())->addTimeout(m_timeoutId, this);
+ scriptExecutionContext()->addTimeout(m_timeoutId, this);
double intervalMilliseconds = max(oneMillisecond, timeout * oneMillisecond);
// Use a minimum interval of 10 ms to match other browsers, but only once we've
// nested enough to notice that we're repeating.
// Faster timers might be "better", but they're incompatible.
- if (intervalMilliseconds < minTimerInterval && m_nestingLevel >= maxTimerNestingLevel)
- intervalMilliseconds = minTimerInterval;
+ if (intervalMilliseconds < s_minTimerInterval && m_nestingLevel >= maxTimerNestingLevel)
+ intervalMilliseconds = s_minTimerInterval;
if (singleShot)
startOneShot(intervalMilliseconds);
else
@@ -79,8 +75,7 @@ DOMTimer::DOMTimer(ScriptExecutionContext* context, ScheduledAction* action, int
DOMTimer::~DOMTimer()
{
if (scriptExecutionContext()) {
- ASSERT(scriptExecutionContext()->isDocument());
- static_cast<Document*>(scriptExecutionContext())->removeTimeout(m_timeoutId);
+ scriptExecutionContext()->removeTimeout(m_timeoutId);
}
}
@@ -100,8 +95,7 @@ void DOMTimer::removeById(ScriptExecutionContext* context, int timeoutId)
// respectively
if (timeoutId <= 0)
return;
- ASSERT(context && context->isDocument());
- delete static_cast<Document*>(context)->findTimeout(timeoutId);
+ delete context->findTimeout(timeoutId);
}
void DOMTimer::fired()
@@ -111,10 +105,10 @@ void DOMTimer::fired()
// Simple case for non-one-shot timers.
if (isActive()) {
- if (repeatInterval() && repeatInterval() < minTimerInterval) {
+ if (repeatInterval() && repeatInterval() < s_minTimerInterval) {
m_nestingLevel++;
if (m_nestingLevel >= maxTimerNestingLevel)
- augmentRepeatInterval(minTimerInterval - repeatInterval());
+ augmentRepeatInterval(s_minTimerInterval - repeatInterval());
}
// No access to member variables after this point, it can delete the timer.
diff --git a/WebCore/page/DOMTimer.h b/WebCore/page/DOMTimer.h
index 200b9b1..f6343fc 100644
--- a/WebCore/page/DOMTimer.h
+++ b/WebCore/page/DOMTimer.h
@@ -51,6 +51,12 @@ public:
virtual void suspend();
virtual void resume();
+ // The lowest allowable timer setting (in seconds, 0.001 == 1 ms).
+ // Default is 10ms.
+ // Chromium uses a non-default timeout.
+ static double minTimerInterval() { return s_minTimerInterval; }
+ static void setMinTimerInterval(double value) { s_minTimerInterval = value; }
+
private:
DOMTimer(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
virtual void fired();
@@ -60,6 +66,7 @@ private:
OwnPtr<ScheduledAction> m_action;
double m_nextFireInterval;
double m_repeatInterval;
+ static double s_minTimerInterval;
};
} // namespace WebCore
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 70ee79e..f6fde05 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -46,6 +46,7 @@
#include "FrameView.h"
#include "HTMLFrameOwnerElement.h"
#include "History.h"
+#include "InspectorController.h"
#include "Location.h"
#include "MessageEvent.h"
#include "Navigator.h"
@@ -56,6 +57,7 @@
#include "Screen.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#include "WebKitPoint.h"
#include <algorithm>
#include <wtf/MathExtras.h>
@@ -323,10 +325,10 @@ Storage* DOMWindow::sessionStorage() const
return 0;
Document* document = m_frame->document();
- if (!document)
- return 0;
RefPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
+ page->inspectorController()->didUseDOMStorage(storageArea.get(), false, m_frame);
+
m_sessionStorage = Storage::create(m_frame, storageArea.release());
return m_sessionStorage.get();
}
@@ -347,8 +349,10 @@ Storage* DOMWindow::localStorage() const
LocalStorage* localStorage = page->group().localStorage();
RefPtr<StorageArea> storageArea = localStorage ? localStorage->storageArea(document->securityOrigin()) : 0;
- if (storageArea)
+ if (storageArea) {
+ page->inspectorController()->didUseDOMStorage(storageArea.get(), true, m_frame);
m_localStorage = Storage::create(m_frame, storageArea.release());
+ }
return m_localStorage.get();
}
@@ -449,7 +453,20 @@ void DOMWindow::close()
if (!m_frame)
return;
- if (m_frame->loader()->openedByDOM() || m_frame->loader()->getHistoryLength() <= 1)
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ if (m_frame != page->mainFrame())
+ return;
+
+ Settings* settings = m_frame->settings();
+ bool allowScriptsToCloseWindows =
+ settings && settings->allowScriptsToCloseWindows();
+
+ if (m_frame->loader()->openedByDOM()
+ || m_frame->loader()->getHistoryLength() <= 1
+ || allowScriptsToCloseWindows)
m_frame->scheduleClose();
}
@@ -480,10 +497,7 @@ void DOMWindow::alert(const String& message)
if (!m_frame)
return;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateRendering();
+ m_frame->document()->updateRendering();
Page* page = m_frame->page();
if (!page)
@@ -497,10 +511,7 @@ bool DOMWindow::confirm(const String& message)
if (!m_frame)
return false;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateRendering();
+ m_frame->document()->updateRendering();
Page* page = m_frame->page();
if (!page)
@@ -514,10 +525,7 @@ String DOMWindow::prompt(const String& message, const String& defaultValue)
if (!m_frame)
return String();
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateRendering();
+ m_frame->document()->updateRendering();
Page* page = m_frame->page();
if (!page)
@@ -625,10 +633,7 @@ int DOMWindow::scrollX() const
if (!view)
return 0;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateLayoutIgnorePendingStylesheets();
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
return static_cast<int>(view->scrollX() / m_frame->pageZoomFactor());
}
@@ -649,10 +654,7 @@ int DOMWindow::scrollY() const
if (!view)
return 0;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateLayoutIgnorePendingStylesheets();
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
return static_cast<int>(view->scrollY() / m_frame->pageZoomFactor());
}
@@ -786,15 +788,32 @@ PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* elt, const String
return 0;
Document* doc = m_frame->document();
- ASSERT(doc);
- if (!doc)
- return 0;
if (!pseudoElt.isEmpty())
return doc->styleSelector()->pseudoStyleRulesForElement(elt, pseudoElt, authorOnly);
return doc->styleSelector()->styleRulesForElement(elt, authorOnly);
}
+PassRefPtr<WebKitPoint> DOMWindow::webkitConvertPointFromNodeToPage(Node* node, const WebKitPoint* p) const
+{
+ if (!node || !p)
+ return 0;
+
+ FloatPoint pagePoint(p->x(), p->y());
+ pagePoint = node->convertToPage(pagePoint);
+ return WebKitPoint::create(pagePoint.x(), pagePoint.y());
+}
+
+PassRefPtr<WebKitPoint> DOMWindow::webkitConvertPointFromPageToNode(Node* node, const WebKitPoint* p) const
+{
+ if (!node || !p)
+ return 0;
+
+ FloatPoint nodePoint(p->x(), p->y());
+ nodePoint = node->convertFromPage(nodePoint);
+ return WebKitPoint::create(nodePoint.x(), nodePoint.y());
+}
+
double DOMWindow::devicePixelRatio() const
{
if (!m_frame)
@@ -814,9 +833,6 @@ PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& v
return 0;
Document* doc = m_frame->document();
- ASSERT(doc);
- if (!doc)
- return 0;
Settings* settings = m_frame->settings();
if (!settings || !settings->databasesEnabled())
@@ -831,10 +847,7 @@ void DOMWindow::scrollBy(int x, int y) const
if (!m_frame)
return;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateLayoutIgnorePendingStylesheets();
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
FrameView* view = m_frame->view();
if (!view)
@@ -848,10 +861,7 @@ void DOMWindow::scrollTo(int x, int y) const
if (!m_frame)
return;
- Document* doc = m_frame->document();
- ASSERT(doc);
- if (doc)
- doc->updateLayoutIgnorePendingStylesheets();
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
FrameView* view = m_frame->view();
if (!view)
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index da84e35..b779cbd 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -52,6 +52,8 @@ namespace WebCore {
class Navigator;
class PostMessageTimer;
class Screen;
+ class WebKitPoint;
+ class Node;
#if ENABLE(DOM_STORAGE)
class SessionStorage;
@@ -163,6 +165,9 @@ namespace WebCore {
PassRefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const;
double devicePixelRatio() const;
+ PassRefPtr<WebKitPoint> webkitConvertPointFromPageToNode(Node* node, const WebKitPoint* p) const;
+ PassRefPtr<WebKitPoint> webkitConvertPointFromNodeToPage(Node* node, const WebKitPoint* p) const;
+
#if ENABLE(DATABASE)
// HTML 5 client-side database
PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, ExceptionCode&);
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index 78c780f..6bb08a8 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -53,7 +53,7 @@ module window {
attribute [Replaceable] BarInfo toolbar;
attribute [Replaceable] Navigator navigator;
attribute [Replaceable] Navigator clientInformation;
- attribute [DoNotCheckDomainSecurity, CustomSetter] Location location;
+ attribute [DoNotCheckDomainSecurity, CustomSetter, V8DisallowShadowing] Location location;
DOMSelection getSelection();
@@ -120,12 +120,12 @@ module window {
// Self referential attributes
attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow self;
- readonly attribute [DoNotCheckDomainSecurity] DOMWindow window;
+ readonly attribute [DoNotCheckDomainSecurity, V8DisallowShadowing] DOMWindow window;
attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow frames;
- attribute [Replaceable, DoNotCheckDomainSecurityOnGet] DOMWindow opener;
+ attribute [Replaceable, DoNotCheckDomainSecurityOnGet, V8CustomSetter] DOMWindow opener;
attribute [Replaceable, DoNotCheckDomainSecurity] DOMWindow parent;
- attribute [Replaceable, DoNotCheckDomainSecurity] DOMWindow top;
+ attribute [Replaceable, DoNotCheckDomainSecurity, V8DisallowShadowing, V8ReadOnly] DOMWindow top;
// DOM Level 2 AbstractView Interface
readonly attribute Document document;
@@ -139,6 +139,9 @@ module window {
in DOMString pseudoElement,
in [Optional] boolean authorOnly);
attribute [Replaceable] double devicePixelRatio;
+
+ WebKitPoint webkitConvertPointFromPageToNode(in Node node, in WebKitPoint p);
+ WebKitPoint webkitConvertPointFromNodeToPage(in Node node, in WebKitPoint p);
#if ENABLE_OFFLINE_WEB_APPLICATIONS
readonly attribute DOMApplicationCache applicationCache;
@@ -210,12 +213,17 @@ module window {
attribute [ProtectedListener] EventListener ontouchcancel;
#endif
+#if defined(V8_BINDING)
+ attribute [ProtectedListener] EventListener ondragdrop;
+ attribute [ProtectedListener] EventListener onmove;
+#endif
+
// EventTarget interface
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
+ [Custom] void addEventListener(in DOMString type,
+ in EventListener listener,
in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
- in EventListener listener,
+ [Custom] void removeEventListener(in DOMString type,
+ in EventListener listener,
in boolean useCapture);
// FIXME: Implement dispatchEvent
@@ -384,6 +392,17 @@ module window {
attribute XMLHttpRequestUploadConstructor XMLHttpRequestUpload;
attribute XMLHttpRequestExceptionConstructor XMLHttpRequestException;
+#if defined(V8_BINDING)
+ // With JSC, these are added in JSDOMWindowBase.cpp.
+ attribute XMLHttpRequestConstructor XMLHttpRequest;
+ attribute XSLTProcessorConstructor XSLTProcessor;
+ attribute MessageChannelConstructor MessageChannel;
+ attribute WebKitPointConstructor WebKitPoint;
+#if ENABLE_WORKERS
+ attribute WorkerConstructor Worker;
+#endif
+ attribute WebKitCSSMatrixConstructor WebKitCSSMatrix;
+#endif // V8_BINDING
attribute PluginConstructor Plugin;
attribute PluginArrayConstructor PluginArray;
@@ -391,6 +410,9 @@ module window {
attribute MimeTypeConstructor MimeType;
attribute MimeTypeArrayConstructor MimeTypeArray;
+ attribute ClientRectConstructor ClientRect;
+ attribute ClientRectListConstructor ClientRectList;
+
#if ENABLE_DOM_STORAGE
attribute StorageConstructor Storage;
attribute StorageEventConstructor StorageEvent;
@@ -440,6 +462,26 @@ module window {
#endif
#endif // defined(LANGUAGE_JAVASCRIPT)
- };
+#if defined(V8_BINDING)
+ // These were implemented in JSCDOMWindowBase and not moved to IDL yet.
+
+ [Custom] DOMWindow open(in DOMString url,
+ in DOMString name,
+ in [Optional] DOMString options);
+
+ [Custom] DOMObject showModalDialog(in DOMString url,
+ in [Optional] DOMObject dialogArgs,
+ in [Optional] DOMString featureArgs);
+
+ // These are defined on JSDOMWindowBase, but not implemented.
+ [Custom=DOMWindowNOP] void captureEvents(in long eventFlags);
+ [Custom=DOMWindowNOP] void releaseEvents(in long eventFlags);
+
+ // window.toString requires special handling
+ [V8DoNotCheckSignature, DoNotCheckDomainSecurity, Custom, DontEnum] DOMString toString();
+#endif // defined(V8_BINDING)
+ };
}
+
+
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index 9911f34..cba109a 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -107,9 +107,9 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD
String title;
String url = dragData->asURL(&title);
if (!url.isEmpty()) {
- ExceptionCode ec;
- RefPtr<HTMLAnchorElement> anchor = static_cast<HTMLAnchorElement*>(document->createElement("a", ec).get());
+ RefPtr<HTMLAnchorElement> anchor = new HTMLAnchorElement(document);
anchor->setHref(url);
+ ExceptionCode ec;
RefPtr<Node> anchorText = document->createTextNode(title);
anchor->appendChild(anchorText, ec);
RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
@@ -280,7 +280,7 @@ DragOperation DragController::tryDocumentDrag(DragData* dragData, DragDestinatio
Frame* innerFrame = element->document()->frame();
ASSERT(innerFrame);
if (!asFileInput(element)) {
- Selection dragCaret;
+ VisibleSelection dragCaret;
if (Frame* frame = m_document->frame())
dragCaret = frame->visiblePositionForPoint(point);
m_page->dragCaretController()->setSelection(dragCaret);
@@ -309,13 +309,13 @@ DragOperation DragController::operationForLoad(DragData* dragData)
return dragOperation(dragData);
}
-static bool setSelectionToDragCaret(Frame* frame, Selection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
+static bool setSelectionToDragCaret(Frame* frame, VisibleSelection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
{
frame->selection()->setSelection(dragCaret);
if (frame->selection()->isNone()) {
dragCaret = frame->visiblePositionForPoint(point);
frame->selection()->setSelection(dragCaret);
- range = dragCaret.toRange();
+ range = dragCaret.toNormalizedRange();
}
return !frame->selection()->isNone() && frame->selection()->isContentEditable();
}
@@ -340,7 +340,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
return false;
if (!innerFrame)
return false;
- RefPtr<Range> innerRange = innerFrame->selection()->toRange();
+ RefPtr<Range> innerRange = innerFrame->selection()->toNormalizedRange();
RefPtr<CSSStyleDeclaration> style = m_document->createCSSStyleDeclaration();
ExceptionCode ec;
style->setProperty("color", color.name(), ec);
@@ -381,9 +381,9 @@ bool DragController::concludeEditDrag(DragData* dragData)
return true;
}
- Selection dragCaret(m_page->dragCaretController()->selection());
+ VisibleSelection dragCaret(m_page->dragCaretController()->selection());
m_page->dragCaretController()->clear();
- RefPtr<Range> range = dragCaret.toRange();
+ RefPtr<Range> range = dragCaret.toNormalizedRange();
// For range to be null a WebKit client must have done something bad while
// manually controlling drag behaviour
@@ -531,7 +531,7 @@ static CachedImage* getCachedImage(Element* element)
RenderObject* renderer = element->renderer();
if (!renderer || !renderer->isImage())
return 0;
- RenderImage* image = static_cast<RenderImage*>(renderer);
+ RenderImage* image = toRenderImage(renderer);
return image->cachedImage();
}
@@ -542,7 +542,7 @@ static Image* getImage(Element* element)
if (!renderer || !renderer->isImage())
return 0;
- RenderImage* image = static_cast<RenderImage*>(renderer);
+ RenderImage* image = toRenderImage(renderer);
if (image->cachedImage() && !image->cachedImage()->errorOccurred())
return image->cachedImage()->image();
return 0;
@@ -554,7 +554,7 @@ static void prepareClipboardForImageDrag(Frame* src, Clipboard* clipboard, Eleme
ExceptionCode ec = 0;
range->selectNode(node, ec);
ASSERT(ec == 0);
- src->selection()->setSelection(Selection(range.get(), DOWNSTREAM));
+ src->selection()->setSelection(VisibleSelection(range.get(), DOWNSTREAM));
clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : imageURL, label, src);
}
@@ -661,7 +661,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
Position pos = src->selection()->base();
Node* node = enclosingAnchorElement(pos);
if (node)
- src->selection()->setSelection(Selection::selectionFromContentsOfNode(node));
+ src->selection()->setSelection(VisibleSelection::selectionFromContentsOfNode(node));
}
m_client->willPerformDragSourceAction(DragSourceActionLink, dragOrigin, clipboard);
@@ -673,7 +673,7 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
- RefPtr<Range> selectionRange = src->selection()->toRange();
+ RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
ASSERT(selectionRange);
if (!clipboard->hasData())
clipboard->writeRange(selectionRange.get(), src);
@@ -771,7 +771,7 @@ void DragController::placeDragCaret(const IntPoint& windowPoint)
if (!frameView)
return;
IntPoint framePoint = frameView->windowToContents(windowPoint);
- Selection dragCaret(frame->visiblePositionForPoint(framePoint));
+ VisibleSelection dragCaret(frame->visiblePositionForPoint(framePoint));
m_page->dragCaretController()->setSelection(dragCaret);
}
diff --git a/WebCore/page/EditorClient.h b/WebCore/page/EditorClient.h
index 56d0435..67462c5 100644
--- a/WebCore/page/EditorClient.h
+++ b/WebCore/page/EditorClient.h
@@ -50,7 +50,7 @@ class HTMLElement;
class KeyboardEvent;
class Node;
class Range;
-class Selection;
+class VisibleSelection;
class String;
class VisiblePosition;
@@ -61,6 +61,13 @@ struct GrammarDetail {
String userDescription;
};
+struct TextCheckingResult {
+ int resultType; // 1 for spelling, 2 for grammar
+ int location;
+ int length;
+ Vector<GrammarDetail> details;
+};
+
class EditorClient {
public:
virtual ~EditorClient() { }
@@ -130,6 +137,9 @@ public:
virtual void learnWord(const String&) = 0;
virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0;
virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0;
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ virtual void checkSpellingAndGrammarOfParagraph(const UChar* text, int length, bool checkGrammar, Vector<TextCheckingResult>& results) = 0;
+#endif
virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail& detail) = 0;
virtual void updateSpellingUIWithMisspelledWord(const String&) = 0;
virtual void showSpellingUI(bool show) = 0;
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 8cb46b7..7e79792 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -57,6 +57,7 @@
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
#include "RenderFrameSet.h"
+#include "RenderTextControlSingleLine.h"
#include "RenderWidget.h"
#include "RenderView.h"
#include "Scrollbar.h"
@@ -117,8 +118,6 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir
return;
}
float pixelsToScroll = delta > 0 ? delta : -delta;
- if (e.granularity() == ScrollByLineWheelEvent)
- pixelsToScroll *= cMouseWheelPixelsPerLineStep;
if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll))
e.accept();
}
@@ -126,6 +125,7 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir
EventHandler::EventHandler(Frame* frame)
: m_frame(frame)
, m_mousePressed(false)
+ , m_capturesDragging(false)
, m_mouseDownMayStartSelect(false)
, m_mouseDownMayStartDrag(false)
, m_mouseDownWasSingleClickInSelection(false)
@@ -186,18 +186,19 @@ void EventHandler::clear()
m_currentMousePosition = IntPoint();
m_mousePressNode = 0;
m_mousePressed = false;
+ m_capturesDragging = false;
m_capturingMouseEventsNode = 0;
}
void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
{
Node* innerNode = result.targetNode();
- Selection newSelection;
+ VisibleSelection newSelection;
if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
if (pos.isNotNull()) {
- newSelection = Selection(pos);
+ newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(WordGranularity);
}
@@ -221,11 +222,11 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
Node* innerNode = result.targetNode();
if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
- Selection newSelection;
+ VisibleSelection newSelection;
Element* URLElement = result.hitTestResult().URLElement();
VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
if (pos.isNotNull() && pos.deepEquivalent().node()->isDescendantOf(URLElement))
- newSelection = Selection::selectionFromContentsOfNode(URLElement);
+ newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
if (newSelection.isRange()) {
m_frame->setSelectionGranularity(WordGranularity);
@@ -264,10 +265,10 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
return false;
- Selection newSelection;
+ VisibleSelection newSelection;
VisiblePosition pos(innerNode->renderer()->positionForPoint(event.localPoint()));
if (pos.isNotNull()) {
- newSelection = Selection(pos);
+ newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(ParagraphGranularity);
}
if (newSelection.isRange()) {
@@ -283,9 +284,6 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
{
- if (event.event().button() != LeftButton)
- return false;
-
Node* innerNode = event.targetNode();
if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
return false;
@@ -306,7 +304,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
visiblePos = VisiblePosition(innerNode, 0, DOWNSTREAM);
Position pos = visiblePos.deepEquivalent();
- Selection newSelection = m_frame->selection()->selection();
+ VisibleSelection newSelection = m_frame->selection()->selection();
if (extendSelection && newSelection.isCaretOrRange()) {
m_frame->selection()->setLastChangeWasHorizontalExtension(false);
@@ -314,17 +312,17 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
// was created right-to-left
Position start = newSelection.start();
Position end = newSelection.end();
- short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
+ short before = Range::compareBoundaryPoints(pos.node(), pos.m_offset, start.node(), start.m_offset);
if (before <= 0)
- newSelection = Selection(pos, end);
+ newSelection = VisibleSelection(pos, end);
else
- newSelection = Selection(start, pos);
+ newSelection = VisibleSelection(start, pos);
if (m_frame->selectionGranularity() != CharacterGranularity)
newSelection.expandUsingGranularity(m_frame->selectionGranularity());
m_beganSelectingText = true;
} else {
- newSelection = Selection(visiblePos);
+ newSelection = VisibleSelection(visiblePos);
m_frame->setSelectionGranularity(CharacterGranularity);
}
@@ -375,18 +373,16 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
m_dragStartPos = event.event().pos();
bool swallowEvent = false;
- if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
- m_frame->selection()->setCaretBlinkingSuspended(true);
- m_mousePressed = true;
- m_beganSelectingText = false;
-
- if (event.event().clickCount() == 2)
- swallowEvent = handleMousePressEventDoubleClick(event);
- else if (event.event().clickCount() >= 3)
- swallowEvent = handleMousePressEventTripleClick(event);
- else
- swallowEvent = handleMousePressEventSingleClick(event);
- }
+ m_frame->selection()->setCaretBlinkingSuspended(true);
+ m_mousePressed = true;
+ m_beganSelectingText = false;
+
+ if (event.event().clickCount() == 2)
+ swallowEvent = handleMousePressEventDoubleClick(event);
+ else if (event.event().clickCount() >= 3)
+ swallowEvent = handleMousePressEventTripleClick(event);
+ else
+ swallowEvent = handleMousePressEventSingleClick(event);
m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect ||
(m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled(true));
@@ -451,7 +447,7 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
if (!DHTMLFlag && !UAFlag)
return false;
- HitTestRequest request(true, false);
+ HitTestRequest request(HitTestRequest::ReadOnly);
HitTestResult result(m_frame->view()->windowToContents(event.pos()));
m_frame->contentRenderer()->layer()->hitTest(request, result);
bool srcIsDHTML;
@@ -470,8 +466,11 @@ void EventHandler::updateSelectionForMouseDrag()
if (!layer)
return;
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active |
+ HitTestRequest::MouseMove);
HitTestResult result(view->windowToContents(m_currentMousePosition));
- layer->hitTest(HitTestRequest(true, true, true), result);
+ layer->hitTest(request, result);
updateSelectionForMouseDrag(result.innerNode(), result.localPoint());
}
@@ -498,7 +497,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
// Restart the selection if this is the first mouse move. This work is usually
// done in handleMousePressEvent, but not if the mouse press was on an existing selection.
- Selection newSelection = m_frame->selection()->selection();
+ VisibleSelection newSelection = m_frame->selection()->selection();
#if ENABLE(SVG)
// Special case to limit selection to the containing block for SVG text.
@@ -512,7 +511,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
if (!m_beganSelectingText) {
m_beganSelectingText = true;
- newSelection = Selection(targetPosition);
+ newSelection = VisibleSelection(targetPosition);
}
newSelection.setExtent(targetPosition);
@@ -550,6 +549,7 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
// the mouse is pressed again.
m_frame->selection()->setCaretBlinkingSuspended(false);
m_mousePressed = false;
+ m_capturesDragging = false;
m_mouseDownMayStartDrag = false;
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartAutoscroll = false;
@@ -563,11 +563,11 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText
&& m_dragStartPos == event.event().pos()
&& m_frame->selection()->isRange()) {
- Selection newSelection;
+ VisibleSelection newSelection;
Node *node = event.targetNode();
if (node && node->isContentEditable() && node->renderer()) {
VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());
- newSelection = Selection(pos);
+ newSelection = VisibleSelection(pos);
}
if (m_frame->shouldChangeSelection(newSelection))
m_frame->selection()->setSelection(newSelection);
@@ -630,6 +630,7 @@ void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
}
}
+#if ENABLE(PAN_SCROLLING)
void EventHandler::setPanScrollCursor()
{
// At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll
@@ -661,6 +662,7 @@ void EventHandler::setPanScrollCursor()
else
m_frame->view()->setCursor(middlePanningCursor());
}
+#endif // ENABLE(PAN_SCROLLING)
RenderObject* EventHandler::autoscrollRenderer() const
{
@@ -688,7 +690,7 @@ void EventHandler::setAutoscrollRenderer(RenderObject* renderer)
void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
{
- if (!m_frame || !m_frame->document()) {
+ if (!m_frame) {
flagDHTML = false;
flagUA = false;
return;
@@ -699,12 +701,15 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));
}
-HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent)
+HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping)
{
HitTestResult result(point);
if (!m_frame->contentRenderer())
return result;
- m_frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), result);
+ int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
+ if (ignoreClipping)
+ hitType |= HitTestRequest::IgnoreClipping;
+ m_frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), result);
while (true) {
Node* n = result.innerNode();
@@ -721,7 +726,7 @@ HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool all
IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(),
result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());
HitTestResult widgetHitTestResult(widgetPoint);
- frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), widgetHitTestResult);
+ frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), widgetHitTestResult);
result = widgetHitTestResult;
}
@@ -732,7 +737,7 @@ HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool all
if (m_frame != mainFrame && resultFrame && resultFrame != mainFrame && !resultFrame->editor()->insideVisibleArea(result.point())) {
IntPoint windowPoint = resultFrame->view()->contentsToWindow(result.point());
IntPoint mainFramePoint = mainFrame->view()->windowToContents(windowPoint);
- result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent);
+ result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent, ignoreClipping);
}
if (!allowShadowContent)
@@ -791,9 +796,6 @@ void EventHandler::setMousePressNode(PassRefPtr<Node> node)
bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity)
{
- if (!m_frame->document())
- return false;
-
Node* node = m_frame->document()->focusedNode();
if (!node)
node = m_mousePressNode.get();
@@ -1002,12 +1004,10 @@ Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scr
bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
- if (!m_frame->document())
- return false;
-
RefPtr<FrameView> protector(m_frame->view());
m_mousePressed = true;
+ m_capturesDragging = true;
m_currentMousePosition = mouseEvent.pos();
m_mouseDownTimestamp = mouseEvent.timestamp();
m_mouseDownMayStartDrag = false;
@@ -1016,7 +1016,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_mouseDownPos = m_frame->view()->windowToContents(mouseEvent.pos());
m_mouseDownWasInSubframe = false;
- MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, true), mouseEvent);
+ HitTestRequest request(HitTestRequest::Active);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
if (!mev.targetNode()) {
invalidateClick();
@@ -1036,7 +1037,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
// Start capturing future events for this frame. We only do this if we didn't clear
// the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
- if (m_mousePressed)
+ m_capturesDragging = subframe->eventHandler()->capturesDragging();
+ if (m_mousePressed && m_capturesDragging)
m_capturingMouseEventsNode = mev.targetNode();
invalidateClick();
return true;
@@ -1082,12 +1084,15 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
}
bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ m_capturesDragging = !swallowEvent;
// If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
// in case the scrollbar widget was destroyed when the mouse event was handled.
if (mev.scrollbar()) {
const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMouse.get();
- mev = prepareMouseEvent(HitTestRequest(true, true), mouseEvent);
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
+ mev = prepareMouseEvent(request, mouseEvent);
if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
m_lastScrollbarUnderMouse = 0;
@@ -1102,8 +1107,11 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
// If a mouse event handler changes the input element type to one that has a widget associated,
// we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
// event target node can't still be the shadow node.
- if (mev.targetNode()->isShadowNode() && mev.targetNode()->shadowParentNode()->hasTagName(inputTag))
- mev = prepareMouseEvent(HitTestRequest(true, true), mouseEvent);
+ if (mev.targetNode()->isShadowNode() && mev.targetNode()->shadowParentNode()->hasTagName(inputTag)) {
+ HitTestRequest request(HitTestRequest::ReadOnly |
+ HitTestRequest::Active);
+ mev = prepareMouseEvent(request, mouseEvent);
+ }
Scrollbar* scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);
if (!scrollbar)
@@ -1120,16 +1128,14 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
// This method only exists for platforms that don't know how to deliver
bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent)
{
- if (!m_frame->document())
- return false;
-
RefPtr<FrameView> protector(m_frame->view());
// We get this instead of a second mouse-up
m_mousePressed = false;
m_currentMousePosition = mouseEvent.pos();
- MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, true), mouseEvent);
+ HitTestRequest request(HitTestRequest::Active);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
Frame* subframe = subframeForHitTestResult(mev);
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
m_capturingMouseEventsNode = 0;
@@ -1178,7 +1184,7 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
// but also assert so that we can try to figure this out in debug
// builds, if it happens.
ASSERT(m_frame);
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return false;
RefPtr<FrameView> protector(m_frame->view());
@@ -1205,7 +1211,12 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
// if we are allowed to select.
// This means that :hover and :active freeze in the state they were in when the mouse
// was pressed, rather than updating for nodes the mouse moves over as you hold the mouse down.
- HitTestRequest request(m_mousePressed && m_mouseDownMayStartSelect, m_mousePressed, true);
+ int hitType = HitTestRequest::MouseMove;
+ if (m_mousePressed && m_mouseDownMayStartSelect)
+ hitType |= HitTestRequest::ReadOnly;
+ if (m_mousePressed)
+ hitType |= HitTestRequest::Active;
+ HitTestRequest request(hitType);
MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
if (hoveredNode)
*hoveredNode = mev.hitTestResult();
@@ -1271,9 +1282,6 @@ void EventHandler::invalidateClick()
bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
{
- if (!m_frame->document())
- return false;
-
RefPtr<FrameView> protector(m_frame->view());
m_mousePressed = false;
@@ -1295,7 +1303,8 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
return m_lastScrollbarUnderMouse->mouseUp();
}
- MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, false, false, true), mouseEvent);
+ HitTestRequest request(HitTestRequest::MouseUp);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
if (subframe && passMouseReleaseEventToSubframe(mev, subframe)) {
m_capturingMouseEventsNode = 0;
@@ -1325,6 +1334,8 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard)
{
+ m_frame->view()->resetDeferredRepaintDelay();
+
IntPoint contentsPos = m_frame->view()->windowToContents(event.pos());
RefPtr<MouseEvent> me = MouseEvent::create(eventType,
@@ -1334,7 +1345,7 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa
0, 0, clipboard);
ExceptionCode ec = 0;
- EventTargetNodeCast(dragTarget)->dispatchEvent(me.get(), ec);
+ dragTarget->dispatchEvent(me.get(), ec);
return me->defaultPrevented();
}
@@ -1342,13 +1353,11 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
{
bool accept = false;
- if (!m_frame->document())
- return false;
-
if (!m_frame->view())
return false;
-
- MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(true, false), event);
+
+ HitTestRequest request(HitTestRequest::ReadOnly);
+ MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
// Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
Node* newTarget = mev.targetNode();
@@ -1361,12 +1370,13 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
// FIXME: this ordering was explicitly chosen to match WinIE. However,
// it is sometimes incorrect when dragging within subframes, as seen with
// LayoutTests/fast/events/drag-in-frames.html.
- if (newTarget)
+ if (newTarget) {
if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
else
accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);
-
+ }
+
if (m_dragTarget) {
Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))
? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
@@ -1376,11 +1386,12 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
}
} else {
- if (newTarget)
+ if (newTarget) {
if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
else
accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);
+ }
}
m_dragTarget = newTarget;
@@ -1520,10 +1531,10 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
// send mouseout event to the old node
if (m_lastNodeUnderMouse)
- EventTargetNodeCast(m_lastNodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventNames().mouseoutEvent, 0, m_nodeUnderMouse.get());
+ m_lastNodeUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoutEvent, 0, m_nodeUnderMouse.get());
// send mouseover event to the new node
if (m_nodeUnderMouse)
- EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventNames().mouseoverEvent, 0, m_lastNodeUnderMouse.get());
+ m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoverEvent, 0, m_lastNodeUnderMouse.get());
}
m_lastNodeUnderMouse = m_nodeUnderMouse;
#if ENABLE(SVG)
@@ -1534,12 +1545,14 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
{
+ m_frame->view()->resetDeferredRepaintDelay();
+
updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
bool swallowEvent = false;
if (m_nodeUnderMouse)
- swallowEvent = EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventType, clickCount);
+ swallowEvent = m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);
if (!swallowEvent && eventType == eventNames().mousedownEvent) {
// Blur current focus node when a link/button is clicked; this
@@ -1551,7 +1564,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
// Walk up the render tree to search for a node to focus.
// Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
while (renderer) {
- node = renderer->element();
+ node = renderer->node();
if (node && node->isFocusable()) {
// To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus a
// node on mouse down if it's selected and inside a focused node. It will be
@@ -1560,7 +1573,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
ExceptionCode ec = 0;
Node* n = node->isShadowNode() ? node->shadowParentNode() : node;
if (m_frame->selection()->isRange() &&
- m_frame->selection()->toRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
+ m_frame->selection()->toNormalizedRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
n->isDescendantOf(m_frame->document()->focusedNode()))
return false;
@@ -1586,8 +1599,6 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
{
Document* doc = m_frame->document();
- if (!doc)
- return false;
RenderObject* docRenderer = doc->renderer();
if (!docRenderer)
@@ -1597,7 +1608,7 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
IntPoint vPoint = m_frame->view()->windowToContents(e.pos());
- HitTestRequest request(true, false);
+ HitTestRequest request(HitTestRequest::ReadOnly);
HitTestResult result(vPoint);
doc->renderView()->layer()->hitTest(request, result);
Node* node = result.innerNode();
@@ -1616,11 +1627,16 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
}
node = node->shadowAncestorNode();
- EventTargetNodeCast(node)->dispatchWheelEvent(e);
+ node->dispatchWheelEvent(e);
if (e.isAccepted())
return true;
-
- if (node->renderer()) {
+
+ // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
+ // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
+ while (node && !node->renderer())
+ node = node->parent();
+
+ if (node && node->renderer()) {
// Just break up into two scrolls if we need to. Diagonal movement on
// a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node);
@@ -1638,12 +1654,13 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
{
Document* doc = m_frame->document();
FrameView* v = m_frame->view();
- if (!doc || !v)
+ if (!v)
return false;
bool swallowEvent;
IntPoint viewportPos = v->windowToContents(event.pos());
- MouseEventWithHitTestResults mev = doc->prepareMouseEvent(HitTestRequest(false, true), viewportPos, event);
+ HitTestRequest request(HitTestRequest::Active);
+ MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
// Context menu events shouldn't select text in GTK+ applications or in Chromium.
// FIXME: This should probably be configurable by embedders. Consider making it a WebPreferences setting.
@@ -1653,7 +1670,7 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
// FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
// If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
// available for text selections. But only if we're above text.
- (m_frame->selection()->isContentEditable() || mev.targetNode() && mev.targetNode()->isTextNode())) {
+ (m_frame->selection()->isContentEditable() || (mev.targetNode() && mev.targetNode()->isTextNode()))) {
m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
selectClosestWordOrLinkFromMouseEvent(mev);
}
@@ -1680,10 +1697,11 @@ bool EventHandler::canMouseDownStartSelect(Node* node)
if (!node->canStartSelection())
return false;
- for (RenderObject* curr = node->renderer(); curr; curr = curr->parent())
- if (Node* node = curr->element())
- return EventTargetNodeCast(node)->dispatchEventForType(eventNames().selectstartEvent, true, true);
-
+ for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
+ if (Node* node = curr->node())
+ return node->dispatchEventForType(eventNames().selectstartEvent, true, true);
+ }
+
return true;
}
@@ -1692,10 +1710,11 @@ bool EventHandler::canMouseDragExtendSelect(Node* node)
if (!node || !node->renderer())
return true;
- for (RenderObject* curr = node->renderer(); curr; curr = curr->parent())
- if (Node* node = curr->element())
- return EventTargetNodeCast(node)->dispatchEventForType(eventNames().selectstartEvent, true, true);
-
+ for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
+ if (Node* node = curr->node())
+ return node->dispatchEventForType(eventNames().selectstartEvent, true, true);
+ }
+
return true;
}
@@ -1718,26 +1737,23 @@ void EventHandler::hoverTimerFired(Timer<EventHandler>*)
ASSERT(m_frame->document());
if (RenderView* renderer = m_frame->contentRenderer()) {
+ HitTestRequest request(HitTestRequest::MouseMove);
HitTestResult result(m_frame->view()->windowToContents(m_currentMousePosition));
- renderer->layer()->hitTest(HitTestRequest(false, false, true), result);
+ renderer->layer()->hitTest(request, result);
m_frame->document()->updateRendering();
}
}
-static EventTargetNode* eventTargetNodeForDocument(Document* doc)
+static Node* eventTargetNodeForDocument(Document* doc)
{
if (!doc)
return 0;
Node* node = doc->focusedNode();
- if (!node) {
- if (doc->isHTMLDocument())
- node = doc->body();
- else
- node = doc->documentElement();
- if (!node)
- return 0;
- }
- return EventTargetNodeCast(node);
+ if (!node && doc->isHTMLDocument())
+ node = doc->body();
+ if (!node)
+ node = doc->documentElement();
+ return node;
}
bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
@@ -1780,9 +1796,11 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
// Check for cases where we are too early for events -- possible unmatched key up
// from pressing return in the location bar.
- RefPtr<EventTargetNode> node = eventTargetNodeForDocument(m_frame->document());
+ RefPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
if (!node)
return false;
+
+ m_frame->view()->resetDeferredRepaintDelay();
// FIXME: what is this doing here, in keyboard event handler?
m_frame->loader()->resetMultipleFormSubmissionProtection();
@@ -1940,8 +1958,7 @@ void EventHandler::freeClipboard()
bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const
{
- ASSERT(node);
- if (node->hasChildNodes() || !m_frame->view())
+ if (!node || node->hasChildNodes() || !m_frame->view())
return false;
return m_frame->page() && m_frame->page()->dragController()->mayStartDragAtEventLocation(m_frame, point);
}
@@ -1994,7 +2011,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
// try to find an element that wants to be dragged
- HitTestRequest request(true, false);
+ HitTestRequest request(HitTestRequest::ReadOnly);
HitTestResult result(m_mouseDownPos);
m_frame->contentRenderer()->layer()->hitTest(request, result);
Node* node = result.innerNode();
@@ -2118,6 +2135,8 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
target = eventTargetNodeForDocument(m_frame->document());
if (!target)
return false;
+
+ m_frame->view()->resetDeferredRepaintDelay();
RefPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text);
event->setUnderlyingEvent(underlyingEvent);
@@ -2219,10 +2238,13 @@ void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
void EventHandler::capsLockStateMayHaveChanged()
{
- if (Document* d = m_frame->document())
- if (Node* node = d->focusedNode())
- if (RenderObject* r = node->renderer())
- r->capsLockStateMayHaveChanged();
+ Document* d = m_frame->document();
+ if (Node* node = d->focusedNode()) {
+ if (RenderObject* r = node->renderer()) {
+ if (r->isTextField())
+ static_cast<RenderTextControlSingleLine*>(r)->capsLockStateMayHaveChanged();
+ }
+ }
}
unsigned EventHandler::pendingFrameUnloadEventCount()
@@ -2252,6 +2274,20 @@ void EventHandler::clearPendingFrameUnloadEventCount()
return;
}
+void EventHandler::sendResizeEvent()
+{
+ m_frame->document()->dispatchWindowEvent(eventNames().resizeEvent, false, false);
+}
+
+void EventHandler::sendScrollEvent()
+{
+ FrameView* v = m_frame->view();
+ if (!v)
+ return;
+ v->setWasScrolledByUser(true);
+ m_frame->document()->dispatchEventForType(eventNames().scrollEvent, true, false);
+}
+
unsigned EventHandler::pendingFrameBeforeUnloadEventCount()
{
return m_pendingFrameBeforeUnloadEventCount;
@@ -2308,7 +2344,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
if (type == TouchEventStart) {
Frame* frame = m_frame;
IntPoint vPoint = frame->view()->windowToContents(e.pos());
- HitTestRequest request(true, false);
+ HitTestRequest request(HitTestRequest::ReadOnly);
HitTestResult result(vPoint);
frame->contentRenderer()->layer()->hitTest(request, result);
Node* node = result.innerNode();
@@ -2332,14 +2368,14 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
}
}
- if (!node || !node->isEventTargetNode()) {
+ if (!node) {
// reset to the top document node
node = doc;
frame = m_frame;
vPoint = frame->view()->windowToContents(e.pos());
}
- m_touch = Touch::create(frame, EventTargetNodeCast(node), 0,
+ m_touch = Touch::create(frame, node, 0,
e.x(), e.y(), vPoint.x(), vPoint.y());
} else if (m_touch) {
if ((type == TouchEventMove) && (e.x() == m_touch->screenX()) &&
@@ -2386,7 +2422,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
return false;
}
ExceptionCode ec = 0;
- static_cast<EventTargetNode*>(m_touch->target())->dispatchEvent(te.get(), ec);
+ m_touch->target()->dispatchEvent(te.get(), ec);
if (type == TouchEventEnd || type == TouchEventCancel) {
m_touch = 0;
}
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index 944bbd3..0a59eb3 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -49,11 +49,11 @@ namespace WebCore {
class AtomicString;
class Clipboard;
class Cursor;
-class EventTargetNode;
class Event;
class FloatPoint;
class FloatRect;
class Frame;
+class HitTestRequest;
class HitTestResult;
class HTMLFrameSetElement;
class KeyboardEvent;
@@ -75,8 +75,6 @@ class PlatformTouchEvent;
class Touch;
#endif
-struct HitTestRequest;
-
extern const int LinkDragHysteresis;
extern const int ImageDragHysteresis;
extern const int TextDragHysteresis;
@@ -101,7 +99,7 @@ public:
RenderObject* autoscrollRenderer() const;
void updateAutoscrollRenderer();
- HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent);
+ HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false);
bool mousePressed() const { return m_mousePressed; }
void setMousePressed(bool pressed) { m_mousePressed = pressed; }
@@ -174,6 +172,9 @@ public:
void addPendingFrameBeforeUnloadEventCount();
void removePendingFrameBeforeUnloadEventCount();
void clearPendingFrameBeforeUnloadEventCount();
+
+ void sendResizeEvent();
+ void sendScrollEvent();
#if PLATFORM(MAC)
PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;
@@ -224,7 +225,9 @@ private:
void handleKeyboardSelectionMovement(KeyboardEvent*);
Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
+#if ENABLE(PAN_SCROLLING)
void setPanScrollCursor();
+#endif
void hoverTimerFired(Timer<EventHandler>*);
@@ -293,9 +296,12 @@ private:
void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint);
+ bool capturesDragging() const { return m_capturesDragging; }
+
Frame* m_frame;
bool m_mousePressed;
+ bool m_capturesDragging;
RefPtr<Node> m_mousePressNode;
bool m_mouseDownMayStartSelect;
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index 9b30362..9760b3c 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -90,8 +90,6 @@ static Node* deepFocusableNode(FocusDirection direction, Node* node, KeyboardEve
break;
Document* document = owner->contentFrame()->document();
- if (!document)
- break;
node = (direction == FocusDirectionForward)
? document->nextFocusableNode(0, event)
@@ -115,8 +113,6 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
Frame* frame = focusedOrMainFrame();
ASSERT(frame);
Document* document = frame->document();
- if (!document)
- return false;
Node* node = (direction == FocusDirectionForward)
? document->nextFocusableNode(document->focusedNode(), event)
@@ -129,8 +125,6 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
break;
Document* parentDocument = parentFrame->document();
- if (!parentDocument)
- break;
HTMLFrameOwnerElement* owner = frame->ownerElement();
if (!owner)
@@ -155,10 +149,10 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
}
// Chrome doesn't want focus, so we should wrap focus.
- if (Document* d = m_page->mainFrame()->document())
- node = (direction == FocusDirectionForward)
- ? d->nextFocusableNode(0, event)
- : d->previousFocusableNode(0, event);
+ Document* d = m_page->mainFrame()->document();
+ node = (direction == FocusDirectionForward)
+ ? d->nextFocusableNode(0, event)
+ : d->previousFocusableNode(0, event);
node = deepFocusableNode(direction, node, event);
@@ -266,9 +260,9 @@ bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFra
m_page->editorClient()->setInputMethodState(false);
return true;
}
-
- RefPtr<Document> newDocument = node ? node->document() : 0;
-
+
+ RefPtr<Document> newDocument = node->document();
+
if (newDocument && newDocument->focusedNode() == node) {
m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
return true;
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index d4632e5..d379e13 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -5,7 +5,7 @@
* 2000 Simon Hausmann <hausmann@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
* 2001 George Staikos <staikos@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
@@ -43,6 +43,7 @@
#include "FocusController.h"
#include "FloatQuad.h"
#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLDocument.h"
@@ -52,7 +53,6 @@
#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
#include "HitTestResult.h"
-#include "JSDOMWindowShell.h"
#include "Logging.h"
#include "markup.h"
#include "MediaFeatureNames.h"
@@ -71,11 +71,15 @@
#include "XMLNames.h"
#include "ScriptController.h"
#include "npruntime_impl.h"
-#include "runtime_root.h"
#include "visible_units.h"
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
+#if USE(JSC)
+#include "JSDOMWindowShell.h"
+#include "runtime_root.h"
+#endif
+
#if FRAME_LOADS_USER_STYLESHEET
#include "UserStyleSheetLoader.h"
#endif
@@ -286,7 +290,7 @@ Settings* Frame::settings() const
String Frame::selectedText() const
{
- return plainText(selection()->toRange().get());
+ return plainText(selection()->toNormalizedRange().get());
}
IntRect Frame::firstRectForRange(Range* range) const
@@ -405,7 +409,7 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE
if (cellAboveRenderer) {
HTMLTableCellElement* aboveCell =
- static_cast<HTMLTableCellElement*>(cellAboveRenderer->element());
+ static_cast<HTMLTableCellElement*>(cellAboveRenderer->node());
if (aboveCell) {
// search within the above cell we found for a match
@@ -511,12 +515,12 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
return String();
}
-const Selection& Frame::mark() const
+const VisibleSelection& Frame::mark() const
{
return m_mark;
}
-void Frame::setMark(const Selection& s)
+void Frame::setMark(const VisibleSelection& s)
{
ASSERT(!s.base().node() || s.base().node()->document() == document());
ASSERT(!s.extent().node() || s.extent().node()->document() == document());
@@ -533,8 +537,8 @@ void Frame::notifyRendererOfSelectionChange(bool userTriggered)
renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer();
// If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
- if (renderer && (renderer->isTextArea() || renderer->isTextField()))
- static_cast<RenderTextControl*>(renderer)->selectionChanged(userTriggered);
+ if (renderer && renderer->isTextControl())
+ toRenderTextControl(renderer)->selectionChanged(userTriggered);
}
void Frame::invalidateSelection()
@@ -577,7 +581,7 @@ static bool isFrameElement(const Node *n)
void Frame::setFocusedNodeIfNeeded()
{
- if (!document() || selection()->isNone() || !selection()->isFocusedAndActive())
+ if (selection()->isNone() || !selection()->isFocusedAndActive())
return;
Node* target = selection()->rootEditableElement();
@@ -596,7 +600,7 @@ void Frame::setFocusedNodeIfNeeded()
}
renderer = renderer->parent();
if (renderer)
- target = renderer->element();
+ target = renderer->node();
}
document()->setFocusedNode(0);
}
@@ -636,7 +640,7 @@ void Frame::selectionLayoutChanged()
if (!view)
return;
- Selection selection = this->selection()->selection();
+ VisibleSelection selection = this->selection()->selection();
if (!selection.isRange())
view->clearSelection();
@@ -657,7 +661,7 @@ void Frame::selectionLayoutChanged()
if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
RenderObject *startRenderer = startPos.node()->renderer();
RenderObject *endRenderer = endPos.node()->renderer();
- view->setSelection(startRenderer, startPos.offset(), endRenderer, endPos.offset());
+ view->setSelection(startRenderer, startPos.m_offset, endRenderer, endPos.m_offset);
}
}
}
@@ -708,7 +712,7 @@ bool Frame::shouldApplyTextZoom() const
if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
return false;
#if ENABLE(SVG)
- if (m_doc && m_doc->isSVGDocument())
+ if (m_doc->isSVGDocument())
return false;
#endif
return true;
@@ -719,7 +723,7 @@ bool Frame::shouldApplyPageZoom() const
if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
return false;
#if ENABLE(SVG)
- if (m_doc && m_doc->isSVGDocument())
+ if (m_doc->isSVGDocument())
return false;
#endif
return true;
@@ -733,7 +737,7 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
#if ENABLE(SVG)
// SVG doesn't care if the zoom factor is text only. It will always apply a
// zoom to the whole SVG.
- if (m_doc && m_doc->isSVGDocument()) {
+ if (m_doc->isSVGDocument()) {
if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled())
return;
m_zoomFactor = percent;
@@ -747,25 +751,21 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
m_zoomFactor = percent;
m_page->settings()->setZoomsTextOnly(isTextOnly);
- if (m_doc)
- m_doc->recalcStyle(Node::Force);
+ m_doc->recalcStyle(Node::Force);
for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
child->setZoomFactor(m_zoomFactor, isTextOnly);
- if (m_doc && m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
+ if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
view()->layout();
}
void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
{
- if (!m_doc)
- return;
-
m_doc->setPrinting(printing);
view()->setMediaType(printing ? "print" : "screen");
m_doc->updateStyleSelector();
- forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
+ view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
child->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
@@ -797,6 +797,12 @@ String Frame::jsDefaultStatusBarText() const
void Frame::setNeedsReapplyStyles()
{
+ // When the frame is not showing web content, it doesn't make sense to apply styles.
+ // If we tried, we'd end up doing things with the document, but the document, if one
+ // exists, is not currently shown and should be in the page cache.
+ if (!m_loader.client()->hasHTMLView())
+ return;
+
if (m_needsReapplyStyles)
return;
@@ -817,11 +823,9 @@ void Frame::reapplyStyles()
{
m_needsReapplyStyles = false;
- // FIXME: This call doesn't really make sense in a method called
- // "reapplyStyles". We should probably eventually move it into its own
- // method.
- if (m_doc)
- m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically());
+ // FIXME: This call doesn't really make sense in a function called reapplyStyles.
+ // We should probably eventually move it into its own function.
+ m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically());
#if FRAME_LOADS_USER_STYLESHEET
const KURL userStyleSheetLocation = m_page ? m_page->settings()->userStyleSheetLocation() : KURL();
@@ -835,32 +839,29 @@ void Frame::reapplyStyles()
// The document automatically does this as required when you set the style sheet.
// But we had problems when this code was removed. Details are in
// <http://bugs.webkit.org/show_bug.cgi?id=8079>.
- if (m_doc)
- m_doc->updateStyleSelector();
+ m_doc->updateStyleSelector();
}
-bool Frame::shouldChangeSelection(const Selection& newSelection) const
+bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
{
return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
}
-bool Frame::shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity affinity, bool stillSelecting) const
+bool Frame::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
{
- return editor()->client()->shouldChangeSelectedRange(oldSelection.toRange().get(), newSelection.toRange().get(),
+ return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(),
affinity, stillSelecting);
}
-bool Frame::shouldDeleteSelection(const Selection& selection) const
+bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const
{
- return editor()->client()->shouldDeleteRange(selection.toRange().get());
+ return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
}
bool Frame::isContentEditable() const
{
if (m_editor.clientIsEditable())
return true;
- if (!m_doc)
- return false;
return m_doc->inDesignMode();
}
@@ -929,7 +930,7 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit
// Handle block styles, substracting these from the typing style.
RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
blockStyle->diff(mutableStyle.get());
- if (document() && blockStyle->length() > 0)
+ if (blockStyle->length() > 0)
applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
// Set the remaining style as the typing style.
@@ -958,13 +959,10 @@ PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nod
{
nodeToRemove = 0;
- if (!document())
- return 0;
-
if (selection()->isNone())
return 0;
- RefPtr<Range> range(selection()->toRange());
+ RefPtr<Range> range(selection()->toNormalizedRange());
Position pos = range->editingStartPosition();
Element *elem = pos.element();
@@ -975,8 +973,7 @@ PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nod
ExceptionCode ec = 0;
if (m_typingStyle) {
- styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
- ASSERT(ec == 0);
+ styleElement = document()->createElement(spanTag, false);
styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec);
ASSERT(ec == 0);
@@ -1044,9 +1041,6 @@ void Frame::textDidChangeInTextArea(Element* e)
void Frame::applyEditingStyleToBodyElement() const
{
- if (!m_doc)
- return;
-
RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
unsigned len = list->length();
for (unsigned i = 0; i < len; i++) {
@@ -1056,9 +1050,6 @@ void Frame::applyEditingStyleToBodyElement() const
void Frame::removeEditingStyleFromBodyElement() const
{
- if (!m_doc)
- return;
-
RefPtr<NodeList> list = m_doc->getElementsByTagName("body");
unsigned len = list->length();
for (unsigned i = 0; i < len; i++) {
@@ -1145,7 +1136,7 @@ RenderView* Frame::contentRenderer() const
if (!object)
return 0;
ASSERT(object->isRenderView());
- return static_cast<RenderView*>(object);
+ return toRenderView(object);
}
HTMLFrameOwnerElement* Frame::ownerElement() const
@@ -1208,7 +1199,7 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
if (!root)
return;
- RefPtr<Range> selectedRange = selection()->toRange();
+ RefPtr<Range> selectedRange = selection()->toNormalizedRange();
Vector<IntRect> intRects;
selectedRange->addLineBoxRects(intRects, true);
@@ -1223,15 +1214,6 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
}
-bool Frame::isFrameSet() const
-{
- Document* document = m_doc.get();
- if (!document || !document->isHTMLDocument())
- return false;
- Node *body = static_cast<HTMLDocument*>(document)->body();
- return body && body->renderer() && body->hasTagName(framesetTag);
-}
-
// Scans logically forward from "start", including any child frames
static HTMLFormElement *scanForForm(Node *start)
{
@@ -1271,66 +1253,32 @@ HTMLFormElement *Frame::currentForm() const
return start ? scanForForm(start) : 0;
}
-// FIXME: should this go in SelectionController?
-void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
+void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
{
IntRect rect;
-
- switch (selection()->state()) {
- case Selection::NONE:
+
+ switch (selection()->selectionType()) {
+ case VisibleSelection::NoSelection:
return;
-
- case Selection::CARET:
+ case VisibleSelection::CaretSelection:
rect = selection()->absoluteCaretBounds();
break;
-
- case Selection::RANGE:
- rect = enclosingIntRect(selectionBounds(false));
+ case VisibleSelection::RangeSelection:
+ rect = revealExtent ? VisiblePosition(selection()->extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(false));
break;
}
Position start = selection()->start();
-
ASSERT(start.node());
if (start.node() && start.node()->renderer()) {
// FIXME: This code only handles scrolling the startContainer's layer, but
// the selection rect could intersect more than just that.
// See <rdar://problem/4799899>.
- if (RenderLayer *layer = start.node()->renderer()->enclosingLayer())
+ if (RenderLayer* layer = start.node()->renderer()->enclosingLayer())
layer->scrollRectToVisible(rect, false, alignment, alignment);
}
}
-void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
-{
- if (selection()->isNone())
- return;
-
- Position extent = selection()->extent();
- if (extent.node() && extent.node()->renderer()) {
- IntRect extentRect = VisiblePosition(extent).absoluteCaretBounds();
- RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
- if (layer)
- layer->scrollRectToVisible(extentRect, false, alignment, alignment);
- }
-}
-
-void Frame::adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
-{
- RenderView* root = contentRenderer();
- if (root) {
- // Use a context with painting disabled.
- GraphicsContext context((PlatformGraphicsContext*)0);
- root->setTruncatedAt((int)floorf(oldBottom));
- IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop));
- root->layer()->paint(&context, dirtyRect);
- *newBottom = root->bestTruncatedAt();
- if (*newBottom == 0)
- *newBottom = oldBottom;
- } else
- *newBottom = oldBottom;
-}
-
Frame* Frame::frameForWidget(const Widget* widget)
{
ASSERT_ARG(widget, widget);
@@ -1345,67 +1293,6 @@ Frame* Frame::frameForWidget(const Widget* widget)
return static_cast<const FrameView*>(widget)->frame();
}
-void Frame::forceLayout(bool allowSubtree)
-{
- FrameView *v = m_view.get();
- if (v) {
- v->layout(allowSubtree);
- // We cannot unschedule a pending relayout, since the force can be called with
- // a tiny rectangle from a drawRect update. By unscheduling we in effect
- // "validate" and stop the necessary full repaint from occurring. Basically any basic
- // append/remove DHTML is broken by this call. For now, I have removed the optimization
- // until we have a better invalidation stategy. -dwh
- //v->unscheduleRelayout();
- }
-}
-
-void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool adjustViewSize)
-{
- // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
- // the state of things before and after the layout
- RenderView *root = static_cast<RenderView*>(document()->renderer());
- if (root) {
- // This magic is basically copied from khtmlview::print
- int pageW = (int)ceilf(minPageWidth);
- root->setWidth(pageW);
- root->setNeedsLayoutAndPrefWidthsRecalc();
- forceLayout();
-
- // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
- // maximum page width, we will lay out to the maximum page width and clip extra content.
- // FIXME: We are assuming a shrink-to-fit printing implementation. A cropping
- // implementation should not do this!
- int rightmostPos = root->rightmostPosition();
- if (rightmostPos > minPageWidth) {
- pageW = min(rightmostPos, (int)ceilf(maxPageWidth));
- root->setWidth(pageW);
- root->setNeedsLayoutAndPrefWidthsRecalc();
- forceLayout();
- }
- }
-
- if (adjustViewSize && view())
- view()->adjustViewSize();
-}
-
-void Frame::sendResizeEvent()
-{
- if (Document* doc = document())
- doc->dispatchWindowEvent(eventNames().resizeEvent, false, false);
-}
-
-void Frame::sendScrollEvent()
-{
- FrameView* v = m_view.get();
- if (!v)
- return;
- v->setWasScrolledByUser(true);
- Document* doc = document();
- if (!doc)
- return;
- doc->dispatchEventForType(eventNames().scrollEvent, true, false);
-}
-
void Frame::clearTimers(FrameView *view, Document *document)
{
if (view) {
@@ -1428,8 +1315,6 @@ RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
{
nodeToRemove = 0;
- if (!document())
- return 0;
if (selection()->isNone())
return 0;
@@ -1443,10 +1328,9 @@ RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
if (!m_typingStyle)
return node->renderer()->style();
- ExceptionCode ec = 0;
- RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
- ASSERT(ec == 0);
+ 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 == 0);
@@ -1466,14 +1350,14 @@ void Frame::setSelectionFromNone()
// Put a caret inside the body if the entire frame is editable (either the
// entire WebView is editable or designMode is on for this document).
Document *doc = document();
- if (!doc || !selection()->isNone() || !isContentEditable())
+ if (!selection()->isNone() || !isContentEditable())
return;
Node* node = doc->documentElement();
while (node && !node->hasTagName(bodyTag))
node = node->traverseNextNode();
if (node)
- selection()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
+ selection()->setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM));
}
bool Frame::inViewSourceMode() const
@@ -1489,7 +1373,7 @@ void Frame::setInViewSourceMode(bool mode)
// 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() || !document())
+ if (target.isEmpty())
return false;
if (excludeFromTextSearch())
@@ -1498,7 +1382,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w
// 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()));
- Selection selection = this->selection()->selection();
+ VisibleSelection selection = this->selection()->selection();
if (forward)
setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
@@ -1518,7 +1402,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w
// 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 && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
+ if (startInSelection && *VisibleSelection(resultRange.get()).toNormalizedRange() == *selection.toNormalizedRange()) {
searchRange = rangeOfContents(document());
if (forward)
setStart(searchRange.get(), selection.visibleEnd());
@@ -1568,14 +1452,14 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w
if (resultRange->collapsed(exception))
return false;
- this->selection()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
+ this->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
revealSelection();
return true;
}
unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit)
{
- if (target.isEmpty() || !document())
+ if (target.isEmpty())
return 0;
RefPtr<Range> searchRange(rangeOfContents(document()));
@@ -1618,7 +1502,7 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
// Do a "fake" paint in order to execute the code that computes the rendered rect for
// each text match.
Document* doc = document();
- if (doc && m_view && contentRenderer()) {
+ if (m_view && contentRenderer()) {
doc->updateLayout(); // Ensure layout is up to date.
IntRect visibleRect = m_view->visibleContentRect();
if (!visibleRect.isEmpty()) {
@@ -1638,7 +1522,7 @@ bool Frame::markedTextMatchesAreHighlighted() const
void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
{
- if (flag == m_highlightTextMatches || !document())
+ if (flag == m_highlightTextMatches)
return;
m_highlightTextMatches = flag;
@@ -1718,10 +1602,8 @@ void Frame::disconnectOwnerElement()
String Frame::documentTypeString() const
{
- if (Document* doc = document()) {
- if (DocumentType* doctype = doc->doctype())
- return createMarkup(doctype);
- }
+ if (DocumentType* doctype = document()->doctype())
+ return createMarkup(doctype);
return String();
}
@@ -1755,8 +1637,6 @@ bool Frame::shouldClose()
return true;
RefPtr<Document> doc = document();
- if (!doc)
- return true;
HTMLElement* body = doc->body();
if (!body)
return true;
@@ -1765,7 +1645,7 @@ bool Frame::shouldClose()
beforeUnloadEvent->setTarget(doc);
doc->handleWindowEvent(beforeUnloadEvent.get(), false);
- if (!beforeUnloadEvent->defaultPrevented() && doc)
+ if (!beforeUnloadEvent->defaultPrevented())
doc->defaultEventHandler(beforeUnloadEvent.get());
if (beforeUnloadEvent->result().isNull())
return true;
@@ -1785,52 +1665,50 @@ void Frame::scheduleClose()
chrome->closeWindowSoon();
}
-void Frame::respondToChangedSelection(const Selection& oldSelection, bool closeTyping)
+void Frame::respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping)
{
- if (document()) {
- bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled();
- bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled();
- if (isContinuousSpellCheckingEnabled) {
- Selection newAdjacentWords;
- Selection newSelectedSentence;
- if (selection()->selection().isContentEditable()) {
- VisiblePosition newStart(selection()->selection().visibleStart());
- newAdjacentWords = Selection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
- if (isContinuousGrammarCheckingEnabled)
- newSelectedSentence = Selection(startOfSentence(newStart), endOfSentence(newStart));
- }
+ bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled();
+ bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled();
+ if (isContinuousSpellCheckingEnabled) {
+ VisibleSelection newAdjacentWords;
+ VisibleSelection newSelectedSentence;
+ if (selection()->selection().isContentEditable()) {
+ 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());
- Selection oldAdjacentWords = Selection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
- if (oldAdjacentWords != newAdjacentWords) {
- editor()->markMisspellings(oldAdjacentWords);
- if (isContinuousGrammarCheckingEnabled) {
- Selection oldSelectedSentence = Selection(startOfSentence(oldStart), endOfSentence(oldStart));
- if (oldSelectedSentence != newSelectedSentence)
- editor()->markBadGrammar(oldSelectedSentence);
- }
+ // 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.toRange())
- document()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
- if (RefPtr<Range> sentenceRange = newSelectedSentence.toRange())
- document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
}
- // When continuous spell checking is off, existing markers disappear after the selection changes.
- if (!isContinuousSpellCheckingEnabled)
- document()->removeMarkers(DocumentMarker::Spelling);
- if (!isContinuousGrammarCheckingEnabled)
- document()->removeMarkers(DocumentMarker::Grammar);
+ // 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()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
+ if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
+ document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
}
+ // When continuous spell checking is off, existing markers disappear after the selection changes.
+ if (!isContinuousSpellCheckingEnabled)
+ document()->removeMarkers(DocumentMarker::Spelling);
+ if (!isContinuousGrammarCheckingEnabled)
+ document()->removeMarkers(DocumentMarker::Grammar);
+
editor()->respondToChangedSelection(oldSelection);
}
@@ -1843,7 +1721,7 @@ VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
RenderObject* renderer = node->renderer();
if (!renderer)
return VisiblePosition();
- VisiblePosition visiblePos = renderer->positionForCoordinates(result.localPoint().x(), result.localPoint().y());
+ VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint());
if (visiblePos.isNull())
visiblePos = VisiblePosition(Position(node, 0));
return visiblePos;
@@ -1862,4 +1740,47 @@ Document* Frame::documentAtPoint(const IntPoint& point)
return result.innerNode() ? result.innerNode()->document() : 0;
}
+void Frame::createView(const IntSize& viewportSize,
+ const Color& backgroundColor, bool transparent,
+ const IntSize& fixedLayoutSize, bool useFixedLayout,
+ ScrollbarMode horizontalScrollbarMode, ScrollbarMode verticalScrollbarMode)
+{
+ ASSERT(this);
+ ASSERT(m_page);
+
+ bool isMainFrame = this == m_page->mainFrame();
+
+ if (isMainFrame && view())
+ view()->setParentVisible(false);
+
+ setView(0);
+
+ FrameView* frameView;
+ if (isMainFrame) {
+ frameView = new FrameView(this, viewportSize);
+ frameView->setFixedLayoutSize(fixedLayoutSize);
+ frameView->setUseFixedLayout(useFixedLayout);
+ } else
+ frameView = new FrameView(this);
+
+ frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode);
+ frameView->updateDefaultScrollbarState();
+
+ setView(frameView);
+ // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
+ frameView->deref();
+
+ if (backgroundColor.isValid())
+ frameView->updateBackgroundRecursively(backgroundColor, transparent);
+
+ if (isMainFrame)
+ frameView->setParentVisible(true);
+
+ if (ownerRenderer())
+ ownerRenderer()->setWidget(frameView);
+
+ if (HTMLFrameOwnerElement* owner = ownerElement())
+ view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
+}
+
} // namespace WebCore
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index bebdc63..5d46acd 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -29,6 +29,7 @@
#define Frame_h
#include "AnimationController.h"
+#include "Document.h"
#include "DragImage.h"
#include "EditAction.h"
#include "Editor.h"
@@ -36,7 +37,7 @@
#include "FrameLoader.h"
#include "FrameTree.h"
#include "Range.h"
-#include "RenderLayer.h"
+#include "ScrollBehavior.h"
#include "ScriptController.h"
#include "SelectionController.h"
#include "TextGranularity.h"
@@ -61,19 +62,21 @@ typedef struct HBITMAP__* HBITMAP;
namespace WebCore {
+class CSSMutableStyleDeclaration;
class Editor;
class EventHandler;
class FrameLoader;
class FrameLoaderClient;
-class FramePrivate;
class FrameTree;
+class FrameView;
class HTMLFrameOwnerElement;
class HTMLTableCellElement;
-class ScriptController;
class RegularExpression;
class RenderPart;
-class Selection;
+class ScriptController;
class SelectionController;
+class Settings;
+class VisibleSelection;
class Widget;
#if FRAME_LOADS_USER_STYLESHEET
@@ -122,7 +125,9 @@ public:
bool excludeFromTextSearch() const;
void setExcludeFromTextSearch(bool);
- friend class FramePrivate;
+ void createView(const IntSize&, const Color&, bool, const IntSize &, bool,
+ ScrollbarMode = ScrollbarAuto, ScrollbarMode = ScrollbarAuto);
+
private:
Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
@@ -172,25 +177,9 @@ public:
private:
void lifeSupportTimerFired(Timer<Frame>*);
-// === to be moved into Document
-
-public:
- bool isFrameSet() const;
-
-// === to be moved into EventHandler
-
-public:
- void sendResizeEvent();
- void sendScrollEvent();
-
// === to be moved into FrameView
public:
- void forceLayout(bool allowSubtree = false);
- void forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool adjustViewSize);
-
- void adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
-
void setZoomFactor(float scale, bool isTextOnly);
float zoomFactor() const;
bool isZoomFactorTextOnly() const;
@@ -218,8 +207,8 @@ public:
String selectedText() const;
bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
- const Selection& mark() const; // Mark, to be used as emacs uses it.
- void setMark(const Selection&);
+ const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
+ void setMark(const VisibleSelection&);
void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
String selectionStartStylePropertyValue(int stylePropertyID) const;
@@ -230,8 +219,8 @@ public:
IntRect firstRectForRange(Range*) const;
- void respondToChangedSelection(const Selection& oldSelection, bool closeTyping);
- bool shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity, bool stillSelecting) 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;
@@ -256,8 +245,8 @@ public:
TextGranularity selectionGranularity() const;
void setSelectionGranularity(TextGranularity);
- bool shouldChangeSelection(const Selection&) const;
- bool shouldDeleteSelection(const Selection&) const;
+ bool shouldChangeSelection(const VisibleSelection&) const;
+ bool shouldDeleteSelection(const VisibleSelection&) const;
void clearCaretRectIfNeeded();
void setFocusedNodeIfNeeded();
void selectionLayoutChanged();
@@ -281,9 +270,8 @@ public:
void selectionTextRects(Vector<FloatRect>&, bool clipToVisibleContent = true) const;
HTMLFormElement* currentForm() const;
-
- void revealSelection(const RenderLayer::ScrollAlignment& = RenderLayer::gAlignCenterIfNeeded) const;
- void revealCaret(const RenderLayer::ScrollAlignment& = RenderLayer::gAlignCenterIfNeeded) const;
+
+ void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
void setSelectionFromNone();
void setUseSecureKeyboardEntry(bool);
@@ -359,7 +347,7 @@ private:
TextGranularity m_selectionGranularity;
mutable SelectionController m_selectionController;
- mutable Selection m_mark;
+ mutable VisibleSelection m_mark;
Timer<Frame> m_caretBlinkTimer;
mutable Editor m_editor;
mutable EventHandler m_eventHandler;
diff --git a/WebCore/page/FrameTree.cpp b/WebCore/page/FrameTree.cpp
index c9b4172..adb5c90 100644
--- a/WebCore/page/FrameTree.cpp
+++ b/WebCore/page/FrameTree.cpp
@@ -82,10 +82,6 @@ void FrameTree::appendChild(PassRefPtr<Frame> child)
void FrameTree::removeChild(Frame* child)
{
child->tree()->m_parent = 0;
- child->setView(0);
- if (child->ownerElement())
- child->page()->decrementFrameCount();
- child->pageDestroyed();
// Slightly tricky way to prevent deleting the child until we are done with it, w/o
// extra refs. These swaps leave the child in a circular list by itself. Clearing its
diff --git a/WebCore/page/FrameTree.h b/WebCore/page/FrameTree.h
index 3b74d5d..d4c8c43 100644
--- a/WebCore/page/FrameTree.h
+++ b/WebCore/page/FrameTree.h
@@ -56,6 +56,7 @@ namespace WebCore {
Frame* traversePreviousWithWrap(bool) const;
void appendChild(PassRefPtr<Frame>);
+ void detachFromParent() { m_parent = 0; }
void removeChild(Frame*);
Frame* child(unsigned index) const;
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 2eefd6c..5f1ee65 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -28,6 +28,7 @@
#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
#include "ChromeClient.h"
+#include "DocLoader.h"
#include "EventHandler.h"
#include "FloatRect.h"
#include "FocusController.h"
@@ -55,15 +56,41 @@
#include "TimeCounter.h"
#endif
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
double FrameView::sCurrentPaintTimeStamp = 0.0;
+#if ENABLE(REPAINT_THROTTLING)
+// Normal delay
+static const double deferredRepaintDelay = 0.025;
+// Negative value would mean that first few repaints happen without a delay
+static const double initialDeferredRepaintDelayDuringLoading = 0;
+// The delay grows on each repaint to this maximum value
+static const double maxDeferredRepaintDelayDuringLoading = 2.5;
+// On each repaint the delay increses by this amount
+static const double deferredRepaintDelayIncrementDuringLoading = 0.5;
+#else
+// FIXME: Repaint throttling could be good to have on all platform.
+// The balance between CPU use and repaint frequency will need some tuning for desktop.
+// More hooks may be needed to reset the delay on things like GIF and CSS animations.
+static const double deferredRepaintDelay = 0;
+static const double initialDeferredRepaintDelayDuringLoading = 0;
+static const double maxDeferredRepaintDelayDuringLoading = 0;
+static const double deferredRepaintDelayIncrementDuringLoading = 0;
+#endif
+
+// The maximum number of updateWidgets iterations that should be done before returning.
+static const unsigned maxUpdateWidgetsIterations = 2;
+
struct ScheduledEvent {
RefPtr<Event> m_event;
- RefPtr<EventTargetNode> m_eventTarget;
+ RefPtr<Node> m_eventTarget;
};
FrameView::FrameView(Frame* frame)
@@ -84,6 +111,7 @@ FrameView::FrameView(Frame* frame)
, m_viewportRenderer(0)
, m_wasScrolledByUser(false)
, m_inProgrammaticScroll(false)
+ , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
, m_shouldUpdateWhileOffscreen(true)
{
init();
@@ -108,6 +136,7 @@ FrameView::FrameView(Frame* frame, const IntSize& initialSize)
, m_viewportRenderer(0)
, m_wasScrolledByUser(false)
, m_inProgrammaticScroll(false)
+ , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
, m_shouldUpdateWhileOffscreen(true)
{
init();
@@ -132,7 +161,7 @@ FrameView::~FrameView()
ASSERT(!m_enqueueEvents);
if (m_frame) {
- ASSERT(m_frame->view() != this || !m_frame->document() || !m_frame->contentRenderer());
+ ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
RenderPart* renderer = m_frame->ownerRenderer();
if (renderer && renderer->widget() == this)
renderer->setWidget(0);
@@ -160,8 +189,10 @@ void FrameView::reset()
m_lastZoomFactor = 1.0f;
m_deferringRepaints = 0;
m_repaintCount = 0;
- m_repaintRect = IntRect();
m_repaintRects.clear();
+ m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading;
+ m_deferredRepaintTimer.stop();
+ m_lastPaintTime = 0;
m_paintRestriction = PaintRestrictionNone;
m_isPainting = false;
m_isVisuallyNonEmpty = false;
@@ -286,22 +317,20 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
{
// FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
Document* doc = m_frame->document();
- if (!doc)
- return ScrollView::createScrollbar(orientation);
// Try the <body> element first as a scrollbar source.
Element* body = doc->body();
- if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR))
+ if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderBox());
// If the <body> didn't have a custom style, then the root element might.
Element* docElement = doc->documentElement();
- if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR))
+ if (docElement && docElement->renderer() && docElement->renderer()->style()->hasPseudoStyle(SCROLLBAR))
return RenderScrollbar::createCustomScrollbar(this, orientation, docElement->renderBox());
// If we have an owning iframe/frame element, then it can set the custom scrollbar also.
RenderPart* frameRenderer = m_frame->ownerRenderer();
- if (frameRenderer && frameRenderer->style()->hasPseudoStyle(RenderStyle::SCROLLBAR))
+ if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR))
return RenderScrollbar::createCustomScrollbar(this, orientation, frameRenderer);
// Nobody set a custom style, so we just use a native scrollbar.
@@ -367,6 +396,41 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S
m_viewportRenderer = o;
}
+#if USE(ACCELERATED_COMPOSITING)
+void FrameView::updateCompositingLayers(CompositingUpdate updateType)
+{
+ RenderView* view = m_frame->contentRenderer();
+ if (!view || !view->usesCompositing())
+ return;
+
+ if (updateType == ForcedCompositingUpdate)
+ view->compositor()->setCompositingLayersNeedUpdate();
+
+ view->compositor()->updateCompositingLayers();
+}
+
+void FrameView::setNeedsOneShotDrawingSynchronization()
+{
+ Page* page = frame() ? frame()->page() : 0;
+ if (page)
+ page->chrome()->client()->setNeedsOneShotDrawingSynchronization();
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+void FrameView::didMoveOnscreen()
+{
+ RenderView* view = m_frame->contentRenderer();
+ if (view)
+ view->didMoveOnscreen();
+}
+
+void FrameView::willMoveOffscreen()
+{
+ RenderView* view = m_frame->contentRenderer();
+ if (view)
+ view->willMoveOffscreen();
+}
+
RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
{
return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
@@ -408,11 +472,6 @@ void FrameView::layout(bool allowSubtree)
return;
Document* document = m_frame->document();
- if (!document) {
- // FIXME: Should we set m_size.height here too?
- m_size.setWidth(layoutWidth());
- return;
- }
m_layoutSchedulingEnabled = false;
@@ -484,7 +543,7 @@ void FrameView::layout(bool allowSubtree)
#endif
}
- m_doFullRepaint = !subtree && (m_firstLayout || static_cast<RenderView*>(root)->printing());
+ m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
if (!subtree) {
// Now set our scrollbar state for the layout.
@@ -539,13 +598,17 @@ void FrameView::layout(bool allowSubtree)
m_layoutSchedulingEnabled = true;
- if (!subtree && !static_cast<RenderView*>(root)->printing())
+ if (!subtree && !toRenderView(root)->printing())
adjustViewSize();
// Now update the positions of all layers.
beginDeferredRepaints();
layer->updateLayerPositions(m_doFullRepaint);
endDeferredRepaints();
+
+#if USE(ACCELERATED_COMPOSITING)
+ updateCompositingLayers();
+#endif
m_layoutCount++;
@@ -573,7 +636,7 @@ void FrameView::layout(bool allowSubtree)
// Calls resumeScheduledEvents()
performPostLayoutTasks();
- if (needsLayout()) {
+ if (!m_postLayoutTasksTimer.isActive() && needsLayout()) {
// Post-layout widget updates or an event handler made us need layout again.
// Lay out again, but this time defer widget updates and event dispatch until after
// we return.
@@ -680,21 +743,31 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
{
ASSERT(!m_frame->document()->ownerElement());
- if (m_deferringRepaints && !immediate) {
+ double delay = adjustedDeferredRepaintDelay();
+ if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
IntRect visibleContent = visibleContentRect();
visibleContent.intersect(r);
- if (!visibleContent.isEmpty()) {
- m_repaintCount++;
- m_repaintRect.unite(r);
- if (m_repaintCount == cRepaintRectUnionThreshold)
- m_repaintRects.clear();
- else if (m_repaintCount < cRepaintRectUnionThreshold)
- m_repaintRects.append(r);
- }
#ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS
- else
+ if (visibleContent.isEmpty())
ScrollView::platformOffscreenContentRectangle(r);
#endif
+ if (visibleContent.isEmpty())
+ return;
+ if (m_repaintCount == cRepaintRectUnionThreshold) {
+ IntRect unionedRect;
+ for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
+ unionedRect.unite(m_repaintRects[i]);
+ m_repaintRects.clear();
+ m_repaintRects.append(unionedRect);
+ }
+ if (m_repaintCount < cRepaintRectUnionThreshold)
+ m_repaintRects.append(r);
+ else
+ m_repaintRects[0].unite(r);
+ m_repaintCount++;
+
+ if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
+ m_deferredRepaintTimer.startOneShot(delay);
return;
}
@@ -711,15 +784,6 @@ void FrameView::beginDeferredRepaints()
return page->mainFrame()->view()->beginDeferredRepaints();
m_deferringRepaints++;
-#ifdef ANDROID_FIX // This allows sub frames to accumulate deferred repaints
- if (m_deferringRepaints == 1) {
-#endif
- m_repaintCount = 0;
- m_repaintRect = IntRect();
- m_repaintRects.clear();
-#ifdef ANDROID_FIX
- }
-#endif
}
@@ -730,22 +794,90 @@ void FrameView::endDeferredRepaints()
return page->mainFrame()->view()->endDeferredRepaints();
ASSERT(m_deferringRepaints > 0);
- if (--m_deferringRepaints == 0) {
- if (m_repaintCount >= cRepaintRectUnionThreshold)
- repaintContentRectangle(m_repaintRect, false);
- else {
- unsigned size = m_repaintRects.size();
- for (unsigned i = 0; i < size; i++)
- repaintContentRectangle(m_repaintRects[i], false);
- m_repaintRects.clear();
- }
+
+ if (--m_deferringRepaints)
+ return;
+
+ if (m_deferredRepaintTimer.isActive())
+ return;
+
+ if (double delay = adjustedDeferredRepaintDelay()) {
+ m_deferredRepaintTimer.startOneShot(delay);
+ return;
}
+
+ doDeferredRepaints();
}
+void FrameView::checkStopDelayingDeferredRepaints()
+{
+ if (!m_deferredRepaintTimer.isActive())
+ return;
+
+ Document* document = m_frame->document();
+ if (document && (document->parsing() || document->docLoader()->requestCount()))
+ return;
+
+ m_deferredRepaintTimer.stop();
+
+ doDeferredRepaints();
+}
+
+void FrameView::doDeferredRepaints()
+{
+ ASSERT(!m_deferringRepaints);
+ if (isOffscreen() && !shouldUpdateWhileOffscreen()) {
+ m_repaintRects.clear();
+ m_repaintCount = 0;
+ return;
+ }
+ unsigned size = m_repaintRects.size();
+ for (unsigned i = 0; i < size; i++)
+ ScrollView::repaintContentRectangle(m_repaintRects[i], false);
+ m_repaintRects.clear();
+ m_repaintCount = 0;
+
+ updateDeferredRepaintDelay();
+}
+
+void FrameView::updateDeferredRepaintDelay()
+{
+ Document* document = m_frame->document();
+ if (!document || (!document->parsing() && !document->docLoader()->requestCount())) {
+ m_deferredRepaintDelay = deferredRepaintDelay;
+ return;
+ }
+ if (m_deferredRepaintDelay < maxDeferredRepaintDelayDuringLoading) {
+ m_deferredRepaintDelay += deferredRepaintDelayIncrementDuringLoading;
+ if (m_deferredRepaintDelay > maxDeferredRepaintDelayDuringLoading)
+ m_deferredRepaintDelay = maxDeferredRepaintDelayDuringLoading;
+ }
+}
+
+void FrameView::resetDeferredRepaintDelay()
+{
+ m_deferredRepaintDelay = 0;
+ if (m_deferredRepaintTimer.isActive())
+ m_deferredRepaintTimer.startOneShot(0);
+}
+
+double FrameView::adjustedDeferredRepaintDelay() const
+{
+ if (!m_deferredRepaintDelay)
+ return 0;
+ double timeSinceLastPaint = currentTime() - m_lastPaintTime;
+ return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
+}
+
+void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
+{
+ doDeferredRepaints();
+}
+
void FrameView::layoutTimerFired(Timer<FrameView>*)
{
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (m_frame->document() && !m_frame->document()->ownerElement())
+ if (!m_frame->document()->ownerElement())
printf("Layout timer fired at %d\n", m_frame->document()->elapsedTime());
#endif
layout();
@@ -753,7 +885,7 @@ void FrameView::layoutTimerFired(Timer<FrameView>*)
void FrameView::scheduleRelayout()
{
- ASSERT(!m_frame->document() || !m_frame->document()->inPageCache());
+ ASSERT(!m_frame->document()->inPageCache());
ASSERT(m_frame->view() == this);
if (m_layoutRoot) {
@@ -764,7 +896,7 @@ void FrameView::scheduleRelayout()
return;
if (!needsLayout())
return;
- if (!m_frame->document() || !m_frame->document()->shouldScheduleLayout())
+ if (!m_frame->document()->shouldScheduleLayout())
return;
#if defined(FLATTEN_IFRAME) || defined(FLATTEN_FRAMESET)
@@ -858,7 +990,7 @@ bool FrameView::needsLayout() const
return layoutPending()
|| (root && root->needsLayout())
|| m_layoutRoot
- || (document && document->hasChangedChild()) // can occur when using WebKit ObjC interface
+ || document->hasChangedChild() // can occur when using WebKit ObjC interface
|| m_frame->needsReapplyStyles();
}
@@ -875,7 +1007,7 @@ void FrameView::unscheduleRelayout()
return;
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (m_frame->document() && !m_frame->document()->ownerElement())
+ if (!m_frame->document()->ownerElement())
printf("Layout timer unscheduled at %d\n", m_frame->document()->elapsedTime());
#endif
@@ -927,7 +1059,7 @@ void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
}
-void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<EventTargetNode> eventTarget)
+void FrameView::scheduleEvent(PassRefPtr<Event> event, PassRefPtr<Node> eventTarget)
{
if (!m_enqueueEvents) {
ExceptionCode ec = 0;
@@ -955,6 +1087,29 @@ void FrameView::resumeScheduledEvents()
ASSERT(m_scheduledEvents.isEmpty() || m_enqueueEvents);
}
+bool FrameView::updateWidgets()
+{
+ if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
+ return true;
+
+ Vector<RenderPartObject*> objectVector;
+ copyToVector(*m_widgetUpdateSet, objectVector);
+ size_t size = objectVector.size();
+ for (size_t i = 0; i < size; ++i) {
+ RenderPartObject* object = objectVector[i];
+ object->updateWidget(false);
+
+ // updateWidget() can destroy the RenderPartObject, so we need to make sure it's
+ // alive by checking if it's still in m_widgetUpdateSet.
+ if (m_widgetUpdateSet->contains(object)) {
+ object->updateWidgetPosition();
+ m_widgetUpdateSet->remove(object);
+ }
+ }
+
+ return m_widgetUpdateSet->isEmpty();
+}
+
void FrameView::performPostLayoutTasks()
{
if (m_firstLayoutCallbackPending) {
@@ -970,22 +1125,12 @@ void FrameView::performPostLayoutTasks()
RenderView* root = m_frame->contentRenderer();
root->updateWidgetPositions();
- if (m_widgetUpdateSet && m_nestedLayoutCount <= 1) {
- Vector<RenderPartObject*> objectVector;
- copyToVector(*m_widgetUpdateSet, objectVector);
- size_t size = objectVector.size();
- for (size_t i = 0; i < size; ++i) {
- RenderPartObject* object = objectVector[i];
- object->updateWidget(false);
-
- // updateWidget() can destroy the RenderPartObject, so we need to make sure it's
- // alive by checking if it's still in m_widgetUpdateSet.
- if (m_widgetUpdateSet->contains(object))
- object->updateWidgetPosition();
- }
- m_widgetUpdateSet->clear();
+
+ for (unsigned i = 0; i < maxUpdateWidgetsIterations; i++) {
+ if (updateWidgets())
+ break;
}
-
+
resumeScheduledEvents();
if (!root->printing()) {
@@ -995,7 +1140,7 @@ void FrameView::performPostLayoutTasks()
m_lastLayoutSize = currentSize;
m_lastZoomFactor = currentZoomFactor;
if (resized)
- m_frame->sendResizeEvent();
+ m_frame->eventHandler()->sendResizeEvent();
}
}
@@ -1025,7 +1170,7 @@ void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverf
scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow,
verticalOverflowChanged, verticalOverflow),
- EventTargetNodeCast(m_viewportRenderer->element()));
+ m_viewportRenderer->node());
}
}
@@ -1058,7 +1203,7 @@ IntRect FrameView::windowClipRect(bool clipToContents) const
// Set our clip rect to be our contents.
IntRect clipRect = contentsToWindow(visibleContentRect(!clipToContents));
- if (!m_frame || !m_frame->document() || !m_frame->document()->ownerElement())
+ if (!m_frame || !m_frame->document()->ownerElement())
return clipRect;
// Take our owner element and get the clip rect from the enclosing layer.
@@ -1100,7 +1245,7 @@ void FrameView::valueChanged(Scrollbar* bar)
IntSize offset = scrollOffset();
ScrollView::valueChanged(bar);
if (offset != scrollOffset())
- frame()->sendScrollEvent();
+ frame()->eventHandler()->sendScrollEvent();
}
void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
@@ -1184,12 +1329,10 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
return;
Document* document = frame()->document();
- if (!document)
- return;
#ifndef NDEBUG
bool fillWithRed;
- if (document || document->printing())
+ if (document->printing())
fillWithRed = false; // Printing, don't fill with red (can't remember why).
else if (document->ownerElement())
fillWithRed = false; // Subframe, don't fill with red.
@@ -1226,8 +1369,9 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
if (m_paintRestriction == PaintRestrictionNone)
document->invalidateRenderedRectsForMarkersInRect(rect);
contentRenderer->layer()->paint(p, rect, m_paintRestriction, eltRenderer);
-
+
m_isPainting = false;
+ m_lastPaintTime = currentTime();
#if ENABLE(DASHBOARD_SUPPORT)
// Regions may have changed as a result of the visibility/z-index of element changing.
@@ -1275,4 +1419,60 @@ void FrameView::layoutIfNeededRecursive()
static_cast<FrameView*>(*current)->layoutIfNeededRecursive();
}
+void FrameView::forceLayout(bool allowSubtree)
+{
+ layout(allowSubtree);
+ // We cannot unschedule a pending relayout, since the force can be called with
+ // a tiny rectangle from a drawRect update. By unscheduling we in effect
+ // "validate" and stop the necessary full repaint from occurring. Basically any basic
+ // append/remove DHTML is broken by this call. For now, I have removed the optimization
+ // until we have a better invalidation stategy. -dwh
+ //unscheduleRelayout();
+}
+
+void FrameView::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool _adjustViewSize)
+{
+ // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
+ // the state of things before and after the layout
+ RenderView *root = toRenderView(m_frame->document()->renderer());
+ if (root) {
+ // This magic is basically copied from khtmlview::print
+ int pageW = (int)ceilf(minPageWidth);
+ root->setWidth(pageW);
+ root->setNeedsLayoutAndPrefWidthsRecalc();
+ forceLayout();
+
+ // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
+ // maximum page width, we will lay out to the maximum page width and clip extra content.
+ // FIXME: We are assuming a shrink-to-fit printing implementation. A cropping
+ // implementation should not do this!
+ int rightmostPos = root->rightmostPosition();
+ if (rightmostPos > minPageWidth) {
+ pageW = std::min(rightmostPos, (int)ceilf(maxPageWidth));
+ root->setWidth(pageW);
+ root->setNeedsLayoutAndPrefWidthsRecalc();
+ forceLayout();
+ }
+ }
+
+ if (_adjustViewSize)
+ adjustViewSize();
+}
+
+void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
+{
+ RenderView* root = m_frame->contentRenderer();
+ if (root) {
+ // Use a context with painting disabled.
+ GraphicsContext context((PlatformGraphicsContext*)0);
+ root->setTruncatedAt((int)floorf(oldBottom));
+ IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop));
+ root->layer()->paint(&context, dirtyRect);
+ *newBottom = root->bestTruncatedAt();
+ if (*newBottom == 0)
+ *newBottom = oldBottom;
+ } else
+ *newBottom = oldBottom;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index a1d514f..07295d3 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -35,7 +35,6 @@ namespace WebCore {
class Color;
class Event;
-class EventTargetNode;
class Frame;
class FrameViewPrivate;
class IntRect;
@@ -97,6 +96,18 @@ public:
bool needsFullRepaint() const { return m_doFullRepaint; }
+#if USE(ACCELERATED_COMPOSITING)
+ enum CompositingUpdate { NormalCompositingUpdate, ForcedCompositingUpdate };
+ void updateCompositingLayers(CompositingUpdate updateType = NormalCompositingUpdate);
+
+ // Called when changes to the GraphicsLayer hierarchy have to be synchronized with
+ // content rendered via the normal painting path.
+ void setNeedsOneShotDrawingSynchronization();
+#endif
+
+ void didMoveOnscreen();
+ void willMoveOffscreen();
+
void resetScrollbars();
void clear();
@@ -138,6 +149,8 @@ public:
void beginDeferredRepaints();
void endDeferredRepaints();
+ void checkStopDelayingDeferredRepaints();
+ void resetDeferredRepaintDelay();
#if ENABLE(DASHBOARD_SUPPORT)
void updateDashboardRegions();
@@ -146,7 +159,7 @@ public:
void restoreScrollbar();
- void scheduleEvent(PassRefPtr<Event>, PassRefPtr<EventTargetNode>);
+ void scheduleEvent(PassRefPtr<Event>, PassRefPtr<Node>);
void pauseScheduledEvents();
void resumeScheduledEvents();
void postLayoutTimerFired(Timer<FrameView>*);
@@ -168,6 +181,12 @@ public:
void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
+ void forceLayout(bool allowSubtree = false);
+ void forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool adjustViewSize);
+
+ void adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float bottomLimit);
+
+
private:
void reset();
void init();
@@ -186,7 +205,14 @@ private:
virtual void repaintContentRectangle(const IntRect&, bool immediate);
virtual void contentsResized() { setNeedsLayout(); }
virtual void visibleContentsResized() { layout(); }
+
+ void deferredRepaintTimerFired(Timer<FrameView>*);
+ void doDeferredRepaints();
+ void updateDeferredRepaintDelay();
+ double adjustedDeferredRepaintDelay() const;
+ bool updateWidgets();
+
static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
unsigned m_refCount;
@@ -237,8 +263,10 @@ private:
unsigned m_deferringRepaints;
unsigned m_repaintCount;
- IntRect m_repaintRect;
Vector<IntRect> m_repaintRects;
+ Timer<FrameView> m_deferredRepaintTimer;
+ double m_deferredRepaintDelay;
+ double m_lastPaintTime;
bool m_shouldUpdateWhileOffscreen;
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index f82e95d..e2f31a1 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,8 +26,10 @@
#include "config.h"
#include "Geolocation.h"
+#include "Chrome.h"
#include "Document.h"
#include "Frame.h"
+#include "Page.h"
#include "PositionError.h"
namespace WebCore {
@@ -54,7 +56,11 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
Geolocation::Geolocation(Frame* frame)
: m_frame(frame)
, m_service(GeolocationService::create(this))
+ , m_allowGeolocation(Unknown)
+ , m_shouldClearCache(false)
{
+ if (!m_frame)
+ return;
ASSERT(m_frame->document());
m_frame->document()->setUsingGeolocation(true);
}
@@ -62,8 +68,6 @@ Geolocation::Geolocation(Frame* frame)
void Geolocation::disconnectFrame()
{
m_service->stopUpdating();
- if (m_frame->document())
- m_frame->document()->setUsingGeolocation(false);
m_frame = 0;
}
@@ -121,6 +125,18 @@ void Geolocation::resume()
m_service->resume();
}
+void Geolocation::setIsAllowed(bool allowed)
+{
+ m_allowGeolocation = allowed ? Yes : No;
+
+ if (isAllowed())
+ geolocationServicePositionChanged(m_service.get());
+ else {
+ WTF::RefPtr<WebCore::PositionError> error = WebCore::PositionError::create(PositionError::PERMISSION_DENIED, "User disallowed GeoLocation");
+ handleError(error.get());
+ }
+}
+
void Geolocation::sendErrorToOneShots(PositionError* error)
{
Vector<RefPtr<GeoNotifier> > copy;
@@ -199,10 +215,32 @@ void Geolocation::handleError(PositionError* error)
m_oneShots.clear();
}
+void Geolocation::requestPermission()
+{
+ if (m_allowGeolocation > Unknown)
+ return;
+
+ if (!m_frame)
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ // Ask the chrome: it maintains the geolocation challenge policy itself.
+ page->chrome()->requestGeolocationPermissionForFrame(m_frame, this);
+
+ m_allowGeolocation = InProgress;
+}
+
void Geolocation::geolocationServicePositionChanged(GeolocationService* service)
{
ASSERT(service->lastPosition());
+ requestPermission();
+ if (!isAllowed())
+ return;
+
sendPositionToOneShots(service->lastPosition());
sendPositionToWatchers(service->lastPosition());
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index 572cbd8..a14fc4b 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,6 +60,12 @@ public:
void suspend();
void resume();
+
+ void setIsAllowed(bool);
+ bool isAllowed() const { return m_allowGeolocation == Yes; }
+
+ void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = shouldClearCache; }
+ bool shouldClearCache() const { return m_shouldClearCache; }
private:
Geolocation(Frame*);
@@ -77,7 +83,7 @@ private:
private:
GeoNotifier(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PositionOptions*);
};
-
+
bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
void sendErrorToOneShots(PositionError*);
@@ -86,10 +92,13 @@ private:
void sendPositionToWatchers(Geoposition*);
void handleError(PositionError*);
-
+
+ void requestPermission();
+
+ // GeolocationServiceClient
virtual void geolocationServicePositionChanged(GeolocationService*);
virtual void geolocationServiceErrorOccurred(GeolocationService*);
-
+
typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
typedef HashMap<int, RefPtr<GeoNotifier> > GeoNotifierMap;
@@ -97,6 +106,14 @@ private:
GeoNotifierMap m_watchers;
Frame* m_frame;
OwnPtr<GeolocationService> m_service;
+
+ enum {
+ Unknown,
+ InProgress,
+ Yes,
+ No
+ } m_allowGeolocation;
+ bool m_shouldClearCache;
};
} // namespace WebCore
diff --git a/WebCore/page/Geoposition.cpp b/WebCore/page/Geoposition.cpp
index 1792a1f..8f7a5c8 100644
--- a/WebCore/page/Geoposition.cpp
+++ b/WebCore/page/Geoposition.cpp
@@ -30,9 +30,7 @@ namespace WebCore {
String Geoposition::toString() const
{
- return String::format("position(%.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.6lg, %.lld)",
- m_latitude, m_longitude, m_altitude, m_accuracy,
- m_altitudeAccuracy, m_heading, m_speed, m_timestamp);
+ return "position(" + m_coordinates->toString() + String::format(", %.lld)", m_timestamp);
}
} // namespace WebCore
diff --git a/WebCore/page/Geoposition.h b/WebCore/page/Geoposition.h
index 9ce50e5..505e8b3 100644
--- a/WebCore/page/Geoposition.h
+++ b/WebCore/page/Geoposition.h
@@ -26,6 +26,7 @@
#ifndef Geoposition_h
#define Geoposition_h
+#include "Coordinates.h"
#include "Event.h"
#include "PlatformString.h"
#include <wtf/RefCounted.h>
@@ -36,39 +37,21 @@ typedef int ExceptionCode;
class Geoposition : public RefCounted<Geoposition> {
public:
- static PassRefPtr<Geoposition> create(double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy, double heading, double speed, DOMTimeStamp timestamp) { return adoptRef(new Geoposition(latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, speed, timestamp)); }
+ static PassRefPtr<Geoposition> create(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp) { return adoptRef(new Geoposition(coordinates, timestamp)); }
- double latitude() const { return m_latitude; }
- double longitude() const { return m_longitude; }
- double altitude() const { return m_altitude; }
- double accuracy() const { return m_accuracy; }
- double altitudeAccuracy() const { return m_altitudeAccuracy; }
- double heading() const { return m_heading; }
- double speed() const { return m_speed; }
DOMTimeStamp timestamp() const { return m_timestamp; }
-
+ Coordinates* coords() const { return m_coordinates.get(); }
+
String toString() const;
private:
- Geoposition(double latitude, double longitude, double altitude, double accuracy, double altitudeAccuracy, double heading, double speed, DOMTimeStamp timestamp)
- : m_latitude(latitude)
- , m_longitude(longitude)
- , m_altitude(altitude)
- , m_accuracy(accuracy)
- , m_altitudeAccuracy(altitudeAccuracy)
- , m_heading(heading)
- , m_speed(speed)
+ Geoposition(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp)
+ : m_coordinates(coordinates)
, m_timestamp(timestamp)
{
}
- double m_latitude;
- double m_longitude;
- double m_altitude;
- double m_accuracy;
- double m_altitudeAccuracy;
- double m_heading;
- double m_speed;
+ RefPtr<Coordinates> m_coordinates;
DOMTimeStamp m_timestamp;
};
diff --git a/WebCore/page/Geoposition.idl b/WebCore/page/Geoposition.idl
index 554bb30..2bcd40d 100644
--- a/WebCore/page/Geoposition.idl
+++ b/WebCore/page/Geoposition.idl
@@ -26,13 +26,7 @@
module core {
interface Geoposition {
- readonly attribute double latitude;
- readonly attribute double longitude;
- readonly attribute double altitude;
- readonly attribute double accuracy;
- readonly attribute double altitudeAccuracy;
- readonly attribute double heading;
- readonly attribute double speed;
+ readonly attribute Coordinates coords;
readonly attribute DOMTimeStamp timestamp;
#if defined(LANGUAGE_JAVASCRIPT)
diff --git a/WebCore/page/History.idl b/WebCore/page/History.idl
index e86cf92..c8cddae 100644
--- a/WebCore/page/History.idl
+++ b/WebCore/page/History.idl
@@ -26,6 +26,9 @@
module window {
interface [
+#if defined(V8_BINDING)
+ CheckDomainSecurity,
+#endif
CustomGetOwnPropertySlot,
CustomPutFunction,
CustomDeleteProperty,
@@ -33,9 +36,9 @@ module window {
] History {
readonly attribute unsigned long length;
- void back();
- void forward();
- void go(in long distance);
+ [DoNotCheckDomainSecurity] void back();
+ [DoNotCheckDomainSecurity] void forward();
+ [DoNotCheckDomainSecurity] void go(in long distance);
};
}
diff --git a/WebCore/page/Location.cpp b/WebCore/page/Location.cpp
index 454aa78..ba28086 100644
--- a/WebCore/page/Location.cpp
+++ b/WebCore/page/Location.cpp
@@ -111,7 +111,8 @@ String Location::search() const
if (!m_frame)
return String();
- return url().query();
+ const KURL& url = this->url();
+ return url.query().isEmpty() ? "" : "?" + url.query();
}
String Location::hash() const
@@ -120,7 +121,7 @@ String Location::hash() const
return String();
const KURL& url = this->url();
- return url.ref().isNull() ? "" : "#" + url.ref();
+ return url.ref().isEmpty() ? "" : "#" + url.ref();
}
String Location::toString() const
diff --git a/WebCore/page/Location.idl b/WebCore/page/Location.idl
index 91822ab..20f8bbd 100644
--- a/WebCore/page/Location.idl
+++ b/WebCore/page/Location.idl
@@ -29,16 +29,19 @@
module window {
interface [
+#if defined(V8_BINDING)
+ CheckDomainSecurity,
+#endif
CustomGetOwnPropertySlot,
CustomPutFunction,
CustomDeleteProperty,
CustomGetPropertyNames
] Location {
- attribute [CustomSetter] DOMString href;
+ attribute [DoNotCheckDomainSecurityOnSet, CustomSetter, V8DisallowShadowing] DOMString href;
- [Custom] void assign(in DOMString url);
- [Custom] void replace(in DOMString url);
- [Custom] void reload();
+ [Custom, V8OnInstance] void assign(in DOMString url);
+ [Custom, V8OnInstance] void replace(in DOMString url);
+ [Custom, V8OnInstance] void reload();
// URI decomposition attributes
attribute [CustomSetter] DOMString protocol;
@@ -50,7 +53,10 @@ module window {
attribute [CustomSetter] DOMString hash;
#if defined(LANGUAGE_JAVASCRIPT)
- [DontEnum, Custom] DOMString toString();
+ [DontEnum, Custom, V8OnInstance, V8ReadOnly] DOMString toString();
+#endif
+#if defined(V8_BINDING)
+ [DontEnum, Custom, V8OnInstance, V8ReadOnly] DOMObject valueOf();
#endif
};
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
index 429ec00..dd4d27d 100644
--- a/WebCore/page/Navigator.cpp
+++ b/WebCore/page/Navigator.cpp
@@ -102,7 +102,13 @@ String Navigator::userAgent() const
{
if (!m_frame)
return String();
- return m_frame->loader()->userAgent(m_frame->document() ? m_frame->document()->url() : KURL());
+
+ // If the frame is already detached, FrameLoader::userAgent may malfunction, because it calls a client method
+ // that uses frame's WebView (at least, in Mac WebKit).
+ if (!m_frame->page())
+ return String();
+
+ return m_frame->loader()->userAgent(m_frame->document()->url());
}
PluginArray* Navigator::plugins() const
@@ -121,6 +127,9 @@ MimeTypeArray* Navigator::mimeTypes() const
bool Navigator::cookieEnabled() const
{
+ if (!m_frame)
+ return false;
+
if (m_frame->page() && !m_frame->page()->cookieEnabled())
return false;
@@ -129,8 +138,9 @@ bool Navigator::cookieEnabled() const
bool Navigator::javaEnabled() const
{
- if (!m_frame)
+ if (!m_frame || !m_frame->settings())
return false;
+
return m_frame->settings()->isJavaEnabled();
}
diff --git a/WebCore/page/NavigatorBase.cpp b/WebCore/page/NavigatorBase.cpp
index 27c9fdd..5138b0f 100644
--- a/WebCore/page/NavigatorBase.cpp
+++ b/WebCore/page/NavigatorBase.cpp
@@ -31,9 +31,9 @@
#include "PlatformString.h"
#ifndef WEBCORE_NAVIGATOR_PLATFORM
-#if PLATFORM(MAC) && PLATFORM(PPC)
+#if PLATFORM(MAC) && (PLATFORM(PPC) || PLATFORM(PPC64))
#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
-#elif PLATFORM(MAC) && PLATFORM(X86)
+#elif PLATFORM(MAC) && (PLATFORM(X86) || PLATFORM(X86_64))
#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel"
#elif PLATFORM(WIN_OS)
#define WEBCORE_NAVIGATOR_PLATFORM "Win32"
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index 460183a..457bcde 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -93,11 +93,8 @@ static void networkStateChanged()
for (unsigned i = 0; i < frames.size(); i++) {
Document* document = frames[i]->document();
- if (!document)
- continue;
-
// If the document does not have a body the event should be dispatched to the document
- EventTargetNode* eventTarget = document->body();
+ Node* eventTarget = document->body();
if (!eventTarget)
eventTarget = document;
@@ -111,7 +108,7 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
, m_dragController(new DragController(this, dragClient))
, m_focusController(new FocusController(this))
, m_contextMenuController(new ContextMenuController(this, contextMenuClient))
- , m_inspectorController(new InspectorController(this, inspectorClient))
+ , m_inspectorController(InspectorController::create(this, inspectorClient))
, m_settings(new Settings(this))
, m_progress(new ProgressTracker)
, m_backForwardList(BackForwardList::create(this))
@@ -157,11 +154,9 @@ Page::~Page()
setGroupName(String());
allPages->remove(this);
- for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (frame->document())
- frame->document()->documentWillBecomeInactive();
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
frame->pageDestroyed();
- }
+
m_editorClient->pageDestroyed();
if (m_parentInspectorController)
m_parentInspectorController->pageDestroyed();
@@ -233,7 +228,7 @@ void Page::setGroupName(const String& name)
}
if (name.isEmpty())
- m_group = 0;
+ m_group = m_singlePageGroup.get();
else {
m_singlePageGroup.clear();
m_group = PageGroup::pageGroup(name);
@@ -358,13 +353,12 @@ void Page::unmarkAllTextMatches()
Frame* frame = mainFrame();
do {
- if (Document* document = frame->document())
- document->removeMarkers(DocumentMarker::TextMatch);
+ frame->document()->removeMarkers(DocumentMarker::TextMatch);
frame = incrementFrame(frame, true, false);
} while (frame);
}
-const Selection& Page::selection() const
+const VisibleSelection& Page::selection() const
{
return focusController()->focusedOrMainFrame()->selection()->selection();
}
@@ -404,8 +398,23 @@ void Page::setMediaVolume(float volume)
m_mediaVolume = volume;
for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (frame->document())
- frame->document()->mediaVolumeDidChange();
+ frame->document()->mediaVolumeDidChange();
+ }
+}
+
+void Page::didMoveOnscreen()
+{
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->view())
+ frame->view()->didMoveOnscreen();
+ }
+}
+
+void Page::willMoveOffscreen()
+{
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->view())
+ frame->view()->willMoveOffscreen();
}
}
@@ -461,7 +470,9 @@ const String& Page::userStyleSheet() const
if (!data)
return m_userStyleSheet;
- m_userStyleSheet = TextResourceDecoder::create("text/css")->decode(data->data(), data->size());
+ RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/css");
+ m_userStyleSheet = decoder->decode(data->data(), data->size());
+ m_userStyleSheet += decoder->flush();
return m_userStyleSheet;
}
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index aea16a2..f140783 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -60,7 +60,7 @@ namespace WebCore {
class PageGroup;
class PluginData;
class ProgressTracker;
- class Selection;
+ class VisibleSelection;
class SelectionController;
#if ENABLE(DOM_STORAGE)
class SessionStorage;
@@ -137,7 +137,7 @@ namespace WebCore {
OwnPtr<SchedulePairHashSet> m_scheduledRunLoopPairs;
#endif
- const Selection& selection() const;
+ const VisibleSelection& selection() const;
void setDefersLoading(bool);
bool defersLoading() const { return m_defersLoading; }
@@ -153,6 +153,10 @@ namespace WebCore {
float mediaVolume() const { return m_mediaVolume; }
void setMediaVolume(float volume);
+ // Notifications when the Page starts and stops being presented via a native window.
+ void didMoveOnscreen();
+ void willMoveOffscreen();
+
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
@@ -204,7 +208,7 @@ namespace WebCore {
OwnPtr<DragController> m_dragController;
OwnPtr<FocusController> m_focusController;
OwnPtr<ContextMenuController> m_contextMenuController;
- OwnPtr<InspectorController> m_inspectorController;
+ RefPtr<InspectorController> m_inspectorController;
OwnPtr<Settings> m_settings;
OwnPtr<ProgressTracker> m_progress;
diff --git a/WebCore/page/PositionOptions.h b/WebCore/page/PositionOptions.h
index dc9c167..10845d3 100644
--- a/WebCore/page/PositionOptions.h
+++ b/WebCore/page/PositionOptions.h
@@ -33,22 +33,26 @@ namespace WebCore {
class PositionOptions : public RefCounted<PositionOptions> {
public:
- static PassRefPtr<PositionOptions> create(bool highAccuracy, unsigned timeout) { return adoptRef(new PositionOptions(highAccuracy, timeout)); }
+ static PassRefPtr<PositionOptions> create(bool highAccuracy, unsigned timeout, unsigned maximumAge) { return adoptRef(new PositionOptions(highAccuracy, timeout, maximumAge)); }
bool enableHighAccuracy() const { return m_highAccuracy; }
void setEnableHighAccuracy(bool enable) { m_highAccuracy = enable; }
unsigned timeout() const { return m_timeout; }
void setTimeout(unsigned t) { m_timeout = t; }
+ unsigned maximumAge() const { return m_maximumAge; }
+ void setMaximumAge(unsigned a) { m_maximumAge = a; }
private:
- PositionOptions(bool highAccuracy, unsigned timeout)
+ PositionOptions(bool highAccuracy, unsigned timeout, unsigned maximumAge)
: m_highAccuracy(highAccuracy)
, m_timeout(timeout)
+ , m_maximumAge(maximumAge)
{
}
bool m_highAccuracy;
unsigned m_timeout;
+ unsigned m_maximumAge;
};
} // namespace WebCore
diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp
index 79672a3..b83d714 100644
--- a/WebCore/page/PrintContext.cpp
+++ b/WebCore/page/PrintContext.cpp
@@ -85,7 +85,7 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
float printedPagesHeight = 0.0;
do {
float proposedBottom = std::min(docHeight, printedPagesHeight + pageHeight);
- m_frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
+ m_frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight));
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index fd8144f..a1863c9 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -58,14 +58,15 @@ SecurityOrigin::SecurityOrigin(const KURL& url)
, m_host(url.host().isNull() ? "" : url.host().lower())
, m_port(url.port())
, m_noAccess(false)
+ , m_universalAccess(false)
, m_domainWasSetInDOM(false)
{
// These protocols do not create security origins; the owner frame provides the origin
if (m_protocol == "about" || m_protocol == "javascript")
m_protocol = "";
- // data: URLs are not allowed access to anything other than themselves.
- if (m_protocol == "data")
+ // Some URLs are not allowed access to anything other than themselves.
+ if (FrameLoader::shouldTreatURLSchemeAsNoAccess(m_protocol))
m_noAccess = true;
// document.domain starts as m_host, but can be set by the DOM.
@@ -84,6 +85,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
, m_domain(other->m_domain.copy())
, m_port(other->m_port)
, m_noAccess(other->m_noAccess)
+ , m_universalAccess(other->m_universalAccess)
, m_domainWasSetInDOM(other->m_domainWasSetInDOM)
, m_canLoadLocalResources(other->m_canLoadLocalResources)
{
@@ -119,7 +121,7 @@ void SecurityOrigin::setDomainFromDOM(const String& newDomain)
bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
{
- if (isLocal())
+ if (m_universalAccess)
return true;
if (m_noAccess || other->m_noAccess)
@@ -160,7 +162,7 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
bool SecurityOrigin::canRequest(const KURL& url) const
{
- if (isLocal())
+ if (m_universalAccess)
return true;
if (m_noAccess)
@@ -184,9 +186,14 @@ void SecurityOrigin::grantLoadLocalResources()
m_canLoadLocalResources = true;
}
+void SecurityOrigin::grantUniversalAccess()
+{
+ m_universalAccess = true;
+}
+
bool SecurityOrigin::isLocal() const
{
- return FrameLoader::shouldTreatSchemeAsLocal(m_protocol);
+ return FrameLoader::shouldTreatURLSchemeAsLocal(m_protocol);
}
bool SecurityOrigin::isSecureTransitionTo(const KURL& url) const
@@ -211,7 +218,7 @@ String SecurityOrigin::toString() const
return String("file://");
Vector<UChar> result;
- result.reserveCapacity(m_protocol.length() + m_host.length() + 10);
+ result.reserveInitialCapacity(m_protocol.length() + m_host.length() + 10);
append(result, m_protocol);
append(result, "://");
append(result, m_host);
@@ -259,7 +266,7 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const St
// Split out the 3 sections of data
String protocol = databaseIdentifier.substring(0, separator1);
String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
- return create(KURL(protocol + "://" + host + ":" + String::number(port)));
+ return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(port)));
}
String SecurityOrigin::databaseIdentifier() const
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index 1f2624e..96f85df 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -90,6 +90,11 @@ namespace WebCore {
// with older versions of WebKit.
void grantLoadLocalResources();
+ // Explicitly grant the ability to access very other SecurityOrigin.
+ //
+ // WARNING: This is an extremely powerful ability. Use with caution!
+ void grantUniversalAccess();
+
bool isSecureTransitionTo(const KURL&) const;
// The local SecurityOrigin is the most privileged SecurityOrigin.
@@ -132,6 +137,7 @@ namespace WebCore {
String m_domain;
unsigned short m_port;
bool m_noAccess;
+ bool m_universalAccess;
bool m_domainWasSetInDOM;
bool m_canLoadLocalResources;
};
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 8c9bb44..1815535 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -72,6 +72,8 @@ Settings::Settings(Page* page)
, m_databasesEnabled(false)
, m_localStorageEnabled(false)
, m_isJavaScriptEnabled(false)
+ , m_isWebSecurityEnabled(true)
+ , m_allowUniversalAccessFromFileURLs(true)
, m_javaScriptCanOpenWindowsAutomatically(false)
, m_shouldPrintBackgrounds(false)
, m_textAreasAreResizable(false)
@@ -80,6 +82,8 @@ Settings::Settings(Page* page)
#endif
, m_needsAdobeFrameReloadingQuirk(false)
, m_needsKeyboardEventDisambiguationQuirks(false)
+ , m_needsLeopardMailQuirks(false)
+ , m_needsTigerMailQuirks(false)
, m_isDOMPasteAllowed(false)
, m_shrinksStandaloneImagesToFit(true)
, m_usesPageCache(false)
@@ -92,12 +96,12 @@ Settings::Settings(Page* page)
, m_webArchiveDebugModeEnabled(false)
, m_inApplicationChromeMode(false)
, m_offlineWebApplicationCacheEnabled(false)
- , m_rangeMutationDisabledForOldAppleMail(false)
, m_shouldPaintCustomScrollbars(false)
, m_zoomsTextOnly(false)
, m_enforceCSSMIMETypeInStrictMode(true)
+ , m_usesEncodingDetector(false)
, m_maximumDecodedImageSize(std::numeric_limits<size_t>::max())
- , m_needsIChatMemoryCacheCallsQuirk(false)
+ , m_allowScriptsToCloseWindows(false)
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -214,6 +218,16 @@ void Settings::setJavaScriptEnabled(bool isJavaScriptEnabled)
m_isJavaScriptEnabled = isJavaScriptEnabled;
}
+void Settings::setWebSecurityEnabled(bool isWebSecurityEnabled)
+{
+ m_isWebSecurityEnabled = isWebSecurityEnabled;
+}
+
+void Settings::setAllowUniversalAccessFromFileURLs(bool allowUniversalAccessFromFileURLs)
+{
+ m_allowUniversalAccessFromFileURLs = allowUniversalAccessFromFileURLs;
+}
+
void Settings::setJavaEnabled(bool isJavaEnabled)
{
m_isJavaEnabled = isJavaEnabled;
@@ -313,6 +327,16 @@ void Settings::setNeedsKeyboardEventDisambiguationQuirks(bool needsQuirks)
m_needsKeyboardEventDisambiguationQuirks = needsQuirks;
}
+void Settings::setNeedsLeopardMailQuirks(bool needsQuirks)
+{
+ m_needsLeopardMailQuirks = needsQuirks;
+}
+
+void Settings::setNeedsTigerMailQuirks(bool needsQuirks)
+{
+ m_needsTigerMailQuirks = needsQuirks;
+}
+
void Settings::setDOMPasteAllowed(bool DOMPasteAllowed)
{
m_isDOMPasteAllowed = DOMPasteAllowed;
@@ -483,11 +507,6 @@ void Settings::setLocalStorageDatabasePath(const String& path)
m_localStorageDatabasePath = path;
}
-void Settings::disableRangeMutationForOldAppleMail(bool disable)
-{
- m_rangeMutationDisabledForOldAppleMail = disable;
-}
-
void Settings::setApplicationChromeMode(bool mode)
{
m_inApplicationChromeMode = mode;
@@ -524,9 +543,14 @@ void Settings::setShouldPaintNativeControls(bool shouldPaintNativeControls)
}
#endif
-void Settings::setNeedsIChatMemoryCacheCallsQuirk(bool needsIChatMemoryCacheCallsQuirk)
+void Settings::setUsesEncodingDetector(bool usesEncodingDetector)
+{
+ m_usesEncodingDetector = usesEncodingDetector;
+}
+
+void Settings::setAllowScriptsToCloseWindows(bool allowScriptsToCloseWindows)
{
- m_needsIChatMemoryCacheCallsQuirk = needsIChatMemoryCacheCallsQuirk;
+ m_allowScriptsToCloseWindows = allowScriptsToCloseWindows;
}
} // namespace WebCore
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index b9b888f..925324f 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -112,6 +112,12 @@ namespace WebCore {
void setJavaScriptEnabled(bool);
bool isJavaScriptEnabled() const { return m_isJavaScriptEnabled; }
+ void setWebSecurityEnabled(bool);
+ bool isWebSecurityEnabled() const { return m_isWebSecurityEnabled; }
+
+ void setAllowUniversalAccessFromFileURLs(bool);
+ bool allowUniversalAccessFromFileURLs() const { return m_allowUniversalAccessFromFileURLs; }
+
void setJavaScriptCanOpenWindowsAutomatically(bool);
bool JavaScriptCanOpenWindowsAutomatically() const { return m_javaScriptCanOpenWindowsAutomatically; }
@@ -137,6 +143,9 @@ namespace WebCore {
void setDefaultTextEncodingName(const String&);
const String& defaultTextEncodingName() const { return m_defaultTextEncodingName; }
+
+ void setUsesEncodingDetector(bool);
+ bool usesEncodingDetector() const { return m_usesEncodingDetector; }
void setUserStyleSheetLocation(const KURL&);
const KURL& userStyleSheetLocation() const { return m_userStyleSheetLocation; }
@@ -164,6 +173,12 @@ namespace WebCore {
void setNeedsKeyboardEventDisambiguationQuirks(bool);
bool needsKeyboardEventDisambiguationQuirks() const { return m_needsKeyboardEventDisambiguationQuirks; }
+ void setNeedsLeopardMailQuirks(bool);
+ bool needsLeopardMailQuirks() const { return m_needsLeopardMailQuirks; }
+
+ void setNeedsTigerMailQuirks(bool);
+ bool needsTigerMailQuirks() const { return m_needsTigerMailQuirks; }
+
void setDOMPasteAllowed(bool);
bool isDOMPasteAllowed() const { return m_isDOMPasteAllowed; }
@@ -218,9 +233,6 @@ namespace WebCore {
void setLocalStorageDatabasePath(const String&);
const String& localStorageDatabasePath() const { return m_localStorageDatabasePath; }
- void disableRangeMutationForOldAppleMail(bool);
- bool rangeMutationDisabledForOldAppleMail() const { return m_rangeMutationDisabledForOldAppleMail; }
-
void setApplicationChromeMode(bool);
bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
@@ -245,8 +257,8 @@ namespace WebCore {
static bool shouldPaintNativeControls() { return gShouldPaintNativeControls; }
#endif
- void setNeedsIChatMemoryCacheCallsQuirk(bool);
- bool needsIChatMemoryCacheCallsQuirk() const { return m_needsIChatMemoryCacheCallsQuirk; }
+ void setAllowScriptsToCloseWindows(bool);
+ bool allowScriptsToCloseWindows() const { return m_allowScriptsToCloseWindows; }
private:
Page* m_page;
@@ -311,6 +323,8 @@ namespace WebCore {
bool m_databasesEnabled : 1;
bool m_localStorageEnabled : 1;
bool m_isJavaScriptEnabled : 1;
+ bool m_isWebSecurityEnabled : 1;
+ bool m_allowUniversalAccessFromFileURLs: 1;
bool m_javaScriptCanOpenWindowsAutomatically : 1;
bool m_shouldPrintBackgrounds : 1;
bool m_textAreasAreResizable : 1;
@@ -319,6 +333,8 @@ namespace WebCore {
#endif
bool m_needsAdobeFrameReloadingQuirk : 1;
bool m_needsKeyboardEventDisambiguationQuirks : 1;
+ bool m_needsLeopardMailQuirks : 1;
+ bool m_needsTigerMailQuirks : 1;
bool m_isDOMPasteAllowed : 1;
bool m_shrinksStandaloneImagesToFit : 1;
bool m_usesPageCache: 1;
@@ -331,12 +347,12 @@ namespace WebCore {
bool m_webArchiveDebugModeEnabled : 1;
bool m_inApplicationChromeMode : 1;
bool m_offlineWebApplicationCacheEnabled : 1;
- bool m_rangeMutationDisabledForOldAppleMail : 1;
bool m_shouldPaintCustomScrollbars : 1;
bool m_zoomsTextOnly : 1;
bool m_enforceCSSMIMETypeInStrictMode : 1;
+ bool m_usesEncodingDetector : 1;
size_t m_maximumDecodedImageSize;
- bool m_needsIChatMemoryCacheCallsQuirk : 1;
+ bool m_allowScriptsToCloseWindows : 1;
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
diff --git a/WebCore/page/WebKitPoint.h b/WebCore/page/WebKitPoint.h
new file mode 100644
index 0000000..501b17f
--- /dev/null
+++ b/WebCore/page/WebKitPoint.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebKitPoint_h
+#define WebKitPoint_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+ class WebKitPoint : public RefCounted<WebKitPoint> {
+ public:
+
+ static PassRefPtr<WebKitPoint> create()
+ {
+ return adoptRef(new WebKitPoint());
+ }
+ static PassRefPtr<WebKitPoint> create(float x, float y)
+ {
+ return adoptRef(new WebKitPoint(x, y));
+ }
+
+ float x() const { return m_x; }
+ float y() const { return m_y; }
+
+ void setX(float x) { m_x = x; }
+ void setY(float y) { m_y = y; }
+
+ private:
+ WebKitPoint(float x=0, float y=0)
+ : m_x(x)
+ , m_y(y)
+ {
+ }
+
+ float m_x, m_y;
+ };
+
+} // namespace WebCore
+
+#endif // WebKitPoint_h
diff --git a/WebCore/page/WebKitPoint.idl b/WebCore/page/WebKitPoint.idl
new file mode 100644
index 0000000..1eefbc3
--- /dev/null
+++ b/WebCore/page/WebKitPoint.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module window {
+
+ interface WebKitPoint {
+ attribute float x;
+ attribute float y;
+ };
+
+}
diff --git a/WebCore/page/android/InspectorControllerAndroid.cpp b/WebCore/page/android/InspectorControllerAndroid.cpp
index d6222d7..8763df1 100644
--- a/WebCore/page/android/InspectorControllerAndroid.cpp
+++ b/WebCore/page/android/InspectorControllerAndroid.cpp
@@ -106,4 +106,6 @@ void InspectorController::failedToParseSource(JSC::ExecState* exec, const JSC::S
void InspectorController::didParseSource(JSC::ExecState* exec, const JSC::SourceCode& source) {}
void InspectorController::didPause() {}
+void InspectorController::scriptImported(unsigned long identifier, const JSC::UString& sourceString) {}
+void InspectorController::startUserInitiatedProfiling(Timer<InspectorController>*) {}
} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index 3e43f66..e500fe4 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "AnimationBase.h"
-#include "AnimationController.h"
+#include "AnimationControllerPrivate.h"
#include "CSSMutableStyleDeclaration.h"
#include "CSSPropertyLonghand.h"
#include "CSSPropertyNames.h"
@@ -43,10 +43,15 @@
#include "ImplicitAnimation.h"
#include "KeyframeAnimation.h"
#include "MatrixTransformOperation.h"
-#include "RenderObject.h"
+#include "Matrix3DTransformOperation.h"
+#include "RenderBox.h"
#include "RenderStyle.h"
#include "UnitBezier.h"
+#include <algorithm>
+
+using namespace std;
+
namespace WebCore {
// The epsilon value we pass to UnitBezier::solve given that the animation is going to run over |dur| seconds. The longer the
@@ -143,7 +148,7 @@ static inline TransformOperations blendFunc(const AnimationBase* anim, const Tra
toT.blend(fromT, progress);
// Append the result
- result.operations().append(MatrixTransformOperation::create(toT.a(), toT.b(), toT.c(), toT.d(), toT.e(), toT.f()));
+ result.operations().append(Matrix3DTransformOperation::create(toT));
}
return result;
}
@@ -180,6 +185,10 @@ public:
int property() const { return m_prop; }
+#if USE(ACCELERATED_COMPOSITING)
+ virtual bool animationIsAccelerated() const { return false; }
+#endif
+
private:
int m_prop;
};
@@ -197,7 +206,7 @@ public:
{
// If the style pointers are the same, don't bother doing the test.
// If either is null, return false. If both are null, return true.
- if (!a && !b || a == b)
+ if ((!a && !b) || a == b)
return true;
if (!a || !b)
return false;
@@ -226,6 +235,41 @@ protected:
void (RenderStyle::*m_setter)(T);
};
+#if USE(ACCELERATED_COMPOSITING)
+class PropertyWrapperAcceleratedOpacity : public PropertyWrapper<float> {
+public:
+ PropertyWrapperAcceleratedOpacity()
+ : PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)
+ {
+ }
+
+ virtual bool animationIsAccelerated() const { return true; }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ float fromOpacity = a->opacity();
+
+ // This makes sure we put the object being animated into a RenderLayer during the animation
+ dst->setOpacity(blendFunc(anim, (fromOpacity == 1) ? 0.999999f : fromOpacity, b->opacity(), progress));
+ }
+};
+
+class PropertyWrapperAcceleratedTransform : public PropertyWrapper<const TransformOperations&> {
+public:
+ PropertyWrapperAcceleratedTransform()
+ : PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)
+ {
+ }
+
+ virtual bool animationIsAccelerated() const { return true; }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ dst->setTransform(blendFunc(anim, a->transform(), b->transform(), progress));
+ }
+};
+#endif // USE(ACCELERATED_COMPOSITING)
+
class PropertyWrapperShadow : public PropertyWrapperGetter<ShadowData*> {
public:
PropertyWrapperShadow(int prop, ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(ShadowData*, bool))
@@ -239,7 +283,7 @@ public:
ShadowData* shadowA = (a->*m_getter)();
ShadowData* shadowB = (b->*m_getter)();
- if (!shadowA && shadowB || shadowA && !shadowB)
+ if ((!shadowA && shadowB) || (shadowA && !shadowB))
return false;
if (shadowA && shadowB && (*shadowA != *shadowB))
return false;
@@ -368,7 +412,6 @@ static void ensurePropertyMap()
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight));
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop));
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity));
gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor));
gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor));
gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyFontSize, &RenderStyle::fontSize, &RenderStyle::setBlendedFontSize));
@@ -384,15 +427,27 @@ static void ensurePropertyMap()
gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth));
gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing));
gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing));
- gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX));
+ gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY));
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX));
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY));
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ));
gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius));
gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius));
gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius));
gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius));
gPropertyWrappers->append(new PropertyWrapper<EVisibility>(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility));
gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoom));
+
+#if USE(ACCELERATED_COMPOSITING)
+ gPropertyWrappers->append(new PropertyWrapperAcceleratedOpacity());
+ gPropertyWrappers->append(new PropertyWrapperAcceleratedTransform());
+#else
+ gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity));
+ gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform));
+#endif
+
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitColumnRuleColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor));
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextStrokeColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor));
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextFillColor, &RenderStyle::textFillColor, &RenderStyle::setTextFillColor));
@@ -507,13 +562,13 @@ static PropertyWrapperBase* wrapperForProperty(int propertyID)
AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim)
: m_animState(AnimationStateNew)
, m_isAnimating(false)
- , m_waitedForResponse(false)
, m_startTime(0)
, m_pauseTime(-1)
, m_requestedStartTime(0)
, m_object(renderer)
, m_animation(const_cast<Animation*>(transition))
, m_compAnim(compAnim)
+ , m_fallbackAnimating(false)
, m_transformFunctionListValid(false)
, m_nextIterationDuration(-1)
, m_next(0)
@@ -526,8 +581,8 @@ AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer
AnimationBase::~AnimationBase()
{
- if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->removeFromStyleAvailableWaitList(this);
+ m_compAnim->removeFromStyleAvailableWaitList(this);
+ m_compAnim->removeFromStartTimeResponseWaitList(this);
}
bool AnimationBase::propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b)
@@ -575,12 +630,25 @@ bool AnimationBase::blendProperties(const AnimationBase* anim, int prop, RenderS
PropertyWrapperBase* wrapper = wrapperForProperty(prop);
if (wrapper) {
wrapper->blend(anim, dst, a, b, progress);
+#if USE(ACCELERATED_COMPOSITING)
+ return !wrapper->animationIsAccelerated() || anim->isFallbackAnimating();
+#else
return true;
+#endif
}
return false;
}
+#if USE(ACCELERATED_COMPOSITING)
+bool AnimationBase::animationOfPropertyIsAccelerated(int prop)
+{
+ ensurePropertyMap();
+ PropertyWrapperBase* wrapper = wrapperForProperty(prop);
+ return wrapper ? wrapper->animationIsAccelerated() : false;
+}
+#endif
+
void AnimationBase::setChanged(Node* node)
{
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
@@ -614,7 +682,6 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_pauseTime = -1;
m_requestedStartTime = 0;
m_nextIterationDuration = -1;
- m_waitedForResponse = false;
endAnimation(false);
return;
}
@@ -661,11 +728,10 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
}
// Execute state machine
- switch(m_animState) {
+ switch (m_animState) {
case AnimationStateNew:
ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
- m_waitedForResponse = false;
m_requestedStartTime = beginAnimationUpdateTime();
m_animState = AnimationStateStartWaitTimer;
}
@@ -681,7 +747,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// Trigger a render so we can start the animation
if (m_object)
- m_object->animation()->addNodeChangeToDispatch(m_object->element());
+ m_compAnim->animationControllerPriv()->addNodeChangeToDispatch(m_object->node());
} else {
ASSERT(!paused());
// We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
@@ -701,12 +767,18 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
onAnimationStart(0); // The elapsedTime is always 0 here
// Start the animation
- if (overridden() || !startAnimation(0)) {
- // We're not going to get a startTime callback, so fire the start time here
+ if (overridden()) {
+ // We won't try to start accelerated animations if we are overridden and
+ // just move on to the next state.
m_animState = AnimationStateStartWaitResponse;
+ m_fallbackAnimating = true;
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
- } else
- m_waitedForResponse = true;
+ }
+ else {
+ bool started = startAnimation(0);
+ m_compAnim->addToStartTimeResponseWaitList(this, started);
+ m_fallbackAnimating = !started;
+ }
break;
case AnimationStateStartWaitResponse:
ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused);
@@ -722,7 +794,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// Dispatch updateRendering so we can start the animation
if (m_object)
- m_object->animation()->addNodeChangeToDispatch(m_object->element());
+ m_compAnim->animationControllerPriv()->addNodeChangeToDispatch(m_object->node());
} else {
// We are pausing while waiting for a start response. Cancel the animation and wait. When
// we unpause, we will act as though the start timer just fired
@@ -762,7 +834,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
resumeOverriddenAnimations();
// Fire off another style change so we can set the final value
- m_object->animation()->addNodeChangeToDispatch(m_object->element());
+ m_compAnim->animationControllerPriv()->addNodeChangeToDispatch(m_object->node());
}
} else {
// We are pausing while running. Cancel the animation and wait
@@ -789,8 +861,19 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
// When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
// that we have already set the startTime and will ignore it.
- ASSERT(input == AnimationStateInputPlayStateRunnning);
+ ASSERT(input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputStartTimeSet);
ASSERT(paused());
+
+ // If we are paused, but we get the callback that notifies us that an accelerated animation started,
+ // then we ignore the start time and just move into the paused-run state.
+ if (m_animState == AnimationStatePausedWaitResponse && input == AnimationStateInputStartTimeSet) {
+ m_animState = AnimationStatePausedRun;
+ ASSERT(m_startTime == 0);
+ m_startTime = param;
+ m_pauseTime += m_startTime;
+ break;
+ }
+
// Update the times
if (m_animState == AnimationStatePausedRun)
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
@@ -802,11 +885,16 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_animState = AnimationStateStartWaitResponse;
// Start the animation
- if (overridden() || !startAnimation(m_startTime)) {
- // We're not going to get a startTime callback, so fire the start time here
+ if (overridden()) {
+ // We won't try to start accelerated animations if we are overridden and
+ // just move on to the next state.
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
- } else
- m_waitedForResponse = true;
+ m_fallbackAnimating = true;
+ } else {
+ bool started = startAnimation(0);
+ m_compAnim->addToStartTimeResponseWaitList(this, started);
+ m_fallbackAnimating = !started;
+ }
break;
case AnimationStateDone:
// We're done. Stay in this state until we are deleted
@@ -835,14 +923,16 @@ void AnimationBase::fireAnimationEventsIfNeeded()
}
double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
- ASSERT(elapsedDuration >= 0);
+ // FIXME: we need to ensure that elapsedDuration is never < 0. If it is, this suggests that
+ // we had a recalcStyle() outside of beginAnimationUpdate()/endAnimationUpdate().
+ // Also check in getTimeToNextEvent().
+ elapsedDuration = max(elapsedDuration, 0.0);
// Check for end timeout
if (m_totalDuration >= 0 && elapsedDuration >= m_totalDuration) {
// Fire an end event
updateStateMachine(AnimationStateInputEndTimerFired, m_totalDuration);
- }
- else {
+ } else {
// Check for iteration timeout
if (m_nextIterationDuration < 0) {
// Hasn't been set yet, set it
@@ -868,18 +958,20 @@ void AnimationBase::updatePlayState(bool run)
updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1);
}
-double AnimationBase::willNeedService() const
+double AnimationBase::willNeedService()
{
// Returns the time at which next service is required. -1 means no service is required. 0 means
// service is required now, and > 0 means service is required that many seconds in the future.
if (paused() || isNew())
return -1;
-
+
if (m_animState == AnimationStateStartWaitTimer) {
double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime);
- return (float) ((timeFromNow > 0) ? timeFromNow : 0);
+ return max(timeFromNow, 0.0);
}
+ fireAnimationEventsIfNeeded();
+
// In all other cases, we need service right away.
return 0;
}
@@ -926,31 +1018,40 @@ double AnimationBase::progress(double scale, double offset, const TimingFunction
return result;
}
-void AnimationBase::goIntoEndingOrLoopingState()
+void AnimationBase::getTimeToNextEvent(double& time, bool& isLooping) const
{
// Decide when the end or loop event needs to fire
double totalDuration = -1;
if (m_animation->iterationCount() > 0)
totalDuration = m_animation->duration() * m_animation->iterationCount();
- const double elapsedDuration = beginAnimationUpdateTime() - m_startTime;
- ASSERT(elapsedDuration >= 0);
+ const double elapsedDuration = max(beginAnimationUpdateTime() - m_startTime, 0.0);
double durationLeft = 0;
- double nextIterationTime = totalDuration;
+ double nextIterationTime = m_totalDuration;
- if (totalDuration < 0 || elapsedDuration < totalDuration) {
+ if (m_totalDuration < 0 || elapsedDuration < m_totalDuration) {
durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
nextIterationTime = elapsedDuration + durationLeft;
}
-
- if (totalDuration < 0 || nextIterationTime < totalDuration) {
+
+ if (m_totalDuration < 0 || nextIterationTime < m_totalDuration) {
// We are not at the end yet
ASSERT(nextIterationTime > 0);
- m_animState = AnimationStateLooping;
+ isLooping = true;
} else {
// We are at the end
- m_animState = AnimationStateEnding;
+ isLooping = false;
}
+
+ time = durationLeft;
+}
+
+void AnimationBase::goIntoEndingOrLoopingState()
+{
+ double t;
+ bool isLooping;
+ getTimeToNextEvent(t, isLooping);
+ m_animState = isLooping ? AnimationStateLooping : AnimationStateEnding;
}
void AnimationBase::pauseAtTime(double t)
@@ -961,7 +1062,7 @@ void AnimationBase::pauseAtTime(double t)
double AnimationBase::beginAnimationUpdateTime() const
{
- return m_compAnim->animationController()->beginAnimationUpdateTime();
+ return m_compAnim->animationControllerPriv()->beginAnimationUpdateTime();
}
double AnimationBase::getElapsedTime() const
diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h
index ce16f93..da4341b 100644
--- a/WebCore/page/animation/AnimationBase.h
+++ b/WebCore/page/animation/AnimationBase.h
@@ -94,7 +94,10 @@ public:
void updateStateMachine(AnimStateInput, double param);
// Animation has actually started, at passed time
- void onAnimationStartResponse(double startTime);
+ void onAnimationStartResponse(double startTime)
+ {
+ updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime);
+ }
// Called to change to or from paused state
void updatePlayState(bool running);
@@ -117,12 +120,12 @@ public:
// "animating" means that something is running that requires a timer to keep firing
// (e.g. a software animation)
void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; }
- double willNeedService() const;
+ virtual double willNeedService();
double progress(double scale, double offset, const TimingFunction*) const;
- virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/,
- const RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) { }
+ virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
+ virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
virtual bool shouldFireEvents() const { return false; }
@@ -142,6 +145,9 @@ public:
virtual bool affectsProperty(int /*property*/) const { return false; }
bool isAnimatingProperty(int property, bool isRunningNow) const
{
+ if (m_fallbackAnimating)
+ return false;
+
if (isRunningNow)
return (!waitingToStart() && !postActive()) && affectsProperty(property);
@@ -164,7 +170,11 @@ public:
ASSERT(waitingForStyleAvailable());
updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
}
-
+
+#if USE(ACCELERATED_COMPOSITING)
+ static bool animationOfPropertyIsAccelerated(int prop);
+#endif
+
protected:
virtual void overrideAnimations() { }
virtual void resumeOverriddenAnimations() { }
@@ -176,23 +186,26 @@ protected:
virtual void onAnimationIteration(double /*elapsedTime*/) { }
virtual void onAnimationEnd(double /*elapsedTime*/) { }
virtual bool startAnimation(double /*beginTime*/) { return false; }
- virtual void endAnimation(bool /*reset*/) { }
+ virtual void endAnimation(bool /*reset*/, double /*forcePauseTime*/ = -1) { }
void goIntoEndingOrLoopingState();
+ bool isFallbackAnimating() const { return m_fallbackAnimating; }
+
static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b);
static int getPropertyAtIndex(int, bool& isShorthand);
static int getNumProperties();
// Return true if we need to start software animation timers
static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress);
-
+
static void setChanged(Node*);
+
+ void getTimeToNextEvent(double& time, bool& isLooping) const;
AnimState m_animState;
bool m_isAnimating; // transition/animation requires continual timer firing
- bool m_waitedForResponse;
double m_startTime;
double m_pauseTime;
double m_requestedStartTime;
@@ -200,6 +213,7 @@ protected:
RefPtr<Animation> m_animation;
CompositeAnimation* m_compAnim;
+ bool m_fallbackAnimating; // true when animating an accelerated property but have to fall back to software
bool m_transformFunctionListValid;
double m_totalDuration, m_nextIterationDuration;
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index f85e6c1..f9c9a47 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -28,84 +28,22 @@
#include "config.h"
#include "AnimationController.h"
+
#include "AnimationBase.h"
-#include "CompositeAnimation.h"
+#include "AnimationControllerPrivate.h"
#include "CSSParser.h"
+#include "CompositeAnimation.h"
#include "EventNames.h"
#include "Frame.h"
-#include "Timer.h"
+#include "RenderObject.h"
#include <wtf/CurrentTime.h>
+#include <wtf/UnusedParam.h>
namespace WebCore {
static const double cAnimationTimerDelay = 0.025;
static const double cBeginAnimationUpdateTimeNotSet = -1;
-class AnimationControllerPrivate {
-public:
- AnimationControllerPrivate(Frame*);
- ~AnimationControllerPrivate();
-
- PassRefPtr<CompositeAnimation> accessCompositeAnimation(RenderObject*);
- bool clear(RenderObject*);
-
- void animationTimerFired(Timer<AnimationControllerPrivate>*);
- void updateAnimationTimer(bool callSetChanged = false);
-
- void updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*);
- void startUpdateRenderingDispatcher();
- void addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime);
- void addNodeChangeToDispatch(PassRefPtr<Node>);
-
- bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
-
- void suspendAnimations(Document*);
- void resumeAnimations(Document*);
-
- void styleAvailable();
-
- bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const;
-
- bool pauseAnimationAtTime(RenderObject*, const String& name, double t);
- bool pauseTransitionAtTime(RenderObject*, const String& property, double t);
- unsigned numberOfActiveAnimations() const;
-
- double beginAnimationUpdateTime()
- {
- if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
- m_beginAnimationUpdateTime = currentTime();
- return m_beginAnimationUpdateTime;
- }
-
- void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
-
- void addToStyleAvailableWaitList(AnimationBase*);
- void removeFromStyleAvailableWaitList(AnimationBase*);
-
-private:
- typedef HashMap<RenderObject*, RefPtr<CompositeAnimation> > RenderObjectAnimationMap;
-
- RenderObjectAnimationMap m_compositeAnimations;
- Timer<AnimationControllerPrivate> m_animationTimer;
- Timer<AnimationControllerPrivate> m_updateRenderingDispatcher;
- Frame* m_frame;
-
- class EventToDispatch {
- public:
- RefPtr<Element> element;
- AtomicString eventType;
- String name;
- double elapsedTime;
- };
-
- Vector<EventToDispatch> m_eventsToDispatch;
- Vector<RefPtr<Node> > m_nodeChangesToDispatch;
-
- double m_beginAnimationUpdateTime;
- AnimationBase* m_styleAvailableWaiters;
- AnimationBase* m_lastStyleAvailableWaiter;
-};
-
AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
: m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)
, m_updateRenderingDispatcher(this, &AnimationControllerPrivate::updateRenderingDispatcherFired)
@@ -113,6 +51,9 @@ AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
, m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)
, m_styleAvailableWaiters(0)
, m_lastStyleAvailableWaiter(0)
+ , m_responseWaiters(0)
+ , m_lastResponseWaiter(0)
+ , m_waitingForAResponse(false)
{
}
@@ -124,7 +65,7 @@ PassRefPtr<CompositeAnimation> AnimationControllerPrivate::accessCompositeAnimat
{
RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
if (!animation) {
- animation = CompositeAnimation::create(m_frame->animation());
+ animation = CompositeAnimation::create(this);
m_compositeAnimations.set(renderer, animation);
}
return animation;
@@ -155,7 +96,7 @@ void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = fa
needsService = t;
if (needsService == 0) {
if (callSetChanged) {
- Node* node = it->first->element();
+ Node* node = it->first->node();
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
node->setChanged(AnimationStyleChange);
calledSetChanged = true;
@@ -209,7 +150,7 @@ void AnimationControllerPrivate::updateRenderingDispatcherFired(Timer<AnimationC
m_nodeChangesToDispatch.clear();
- if (m_frame && m_frame->document())
+ if (m_frame)
m_frame->document()->updateRendering();
}
@@ -233,6 +174,10 @@ void AnimationControllerPrivate::addEventToDispatch(PassRefPtr<Element> element,
void AnimationControllerPrivate::addNodeChangeToDispatch(PassRefPtr<Node> node)
{
+ ASSERT(!node || (node->document() && !node->document()->inPageCache()));
+ if (!node)
+ return;
+
m_nodeChangesToDispatch.append(node);
startUpdateRenderingDispatcher();
}
@@ -240,7 +185,7 @@ void AnimationControllerPrivate::addNodeChangeToDispatch(PassRefPtr<Node> node)
void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>*)
{
// Make sure animationUpdateTime is updated, so that it is current even if no
- // styleChange has happened (e.g. hardware animations)
+ // styleChange has happened (e.g. accelerated animations)
setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
// When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
@@ -248,7 +193,7 @@ void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPr
updateAnimationTimer(true);
}
-bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const
+bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const
{
RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
if (!animation)
@@ -294,6 +239,7 @@ bool AnimationControllerPrivate::pauseAnimationAtTime(RenderObject* renderer, co
if (compAnim->pauseAnimationAtTime(name, t)) {
renderer->node()->setChanged(AnimationStyleChange);
+ startUpdateRenderingDispatcher();
return true;
}
@@ -311,12 +257,39 @@ bool AnimationControllerPrivate::pauseTransitionAtTime(RenderObject* renderer, c
if (compAnim->pauseTransitionAtTime(cssPropertyID(property), t)) {
renderer->node()->setChanged(AnimationStyleChange);
+ startUpdateRenderingDispatcher();
return true;
}
return false;
}
+double AnimationControllerPrivate::beginAnimationUpdateTime()
+{
+ if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
+ m_beginAnimationUpdateTime = currentTime();
+ return m_beginAnimationUpdateTime;
+}
+
+PassRefPtr<RenderStyle> AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderObject* renderer)
+{
+ if (!renderer)
+ return 0;
+
+ RefPtr<CompositeAnimation> rendererAnimations = m_compositeAnimations.get(renderer);
+ if (!rendererAnimations)
+ return renderer->style();
+
+ // Make sure animationUpdateTime is updated, so that it is current even if no
+ // styleChange has happened (e.g. accelerated animations).
+ setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
+ RefPtr<RenderStyle> animatingStyle = rendererAnimations->getAnimatedStyle();
+ if (!animatingStyle)
+ animatingStyle = renderer->style();
+
+ return animatingStyle.release();
+}
+
unsigned AnimationControllerPrivate::numberOfActiveAnimations() const
{
unsigned count = 0;
@@ -364,13 +337,83 @@ void AnimationControllerPrivate::removeFromStyleAvailableWaitList(AnimationBase*
void AnimationControllerPrivate::styleAvailable()
{
// Go through list of waiters and send them on their way
- for (AnimationBase* animation = m_styleAvailableWaiters; animation; animation = animation->next())
+ for (AnimationBase* animation = m_styleAvailableWaiters; animation; ) {
+ AnimationBase* nextAnimation = animation->next();
+ animation->setNext(0);
animation->styleAvailable();
+ animation = nextAnimation;
+ }
m_styleAvailableWaiters = 0;
m_lastStyleAvailableWaiter = 0;
}
+void AnimationControllerPrivate::addToStartTimeResponseWaitList(AnimationBase* animation, bool willGetResponse)
+{
+ // If willGetResponse is true, it means this animation is actually waiting for a response
+ // (which will come in as a call to notifyAnimationStarted()).
+ // In that case we don't need to add it to this list. We just set a waitingForAResponse flag
+ // which says we are waiting for the response. If willGetResponse is false, this animation
+ // is not waiting for a response for itself, but rather for a notifyXXXStarted() call for
+ // another animation to which it will sync.
+ //
+ // When endAnimationUpdate() is called we check to see if the waitingForAResponse flag is
+ // true. If so, we just return and will do our work when the first notifyXXXStarted() call
+ // comes in. If it is false, we will not be getting a notifyXXXStarted() call, so we will
+ // do our work right away. In both cases we call the onAnimationStartResponse() method
+ // on each animation. In the first case we send in the time we got from notifyXXXStarted().
+ // In the second case, we just pass in the beginAnimationUpdateTime().
+ //
+ // This will synchronize all software and accelerated animations started in the same
+ // updateRendering cycle.
+ //
+ ASSERT(!animation->next());
+
+ if (willGetResponse)
+ m_waitingForAResponse = true;
+
+ if (m_responseWaiters)
+ m_lastResponseWaiter->setNext(animation);
+ else
+ m_responseWaiters = animation;
+
+ m_lastResponseWaiter = animation;
+ animation->setNext(0);
+}
+
+void AnimationControllerPrivate::removeFromStartTimeResponseWaitList(AnimationBase* animationToRemove)
+{
+ AnimationBase* prevAnimation = 0;
+ for (AnimationBase* animation = m_responseWaiters; animation; animation = animation->next()) {
+ if (animation == animationToRemove) {
+ if (prevAnimation)
+ prevAnimation->setNext(animation->next());
+ else
+ m_responseWaiters = animation->next();
+
+ if (m_lastResponseWaiter == animation)
+ m_lastResponseWaiter = prevAnimation;
+
+ animationToRemove->setNext(0);
+ }
+ prevAnimation = animation;
+ }
+}
+
+void AnimationControllerPrivate::startTimeResponse(double t)
+{
+ // Go through list of waiters and send them on their way
+ for (AnimationBase* animation = m_responseWaiters; animation; ) {
+ AnimationBase* nextAnimation = animation->next();
+ animation->setNext(0);
+ animation->onAnimationStartResponse(t);
+ animation = nextAnimation;
+ }
+
+ m_responseWaiters = 0;
+ m_lastResponseWaiter = 0;
+}
+
AnimationController::AnimationController(Frame* frame)
: m_data(new AnimationControllerPrivate(frame))
{
@@ -387,7 +430,7 @@ void AnimationController::cancelAnimations(RenderObject* renderer)
return;
if (m_data->clear(renderer)) {
- Node* node = renderer->element();
+ Node* node = renderer->node();
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
node->setChanged(AnimationStyleChange);
}
@@ -408,7 +451,7 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend
// against the animations in the style and make sure we're in sync. If destination values
// have changed, we reset the animation. We then do a blend to get new values and we return
// a new style.
- ASSERT(renderer->element()); // FIXME: We do not animate generated content yet.
+ ASSERT(renderer->node()); // FIXME: We do not animate generated content yet.
RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
RefPtr<RenderStyle> blendedStyle = rendererAnimations->animate(renderer, oldStyle, newStyle);
@@ -425,16 +468,14 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend
return blendedStyle.release();
}
-void AnimationController::setAnimationStartTime(RenderObject* renderer, double t)
+PassRefPtr<RenderStyle> AnimationController::getAnimatedStyleForRenderer(RenderObject* renderer)
{
- RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
- rendererAnimations->setAnimationStartTime(t);
+ return m_data->getAnimatedStyleForRenderer(renderer);
}
-void AnimationController::setTransitionStartTime(RenderObject* renderer, int property, double t)
+void AnimationController::notifyAnimationStarted(RenderObject*, double startTime)
{
- RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
- rendererAnimations->setTransitionStartTime(property, t);
+ m_data->receivedStartTimeResponse(startTime);
}
bool AnimationController::pauseAnimationAtTime(RenderObject* renderer, const String& name, double t)
@@ -452,7 +493,7 @@ bool AnimationController::pauseTransitionAtTime(RenderObject* renderer, const St
return m_data->pauseTransitionAtTime(renderer, property, t);
}
-bool AnimationController::isAnimatingPropertyOnRenderer(RenderObject* renderer, int property, bool isRunningNow) const
+bool AnimationController::isAnimatingPropertyOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const
{
return m_data->isAnimatingPropertyOnRenderer(renderer, property, isRunningNow);
}
@@ -467,28 +508,6 @@ void AnimationController::resumeAnimations(Document* document)
m_data->resumeAnimations(document);
}
-void AnimationController::startUpdateRenderingDispatcher()
-{
- m_data->startUpdateRenderingDispatcher();
-}
-
-void AnimationController::addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime)
-{
- m_data->addEventToDispatch(element, eventType, name, elapsedTime);
-}
-
-void AnimationController::addNodeChangeToDispatch(PassRefPtr<Node> node)
-{
- ASSERT(!node || (node->document() && !node->document()->inPageCache()));
- if (node)
- m_data->addNodeChangeToDispatch(node);
-}
-
-double AnimationController::beginAnimationUpdateTime()
-{
- return m_data->beginAnimationUpdateTime();
-}
-
void AnimationController::beginAnimationUpdate()
{
m_data->setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
@@ -496,17 +515,17 @@ void AnimationController::beginAnimationUpdate()
void AnimationController::endAnimationUpdate()
{
- m_data->styleAvailable();
+ m_data->endAnimationUpdate();
}
-void AnimationController::addToStyleAvailableWaitList(AnimationBase* animation)
+bool AnimationController::supportsAcceleratedAnimationOfProperty(CSSPropertyID property)
{
- m_data->addToStyleAvailableWaitList(animation);
-}
-
-void AnimationController::removeFromStyleAvailableWaitList(AnimationBase* animation)
-{
- m_data->removeFromStyleAvailableWaitList(animation);
+#if USE(ACCELERATED_COMPOSITING)
+ return AnimationBase::animationOfPropertyIsAccelerated(property);
+#else
+ UNUSED_PARAM(property);
+ return false;
+#endif
}
} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationController.h b/WebCore/page/animation/AnimationController.h
index 13ea1bd..db82618 100644
--- a/WebCore/page/animation/AnimationController.h
+++ b/WebCore/page/animation/AnimationController.h
@@ -29,6 +29,7 @@
#ifndef AnimationController_h
#define AnimationController_h
+#include "CSSPropertyNames.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -51,30 +52,24 @@ public:
void cancelAnimations(RenderObject*);
PassRefPtr<RenderStyle> updateAnimations(RenderObject*, RenderStyle* newStyle);
+ PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderObject*);
- void setAnimationStartTime(RenderObject*, double t);
- void setTransitionStartTime(RenderObject*, int property, double t);
+ // This is called when an accelerated animation or transition has actually started to animate.
+ void notifyAnimationStarted(RenderObject*, double startTime);
bool pauseAnimationAtTime(RenderObject*, const String& name, double t); // To be used only for testing
bool pauseTransitionAtTime(RenderObject*, const String& property, double t); // To be used only for testing
unsigned numberOfActiveAnimations() const; // To be used only for testing
- bool isAnimatingPropertyOnRenderer(RenderObject*, int property, bool isRunningNow) const;
+ bool isAnimatingPropertyOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const;
void suspendAnimations(Document*);
void resumeAnimations(Document*);
- void startUpdateRenderingDispatcher();
- void addEventToDispatch(PassRefPtr<Element>, const AtomicString& eventType, const String& name, double elapsedTime);
- void addNodeChangeToDispatch(PassRefPtr<Node>);
-
- void addToStyleAvailableWaitList(AnimationBase*);
- void removeFromStyleAvailableWaitList(AnimationBase*);
-
- double beginAnimationUpdateTime();
-
void beginAnimationUpdate();
void endAnimationUpdate();
+
+ static bool supportsAcceleratedAnimationOfProperty(CSSPropertyID);
private:
AnimationControllerPrivate* m_data;
diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h
new file mode 100644
index 0000000..f9a3405
--- /dev/null
+++ b/WebCore/page/animation/AnimationControllerPrivate.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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 AnimationControllerPrivate_h
+#define AnimationControllerPrivate_h
+
+#include "AtomicString.h"
+#include "CSSPropertyNames.h"
+#include "PlatformString.h"
+#include "Timer.h"
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AnimationBase;
+class CompositeAnimation;
+class Document;
+class Element;
+class Frame;
+class Node;
+class RenderObject;
+class RenderStyle;
+
+class AnimationControllerPrivate {
+public:
+ AnimationControllerPrivate(Frame*);
+ ~AnimationControllerPrivate();
+
+ PassRefPtr<CompositeAnimation> accessCompositeAnimation(RenderObject*);
+ bool clear(RenderObject*);
+
+ void animationTimerFired(Timer<AnimationControllerPrivate>*);
+ void updateAnimationTimer(bool callSetChanged = false);
+
+ void updateRenderingDispatcherFired(Timer<AnimationControllerPrivate>*);
+ void startUpdateRenderingDispatcher();
+ void addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime);
+ void addNodeChangeToDispatch(PassRefPtr<Node>);
+
+ bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
+
+ void suspendAnimations(Document*);
+ void resumeAnimations(Document*);
+
+ bool isAnimatingPropertyOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const;
+
+ bool pauseAnimationAtTime(RenderObject*, const String& name, double t);
+ bool pauseTransitionAtTime(RenderObject*, const String& property, double t);
+ unsigned numberOfActiveAnimations() const;
+
+ PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderObject* renderer);
+
+ double beginAnimationUpdateTime();
+ void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
+ void endAnimationUpdate()
+ {
+ styleAvailable();
+ if (!m_waitingForAResponse)
+ startTimeResponse(beginAnimationUpdateTime());
+ }
+
+ void receivedStartTimeResponse(double t)
+ {
+ m_waitingForAResponse = false;
+ startTimeResponse(t);
+ }
+
+ void addToStyleAvailableWaitList(AnimationBase*);
+ void removeFromStyleAvailableWaitList(AnimationBase*);
+
+ void addToStartTimeResponseWaitList(AnimationBase*, bool willGetResponse);
+ void removeFromStartTimeResponseWaitList(AnimationBase*);
+ void startTimeResponse(double t);
+
+private:
+ void styleAvailable();
+
+ typedef HashMap<RenderObject*, RefPtr<CompositeAnimation> > RenderObjectAnimationMap;
+
+ RenderObjectAnimationMap m_compositeAnimations;
+ Timer<AnimationControllerPrivate> m_animationTimer;
+ Timer<AnimationControllerPrivate> m_updateRenderingDispatcher;
+ Frame* m_frame;
+
+ class EventToDispatch {
+ public:
+ RefPtr<Element> element;
+ AtomicString eventType;
+ String name;
+ double elapsedTime;
+ };
+
+ Vector<EventToDispatch> m_eventsToDispatch;
+ Vector<RefPtr<Node> > m_nodeChangesToDispatch;
+
+ double m_beginAnimationUpdateTime;
+ AnimationBase* m_styleAvailableWaiters;
+ AnimationBase* m_lastStyleAvailableWaiter;
+
+ AnimationBase* m_responseWaiters;
+ AnimationBase* m_lastResponseWaiter;
+ bool m_waitingForAResponse;
+};
+
+} // namespace WebCore
+
+#endif // AnimationControllerPrivate_h
diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp
index bf61b78..d386f1b 100644
--- a/WebCore/page/animation/CompositeAnimation.cpp
+++ b/WebCore/page/animation/CompositeAnimation.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "CompositeAnimation.h"
-#include "AnimationController.h"
+#include "AnimationControllerPrivate.h"
#include "CSSPropertyNames.h"
#include "ImplicitAnimation.h"
#include "KeyframeAnimation.h"
@@ -40,7 +40,7 @@ namespace WebCore {
class CompositeAnimationPrivate {
public:
- CompositeAnimationPrivate(AnimationController* animationController, CompositeAnimation* compositeAnimation)
+ CompositeAnimationPrivate(AnimationControllerPrivate* animationController, CompositeAnimation* compositeAnimation)
: m_isSuspended(false)
, m_animationController(animationController)
, m_compositeAnimation(compositeAnimation)
@@ -53,8 +53,9 @@ public:
void clearRenderer();
PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+ PassRefPtr<RenderStyle> getAnimatedStyle();
- AnimationController* animationController() { return m_animationController; }
+ AnimationControllerPrivate* animationControllerPriv() const { return m_animationController; }
void setAnimating(bool);
double willNeedService() const;
@@ -63,9 +64,6 @@ public:
void cleanupFinishedAnimations(RenderObject*);
- void setAnimationStartTime(double t);
- void setTransitionStartTime(int property, double t);
-
void suspendAnimations();
void resumeAnimations();
bool isSuspended() const { return m_isSuspended; }
@@ -80,6 +78,9 @@ public:
void addToStyleAvailableWaitList(AnimationBase*);
void removeFromStyleAvailableWaitList(AnimationBase*);
+ void addToStartTimeResponseWaitList(AnimationBase*, bool willGetResponse);
+ void removeFromStartTimeResponseWaitList(AnimationBase*);
+
bool pauseAnimationAtTime(const AtomicString& name, double t);
bool pauseTransitionAtTime(int property, double t);
unsigned numberOfActiveAnimations() const;
@@ -94,8 +95,9 @@ private:
CSSPropertyTransitionsMap m_transitions;
AnimationNameMap m_keyframeAnimations;
+ Vector<AtomicStringImpl*> m_keyframeAnimationOrderMap;
bool m_isSuspended;
- AnimationController* m_animationController;
+ AnimationControllerPrivate* m_animationController;
CompositeAnimation* m_compositeAnimation;
unsigned m_numStyleAvailableWaiters;
};
@@ -126,9 +128,11 @@ void CompositeAnimationPrivate::clearRenderer()
}
}
}
-
+
void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
{
+ RefPtr<RenderStyle> modifiedCurrentStyle;
+
// If currentStyle is null, we don't do transitions
if (!currentStyle || !targetStyle->transitions())
return;
@@ -176,6 +180,16 @@ void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, Render
// list. In this case, the latter one overrides the earlier one, so we
// behave as though this is a running animation being replaced.
if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) {
+#if USE(ACCELERATED_COMPOSITING)
+ // For accelerated animations we need to return a new RenderStyle with the _current_ value
+ // of the property, so that restarted transitions use the correct starting point.
+ if (AnimationBase::animationOfPropertyIsAccelerated(prop) && !implAnim->isFallbackAnimating()) {
+ if (!modifiedCurrentStyle)
+ modifiedCurrentStyle = RenderStyle::clone(currentStyle);
+
+ implAnim->blendPropertyValueInStyle(prop, modifiedCurrentStyle.get());
+ }
+#endif
m_transitions.remove(prop);
equal = false;
}
@@ -186,7 +200,7 @@ void CompositeAnimationPrivate::updateTransitions(RenderObject* renderer, Render
if (!equal) {
// Add the new transition
- m_transitions.set(prop, ImplicitAnimation::create(const_cast<Animation*>(anim), prop, renderer, m_compositeAnimation, fromStyle));
+ m_transitions.set(prop, ImplicitAnimation::create(const_cast<Animation*>(anim), prop, renderer, m_compositeAnimation, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle));
}
// We only need one pass for the single prop case
@@ -210,6 +224,9 @@ void CompositeAnimationPrivate::updateKeyframeAnimations(RenderObject* renderer,
AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
it->second->setIndex(-1);
+
+ // Toss the animation order map
+ m_keyframeAnimationOrderMap.clear();
// Now mark any still active animations as active and add any new animations
if (targetStyle->animations()) {
@@ -237,6 +254,10 @@ void CompositeAnimationPrivate::updateKeyframeAnimations(RenderObject* renderer,
keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, m_compositeAnimation, currentStyle ? currentStyle : targetStyle);
m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
}
+
+ // Add this to the animation order map
+ if (keyframeAnim)
+ m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
}
}
@@ -278,17 +299,10 @@ PassRefPtr<RenderStyle> CompositeAnimationPrivate::animate(RenderObject* rendere
// Now that we have animation objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
- if (targetStyle->hasAnimations()) {
- for (size_t i = 0; i < targetStyle->animations()->size(); ++i) {
- const Animation* anim = targetStyle->animations()->animation(i);
-
- if (anim->isValidAnimation()) {
- AtomicString animationName(anim->name());
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
- if (keyframeAnim)
- keyframeAnim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
- }
- }
+ for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(*it);
+ if (keyframeAnim)
+ keyframeAnim->animate(m_compositeAnimation, renderer, currentStyle, targetStyle, resultStyle);
}
cleanupFinishedAnimations(renderer);
@@ -296,6 +310,24 @@ PassRefPtr<RenderStyle> CompositeAnimationPrivate::animate(RenderObject* rendere
return resultStyle ? resultStyle.release() : targetStyle;
}
+PassRefPtr<RenderStyle> CompositeAnimationPrivate::getAnimatedStyle()
+{
+ RefPtr<RenderStyle> resultStyle;
+ CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
+ for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
+ if (ImplicitAnimation* implicitAnimation = it->second.get())
+ implicitAnimation->getAnimatedStyle(resultStyle);
+ }
+
+ for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
+ RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
+ if (keyframeAnimation)
+ keyframeAnimation->getAnimatedStyle(resultStyle);
+ }
+
+ return resultStyle;
+}
+
// "animating" means that something is running that requires the timer to keep firing
void CompositeAnimationPrivate::setAnimating(bool animating)
{
@@ -409,32 +441,6 @@ void CompositeAnimationPrivate::cleanupFinishedAnimations(RenderObject*)
}
}
-void CompositeAnimationPrivate::setAnimationStartTime(double t)
-{
- // Set start time on all animations waiting for it
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator end = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != end; ++it) {
- KeyframeAnimation* anim = it->second.get();
- if (anim && anim->waitingForStartTime())
- anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
- }
- }
-}
-
-void CompositeAnimationPrivate::setTransitionStartTime(int property, double t)
-{
- // Set the start time for given property transition
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->second.get();
- if (anim && anim->waitingForStartTime() && anim->animatingProperty() == property)
- anim->updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, t);
- }
- }
-}
-
void CompositeAnimationPrivate::suspendAnimations()
{
if (m_isSuspended)
@@ -541,6 +547,16 @@ void CompositeAnimationPrivate::removeFromStyleAvailableWaitList(AnimationBase*
m_animationController->removeFromStyleAvailableWaitList(animation);
}
+void CompositeAnimationPrivate::addToStartTimeResponseWaitList(AnimationBase* animation, bool willGetResponse)
+{
+ m_animationController->addToStartTimeResponseWaitList(animation, willGetResponse);
+}
+
+void CompositeAnimationPrivate::removeFromStartTimeResponseWaitList(AnimationBase* animation)
+{
+ m_animationController->removeFromStartTimeResponseWaitList(animation);
+}
+
bool CompositeAnimationPrivate::pauseAnimationAtTime(const AtomicString& name, double t)
{
if (!name)
@@ -601,7 +617,7 @@ unsigned CompositeAnimationPrivate::numberOfActiveAnimations() const
return count;
}
-CompositeAnimation::CompositeAnimation(AnimationController* animationController)
+CompositeAnimation::CompositeAnimation(AnimationControllerPrivate* animationController)
: m_data(new CompositeAnimationPrivate(animationController, this))
{
}
@@ -611,9 +627,9 @@ CompositeAnimation::~CompositeAnimation()
delete m_data;
}
-AnimationController* CompositeAnimation::animationController()
+AnimationControllerPrivate* CompositeAnimation::animationControllerPriv() const
{
- return m_data->animationController();
+ return m_data->animationControllerPriv();
}
void CompositeAnimation::clearRenderer()
@@ -626,6 +642,11 @@ PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, Rend
return m_data->animate(renderer, currentStyle, targetStyle);
}
+PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle()
+{
+ return m_data->getAnimatedStyle();
+}
+
double CompositeAnimation::willNeedService() const
{
return m_data->willNeedService();
@@ -641,6 +662,16 @@ void CompositeAnimation::removeFromStyleAvailableWaitList(AnimationBase* animati
m_data->removeFromStyleAvailableWaitList(animation);
}
+void CompositeAnimation::addToStartTimeResponseWaitList(AnimationBase* animation, bool willGetResponse)
+{
+ m_data->addToStartTimeResponseWaitList(animation, willGetResponse);
+}
+
+void CompositeAnimation::removeFromStartTimeResponseWaitList(AnimationBase* animation)
+{
+ m_data->removeFromStartTimeResponseWaitList(animation);
+}
+
void CompositeAnimation::suspendAnimations()
{
m_data->suspendAnimations();
@@ -676,16 +707,6 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int pr
return m_data->getAnimationForProperty(property);
}
-void CompositeAnimation::setAnimationStartTime(double t)
-{
- m_data->setAnimationStartTime(t);
-}
-
-void CompositeAnimation::setTransitionStartTime(int property, double t)
-{
- m_data->setTransitionStartTime(property, t);
-}
-
void CompositeAnimation::overrideImplicitAnimations(int property)
{
m_data->overrideImplicitAnimations(property);
diff --git a/WebCore/page/animation/CompositeAnimation.h b/WebCore/page/animation/CompositeAnimation.h
index 3517b34..b5857aa 100644
--- a/WebCore/page/animation/CompositeAnimation.h
+++ b/WebCore/page/animation/CompositeAnimation.h
@@ -36,6 +36,7 @@
namespace WebCore {
+class AnimationControllerPrivate;
class CompositeAnimationPrivate;
class AnimationBase;
class AnimationController;
@@ -47,7 +48,7 @@ class RenderStyle;
// on a single RenderObject, such as a number of properties transitioning at once.
class CompositeAnimation : public RefCounted<CompositeAnimation> {
public:
- static PassRefPtr<CompositeAnimation> create(AnimationController* animationController)
+ static PassRefPtr<CompositeAnimation> create(AnimationControllerPrivate* animationController)
{
return adoptRef(new CompositeAnimation(animationController));
};
@@ -57,9 +58,17 @@ public:
void clearRenderer();
PassRefPtr<RenderStyle> animate(RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle);
+ PassRefPtr<RenderStyle> getAnimatedStyle();
+
double willNeedService() const;
- AnimationController* animationController();
+ AnimationControllerPrivate* animationControllerPriv() const;
+
+ void addToStyleAvailableWaitList(AnimationBase*);
+ void removeFromStyleAvailableWaitList(AnimationBase*);
+
+ void addToStartTimeResponseWaitList(AnimationBase*, bool willGetResponse);
+ void removeFromStartTimeResponseWaitList(AnimationBase*);
void suspendAnimations();
void resumeAnimations();
@@ -72,10 +81,6 @@ public:
PassRefPtr<KeyframeAnimation> getAnimationForProperty(int property);
-
- void setAnimationStartTime(double t);
- void setTransitionStartTime(int property, double t);
-
void overrideImplicitAnimations(int property);
void resumeOverriddenImplicitAnimations(int property);
@@ -83,11 +88,8 @@ public:
bool pauseTransitionAtTime(int property, double t);
unsigned numberOfActiveAnimations() const;
- void addToStyleAvailableWaitList(AnimationBase*);
- void removeFromStyleAvailableWaitList(AnimationBase*);
-
private:
- CompositeAnimation(AnimationController* animationController);
+ CompositeAnimation(AnimationControllerPrivate* animationController);
CompositeAnimationPrivate* m_data;
};
diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp
index f984909..8ec0be0 100644
--- a/WebCore/page/animation/ImplicitAnimation.cpp
+++ b/WebCore/page/animation/ImplicitAnimation.cpp
@@ -28,13 +28,15 @@
#include "config.h"
-#include "AnimationController.h"
+#include "AnimationControllerPrivate.h"
#include "CompositeAnimation.h"
#include "CSSPropertyNames.h"
#include "EventNames.h"
#include "ImplicitAnimation.h"
#include "KeyframeAnimation.h"
-#include "RenderObject.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -55,12 +57,12 @@ ImplicitAnimation::~ImplicitAnimation()
updateStateMachine(AnimationStateInputEndAnimation, -1);
}
-bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType)
+bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) const
{
return m_object->document()->hasListenerType(inListenerType);
}
-void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
{
// If we get this far and the animation is done, it means we are cleaning up a just finished animation.
// So just return. Everything is already all cleaned up.
@@ -76,13 +78,58 @@ void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, RenderStyle*
if (!animatedStyle)
animatedStyle = RenderStyle::clone(targetStyle);
- if (blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0)))
+ bool needsAnim = blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
+ // FIXME: we also need to detect cases where we have to software animate for other reasons,
+ // such as a child using inheriting the transform. https://bugs.webkit.org/show_bug.cgi?id=23902
+ if (needsAnim)
setAnimating();
+ else {
+#if USE(ACCELERATED_COMPOSITING)
+ // If we are running an accelerated animation, set a flag in the style which causes the style
+ // to compare as different to any other style. This ensures that changes to the property
+ // that is animating are correctly detected during the animation (e.g. when a transition
+ // gets interrupted).
+ animatedStyle->setIsRunningAcceleratedAnimation();
+#endif
+ }
// Fire the start timeout if needed
fireAnimationEventsIfNeeded();
}
+void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
+{
+ if (!animatedStyle)
+ animatedStyle = RenderStyle::clone(m_toStyle.get());
+
+ blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
+}
+
+bool ImplicitAnimation::startAnimation(double beginTime)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object && m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ return layer->backing()->startTransition(beginTime, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
+ }
+#else
+ UNUSED_PARAM(beginTime);
+#endif
+ return false;
+}
+
+void ImplicitAnimation::endAnimation(bool /*reset*/)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object && m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ layer->backing()->transitionFinished(m_animatingProperty);
+ }
+#endif
+}
+
void ImplicitAnimation::onAnimationEnd(double elapsedTime)
{
// If we have a keyframe animation on this property, this transition is being overridden. The keyframe
@@ -120,7 +167,7 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl
return false;
// Schedule event handling
- m_object->animation()->addEventToDispatch(element, eventType, propertyName, elapsedTime);
+ m_compAnim->animationControllerPriv()->addEventToDispatch(element, eventType, propertyName, elapsedTime);
// Restore the original (unanimated) style
if (eventType == eventNames().webkitTransitionEndEvent && element->renderer())
@@ -137,7 +184,6 @@ void ImplicitAnimation::reset(RenderStyle* to)
{
ASSERT(to);
ASSERT(m_fromStyle);
-
m_toStyle = to;
@@ -209,4 +255,21 @@ void ImplicitAnimation::validateTransformFunctionList()
m_transformFunctionListValid = true;
}
+double ImplicitAnimation::willNeedService()
+{
+ double t = AnimationBase::willNeedService();
+#if USE(ACCELERATED_COMPOSITING)
+ if (t != 0 || preActive())
+ return t;
+
+ // A return value of 0 means we need service. But if this is an accelerated animation we
+ // only need service at the end of the transition.
+ if (animationOfPropertyIsAccelerated(m_animatingProperty) && !isFallbackAnimating()) {
+ bool isLooping;
+ getTimeToNextEvent(t, isLooping);
+ }
+#endif
+ return t;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h
index cf98bba..221c45e 100644
--- a/WebCore/page/animation/ImplicitAnimation.h
+++ b/WebCore/page/animation/ImplicitAnimation.h
@@ -47,8 +47,11 @@ public:
int animatingProperty() const { return m_animatingProperty; }
virtual void onAnimationEnd(double elapsedTime);
+ virtual bool startAnimation(double beginTime);
+ virtual void endAnimation(bool reset);
- virtual void animate(CompositeAnimation*, RenderObject*, RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
+ virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
+ virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
virtual void reset(RenderStyle* to);
void setOverridden(bool);
@@ -62,8 +65,10 @@ public:
void blendPropertyValueInStyle(int, RenderStyle* currentStyle);
+ virtual double willNeedService();
+
protected:
- bool shouldSendEventForListener(Document::ListenerType);
+ bool shouldSendEventForListener(Document::ListenerType) const;
bool sendTransitionEvent(const AtomicString&, double elapsedTime);
void validateTransformFunctionList();
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
index 2efa578..88a5f6a 100644
--- a/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -29,12 +29,14 @@
#include "config.h"
#include "KeyframeAnimation.h"
-#include "AnimationController.h"
+#include "AnimationControllerPrivate.h"
#include "CSSPropertyNames.h"
#include "CSSStyleSelector.h"
#include "CompositeAnimation.h"
#include "EventNames.h"
-#include "RenderObject.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -45,8 +47,8 @@ KeyframeAnimation::KeyframeAnimation(const Animation* animation, RenderObject* r
, m_unanimatedStyle(unanimatedStyle)
{
// Get the keyframe RenderStyles
- if (m_object && m_object->element() && m_object->element()->isElementNode())
- m_object->document()->styleSelector()->keyframeStylesForAnimation(static_cast<Element*>(m_object->element()), unanimatedStyle, m_keyframes);
+ if (m_object && m_object->node() && m_object->node()->isElementNode())
+ m_object->document()->styleSelector()->keyframeStylesForAnimation(static_cast<Element*>(m_object->node()), unanimatedStyle, m_keyframes);
// Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
validateTransformFunctionList();
@@ -59,32 +61,8 @@ KeyframeAnimation::~KeyframeAnimation()
updateStateMachine(AnimationStateInputEndAnimation, -1);
}
-void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+void KeyframeAnimation::getKeyframeAnimationInterval(const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
{
- // Fire the start timeout if needed
- fireAnimationEventsIfNeeded();
-
- // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
- if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
- updateStateMachine(AnimationStateInputStartAnimation, -1);
-
- // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
- // If so, we need to send back the targetStyle.
- if (postActive()) {
- if (!animatedStyle)
- animatedStyle = const_cast<RenderStyle*>(targetStyle);
- return;
- }
-
- // If we are waiting for the start timer, we don't want to change the style yet.
- // Special case - if the delay time is 0, then we do want to set the first frame of the
- // animation right away. This avoids a flash when the animation starts.
- if (waitingToStart() && m_animation->delay() > 0)
- return;
-
- // FIXME: we need to be more efficient about determining which keyframes we are animating between.
- // We should cache the last pair or something.
-
// Find the first key
double elapsedTime = getElapsedTime();
@@ -94,8 +72,6 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
if (m_animation->direction() && (i & 1))
t = 1 - t;
- const RenderStyle* fromStyle = 0;
- const RenderStyle* toStyle = 0;
double scale = 1;
double offset = 0;
Vector<KeyframeValue>::const_iterator endKeyframes = m_keyframes.endKeyframes();
@@ -113,6 +89,48 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
fromStyle = it->style();
}
+ if (!fromStyle || !toStyle)
+ return;
+
+ const TimingFunction* timingFunction = 0;
+ if (fromStyle->animations() && fromStyle->animations()->size() > 0)
+ timingFunction = &(fromStyle->animations()->animation(0)->timingFunction());
+
+ prog = progress(scale, offset, timingFunction);
+}
+
+void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
+{
+ // Fire the start timeout if needed
+ fireAnimationEventsIfNeeded();
+
+ // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
+ if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
+ updateStateMachine(AnimationStateInputStartAnimation, -1);
+
+ // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
+ // If so, we need to send back the targetStyle.
+ if (postActive()) {
+ if (!animatedStyle)
+ animatedStyle = const_cast<RenderStyle*>(targetStyle);
+ return;
+ }
+
+ // If we are waiting for the start timer, we don't want to change the style yet.
+ // Special case - if the delay time is 0, then we do want to set the first frame of the
+ // animation right away. This avoids a flash when the animation starts.
+ if (waitingToStart() && m_animation->delay() > 0)
+ return;
+
+ // FIXME: we need to be more efficient about determining which keyframes we are animating between.
+ // We should cache the last pair or something.
+
+ // Get the from/to styles and progress between
+ const RenderStyle* fromStyle = 0;
+ const RenderStyle* toStyle = 0;
+ double progress;
+ getKeyframeAnimationInterval(fromStyle, toStyle, progress);
+
// If either style is 0 we have an invalid case, just stop the animation.
if (!fromStyle || !toStyle) {
updateStateMachine(AnimationStateInputEndAnimation, -1);
@@ -124,19 +142,42 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
if (!animatedStyle)
animatedStyle = RenderStyle::clone(targetStyle);
- const TimingFunction* timingFunction = 0;
- if (fromStyle->animations() && fromStyle->animations()->size() > 0)
- timingFunction = &(fromStyle->animations()->animation(0)->timingFunction());
-
- double prog = progress(scale, offset, timingFunction);
-
HashSet<int>::const_iterator endProperties = m_keyframes.endProperties();
for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- if (blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, prog))
+ bool needsAnim = blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
+ if (needsAnim)
setAnimating();
+ else {
+#if USE(ACCELERATED_COMPOSITING)
+ // If we are running an accelerated animation, set a flag in the style
+ // to indicate it. This can be used to make sure we get an updated
+ // style for hit testing, etc.
+ animatedStyle->setIsRunningAcceleratedAnimation();
+#endif
+ }
}
}
+void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
+{
+ // Get the from/to styles and progress between
+ const RenderStyle* fromStyle = 0;
+ const RenderStyle* toStyle = 0;
+ double progress;
+ getKeyframeAnimationInterval(fromStyle, toStyle, progress);
+
+ // If either style is 0 we have an invalid case
+ if (!fromStyle || !toStyle)
+ return;
+
+ if (!animatedStyle)
+ animatedStyle = RenderStyle::clone(m_object->style());
+
+ HashSet<int>::const_iterator endProperties = m_keyframes.endProperties();
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it)
+ blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
+}
+
bool KeyframeAnimation::hasAnimationForProperty(int property) const
{
HashSet<int>::const_iterator end = m_keyframes.endProperties();
@@ -148,14 +189,38 @@ bool KeyframeAnimation::hasAnimationForProperty(int property) const
return false;
}
-void KeyframeAnimation::endAnimation(bool)
+bool KeyframeAnimation::startAnimation(double beginTime)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object && m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ return layer->backing()->startAnimation(beginTime, m_animation.get(), m_keyframes);
+ }
+#else
+ UNUSED_PARAM(beginTime);
+#endif
+ return false;
+}
+
+void KeyframeAnimation::endAnimation(bool reset)
{
- // Restore the original (unanimated) style
- if (m_object)
- setChanged(m_object->element());
+ if (m_object) {
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ layer->backing()->animationFinished(m_keyframes.animationName(), 0, reset);
+ }
+#else
+ UNUSED_PARAM(reset);
+#endif
+ // Restore the original (unanimated) style
+ setChanged(m_object->node());
+ }
}
-bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType)
+bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const
{
return m_object->document()->hasListenerType(listenerType);
}
@@ -201,7 +266,7 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
return false;
// Schedule event handling
- m_object->animation()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
+ m_compAnim->animationControllerPriv()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
// Restore the original (unanimated) style
if (eventType == eventNames().webkitAnimationEndEvent && element->renderer())
@@ -287,4 +352,31 @@ void KeyframeAnimation::validateTransformFunctionList()
m_transformFunctionListValid = true;
}
+double KeyframeAnimation::willNeedService()
+{
+ double t = AnimationBase::willNeedService();
+#if USE(ACCELERATED_COMPOSITING)
+ if (t != 0 || preActive())
+ return t;
+
+ // A return value of 0 means we need service. But if we only have accelerated animations we
+ // only need service at the end of the transition
+ HashSet<int>::const_iterator endProperties = m_keyframes.endProperties();
+ bool acceleratedPropertiesOnly = true;
+
+ for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
+ if (!animationOfPropertyIsAccelerated(*it) || isFallbackAnimating()) {
+ acceleratedPropertiesOnly = false;
+ break;
+ }
+ }
+
+ if (acceleratedPropertiesOnly) {
+ bool isLooping;
+ getTimeToNextEvent(t, isLooping);
+ }
+#endif
+ return t;
+}
+
} // namespace WebCore
diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h
index 5c3176c..1090e5b 100644
--- a/WebCore/page/animation/KeyframeAnimation.h
+++ b/WebCore/page/animation/KeyframeAnimation.h
@@ -44,8 +44,9 @@ public:
{
return adoptRef(new KeyframeAnimation(animation, renderer, index, compositeAnimation, unanimatedStyle));
};
-
- virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, const RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
+
+ virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
+ virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
const AtomicString& name() const { return m_keyframes.animationName(); }
int index() const { return m_index; }
@@ -56,16 +57,19 @@ public:
void setUnanimatedStyle(PassRefPtr<RenderStyle> style) { m_unanimatedStyle = style; }
RenderStyle* unanimatedStyle() const { return m_unanimatedStyle.get(); }
+ virtual double willNeedService();
+
protected:
virtual void onAnimationStart(double elapsedTime);
virtual void onAnimationIteration(double elapsedTime);
virtual void onAnimationEnd(double elapsedTime);
+ virtual bool startAnimation(double beginTime);
virtual void endAnimation(bool reset);
virtual void overrideAnimations();
virtual void resumeOverriddenAnimations();
- bool shouldSendEventForListener(Document::ListenerType inListenerType);
+ bool shouldSendEventForListener(Document::ListenerType inListenerType) const;
bool sendAnimationEvent(const AtomicString&, double elapsedTime);
virtual bool affectsProperty(int) const;
@@ -76,6 +80,9 @@ private:
KeyframeAnimation(const Animation* animation, RenderObject*, int index, CompositeAnimation*, RenderStyle* unanimatedStyle);
virtual ~KeyframeAnimation();
+ // Get the styles surrounding the current animation time and the progress between them
+ void getKeyframeAnimationInterval(const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& progress) const;
+
// The keyframes that we are blending.
KeyframeList m_keyframes;
diff --git a/WebCore/page/chromium/AccessibilityObjectWrapper.h b/WebCore/page/chromium/AccessibilityObjectWrapper.h
index 9920e4d..6420b32 100644
--- a/WebCore/page/chromium/AccessibilityObjectWrapper.h
+++ b/WebCore/page/chromium/AccessibilityObjectWrapper.h
@@ -39,7 +39,11 @@ namespace WebCore {
protected:
AccessibilityObjectWrapper(AccessibilityObject* obj)
- : RefCounted<AccessibilityObjectWrapper>(0), m_object(obj) { }
+ : m_object(obj)
+ {
+ // FIXME: Remove this once our immediate subclass no longer uses COM.
+ m_refCount = 0;
+ }
AccessibilityObjectWrapper() : m_object(0) { }
AccessibilityObject* m_object;
diff --git a/WebCore/page/chromium/EventHandlerChromium.cpp b/WebCore/page/chromium/EventHandlerChromium.cpp
index 883bece..0cfc12d 100644
--- a/WebCore/page/chromium/EventHandlerChromium.cpp
+++ b/WebCore/page/chromium/EventHandlerChromium.cpp
@@ -62,7 +62,7 @@ bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m
if (m_frame->selection()->contains(p)) {
VisiblePosition visiblePos(
mev.targetNode()->renderer()->positionForPoint(mev.localPoint()));
- Selection newSelection(visiblePos);
+ VisibleSelection newSelection(visiblePos);
if (m_frame->shouldChangeSelection(newSelection))
m_frame->selection()->setSelection(newSelection);
}
@@ -148,7 +148,11 @@ bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
unsigned EventHandler::accessKeyModifiers()
{
+#if PLATFORM(DARWIN)
+ return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
+#else
return PlatformKeyboardEvent::AltKey;
+#endif
}
} // namespace WebCore
diff --git a/WebCore/page/chromium/FrameChromium.cpp b/WebCore/page/chromium/FrameChromium.cpp
index 1e4ed16..d85fbcc 100644
--- a/WebCore/page/chromium/FrameChromium.cpp
+++ b/WebCore/page/chromium/FrameChromium.cpp
@@ -79,7 +79,7 @@ void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float head
float printedPagesHeight = 0.0f;
do {
float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
- frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
+ frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
diff --git a/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
index c1a405e..84f3d34 100644
--- a/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/WebCore/page/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -110,7 +110,7 @@ static const gchar* webkit_accessible_get_name(AtkObject* object)
{
// TODO: Deal with later changes.
if (!object->name)
- atk_object_set_name(object, core(object)->title().utf8().data());
+ atk_object_set_name(object, core(object)->stringValue().utf8().data());
return object->name;
}
@@ -650,7 +650,7 @@ void webkit_accessible_detach(WebKitAccessible* accessible)
// detachment.
// FIXME: Using fallbackCache->get(ListBoxOptionRole) is a hack.
- accessible->m_object = fallbackCache->get(ListBoxOptionRole);
+ accessible->m_object = fallbackCache->getOrCreate(ListBoxOptionRole);
}
}
diff --git a/WebCore/page/mac/AXObjectCacheMac.mm b/WebCore/page/mac/AXObjectCacheMac.mm
index d5ce8f3..936d9de 100644
--- a/WebCore/page/mac/AXObjectCacheMac.mm
+++ b/WebCore/page/mac/AXObjectCacheMac.mm
@@ -58,9 +58,9 @@ void AXObjectCache::postNotification(RenderObject* renderer, const String& messa
// notifications for text input objects are sent to that object
// all others are sent to the top WebArea
- RefPtr<AccessibilityObject> obj = get(renderer)->observableObject();
+ RefPtr<AccessibilityObject> obj = getOrCreate(renderer)->observableObject();
if (!obj)
- obj = get(renderer->document()->renderer());
+ obj = getOrCreate(renderer->document()->renderer());
if (!obj)
return;
@@ -74,7 +74,7 @@ void AXObjectCache::postNotificationToElement(RenderObject* renderer, const Stri
if (!renderer)
return;
- RefPtr<AccessibilityObject> obj = get(renderer);
+ RefPtr<AccessibilityObject> obj = getOrCreate(renderer);
if (!obj)
return;
diff --git a/WebCore/page/mac/AccessibilityObjectWrapper.h b/WebCore/page/mac/AccessibilityObjectWrapper.h
index 5a55fe0..3b584a9 100644
--- a/WebCore/page/mac/AccessibilityObjectWrapper.h
+++ b/WebCore/page/mac/AccessibilityObjectWrapper.h
@@ -25,8 +25,11 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-#import <wtf/RefPtr.h>
+
+#ifndef AccessibilityObjectWrapper_h
+#define AccessibilityObjectWrapper_h
+
+#import <wtf/RefPtr.h>
#ifdef __OBJC__
@class WebCoreTextMarker;
@@ -53,3 +56,5 @@ namespace WebCore {
- (NSView*)attachmentView;
@end
+
+#endif // AccessibilityObjectWrapper_h
diff --git a/WebCore/page/mac/AccessibilityObjectWrapper.mm b/WebCore/page/mac/AccessibilityObjectWrapper.mm
index 1e28f00..1e596eb 100644
--- a/WebCore/page/mac/AccessibilityObjectWrapper.mm
+++ b/WebCore/page/mac/AccessibilityObjectWrapper.mm
@@ -181,9 +181,11 @@ static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& vi
if (!domNode)
return nil;
- if (domNode->isHTMLElement())
- if (static_cast<HTMLElement*>(domNode)->isPasswordField())
+ if (domNode->isHTMLElement()) {
+ InputElement* inputElement = toInputElement(static_cast<Element*>(domNode));
+ if (inputElement && inputElement->isPasswordField())
return nil;
+ }
// locate the renderer, which must exist for a visible dom node
RenderObject* renderer = domNode->renderer();
@@ -191,7 +193,7 @@ static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& vi
// find or create an accessibility object for this renderer
AXObjectCache* cache = renderer->document()->axObjectCache();
- RefPtr<AccessibilityObject> obj = cache->get(renderer);
+ RefPtr<AccessibilityObject> obj = cache->getOrCreate(renderer);
// create a text marker, adding an ID for the AccessibilityObject if needed
TextMarkerData textMarkerData;
@@ -201,7 +203,7 @@ static WebCoreTextMarker* textMarkerForVisiblePosition(const VisiblePosition& vi
bzero(&textMarkerData, sizeof(TextMarkerData));
textMarkerData.axID = obj.get()->axObjectID();
textMarkerData.node = domNode;
- textMarkerData.offset = deepPos.offset();
+ textMarkerData.offset = deepPos.m_offset;
textMarkerData.affinity = visiblePos.affinity();
return [[WebCoreViewFactory sharedFactory] textMarkerWithBytes:&textMarkerData length:sizeof(textMarkerData)];
}
@@ -226,7 +228,7 @@ static VisiblePosition visiblePositionForTextMarker(WebCoreTextMarker* textMarke
if (!cache->isIDinUse(textMarkerData.axID))
return VisiblePosition();
- if (deepPos.node() != textMarkerData.node || deepPos.offset() != textMarkerData.offset)
+ if (deepPos.node() != textMarkerData.node || deepPos.m_offset != textMarkerData.offset)
return VisiblePosition();
return visiblePos;
@@ -374,7 +376,7 @@ static int blockquoteLevel(RenderObject* renderer)
return 0;
int result = 0;
- for (Node* node = renderer->element(); node; node = node->parent()) {
+ for (Node* node = renderer->node(); node; node = node->parent()) {
if (node->hasTagName(blockquoteTag))
result += 1;
}
@@ -423,7 +425,7 @@ static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString,
static void AXAttributeStringSetHeadingLevel(NSMutableAttributedString* attrString, RenderObject* renderer, NSRange range)
{
- int parentHeadingLevel = AccessibilityRenderObject::headingLevel(renderer->parent()->element());
+ int parentHeadingLevel = AccessibilityRenderObject::headingLevel(renderer->parent()->node());
if (parentHeadingLevel)
[attrString addAttribute:@"AXHeadingLevel" value:[NSNumber numberWithInt:parentHeadingLevel] range:range];
@@ -437,7 +439,7 @@ static AccessibilityObject* AXLinkElementForNode(Node* node)
if (!obj)
return 0;
- RefPtr<AccessibilityObject> axObj = obj->document()->axObjectCache()->get(obj);
+ RefPtr<AccessibilityObject> axObj = obj->document()->axObjectCache()->getOrCreate(obj);
Element* anchor = axObj->anchorElement();
if (!anchor)
return 0;
@@ -446,7 +448,7 @@ static AccessibilityObject* AXLinkElementForNode(Node* node)
if (!anchorRenderer)
return 0;
- return anchorRenderer->document()->axObjectCache()->get(anchorRenderer);
+ return anchorRenderer->document()->axObjectCache()->getOrCreate(anchorRenderer);
}
static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, NSString* attribute, AccessibilityObject* object, NSRange range)
@@ -515,7 +517,7 @@ static NSString* nsStringForReplacedNode(Node* replacedNode)
}
// create an AX object, but skip it if it is not supposed to be seen
- RefPtr<AccessibilityObject> obj = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer());
+ RefPtr<AccessibilityObject> obj = replacedNode->renderer()->document()->axObjectCache()->getOrCreate(replacedNode->renderer());
if (obj->accessibilityIsIgnored())
return nil;
@@ -561,7 +563,7 @@ static NSString* nsStringForReplacedNode(Node* replacedNode)
[attrString setAttributes:nil range:attrStringRange];
// add the attachment attribute
- AccessibilityObject* obj = replacedNode->renderer()->document()->axObjectCache()->get(replacedNode->renderer());
+ AccessibilityObject* obj = replacedNode->renderer()->document()->axObjectCache()->getOrCreate(replacedNode->renderer());
AXAttributeStringSetElement(attrString, NSAccessibilityAttachmentTextAttribute, obj, attrStringRange);
}
}
@@ -580,6 +582,9 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
- (NSArray*)accessibilityActionNames
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
static NSArray* actionElementActions = [[NSArray alloc] initWithObjects: NSAccessibilityPressAction, NSAccessibilityShowMenuAction, nil];
@@ -601,6 +606,9 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
- (NSArray*)accessibilityAttributeNames
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
if (m_object->isAttachment())
@@ -871,7 +879,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
static void convertToVector(NSArray* array, AccessibilityObject::AccessibilityChildrenVector& vector)
{
unsigned length = [array count];
- vector.reserveCapacity(length);
+ vector.reserveInitialCapacity(length);
for (unsigned i = 0; i < length; ++i) {
AccessibilityObject* obj = [[array objectAtIndex:i] accessibilityObject];
if (obj)
@@ -884,16 +892,23 @@ static NSMutableArray* convertToNSArray(const AccessibilityObject::Accessibility
unsigned length = vector.size();
NSMutableArray* array = [NSMutableArray arrayWithCapacity: length];
for (unsigned i = 0; i < length; ++i) {
- ASSERT(vector[i]->wrapper());
- if (vector[i]->wrapper())
- [array addObject:vector[i]->wrapper()];
+ AccessibilityObjectWrapper* wrapper = vector[i]->wrapper();
+ ASSERT(wrapper);
+ if (wrapper) {
+ // we want to return the attachment view instead of the object representing the attachment.
+ // otherwise, we get palindrome errors in the AX hierarchy
+ if (vector[i]->isAttachment() && [wrapper attachmentView])
+ [array addObject:[wrapper attachmentView]];
+ else
+ [array addObject:wrapper];
+ }
}
return array;
}
- (WebCoreTextMarkerRange*)textMarkerRangeForSelection
{
- Selection selection = m_object->selection();
+ VisibleSelection selection = m_object->selection();
if (selection.isNone())
return nil;
return textMarkerRangeFromVisiblePositions(selection.visibleStart(), selection.visibleEnd());
@@ -1436,6 +1451,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (id)accessibilityFocusedUIElement
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
RefPtr<AccessibilityObject> focusedObj = m_object->focusedUIElement();
@@ -1448,6 +1466,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (id)accessibilityHitTest:(NSPoint)point
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
RefPtr<AccessibilityObject> axObject = m_object->doAccessibilityHitTest(IntPoint(point));
@@ -1458,6 +1479,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attributeName
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
if ([attributeName isEqualToString: @"AXSelectedTextMarkerRange"])
@@ -1494,6 +1518,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
// Registering an object is also required for observing notifications. Only registered objects can be observed.
- (BOOL)accessibilityIsIgnored
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
if (m_object->isAttachment())
@@ -1503,6 +1530,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (NSArray* )accessibilityParameterizedAttributeNames
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
if (m_object->isAttachment())
@@ -1585,6 +1615,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (void)accessibilityPerformPressAction
{
+ if (!m_object)
+ return;
+
m_object->updateBackingStore();
if (m_object->isAttachment())
@@ -1631,6 +1664,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (void)accessibilityPerformAction:(NSString*)action
{
+ if (!m_object)
+ return;
+
m_object->updateBackingStore();
if ([action isEqualToString:NSAccessibilityPressAction])
@@ -1642,6 +1678,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attributeName
{
+ if (!m_object)
+ return;
+
m_object->updateBackingStore();
WebCoreTextMarkerRange* textMarkerRange = nil;
@@ -1721,7 +1760,7 @@ static RenderObject* rendererForView(NSView* view)
if (!renderer)
return nil;
- AccessibilityObject* obj = renderer->document()->axObjectCache()->get(renderer);
+ AccessibilityObject* obj = renderer->document()->axObjectCache()->getOrCreate(renderer);
if (obj)
return obj->parentObjectUnignored()->wrapper();
return nil;
@@ -2013,6 +2052,9 @@ static RenderObject* rendererForView(NSView* view)
// API that AppKit uses for faster access
- (NSUInteger)accessibilityIndexOfChild:(id)child
{
+ if (!m_object)
+ return NSNotFound;
+
m_object->updateBackingStore();
const AccessibilityObject::AccessibilityChildrenVector& children = m_object->children();
@@ -2022,7 +2064,8 @@ static RenderObject* rendererForView(NSView* view)
unsigned count = children.size();
for (unsigned k = 0; k < count; ++k) {
- if (children[k]->wrapper() == child)
+ AccessibilityObjectWrapper* wrapper = children[k]->wrapper();
+ if (wrapper == child || (children[k]->isAttachment() && [wrapper attachmentView] == child))
return k;
}
@@ -2031,6 +2074,9 @@ static RenderObject* rendererForView(NSView* view)
- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
{
+ if (!m_object)
+ return 0;
+
m_object->updateBackingStore();
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
@@ -2046,6 +2092,9 @@ static RenderObject* rendererForView(NSView* view)
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
{
+ if (!m_object)
+ return nil;
+
m_object->updateBackingStore();
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
@@ -2070,8 +2119,16 @@ static RenderObject* rendererForView(NSView* view)
unsigned available = min(childCount - index, maxCount);
NSMutableArray *subarray = [NSMutableArray arrayWithCapacity:available];
- for (unsigned added = 0; added < available; ++index, ++added)
- [subarray addObject:children[index]->wrapper()];
+ for (unsigned added = 0; added < available; ++index, ++added) {
+ AccessibilityObjectWrapper* wrapper = children[index]->wrapper();
+ if (wrapper) {
+ // The attachment view should be returned, otherwise AX palindrome errors occur.
+ if (children[index]->isAttachment() && [wrapper attachmentView])
+ [subarray addObject:[wrapper attachmentView]];
+ else
+ [subarray addObject:wrapper];
+ }
+ }
return subarray;
}
diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm
index 5d09843..33d1c5f 100644
--- a/WebCore/page/mac/EventHandlerMac.mm
+++ b/WebCore/page/mac/EventHandlerMac.mm
@@ -83,10 +83,10 @@ PassRefPtr<KeyboardEvent> EventHandler::currentKeyboardEvent() const
case NSKeyDown: {
PlatformKeyboardEvent platformEvent(event);
platformEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
- return KeyboardEvent::create(platformEvent, m_frame->document() ? m_frame->document()->defaultView() : 0);
+ return KeyboardEvent::create(platformEvent, m_frame->document()->defaultView());
}
case NSKeyUp:
- return KeyboardEvent::create(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
+ return KeyboardEvent::create(event, m_frame->document()->defaultView());
default:
return 0;
}
@@ -140,8 +140,6 @@ bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
}
Document* document = m_frame->document();
- if (!document)
- return false;
// RSS view needs arrow key keypress events.
if (isSafari && document->url().protocolIs("feed") || document->url().protocolIs("feeds"))
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index 84d7549..f360511 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -156,7 +156,7 @@ NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTable
if (cellAboveRenderer) {
HTMLTableCellElement* aboveCell =
- static_cast<HTMLTableCellElement*>(cellAboveRenderer->element());
+ static_cast<HTMLTableCellElement*>(cellAboveRenderer->node());
if (aboveCell) {
// search within the above cell we found for a match
@@ -490,8 +490,6 @@ void Frame::setUseSecureKeyboardEntry(bool enable)
NSMutableDictionary* Frame::dashboardRegionsDictionary()
{
Document* doc = document();
- if (!doc)
- return nil;
const Vector<DashboardRegionValue>& regions = doc->dashboardRegions();
size_t n = regions.size();
@@ -537,7 +535,7 @@ void Frame::setUserStyleSheetLocation(const KURL& url)
{
delete m_userStyleSheetLoader;
m_userStyleSheetLoader = 0;
- if (m_doc && m_doc->docLoader())
+ if (m_doc->docLoader())
m_userStyleSheetLoader = new UserStyleSheetLoader(m_doc, url.string());
}
@@ -545,8 +543,7 @@ void Frame::setUserStyleSheet(const String& styleSheet)
{
delete m_userStyleSheetLoader;
m_userStyleSheetLoader = 0;
- if (m_doc)
- m_doc->setUserStyleSheet(styleSheet);
+ m_doc->setUserStyleSheet(styleSheet);
}
} // namespace WebCore
diff --git a/WebCore/page/win/FrameWin.cpp b/WebCore/page/win/FrameWin.cpp
index fef1ffa..db55d30 100644
--- a/WebCore/page/win/FrameWin.cpp
+++ b/WebCore/page/win/FrameWin.cpp
@@ -81,7 +81,7 @@ void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float head
float printedPagesHeight = 0.0f;
do {
float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
- frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
+ frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
diff --git a/WebCore/platform/ContentType.cpp b/WebCore/platform/ContentType.cpp
new file mode 100644
index 0000000..3dce7b5
--- /dev/null
+++ b/WebCore/platform/ContentType.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ContentType.h"
+
+namespace WebCore {
+
+ContentType::ContentType(const String& contentType)
+ : m_type(contentType)
+{
+}
+
+String ContentType::parameter(const String& parameterName) const
+{
+ String parameterValue;
+ String strippedType = m_type.stripWhiteSpace();
+
+ // a MIME type can have one or more "param=value" after a semi-colon, and separated from each other by semi-colons
+ int semi = strippedType.find(';');
+ if (semi != -1) {
+ int start = strippedType.find(parameterName, semi + 1, false);
+ if (start != -1) {
+ start = strippedType.find('=', start + 6);
+ if (start != -1) {
+ int end = strippedType.find(';', start + 6);
+ if (end == -1)
+ end = strippedType.length();
+ parameterValue = strippedType.substring(start + 1, end - (start + 1)).stripWhiteSpace();
+ }
+ }
+ }
+
+ return parameterValue;
+}
+
+String ContentType::type() const
+{
+ String strippedType = m_type.stripWhiteSpace();
+
+ // "type" can have parameters after a semi-colon, strip them
+ int semi = strippedType.find(';');
+ if (semi != -1)
+ strippedType = strippedType.left(semi).stripWhiteSpace();
+
+ return strippedType;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/ContentType.h b/WebCore/platform/ContentType.h
new file mode 100644
index 0000000..bf8fc4c
--- /dev/null
+++ b/WebCore/platform/ContentType.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ContentType_h
+#define ContentType_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+ class ContentType {
+ public:
+ ContentType(const String& type);
+
+ String parameter (const String& parameterName) const;
+ String type() const;
+ const String& raw() const { return m_type; }
+ private:
+ String m_type;
+ };
+
+} // namespace WebCore
+
+#endif // ContentType_h
diff --git a/WebCore/platform/ContextMenu.cpp b/WebCore/platform/ContextMenu.cpp
index f086b63..f66a891 100644
--- a/WebCore/platform/ContextMenu.cpp
+++ b/WebCore/platform/ContextMenu.cpp
@@ -192,7 +192,7 @@ static void createAndAppendTextDirectionSubMenu(const HitTestResult& result, Con
static bool selectionContainsPossibleWord(Frame* frame)
{
// Current algorithm: look for a character that's not just a separator.
- for (TextIterator it(frame->selection()->toRange().get()); !it.atEnd(); it.advance()) {
+ for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atEnd(); it.advance()) {
int length = it.length();
const UChar* characters = it.characters();
for (int i = 0; i < length; ++i)
@@ -252,7 +252,7 @@ void ContextMenu::populate()
if (!node)
return;
#if PLATFORM(GTK)
- if (!result.isContentEditable() && node->isControl())
+ if (!result.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()))
return;
#endif
Frame* frame = node->document()->frame();
@@ -328,12 +328,10 @@ void ContextMenu::populate()
if (!inPasswordField) {
// Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
// is never considered a misspelling and bad grammar at the same time)
- bool misspelling = frame->editor()->isSelectionMisspelled();
- bool badGrammar = !misspelling && (frame->editor()->isGrammarCheckingEnabled() && frame->editor()->isSelectionUngrammatical());
-
+ bool misspelling;
+ bool badGrammar;
+ Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar);
if (misspelling || badGrammar) {
- Vector<String> guesses = misspelling ? frame->editor()->guessesForMisspelledSelection()
- : frame->editor()->guessesForUngrammaticalSelection();
size_t size = guesses.size();
if (size == 0) {
// If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
@@ -427,7 +425,7 @@ void ContextMenu::populate()
if (Page* page = frame->page()) {
if (Settings* settings = page->settings()) {
bool includeTextDirectionSubmenu = settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
- || settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection();
+ || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection());
if (includeTextDirectionSubmenu) {
ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu,
contextMenuItemTagTextDirectionMenu());
diff --git a/WebCore/platform/CrossThreadCopier.cpp b/WebCore/platform/CrossThreadCopier.cpp
new file mode 100644
index 0000000..9ca626f
--- /dev/null
+++ b/WebCore/platform/CrossThreadCopier.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "CrossThreadCopier.h"
+
+#include "PlatformString.h"
+#include "ResourceError.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+
+namespace WebCore {
+
+CrossThreadCopierBase<false, String>::Type CrossThreadCopierBase<false, String>::copy(const String& str)
+{
+ return str.copy();
+}
+
+CrossThreadCopierBase<false, ResourceError>::Type CrossThreadCopierBase<false, ResourceError>::copy(const ResourceError& error)
+{
+ return error.copy();
+}
+
+CrossThreadCopierBase<false, ResourceRequest>::Type CrossThreadCopierBase<false, ResourceRequest>::copy(const ResourceRequest& request)
+{
+ return request.copyData();
+}
+
+CrossThreadCopierBase<false, ResourceResponse>::Type CrossThreadCopierBase<false, ResourceResponse>::copy(const ResourceResponse& response)
+{
+ return response.copyData();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/CrossThreadCopier.h b/WebCore/platform/CrossThreadCopier.h
new file mode 100644
index 0000000..e7b4c0e
--- /dev/null
+++ b/WebCore/platform/CrossThreadCopier.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CrossThreadCopier_h
+#define CrossThreadCopier_h
+
+#include <memory>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/TypeTraits.h>
+
+namespace WebCore {
+
+ class ResourceError;
+ struct ResourceRequest;
+ class ResourceResponse;
+ class String;
+ struct CrossThreadResourceResponseData;
+ struct CrossThreadResourceRequestData;
+
+ template<typename T> struct CrossThreadCopierPassThrough {
+ typedef T Type;
+ static Type copy(const T& parameter)
+ {
+ return parameter;
+ }
+ };
+
+ template<bool isConvertibleToInteger, typename T> struct CrossThreadCopierBase;
+
+ // Integers get passed through without any changes.
+ template<typename T> struct CrossThreadCopierBase<true, T> : public CrossThreadCopierPassThrough<T> {
+ };
+
+ // Pointers get passed through without any significant changes.
+ template<typename T> struct CrossThreadCopierBase<false, T*> : public CrossThreadCopierPassThrough<T*> {
+ };
+
+ // Custom copy methods.
+ template<typename T> struct CrossThreadCopierBase<false, RefPtr<ThreadSafeShared<T> > > {
+ typedef PassRefPtr<T> Type;
+ static Type copy(const RefPtr<ThreadSafeShared<T> >& refPtr)
+ {
+ return PassRefPtr<T>(static_cast<T*>(refPtr.get()));
+ }
+ };
+
+ template<typename T> struct CrossThreadCopierBase<false, std::auto_ptr<T> > {
+ typedef std::auto_ptr<T> Type;
+ static Type copy(const std::auto_ptr<T>& autoPtr)
+ {
+ return std::auto_ptr<T>(*const_cast<std::auto_ptr<T>*>(&autoPtr));
+ }
+ };
+
+ template<> struct CrossThreadCopierBase<false, String> {
+ typedef String Type;
+ static Type copy(const String&);
+ };
+
+ template<> struct CrossThreadCopierBase<false, ResourceError> {
+ typedef ResourceError Type;
+ static Type copy(const ResourceError&);
+ };
+
+ template<> struct CrossThreadCopierBase<false, ResourceRequest> {
+ typedef std::auto_ptr<CrossThreadResourceRequestData> Type;
+ static Type copy(const ResourceRequest&);
+ };
+
+ template<> struct CrossThreadCopierBase<false, ResourceResponse> {
+ typedef std::auto_ptr<CrossThreadResourceResponseData> Type;
+ static Type copy(const ResourceResponse&);
+ };
+
+ template<typename T> struct CrossThreadCopier : public CrossThreadCopierBase<WTF::IsConvertibleToInteger<T>::value, T> {
+ };
+
+} // namespace WebCore
+
+#endif // CrossThreadCopier_h
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index 66dbc20..8ccefab 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -97,9 +97,6 @@ const PlatformFileHandle invalidPlatformFileHandle = 0;
#if defined(Q_WS_MAC)
typedef CFBundleRef PlatformModule;
typedef unsigned PlatformModuleVersion;
-#elif defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_S60)
-typedef QLibrary* PlatformModule;
-typedef unsigned PlatformModuleVersion;
#elif defined(Q_OS_WIN)
typedef HMODULE PlatformModule;
struct PlatformModuleVersion {
@@ -119,6 +116,9 @@ struct PlatformModuleVersion {
}
};
+#else
+typedef QLibrary* PlatformModule;
+typedef unsigned PlatformModuleVersion;
#endif
#else
diff --git a/WebCore/platform/GeolocationService.cpp b/WebCore/platform/GeolocationService.cpp
index dfd5a5c..9b362c8 100644
--- a/WebCore/platform/GeolocationService.cpp
+++ b/WebCore/platform/GeolocationService.cpp
@@ -26,9 +26,7 @@
#include "config.h"
#include "GeolocationService.h"
-#include "Geoposition.h"
-#include "PositionError.h"
-#include "PositionOptions.h"
+#include <wtf/Assertions.h>
namespace WebCore {
diff --git a/WebCore/platform/GeolocationService.h b/WebCore/platform/GeolocationService.h
index 90d52eb..74a6ead 100644
--- a/WebCore/platform/GeolocationService.h
+++ b/WebCore/platform/GeolocationService.h
@@ -38,21 +38,21 @@ class PositionOptions;
class GeolocationServiceClient {
public:
virtual ~GeolocationServiceClient() { }
- virtual void geolocationServicePositionChanged(GeolocationService*) { }
- virtual void geolocationServiceErrorOccurred(GeolocationService*) { }
+ virtual void geolocationServicePositionChanged(GeolocationService*) = 0;
+ virtual void geolocationServiceErrorOccurred(GeolocationService*) = 0;
};
class GeolocationService : public Noncopyable {
public:
static GeolocationService* create(GeolocationServiceClient*);
- virtual ~GeolocationService() {}
+ virtual ~GeolocationService() { }
virtual bool startUpdating(PositionOptions*) { return false; }
- virtual void stopUpdating() {}
+ virtual void stopUpdating() { }
virtual void suspend() { }
virtual void resume() { }
-
+
virtual Geoposition* lastPosition() const { return 0; }
virtual PositionError* lastError() const { return 0; }
@@ -65,7 +65,7 @@ protected:
private:
GeolocationServiceClient* m_geolocationServiceClient;
};
-
+
} // namespace WebCore
#endif // GeolocationService_h
diff --git a/WebCore/platform/KURL.cpp b/WebCore/platform/KURL.cpp
index 6fcb9b9..6901782 100644
--- a/WebCore/platform/KURL.cpp
+++ b/WebCore/platform/KURL.cpp
@@ -289,6 +289,7 @@ inline bool KURL::protocolIs(const String& string, const char* protocol)
void KURL::invalidate()
{
m_isValid = false;
+ m_protocolInHTTPFamily = false;
m_schemeEnd = 0;
m_userStart = 0;
m_userEnd = 0;
@@ -604,6 +605,11 @@ bool KURL::hasRef() const
return m_fragmentEnd != m_queryEnd;
}
+String KURL::baseAsString() const
+{
+ return m_string.left(m_pathAfterLastSlash);
+}
+
#ifdef NDEBUG
static inline void assertProtocolIsGood(const char*)
@@ -638,7 +644,10 @@ bool KURL::protocolIs(const char* protocol) const
String KURL::query() const
{
- return m_string.substring(m_pathEnd, m_queryEnd - m_pathEnd);
+ if (m_queryEnd == m_pathEnd)
+ return String();
+
+ return m_string.substring(m_pathEnd + 1, m_queryEnd - (m_pathEnd + 1));
}
String KURL::path() const
@@ -677,13 +686,13 @@ void KURL::setPort(unsigned short i)
if (!m_isValid)
return;
- // FIXME: Non-ASCII characters must be encoded and escaped to match parse() expectations,
- // and to avoid changing more than just the port.
-
- bool colonNeeded = m_portEnd == m_hostEnd;
- int portStart = (colonNeeded ? m_hostEnd : m_hostEnd + 1);
+ if (i) {
+ bool colonNeeded = m_portEnd == m_hostEnd;
+ int portStart = (colonNeeded ? m_hostEnd : m_hostEnd + 1);
- parse(m_string.left(portStart) + (colonNeeded ? ":" : "") + String::number(i) + m_string.substring(m_portEnd));
+ parse(m_string.left(portStart) + (colonNeeded ? ":" : "") + String::number(i) + m_string.substring(m_portEnd));
+ } else
+ parse(m_string.left(m_hostEnd) + m_string.substring(m_portEnd));
}
void KURL::setHostAndPort(const String& hostAndPort)
@@ -822,7 +831,11 @@ String KURL::prettyURL() const
}
append(result, path());
- append(result, query());
+
+ if (m_pathEnd != m_queryEnd) {
+ result.append('?');
+ append(result, query());
+ }
if (m_fragmentEnd != m_queryEnd) {
result.append('#');
@@ -1047,7 +1060,7 @@ void KURL::parse(const char* url, const String* originalString)
&& matchLetter(url[2], 'l')
&& matchLetter(url[3], 'e');
- bool isHTTPorHTTPS = matchLetter(url[0], 'h')
+ m_protocolInHTTPFamily = matchLetter(url[0], 'h')
&& matchLetter(url[1], 't')
&& matchLetter(url[2], 't')
&& matchLetter(url[3], 'p')
@@ -1129,7 +1142,7 @@ void KURL::parse(const char* url, const String* originalString)
return;
}
- if (userStart == portEnd && !isHTTPorHTTPS && !isFile) {
+ if (userStart == portEnd && !m_protocolInHTTPFamily && !isFile) {
// No authority found, which means that this is not a net_path, but rather an abs_path whose first two
// path segments are empty. For file, http and https only, an empty authority is allowed.
userStart -= 2;
@@ -1253,7 +1266,7 @@ void KURL::parse(const char* url, const String* originalString)
// For canonicalization, ensure we have a '/' for no path.
// Only do this for http and https.
- if (isHTTPorHTTPS && pathEnd - pathStart == 0)
+ if (m_protocolInHTTPFamily && pathEnd - pathStart == 0)
*p++ = '/';
// add path, escaping bad characters
@@ -1291,7 +1304,7 @@ void KURL::parse(const char* url, const String* originalString)
// If we didn't end up actually changing the original string and
// it was already in a String, reuse it to avoid extra allocation.
- if (originalString && strncmp(buffer.data(), url, m_fragmentEnd) == 0)
+ if (originalString && originalString->length() == static_cast<unsigned>(m_fragmentEnd) && strncmp(buffer.data(), url, m_fragmentEnd) == 0)
m_string = *originalString;
else
m_string = String(buffer.data(), m_fragmentEnd);
diff --git a/WebCore/platform/KURL.h b/WebCore/platform/KURL.h
index 7f6b102..46b72c7 100644
--- a/WebCore/platform/KURL.h
+++ b/WebCore/platform/KURL.h
@@ -47,7 +47,7 @@ QT_END_NAMESPACE
#endif
#if USE(GOOGLEURL)
-#include "GoogleURLPrivate.h"
+#include "KURLGooglePrivate.h"
#endif
namespace WebCore {
@@ -84,7 +84,7 @@ public:
// For conversions for other structures that have already parsed and
// canonicalized the URL. The input must be exactly what KURL would have
// done with the same input.
- KURL(const char* canonicalSpec, int canonicalSpecLen,
+ KURL(const CString& canonicalSpec,
const url_parse::Parsed& parsed, bool isValid);
#endif
@@ -119,16 +119,19 @@ public:
String pass() const;
String path() const;
String lastPathComponent() const;
- String query() const; // Includes the "?".
- String ref() const; // Does *not* include the "#".
+ String query() const;
+ String ref() const;
bool hasRef() const;
+ String baseAsString() const;
+
String prettyURL() const;
String fileSystemPath() const;
// Returns true if the current URL's protocol is the same as the null-
// terminated ASCII argument. The argument must be lower-case.
bool protocolIs(const char*) const;
+ bool protocolInHTTPFamily() const;
bool isLocalFile() const;
void setProtocol(const String&);
@@ -203,10 +206,10 @@ private:
bool isHierarchical() const;
static bool protocolIs(const String&, const char*);
#if USE(GOOGLEURL)
- friend class GoogleURLPrivate;
+ friend class KURLGooglePrivate;
void parse(const char* url, const String* originalString); // KURLMac calls this.
void copyToBuffer(Vector<char, 512>& buffer) const; // KURLCFNet uses this.
- GoogleURLPrivate m_url;
+ KURLGooglePrivate m_url;
#else // !USE(GOOGLEURL)
void init(const KURL&, const String&, const TextEncoding&);
void copyToBuffer(Vector<char, 512>& buffer) const;
@@ -218,7 +221,9 @@ private:
void parse(const char* url, const String* originalString);
String m_string;
- bool m_isValid;
+ bool m_isValid : 1;
+ bool m_protocolInHTTPFamily : 1;
+
int m_schemeEnd;
int m_userStart;
int m_userEnd;
@@ -311,6 +316,11 @@ inline bool KURL::isValid() const
return m_isValid;
}
+inline bool KURL::protocolInHTTPFamily() const
+{
+ return m_protocolInHTTPFamily;
+}
+
inline unsigned KURL::hostStart() const
{
return (m_passwordEnd == m_userStart) ? m_passwordEnd : m_passwordEnd + 1;
diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
new file mode 100644
index 0000000..c2e8272
--- /dev/null
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -0,0 +1,944 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(GOOGLEURL)
+#include "KURL.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+#include "CString.h"
+#include "NotImplemented.h"
+#include "TextEncoding.h"
+#include <wtf/Vector.h>
+
+#include <googleurl/src/url_canon_internal.h>
+#include <googleurl/src/url_util.h>
+
+using WTF::isASCIILower;
+using WTF::toASCIILower;
+
+namespace WebCore {
+
+// Wraps WebCore's text encoding in a character set converter for the
+// canonicalizer.
+class KURLCharsetConverter : public url_canon::CharsetConverter {
+public:
+ // The encoding parameter may be NULL, but in this case the object must not
+ // be called.
+ KURLCharsetConverter(const TextEncoding* encoding)
+ : m_encoding(encoding)
+ {
+ }
+
+ virtual void ConvertFromUTF16(const url_parse::UTF16Char* input, int inputLength,
+ url_canon::CanonOutput* output)
+ {
+ CString encoded = m_encoding->encode(input, inputLength, URLEncodedEntitiesForUnencodables);
+ output->Append(encoded.data(), static_cast<int>(encoded.length()));
+ }
+
+private:
+ const TextEncoding* m_encoding;
+};
+
+// Note that this function must be named differently than the one in KURL.cpp
+// since our unit tests evilly include both files, and their local definition
+// will be ambiguous.
+static inline void assertProtocolIsGood(const char* protocol)
+{
+#ifndef NDEBUG
+ const char* p = protocol;
+ while (*p) {
+ ASSERT(*p > ' ' && *p < 0x7F && !(*p >= 'A' && *p <= 'Z'));
+ ++p;
+ }
+#endif
+}
+
+// Returns the characters for the given string, or a pointer to a static empty
+// string if the input string is NULL. This will always ensure we have a non-
+// NULL character pointer since ReplaceComponents has special meaning for NULL.
+static inline const url_parse::UTF16Char* CharactersOrEmpty(const String& str)
+{
+ static const url_parse::UTF16Char zero = 0;
+ return str.characters() ?
+ reinterpret_cast<const url_parse::UTF16Char*>(str.characters()) :
+ &zero;
+}
+
+static inline bool isUnicodeEncoding(const TextEncoding* encoding)
+{
+ return encoding->encodingForFormSubmission() == UTF8Encoding();
+}
+
+static bool lowerCaseEqualsASCII(const char* begin, const char* end, const char* str)
+{
+ while (begin != end && *str) {
+ ASSERT(isASCIILower(*str));
+ if (toASCIILower(*begin++) != *str++)
+ return false;
+ }
+
+ // Both strings are equal (ignoring case) if and only if all of the characters were equal,
+ // and the end of both has been reached.
+ return begin == end && !*str;
+}
+
+
+// KURLGooglePrivate -----------------------------------------------------------
+
+KURLGooglePrivate::KURLGooglePrivate()
+ : m_isValid(false)
+ , m_protocolInHTTPFamily(false)
+ , m_utf8IsASCII(true)
+ , m_stringIsValid(false)
+{
+}
+
+KURLGooglePrivate::KURLGooglePrivate(const url_parse::Parsed& parsed, bool isValid)
+ : m_isValid(isValid)
+ , m_protocolInHTTPFamily(false)
+ , m_parsed(parsed)
+ , m_utf8IsASCII(true)
+ , m_stringIsValid(false)
+{
+}
+
+// Setters for the data. Using the ASCII version when you know the
+// data is ASCII will be slightly more efficient. The UTF-8 version
+// will always be correct if the caller is unsure.
+void KURLGooglePrivate::setUtf8(const CString& str)
+{
+ const char* data = str.data();
+ unsigned dataLength = str.length();
+
+ // The m_utf8IsASCII must always be correct since the DeprecatedString
+ // getter must create it with the proper constructor. This test can be
+ // removed when DeprecatedString is gone, but it still might be a
+ // performance win.
+ m_utf8IsASCII = true;
+ for (unsigned i = 0; i < dataLength; i++) {
+ if (static_cast<unsigned char>(data[i]) >= 0x80) {
+ m_utf8IsASCII = false;
+ break;
+ }
+ }
+
+ m_utf8 = str;
+ m_stringIsValid = false;
+ initProtocolInHTTPFamily();
+}
+
+void KURLGooglePrivate::setAscii(const CString& str)
+{
+ m_utf8 = str;
+ m_utf8IsASCII = true;
+ m_stringIsValid = false;
+ initProtocolInHTTPFamily();
+}
+
+void KURLGooglePrivate::init(const KURL& base,
+ const String& relative,
+ const TextEncoding* queryEncoding)
+{
+ init(base, relative.characters(), relative.length(), queryEncoding);
+}
+
+// Note: code mostly duplicated below.
+void KURLGooglePrivate::init(const KURL& base, const char* rel, int relLength,
+ const TextEncoding* queryEncoding)
+{
+ // As a performance optimization, we do not use the charset converter if
+ // encoding is UTF-8 or other Unicode encodings. Note that this is
+ // per HTML5 2.5.3 (resolving URL). The URL canonicalizer will be
+ // more efficient with no charset converter object because it
+ // can do UTF-8 internally with no extra copies.
+
+ // We feel free to make the charset converter object every time since it's
+ // just a wrapper around a reference.
+ KURLCharsetConverter charsetConverterObject(queryEncoding);
+ KURLCharsetConverter* charsetConverter =
+ (!queryEncoding || isUnicodeEncoding(queryEncoding)) ? 0 :
+ &charsetConverterObject;
+
+ url_canon::RawCanonOutputT<char> output;
+ const CString& baseStr = base.m_url.utf8String();
+ m_isValid = url_util::ResolveRelative(baseStr.data(), baseStr.length(),
+ base.m_url.m_parsed, rel, relLength,
+ charsetConverter,
+ &output, &m_parsed);
+
+ // See FIXME in KURLGooglePrivate in the header. If canonicalization has not
+ // changed the string, we can avoid an extra allocation by using assignment.
+ //
+ // When KURL encounters an error such that the URL is invalid and empty
+ // (for example, resolving a relative URL on a non-hierarchical base), it
+ // will produce an isNull URL, and calling setUtf8 will produce an empty
+ // non-null URL. This is unlikely to affect anything, but we preserve this
+ // just in case.
+ if (m_isValid || output.length()) {
+ // Without ref, the whole url is guaranteed to be ASCII-only.
+ if (m_parsed.ref.is_nonempty())
+ setUtf8(CString(output.data(), output.length()));
+ else
+ setAscii(CString(output.data(), output.length()));
+ } else {
+ // WebCore expects resolved URLs to be empty rather than NULL.
+ setUtf8(CString("", 0));
+ }
+}
+
+// Note: code mostly duplicated above. See FIXMEs and comments there.
+void KURLGooglePrivate::init(const KURL& base, const UChar* rel, int relLength,
+ const TextEncoding* queryEncoding)
+{
+ KURLCharsetConverter charsetConverterObject(queryEncoding);
+ KURLCharsetConverter* charsetConverter =
+ (!queryEncoding || isUnicodeEncoding(queryEncoding)) ? 0 :
+ &charsetConverterObject;
+
+ url_canon::RawCanonOutputT<char> output;
+ const CString& baseStr = base.m_url.utf8String();
+ m_isValid = url_util::ResolveRelative(baseStr.data(), baseStr.length(),
+ base.m_url.m_parsed, rel, relLength,
+ charsetConverter,
+ &output, &m_parsed);
+
+ if (m_isValid || output.length()) {
+ if (m_parsed.ref.is_nonempty())
+ setUtf8(CString(output.data(), output.length()));
+ else
+ setAscii(CString(output.data(), output.length()));
+ } else
+ setUtf8(CString("", 0));
+}
+
+void KURLGooglePrivate::initProtocolInHTTPFamily()
+{
+ if (!m_isValid) {
+ m_protocolInHTTPFamily = false;
+ return;
+ }
+
+ const char* scheme = m_utf8.data() + m_parsed.scheme.begin;
+ if (m_parsed.scheme.len == 4)
+ m_protocolInHTTPFamily = lowerCaseEqualsASCII(scheme, scheme + 4, "http");
+ else if (m_parsed.scheme.len == 5)
+ m_protocolInHTTPFamily = lowerCaseEqualsASCII(scheme, scheme + 5, "https");
+ else
+ m_protocolInHTTPFamily = false;
+}
+
+void KURLGooglePrivate::copyTo(KURLGooglePrivate* dest) const
+{
+ dest->m_isValid = m_isValid;
+ dest->m_protocolInHTTPFamily = m_protocolInHTTPFamily;
+ dest->m_parsed = m_parsed;
+
+ // Don't copy the 16-bit string since that will be regenerated as needed.
+ dest->m_utf8 = CString(m_utf8.data(), m_utf8.length());
+ dest->m_utf8IsASCII = m_utf8IsASCII;
+ dest->m_stringIsValid = false;
+}
+
+String KURLGooglePrivate::componentString(const url_parse::Component& comp) const
+{
+ if (!m_isValid || comp.len <= 0) {
+ // KURL returns a NULL string if the URL is itself a NULL string, and an
+ // empty string for other nonexistant entities.
+ if (utf8String().isNull())
+ return String();
+ return String("", 0);
+ }
+ // begin and len are in terms of bytes which do not match
+ // if string() is UTF-16 and input contains non-ASCII characters.
+ // However, the only part in urlString that can contain non-ASCII
+ // characters is 'ref' at the end of the string. In that case,
+ // begin will always match the actual value and len (in terms of
+ // byte) will be longer than what's needed by 'mid'. However, mid
+ // truncates len to avoid go past the end of a string so that we can
+ // get away withtout doing anything here.
+ return string().substring(comp.begin, comp.len);
+}
+
+void KURLGooglePrivate::replaceComponents(const Replacements& replacements)
+{
+ url_canon::RawCanonOutputT<char> output;
+ url_parse::Parsed newParsed;
+
+ m_isValid = url_util::ReplaceComponents(utf8String().data(),
+ utf8String().length(), m_parsed, replacements, 0, &output, &newParsed);
+
+ m_parsed = newParsed;
+ if (m_parsed.ref.is_nonempty())
+ setUtf8(CString(output.data(), output.length()));
+ else
+ setAscii(CString(output.data(), output.length()));
+}
+
+const String& KURLGooglePrivate::string() const
+{
+ if (!m_stringIsValid) {
+ // Must special case the NULL case, since constructing the
+ // string like we do below will generate an empty rather than
+ // a NULL string.
+ if (m_utf8.isNull())
+ m_string = String();
+ else if (m_utf8IsASCII)
+ m_string = String(m_utf8.data(), m_utf8.length());
+ else
+ m_string = String::fromUTF8(m_utf8.data(), m_utf8.length());
+ m_stringIsValid = true;
+ }
+ return m_string;
+}
+
+// KURL ------------------------------------------------------------------------
+
+// Creates with NULL-terminated string input representing an absolute URL.
+// WebCore generally calls this only with hardcoded strings, so the input is
+// ASCII. We treat is as UTF-8 just in case.
+KURL::KURL(const char *url)
+{
+ // FIXME The Mac code checks for beginning with a slash and converting to a
+ // file: URL. We will want to add this as well once we can compile on a
+ // system like that.
+ m_url.init(KURL(), url, strlen(url), 0);
+
+ // The one-argument constructors should never generate a NULL string.
+ // This is a funny quirk of KURL.cpp (probably a bug) which we preserve.
+ if (m_url.utf8String().isNull())
+ m_url.setAscii(CString("", 0));
+}
+
+// Initializes with a string representing an absolute URL. No encoding
+// information is specified. This generally happens when a KURL is converted
+// to a string and then converted back. In this case, the URL is already
+// canonical and in proper escaped form so needs no encoding. We treat it was
+// UTF-8 just in case.
+KURL::KURL(const String& url)
+{
+ if (!url.isNull())
+ m_url.init(KURL(), url, 0);
+ else {
+ // WebCore expects us to preserve the nullness of strings when this
+ // constructor is used. In all other cases, it expects a non-null
+ // empty string, which is what init() will create.
+ m_url.m_isValid = false;
+ m_url.m_protocolInHTTPFamily = false;
+ }
+}
+
+// Constructs a new URL given a base URL and a possibly relative input URL.
+// This assumes UTF-8 encoding.
+KURL::KURL(const KURL& base, const String& relative)
+{
+ m_url.init(base, relative, 0);
+}
+
+// Constructs a new URL given a base URL and a possibly relative input URL.
+// Any query portion of the relative URL will be encoded in the given encoding.
+KURL::KURL(const KURL& base,
+ const String& relative,
+ const TextEncoding& encoding)
+{
+ m_url.init(base, relative, &encoding.encodingForFormSubmission());
+}
+
+KURL::KURL(const CString& canonicalSpec,
+ const url_parse::Parsed& parsed, bool isValid)
+ : m_url(parsed, isValid)
+{
+ // We know the reference fragment is the only part that can be UTF-8, so
+ // we know it's ASCII when there is no ref.
+ if (parsed.ref.is_nonempty())
+ m_url.setUtf8(canonicalSpec);
+ else
+ m_url.setAscii(canonicalSpec);
+}
+
+#if PLATFORM(CF)
+KURL::KURL(CFURLRef)
+{
+ notImplemented();
+ invalidate();
+}
+
+CFURLRef KURL::createCFURL() const
+{
+ notImplemented();
+ return 0;
+}
+#endif
+
+KURL KURL::copy() const
+{
+ KURL result = *this;
+ m_url.copyTo(&result.m_url);
+ return result;
+}
+
+bool KURL::isNull() const
+{
+ return m_url.utf8String().isNull();
+}
+
+bool KURL::isEmpty() const
+{
+ return !m_url.utf8String().length();
+}
+
+bool KURL::isValid() const
+{
+ return m_url.m_isValid;
+}
+
+bool KURL::protocolInHTTPFamily() const
+{
+ return m_url.m_protocolInHTTPFamily;
+}
+
+bool KURL::hasPath() const
+{
+ // Note that http://www.google.com/" has a path, the path is "/". This can
+ // return false only for invalid or nonstandard URLs.
+ return m_url.m_parsed.path.len >= 0;
+}
+
+// We handle "parameters" separated by a semicolon, while KURL.cpp does not,
+// which can lead to different results in some cases.
+String KURL::lastPathComponent() const
+{
+ // When the output ends in a slash, WebCore has different expectations than
+ // the GoogleURL library. For "/foo/bar/" the library will return the empty
+ // string, but WebCore wants "bar".
+ url_parse::Component path = m_url.m_parsed.path;
+ if (path.len > 0 && m_url.utf8String().data()[path.end() - 1] == '/')
+ path.len--;
+
+ url_parse::Component file;
+ url_parse::ExtractFileName(m_url.utf8String().data(), path, &file);
+
+ // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns
+ // a null string when the path is empty, which we duplicate here.
+ if (!file.is_nonempty())
+ return String();
+ return m_url.componentString(file);
+}
+
+String KURL::protocol() const
+{
+ return m_url.componentString(m_url.m_parsed.scheme);
+}
+
+String KURL::host() const
+{
+ // Note: KURL.cpp unescapes here.
+ return m_url.componentString(m_url.m_parsed.host);
+}
+
+// Returns 0 when there is no port or it is invalid.
+//
+// We treat URL's with out-of-range port numbers as invalid URLs, and they will
+// be rejected by the canonicalizer. KURL.cpp will allow them in parsing, but
+// return 0 from this port() function, so we mirror that behavior here.
+unsigned short KURL::port() const
+{
+ if (!m_url.m_isValid || m_url.m_parsed.port.len <= 0)
+ return 0;
+ int port = url_parse::ParsePort(m_url.utf8String().data(), m_url.m_parsed.port);
+ if (port == url_parse::PORT_UNSPECIFIED)
+ return 0;
+ return static_cast<unsigned short>(port);
+}
+
+// Returns the empty string if there is no password.
+String KURL::pass() const
+{
+ // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns
+ // a null string when the password is empty, which we duplicate here.
+ if (!m_url.m_parsed.password.is_nonempty())
+ return String();
+
+ // Note: KURL.cpp unescapes here.
+ return m_url.componentString(m_url.m_parsed.password);
+}
+
+// Returns the empty string if there is no username.
+String KURL::user() const
+{
+ // Note: KURL.cpp unescapes here.
+ return m_url.componentString(m_url.m_parsed.username);
+}
+
+String KURL::ref() const
+{
+ // Empty but present refs ("foo.com/bar#") should result in the empty
+ // string, which m_url.componentString will produce. Nonexistant refs should be
+ // the NULL string.
+ if (!m_url.m_parsed.ref.is_valid())
+ return String();
+
+ // Note: KURL.cpp unescapes here.
+ return m_url.componentString(m_url.m_parsed.ref);
+}
+
+bool KURL::hasRef() const
+{
+ // Note: KURL.cpp unescapes here.
+ // FIXME determine if KURL.cpp agrees about an empty ref
+ return m_url.m_parsed.ref.len >= 0;
+}
+
+String KURL::query() const
+{
+ if (m_url.m_parsed.query.len >= 0)
+ return m_url.componentString(m_url.m_parsed.query);
+
+ // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns
+ // an empty string when the query is empty rather than a null (not sure
+ // which is right).
+ return String("", 0);
+}
+
+String KURL::path() const
+{
+ // Note: KURL.cpp unescapes here.
+ return m_url.componentString(m_url.m_parsed.path);
+}
+
+void KURL::setProtocol(const String& protocol)
+{
+ KURLGooglePrivate::Replacements replacements;
+ replacements.SetScheme(CharactersOrEmpty(protocol),
+ url_parse::Component(0, protocol.length()));
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setHost(const String& host)
+{
+ KURLGooglePrivate::Replacements replacements;
+ replacements.SetHost(CharactersOrEmpty(host),
+ url_parse::Component(0, host.length()));
+ m_url.replaceComponents(replacements);
+}
+
+// This function is used only in the JSC build.
+void KURL::setHostAndPort(const String& s)
+{
+ String newhost = s.left(s.find(":"));
+ String newport = s.substring(s.find(":") + 1);
+
+ KURLGooglePrivate::Replacements replacements;
+ // Host can't be removed, so we always set.
+ replacements.SetHost(CharactersOrEmpty(newhost),
+ url_parse::Component(0, newhost.length()));
+
+ if (newport.isEmpty()) // Port may be removed, so we support clearing.
+ replacements.ClearPort();
+ else
+ replacements.SetPort(CharactersOrEmpty(newport), url_parse::Component(0, newport.length()));
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setPort(unsigned short i)
+{
+ KURLGooglePrivate::Replacements replacements;
+ String portStr;
+ if (i) {
+ portStr = String::number(static_cast<int>(i));
+ replacements.SetPort(
+ reinterpret_cast<const url_parse::UTF16Char*>(portStr.characters()),
+ url_parse::Component(0, portStr.length()));
+
+ } else {
+ // Clear any existing port when it is set to 0.
+ replacements.ClearPort();
+ }
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setUser(const String& user)
+{
+ // This function is commonly called to clear the username, which we
+ // normally don't have, so we optimize this case.
+ if (user.isEmpty() && !m_url.m_parsed.username.is_valid())
+ return;
+
+ // The canonicalizer will clear any usernames that are empty, so we
+ // don't have to explicitly call ClearUsername() here.
+ KURLGooglePrivate::Replacements replacements;
+ replacements.SetUsername(CharactersOrEmpty(user),
+ url_parse::Component(0, user.length()));
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setPass(const String& pass)
+{
+ // This function is commonly called to clear the password, which we
+ // normally don't have, so we optimize this case.
+ if (pass.isEmpty() && !m_url.m_parsed.password.is_valid())
+ return;
+
+ // The canonicalizer will clear any passwords that are empty, so we
+ // don't have to explicitly call ClearUsername() here.
+ KURLGooglePrivate::Replacements replacements;
+ replacements.SetPassword(CharactersOrEmpty(pass),
+ url_parse::Component(0, pass.length()));
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setRef(const String& ref)
+{
+ // This function is commonly called to clear the ref, which we
+ // normally don't have, so we optimize this case.
+ if (ref.isNull() && !m_url.m_parsed.ref.is_valid())
+ return;
+
+ KURLGooglePrivate::Replacements replacements;
+ if (ref.isNull())
+ replacements.ClearRef();
+ else
+ replacements.SetRef(CharactersOrEmpty(ref), url_parse::Component(0, ref.length()));
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::removeRef()
+{
+ KURLGooglePrivate::Replacements replacements;
+ replacements.ClearRef();
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setQuery(const String& query)
+{
+ KURLGooglePrivate::Replacements replacements;
+ if (query.isNull()) {
+ // KURL.cpp sets to NULL to clear any query.
+ replacements.ClearQuery();
+ } else if (query.length() > 0 && query[0] == '?') {
+ // WebCore expects the query string to begin with a question mark, but
+ // GoogleURL doesn't. So we trim off the question mark when setting.
+ replacements.SetQuery(CharactersOrEmpty(query),
+ url_parse::Component(1, query.length() - 1));
+ } else {
+ // When set with the empty string or something that doesn't begin with
+ // a question mark, KURL.cpp will add a question mark for you. The only
+ // way this isn't compatible is if you call this function with an empty
+ // string. KURL.cpp will leave a '?' with nothing following it in the
+ // URL, whereas we'll clear it.
+ // FIXME We should eliminate this difference.
+ replacements.SetQuery(CharactersOrEmpty(query),
+ url_parse::Component(0, query.length()));
+ }
+ m_url.replaceComponents(replacements);
+}
+
+void KURL::setPath(const String& path)
+{
+ // Empty paths will be canonicalized to "/", so we don't have to worry
+ // about calling ClearPath().
+ KURLGooglePrivate::Replacements replacements;
+ replacements.SetPath(CharactersOrEmpty(path),
+ url_parse::Component(0, path.length()));
+ m_url.replaceComponents(replacements);
+}
+
+// On Mac, this just seems to return the same URL, but with "/foo/bar" for
+// file: URLs instead of file:///foo/bar. We don't bother with any of this,
+// at least for now.
+String KURL::prettyURL() const
+{
+ if (!m_url.m_isValid)
+ return String();
+ return m_url.string();
+}
+
+// We copied the KURL version here on Sept 12, 2008 while doing a WebKit
+// merge.
+//
+// FIXME Somehow share this with KURL? Like we'd theoretically merge with
+// decodeURLEscapeSequences below?
+String mimeTypeFromDataURL(const String& url)
+{
+ ASSERT(protocolIs(url, "data"));
+ int index = url.find(';');
+ if (index == -1)
+ index = url.find(',');
+ if (index != -1) {
+ int len = index - 5;
+ if (len > 0)
+ return url.substring(5, len);
+ return "text/plain"; // Data URLs with no MIME type are considered text/plain.
+ }
+ return "";
+}
+
+String decodeURLEscapeSequences(const String& str)
+{
+ return decodeURLEscapeSequences(str, UTF8Encoding());
+}
+
+// In KURL.cpp's implementation, this is called by every component getter.
+// It will unescape every character, including NULL. This is scary, and may
+// cause security holes. We never call this function for components, and
+// just return the ASCII versions instead.
+//
+// However, this static function is called directly in some cases. It appears
+// that this only happens for javascript: URLs, so this is essentially the
+// JavaScript URL decoder. It assumes UTF-8 encoding.
+//
+// IE doesn't unescape %00, forcing you to use \x00 in JS strings, so we do
+// the same. This also eliminates NULL-related problems should a consumer
+// incorrectly call this function for non-JavaScript.
+//
+// FIXME These should be merged to the KURL.cpp implementation.
+String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding)
+{
+ // FIXME We can probably use KURL.cpp's version of this function
+ // without modification. However, I'm concerned about
+ // https://bugs.webkit.org/show_bug.cgi?id=20559 so am keeping this old
+ // custom code for now. Using their version will also fix the bug that
+ // we ignore the encoding.
+ //
+ // FIXME b/1350291: This does not get called very often. We just convert
+ // first to 8-bit UTF-8, then unescape, then back to 16-bit. This kind of
+ // sucks, and we don't use the encoding properly, which will make some
+ // obscure anchor navigations fail.
+ CString cstr = str.utf8();
+
+ const char* input = cstr.data();
+ int inputLength = cstr.length();
+ url_canon::RawCanonOutputT<char> unescaped;
+ for (int i = 0; i < inputLength; i++) {
+ if (input[i] == '%') {
+ unsigned char ch;
+ if (url_canon::DecodeEscaped(input, &i, inputLength, &ch)) {
+ if (!ch) {
+ // Never unescape NULLs.
+ unescaped.push_back('%');
+ unescaped.push_back('0');
+ unescaped.push_back('0');
+ } else
+ unescaped.push_back(ch);
+ } else {
+ // Invalid escape sequence, copy the percent literal.
+ unescaped.push_back('%');
+ }
+ } else {
+ // Regular non-escaped 8-bit character.
+ unescaped.push_back(input[i]);
+ }
+ }
+
+ // Convert that 8-bit to UTF-16. It's not clear IE does this at all to
+ // JavaScript URLs, but Firefox and Safari do.
+ url_canon::RawCanonOutputT<url_parse::UTF16Char> utf16;
+ for (int i = 0; i < unescaped.length(); i++) {
+ unsigned char uch = static_cast<unsigned char>(unescaped.at(i));
+ if (uch < 0x80) {
+ // Non-UTF-8, just append directly
+ utf16.push_back(uch);
+ } else {
+ // next_ch will point to the last character of the decoded
+ // character.
+ int nextCharacter = i;
+ unsigned codePoint;
+ if (url_canon::ReadUTFChar(unescaped.data(), &nextCharacter,
+ unescaped.length(), &codePoint)) {
+ // Valid UTF-8 character, convert to UTF-16.
+ url_canon::AppendUTF16Value(codePoint, &utf16);
+ i = nextCharacter;
+ } else {
+ // KURL.cpp strips any sequences that are not valid UTF-8. This
+ // sounds scary. Instead, we just keep those invalid code
+ // points and promote to UTF-16. We copy all characters from
+ // the current position to the end of the identified sqeuqnce.
+ while (i < nextCharacter) {
+ utf16.push_back(static_cast<unsigned char>(unescaped.at(i)));
+ i++;
+ }
+ utf16.push_back(static_cast<unsigned char>(unescaped.at(i)));
+ }
+ }
+ }
+
+ return String(reinterpret_cast<UChar*>(utf16.data()), utf16.length());
+}
+
+bool KURL::protocolIs(const char* protocol) const
+{
+ assertProtocolIsGood(protocol);
+ if (m_url.m_parsed.scheme.len <= 0)
+ return !protocol;
+ return lowerCaseEqualsASCII(
+ m_url.utf8String().data() + m_url.m_parsed.scheme.begin,
+ m_url.utf8String().data() + m_url.m_parsed.scheme.end(),
+ protocol);
+}
+
+bool KURL::isLocalFile() const
+{
+ return protocolIs("file");
+}
+
+// This is called to escape a URL string. It is only used externally when
+// constructing mailto: links to set the query section. Since our query setter
+// will automatically do the correct escaping, this function does not have to
+// do any work.
+//
+// There is a possibility that a future called may use this function in other
+// ways, and may expect to get a valid URL string. The dangerous thing we want
+// to protect against here is accidentally getting NULLs in a string that is
+// not supposed to have NULLs. Therefore, we escape NULLs here to prevent this.
+String encodeWithURLEscapeSequences(const String& notEncodedString)
+{
+ CString utf8 = UTF8Encoding().encode(
+ reinterpret_cast<const UChar*>(notEncodedString.characters()),
+ notEncodedString.length(),
+ URLEncodedEntitiesForUnencodables);
+ const char* input = utf8.data();
+ int inputLength = utf8.length();
+
+ Vector<char, 2048> buffer;
+ for (int i = 0; i < inputLength; i++) {
+ if (!input[i])
+ buffer.append("%00", 3);
+ else
+ buffer.append(input[i]);
+ }
+ return String(buffer.data(), buffer.size());
+}
+
+bool KURL::isHierarchical() const
+{
+ if (!m_url.m_parsed.scheme.is_nonempty())
+ return false;
+ return url_util::IsStandard(
+ &m_url.utf8String().data()[m_url.m_parsed.scheme.begin],
+ m_url.utf8String().length(),
+ m_url.m_parsed.scheme);
+}
+
+#ifndef NDEBUG
+void KURL::print() const
+{
+ printf("%s\n", m_url.utf8String().data());
+}
+#endif
+
+void KURL::invalidate()
+{
+ // This is only called from the constructor so resetting the (automatically
+ // initialized) string and parsed structure would be a waste of time.
+ m_url.m_isValid = false;
+ m_url.m_protocolInHTTPFamily = false;
+}
+
+// Equal up to reference fragments, if any.
+bool equalIgnoringRef(const KURL& a, const KURL& b)
+{
+ // Compute the length of each URL without its ref. Note that the reference
+ // begin (if it exists) points to the character *after* the '#', so we need
+ // to subtract one.
+ int aLength = a.m_url.utf8String().length();
+ if (a.m_url.m_parsed.ref.len >= 0)
+ aLength = a.m_url.m_parsed.ref.begin - 1;
+
+ int bLength = b.m_url.utf8String().length();
+ if (b.m_url.m_parsed.ref.len >= 0)
+ bLength = b.m_url.m_parsed.ref.begin - 1;
+
+ return aLength == bLength
+ && !strncmp(a.m_url.utf8String().data(), b.m_url.utf8String().data(), aLength);
+}
+
+unsigned KURL::hostStart() const
+{
+ return m_url.m_parsed.CountCharactersBefore(url_parse::Parsed::HOST, false);
+}
+
+unsigned KURL::hostEnd() const
+{
+ return m_url.m_parsed.CountCharactersBefore(url_parse::Parsed::PORT, true);
+}
+
+unsigned KURL::pathStart() const
+{
+ return m_url.m_parsed.CountCharactersBefore(url_parse::Parsed::PATH, false);
+}
+
+unsigned KURL::pathEnd() const
+{
+ return m_url.m_parsed.CountCharactersBefore(url_parse::Parsed::QUERY, true);
+}
+
+unsigned KURL::pathAfterLastSlash() const
+{
+ // When there's no path, ask for what would be the beginning of it.
+ if (!m_url.m_parsed.path.is_valid())
+ return m_url.m_parsed.CountCharactersBefore(url_parse::Parsed::PATH, false);
+
+ url_parse::Component filename;
+ url_parse::ExtractFileName(m_url.utf8String().data(), m_url.m_parsed.path,
+ &filename);
+ return filename.begin;
+}
+
+const KURL& blankURL()
+{
+ static KURL staticBlankURL("about:blank");
+ return staticBlankURL;
+}
+
+bool protocolIs(const String& url, const char* protocol)
+{
+ // Do the comparison without making a new string object.
+ assertProtocolIsGood(protocol);
+ for (int i = 0; ; ++i) {
+ if (!protocol[i])
+ return url[i] == ':';
+ if (toASCIILower(url[i]) != protocol[i])
+ return false;
+ }
+}
+
+inline bool KURL::protocolIs(const String& string, const char* protocol)
+{
+ return WebCore::protocolIs(string, protocol);
+}
+
+} // namespace WebCore
+
+#endif // USE(GOOGLEURL)
diff --git a/WebCore/platform/KURLGooglePrivate.h b/WebCore/platform/KURLGooglePrivate.h
new file mode 100644
index 0000000..a70cce5
--- /dev/null
+++ b/WebCore/platform/KURLGooglePrivate.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef KURLGooglePrivate_h
+#define KURLGooglePrivate_h
+
+#include "CString.h"
+
+#include <googleurl/src/url_parse.h>
+#include <googleurl/src/url_canon.h>
+
+namespace WebCore {
+
+ class KURL;
+ class TextEncoding;
+
+ // Wraps the internals related to using Google-URL as the bnackend for KURL.
+ // This maintains the state and has auxiliary functions so that we don't need
+ // to uglify KURL.h while allowing Google-URL to be evaluated.
+ class KURLGooglePrivate {
+ public:
+ KURLGooglePrivate();
+ KURLGooglePrivate(const url_parse::Parsed&, bool isValid);
+
+ // Initializes the object. This will call through to one of the backend
+ // initializers below depending on whether the string's internal
+ // representation is 8 or 16 bit.
+ void init(const KURL& base, const String& relative,
+ const TextEncoding* queryEncoding);
+
+ // Backend initializers. The query encoding parameters are optional and can
+ // be NULL (this implies UTF-8). These initializers require that the object
+ // has just been created and the strings are NULL. Do not call on an
+ // already-constructed object.
+ void init(const KURL& base, const char* rel, int relLength,
+ const TextEncoding* queryEncoding);
+ void init(const KURL& base, const UChar* rel, int relLength,
+ const TextEncoding* queryEncoding);
+
+ // Does a deep copy to the given output object.
+ void copyTo(KURLGooglePrivate* dest) const;
+
+ // Returns the substring of the input identified by the given component.
+ String componentString(const url_parse::Component&) const;
+
+ // Replaces the given components, modifying the current URL. The current
+ // URL must be valid.
+ typedef url_canon::Replacements<url_parse::UTF16Char> Replacements;
+ void replaceComponents(const Replacements&);
+
+ // Setters for the data. Using the ASCII version when you know the
+ // data is ASCII will be slightly more efficient. The UTF-8 version
+ // will always be correct if the caller is unsure.
+ void setUtf8(const CString&);
+ void setAscii(const CString&);
+
+ // TODO(brettw) we can support an additional optimization. Make this
+ // buffer support both optinal Strings and UTF-8 data. This way, we can use
+ // the optimization from the original KURL which uses = with the original
+ // string when canonicalization did not change it. This allows the strings
+ // to share a buffer internally, and saves a malloc.
+
+ // Getters for the data.
+ const CString& utf8String() const { return m_utf8; }
+ const String& string() const;
+
+ bool m_isValid;
+ bool m_protocolInHTTPFamily;
+ url_parse::Parsed m_parsed; // Indexes into the UTF-8 version of the string.
+
+ private:
+ void initProtocolInHTTPFamily();
+
+ CString m_utf8;
+
+ // Set to true when the caller set us using the ASCII setter. We can
+ // be more efficient when we know there is no UTF-8 to worry about.
+ // This flag is currently always correct, but should be changed to be a
+ // hint (see setUtf8).
+ bool m_utf8IsASCII;
+
+ mutable bool m_stringIsValid;
+ mutable String m_string;
+ };
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/MIMETypeRegistry.h b/WebCore/platform/MIMETypeRegistry.h
index be741a4..fca467f 100644
--- a/WebCore/platform/MIMETypeRegistry.h
+++ b/WebCore/platform/MIMETypeRegistry.h
@@ -38,6 +38,7 @@ public:
static String getMIMETypeForExtension(const String& ext);
static Vector<String> getExtensionsForMIMEType(const String& type);
static String getPreferredExtensionForMIMEType(const String& type);
+
static String getMIMETypeForPath(const String& path);
// Check to see if a mime type is suitable for being loaded inline as an
diff --git a/WebCore/platform/PlatformWheelEvent.h b/WebCore/platform/PlatformWheelEvent.h
index fc954ed..9395e93 100644
--- a/WebCore/platform/PlatformWheelEvent.h
+++ b/WebCore/platform/PlatformWheelEvent.h
@@ -59,23 +59,13 @@ class wxPoint;
namespace WebCore {
- // Wheel events come in three flavors:
- // The ScrollByPixelWheelEvent is a fine-grained event that specifies the precise number of pixels to scroll. It is sent by MacBook touchpads on OS X.
- // For ScrollByPixelWheelEvents, the delta values contain the precise number of pixels to scroll.
- // The ScrollByLineWheelEvent (the normal wheel event) sends a delta that can be corrected by a line multiplier to determine how many lines to scroll.
- // If the platform has configurable line sensitivity (Windows), then the number of lines to scroll is used in order to behave like the platform.
- // If the platform does not have configurable line sensitivity, then WebCore's default behavior is used (which scrolls 3 * the wheel line delta).
- // For ScrollByLineWheelEvents, the delta values represent the number of lines to scroll.
- // The ScrollByPageWheelEvent indicates that the wheel event should scroll an entire page instead. In this case WebCore's built in paging behavior is used to page
+ // Wheel events come in two flavors:
+ // The ScrollByPixelWheelEvent is a fine-grained event that specifies the precise number of pixels to scroll. It is sent directly by MacBook touchpads on OS X,
+ // and synthesized in other cases where platforms generate line-by-line scrolling events.
+ // The ScrollByPageWheelEvent indicates that the wheel event should scroll an entire page. In this case WebCore's built in paging behavior is used to page
// up and down (you get the same behavior as if the user was clicking in a scrollbar track to page up or page down). Page scrolling only works in the vertical direction.
- enum PlatformWheelEventGranularity { ScrollByLineWheelEvent, ScrollByPageWheelEvent, ScrollByPixelWheelEvent };
+ enum PlatformWheelEventGranularity { ScrollByPageWheelEvent, ScrollByPixelWheelEvent };
- // WebCore uses a line multiple of ~3 (40px per line step) when doing arrowing with a scrollbar or line stepping via the arrow keys. The delta for wheeling is expressed
- // as a # of actual lines (40 / 3 = 1 wheel line). We use the horizontalLineMultiplier and verticalLineMultiplier methods to incorporate the line multiplier into the deltas. On
- // platforms that do not support wheel sensitivity, we use this hardcoded constant value of 3 to ensure that wheeling by default matches the WebCore multiplier you
- // get when doing other kinds of line stepping.
- const int cLineMultiplier = 3;
-
class PlatformWheelEvent {
public:
const IntPoint& pos() const { return m_position; } // PlatformWindow coordinates.
@@ -84,6 +74,9 @@ namespace WebCore {
float deltaX() const { return m_deltaX; }
float deltaY() const { return m_deltaY; }
+ float wheelTicksX() const { return m_wheelTicksX; }
+ float wheelTicksY() const { return m_wheelTicksY; }
+
PlatformWheelEventGranularity granularity() const { return m_granularity; }
bool isAccepted() const { return m_isAccepted; }
@@ -104,7 +97,7 @@ namespace WebCore {
PlatformWheelEvent(NSEvent*);
#endif
#if PLATFORM(WIN)
- PlatformWheelEvent(HWND, WPARAM, LPARAM, bool isHorizontal);
+ PlatformWheelEvent(HWND, WPARAM, LPARAM, bool isMouseHWheel);
#endif
#if PLATFORM(GTK)
PlatformWheelEvent(GdkEventScroll*);
@@ -117,18 +110,12 @@ namespace WebCore {
#endif
protected:
-#if !PLATFORM(WIN)
- int horizontalLineMultiplier() const { return cLineMultiplier; }
- int verticalLineMultiplier() const { return cLineMultiplier; }
-#else
- int horizontalLineMultiplier() const;
- int verticalLineMultiplier() const;
-#endif
-
IntPoint m_position;
IntPoint m_globalPosition;
float m_deltaX;
float m_deltaY;
+ float m_wheelTicksX;
+ float m_wheelTicksY;
PlatformWheelEventGranularity m_granularity;
bool m_isAccepted;
bool m_shiftKey;
diff --git a/WebCore/platform/PopupMenuStyle.h b/WebCore/platform/PopupMenuStyle.h
index 89a7a74..5325ff3 100644
--- a/WebCore/platform/PopupMenuStyle.h
+++ b/WebCore/platform/PopupMenuStyle.h
@@ -28,16 +28,20 @@
#include "Color.h"
#include "Font.h"
+#include "Length.h"
+#include "TextDirection.h"
namespace WebCore {
class PopupMenuStyle {
public:
- PopupMenuStyle(const Color& foreground, const Color& background, const Font& font, bool visible)
+ PopupMenuStyle(const Color& foreground, const Color& background, const Font& font, bool visible, Length textIndent, TextDirection textDirection)
: m_foregroundColor(foreground)
, m_backgroundColor(background)
, m_font(font)
, m_visible(visible)
+ , m_textIndent(textIndent)
+ , m_textDirection(textDirection)
{
}
@@ -45,12 +49,16 @@ public:
const Color& backgroundColor() const { return m_backgroundColor; }
const Font& font() const { return m_font; }
bool isVisible() const { return m_visible; }
+ Length textIndent() const { return m_textIndent; }
+ TextDirection textDirection() const { return m_textDirection; }
private:
Color m_foregroundColor;
Color m_backgroundColor;
Font m_font;
bool m_visible;
+ Length m_textIndent;
+ TextDirection m_textDirection;
};
} // namespace WebCore
diff --git a/WebCore/storage/SQLStatementErrorCallback.idl b/WebCore/platform/RunLoopTimer.h
index 9fae8bf..96eb8d8 100644
--- a/WebCore/storage/SQLStatementErrorCallback.idl
+++ b/WebCore/platform/RunLoopTimer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,10 +26,54 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-module storage {
+#ifndef RunLoopTimer_h
+#define RunLoopTimer_h
- interface SQLStatementErrorCallback {
- boolean handleEvent(in SQLTransaction transaction, in SQLError error);
- };
+#include "SchedulePair.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
-}
+namespace WebCore {
+
+// Time intervals are all in seconds.
+
+class RunLoopTimerBase : Noncopyable {
+public:
+ virtual ~RunLoopTimerBase();
+
+ void schedule(const SchedulePair*);
+ void schedule(const SchedulePairHashSet&);
+
+ void start(double nextFireInterval, double repeatInterval);
+
+ void startRepeating(double repeatInterval) { start(repeatInterval, repeatInterval); }
+ void startOneShot(double interval) { start(interval, 0); }
+
+ void stop();
+ bool isActive() const;
+
+ virtual void fired() = 0;
+
+private:
+#if PLATFORM(CF)
+ RetainPtr<CFRunLoopTimerRef> m_timer;
+#endif
+};
+
+template <typename TimerFiredClass> class RunLoopTimer : public RunLoopTimerBase {
+public:
+ typedef void (TimerFiredClass::*TimerFiredFunction)(RunLoopTimer*);
+
+ RunLoopTimer(TimerFiredClass* o, TimerFiredFunction f)
+ : m_object(o), m_function(f) { }
+
+ virtual void fired() { (m_object->*m_function)(this); }
+
+private:
+ TimerFiredClass* m_object;
+ TimerFiredFunction m_function;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 573dabe..5a12304 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -441,6 +441,9 @@ const int panIconSizeLength = 20;
void ScrollView::scrollContents(const IntSize& scrollDelta)
{
+ if (!hostWindow())
+ return;
+
// Since scrolling is double buffered, we will be blitting the scroll view's intersection
// with the clip rect every time to keep it smooth.
IntRect clipRect = windowClipRect();
@@ -531,8 +534,8 @@ void ScrollView::adjustScrollbarsAvoidingResizerCount(int overlapDelta)
// If we went from n to 0 or from 0 to n and we're the outermost view,
// we need to invalidate the windowResizerRect(), since it will now need to paint
// differently.
- if (oldCount > 0 && m_scrollbarsAvoidingResizer == 0 ||
- oldCount == 0 && m_scrollbarsAvoidingResizer > 0)
+ if ((oldCount > 0 && m_scrollbarsAvoidingResizer == 0) ||
+ (oldCount == 0 && m_scrollbarsAvoidingResizer > 0))
invalidateRect(windowResizerRect());
}
}
@@ -615,10 +618,7 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
e.accept();
float deltaX = e.deltaX();
float deltaY = e.deltaY();
- if (e.granularity() == ScrollByLineWheelEvent) {
- deltaX *= cMouseWheelPixelsPerLineStep;
- deltaY *= cMouseWheelPixelsPerLineStep;
- } else if (e.granularity() == ScrollByPageWheelEvent) {
+ if (e.granularity() == ScrollByPageWheelEvent) {
ASSERT(deltaX == 0);
bool negative = deltaY < 0;
deltaY = max(0, visibleHeight() - cAmountToKeepWhenPaging);
diff --git a/WebCore/platform/Scrollbar.h b/WebCore/platform/Scrollbar.h
index 9238a77..2c5b274 100644
--- a/WebCore/platform/Scrollbar.h
+++ b/WebCore/platform/Scrollbar.h
@@ -42,8 +42,7 @@ class ScrollbarTheme;
class PlatformMouseEvent;
// These match the numbers we use over in WebKit (WebFrameView.m).
-const int cScrollbarPixelsPerLineStep = 40;
-const float cMouseWheelPixelsPerLineStep = 40.0f / 3.0f;
+const int cScrollbarPixelsPerLineStep = 40;
const int cAmountToKeepWhenPaging = 40;
class Scrollbar : public Widget, public RefCounted<Scrollbar> {
diff --git a/WebCore/platform/SharedTimer.h b/WebCore/platform/SharedTimer.h
index 4cc90a2..a005add 100644
--- a/WebCore/platform/SharedTimer.h
+++ b/WebCore/platform/SharedTimer.h
@@ -28,17 +28,46 @@
namespace WebCore {
- // Single timer, shared to implement all the timers managed by the Timer class.
+ // Each thread has its own single instance of shared timer, which implements this interface.
+ // This instance is shared by all timers in the thread.
// Not intended to be used directly; use the Timer class instead.
+ class SharedTimer {
+ public:
+ virtual ~SharedTimer() {}
+ virtual void setFiredFunction(void (*)()) = 0;
- void setSharedTimerFiredFunction(void (*)());
+ // The fire time is relative to the classic POSIX epoch of January 1, 1970,
+ // as the result of currentTime() is.
+ virtual void setFireTime(double) = 0;
+ virtual void stop() = 0;
+ };
- // The fire time is relative to the classic POSIX epoch of January 1, 1970,
- // as the result of currentTime() is.
- void setSharedTimerFireTime(double fireTime);
+ // Implemented by port (since it provides the run loop for the main thread).
+ // FIXME: make ports implement MainThreadSharedTimer directly instead.
+ void setSharedTimerFiredFunction(void (*)());
+ void setSharedTimerFireTime(double);
void stopSharedTimer();
-}
+ // Implementation of SharedTimer for the main thread.
+ class MainThreadSharedTimer : public SharedTimer {
+ public:
+ virtual void setFiredFunction(void (*function)())
+ {
+ setSharedTimerFiredFunction(function);
+ }
+
+ virtual void setFireTime(double fireTime)
+ {
+ setSharedTimerFireTime(fireTime);
+ }
+
+ virtual void stop()
+ {
+ stopSharedTimer();
+ }
+ };
+
+} // namespace WebCore
-#endif
+#endif // SharedTimer_h
diff --git a/WebCore/platform/ThreadCheck.h b/WebCore/platform/ThreadCheck.h
index d1ff4a4..07eb463 100644
--- a/WebCore/platform/ThreadCheck.h
+++ b/WebCore/platform/ThreadCheck.h
@@ -33,12 +33,18 @@ namespace WebCore {
LogOnThreadViolation,
RaiseExceptionOnThreadViolation
};
- void setDefaultThreadViolationBehavior(ThreadViolationBehavior);
- void reportThreadViolation(const char* function);
+ enum ThreadViolationRound {
+ ThreadViolationRoundOne = 0,
+ ThreadViolationRoundTwo,
+ MaximumThreadViolationRound
+ };
+ void setDefaultThreadViolationBehavior(ThreadViolationBehavior, ThreadViolationRound);
+ void reportThreadViolation(const char* function, ThreadViolationRound);
}
-extern "C" void WebCoreReportThreadViolation(const char* function);
+extern "C" void WebCoreReportThreadViolation(const char* function, WebCore::ThreadViolationRound);
-#define WebCoreThreadViolationCheck() ::WebCore::reportThreadViolation(WTF_PRETTY_FUNCTION)
+#define WebCoreThreadViolationCheckRoundOne() ::WebCore::reportThreadViolation(WTF_PRETTY_FUNCTION, WebCore::ThreadViolationRoundOne)
+#define WebCoreThreadViolationCheckRoundTwo() ::WebCore::reportThreadViolation(WTF_PRETTY_FUNCTION, WebCore::ThreadViolationRoundTwo)
#endif
diff --git a/WebCore/platform/ThreadGlobalData.cpp b/WebCore/platform/ThreadGlobalData.cpp
index 9bf0bf2..903af66 100644
--- a/WebCore/platform/ThreadGlobalData.cpp
+++ b/WebCore/platform/ThreadGlobalData.cpp
@@ -29,6 +29,7 @@
#include "EventNames.h"
#include "StringImpl.h"
+#include "ThreadTimers.h"
#include <wtf/UnusedParam.h>
#if USE(ICU_UNICODE)
@@ -70,6 +71,7 @@ ThreadGlobalData::ThreadGlobalData()
: m_emptyString(new StringImpl)
, m_atomicStringTable(new HashSet<StringImpl*>)
, m_eventNames(new EventNames)
+ , m_threadTimers(new ThreadTimers)
#if USE(ICU_UNICODE)
, m_cachedConverterICU(new ICUConverterWrapper)
#endif
@@ -90,6 +92,7 @@ ThreadGlobalData::~ThreadGlobalData()
delete m_eventNames;
delete m_atomicStringTable;
+ delete m_threadTimers;
ASSERT(isMainThread() || m_emptyString->hasOneRef()); // We intentionally don't clean up static data on application quit, so there will be many strings remaining on the main thread.
delete m_emptyString;
diff --git a/WebCore/platform/ThreadGlobalData.h b/WebCore/platform/ThreadGlobalData.h
index 17637aa..7faca36 100644
--- a/WebCore/platform/ThreadGlobalData.h
+++ b/WebCore/platform/ThreadGlobalData.h
@@ -36,6 +36,7 @@ namespace WebCore {
class EventNames;
struct ICUConverterWrapper;
struct TECConverterWrapper;
+ class ThreadTimers;
class ThreadGlobalData : Noncopyable {
public:
@@ -45,6 +46,7 @@ namespace WebCore {
EventNames& eventNames() { return *m_eventNames; }
StringImpl* emptyString() { return m_emptyString; }
HashSet<StringImpl*>& atomicStringTable() { return *m_atomicStringTable; }
+ ThreadTimers& threadTimers() { return *m_threadTimers; }
#if USE(ICU_UNICODE)
ICUConverterWrapper& cachedConverterICU() { return *m_cachedConverterICU; }
@@ -58,6 +60,7 @@ namespace WebCore {
StringImpl* m_emptyString;
HashSet<StringImpl*>* m_atomicStringTable;
EventNames* m_eventNames;
+ ThreadTimers* m_threadTimers;
#if USE(ICU_UNICODE)
ICUConverterWrapper* m_cachedConverterICU;
diff --git a/WebCore/platform/ThreadTimers.cpp b/WebCore/platform/ThreadTimers.cpp
new file mode 100644
index 0000000..71a06b0
--- /dev/null
+++ b/WebCore/platform/ThreadTimers.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ThreadTimers.h"
+
+#include "SharedTimer.h"
+#include "ThreadGlobalData.h"
+#include "Timer.h"
+#include <wtf/CurrentTime.h>
+
+namespace WebCore {
+
+// Timers are created, started and fired on the same thread, and each thread has its own ThreadTimers
+// copy to keep the heap and a set of currently firing timers.
+
+static MainThreadSharedTimer* mainThreadSharedTimer()
+{
+ static MainThreadSharedTimer* timer = new MainThreadSharedTimer;
+ return timer;
+}
+
+ThreadTimers::ThreadTimers()
+ : m_sharedTimer(0)
+ , m_firingTimers(false)
+{
+ if (isMainThread())
+ setSharedTimer(mainThreadSharedTimer());
+}
+
+// A worker thread may initialize SharedTimer after some timers are created.
+// Also, SharedTimer can be replaced with 0 before all timers are destroyed.
+void ThreadTimers::setSharedTimer(SharedTimer* sharedTimer)
+{
+ if (m_sharedTimer) {
+ m_sharedTimer->setFiredFunction(0);
+ m_sharedTimer->stop();
+ }
+
+ m_sharedTimer = sharedTimer;
+
+ if (sharedTimer) {
+ m_sharedTimer->setFiredFunction(ThreadTimers::sharedTimerFired);
+ updateSharedTimer();
+ }
+}
+
+void ThreadTimers::updateSharedTimer()
+{
+ if (!m_sharedTimer)
+ return;
+
+ if (m_firingTimers || m_timerHeap.isEmpty())
+ m_sharedTimer->stop();
+ else
+ m_sharedTimer->setFireTime(m_timerHeap.first()->m_nextFireTime);
+}
+
+
+void ThreadTimers::collectFiringTimers(double fireTime, Vector<TimerBase*>& firingTimers)
+{
+ while (!m_timerHeap.isEmpty() && m_timerHeap.first()->m_nextFireTime <= fireTime) {
+ TimerBase* timer = m_timerHeap.first();
+ firingTimers.append(timer);
+ m_timersReadyToFire.add(timer);
+ timer->m_nextFireTime = 0;
+ timer->heapDeleteMin();
+ }
+}
+
+void ThreadTimers::fireTimers(double fireTime, const Vector<TimerBase*>& firingTimers)
+{
+ size_t size = firingTimers.size();
+ for (size_t i = 0; i != size; ++i) {
+ TimerBase* timer = firingTimers[i];
+
+ // If not in the set, this timer has been deleted or re-scheduled in another timer's fired function.
+ // So either we don't want to fire it at all or we will fire it next time the shared timer goes off.
+ // It might even have been deleted; that's OK because we won't do anything else with the pointer.
+ if (!m_timersReadyToFire.contains(timer))
+ continue;
+
+ // Setting the next fire time has a side effect of removing the timer from the firing timers set.
+ double interval = timer->repeatInterval();
+ timer->setNextFireTime(interval ? fireTime + interval : 0);
+
+ // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
+ timer->fired();
+
+ // Catch the case where the timer asked timers to fire in a nested event loop.
+ if (!m_firingTimers)
+ break;
+ }
+}
+
+void ThreadTimers::sharedTimerFired()
+{
+ // Redirect to non-static method.
+ threadGlobalData().threadTimers().sharedTimerFiredInternal();
+}
+
+void ThreadTimers::sharedTimerFiredInternal()
+{
+ // Do a re-entrancy check.
+ if (m_firingTimers)
+ return;
+ m_firingTimers = true;
+
+ double fireTime = currentTime();
+ Vector<TimerBase*> firingTimers;
+
+ // m_timersReadyToFire will initially contain the same set as firingTimers, but
+ // as timers fire some mat become re-scheduled or deleted. They get removed from
+ // m_timersReadyToFire so we can avoid firing them.
+ ASSERT(m_timersReadyToFire.isEmpty());
+
+ collectFiringTimers(fireTime, firingTimers);
+ fireTimers(fireTime, firingTimers);
+
+ m_timersReadyToFire.clear();
+ m_firingTimers = false;
+
+ updateSharedTimer();
+}
+
+void ThreadTimers::fireTimersInNestedEventLoop()
+{
+ // Reset the reentrancy guard so the timers can fire again.
+ m_firingTimers = false;
+ m_timersReadyToFire.clear();
+ updateSharedTimer();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/ThreadTimers.h b/WebCore/platform/ThreadTimers.h
new file mode 100644
index 0000000..366c320
--- /dev/null
+++ b/WebCore/platform/ThreadTimers.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ThreadTimer_h
+#define ThreadTimer_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class SharedTimer;
+ class TimerBase;
+
+ // A collection of timers per thread. Kept in ThreadGlobalData.
+ class ThreadTimers : Noncopyable {
+ public:
+ ThreadTimers();
+
+ // On a thread different then main, we should set the thread's instance of the SharedTimer.
+ void setSharedTimer(SharedTimer*);
+
+ Vector<TimerBase*>& timerHeap() { return m_timerHeap; }
+ HashSet<const TimerBase*>& timersReadyToFire() { return m_timersReadyToFire; }
+
+ void updateSharedTimer();
+ void fireTimersInNestedEventLoop();
+
+ private:
+ static void sharedTimerFired();
+
+ void fireTimers(double fireTime, const Vector<TimerBase*>&);
+ void collectFiringTimers(double fireTime, Vector<TimerBase*>&);
+ void sharedTimerFiredInternal();
+ void fireTimersInNestedEventLoopInternal();
+
+ Vector<TimerBase*> m_timerHeap;
+ HashSet<const TimerBase*> m_timersReadyToFire; // Temporarily holds a pointer to a stack object. No ownership.
+ SharedTimer* m_sharedTimer; // External object, can be a run loop on a worker thread. Normally set/reset by worker thread.
+ bool m_firingTimers; // Reentrancy guard.
+ };
+
+}
+
+#endif
diff --git a/WebCore/platform/Timer.cpp b/WebCore/platform/Timer.cpp
index a8fcbb8..353a2a7 100644
--- a/WebCore/platform/Timer.cpp
+++ b/WebCore/platform/Timer.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +28,8 @@
#include "Timer.h"
#include "SharedTimer.h"
+#include "ThreadGlobalData.h"
+#include "ThreadTimers.h"
#include <limits.h>
#include <limits>
#include <math.h>
@@ -44,22 +47,28 @@ namespace WebCore {
//
// When a timer's "next fire time" changes, we need to move it around in the priority queue.
-// ----------------
-
-#ifdef ANDROID_FIX // it is removed in http://trac.webkit.org/changeset/40080, but Android needs it
-static bool deferringTimers;
-#endif
-static Vector<TimerBase*>* timerHeap;
-static HashSet<const TimerBase*>* timersReadyToFire;
+// Simple accessors to thread-specific data.
+static Vector<TimerBase*>& timerHeap()
+{
+ return threadGlobalData().threadTimers().timerHeap();
+}
-// ----------------
+static HashSet<const TimerBase*>& timersReadyToFire()
+{
+ return threadGlobalData().threadTimers().timersReadyToFire();
+}
// Class to represent elements in the heap when calling the standard library heap algorithms.
// Maintains the m_heapIndex value in the timers themselves, which allows us to do efficient
// modification of the heap.
class TimerHeapElement {
public:
- explicit TimerHeapElement(int i) : m_index(i), m_timer((*timerHeap)[m_index]) { checkConsistency(); }
+ explicit TimerHeapElement(int i)
+ : m_index(i)
+ , m_timer(timerHeap()[m_index])
+ {
+ checkConsistency();
+ }
TimerHeapElement(const TimerHeapElement&);
TimerHeapElement& operator=(const TimerHeapElement&);
@@ -69,7 +78,7 @@ public:
void checkConsistency() const
{
ASSERT(m_index >= 0);
- ASSERT(m_index < (timerHeap ? static_cast<int>(timerHeap->size()) : 0));
+ ASSERT(m_index < static_cast<int>(timerHeap().size()));
}
private:
@@ -90,7 +99,7 @@ inline TimerHeapElement& TimerHeapElement::operator=(const TimerHeapElement& o)
m_timer = t;
if (m_index != -1) {
checkConsistency();
- (*timerHeap)[m_index] = t;
+ timerHeap()[m_index] = t;
t->m_heapIndex = m_index;
}
return *this;
@@ -137,7 +146,7 @@ public:
void checkConsistency(int offset = 0) const
{
ASSERT_UNUSED(offset, m_index + offset >= 0);
- ASSERT_UNUSED(offset, m_index + offset <= (timerHeap ? static_cast<int>(timerHeap->size()) : 0));
+ ASSERT_UNUSED(offset, m_index + offset <= static_cast<int>(timerHeap().size()));
}
private:
@@ -156,31 +165,16 @@ inline int operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.index(
// ----------------
-void updateSharedTimer()
-{
-#ifdef ANDROID_FIX // it is removed in http://trac.webkit.org/changeset/40080, but Android needs it
- if (timersReadyToFire || deferringTimers || !timerHeap || timerHeap->isEmpty())
-#else
- if (timersReadyToFire || !timerHeap || timerHeap->isEmpty())
-#endif
- stopSharedTimer();
- else
- setSharedTimerFireTime(timerHeap->first()->m_nextFireTime);
-}
-
-// ----------------
-
TimerBase::TimerBase()
- : m_nextFireTime(0), m_repeatInterval(0), m_heapIndex(-1)
+ : m_nextFireTime(0)
+ , m_repeatInterval(0)
+ , m_heapIndex(-1)
{
- // We only need to do this once, but probably not worth trying to optimize it.
- setSharedTimerFiredFunction(sharedTimerFired);
}
TimerBase::~TimerBase()
{
stop();
-
ASSERT(!inHeap());
}
@@ -202,7 +196,7 @@ void TimerBase::stop()
bool TimerBase::isActive() const
{
- return m_nextFireTime || (timersReadyToFire && timersReadyToFire->contains(this));
+ return m_nextFireTime || timersReadyToFire().contains(this);
}
double TimerBase::nextFireInterval() const
@@ -216,11 +210,10 @@ double TimerBase::nextFireInterval() const
inline void TimerBase::checkHeapIndex() const
{
- ASSERT(timerHeap);
- ASSERT(!timerHeap->isEmpty());
+ ASSERT(!timerHeap().isEmpty());
ASSERT(m_heapIndex >= 0);
- ASSERT(m_heapIndex < static_cast<int>(timerHeap->size()));
- ASSERT((*timerHeap)[m_heapIndex] == this);
+ ASSERT(m_heapIndex < static_cast<int>(timerHeap().size()));
+ ASSERT(timerHeap()[m_heapIndex] == this);
}
inline void TimerBase::checkConsistency() const
@@ -243,15 +236,15 @@ inline void TimerBase::heapDelete()
{
ASSERT(m_nextFireTime == 0);
heapPop();
- timerHeap->removeLast();
+ timerHeap().removeLast();
m_heapIndex = -1;
}
-inline void TimerBase::heapDeleteMin()
+void TimerBase::heapDeleteMin()
{
ASSERT(m_nextFireTime == 0);
heapPopMin();
- timerHeap->removeLast();
+ timerHeap().removeLast();
m_heapIndex = -1;
}
@@ -265,10 +258,8 @@ inline void TimerBase::heapIncreaseKey()
inline void TimerBase::heapInsert()
{
ASSERT(!inHeap());
- if (!timerHeap)
- timerHeap = new Vector<TimerBase*>;
- timerHeap->append(this);
- m_heapIndex = timerHeap->size() - 1;
+ timerHeap().append(this);
+ m_heapIndex = timerHeap().size() - 1;
heapDecreaseKey();
}
@@ -284,19 +275,18 @@ inline void TimerBase::heapPop()
void TimerBase::heapPopMin()
{
- ASSERT(this == timerHeap->first());
+ ASSERT(this == timerHeap().first());
checkHeapIndex();
- pop_heap(TimerHeapIterator(0), TimerHeapIterator(timerHeap->size()));
+ pop_heap(TimerHeapIterator(0), TimerHeapIterator(timerHeap().size()));
checkHeapIndex();
- ASSERT(this == timerHeap->last());
+ ASSERT(this == timerHeap().last());
}
void TimerBase::setNextFireTime(double newTime)
{
// Keep heap valid while changing the next-fire time.
- if (timersReadyToFire)
- timersReadyToFire->remove(this);
+ timersReadyToFire().remove(this);
double oldTime = m_nextFireTime;
if (oldTime != newTime) {
@@ -318,89 +308,16 @@ void TimerBase::setNextFireTime(double newTime)
bool isFirstTimerInHeap = m_heapIndex == 0;
if (wasFirstTimerInHeap || isFirstTimerInHeap)
- updateSharedTimer();
+ threadGlobalData().threadTimers().updateSharedTimer();
}
checkConsistency();
}
-void TimerBase::collectFiringTimers(double fireTime, Vector<TimerBase*>& firingTimers)
-{
- while (!timerHeap->isEmpty() && timerHeap->first()->m_nextFireTime <= fireTime) {
- TimerBase* timer = timerHeap->first();
- firingTimers.append(timer);
- timersReadyToFire->add(timer);
- timer->m_nextFireTime = 0;
- timer->heapDeleteMin();
- }
-}
-
-void TimerBase::fireTimers(double fireTime, const Vector<TimerBase*>& firingTimers)
-{
- int size = firingTimers.size();
- for (int i = 0; i != size; ++i) {
- TimerBase* timer = firingTimers[i];
-
- // If not in the set, this timer has been deleted or re-scheduled in another timer's fired function.
- // So either we don't want to fire it at all or we will fire it next time the shared timer goes off.
- // It might even have been deleted; that's OK because we won't do anything else with the pointer.
- if (!timersReadyToFire->contains(timer))
- continue;
-
- // Setting the next fire time has a side effect of removing the timer from the firing timers set.
- double interval = timer->repeatInterval();
- timer->setNextFireTime(interval ? fireTime + interval : 0);
-
- // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
- timer->fired();
-
- // Catch the case where the timer asked timers to fire in a nested event loop.
- if (!timersReadyToFire)
- break;
- }
-}
-
-void TimerBase::sharedTimerFired()
-{
- // Do a re-entrancy check.
- if (timersReadyToFire)
- return;
-
- double fireTime = currentTime();
- Vector<TimerBase*> firingTimers;
- HashSet<const TimerBase*> firingTimersSet;
-
- timersReadyToFire = &firingTimersSet;
-
- collectFiringTimers(fireTime, firingTimers);
- fireTimers(fireTime, firingTimers);
-
- timersReadyToFire = 0;
-
- updateSharedTimer();
-}
-
void TimerBase::fireTimersInNestedEventLoop()
{
- timersReadyToFire = 0;
- updateSharedTimer();
-}
-
-#ifdef ANDROID_FIX // it is removed in http://trac.webkit.org/changeset/40080, but Android needs it
-// ----------------
-
-bool isDeferringTimers()
-{
- return deferringTimers;
-}
-
-void setDeferringTimers(bool shouldDefer)
-{
- if (shouldDefer == deferringTimers)
- return;
- deferringTimers = shouldDefer;
- updateSharedTimer();
+ // Redirect to ThreadTimers.
+ threadGlobalData().threadTimers().fireTimersInNestedEventLoop();
}
-#endif
-}
+} // namespace WebCore
diff --git a/WebCore/platform/Timer.h b/WebCore/platform/Timer.h
index a2589f7..aab52c2 100644
--- a/WebCore/platform/Timer.h
+++ b/WebCore/platform/Timer.h
@@ -27,7 +27,6 @@
#define Timer_h
#include <wtf/Noncopyable.h>
-#include <wtf/Vector.h>
namespace WebCore {
@@ -73,20 +72,13 @@ private:
void heapPop();
void heapPopMin();
- static void collectFiringTimers(double fireTime, Vector<TimerBase*>&);
- static void fireTimers(double fireTime, const Vector<TimerBase*>&);
- static void sharedTimerFired();
-
double m_nextFireTime; // 0 if inactive
double m_repeatInterval; // 0 if not repeating
int m_heapIndex; // -1 if not in heap
unsigned m_heapInsertionOrder; // Used to keep order among equal-fire-time timers
- friend void updateSharedTimer();
-#ifdef ANDROID_FIX // it is removed in http://trac.webkit.org/changeset/40080, but Android needs it
- friend void setDeferringTimers(bool);
-#endif
friend class TimerHeapElement;
+ friend class ThreadTimers;
friend bool operator<(const TimerHeapElement&, const TimerHeapElement&);
};
@@ -104,13 +96,6 @@ private:
TimerFiredFunction m_function;
};
-#ifdef ANDROID_FIX // it is removed in http://trac.webkit.org/changeset/40080, but Android needs it
-// Set to true to prevent any timers from firing.
-// When set back to false, timers that were deferred will fire.
-bool isDeferringTimers();
-void setDeferringTimers(bool);
-#endif
-
}
#endif
diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h
index 6684eb2..459d615 100644
--- a/WebCore/platform/Widget.h
+++ b/WebCore/platform/Widget.h
@@ -142,7 +142,6 @@ public:
virtual void setFocus();
void setCursor(const Cursor&);
- Cursor cursor();
virtual void show();
virtual void hide();
@@ -198,7 +197,7 @@ private:
IntRect m_frame; // Not used when a native widget exists.
-#if PLATFORM(MAC) || PLATFORM(GTK)
+#if PLATFORM(MAC)
WidgetPrivate* m_data;
#endif
#if PLATFORM(ANDROID)
diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp
index 5a935ce..66ad2c7 100644
--- a/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -24,6 +24,9 @@
*/
#include "config.h"
+
+#include "FormControlElement.h"
+
#include "RenderThemeAndroid.h"
#include "RenderSkinAndroid.h"
@@ -170,19 +173,20 @@ void RenderThemeAndroid::adjustButtonStyle(CSSStyleSelector* selector, RenderSty
bool RenderThemeAndroid::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& ir)
{
- RenderSkinRadio::Draw(getCanvasFromInfo(i), o->element(), ir, true);
+ RenderSkinRadio::Draw(getCanvasFromInfo(i), o->node(), ir, true);
return false;
}
bool RenderThemeAndroid::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& ir)
{
// If it is a disabled button, simply paint it to the master picture.
- Node* element = o->element();
- if (!element->isEnabled()) {
+ Node* node = o->node();
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(node));
+ if (formControlElement && !formControlElement->isEnabled()) {
RenderSkinButton::Draw(getCanvasFromInfo(i), ir, RenderSkinAndroid::kDisabled);
} else {
// Store all the important information in the platform context.
- i.context->platformContext()->storeButtonInfo(element, ir);
+ i.context->platformContext()->storeButtonInfo(node, ir);
}
// We always return false so we do not request to be redrawn.
return false;
@@ -190,7 +194,7 @@ bool RenderThemeAndroid::paintButton(RenderObject* o, const RenderObject::PaintI
bool RenderThemeAndroid::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& ir)
{
- RenderSkinRadio::Draw(getCanvasFromInfo(i), o->element(), ir, false);
+ RenderSkinRadio::Draw(getCanvasFromInfo(i), o->node(), ir, false);
return false;
}
@@ -256,7 +260,7 @@ bool RenderThemeAndroid::paintCombo(RenderObject* o, const RenderObject::PaintIn
{
if (o->style() && o->style()->backgroundColor().alpha() == 0)
return true;
- Node* element = o->element();
+ Node* node = o->node();
int height = ir.height();
int y = ir.y();
// If the combo box is too large, leave it at its max height, and center it.
@@ -264,7 +268,7 @@ bool RenderThemeAndroid::paintCombo(RenderObject* o, const RenderObject::PaintIn
y += (height - MAX_COMBO_HEIGHT) >> 1;
height = MAX_COMBO_HEIGHT;
}
- return RenderSkinCombo::Draw(getCanvasFromInfo(i), element, ir.x(), y,
+ return RenderSkinCombo::Draw(getCanvasFromInfo(i), node, ir.x(), y,
ir.width(), height);
}
diff --git a/WebCore/platform/animation/Animation.cpp b/WebCore/platform/animation/Animation.cpp
index 5df4480..05761f8 100644
--- a/WebCore/platform/animation/Animation.cpp
+++ b/WebCore/platform/animation/Animation.cpp
@@ -25,13 +25,13 @@
namespace WebCore {
Animation::Animation()
- : m_delay(initialAnimationDelay())
- , m_direction(initialAnimationDirection())
- , m_duration(initialAnimationDuration())
- , m_iterationCount(initialAnimationIterationCount())
- , m_name(initialAnimationName())
+ : m_name(initialAnimationName())
, m_property(initialAnimationProperty())
+ , m_iterationCount(initialAnimationIterationCount())
+ , m_delay(initialAnimationDelay())
+ , m_duration(initialAnimationDuration())
, m_timingFunction(initialAnimationTimingFunction())
+ , m_direction(initialAnimationDirection())
, m_playState(initialAnimationPlayState())
, m_delaySet(false)
, m_directionSet(false)
@@ -47,13 +47,13 @@ Animation::Animation()
Animation::Animation(const Animation& o)
: RefCounted<Animation>()
- , m_delay(o.m_delay)
- , m_direction(o.m_direction)
- , m_duration(o.m_duration)
- , m_iterationCount(o.m_iterationCount)
, 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_playState(o.m_playState)
, m_delaySet(o.m_delaySet)
, m_directionSet(o.m_directionSet)
@@ -69,14 +69,14 @@ Animation::Animation(const Animation& o)
Animation& Animation::operator=(const Animation& o)
{
- m_delay = o.m_delay;
- m_direction = o.m_direction;
- m_duration = o.m_duration;
- m_iterationCount = o.m_iterationCount;
m_name = o.m_name;
- m_playState = o.m_playState;
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_playState = o.m_playState;
m_delaySet = o.m_delaySet;
m_directionSet = o.m_directionSet;
@@ -86,7 +86,6 @@ Animation& Animation::operator=(const Animation& o)
m_playStateSet = o.m_playStateSet;
m_propertySet = o.m_propertySet;
m_timingFunctionSet = o.m_timingFunctionSet;
-
m_isNone = o.m_isNone;
return *this;
@@ -101,13 +100,13 @@ bool Animation::animationsMatch(const Animation* o, bool matchPlayStates) const
if (!o)
return false;
- bool result = m_delay == o->m_delay &&
- m_direction == o->m_direction &&
- m_duration == o->m_duration &&
- m_iterationCount == o->m_iterationCount &&
- m_name == o->m_name &&
+ 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_delaySet == o->m_delaySet &&
m_directionSet == o->m_directionSet &&
m_durationSet == o->m_durationSet &&
diff --git a/WebCore/platform/animation/Animation.h b/WebCore/platform/animation/Animation.h
index 294acdf..9e1e8e1 100644
--- a/WebCore/platform/animation/Animation.h
+++ b/WebCore/platform/animation/Animation.h
@@ -35,6 +35,12 @@ namespace WebCore {
const int cAnimateNone = 0;
const int cAnimateAll = -2;
+// These were in RenderStyle, but have been moved here as
+// animation-play-state is in the process of being removed.
+
+const unsigned AnimPlayStatePlaying = 0;
+const unsigned AnimPlayStatePaused = 1;
+
class Animation : public RefCounted<Animation> {
public:
~Animation();
@@ -77,8 +83,13 @@ public:
void clearTimingFunction() { m_timingFunctionSet = false; }
double delay() const { return m_delay; }
- bool direction() const { return m_direction; }
+
+ enum AnimationDirection { AnimationDirectionNormal, AnimationDirectionAlternate };
+ AnimationDirection direction() const { return m_direction; }
+
double duration() const { return m_duration; }
+
+ enum { IterationCountInfinite = -1 };
int iterationCount() const { return m_iterationCount; }
const String& name() const { return m_name; }
unsigned playState() const { return m_playState; }
@@ -86,7 +97,7 @@ public:
const TimingFunction& timingFunction() const { return m_timingFunction; }
void setDelay(double c) { m_delay = c; m_delaySet = true; }
- void setDirection(bool d) { m_direction = d; m_directionSet = true; }
+ void setDirection(AnimationDirection d) { m_direction = d; m_directionSet = true; }
void setDuration(double d) { ASSERT(d >= 0); m_duration = d; m_durationSet = true; }
void setIterationCount(int c) { m_iterationCount = c; m_iterationCountSet = true; }
void setName(const String& n) { m_name = n; m_nameSet = true; }
@@ -109,13 +120,13 @@ private:
Animation();
Animation(const Animation& o);
- double m_delay;
- bool m_direction;
- double m_duration;
- int m_iterationCount;
String m_name;
int m_property;
+ int m_iterationCount;
+ double m_delay;
+ double m_duration;
TimingFunction m_timingFunction;
+ AnimationDirection m_direction : 1;
unsigned m_playState : 2;
@@ -132,7 +143,7 @@ private:
public:
static float initialAnimationDelay() { return 0; }
- static bool initialAnimationDirection() { return false; }
+ static AnimationDirection initialAnimationDirection() { return AnimationDirectionNormal; }
static double initialAnimationDuration() { return 0; }
static int initialAnimationIterationCount() { return 1; }
static String initialAnimationName() { return String("none"); }
diff --git a/WebCore/platform/cf/RunLoopTimerCF.cpp b/WebCore/platform/cf/RunLoopTimerCF.cpp
new file mode 100644
index 0000000..c97dd21
--- /dev/null
+++ b/WebCore/platform/cf/RunLoopTimerCF.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RunLoopTimer.h"
+
+#if PLATFORM(MAC)
+
+namespace WebCore {
+
+RunLoopTimerBase::~RunLoopTimerBase()
+{
+ stop();
+}
+
+static void timerFired(CFRunLoopTimerRef, void* context)
+{
+ RunLoopTimerBase* timer = static_cast<RunLoopTimerBase*>(context);
+ timer->fired();
+}
+
+void RunLoopTimerBase::start(double nextFireInterval, double repeatInterval)
+{
+ if (m_timer)
+ CFRunLoopTimerInvalidate(m_timer.get());
+ CFRunLoopTimerContext context = { 0, this, 0, 0, 0 };
+ m_timer.adoptCF(CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + nextFireInterval, repeatInterval, 0, 0, timerFired, &context));
+}
+
+void RunLoopTimerBase::schedule(const SchedulePair* schedulePair)
+{
+ ASSERT_ARG(schedulePair, schedulePair);
+ ASSERT_WITH_MESSAGE(m_timer, "Timer must have one of the start functions called before calling schedule().");
+ CFRunLoopAddTimer(schedulePair->runLoop(), m_timer.get(), schedulePair->mode());
+}
+
+void RunLoopTimerBase::schedule(const SchedulePairHashSet& schedulePairs)
+{
+ SchedulePairHashSet::const_iterator end = schedulePairs.end();
+ for (SchedulePairHashSet::const_iterator it = schedulePairs.begin(); it != end; ++it)
+ schedule((*it).get());
+}
+
+void RunLoopTimerBase::stop()
+{
+ if (!m_timer)
+ return;
+ CFRunLoopTimerInvalidate(m_timer.get());
+ m_timer = 0;
+}
+
+bool RunLoopTimerBase::isActive() const
+{
+ return m_timer && CFRunLoopTimerIsValid(m_timer.get());
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index dd36c1a..3e5c404 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -92,6 +92,7 @@ namespace WebCore {
// JavaScript ---------------------------------------------------------
static void notifyJSOutOfMemory(Frame*);
+ static bool allowScriptDespiteSettings(const KURL& documentURL);
// Language -----------------------------------------------------------
static String computedDefaultLanguage();
@@ -100,11 +101,10 @@ namespace WebCore {
static bool layoutTestMode();
// MimeType -----------------------------------------------------------
- static bool isSupportedImageMIMEType(const char* mimeType);
- static bool isSupportedJavascriptMIMEType(const char* mimeType);
- static bool isSupportedNonImageMIMEType(const char* mimeType);
- static bool matchesMIMEType(const String& pattern, const String& type);
- static String mimeTypeForExtension(const String& ext);
+ static bool isSupportedImageMIMEType(const String& mimeType);
+ static bool isSupportedJavaScriptMIMEType(const String& mimeType);
+ static bool isSupportedNonImageMIMEType(const String& mimeType);
+ static String mimeTypeForExtension(const String& fileExtension);
static String mimeTypeFromFile(const String& filePath);
static String preferredExtensionForMIMEType(const String& mimeType);
@@ -114,7 +114,7 @@ namespace WebCore {
static bool popupsAllowed(NPP);
// Protocol -----------------------------------------------------------
- static String uiResourceProtocol();
+ static String uiResourceProtocol(); // deprecated
// Resources ----------------------------------------------------------
static PassRefPtr<Image> loadPlatformImageResource(const char* name);
@@ -134,7 +134,6 @@ namespace WebCore {
// StatsCounters ------------------------------------------------------
static void decrementStatsCounter(const char* name);
static void incrementStatsCounter(const char* name);
- static void initV8CounterFunction();
// SystemTime ---------------------------------------------------------
static double currentTime();
@@ -153,15 +152,14 @@ namespace WebCore {
GraphicsContext*, int part, int state, int classicState, const IntRect&, const IntRect& alignRect);
static void paintTextField(
GraphicsContext*, int part, int state, int classicState, const IntRect&, const Color&, bool fillContentArea, bool drawEdges);
+ static void paintTrackbar(
+ GraphicsContext*, int part, int state, int classicState, const IntRect&);
#endif
// Trace Event --------------------------------------------------------
static void traceEventBegin(const char* name, void* id, const char* extra);
static void traceEventEnd(const char* name, void* id, const char* extra);
- // URL ----------------------------------------------------------------
- static KURL inspectorURL();
-
// Visited links ------------------------------------------------------
static LinkHash visitedLinkHash(const UChar* url, unsigned length);
static LinkHash visitedLinkHash(const KURL& base, const AtomicString& attributeURL);
diff --git a/WebCore/platform/chromium/ChromiumDataObject.cpp b/WebCore/platform/chromium/ChromiumDataObject.cpp
index 67e9d00..dee4568 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.cpp
+++ b/WebCore/platform/chromium/ChromiumDataObject.cpp
@@ -37,6 +37,7 @@ void ChromiumDataObject::clear()
{
url = KURL();
urlTitle = "";
+ fileExtension = "";
filenames.clear();
plainText = "";
textHtml = "";
@@ -49,6 +50,7 @@ void ChromiumDataObject::clear()
bool ChromiumDataObject::hasData()
{
return !url.isEmpty()
+ || !fileExtension.isEmpty()
|| !filenames.isEmpty()
|| !plainText.isEmpty()
|| !textHtml.isEmpty()
diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h
index 448e763..19b91c4 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/WebCore/platform/chromium/ChromiumDataObject.h
@@ -54,6 +54,7 @@ namespace WebCore {
KURL url;
String urlTitle;
+ String fileExtension;
Vector<String> filenames;
String plainText;
diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp
index 7fc156e..b28503d 100644
--- a/WebCore/platform/chromium/ClipboardChromium.cpp
+++ b/WebCore/platform/chromium/ClipboardChromium.cpp
@@ -268,15 +268,15 @@ static void writeImageToDataObject(ChromiumDataObject* dataObject, Element* elem
// use the alt tag if one exists, otherwise we fall back on the suggested
// filename in the http header, and finally we resort to using the filename
// in the URL.
- String extension(".");
- extension += MIMETypeRegistry::getPreferredExtensionForMIMEType(
+ String extension = MIMETypeRegistry::getPreferredExtensionForMIMEType(
cachedImage->response().mimeType());
+ dataObject->fileExtension = extension.isEmpty() ? "" : "." + extension;
String title = element->getAttribute(altAttr);
- if (title.isEmpty()) {
+ if (title.isEmpty())
title = cachedImage->response().suggestedFilename();
- // FIXME: If title is empty, get the filename from the URL.
- }
- dataObject->fileContentFilename = title + extension;
+
+ title = ClipboardChromium::validateFileName(title, dataObject);
+ dataObject->fileContentFilename = title + dataObject->fileExtension;
}
void ClipboardChromium::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame)
diff --git a/WebCore/platform/chromium/ClipboardChromium.h b/WebCore/platform/chromium/ClipboardChromium.h
index 1864c1a..53699da 100644
--- a/WebCore/platform/chromium/ClipboardChromium.h
+++ b/WebCore/platform/chromium/ClipboardChromium.h
@@ -47,6 +47,12 @@ namespace WebCore {
static PassRefPtr<ClipboardChromium> create(
bool isForDragging, PassRefPtr<ChromiumDataObject>, ClipboardAccessPolicy);
+ // Returns the file name (not including the extension). This removes any
+ // invalid file system characters as well as making sure the
+ // path + extension is not bigger than allowed by the file system.
+ // This may change the file extension in dataObject.
+ static String validateFileName(const String& title, ChromiumDataObject* dataObject);
+
virtual void clearData(const String& type);
void clearAllData();
String getData(const String& type, bool& success) const;
diff --git a/WebCore/svg/graphics/cg/SVGResourceMaskerCg.cpp b/WebCore/platform/chromium/ClipboardChromiumLinux.cpp
index 4d2100b..2c89f6e 100644
--- a/WebCore/svg/graphics/cg/SVGResourceMaskerCg.cpp
+++ b/WebCore/platform/chromium/ClipboardChromiumLinux.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2007 Apple Inc.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -20,23 +21,21 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (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"
+#include "ClipboardChromium.h"
-#if ENABLE(SVG)
-#include "SVGResourceMasker.h"
+#include "ChromiumDataObject.h"
#include "NotImplemented.h"
namespace WebCore {
-void SVGResourceMasker::applyMask(GraphicsContext*, const FloatRect&)
+String ClipboardChromium::validateFileName(const String& title, ChromiumDataObject* dataObject)
{
notImplemented();
+ return title;
}
-} // namespace WebCore
-
-#endif // ENABLE(SVG)
+} // namespace WebCore
diff --git a/WebCore/dom/WorkerTask.h b/WebCore/platform/chromium/ClipboardChromiumMac.cpp
index a842ce2..2c89f6e 100644
--- a/WebCore/dom/WorkerTask.h
+++ b/WebCore/platform/chromium/ClipboardChromiumMac.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -20,29 +21,21 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (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 WorkerTask_h
-#define WorkerTask_h
-
-#if ENABLE(WORKERS)
+#include "config.h"
+#include "ClipboardChromium.h"
-#include <wtf/Threading.h>
+#include "ChromiumDataObject.h"
+#include "NotImplemented.h"
namespace WebCore {
- class WorkerContext;
-
- class WorkerTask : public ThreadSafeShared<WorkerTask> {
- public:
- virtual ~WorkerTask();
- virtual void performTask(WorkerContext*) = 0;
- };
-
-} // namespace WebCore
-
-#endif // ENABLE(WORKERS)
+String ClipboardChromium::validateFileName(const String& title, ChromiumDataObject* dataObject)
+{
+ notImplemented();
+ return title;
+}
-#endif // WorkerTask_h
+} // namespace WebCore
diff --git a/WebCore/platform/chromium/ClipboardChromiumWin.cpp b/WebCore/platform/chromium/ClipboardChromiumWin.cpp
new file mode 100644
index 0000000..b4a2c21
--- /dev/null
+++ b/WebCore/platform/chromium/ClipboardChromiumWin.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ClipboardChromium.h"
+
+#include "ChromiumDataObject.h"
+
+#include <shlwapi.h>
+
+namespace WebCore {
+
+// Returns true if the specified character is not valid in a file name. This
+// is intended for use with removeCharacters.
+static bool isInvalidFileCharacter(UChar c)
+{
+ return (PathGetCharType(c) & (GCT_LFNCHAR | GCT_SHORTCHAR)) == 0;
+}
+
+String ClipboardChromium::validateFileName(const String& title, ChromiumDataObject* dataObject)
+{
+ // Remove any invalid file system characters.
+ String result = title.removeCharacters(&isInvalidFileCharacter);
+ if (result.length() + dataObject->fileExtension.length() + 1 >= MAX_PATH) {
+ if (dataObject->fileExtension.length() + 1 >= MAX_PATH)
+ dataObject->fileExtension = "";
+ if (result.length() + dataObject->fileExtension.length() + 1 >= MAX_PATH)
+ result = result.substring(0, MAX_PATH - dataObject->fileExtension.length() - 1);
+ }
+ return result;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp b/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp
index 5d6f426..1aac5ec 100644
--- a/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp
+++ b/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp
@@ -83,8 +83,7 @@ String MIMETypeRegistry::getMIMETypeForPath(const String& path)
bool MIMETypeRegistry::isSupportedImageMIMEType(const String& mimeType)
{
- return !mimeType.isEmpty()
- && ChromiumBridge::isSupportedImageMIMEType(mimeType.latin1().data());
+ return ChromiumBridge::isSupportedImageMIMEType(mimeType);
}
bool MIMETypeRegistry::isSupportedImageResourceMIMEType(const String& mimeType)
@@ -100,14 +99,12 @@ bool MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(const String& mimeTyp
bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType)
{
- return !mimeType.isEmpty()
- && ChromiumBridge::isSupportedJavascriptMIMEType(mimeType.latin1().data());
+ return ChromiumBridge::isSupportedJavaScriptMIMEType(mimeType);
}
bool MIMETypeRegistry::isSupportedNonImageMIMEType(const String& mimeType)
{
- return !mimeType.isEmpty()
- && ChromiumBridge::isSupportedNonImageMIMEType(mimeType.latin1().data());
+ return ChromiumBridge::isSupportedNonImageMIMEType(mimeType);
}
bool MIMETypeRegistry::isSupportedMediaMIMEType(const String& mimeType)
diff --git a/WebCore/platform/chromium/PasteboardChromium.cpp b/WebCore/platform/chromium/PasteboardChromium.cpp
index e7b2203..9b32bae 100644
--- a/WebCore/platform/chromium/PasteboardChromium.cpp
+++ b/WebCore/platform/chromium/PasteboardChromium.cpp
@@ -98,6 +98,15 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
void Pasteboard::writeImage(Node* node, const KURL&, const String& title)
{
+ ASSERT(node);
+ ASSERT(node->renderer());
+ ASSERT(node->renderer()->isImage());
+ RenderImage* renderer = static_cast<RenderImage*>(node->renderer());
+ CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage());
+ ASSERT(cachedImage);
+ Image* image = cachedImage->image();
+ ASSERT(image);
+
// If the image is wrapped in a link, |url| points to the target of the
// link. This isn't useful to us, so get the actual image URL.
AtomicString urlString;
@@ -113,16 +122,6 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String& title)
}
KURL url = urlString.isEmpty() ? KURL() : node->document()->completeURL(parseURL(urlString));
- ASSERT(node);
- ASSERT(node->renderer());
- ASSERT(node->renderer()->isImage());
-
- RenderImage* renderer = static_cast<RenderImage*>(node->renderer());
- CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage());
- ASSERT(cachedImage);
- Image* image = cachedImage->image();
- ASSERT(image);
-
NativeImageSkia* bitmap = 0;
#if !PLATFORM(CG)
bitmap = image->nativeImageForCurrentFrame();
diff --git a/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp b/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
index 6840bdf..ae55afe 100644
--- a/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
+++ b/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp
@@ -42,7 +42,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom
#if PLATFORM(WIN_OS)
// No KeyDown events on Windows to disambiguate.
ASSERT_NOT_REACHED();
-#elif PLATFORM(DARWIN)
+#else
// Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
ASSERT(m_type == KeyDown);
ASSERT(type == RawKeyDown || type == Char);
@@ -56,6 +56,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom
} else {
m_keyIdentifier = String();
m_windowsVirtualKeyCode = 0;
+#if PLATFORM(DARWIN)
if (m_text.length() == 1 && (m_text[0U] >= 0xF700 && m_text[0U] <= 0xF7FF)) {
// According to NSEvents.h, OpenStep reserves the range 0xF700-0xF8FF for function keys. However, some actual private use characters
// happen to be in this range, e.g. the Apple logo (Option+Shift+K).
@@ -63,6 +64,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom
m_text = String();
m_unmodifiedText = String();
}
+#endif
}
#endif
}
diff --git a/WebCore/platform/chromium/PlatformWidget.h b/WebCore/platform/chromium/PlatformWidget.h
index e4e6a18..b9dddf3 100644
--- a/WebCore/platform/chromium/PlatformWidget.h
+++ b/WebCore/platform/chromium/PlatformWidget.h
@@ -31,10 +31,12 @@
#ifndef PlatformWidget_h
#define PlatformWidget_h
+#include <wtf/StdLibExtras.h> // for intptr_t
+
// PlatformWidget is an opaque identifier corresponding to whatever native
// view type the embedder may use. PlatformWidget CANNOT be assumed to be
// a valid pointer. Some embedders may not use this identifier at all.
-typedef void* PlatformWidget;
+typedef intptr_t PlatformWidget;
#endif
diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp
index fad0a6b..53f565a 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -69,10 +69,24 @@ static const int kMaxHeight = 500;
static const int kBorderSize = 1;
static const TimeStamp kTypeAheadTimeoutMs = 1000;
+// The settings used for the drop down menu.
+// This is the delegate used if none is provided.
+static const PopupContainerSettings dropDownSettings = {
+ true, // focusOnShow
+ true, // setTextOnIndexChange
+ true, // acceptOnAbandon
+ false // loopSelectionNavigation
+};
+
// This class uses WebCore code to paint and handle events for a drop-down list
// box ("combobox" on Windows).
class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> {
public:
+ static PassRefPtr<PopupListBox> create(PopupMenuClient* client, const PopupContainerSettings& settings)
+ {
+ return adoptRef(new PopupListBox(client, settings));
+ }
+
// FramelessScrollView
virtual void paint(GraphicsContext*, const IntRect&);
virtual bool handleMouseDownEvent(const PlatformMouseEvent&);
@@ -84,9 +98,6 @@ public:
// ScrollView
virtual HostWindow* hostWindow() const;
- // Widget
- virtual void invalidateRect(const IntRect&);
-
// PopupListBox methods
// Shows the popup
@@ -125,20 +136,6 @@ public:
// Returns whether the popup wants to process events for the passed key.
bool isInterestedInEventForKey(int keyCode);
- // Sets whether the PopupMenuClient should be told to change its text when a
- // new item is selected (by using the arrow keys). Default is true.
- void setTextOnIndexChange(bool value) { m_setTextOnIndexChange = value; }
-
- // Sets whether we should accept the selected index when the popup is
- // abandonned.
- void setAcceptOnAbandon(bool value) { m_shouldAcceptOnAbandon = value; }
-
- // Sets whether pressing the down/up arrow when the last/first row is
- // selected clears the selection on the first key press and then selects the
- // first/last row on the next key press. If false, the selected row stays
- // the last/first row.
- void setLoopSelectionNavigation(bool value) { m_loopSelectionNavigation = value; }
-
private:
friend class PopupContainer;
friend class RefCounted<PopupListBox>;
@@ -159,17 +156,15 @@ private:
int y; // y offset of this item, relative to the top of the popup.
};
- PopupListBox(PopupMenuClient* client)
- : m_originalIndex(0)
+ PopupListBox(PopupMenuClient* client, const PopupContainerSettings& settings)
+ : m_settings(settings)
+ , m_originalIndex(0)
, m_selectedIndex(0)
- , m_shouldAcceptOnAbandon(true)
, m_willAcceptOnAbandon(false)
, m_visibleRows(0)
, m_popupClient(client)
, m_repeatingChar(0)
, m_lastCharTime(0)
- , m_setTextOnIndexChange(true)
- , m_loopSelectionNavigation(false)
{
setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
}
@@ -228,6 +223,9 @@ private:
void selectPreviousRow();
void selectNextRow();
+ // The settings that specify the behavior for this Popup window.
+ PopupContainerSettings m_settings;
+
// This is the index of the item marked as "selected" - i.e. displayed in the widget on the
// page.
int m_originalIndex;
@@ -237,15 +235,10 @@ private:
// enter yet however.
int m_selectedIndex;
- // Whether we should accept the selectedIndex as chosen when the popup is
- // "abandoned". This value is set through its setter and is useful as
- // select popup menu and form autofill popup menu have different behaviors.
- bool m_shouldAcceptOnAbandon;
-
// True if we should accept the selectedIndex as chosen, even if the popup
// is "abandoned". This is used for keyboard navigation, where we want the
- // selection to change immediately, and is only used if
- // m_shouldAcceptOnAbandon is true.
+ // selection to change immediately, and is only used if the settings
+ // acceptOnAbandon field is true.
bool m_willAcceptOnAbandon;
// This is the number of rows visible in the popup. The maximum number visible at a time is
@@ -277,10 +270,6 @@ private:
// The last time the user hit a key. Used for typeAheadFind.
TimeStamp m_lastCharTime;
-
- bool m_setTextOnIndexChange;
-
- bool m_loopSelectionNavigation;
};
static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent& e,
@@ -316,19 +305,15 @@ static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent&
// static
PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client,
- bool focusOnShow)
+ const PopupContainerSettings& settings)
{
- return adoptRef(new PopupContainer(client, focusOnShow));
+ return adoptRef(new PopupContainer(client, settings));
}
-PopupContainer::PopupContainer(PopupMenuClient* client, bool focusOnShow)
- : m_listBox(new PopupListBox(client)),
- m_focusOnShow(focusOnShow)
+PopupContainer::PopupContainer(PopupMenuClient* client, const PopupContainerSettings& settings)
+ : m_listBox(PopupListBox::create(client, settings))
+ , m_settings(settings)
{
- // FrameViews are created with a refcount of 1 so it needs releasing after we
- // assign it to a RefPtr.
- m_listBox->deref();
-
setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
}
@@ -352,19 +337,19 @@ void PopupContainer::showPopup(FrameView* view)
if (chromeClient) {
// If the popup would extend past the bottom of the screen, open upwards
// instead.
- FloatRect screen = screenRect(view);
+ FloatRect screen = screenAvailableRect(view);
IntRect widgetRect = chromeClient->windowToScreen(frameRect());
if (widgetRect.bottom() > static_cast<int>(screen.bottom()))
widgetRect.move(0, -(widgetRect.height() + selectHeight));
- chromeClient->popupOpened(this, widgetRect, m_focusOnShow);
+ chromeClient->popupOpened(this, widgetRect, m_settings.focusOnShow);
}
- // Must get called after we have a client and containingWindow.
- addChild(m_listBox.get());
+ if (!m_listBox->parent())
+ addChild(m_listBox.get());
- // Enable scrollbars after the listbox is inserted into the hierarchy, so
- // it has a proper WidgetClient.
+ // Enable scrollbars after the listbox is inserted into the hierarchy,
+ // so it has a proper WidgetClient.
m_listBox->setVerticalScrollbarMode(ScrollbarAuto);
m_listBox->scrollToRevealSelection();
@@ -374,12 +359,6 @@ void PopupContainer::showPopup(FrameView* view)
void PopupContainer::hidePopup()
{
- invalidate();
-
- m_listBox->disconnectClient();
- removeChild(m_listBox.get());
- m_listBox = 0;
-
if (client())
client()->popupClosed(this);
}
@@ -495,27 +474,17 @@ void PopupContainer::show(const IntRect& r, FrameView* v, int index)
showPopup(v);
}
-void PopupContainer::setTextOnIndexChange(bool value)
-{
- listBox()->setTextOnIndexChange(value);
-}
-
-void PopupContainer::setAcceptOnAbandon(bool value)
-{
- listBox()->setAcceptOnAbandon(value);
-}
-
-void PopupContainer::setLoopSelectionNavigation(bool value)
-{
- listBox()->setLoopSelectionNavigation(value);
-}
-
void PopupContainer::refresh()
{
listBox()->updateFromElement();
layout();
}
+int PopupContainer::selectedIndex() const
+{
+ return m_listBox->selectedIndex();
+}
+
///////////////////////////////////////////////////////////////////////////////
// PopupListBox implementation
@@ -658,13 +627,14 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
// want to fire the onchange event until the popup is closed, to match
// IE). We change the original index so we revert to that when the
// popup is closed.
- if (m_shouldAcceptOnAbandon)
+ if (m_settings.acceptOnAbandon)
m_willAcceptOnAbandon = true;
setOriginalIndex(m_selectedIndex);
- if (m_setTextOnIndexChange)
+ if (m_settings.setTextOnIndexChange)
m_popupClient->setTextFromItem(m_selectedIndex);
- } else if (!m_setTextOnIndexChange && event.windowsVirtualKeyCode() == VKEY_TAB) {
+ } else if (!m_settings.setTextOnIndexChange &&
+ event.windowsVirtualKeyCode() == VKEY_TAB) {
// TAB is a special case as it should select the current item if any and
// advance focus.
if (m_selectedIndex >= 0)
@@ -683,15 +653,6 @@ HostWindow* PopupListBox::hostWindow() const
return parent() ? parent()->hostWindow() : 0;
}
-void PopupListBox::invalidateRect(const IntRect& rect)
-{
- // Since we are returning the HostWindow of our parent as our own in
- // hostWindow(), we need to invalidate in our parent's coordinates.
- IntRect newRect(rect);
- newRect.move(kBorderSize, kBorderSize);
- FramelessScrollView::invalidateRect(newRect);
-}
-
// From HTMLSelectElement.cpp
static String stripLeadingWhiteSpace(const String& string)
{
@@ -855,12 +816,10 @@ void PopupListBox::abandon()
m_selectedIndex = m_originalIndex;
+ m_popupClient->hidePopup();
+
if (m_willAcceptOnAbandon)
m_popupClient->valueChanged(m_selectedIndex);
-
- // valueChanged may have torn down the popup!
- if (m_popupClient)
- m_popupClient->hidePopup();
}
int PopupListBox::pointToRowIndex(const IntPoint& point)
@@ -892,12 +851,11 @@ void PopupListBox::acceptIndex(int index)
if (isSelectableItem(index)) {
RefPtr<PopupListBox> keepAlive(this);
- // Tell the <select> PopupMenuClient what index was selected, and hide ourself.
- m_popupClient->valueChanged(index);
+ // Hide ourselves first since valueChanged may have numerous side-effects.
+ m_popupClient->hidePopup();
- // valueChanged may have torn down the popup!
- if (m_popupClient)
- m_popupClient->hidePopup();
+ // Tell the <select> PopupMenuClient what index was selected.
+ m_popupClient->valueChanged(index);
}
}
@@ -940,7 +898,9 @@ void PopupListBox::invalidateRow(int index)
if (index < 0)
return;
- invalidateRect(getRowBounds(index));
+ // Invalidate in the window contents, as FramelessScrollView::invalidateRect
+ // paints in the window coordinates.
+ invalidateRect(contentsToWindow(getRowBounds(index)));
}
void PopupListBox::scrollToRevealRow(int index)
@@ -959,7 +919,8 @@ void PopupListBox::scrollToRevealRow(int index)
}
}
-bool PopupListBox::isSelectableItem(int index) {
+bool PopupListBox::isSelectableItem(int index)
+{
return m_items[index]->type == TypeOption && m_popupClient->itemIsEnabled(index);
}
@@ -973,7 +934,7 @@ void PopupListBox::clearSelection()
void PopupListBox::selectNextRow()
{
- if (!m_loopSelectionNavigation || m_selectedIndex != numItems() - 1) {
+ if (!m_settings.loopSelectionNavigation || m_selectedIndex != numItems() - 1) {
adjustSelectedIndex(1);
return;
}
@@ -984,7 +945,7 @@ void PopupListBox::selectNextRow()
void PopupListBox::selectPreviousRow()
{
- if (!m_loopSelectionNavigation || m_selectedIndex > 0) {
+ if (!m_settings.loopSelectionNavigation || m_selectedIndex > 0) {
adjustSelectedIndex(-1);
return;
}
@@ -1156,16 +1117,15 @@ PopupMenu::~PopupMenu()
void PopupMenu::show(const IntRect& r, FrameView* v, int index)
{
- p.popup = PopupContainer::create(client(), true);
+ if (!p.popup)
+ p.popup = PopupContainer::create(client(), dropDownSettings);
p.popup->show(r, v, index);
}
void PopupMenu::hide()
{
- if (p.popup) {
+ if (p.popup)
p.popup->hidePopup();
- p.popup = 0;
- }
}
void PopupMenu::updateFromElement()
diff --git a/WebCore/platform/chromium/PopupMenuChromium.h b/WebCore/platform/chromium/PopupMenuChromium.h
index a57383d..cd13c22 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.h
+++ b/WebCore/platform/chromium/PopupMenuChromium.h
@@ -44,7 +44,7 @@ namespace WebCore {
// FIXME: Our FramelessScrollView classes should probably implement HostWindow!
- // This class holds a PopupListBox (see cpp file). Its sole purpose is to be
+ // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be
// able to draw a border around its child. All its paint/event handling is
// just forwarded to the child listBox (with the appropriate transforms).
// NOTE: this class is exposed so it can be instantiated direcly for the
@@ -52,9 +52,30 @@ namespace WebCore {
// autofill popup should not be focused when shown and we want to forward the
// key events to it (through handleKeyEvent).
+ struct PopupContainerSettings {
+ // Whether the popup should get the focus when displayed.
+ bool focusOnShow;
+
+ // Whether the PopupMenuClient should be told to change its text when a
+ // new item is selected by using the arrow keys.
+ bool setTextOnIndexChange;
+
+ // Whether the selection should be accepted when the popup menu is
+ // closed (through ESC being pressed or the focus going away).
+ // Note that when TAB is pressed, the selection is always accepted
+ // regardless of this setting.
+ bool acceptOnAbandon;
+
+ // Whether the we should move the selection to the first/last item when
+ // the user presses down/up arrow keys and the last/first item is
+ // selected.
+ bool loopSelectionNavigation;
+ };
+
class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> {
public:
- static PassRefPtr<PopupContainer> create(PopupMenuClient*, bool focusOnShow);
+ static PassRefPtr<PopupContainer> create(PopupMenuClient*,
+ const PopupContainerSettings&);
// Whether a key event should be sent to this popup.
virtual bool isInterestedInEventForKey(int keyCode);
@@ -84,31 +105,19 @@ namespace WebCore {
// Compute size of widget and children.
void layout();
- // Sets whether the PopupMenuClient should be told to change its text when a
- // new item is selected (by using the arrow keys). Default is true.
- void setTextOnIndexChange(bool);
-
- // Sets whether the selection should be accepted when the popup menu is
- // closed (through ESC being pressed or the focus going away). Default
- // is true. Note that when TAB is pressed, the selection is always
- // accepted regardless of this setting.
- void setAcceptOnAbandon(bool);
-
- // Sets whether we should move the selection to the first/last item
- // when the user presses down/up arrow keys and the last/first item is
- // selected. Default is false, causing the first/last item to stay
- // selected.
- void setLoopSelectionNavigation(bool);
-
PopupListBox* listBox() const { return m_listBox.get(); }
+ // Gets the index of the item that the user is currently moused-over or
+ // has selected with the keyboard up/down arrows.
+ int selectedIndex() const;
+
// Refresh the popup values from the PopupMenuClient.
void refresh();
private:
friend class WTF::RefCounted<PopupContainer>;
- PopupContainer(PopupMenuClient*, bool focusOnShow);
+ PopupContainer(PopupMenuClient*, const PopupContainerSettings&);
~PopupContainer();
// Paint the border.
@@ -116,8 +125,7 @@ namespace WebCore {
RefPtr<PopupListBox> m_listBox;
- // Whether the window showing this popup should be focused when shown.
- bool m_focusOnShow;
+ PopupContainerSettings m_settings;
};
} // namespace WebCore
diff --git a/WebCore/platform/chromium/ScrollbarThemeChromium.cpp b/WebCore/platform/chromium/ScrollbarThemeChromium.cpp
index de40572..426a078 100644
--- a/WebCore/platform/chromium/ScrollbarThemeChromium.cpp
+++ b/WebCore/platform/chromium/ScrollbarThemeChromium.cpp
@@ -96,7 +96,7 @@ IntRect ScrollbarThemeChromium::forwardButtonRect(Scrollbar* scrollbar, Scrollba
IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool)
{
IntSize bs = buttonSize(scrollbar);
- int thickness = scrollbarThickness();
+ int thickness = scrollbarThickness(scrollbar->controlSize());
if (scrollbar->orientation() == HorizontalScrollbar) {
if (scrollbar->width() < 2 * thickness)
return IntRect();
@@ -167,26 +167,26 @@ bool ScrollbarThemeChromium::shouldCenterOnThumb(Scrollbar*, const PlatformMouse
IntSize ScrollbarThemeChromium::buttonSize(Scrollbar* scrollbar)
{
+#if defined(__linux__)
+ // On Linux, we don't use buttons
+ return IntSize(0, 0);
+#endif
+
// Our desired rect is essentially thickness by thickness.
// Our actual rect will shrink to half the available space when we have < 2
// times thickness pixels left. This allows the scrollbar to scale down
// and function even at tiny sizes.
- int thickness = scrollbarThickness();
+ int thickness = scrollbarThickness(scrollbar->controlSize());
-#if !defined(__linux__)
// In layout test mode, we force the button "girth" (i.e., the length of
// the button along the axis of the scrollbar) to be a fixed size.
// FIXME: This is retarded! scrollbarThickness is already fixed in layout
// test mode so that should be enough to result in repeatable results, but
// preserving this hack avoids having to rebaseline pixel tests.
const int kLayoutTestModeGirth = 17;
-
int girth = ChromiumBridge::layoutTestMode() ? kLayoutTestModeGirth : thickness;
-#else
- int girth = thickness;
-#endif
if (scrollbar->orientation() == HorizontalScrollbar) {
int width = scrollbar->width() < 2 * girth ? scrollbar->width() / 2 : girth;
diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
index 95d0f78..a99d778 100644
--- a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
+++ b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -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
@@ -37,112 +37,106 @@
#include "Scrollbar.h"
#include "TransformationMatrix.h"
-#include "gtkdrawing.h"
-#include <gtk/gtk.h>
-#include "skia/ext/GdkSkia.h"
-
namespace WebCore {
int ScrollbarThemeChromium::scrollbarThickness(ScrollbarControlSize controlSize)
{
- static int size = 0;
- if (!size) {
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
- size = metrics.slider_width;
- }
- return size;
+ return 15;
}
bool ScrollbarThemeChromium::invalidateOnMouseEnterExit()
{
- notImplemented();
return false;
}
-// Given an uninitialised widget state object, set the members such that it's
-// sane for drawing scrollbars
-static void initMozState(GtkWidgetState* mozState)
+static void drawVertLine(SkCanvas* canvas, int x, int y1, int y2, const SkPaint& paint)
{
- mozState->active = true;
- mozState->focused = false;
- mozState->inHover = false;
- mozState->disabled = false;
- mozState->isDefault = false;
- mozState->canDefault = false;
- mozState->depressed = false;
- mozState->curpos = 0;
- mozState->maxpos = 0;
+ SkIRect skrect;
+ skrect.set(x, y1, x + 1, y2 + 1);
+ canvas->drawIRect(skrect, paint);
}
-// Paint a GTK widget
-// gc: context to draw onto
-// rect: the area of the widget
-// widget_type: the type of widget to draw
-// flags: widget dependent flags (e.g. direction of scrollbar arrows etc)
-//
-// See paintMozWiget in RenderThemeGtk.cpp for an explanation of the clipping.
-static void paintScrollbarWidget(GraphicsContext* gc, const IntRect& rect,
- GtkThemeWidgetType widget_type, gint flags)
+static void drawHorizLine(SkCanvas* canvas, int x1, int x2, int y, const SkPaint& paint)
{
- PlatformContextSkia* pcs = gc->platformContext();
-
- GdkRectangle gdkRect = { rect.x(), rect.y(), rect.width(), rect.height() };
-
- const SkIRect clip_region = pcs->canvas()->getTotalClip().getBounds();
- TransformationMatrix ctm = gc->getCTM().inverse();
- IntPoint pos = ctm.mapPoint(
- IntPoint(SkScalarRound(clip_region.fLeft), SkScalarRound(clip_region.fTop)));
- GdkRectangle gdkClipRect;
- gdkClipRect.x = pos.x();
- gdkClipRect.y = pos.y();
- gdkClipRect.width = clip_region.width();
- gdkClipRect.height = clip_region.height();
-
- gdk_rectangle_intersect(&gdkRect, &gdkClipRect, &gdkClipRect);
-
- GtkWidgetState mozState;
- initMozState(&mozState);
+ SkIRect skrect;
+ skrect.set(x1, y, x2 + 1, y + 1);
+ canvas->drawIRect(skrect, paint);
+}
- moz_gtk_widget_paint(widget_type, pcs->gdk_skia(), &gdkRect, &gdkClipRect,
- &mozState, flags, GTK_TEXT_DIR_LTR);
+static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint)
+{
+ const int right = rect.x() + rect.width() - 1;
+ const int bottom = rect.y() + rect.height() - 1;
+ drawHorizLine(canvas, rect.x(), right, rect.y(), paint);
+ drawVertLine(canvas, right, rect.y(), bottom, paint);
+ drawHorizLine(canvas, rect.x(), right, bottom, paint);
+ drawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
}
void ScrollbarThemeChromium::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar,
const IntRect& rect, ScrollbarPart partType)
{
- const bool horz = scrollbar->orientation() == HorizontalScrollbar;
- const GtkThemeWidgetType track_type =
- horz ? MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL : MOZ_GTK_SCROLLBAR_TRACK_VERTICAL;
- paintScrollbarWidget(gc, rect, track_type, 0);
+ SkCanvas* const canvas = gc->platformContext()->canvas();
+ SkPaint paint;
+ SkIRect skrect;
+
+ skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
+ paint.setARGB(0xff, 0xe3, 0xdd, 0xd8);
+ canvas->drawIRect(skrect, paint);
+
+ paint.setARGB(0xff, 0xc5, 0xba, 0xb0);
+ drawBox(canvas, rect, paint);
}
void ScrollbarThemeChromium::paintButton(GraphicsContext* gc, Scrollbar* scrollbar,
- const IntRect& rect, ScrollbarPart part)
+ const IntRect& rect, ScrollbarPart part)
{
- // FIXME: It appears the either we're upsetting GTK by forcing WebKit sizes
- // on it, or the buttons expect the track to be drawn under them. Either
- // way, we end up with unpainted pixels which are upsetting the pixel
- // tests. Thus we paint green under the buttons to, at least, make the
- // pixel output the same between debug and opt builds.
- SkPaint paint;
- paint.setARGB(255, 0, 255, 128);
- SkRect skrect;
- skrect.set(rect.x(), rect.y(), rect.x() + rect.width() - 1, rect.y() + rect.height() - 1);
- gc->platformContext()->canvas()->drawRect(skrect, paint);
-
- const bool horz = scrollbar->orientation() == HorizontalScrollbar;
- gint flags = horz ? 0 : MOZ_GTK_STEPPER_VERTICAL;
- flags |= ForwardButtonEndPart == part ? MOZ_GTK_STEPPER_DOWN : 0;
- paintScrollbarWidget(gc, rect, MOZ_GTK_SCROLLBAR_BUTTON, flags);
+ // We don't use buttons
}
void ScrollbarThemeChromium::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect)
{
- const bool horz = scrollbar->orientation() == HorizontalScrollbar;
- const GtkThemeWidgetType thumb_type =
- horz ? MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL : MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
- paintScrollbarWidget(gc, rect, thumb_type, 0);
+ const bool hovered = scrollbar->hoveredPart() == ThumbPart;
+ const int midx = rect.x() + rect.width() / 2;
+ const int midy = rect.y() + rect.height() / 2;
+ const bool vertical = scrollbar->orientation() == VerticalScrollbar;
+ SkCanvas* const canvas = gc->platformContext()->canvas();
+
+ SkPaint paint;
+ if (hovered)
+ paint.setARGB(0xff, 0xff, 0xff, 0xff);
+ else
+ paint.setARGB(0xff, 0xf4, 0xf2, 0xef);
+
+ SkIRect skrect;
+ if (vertical)
+ skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height());
+ else
+ skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1);
+
+ canvas->drawIRect(skrect, paint);
+
+ if (hovered)
+ paint.setARGB(0xff, 0xf4, 0xf2, 0xef);
+ else
+ paint.setARGB(0xff, 0xea, 0xe5, 0xe0);
+
+ if (vertical)
+ skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
+ else
+ skrect.set(rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height());
+
+ canvas->drawIRect(skrect, paint);
+
+ paint.setARGB(0xff, 0x9d, 0x96, 0x8e);
+ drawBox(canvas, rect, paint);
+
+ if (rect.height() > 10 && rect.width() > 10) {
+ paint.setARGB(0xff, 0x9d, 0x96, 0x8e);
+ drawHorizLine(canvas, midx - 1, midx + 3, midy, paint);
+ drawHorizLine(canvas, midx - 1, midx + 3, midy - 3, paint);
+ drawHorizLine(canvas, midx - 1, midx + 3, midy + 3, paint);
+ }
}
} // namespace WebCore
diff --git a/WebCore/platform/chromium/TemporaryLinkStubs.cpp b/WebCore/platform/chromium/TemporaryLinkStubs.cpp
index 4a028da..f6e77d4 100644
--- a/WebCore/platform/chromium/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/chromium/TemporaryLinkStubs.cpp
@@ -44,11 +44,3 @@ String KURL::fileSystemPath() const { notImplemented(); return String(); }
PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&) { notImplemented(); return 0; }
} // namespace WebCore
-
-namespace WTF {
-
-#if !defined(__linux__)
-void scheduleDispatchFunctionsOnMainThread() { notImplemented(); }
-#endif
-
-} // namespace WTF
diff --git a/WebCore/platform/graphics/BitmapImage.cpp b/WebCore/platform/graphics/BitmapImage.cpp
index 68863df..1d97632 100644
--- a/WebCore/platform/graphics/BitmapImage.cpp
+++ b/WebCore/platform/graphics/BitmapImage.cpp
@@ -53,6 +53,7 @@ BitmapImage::BitmapImage(ImageObserver* observer)
, m_repetitionsComplete(0)
, m_desiredFrameStartTime(0)
, m_isSolidColor(false)
+ , m_checkedForSolidColor(false)
, m_animationFinished(false)
, m_allDataReceived(false)
, m_haveSize(false)
diff --git a/WebCore/platform/graphics/BitmapImage.h b/WebCore/platform/graphics/BitmapImage.h
index 110aec4..db05d1c 100644
--- a/WebCore/platform/graphics/BitmapImage.h
+++ b/WebCore/platform/graphics/BitmapImage.h
@@ -166,7 +166,7 @@ protected:
virtual void drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator);
#endif
virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator);
-#if PLATFORM(QT) || PLATFORM(WX)
+#if PLATFORM(WX)
virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform,
const FloatPoint& phase, CompositeOperator, const FloatRect& destRect);
#endif
@@ -218,9 +218,18 @@ protected:
void invalidatePlatformData();
// Checks to see if the image is a 1x1 solid color. We optimize these images and just do a fill rect instead.
+ // This check should happen regardless whether m_checkedForSolidColor is already set, as the frame may have
+ // changed.
void checkForSolidColor();
- virtual bool mayFillWithSolidColor() const { return m_isSolidColor && m_currentFrame == 0; }
+ virtual bool mayFillWithSolidColor()
+ {
+ if (!m_checkedForSolidColor && frameCount() > 0) {
+ checkForSolidColor();
+ ASSERT(m_checkedForSolidColor);
+ }
+ return m_isSolidColor && m_currentFrame == 0;
+ }
virtual Color solidColor() const { return m_solidColor; }
ImageSource m_source;
@@ -242,6 +251,7 @@ protected:
Color m_solidColor; // If we're a 1x1 solid color, this is the color to use to fill.
bool m_isSolidColor; // Whether or not we are a 1x1 solid image.
+ bool m_checkedForSolidColor; // Whether we've checked the frame for solid color.
bool m_animationFinished; // Whether or not we've completed the entire animation.
diff --git a/WebCore/platform/graphics/Color.cpp b/WebCore/platform/graphics/Color.cpp
index c7e11ee..e85ac00 100644
--- a/WebCore/platform/graphics/Color.cpp
+++ b/WebCore/platform/graphics/Color.cpp
@@ -116,6 +116,15 @@ RGBA32 makeRGBAFromHSLA(double hue, double saturation, double lightness, double
static_cast<int>(alpha * scaleFactor));
}
+RGBA32 makeRGBAFromCMYKA(float c, float m, float y, float k, float a)
+{
+ double colors = 1 - k;
+ int r = static_cast<int>(nextafter(256, 0) * (colors * (1 - c)));
+ int g = static_cast<int>(nextafter(256, 0) * (colors * (1 - m)));
+ int b = static_cast<int>(nextafter(256, 0) * (colors * (1 - y)));
+ return makeRGBA(r, g, b, static_cast<float>(nextafter(256, 0) * a));
+}
+
// originally moved here from the CSS parser
bool Color::parseHexColor(const String& name, RGBA32& rgb)
{
@@ -312,4 +321,34 @@ void Color::getRGBA(double& r, double& g, double& b, double& a) const
a = alpha() / 255.0;
}
+Color colorFromPremultipliedARGB(unsigned pixelColor)
+{
+ RGBA32 rgba;
+
+ if (unsigned alpha = (pixelColor & 0xFF000000) >> 24) {
+ rgba = makeRGBA(((pixelColor & 0x00FF0000) >> 16) * 255 / alpha,
+ ((pixelColor & 0x0000FF00) >> 8) * 255 / alpha,
+ (pixelColor & 0x000000FF) * 255 / alpha,
+ alpha);
+ } else
+ rgba = pixelColor;
+
+ return Color(rgba);
+}
+
+unsigned premultipliedARGBFromColor(const Color& color)
+{
+ unsigned pixelColor;
+
+ if (unsigned alpha = color.alpha()) {
+ pixelColor = alpha << 24 |
+ ((color.red() * alpha + 254) / 255) << 16 |
+ ((color.green() * alpha + 254) / 255) << 8 |
+ ((color.blue() * alpha + 254) / 255);
+ } else
+ pixelColor = color.rgb();
+
+ return pixelColor;
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/graphics/Color.h b/WebCore/platform/graphics/Color.h
index 61fc74c..3c889f9 100644
--- a/WebCore/platform/graphics/Color.h
+++ b/WebCore/platform/graphics/Color.h
@@ -60,6 +60,7 @@ RGBA32 makeRGBA(int r, int g, int b, int a);
RGBA32 colorWithOverrideAlpha(RGBA32 color, float overrideAlpha);
RGBA32 makeRGBA32FromFloats(float r, float g, float b, float a);
RGBA32 makeRGBAFromHSLA(double h, double s, double l, double a);
+RGBA32 makeRGBAFromCMYKA(float c, float m, float y, float k, float a);
int differenceSquared(const Color&, const Color&);
@@ -71,6 +72,8 @@ public:
Color(int r, int g, int b, int a) : m_color(makeRGBA(r, g, b, a)), m_valid(true) { }
// Color is currently limited to 32bit RGBA, perhaps some day we'll support better colors
Color(float r, float g, float b, float a) : m_color(makeRGBA32FromFloats(r, g, b, a)), m_valid(true) { }
+ // Creates a new color from the specific CMYK and alpha values.
+ Color(float c, float m, float y, float k, float a) : m_color(makeRGBAFromCMYKA(c, m, y, k, a)), m_valid(true) { }
explicit Color(const String&);
explicit Color(const char*);
@@ -146,9 +149,11 @@ inline bool operator!=(const Color& a, const Color& b)
}
Color focusRingColor();
+Color colorFromPremultipliedARGB(unsigned);
+unsigned premultipliedARGBFromColor(const Color&);
#if PLATFORM(CG)
-CGColorRef cgColor(const Color&);
+CGColorRef createCGColor(const Color&);
#endif
} // namespace WebCore
diff --git a/WebCore/platform/graphics/FloatPoint.cpp b/WebCore/platform/graphics/FloatPoint.cpp
index 564ea86..7765ba9 100644
--- a/WebCore/platform/graphics/FloatPoint.cpp
+++ b/WebCore/platform/graphics/FloatPoint.cpp
@@ -40,7 +40,7 @@ FloatPoint::FloatPoint(const IntPoint& p) : m_x(p.x()), m_y(p.y())
FloatPoint FloatPoint::matrixTransform(const TransformationMatrix& transform) const
{
double newX, newY;
- transform.map(static_cast<double>(m_x), static_cast<double>(m_y), &newX, &newY);
+ transform.map(static_cast<double>(m_x), static_cast<double>(m_y), newX, newY);
return narrowPrecision(newX, newY);
}
diff --git a/WebCore/platform/graphics/FloatPoint3D.cpp b/WebCore/platform/graphics/FloatPoint3D.cpp
index e3ba422..8c21ef3 100644
--- a/WebCore/platform/graphics/FloatPoint3D.cpp
+++ b/WebCore/platform/graphics/FloatPoint3D.cpp
@@ -21,7 +21,6 @@
#include "config.h"
-#if ENABLE(SVG)
#include <math.h>
#include "FloatPoint.h"
#include "FloatPoint3D.h"
@@ -62,4 +61,3 @@ void FloatPoint3D::normalize()
} // namespace WebCore
-#endif // ENABLE(SVG)
diff --git a/WebCore/platform/graphics/FloatPoint3D.h b/WebCore/platform/graphics/FloatPoint3D.h
index 184e914..2e71ddd 100644
--- a/WebCore/platform/graphics/FloatPoint3D.h
+++ b/WebCore/platform/graphics/FloatPoint3D.h
@@ -22,8 +22,6 @@
#ifndef FloatPoint3D_h
#define FloatPoint3D_h
-#if ENABLE(SVG)
-
namespace WebCore {
class FloatPoint;
@@ -53,6 +51,4 @@ private:
} // namespace WebCore
-#endif // ENABLE(SVG)
-
#endif // FloatPoint3D_h
diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp
index 2d219be..130313d 100644
--- a/WebCore/platform/graphics/FontCache.cpp
+++ b/WebCore/platform/graphics/FontCache.cpp
@@ -139,8 +139,13 @@ static const AtomicString& alternateFamilyName(const AtomicString& familyName)
DEFINE_STATIC_LOCAL(AtomicString, courierNew, ("Courier New"));
if (equalIgnoringCase(familyName, courier))
return courierNew;
+#if !PLATFORM(WIN_OS)
+ // On Windows, Courier New (truetype font) is always present and
+ // Courier is a bitmap font. So, we don't want to map Courier New to
+ // Courier.
if (equalIgnoringCase(familyName, courierNew))
return courier;
+#endif
// Alias Times and Times New Roman.
DEFINE_STATIC_LOCAL(AtomicString, times, ("Times"));
@@ -158,6 +163,21 @@ static const AtomicString& alternateFamilyName(const AtomicString& familyName)
if (equalIgnoringCase(familyName, helvetica))
return arial;
+#if PLATFORM(WIN_OS)
+ // On Windows, bitmap fonts are blocked altogether so that we have to
+ // alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font)
+ DEFINE_STATIC_LOCAL(AtomicString, msSans, ("MS Sans Serif"));
+ DEFINE_STATIC_LOCAL(AtomicString, microsoftSans, ("Microsoft Sans Serif"));
+ if (equalIgnoringCase(familyName, msSans))
+ return microsoftSans;
+
+ // Alias MS Serif (bitmap) -> Times New Roman (truetype font). There's no
+ // 'Microsoft Sans Serif-equivalent' for Serif.
+ static AtomicString msSerif("MS Serif");
+ if (equalIgnoringCase(familyName, msSerif))
+ return timesNewRoman;
+#endif
+
return emptyAtom;
}
@@ -216,7 +236,7 @@ struct FontDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformData> {
static const bool needsDestruction = true;
static const FontPlatformData& emptyValue()
{
- DEFINE_STATIC_LOCAL(FontPlatformData, key, ());
+ DEFINE_STATIC_LOCAL(FontPlatformData, key, (0.f, false, false));
return key;
}
static void constructDeletedValue(FontPlatformData& slot)
@@ -304,7 +324,7 @@ void FontCache::purgeInactiveFontData(int count)
}
Vector<FontPlatformDataCacheKey> keysToRemove;
- keysToRemove.reserveCapacity(gFontPlatformDataCache->size());
+ keysToRemove.reserveInitialCapacity(gFontPlatformDataCache->size());
FontPlatformDataCache::iterator platformDataEnd = gFontPlatformDataCache->end();
for (FontPlatformDataCache::iterator platformData = gFontPlatformDataCache->begin(); platformData != platformDataEnd; ++platformData) {
if (platformData->second && !gFontDataCache->contains(*platformData->second))
@@ -424,7 +444,7 @@ void FontCache::invalidate()
Vector<RefPtr<FontSelector> > clients;
size_t numClients = gClients->size();
- clients.reserveCapacity(numClients);
+ clients.reserveInitialCapacity(numClients);
HashSet<FontSelector*>::iterator end = gClients->end();
for (HashSet<FontSelector*>::iterator it = gClients->begin(); it != end; ++it)
clients.append(*it);
diff --git a/WebCore/platform/graphics/GlyphBuffer.h b/WebCore/platform/graphics/GlyphBuffer.h
index fdb306f..dcda419 100644
--- a/WebCore/platform/graphics/GlyphBuffer.h
+++ b/WebCore/platform/graphics/GlyphBuffer.h
@@ -37,7 +37,7 @@
#include <ApplicationServices/ApplicationServices.h>
#endif
-#if PLATFORM(CAIRO)
+#if PLATFORM(CAIRO) || (PLATFORM(WX) && defined(__WXGTK__))
#include <cairo.h>
#endif
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index 6b9d23d..bd838de 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -218,6 +218,7 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
}
haveGlyphs |= pageToFill->fill(from, to - from, buffer + from * (start < 0x10000 ? 1 : 2), (to - from) * (start < 0x10000 ? 1 : 2), range.fontData());
if (scratchPage) {
+ ASSERT(to <= static_cast<int>(GlyphPage::size));
for (int j = from; j < to; j++) {
if (!m_page->m_glyphs[j].glyph && pageToFill->m_glyphs[j].glyph)
m_page->m_glyphs[j] = pageToFill->m_glyphs[j];
diff --git a/WebCore/platform/graphics/GlyphWidthMap.cpp b/WebCore/platform/graphics/GlyphWidthMap.cpp
index 6e8d68d..43cab65 100644
--- a/WebCore/platform/graphics/GlyphWidthMap.cpp
+++ b/WebCore/platform/graphics/GlyphWidthMap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,43 +29,22 @@
#include "config.h"
#include "GlyphWidthMap.h"
-namespace WebCore
-{
-
-float GlyphWidthMap::widthForGlyph(Glyph g)
-{
- unsigned pageNumber = (g / GlyphWidthPage::size);
- GlyphWidthPage* page = locatePage(pageNumber);
- if (page)
- return page->widthForGlyph(g);
- return cGlyphWidthUnknown;
-}
-
-void GlyphWidthMap::setWidthForGlyph(Glyph glyph, float width)
-{
- unsigned pageNumber = (glyph / GlyphWidthPage::size);
- GlyphWidthPage* page = locatePage(pageNumber);
- if (page)
- page->setWidthForGlyph(glyph, width);
-}
+namespace WebCore {
-inline GlyphWidthMap::GlyphWidthPage* GlyphWidthMap::locatePage(unsigned pageNumber)
+GlyphWidthMap::GlyphWidthPage* GlyphWidthMap::locatePageSlowCase(unsigned pageNumber)
{
GlyphWidthPage* page;
if (pageNumber == 0) {
- if (m_filledPrimaryPage)
- return &m_primaryPage;
+ ASSERT(!m_filledPrimaryPage);
page = &m_primaryPage;
m_filledPrimaryPage = true;
} else {
if (m_pages) {
- GlyphWidthPage* result = m_pages->get(pageNumber);
- if (result)
- return result;
- }
+ if ((page = m_pages->get(pageNumber)))
+ return page;
+ } else
+ m_pages.set(new HashMap<int, GlyphWidthPage*>);
page = new GlyphWidthPage;
- if (!m_pages)
- m_pages = new HashMap<int, GlyphWidthPage*>;
m_pages->set(pageNumber, page);
}
diff --git a/WebCore/platform/graphics/GlyphWidthMap.h b/WebCore/platform/graphics/GlyphWidthMap.h
index 1633769..e194ecf 100644
--- a/WebCore/platform/graphics/GlyphWidthMap.h
+++ b/WebCore/platform/graphics/GlyphWidthMap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,9 +29,9 @@
#ifndef GlyphWidthMap_h
#define GlyphWidthMap_h
-#include <wtf/unicode/Unicode.h>
-#include <wtf/Noncopyable.h>
#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/unicode/Unicode.h>
namespace WebCore {
@@ -41,34 +41,49 @@ const float cGlyphWidthUnknown = -1;
class GlyphWidthMap : Noncopyable {
public:
- GlyphWidthMap() : m_filledPrimaryPage(false), m_pages(0) {}
- ~GlyphWidthMap() { if (m_pages) { deleteAllValues(*m_pages); delete m_pages; } }
+ GlyphWidthMap() : m_filledPrimaryPage(false) { }
+ ~GlyphWidthMap() { if (m_pages) { deleteAllValues(*m_pages); } }
+
+ float widthForGlyph(Glyph glyph)
+ {
+ return locatePage(glyph / GlyphWidthPage::size)->widthForGlyph(glyph);
+ }
- float widthForGlyph(Glyph);
- void setWidthForGlyph(Glyph, float);
+ void setWidthForGlyph(Glyph glyph, float width)
+ {
+ locatePage(glyph / GlyphWidthPage::size)->setWidthForGlyph(glyph, width);
+ }
private:
struct GlyphWidthPage {
static const size_t size = 256; // Usually covers Latin-1 in a single page.
float m_widths[size];
- float widthForGlyph(Glyph g) const { return m_widths[g % size]; }
- void setWidthForGlyph(Glyph g, float w)
+ float widthForGlyph(Glyph glyph) const { return m_widths[glyph % size]; }
+ void setWidthForGlyph(Glyph glyph, float width)
{
- setWidthForIndex(g % size, w);
+ setWidthForIndex(glyph % size, width);
}
- void setWidthForIndex(unsigned index, float w)
+ void setWidthForIndex(unsigned index, float width)
{
- m_widths[index] = w;
+ m_widths[index] = width;
}
};
- GlyphWidthPage* locatePage(unsigned page);
+ GlyphWidthPage* locatePage(unsigned pageNumber)
+ {
+ if (!pageNumber && m_filledPrimaryPage)
+ return &m_primaryPage;
+ return locatePageSlowCase(pageNumber);
+ }
+
+ GlyphWidthPage* locatePageSlowCase(unsigned pageNumber);
bool m_filledPrimaryPage;
GlyphWidthPage m_primaryPage; // We optimize for the page that contains glyph indices 0-255.
- HashMap<int, GlyphWidthPage*>* m_pages;
+ OwnPtr<HashMap<int, GlyphWidthPage*> > m_pages;
};
}
+
#endif
diff --git a/WebCore/platform/graphics/Gradient.cpp b/WebCore/platform/graphics/Gradient.cpp
index 2e6a5d2..24e8bbf 100644
--- a/WebCore/platform/graphics/Gradient.cpp
+++ b/WebCore/platform/graphics/Gradient.cpp
@@ -39,6 +39,7 @@ Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1)
, m_r1(0)
, m_stopsSorted(false)
, m_lastStop(0)
+ , m_spreadMethod(SpreadMethodPad)
{
platformInit();
}
@@ -146,4 +147,11 @@ int Gradient::findStop(float value) const
return m_lastStop;
}
+void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod)
+{
+ // FIXME: Should it become necessary, allow calls to this method after m_gradient has been set.
+ ASSERT(m_gradient == 0);
+ m_spreadMethod = spreadMethod;
+}
+
} //namespace
diff --git a/WebCore/platform/graphics/Gradient.h b/WebCore/platform/graphics/Gradient.h
index 00ef2b6..764deee 100644
--- a/WebCore/platform/graphics/Gradient.h
+++ b/WebCore/platform/graphics/Gradient.h
@@ -29,6 +29,8 @@
#include "FloatPoint.h"
#include "Generator.h"
+#include "GraphicsTypes.h"
+#include "TransformationMatrix.h"
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
@@ -93,6 +95,12 @@ namespace WebCore {
void setStopsSorted(bool s) { m_stopsSorted = s; }
+ void setSpreadMethod(GradientSpreadMethod);
+ GradientSpreadMethod spreadMethod() { return m_spreadMethod; }
+ void setGradientSpaceTransform(const TransformationMatrix& gradientSpaceTransformation) { m_gradientSpaceTransformation = gradientSpaceTransformation; }
+ // Qt and CG transform the gradient at draw time
+ TransformationMatrix gradientSpaceTransform() { return m_gradientSpaceTransformation; }
+
virtual void fill(GraphicsContext*, const FloatRect&);
private:
@@ -112,6 +120,8 @@ namespace WebCore {
mutable Vector<ColorStop> m_stops;
mutable bool m_stopsSorted;
mutable int m_lastStop;
+ GradientSpreadMethod m_spreadMethod;
+ TransformationMatrix m_gradientSpaceTransformation;
PlatformGradient m_gradient;
};
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index 8426011..8cad794 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -128,6 +128,11 @@ void GraphicsContext::setStrokeColor(const Color& color)
setPlatformStrokeColor(color);
}
+ColorSpace GraphicsContext::strokeColorSpace() const
+{
+ return m_common->state.strokeColorSpace;
+}
+
void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& color)
{
m_common->state.shadowSize = size;
@@ -178,16 +183,6 @@ void GraphicsContext::setFillRule(WindRule fillRule)
m_common->state.fillRule = fillRule;
}
-GradientSpreadMethod GraphicsContext::spreadMethod() const
-{
- return m_common->state.spreadMethod;
-}
-
-void GraphicsContext::setSpreadMethod(GradientSpreadMethod spreadMethod)
-{
- m_common->state.spreadMethod = spreadMethod;
-}
-
void GraphicsContext::setFillColor(const Color& color)
{
m_common->state.fillColorSpace = SolidColorSpace;
@@ -255,6 +250,31 @@ void GraphicsContext::setFillGradient(PassRefPtr<Gradient> gradient)
m_common->state.fillGradient = gradient;
}
+Gradient* GraphicsContext::fillGradient() const
+{
+ return m_common->state.fillGradient.get();
+}
+
+ColorSpace GraphicsContext::fillColorSpace() const
+{
+ return m_common->state.fillColorSpace;
+}
+
+Gradient* GraphicsContext::strokeGradient() const
+{
+ return m_common->state.strokeGradient.get();
+}
+
+Pattern* GraphicsContext::fillPattern() const
+{
+ return m_common->state.fillPattern.get();
+}
+
+Pattern* GraphicsContext::strokePattern() const
+{
+ return m_common->state.strokePattern.get();
+}
+
void GraphicsContext::setShadowsIgnoreTransforms(bool ignoreTransforms)
{
m_common->state.shadowsIgnoreTransforms = ignoreTransforms;
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index c27f38f..7c1c4b0 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -123,6 +123,18 @@ namespace WebCore {
DashedStroke
};
+// FIXME: This is a place-holder until we decide to add
+// real color space support to WebCore. At that time, ColorSpace will be a
+// class and instances will be held off of Colors. There will be
+// special singleton Gradient and Pattern color spaces to mark when
+// a fill or stroke is using a gradient or pattern instead of a solid color.
+// https://bugs.webkit.org/show_bug.cgi?id=20558
+ enum ColorSpace {
+ SolidColorSpace,
+ PatternColorSpace,
+ GradientColorSpace
+ };
+
enum InterpolationQuality {
InterpolationDefault,
InterpolationNone,
@@ -131,14 +143,6 @@ namespace WebCore {
InterpolationHigh
};
- // FIXME: Currently these constants have to match the values used in the SVG
- // DOM API. That's a mistake. We need to make cut that dependency.
- enum GradientSpreadMethod {
- SpreadMethodPad = 1,
- SpreadMethodReflect = 2,
- SpreadMethodRepeat = 3
- };
-
class GraphicsContext : Noncopyable {
public:
GraphicsContext(PlatformGraphicsContext*);
@@ -152,17 +156,28 @@ namespace WebCore {
void setStrokeStyle(const StrokeStyle& style);
Color strokeColor() const;
void setStrokeColor(const Color&);
+
+ ColorSpace strokeColorSpace() const;
+
void setStrokePattern(PassRefPtr<Pattern>);
+ Pattern* strokePattern() const;
+
void setStrokeGradient(PassRefPtr<Gradient>);
+ Gradient* strokeGradient() const;
WindRule fillRule() const;
void setFillRule(WindRule);
- GradientSpreadMethod spreadMethod() const;
- void setSpreadMethod(GradientSpreadMethod);
Color fillColor() const;
void setFillColor(const Color&);
+
void setFillPattern(PassRefPtr<Pattern>);
+ Pattern* fillPattern() const;
+
void setFillGradient(PassRefPtr<Gradient>);
+ Gradient* fillGradient() const;
+
+ ColorSpace fillColorSpace() const;
+
void setShadowsIgnoreTransforms(bool);
void setShouldAntialias(bool);
@@ -206,6 +221,9 @@ namespace WebCore {
void restore();
// These draw methods will do both stroking and filling.
+ // FIXME: ...except drawRect(), which fills properly but always strokes
+ // using a 1-pixel stroke inset from the rect borders (of the correct
+ // stroke color).
void drawRect(const IntRect&);
void drawLine(const IntPoint&, const IntPoint&);
void drawEllipse(const IntRect&);
@@ -402,3 +420,4 @@ namespace WebCore {
} // namespace WebCore
#endif // GraphicsContext_h
+
diff --git a/WebCore/platform/graphics/GraphicsContextPrivate.h b/WebCore/platform/graphics/GraphicsContextPrivate.h
index 87123eb..98baab1 100644
--- a/WebCore/platform/graphics/GraphicsContextPrivate.h
+++ b/WebCore/platform/graphics/GraphicsContextPrivate.h
@@ -33,18 +33,6 @@
namespace WebCore {
-// FIXME: This is a place-holder until we decide to add
-// real color space support to WebCore. At that time, ColorSpace will be a
-// class and instances will be held off of Colors. There will be
-// special singleton Gradient and Pattern color spaces to mark when
-// a fill or stroke is using a gradient or pattern instead of a solid color.
-// https://bugs.webkit.org/show_bug.cgi?id=20558
- enum ColorSpace {
- SolidColorSpace,
- PatternColorSpace,
- GradientColorSpace
- };
-
struct GraphicsContextState {
GraphicsContextState()
: textDrawingMode(cTextFill)
@@ -80,7 +68,6 @@ namespace WebCore {
RefPtr<Pattern> strokePattern;
WindRule fillRule;
- GradientSpreadMethod spreadMethod;
ColorSpace fillColorSpace;
Color fillColor;
RefPtr<Gradient> fillGradient;
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
new file mode 100644
index 0000000..0c442a2
--- /dev/null
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GraphicsLayer.h"
+
+#include "FloatPoint.h"
+#include "RotateTransformOperation.h"
+#include "TextStream.h"
+
+namespace WebCore {
+
+void GraphicsLayer::FloatValue::set(float key, float value, const TimingFunction* timingFunction)
+{
+ m_key = key;
+ m_value = value;
+ if (timingFunction != m_timingFunction) {
+ if (timingFunction)
+ m_timingFunction.set(new TimingFunction(*timingFunction));
+ else
+ m_timingFunction.clear();
+ }
+}
+
+void GraphicsLayer::TransformValue::set(float key, const TransformOperations* value, const TimingFunction* timingFunction)
+{
+ m_key = key;
+ if (value != m_value) {
+ if (value)
+ m_value.set(new TransformOperations(*value));
+ else
+ m_value.clear();
+ }
+ if (timingFunction != m_timingFunction) {
+ if (timingFunction)
+ m_timingFunction.set(new TimingFunction(*timingFunction));
+ else
+ m_timingFunction.clear();
+ }
+}
+
+void GraphicsLayer::FloatValueList::insert(float key, float value, const TimingFunction* timingFunction)
+{
+ for (size_t i = 0; i < m_values.size(); ++i) {
+ FloatValue& curFloatValue = m_values[i];
+ if (curFloatValue.key() == key) {
+ curFloatValue.set(key, value, timingFunction);
+ return;
+ }
+ if (curFloatValue.key() > key) {
+ // insert before
+ m_values.insert(i, FloatValue(key, value, timingFunction));
+ return;
+ }
+ }
+
+ // append
+ m_values.append(FloatValue(key, value, timingFunction));
+}
+
+void GraphicsLayer::TransformValueList::insert(float key, const TransformOperations* value, const TimingFunction* timingFunction)
+{
+ for (size_t i = 0; i < m_values.size(); ++i) {
+ TransformValue& curTransValue = m_values[i];
+ if (curTransValue.key() == key) {
+ curTransValue.set(key, value, timingFunction);
+ return;
+ }
+ if (curTransValue.key() > key) {
+ // insert before
+ m_values.insert(i, TransformValue(key, value, timingFunction));
+ return;
+ }
+ }
+
+ // append
+ m_values.append(TransformValue(key, value, timingFunction));
+}
+
+// An "invalid" list is one whose functions don't match, and therefore has to be animated as a Matrix
+// The hasBigRotation flag will always return false if isValid is false. Otherwise hasBigRotation is
+// true if the rotation between any two keyframes is >= 180 degrees.
+void GraphicsLayer::TransformValueList::makeFunctionList(FunctionList& list, bool& isValid, bool& hasBigRotation) const
+{
+ list.clear();
+ isValid = false;
+ hasBigRotation = false;
+
+ if (m_values.size() < 2)
+ return;
+
+ // empty transforms match anything, so find the first non-empty entry as the reference
+ size_t firstIndex = 0;
+ for ( ; firstIndex < m_values.size(); ++firstIndex) {
+ if (m_values[firstIndex].value()->operations().size() > 0)
+ break;
+ }
+
+ if (firstIndex >= m_values.size())
+ return;
+
+ const TransformOperations* firstVal = m_values[firstIndex].value();
+
+ // see if the keyframes are valid
+ for (size_t i = firstIndex + 1; i < m_values.size(); ++i) {
+ const TransformOperations* val = m_values[i].value();
+
+ // a null transform matches anything
+ if (val->operations().isEmpty())
+ continue;
+
+ if (firstVal->operations().size() != val->operations().size())
+ return;
+
+ for (size_t j = 0; j < firstVal->operations().size(); ++j) {
+ if (!firstVal->operations().at(j)->isSameType(*val->operations().at(j)))
+ return;
+ }
+ }
+
+ // keyframes are valid, fill in the list
+ isValid = true;
+
+ double lastRotAngle = 0.0;
+ double maxRotAngle = -1.0;
+
+ list.resize(firstVal->operations().size());
+ for (size_t j = 0; j < firstVal->operations().size(); ++j) {
+ TransformOperation::OperationType type = firstVal->operations().at(j)->getOperationType();
+ list[j] = type;
+
+ // if this is a rotation entry, we need to see if any angle differences are >= 180 deg
+ if (type == TransformOperation::ROTATE_X ||
+ type == TransformOperation::ROTATE_Y ||
+ type == TransformOperation::ROTATE_Z ||
+ type == TransformOperation::ROTATE_3D) {
+ lastRotAngle = static_cast<RotateTransformOperation*>(firstVal->operations().at(j).get())->angle();
+
+ if (maxRotAngle < 0)
+ maxRotAngle = fabs(lastRotAngle);
+
+ for (size_t i = firstIndex + 1; i < m_values.size(); ++i) {
+ const TransformOperations* val = m_values[i].value();
+ double rotAngle = val->operations().isEmpty() ? 0 : (static_cast<RotateTransformOperation*>(val->operations().at(j).get())->angle());
+ double diffAngle = fabs(rotAngle - lastRotAngle);
+ if (diffAngle > maxRotAngle)
+ maxRotAngle = diffAngle;
+ lastRotAngle = rotAngle;
+ }
+ }
+ }
+
+ hasBigRotation = maxRotAngle >= 180.0;
+}
+
+GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
+ : m_client(client)
+ , m_anchorPoint(0.5f, 0.5f, 0)
+ , m_opacity(1)
+#ifndef NDEBUG
+ , m_zPosition(0)
+#endif
+ , m_backgroundColorSet(false)
+ , m_contentsOpaque(false)
+ , m_preserves3D(false)
+ , m_backfaceVisibility(true)
+ , m_usingTiledLayer(false)
+ , m_masksToBounds(false)
+ , m_drawsContent(false)
+ , m_paintingPhase(GraphicsLayerPaintAllMask)
+ , m_parent(0)
+#ifndef NDEBUG
+ , m_repaintCount(0)
+#endif
+{
+}
+
+GraphicsLayer::~GraphicsLayer()
+{
+ removeAllAnimations();
+
+ removeAllChildren();
+ removeFromParent();
+}
+
+void GraphicsLayer::addChild(GraphicsLayer* childLayer)
+{
+ ASSERT(childLayer != this);
+
+ if (childLayer->parent())
+ childLayer->removeFromParent();
+
+ childLayer->setParent(this);
+ m_children.append(childLayer);
+}
+
+void GraphicsLayer::addChildAtIndex(GraphicsLayer* childLayer, int index)
+{
+ ASSERT(childLayer != this);
+
+ if (childLayer->parent())
+ childLayer->removeFromParent();
+
+ childLayer->setParent(this);
+ m_children.insert(index, childLayer);
+}
+
+void GraphicsLayer::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
+{
+ ASSERT(childLayer != this);
+ childLayer->removeFromParent();
+
+ bool found = false;
+ for (unsigned i = 0; i < m_children.size(); i++) {
+ if (sibling == m_children[i]) {
+ m_children.insert(i, childLayer);
+ found = true;
+ break;
+ }
+ }
+
+ childLayer->setParent(this);
+
+ if (!found)
+ m_children.append(childLayer);
+}
+
+void GraphicsLayer::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
+{
+ childLayer->removeFromParent();
+ ASSERT(childLayer != this);
+
+ bool found = false;
+ for (unsigned i = 0; i < m_children.size(); i++) {
+ if (sibling == m_children[i]) {
+ m_children.insert(i+1, childLayer);
+ found = true;
+ break;
+ }
+ }
+
+ childLayer->setParent(this);
+
+ if (!found)
+ m_children.append(childLayer);
+}
+
+bool GraphicsLayer::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
+{
+ ASSERT(!newChild->parent());
+ bool found = false;
+ for (unsigned i = 0; i < m_children.size(); i++) {
+ if (oldChild == m_children[i]) {
+ m_children[i] = newChild;
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ oldChild->setParent(0);
+
+ newChild->removeFromParent();
+ newChild->setParent(this);
+ return true;
+ }
+ return false;
+}
+
+void GraphicsLayer::removeAllChildren()
+{
+ while (m_children.size()) {
+ GraphicsLayer* curLayer = m_children[0];
+ ASSERT(curLayer->parent());
+ curLayer->removeFromParent();
+ }
+}
+
+void GraphicsLayer::removeFromParent()
+{
+ if (m_parent) {
+ unsigned i;
+ for (i = 0; i < m_parent->m_children.size(); i++) {
+ if (this == m_parent->m_children[i]) {
+ m_parent->m_children.remove(i);
+ break;
+ }
+ }
+
+ setParent(0);
+ }
+}
+
+void GraphicsLayer::setBackgroundColor(const Color& inColor, const Animation*, double /*beginTime*/)
+{
+ m_backgroundColor = inColor;
+ m_backgroundColorSet = true;
+}
+
+void GraphicsLayer::clearBackgroundColor()
+{
+ m_backgroundColor = Color();
+ m_backgroundColorSet = false;
+}
+
+bool GraphicsLayer::setOpacity(float opacity, const Animation*, double)
+{
+ m_opacity = opacity;
+ return false; // not animating
+}
+
+void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const IntRect& clip)
+{
+ m_client->paintContents(this, context, m_paintingPhase, clip);
+}
+
+String GraphicsLayer::propertyIdToString(AnimatedPropertyID property)
+{
+ switch (property) {
+ case AnimatedPropertyWebkitTransform:
+ return "transform";
+ case AnimatedPropertyOpacity:
+ return "opacity";
+ case AnimatedPropertyBackgroundColor:
+ return "backgroundColor";
+ case AnimatedPropertyInvalid:
+ ASSERT_NOT_REACHED();
+ }
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+int GraphicsLayer::findAnimationEntry(AnimatedPropertyID property, short index) const
+{
+ for (size_t i = 0; i < m_animations.size(); ++i) {
+ if (m_animations[i].matches(property, index))
+ return static_cast<int>(i);
+ }
+ return -1;
+}
+
+void GraphicsLayer::addAnimationEntry(AnimatedPropertyID property, short index, bool isTransition, const Animation* transition)
+{
+ int i = findAnimationEntry(property, index);
+
+ if (i >= 0)
+ m_animations[i].reset(transition, isTransition);
+ else
+ m_animations.append(AnimationEntry(transition, property, index, isTransition));
+}
+
+void GraphicsLayer::removeAllAnimations()
+{
+ size_t size = m_animations.size();
+ for (size_t i = 0; i < size; ++i)
+ removeAnimation(0, true);
+}
+
+void GraphicsLayer::removeAllAnimationsForProperty(AnimatedPropertyID property)
+{
+ for (short j = 0; ; ++j) {
+ int i = findAnimationEntry(property, j);
+ if (i < 0)
+ break;
+ removeAnimation(i, false);
+ }
+}
+
+void GraphicsLayer::removeFinishedAnimations(const String& name, int /*index*/, bool reset)
+{
+ size_t size = m_animations.size();
+ for (size_t i = 0; i < size; ) {
+ AnimationEntry& anim = m_animations[i];
+ if (!anim.isTransition() && anim.animation()->name() == name) {
+ removeAnimation(i, reset);
+ --size;
+ } else
+ ++i;
+ }
+}
+
+void GraphicsLayer::removeFinishedTransitions(AnimatedPropertyID property)
+{
+ size_t size = m_animations.size();
+ for (size_t i = 0; i < size; ) {
+ AnimationEntry& anim = m_animations[i];
+ if (anim.isTransition() && property == anim.property()) {
+ removeAnimation(i, false);
+ --size;
+ } else
+ ++i;
+ }
+}
+
+void GraphicsLayer::suspendAnimations()
+{
+}
+
+void GraphicsLayer::resumeAnimations()
+{
+}
+
+#ifndef NDEBUG
+void GraphicsLayer::updateDebugIndicators()
+{
+ if (GraphicsLayer::showDebugBorders()) {
+ if (drawsContent()) {
+ if (m_usingTiledLayer)
+ setDebugBorder(Color(0, 255, 0, 204), 2.0f); // tiled layer: green
+ else
+ setDebugBorder(Color(255, 0, 0, 204), 2.0f); // normal layer: red
+ } else if (masksToBounds()) {
+ setDebugBorder(Color(128, 255, 255, 178), 2.0f); // masking layer: pale blue
+ if (GraphicsLayer::showDebugBorders())
+ setDebugBackgroundColor(Color(128, 255, 255, 52));
+ } else
+ setDebugBorder(Color(255, 255, 0, 204), 2.0f); // container: yellow
+ }
+}
+
+void GraphicsLayer::setZPosition(float position)
+{
+ m_zPosition = position;
+}
+#endif
+
+static void writeIndent(TextStream& ts, int indent)
+{
+ for (int i = 0; i != indent; ++i)
+ ts << " ";
+}
+
+void GraphicsLayer::dumpLayer(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "(" << "GraphicsLayer" << " " << static_cast<void*>(const_cast<GraphicsLayer*>(this));
+ ts << " \"" << m_name << "\"\n";
+ dumpProperties(ts, indent);
+ writeIndent(ts, indent);
+ ts << ")\n";
+}
+
+void GraphicsLayer::dumpProperties(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent + 1);
+ ts << "(position " << m_position.x() << " " << m_position.y() << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(anchor " << m_anchorPoint.x() << " " << m_anchorPoint.y() << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(bounds " << m_size.width() << " " << m_size.height() << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(opacity " << m_opacity << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(usingTiledLayer " << m_usingTiledLayer << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(m_preserves3D " << m_preserves3D << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(drawsContent " << m_drawsContent << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(m_backfaceVisibility " << (m_backfaceVisibility ? "visible" : "hidden") << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(client ";
+ if (m_client)
+ ts << static_cast<void*>(m_client);
+ else
+ ts << "none";
+ ts << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(backgroundColor ";
+ if (!m_backgroundColorSet)
+ ts << "none";
+ else
+ ts << m_backgroundColor.name();
+ ts << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(transform ";
+ if (m_transform.isIdentity())
+ ts << "identity";
+ else {
+ ts << "[" << m_transform.m11() << " " << m_transform.m12() << " " << m_transform.m13() << " " << m_transform.m14() << "] ";
+ ts << "[" << m_transform.m21() << " " << m_transform.m22() << " " << m_transform.m23() << " " << m_transform.m24() << "] ";
+ ts << "[" << m_transform.m31() << " " << m_transform.m32() << " " << m_transform.m33() << " " << m_transform.m34() << "] ";
+ ts << "[" << m_transform.m41() << " " << m_transform.m42() << " " << m_transform.m43() << " " << m_transform.m44() << "]";
+ }
+ ts << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(childrenTransform ";
+ if (m_childrenTransform.isIdentity())
+ ts << "identity";
+ else {
+ ts << "[" << m_childrenTransform.m11() << " " << m_childrenTransform.m12() << " " << m_childrenTransform.m13() << " " << m_childrenTransform.m14() << "] ";
+ ts << "[" << m_childrenTransform.m21() << " " << m_childrenTransform.m22() << " " << m_childrenTransform.m23() << " " << m_childrenTransform.m24() << "] ";
+ ts << "[" << m_childrenTransform.m31() << " " << m_childrenTransform.m32() << " " << m_childrenTransform.m33() << " " << m_childrenTransform.m34() << "] ";
+ ts << "[" << m_childrenTransform.m41() << " " << m_childrenTransform.m42() << " " << m_childrenTransform.m43() << " " << m_childrenTransform.m44() << "]";
+ }
+ ts << ")\n";
+
+ writeIndent(ts, indent + 1);
+ ts << "(children " << m_children.size() << "\n";
+
+ unsigned i;
+ for (i = 0; i < m_children.size(); i++)
+ m_children[i]->dumpLayer(ts, indent+2);
+ writeIndent(ts, indent + 1);
+ ts << ")\n";
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
new file mode 100644
index 0000000..f928ce8
--- /dev/null
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsLayer_h
+#define GraphicsLayer_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "Animation.h"
+#include "Color.h"
+#include "FloatPoint.h"
+#include "FloatPoint3D.h"
+#include "FloatSize.h"
+#include "GraphicsLayerClient.h"
+#include "TransformationMatrix.h"
+#include "TransformOperations.h"
+#include <wtf/OwnPtr.h>
+
+#if PLATFORM(MAC)
+#ifdef __OBJC__
+@class WebLayer;
+@class CALayer;
+typedef WebLayer PlatformLayer;
+typedef CALayer* NativeLayer;
+#else
+typedef void* PlatformLayer;
+typedef void* NativeLayer;
+#endif
+#else
+typedef void* PlatformLayer;
+typedef void* NativeLayer;
+#endif
+
+namespace WebCore {
+
+class FloatPoint3D;
+class GraphicsContext;
+class Image;
+class TextStream;
+class TimingFunction;
+
+// GraphicsLayer is an abstraction for a rendering surface with backing store,
+// which may have associated transformation and animations.
+
+class GraphicsLayer {
+public:
+ // Used to store one float value of a keyframe animation.
+ class FloatValue {
+ public:
+ FloatValue(float key, float value, const TimingFunction* timingFunction = 0)
+ : m_key(key), m_value(value), m_timingFunction(0)
+ {
+ if (timingFunction)
+ m_timingFunction.set(new TimingFunction(*timingFunction));
+ }
+
+ FloatValue(const FloatValue& other)
+ : m_key(other.key()), m_value(other.value()), m_timingFunction(0)
+ {
+ if (other.timingFunction())
+ m_timingFunction.set(new TimingFunction(*other.timingFunction()));
+ }
+
+ const FloatValue& operator=(const FloatValue& other)
+ {
+ if (&other != this)
+ set(other.key(), other.value(), other.timingFunction());
+ return *this;
+ }
+
+ void set(float key, float value, const TimingFunction*);
+
+ float key() const { return m_key; }
+ float value() const { return m_value; }
+ const TimingFunction* timingFunction() const { return m_timingFunction.get(); }
+
+ private:
+ float m_key;
+ float m_value;
+ OwnPtr<TimingFunction> m_timingFunction;
+ };
+
+
+ class FloatValueList {
+ public:
+ void insert(float key, float value, const TimingFunction* timingFunction);
+
+ size_t size() const { return m_values.size(); }
+ const FloatValue& at(size_t i) const { return m_values.at(i); }
+ const Vector<FloatValue>& values() const { return m_values; }
+
+ private:
+ Vector<FloatValue> m_values;
+ };
+
+ // Used to store one transform in a keyframe list.
+ class TransformValue {
+ public:
+ TransformValue(float key = NAN, const TransformOperations* value = 0, const TimingFunction* timingFunction = 0)
+ : m_key(key)
+ {
+ if (value)
+ m_value.set(new TransformOperations(*value));
+ if (timingFunction)
+ m_timingFunction.set(new TimingFunction(*timingFunction));
+ }
+
+ TransformValue(const TransformValue& other)
+ : m_key(other.key())
+ {
+ if (other.value())
+ m_value.set(new TransformOperations(*other.value()));
+ if (other.timingFunction())
+ m_timingFunction.set(new TimingFunction(*other.timingFunction()));
+ }
+
+ const TransformValue& operator=(const TransformValue& other)
+ {
+ if (&other != this)
+ set(other.key(), other.value(), other.timingFunction());
+ return *this;
+ }
+
+ void set(float key, const TransformOperations* value, const TimingFunction* timingFunction);
+
+ float key() const { return m_key; }
+ const TransformOperations* value() const { return m_value.get(); }
+ const TimingFunction* timingFunction() const { return m_timingFunction.get(); }
+
+ private:
+ float m_key;
+ OwnPtr<TransformOperations> m_value;
+ OwnPtr<TimingFunction> m_timingFunction;
+ };
+
+ // Used to store a series of transforms in a keyframe list.
+ class TransformValueList {
+ public:
+ typedef Vector<TransformOperation::OperationType> FunctionList;
+
+ size_t size() const { return m_values.size(); }
+ const TransformValue& at(size_t i) const { return m_values.at(i); }
+ const Vector<TransformValue>& values() const { return m_values; }
+
+ void insert(float key, const TransformOperations* value, const TimingFunction* timingFunction);
+
+ // return a list of the required functions. List is empty if keyframes are not valid
+ // If return value is true, functions contain rotations of >= 180 degrees
+ void makeFunctionList(FunctionList& list, bool& isValid, bool& hasBigRotation) const;
+ private:
+ Vector<TransformValue> m_values;
+ };
+
+ static GraphicsLayer* createGraphicsLayer(GraphicsLayerClient*);
+
+ virtual ~GraphicsLayer();
+
+ GraphicsLayerClient* client() const { return m_client; }
+
+ // Layer name. Only used to identify layers in debug output
+ const String& name() const { return m_name; }
+ virtual void setName(const String& name) { m_name = name; }
+
+ // For hosting this GraphicsLayer in a native layer hierarchy.
+ virtual NativeLayer nativeLayer() const { return 0; }
+
+ GraphicsLayer* parent() const { return m_parent; };
+ void setParent(GraphicsLayer* layer) { m_parent = layer; } // Internal use only.
+
+ const Vector<GraphicsLayer*>& children() const { return m_children; }
+
+ // Add child layers. If the child is already parented, it will be removed from its old parent.
+ virtual void addChild(GraphicsLayer*);
+ virtual void addChildAtIndex(GraphicsLayer*, int index);
+ virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling);
+ virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling);
+ virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
+
+ void removeAllChildren();
+ virtual void removeFromParent();
+
+ // Offset is origin of the renderer minus origin of the graphics layer (so either zero or negative).
+ IntSize offsetFromRenderer() const { return m_offsetFromRenderer; }
+ void setOffsetFromRenderer(const IntSize& offset) { m_offsetFromRenderer = offset; }
+
+ // The position of the layer (the location of its top-left corner in its parent)
+ const FloatPoint& position() const { return m_position; }
+ virtual void setPosition(const FloatPoint& p) { m_position = p; }
+
+ // Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point
+ // affects the origin of the transforms.
+ const FloatPoint3D& anchorPoint() const { return m_anchorPoint; }
+ virtual void setAnchorPoint(const FloatPoint3D& p) { m_anchorPoint = p; }
+
+ // The bounds of the layer
+ const FloatSize& size() const { return m_size; }
+ virtual void setSize(const FloatSize& size) { m_size = size; }
+
+ const TransformationMatrix& transform() const { return m_transform; }
+ virtual void setTransform(const TransformationMatrix& t) { m_transform = t; }
+
+ const TransformationMatrix& childrenTransform() const { return m_childrenTransform; }
+ virtual void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
+
+ bool preserves3D() const { return m_preserves3D; }
+ virtual void setPreserves3D(bool b) { m_preserves3D = b; }
+
+ bool masksToBounds() const { return m_masksToBounds; }
+ virtual void setMasksToBounds(bool b) { m_masksToBounds = b; }
+
+ bool drawsContent() const { return m_drawsContent; }
+ virtual void setDrawsContent(bool b) { m_drawsContent = b; }
+
+ // The color used to paint the layer backgrounds
+ const Color& backgroundColor() const { return m_backgroundColor; }
+ virtual void setBackgroundColor(const Color&, const Animation* = 0, double beginTime = 0);
+ virtual void clearBackgroundColor();
+ bool backgroundColorSet() const { return m_backgroundColorSet; }
+
+ // opaque means that we know the layer contents have no alpha
+ bool contentsOpaque() const { return m_contentsOpaque; }
+ virtual void setContentsOpaque(bool b) { m_contentsOpaque = b; }
+
+ bool backfaceVisibility() const { return m_backfaceVisibility; }
+ virtual void setBackfaceVisibility(bool b) { m_backfaceVisibility = b; }
+
+ float opacity() const { return m_opacity; }
+ // return true if we started an animation
+ virtual bool setOpacity(float o, const Animation* = 0, double beginTime = 0);
+
+ // Some GraphicsLayers paint only the foreground or the background content
+ GraphicsLayerPaintingPhase drawingPhase() const { return m_paintingPhase; }
+ void setDrawingPhase(GraphicsLayerPaintingPhase phase) { m_paintingPhase = phase; }
+
+ virtual void setNeedsDisplay() = 0;
+ // mark the given rect (in layer coords) as needing dispay. Never goes deep.
+ virtual void setNeedsDisplayInRect(const FloatRect&) = 0;
+
+ virtual bool animateTransform(const TransformValueList&, const IntSize&, const Animation*, double beginTime, bool isTransition) = 0;
+ virtual bool animateFloat(AnimatedPropertyID, const FloatValueList&, const Animation*, double beginTime) = 0;
+
+ void removeFinishedAnimations(const String& name, int index, bool reset);
+ void removeFinishedTransitions(AnimatedPropertyID);
+ void removeAllAnimations();
+
+ virtual void suspendAnimations();
+ virtual void resumeAnimations();
+
+ // Layer contents
+ virtual void setContentsToImage(Image*) { }
+ virtual void setContentsToVideo(PlatformLayer*) { }
+ virtual void setContentsBackgroundColor(const Color&) { }
+ virtual void clearContents() { }
+
+ virtual void updateContentsRect() { }
+
+ // Callback from the underlying graphics system to draw layer contents.
+ void paintGraphicsLayerContents(GraphicsContext&, const IntRect& clip);
+
+ virtual PlatformLayer* platformLayer() const { return 0; }
+
+ void dumpLayer(TextStream&, int indent = 0) const;
+
+#ifndef NDEBUG
+ int repaintCount() const { return m_repaintCount; }
+ int incrementRepaintCount() { return ++m_repaintCount; }
+#endif
+
+ // Platform behaviors
+ static bool graphicsContextsFlipped();
+
+#ifndef NDEBUG
+ static bool showDebugBorders();
+ static bool showRepaintCounter();
+
+ void updateDebugIndicators();
+
+ virtual void setDebugBackgroundColor(const Color&) { }
+ virtual void setDebugBorder(const Color&, float /*borderWidth*/) { }
+ // z-position is the z-equivalent of position(). It's only used for debugging purposes.
+ virtual float zPosition() const { return m_zPosition; }
+ virtual void setZPosition(float);
+#endif
+
+ static String propertyIdToString(AnimatedPropertyID);
+
+protected:
+ GraphicsLayer(GraphicsLayerClient*);
+
+ void dumpProperties(TextStream&, int indent) const;
+
+ // returns -1 if not found
+ int findAnimationEntry(AnimatedPropertyID, short index) const;
+ void addAnimationEntry(AnimatedPropertyID, short index, bool isTransition, const Animation*);
+
+ virtual void removeAnimation(int /*index*/, bool /*reset*/) {}
+ void removeAllAnimationsForProperty(AnimatedPropertyID);
+
+ GraphicsLayerClient* m_client;
+ String m_name;
+
+ // Offset from the owning renderer
+ IntSize m_offsetFromRenderer;
+
+ // Position is relative to the parent GraphicsLayer
+ FloatPoint m_position;
+ FloatPoint3D m_anchorPoint;
+ FloatSize m_size;
+ TransformationMatrix m_transform;
+ TransformationMatrix m_childrenTransform;
+
+ Color m_backgroundColor;
+ float m_opacity;
+#ifndef NDEBUG
+ float m_zPosition;
+#endif
+
+ bool m_backgroundColorSet : 1;
+ bool m_contentsOpaque : 1;
+ bool m_preserves3D: 1;
+ bool m_backfaceVisibility : 1;
+ bool m_usingTiledLayer : 1;
+ bool m_masksToBounds : 1;
+ bool m_drawsContent : 1;
+
+ GraphicsLayerPaintingPhase m_paintingPhase;
+
+ Vector<GraphicsLayer*> m_children;
+ GraphicsLayer* m_parent;
+
+ // AnimationEntry represents an animation of a property on this layer.
+ // For transform only, there may be more than one, in which case 'index'
+ // is an index into the list of transforms.
+ class AnimationEntry {
+ public:
+ AnimationEntry(const Animation* animation, AnimatedPropertyID property, short index, bool isTransition)
+ : m_animation(const_cast<Animation*>(animation))
+ , m_property(property)
+ , m_index(index)
+ , m_isCurrent(true)
+ , m_isTransition(isTransition)
+ {
+ }
+
+ const Animation* animation() const { return m_animation.get(); }
+ AnimatedPropertyID property() const { return m_property; }
+ int index() const { return m_index; }
+ bool isCurrent() const { return m_isCurrent; }
+ void setIsCurrent(bool b = true) { m_isCurrent = b; }
+ bool isTransition() const { return m_isTransition; }
+
+ bool matches(AnimatedPropertyID property, short index) const
+ {
+ return m_property == property && m_index == index;
+ }
+
+ void reset(const Animation* animation, bool isTransition)
+ {
+ m_animation = const_cast<Animation*>(animation);
+ m_isTransition = isTransition;
+ m_isCurrent = true;
+ }
+
+ private:
+ RefPtr<Animation> m_animation;
+ AnimatedPropertyID m_property : 14;
+ short m_index : 16;
+ bool m_isCurrent : 1;
+ bool m_isTransition : 1;
+ };
+
+ Vector<AnimationEntry> m_animations; // running animations/transitions
+
+#ifndef NDEBUG
+ int m_repaintCount;
+#endif
+};
+
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // GraphicsLayer_h
+
diff --git a/WebCore/platform/graphics/GraphicsLayerClient.h b/WebCore/platform/graphics/GraphicsLayerClient.h
new file mode 100644
index 0000000..46382f2
--- /dev/null
+++ b/WebCore/platform/graphics/GraphicsLayerClient.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 GraphicsLayerClient_h
+#define GraphicsLayerClient_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+namespace WebCore {
+
+class GraphicsContext;
+class GraphicsLayer;
+class IntPoint;
+class IntRect;
+class FloatPoint;
+
+enum GraphicsLayerPaintingPhase {
+ GraphicsLayerPaintBackgroundMask = (1 << 0),
+ GraphicsLayerPaintForegroundMask = (1 << 1),
+ GraphicsLayerPaintAllMask = (GraphicsLayerPaintBackgroundMask | GraphicsLayerPaintForegroundMask)
+};
+
+enum AnimatedPropertyID {
+ AnimatedPropertyInvalid,
+ AnimatedPropertyWebkitTransform,
+ AnimatedPropertyOpacity,
+ AnimatedPropertyBackgroundColor
+};
+
+class GraphicsLayerClient {
+public:
+ virtual ~GraphicsLayerClient() {}
+
+ // Callbacks for when hardware-accelerated transitions and animation started
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double time) = 0;
+
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip) = 0;
+
+ // Return a rect for the "contents" of the graphics layer, i.e. video or image content, in GraphicsLayer coordinates.
+ virtual IntRect contentsBox(const GraphicsLayer*) = 0;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // GraphicsLayerClient_h
diff --git a/WebCore/platform/graphics/GraphicsTypes.h b/WebCore/platform/graphics/GraphicsTypes.h
index cdf5e31..769207a 100644
--- a/WebCore/platform/graphics/GraphicsTypes.h
+++ b/WebCore/platform/graphics/GraphicsTypes.h
@@ -50,6 +50,14 @@ namespace WebCore {
CompositePlusLighter
};
+ // FIXME: Currently these constants have to match the values used in the SVG
+ // DOM API. That's a mistake. We need to make cut that dependency.
+ enum GradientSpreadMethod {
+ SpreadMethodPad = 1,
+ SpreadMethodReflect = 2,
+ SpreadMethodRepeat = 3
+ };
+
enum LineCap { ButtCap, RoundCap, SquareCap };
enum LineJoin { MiterJoin, RoundJoin, BevelJoin };
diff --git a/WebCore/platform/graphics/Image.cpp b/WebCore/platform/graphics/Image.cpp
index 49961e1..08d96b4 100644
--- a/WebCore/platform/graphics/Image.cpp
+++ b/WebCore/platform/graphics/Image.cpp
@@ -119,7 +119,7 @@ void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, const Fl
FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(),
scaledTileSize.height() / intrinsicTileSize.height());
- TransformationMatrix patternTransform = TransformationMatrix().scale(scale.width(), scale.height());
+ TransformationMatrix patternTransform = TransformationMatrix().scaleNonUniform(scale.width(), scale.height());
FloatRect oneTileRect;
oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), scaledTileSize.width()) - scaledTileSize.width(), scaledTileSize.width()));
@@ -158,7 +158,7 @@ void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const Flo
vRule = RepeatTile;
FloatSize scale = calculatePatternScale(dstRect, srcRect, hRule, vRule);
- TransformationMatrix patternTransform = TransformationMatrix().scale(scale.width(), scale.height());
+ TransformationMatrix patternTransform = TransformationMatrix().scaleNonUniform(scale.width(), scale.height());
// We want to construct the phase such that the pattern is centered (when stretch is not
// set for a particular rule).
diff --git a/WebCore/platform/graphics/Image.h b/WebCore/platform/graphics/Image.h
index c3cf2e7..70f6d49 100644
--- a/WebCore/platform/graphics/Image.h
+++ b/WebCore/platform/graphics/Image.h
@@ -118,9 +118,9 @@ public:
SharedBuffer* data() { return m_data.get(); }
- // It may look unusual that there is no start animation call as public API. This is because
- // we start and stop animating lazily. Animation begins whenever someone draws the image. It will
- // automatically pause once all observers no longer want to render the image anywhere.
+ // Animation begins whenever someone draws the image, so startAnimation() is not normally called.
+ // It will automatically pause once all observers no longer want to render the image anywhere.
+ virtual void startAnimation(bool /*catchUpIfNecessary*/ = true) { }
virtual void stopAnimation() {}
virtual void resetAnimation() {}
@@ -164,11 +164,9 @@ protected:
void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator);
// Supporting tiled drawing
- virtual bool mayFillWithSolidColor() const { return false; }
+ virtual bool mayFillWithSolidColor() { return false; }
virtual Color solidColor() const { return Color(); }
- virtual void startAnimation(bool /*catchUpIfNecessary*/ = true) { }
-
virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const TransformationMatrix& patternTransform,
const FloatPoint& phase, CompositeOperator, const FloatRect& destRect);
#if PLATFORM(CG)
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 21e31fc..99d6aa4 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,7 +27,9 @@
#if ENABLE(VIDEO)
#include "MediaPlayer.h"
+#include "MediaPlayerPrivate.h"
+#include "ContentType.h"
#include "IntRect.h"
#include "MIMETypeRegistry.h"
#include "FrameView.h"
@@ -47,26 +49,196 @@
#endif
namespace WebCore {
+
+// a null player to make MediaPlayer logic simpler
+
+class NullMediaPlayerPrivate : public MediaPlayerPrivateInterface {
+public:
+ NullMediaPlayerPrivate(MediaPlayer*) { }
+
+ virtual void load(const String&) { }
+ virtual void cancelLoad() { }
+
+ virtual void play() { }
+ virtual void pause() { }
+
+ virtual IntSize naturalSize() const { return IntSize(0, 0); }
+
+ virtual bool hasVideo() const { return false; }
+
+ virtual void setVisible(bool) { }
+
+ virtual float duration() const { return 0; }
+
+ virtual float currentTime() const { return 0; }
+ virtual void seek(float) { }
+ virtual bool seeking() const { return false; }
+
+ virtual void setEndTime(float) { }
+
+ virtual void setRate(float) { }
+ virtual bool paused() const { return false; }
+
+ virtual void setVolume(float) { }
+
+ virtual MediaPlayer::NetworkState networkState() const { return MediaPlayer::Empty; }
+ virtual MediaPlayer::ReadyState readyState() const { return MediaPlayer::HaveNothing; }
+
+ virtual float maxTimeSeekable() const { return 0; }
+ virtual float maxTimeBuffered() const { return 0; }
+
+ virtual int dataRate() const { return 0; }
+
+ virtual bool totalBytesKnown() const { return false; }
+ virtual unsigned totalBytes() const { return 0; }
+ virtual unsigned bytesLoaded() const { return 0; }
+
+ virtual void setSize(const IntSize&) { }
+
+ virtual void paint(GraphicsContext*, const IntRect&) { }
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ virtual void setPoster(const String& /*url*/) { }
+ virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
+ virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
+#endif
+};
+
+static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player)
+{
+ return new NullMediaPlayerPrivate(player);
+}
+
+
+// engine support
+
+struct MediaPlayerFactory {
+ MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs)
+ : constructor(constructor)
+ , getSupportedTypes(getSupportedTypes)
+ , supportsTypeAndCodecs(supportsTypeAndCodecs)
+ {
+ }
+
+ CreateMediaEnginePlayer constructor;
+ MediaEngineSupportedTypes getSupportedTypes;
+ MediaEngineSupportsType supportsTypeAndCodecs;
+};
+
+static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
+static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs);
+
+static Vector<MediaPlayerFactory*>& installedMediaEngines()
+{
+ DEFINE_STATIC_LOCAL(Vector<MediaPlayerFactory*>, installedEngines, ());
+ static bool enginesQueried = false;
+
+ if (!enginesQueried) {
+ enginesQueried = true;
+ MediaPlayerPrivate::registerMediaEngine(addMediaEngine);
+
+ // register additional engines here
+ }
- MediaPlayer::MediaPlayer(MediaPlayerClient* client)
+ return installedEngines;
+}
+
+static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType)
+{
+ ASSERT(constructor);
+ ASSERT(getSupportedTypes);
+ ASSERT(supportsType);
+ installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType));
+}
+
+static MediaPlayerFactory* chooseBestEngineForTypeAndCodecs(const String& type, const String& codecs)
+{
+ Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
+
+ if (engines.isEmpty())
+ return 0;
+
+ MediaPlayerFactory* engine = 0;
+ MediaPlayer::SupportsType supported = MediaPlayer::IsNotSupported;
+
+ unsigned count = engines.size();
+ for (unsigned ndx = 0; ndx < count; ndx++) {
+ MediaPlayer::SupportsType engineSupport = engines[ndx]->supportsTypeAndCodecs(type, codecs);
+ if (engineSupport > supported) {
+ supported = engineSupport;
+ engine = engines[ndx];
+ }
+ }
+
+ return engine;
+}
+
+// media player
+
+MediaPlayer::MediaPlayer(MediaPlayerClient* client)
: m_mediaPlayerClient(client)
- , m_private(new MediaPlayerPrivate(this))
+ , m_private(createNullMediaPlayer(this))
+ , m_currentMediaEngine(0)
, m_frameView(0)
, m_visible(false)
, m_rate(1.0f)
, m_volume(1.0f)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ , m_playerProxy(0)
+#endif
{
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
+ if (!engines.isEmpty()) {
+ m_currentMediaEngine = engines[0];
+ m_private.clear();
+ m_private.set(engines[0]->constructor(this));
+ }
+#endif
}
MediaPlayer::~MediaPlayer()
{
- delete m_private;
}
-void MediaPlayer::load(const String& url)
+void MediaPlayer::load(const String& url, const ContentType& contentType)
+{
+ String type = contentType.type();
+ String codecs = contentType.parameter("codecs");
+
+ // if we don't know the MIME type, see if the path can help
+ if (type.isEmpty())
+ type = MIMETypeRegistry::getMIMETypeForPath(url);
+
+ MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
+
+ // if we didn't find an engine that claims the MIME type, just use the first engine
+ if (!engine)
+ engine = installedMediaEngines()[0];
+
+ // don't delete and recreate the player unless it comes from a different engine
+ if (engine && m_currentMediaEngine != engine) {
+ m_currentMediaEngine = engine;
+ m_private.clear();
+ m_private.set(engine->constructor(this));
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ m_private->setMediaPlayerProxy(m_playerProxy);
+#endif
+
+ }
+
+ if (m_private)
+ m_private->load(url);
+ else
+ m_private.set(createNullMediaPlayer(this));
+}
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+void MediaPlayer::setPoster(const String& url)
{
- m_private->load(url);
+ m_private->setPoster(url);
}
+#endif
void MediaPlayer::cancelLoad()
{
@@ -90,7 +262,7 @@ float MediaPlayer::duration() const
float MediaPlayer::currentTime() const
{
- return m_private->currentTime();
+ return m_private->currentTime();
}
void MediaPlayer::seek(float time)
@@ -193,10 +365,10 @@ unsigned MediaPlayer::totalBytes()
return m_private->totalBytes();
}
-void MediaPlayer::setRect(const IntRect& r)
+void MediaPlayer::setSize(const IntSize& size)
{
- m_rect = r;
- m_private->setRect(r);
+ m_size = size;
+ m_private->setSize(size);
}
bool MediaPlayer::visible() const
@@ -215,29 +387,47 @@ void MediaPlayer::paint(GraphicsContext* p, const IntRect& r)
m_private->paint(p, r);
}
-bool MediaPlayer::supportsType(const String& type)
+MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
{
- HashSet<String> types;
- getSupportedTypes(types);
- return MIMETypeRegistry::isSupportedMediaMIMEType(type) && types.contains(type);
+ String type = contentType.type();
+ String codecs = contentType.parameter("codecs");
+ MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, codecs);
+
+ if (!engine)
+ return IsNotSupported;
+
+ return engine->supportsTypeAndCodecs(type, codecs);
}
void MediaPlayer::getSupportedTypes(HashSet<String>& types)
{
- MediaPlayerPrivate::getSupportedTypes(types);
+ Vector<MediaPlayerFactory*>& engines = installedMediaEngines();
+ if (engines.isEmpty())
+ return;
+
+ unsigned count = engines.size();
+ for (unsigned ndx = 0; ndx < count; ndx++)
+ engines[ndx]->getSupportedTypes(types);
}
-
+
bool MediaPlayer::isAvailable()
{
- static bool availabityKnown = false;
- static bool isAvailable;
- if (!availabityKnown) {
- isAvailable = MediaPlayerPrivate::isAvailable();
- availabityKnown = true;
- }
- return isAvailable;
+ return !installedMediaEngines().isEmpty();
}
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+void MediaPlayer::deliverNotification(MediaPlayerProxyNotificationType notification)
+{
+ m_private->deliverNotification(notification);
+}
+
+void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
+{
+ m_playerProxy = proxy;
+ m_private->setMediaPlayerProxy(proxy);
+}
+#endif
+
void MediaPlayer::networkStateChanged()
{
if (m_mediaPlayerClient)
@@ -262,11 +452,29 @@ void MediaPlayer::timeChanged()
m_mediaPlayerClient->mediaPlayerTimeChanged(this);
}
+void MediaPlayer::sizeChanged()
+{
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerSizeChanged(this);
+}
+
void MediaPlayer::repaint()
{
if (m_mediaPlayerClient)
m_mediaPlayerClient->mediaPlayerRepaint(this);
}
+void MediaPlayer::durationChanged()
+{
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerDurationChanged(this);
+}
+
+void MediaPlayer::rateChanged()
+{
+ if (m_mediaPlayerClient)
+ m_mediaPlayerClient->mediaPlayerRateChanged(this);
+}
+
}
#endif
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index 203f299..7d90e44 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -28,52 +28,78 @@
#if ENABLE(VIDEO)
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "MediaPlayerProxy.h"
+#endif
+
#include "IntRect.h"
#include "StringHash.h"
#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
#include <wtf/Noncopyable.h>
namespace WebCore {
+class ContentType;
class FrameView;
class GraphicsContext;
+class IntRect;
class IntSize;
class MediaPlayer;
-class MediaPlayerPrivate;
+class MediaPlayerPrivateInterface;
class String;
class MediaPlayerClient {
public:
virtual ~MediaPlayerClient() { }
+
+ // the network state has changed
virtual void mediaPlayerNetworkStateChanged(MediaPlayer*) { }
+
+ // the ready state has changed
virtual void mediaPlayerReadyStateChanged(MediaPlayer*) { }
+
+ // the volume or muted state has changed
virtual void mediaPlayerVolumeChanged(MediaPlayer*) { }
+
+ // time has jumped, eg. not as a result of normal playback
virtual void mediaPlayerTimeChanged(MediaPlayer*) { }
+
+ // a new frame of video is available
virtual void mediaPlayerRepaint(MediaPlayer*) { }
+
+ // the media file duration has changed, or is now known
+ virtual void mediaPlayerDurationChanged(MediaPlayer*) { }
+
+ // the playback rate has changed
+ virtual void mediaPlayerRateChanged(MediaPlayer*) { }
+
+ // the movie size has changed
+ virtual void mediaPlayerSizeChanged(MediaPlayer*) { }
};
class MediaPlayer : Noncopyable {
public:
MediaPlayer(MediaPlayerClient*);
virtual ~MediaPlayer();
-
- static bool isAvailable();
- static bool supportsType(const String&);
+
+ // media engine support
+ enum SupportsType { IsNotSupported, IsSupported, MayBeSupported };
+ static MediaPlayer::SupportsType supportsType(ContentType contentType);
static void getSupportedTypes(HashSet<String>&);
+ static bool isAvailable();
IntSize naturalSize();
bool hasVideo();
void setFrameView(FrameView* frameView) { m_frameView = frameView; }
+ FrameView* frameView() { return m_frameView; }
bool inMediaDocument();
- // FIXME: it would be better to just have a getter and setter for size.
- // This is currently an absolute rect, which is not appropriate for
- // content with transforms
- IntRect rect() const { return m_rect; }
- void setRect(const IntRect& r);
+ IntSize size() const { return m_size; }
+ void setSize(const IntSize& size);
- void load(const String& url);
+ void load(const String& url, const ContentType& contentType);
void cancelLoad();
bool visible() const;
@@ -96,7 +122,7 @@ public:
float maxTimeBuffered();
float maxTimeSeekable();
-
+
unsigned bytesLoaded();
bool totalBytesKnown();
unsigned totalBytes();
@@ -108,33 +134,55 @@ public:
void paint(GraphicsContext*, const IntRect&);
- enum NetworkState { Empty, LoadFailed, Loading, LoadedMetaData, LoadedFirstFrame, Loaded };
+ enum NetworkState { Empty, Idle, Loading, Loaded, FormatError, NetworkError, DecodeError };
NetworkState networkState();
- enum ReadyState { DataUnavailable, CanShowCurrentFrame, CanPlay, CanPlayThrough };
+ enum ReadyState { HaveNothing, HaveMetadata, HaveCurrentData, HaveFutureData, HaveEnoughData };
ReadyState readyState();
void networkStateChanged();
void readyStateChanged();
void volumeChanged();
void timeChanged();
+ void sizeChanged();
+ void rateChanged();
+ void durationChanged();
void repaint();
-
+
+ MediaPlayerClient* mediaPlayerClient() const { return m_mediaPlayerClient; }
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ void setPoster(const String& url);
+ void deliverNotification(MediaPlayerProxyNotificationType notification);
+ void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
+#endif
+
private:
-
- friend class MediaPlayerPrivate;
-
+ static void initializeMediaEngines();
+
MediaPlayerClient* m_mediaPlayerClient;
- MediaPlayerPrivate* m_private;
+ OwnPtr<MediaPlayerPrivateInterface*> m_private;
+ void* m_currentMediaEngine;
FrameView* m_frameView;
- IntRect m_rect;
+ IntSize m_size;
bool m_visible;
float m_rate;
float m_volume;
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ WebMediaPlayerProxy* m_playerProxy; // not owned or used, passed to m_private
+#endif
};
+typedef MediaPlayerPrivateInterface* (*CreateMediaEnginePlayer)(MediaPlayer*);
+typedef void (*MediaEngineSupportedTypes)(HashSet<String>& types);
+typedef MediaPlayer::SupportsType (*MediaEngineSupportsType)(const String& type, const String& codecs);
+
+typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType);
+
+
}
-#endif
+#endif // ENABLE(VIDEO)
+
#endif
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
new file mode 100644
index 0000000..2e73e7e
--- /dev/null
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaPlayerPrivate_h
+#define MediaPlayerPrivate_h
+
+#if ENABLE(VIDEO)
+
+#include "MediaPlayer.h"
+
+namespace WebCore {
+
+class IntRect;
+class IntSize;
+class String;
+
+class MediaPlayerPrivateInterface {
+public:
+ virtual ~MediaPlayerPrivateInterface() { }
+
+ virtual void load(const String& url) = 0;
+ virtual void cancelLoad() = 0;
+
+ virtual void play() = 0;
+ virtual void pause() = 0;
+
+ virtual IntSize naturalSize() const = 0;
+
+ virtual bool hasVideo() const = 0;
+
+ virtual void setVisible(bool) = 0;
+
+ virtual float duration() const = 0;
+
+ virtual float currentTime() const = 0;
+ virtual void seek(float time) = 0;
+ virtual bool seeking() const = 0;
+
+ virtual void setEndTime(float time) = 0;
+
+ virtual void setRate(float) = 0;
+ virtual bool paused() const = 0;
+
+ virtual void setVolume(float) = 0;
+
+ virtual MediaPlayer::NetworkState networkState() const = 0;
+ virtual MediaPlayer::ReadyState readyState() const = 0;
+
+ virtual float maxTimeSeekable() const = 0;
+ virtual float maxTimeBuffered() const = 0;
+
+ virtual int dataRate() const = 0;
+
+ virtual bool totalBytesKnown() const { return totalBytes() > 0; }
+ virtual unsigned totalBytes() const = 0;
+ virtual unsigned bytesLoaded() const = 0;
+
+ virtual void setSize(const IntSize&) = 0;
+
+ virtual void paint(GraphicsContext*, const IntRect&) = 0 ;
+
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ virtual void setPoster(const String& url) = 0;
+ virtual void deliverNotification(MediaPlayerProxyNotificationType) = 0;
+ virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) = 0;
+#endif
+};
+
+}
+
+#endif
+#endif
diff --git a/WebCore/platform/graphics/Pattern.h b/WebCore/platform/graphics/Pattern.h
index 716a645..6981748 100644
--- a/WebCore/platform/graphics/Pattern.h
+++ b/WebCore/platform/graphics/Pattern.h
@@ -30,6 +30,7 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
+#include "TransformationMatrix.h"
#if PLATFORM(CG)
typedef struct CGPattern* CGPatternRef;
@@ -67,7 +68,9 @@ namespace WebCore {
Image* tileImage() const { return m_tileImage.get(); }
- PlatformPatternPtr createPlatformPattern(const TransformationMatrix& patternTransform) const;
+ // Pattern space is an abstract space that maps to the default user space by the transformation 'userSpaceTransformation'
+ PlatformPatternPtr createPlatformPattern(const TransformationMatrix& userSpaceTransformation) const;
+ void setPatternSpaceTransform(const TransformationMatrix& patternSpaceTransformation) { m_patternSpaceTransformation = patternSpaceTransformation; }
private:
Pattern(Image*, bool repeatX, bool repeatY);
@@ -75,6 +78,7 @@ namespace WebCore {
RefPtr<Image> m_tileImage;
bool m_repeatX;
bool m_repeatY;
+ TransformationMatrix m_patternSpaceTransformation;
};
} //namespace
diff --git a/WebCore/platform/graphics/SimpleFontData.cpp b/WebCore/platform/graphics/SimpleFontData.cpp
index 9670b55..9f51037 100644
--- a/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/WebCore/platform/graphics/SimpleFontData.cpp
@@ -136,20 +136,6 @@ SimpleFontData::~SimpleFontData()
}
}
-#if !PLATFORM(QT)
-float SimpleFontData::widthForGlyph(Glyph glyph) const
-{
- float width = m_glyphToWidthMap.widthForGlyph(glyph);
- if (width != cGlyphWidthUnknown)
- return width;
-
- width = platformWidthForGlyph(glyph);
- m_glyphToWidthMap.setWidthForGlyph(glyph, width);
-
- return width;
-}
-#endif
-
const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const
{
return this;
diff --git a/WebCore/platform/graphics/SimpleFontData.h b/WebCore/platform/graphics/SimpleFontData.h
index e572e30..d2dd0b9 100644
--- a/WebCore/platform/graphics/SimpleFontData.h
+++ b/WebCore/platform/graphics/SimpleFontData.h
@@ -131,7 +131,7 @@ public:
#endif
#if PLATFORM(WX)
- wxFont getWxFont() const { return m_font.font(); }
+ wxFont* getWxFont() const { return m_font.font(); }
#endif
private:
@@ -205,6 +205,21 @@ public:
mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
#endif
};
+
+
+#if !PLATFORM(QT)
+ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
+{
+ float width = m_glyphToWidthMap.widthForGlyph(glyph);
+ if (width != cGlyphWidthUnknown)
+ return width;
+
+ width = platformWidthForGlyph(glyph);
+ m_glyphToWidthMap.setWidthForGlyph(glyph, width);
+
+ return width;
+}
+#endif
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/FontPlatformData.h b/WebCore/platform/graphics/android/FontPlatformData.h
index 2bb8834..35b7200 100644
--- a/WebCore/platform/graphics/android/FontPlatformData.h
+++ b/WebCore/platform/graphics/android/FontPlatformData.h
@@ -42,6 +42,8 @@ public:
FontPlatformData(const FontPlatformData&);
FontPlatformData(SkTypeface*, float textSize, bool fakeBold, bool fakeItalic);
FontPlatformData(const FontPlatformData& src, float textSize);
+ FontPlatformData(float size, bool syntheticBold, bool syntheticOblique);
+
~FontPlatformData();
FontPlatformData(WTF::HashTableDeletedValueType)
diff --git a/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp b/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
index e82c1f6..4496408 100644
--- a/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
+++ b/WebCore/platform/graphics/android/FontPlatformDataAndroid.cpp
@@ -103,6 +103,13 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
trace(4);
}
+FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
+ : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique)
+{
+ inc_count();
+ trace(5);
+}
+
FontPlatformData::~FontPlatformData()
{
dec_count();
diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
index 6a92a7f..7571926 100644
--- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -315,7 +315,8 @@ static SkShader::TileMode SpreadMethod2TileMode(GradientSpreadMethod sm) {
}
static void extactShader(SkPaint* paint, ColorSpace cs, Pattern* pat,
- Gradient* grad, GradientSpreadMethod sm) {
+ Gradient* grad)
+{
switch (cs) {
case PatternColorSpace:
// createPlatformPattern() returns a new inst
@@ -324,6 +325,7 @@ static void extactShader(SkPaint* paint, ColorSpace cs, Pattern* pat,
break;
case GradientColorSpace: {
// grad->getShader() returns a cached obj
+ GradientSpreadMethod sm = grad->spreadMethod();
paint->setShader(grad->getShader(SpreadMethod2TileMode(sm)));
break;
}
@@ -670,7 +672,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
extactShader(&paint, m_common->state.fillColorSpace,
m_common->state.fillPattern.get(),
- m_common->state.fillGradient.get(), spreadMethod());
+ m_common->state.fillGradient.get());
GC2Canvas(this)->drawRect(r, paint);
}
@@ -1077,7 +1079,13 @@ void GraphicsContext::setPlatformShouldAntialias(bool useAA)
TransformationMatrix GraphicsContext::getCTM() const
{
- return TransformationMatrix(GC2Canvas(this)->getTotalMatrix());
+ const SkMatrix& m = GC2Canvas(this)->getTotalMatrix();
+ return TransformationMatrix(SkScalarToDouble(m.getScaleX()), // a
+ SkScalarToDouble(m.getSkewY()), // b
+ SkScalarToDouble(m.getSkewX()), // c
+ SkScalarToDouble(m.getScaleY()), // d
+ SkScalarToDouble(m.getTranslateX()), // e
+ SkScalarToDouble(m.getTranslateY())); // f
}
///////////////////////////////////////////////////////////////////////////////
@@ -1118,7 +1126,7 @@ void GraphicsContext::fillPath()
extactShader(&paint, m_common->state.fillColorSpace,
m_common->state.fillPattern.get(),
- m_common->state.fillGradient.get(), spreadMethod());
+ m_common->state.fillGradient.get());
GC2Canvas(this)->drawPath(*path, paint);
}
@@ -1134,7 +1142,7 @@ void GraphicsContext::strokePath()
extactShader(&paint, m_common->state.strokeColorSpace,
m_common->state.strokePattern.get(),
- m_common->state.strokeGradient.get(), spreadMethod());
+ m_common->state.strokeGradient.get());
GC2Canvas(this)->drawPath(*path, paint);
}
diff --git a/WebCore/platform/graphics/android/TransformationMatrixAndroid.cpp b/WebCore/platform/graphics/android/TransformationMatrixAndroid.cpp
index 6a4c670..a57abc0 100644
--- a/WebCore/platform/graphics/android/TransformationMatrixAndroid.cpp
+++ b/WebCore/platform/graphics/android/TransformationMatrixAndroid.cpp
@@ -1,232 +1,56 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * 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 APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+// 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
+// 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 "TransformationMatrix.h"
-#include "FloatRect.h"
-#include "IntRect.h"
-
-#include "android_graphics.h"
+#include "SkiaUtils.h"
namespace WebCore {
-static const double deg2rad = 0.017453292519943295769; // pi/180
-
-TransformationMatrix::TransformationMatrix()
-{
- m_transform.reset();
-}
-
-TransformationMatrix::TransformationMatrix(const SkMatrix& mat) : m_transform(mat) {}
-
-TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- m_transform.reset();
-
- m_transform.set(SkMatrix::kMScaleX, SkDoubleToScalar(a));
- m_transform.set(SkMatrix::kMSkewX, SkDoubleToScalar(b));
- m_transform.set(SkMatrix::kMTransX, SkDoubleToScalar(tx));
-
- m_transform.set(SkMatrix::kMScaleY, SkDoubleToScalar(d));
- m_transform.set(SkMatrix::kMSkewY, SkDoubleToScalar(c));
- m_transform.set(SkMatrix::kMTransY, SkDoubleToScalar(ty));
-}
-
-void TransformationMatrix::setMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- m_transform.set(SkMatrix::kMScaleX, SkDoubleToScalar(a));
- m_transform.set(SkMatrix::kMSkewX, SkDoubleToScalar(b));
- m_transform.set(SkMatrix::kMTransX, SkDoubleToScalar(tx));
-
- m_transform.set(SkMatrix::kMScaleY, SkDoubleToScalar(d));
- m_transform.set(SkMatrix::kMSkewY, SkDoubleToScalar(c));
- m_transform.set(SkMatrix::kMTransY, SkDoubleToScalar(ty));
-}
-
-void TransformationMatrix::map(double x, double y, double *x2, double *y2) const
-{
- SkPoint pt;
-
- m_transform.mapXY(SkDoubleToScalar(x), SkDoubleToScalar(y), &pt);
- *x2 = SkScalarToDouble(pt.fX);
- *y2 = SkScalarToDouble(pt.fY);
-}
-
-IntRect TransformationMatrix::mapRect(const IntRect &rect) const
-{
- SkRect src, dst;
- SkIRect ir;
-
- android_setrect(&src, rect);
- m_transform.mapRect(&dst, src);
- // we round out to mimic enclosingIntRect()
- dst.roundOut(&ir);
-
- return IntRect(ir.fLeft, ir.fTop, ir.width(), ir.height());
-}
-
-FloatRect TransformationMatrix::mapRect(const FloatRect &rect) const
-{
- SkRect r;
-
- android_setrect(&r, rect);
- m_transform.mapRect(&r);
-
- return FloatRect(r.fLeft, r.fTop, r.width(), r.height());
-}
-
-bool TransformationMatrix::isIdentity() const
-{
- return m_transform.isIdentity();
-}
-
-void TransformationMatrix::reset()
-{
- m_transform.reset();
-}
-
-double TransformationMatrix::a() const
-{
- return SkScalarToDouble(m_transform[0]);
-}
-
-void TransformationMatrix::setA(double a)
-{
- m_transform.set(0, SkDoubleToScalar(a));
-}
-
-double TransformationMatrix::b() const
-{
- return SkScalarToDouble(m_transform[1]);
-}
-
-void TransformationMatrix::setB(double b)
-{
- m_transform.set(1, SkDoubleToScalar(b));
-}
-
-double TransformationMatrix::c() const
-{
- return SkScalarToDouble(m_transform[3]);
-}
-
-void TransformationMatrix::setC(double c)
-{
- m_transform.set(3, SkDoubleToScalar(c));
-}
-
-double TransformationMatrix::d() const {
- return SkScalarToDouble(m_transform[4]);
-}
-
-void TransformationMatrix::setD(double d)
-{
- m_transform.set(4, SkDoubleToScalar(d));
-}
-
-double TransformationMatrix::e() const
-{
- return SkScalarToDouble(m_transform[2]);
-}
-
-void TransformationMatrix::setE(double e)
-{
- m_transform.set(2, SkDoubleToScalar(e));
-}
-
-double TransformationMatrix::f() const {
- return SkScalarToDouble(m_transform[5]);
-}
-void TransformationMatrix::setF(double f) {
- m_transform.set(5, SkDoubleToScalar(f));
-}
-
-TransformationMatrix &TransformationMatrix::scale(double sx, double sy)
-{
- m_transform.preScale(SkDoubleToScalar(sx), SkDoubleToScalar(sy));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::rotate(double d)
-{
- m_transform.preRotate(SkDoubleToScalar(d));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::translate(double tx, double ty)
-{
- m_transform.preTranslate(SkDoubleToScalar(tx), SkDoubleToScalar(ty));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::shear(double sx, double sy)
-{
- m_transform.preSkew(SkDoubleToScalar(sx), SkDoubleToScalar(sy));
- return *this;
-}
-
-double TransformationMatrix::det() const
-{
- return SkScalarToDouble(m_transform[SkMatrix::kMScaleX]) * SkScalarToDouble(m_transform[SkMatrix::kMScaleY]) -
- SkScalarToDouble(m_transform[SkMatrix::kMSkewX]) * SkScalarToDouble(m_transform[SkMatrix::kMSkewY]);
-}
-
-TransformationMatrix TransformationMatrix::inverse() const
-{
- // the constructor initializes inverse to the identity
- TransformationMatrix inverse;
-
- // if we are not invertible, inverse will stay identity
- m_transform.invert(&inverse.m_transform);
-
- return inverse;
-}
-
TransformationMatrix::operator SkMatrix() const
{
- return m_transform;
-}
+ SkMatrix result;
-bool TransformationMatrix::operator==(const TransformationMatrix &m2) const
-{
- return m_transform == m2.m_transform;
-}
+ result.setScaleX(WebCoreDoubleToSkScalar(a()));
+ result.setSkewX(WebCoreDoubleToSkScalar(c()));
+ result.setTranslateX(WebCoreDoubleToSkScalar(e()));
-TransformationMatrix &TransformationMatrix::operator*= (const TransformationMatrix &m2)
-{
- m_transform.setConcat(m2.m_transform, m_transform);
- return *this;
-}
+ result.setScaleY(WebCoreDoubleToSkScalar(d()));
+ result.setSkewY(WebCoreDoubleToSkScalar(b()));
+ result.setTranslateY(WebCoreDoubleToSkScalar(f()));
-TransformationMatrix TransformationMatrix::operator* (const TransformationMatrix &m2)
-{
- TransformationMatrix cat;
-
- cat.m_transform.setConcat(m2.m_transform, m_transform);
- return cat;
+ // FIXME: Set perspective properly.
+ result.setPerspX(0);
+ result.setPerspY(0);
+ result.set(SkMatrix::kMPersp2, SK_Scalar1);
+ return result;
}
-}
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index 9da9426..b23182d 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
* Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,8 +30,11 @@
#include "Font.h"
#include "GlyphBuffer.h"
+#include "Gradient.h"
#include "GraphicsContext.h"
+#include "Pattern.h"
#include "SimpleFontData.h"
+#include "TransformationMatrix.h"
namespace WebCore {
@@ -78,18 +82,51 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
}
if (context->textDrawingMode() & cTextFill) {
- float red, green, blue, alpha;
- fillColor.getRGBA(red, green, blue, alpha);
- cairo_set_source_rgba(cr, red, green, blue, alpha);
-
+ if (context->fillGradient()) {
+ cairo_set_source(cr, context->fillGradient()->platformGradient());
+ if (context->getAlpha() < 1.0f) {
+ cairo_push_group(cr);
+ cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_pop_group_to_source(cr);
+ }
+ } else if (context->fillPattern()) {
+ TransformationMatrix affine;
+ cairo_set_source(cr, context->fillPattern()->createPlatformPattern(affine));
+ if (context->getAlpha() < 1.0f) {
+ cairo_push_group(cr);
+ cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_pop_group_to_source(cr);
+ }
+ } else {
+ float red, green, blue, alpha;
+ fillColor.getRGBA(red, green, blue, alpha);
+ cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha());
+ }
cairo_show_glyphs(cr, glyphs, numGlyphs);
}
if (context->textDrawingMode() & cTextStroke) {
- Color strokeColor = context->strokeColor();
- float red, green, blue, alpha;
- strokeColor.getRGBA(red, green, blue, alpha);
- cairo_set_source_rgba(cr, red, green, blue, alpha);
+ if (context->strokeGradient()) {
+ cairo_set_source(cr, context->strokeGradient()->platformGradient());
+ if (context->getAlpha() < 1.0f) {
+ cairo_push_group(cr);
+ cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_pop_group_to_source(cr);
+ }
+ } else if (context->strokePattern()) {
+ TransformationMatrix affine;
+ cairo_set_source(cr, context->strokePattern()->createPlatformPattern(affine));
+ if (context->getAlpha() < 1.0f) {
+ cairo_push_group(cr);
+ cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_pop_group_to_source(cr);
+ }
+ } else {
+ Color strokeColor = context->strokeColor();
+ float red, green, blue, alpha;
+ strokeColor.getRGBA(red, green, blue, alpha);
+ cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha());
+ }
cairo_glyph_path(cr, glyphs, numGlyphs);
cairo_set_line_width(cr, context->strokeThickness());
cairo_stroke(cr);
diff --git a/WebCore/platform/graphics/cairo/GradientCairo.cpp b/WebCore/platform/graphics/cairo/GradientCairo.cpp
index 7776424..72fb0c5 100644
--- a/WebCore/platform/graphics/cairo/GradientCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GradientCairo.cpp
@@ -57,6 +57,22 @@ cairo_pattern_t* Gradient::platformGradient()
++stopIterator;
}
+ switch (m_spreadMethod) {
+ case SpreadMethodPad:
+ cairo_pattern_set_extend(m_gradient, CAIRO_EXTEND_PAD);
+ break;
+ case SpreadMethodReflect:
+ cairo_pattern_set_extend(m_gradient, CAIRO_EXTEND_REFLECT);
+ break;
+ case SpreadMethodRepeat:
+ cairo_pattern_set_extend(m_gradient, CAIRO_EXTEND_REPEAT);
+ break;
+ }
+
+ cairo_matrix_t matrix = m_gradientSpaceTransformation;
+ cairo_matrix_invert(&matrix);
+ cairo_pattern_set_matrix(m_gradient, &matrix);
+
return m_gradient;
}
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index ef748cf..35ebd3c 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -87,22 +87,6 @@ static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const
cairo_fill(cr);
}
-static inline cairo_pattern_t* applySpreadMethod(cairo_pattern_t* pattern, GradientSpreadMethod spreadMethod)
-{
- switch (spreadMethod) {
- case SpreadMethodPad:
- cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD);
- break;
- case SpreadMethodReflect:
- cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT);
- break;
- case SpreadMethodRepeat:
- cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
- break;
- }
- return pattern;
-}
-
GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
: m_common(createGraphicsContextPrivate())
, m_data(new GraphicsContextPlatformPrivate)
@@ -122,7 +106,7 @@ TransformationMatrix GraphicsContext::getCTM() const
cairo_t* cr = platformContext();
cairo_matrix_t m;
cairo_get_matrix(cr, &m);
- return m;
+ return TransformationMatrix(m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
}
cairo_t* GraphicsContext::platformContext() const
@@ -463,7 +447,6 @@ void GraphicsContext::fillPath()
}
case GradientColorSpace:
cairo_pattern_t* pattern = m_common->state.fillGradient->platformGradient();
- pattern = applySpreadMethod(pattern, spreadMethod());
cairo_set_source(cr, pattern);
cairo_clip(cr);
cairo_paint_with_alpha(cr, m_common->state.globalAlpha);
@@ -501,7 +484,6 @@ void GraphicsContext::strokePath()
}
case GradientColorSpace:
cairo_pattern_t* pattern = m_common->state.strokeGradient->platformGradient();
- pattern = applySpreadMethod(pattern, spreadMethod());
cairo_set_source(cr, pattern);
if (m_common->state.globalAlpha < 1.0f) {
cairo_push_group(cr);
@@ -750,8 +732,8 @@ void GraphicsContext::concatCTM(const TransformationMatrix& transform)
return;
cairo_t* cr = m_data->cr;
- const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
- cairo_transform(cr, matrix);
+ const cairo_matrix_t matrix = cairo_matrix_t(transform);
+ cairo_transform(cr, &matrix);
m_data->concatCTM(transform);
}
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
index 535f70d..55b2e25 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
+++ b/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
@@ -51,6 +51,7 @@ public:
// NOTE: These may note be needed: review and remove once Cairo implementation is complete
, m_hdc(0)
, m_transparencyCount(0)
+ , m_shouldIncludeChildWindows(false)
#endif
{
}
@@ -94,6 +95,7 @@ public:
#elif PLATFORM(WIN)
HDC m_hdc;
unsigned m_transparencyCount;
+ bool m_shouldIncludeChildWindows;
#endif
};
diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 3e06669..dff39b7 100644
--- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2007 Holger Hans Peter Freyther <zecke@selfish.org>
- * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de>
+ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include "Base64.h"
#include "BitmapImage.h"
+#include "Color.h"
#include "GraphicsContext.h"
#include "ImageData.h"
#include "MIMETypeRegistry.h"
@@ -126,17 +127,15 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
unsigned char* destRows = dataDst + desty * destBytesPerRow + destx * 4;
for (int y = 0; y < numRows; ++y) {
- unsigned char *row = dataSrc + stride * (y + originy);
+ unsigned* row = reinterpret_cast<unsigned*>(dataSrc + stride * (y + originy));
for (int x = 0; x < numColumns; x++) {
- uint32_t *pixel = (uint32_t *) row + x + originx;
int basex = x * 4;
- if (unsigned int alpha = (*pixel & 0xff000000) >> 24) {
- destRows[basex] = (*pixel & 0x00ff0000) >> 16;
- destRows[basex + 1] = (*pixel & 0x0000ff00) >> 8;
- destRows[basex + 2] = (*pixel & 0x000000ff);
- destRows[basex + 3] = alpha;
- } else
- reinterpret_cast<uint32_t*>(destRows + basex)[0] = pixel[0];
+ unsigned* pixel = row + x + originx;
+ Color pixelColor = colorFromPremultipliedARGB(*pixel);
+ destRows[basex] = pixelColor.red();
+ destRows[basex + 1] = pixelColor.green();
+ destRows[basex + 2] = pixelColor.blue();
+ destRows[basex + 3] = pixelColor.alpha();
}
destRows += destBytesPerRow;
}
@@ -181,14 +180,15 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, con
unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4;
for (int y = 0; y < numRows; ++y) {
- unsigned char *row = dataDst + stride * (y + desty);
+ unsigned* row = reinterpret_cast<unsigned*>(dataDst + stride * (y + desty));
for (int x = 0; x < numColumns; x++) {
- uint32_t *pixel = (uint32_t *) row + x + destx;
int basex = x * 4;
- if (unsigned int alpha = srcRows[basex + 3]) {
- *pixel = alpha << 24 | srcRows[basex] << 16 | srcRows[basex + 1] << 8 | srcRows[basex + 2];
- } else
- pixel[0] = reinterpret_cast<uint32_t*>(srcRows + basex)[0];
+ unsigned* pixel = row + x + destx;
+ Color pixelColor(srcRows[basex],
+ srcRows[basex + 1],
+ srcRows[basex + 2],
+ srcRows[basex + 3]);
+ *pixel = premultipliedARGBFromColor(pixelColor);
}
srcRows += srcBytesPerRow;
}
diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp
index 2850488..224154e 100644
--- a/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,10 +30,11 @@
#if PLATFORM(CAIRO)
-#include "TransformationMatrix.h"
+#include "Color.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "ImageObserver.h"
+#include "TransformationMatrix.h"
#include <cairo.h>
#include <math.h>
@@ -60,6 +62,7 @@ BitmapImage::BitmapImage(cairo_surface_t* surface, ImageObserver* observer)
, m_repetitionCountStatus(Unknown)
, m_repetitionsComplete(0)
, m_isSolidColor(false)
+ , m_checkedForSolidColor(false)
, m_animationFinished(true)
, m_allDataReceived(true)
, m_haveSize(true)
@@ -180,8 +183,28 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con
void BitmapImage::checkForSolidColor()
{
- // FIXME: It's easy to implement this optimization. Just need to check the RGBA32 buffer to see if it is 1x1.
m_isSolidColor = false;
+ m_checkedForSolidColor = true;
+
+ if (frameCount() > 1)
+ return;
+
+ cairo_surface_t* frameSurface = frameAtIndex(0);
+ if (!frameSurface)
+ return;
+
+ ASSERT(cairo_surface_get_type(frameSurface) == CAIRO_SURFACE_TYPE_IMAGE);
+
+ int width = cairo_image_surface_get_width(frameSurface);
+ int height = cairo_image_surface_get_height(frameSurface);
+
+ if (width != 1 || height != 1)
+ return;
+
+ unsigned* pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(frameSurface));
+ m_solidColor = colorFromPremultipliedARGB(*pixelColor);
+
+ m_isSolidColor = true;
}
}
diff --git a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp b/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
index 6841599..c6d54f2 100644
--- a/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
@@ -111,7 +111,7 @@ void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer*
delete m_decoder;
m_decoder = 0;
if (data)
- setData(data, allDataReceived);
+ setData(data, allDataReceived);
}
bool ImageSource::initialized() const
diff --git a/WebCore/platform/graphics/cairo/PatternCairo.cpp b/WebCore/platform/graphics/cairo/PatternCairo.cpp
index 7d75db3..58c5d00 100644
--- a/WebCore/platform/graphics/cairo/PatternCairo.cpp
+++ b/WebCore/platform/graphics/cairo/PatternCairo.cpp
@@ -26,23 +26,26 @@
#include "config.h"
#include "Pattern.h"
-#include "TransformationMatrix.h"
#include "GraphicsContext.h"
+#include "TransformationMatrix.h"
#include <cairo.h>
namespace WebCore {
-cairo_pattern_t* Pattern::createPlatformPattern(const TransformationMatrix& patternTransform) const
+cairo_pattern_t* Pattern::createPlatformPattern(const TransformationMatrix&) const
{
cairo_surface_t* surface = tileImage()->nativeImageForCurrentFrame();
if (!surface)
return 0;
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface);
- const TransformationMatrix& inverse = patternTransform.inverse();
- const cairo_matrix_t* pattern_matrix = reinterpret_cast<const cairo_matrix_t*>(&inverse);
- cairo_pattern_set_matrix(pattern, pattern_matrix);
+
+ // cairo merges patter space and user space itself
+ cairo_matrix_t matrix = m_patternSpaceTransformation;
+ cairo_matrix_invert(&matrix);
+ cairo_pattern_set_matrix(pattern, &matrix);
+
if (m_repeatX || m_repeatY)
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
return pattern;
diff --git a/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp b/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp
index b78620f..1b83a29 100644
--- a/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp
+++ b/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp
@@ -32,248 +32,18 @@
namespace WebCore {
-static const double deg2rad = 0.017453292519943295769; // pi/180
-
-TransformationMatrix::TransformationMatrix()
-{
- cairo_matrix_init_identity(&m_transform);
-}
-
-TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- cairo_matrix_init(&m_transform, a, b, c, d, tx, ty);
-}
-
-TransformationMatrix::TransformationMatrix(const PlatformTransformationMatrix& matrix)
-{
- m_transform = matrix;
-}
-
-void TransformationMatrix::setMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- cairo_matrix_init(&m_transform, a, b, c, d, tx, ty);
-}
-
-void TransformationMatrix::map(double x, double y, double* x2, double* y2) const
-{
- *x2 = x;
- *y2 = y;
- cairo_matrix_transform_point(&m_transform, x2, y2);
-}
-
-IntRect TransformationMatrix::mapRect(const IntRect &rect) const
-{
- FloatRect floatRect(rect);
- FloatRect enclosingFloatRect = this->mapRect(floatRect);
-
- return enclosingIntRect(enclosingFloatRect);
-}
-
-FloatRect TransformationMatrix::mapRect(const FloatRect &rect) const
-{
- double rectMinX = rect.x();
- double rectMaxX = rect.x() + rect.width();
- double rectMinY = rect.y();
- double rectMaxY = rect.y() + rect.height();
-
- double px = rectMinX;
- double py = rectMinY;
- cairo_matrix_transform_point(&m_transform, &px, &py);
-
- double enclosingRectMinX = px;
- double enclosingRectMinY = py;
- double enclosingRectMaxX = px;
- double enclosingRectMaxY = py;
-
- px = rectMaxX;
- py = rectMinY;
- cairo_matrix_transform_point(&m_transform, &px, &py);
- if (px < enclosingRectMinX)
- enclosingRectMinX = px;
- else if (px > enclosingRectMaxX)
- enclosingRectMaxX = px;
- if (py < enclosingRectMinY)
- enclosingRectMinY = py;
- else if (py > enclosingRectMaxY)
- enclosingRectMaxY = py;
-
- px = rectMaxX;
- py = rectMaxY;
- cairo_matrix_transform_point(&m_transform, &px, &py);
- if (px < enclosingRectMinX)
- enclosingRectMinX = px;
- else if (px > enclosingRectMaxX)
- enclosingRectMaxX = px;
- if (py < enclosingRectMinY)
- enclosingRectMinY = py;
- else if (py > enclosingRectMaxY)
- enclosingRectMaxY = py;
-
- px = rectMinX;
- py = rectMaxY;
- cairo_matrix_transform_point(&m_transform, &px, &py);
- if (px < enclosingRectMinX)
- enclosingRectMinX = px;
- else if (px > enclosingRectMaxX)
- enclosingRectMaxX = px;
- if (py < enclosingRectMinY)
- enclosingRectMinY = py;
- else if (py > enclosingRectMaxY)
- enclosingRectMaxY = py;
-
-
- double enclosingRectWidth = enclosingRectMaxX - enclosingRectMinX;
- double enclosingRectHeight = enclosingRectMaxY - enclosingRectMinY;
-
- return FloatRect(enclosingRectMinX, enclosingRectMinY, enclosingRectWidth, enclosingRectHeight);
-}
-
-bool TransformationMatrix::isIdentity() const
-{
- return ((m_transform.xx == 1) && (m_transform.yy == 1)
- && (m_transform.xy == 0) && (m_transform.yx == 0)
- && (m_transform.x0 == 0) && (m_transform.y0 == 0));
-}
-
-double TransformationMatrix::a() const
-{
- return m_transform.xx;
-}
-
-void TransformationMatrix::setA(double a)
-{
- m_transform.xx = a;
-}
-
-double TransformationMatrix::b() const
-{
- return m_transform.yx;
-}
-
-void TransformationMatrix::setB(double b)
-{
- m_transform.yx = b;
-}
-
-double TransformationMatrix::c() const
-{
- return m_transform.xy;
-}
-
-void TransformationMatrix::setC(double c)
-{
- m_transform.xy = c;
-}
-
-double TransformationMatrix::d() const
-{
- return m_transform.yy;
-}
-
-void TransformationMatrix::setD(double d)
-{
- m_transform.yy = d;
-}
-
-double TransformationMatrix::e() const
-{
- return m_transform.x0;
-}
-
-void TransformationMatrix::setE(double e)
-{
- m_transform.x0 = e;
-}
-
-double TransformationMatrix::f() const
-{
- return m_transform.y0;
-}
-
-void TransformationMatrix::setF(double f)
-{
- m_transform.y0 = f;
-}
-
-void TransformationMatrix::reset()
-{
- cairo_matrix_init_identity(&m_transform);
-}
-
-TransformationMatrix &TransformationMatrix::scale(double sx, double sy)
-{
- cairo_matrix_scale(&m_transform, sx, sy);
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::rotate(double d)
-{
- cairo_matrix_rotate(&m_transform, d * deg2rad);
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::translate(double tx, double ty)
-{
- cairo_matrix_translate(&m_transform, tx, ty);
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::shear(double sx, double sy)
-{
- cairo_matrix_t shear;
- cairo_matrix_init(&shear, 1, sy, sx, 1, 0, 0);
-
- cairo_matrix_t result;
- cairo_matrix_multiply(&result, &shear, &m_transform);
- m_transform = result;
-
- return *this;
-}
-
-double TransformationMatrix::det() const
-{
- return m_transform.xx * m_transform.yy - m_transform.xy * m_transform.yx;
-}
-
-TransformationMatrix TransformationMatrix::inverse() const
-{
- if (!isInvertible()) return TransformationMatrix();
-
- cairo_matrix_t result = m_transform;
- cairo_matrix_invert(&result);
- return TransformationMatrix(result);
-}
-
TransformationMatrix::operator cairo_matrix_t() const
{
- return m_transform;
-}
+ cairo_matrix_t m;
-bool TransformationMatrix::operator== (const TransformationMatrix &m2) const
-{
- return ((m_transform.xx == m2.m_transform.xx)
- && (m_transform.yy == m2.m_transform.yy)
- && (m_transform.xy == m2.m_transform.xy)
- && (m_transform.yx == m2.m_transform.yx)
- && (m_transform.x0 == m2.m_transform.x0)
- && (m_transform.y0 == m2.m_transform.y0));
-
-}
-
-TransformationMatrix &TransformationMatrix::operator*= (const TransformationMatrix &m2)
-{
- cairo_matrix_t result;
- cairo_matrix_multiply(&result, &m_transform, &m2.m_transform);
- m_transform = result;
-
- return *this;
-}
-
-TransformationMatrix TransformationMatrix::operator* (const TransformationMatrix &m2)
-{
- cairo_matrix_t result;
- cairo_matrix_multiply(&result, &m_transform, &m2.m_transform);
- return result;
+ cairo_matrix_init (&m,
+ a(),
+ b(),
+ c(),
+ d(),
+ e(),
+ f());
+ return m;
}
}
diff --git a/WebCore/platform/graphics/cg/ColorCG.cpp b/WebCore/platform/graphics/cg/ColorCG.cpp
index 48ce9f2..0465c0b 100644
--- a/WebCore/platform/graphics/cg/ColorCG.cpp
+++ b/WebCore/platform/graphics/cg/ColorCG.cpp
@@ -67,9 +67,9 @@ Color::Color(CGColorRef color)
m_color = makeRGBA(r * 255, g * 255, b * 255, a * 255);
}
-#if !PLATFORM(MAC)
+#if PLATFORM(WIN_OS)
-CGColorRef cgColor(const Color& c)
+CGColorRef createCGColor(const Color& c)
{
CGColorRef color = NULL;
CMProfileRef prof = NULL;
@@ -89,7 +89,7 @@ CGColorRef cgColor(const Color& c)
return color;
}
-#endif // !PLATFORM(MAC)
+#endif // PLATFORM(WIN_OS)
}
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 1cc55a4..4b8a555 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -504,6 +504,7 @@ void GraphicsContext::fillPath()
CGContextEOClip(context);
else
CGContextClip(context);
+ CGContextConcatCTM(context, m_common->state.fillGradient->gradientSpaceTransform());
CGContextDrawShading(context, m_common->state.fillGradient->platformGradient());
CGContextRestoreGState(context);
break;
@@ -529,6 +530,7 @@ void GraphicsContext::strokePath()
CGContextSaveGState(context);
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
+ CGContextConcatCTM(context, m_common->state.strokeGradient->gradientSpaceTransform());
CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient());
CGContextRestoreGState(context);
break;
@@ -552,6 +554,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
case GradientColorSpace:
CGContextSaveGState(context);
CGContextClipToRect(context, rect);
+ CGContextConcatCTM(context, m_common->state.fillGradient->gradientSpaceTransform());
CGContextDrawShading(context, m_common->state.fillGradient->platformGradient());
CGContextRestoreGState(context);
break;
@@ -734,7 +737,7 @@ void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Col
if (!color.isValid())
CGContextSetShadow(context, CGSizeMake(width, height), blurRadius);
else {
- CGColorRef colorCG = cgColor(color);
+ CGColorRef colorCG = createCGColor(color);
CGContextSetShadowWithColor(context,
CGSizeMake(width, height),
blurRadius,
@@ -907,7 +910,8 @@ void GraphicsContext::concatCTM(const TransformationMatrix& transform)
TransformationMatrix GraphicsContext::getCTM() const
{
- return CGContextGetCTM(platformContext());
+ CGAffineTransform t = CGContextGetCTM(platformContext());
+ return TransformationMatrix(t.a, t.b, t.c, t.d, t.tx, t.ty);
}
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
diff --git a/WebCore/platform/graphics/cg/ImageCG.cpp b/WebCore/platform/graphics/cg/ImageCG.cpp
index 13c8c07..dbf1d85 100644
--- a/WebCore/platform/graphics/cg/ImageCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageCG.cpp
@@ -73,6 +73,7 @@ BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer)
, m_repetitionCountStatus(Unknown)
, m_repetitionsComplete(0)
, m_isSolidColor(false)
+ , m_checkedForSolidColor(false)
, m_animationFinished(true)
, m_allDataReceived(true)
, m_haveSize(true)
@@ -99,6 +100,7 @@ BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer)
void BitmapImage::checkForSolidColor()
{
+ m_checkedForSolidColor = true;
if (frameCount() > 1)
m_isSolidColor = false;
else {
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index 0b276cc..c059985 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -58,7 +58,7 @@ void ImageSource::clear(bool, size_t, SharedBuffer* data, bool allDataReceived)
m_decoder = 0;
}
if (data)
- setData(data, allDataReceived);
+ setData(data, allDataReceived);
}
static CFDictionaryRef imageSourceOptions()
diff --git a/WebCore/platform/graphics/cg/PatternCG.cpp b/WebCore/platform/graphics/cg/PatternCG.cpp
index 2b9c12f..697bc57 100644
--- a/WebCore/platform/graphics/cg/PatternCG.cpp
+++ b/WebCore/platform/graphics/cg/PatternCG.cpp
@@ -50,12 +50,13 @@ static void patternReleaseCallback(void* info)
static_cast<Image*>(info)->deref();
}
-CGPatternRef Pattern::createPlatformPattern(const TransformationMatrix& transform) const
+CGPatternRef Pattern::createPlatformPattern(const TransformationMatrix& userSpaceTransformation) const
{
IntRect tileRect = tileImage()->rect();
- TransformationMatrix patternTransform = transform;
- patternTransform.scale(1, -1);
+ TransformationMatrix patternTransform = m_patternSpaceTransformation;
+ patternTransform.multiply(userSpaceTransformation);
+ patternTransform.scaleNonUniform(1, -1);
patternTransform.translate(0, -tileRect.height());
// If FLT_MAX should also be used for xStep or yStep, nothing is rendered. Using fractions of FLT_MAX also
diff --git a/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp b/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp
index 9b3181a..568a6b3 100644
--- a/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp
+++ b/WebCore/platform/graphics/cg/TransformationMatrixCG.cpp
@@ -28,187 +28,19 @@
#if PLATFORM(CG)
+#include <CoreGraphics/CGAffineTransform.h>
#include "FloatConversion.h"
-#include "FloatRect.h"
-#include "IntRect.h"
-
-#include <wtf/MathExtras.h>
namespace WebCore {
-TransformationMatrix::TransformationMatrix()
- : m_transform(CGAffineTransformIdentity)
-{
-}
-
-TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- m_transform = CGAffineTransformMake(narrowPrecisionToCGFloat(a),
- narrowPrecisionToCGFloat(b),
- narrowPrecisionToCGFloat(c),
- narrowPrecisionToCGFloat(d),
- narrowPrecisionToCGFloat(tx),
- narrowPrecisionToCGFloat(ty));
-}
-
-TransformationMatrix::TransformationMatrix(const PlatformTransformationMatrix& t)
- : m_transform(t)
-{
-}
-
-void TransformationMatrix::setMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- m_transform = CGAffineTransformMake(narrowPrecisionToCGFloat(a),
- narrowPrecisionToCGFloat(b),
- narrowPrecisionToCGFloat(c),
- narrowPrecisionToCGFloat(d),
- narrowPrecisionToCGFloat(tx),
- narrowPrecisionToCGFloat(ty));
-}
-
-void TransformationMatrix::map(double x, double y, double *x2, double *y2) const
-{
- CGPoint result = CGPointApplyAffineTransform(CGPointMake(narrowPrecisionToCGFloat(x), narrowPrecisionToCGFloat(y)), m_transform);
- *x2 = result.x;
- *y2 = result.y;
-}
-
-IntRect TransformationMatrix::mapRect(const IntRect &rect) const
-{
- return enclosingIntRect(CGRectApplyAffineTransform(CGRect(rect), m_transform));
-}
-
-FloatRect TransformationMatrix::mapRect(const FloatRect &rect) const
-{
- return FloatRect(CGRectApplyAffineTransform(CGRect(rect), m_transform));
-}
-
-bool TransformationMatrix::isIdentity() const
-{
- return CGAffineTransformIsIdentity(m_transform);
-}
-
-double TransformationMatrix::a() const
-{
- return m_transform.a;
-}
-
-void TransformationMatrix::setA(double a)
-{
- m_transform.a = narrowPrecisionToCGFloat(a);
-}
-
-double TransformationMatrix::b() const
-{
- return m_transform.b;
-}
-
-void TransformationMatrix::setB(double b)
-{
- m_transform.b = narrowPrecisionToCGFloat(b);
-}
-
-double TransformationMatrix::c() const
-{
- return m_transform.c;
-}
-
-void TransformationMatrix::setC(double c)
-{
- m_transform.c = narrowPrecisionToCGFloat(c);
-}
-
-double TransformationMatrix::d() const
-{
- return m_transform.d;
-}
-
-void TransformationMatrix::setD(double d)
-{
- m_transform.d = narrowPrecisionToCGFloat(d);
-}
-
-double TransformationMatrix::e() const
-{
- return m_transform.tx;
-}
-
-void TransformationMatrix::setE(double e)
-{
- m_transform.tx = narrowPrecisionToCGFloat(e);
-}
-
-double TransformationMatrix::f() const
-{
- return m_transform.ty;
-}
-
-void TransformationMatrix::setF(double f)
-{
- m_transform.ty = narrowPrecisionToCGFloat(f);
-}
-
-void TransformationMatrix::reset()
-{
- m_transform = CGAffineTransformIdentity;
-}
-
-TransformationMatrix &TransformationMatrix::scale(double sx, double sy)
-{
- m_transform = CGAffineTransformScale(m_transform, narrowPrecisionToCGFloat(sx), narrowPrecisionToCGFloat(sy));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::rotate(double d)
-{
- m_transform = CGAffineTransformRotate(m_transform, narrowPrecisionToCGFloat(deg2rad(d)));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::translate(double tx, double ty)
-{
- m_transform = CGAffineTransformTranslate(m_transform, narrowPrecisionToCGFloat(tx), narrowPrecisionToCGFloat(ty));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::shear(double sx, double sy)
-{
- CGAffineTransform shear = CGAffineTransformMake(1.0f, narrowPrecisionToCGFloat(sy), narrowPrecisionToCGFloat(sx), 1.0f, 0.0f, 0.0f);
- m_transform = CGAffineTransformConcat(shear, m_transform);
- return *this;
-}
-
-double TransformationMatrix::det() const
-{
- return m_transform.a * m_transform.d - m_transform.b * m_transform.c;
-}
-
-TransformationMatrix TransformationMatrix::inverse() const
-{
- if (isInvertible())
- return TransformationMatrix(CGAffineTransformInvert(m_transform));
- return TransformationMatrix();
-}
-
-TransformationMatrix::operator PlatformTransformationMatrix() const
-{
- return m_transform;
-}
-
-bool TransformationMatrix::operator== (const TransformationMatrix &m2) const
-{
- return CGAffineTransformEqualToTransform(m_transform, CGAffineTransform(m2));
-}
-
-TransformationMatrix &TransformationMatrix::operator*= (const TransformationMatrix &m2)
-{
- m_transform = CGAffineTransformConcat(m_transform, CGAffineTransform(m2));
- return *this;
-}
-
-TransformationMatrix TransformationMatrix::operator* (const TransformationMatrix &m2)
+TransformationMatrix::operator CGAffineTransform() const
{
- return CGAffineTransformConcat(m_transform, CGAffineTransform(m2));
+ return CGAffineTransformMake(narrowPrecisionToCGFloat(a()),
+ narrowPrecisionToCGFloat(b()),
+ narrowPrecisionToCGFloat(c()),
+ narrowPrecisionToCGFloat(d()),
+ narrowPrecisionToCGFloat(e()),
+ narrowPrecisionToCGFloat(f()));
}
}
diff --git a/WebCore/platform/graphics/chromium/ColorChromium.cpp b/WebCore/platform/graphics/chromium/ColorChromium.cpp
index 16ca17d..647169c 100644
--- a/WebCore/platform/graphics/chromium/ColorChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ColorChromium.cpp
@@ -28,35 +28,15 @@
namespace WebCore {
+#if !PLATFORM(DARWIN)
+// On OS X, there's code to monitor changes in the focus color system setting.
+// On Windows/Linux there is no equivalent system setting and therefore a static
+// color is all we need.
Color focusRingColor()
{
-// FIXME: This should be split up to ColorChromiumWin and ColorChromiumMac.
-#if PLATFORM(DARWIN)
- // To avoid the Mac Chromium build having to rebasline 500+ layout tests and
- // continue to do this w/ new tests that get landed in WebKit, we want to
- // run the layout tests w/ the same color that stock WebKit uses.
- //
- // TODO: For now we've hard coded the color that WebKit uses for layout
- // tests. We need to revisit this and do either of the following:
- // A. Fully honor the color from the UI, which means collecting the color
- // (and change notifications) in the browser process, and messaging the
- // color to the render process.
- // B. Adding a "layout tests" flag, to control the orage vs. blue colors
- // depending if we're running layout tests.
- // To see the WebKit implementation of using the UI color and/or a flag for
- // layout tests see WebKit/WebCore/platform/graphics/mac/ColorMac.mm.
- // (Reality is we just need an api to override the focus color and both
- // of the above are covered for what this file needs to provide, the
- // two options would be details that happen in other places.)
-
- // From WebKit:
- // static RGBA32 oldAquaFocusRingColorRGBA = 0xFF7DADD9;
- static Color oldAquaFocusRingColor(0x7D, 0xAD, 0xD9, 0xFF);
- return oldAquaFocusRingColor;
-#else
static Color focusRingColor(229, 151, 0, 255);
return focusRingColor;
-#endif
}
+#endif
} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/ColorChromiumMac.mm b/WebCore/platform/graphics/chromium/ColorChromiumMac.mm
new file mode 100644
index 0000000..01dff7e
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/ColorChromiumMac.mm
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Color.h"
+
+#import <AppKit/NSColor.h>
+#import <wtf/Assertions.h>
+#import <wtf/StdLibExtras.h>
+#import <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+Color focusRingColor()
+{
+ // To avoid the Mac Chromium build having to rebasline 500+ layout tests and
+ // continue to do this w/ new tests that get landed in WebKit, we want to
+ // run the layout tests w/ the same color that stock WebKit uses.
+ //
+ // FIXME: For now we've hard coded the color that WebKit uses for layout
+ // tests. We need to revisit this and do either of the following:
+ // A. Fully honor the color from the UI, which means collecting the color
+ // (and change notifications) in the browser process, and messaging the
+ // color to the render process.
+ // B. Adding a "layout tests" flag, to control the orage vs. blue colors
+ // depending if we're running layout tests.
+ // To see the WebKit implementation of using the UI color and/or a flag for
+ // layout tests see WebKit/WebCore/platform/graphics/mac/ColorMac.mm.
+ // (Reality is we just need an api to override the focus color and both
+ // of the above are covered for what this file needs to provide, the
+ // two options would be details that happen in other places.)
+
+ // From WebKit:
+ // static RGBA32 oldAquaFocusRingColorRGBA = 0xFF7DADD9;
+ static Color oldAquaFocusRingColor(0x7D, 0xAD, 0xD9, 0xFF);
+ return oldAquaFocusRingColor;
+}
+
+// createCGColor() and the functions it calls are verbatum copies of
+// graphics/mac/ColorMac.mm. These are copied here so that we don't need to
+// include ColorMac.mm in the Chromium build.
+// FIXME: Check feasibility of using pure CG calls and unifying this copy with
+// ColorMac.mm's under graphics/cg.
+
+NSColor* nsColor(const Color& color)
+{
+ unsigned c = color.rgb();
+ switch (c) {
+ case 0: {
+ // Need this to avoid returning nil because cachedRGBAValues will default to 0.
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, clearColor, ([NSColor colorWithDeviceRed:0.0f green:0.0f blue:0.0f alpha:0.0f]));
+ return clearColor.get();
+ }
+ case Color::black: {
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, blackColor, ([NSColor colorWithDeviceRed:0.0f green:0.0f blue:0.0f alpha:1.0f]));
+ return blackColor.get();
+ }
+ case Color::white: {
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, whiteColor, ([NSColor colorWithDeviceRed:1.0f green:1.0f blue:1.0f alpha:1.0f]));
+ return whiteColor.get();
+ }
+ default: {
+ const int cacheSize = 32;
+ static unsigned cachedRGBAValues[cacheSize];
+ static RetainPtr<NSColor>* cachedColors = new RetainPtr<NSColor>[cacheSize];
+
+ for (int i = 0; i != cacheSize; ++i)
+ if (cachedRGBAValues[i] == c)
+ return cachedColors[i].get();
+
+ NSColor* result = [NSColor colorWithDeviceRed:color.red() / 255.0f
+ green:color.green() / 255.0f
+ blue:color.blue() / 255.0f
+ alpha:color.alpha() /255.0f];
+
+ static int cursor;
+ cachedRGBAValues[cursor] = c;
+ cachedColors[cursor] = result;
+ if (++cursor == cacheSize)
+ cursor = 0;
+ return result;
+ }
+ }
+}
+
+static CGColorRef CGColorFromNSColor(NSColor* color)
+{
+ // This needs to always use device colorspace so it can de-calibrate the color for
+ // CGColor to possibly recalibrate it.
+ NSColor* deviceColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ CGFloat red = [deviceColor redComponent];
+ CGFloat green = [deviceColor greenComponent];
+ CGFloat blue = [deviceColor blueComponent];
+ CGFloat alpha = [deviceColor alphaComponent];
+ const CGFloat components[4] = { red, green, blue, alpha };
+ static CGColorSpaceRef deviceRGBColorSpace = CGColorSpaceCreateDeviceRGB();
+ CGColorRef cgColor = CGColorCreate(deviceRGBColorSpace, components);
+ return cgColor;
+}
+
+CGColorRef createCGColor(const Color& c)
+{
+ // We could directly create a CGColor here, but that would
+ // skip any RGB caching the nsColor method does. A direct
+ // creation could be investigated for a possible performance win.
+ return CGColorFromNSColor(nsColor(c));
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
index 03583a0..129776e 100644
--- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp
@@ -394,53 +394,18 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, cons
family = panUniFonts[i];
data = getCachedFontPlatformData(font.fontDescription(), AtomicString(family, wcslen(family)));
}
- if (i < numFonts) // we found the font that covers this character !
+ // When i-th font (0-base) in |panUniFonts| contains a character and
+ // we get out of the loop, |i| will be |i + 1|. That is, if only the
+ // last font in the array covers the character, |i| will be numFonts.
+ // So, we have to use '<=" rather than '<' to see if we found a font
+ // covering the character.
+ if (i <= numFonts)
return getCachedFontData(data);
return 0;
}
-const AtomicString& FontCache::alternateFamilyName(const AtomicString& familyName)
-{
- // Note that mapping to Courier is removed because
- // because it's a bitmap font on Windows.
- // Alias Courier -> Courier New
- static AtomicString courier("Courier"), courierNew("Courier New");
- if (equalIgnoringCase(familyName, courier))
- return courierNew;
-
- // Alias Times <-> Times New Roman.
- static AtomicString times("Times"), timesNewRoman("Times New Roman");
- if (equalIgnoringCase(familyName, times))
- return timesNewRoman;
- if (equalIgnoringCase(familyName, timesNewRoman))
- return times;
-
- // Alias Helvetica <-> Arial
- static AtomicString arial("Arial"), helvetica("Helvetica");
- if (equalIgnoringCase(familyName, helvetica))
- return arial;
- if (equalIgnoringCase(familyName, arial))
- return helvetica;
-
- // We block bitmap fonts altogether so that we have to
- // alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font)
- static AtomicString msSans("MS Sans Serif");
- static AtomicString microsoftSans("Microsoft Sans Serif");
- if (equalIgnoringCase(familyName, msSans))
- return microsoftSans;
-
- // Alias MS Serif (bitmap) -> Times New Roman (truetype font). There's no
- // 'Microsoft Sans Serif-equivalent' for Serif.
- static AtomicString msSerif("MS Serif");
- if (equalIgnoringCase(familyName, msSerif))
- return timesNewRoman;
-
- // FIXME: should we map 'system' to something ('Tahoma') ?
- return emptyAtom;
-}
-
FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
diff --git a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
index f187c55..89433e1 100644
--- a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
@@ -91,16 +91,6 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font,
return ret;
}
-const AtomicString& FontCache::alternateFamilyName(const AtomicString& familyName)
-{
- notImplemented();
-
- // This is just to stop GCC emitting a warning about returning a reference
- // to a temporary variable
- static AtomicString a;
- return a;
-}
-
FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font)
{
return 0;
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 3cf18a6..1b71946 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -32,7 +32,6 @@
#include "config.h"
#include "Font.h"
-#include "TransformationMatrix.h"
#include "ChromiumBridge.h"
#include "FontFallbackList.h"
#include "GlyphBuffer.h"
@@ -40,6 +39,7 @@
#include "SimpleFontData.h"
#include "SkiaFontWin.h"
#include "SkiaUtils.h"
+#include "TransparencyWin.h"
#include "UniscribeHelperTextRun.h"
#include "skia/ext/platform_canvas_win.h"
@@ -49,122 +49,274 @@
namespace WebCore {
-static bool windowsCanHandleTextDrawing(GraphicsContext* context)
+namespace {
+
+bool canvasHasMultipleLayers(const SkCanvas* canvas)
+{
+ SkCanvas::LayerIter iter(const_cast<SkCanvas*>(canvas), false);
+ iter.next(); // There is always at least one layer.
+ return !iter.done(); // There is > 1 layer if the the iterator can stil advance.
+}
+
+class TransparencyAwareFontPainter {
+public:
+ TransparencyAwareFontPainter(GraphicsContext*, const FloatPoint&);
+ ~TransparencyAwareFontPainter();
+
+protected:
+ // Called by our subclass' constructor to initialize GDI if necessary. This
+ // is a separate function so it can be called after the subclass finishes
+ // construction (it calls virtual functions).
+ void init();
+
+ virtual IntRect estimateTextBounds() = 0;
+
+ // Use the context from the transparency helper when drawing with GDI. It
+ // may point to a temporary one.
+ GraphicsContext* m_graphicsContext;
+ PlatformGraphicsContext* m_platformContext;
+
+ FloatPoint m_point;
+
+ // Set when Windows can handle the type of drawing we're doing.
+ bool m_useGDI;
+
+ // These members are valid only when m_useGDI is set.
+ HDC m_hdc;
+ TransparencyWin m_transparency;
+
+private:
+ // Call when we're using GDI mode to initialize the TransparencyWin to help
+ // us draw GDI text.
+ void initializeForGDI();
+
+ bool m_createdTransparencyLayer; // We created a layer to give the font some alpha.
+};
+
+TransparencyAwareFontPainter::TransparencyAwareFontPainter(GraphicsContext* context,
+ const FloatPoint& point)
+ : m_graphicsContext(context)
+ , m_platformContext(context->platformContext())
+ , m_point(point)
+ , m_useGDI(windowsCanHandleTextDrawing(context))
+ , m_hdc(0)
+ , m_createdTransparencyLayer(false)
+{
+}
+
+void TransparencyAwareFontPainter::init()
{
- // Check for non-translation transforms. Sometimes zooms will look better in
- // Skia, and sometimes better in Windows. The main problem is that zooming
- // in using Skia will show you the hinted outlines for the smaller size,
- // which look weird. All else being equal, it's better to use Windows' text
- // drawing, so we don't check for zooms.
- const TransformationMatrix& matrix = context->getCTM();
- if (matrix.b() != 0 || matrix.c() != 0) // Check for skew.
- return false;
-
- // Check for stroke effects.
- if (context->platformContext()->getTextDrawingMode() != cTextFill)
- return false;
-
- // Check for shadow effects.
- if (context->platformContext()->getDrawLooper())
- return false;
-
- return true;
+ if (m_useGDI)
+ initializeForGDI();
}
-// Skia equivalents to Windows text drawing functions. They
-// will get the outlines from Windows and draw then using Skia using the given
-// parameters in the paint arguments. This allows more complex effects and
-// transforms to be drawn than Windows allows.
-//
-// These functions will be significantly slower than Windows GDI, and the text
-// will look different (no ClearType), so use only when necessary.
-//
-// When you call a Skia* text drawing function, various glyph outlines will be
-// cached. As a result, you should call SkiaWinOutlineCache::removePathsForFont
-// when the font is destroyed so that the cache does not outlive the font (since
-// the HFONTs are recycled).
-
-// Analog of the Windows GDI function DrawText, except using the given SkPaint
-// attributes for the text. See above for more.
-//
-// Returns true of the text was drawn successfully. False indicates an error
-// from Windows.
-static bool skiaDrawText(HFONT hfont,
- SkCanvas* canvas,
- const SkPoint& point,
- SkPaint* paint,
- const WORD* glyphs,
- const int* advances,
- int numGlyphs)
+void TransparencyAwareFontPainter::initializeForGDI()
{
- HDC dc = GetDC(0);
- HGDIOBJ oldFont = SelectObject(dc, hfont);
-
- canvas->save();
- canvas->translate(point.fX, point.fY);
-
- for (int i = 0; i < numGlyphs; i++) {
- const SkPath* path = SkiaWinOutlineCache::lookupOrCreatePathForGlyph(dc, hfont, glyphs[i]);
- if (!path)
- return false;
- canvas->drawPath(*path, *paint);
- canvas->translate(advances[i], 0);
+ SkColor color = m_platformContext->effectiveFillColor();
+ if (SkColorGetA(color) != 0xFF) {
+ // When the font has some transparency, apply it by creating a new
+ // transparency layer with that opacity applied.
+ m_createdTransparencyLayer = true;
+ m_graphicsContext->beginTransparencyLayer(SkColorGetA(color) / 255.0f);
+ // The color should be opaque now.
+ color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
}
- canvas->restore();
+ TransparencyWin::LayerMode layerMode;
+ IntRect layerRect;
+ if (m_platformContext->isDrawingToImageBuffer()) {
+ // Assume if we're drawing to an image buffer that the background
+ // is not opaque and we have to undo ClearType. We may want to
+ // enhance this to actually check, since it will often be opaque
+ // and we could do ClearType in that case.
+ layerMode = TransparencyWin::TextComposite;
+ layerRect = estimateTextBounds();
+
+ // The transparency helper requires that we draw text in black in
+ // this mode and it will apply the color.
+ m_transparency.setTextCompositeColor(color);
+ color = SkColorSetRGB(0, 0, 0);
+ } else if (canvasHasMultipleLayers(m_platformContext->canvas())) {
+ // When we're drawing a web page, we know the background is opaque,
+ // but if we're drawing to a layer, we still need extra work.
+ layerMode = TransparencyWin::OpaqueCompositeLayer;
+ layerRect = estimateTextBounds();
+ } else {
+ // Common case of drawing onto the bottom layer of a web page: we
+ // know everything is opaque so don't need to do anything special.
+ layerMode = TransparencyWin::NoLayer;
+ }
+ m_transparency.init(m_graphicsContext, layerMode, TransparencyWin::KeepTransform, layerRect);
- SelectObject(dc, oldFont);
- ReleaseDC(0, dc);
- return true;
+ // Set up the DC, using the one from the transparency helper.
+ m_hdc = m_transparency.platformContext()->canvas()->beginPlatformPaint();
+ SetTextColor(m_hdc, skia::SkColorToCOLORREF(color));
+ SetBkMode(m_hdc, TRANSPARENT);
}
-static bool paintSkiaText(PlatformContextSkia* platformContext,
- HFONT hfont,
- int numGlyphs,
- const WORD* glyphs,
- const int* advances,
- const SkPoint& origin)
+TransparencyAwareFontPainter::~TransparencyAwareFontPainter()
{
- int textMode = platformContext->getTextDrawingMode();
-
- // Filling (if necessary). This is the common case.
- SkPaint paint;
- platformContext->setupPaintForFilling(&paint);
- paint.setFlags(SkPaint::kAntiAlias_Flag);
- bool didFill = false;
- if ((textMode & cTextFill) && SkColorGetA(paint.getColor())) {
- if (!skiaDrawText(hfont, platformContext->canvas(), origin, &paint, &glyphs[0], &advances[0], numGlyphs))
- return false;
- didFill = true;
- }
+ if (!m_useGDI)
+ return; // Nothing to do.
+ m_transparency.composite();
+ if (m_createdTransparencyLayer)
+ m_graphicsContext->endTransparencyLayer();
+ m_platformContext->canvas()->endPlatformPaint();
+}
- // Stroking on top (if necessary).
- if ((textMode & WebCore::cTextStroke)
- && platformContext->getStrokeStyle() != NoStroke
- && platformContext->getStrokeThickness() > 0) {
-
- paint.reset();
- platformContext->setupPaintForStroking(&paint, 0, 0);
- paint.setFlags(SkPaint::kAntiAlias_Flag);
- if (didFill) {
- // If there is a shadow and we filled above, there will already be
- // a shadow. We don't want to draw it again or it will be too dark
- // and it will go on top of the fill.
- //
- // Note that this isn't strictly correct, since the stroke could be
- // very thick and the shadow wouldn't account for this. The "right"
- // thing would be to draw to a new layer and then draw that layer
- // with a shadow. But this is a lot of extra work for something
- // that isn't normally an issue.
- paint.setLooper(0)->safeUnref();
- }
+// Specialization for simple GlyphBuffer painting.
+class TransparencyAwareGlyphPainter : public TransparencyAwareFontPainter {
+ public:
+ TransparencyAwareGlyphPainter(GraphicsContext*,
+ const SimpleFontData*,
+ const GlyphBuffer&,
+ int from, int numGlyphs,
+ const FloatPoint&);
+ ~TransparencyAwareGlyphPainter();
+
+ // Draws the partial string of glyphs, starting at |startAdvance| to the
+ // left of m_point. We express it this way so that if we're using the Skia
+ // drawing path we can use floating-point positioning, even though we have
+ // to use integer positioning in the GDI path.
+ bool drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, int startAdvance) const;
+
+ private:
+ virtual IntRect estimateTextBounds();
+
+ const SimpleFontData* m_font;
+ const GlyphBuffer& m_glyphBuffer;
+ int m_from;
+ int m_numGlyphs;
+
+ // When m_useGdi is set, this stores the previous HFONT selected into the
+ // m_hdc so we can restore it.
+ HGDIOBJ m_oldFont; // For restoring the DC to its original state.
+};
+
+TransparencyAwareGlyphPainter::TransparencyAwareGlyphPainter(
+ GraphicsContext* context,
+ const SimpleFontData* font,
+ const GlyphBuffer& glyphBuffer,
+ int from, int numGlyphs,
+ const FloatPoint& point)
+ : TransparencyAwareFontPainter(context, point)
+ , m_font(font)
+ , m_glyphBuffer(glyphBuffer)
+ , m_from(from)
+ , m_numGlyphs(numGlyphs)
+ , m_oldFont(0)
+{
+ init();
+
+ m_oldFont = ::SelectObject(m_hdc, m_font->platformData().hfont());
+}
- if (!skiaDrawText(hfont, platformContext->canvas(), origin, &paint, &glyphs[0], &advances[0], numGlyphs))
- return false;
+TransparencyAwareGlyphPainter::~TransparencyAwareGlyphPainter()
+{
+ if (m_useGDI)
+ ::SelectObject(m_hdc, m_oldFont);
+}
+
+
+// Estimates the bounding box of the given text. This is copied from
+// FontCGWin.cpp, it is possible, but a lot more work, to get the precide
+// bounds.
+IntRect TransparencyAwareGlyphPainter::estimateTextBounds()
+{
+ int totalWidth = 0;
+ for (int i = 0; i < m_numGlyphs; i++)
+ totalWidth += lroundf(m_glyphBuffer.advanceAt(m_from + i));
+
+ return IntRect(m_point.x() - (m_font->ascent() + m_font->descent()) / 2,
+ m_point.y() - m_font->ascent() - m_font->lineGap(),
+ totalWidth + m_font->ascent() + m_font->descent(),
+ m_font->lineSpacing());
+}
+
+bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
+ const WORD* glyphs,
+ const int* advances,
+ int startAdvance) const
+{
+ if (!m_useGDI) {
+ SkPoint origin = m_point;
+ origin.fX += startAdvance;
+ return paintSkiaText(m_graphicsContext, m_font->platformData().hfont(),
+ numGlyphs, glyphs, advances, 0, &origin);
}
- return true;
+
+ // Windows' origin is the top-left of the bounding box, so we have
+ // to subtract off the font ascent to get it.
+ int x = lroundf(m_point.x() + startAdvance);
+ int y = lroundf(m_point.y() - m_font->ascent());
+ return !!ExtTextOut(m_hdc, x, y, ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
+}
+
+
+class TransparencyAwareUniscribePainter : public TransparencyAwareFontPainter {
+ public:
+ TransparencyAwareUniscribePainter(GraphicsContext*,
+ const Font*,
+ const TextRun&,
+ int from, int to,
+ const FloatPoint&);
+ ~TransparencyAwareUniscribePainter();
+
+ // Uniscibe will draw directly into our buffer, so we need to expose our DC.
+ HDC hdc() const { return m_hdc; }
+
+ private:
+ virtual IntRect estimateTextBounds();
+
+ const Font* m_font;
+ const TextRun& m_run;
+ int m_from;
+ int m_to;
+};
+
+TransparencyAwareUniscribePainter::TransparencyAwareUniscribePainter(
+ GraphicsContext* context,
+ const Font* font,
+ const TextRun& run,
+ int from, int to,
+ const FloatPoint& point)
+ : TransparencyAwareFontPainter(context, point)
+ , m_font(font)
+ , m_run(run)
+ , m_from(from)
+ , m_to(to)
+{
+ init();
}
+TransparencyAwareUniscribePainter::~TransparencyAwareUniscribePainter()
+{
+}
+
+IntRect TransparencyAwareUniscribePainter::estimateTextBounds()
+{
+ // This case really really sucks. There is no convenient way to estimate
+ // the bounding box. So we run Uniscribe twice. If we find this happens a
+ // lot, the way to fix it is to make the extra layer after the
+ // UniscribeHelper has measured the text.
+ IntPoint intPoint(lroundf(m_point.x()),
+ lroundf(m_point.y()));
+
+ UniscribeHelperTextRun state(m_run, *m_font);
+ int left = lroundf(m_point.x()) + state.characterToX(m_from);
+ int right = lroundf(m_point.x()) + state.characterToX(m_to);
+
+ // This algorithm for estimating how much extra space we need (the text may
+ // go outside the selection rect) is based roughly on
+ // TransparencyAwareGlyphPainter::estimateTextBounds above.
+ return IntRect(left - (m_font->ascent() + m_font->descent()) / 2,
+ m_point.y() - m_font->ascent() - m_font->lineGap(),
+ (right - left) + m_font->ascent() + m_font->descent(),
+ m_font->lineSpacing());
+}
+
+} // namespace
+
void Font::drawGlyphs(GraphicsContext* graphicsContext,
const SimpleFontData* font,
const GlyphBuffer& glyphBuffer,
@@ -172,51 +324,27 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
int numGlyphs,
const FloatPoint& point) const
{
- PlatformGraphicsContext* context = graphicsContext->platformContext();
-
- // Max buffer length passed to the underlying windows API.
- const int kMaxBufferLength = 1024;
- // Default size for the buffer. It should be enough for most of cases.
- const int kDefaultBufferLength = 256;
-
- SkColor color = context->fillColor();
+ SkColor color = graphicsContext->platformContext()->effectiveFillColor();
unsigned char alpha = SkColorGetA(color);
// Skip 100% transparent text; no need to draw anything.
- if (!alpha && context->getStrokeStyle() == NoStroke)
+ if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke)
return;
- // Set up our graphics context.
- HDC hdc = context->canvas()->beginPlatformPaint();
- HGDIOBJ oldFont = SelectObject(hdc, font->platformData().hfont());
-
- // TODO(maruel): http://b/700464 SetTextColor doesn't support transparency.
- // Enforce non-transparent color.
- color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
- SetTextColor(hdc, skia::SkColorToCOLORREF(color));
- SetBkMode(hdc, TRANSPARENT);
-
- // Windows needs the characters and the advances in nice contiguous
- // buffers, which we build here.
- Vector<WORD, kDefaultBufferLength> glyphs;
- Vector<int, kDefaultBufferLength> advances;
-
- // Compute the coordinate. The 'origin' represents the baseline, so we need
- // to move it up to the top of the bounding square.
- int x = static_cast<int>(point.x());
- int lineTop = static_cast<int>(point.y()) - font->ascent();
-
- bool canUseGDI = windowsCanHandleTextDrawing(graphicsContext);
+ TransparencyAwareGlyphPainter painter(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
// We draw the glyphs in chunks to avoid having to do a heap allocation for
// the arrays of characters and advances. Since ExtTextOut is the
// lowest-level text output function on Windows, there should be little
// penalty for splitting up the text. On the other hand, the buffer cannot
// be bigger than 4094 or the function will fail.
- int glyphIndex = 0;
+ const int kMaxBufferLength = 256;
+ Vector<WORD, kMaxBufferLength> glyphs;
+ Vector<int, kMaxBufferLength> advances;
+ int glyphIndex = 0; // The starting glyph of the current chunk.
+ int curAdvance = 0; // How far from the left the current chunk is.
while (glyphIndex < numGlyphs) {
- // how many chars will be in this chunk?
+ // How many chars will be in this chunk?
int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
-
glyphs.resize(curLen);
advances.resize(curLen);
@@ -227,17 +355,10 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
curWidth += advances[i];
}
+ // Actually draw the glyphs (with retry on failure).
bool success = false;
for (int executions = 0; executions < 2; ++executions) {
- if (canUseGDI)
- success = !!ExtTextOut(hdc, x, lineTop, ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), curLen, &advances[0]);
- else {
- // Skia's text draing origin is the baseline, like WebKit, not
- // the top, like Windows.
- SkPoint origin = { x, point.y() };
- success = paintSkiaText(context, font->platformData().hfont(), numGlyphs, reinterpret_cast<const WORD*>(&glyphs[0]), &advances[0], origin);
- }
-
+ success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], curAdvance);
if (!success && executions == 0) {
// Ask the browser to load the font for us and retry.
ChromiumBridge::ensureFontLoaded(font->platformData().hfont());
@@ -247,12 +368,8 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext,
}
ASSERT(success);
-
- x += curWidth;
+ curAdvance += curWidth;
}
-
- SelectObject(hdc, oldFont);
- context->canvas()->endPlatformPaint();
}
FloatRect Font::selectionRectForComplexText(const TextRun& run,
@@ -283,13 +400,15 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
PlatformGraphicsContext* context = graphicsContext->platformContext();
UniscribeHelperTextRun state(run, *this);
- SkColor color = context->fillColor();
+ SkColor color = graphicsContext->platformContext()->effectiveFillColor();
unsigned char alpha = SkColorGetA(color);
// Skip 100% transparent text; no need to draw anything.
- if (!alpha)
+ if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke)
return;
- HDC hdc = context->canvas()->beginPlatformPaint();
+ TransparencyAwareUniscribePainter painter(graphicsContext, this, run, from, to, point);
+
+ HDC hdc = painter.hdc();
// TODO(maruel): http://b/700464 SetTextColor doesn't support transparency.
// Enforce non-transparent color.
@@ -299,7 +418,9 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
// Uniscribe counts the coordinates from the upper left, while WebKit uses
// the baseline, so we have to subtract off the ascent.
- state.draw(hdc, static_cast<int>(point.x()), static_cast<int>(point.y() - ascent()), from, to);
+ state.draw(graphicsContext, hdc, static_cast<int>(point.x()),
+ static_cast<int>(point.y() - ascent()), from, to);
+
context->canvas()->endPlatformPaint();
}
diff --git a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp b/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
index 8f8df88..1e923ac 100644
--- a/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/chromium/FontCustomPlatformData.cpp
@@ -116,7 +116,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
// Streams the concatenation of a header and font data.
class EOTStream {
public:
- EOTStream(const Vector<UInt8, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
+ EOTStream(const Vector<uint8_t, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
: m_eotHeader(eotHeader)
, m_fontData(fontData)
, m_overlayDst(overlayDst)
@@ -130,7 +130,7 @@ public:
size_t read(void* buffer, size_t count);
private:
- const Vector<UInt8, 512>& m_eotHeader;
+ const Vector<uint8_t, 512>& m_eotHeader;
const SharedBuffer* m_fontData;
size_t m_overlayDst;
size_t m_overlaySrc;
@@ -200,7 +200,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
// TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data,
// so we need to create an EOT header and prepend it to the font data.
- Vector<UInt8, 512> eotHeader;
+ Vector<uint8_t, 512> eotHeader;
size_t overlayDst;
size_t overlaySrc;
size_t overlayLength;
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index 7a3e614..2b7c562 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -49,14 +49,6 @@ namespace WebCore {
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const {
- SkCanvas* canvas = gc->platformContext()->canvas();
- SkPaint paint;
-
- gc->platformContext()->setupPaintCommon(&paint);
- font->platformData().setupPaint(&paint);
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- paint.setColor(gc->fillColor().rgb());
-
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t)); // compile-time assert
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
@@ -78,7 +70,39 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
- canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
+
+ SkCanvas* canvas = gc->platformContext()->canvas();
+ int textMode = gc->platformContext()->getTextDrawingMode();
+
+ // 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);
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ paint.setColor(gc->fillColor().rgb());
+ canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
+ }
+
+ if ((textMode & cTextStroke)
+ && gc->platformContext()->getStrokeStyle() != NoStroke
+ && gc->platformContext()->getStrokeThickness() > 0) {
+
+ SkPaint paint;
+ gc->platformContext()->setupPaintForStroking(&paint, 0, 0);
+ font->platformData().setupPaint(&paint);
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ paint.setColor(gc->strokeColor().rgb());
+
+ if (textMode & cTextFill) {
+ // If we also filled, we don't want to draw shadows twice.
+ // See comment in FontChromiumWin.cpp::paintSkiaText() for more details.
+ paint.setLooper(0)->safeUnref();
+ }
+
+ canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
+ }
}
void Font::drawComplexText(GraphicsContext* context, const TextRun& run,
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index 86f96ee..7b7d197 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -86,7 +86,7 @@ void FontPlatformData::setupPaint(SkPaint* paint) const
{
const float ts = m_textSize > 0 ? m_textSize : 12;
- paint->setAntiAlias(false);
+ paint->setAntiAlias(true);
paint->setSubpixelText(false);
paint->setTextSize(SkFloatToScalar(ts));
paint->setTypeface(m_typeface);
diff --git a/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp b/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
index 4c5cf7b..31c5256 100644
--- a/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/GlyphPageTreeNodeChromiumWin.cpp
@@ -147,27 +147,17 @@ static bool fillBMPGlyphs(unsigned offset,
// When this character should be a space, we ignore whatever the font
// says and use a space. Otherwise, if fonts don't map one of these
// space or zero width glyphs, we will get a box.
- if (Font::treatAsSpace(c))
+ if (Font::treatAsSpace(c)) {
// Hard code the glyph indices for characters that should be
// treated like spaces.
glyph = initSpaceGlyph(dc, &spaceGlyph);
- else if (Font::treatAsZeroWidthSpace(c) || c == 0x200B) {
- // FIXME: change Font::treatAsZeroWidthSpace to use
- // u_hasBinaryProperty, per jungshik's comment here:
- // https://bugs.webkit.org/show_bug.cgi?id=20237#c6.
- // Then the additional OR above won't be necessary.
- glyph = initSpaceGlyph(dc, &spaceGlyph);
- glyphFontData = fontData->zeroWidthFontData();
} else if (glyph == invalidGlyph) {
// WebKit expects both the glyph index and FontData
// pointer to be 0 if the glyph is not present
glyph = 0;
glyphFontData = 0;
- } else {
- if (SimpleFontData::isCJKCodePoint(c))
- glyphFontData = fontData->cjkWidthFontData();
+ } else
haveGlyphs = true;
- }
page->setGlyphDataForCharacter(offset + i, glyph, glyphFontData);
}
@@ -205,6 +195,7 @@ static bool fillNonBMPGlyphs(unsigned offset,
fontData->m_font.scriptCache(),
fontData->m_font.scriptFontProperties());
state.setInhibitLigate(true);
+ state.setDisableFontFallback(true);
state.init();
for (unsigned i = 0; i < length; i++) {
diff --git a/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h b/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h
index 959147a..e8ba0ad 100644
--- a/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h
+++ b/WebCore/platform/graphics/chromium/MediaPlayerPrivateChromium.h
@@ -33,13 +33,13 @@
#if ENABLE(VIDEO)
-#include "MediaPlayer.h"
+#include "MediaPlayerPrivate.h"
namespace WebCore {
-class MediaPlayerPrivate : public Noncopyable {
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
public:
- MediaPlayerPrivate(MediaPlayer*);
+ static void registerMediaEngine(MediaEngineRegistrar);
~MediaPlayerPrivate();
IntSize naturalSize() const;
@@ -74,13 +74,10 @@ public:
unsigned totalBytes() const;
void setVisible(bool);
- void setRect(const IntRect&);
+ void setSize(const IntSize&);
void paint(GraphicsContext*, const IntRect&);
- static void getSupportedTypes(HashSet<String>&);
- static bool isAvailable();
-
// Public methods to be called by WebMediaPlayer
FrameView* frameView();
void networkStateChanged();
@@ -90,6 +87,12 @@ public:
void repaint();
private:
+ MediaPlayerPrivate(MediaPlayer*);
+ static MediaPlayerPrivateInterface* create(MediaPlayer* player);
+ static void getSupportedTypes(HashSet<String>&);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable();
+
MediaPlayer* m_player;
void* m_data;
};
diff --git a/WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.cpp b/WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.cpp
deleted file mode 100644
index 798ee32..0000000
--- a/WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ThemeHelperChromiumWin.h"
-
-#include "FloatRect.h"
-#include "GraphicsContext.h"
-
-namespace WebCore {
-
-ThemeHelperWin::ThemeHelperWin(GraphicsContext* context, const IntRect& rect)
- : m_orgContext(context)
- , m_orgMatrix(context->getCTM())
- , m_orgRect(rect)
-{
- if (m_orgMatrix.b() != 0 || m_orgMatrix.c() != 0) { // Check for skew.
- // Complicated effects, make a copy and draw the bitmap there.
- m_type = COPY;
- m_rect.setSize(rect.size());
-
- m_newBuffer.set(ImageBuffer::create(rect.size(), false).release());
-
- // Theme drawing messes with the transparency.
- // FIXME: Ideally, we would leave this transparent, but I was
- // having problems with button drawing, so we fill with white. Buttons
- // looked good with transparent here and no fixing up of the alpha
- // later, but text areas didn't. This makes text areas look good but
- // gives buttons a white halo. Is there a way to fix this? I think
- // buttons actually have antialised edges which is just not possible
- // to handle on a transparent background given that it messes with the
- // alpha channel.
- FloatRect newContextRect(0, 0, rect.width(), rect.height());
- GraphicsContext* newContext = m_newBuffer->context();
- newContext->setFillColor(Color::white);
- newContext->fillRect(newContextRect);
-
- return;
- }
-
- if (m_orgMatrix.a() != 1.0 || m_orgMatrix.d() != 1.0) { // Check for scale.
- // Only a scaling is applied.
- m_type = SCALE;
-
- // Save the transformed coordinates to draw.
- m_rect = m_orgMatrix.mapRect(rect);
-
- m_orgContext->save();
- m_orgContext->concatCTM(m_orgContext->getCTM().inverse());
- return;
- }
-
- // Nothing interesting.
- m_rect = rect;
- m_type = ORIGINAL;
-}
-
-ThemeHelperWin::~ThemeHelperWin()
-{
- switch (m_type) {
- case SCALE:
- m_orgContext->restore();
- break;
- case COPY: {
- // Copy the duplicate bitmap with our control to the original canvas.
- FloatRect destRect(m_orgRect);
- m_newBuffer->context()->platformContext()->canvas()->
- getTopPlatformDevice().fixupAlphaBeforeCompositing();
- m_orgContext->drawImage(m_newBuffer->image(), destRect);
- break;
- }
- case ORIGINAL:
- break;
- }
-}
-
-} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.h b/WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.h
deleted file mode 100644
index 1771fb4..0000000
--- a/WebCore/platform/graphics/chromium/ThemeHelperChromiumWin.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ThemeHelperWin_h
-#define ThemeHelperWin_h
-
-#include "TransformationMatrix.h"
-#include "ImageBuffer.h"
-#include "IntRect.h"
-#include <wtf/OwnPtr.h>
-
-namespace WebCore {
-
-class GraphicsContext;
-class IntRect;
-
-// Helps drawing theme elements like buttons and scroll bars. This will handle
-// translations and scalings that Windows might not, by either making Windows
-// draw the appropriate sized control, or by rendering it into an off-screen
-// context and transforming it ourselves.
-class ThemeHelperWin {
- enum Type {
- // Use the original canvas with no changes. This is the normal mode.
- ORIGINAL,
-
- // Use the original canvas but scale the rectangle of the control so
- // that it will be the correct size, undoing any scale already on the
- // canvas. This will have the effect of just drawing the control bigger
- // or smaller and not actually expanding or contracting the pixels in
- // it. This usually looks better.
- SCALE,
-
- // Make a copy of the control and then transform it ourselves after
- // Windows draws it. This allows us to get complex effects.
- COPY,
- };
-
-public:
- // Prepares drawing a control with the given rect to the given context.
- ThemeHelperWin(GraphicsContext* context, const IntRect& rect);
- ~ThemeHelperWin();
-
- // Returns the context to draw the control into, which may be the original
- // or the copy, depending on the mode.
- GraphicsContext* context()
- {
- return m_newBuffer.get() ? m_newBuffer->context() : m_orgContext;
- }
-
- // Returns the rectangle in which to draw into the canvas() by Windows.
- const IntRect& rect() { return m_rect; }
-
-private:
- Type m_type;
-
- // The original canvas to wrote to. Not owned by this class.
- GraphicsContext* m_orgContext;
- TransformationMatrix m_orgMatrix;
- IntRect m_orgRect;
-
- // When m_type == COPY, this will be a new surface owned by this class that
- // represents the copy.
- OwnPtr<ImageBuffer> m_newBuffer;
-
- // The control rectangle in the coordinate space of canvas().
- IntRect m_rect;
-};
-
-} // namespace WebCore
-
-#endif // ThemeHelperWin_h
diff --git a/WebCore/platform/graphics/chromium/TransparencyWin.cpp b/WebCore/platform/graphics/chromium/TransparencyWin.cpp
new file mode 100644
index 0000000..8c790af
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/TransparencyWin.cpp
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <windows.h>
+
+#include "GraphicsContext.h"
+#include "ImageBuffer.h"
+#include "PlatformContextSkia.h"
+#include "SimpleFontData.h"
+#include "TransformationMatrix.h"
+#include "TransparencyWin.h"
+
+#include "SkColorPriv.h"
+#include "skia/ext/platform_canvas.h"
+
+namespace WebCore {
+
+namespace {
+
+// The maximum size in pixels of the buffer we'll keep around for drawing text
+// into. Buffers larger than this will be destroyed when we're done with them.
+const int maxCachedBufferPixelSize = 65536;
+
+inline skia::PlatformCanvas* canvasForContext(const GraphicsContext& context)
+{
+ return context.platformContext()->canvas();
+}
+
+inline const SkBitmap& bitmapForContext(const GraphicsContext& context)
+{
+ return canvasForContext(context)->getTopPlatformDevice().accessBitmap(false);
+}
+
+void compositeToCopy(const GraphicsContext& sourceLayers,
+ GraphicsContext& destContext,
+ const TransformationMatrix& matrix)
+{
+ // Make a list of all devices. The iterator goes top-down, and we want
+ // bottom-up. Note that each layer can also have an offset in canvas
+ // coordinates, which is the (x, y) position.
+ struct DeviceInfo {
+ DeviceInfo(SkDevice* d, int lx, int ly)
+ : device(d)
+ , x(lx)
+ , y(ly) {}
+ SkDevice* device;
+ int x;
+ int y;
+ };
+ Vector<DeviceInfo> devices;
+ SkCanvas* sourceCanvas = canvasForContext(sourceLayers);
+ SkCanvas::LayerIter iter(sourceCanvas, false);
+ while (!iter.done()) {
+ devices.append(DeviceInfo(iter.device(), iter.x(), iter.y()));
+ iter.next();
+ }
+
+ // Create a temporary canvas for the compositing into the destination.
+ SkBitmap* destBmp = const_cast<SkBitmap*>(&bitmapForContext(destContext));
+ SkCanvas destCanvas(*destBmp);
+ destCanvas.setMatrix(matrix);
+
+ for (int i = devices.size() - 1; i >= 0; i--) {
+ const SkBitmap& srcBmp = devices[i].device->accessBitmap(false);
+
+ SkRect destRect;
+ destRect.fLeft = devices[i].x;
+ destRect.fTop = devices[i].y;
+ destRect.fRight = destRect.fLeft + srcBmp.width();
+ destRect.fBottom = destRect.fTop + srcBmp.height();
+
+ destCanvas.drawBitmapRect(srcBmp, 0, destRect);
+ }
+}
+
+} // namespace
+
+// If either of these pointers is non-null, both must be valid and point to
+// bitmaps of the same size.
+class TransparencyWin::OwnedBuffers {
+public:
+ OwnedBuffers(const IntSize& size, bool needReferenceBuffer)
+ {
+ m_destBitmap.adopt(ImageBuffer::create(size, false));
+
+ if (needReferenceBuffer) {
+ m_referenceBitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
+ m_referenceBitmap.allocPixels();
+ m_referenceBitmap.eraseARGB(0, 0, 0, 0);
+ }
+ }
+
+ ImageBuffer* destBitmap() { return m_destBitmap.get(); }
+
+ // This bitmap will be empty if you don't specify needReferenceBuffer to the
+ // constructor.
+ SkBitmap* referenceBitmap() { return &m_referenceBitmap; }
+
+ // Returns whether the current layer will fix a buffer of the given size.
+ bool canHandleSize(const IntSize& size) const
+ {
+ return m_destBitmap->size().width() >= size.width() && m_destBitmap->size().height() >= size.height();
+ }
+
+private:
+ // The destination bitmap we're drawing into.
+ OwnPtr<ImageBuffer> m_destBitmap;
+
+ // This could be an ImageBuffer but this is an optimization. Since this is
+ // only ever used as a reference, we don't need to make a full
+ // PlatformCanvas using Skia on Windows. Just allocating a regular SkBitmap
+ // is much faster since it's just a Malloc rather than a GDI call.
+ SkBitmap m_referenceBitmap;
+};
+
+TransparencyWin::OwnedBuffers* TransparencyWin::m_cachedBuffers = 0;
+
+TransparencyWin::TransparencyWin()
+ : m_destContext(0)
+ , m_orgTransform()
+ , m_layerMode(NoLayer)
+ , m_transformMode(KeepTransform)
+ , m_drawContext(0)
+ , m_savedOnDrawContext(false)
+ , m_layerBuffer(0)
+ , m_referenceBitmap(0)
+{
+}
+
+TransparencyWin::~TransparencyWin()
+{
+ // This should be false, since calling composite() is mandatory.
+ ASSERT(!m_savedOnDrawContext);
+}
+
+void TransparencyWin::composite()
+{
+ // Matches the save() in initializeNewTextContext (or the constructor for
+ // SCALE) to put the context back into the same state we found it.
+ if (m_savedOnDrawContext) {
+ m_drawContext->restore();
+ m_savedOnDrawContext = false;
+ }
+
+ switch (m_layerMode) {
+ case NoLayer:
+ break;
+ case OpaqueCompositeLayer:
+ case WhiteLayer:
+ compositeOpaqueComposite();
+ break;
+ case TextComposite:
+ compositeTextComposite();
+ break;
+ }
+}
+
+void TransparencyWin::init(GraphicsContext* dest,
+ LayerMode layerMode,
+ TransformMode transformMode,
+ const IntRect& region)
+{
+ m_destContext = dest;
+ m_orgTransform = dest->getCTM();
+ m_layerMode = layerMode;
+ m_transformMode = transformMode;
+ m_sourceRect = region;
+
+ computeLayerSize();
+ setupLayer();
+ setupTransform(region);
+}
+
+void TransparencyWin::computeLayerSize()
+{
+ if (m_transformMode == Untransform) {
+ // The meaning of the "transformed" source rect is a little ambigous
+ // here. The rest of the code doesn't care about it in the Untransform
+ // case since we're using our own happy coordinate system. So we set it
+ // to be the source rect since that matches how the code below actually
+ // uses the variable: to determine how to translate things to account
+ // for the offset of the layer.
+ m_transformedSourceRect = m_sourceRect;
+ m_layerSize = IntSize(m_sourceRect.width(), m_sourceRect.height());
+ } else {
+ m_transformedSourceRect = m_orgTransform.mapRect(m_sourceRect);
+ m_layerSize = IntSize(m_transformedSourceRect.width(), m_transformedSourceRect.height());
+ }
+}
+
+void TransparencyWin::setupLayer()
+{
+ switch (m_layerMode) {
+ case NoLayer:
+ setupLayerForNoLayer();
+ break;
+ case OpaqueCompositeLayer:
+ setupLayerForOpaqueCompositeLayer();
+ break;
+ case TextComposite:
+ setupLayerForTextComposite();
+ break;
+ case WhiteLayer:
+ setupLayerForWhiteLayer();
+ break;
+ }
+}
+
+void TransparencyWin::setupLayerForNoLayer()
+{
+ m_drawContext = m_destContext; // Draw to the source context.
+}
+
+void TransparencyWin::setupLayerForOpaqueCompositeLayer()
+{
+ initializeNewContext();
+
+ TransformationMatrix mapping;
+ mapping.translate(-m_transformedSourceRect.x(), -m_transformedSourceRect.y());
+ if (m_transformMode == Untransform){
+ // Compute the inverse mapping from the canvas space to the
+ // coordinate space of our bitmap.
+ mapping = m_orgTransform.inverse() * mapping;
+ }
+ compositeToCopy(*m_destContext, *m_drawContext, mapping);
+
+ // Save the reference layer so we can tell what changed.
+ SkCanvas referenceCanvas(*m_referenceBitmap);
+ referenceCanvas.drawBitmap(bitmapForContext(*m_drawContext), 0, 0);
+ // Layer rect represents the part of the original layer.
+}
+
+void TransparencyWin::setupLayerForTextComposite()
+{
+ ASSERT(m_transformMode == KeepTransform);
+ // Fall through to filling with white.
+ setupLayerForWhiteLayer();
+}
+
+void TransparencyWin::setupLayerForWhiteLayer()
+{
+ initializeNewContext();
+ m_drawContext->fillRect(IntRect(IntPoint(0, 0), m_layerSize), Color::white);
+ // Layer rect represents the part of the original layer.
+}
+
+void TransparencyWin::setupTransform(const IntRect& region)
+{
+ switch (m_transformMode) {
+ case KeepTransform:
+ setupTransformForKeepTransform(region);
+ break;
+ case Untransform:
+ setupTransformForUntransform();
+ break;
+ case ScaleTransform:
+ setupTransformForScaleTransform();
+ break;
+ }
+}
+
+void TransparencyWin::setupTransformForKeepTransform(const IntRect& region)
+{
+ if (m_layerMode != NoLayer) {
+ // Need to save things since we're modifying the transform.
+ m_drawContext->save();
+ m_savedOnDrawContext = true;
+
+ // Account for the fact that the layer may be offset from the
+ // original. This only happens when we create a layer that has the
+ // same coordinate space as the parent.
+ TransformationMatrix xform;
+ xform.translate(-m_transformedSourceRect.x(), -m_transformedSourceRect.y());
+
+ // We're making a layer, so apply the old transform to the new one
+ // so it's maintained. We know the new layer has the identity
+ // transform now, we we can just multiply it.
+ xform = m_orgTransform * xform;
+ m_drawContext->concatCTM(xform);
+ }
+ m_drawRect = m_sourceRect;
+}
+
+void TransparencyWin::setupTransformForUntransform()
+{
+ ASSERT(m_layerMode != NoLayer);
+ // We now have a new layer with the identity transform, which is the
+ // Untransformed space we'll use for drawing.
+ m_drawRect = IntRect(IntPoint(0, 0), m_layerSize);
+}
+
+void TransparencyWin::setupTransformForScaleTransform()
+{
+ if (m_layerMode == NoLayer) {
+ // Need to save things since we're modifying the layer.
+ m_drawContext->save();
+ m_savedOnDrawContext = true;
+
+ // Undo the transform on the current layer when we're re-using the
+ // current one.
+ m_drawContext->concatCTM(m_drawContext->getCTM().inverse());
+
+ // We're drawing to the original layer with just a different size.
+ m_drawRect = m_transformedSourceRect;
+ } else {
+ // Just go ahead and use the layer's coordinate space to draw into.
+ // It will have the scaled size, and an identity transform loaded.
+ m_drawRect = IntRect(IntPoint(0, 0), m_layerSize);
+ }
+}
+
+void TransparencyWin::setTextCompositeColor(Color color)
+{
+ m_textCompositeColor = color;
+}
+
+void TransparencyWin::initializeNewContext()
+{
+ int pixelSize = m_layerSize.width() * m_layerSize.height();
+ if (pixelSize > maxCachedBufferPixelSize) {
+ // Create a 1-off buffer for drawing into. We only need the reference
+ // buffer if we're making an OpaqueCompositeLayer.
+ bool needReferenceBitmap = m_layerMode == OpaqueCompositeLayer;
+ m_ownedBuffers.set(new OwnedBuffers(m_layerSize, needReferenceBitmap));
+
+ m_layerBuffer = m_ownedBuffers->destBitmap();
+ m_drawContext = m_layerBuffer->context();
+ if (needReferenceBitmap)
+ m_referenceBitmap = m_ownedBuffers->referenceBitmap();
+ return;
+ }
+
+ if (m_cachedBuffers && m_cachedBuffers->canHandleSize(m_layerSize)) {
+ // We can re-use the existing buffer. We don't need to clear it since
+ // all layer modes will clear it in their initialization.
+ m_layerBuffer = m_cachedBuffers->destBitmap();
+ m_drawContext = m_cachedBuffers->destBitmap()->context();
+ bitmapForContext(*m_drawContext).eraseARGB(0, 0, 0, 0);
+ m_referenceBitmap = m_cachedBuffers->referenceBitmap();
+ m_referenceBitmap->eraseARGB(0, 0, 0, 0);
+ return;
+ }
+
+ // Create a new cached buffer.
+ if (m_cachedBuffers)
+ delete m_cachedBuffers;
+ m_cachedBuffers = new OwnedBuffers(m_layerSize, true);
+
+ m_layerBuffer = m_cachedBuffers->destBitmap();
+ m_drawContext = m_cachedBuffers->destBitmap()->context();
+ m_referenceBitmap = m_cachedBuffers->referenceBitmap();
+}
+
+void TransparencyWin::compositeOpaqueComposite()
+{
+ SkCanvas* destCanvas = canvasForContext(*m_destContext);
+ destCanvas->save();
+
+ SkBitmap* bitmap = const_cast<SkBitmap*>(
+ &bitmapForContext(*m_layerBuffer->context()));
+
+ // This function will be called for WhiteLayer as well, which we don't want
+ // to change.
+ if (m_layerMode == OpaqueCompositeLayer) {
+ // Fix up our bitmap, making it contain only the pixels which changed
+ // and transparent everywhere else.
+ SkAutoLockPixels sourceLock(*m_referenceBitmap);
+ SkAutoLockPixels lock(*bitmap);
+ for (int y = 0; y < bitmap->height(); y++) {
+ uint32_t* source = m_referenceBitmap->getAddr32(0, y);
+ uint32_t* dest = bitmap->getAddr32(0, y);
+ for (int x = 0; x < bitmap->width(); x++) {
+ // Clear out any pixels that were untouched.
+ if (dest[x] == source[x])
+ dest[x] = 0;
+ else
+ dest[x] |= (0xFF << SK_A32_SHIFT);
+ }
+ }
+ } else
+ makeLayerOpaque();
+
+ SkRect destRect;
+ if (m_transformMode != Untransform) {
+ // We want to use Untransformed space.
+ //
+ // Note that we DON'T call m_layerBuffer->image() here. This actually
+ // makes a copy of the image, which is unnecessary and slow. Instead, we
+ // just draw the image from inside the destination context.
+ SkMatrix identity;
+ identity.reset();
+ destCanvas->setMatrix(identity);
+
+ destRect.set(m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.right(), m_transformedSourceRect.bottom());
+ } else
+ destRect.set(m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.right(), m_sourceRect.bottom());
+
+ SkPaint paint;
+ paint.setFilterBitmap(true);
+ paint.setAntiAlias(true);
+
+ // Note that we need to specify the source layer subset, since the bitmap
+ // may have been cached and it could be larger than what we're using.
+ SkIRect sourceRect = { 0, 0, m_layerSize.width(), m_layerSize.height() };
+ destCanvas->drawBitmapRect(*bitmap, &sourceRect, destRect, &paint);
+ destCanvas->restore();
+}
+
+void TransparencyWin::compositeTextComposite()
+{
+ const SkBitmap& bitmap = m_layerBuffer->context()->platformContext()->canvas()->getTopPlatformDevice().accessBitmap(true);
+ SkColor textColor = m_textCompositeColor.rgb();
+ for (int y = 0; y < m_layerSize.height(); y++) {
+ uint32_t* row = bitmap.getAddr32(0, y);
+ for (int x = 0; x < m_layerSize.width(); x++) {
+ // The alpha is the average of the R, G, and B channels.
+ int alpha = (SkGetPackedR32(row[x]) + SkGetPackedG32(row[x]) + SkGetPackedB32(row[x])) / 3;
+
+ // Apply that alpha to the text color and write the result.
+ row[x] = SkAlphaMulQ(textColor, SkAlpha255To256(255 - alpha));
+ }
+ }
+
+ // Now the layer has text with the proper color and opacity.
+ SkCanvas* destCanvas = canvasForContext(*m_destContext);
+
+ // We want to use Untransformed space (see above)
+ SkMatrix identity;
+ identity.reset();
+ destCanvas->setMatrix(identity);
+ SkRect destRect = { m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.right(), m_transformedSourceRect.bottom() };
+
+ // Note that we need to specify the source layer subset, since the bitmap
+ // may have been cached and it could be larger than what we're using.
+ SkIRect sourceRect = { 0, 0, m_layerSize.width(), m_layerSize.height() };
+ destCanvas->drawBitmapRect(bitmap, &sourceRect, destRect, 0);
+ destCanvas->restore();
+}
+
+void TransparencyWin::makeLayerOpaque()
+{
+ SkBitmap& bitmap = const_cast<SkBitmap&>(m_drawContext->platformContext()->
+ canvas()->getTopPlatformDevice().accessBitmap(true));
+ for (int y = 0; y < m_layerSize.height(); y++) {
+ uint32_t* row = bitmap.getAddr32(0, y);
+ for (int x = 0; x < m_layerSize.width(); x++)
+ row[x] |= 0xFF000000;
+ }
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/graphics/chromium/TransparencyWin.h b/WebCore/platform/graphics/chromium/TransparencyWin.h
new file mode 100644
index 0000000..e1963b3
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/TransparencyWin.h
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TransparencyWin_h
+#define TransparencyWin_h
+
+#include <windows.h>
+
+#include "ImageBuffer.h"
+#include "Noncopyable.h"
+#include "TransformationMatrix.h"
+#include "wtf/OwnPtr.h"
+
+class SkBitmap;
+class SkCanvas;
+
+namespace WebCore {
+
+class GraphicsContext;
+class TransparencyWin_NoLayer_Test;
+class TransparencyWin_WhiteLayer_Test;
+class TransparencyWin_TextComposite_Test;
+class TransparencyWin_OpaqueCompositeLayer_Test;
+
+// Helper class that abstracts away drawing ClearType text and Windows form
+// controls either to the original context directly, or to an offscreen context
+// that is composited later manually. This is to get around Windows' inability
+// to handle the alpha channel, semitransparent text, and transformed form
+// controls.
+class TransparencyWin : public Noncopyable {
+public:
+ enum LayerMode {
+ // No extra layer is created. Drawing will happen to the source.
+ // Valid only with KeepTransform and ScaleTransform. The region being
+ // drawn onto must be opaque, since the modified region will be forced
+ // to opaque when drawing is complete.
+ NoLayer,
+
+ // Makes a temporary layer consisting of the composited layers below
+ // it. This result must be opaque. When complete, the result will be
+ // compared to the original, and the difference will be added to a thee
+ // destination layer.
+ //
+ // This mode only works if the lower layers are opque (normally the
+ // case for a web page) and layers are only drawn in the stack order,
+ // meaning you can never draw underneath a layer.
+ //
+ // This doesn't technically produce the correct answer in all cases. If
+ // you have an opaque base, a transparency layer, than a semitransparent
+ // drawing on top, the result will actually be blended in twice. But
+ // this isn't a very important case. This mode is used for form
+ // controls which are always opaque except for occationally some
+ // antialiasing. It means form control antialiasing will be too light in
+ // some cases, but only if you have extra layers.
+ OpaqueCompositeLayer,
+
+ // Allows semitransparent text to be drawn on any background (even if it
+ // is itself semitransparent), but disables ClearType.
+ //
+ // It makes a trmporary layer filled with white. This is composited with
+ // the lower layer with a custom color applied to produce the result.
+ // The caller must draw the text in black, and set the desired final
+ // text color by calling setTextCompositeColor().
+ //
+ // Only valid with KeepTransform, which is the only mode where drawing
+ // text in this fashion makes sense.
+ TextComposite,
+
+ // Makes a temporary layer filled with white. When complete, the layer
+ // will be forced to be opqaue (since Windows may have messed up the
+ // alpha channel) and composited down. Any areas not drawn into will
+ // remain white.
+ //
+ // This is the mode of last resort. If the opacity of the final image
+ // is unknown and we can't do the text trick (since we know its color),
+ // then we have to live with potential white halos. This is used for
+ // form control drawing, for example.
+ WhiteLayer,
+ };
+
+ enum TransformMode {
+ // There are no changes to the transform. Use this when drawing
+ // horizontal text. The current transform must not have rotation.
+ KeepTransform,
+
+ // Drawing happens in an Untransformed space, and then that bitmap is
+ // transformed according to the current context when it is copied down.
+ // Requires that a layer be created (layer mode is not NoLayer).
+ Untransform,
+
+ // When the current transform only has a scaling factor applied and
+ // you're drawing form elements, use this parameter. This will unscale
+ // the coordinate space, so the OS will just draw the form controls
+ // larger or smaller depending on the destination size.
+ ScaleTransform,
+ };
+
+ // You MUST call init() below.
+ // |region| is expressed relative to the current transformation.
+ TransparencyWin();
+ ~TransparencyWin();
+
+ // Initializes the members if you use the 0-argument constructor. Don't call
+ // this if you use the multiple-argument constructor.
+ void init(GraphicsContext* dest,
+ LayerMode layerMode,
+ TransformMode transformMode,
+ const IntRect& region);
+
+ // Combines the source and destination bitmaps using the given mode.
+ void composite();
+
+ // Returns the context for drawing into, which may be the destination
+ // context, or a temporary one.
+ GraphicsContext* context() const { return m_drawContext; }
+
+ PlatformGraphicsContext* platformContext() const { return m_drawContext->platformContext(); }
+
+ // When the mode is TextComposite, this sets the color that the text will
+ // get. See the enum above for more.
+ void setTextCompositeColor(Color color);
+
+ // Returns the input bounds translated into the destination space. This is
+ // not necessary for KeepTransform since the rectangle will be unchanged.
+ const IntRect& drawRect() { return m_drawRect; }
+
+private:
+ friend TransparencyWin_NoLayer_Test;
+ friend TransparencyWin_WhiteLayer_Test;
+ friend TransparencyWin_TextComposite_Test;
+ friend TransparencyWin_OpaqueCompositeLayer_Test;
+
+ class OwnedBuffers;
+
+ void computeLayerSize();
+
+ // Sets up a new layer, if any. setupLayer() will call the appopriate layer-
+ // specific helper. Must be called after computeLayerSize();
+ void setupLayer();
+ void setupLayerForNoLayer();
+ void setupLayerForOpaqueCompositeLayer();
+ void setupLayerForTextComposite();
+ void setupLayerForWhiteLayer();
+
+ // Sets up the transformation on the newly created layer. setupTransform()
+ // will call the appropriate transform-specific helper. Must be called after
+ // setupLayer().
+ void setupTransform(const IntRect& region);
+ void setupTransformForKeepTransform(const IntRect& region);
+ void setupTransformForUntransform();
+ void setupTransformForScaleTransform();
+
+ void initializeNewContext();
+
+ void compositeOpaqueComposite();
+ void compositeTextComposite();
+
+ // Fixes the alpha channel to make the region inside m_transformedRect
+ // opaque.
+ void makeLayerOpaque();
+
+ // The context our drawing will eventually end up in.
+ GraphicsContext* m_destContext;
+
+ // The original transform from the destination context.
+ TransformationMatrix m_orgTransform;
+
+ LayerMode m_layerMode;
+ TransformMode m_transformMode;
+
+ // The rectangle we're drawing in the destination's coordinate space
+ IntRect m_sourceRect;
+
+ // The source rectangle transformed into pixels in the final image. For
+ // Untransform this has no meaning, since the destination might not be a
+ // rectangle.
+ IntRect m_transformedSourceRect;
+
+ // The size of the layer we created. If there's no layer, this is the size
+ // of the region we're using in the source.
+ IntSize m_layerSize;
+
+ // The rectangle we're drawing to in the draw context's coordinate space.
+ // This will be the same as the source rectangle except for ScaleTransform
+ // where we create a new virtual coordinate space for the layer.
+ IntRect m_drawRect;
+
+ // Points to the graphics context to draw text to, which will either be
+ // the original context or the copy, depending on our mode.
+ GraphicsContext* m_drawContext;
+
+ // This flag is set when we call save() on the draw context during
+ // initialization. It allows us to avoid doing an extra save()/restore()
+ // when one is unnecessary.
+ bool m_savedOnDrawContext;
+
+ // Used only when m_mode = TextComposite, this is the color that the text
+ // will end up being once we figure out the transparency.
+ Color m_textCompositeColor;
+
+ // Layer we're drawing to.
+ ImageBuffer* m_layerBuffer;
+
+ // When the layer type is OpaqueCompositeLayer, this will contain a copy
+ // of the original contents of the m_layerBuffer before Windows drew on it.
+ // It allows us to re-create what Windows did to the layer. It is an
+ // SkBitmap instead of an ImageBuffer because an SkBitmap is lighter-weight
+ // (ImageBuffers are also GDI surfaces, which we don't need here).
+ SkBitmap* m_referenceBitmap;
+
+ // If the given size of bitmap can be cached, they will be stored here. Both
+ // the bitmap and the reference are guaranteed to be allocated if this
+ // member is non-null.
+ static OwnedBuffers* m_cachedBuffers;
+
+ // If a buffer was too big to be cached, it will be created temporarily, and
+ // this member tracks its scope to make sure it gets deleted. Always use
+ // m_layerBuffer, which will either point to this object, or the statically
+ // cached one. Don't access directly.
+ OwnPtr<OwnedBuffers> m_ownedBuffers;
+};
+
+} // namespace WebCore
+
+#endif // TransaprencyWin_h
diff --git a/WebCore/platform/graphics/chromium/UniscribeHelper.cpp b/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
index caeb959..39b0847 100644
--- a/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
+++ b/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
@@ -34,6 +34,9 @@
#include <windows.h>
#include "FontUtilsChromiumWin.h"
+#include "PlatformContextSkia.h"
+#include "SkiaFontWin.h"
+#include "SkPoint.h"
#include <wtf/Assertions.h>
namespace WebCore {
@@ -58,7 +61,7 @@ static bool containsMissingGlyphs(WORD *glyphs,
SCRIPT_FONTPROPERTIES* properties)
{
for (int i = 0; i < length; ++i) {
- if (glyphs[i] == properties->wgDefault
+ if (glyphs[i] == properties->wgDefault
|| (glyphs[i] == properties->wgInvalid
&& glyphs[i] != properties->wgBlank))
return true;
@@ -112,6 +115,8 @@ UniscribeHelper::UniscribeHelper(const UChar* input,
, m_spaceWidth(0)
, m_wordSpacing(0)
, m_ascent(0)
+ , m_disableFontFallback(false)
+
{
m_logfont.lfFaceName[0] = 0;
}
@@ -285,11 +290,13 @@ int UniscribeHelper::xToCharacter(int x) const
return 0;
}
-void UniscribeHelper::draw(HDC dc, int x, int y, int from, int to)
+void UniscribeHelper::draw(GraphicsContext* graphicsContext,
+ HDC dc, int x, int y, int from, int to)
{
HGDIOBJ oldFont = 0;
int curX = x;
bool firstRun = true;
+ bool useWindowsDrawing = windowsCanHandleTextDrawing(graphicsContext);
for (size_t screenIndex = 0; screenIndex < m_runs.size(); screenIndex++) {
int itemIndex = m_screenOrder[screenIndex];
@@ -360,7 +367,7 @@ void UniscribeHelper::draw(HDC dc, int x, int y, int from, int to)
// Actually draw the glyphs we found.
int glyphCount = afterGlyph - fromGlyph;
if (fromGlyph >= 0 && glyphCount > 0) {
- // Account for the preceeding space we need to add to this run. We
+ // Account for the preceding space we need to add to this run. We
// don't need to count for the following space because that will be
// counted in advanceForItem below when we move to the next run.
innerOffset += shaping.m_prePadding;
@@ -377,30 +384,44 @@ void UniscribeHelper::draw(HDC dc, int x, int y, int from, int to)
// Fonts with different ascents can be used to render different
// runs. 'Across-runs' y-coordinate correction needs to be
// adjusted for each font.
- HRESULT hr = S_FALSE;
+ bool textOutOk = false;
for (int executions = 0; executions < 2; ++executions) {
- hr = ScriptTextOut(dc, shaping.m_scriptCache,
- curX + innerOffset,
- y - shaping.m_ascentOffset,
- 0, 0, &item.a, 0, 0,
- &shaping.m_glyphs[fromGlyph],
- glyphCount,
- &shaping.m_advance[fromGlyph],
- justify,
- &shaping.m_offsets[fromGlyph]);
- if (S_OK != hr && 0 == executions) {
- // If this ScriptTextOut is called from the renderer it
- // might fail because the sandbox is preventing it from
- // opening the font files. If we are running in the
- // renderer, TryToPreloadFont is overridden to ask the
- // browser to preload the font for us so we can access it.
+ if (useWindowsDrawing) {
+ HRESULT hr = ScriptTextOut(dc, shaping.m_scriptCache,
+ curX + innerOffset,
+ y - shaping.m_ascentOffset,
+ 0, 0, &item.a, 0, 0,
+ &shaping.m_glyphs[fromGlyph],
+ glyphCount,
+ &shaping.m_advance[fromGlyph],
+ justify,
+ &shaping.m_offsets[fromGlyph]);
+ ASSERT(S_OK == hr);
+ textOutOk = (hr == S_OK);
+ } else {
+ SkPoint origin;
+ origin.fX = curX + + innerOffset;
+ origin.fY = y + m_ascent - shaping.m_ascentOffset;
+ textOutOk = paintSkiaText(graphicsContext,
+ shaping.m_hfont,
+ glyphCount,
+ &shaping.m_glyphs[fromGlyph],
+ &shaping.m_advance[fromGlyph],
+ &shaping.m_offsets[fromGlyph],
+ &origin);
+ }
+
+ if (!textOutOk && 0 == executions) {
+ // If TextOut is called from the renderer it might fail
+ // because the sandbox is preventing it from opening the
+ // font files. If we are running in the renderer,
+ // TryToPreloadFont is overridden to ask the browser to
+ // preload the font for us so we can access it.
tryToPreloadFont(shaping.m_hfont);
continue;
}
break;
}
-
- ASSERT(S_OK == hr);
}
curX += advanceForItem(itemIndex);
@@ -527,7 +548,10 @@ bool UniscribeHelper::shape(const UChar* input,
HDC tempDC = 0;
HGDIOBJ oldFont = 0;
HRESULT hr;
- bool lastFallbackTried = false;
+ // When used to fill up glyph pages for simple scripts in non-BMP,
+ // we don't want any font fallback in this class. The simple script
+ // font path can take care of font fallback.
+ bool lastFallbackTried = m_disableFontFallback;
bool result;
int generatedGlyphs = 0;
@@ -557,7 +581,7 @@ bool UniscribeHelper::shape(const UChar* input,
// PurifyMarkAsInitialized(
// &shaping.m_glyphs[0],
// sizeof(shaping.m_glyphs[0] * generatedGlyphs);
-
+
ZeroMemory(&shaping.m_glyphs[0],
sizeof(shaping.m_glyphs[0]) * shaping.m_glyphs.size());
#endif
@@ -587,7 +611,8 @@ bool UniscribeHelper::shape(const UChar* input,
tempDC = 0;
}
- if (nextWinFontData(&hfont, &scriptCache, &fontProperties, &ascent)) {
+ if (!m_disableFontFallback &&
+ nextWinFontData(&hfont, &scriptCache, &fontProperties, &ascent)) {
// The primary font does not support this run. Try next font.
// In case of web page rendering, they come from fonts specified in
// CSS stylesheets.
@@ -702,6 +727,13 @@ void UniscribeHelper::fillShapes()
if (!shape(&m_input[startItem], itemLength, numGlyphs, m_runs[i], shaping))
continue;
+ // At the moment, the only time m_disableFontFallback is set is
+ // when we look up glyph indices for non-BMP code ranges. So,
+ // we can skip the glyph placement. When that becomes not the case
+ // any more, we have to add a new flag to control glyph placement.
+ if (m_disableFontFallback)
+ continue;
+
// Compute placements. Note that offsets is documented incorrectly
// and is actually an array.
@@ -779,9 +811,6 @@ void UniscribeHelper::adjustSpaceAdvances()
int glyphIndex = shaping.m_logs[i];
int currentAdvance = shaping.m_advance[glyphIndex];
- // Don't give zero-width spaces a width.
- if (!currentAdvance)
- continue;
// currentAdvance does not include additional letter-spacing, but
// space_width does. Here we find out how off we are from the
diff --git a/WebCore/platform/graphics/chromium/UniscribeHelper.h b/WebCore/platform/graphics/chromium/UniscribeHelper.h
index d291105..ffd57db 100644
--- a/WebCore/platform/graphics/chromium/UniscribeHelper.h
+++ b/WebCore/platform/graphics/chromium/UniscribeHelper.h
@@ -44,6 +44,8 @@ class UniscribeTest_TooBig_Test; // A gunit test for UniscribeHelper.
namespace WebCore {
+class GraphicsContext;
+
#define UNISCRIBE_HELPER_STACK_RUNS 8
#define UNISCRIBE_HELPER_STACK_CHARS 32
@@ -145,6 +147,16 @@ public:
m_ascent = ascent;
}
+ // When set to true, this class is used only to look up glyph
+ // indices for a range of Unicode characters without glyph placement.
+ // By default, it's false. This should be set to true when this
+ // class is used for glyph index look-up for non-BMP characters
+ // in GlyphPageNodeChromiumWin.cpp.
+ void setDisableFontFallback(bool disableFontFallback)
+ {
+ m_disableFontFallback = true;
+ }
+
// You must call this after setting any options but before doing any
// other calls like asking for widths or drawing.
void init()
@@ -177,7 +189,8 @@ public:
// be pre-set.
//
// The y position is the upper left corner, NOT the baseline.
- void draw(HDC, int x, int y, int from, int to);
+ void draw(GraphicsContext* graphicsContext, HDC dc, int x, int y, int from,
+ int to);
// Returns the first glyph assigned to the character at the given offset.
// This function is used to retrieve glyph information when Uniscribe is
@@ -378,6 +391,7 @@ private:
int m_letterSpacing;
int m_spaceWidth;
int m_wordSpacing;
+ bool m_disableFontFallback;
// Uniscribe breaks the text into Runs. These are one length of text that is
// in one script and one direction. This array is in reading order.
diff --git a/WebCore/platform/graphics/gtk/FontPlatformData.h b/WebCore/platform/graphics/gtk/FontPlatformData.h
index efa5dd5..20c52e5 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformData.h
+++ b/WebCore/platform/graphics/gtk/FontPlatformData.h
@@ -74,6 +74,7 @@ public:
FontPlatformData(float size, bool bold, bool italic);
FontPlatformData(cairo_font_face_t* fontFace, int size, bool bold, bool italic);
+ FontPlatformData(const FontPlatformData&);
~FontPlatformData();
@@ -95,6 +96,7 @@ public:
}
bool operator==(const FontPlatformData&) const;
+ FontPlatformData& operator=(const FontPlatformData&);
bool isHashTableDeletedValue() const {
#if defined(USE_FREETYPE)
return m_pattern == hashTableDeletedFontValue();
diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp b/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
index 17d789b..68685e9 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
* Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
* Copyright (C) 2007 Holger Hans Peter Freyther
+ * Copyright (C) 2009 Igalia S.L.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -161,6 +162,45 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, int size, bool b
m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
}
+FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
+{
+ // Check for self-assignment.
+ if (this == &other)
+ return *this;
+
+ m_size = other.m_size;
+ m_syntheticBold = other.m_syntheticBold;
+ m_syntheticOblique = other.m_syntheticOblique;
+
+ if (other.m_scaledFont)
+ cairo_scaled_font_reference(other.m_scaledFont);
+ if (m_scaledFont)
+ cairo_scaled_font_destroy(m_scaledFont);
+ m_scaledFont = other.m_scaledFont;
+
+ if (other.m_pattern)
+ FcPatternReference(other.m_pattern);
+ if (m_pattern)
+ FcPatternDestroy(m_pattern);
+ m_pattern = other.m_pattern;
+
+ if (m_fallbacks) {
+ FcFontSetDestroy(m_fallbacks);
+ // This will be re-created on demand.
+ m_fallbacks = 0;
+ }
+
+ return *this;
+}
+
+FontPlatformData::FontPlatformData(const FontPlatformData& other)
+ : m_pattern(0)
+ , m_fallbacks(0)
+ , m_scaledFont(0)
+{
+ *this = other;
+}
+
bool FontPlatformData::init()
{
static bool initialized = false;
@@ -176,6 +216,20 @@ bool FontPlatformData::init()
FontPlatformData::~FontPlatformData()
{
+ if (m_pattern && ((FcPattern*)-1 != m_pattern)) {
+ FcPatternDestroy(m_pattern);
+ m_pattern = 0;
+ }
+
+ if (m_fallbacks) {
+ FcFontSetDestroy(m_fallbacks);
+ m_fallbacks = 0;
+ }
+
+ if (m_scaledFont) {
+ cairo_scaled_font_destroy(m_scaledFont);
+ m_scaledFont = 0;
+ }
}
bool FontPlatformData::isFixedPitch()
diff --git a/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp b/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
index be3fd43..88bf427 100644
--- a/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
+++ b/WebCore/platform/graphics/gtk/FontPlatformDataPango.cpp
@@ -4,6 +4,7 @@
* Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
* Copyright (C) 2007 Holger Hans Peter Freyther
* Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2009 Igalia S.L.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -46,8 +47,8 @@
namespace WebCore {
- PangoFontMap* FontPlatformData::m_fontMap = 0;
- GHashTable* FontPlatformData::m_hashTable = 0;
+PangoFontMap* FontPlatformData::m_fontMap = 0;
+GHashTable* FontPlatformData::m_hashTable = 0;
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
: m_context(0)
@@ -193,7 +194,20 @@ bool FontPlatformData::init()
FontPlatformData::~FontPlatformData()
{
- // Destroy takes place in FontData::platformDestroy().
+ if (m_font && m_font != reinterpret_cast<PangoFont*>(-1)) {
+ g_object_unref(m_font);
+ m_font = 0;
+ }
+
+ if (m_context) {
+ g_object_unref(m_context);
+ m_context = 0;
+ }
+
+ if (m_scaledFont) {
+ cairo_scaled_font_destroy(m_scaledFont);
+ m_scaledFont = 0;
+ }
}
bool FontPlatformData::isFixedPitch()
@@ -211,6 +225,45 @@ void FontPlatformData::setFont(cairo_t* cr) const
cairo_set_scaled_font(cr, m_scaledFont);
}
+FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
+{
+ // Check for self-assignment.
+ if (this == &other)
+ return *this;
+
+ m_size = other.m_size;
+ m_syntheticBold = other.m_syntheticBold;
+ m_syntheticOblique = other.m_syntheticOblique;
+
+ if (other.m_scaledFont)
+ cairo_scaled_font_reference(other.m_scaledFont);
+ if (m_scaledFont)
+ cairo_scaled_font_destroy(m_scaledFont);
+ m_scaledFont = other.m_scaledFont;
+
+ if (other.m_font)
+ g_object_ref(other.m_font);
+ if (m_font)
+ g_object_unref(m_font);
+ m_font = other.m_font;
+
+ if (other.m_context)
+ g_object_ref(other.m_context);
+ if (m_context)
+ g_object_unref(m_context);
+ m_context = other.m_context;
+
+ return *this;
+}
+
+FontPlatformData::FontPlatformData(const FontPlatformData& other)
+ : m_context(0)
+ , m_font(0)
+ , m_scaledFont(0)
+{
+ *this = other;
+}
+
bool FontPlatformData::operator==(const FontPlatformData& other) const
{
if (m_font == other.m_font)
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 1f0cac6..8dd1333 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Collabora Ltd. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
@@ -101,6 +101,22 @@ gboolean mediaPlayerPrivateBufferingCallback(GstBus* bus, GstMessage* message, g
return true;
}
+static void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, MediaPlayerPrivate* playerPrivate)
+{
+ playerPrivate->repaint();
+}
+
+MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player)
+{
+ return new MediaPlayerPrivate(player);
+}
+
+void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+ if (isAvailable())
+ registrar(create, getSupportedTypes, supportsType);
+}
+
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_playBin(0)
@@ -111,10 +127,10 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_isEndReached(false)
, m_volume(0.5f)
, m_networkState(MediaPlayer::Empty)
- , m_readyState(MediaPlayer::DataUnavailable)
+ , m_readyState(MediaPlayer::HaveNothing)
, m_startedPlaying(false)
, m_isStreaming(false)
- , m_rect(IntRect())
+ , m_size(IntSize())
, m_visible(true)
{
@@ -140,15 +156,15 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
}
}
-void MediaPlayerPrivate::load(String url)
+void MediaPlayerPrivate::load(const String& url)
{
LOG_VERBOSE(Media, "Load %s", url.utf8().data());
if (m_networkState != MediaPlayer::Loading) {
m_networkState = MediaPlayer::Loading;
m_player->networkStateChanged();
}
- if (m_readyState != MediaPlayer::DataUnavailable) {
- m_readyState = MediaPlayer::DataUnavailable;
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
m_player->readyStateChanged();
}
@@ -175,24 +191,28 @@ void MediaPlayerPrivate::pause()
m_startedPlaying = false;
}
-float MediaPlayerPrivate::duration()
+float MediaPlayerPrivate::duration() const
{
if (!m_playBin)
return 0.0;
- GstFormat fmt = GST_FORMAT_TIME;
- gint64 len = 0;
-
- if (gst_element_query_duration(m_playBin, &fmt, &len))
- LOG_VERBOSE(Media, "Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(len));
- else
- LOG_VERBOSE(Media, "Duration query failed ");
+ GstFormat timeFormat = GST_FORMAT_TIME;
+ gint64 timeLength = 0;
- if ((GstClockTime)len == GST_CLOCK_TIME_NONE) {
+ // FIXME: We try to get the duration, but we do not trust the
+ // return value of the query function only; the problem we are
+ // trying to work-around here is that pipelines in stream mode may
+ // not be able to figure out the duration, but still return true!
+ // See https://bugs.webkit.org/show_bug.cgi?id=24639.
+ if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeLength <= 0) {
+ LOG_VERBOSE(Media, "Time duration query failed.");
m_isStreaming = true;
return numeric_limits<float>::infinity();
}
- return (float) (len / 1000000000.0);
+
+ LOG_VERBOSE(Media, "Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(timeLength));
+
+ return (float) (timeLength / 1000000000.0);
// FIXME: handle 3.14.9.5 properly
}
@@ -288,7 +308,7 @@ bool MediaPlayerPrivate::seeking() const
}
// Returns the size of the video
-IntSize MediaPlayerPrivate::naturalSize()
+IntSize MediaPlayerPrivate::naturalSize() const
{
if (!hasVideo())
return IntSize();
@@ -302,7 +322,7 @@ IntSize MediaPlayerPrivate::naturalSize()
return IntSize(x, y);
}
-bool MediaPlayerPrivate::hasVideo()
+bool MediaPlayerPrivate::hasVideo() const
{
gint currentVideo = -1;
if (m_playBin)
@@ -355,17 +375,17 @@ int MediaPlayerPrivate::dataRate() const
return 1;
}
-MediaPlayer::NetworkState MediaPlayerPrivate::networkState()
+MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
{
return m_networkState;
}
-MediaPlayer::ReadyState MediaPlayerPrivate::readyState()
+MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
{
return m_readyState;
}
-float MediaPlayerPrivate::maxTimeBuffered()
+float MediaPlayerPrivate::maxTimeBuffered() const
{
notImplemented();
LOG_VERBOSE(Media, "maxTimeBuffered");
@@ -373,7 +393,7 @@ float MediaPlayerPrivate::maxTimeBuffered()
return m_isStreaming ? 0 : maxTimeLoaded();
}
-float MediaPlayerPrivate::maxTimeSeekable()
+float MediaPlayerPrivate::maxTimeSeekable() const
{
// TODO
LOG_VERBOSE(Media, "maxTimeSeekable");
@@ -383,7 +403,7 @@ float MediaPlayerPrivate::maxTimeSeekable()
return maxTimeLoaded();
}
-float MediaPlayerPrivate::maxTimeLoaded()
+float MediaPlayerPrivate::maxTimeLoaded() const
{
// TODO
LOG_VERBOSE(Media, "maxTimeLoaded");
@@ -391,7 +411,7 @@ float MediaPlayerPrivate::maxTimeLoaded()
return duration();
}
-unsigned MediaPlayerPrivate::bytesLoaded()
+unsigned MediaPlayerPrivate::bytesLoaded() const
{
notImplemented();
LOG_VERBOSE(Media, "bytesLoaded");
@@ -404,14 +424,14 @@ unsigned MediaPlayerPrivate::bytesLoaded()
return 1;//totalBytes() * maxTime / dur;
}
-bool MediaPlayerPrivate::totalBytesKnown()
+bool MediaPlayerPrivate::totalBytesKnown() const
{
notImplemented();
LOG_VERBOSE(Media, "totalBytesKnown");
return totalBytes() > 0;
}
-unsigned MediaPlayerPrivate::totalBytes()
+unsigned MediaPlayerPrivate::totalBytes() const
{
notImplemented();
LOG_VERBOSE(Media, "totalBytes");
@@ -455,12 +475,11 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(pending));
if (state == GST_STATE_READY) {
- m_readyState = MediaPlayer::CanPlayThrough;
+ m_readyState = MediaPlayer::HaveEnoughData;
} else if (state == GST_STATE_PAUSED) {
- m_readyState = MediaPlayer::CanPlayThrough;
+ m_readyState = MediaPlayer::HaveEnoughData;
}
- if (m_networkState < MediaPlayer::Loaded)
- m_networkState = MediaPlayer::Loaded;
+ m_networkState = MediaPlayer::Loaded;
g_object_get(m_playBin, "source", &m_source, NULL);
if (!m_source)
@@ -478,12 +497,11 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(state),
gst_element_state_get_name(pending));
if (state == GST_STATE_READY) {
- m_readyState = MediaPlayer::CanPlay;
+ m_readyState = MediaPlayer::HaveFutureData;
} else if (state == GST_STATE_PAUSED) {
- m_readyState = MediaPlayer::CanPlay;
+ m_readyState = MediaPlayer::HaveCurrentData;
}
- if (m_networkState < MediaPlayer::LoadedMetaData)
- m_networkState = MediaPlayer::LoadedMetaData;
+ m_networkState = MediaPlayer::Loading;
break;
default:
LOG_VERBOSE(Media, "Else : %d", ret);
@@ -491,7 +509,7 @@ void MediaPlayerPrivate::updateStates()
}
if (seeking())
- m_readyState = MediaPlayer::DataUnavailable;
+ m_readyState = MediaPlayer::HaveNothing;
if (m_networkState != oldNetworkState) {
LOG_VERBOSE(Media, "Network State Changed from %u to %u",
@@ -540,19 +558,19 @@ void MediaPlayerPrivate::didEnd()
void MediaPlayerPrivate::loadingFailed()
{
- if (m_networkState != MediaPlayer::LoadFailed) {
- m_networkState = MediaPlayer::LoadFailed;
+ if (m_networkState != MediaPlayer::NetworkError) {
+ m_networkState = MediaPlayer::NetworkError;
m_player->networkStateChanged();
}
- if (m_readyState != MediaPlayer::DataUnavailable) {
- m_readyState = MediaPlayer::DataUnavailable;
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
m_player->readyStateChanged();
}
}
-void MediaPlayerPrivate::setRect(const IntRect& rect)
+void MediaPlayerPrivate::setSize(const IntSize& size)
{
- m_rect = rect;
+ m_size = size;
}
void MediaPlayerPrivate::setVisible(bool visible)
@@ -573,7 +591,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
if (!m_visible)
return;
- //TODO: m_rect vs rect?
+ //TODO: m_size vs rect?
cairo_t* cr = context->platformContext();
cairo_save(cr);
@@ -587,11 +605,18 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
{
- // FIXME: do the real thing
+ // FIXME: query the engine to see what types are supported
notImplemented();
types.add(String("video/x-theora+ogg"));
}
+MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
+{
+ // FIXME: query the engine to see what types are supported
+ notImplemented();
+ return type == "video/x-theora+ogg" ? (!codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
+}
+
void MediaPlayerPrivate::createGSTPlayBin(String url)
{
ASSERT(!m_playBin);
@@ -613,6 +638,8 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
g_object_set(m_playBin, "audio-sink", audioSink, NULL);
g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
+ g_signal_connect(m_videoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
+
setVolume(m_volume);
}
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index 3f08bc0..628f0ac 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Collabora Ltd. All rights reserved.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
*
@@ -24,7 +24,7 @@
#if ENABLE(VIDEO)
-#include "MediaPlayer.h"
+#include "MediaPlayerPrivate.h"
#include "Timer.h"
#include <gtk/gtk.h>
@@ -44,20 +44,21 @@ namespace WebCore {
gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data);
gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data);
- class MediaPlayerPrivate : Noncopyable
+ class MediaPlayerPrivate : public MediaPlayerPrivateInterface
{
friend gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpointer data);
friend gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data);
friend gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data);
public:
- MediaPlayerPrivate(MediaPlayer*);
+
+ static void registerMediaEngine(MediaEngineRegistrar);
~MediaPlayerPrivate();
- IntSize naturalSize();
- bool hasVideo();
+ IntSize naturalSize() const;
+ bool hasVideo() const;
- void load(String url);
+ void load(const String &url);
void cancelLoad();
void play();
@@ -66,7 +67,7 @@ namespace WebCore {
bool paused() const;
bool seeking() const;
- float duration();
+ float duration() const;
float currentTime() const;
void seek(float);
void setEndTime(float);
@@ -77,17 +78,17 @@ namespace WebCore {
int dataRate() const;
- MediaPlayer::NetworkState networkState();
- MediaPlayer::ReadyState readyState();
+ MediaPlayer::NetworkState networkState() const;
+ MediaPlayer::ReadyState readyState() const;
- float maxTimeBuffered();
- float maxTimeSeekable();
- unsigned bytesLoaded();
- bool totalBytesKnown();
- unsigned totalBytes();
+ float maxTimeBuffered() const;
+ float maxTimeSeekable() const;
+ unsigned bytesLoaded() const;
+ bool totalBytesKnown() const;
+ unsigned totalBytes() const;
void setVisible(bool);
- void setRect(const IntRect&);
+ void setSize(const IntSize&);
void loadStateChanged();
void rateChanged();
@@ -99,15 +100,20 @@ namespace WebCore {
void repaint();
void paint(GraphicsContext*, const IntRect&);
- static void getSupportedTypes(HashSet<String>&);
- static bool isAvailable() { return true; }
private:
+ MediaPlayerPrivate(MediaPlayer*);
+ static MediaPlayerPrivateInterface* create(MediaPlayer* player);
+
+ static void getSupportedTypes(HashSet<String>&);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable() { return true; }
+
void updateStates();
void cancelSeek();
void endPointTimerFired(Timer<MediaPlayerPrivate>*);
- float maxTimeLoaded();
+ float maxTimeLoaded() const;
void startEndPointTimerIfNeeded();
void createGSTPlayBin(String url);
@@ -124,8 +130,8 @@ namespace WebCore {
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
bool m_startedPlaying;
- bool m_isStreaming;
- IntRect m_rect;
+ mutable bool m_isStreaming;
+ IntSize m_size;
bool m_visible;
cairo_surface_t* m_surface;
};
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
index d076cb6..4203a3c 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
@@ -53,6 +53,13 @@ void SimpleFontData::platformInit()
m_ascent = static_cast<int>(font_extents.ascent);
m_descent = static_cast<int>(font_extents.descent);
m_lineSpacing = static_cast<int>(font_extents.height);
+ // There seems to be some rounding error in cairo (or in how we
+ // use cairo) with some fonts, like DejaVu Sans Mono, which makes
+ // cairo report a height smaller than ascent + descent, which is
+ // wrong and confuses WebCore's layout system. Workaround this
+ // while we figure out what's going on.
+ if (m_lineSpacing < m_ascent + m_descent)
+ m_lineSpacing = m_ascent + m_descent;
cairo_scaled_font_text_extents(m_font.m_scaledFont, "x", &text_extents);
m_xHeight = text_extents.height;
cairo_scaled_font_text_extents(m_font.m_scaledFont, " ", &text_extents);
@@ -64,31 +71,13 @@ void SimpleFontData::platformDestroy()
{
delete m_smallCapsFontData;
m_smallCapsFontData = 0;
-
- if (isCustomFont())
- return;
-
- if (m_font.m_pattern && ((FcPattern*)-1 != m_font.m_pattern)) {
- FcPatternDestroy(m_font.m_pattern);
- m_font.m_pattern = 0;
- }
-
- if (m_font.m_fallbacks) {
- FcFontSetDestroy(m_font.m_fallbacks);
- m_font.m_fallbacks = 0;
- }
-
- if (m_font.m_scaledFont) {
- cairo_scaled_font_destroy(m_font.m_scaledFont);
- m_font.m_scaledFont = 0;
- }
}
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_smallCapsFontData) {
FontDescription desc = FontDescription(fontDescription);
- desc.setSpecifiedSize(0.70f*fontDescription.computedSize());
+ desc.setComputedSize(0.70f*fontDescription.computedSize());
const FontPlatformData* pdata = new FontPlatformData(desc, desc.family().family());
m_smallCapsFontData = new SimpleFontData(*pdata);
}
diff --git a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
index db8dd3b..e345a8c 100644
--- a/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
+++ b/WebCore/platform/graphics/gtk/SimpleFontDataPango.cpp
@@ -52,6 +52,13 @@ void SimpleFontData::platformInit()
m_ascent = static_cast<int>(font_extents.ascent);
m_descent = static_cast<int>(font_extents.descent);
m_lineSpacing = static_cast<int>(font_extents.height);
+ // There seems to be some rounding error in cairo (or in how we
+ // use cairo) with some fonts, like DejaVu Sans Mono, which makes
+ // cairo report a height smaller than ascent + descent, which is
+ // wrong and confuses WebCore's layout system. Workaround this
+ // while we figure out what's going on.
+ if (m_lineSpacing < m_ascent + m_descent)
+ m_lineSpacing = m_ascent + m_descent;
cairo_scaled_font_text_extents(m_font.m_scaledFont, "x", &text_extents);
m_xHeight = text_extents.height;
cairo_scaled_font_text_extents(m_font.m_scaledFont, " ", &text_extents);
@@ -61,24 +68,6 @@ void SimpleFontData::platformInit()
void SimpleFontData::platformDestroy()
{
- if (!isCustomFont()) {
-
- if (m_font.m_font && m_font.m_font != reinterpret_cast<PangoFont*>(-1)) {
- g_object_unref(m_font.m_font);
- m_font.m_font = 0;
- }
-
- if (m_font.m_context) {
- g_object_unref (m_font.m_context);
- m_font.m_context = 0;
- }
-
- if (m_font.m_scaledFont) {
- cairo_scaled_font_destroy(m_font.m_scaledFont);
- m_font.m_scaledFont = 0;
- }
- }
-
delete m_smallCapsFontData;
m_smallCapsFontData = 0;
}
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index 04df7ac..436841c 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
@@ -46,10 +46,17 @@ static GstElementDetails webkit_video_sink_details =
(gchar*) "Alp Toker <alp@atoker.com>");
enum {
+ REPAINT_REQUESTED,
+ LAST_SIGNAL
+};
+
+enum {
PROP_0,
PROP_SURFACE
};
+static guint webkit_video_sink_signals[LAST_SIGNAL] = { 0, };
+
struct _WebKitVideoSinkPrivate {
cairo_surface_t* surface;
GAsyncQueue* async_queue;
@@ -95,11 +102,10 @@ webkit_video_sink_init(WebKitVideoSink* sink, WebKitVideoSinkClass* klass)
static gboolean
webkit_video_sink_idle_func(gpointer data)
{
- WebKitVideoSinkPrivate* priv;
+ WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(data);
+ WebKitVideoSinkPrivate* priv = sink->priv;
GstBuffer* buffer;
- priv = (WebKitVideoSinkPrivate*)data;
-
if (!priv->async_queue)
return FALSE;
@@ -121,6 +127,8 @@ webkit_video_sink_idle_func(gpointer data)
gst_buffer_unref(buffer);
+ g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0);
+
return FALSE;
}
@@ -131,7 +139,7 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
WebKitVideoSinkPrivate* priv = sink->priv;
g_async_queue_push(priv->async_queue, gst_buffer_ref(buffer));
- g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, priv, NULL);
+ g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, sink, NULL);
return GST_FLOW_OK;
}
@@ -279,6 +287,15 @@ webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
gstbase_sink_class->stop = webkit_video_sink_stop;
gstbase_sink_class->set_caps = webkit_video_sink_set_caps;
+ webkit_video_sink_signals[REPAINT_REQUESTED] = g_signal_new("repaint-requested",
+ G_TYPE_FROM_CLASS(klass),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
g_object_class_install_property(
gobject_class, PROP_SURFACE,
g_param_spec_pointer("surface", "surface", "Target cairo_surface_t*",
diff --git a/WebCore/platform/graphics/mac/ColorMac.mm b/WebCore/platform/graphics/mac/ColorMac.mm
index 9b0f770..1c4350c 100644
--- a/WebCore/platform/graphics/mac/ColorMac.mm
+++ b/WebCore/platform/graphics/mac/ColorMac.mm
@@ -27,6 +27,7 @@
#import "Color.h"
#import "ColorMac.h"
+#import <AppKit/AppKit.h>
#import <wtf/Assertions.h>
#import <wtf/StdLibExtras.h>
#import <wtf/RetainPtr.h>
@@ -110,7 +111,7 @@ static CGColorRef CGColorFromNSColor(NSColor* color)
return cgColor;
}
-CGColorRef cgColor(const Color& c)
+CGColorRef createCGColor(const Color& c)
{
// We could directly create a CGColor here, but that would
// skip any RGB caching the nsColor method does. A direct
diff --git a/WebCore/platform/graphics/mac/FontCacheMac.mm b/WebCore/platform/graphics/mac/FontCacheMac.mm
index 26d84cc..2202459 100644
--- a/WebCore/platform/graphics/mac/FontCacheMac.mm
+++ b/WebCore/platform/graphics/mac/FontCacheMac.mm
@@ -35,7 +35,8 @@
#import "FontPlatformData.h"
#import "WebCoreSystemInterface.h"
#import "WebFontCache.h"
-#include <wtf/StdLibExtras.h>
+#import <AppKit/AppKit.h>
+#import <wtf/StdLibExtras.h>
#ifdef BUILDING_ON_TIGER
typedef int NSInteger;
@@ -191,13 +192,11 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
actualTraits = [fontManager traitsOfFont:nsFont];
NSInteger actualWeight = [fontManager weightOfFont:nsFont];
- FontPlatformData* result = new FontPlatformData;
+ NSFont *platformFont = fontDescription.usePrinterFont() ? [nsFont printerFont] : [nsFont screenFont];
+ bool syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight);
+ bool syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait);
- // Use the correct font for print vs. screen.
- result->setFont(fontDescription.usePrinterFont() ? [nsFont printerFont] : [nsFont screenFont]);
- result->m_syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight);
- result->m_syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait);
- return result;
+ return new FontPlatformData(platformFont, syntheticBold, syntheticOblique);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
index 9aa4997..e40bbab 100644
--- a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp
@@ -29,7 +29,8 @@ namespace WebCore {
FontCustomPlatformData::~FontCustomPlatformData()
{
- ATSFontDeactivate(m_atsContainer, NULL, kATSOptionFlagsDefault);
+ if (m_atsContainer)
+ ATSFontDeactivate(m_atsContainer, NULL, kATSOptionFlagsDefault);
CGFontRelease(m_cgFont);
}
@@ -42,8 +43,18 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
ASSERT_ARG(buffer, buffer);
- // Use ATS to activate the font.
ATSFontContainerRef containerRef = 0;
+ ATSFontRef fontRef = 0;
+
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ RetainPtr<CFDataRef> bufferData(AdoptCF, buffer->createCFData());
+ RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(bufferData.get()));
+
+ CGFontRef cgFontRef = CGFontCreateWithDataProvider(dataProvider.get());
+ if (!cgFontRef)
+ return 0;
+#else
+ // Use ATS to activate the font.
// The value "3" means that the font is private and can't be seen by anyone else.
ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef);
@@ -58,7 +69,6 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
return 0;
}
- ATSFontRef fontRef = 0;
ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL);
if (!fontRef) {
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
@@ -77,6 +87,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault);
return 0;
}
+#endif // !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
return new FontCustomPlatformData(containerRef, fontRef, cgFontRef);
}
diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.h b/WebCore/platform/graphics/mac/FontCustomPlatformData.h
index 1e73ae0..2c1222f 100644
--- a/WebCore/platform/graphics/mac/FontCustomPlatformData.h
+++ b/WebCore/platform/graphics/mac/FontCustomPlatformData.h
@@ -22,6 +22,7 @@
#define FontCustomPlatformData_h
#include "FontRenderingMode.h"
+#include <CoreFoundation/CFBase.h>
#include <wtf/Noncopyable.h>
typedef struct CGFont* CGFontRef;
diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm
index bef18d0..dc86c4b 100644
--- a/WebCore/platform/graphics/mac/FontMac.mm
+++ b/WebCore/platform/graphics/mac/FontMac.mm
@@ -29,6 +29,7 @@
#import "SimpleFontData.h"
#import "WebCoreSystemInterface.h"
#import "WebCoreTextRenderer.h"
+#import <AppKit/AppKit.h>
#define SYNTHETIC_OBLIQUE_ANGLE 14
diff --git a/WebCore/platform/graphics/mac/FontMacATSUI.mm b/WebCore/platform/graphics/mac/FontMacATSUI.mm
index 52493e7..3794149 100644
--- a/WebCore/platform/graphics/mac/FontMacATSUI.mm
+++ b/WebCore/platform/graphics/mac/FontMacATSUI.mm
@@ -30,6 +30,7 @@
#import "Logging.h"
#import "ShapeArabic.h"
#import "SimpleFontData.h"
+#import <AppKit/NSGraphicsContext.h>
#import <wtf/OwnArrayPtr.h>
#define SYNTHETIC_OBLIQUE_ANGLE 14
diff --git a/WebCore/platform/graphics/mac/FontPlatformData.h b/WebCore/platform/graphics/mac/FontPlatformData.h
index 40a2dbd..e911867 100644
--- a/WebCore/platform/graphics/mac/FontPlatformData.h
+++ b/WebCore/platform/graphics/mac/FontPlatformData.h
@@ -1,8 +1,8 @@
/*
* This file is part of the internal font implementation.
- * It should not be included by source files outside it.
+ * It should not be included by source files outside of it.
*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,7 +33,6 @@ class NSFont;
#endif
typedef struct CGFont* CGFontRef;
-typedef UInt32 ATSUFontID;
#ifndef BUILDING_ON_TIGER
typedef const struct __CTFont* CTFontRef;
#endif
@@ -42,6 +41,8 @@ typedef const struct __CTFont* CTFontRef;
#include <objc/objc-auto.h>
#include <wtf/RetainPtr.h>
+typedef UInt32 ATSUFontID;
+
namespace WebCore {
#ifndef BUILDING_ON_TIGER
@@ -61,10 +62,15 @@ struct FontPlatformData {
{
}
- FontPlatformData(NSFont * = 0, bool syntheticBold = false, bool syntheticOblique = false);
+ FontPlatformData(NSFont *nsFont, bool syntheticBold = false, bool syntheticOblique = false);
- FontPlatformData(CGFontRef f, ATSUFontID fontID, float s, bool b , bool o)
- : m_syntheticBold(b), m_syntheticOblique(o), m_atsuFontID(fontID), m_size(s), m_font(0), m_cgFont(f)
+ FontPlatformData(CGFontRef cgFont, ATSUFontID fontID, float size, bool syntheticBold, bool syntheticOblique)
+ : m_syntheticBold(syntheticBold)
+ , m_syntheticOblique(syntheticOblique)
+ , m_atsuFontID(fontID)
+ , m_size(size)
+ , m_font(0)
+ , m_cgFont(cgFont)
{
}
diff --git a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
index 7cd9ab6..83da4a9 100644
--- a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
+++ b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
@@ -1,7 +1,7 @@
/*
* This file is part of the internal font implementation.
*
- * Copyright (C) 2006-7 Apple Computer, Inc.
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,21 +24,24 @@
#import "FontPlatformData.h"
#import "WebCoreSystemInterface.h"
+#import <AppKit/NSFont.h>
namespace WebCore {
-FontPlatformData::FontPlatformData(NSFont *f, bool b , bool o)
-: m_syntheticBold(b), m_syntheticOblique(o), m_font(f)
+FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool syntheticOblique)
+ : m_syntheticBold(syntheticBold)
+ , m_syntheticOblique(syntheticOblique)
+ , m_font(nsFont)
{
- if (f)
- CFRetain(f);
- m_size = f ? [f pointSize] : 0.0f;
+ if (nsFont)
+ CFRetain(nsFont);
+ m_size = nsFont ? [nsFont pointSize] : 0.0f;
#ifndef BUILDING_ON_TIGER
- m_cgFont.adoptCF(CTFontCopyGraphicsFont(toCTFontRef(f), 0));
- m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(f), 0);
+ m_cgFont.adoptCF(CTFontCopyGraphicsFont(toCTFontRef(nsFont), 0));
+ m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(nsFont), 0);
#else
- m_cgFont = wkGetCGFontFromNSFont(f);
- m_atsuFontID = wkGetNSFontATSUFontId(f);
+ m_cgFont = wkGetCGFontFromNSFont(nsFont);
+ m_atsuFontID = wkGetNSFontATSUFontId(nsFont);
#endif
}
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index ae829e2..4e11602 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -27,10 +27,13 @@
#import "GraphicsContext.h"
#import "../cg/GraphicsContextPlatformPrivateCG.h"
+#import <AppKit/AppKit.h>
#import <wtf/StdLibExtras.h>
#import "WebCoreSystemInterface.h"
+@class NSColor;
+
// FIXME: More of this should use CoreGraphics instead of AppKit.
// FIXME: More of this should move into GraphicsContextCG.cpp.
@@ -47,7 +50,7 @@ void GraphicsContext::drawFocusRing(const Color& color)
int radius = (focusRingWidth() - 1) / 2;
int offset = radius + focusRingOffset();
- CGColorRef colorRef = color.isValid() ? cgColor(color) : 0;
+ CGColorRef colorRef = color.isValid() ? createCGColor(color) : 0;
CGMutablePathRef focusRingPath = CGPathCreateMutable();
const Vector<IntRect>& rects = focusRingRects();
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
new file mode 100644
index 0000000..3a692d3
--- /dev/null
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsLayerCA_h
+#define GraphicsLayerCA_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GraphicsLayer.h"
+#include <wtf/RetainPtr.h>
+
+@class WebAnimationDelegate;
+@class WebLayer;
+
+namespace WebCore {
+
+class GraphicsLayerCA : public GraphicsLayer {
+public:
+
+ GraphicsLayerCA(GraphicsLayerClient*);
+ virtual ~GraphicsLayerCA();
+
+ virtual void setName(const String&);
+
+ // for hosting this GraphicsLayer in a native layer hierarchy
+ virtual NativeLayer nativeLayer() const;
+
+ virtual void addChild(GraphicsLayer*);
+ virtual void addChildAtIndex(GraphicsLayer*, int index);
+ virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling);
+ virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling);
+ virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild);
+
+ virtual void removeFromParent();
+
+ virtual void setPosition(const FloatPoint&);
+ virtual void setAnchorPoint(const FloatPoint3D&);
+ virtual void setSize(const FloatSize&);
+
+ virtual void setTransform(const TransformationMatrix&);
+
+ virtual void setChildrenTransform(const TransformationMatrix&);
+
+ virtual void setPreserves3D(bool);
+ virtual void setMasksToBounds(bool);
+ virtual void setDrawsContent(bool);
+
+ virtual void setBackgroundColor(const Color&, const Animation* anim = 0, double beginTime = 0);
+ virtual void clearBackgroundColor();
+
+ virtual void setContentsOpaque(bool);
+ virtual void setBackfaceVisibility(bool);
+
+ // return true if we started an animation
+ virtual bool setOpacity(float, const Animation* anim = 0, double beginTime = 0);
+
+ virtual void setNeedsDisplay();
+ virtual void setNeedsDisplayInRect(const FloatRect&);
+
+ virtual void suspendAnimations();
+ virtual void resumeAnimations();
+
+ virtual bool animateTransform(const TransformValueList&, const IntSize&, const Animation*, double beginTime, bool isTransition);
+ virtual bool animateFloat(AnimatedPropertyID, const FloatValueList&, const Animation*, double beginTime);
+
+ virtual void setContentsToImage(Image*);
+ virtual void setContentsToVideo(PlatformLayer*);
+ virtual void clearContents();
+
+ virtual void updateContentsRect();
+
+ virtual PlatformLayer* platformLayer() const;
+
+#ifndef NDEBUG
+ virtual void setDebugBackgroundColor(const Color&);
+ virtual void setDebugBorder(const Color&, float borderWidth);
+ virtual void setZPosition(float);
+#endif
+
+private:
+ WebLayer* primaryLayer() const { return m_transformLayer.get() ? m_transformLayer.get() : m_layer.get(); }
+ WebLayer* hostLayerForSublayers() const;
+ WebLayer* layerForSuperlayer() const;
+
+ WebLayer* animatedLayer(AnimatedPropertyID property) const
+ {
+ return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer();
+ }
+
+ void setBasicAnimation(AnimatedPropertyID, TransformOperation::OperationType, short index, void* fromVal, void* toVal, bool isTransition, const Animation*, double time);
+ void setKeyframeAnimation(AnimatedPropertyID, TransformOperation::OperationType, short index, void* keys, void* values, void* timingFunctions, bool isTransition, const Animation*, double time);
+
+ virtual void removeAnimation(int index, bool reset);
+
+ bool requiresTiledLayer(const FloatSize&) const;
+ void swapFromOrToTiledLayer(bool useTiledLayer);
+
+ void setHasContentsLayer(bool);
+ void setContentsLayer(WebLayer*);
+ void setContentsLayerFlipped(bool);
+
+ RetainPtr<WebLayer> m_layer;
+ RetainPtr<WebLayer> m_transformLayer;
+ RetainPtr<WebLayer> m_contentsLayer;
+
+ RetainPtr<WebAnimationDelegate> m_animationDelegate;
+
+ bool m_contentLayerForImageOrVideo;
+};
+
+} // namespace WebCore
+
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // GraphicsLayerCA_h
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
new file mode 100644
index 0000000..f3f2d7f
--- /dev/null
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -0,0 +1,1540 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#import "GraphicsLayerCA.h"
+
+#import "Animation.h"
+#import "BlockExceptions.h"
+#import "CString.h"
+#import "FloatConversion.h"
+#import "FloatRect.h"
+#import "Image.h"
+#import "PlatformString.h"
+#import <QuartzCore/QuartzCore.h>
+#import "RotateTransformOperation.h"
+#import "ScaleTransformOperation.h"
+#import "SystemTime.h"
+#import "TranslateTransformOperation.h"
+#import "WebLayer.h"
+#import "WebTiledLayer.h"
+#import <wtf/CurrentTime.h>
+#import <wtf/UnusedParam.h>
+
+using namespace std;
+
+#define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))
+
+namespace WebCore {
+
+// The threshold width or height above which a tiled layer will be used. This should be
+// large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
+// texture size limit on all supported hardware.
+static const int cMaxPixelDimension = 2000;
+
+// The width and height of a single tile in a tiled layer. Should be large enough to
+// avoid lots of small tiles (and therefore lots of drawing callbacks), but small enough
+// to keep the overall tile cost low.
+static const int cTiledLayerTileSize = 512;
+
+// If we send a duration of 0 to CA, then it will use the default duration
+// of 250ms. So send a very small value instead.
+static const float cAnimationAlmostZeroDuration = 1e-3f;
+
+// CACurrentMediaTime() is a time since boot. These methods convert between that and
+// WebCore time, which is system time (UTC).
+static CFTimeInterval currentTimeToMediaTime(double t)
+{
+ return CACurrentMediaTime() + t - WTF::currentTime();
+}
+
+static double mediaTimeToCurrentTime(CFTimeInterval t)
+{
+ return WTF::currentTime() + t - CACurrentMediaTime();
+}
+
+} // namespace WebCore
+
+static NSString* const WebAnimationCSSPropertyKey = @"GraphicsLayerCA_property";
+
+@interface WebAnimationDelegate : NSObject {
+ WebCore::GraphicsLayerCA* m_graphicsLayer;
+}
+
+- (void)animationDidStart:(CAAnimation *)anim;
+- (WebCore::GraphicsLayerCA*)graphicsLayer;
+- (void)setLayer:(WebCore::GraphicsLayerCA*)graphicsLayer;
+
+@end
+
+@implementation WebAnimationDelegate
+
+- (void)animationDidStart:(CAAnimation *)animation
+{
+ if (!m_graphicsLayer)
+ return;
+
+ double startTime = WebCore::mediaTimeToCurrentTime([animation beginTime]);
+ m_graphicsLayer->client()->notifyAnimationStarted(m_graphicsLayer, startTime);
+}
+
+- (WebCore::GraphicsLayerCA*)graphicsLayer
+{
+ return m_graphicsLayer;
+}
+
+- (void)setLayer:(WebCore::GraphicsLayerCA*)graphicsLayer
+{
+ m_graphicsLayer = graphicsLayer;
+}
+
+@end
+
+namespace WebCore {
+
+static inline void copyTransform(CATransform3D& toT3D, const TransformationMatrix& t)
+{
+ toT3D.m11 = narrowPrecisionToFloat(t.m11());
+ toT3D.m12 = narrowPrecisionToFloat(t.m12());
+ toT3D.m13 = narrowPrecisionToFloat(t.m13());
+ toT3D.m14 = narrowPrecisionToFloat(t.m14());
+ toT3D.m21 = narrowPrecisionToFloat(t.m21());
+ toT3D.m22 = narrowPrecisionToFloat(t.m22());
+ toT3D.m23 = narrowPrecisionToFloat(t.m23());
+ toT3D.m24 = narrowPrecisionToFloat(t.m24());
+ toT3D.m31 = narrowPrecisionToFloat(t.m31());
+ toT3D.m32 = narrowPrecisionToFloat(t.m32());
+ toT3D.m33 = narrowPrecisionToFloat(t.m33());
+ toT3D.m34 = narrowPrecisionToFloat(t.m34());
+ toT3D.m41 = narrowPrecisionToFloat(t.m41());
+ toT3D.m42 = narrowPrecisionToFloat(t.m42());
+ toT3D.m43 = narrowPrecisionToFloat(t.m43());
+ toT3D.m44 = narrowPrecisionToFloat(t.m44());
+}
+
+static NSValue* getTransformFunctionValue(const GraphicsLayer::TransformValue& transformValue, size_t index, const IntSize& size, TransformOperation::OperationType transformType)
+{
+ TransformOperation* op = (index >= transformValue.value()->operations().size()) ? 0 : transformValue.value()->operations()[index].get();
+
+ switch (transformType) {
+ case TransformOperation::ROTATE:
+ case TransformOperation::ROTATE_X:
+ case TransformOperation::ROTATE_Y:
+ return [NSNumber numberWithDouble:op ? deg2rad(static_cast<RotateTransformOperation*>(op)->angle()) : 0];
+ case TransformOperation::SCALE_X:
+ return [NSNumber numberWithDouble:op ? static_cast<ScaleTransformOperation*>(op)->x() : 0];
+ case TransformOperation::SCALE_Y:
+ return [NSNumber numberWithDouble:op ? static_cast<ScaleTransformOperation*>(op)->y() : 0];
+ case TransformOperation::SCALE_Z:
+ return [NSNumber numberWithDouble:op ? static_cast<ScaleTransformOperation*>(op)->z() : 0];
+ case TransformOperation::TRANSLATE_X:
+ return [NSNumber numberWithDouble:op ? static_cast<TranslateTransformOperation*>(op)->x(size) : 0];
+ case TransformOperation::TRANSLATE_Y:
+ return [NSNumber numberWithDouble:op ? static_cast<TranslateTransformOperation*>(op)->y(size) : 0];
+ case TransformOperation::TRANSLATE_Z:
+ return [NSNumber numberWithDouble:op ? static_cast<TranslateTransformOperation*>(op)->z(size) : 0];
+ case TransformOperation::SCALE:
+ case TransformOperation::TRANSLATE:
+ case TransformOperation::SKEW_X:
+ case TransformOperation::SKEW_Y:
+ case TransformOperation::SKEW:
+ case TransformOperation::MATRIX:
+ case TransformOperation::SCALE_3D:
+ case TransformOperation::TRANSLATE_3D:
+ case TransformOperation::ROTATE_3D:
+ case TransformOperation::MATRIX_3D:
+ case TransformOperation::PERSPECTIVE:
+ case TransformOperation::IDENTITY:
+ case TransformOperation::NONE: {
+ TransformationMatrix t;
+ if (op)
+ op->apply(t, size);
+ CATransform3D cat;
+ copyTransform(cat, t);
+ return [NSValue valueWithCATransform3D:cat];
+ }
+ }
+
+ return 0;
+}
+
+#if HAVE_MODERN_QUARTZCORE
+static NSString* getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
+{
+ // Use literal strings to avoid link-time dependency on those symbols.
+ switch (transformType) {
+ case TransformOperation::ROTATE_X:
+ return @"rotateX"; // kCAValueFunctionRotateX;
+ case TransformOperation::ROTATE_Y:
+ return @"rotateY"; // kCAValueFunctionRotateY;
+ case TransformOperation::ROTATE:
+ return @"rotateZ"; // kCAValueFunctionRotateZ;
+ case TransformOperation::SCALE_X:
+ return @"scaleX"; // kCAValueFunctionScaleX;
+ case TransformOperation::SCALE_Y:
+ return @"scaleY"; // kCAValueFunctionScaleY;
+ case TransformOperation::SCALE_Z:
+ return @"scaleZ"; // kCAValueFunctionScaleZ;
+ case TransformOperation::TRANSLATE_X:
+ return @"translateX"; // kCAValueFunctionTranslateX;
+ case TransformOperation::TRANSLATE_Y:
+ return @"translateY"; // kCAValueFunctionTranslateY;
+ case TransformOperation::TRANSLATE_Z:
+ return @"translateZ"; // kCAValueFunctionTranslateZ;
+ default:
+ return nil;
+ }
+}
+#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;
+}
+
+#ifndef NDEBUG
+static void setLayerBorderColor(PlatformLayer* layer, const Color& color)
+{
+ CGColorRef borderColor = createCGColor(color);
+ [layer setBorderColor:borderColor];
+ CGColorRelease(borderColor);
+}
+
+static void clearBorderColor(PlatformLayer* layer)
+{
+ [layer setBorderColor:nil];
+}
+#endif
+
+static void setLayerBackgroundColor(PlatformLayer* layer, const Color& color)
+{
+ CGColorRef bgColor = createCGColor(color);
+ [layer setBackgroundColor:bgColor];
+ CGColorRelease(bgColor);
+}
+
+static void clearLayerBackgroundColor(PlatformLayer* layer)
+{
+ [layer setBackgroundColor:0];
+}
+
+static CALayer* getPresentationLayer(CALayer* layer)
+{
+ CALayer* presLayer = [layer presentationLayer];
+ if (!presLayer)
+ presLayer = layer;
+
+ return presLayer;
+}
+
+static bool caValueFunctionSupported()
+{
+ static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)];
+ return sHaveValueFunction;
+}
+
+static bool forceSoftwareAnimation()
+{
+ static bool forceSoftwareAnimation = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreForceSoftwareAnimation"];
+ return forceSoftwareAnimation;
+}
+
+bool GraphicsLayer::graphicsContextsFlipped()
+{
+ return true;
+}
+
+#ifndef NDEBUG
+bool GraphicsLayer::showDebugBorders()
+{
+ static bool showDebugBorders = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreLayerBorders"];
+ return showDebugBorders;
+}
+
+bool GraphicsLayer::showRepaintCounter()
+{
+ static bool showRepaintCounter = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreLayerRepaintCounter"];
+ return showRepaintCounter;
+}
+#endif
+
+static NSDictionary* nullActionsDictionary()
+{
+ NSNull* nullValue = [NSNull null];
+ NSDictionary* actions = [NSDictionary dictionaryWithObjectsAndKeys:
+ nullValue, @"anchorPoint",
+ nullValue, @"bounds",
+ nullValue, @"contents",
+ nullValue, @"contentsRect",
+ nullValue, @"opacity",
+ nullValue, @"position",
+ nullValue, @"shadowColor",
+ nullValue, @"sublayerTransform",
+ nullValue, @"sublayers",
+ nullValue, @"transform",
+#ifndef NDEBUG
+ nullValue, @"zPosition",
+#endif
+ nil];
+ return actions;
+}
+
+GraphicsLayer* GraphicsLayer::createGraphicsLayer(GraphicsLayerClient* client)
+{
+ return new GraphicsLayerCA(client);
+}
+
+GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
+: GraphicsLayer(client)
+, m_contentLayerForImageOrVideo(false)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ m_layer.adoptNS([[WebLayer alloc] init]);
+ [m_layer.get() setLayerOwner:this];
+
+#ifndef NDEBUG
+ updateDebugIndicators();
+#endif
+
+ m_animationDelegate.adoptNS([[WebAnimationDelegate alloc] init]);
+ [m_animationDelegate.get() setLayer:this];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+GraphicsLayerCA::~GraphicsLayerCA()
+{
+ // Remove a inner layer if there is one.
+ clearContents();
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ // Clean up the WK layer.
+ if (m_layer) {
+ WebLayer* layer = m_layer.get();
+ [layer setLayerOwner:nil];
+ [layer removeFromSuperlayer];
+ }
+
+ if (m_transformLayer)
+ [m_transformLayer.get() removeFromSuperlayer];
+
+ // animationDidStart: can fire after this, so we need to clear out the layer on the delegate.
+ [m_animationDelegate.get() setLayer:0];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setName(const String& name)
+{
+ String longName = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + name;
+ GraphicsLayer::setName(longName);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [m_layer.get() setName:name];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+NativeLayer GraphicsLayerCA::nativeLayer() const
+{
+ return m_layer.get();
+}
+
+void GraphicsLayerCA::addChild(GraphicsLayer* childLayer)
+{
+ GraphicsLayer::addChild(childLayer);
+
+ GraphicsLayerCA* childLayerCA = static_cast<GraphicsLayerCA*>(childLayer);
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [hostLayerForSublayers() addSublayer:childLayerCA->layerForSuperlayer()];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index)
+{
+ GraphicsLayer::addChildAtIndex(childLayer, index);
+
+ GraphicsLayerCA* childLayerCA = static_cast<GraphicsLayerCA*>(childLayer);
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [hostLayerForSublayers() insertSublayer:childLayerCA->layerForSuperlayer() atIndex:index];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling)
+{
+ // FIXME: share code with base class
+ ASSERT(childLayer != this);
+ childLayer->removeFromParent();
+
+ bool found = false;
+ for (unsigned i = 0; i < m_children.size(); i++) {
+ if (sibling == m_children[i]) {
+ m_children.insert(i, childLayer);
+ found = true;
+ break;
+ }
+ }
+ childLayer->setParent(this);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ GraphicsLayerCA* childLayerCA = static_cast<GraphicsLayerCA*>(childLayer);
+ GraphicsLayerCA* siblingLayerCA = static_cast<GraphicsLayerCA*>(sibling);
+ if (found)
+ [hostLayerForSublayers() insertSublayer:childLayerCA->layerForSuperlayer() below:siblingLayerCA->layerForSuperlayer()];
+ else {
+ m_children.append(childLayer);
+ [hostLayerForSublayers() addSublayer:childLayerCA->layerForSuperlayer()];
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling)
+{
+ // FIXME: share code with base class
+ ASSERT(childLayer != this);
+ childLayer->removeFromParent();
+
+ unsigned i;
+ bool found = false;
+ for (i = 0; i < m_children.size(); i++) {
+ if (sibling == m_children[i]) {
+ m_children.insert(i+1, childLayer);
+ found = true;
+ break;
+ }
+ }
+ childLayer->setParent(this);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ GraphicsLayerCA* childLayerCA = static_cast<GraphicsLayerCA*>(childLayer);
+ GraphicsLayerCA* siblingLayerCA = static_cast<GraphicsLayerCA*>(sibling);
+ if (found) {
+ [hostLayerForSublayers() insertSublayer:childLayerCA->layerForSuperlayer() above:siblingLayerCA->layerForSuperlayer()];
+ } else {
+ m_children.append(childLayer);
+ [hostLayerForSublayers() addSublayer:childLayerCA->layerForSuperlayer()];
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild)
+{
+ // FIXME: share code with base class
+ ASSERT(!newChild->parent());
+
+ bool found = false;
+ for (unsigned i = 0; i < m_children.size(); i++) {
+ if (oldChild == m_children[i]) {
+ m_children[i] = newChild;
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ oldChild->setParent(0);
+
+ newChild->removeFromParent();
+ newChild->setParent(this);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ GraphicsLayerCA* oldChildCA = static_cast<GraphicsLayerCA*>(oldChild);
+ GraphicsLayerCA* newChildCA = static_cast<GraphicsLayerCA*>(newChild);
+ [hostLayerForSublayers() replaceSublayer:oldChildCA->layerForSuperlayer() with:newChildCA->layerForSuperlayer()];
+ END_BLOCK_OBJC_EXCEPTIONS
+ return true;
+ }
+ return false;
+}
+
+void GraphicsLayerCA::removeFromParent()
+{
+ GraphicsLayer::removeFromParent();
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [layerForSuperlayer() removeFromSuperlayer];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setPosition(const FloatPoint& point)
+{
+ // Don't short-circuit here, because position and anchor point are inter-dependent.
+ GraphicsLayer::setPosition(point);
+
+ // Position is offset on the layer by the layer anchor point.
+ CGPoint posPoint = CGPointMake(m_position.x() + m_anchorPoint.x() * m_size.width(),
+ m_position.y() + m_anchorPoint.y() * m_size.height());
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [primaryLayer() setPosition:posPoint];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setAnchorPoint(const FloatPoint3D& point)
+{
+ // Don't short-circuit here, because position and anchor point are inter-dependent.
+ bool zChanged = (point.z() != m_anchorPoint.z());
+ GraphicsLayer::setAnchorPoint(point);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ // set the value on the layer to the new transform.
+ [primaryLayer() setAnchorPoint:FloatPoint(point.x(), point.y())];
+
+ if (zChanged) {
+#if HAVE_MODERN_QUARTZCORE
+ [primaryLayer() setAnchorPointZ:m_anchorPoint.z()];
+#endif
+ }
+
+ // Position depends on anchor point, so update it now.
+ setPosition(m_position);
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setSize(const FloatSize& size)
+{
+ GraphicsLayer::setSize(size);
+
+ CGRect rect = CGRectMake(0.0f,
+ 0.0f,
+ m_size.width(),
+ m_size.height());
+
+ CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (m_transformLayer) {
+ [m_transformLayer.get() setBounds:rect];
+
+ // the anchor of the contents layer is always at 0.5, 0.5, so the position
+ // is center-relative
+ [m_layer.get() setPosition:centerPoint];
+ }
+
+ bool needTiledLayer = requiresTiledLayer(m_size);
+ if (needTiledLayer != m_usingTiledLayer)
+ swapFromOrToTiledLayer(needTiledLayer);
+
+ [m_layer.get() setBounds:rect];
+
+ // Note that we don't resize m_contentsLayer. It's up the caller to do that.
+
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ // if we've changed the bounds, we need to recalculate the position
+ // of the layer, taking anchor point into account
+ setPosition(m_position);
+}
+
+void GraphicsLayerCA::setTransform(const TransformationMatrix& t)
+{
+ GraphicsLayer::setTransform(t);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ CATransform3D transform;
+ copyTransform(transform, t);
+ [primaryLayer() setTransform:transform];
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ // Remove any old transition entries for transform.
+ removeAllAnimationsForProperty(AnimatedPropertyWebkitTransform);
+
+ // Even if we don't have a transition in the list, the layer may still have one.
+ // This happens when we are setting the final transform value after an animation or
+ // transition has ended. In removeAnimation we toss the entry from the list but don't
+ // remove it from the list. That way we aren't in danger of displaying a stale transform
+ // in the time between removing the animation and setting the new unanimated value. We
+ // can't do this in removeAnimation because we don't know the new transform value there.
+ String keyPath = propertyIdToString(AnimatedPropertyWebkitTransform);
+ CALayer* layer = animatedLayer(AnimatedPropertyWebkitTransform);
+
+ for (int i = 0; ; ++i) {
+ String animName = keyPath + "_" + String::number(i);
+ if (![layer animationForKey: animName])
+ break;
+ [layer removeAnimationForKey:animName];
+ }
+}
+
+void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
+{
+ if (t == m_childrenTransform)
+ return;
+
+ GraphicsLayer::setChildrenTransform(t);
+
+ CATransform3D transform;
+ copyTransform(transform, t);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ // Set the value on the layer to the new transform.
+ [primaryLayer() setSublayerTransform:transform];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+static void moveAnimation(AnimatedPropertyID property, CALayer* fromLayer, CALayer* toLayer)
+{
+ String keyPath = GraphicsLayer::propertyIdToString(property);
+ for (short index = 0; ; ++index) {
+ String animName = keyPath + "_" + String::number(index);
+ CAAnimation* anim = [fromLayer animationForKey:animName];
+ if (!anim)
+ break;
+
+ [anim retain];
+ [fromLayer removeAnimationForKey:animName];
+ [toLayer addAnimation:anim forKey:animName];
+ [anim release];
+ }
+}
+
+static void moveSublayers(CALayer* fromLayer, CALayer* toLayer)
+{
+ NSArray* sublayersCopy = [[fromLayer sublayers] copy]; // Avoid mutation while enumerating, and keep the sublayers alive.
+ NSEnumerator* childrenEnumerator = [sublayersCopy objectEnumerator];
+
+ CALayer* layer;
+ while ((layer = [childrenEnumerator nextObject]) != nil) {
+ [layer removeFromSuperlayer];
+ [toLayer addSublayer:layer];
+ }
+ [sublayersCopy release];
+}
+
+void GraphicsLayerCA::setPreserves3D(bool preserves3D)
+{
+ GraphicsLayer::setPreserves3D(preserves3D);
+
+ CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f);
+ CGPoint centerPoint = CGPointMake(0.5f, 0.5f);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ Class transformLayerClass = NSClassFromString(@"CATransformLayer");
+ if (preserves3D && !m_transformLayer && transformLayerClass) {
+ // Create the transform layer.
+ m_transformLayer.adoptNS([[transformLayerClass alloc] init]);
+
+ // Turn off default animations.
+ [m_transformLayer.get() setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
+
+#ifndef NDEBUG
+ [m_transformLayer.get() setName:[NSString stringWithFormat:@"Transform Layer CATransformLayer(%p) GraphicsLayer(%p)", m_transformLayer.get(), this]];
+#endif
+ // Copy the position from this layer.
+ [m_transformLayer.get() setBounds:[m_layer.get() bounds]];
+ [m_transformLayer.get() setPosition:[m_layer.get() position]];
+ [m_transformLayer.get() setAnchorPoint:[m_layer.get() anchorPoint]];
+#if HAVE_MODERN_QUARTZCORE
+ [m_transformLayer.get() setAnchorPointZ:[m_layer.get() anchorPointZ]];
+#endif
+ [m_transformLayer.get() setContentsRect:[m_layer.get() contentsRect]];
+#ifndef NDEBUG
+ [m_transformLayer.get() setZPosition:[m_layer.get() zPosition]];
+#endif
+
+ // The contents layer is positioned at (0,0) relative to the transformLayer.
+ [m_layer.get() setPosition:point];
+ [m_layer.get() setAnchorPoint:centerPoint];
+#ifndef NDEBUG
+ [m_layer.get() setZPosition:0.0f];
+#endif
+
+ // Transfer the transform over.
+ [m_transformLayer.get() setTransform:[m_layer.get() transform]];
+ [m_layer.get() setTransform:CATransform3DIdentity];
+
+ // Transfer the opacity from the old layer to the transform layer.
+ [m_transformLayer.get() setOpacity:m_opacity];
+ [m_layer.get() setOpacity:1];
+
+ // Move this layer to be a child of the transform layer.
+ [[m_layer.get() superlayer] replaceSublayer:m_layer.get() with:m_transformLayer.get()];
+ [m_transformLayer.get() addSublayer:m_layer.get()];
+
+ moveAnimation(AnimatedPropertyWebkitTransform, m_layer.get(), m_transformLayer.get());
+ moveSublayers(m_layer.get(), m_transformLayer.get());
+
+ } else if (!preserves3D && m_transformLayer) {
+ // Relace the transformLayer in the parent with this layer.
+ [m_layer.get() removeFromSuperlayer];
+ [[m_transformLayer.get() superlayer] replaceSublayer:m_transformLayer.get() with:m_layer.get()];
+
+ moveAnimation(AnimatedPropertyWebkitTransform, m_transformLayer.get(), m_layer.get());
+ moveSublayers(m_transformLayer.get(), m_layer.get());
+
+ // Reset the layer position and transform.
+ [m_layer.get() setPosition:[m_transformLayer.get() position]];
+ [m_layer.get() setAnchorPoint:[m_transformLayer.get() anchorPoint]];
+#if HAVE_MODERN_QUARTZCORE
+ [m_layer.get() setAnchorPointZ:[m_transformLayer.get() anchorPointZ]];
+#endif
+ [m_layer.get() setContentsRect:[m_transformLayer.get() contentsRect]];
+ [m_layer.get() setTransform:[m_transformLayer.get() transform]];
+ [m_layer.get() setOpacity:[m_transformLayer.get() opacity]];
+#ifndef NDEBUG
+ [m_layer.get() setZPosition:[m_transformLayer.get() zPosition]];
+#endif
+
+ // Release the transform layer.
+ m_transformLayer = 0;
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setMasksToBounds(bool masksToBounds)
+{
+ if (masksToBounds == m_masksToBounds)
+ return;
+
+ GraphicsLayer::setMasksToBounds(masksToBounds);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [m_layer.get() setMasksToBounds:masksToBounds];
+ END_BLOCK_OBJC_EXCEPTIONS
+
+#ifndef NDEBUG
+ updateDebugIndicators();
+#endif
+}
+
+void GraphicsLayerCA::setDrawsContent(bool drawsContent)
+{
+ if (drawsContent != m_drawsContent) {
+ GraphicsLayer::setDrawsContent(drawsContent);
+
+ bool needTiledLayer = requiresTiledLayer(m_size);
+ if (needTiledLayer != m_usingTiledLayer)
+ swapFromOrToTiledLayer(needTiledLayer);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ // Clobber any existing content. If necessary, CA will create backing store on the next display.
+ [m_layer.get() setContents:nil];
+
+#ifndef NDEBUG
+ updateDebugIndicators();
+#endif
+ END_BLOCK_OBJC_EXCEPTIONS
+ }
+}
+
+void GraphicsLayerCA::setBackgroundColor(const Color& color, const Animation* transition, double beginTime)
+{
+ GraphicsLayer::setBackgroundColor(color, transition, beginTime);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ setHasContentsLayer(true);
+
+ if (transition && !transition->isEmptyOrZeroDuration()) {
+ CALayer* presLayer = [m_contentsLayer.get() presentationLayer];
+ // If we don't have a presentationLayer, just use the CALayer
+ if (!presLayer)
+ presLayer = m_contentsLayer.get();
+
+ // Get the current value of the background color from the layer
+ CGColorRef fromBackgroundColor = [presLayer backgroundColor];
+
+ CGColorRef bgColor = createCGColor(color);
+ setBasicAnimation(AnimatedPropertyBackgroundColor, TransformOperation::NONE, 0, fromBackgroundColor, bgColor, true, transition, beginTime);
+ CGColorRelease(bgColor);
+ } else {
+ removeAllAnimationsForProperty(AnimatedPropertyBackgroundColor);
+ setHasContentsLayer(true);
+ setLayerBackgroundColor(m_contentsLayer.get(), m_backgroundColor);
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::clearBackgroundColor()
+{
+ if (!m_contentLayerForImageOrVideo)
+ setHasContentsLayer(false);
+ else
+ clearLayerBackgroundColor(m_contentsLayer.get());
+}
+
+void GraphicsLayerCA::setContentsOpaque(bool opaque)
+{
+ GraphicsLayer::setContentsOpaque(opaque);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [m_layer.get() setOpaque:m_contentsOpaque];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setBackfaceVisibility(bool visible)
+{
+ if (m_backfaceVisibility == visible)
+ return;
+
+ GraphicsLayer::setBackfaceVisibility(visible);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [m_layer.get() setDoubleSided:visible];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+bool GraphicsLayerCA::setOpacity(float opacity, const Animation* transition, double beginTime)
+{
+ if (forceSoftwareAnimation())
+ return false;
+
+ float clampedOpacity = max(0.0f, min(opacity, 1.0f));
+
+ bool opacitiesDiffer = (m_opacity != clampedOpacity);
+
+ GraphicsLayer::setOpacity(clampedOpacity, transition, beginTime);
+
+ int animIndex = findAnimationEntry(AnimatedPropertyOpacity, 0);
+
+ // If we don't have a transition just set the opacity
+ if (!transition || transition->isEmptyOrZeroDuration()) {
+ // Three cases:
+ // 1) no existing animation or transition: just set opacity
+ // 2) existing transition: clear it and set opacity
+ // 3) existing animation: just return
+ //
+ if (animIndex < 0 || m_animations[animIndex].isTransition()) {
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [primaryLayer() setOpacity:opacity];
+ if (animIndex >= 0) {
+ removeAllAnimationsForProperty(AnimatedPropertyOpacity);
+ animIndex = -1;
+ } else {
+ String keyPath = propertyIdToString(AnimatedPropertyOpacity);
+
+ // FIXME: using hardcoded '0' here. We should be clearing all animations. For now there is only 1.
+ String animName = keyPath + "_0";
+ [animatedLayer(AnimatedPropertyOpacity) removeAnimationForKey:animName];
+ }
+ END_BLOCK_OBJC_EXCEPTIONS
+ } else {
+ // We have an animation, so don't set the opacity directly.
+ return false;
+ }
+ } else {
+ // At this point, we know we have a transition. But if it is the same and
+ // the opacity value has not changed, don't do anything.
+ if (!opacitiesDiffer &&
+ ((animIndex == -1) ||
+ (m_animations[animIndex].isTransition() && *(m_animations[animIndex].animation()) == *transition))) {
+ return false;
+ }
+ }
+
+ // If an animation is running, ignore this transition, but still save the value.
+ if (animIndex >= 0 && !m_animations[animIndex].isTransition())
+ return false;
+
+ bool didAnimate = false;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ NSNumber* fromOpacityValue = nil;
+ NSNumber* toOpacityValue = [NSNumber numberWithFloat:opacity];
+
+ if (transition && !transition->isEmptyOrZeroDuration()) {
+ CALayer* presLayer = getPresentationLayer(primaryLayer());
+ float fromOpacity = [presLayer opacity];
+ fromOpacityValue = [NSNumber numberWithFloat:fromOpacity];
+ setBasicAnimation(AnimatedPropertyOpacity, TransformOperation::NONE, 0, fromOpacityValue, toOpacityValue, true, transition, beginTime);
+ didAnimate = true;
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ return didAnimate;
+}
+
+void GraphicsLayerCA::setNeedsDisplay()
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (drawsContent())
+ [m_layer.get() setNeedsDisplay];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setNeedsDisplayInRect(const FloatRect& rect)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (drawsContent())
+ [m_layer.get() setNeedsDisplayInRect:rect];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+
+bool GraphicsLayerCA::animateTransform(const TransformValueList& valueList, const IntSize& size, const Animation* anim, double beginTime, bool isTransition)
+{
+ if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
+ return false;
+
+ TransformValueList::FunctionList functionList;
+ bool isValid, hasBigRotation;
+ valueList.makeFunctionList(functionList, isValid, hasBigRotation);
+
+ // We need to fall back to software animation if we don't have setValueFunction:, and
+ // we would need to animate each incoming transform function separately. This is the
+ // case if we have a rotation >= 180 or we have more than one transform function.
+ if ((hasBigRotation || functionList.size() > 1) && !caValueFunctionSupported())
+ return false;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ // Rules for animation:
+ //
+ // 1) If functionList is empty or we don't have a big rotation, we do a matrix animation. We could
+ // use component animation for lists without a big rotation, but there is no need to, and this
+ // is more efficient.
+ //
+ // 2) Otherwise we do a component hardware animation.
+ bool isMatrixAnimation = !isValid || !hasBigRotation;
+
+ // Set transform to identity since we are animating components and we need the base
+ // to be the identity transform.
+ TransformationMatrix t;
+ CATransform3D toT3D;
+ copyTransform(toT3D, t);
+ [primaryLayer() setTransform:toT3D];
+
+ bool isKeyframe = valueList.size() > 2;
+
+ // Iterate through the transform functions, sending an animation for each one.
+ for (int functionIndex = 0; ; ++functionIndex) {
+ if (functionIndex >= static_cast<int>(functionList.size()) && !isMatrixAnimation)
+ break;
+
+ TransformOperation::OperationType opType = isMatrixAnimation ? TransformOperation::MATRIX_3D : functionList[functionIndex];
+
+ if (isKeyframe) {
+ NSMutableArray* timesArray = [[NSMutableArray alloc] init];
+ NSMutableArray* valArray = [[NSMutableArray alloc] init];
+ NSMutableArray* tfArray = [[NSMutableArray alloc] init];
+
+ // Iterate through the keyframes, building arrays for the animation.
+ for (Vector<TransformValue>::const_iterator it = valueList.values().begin(); it != valueList.values().end(); ++it) {
+ const TransformValue& curValue = (*it);
+
+ // fill in the key time and timing function
+ [timesArray addObject:[NSNumber numberWithFloat:curValue.key()]];
+
+ const TimingFunction* tf = 0;
+ if (curValue.timingFunction())
+ tf = curValue.timingFunction();
+ else if (anim->isTimingFunctionSet())
+ tf = &anim->timingFunction();
+
+ CAMediaTimingFunction* timingFunction = getCAMediaTimingFunction(tf ? *tf : TimingFunction(LinearTimingFunction));
+ [tfArray addObject:timingFunction];
+
+ // fill in the function
+ if (isMatrixAnimation) {
+ TransformationMatrix t;
+ curValue.value()->apply(size, t);
+ CATransform3D cat;
+ copyTransform(cat, t);
+ [valArray addObject:[NSValue valueWithCATransform3D:cat]];
+ } else
+ [valArray addObject:getTransformFunctionValue(curValue, functionIndex, size, opType)];
+ }
+
+ // We toss the last tfArray value because it has to one shorter than the others.
+ [tfArray removeLastObject];
+
+ setKeyframeAnimation(AnimatedPropertyWebkitTransform, opType, functionIndex, timesArray, valArray, tfArray, isTransition, anim, beginTime);
+
+ [timesArray release];
+ [valArray release];
+ [tfArray release];
+ } else {
+ // Is a transition
+ id fromValue, toValue;
+
+ if (isMatrixAnimation) {
+ TransformationMatrix fromt, tot;
+ valueList.at(0).value()->apply(size, fromt);
+ valueList.at(1).value()->apply(size, tot);
+
+ CATransform3D cat;
+ copyTransform(cat, fromt);
+ fromValue = [NSValue valueWithCATransform3D:cat];
+ copyTransform(cat, tot);
+ toValue = [NSValue valueWithCATransform3D:cat];
+ } else {
+ fromValue = getTransformFunctionValue(valueList.at(0), functionIndex, size, opType);
+ toValue = getTransformFunctionValue(valueList.at(1), functionIndex, size, opType);
+ }
+
+ setBasicAnimation(AnimatedPropertyWebkitTransform, opType, functionIndex, fromValue, toValue, isTransition, anim, beginTime);
+ }
+
+ if (isMatrixAnimation)
+ break;
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+ return true;
+}
+
+bool GraphicsLayerCA::animateFloat(AnimatedPropertyID property, const FloatValueList& valueList, const Animation* animation, double beginTime)
+{
+ if (forceSoftwareAnimation() || valueList.size() < 2)
+ return false;
+
+ // if there is already is an animation for this property and it hasn't changed, ignore it.
+ int i = findAnimationEntry(property, 0);
+ if (i >= 0 && *m_animations[i].animation() == *animation) {
+ m_animations[i].setIsCurrent();
+ return false;
+ }
+
+ if (valueList.size() == 2) {
+ float fromVal = valueList.at(0).value();
+ float toVal = valueList.at(1).value();
+ if (isnan(toVal) && isnan(fromVal))
+ return false;
+
+ // initialize the property to 0
+ [animatedLayer(property) setValue:0 forKeyPath:propertyIdToString(property)];
+ setBasicAnimation(property, TransformOperation::NONE, 0, isnan(fromVal) ? nil : [NSNumber numberWithFloat:fromVal], isnan(toVal) ? nil : [NSNumber numberWithFloat:toVal], false, animation, beginTime);
+ return true;
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ NSMutableArray* timesArray = [[NSMutableArray alloc] init];
+ NSMutableArray* valArray = [[NSMutableArray alloc] init];
+ NSMutableArray* tfArray = [[NSMutableArray alloc] init];
+
+ for (unsigned i = 0; i < valueList.values().size(); ++i) {
+ const FloatValue& curValue = valueList.values()[i];
+ [timesArray addObject:[NSNumber numberWithFloat:curValue.key()]];
+ [valArray addObject:[NSNumber numberWithFloat:curValue.value()]];
+
+ const TimingFunction* tf = 0;
+ if (curValue.timingFunction())
+ tf = curValue.timingFunction();
+ else if (animation->isTimingFunctionSet())
+ tf = &animation->timingFunction();
+
+ CAMediaTimingFunction* timingFunction = getCAMediaTimingFunction(tf ? *tf : TimingFunction());
+ [tfArray addObject:timingFunction];
+ }
+
+ // We toss the last tfArray value because it has to one shorter than the others.
+ [tfArray removeLastObject];
+
+ // Initialize the property to 0.
+ [animatedLayer(property) setValue:0 forKeyPath:propertyIdToString(property)];
+ // Then set the animation.
+ setKeyframeAnimation(property, TransformOperation::NONE, 0, timesArray, valArray, tfArray, false, animation, beginTime);
+
+ [timesArray release];
+ [valArray release];
+ [tfArray release];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+ return true;
+}
+
+void GraphicsLayerCA::setContentsToImage(Image* image)
+{
+ if (image) {
+ setHasContentsLayer(true);
+
+ // FIXME: is image flipping really a property of the graphics context?
+ bool needToFlip = GraphicsLayer::graphicsContextsFlipped();
+ CGPoint anchorPoint = needToFlip ? CGPointMake(0.0f, 1.0f) : CGPointZero;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ {
+ CGImageRef theImage = image->nativeImageForCurrentFrame();
+ // FIXME: maybe only do trilinear if the image is being scaled down,
+ // but then what if the layer size changes?
+#if HAVE_MODERN_QUARTZCORE
+ [m_contentsLayer.get() setMinificationFilter:kCAFilterTrilinear];
+#endif
+ if (needToFlip) {
+ CATransform3D flipper = {
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
+ [m_contentsLayer.get() setTransform:flipper];
+ }
+
+ [m_contentsLayer.get() setAnchorPoint:anchorPoint];
+ [m_contentsLayer.get() setContents:(id)theImage];
+ }
+ END_BLOCK_OBJC_EXCEPTIONS
+ } else
+ setHasContentsLayer(false);
+
+ m_contentLayerForImageOrVideo = (image != 0);
+}
+
+void GraphicsLayerCA::setContentsToVideo(PlatformLayer* videoLayer)
+{
+ setContentsLayer(videoLayer);
+ m_contentLayerForImageOrVideo = (videoLayer != 0);
+}
+
+void GraphicsLayerCA::clearContents()
+{
+ if (m_contentLayerForImageOrVideo) {
+ setHasContentsLayer(false);
+ m_contentLayerForImageOrVideo = false;
+ }
+}
+
+void GraphicsLayerCA::updateContentsRect()
+{
+ if (m_client && m_contentsLayer) {
+ IntRect contentRect = m_client->contentsBox(this);
+
+ CGPoint point = CGPointMake(contentRect.x(),
+ contentRect.y());
+ CGRect rect = CGRectMake(0.0f,
+ 0.0f,
+ contentRect.width(),
+ contentRect.height());
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [m_contentsLayer.get() setPosition:point];
+ [m_contentsLayer.get() setBounds:rect];
+ END_BLOCK_OBJC_EXCEPTIONS
+ }
+}
+
+void GraphicsLayerCA::setBasicAnimation(AnimatedPropertyID property, TransformOperation::OperationType operationType, short index, void* fromVal, void* toVal, bool isTransition, const Animation* transition, double beginTime)
+{
+ ASSERT(fromVal || toVal);
+
+ WebLayer* layer = animatedLayer(property);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ // add an entry for this animation
+ addAnimationEntry(property, index, isTransition, transition);
+
+ String keyPath = propertyIdToString(property);
+ String animName = keyPath + "_" + String::number(index);
+
+ CABasicAnimation* basicAnim = [CABasicAnimation animationWithKeyPath:keyPath];
+
+ double duration = transition->duration();
+ if (duration <= 0)
+ duration = cAnimationAlmostZeroDuration;
+
+ float repeatCount = transition->iterationCount();
+ if (repeatCount == Animation::IterationCountInfinite)
+ repeatCount = FLT_MAX;
+ else if (transition->direction() == Animation::AnimationDirectionAlternate)
+ repeatCount /= 2;
+
+ [basicAnim setDuration:duration];
+ [basicAnim setRepeatCount:repeatCount];
+ [basicAnim setAutoreverses:transition->direction()];
+ [basicAnim setRemovedOnCompletion:NO];
+
+ // Note that currently transform is the only property which has animations
+ // with an index > 0.
+ [basicAnim setAdditive:property == AnimatedPropertyWebkitTransform];
+ [basicAnim setFillMode:@"extended"];
+#if HAVE_MODERN_QUARTZCORE
+ if (NSString* valueFunctionName = getValueFunctionNameForTransformOperation(operationType))
+ [basicAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
+#else
+ UNUSED_PARAM(operationType);
+#endif
+
+ // Set the delegate (and property value).
+ int prop = isTransition ? property : AnimatedPropertyInvalid;
+ [basicAnim setValue:[NSNumber numberWithInt:prop] forKey:WebAnimationCSSPropertyKey];
+ [basicAnim setDelegate:m_animationDelegate.get()];
+
+ NSTimeInterval bt = beginTime ? [layer convertTime:currentTimeToMediaTime(beginTime) fromLayer:nil] : 0;
+ [basicAnim setBeginTime:bt];
+
+ if (fromVal)
+ [basicAnim setFromValue:reinterpret_cast<id>(fromVal)];
+ if (toVal)
+ [basicAnim setToValue:reinterpret_cast<id>(toVal)];
+
+ const TimingFunction* tf = 0;
+ if (transition->isTimingFunctionSet())
+ tf = &transition->timingFunction();
+
+ CAMediaTimingFunction* timingFunction = getCAMediaTimingFunction(tf ? *tf : TimingFunction());
+ [basicAnim setTimingFunction:timingFunction];
+
+ // Send over the animation.
+ [layer removeAnimationForKey:animName];
+ [layer addAnimation:basicAnim forKey:animName];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setKeyframeAnimation(AnimatedPropertyID property, TransformOperation::OperationType operationType, short index, void* keys, void* values, void* timingFunctions,
+ bool isTransition, const Animation* anim, double beginTime)
+{
+ PlatformLayer* layer = animatedLayer(property);
+
+ // Add an entry for this animation (which may change beginTime).
+ addAnimationEntry(property, index, isTransition, anim);
+
+ String keyPath = propertyIdToString(property);
+ String animName = keyPath + "_" + String::number(index);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ CAKeyframeAnimation* keyframeAnim = [CAKeyframeAnimation animationWithKeyPath:keyPath];
+
+ double duration = anim->duration();
+ if (duration <= 0)
+ duration = cAnimationAlmostZeroDuration;
+
+ float repeatCount = anim->iterationCount();
+ if (repeatCount == Animation::IterationCountInfinite)
+ repeatCount = FLT_MAX;
+ else if (anim->direction() == Animation::AnimationDirectionAlternate)
+ repeatCount /= 2;
+
+ [keyframeAnim setDuration:duration];
+ [keyframeAnim setRepeatCount:repeatCount];
+ [keyframeAnim setAutoreverses:anim->direction()];
+ [keyframeAnim setRemovedOnCompletion:NO];
+
+ // The first animation is non-additive, all the rest are additive.
+ // Note that currently transform is the only property which has animations
+ // with an index > 0.
+ [keyframeAnim setAdditive:(property == AnimatedPropertyWebkitTransform) ? YES : NO];
+ [keyframeAnim setFillMode:@"extended"];
+#if HAVE_MODERN_QUARTZCORE
+ if (NSString* valueFunctionName = getValueFunctionNameForTransformOperation(operationType))
+ [keyframeAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
+#else
+ UNUSED_PARAM(operationType);
+#endif
+
+ [keyframeAnim setKeyTimes:reinterpret_cast<id>(keys)];
+ [keyframeAnim setValues:reinterpret_cast<id>(values)];
+
+ // Set the delegate (and property value).
+ int prop = isTransition ? property : AnimatedPropertyInvalid;
+ [keyframeAnim setValue:[NSNumber numberWithInt: prop] forKey:WebAnimationCSSPropertyKey];
+ [keyframeAnim setDelegate:m_animationDelegate.get()];
+
+ NSTimeInterval bt = beginTime ? [layer convertTime:currentTimeToMediaTime(beginTime) fromLayer:nil] : 0;
+ [keyframeAnim setBeginTime:bt];
+
+ // Set the timing functions, if any.
+ if (timingFunctions != nil)
+ [keyframeAnim setTimingFunctions:(id)timingFunctions];
+
+ // Send over the animation.
+ [layer removeAnimationForKey:animName];
+ [layer addAnimation:keyframeAnim forKey:animName];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::suspendAnimations()
+{
+ double t = currentTimeToMediaTime(currentTime());
+ [primaryLayer() setSpeed:0];
+ [primaryLayer() setTimeOffset:t];
+}
+
+void GraphicsLayerCA::resumeAnimations()
+{
+ [primaryLayer() setSpeed:1];
+ [primaryLayer() setTimeOffset:0];
+}
+
+void GraphicsLayerCA::removeAnimation(int index, bool reset)
+{
+ ASSERT(index >= 0);
+
+ AnimatedPropertyID property = m_animations[index].property();
+
+ // Set the value of the property and remove the animation.
+ String keyPath = propertyIdToString(property);
+ String animName = keyPath + "_" + String::number(m_animations[index].index());
+ CALayer* layer = animatedLayer(property);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ // If we are not resetting, it means we are pausing. So we need to get the current presentation
+ // value into the property before we remove the animation.
+ if (!reset) {
+ // Put the current value into the property.
+ CALayer* presLayer = [layer presentationLayer];
+ if (presLayer)
+ [layer setValue:[presLayer valueForKeyPath:keyPath] forKeyPath:keyPath];
+
+ // Make sure the saved values accurately reflect the value in the layer.
+ id val = [layer valueForKeyPath:keyPath];
+ switch (property) {
+ case AnimatedPropertyWebkitTransform:
+ // FIXME: needs comment explaining why the m_transform is not obtained from the layer
+ break;
+ case AnimatedPropertyBackgroundColor:
+ m_backgroundColor = Color(reinterpret_cast<CGColorRef>(val));
+ break;
+ case AnimatedPropertyOpacity:
+ m_opacity = [val floatValue];
+ break;
+ case AnimatedPropertyInvalid:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ // If we have reached the end of an animation, we don't want to actually remove the
+ // animation from the CALayer. At some point we will be setting the property to its
+ // unanimated value and at that point we will remove the animation. That will avoid
+ // any flashing between the time the animation is removed and the property is set.
+ if (!reset || m_animations[index].isTransition())
+ [layer removeAnimationForKey:animName];
+
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ // Remove the animation entry.
+ m_animations.remove(index);
+}
+
+PlatformLayer* GraphicsLayerCA::hostLayerForSublayers() const
+{
+ return m_transformLayer ? m_transformLayer.get() : m_layer.get();
+}
+
+PlatformLayer* GraphicsLayerCA::layerForSuperlayer() const
+{
+ if (m_transformLayer)
+ return m_transformLayer.get();
+
+ return m_layer.get();
+}
+
+PlatformLayer* GraphicsLayerCA::platformLayer() const
+{
+ return primaryLayer();
+}
+
+#ifndef NDEBUG
+void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (color.isValid())
+ setLayerBackgroundColor(m_layer.get(), color);
+ else
+ clearLayerBackgroundColor(m_layer.get());
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (color.isValid()) {
+ setLayerBorderColor(m_layer.get(), color);
+ [m_layer.get() setBorderWidth:borderWidth];
+ } else {
+ clearBorderColor(m_layer.get());
+ [m_layer.get() setBorderWidth:0];
+ }
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setZPosition(float position)
+{
+ GraphicsLayer::setZPosition(position);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+ [primaryLayer() setZPosition:position];
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+#endif
+
+bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const
+{
+ if (!m_drawsContent)
+ return false;
+
+ // FIXME: catch zero-size height or width here (or earlier)?
+ return size.width() > cMaxPixelDimension || size.height() > cMaxPixelDimension;
+}
+
+void GraphicsLayerCA::swapFromOrToTiledLayer(bool userTiledLayer)
+{
+ if (userTiledLayer == m_usingTiledLayer)
+ return;
+
+ CGSize tileSize = CGSizeMake(cTiledLayerTileSize, cTiledLayerTileSize);
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ RetainPtr<CALayer> oldLayer = m_layer.get();
+
+ Class layerClass = userTiledLayer ? [WebTiledLayer self] : [WebLayer self];
+ m_layer.adoptNS([[layerClass alloc] init]);
+
+ if (userTiledLayer) {
+ WebTiledLayer* tiledLayer = (WebTiledLayer*)m_layer.get();
+ [tiledLayer setTileSize:tileSize];
+ [tiledLayer setLevelsOfDetail:1];
+ [tiledLayer setLevelsOfDetailBias:0];
+
+ if (GraphicsLayer::graphicsContextsFlipped())
+ [tiledLayer setContentsGravity:@"bottomLeft"];
+ else
+ [tiledLayer setContentsGravity:@"topLeft"];
+ }
+
+ [m_layer.get() setLayerOwner:this];
+ [m_layer.get() setSublayers:[oldLayer.get() sublayers]];
+
+ [[oldLayer.get() superlayer] replaceSublayer:oldLayer.get() with:m_layer.get()];
+
+ [m_layer.get() setBounds:[oldLayer.get() bounds]];
+ [m_layer.get() setPosition:[oldLayer.get() position]];
+ [m_layer.get() setAnchorPoint:[oldLayer.get() anchorPoint]];
+ [m_layer.get() setOpaque:[oldLayer.get() isOpaque]];
+ [m_layer.get() setOpacity:[oldLayer.get() opacity]];
+ [m_layer.get() setTransform:[oldLayer.get() transform]];
+ [m_layer.get() setSublayerTransform:[oldLayer.get() sublayerTransform]];
+ [m_layer.get() setDoubleSided:[oldLayer.get() isDoubleSided]];
+#ifndef NDEBUG
+ [m_layer.get() setZPosition:[oldLayer.get() zPosition]];
+#endif
+
+#ifndef NDEBUG
+ String name = String::format("CALayer(%p) GraphicsLayer(%p) ", m_layer.get(), this) + m_name;
+ [m_layer.get() setName:name];
+#endif
+
+ // move over animations
+ moveAnimation(AnimatedPropertyWebkitTransform, oldLayer.get(), m_layer.get());
+ moveAnimation(AnimatedPropertyOpacity, oldLayer.get(), m_layer.get());
+ moveAnimation(AnimatedPropertyBackgroundColor, oldLayer.get(), m_layer.get());
+
+ // need to tell new layer to draw itself
+ setNeedsDisplay();
+
+ END_BLOCK_OBJC_EXCEPTIONS
+
+ m_usingTiledLayer = userTiledLayer;
+
+#ifndef NDEBUG
+ updateDebugIndicators();
+#endif
+}
+
+void GraphicsLayerCA::setHasContentsLayer(bool hasLayer)
+{
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (hasLayer && !m_contentsLayer) {
+ // create the inner layer
+ WebLayer* contentsLayer = [WebLayer layer];
+#ifndef NDEBUG
+ [contentsLayer setName:@"Contents Layer"];
+#endif
+ setContentsLayer(contentsLayer);
+
+ } else if (!hasLayer && m_contentsLayer)
+ setContentsLayer(0);
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+void GraphicsLayerCA::setContentsLayer(WebLayer* contentsLayer)
+{
+ if (contentsLayer == m_contentsLayer)
+ return;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS
+
+ if (m_contentsLayer) {
+ [m_contentsLayer.get() removeFromSuperlayer];
+ m_contentsLayer = 0;
+ }
+
+ if (contentsLayer) {
+ // Turn off implicit animations on the inner layer.
+ [contentsLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]];
+
+ m_contentsLayer.adoptNS([contentsLayer retain]);
+ [m_contentsLayer.get() setAnchorPoint:CGPointZero];
+ [m_layer.get() addSublayer:m_contentsLayer.get()];
+
+ updateContentsRect();
+
+ // Set contents to nil if the layer does not draw its own content.
+ if (m_client && !drawsContent())
+ [m_layer.get() setContents:nil];
+
+#ifndef NDEBUG
+ if (showDebugBorders()) {
+ setLayerBorderColor(m_contentsLayer.get(), Color(0, 0, 128, 180));
+ [m_contentsLayer.get() setBorderWidth:1.0f];
+ }
+#endif
+ }
+#ifndef NDEBUG
+ updateDebugIndicators();
+#endif
+
+ END_BLOCK_OBJC_EXCEPTIONS
+}
+
+} // namespace WebCore
+
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
index 3f18ab4..677c31a 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,7 +28,7 @@
#if ENABLE(VIDEO)
-#include "MediaPlayer.h"
+#include "MediaPlayerPrivate.h"
#include "Timer.h"
#include <wtf/RetainPtr.h>
@@ -52,11 +52,28 @@ class WebCoreMovieObserver;
namespace WebCore {
-class MediaPlayerPrivate : Noncopyable {
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
public:
- MediaPlayerPrivate(MediaPlayer*);
+ static void registerMediaEngine(MediaEngineRegistrar);
+
~MediaPlayerPrivate();
-
+
+ void repaint();
+ void loadStateChanged();
+ void rateChanged();
+ void sizeChanged();
+ void timeChanged();
+ void didEnd();
+
+private:
+ MediaPlayerPrivate(MediaPlayer*);
+
+ // engine support
+ static MediaPlayerPrivateInterface* create(MediaPlayer* player);
+ static void getSupportedTypes(HashSet<String>& types);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable();
+
IntSize naturalSize() const;
bool hasVideo() const;
@@ -72,11 +89,12 @@ public:
float duration() const;
float currentTime() const;
void seek(float time);
- void setEndTime(float time);
void setRate(float);
void setVolume(float);
-
+
+ void setEndTime(float time);
+
int dataRate() const;
MediaPlayer::NetworkState networkState() const { return m_networkState; }
@@ -89,21 +107,10 @@ public:
unsigned totalBytes() const;
void setVisible(bool);
- void setRect(const IntRect& r);
-
- void loadStateChanged();
- void rateChanged();
- void sizeChanged();
- void timeChanged();
- void didEnd();
+ void setSize(const IntSize&);
- void repaint();
void paint(GraphicsContext*, const IntRect&);
-
- static void getSupportedTypes(HashSet<String>& types);
- static bool isAvailable();
-
-private:
+
void createQTMovie(const String& url);
void setUpVideoRendering();
void tearDownVideoRendering();
@@ -117,10 +124,10 @@ private:
void doSeek();
void cancelSeek();
void seekTimerFired(Timer<MediaPlayerPrivate>*);
- void endPointTimerFired(Timer<MediaPlayerPrivate>*);
float maxTimeLoaded() const;
- void startEndPointTimerIfNeeded();
- void disableUnsupportedTracks(unsigned& enabledTrackCount);
+ void disableUnsupportedTracks();
+
+ bool metaDataAvailable() const { return m_qtMovie && m_readyState >= MediaPlayer::HaveMetadata; }
MediaPlayer* m_player;
RetainPtr<QTMovie> m_qtMovie;
@@ -128,14 +135,15 @@ private:
RetainPtr<QTVideoRendererWebKitOnly> m_qtVideoRenderer;
RetainPtr<WebCoreMovieObserver> m_objcObserver;
float m_seekTo;
- float m_endTime;
Timer<MediaPlayerPrivate> m_seekTimer;
- Timer<MediaPlayerPrivate> m_endPointTimer;
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
bool m_startedPlaying;
bool m_isStreaming;
bool m_visible;
+ IntRect m_rect;
+ unsigned m_enabledTrackCount;
+ float m_duration;
#if DRAW_FRAME_RATE
int m_frameCountWhilePlaying;
double m_timeStartedPlaying;
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index a33c8d2..74a9ff9 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -69,6 +69,7 @@ SOFT_LINK_CLASS(QTKit, QTMovieView)
SOFT_LINK_POINTER(QTKit, QTMediaTypeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeBase, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMediaTypeMPEG, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeSound, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeText, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeVideo, NSString *)
@@ -95,6 +96,7 @@ SOFT_LINK_POINTER(QTKit, QTVideoRendererWebKitOnlyNewImageAvailableNotification,
#define QTMediaTypeAttribute getQTMediaTypeAttribute()
#define QTMediaTypeBase getQTMediaTypeBase()
+#define QTMediaTypeMPEG getQTMediaTypeMPEG()
#define QTMediaTypeSound getQTMediaTypeSound()
#define QTMediaTypeText getQTMediaTypeText()
#define QTMediaTypeVideo getQTMediaTypeVideo()
@@ -155,24 +157,35 @@ using namespace std;
namespace WebCore {
-static const float endPointTimerInterval = 0.020f;
-
#ifdef BUILDING_ON_TIGER
static const long minimumQuickTimeVersion = 0x07300000; // 7.3
#endif
+
+MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player)
+{
+ return new MediaPlayerPrivate(player);
+}
+
+void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+ if (isAvailable())
+ registrar(create, getSupportedTypes, supportsType);
+}
+
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_objcObserver(AdoptNS, [[WebCoreMovieObserver alloc] initWithCallback:this])
, m_seekTo(-1)
- , m_endTime(numeric_limits<float>::infinity())
, m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
- , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired)
, m_networkState(MediaPlayer::Empty)
- , m_readyState(MediaPlayer::DataUnavailable)
+ , m_readyState(MediaPlayer::HaveNothing)
, m_startedPlaying(false)
, m_isStreaming(false)
, m_visible(false)
+ , m_rect()
+ , m_enabledTrackCount(0)
+ , m_duration(-1.0f)
#if DRAW_FRAME_RATE
, m_frameCountWhilePlaying(0)
, m_timeStartedPlaying(0)
@@ -270,7 +283,7 @@ void MediaPlayerPrivate::createQTMovieView()
detachQTMovieView();
static bool addedCustomMethods = false;
- if (!addedCustomMethods) {
+ if (!m_player->inMediaDocument() && !addedCustomMethods) {
Class QTMovieContentViewClass = NSClassFromString(@"QTMovieContentView");
ASSERT(QTMovieContentViewClass);
@@ -281,9 +294,12 @@ void MediaPlayerPrivate::createQTMovieView()
addedCustomMethods = true;
}
+ // delay callbacks as we *will* get notifications during setup
+ [m_objcObserver.get() setDelayCallbacks:YES];
+
m_qtMovieView.adoptNS([[QTMovieView alloc] init]);
- setRect(m_player->rect());
- NSView* parentView = m_player->m_frameView->documentView();
+ setSize(m_player->size());
+ NSView* parentView = m_player->frameView()->documentView();
[parentView addSubview:m_qtMovieView.get()];
#ifdef BUILDING_ON_TIGER
// setDelegate: isn't a public call in Tiger, so use performSelector to keep the compiler happy
@@ -303,6 +319,8 @@ void MediaPlayerPrivate::createQTMovieView()
// Note that we expect mainThreadSetNeedsDisplay to be invoked only when synchronous drawing is requested.
if (!m_player->inMediaDocument())
wkQTMovieViewSetDrawSynchronously(m_qtMovieView.get(), YES);
+
+ [m_objcObserver.get() setDelayCallbacks:NO];
}
void MediaPlayerPrivate::detachQTMovieView()
@@ -356,7 +374,7 @@ void MediaPlayerPrivate::destroyQTVideoRenderer()
void MediaPlayerPrivate::setUpVideoRendering()
{
- if (!m_player->m_frameView || !m_qtMovie)
+ if (!m_player->frameView() || !m_qtMovie)
return;
if (m_player->inMediaDocument() || !QTVideoRendererClass() )
@@ -375,7 +393,7 @@ void MediaPlayerPrivate::tearDownVideoRendering()
QTTime MediaPlayerPrivate::createQTTime(float time) const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return QTMakeTime(0, 600);
long timeScale = [[m_qtMovie.get() attributeForKey:QTMovieTimeScaleAttribute] longValue];
return QTMakeTime(time * timeScale, timeScale);
@@ -387,12 +405,11 @@ void MediaPlayerPrivate::load(const String& url)
m_networkState = MediaPlayer::Loading;
m_player->networkStateChanged();
}
- if (m_readyState != MediaPlayer::DataUnavailable) {
- m_readyState = MediaPlayer::DataUnavailable;
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
m_player->readyStateChanged();
}
cancelSeek();
- m_endPointTimer.stop();
[m_objcObserver.get() setDelayCallbacks:YES];
@@ -404,7 +421,7 @@ void MediaPlayerPrivate::load(const String& url)
void MediaPlayerPrivate::play()
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return;
m_startedPlaying = true;
#if DRAW_FRAME_RATE
@@ -413,12 +430,11 @@ void MediaPlayerPrivate::play()
[m_objcObserver.get() setDelayCallbacks:YES];
[m_qtMovie.get() setRate:m_player->rate()];
[m_objcObserver.get() setDelayCallbacks:NO];
- startEndPointTimerIfNeeded();
}
void MediaPlayerPrivate::pause()
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return;
m_startedPlaying = false;
#if DRAW_FRAME_RATE
@@ -427,12 +443,11 @@ void MediaPlayerPrivate::pause()
[m_objcObserver.get() setDelayCallbacks:YES];
[m_qtMovie.get() stop];
[m_objcObserver.get() setDelayCallbacks:NO];
- m_endPointTimer.stop();
}
float MediaPlayerPrivate::duration() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return 0;
QTTime time = [m_qtMovie.get() duration];
if (time.flags == kQTTimeIsIndefinite)
@@ -442,22 +457,22 @@ float MediaPlayerPrivate::duration() const
float MediaPlayerPrivate::currentTime() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return 0;
QTTime time = [m_qtMovie.get() currentTime];
- return min(static_cast<float>(time.timeValue) / time.timeScale, m_endTime);
+ return static_cast<float>(time.timeValue) / time.timeScale;
}
void MediaPlayerPrivate::seek(float time)
{
cancelSeek();
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return;
if (time > duration())
time = duration();
-
+
m_seekTo = time;
if (maxTimeLoaded() >= m_seekTo)
doSeek();
@@ -475,7 +490,7 @@ void MediaPlayerPrivate::doSeek()
[m_qtMovie.get() setCurrentTime:qttime];
float timeAfterSeek = currentTime();
// restore playback only if not at end, othewise QTMovie will loop
- if (timeAfterSeek < duration() && timeAfterSeek < m_endTime)
+ if (oldRate && timeAfterSeek < duration())
[m_qtMovie.get() setRate:oldRate];
cancelSeek();
[m_objcObserver.get() setDelayCallbacks:NO];
@@ -489,7 +504,7 @@ void MediaPlayerPrivate::cancelSeek()
void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
{
- if (!m_qtMovie || !seeking() || currentTime() == m_seekTo) {
+ if (!metaDataAvailable()|| !seeking() || currentTime() == m_seekTo) {
cancelSeek();
updateStates();
m_player->timeChanged();
@@ -508,67 +523,48 @@ void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
}
}
-void MediaPlayerPrivate::setEndTime(float time)
+void MediaPlayerPrivate::setEndTime(float)
{
- m_endTime = time;
- startEndPointTimerIfNeeded();
-}
-
-void MediaPlayerPrivate::startEndPointTimerIfNeeded()
-{
- if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive())
- m_endPointTimer.startRepeating(endPointTimerInterval);
-}
-
-void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*)
-{
- float time = currentTime();
-
- // just do end for now
- if (time >= m_endTime) {
- pause();
- didEnd();
- }
}
bool MediaPlayerPrivate::paused() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return true;
return [m_qtMovie.get() rate] == 0;
}
bool MediaPlayerPrivate::seeking() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return false;
return m_seekTo >= 0;
}
IntSize MediaPlayerPrivate::naturalSize() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return IntSize();
return IntSize([[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]);
}
bool MediaPlayerPrivate::hasVideo() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return false;
return [[m_qtMovie.get() attributeForKey:QTMovieHasVideoAttribute] boolValue];
}
void MediaPlayerPrivate::setVolume(float volume)
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return;
[m_qtMovie.get() setVolume:volume];
}
void MediaPlayerPrivate::setRate(float rate)
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return;
if (!paused())
[m_qtMovie.get() setRate:rate];
@@ -576,7 +572,7 @@ void MediaPlayerPrivate::setRate(float rate)
int MediaPlayerPrivate::dataRate() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return 0;
return wkQTMovieDataRate(m_qtMovie.get());
}
@@ -596,7 +592,7 @@ float MediaPlayerPrivate::maxTimeSeekable() const
float MediaPlayerPrivate::maxTimeLoaded() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return 0;
return wkQTMovieMaxTimeLoaded(m_qtMovie.get());
}
@@ -616,7 +612,7 @@ bool MediaPlayerPrivate::totalBytesKnown() const
unsigned MediaPlayerPrivate::totalBytes() const
{
- if (!m_qtMovie)
+ if (!metaDataAvailable())
return 0;
return [[m_qtMovie.get() attributeForKey:QTMovieDataSizeAttribute] intValue];
}
@@ -639,52 +635,66 @@ void MediaPlayerPrivate::updateStates()
MediaPlayer::ReadyState oldReadyState = m_readyState;
long loadState = m_qtMovie ? [[m_qtMovie.get() attributeForKey:QTMovieLoadStateAttribute] longValue] : static_cast<long>(QTMovieLoadStateError);
-
- if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData && !m_player->inMediaDocument()) {
- unsigned enabledTrackCount;
- disableUnsupportedTracks(enabledTrackCount);
- // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692>
- if (!enabledTrackCount)
+
+ if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata && !m_player->inMediaDocument()) {
+ disableUnsupportedTracks();
+ if (!m_enabledTrackCount)
loadState = QTMovieLoadStateError;
}
- // "Loaded" is reserved for fully buffered movies, never the case when streaming
if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {
- if (m_networkState < MediaPlayer::Loaded)
- m_networkState = MediaPlayer::Loaded;
- m_readyState = MediaPlayer::CanPlayThrough;
+ // "Loaded" is reserved for fully buffered movies, never the case when streaming
+ m_networkState = MediaPlayer::Loaded;
+ m_readyState = MediaPlayer::HaveEnoughData;
} else if (loadState >= QTMovieLoadStatePlaythroughOK) {
- if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
- m_networkState = MediaPlayer::LoadedFirstFrame;
- m_readyState = MediaPlayer::CanPlayThrough;
+ m_readyState = MediaPlayer::HaveFutureData;
+ m_networkState = MediaPlayer::Loading;
} else if (loadState >= QTMovieLoadStatePlayable) {
- if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
- m_networkState = MediaPlayer::LoadedFirstFrame;
// FIXME: This might not work correctly in streaming case, <rdar://problem/5693967>
- m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::CanPlay : MediaPlayer::DataUnavailable;
+ m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
+ m_networkState = MediaPlayer::Loading;
} else if (loadState >= QTMovieLoadStateLoaded) {
- if (m_networkState < MediaPlayer::LoadedMetaData)
- m_networkState = MediaPlayer::LoadedMetaData;
- m_readyState = MediaPlayer::DataUnavailable;
+ m_readyState = MediaPlayer::HaveMetadata;
+ m_networkState = MediaPlayer::Loading;
} else if (loadState > QTMovieLoadStateError) {
- if (m_networkState < MediaPlayer::Loading)
- m_networkState = MediaPlayer::Loading;
- m_readyState = MediaPlayer::DataUnavailable;
+ m_readyState = MediaPlayer::HaveNothing;
+ m_networkState = MediaPlayer::Loading;
} else {
- m_networkState = MediaPlayer::LoadFailed;
- m_readyState = MediaPlayer::DataUnavailable;
+ float loaded = maxTimeLoaded();
+
+ if (!loaded)
+ m_readyState = MediaPlayer::HaveNothing;
+
+ if (!m_enabledTrackCount)
+ m_networkState = MediaPlayer::FormatError;
+ else {
+ // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692>
+ if (loaded > 0)
+ m_networkState = MediaPlayer::DecodeError;
+ else
+ m_readyState = MediaPlayer::HaveNothing;
+ }
}
if (seeking())
- m_readyState = MediaPlayer::DataUnavailable;
-
+ m_readyState = MediaPlayer::HaveNothing;
+
if (m_networkState != oldNetworkState)
m_player->networkStateChanged();
if (m_readyState != oldReadyState)
m_player->readyStateChanged();
- if (loadState >= QTMovieLoadStateLoaded && oldNetworkState < MediaPlayer::LoadedMetaData && m_player->visible())
+ if (loadState >= QTMovieLoadStateLoaded && oldReadyState < MediaPlayer::HaveMetadata && m_player->visible())
setUpVideoRendering();
+
+ if (loadState >= QTMovieLoadStateLoaded) {
+ float dur = duration();
+ if (dur != m_duration) {
+ if (m_duration != -1.0f)
+ m_player->durationChanged();
+ m_duration = dur;
+ }
+ }
}
void MediaPlayerPrivate::loadStateChanged()
@@ -695,10 +705,12 @@ void MediaPlayerPrivate::loadStateChanged()
void MediaPlayerPrivate::rateChanged()
{
updateStates();
+ m_player->rateChanged();
}
void MediaPlayerPrivate::sizeChanged()
{
+ m_player->sizeChanged();
}
void MediaPlayerPrivate::timeChanged()
@@ -709,7 +721,6 @@ void MediaPlayerPrivate::timeChanged()
void MediaPlayerPrivate::didEnd()
{
- m_endPointTimer.stop();
m_startedPlaying = false;
#if DRAW_FRAME_RATE
m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate];
@@ -718,18 +729,19 @@ void MediaPlayerPrivate::didEnd()
m_player->timeChanged();
}
-void MediaPlayerPrivate::setRect(const IntRect& r)
+void MediaPlayerPrivate::setSize(const IntSize& size)
{
if (!m_qtMovieView)
return;
+ m_rect.setSize(size);
if (m_player->inMediaDocument())
// We need the QTMovieView to be placed in the proper location for document mode.
- [m_qtMovieView.get() setFrame:r];
+ [m_qtMovieView.get() setFrame:m_rect];
else {
// We don't really need the QTMovieView in any specific location so let's just get it out of the way
// where it won't intercept events or try to bring up the context menu.
- IntRect farAwayButCorrectSize(r);
+ IntRect farAwayButCorrectSize(m_rect);
farAwayButCorrectSize.move(-1000000, -1000000);
[m_qtMovieView.get() setFrame:farAwayButCorrectSize];
}
@@ -740,7 +752,7 @@ void MediaPlayerPrivate::setVisible(bool b)
if (m_visible != b) {
m_visible = b;
if (b) {
- if (m_networkState >= MediaPlayer::LoadedMetaData)
+ if (m_readyState >= MediaPlayer::HaveMetadata)
setUpVideoRendering();
} else
tearDownVideoRendering();
@@ -789,13 +801,19 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r)
[NSGraphicsContext setCurrentContext:newContext];
[(id<WebKitVideoRenderingDetails>)qtVideoRenderer drawInRect:paintRect];
[NSGraphicsContext restoreGraphicsState];
- } else
+ } else {
+ if (m_player->inMediaDocument() && r != m_rect) {
+ // the QTMovieView needs to be placed in the proper location for document mode
+ m_rect = r;
+ [view setFrame:m_rect];
+ }
[view displayRectIgnoringOpacity:paintRect inContext:newContext];
+ }
#if DRAW_FRAME_RATE
// Draw the frame rate only after having played more than 10 frames.
if (m_frameCountWhilePlaying > 10) {
- Frame* frame = m_player->m_frameView ? m_player->m_frameView->frame() : NULL;
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;
Document* document = frame ? frame->document() : NULL;
RenderObject* renderer = document ? document->renderer() : NULL;
RenderStyle* styleToUse = renderer ? renderer->style() : NULL;
@@ -821,22 +839,42 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r)
[m_objcObserver.get() setDelayCallbacks:NO];
}
-void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+static HashSet<String> mimeTypeCache()
{
- NSArray* fileTypes = [QTMovie movieFileTypes:QTIncludeCommonTypes];
- int count = [fileTypes count];
- for (int n = 0; n < count; n++) {
- CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]);
- RetainPtr<CFStringRef> uti(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL));
- if (!uti)
- continue;
- RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType));
- if (!mime)
- continue;
- types.add(mime.get());
+ DEFINE_STATIC_LOCAL(HashSet<String>, cache, ());
+ static bool typeListInitialized = false;
+
+ if (!typeListInitialized) {
+ NSArray* fileTypes = [QTMovie movieFileTypes:QTIncludeCommonTypes];
+ int count = [fileTypes count];
+ for (int n = 0; n < count; n++) {
+ CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]);
+ RetainPtr<CFStringRef> uti(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL));
+ if (!uti)
+ continue;
+ RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType));
+ if (!mime)
+ continue;
+ cache.add(mime.get());
+ }
+ typeListInitialized = true;
}
-}
+ return cache;
+}
+
+void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+{
+ types = mimeTypeCache();
+}
+
+MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
+{
+ // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an
+ // extended MIME type yet
+ return mimeTypeCache().contains(type) ? (codecs && !codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
+}
+
bool MediaPlayerPrivate::isAvailable()
{
#ifdef BUILDING_ON_TIGER
@@ -858,10 +896,10 @@ bool MediaPlayerPrivate::isAvailable()
#endif
}
-void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount)
+void MediaPlayerPrivate::disableUnsupportedTracks()
{
if (!m_qtMovie) {
- enabledTrackCount = 0;
+ m_enabledTrackCount = 0;
return;
}
@@ -872,6 +910,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount)
allowedTrackTypes->add(QTMediaTypeSound);
allowedTrackTypes->add(QTMediaTypeText);
allowedTrackTypes->add(QTMediaTypeBase);
+ allowedTrackTypes->add(QTMediaTypeMPEG);
allowedTrackTypes->add("clcp");
allowedTrackTypes->add("sbtl");
}
@@ -879,7 +918,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount)
NSArray *tracks = [m_qtMovie.get() tracks];
unsigned trackCount = [tracks count];
- enabledTrackCount = trackCount;
+ m_enabledTrackCount = trackCount;
for (unsigned trackIndex = 0; trackIndex < trackCount; trackIndex++) {
// Grab the track at the current index. If there isn't one there, then
// we can move onto the next one.
@@ -907,7 +946,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount)
if (!allowedTrackTypes->contains(mediaType)) {
// If this track type is not allowed, then we need to disable it.
[track setEnabled:NO];
- --enabledTrackCount;
+ --m_enabledTrackCount;
}
// Disable chapter tracks. These are most likely to lead to trouble, as
@@ -939,7 +978,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount)
// Disable the evil, evil track.
[chapterTrack setEnabled:NO];
- --enabledTrackCount;
+ --m_enabledTrackCount;
}
}
@@ -947,7 +986,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount)
@implementation WebCoreMovieObserver
-- (id)initWithCallback:(MediaPlayerPrivate *)callback
+- (id)initWithCallback:(MediaPlayerPrivate*)callback
{
m_callback = callback;
return [super init];
diff --git a/WebCore/platform/graphics/mac/MediaPlayerProxy.h b/WebCore/platform/graphics/mac/MediaPlayerProxy.h
new file mode 100644
index 0000000..6060484
--- /dev/null
+++ b/WebCore/platform/graphics/mac/MediaPlayerProxy.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaPlayerProxy_h
+#define MediaPlayerProxy_h
+
+#ifdef __OBJC__
+@class WebMediaPlayerProxy;
+#else
+class WebMediaPlayerProxy;
+#endif
+
+enum MediaPlayerProxyNotificationType {
+
+ MediaPlayerNotificationMediaValidated = 1,
+ MediaPlayerNotificationMediaFailedToValidate,
+
+ MediaPlayerNotificationStartUsingNetwork,
+ MediaPlayerNotificationStopUsingNetwork,
+
+ MediaPlayerNotificationEnteredFullScreen,
+ MediaPlayerNotificationExitedFullScreen,
+
+ MediaPlayerNotificationReadyForInspection,
+ MediaPlayerNotificationReadyForPlayback,
+ MediaPlayerNotificationDidPlayToTheEnd,
+
+ MediaPlayerNotificationPlaybackFailed,
+
+ MediaPlayerNotificationStreamLikelyToKeepUp,
+ MediaPlayerNotificationStreamUnlikelyToKeepUp,
+ MediaPlayerNotificationStreamBufferFull,
+ MediaPlayerNotificationStreamRanDry,
+ MediaPlayerNotificationFileLoaded,
+
+ MediaPlayerNotificationSizeDidChange,
+ MediaPlayerNotificationVolumeDidChange,
+ MediaPlayerNotificationMutedDidChange,
+ MediaPlayerNotificationTimeJumped,
+
+ MediaPlayerNotificationPlayPauseButtonPressed,
+};
+
+#ifdef __OBJC__
+@interface NSObject (WebMediaPlayerProxy)
+
+- (int)_interfaceVersion;
+
+- (void)_disconnect;
+
+- (void)_load:(NSURL *)url;
+- (void)_cancelLoad;
+
+- (void)_setPoster:(NSURL *)url;
+
+- (void)_play;
+- (void)_pause;
+
+- (NSSize)_naturalSize;
+
+- (BOOL)_hasVideo;
+- (BOOL)_hasAudio;
+
+- (NSTimeInterval)_duration;
+
+- (double)_currentTime;
+- (void)_setCurrentTime:(double)time;
+- (BOOL)_seeking;
+
+- (void)_setEndTime:(double)time;
+
+- (float)_rate;
+- (void)_setRate:(float)rate;
+
+- (float)_volume;
+- (void)_setVolume:(float)newVolume;
+
+- (BOOL)_muted;
+- (void)_setMuted:(BOOL)muted;
+
+- (float)_maxTimeBuffered;
+- (float)_maxTimeSeekable;
+- (NSArray *)_bufferedTimeRanges;
+
+- (int)_dataRate;
+
+- (BOOL)_totalBytesKnown;
+- (unsigned)_totalBytes;
+- (unsigned)_bytesLoaded;
+
+- (NSArray *)_mimeTypes;
+
+@end
+#endif
+
+#endif
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 30dbf97..a3c10fa 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -38,6 +38,7 @@
#import "FontDescription.h"
#import "SharedBuffer.h"
#import "WebCoreSystemInterface.h"
+#import <AppKit/AppKit.h>
#import <ApplicationServices/ApplicationServices.h>
#import <float.h>
#import <unicode/uchar.h>
diff --git a/WebCore/platform/graphics/mac/WebLayer.h b/WebCore/platform/graphics/mac/WebLayer.h
new file mode 100644
index 0000000..b8b46ed
--- /dev/null
+++ b/WebCore/platform/graphics/mac/WebLayer.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebLayer_h
+#define WebLayer_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#import <QuartzCore/QuartzCore.h>
+
+namespace WebCore {
+ class GraphicsLayer;
+}
+
+// Category implemented by WebLayer and WebTiledLayer.
+@interface CALayer(WebLayerAdditions)
+
+- (void)setLayerOwner:(WebCore::GraphicsLayer*)layer;
+- (WebCore::GraphicsLayer*)layerOwner;
+
+@end
+
+@interface WebLayer : CALayer
+{
+ WebCore::GraphicsLayer* m_layerOwner;
+}
+
+// Class method allows us to share implementation across TiledLayerMac and WebLayer
++ (void)drawContents:(WebCore::GraphicsLayer*)layerContents ofLayer:(CALayer*)layer intoContext:(CGContextRef)context;
+
+@end
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // WebLayer_h
diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm
new file mode 100644
index 0000000..267b5bc
--- /dev/null
+++ b/WebCore/platform/graphics/mac/WebLayer.mm
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#import "WebLayer.h"
+
+#import "GraphicsContext.h"
+#import "GraphicsLayer.h"
+#import <QuartzCore/QuartzCore.h>
+#import "WebCoreTextRenderer.h"
+#import <wtf/UnusedParam.h>
+
+using namespace WebCore;
+
+@implementation WebLayer
+
++ (void)drawContents:(WebCore::GraphicsLayer*)layerContents ofLayer:(CALayer*)layer intoContext:(CGContextRef)context
+{
+ UNUSED_PARAM(layer);
+ CGContextSaveGState(context);
+
+ if (layerContents && layerContents->client()) {
+ [NSGraphicsContext saveGraphicsState];
+
+ // Set up an NSGraphicsContext for the context, so that parts of AppKit that rely on
+ // the current NSGraphicsContext (e.g. NSCell drawing) get the right one.
+ NSGraphicsContext* layerContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:YES];
+ [NSGraphicsContext setCurrentContext:layerContext];
+
+ GraphicsContext graphicsContext(context);
+
+ // It's important to get the clip from the context, because it may be significantly
+ // smaller than the layer bounds (e.g. tiled layers)
+ CGRect clipBounds = CGContextGetClipBoundingBox(context);
+ IntRect clip(enclosingIntRect(clipBounds));
+ layerContents->paintGraphicsLayerContents(graphicsContext, clip);
+
+ [NSGraphicsContext restoreGraphicsState];
+ }
+#ifndef NDEBUG
+ else {
+ ASSERT_NOT_REACHED();
+
+ // FIXME: ideally we'd avoid calling -setNeedsDisplay on a layer that is a plain color,
+ // so CA never makes backing store for it (which is what -setNeedsDisplay will do above).
+ CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 1.0f);
+ CGRect aBounds = [layer bounds];
+ CGContextFillRect(context, aBounds);
+ }
+#endif
+
+ CGContextRestoreGState(context);
+
+#ifndef NDEBUG
+ if (layerContents && layerContents->showRepaintCounter()) {
+ bool isTiledLayer = [layer isKindOfClass:[CATiledLayer class]];
+
+ char text[16]; // that's a lot of repaints
+ snprintf(text, sizeof(text), "%d", layerContents->incrementRepaintCount());
+
+ CGAffineTransform a = CGContextGetCTM(context);
+
+ CGContextSaveGState(context);
+ if (isTiledLayer)
+ CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 0.8f);
+ else
+ CGContextSetRGBFillColor(context, 1.0f, 0.0f, 0.0f, 0.8f);
+
+ CGRect aBounds = [layer bounds];
+
+ aBounds.size.width = 10 + 12 * strlen(text);
+ aBounds.size.height = 25;
+ CGContextFillRect(context, aBounds);
+
+ CGContextSetRGBFillColor(context, 0.0f, 0.0f, 0.0f, 1.0f);
+
+ CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0f, -1.0f));
+ CGContextSelectFont(context, "Helvetica", 25, kCGEncodingMacRoman);
+ CGContextShowTextAtPoint(context, aBounds.origin.x + 3.0f, aBounds.origin.y + 20.0f, text, strlen(text));
+
+ CGContextRestoreGState(context);
+ }
+#endif
+}
+
+// Disable default animations
+- (id<CAAction>)actionForKey:(NSString *)key
+{
+ UNUSED_PARAM(key);
+ return nil;
+}
+
+// Implement this so presentationLayer can get our custom attributes
+- (id)initWithLayer:(id)layer
+{
+ if ((self = [super initWithLayer:layer]))
+ m_layerOwner = [(WebLayer*)layer layerOwner];
+
+ return self;
+}
+
+- (void)setNeedsDisplay
+{
+ if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent())
+ [super setNeedsDisplay];
+}
+
+- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
+{
+ if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent()) {
+ [super setNeedsDisplayInRect:dirtyRect];
+
+#ifndef NDEBUG
+ if (m_layerOwner->showRepaintCounter()) {
+ CGRect bounds = [self bounds];
+ [super setNeedsDisplayInRect:CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25)];
+ }
+#endif
+ }
+}
+
+- (void)drawInContext:(CGContextRef)context
+{
+ [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:context];
+}
+
+@end // implementation WebLayer
+
+#pragma mark -
+
+@implementation WebLayer(WebLayerAdditions)
+
+- (void)setLayerOwner:(GraphicsLayer*)aLayer
+{
+ m_layerOwner = aLayer;
+}
+
+- (GraphicsLayer*)layerOwner
+{
+ return m_layerOwner;
+}
+
+@end
+
+#pragma mark -
+
+#ifndef NDEBUG
+
+@implementation CALayer(ExtendedDescription)
+
+- (NSString*)_descriptionWithPrefix:(NSString*)inPrefix
+{
+ CGRect aBounds = [self bounds];
+ CGPoint aPos = [self position];
+ CATransform3D t = [self transform];
+
+ NSString* selfString = [NSString stringWithFormat:@"%@<%@ 0x%08x> \"%@\" bounds(%.1f, %.1f, %.1f, %.1f) pos(%.1f, %.1f), sublayers=%d masking=%d",
+ inPrefix,
+ [self class],
+ self,
+ [self name],
+ aBounds.origin.x, aBounds.origin.y, aBounds.size.width, aBounds.size.height,
+ aPos.x, aPos.y,
+ [[self sublayers] count],
+ [self masksToBounds]];
+
+ NSMutableString* curDesc = [NSMutableString stringWithString:selfString];
+
+ if ([[self sublayers] count] > 0)
+ [curDesc appendString:@"\n"];
+
+ NSString* sublayerPrefix = [inPrefix stringByAppendingString:@"\t"];
+
+ NSEnumerator* sublayersEnum = [[self sublayers] objectEnumerator];
+ CALayer* curLayer;
+ while ((curLayer = [sublayersEnum nextObject]))
+ [curDesc appendString:[curLayer _descriptionWithPrefix:sublayerPrefix]];
+
+ if ([[self sublayers] count] == 0)
+ [curDesc appendString:@"\n"];
+
+ return curDesc;
+}
+
+- (NSString*)extendedDescription
+{
+ return [self _descriptionWithPrefix:@""];
+}
+
+@end // implementation WebLayer(ExtendedDescription)
+
+#endif // NDEBUG
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.h b/WebCore/platform/graphics/mac/WebTiledLayer.h
new file mode 100644
index 0000000..1c9144d
--- /dev/null
+++ b/WebCore/platform/graphics/mac/WebTiledLayer.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebTiledLayer_h
+#define WebTiledLayer_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#import "WebLayer.h"
+
+@interface WebTiledLayer : CATiledLayer
+{
+ WebCore::GraphicsLayer* m_layerOwner;
+}
+
+// implements WebLayerAdditions
+
+@end
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // WebTiledLayer_h
+
diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.mm b/WebCore/platform/graphics/mac/WebTiledLayer.mm
new file mode 100644
index 0000000..1dd00ba
--- /dev/null
+++ b/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#import "WebTiledLayer.h"
+
+#import "GraphicsContext.h"
+#import "GraphicsLayer.h"
+#import <wtf/UnusedParam.h>
+
+using namespace WebCore;
+
+@implementation WebTiledLayer
+
+// Set a zero duration for the fade in of tiles
++ (CFTimeInterval)fadeDuration
+{
+ return 0;
+}
+
+// Make sure that tiles are drawn on the main thread
++ (BOOL)shouldDrawOnMainThread
+{
+ return YES;
+}
+
+// Disable default animations
+- (id<CAAction>)actionForKey:(NSString *)key
+{
+ UNUSED_PARAM(key);
+ return nil;
+}
+
+// Implement this so presentationLayer can get our custom attributes
+- (id)initWithLayer:(id)layer
+{
+ if ((self = [super initWithLayer:layer]))
+ m_layerOwner = [(WebLayer*)layer layerOwner];
+
+ return self;
+}
+
+- (void)setNeedsDisplay
+{
+ if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent())
+ [super setNeedsDisplay];
+}
+
+- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
+{
+ if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent()) {
+ [super setNeedsDisplayInRect:dirtyRect];
+
+#ifndef NDEBUG
+ if (m_layerOwner->showRepaintCounter()) {
+ CGRect bounds = [self bounds];
+ [super setNeedsDisplayInRect:CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25)];
+ }
+#endif
+ }
+}
+
+- (void)drawInContext:(CGContextRef)ctx
+{
+ [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:ctx];
+}
+
+@end // implementation WebTiledLayer
+
+#pragma mark -
+
+@implementation WebTiledLayer(LayerMacAdditions)
+
+- (void)setLayerOwner:(GraphicsLayer*)aLayer
+{
+ m_layerOwner = aLayer;
+}
+
+- (GraphicsLayer*)layerOwner
+{
+ return m_layerOwner;
+}
+
+@end
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/win/OpenTypeUtilities.cpp b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
index 1951320..16c3c00 100644
--- a/WebCore/platform/graphics/win/OpenTypeUtilities.cpp
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
@@ -49,9 +49,9 @@ struct EOTPrefix {
unsigned fontDataSize;
unsigned version;
unsigned flags;
- UInt8 fontPANOSE[10];
- UInt8 charset;
- UInt8 italic;
+ uint8_t fontPANOSE[10];
+ uint8_t charset;
+ uint8_t italic;
unsigned weight;
unsigned short fsType;
unsigned short magicNumber;
@@ -69,6 +69,15 @@ struct TableDirectoryEntry {
BigEndianULong length;
};
+#if !PLATFORM(CG)
+// Fixed type is not defined on non-CG platforms. |version| in sfntHeader
+// and headTable and |fontRevision| in headTable are of Fixed, but they're
+// not actually refered to anywhere. Therefore, we just have to match
+// the size (4 bytes). For the definition of Fixed type, see
+// http://developer.apple.com/documentation/mac/Legacy/GXEnvironment/GXEnvironment-356.html#HEADING356-6.
+typedef int32_t Fixed;
+#endif
+
struct sfntHeader {
Fixed version;
BigEndianUShort numTables;
@@ -95,9 +104,9 @@ struct OS2Table {
BigEndianUShort strikeoutSize;
BigEndianUShort strikeoutPosition;
BigEndianUShort familyClass;
- UInt8 panose[10];
+ uint8_t panose[10];
BigEndianULong unicodeRange[4];
- UInt8 vendID[4];
+ uint8_t vendID[4];
BigEndianUShort fsSelection;
BigEndianUShort firstCharIndex;
BigEndianUShort lastCharIndex;
@@ -152,7 +161,7 @@ struct nameTable {
#pragma pack()
-static void appendBigEndianStringToEOTHeader(Vector<UInt8, 512>& eotHeader, const BigEndianUShort* string, unsigned short length)
+static void appendBigEndianStringToEOTHeader(Vector<uint8_t, 512>& eotHeader, const BigEndianUShort* string, unsigned short length)
{
size_t size = eotHeader.size();
eotHeader.resize(size + length + 2 * sizeof(unsigned short));
@@ -165,7 +174,7 @@ static void appendBigEndianStringToEOTHeader(Vector<UInt8, 512>& eotHeader, cons
dst[i] = 0;
}
-bool getEOTHeader(SharedBuffer* fontData, Vector<UInt8, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength)
+bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength)
{
overlayDst = 0;
overlaySrc = 0;
@@ -311,7 +320,7 @@ bool getEOTHeader(SharedBuffer* fontData, Vector<UInt8, 512>& eotHeader, size_t&
appendBigEndianStringToEOTHeader(eotHeader, fullName, fullNameLength);
unsigned short padding = 0;
- eotHeader.append(reinterpret_cast<UInt8*>(&padding), sizeof(padding));
+ eotHeader.append(reinterpret_cast<uint8_t*>(&padding), sizeof(padding));
prefix->eotSize = eotHeader.size() + fontData->size();
diff --git a/WebCore/platform/graphics/win/OpenTypeUtilities.h b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
index ab35551..a67ffc7 100644
--- a/WebCore/platform/graphics/win/OpenTypeUtilities.h
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.h
@@ -33,7 +33,7 @@ namespace WebCore {
class SharedBuffer;
-bool getEOTHeader(SharedBuffer* fontData, Vector<UInt8, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength);
+bool getEOTHeader(SharedBuffer* fontData, Vector<uint8_t, 512>& eotHeader, size_t& overlayDst, size_t& overlaySrc, size_t& overlayLength);
HANDLE renameAndActivateFont(SharedBuffer*, const String&);
} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
index ea51fe8..f0dd3ea 100644
--- a/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
+++ b/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp
@@ -61,12 +61,14 @@ FontPlatformData::FontPlatformData(const QFont& font, bool bold)
{
}
+#if ENABLE(SVG_FONTS)
FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
: m_size(size)
, m_bold(bold)
, m_oblique(oblique)
{
}
+#endif
FontPlatformData::FontPlatformData()
: m_size(0.0f)
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index deeea99..9ed5915 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -1,6 +1,7 @@
/*
Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
Copyright (C) 2008 Holger Hans Peter Freyther
+ Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -24,11 +25,18 @@
#include "FontFallbackList.h"
#include "FontSelector.h"
+#include "Gradient.h"
#include "GraphicsContext.h"
-#include <QTextLayout>
-#include <QPainter>
-#include <QFontMetrics>
+#include "Pattern.h"
+#include "TransformationMatrix.h"
+
+#include <QBrush>
#include <QFontInfo>
+#include <QFontMetrics>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPen>
+#include <QTextLayout>
#include <qalgorithms.h>
#include <qdebug.h>
@@ -37,20 +45,27 @@
#if QT_VERSION >= 0x040400
namespace WebCore {
-static QString qstring(const TextRun& run)
+static const QString qstring(const TextRun& run)
+{
+ //We don't detach
+ return QString::fromRawData((const QChar *)run.characters(), run.length());
+}
+
+static const QString fixSpacing(const QString &string)
{
- QString string((QChar *)run.characters(), run.length());
- QChar *uc = string.data();
+ //Only detach if we're actually changing something
+ QString possiblyDetached = string;
for (int i = 0; i < string.length(); ++i) {
- if (Font::treatAsSpace(uc[i].unicode()))
- uc[i] = 0x20;
- else if (Font::treatAsZeroWidthSpace(uc[i].unicode()))
- uc[i] = 0x200c;
+ const QChar c = string.at(i);
+ if (c.unicode() != 0x20 && Font::treatAsSpace(c.unicode())) {
+ possiblyDetached[i] = 0x20; //detach
+ } else if (c.unicode() != 0x200c && Font::treatAsZeroWidthSpace(c.unicode())) {
+ possiblyDetached[i] = 0x200c; //detach
+ }
}
- return string;
+ return possiblyDetached;
}
-
static QTextLine setupLayout(QTextLayout* layout, const TextRun& style)
{
int flags = style.rtl() ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
@@ -72,10 +87,32 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float
to = run.length();
QPainter *p = ctx->platformContext();
- Color color = ctx->fillColor();
- p->setPen(QColor(color));
- QString string = qstring(run);
+ if (ctx->textDrawingMode() & cTextFill) {
+ if (ctx->fillGradient()) {
+ QBrush brush(*ctx->fillGradient()->platformGradient());
+ brush.setTransform(ctx->fillGradient()->gradientSpaceTransform());
+ p->setPen(QPen(brush, 0));
+ } else if (ctx->fillPattern()) {
+ TransformationMatrix affine;
+ p->setPen(QPen(QBrush(ctx->fillPattern()->createPlatformPattern(affine)), 0));
+ } else
+ p->setPen(QColor(ctx->fillColor()));
+ }
+
+ if (ctx->textDrawingMode() & cTextStroke) {
+ if (ctx->strokeGradient()) {
+ QBrush brush(*ctx->strokeGradient()->platformGradient());
+ brush.setTransform(ctx->strokeGradient()->gradientSpaceTransform());
+ p->setPen(QPen(brush, ctx->strokeThickness()));
+ } else if (ctx->strokePattern()) {
+ TransformationMatrix affine;
+ p->setPen(QPen(QBrush(ctx->strokePattern()->createPlatformPattern(affine)), ctx->strokeThickness()));
+ } else
+ p->setPen(QPen(QColor(ctx->strokeColor()), ctx->strokeThickness()));
+ }
+
+ const QString string = fixSpacing(qstring(run));
// text shadow
IntSize shadowSize;
@@ -137,14 +174,20 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float
p->drawText(pt, string, flags, run.padding());
p->restore();
}
- p->drawText(pt, string, flags, run.padding());
+ if (ctx->textDrawingMode() & cTextStroke) {
+ QPainterPath path;
+ path.addText(pt, font(), string);
+ p->strokePath(path, p->pen());
+ }
+ if (ctx->textDrawingMode() & cTextFill)
+ p->drawText(pt, string, flags, run.padding());
}
float Font::floatWidthForComplexText(const TextRun& run) const
{
if (!run.length())
return 0;
- QString string = qstring(run);
+ const QString string = fixSpacing(qstring(run));
QTextLayout layout(string, font());
QTextLine line = setupLayout(&layout, run);
int w = int(line.naturalTextWidth());
@@ -157,7 +200,7 @@ float Font::floatWidthForComplexText(const TextRun& run) const
int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool includePartialGlyphs) const
{
- QString string = qstring(run);
+ const QString string = fixSpacing(qstring(run));
QTextLayout layout(string, font());
QTextLine line = setupLayout(&layout, run);
return line.xToCursor(position);
@@ -165,7 +208,7 @@ int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& pt, int h, int from, int to) const
{
- QString string = qstring(run);
+ const QString string = fixSpacing(qstring(run));
QTextLayout layout(string, font());
QTextLine line = setupLayout(&layout, run);
diff --git a/WebCore/platform/graphics/qt/GradientQt.cpp b/WebCore/platform/graphics/qt/GradientQt.cpp
index a0edf8d..1e71f58 100644
--- a/WebCore/platform/graphics/qt/GradientQt.cpp
+++ b/WebCore/platform/graphics/qt/GradientQt.cpp
@@ -28,9 +28,10 @@
#include "Gradient.h"
#include "CSSParser.h"
-#include "NotImplemented.h"
+#include "GraphicsContext.h"
#include <QGradient>
+#include <QPainter>
namespace WebCore {
@@ -66,12 +67,24 @@ QGradient* Gradient::platformGradient()
++stopIterator;
}
+ switch(m_spreadMethod) {
+ case SpreadMethodPad:
+ m_gradient->setSpread(QGradient::PadSpread);
+ break;
+ case SpreadMethodReflect:
+ m_gradient->setSpread(QGradient::ReflectSpread);
+ break;
+ case SpreadMethodRepeat:
+ m_gradient->setSpread(QGradient::RepeatSpread);
+ break;
+ }
+
return m_gradient;
}
void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
{
- notImplemented();
+ context->platformContext()->fillRect(rect, *platformGradient());
}
} //namespace
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 2e7cdcb..ccf4b06 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -51,6 +51,7 @@
#include "Pen.h"
#include "NotImplemented.h"
+#include <QBrush>
#include <QDebug>
#include <QGradient>
#include <QPainter>
@@ -152,22 +153,6 @@ static Qt::PenStyle toQPenStyle(StrokeStyle style)
return Qt::NoPen;
}
-static inline QGradient applySpreadMethod(QGradient gradient, GradientSpreadMethod spreadMethod)
-{
- switch (spreadMethod) {
- case SpreadMethodPad:
- gradient.setSpread(QGradient::PadSpread);
- break;
- case SpreadMethodReflect:
- gradient.setSpread(QGradient::ReflectSpread);
- break;
- case SpreadMethodRepeat:
- gradient.setSpread(QGradient::RepeatSpread);
- break;
- }
- return gradient;
-}
-
struct TransparencyLayer
{
TransparencyLayer(const QPainter* p, const QRect &rect)
@@ -282,7 +267,11 @@ PlatformGraphicsContext* GraphicsContext::platformContext() const
TransformationMatrix GraphicsContext::getCTM() const
{
- return platformContext()->combinedMatrix();
+ QTransform matrix(platformContext()->combinedTransform());
+ return TransformationMatrix(matrix.m11(), matrix.m12(), 0, matrix.m13(),
+ matrix.m21(), matrix.m22(), 0, matrix.m23(),
+ 0, 0, 1, 0,
+ matrix.m31(), matrix.m32(), 0, matrix.m33());
}
void GraphicsContext::savePlatformState()
@@ -295,7 +284,7 @@ void GraphicsContext::restorePlatformState()
m_data->p()->restore();
if (!m_data->currentPath.isEmpty() && m_common->state.pathTransform.isInvertible()) {
- QMatrix matrix = m_common->state.pathTransform;
+ QTransform matrix = m_common->state.pathTransform;
m_data->currentPath = m_data->currentPath * matrix;
}
}
@@ -458,13 +447,21 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
if (paintingDisabled())
return;
+ StrokeStyle style = strokeStyle();
+ Color color = strokeColor();
+ if (style == NoStroke || !color.alpha())
+ return;
+
+ float width = strokeThickness();
+
FloatPoint p1 = point1;
FloatPoint p2 = point2;
+ bool isVerticalLine = (p1.x() == p2.x());
QPainter *p = m_data->p();
const bool antiAlias = p->testRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines);
- adjustLineToPixelBoundaries(p1, p2, strokeThickness(), strokeStyle());
+ adjustLineToPixelBoundaries(p1, p2, width, style);
IntSize shadowSize;
int shadowBlur;
@@ -477,8 +474,76 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
p->restore();
}
+ int patWidth = 0;
+ switch (style) {
+ case NoStroke:
+ case SolidStroke:
+ break;
+ case DottedStroke:
+ patWidth = (int)width;
+ break;
+ case DashedStroke:
+ patWidth = 3 * (int)width;
+ break;
+ }
+
+ if (patWidth) {
+ p->save();
+
+ // Do a rect fill of our endpoints. This ensures we always have the
+ // appearance of being a border. We then draw the actual dotted/dashed line.
+ if (isVerticalLine) {
+ p->fillRect(FloatRect(p1.x() - width / 2, p1.y() - width, width, width), QColor(color));
+ p->fillRect(FloatRect(p2.x() - width / 2, p2.y(), width, width), QColor(color));
+ } else {
+ p->fillRect(FloatRect(p1.x() - width, p1.y() - width / 2, width, width), QColor(color));
+ p->fillRect(FloatRect(p2.x(), p2.y() - width / 2, width, width), QColor(color));
+ }
+
+ // Example: 80 pixels with a width of 30 pixels.
+ // Remainder is 20. The maximum pixels of line we could paint
+ // will be 50 pixels.
+ int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*(int)width;
+ int remainder = distance % patWidth;
+ int coverage = distance - remainder;
+ int numSegments = coverage / patWidth;
+
+ float patternOffset = 0.0f;
+ // Special case 1px dotted borders for speed.
+ if (patWidth == 1)
+ patternOffset = 1.0f;
+ else {
+ bool evenNumberOfSegments = numSegments % 2 == 0;
+ if (remainder)
+ evenNumberOfSegments = !evenNumberOfSegments;
+ if (evenNumberOfSegments) {
+ if (remainder) {
+ patternOffset += patWidth - remainder;
+ patternOffset += remainder / 2;
+ } else
+ patternOffset = patWidth / 2;
+ } else {
+ if (remainder)
+ patternOffset = (patWidth - remainder)/2;
+ }
+ }
+
+ QVector<qreal> dashes;
+ dashes << qreal(patWidth) / width << qreal(patWidth) / width;
+
+ QPen pen = p->pen();
+ pen.setWidthF(width);
+ pen.setCapStyle(Qt::FlatCap);
+ pen.setDashPattern(dashes);
+ pen.setDashOffset(patternOffset / width);
+ p->setPen(pen);
+ }
+
p->drawLine(p1, p2);
+ if (patWidth)
+ p->restore();
+
p->setRenderHint(QPainter::Antialiasing, antiAlias);
}
@@ -553,9 +618,9 @@ void GraphicsContext::fillPath()
break;
}
case GradientColorSpace:
- QGradient* gradient = m_common->state.fillGradient->platformGradient();
- *gradient = applySpreadMethod(*gradient, spreadMethod());
- p->fillPath(path, QBrush(*gradient));
+ QBrush brush(*m_common->state.fillGradient->platformGradient());
+ brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
+ p->fillPath(path, brush);
break;
}
m_data->currentPath = QPainterPath();
@@ -583,9 +648,9 @@ void GraphicsContext::strokePath()
break;
}
case GradientColorSpace: {
- QGradient* gradient = m_common->state.strokeGradient->platformGradient();
- *gradient = applySpreadMethod(*gradient, spreadMethod());
- pen.setBrush(QBrush(*gradient));
+ QBrush brush(*m_common->state.strokeGradient->platformGradient());
+ brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
+ pen.setBrush(brush);
p->setPen(pen);
p->strokePath(path, pen);
break;
@@ -612,7 +677,9 @@ void GraphicsContext::fillRect(const FloatRect& rect)
break;
}
case GradientColorSpace:
- p->fillRect(rect, QBrush(*(m_common->state.fillGradient.get()->platformGradient())));
+ QBrush brush(*m_common->state.fillGradient->platformGradient());
+ brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
+ p->fillRect(rect, brush);
break;
}
m_data->currentPath = QPainterPath();
@@ -663,10 +730,7 @@ void GraphicsContext::clip(const FloatRect& rect)
if (paintingDisabled())
return;
- QPainter *p = m_data->p();
- if (p->clipRegion().isEmpty())
- p->setClipRect(rect);
- else p->setClipRect(rect, Qt::IntersectClip);
+ m_data->p()->setClipRect(rect, Qt::IntersectClip);
}
void GraphicsContext::clipPath(WindRule clipRule)
@@ -818,7 +882,7 @@ void GraphicsContext::clearRect(const FloatRect& rect)
QPainter::CompositionMode currentCompositionMode = p->compositionMode();
if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
p->setCompositionMode(QPainter::CompositionMode_Source);
- p->eraseRect(rect);
+ p->fillRect(rect, Qt::transparent);
if (p->paintEngine()->hasFeature(QPaintEngine::PorterDuff))
p->setCompositionMode(currentCompositionMode);
}
@@ -939,7 +1003,7 @@ void GraphicsContext::translate(float x, float y)
m_data->p()->translate(x, y);
if (!m_data->currentPath.isEmpty()) {
- QMatrix matrix;
+ QTransform matrix;
m_data->currentPath = m_data->currentPath * matrix.translate(-x, -y);
m_common->state.pathTransform.translate(x, y);
}
@@ -961,7 +1025,7 @@ void GraphicsContext::rotate(float radians)
m_data->p()->rotate(180/M_PI*radians);
if (!m_data->currentPath.isEmpty()) {
- QMatrix matrix;
+ QTransform matrix;
m_data->currentPath = m_data->currentPath * matrix.rotate(-180/M_PI*radians);
m_common->state.pathTransform.rotate(radians);
}
@@ -975,9 +1039,9 @@ void GraphicsContext::scale(const FloatSize& s)
m_data->p()->scale(s.width(), s.height());
if (!m_data->currentPath.isEmpty()) {
- QMatrix matrix;
+ QTransform matrix;
m_data->currentPath = m_data->currentPath * matrix.scale(1 / s.width(), 1 / s.height());
- m_common->state.pathTransform.scale(s.width(), s.height());
+ m_common->state.pathTransform.scaleNonUniform(s.width(), s.height());
}
}
@@ -1041,12 +1105,12 @@ void GraphicsContext::concatCTM(const TransformationMatrix& transform)
if (paintingDisabled())
return;
- m_data->p()->setMatrix(transform, true);
+ m_data->p()->setWorldTransform(transform, true);
// Transformations to the context shouldn't transform the currentPath.
// We have to undo every change made to the context from the currentPath to avoid wrong drawings.
if (!m_data->currentPath.isEmpty() && transform.isInvertible()) {
- QMatrix matrix = transform.inverse();
+ QTransform matrix = transform.inverse();
m_data->currentPath = m_data->currentPath * matrix;
m_common->state.pathTransform.multiply(transform);
}
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index d4ab59f..d748305 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2008 Holger Hans Peter Freyther
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,10 +32,11 @@
#include "GraphicsContext.h"
#include "ImageData.h"
#include "MIMETypeRegistry.h"
-#include "NotImplemented.h"
#include "StillImageQt.h"
#include <QBuffer>
+#include <QColor>
+#include <QImage>
#include <QImageWriter>
#include <QPainter>
#include <QPixmap>
@@ -79,15 +81,108 @@ Image* ImageBuffer::image() const
return m_image.get();
}
-PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const
+PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
{
- notImplemented();
- return 0;
+ PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
+ unsigned char* data = result->data()->data()->data();
+
+ if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height())
+ memset(data, 0, result->data()->length());
+
+ int originx = rect.x();
+ int destx = 0;
+ if (originx < 0) {
+ destx = -originx;
+ originx = 0;
+ }
+ int endx = rect.x() + rect.width();
+ if (endx > m_size.width())
+ endx = m_size.width();
+ int numColumns = endx - originx;
+
+ int originy = rect.y();
+ int desty = 0;
+ if (originy < 0) {
+ desty = -originy;
+ originy = 0;
+ }
+ int endy = rect.y() + rect.height();
+ if (endy > m_size.height())
+ endy = m_size.height();
+ int numRows = endy - originy;
+
+ QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+ ASSERT(!image.isNull());
+
+ unsigned destBytesPerRow = 4 * rect.width();
+ unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
+ for (int y = 0; y < numRows; ++y) {
+ for (int x = 0; x < numColumns; x++) {
+ QRgb value = image.pixel(x + originx, y + originy);
+ int basex = x * 4;
+
+ destRows[basex] = qRed(value);
+ destRows[basex + 1] = qGreen(value);
+ destRows[basex + 2] = qBlue(value);
+ destRows[basex + 3] = qAlpha(value);
+ }
+ destRows += destBytesPerRow;
+ }
+
+ return result;
}
-void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&)
+void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect, const IntPoint& destPoint)
{
- notImplemented();
+ ASSERT(sourceRect.width() > 0);
+ ASSERT(sourceRect.height() > 0);
+
+ int originx = sourceRect.x();
+ int destx = destPoint.x() + sourceRect.x();
+ ASSERT(destx >= 0);
+ ASSERT(destx < m_size.width());
+ ASSERT(originx >= 0);
+ ASSERT(originx <= sourceRect.right());
+
+ int endx = destPoint.x() + sourceRect.right();
+ ASSERT(endx <= m_size.width());
+
+ int numColumns = endx - destx;
+
+ int originy = sourceRect.y();
+ int desty = destPoint.y() + sourceRect.y();
+ ASSERT(desty >= 0);
+ ASSERT(desty < m_size.height());
+ ASSERT(originy >= 0);
+ ASSERT(originy <= sourceRect.bottom());
+
+ int endy = destPoint.y() + sourceRect.bottom();
+ ASSERT(endy <= m_size.height());
+ int numRows = endy - desty;
+
+ unsigned srcBytesPerRow = 4 * source->width();
+
+ bool isPainting = m_data.m_painter->isActive();
+ if (isPainting)
+ m_data.m_painter->end();
+
+ QImage image = m_data.m_pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+
+ unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4;
+ for (int y = 0; y < numRows; ++y) {
+ quint32* scanLine = reinterpret_cast<quint32*>(image.scanLine(y + desty));
+ for (int x = 0; x < numColumns; x++) {
+ int basex = x * 4;
+ scanLine[x + destx] = reinterpret_cast<quint32*>(srcRows + basex)[0];
+ }
+
+ srcRows += srcBytesPerRow;
+ }
+
+ m_data.m_pixmap = QPixmap::fromImage(image);
+
+ if (isPainting)
+ m_data.m_painter->begin(&m_data.m_pixmap);
}
// We get a mimeType here but QImageWriter does not support mimetypes but
diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp
index 99062f9..3bc67ae 100644
--- a/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
* Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
+ * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
*
* All rights reserved.
*
@@ -96,7 +97,26 @@ PassRefPtr<Image> Image::loadPlatformResource(const char* name)
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const TransformationMatrix& patternTransform,
const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
{
- notImplemented();
+ QPixmap* framePixmap = nativeImageForCurrentFrame();
+ if (!framePixmap) // If it's too early we won't have an image yet.
+ return;
+
+ QPixmap pixmap = *framePixmap;
+ QRect tr = QRectF(tileRect).toRect();
+ if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height()) {
+ pixmap = pixmap.copy(tr);
+ }
+
+ QBrush b(pixmap);
+ b.setTransform(patternTransform);
+ ctxt->save();
+ ctxt->setCompositeOperation(op);
+ QPainter* p = ctxt->platformContext();
+ if (!pixmap.hasAlpha() && p->compositionMode() == QPainter::CompositionMode_SourceOver)
+ p->setCompositionMode(QPainter::CompositionMode_Source);
+ p->setBrushOrigin(phase);
+ p->fillRect(destRect, b);
+ ctxt->restore();
}
void BitmapImage::initPlatformData()
@@ -131,6 +151,9 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
QPainter* painter(ctxt->platformContext());
+ if (!image->hasAlpha() && painter->compositionMode() == QPainter::CompositionMode_SourceOver)
+ painter->setCompositionMode(QPainter::CompositionMode_Source);
+
// Test using example site at
// http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
painter->drawPixmap(dst, *image, src);
@@ -138,33 +161,20 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
ctxt->restore();
}
-void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const TransformationMatrix& patternTransform,
- const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
+void BitmapImage::checkForSolidColor()
{
- QPixmap* framePixmap = nativeImageForCurrentFrame();
- if (!framePixmap) // If it's too early we won't have an image yet.
- return;
+ m_isSolidColor = false;
+ m_checkedForSolidColor = true;
- QPixmap pixmap = *framePixmap;
- QRect tr = QRectF(tileRect).toRect();
- if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height()) {
- pixmap = pixmap.copy(tr);
- }
+ if (frameCount() > 1)
+ return;
- QBrush b(pixmap);
- b.setMatrix(patternTransform);
- ctxt->save();
- ctxt->setCompositeOperation(op);
- QPainter* p = ctxt->platformContext();
- p->setBrushOrigin(phase);
- p->fillRect(destRect, b);
- ctxt->restore();
-}
+ QPixmap* framePixmap = frameAtIndex(0);
+ if (!framePixmap || framePixmap->width() != 1 || framePixmap->height() != 1)
+ return;
-void BitmapImage::checkForSolidColor()
-{
- // FIXME: It's easy to implement this optimization. Just need to check the RGBA32 buffer to see if it is 1x1.
- m_isSolidColor = false;
+ m_isSolidColor = true;
+ m_solidColor = QColor::fromRgba(framePixmap->toImage().pixel(0, 0));
}
}
diff --git a/WebCore/platform/graphics/qt/ImageSourceQt.cpp b/WebCore/platform/graphics/qt/ImageSourceQt.cpp
index d62acc3..84de443 100644
--- a/WebCore/platform/graphics/qt/ImageSourceQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageSourceQt.cpp
@@ -163,7 +163,7 @@ void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer*
delete m_decoder;
m_decoder = 0;
if (data)
- setData(data, allDataReceived);
+ setData(data, allDataReceived);
}
}
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
index b1a48fb..c80d73b 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -1,5 +1,6 @@
/*
Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2009 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -76,7 +77,7 @@ namespace WebCore {
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_networkState(MediaPlayer::Empty)
- , m_readyState(MediaPlayer::DataUnavailable)
+ , m_readyState(MediaPlayer::HaveNothing)
, m_mediaObject(new MediaObject())
, m_videoWidget(new VideoWidget(0))
, m_audioOutput(new AudioOutput())
@@ -110,6 +111,18 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
connect(m_mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
}
+MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player)
+{
+ return new MediaPlayerPrivate(player);
+}
+
+void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+ if (isAvailable())
+ registrar(create, getSupportedTypes, supportsType);
+}
+
+
MediaPlayerPrivate::~MediaPlayerPrivate()
{
LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting videowidget");
@@ -131,6 +144,13 @@ void MediaPlayerPrivate::getSupportedTypes(HashSet<String>&)
notImplemented();
}
+MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
+{
+ // FIXME: do the real thing
+ notImplemented();
+ return MediaPlayer::IsNotSupported;
+}
+
bool MediaPlayerPrivate::hasVideo() const
{
bool hasVideo = m_mediaObject->hasVideo();
@@ -138,7 +158,7 @@ bool MediaPlayerPrivate::hasVideo() const
return hasVideo;
}
-void MediaPlayerPrivate::load(String url)
+void MediaPlayerPrivate::load(const String& url)
{
LOG(Media, "MediaPlayerPrivatePhonon::load(\"%s\")", url.utf8().data());
@@ -149,8 +169,8 @@ void MediaPlayerPrivate::load(String url)
}
// And we don't have any data yet
- if (m_readyState != MediaPlayer::DataUnavailable) {
- m_readyState = MediaPlayer::DataUnavailable;
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
m_player->readyStateChanged();
}
@@ -205,7 +225,7 @@ bool MediaPlayerPrivate::seeking() const
float MediaPlayerPrivate::duration() const
{
- if (m_networkState < MediaPlayer::LoadedMetaData)
+ if (m_readyState < MediaPlayer::HaveMetadata)
return 0.0f;
float duration = m_mediaObject->totalTime() / 1000.0f;
@@ -309,18 +329,19 @@ void MediaPlayerPrivate::updateStates()
Phonon::State phononState = m_mediaObject->state();
if (phononState == Phonon::StoppedState) {
- if (oldNetworkState < MediaPlayer::LoadedMetaData) {
- m_networkState = MediaPlayer::LoadedMetaData;
- m_readyState = MediaPlayer::DataUnavailable;
+ if (m_readyState < MediaPlayer::HaveMetadata) {
+ m_networkState = MediaPlayer::Loading; // FIXME: should this be MediaPlayer::Idle?
+ m_readyState = MediaPlayer::HaveMetadata;
m_mediaObject->pause();
}
} else if (phononState == Phonon::PausedState) {
m_networkState = MediaPlayer::Loaded;
- m_readyState = MediaPlayer::CanPlayThrough;
+ m_readyState = MediaPlayer::HaveEnoughData;
} else if (phononState == Phonon::ErrorState) {
if (!m_mediaObject || m_mediaObject->errorType() == Phonon::FatalError) {
- m_networkState = MediaPlayer::LoadFailed;
- m_readyState = MediaPlayer::DataUnavailable;
+ // FIXME: is it possile to differentiate between different types of errors
+ m_networkState = MediaPlayer::NetworkError;
+ m_readyState = MediaPlayer::HaveNothing;
cancelLoad();
} else {
m_mediaObject->pause();
@@ -328,7 +349,7 @@ void MediaPlayerPrivate::updateStates()
}
if (seeking())
- m_readyState = MediaPlayer::DataUnavailable;
+ m_readyState = MediaPlayer::HaveNothing;
if (m_networkState != oldNetworkState) {
const QMetaObject* metaObj = this->metaObject();
@@ -357,19 +378,18 @@ void MediaPlayerPrivate::setVisible(bool visible)
m_videoWidget->setVisible(m_isVisible);
}
-void MediaPlayerPrivate::setRect(const IntRect& newRect)
+void MediaPlayerPrivate::setSize(const IntSize& newSize)
{
if (!m_videoWidget)
return;
- LOG(Media, "MediaPlayerPrivatePhonon::setRect(%d,%d %dx%d)",
- newRect.x(), newRect.y(),
- newRect.width(), newRect.height());
+ LOG(Media, "MediaPlayerPrivatePhonon::setSize(%d,%d)",
+ newSize.width(), newSize.height());
QRect currentRect = m_videoWidget->rect();
- if (newRect.width() != currentRect.width() || newRect.height() != currentRect.height())
- m_videoWidget->resize(newRect.width(), newRect.height());
+ if (newSize.width() != currentRect.width() || newSize.height() != currentRect.height())
+ m_videoWidget->resize(newSize.width(), newSize.height());
}
IntSize MediaPlayerPrivate::naturalSize() const
@@ -380,7 +400,7 @@ IntSize MediaPlayerPrivate::naturalSize() const
return IntSize();
}
- if (m_networkState < MediaPlayer::LoadedMetaData) {
+ if (m_readyState < MediaPlayer::HaveMetadata) {
LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d",
0, 0);
return IntSize();
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
index 1b20a84..9572d61 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
@@ -1,5 +1,6 @@
/*
Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2009 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -20,8 +21,7 @@
#ifndef MediaPlayerPrivatePhonon_h
#define MediaPlayerPrivatePhonon_h
-#include "MediaPlayer.h"
-#include <wtf/Noncopyable.h>
+#include "MediaPlayerPrivate.h"
#include <QObject>
#include <phononnamespace.h>
@@ -40,31 +40,33 @@ QT_END_NAMESPACE
namespace WebCore {
- class MediaPlayerPrivate : public QObject, Noncopyable {
+ class MediaPlayerPrivate : public QObject, public MediaPlayerPrivateInterface {
Q_OBJECT
public:
- MediaPlayerPrivate(MediaPlayer*);
+ static void registerMediaEngine(MediaEngineRegistrar);
~MediaPlayerPrivate();
// These enums are used for debugging
Q_ENUMS(ReadyState NetworkState PhononState)
enum ReadyState {
- DataUnavailable,
- CanShowCurrentFrame,
- CanPlay,
- CanPlayThrough
+ HaveNothing,
+ HaveMetadata,
+ HaveCurrentData,
+ HaveFutureData,
+ HaveEnoughData
};
enum NetworkState {
- Empty,
- LoadFailed,
- Loading,
- LoadedMetaData,
- LoadedFirstFrame,
- Loaded
+ Empty,
+ Idle,
+ Loading,
+ Loaded,
+ FormatError,
+ NetworkError,
+ DecodeError
};
enum PhononState {
@@ -79,7 +81,7 @@ namespace WebCore {
IntSize naturalSize() const;
bool hasVideo() const;
- void load(String url);
+ void load(const String &url);
void cancelLoad();
void play();
@@ -109,11 +111,9 @@ namespace WebCore {
unsigned totalBytes() const;
void setVisible(bool);
- void setRect(const IntRect&);
+ void setSize(const IntSize&);
void paint(GraphicsContext*, const IntRect&);
- static void getSupportedTypes(HashSet<String>&);
- static bool isAvailable() { return true; }
protected:
bool eventFilter(QObject*, QEvent*);
@@ -130,6 +130,13 @@ namespace WebCore {
void totalTimeChanged(qint64);
private:
+ MediaPlayerPrivate(MediaPlayer*);
+ static MediaPlayerPrivateInterface* create(MediaPlayer* player);
+
+ static void getSupportedTypes(HashSet<String>&);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable() { return true; }
+
void updateStates();
MediaPlayer* m_player;
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index bd0192c..a8a3ea2 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006 Zack Rusin <zack@kde.org>
- * 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * 2006 Rob Buis <buis@kde.org>
+ * 2009 Dirk Schulze <krit@webkit.org>
*
* All rights reserved.
*
@@ -36,7 +37,7 @@
#include "PlatformString.h"
#include "StrokeStyleApplier.h"
#include <QPainterPath>
-#include <QMatrix>
+#include <QTransform>
#include <QString>
#define _USE_MATH_DEFINES
@@ -108,7 +109,7 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point)
void Path::translate(const FloatSize& size)
{
- QMatrix matrix;
+ QTransform matrix;
matrix.translate(size.width(), size.height());
*m_path = (*m_path) * matrix;
}
@@ -161,9 +162,72 @@ void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const
void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
{
- //FIXME: busted
- qWarning("arcTo is busted");
- m_path->arcTo(p1.x(), p1.y(), p2.x(), p2.y(), radius, 90);
+ FloatPoint p0(m_path->currentPosition());
+
+ if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || radius == 0.f) {
+ m_path->lineTo(p1);
+ return;
+ }
+
+ FloatPoint p1p0((p0.x() - p1.x()),(p0.y() - p1.y()));
+ FloatPoint p1p2((p2.x() - p1.x()),(p2.y() - p1.y()));
+ float p1p0_length = sqrtf(p1p0.x() * p1p0.x() + p1p0.y() * p1p0.y());
+ float p1p2_length = sqrtf(p1p2.x() * p1p2.x() + p1p2.y() * p1p2.y());
+
+ double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length);
+ // all points on a line logic
+ if (cos_phi == -1) {
+ m_path->lineTo(p1);
+ return;
+ }
+ if (cos_phi == 1) {
+ // add infinite far away point
+ unsigned int max_length = 65535;
+ double factor_max = max_length / p1p0_length;
+ FloatPoint ep((p0.x() + factor_max * p1p0.x()), (p0.y() + factor_max * p1p0.y()));
+ m_path->lineTo(ep);
+ return;
+ }
+
+ float tangent = radius / tan(acos(cos_phi) / 2);
+ float factor_p1p0 = tangent / p1p0_length;
+ FloatPoint t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
+
+ FloatPoint orth_p1p0(p1p0.y(), -p1p0.x());
+ float orth_p1p0_length = sqrt(orth_p1p0.x() * orth_p1p0.x() + orth_p1p0.y() * orth_p1p0.y());
+ float factor_ra = radius / orth_p1p0_length;
+
+ // angle between orth_p1p0 and p1p2 to get the right vector orthographic to p1p0
+ double cos_alpha = (orth_p1p0.x() * p1p2.x() + orth_p1p0.y() * p1p2.y()) / (orth_p1p0_length * p1p2_length);
+ if (cos_alpha < 0.f)
+ orth_p1p0 = FloatPoint(-orth_p1p0.x(), -orth_p1p0.y());
+
+ FloatPoint p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
+
+ // calculate angles for addArc
+ orth_p1p0 = FloatPoint(-orth_p1p0.x(), -orth_p1p0.y());
+ float sa = acos(orth_p1p0.x() / orth_p1p0_length);
+ if (orth_p1p0.y() < 0.f)
+ sa = 2 * piDouble - sa;
+
+ // anticlockwise logic
+ bool anticlockwise = false;
+
+ float factor_p1p2 = tangent / p1p2_length;
+ FloatPoint t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
+ FloatPoint orth_p1p2((t_p1p2.x() - p.x()),(t_p1p2.y() - p.y()));
+ float orth_p1p2_length = sqrtf(orth_p1p2.x() * orth_p1p2.x() + orth_p1p2.y() * orth_p1p2.y());
+ float ea = acos(orth_p1p2.x() / orth_p1p2_length);
+ if (orth_p1p2.y() < 0)
+ ea = 2 * piDouble - ea;
+ if ((sa > ea) && ((sa - ea) < piDouble))
+ anticlockwise = true;
+ if ((sa < ea) && ((ea - sa) > piDouble))
+ anticlockwise = true;
+
+ m_path->lineTo(t_p1p0);
+
+ addArc(p, radius, sa, ea, anticlockwise);
}
void Path::closeSubpath()
@@ -316,7 +380,7 @@ void Path::apply(void* info, PathApplierFunction function) const
void Path::transform(const TransformationMatrix& transform)
{
if (m_path) {
- QMatrix mat = transform;
+ QTransform mat = transform;
QPainterPath temp = mat.map(*m_path);
delete m_path;
m_path = new QPainterPath(temp);
diff --git a/WebCore/platform/graphics/qt/PatternQt.cpp b/WebCore/platform/graphics/qt/PatternQt.cpp
index 5b76841..b261613 100644
--- a/WebCore/platform/graphics/qt/PatternQt.cpp
+++ b/WebCore/platform/graphics/qt/PatternQt.cpp
@@ -31,14 +31,15 @@
namespace WebCore {
-QBrush Pattern::createPlatformPattern(const TransformationMatrix& transform) const
+QBrush Pattern::createPlatformPattern(const TransformationMatrix&) const
{
QPixmap* pixmap = tileImage()->nativeImageForCurrentFrame();
if (!pixmap)
return QBrush();
+ // Qt merges patter space and user space itself
QBrush brush(*pixmap);
- brush.setMatrix(transform);
+ brush.setTransform(m_patternSpaceTransformation);
return brush;
}
diff --git a/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp b/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp
index 47abd17..15f0cc5 100644
--- a/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp
+++ b/WebCore/platform/graphics/qt/TransformationMatrixQt.cpp
@@ -31,170 +31,9 @@
namespace WebCore {
-TransformationMatrix::TransformationMatrix()
- : m_transform()
-{
-}
-
-TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double tx, double ty)
- : m_transform(a, b, c, d, tx, ty)
-{
-}
-
-TransformationMatrix::TransformationMatrix(const PlatformTransformationMatrix& matrix)
- : m_transform(matrix)
-{
-}
-
-void TransformationMatrix::setMatrix(double a, double b, double c, double d, double tx, double ty)
-{
- m_transform.setMatrix(a, b, c, d, tx, ty);
-}
-
-void TransformationMatrix::map(double x, double y, double* x2, double* y2) const
-{
- qreal tx2, ty2;
- m_transform.map(qreal(x), qreal(y), &tx2, &ty2);
- *x2 = tx2;
- *y2 = ty2;
-}
-
-IntRect TransformationMatrix::mapRect(const IntRect& rect) const
-{
- return m_transform.mapRect(rect);
-}
-
-FloatRect TransformationMatrix::mapRect(const FloatRect& rect) const
-{
- return m_transform.mapRect(rect);
-}
-
-bool TransformationMatrix::isIdentity() const
-{
- return m_transform.isIdentity();
-}
-
-double TransformationMatrix::a() const
-{
- return m_transform.m11();
-}
-
-void TransformationMatrix::setA(double a)
-{
- m_transform.setMatrix(a, b(), c(), d(), e(), f());
-}
-
-double TransformationMatrix::b() const
-{
- return m_transform.m12();
-}
-
-void TransformationMatrix::setB(double b)
-{
- m_transform.setMatrix(a(), b, c(), d(), e(), f());
-}
-
-double TransformationMatrix::c() const
-{
- return m_transform.m21();
-}
-
-void TransformationMatrix::setC(double c)
-{
- m_transform.setMatrix(a(), b(), c, d(), e(), f());
-}
-
-double TransformationMatrix::d() const
-{
- return m_transform.m22();
-}
-
-void TransformationMatrix::setD(double d)
-{
- m_transform.setMatrix(a(), b(), c(), d, e(), f());
-}
-
-double TransformationMatrix::e() const
-{
- return m_transform.dx();
-}
-
-void TransformationMatrix::setE(double e)
-{
- m_transform.setMatrix(a(), b(), c(), d(), e, f());
-}
-
-double TransformationMatrix::f() const
-{
- return m_transform.dy();
-}
-
-void TransformationMatrix::setF(double f)
-{
- m_transform.setMatrix(a(), b(), c(), d(), e(), f);
-}
-
-void TransformationMatrix::reset()
-{
- m_transform.reset();
-}
-
-TransformationMatrix& TransformationMatrix::scale(double sx, double sy)
-{
- m_transform.scale(sx, sy);
- return *this;
-}
-
-TransformationMatrix& TransformationMatrix::rotate(double d)
-{
- m_transform.rotate(d);
- return *this;
-}
-
-TransformationMatrix& TransformationMatrix::translate(double tx, double ty)
-{
- m_transform.translate(tx, ty);
- return *this;
-}
-
-TransformationMatrix& TransformationMatrix::shear(double sx, double sy)
-{
- m_transform.shear(sx, sy);
- return *this;
-}
-
-double TransformationMatrix::det() const
-{
- return m_transform.det();
-}
-
-TransformationMatrix TransformationMatrix::inverse() const
-{
- if(!isInvertible())
- return TransformationMatrix();
-
- return m_transform.inverted();
-}
-
-TransformationMatrix::operator QMatrix() const
-{
- return m_transform;
-}
-
-bool TransformationMatrix::operator==(const TransformationMatrix& other) const
-{
- return m_transform == other.m_transform;
-}
-
-TransformationMatrix& TransformationMatrix::operator*=(const TransformationMatrix& other)
-{
- m_transform *= other.m_transform;
- return *this;
-}
-
-TransformationMatrix TransformationMatrix::operator*(const TransformationMatrix& other)
-{
- return m_transform * other.m_transform;
+TransformationMatrix::operator QTransform() const
+{
+ return QTransform(m11(), m12(), m14(), m21(), m22(), m24(), m41(), m42(), m44());
}
}
diff --git a/WebCore/platform/graphics/skia/GradientSkia.cpp b/WebCore/platform/graphics/skia/GradientSkia.cpp
index eff7c66..2d2000c 100644
--- a/WebCore/platform/graphics/skia/GradientSkia.cpp
+++ b/WebCore/platform/graphics/skia/GradientSkia.cpp
@@ -136,6 +136,19 @@ SkShader* Gradient::platformGradient()
fillStops(m_stops.data(), m_stops.size(), pos, colors);
+ SkShader::TileMode tile = SkShader::kClamp_TileMode;
+ switch (m_spreadMethod) {
+ case SpreadMethodReflect:
+ tile = SkShader::kMirror_TileMode;
+ break;
+ case SpreadMethodRepeat:
+ tile = SkShader::kRepeat_TileMode;
+ break;
+ case SpreadMethodPad:
+ tile = SkShader::kClamp_TileMode;
+ break;
+ }
+
if (m_radial) {
// FIXME: CSS radial Gradients allow an offset focal point (the
// "start circle"), but skia doesn't seem to support that, so this just
@@ -145,13 +158,16 @@ SkShader* Gradient::platformGradient()
// description of the expected behavior.
m_gradient = SkGradientShader::CreateRadial(m_p1,
WebCoreFloatToSkScalar(m_r1), colors, pos,
- static_cast<int>(countUsed), SkShader::kClamp_TileMode);
+ static_cast<int>(countUsed), tile);
} else {
SkPoint pts[2] = { m_p0, m_p1 };
m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
- static_cast<int>(countUsed), SkShader::kClamp_TileMode);
+ static_cast<int>(countUsed), tile);
}
+ SkMatrix matrix = m_gradientSpaceTransformation;
+ m_gradient->setLocalMatrix(matrix);
+
return m_gradient;
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index e6c7783..376fa4b 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -36,6 +36,7 @@
#include "Color.h"
#include "FloatRect.h"
#include "Gradient.h"
+#include "ImageBuffer.h"
#include "IntRect.h"
#include "NativeImageSkia.h"
#include "NotImplemented.h"
@@ -274,11 +275,6 @@ void GraphicsContext::endTransparencyLayer()
{
if (paintingDisabled())
return;
-
-#if PLATFORM(WIN_OS)
- platformContext()->canvas()->getTopPlatformDevice().
- fixupAlphaBeforeCompositing();
-#endif
platformContext()->canvas()->restore();
}
@@ -406,8 +402,7 @@ void GraphicsContext::clipPath(WindRule clipRule)
if (paintingDisabled())
return;
- const SkPath* oldPath = platformContext()->currentPath();
- SkPath path(*oldPath);
+ SkPath path = platformContext()->currentPathInLocalCoordinates();
path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
platformContext()->canvas()->clipPath(path);
}
@@ -418,8 +413,9 @@ void GraphicsContext::clipToImageBuffer(const FloatRect& rect,
if (paintingDisabled())
return;
- // FIXME: This is needed for image masking and complex text fills.
- notImplemented();
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ platformContext()->beginLayerClippedToImage(rect, imageBuffer);
+#endif
}
void GraphicsContext::concatCTM(const TransformationMatrix& xform)
@@ -645,6 +641,9 @@ void GraphicsContext::drawLineForText(const IntPoint& pt,
if (paintingDisabled())
return;
+ if (width <= 0)
+ return;
+
int thickness = SkMax32(static_cast<int>(strokeThickness()), 1);
SkRect r;
r.fLeft = SkIntToScalar(pt.x());
@@ -653,7 +652,9 @@ void GraphicsContext::drawLineForText(const IntPoint& pt,
r.fBottom = r.fTop + SkIntToScalar(thickness);
SkPaint paint;
- paint.setColor(strokeColor().rgb());
+ platformContext()->setupPaintForFilling(&paint);
+ // Text lines are drawn using the stroke color.
+ paint.setColor(platformContext()->effectiveStrokeColor());
platformContext()->canvas()->drawRect(r, paint);
}
@@ -664,9 +665,10 @@ void GraphicsContext::drawRect(const IntRect& rect)
return;
SkRect r = rect;
- if (!isRectSkiaSafe(getCTM(), r))
+ if (!isRectSkiaSafe(getCTM(), r)) {
// See the fillRect below.
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
+ }
platformContext()->drawRect(r);
}
@@ -676,7 +678,7 @@ void GraphicsContext::fillPath()
if (paintingDisabled())
return;
- const SkPath& path = *platformContext()->currentPath();
+ SkPath path = platformContext()->currentPathInLocalCoordinates();
if (!isPathSkiaSafe(getCTM(), path))
return;
@@ -686,7 +688,7 @@ void GraphicsContext::fillPath()
if (colorSpace == SolidColorSpace && !fillColor().alpha())
return;
- platformContext()->setFillRule(state.fillRule == RULE_EVENODD ?
+ path.setFillType(state.fillRule == RULE_EVENODD ?
SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
SkPaint paint;
@@ -708,9 +710,10 @@ void GraphicsContext::fillRect(const FloatRect& rect)
return;
SkRect r = rect;
- if (!isRectSkiaSafe(getCTM(), r))
+ if (!isRectSkiaSafe(getCTM(), r)) {
// See the other version of fillRect below.
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
+ }
const GraphicsContextState& state = m_common->state;
ColorSpace colorSpace = state.fillColorSpace;
@@ -775,6 +778,17 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect,
// See fillRect().
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
+ if (topLeft.width() + topRight.width() > rect.width()
+ || bottomLeft.width() + bottomRight.width() > rect.width()
+ || topLeft.height() + bottomLeft.height() > rect.height()
+ || topRight.height() + bottomRight.height() > rect.height()) {
+ // Not all the radii fit, return a rect. This matches the behavior of
+ // Path::createRoundedRectangle. Without this we attempt to draw a round
+ // shadow for a square box.
+ fillRect(rect, color);
+ return;
+ }
+
SkPath path;
addCornerArc(&path, r, topRight, 270);
addCornerArc(&path, r, bottomRight, 0);
@@ -784,12 +798,17 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect,
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
platformContext()->canvas()->drawPath(path, paint);
- return fillRect(rect, color);
}
TransformationMatrix GraphicsContext::getCTM() const
{
- return platformContext()->canvas()->getTotalMatrix();
+ const SkMatrix& m = platformContext()->canvas()->getTotalMatrix();
+ return TransformationMatrix(SkScalarToDouble(m.getScaleX()), // a
+ SkScalarToDouble(m.getSkewY()), // b
+ SkScalarToDouble(m.getSkewX()), // c
+ SkScalarToDouble(m.getScaleY()), // d
+ SkScalarToDouble(m.getTranslateX()), // e
+ SkScalarToDouble(m.getTranslateY())); // f
}
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
@@ -1050,7 +1069,7 @@ void GraphicsContext::strokePath()
if (paintingDisabled())
return;
- const SkPath& path = *platformContext()->currentPath();
+ SkPath path = platformContext()->currentPathInLocalCoordinates();
if (!isPathSkiaSafe(getCTM(), path))
return;
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index fdfcb85..5e90491 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -31,12 +31,14 @@
#include "config.h"
#include "ImageBuffer.h"
+#include "Base64.h"
#include "BitmapImage.h"
#include "BitmapImageSingleFrameSkia.h"
#include "GraphicsContext.h"
#include "ImageData.h"
#include "NotImplemented.h"
#include "PlatformContextSkia.h"
+#include "PNGImageEncoder.h"
#include "SkiaUtils.h"
using namespace std;
@@ -63,6 +65,9 @@ ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
m_data.m_platformContext.setCanvas(&m_data.m_canvas);
m_context.set(new GraphicsContext(&m_data.m_platformContext));
+#if PLATFORM(WIN_OS)
+ 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
@@ -101,7 +106,7 @@ PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
ASSERT(context());
RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height());
- unsigned char* data = result->data()->data();
+ unsigned char* data = result->data()->data()->data();
if (rect.x() < 0 || rect.y() < 0 ||
(rect.x() + rect.width()) > m_size.width() ||
@@ -188,7 +193,7 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect,
unsigned srcBytesPerRow = 4 * source->width();
- const unsigned char* srcRow = source->data()->data() + originY * srcBytesPerRow + originX * 4;
+ const unsigned char* srcRow = source->data()->data()->data() + originY * srcBytesPerRow + originX * 4;
for (int y = 0; y < numRows; ++y) {
uint32_t* destRow = bitmap.getAddr32(destX, destY + y);
@@ -203,8 +208,18 @@ void ImageBuffer::putImageData(ImageData* source, const IntRect& sourceRect,
String ImageBuffer::toDataURL(const String&) const
{
- notImplemented();
- return String();
+ // Encode the image into a vector.
+ Vector<unsigned char> pngEncodedData;
+ PNGImageEncoder::encode(*context()->platformContext()->bitmap(), &pngEncodedData);
+
+ // Convert it into base64.
+ Vector<char> base64EncodedData;
+ base64Encode(*reinterpret_cast<Vector<char>*>(&pngEncodedData), base64EncodedData);
+ // Append with a \0 so that it's a valid string.
+ base64EncodedData.append('\0');
+
+ // And the resulting string.
+ return String::format("data:image/png;base64,%s", base64EncodedData.data());
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index 1123fe9..d7f2830 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -225,6 +225,7 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
{
SkPaint paint;
paint.setPorterDuffXfermode(compOp);
+ paint.setFilterBitmap(true);
skia::PlatformCanvas* canvas = platformContext->canvas();
@@ -233,7 +234,6 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
SkScalarToFloat(destRect.width()),
SkScalarToFloat(destRect.height()));
if (resampling == RESAMPLE_AWESOME) {
- paint.setFilterBitmap(false);
drawResampledBitmap(*canvas, paint, bitmap, srcRect, destRect);
} else {
// No resampling necessary, we can just draw the bitmap. We want to
@@ -241,7 +241,6 @@ static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImag
// is something interesting going on with the matrix (like a rotation).
// Note: for serialization, we will want to subset the bitmap first so
// we don't send extra pixels.
- paint.setFilterBitmap(resampling == RESAMPLE_LINEAR);
canvas->drawBitmapRect(bitmap, &srcRect, destRect, &paint);
}
}
@@ -401,6 +400,7 @@ void BitmapImage::invalidatePlatformData()
void BitmapImage::checkForSolidColor()
{
+ m_checkedForSolidColor = true;
}
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
@@ -427,7 +427,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
paintSkBitmap(ctxt->platformContext(),
*bm,
enclosingIntRect(normSrcRect),
- enclosingIntRect(normDstRect),
+ normDstRect,
WebCoreCompositeToSkiaComposite(compositeOp));
}
@@ -447,7 +447,7 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
paintSkBitmap(ctxt->platformContext(),
m_nativeImage,
enclosingIntRect(normSrcRect),
- enclosingIntRect(normDstRect),
+ normDstRect,
WebCoreCompositeToSkiaComposite(compositeOp));
}
diff --git a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp b/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
index f77620b..b5f7e1d 100644
--- a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
@@ -100,16 +100,16 @@ ImageSource::~ImageSource()
void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived)
{
- // TODO(darin): Figure out what to do with the |data| and |allDataReceived| params.
-
- if (destroyAll) {
- delete m_decoder;
- m_decoder = 0;
+ if (!destroyAll) {
+ if (m_decoder)
+ m_decoder->clearFrameBufferCache(clearBeforeFrame);
return;
}
- if (m_decoder)
- m_decoder->clearFrameBufferCache(clearBeforeFrame);
+ delete m_decoder;
+ m_decoder = 0;
+ if (data)
+ setData(data, allDataReceived);
}
bool ImageSource::initialized() const
diff --git a/WebCore/platform/graphics/skia/PathSkia.cpp b/WebCore/platform/graphics/skia/PathSkia.cpp
index ca99322..2700da8 100644
--- a/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -274,7 +274,7 @@ static FloatRect boundingBoxForCurrentStroke(const GraphicsContext* context)
SkPaint paint;
context->platformContext()->setupPaintForStroking(&paint, 0, 0);
SkPath boundingPath;
- paint.getFillPath(context->platformContext()->currentPath(), &boundingPath);
+ paint.getFillPath(context->platformContext()->currentPathInLocalCoordinates(), &boundingPath);
SkRect r;
boundingPath.computeBounds(&r, SkPath::kExact_BoundsType);
return r;
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 60dbbe0..6c633f2 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "GraphicsContext.h"
+#include "ImageBuffer.h"
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
#include "SkiaUtils.h"
@@ -45,10 +46,6 @@
#include <wtf/MathExtras.h>
-#if defined(__linux__)
-#include "GdkSkia.h"
-#endif
-
// State -----------------------------------------------------------------------
// Encapsulates the additional painting state information we store for each
@@ -86,6 +83,13 @@ struct PlatformContextSkia::State {
// color to produce a new output color.
SkColor applyAlpha(SkColor) const;
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ // 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.
+ WebCore::FloatRect m_clip;
+#endif
+
private:
// Not supported.
void operator=(const State&);
@@ -113,9 +117,28 @@ PlatformContextSkia::State::State()
}
PlatformContextSkia::State::State(const State& other)
+ : m_alpha(other.m_alpha)
+ , m_porterDuffMode(other.m_porterDuffMode)
+ , m_gradient(other.m_gradient)
+ , m_pattern(other.m_pattern)
+ , m_useAntialiasing(other.m_useAntialiasing)
+ , m_looper(other.m_looper)
+ , m_fillColor(other.m_fillColor)
+ , m_strokeStyle(other.m_strokeStyle)
+ , m_strokeColor(other.m_strokeColor)
+ , m_strokeThickness(other.m_strokeThickness)
+ , m_dashRatio(other.m_dashRatio)
+ , m_miterLimit(other.m_miterLimit)
+ , m_lineCap(other.m_lineCap)
+ , m_lineJoin(other.m_lineJoin)
+ , m_dash(other.m_dash)
+ , m_textDrawingMode(other.m_textDrawingMode)
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ , m_imageBufferClip(other.m_imageBufferClip)
+ , m_clip(other.m_clip)
+#endif
{
- memcpy(this, &other, sizeof(State));
-
+ // Up the ref count of these. saveRef does nothing if 'this' is NULL.
m_looper->safeRef();
m_dash->safeRef();
m_gradient->safeRef();
@@ -148,22 +171,16 @@ SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
: m_canvas(canvas)
, m_stateStack(sizeof(State))
+#if PLATFORM(WIN_OS)
+ , m_drawingToImageBuffer(false)
+#endif
{
m_stateStack.append(State());
m_state = &m_stateStack.last();
-#if defined(OS_LINUX)
- m_gdkskia = m_canvas ? gdk_skia_new(m_canvas) : 0;
-#endif
}
PlatformContextSkia::~PlatformContextSkia()
{
-#if defined(OS_LINUX)
- if (m_gdkskia) {
- g_object_unref(m_gdkskia);
- m_gdkskia = 0;
- }
-#endif
}
void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
@@ -171,17 +188,72 @@ void PlatformContextSkia::setCanvas(skia::PlatformCanvas* canvas)
m_canvas = canvas;
}
+#if PLATFORM(WIN_OS)
+void PlatformContextSkia::setDrawingToImageBuffer(bool value)
+{
+ m_drawingToImageBuffer = value;
+}
+
+bool PlatformContextSkia::isDrawingToImageBuffer() const
+{
+ return m_drawingToImageBuffer;
+}
+#endif
+
void PlatformContextSkia::save()
{
m_stateStack.append(*m_state);
m_state = &m_stateStack.last();
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ // 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 defined(__linux__) || PLATFORM(WIN_OS)
+void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rect,
+ const WebCore::ImageBuffer* imageBuffer)
+{
+ // Skia doesn't support clipping to an image, so we create a layer. The next
+ // time restore is invoked the layer and |imageBuffer| are combined to
+ // create the resulting image.
+ m_state->m_clip = rect;
+ SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()),
+ SkFloatToScalar(rect.right()), SkFloatToScalar(rect.bottom()) };
+
+ canvas()->saveLayerAlpha(&bounds, 255,
+ static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
+ // Copy off the image as |imageBuffer| may be deleted before restore is invoked.
+ const SkBitmap* bitmap = imageBuffer->context()->platformContext()->bitmap();
+ if (!bitmap->pixelRef()) {
+ // The bitmap owns it's pixels. This happens when we've allocated the
+ // pixels in some way and assigned them directly to the bitmap (as
+ // happens when we allocate a DIB). In this case the assignment operator
+ // does not copy the pixels, rather the copied bitmap ends up
+ // referencing the same pixels. As the pixels may not live as long as we
+ // need it to, we copy the image.
+ bitmap->copyTo(&m_state->m_imageBufferClip, SkBitmap::kARGB_8888_Config);
+ } else {
+ // If there is a pixel ref, we can safely use the assignment operator.
+ m_state->m_imageBufferClip = *bitmap;
+ }
+}
+#endif
+
void PlatformContextSkia::restore()
{
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ if (!m_state->m_imageBufferClip.empty()) {
+ applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip);
+ canvas()->restore();
+ }
+#endif
+
m_stateStack.removeLast();
m_state = &m_stateStack.last();
@@ -200,12 +272,21 @@ void PlatformContextSkia::drawRect(SkRect rect)
if (m_state->m_strokeStyle != WebCore::NoStroke &&
(m_state->m_strokeColor & 0xFF000000)) {
- if (fillcolorNotTransparent) {
- // This call is expensive so don't call it unnecessarily.
- paint.reset();
- }
- setupPaintForStroking(&paint, &rect, 0);
- canvas()->drawRect(rect, paint);
+ // We do a fill of four rects to simulate the stroke of a border.
+ SkColor oldFillColor = m_state->m_fillColor;
+ if (oldFillColor != m_state->m_strokeColor)
+ setFillColor(m_state->m_strokeColor);
+ setupPaintForFilling(&paint);
+ SkRect topBorder = { rect.fLeft, rect.fTop, rect.width(), 1 };
+ canvas()->drawRect(topBorder, paint);
+ SkRect bottomBorder = { rect.fLeft, rect.fBottom - 1, rect.width(), 1 };
+ canvas()->drawRect(bottomBorder, paint);
+ SkRect leftBorder = { rect.fLeft, rect.fTop + 1, 1, rect.height() - 2 };
+ canvas()->drawRect(leftBorder, paint);
+ SkRect rightBorder = { rect.fRight - 1, rect.fTop + 1, 1, rect.height() - 2 };
+ canvas()->drawRect(rightBorder, paint);
+ if (oldFillColor != m_state->m_strokeColor)
+ setFillColor(oldFillColor);
}
}
@@ -239,10 +320,6 @@ float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
setupPaintCommon(paint);
float width = m_state->m_strokeThickness;
- // This allows dashing and dotting to work properly for hairline strokes.
- if (width == 0)
- width = 1;
-
paint->setColor(m_state->applyAlpha(m_state->m_strokeColor));
paint->setStyle(SkPaint::kStroke_Style);
paint->setStrokeWidth(SkFloatToScalar(width));
@@ -250,9 +327,6 @@ float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
paint->setStrokeJoin(m_state->m_lineJoin);
paint->setStrokeMiter(SkFloatToScalar(m_state->m_miterLimit));
- if (rect != 0 && (static_cast<int>(roundf(width)) & 1))
- rect->inset(-SK_ScalarHalf, -SK_ScalarHalf);
-
if (m_state->m_dash)
paint->setPathEffect(m_state->m_dash);
else {
@@ -267,7 +341,8 @@ float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
SkScalar dashLength;
if (length) {
// Determine about how many dashes or dots we should have.
- int numDashes = length / roundf(width);
+ float roundedWidth = roundf(width);
+ int numDashes = roundedWidth ? (length / roundedWidth) : length;
if (!(numDashes & 1))
numDashes++; // Make it odd so we end on a dash/dot.
// Use the number of dashes to determine the length of a
@@ -366,9 +441,14 @@ void PlatformContextSkia::setUseAntialiasing(bool enable)
m_state->m_useAntialiasing = enable;
}
-SkColor PlatformContextSkia::fillColor() const
+SkColor PlatformContextSkia::effectiveFillColor() const
{
- return m_state->m_fillColor;
+ return m_state->applyAlpha(m_state->m_fillColor);
+}
+
+SkColor PlatformContextSkia::effectiveStrokeColor() const
+{
+ return m_state->applyAlpha(m_state->m_strokeColor);
}
void PlatformContextSkia::beginPath()
@@ -378,7 +458,17 @@ void PlatformContextSkia::beginPath()
void PlatformContextSkia::addPath(const SkPath& path)
{
- m_path.addPath(path);
+ m_path.addPath(path, m_canvas->getTotalMatrix());
+}
+
+SkPath PlatformContextSkia::currentPathInLocalCoordinates() const
+{
+ SkPath localPath = m_path;
+ const SkMatrix& matrix = m_canvas->getTotalMatrix();
+ SkMatrix inverseMatrix;
+ matrix.invert(&inverseMatrix);
+ localPath.transform(inverseMatrix);
+ return localPath;
}
void PlatformContextSkia::setFillRule(SkPath::FillType fr)
@@ -425,3 +515,14 @@ bool PlatformContextSkia::isPrinting()
{
return m_canvas->getTopPlatformDevice().IsVectorial();
}
+
+#if defined(__linux__) || PLATFORM(WIN_OS)
+void PlatformContextSkia::applyClipFromImage(const WebCore::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
+ // only look at the alpha when compositing. I'm not 100% sure this is what WebKit expects for image clipping.
+ SkPaint paint;
+ paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode);
+ m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint);
+}
+#endif
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 78e9a19..8850a6a 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -43,8 +43,6 @@
#include <wtf/Vector.h>
-typedef struct _GdkDrawable GdkSkia;
-
// 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
// be moved to GraphicsContext directly, except that some code external to this
@@ -73,9 +71,28 @@ public:
// to the constructor.
void setCanvas(skia::PlatformCanvas*);
+#if PLATFORM(WIN_OS)
+ // 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
+ // color and all text drawing needs to go to a layer so that the alpha is
+ // correctly updated.
+ void setDrawingToImageBuffer(bool);
+ bool isDrawingToImageBuffer() const;
+#endif
+
void save();
void restore();
+ // Begins a layer that is clipped to the image |imageBuffer| at the location
+ // |rect|. This layer is implicitly restored when the next restore is
+ // invoked.
+ // NOTE: |imageBuffer| may be deleted before the |restore| is invoked.
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ void beginLayerClippedToImage(const WebCore::FloatRect&,
+ const WebCore::ImageBuffer*);
+#endif
+
// Sets up the common flags on a paint for antialiasing, effects, etc.
// This is implicitly called by setupPaintFill and setupPaintStroke, but
// you may wish to call it directly sometimes if you don't want that other
@@ -116,9 +133,15 @@ public:
void beginPath();
void addPath(const SkPath&);
- const SkPath* currentPath() const { return &m_path; }
+ SkPath currentPathInLocalCoordinates() const;
+
+ // Returns the fill color. The returned color has it's alpha adjusted
+ // by the current alpha.
+ SkColor effectiveFillColor() const;
- SkColor fillColor() const;
+ // Returns the stroke color. The returned color has it's alpha adjusted
+ // by the current alpha.
+ SkColor effectiveStrokeColor() const;
skia::PlatformCanvas* canvas() { return m_canvas; }
@@ -142,12 +165,13 @@ public:
// possible quality.
bool isPrinting();
-#if defined(__linux__)
- // FIXME: should be camelCase.
- GdkSkia* gdk_skia() const { return m_gdkskia; }
+private:
+#if defined(__linux__) || PLATFORM(WIN_OS)
+ // 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 WebCore::FloatRect&, const SkBitmap&);
#endif
-private:
// Defines drawing style.
struct State;
@@ -161,12 +185,11 @@ private:
// mStateStack.back().
State* m_state;
- // Current path.
+ // Current path in global coordinates.
SkPath m_path;
-#if defined(__linux__)
- // A pointer to a GDK Drawable wrapping of this Skia canvas
- GdkSkia* m_gdkskia;
+#if PLATFORM(WIN_OS)
+ bool m_drawingToImageBuffer;
#endif
};
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index 6e79a7e..d0cd4c5 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -31,8 +31,13 @@
#include "config.h"
#include "SkiaFontWin.h"
+#include "PlatformContextSkia.h"
+#include "Gradient.h"
+#include "Pattern.h"
#include "SkCanvas.h"
#include "SkPaint.h"
+#include "SkShader.h"
+#include "TransformationMatrix.h"
#include <wtf/ListHashSet.h>
#include <wtf/Vector.h>
@@ -162,10 +167,10 @@ static bool getPathForGlyph(HDC dc, WORD glyph, SkPath* path)
addPolyCurveToPath(polyCurve, path);
curPoly += sizeof(WORD) * 2 + sizeof(POINTFX) * polyCurve->cpfx;
}
+ path->close();
curGlyph += polyHeader->cb;
}
- path->close();
return true;
}
@@ -215,4 +220,152 @@ void SkiaWinOutlineCache::removePathsForFont(HFONT hfont)
deleteOutline(outlineCache.find(*i));
}
+bool windowsCanHandleTextDrawing(GraphicsContext* context)
+{
+ // Check for non-translation transforms. Sometimes zooms will look better in
+ // Skia, and sometimes better in Windows. The main problem is that zooming
+ // in using Skia will show you the hinted outlines for the smaller size,
+ // which look weird. All else being equal, it's better to use Windows' text
+ // drawing, so we don't check for zooms.
+ const TransformationMatrix& matrix = context->getCTM();
+ if (matrix.b() != 0 || matrix.c() != 0) // Check for skew.
+ return false;
+
+ // Check for stroke effects.
+ if (context->platformContext()->getTextDrawingMode() != cTextFill)
+ return false;
+
+ // Check for gradients.
+ if (context->fillGradient() || context->strokeGradient())
+ return false;
+
+ // Check for patterns.
+ if (context->fillPattern() || context->strokePattern())
+ return false;
+
+ // Check for shadow effects.
+ if (context->platformContext()->getDrawLooper())
+ return false;
+
+ return true;
+}
+
+// Draws the given text string using skia. Note that gradient or
+// pattern may be NULL, in which case a solid colour is used.
+static bool skiaDrawText(HFONT hfont,
+ HDC dc,
+ SkCanvas* canvas,
+ const SkPoint& point,
+ SkPaint* paint,
+ const TransformationMatrix& transformationMatrix,
+ Gradient* gradient,
+ Pattern* pattern,
+ const WORD* glyphs,
+ const int* advances,
+ const GOFFSET* offsets,
+ int numGlyphs)
+{
+ SkShader* shader = NULL;
+ if (gradient)
+ shader = gradient->platformGradient();
+ else if (pattern)
+ shader = pattern->createPlatformPattern(transformationMatrix);
+
+ paint->setShader(shader);
+ float x = point.fX, y = point.fY;
+
+ for (int i = 0; i < numGlyphs; i++) {
+ const SkPath* path = SkiaWinOutlineCache::lookupOrCreatePathForGlyph(dc, hfont, glyphs[i]);
+ if (!path)
+ return false;
+
+ float offsetX = 0.0f, offsetY = 0.0f;
+ if (offsets && (offsets[i].du != 0 || offsets[i].dv != 0)) {
+ offsetX = offsets[i].du;
+ offsetY = offsets[i].dv;
+ }
+
+ SkPath newPath;
+ newPath.addPath(*path, x + offsetX, y + offsetY);
+ canvas->drawPath(newPath, *paint);
+
+ x += advances[i];
+ }
+
+ return true;
+}
+
+bool paintSkiaText(GraphicsContext* context,
+ HFONT hfont,
+ int numGlyphs,
+ const WORD* glyphs,
+ const int* advances,
+ const GOFFSET* offsets,
+ const SkPoint* origin)
+{
+ HDC dc = GetDC(0);
+ HGDIOBJ oldFont = SelectObject(dc, hfont);
+
+ PlatformContextSkia* platformContext = context->platformContext();
+ int textMode = platformContext->getTextDrawingMode();
+
+ // Filling (if necessary). This is the common case.
+ SkPaint paint;
+ platformContext->setupPaintForFilling(&paint);
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ bool didFill = false;
+
+ if ((textMode & cTextFill) && SkColorGetA(paint.getColor())) {
+ Gradient* fillGradient = 0;
+ Pattern* fillPattern = 0;
+ if (context->fillColorSpace() == GradientColorSpace)
+ fillGradient = context->fillGradient();
+ else if (context->fillColorSpace() == PatternColorSpace)
+ fillPattern = context->fillPattern();
+ if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
+ context->getCTM(), fillGradient, fillPattern,
+ &glyphs[0], &advances[0], &offsets[0], numGlyphs))
+ return false;
+ didFill = true;
+ }
+
+ // Stroking on top (if necessary).
+ if ((textMode & WebCore::cTextStroke)
+ && platformContext->getStrokeStyle() != NoStroke
+ && platformContext->getStrokeThickness() > 0) {
+
+ paint.reset();
+ platformContext->setupPaintForStroking(&paint, 0, 0);
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ if (didFill) {
+ // If there is a shadow and we filled above, there will already be
+ // a shadow. We don't want to draw it again or it will be too dark
+ // and it will go on top of the fill.
+ //
+ // Note that this isn't strictly correct, since the stroke could be
+ // very thick and the shadow wouldn't account for this. The "right"
+ // thing would be to draw to a new layer and then draw that layer
+ // with a shadow. But this is a lot of extra work for something
+ // that isn't normally an issue.
+ paint.setLooper(0)->safeUnref();
+ }
+
+ Gradient* strokeGradient = 0;
+ Pattern* strokePattern = 0;
+ if (context->strokeColorSpace() == GradientColorSpace)
+ strokeGradient = context->strokeGradient();
+ else if (context->strokeColorSpace() == PatternColorSpace)
+ strokePattern = context->strokePattern();
+ if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
+ context->getCTM(), strokeGradient, strokePattern,
+ &glyphs[0], &advances[0], &offsets[0], numGlyphs))
+ return false;
+ }
+
+ SelectObject(dc, oldFont);
+ ReleaseDC(0, dc);
+
+ return true;
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.h b/WebCore/platform/graphics/skia/SkiaFontWin.h
index 2adab39..0e0c953 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.h
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.h
@@ -32,8 +32,12 @@
#define SkiaWinOutlineCache_h
#include <windows.h>
+#include <usp10.h>
+class GraphicsContext;
class SkPath;
+class SkPoint;
+class PlatformContextSkia;
namespace WebCore {
@@ -49,6 +53,37 @@ private:
SkiaWinOutlineCache();
};
+// The functions below are used for more complex font drawing (effects such as
+// stroking and more complex transforms) than Windows supports directly. Since
+// Windows drawing is faster you should use windowsCanHandleTextDrawing first to
+// check if using Skia is required at all.
+// Note that the text will look different (no ClearType) so this should only be
+// used when necessary.
+//
+// When you call a Skia* text drawing function, various glyph outlines will be
+// cached. As a result, you should call SkiaWinOutlineCache::removePathsForFont
+// when the font is destroyed so that the cache does not outlive the font (since
+// the HFONTs are recycled).
+//
+// Remember that Skia's text drawing origin is the baseline, like WebKit, not
+// the top, like Windows.
+
+// Returns true if advanced font rendering is recommended.
+bool windowsCanHandleTextDrawing(GraphicsContext* context);
+
+// Note that the offsets parameter is optional. If not NULL it represents a
+// per glyph offset (such as returned by ScriptPlace Windows API function).
+//
+// Returns true of the text was drawn successfully. False indicates an error
+// from Windows.
+bool paintSkiaText(GraphicsContext* graphicsContext,
+ HFONT hfont,
+ int numGlyphs,
+ const WORD* glyphs,
+ const int* advances,
+ const GOFFSET* offsets,
+ const SkPoint* origin);
+
} // namespace WebCore
#endif // SkiaWinOutlineCache_h
diff --git a/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp b/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp
index 1e2a194..2d0f9f8 100644
--- a/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp
+++ b/WebCore/platform/graphics/skia/TransformationMatrixSkia.cpp
@@ -30,193 +30,28 @@
#include "config.h"
#include "TransformationMatrix.h"
-#include "FloatRect.h"
-#include "IntRect.h"
-
#include "SkiaUtils.h"
namespace WebCore {
-TransformationMatrix::TransformationMatrix()
-{
- m_transform.reset();
-}
-
-TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double e, double f)
-{
- setMatrix(a, b, c, d, e, f);
-}
-
-TransformationMatrix::TransformationMatrix(const SkMatrix& matrix)
- : m_transform(matrix)
-{
-}
-
-void TransformationMatrix::setMatrix(double a, double b, double c, double d, double e, double f)
-{
- m_transform.reset();
-
- m_transform.setScaleX(WebCoreDoubleToSkScalar(a));
- m_transform.setSkewX(WebCoreDoubleToSkScalar(c));
- m_transform.setTranslateX(WebCoreDoubleToSkScalar(e));
-
- m_transform.setScaleY(WebCoreDoubleToSkScalar(d));
- m_transform.setSkewY(WebCoreDoubleToSkScalar(b));
- m_transform.setTranslateY(WebCoreDoubleToSkScalar(f));
-}
-
-void TransformationMatrix::map(double x, double y, double* x2, double* y2) const
-{
- SkPoint src, dst;
- src.set(WebCoreDoubleToSkScalar(x), WebCoreDoubleToSkScalar(y));
- m_transform.mapPoints(&dst, &src, 1);
-
- *x2 = SkScalarToDouble(dst.fX);
- *y2 = SkScalarToDouble(dst.fY);
-}
-
-IntRect TransformationMatrix::mapRect(const IntRect& src) const
-{
- SkRect dst;
- m_transform.mapRect(&dst, src);
- return enclosingIntRect(dst);
-}
-
-FloatRect TransformationMatrix::mapRect(const FloatRect& src) const
-{
- SkRect dst;
- m_transform.mapRect(&dst, src);
- return dst;
-}
-
-bool TransformationMatrix::isIdentity() const
-{
- return m_transform.isIdentity();
-}
-
-void TransformationMatrix::reset()
-{
- m_transform.reset();
-}
-
-TransformationMatrix &TransformationMatrix::scale(double sx, double sy)
-{
- m_transform.preScale(WebCoreDoubleToSkScalar(sx), WebCoreDoubleToSkScalar(sy), 0, 0);
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::rotate(double d)
-{
- m_transform.preRotate(WebCoreDoubleToSkScalar(d), 0, 0);
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::translate(double tx, double ty)
-{
- m_transform.preTranslate(WebCoreDoubleToSkScalar(tx), WebCoreDoubleToSkScalar(ty));
- return *this;
-}
-
-TransformationMatrix &TransformationMatrix::shear(double sx, double sy)
-{
- m_transform.preSkew(WebCoreDoubleToSkScalar(sx), WebCoreDoubleToSkScalar(sy), 0, 0);
- return *this;
-}
-
-double TransformationMatrix::det() const
-{
- return SkScalarToDouble(m_transform.getScaleX()) * SkScalarToDouble(m_transform.getScaleY()) -
- SkScalarToDouble(m_transform.getSkewY()) * SkScalarToDouble(m_transform.getSkewX());
-}
-
-TransformationMatrix TransformationMatrix::inverse() const
-{
- TransformationMatrix inverse;
- m_transform.invert(&inverse.m_transform);
- return inverse;
-}
-
TransformationMatrix::operator SkMatrix() const
{
- return m_transform;
-}
-
-bool TransformationMatrix::operator==(const TransformationMatrix& m2) const
-{
- return m_transform == m2.m_transform;
-}
+ SkMatrix result;
-TransformationMatrix &TransformationMatrix::operator*=(const TransformationMatrix& m2)
-{
- m_transform.setConcat(m2.m_transform, m_transform);
- return *this;
-}
+ result.setScaleX(WebCoreDoubleToSkScalar(a()));
+ result.setSkewX(WebCoreDoubleToSkScalar(c()));
+ result.setTranslateX(WebCoreDoubleToSkScalar(e()));
-TransformationMatrix TransformationMatrix::operator*(const TransformationMatrix& m2)
-{
- TransformationMatrix cat;
- cat.m_transform.setConcat(m2.m_transform, m_transform);
- return cat;
-}
+ result.setScaleY(WebCoreDoubleToSkScalar(d()));
+ result.setSkewY(WebCoreDoubleToSkScalar(b()));
+ result.setTranslateY(WebCoreDoubleToSkScalar(f()));
-double TransformationMatrix::a() const
-{
- return SkScalarToDouble(m_transform.getScaleX());
-}
-
-void TransformationMatrix::setA(double a)
-{
- m_transform.setScaleX(WebCoreDoubleToSkScalar(a));
-}
-
-double TransformationMatrix::b() const
-{
- return SkScalarToDouble(m_transform.getSkewY());
-}
-
-void TransformationMatrix::setB(double b)
-{
- m_transform.setSkewY(WebCoreDoubleToSkScalar(b));
-}
+ // FIXME: Set perspective properly.
+ result.setPerspX(0);
+ result.setPerspY(0);
+ result.set(SkMatrix::kMPersp2, SK_Scalar1);
-double TransformationMatrix::c() const
-{
- return SkScalarToDouble(m_transform.getSkewX());
-}
-
-void TransformationMatrix::setC(double c)
-{
- m_transform.setSkewX(WebCoreDoubleToSkScalar(c));
-}
-
-double TransformationMatrix::d() const
-{
- return SkScalarToDouble(m_transform.getScaleY());
-}
-
-void TransformationMatrix::setD(double d)
-{
- m_transform.setScaleY(WebCoreDoubleToSkScalar(d));
-}
-
-double TransformationMatrix::e() const
-{
- return SkScalarToDouble(m_transform.getTranslateX());
-}
-
-void TransformationMatrix::setE(double e)
-{
- m_transform.setTranslateX(WebCoreDoubleToSkScalar(e));
-}
-
-double TransformationMatrix::f() const
-{
- return SkScalarToDouble(m_transform.getTranslateY());
-}
-
-void TransformationMatrix::setF(double f)
-{
- m_transform.setTranslateY(WebCoreDoubleToSkScalar(f));
+ return result;
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp b/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp
new file mode 100644
index 0000000..ab3413b
--- /dev/null
+++ b/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Matrix3DTransformOperation.h"
+
+#include <algorithm>
+
+using namespace std;
+
+namespace WebCore {
+
+PassRefPtr<TransformOperation> Matrix3DTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
+{
+ if (from && !from->isSameType(*this))
+ return this;
+
+ // Convert the TransformOperations into matrices
+ IntSize size;
+ TransformationMatrix fromT;
+ TransformationMatrix toT;
+ if (from)
+ from->apply(fromT, size);
+
+ apply(toT, size);
+
+ if (blendToIdentity)
+ swap(fromT, toT);
+
+ toT.blend(fromT, progress);
+ return Matrix3DTransformOperation::create(toT);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h b/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h
new file mode 100644
index 0000000..7430dbc
--- /dev/null
+++ b/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Matrix3DTransformOperation_h
+#define Matrix3DTransformOperation_h
+
+#include "TransformOperation.h"
+
+namespace WebCore {
+
+class Matrix3DTransformOperation : public TransformOperation {
+public:
+ static PassRefPtr<Matrix3DTransformOperation> create(const TransformationMatrix& matrix)
+ {
+ return adoptRef(new Matrix3DTransformOperation(matrix));
+ }
+
+private:
+ virtual bool isIdentity() const { return m_matrix.isIdentity(); }
+
+ virtual OperationType getOperationType() const { return MATRIX_3D; }
+ virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == MATRIX_3D; }
+
+ virtual bool operator==(const TransformOperation& o) const
+ {
+ if (!isSameType(o))
+ return false;
+ const Matrix3DTransformOperation* m = static_cast<const Matrix3DTransformOperation*>(&o);
+ return m_matrix == m->m_matrix;
+ }
+
+ virtual bool apply(TransformationMatrix& transform, const IntSize&) const
+ {
+ transform.multLeft(TransformationMatrix(m_matrix));
+ return false;
+ }
+
+ virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
+
+ Matrix3DTransformOperation(const TransformationMatrix& mat)
+ {
+ m_matrix = mat;
+ }
+
+ TransformationMatrix m_matrix;
+};
+
+} // namespace WebCore
+
+#endif // Matrix3DTransformOperation_h
diff --git a/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp b/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp
index 153d96d..4934fa6 100644
--- a/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp
+++ b/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp
@@ -24,6 +24,8 @@
#include <algorithm>
+using namespace std;
+
namespace WebCore {
PassRefPtr<TransformOperation> MatrixTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
@@ -41,7 +43,7 @@ PassRefPtr<TransformOperation> MatrixTransformOperation::blend(const TransformOp
}
if (blendToIdentity)
- std::swap(fromT, toT);
+ swap(fromT, toT);
toT.blend(fromT, progress);
return MatrixTransformOperation::create(toT.a(), toT.b(), toT.c(), toT.d(), toT.e(), toT.f());
diff --git a/WebCore/platform/graphics/transforms/MatrixTransformOperation.h b/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
index d272229..ee47a11 100644
--- a/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
+++ b/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
@@ -26,6 +26,7 @@
#define MatrixTransformOperation_h
#include "TransformOperation.h"
+#include "TransformationMatrix.h"
namespace WebCore {
@@ -36,8 +37,14 @@ public:
return adoptRef(new MatrixTransformOperation(a, b, c, d, e, f));
}
+ static PassRefPtr<MatrixTransformOperation> create(const TransformationMatrix& t)
+ {
+ return adoptRef(new MatrixTransformOperation(t));
+ }
+
private:
virtual bool isIdentity() const { return m_a == 1 && m_b == 0 && m_c == 0 && m_d == 1 && m_e == 0 && m_f == 0; }
+
virtual OperationType getOperationType() const { return MATRIX; }
virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == MATRIX; }
@@ -53,7 +60,7 @@ private:
virtual bool apply(TransformationMatrix& transform, const IntSize&) const
{
TransformationMatrix matrix(m_a, m_b, m_c, m_d, m_e, m_f);
- transform = matrix * transform;
+ transform.multLeft(TransformationMatrix(matrix));
return false;
}
@@ -68,6 +75,16 @@ private:
, m_f(f)
{
}
+
+ MatrixTransformOperation(const TransformationMatrix& t)
+ : m_a(t.a())
+ , m_b(t.b())
+ , m_c(t.c())
+ , m_d(t.d())
+ , m_e(t.e())
+ , m_f(t.f())
+ {
+ }
double m_a;
double m_b;
diff --git a/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp b/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp
new file mode 100644
index 0000000..9fd03a1
--- /dev/null
+++ b/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PerspectiveTransformOperation.h"
+
+#include <algorithm>
+
+using namespace std;
+
+namespace WebCore {
+
+PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
+{
+ if (from && !from->isSameType(*this))
+ return this;
+
+ if (blendToIdentity)
+ return PerspectiveTransformOperation::create(m_p + (1. - m_p) * progress);
+
+ const PerspectiveTransformOperation* fromOp = static_cast<const PerspectiveTransformOperation*>(from);
+ double fromP = fromOp ? fromOp->m_p : 0;
+ double toP = m_p;
+
+ TransformationMatrix fromT;
+ TransformationMatrix toT;
+ fromT.applyPerspective(fromP);
+ toT.applyPerspective(toP);
+ toT.blend(fromT, progress);
+ TransformationMatrix::DecomposedType decomp;
+ toT.decompose(decomp);
+
+ return PerspectiveTransformOperation::create(decomp.perspectiveZ ? -1.0 / decomp.perspectiveZ : 0.0);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h b/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h
new file mode 100644
index 0000000..a665f3e
--- /dev/null
+++ b/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED 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 PerspectiveTransformOperation_h
+#define PerspectiveTransformOperation_h
+
+#include "TransformOperation.h"
+
+namespace WebCore {
+
+class PerspectiveTransformOperation : public TransformOperation {
+public:
+ static PassRefPtr<PerspectiveTransformOperation> create(double p)
+ {
+ return adoptRef(new PerspectiveTransformOperation(p));
+ }
+
+private:
+ virtual bool isIdentity() const { return m_p == 0; }
+ virtual OperationType getOperationType() const { return PERSPECTIVE; }
+ virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == PERSPECTIVE; }
+
+ virtual bool operator==(const TransformOperation& o) const
+ {
+ if (!isSameType(o))
+ return false;
+ const PerspectiveTransformOperation* p = static_cast<const PerspectiveTransformOperation*>(&o);
+ return m_p == p->m_p;
+ }
+
+ virtual bool apply(TransformationMatrix& transform, const IntSize&) const
+ {
+ transform.applyPerspective(m_p);
+ return false;
+ }
+
+ virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
+
+ PerspectiveTransformOperation(double p)
+ : m_p(p)
+ {
+ }
+
+ double m_p;
+};
+
+} // namespace WebCore
+
+#endif // PerspectiveTransformOperation_h
diff --git a/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp b/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
index 4887cee..919d174 100644
--- a/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
+++ b/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
@@ -22,6 +22,11 @@
#include "config.h"
#include "RotateTransformOperation.h"
+#include <algorithm>
+#include <wtf/MathExtras.h>
+
+using namespace std;
+
namespace WebCore {
PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
@@ -30,11 +35,61 @@ PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOp
return this;
if (blendToIdentity)
- return RotateTransformOperation::create(m_angle - m_angle * progress, m_type);
+ return RotateTransformOperation::create(m_x, m_y, m_z, m_angle - m_angle * progress, m_type);
const RotateTransformOperation* fromOp = static_cast<const RotateTransformOperation*>(from);
- double fromAngle = fromOp ? fromOp->m_angle : 0;
- return RotateTransformOperation::create(fromAngle + (m_angle - fromAngle) * progress, m_type);
+
+ // Optimize for single axis rotation
+ if (!fromOp || (fromOp->m_x == 0 && fromOp->m_y == 0 && fromOp->m_z == 1) ||
+ (fromOp->m_x == 0 && fromOp->m_y == 1 && fromOp->m_z == 0) ||
+ (fromOp->m_x == 1 && fromOp->m_y == 0 && fromOp->m_z == 0)) {
+ double fromAngle = fromOp ? fromOp->m_angle : 0;
+ return RotateTransformOperation::create(fromOp ? fromOp->m_x : m_x,
+ fromOp ? fromOp->m_y : m_y,
+ fromOp ? fromOp->m_z : m_z,
+ fromAngle + (m_angle - fromAngle) * progress, m_type);
+ }
+
+ const RotateTransformOperation* toOp = this;
+
+ // Create the 2 rotation matrices
+ TransformationMatrix fromT;
+ TransformationMatrix toT;
+ fromT.rotate3d((float)(fromOp ? fromOp->m_x : 0),
+ (float)(fromOp ? fromOp->m_y : 0),
+ (float)(fromOp ? fromOp->m_z : 1),
+ (float)(fromOp ? fromOp->m_angle : 0));
+
+ toT.rotate3d((float)(toOp ? toOp->m_x : 0),
+ (float)(toOp ? toOp->m_y : 0),
+ (float)(toOp ? toOp->m_z : 1),
+ (float)(toOp ? toOp->m_angle : 0));
+
+ // Blend them
+ toT.blend(fromT, progress);
+
+ // Extract the result as a quaternion
+ TransformationMatrix::DecomposedType decomp;
+ toT.decompose(decomp);
+
+ // Convert that to Axis/Angle form
+ double x = -decomp.quaternionX;
+ double y = -decomp.quaternionY;
+ double z = -decomp.quaternionZ;
+ double length = sqrt(x * x + y * y + z * z);
+ double angle = 0;
+
+ if (length > 0.00001) {
+ x /= length;
+ y /= length;
+ z /= length;
+ angle = rad2deg(acos(decomp.quaternionW) * 2);
+ } else {
+ x = 0;
+ y = 0;
+ z = 1;
+ }
+ return RotateTransformOperation::create(x, y, z, angle, ROTATE_3D);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/RotateTransformOperation.h b/WebCore/platform/graphics/transforms/RotateTransformOperation.h
index adc6c4c..699ea43 100644
--- a/WebCore/platform/graphics/transforms/RotateTransformOperation.h
+++ b/WebCore/platform/graphics/transforms/RotateTransformOperation.h
@@ -33,10 +33,19 @@ class RotateTransformOperation : public TransformOperation {
public:
static PassRefPtr<RotateTransformOperation> create(double angle, OperationType type)
{
- return adoptRef(new RotateTransformOperation(angle, type));
+ return adoptRef(new RotateTransformOperation(0, 0, 1, angle, type));
}
+ static PassRefPtr<RotateTransformOperation> create(double x, double y, double z, double angle, OperationType type)
+ {
+ return adoptRef(new RotateTransformOperation(x, y, z, angle, type));
+ }
+
+ double angle() const { return m_angle; }
+
+private:
virtual bool isIdentity() const { return m_angle == 0; }
+
virtual OperationType getOperationType() const { return m_type; }
virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == m_type; }
@@ -45,26 +54,30 @@ public:
if (!isSameType(o))
return false;
const RotateTransformOperation* r = static_cast<const RotateTransformOperation*>(&o);
- return m_angle == r->m_angle;
+ return m_x == r->m_x && m_y == r->m_y && m_z == r->m_z && m_angle == r->m_angle;
}
virtual bool apply(TransformationMatrix& transform, const IntSize& /*borderBoxSize*/) const
{
- transform.rotate(m_angle);
+ transform.rotate3d(m_x, m_y, m_z, m_angle);
return false;
}
virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
- double angle() const { return m_angle; }
-
-private:
- RotateTransformOperation(double angle, OperationType type)
- : m_angle(angle)
+ RotateTransformOperation(double x, double y, double z, double angle, OperationType type)
+ : m_x(x)
+ , m_y(y)
+ , m_z(z)
+ , m_angle(angle)
, m_type(type)
{
+ ASSERT(type == ROTATE_X || type == ROTATE_Y || type == ROTATE_Z || type == ROTATE_3D);
}
+ double m_x;
+ double m_y;
+ double m_z;
double m_angle;
OperationType m_type;
};
diff --git a/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp b/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp
index 49a8fd8..45d119c 100644
--- a/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp
+++ b/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp
@@ -30,12 +30,17 @@ PassRefPtr<TransformOperation> ScaleTransformOperation::blend(const TransformOpe
return this;
if (blendToIdentity)
- return ScaleTransformOperation::create(m_x + (1. - m_x) * progress, m_y + (1. - m_y) * progress, m_type);
+ return ScaleTransformOperation::create(m_x + (1. - m_x) * progress,
+ m_y + (1. - m_y) * progress,
+ m_z + (1. - m_z) * progress, m_type);
const ScaleTransformOperation* fromOp = static_cast<const ScaleTransformOperation*>(from);
double fromX = fromOp ? fromOp->m_x : 1.;
double fromY = fromOp ? fromOp->m_y : 1.;
- return ScaleTransformOperation::create(fromX + (m_x - fromX) * progress, fromY + (m_y - fromY) * progress, m_type);
+ double fromZ = fromOp ? fromOp->m_z : 1.;
+ return ScaleTransformOperation::create(fromX + (m_x - fromX) * progress,
+ fromY + (m_y - fromY) * progress,
+ fromZ + (m_z - fromZ) * progress, m_type);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/ScaleTransformOperation.h b/WebCore/platform/graphics/transforms/ScaleTransformOperation.h
index 289f8a1..a87bb3b 100644
--- a/WebCore/platform/graphics/transforms/ScaleTransformOperation.h
+++ b/WebCore/platform/graphics/transforms/ScaleTransformOperation.h
@@ -33,11 +33,21 @@ class ScaleTransformOperation : public TransformOperation {
public:
static PassRefPtr<ScaleTransformOperation> create(double sx, double sy, OperationType type)
{
- return adoptRef(new ScaleTransformOperation(sx, sy, type));
+ return adoptRef(new ScaleTransformOperation(sx, sy, 1, type));
}
+ static PassRefPtr<ScaleTransformOperation> create(double sx, double sy, double sz, OperationType type)
+ {
+ return adoptRef(new ScaleTransformOperation(sx, sy, sz, type));
+ }
+
+ double x() const { return m_x; }
+ double y() const { return m_y; }
+ double z() const { return m_z; }
+
private:
- virtual bool isIdentity() const { return m_x == 1 && m_y == 1; }
+ virtual bool isIdentity() const { return m_x == 1 && m_y == 1 && m_z == 1; }
+
virtual OperationType getOperationType() const { return m_type; }
virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == m_type; }
@@ -46,26 +56,29 @@ private:
if (!isSameType(o))
return false;
const ScaleTransformOperation* s = static_cast<const ScaleTransformOperation*>(&o);
- return m_x == s->m_x && m_y == s->m_y;
+ return m_x == s->m_x && m_y == s->m_y && m_z == s->m_z;
}
virtual bool apply(TransformationMatrix& transform, const IntSize&) const
{
- transform.scale(m_x, m_y);
+ transform.scale3d(m_x, m_y, m_z);
return false;
}
virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
- ScaleTransformOperation(double sx, double sy, OperationType type)
+ ScaleTransformOperation(double sx, double sy, double sz, OperationType type)
: m_x(sx)
, m_y(sy)
+ , m_z(sz)
, m_type(type)
{
+ ASSERT(type == SCALE_X || type == SCALE_Y || type == SCALE_Z || type == SCALE || type == SCALE_3D);
}
double m_x;
double m_y;
+ double m_z;
OperationType m_type;
};
diff --git a/WebCore/platform/graphics/transforms/TransformOperation.h b/WebCore/platform/graphics/transforms/TransformOperation.h
index 65a0def..c610c4b 100644
--- a/WebCore/platform/graphics/transforms/TransformOperation.h
+++ b/WebCore/platform/graphics/transforms/TransformOperation.h
@@ -39,9 +39,16 @@ public:
enum OperationType {
SCALE_X, SCALE_Y, SCALE,
TRANSLATE_X, TRANSLATE_Y, TRANSLATE,
- ROTATE,
+ ROTATE,
+ ROTATE_Z = ROTATE,
SKEW_X, SKEW_Y, SKEW,
- MATRIX, IDENTITY, NONE
+ MATRIX,
+ SCALE_Z, SCALE_3D,
+ TRANSLATE_Z, TRANSLATE_3D,
+ ROTATE_X, ROTATE_Y, ROTATE_3D,
+ MATRIX_3D,
+ PERSPECTIVE,
+ IDENTITY, NONE
};
virtual ~TransformOperation() { }
@@ -51,12 +58,27 @@ public:
virtual bool isIdentity() const = 0;
+ // Return true if the borderBoxSize was used in the computation, false otherwise.
virtual bool apply(TransformationMatrix&, const IntSize& borderBoxSize) const = 0;
virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) = 0;
virtual OperationType getOperationType() const = 0;
virtual bool isSameType(const TransformOperation&) const { return false; }
+
+ bool is3DOperation() const
+ {
+ OperationType opType = getOperationType();
+ return opType == SCALE_Z ||
+ opType == SCALE_3D ||
+ opType == TRANSLATE_Z ||
+ opType == TRANSLATE_3D ||
+ opType == ROTATE_X ||
+ opType == ROTATE_Y ||
+ opType == ROTATE_3D ||
+ opType == MATRIX_3D ||
+ opType == PERSPECTIVE;
+ }
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/TransformOperations.h b/WebCore/platform/graphics/transforms/TransformOperations.h
index f929417..11605e8 100644
--- a/WebCore/platform/graphics/transforms/TransformOperations.h
+++ b/WebCore/platform/graphics/transforms/TransformOperations.h
@@ -47,6 +47,16 @@ public:
m_operations[i]->apply(t, sz);
}
+ // Return true if any of the operation types are 3D operation types (even if the
+ // values describe affine transforms)
+ bool has3DOperation() const
+ {
+ for (unsigned i = 0; i < m_operations.size(); ++i)
+ if (m_operations[i]->is3DOperation())
+ return true;
+ return false;
+ }
+
Vector<RefPtr<TransformOperation> >& operations() { return m_operations; }
const Vector<RefPtr<TransformOperation> >& operations() const { return m_operations; }
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
index b48d572..4bcfdb2 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "TransformationMatrix.h"
+#include "FloatPoint3D.h"
#include "FloatRect.h"
#include "FloatQuad.h"
#include "IntRect.h"
@@ -34,76 +35,467 @@
namespace WebCore {
-static void affineTransformDecompose(const TransformationMatrix& matrix, double sr[9])
+//
+// Supporting Math Functions
+//
+// This is a set of function from various places (attributed inline) to do things like
+// inversion and decomposition of a 4x4 matrix. They are used throughout the code
+//
+
+//
+// Adapted from Matrix Inversion by Richard Carling, Graphics Gems <http://tog.acm.org/GraphicsGems/index.html>.
+
+// EULA: The Graphics Gems code is copyright-protected. In other words, you cannot claim the text of the code
+// as your own and resell it. Using the code is permitted in any program, product, or library, non-commercial
+// or commercial. Giving credit is not required, though is a nice gesture. The code comes as-is, and if there
+// are any flaws or problems with any Gems code, nobody involved with Gems - authors, editors, publishers, or
+// webmasters - are to be held responsible. Basically, don't be a jerk, and remember that anything free comes
+// with no guarantee.
+
+typedef double Vector4[4];
+typedef double Vector3[3];
+
+const double SMALL_NUMBER = 1.e-8;
+
+// inverse(original_matrix, inverse_matrix)
+//
+// calculate the inverse of a 4x4 matrix
+//
+// -1
+// A = ___1__ adjoint A
+// det A
+
+// double = determinant2x2(double a, double b, double c, double d)
+//
+// calculate the determinant of a 2x2 matrix.
+
+static double determinant2x2(double a, double b, double c, double d)
{
- TransformationMatrix m(matrix);
+ return a * d - b * c;
+}
- // Compute scaling factors
- double sx = sqrt(m.a() * m.a() + m.b() * m.b());
- double sy = sqrt(m.c() * m.c() + m.d() * m.d());
+// double = determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3)
+//
+// Calculate the determinant of a 3x3 matrix
+// in the form
+//
+// | a1, b1, c1 |
+// | a2, b2, c2 |
+// | a3, b3, c3 |
- /* Compute cross product of transformed unit vectors. If negative,
- one axis was flipped. */
+static double determinant3x3(double a1, double a2, double a3, double b1, double b2, double b3, double c1, double c2, double c3)
+{
+ return a1 * determinant2x2(b2, b3, c2, c3)
+ - b1 * determinant2x2(a2, a3, c2, c3)
+ + c1 * determinant2x2(a2, a3, b2, b3);
+}
- if (m.a() * m.d() - m.c() * m.b() < 0.0) {
- // Flip axis with minimum unit vector dot product
+// double = determinant4x4(matrix)
+//
+// calculate the determinant of a 4x4 matrix.
- if (m.a() < m.d())
- sx = -sx;
- else
- sy = -sy;
- }
+static double determinant4x4(const TransformationMatrix::Matrix4& m)
+{
+ // Assign to individual variable names to aid selecting
+ // correct elements
+
+ double a1 = m[0][0];
+ double b1 = m[0][1];
+ double c1 = m[0][2];
+ double d1 = m[0][3];
+
+ double a2 = m[1][0];
+ double b2 = m[1][1];
+ double c2 = m[1][2];
+ double d2 = m[1][3];
+
+ double a3 = m[2][0];
+ double b3 = m[2][1];
+ double c3 = m[2][2];
+ double d3 = m[2][3];
+
+ double a4 = m[3][0];
+ double b4 = m[3][1];
+ double c4 = m[3][2];
+ double d4 = m[3][3];
+
+ return a1 * determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
+ - b1 * determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
+ + c1 * determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
+ - d1 * determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
+}
+
+// adjoint( original_matrix, inverse_matrix )
+//
+// calculate the adjoint of a 4x4 matrix
+//
+// Let a denote the minor determinant of matrix A obtained by
+// ij
+//
+// deleting the ith row and jth column from A.
+//
+// i+j
+// Let b = (-1) a
+// ij ji
+//
+// The matrix B = (b ) is the adjoint of A
+// ij
+
+static void adjoint(const TransformationMatrix::Matrix4& matrix, TransformationMatrix::Matrix4& result)
+{
+ // Assign to individual variable names to aid
+ // selecting correct values
+ double a1 = matrix[0][0];
+ double b1 = matrix[0][1];
+ double c1 = matrix[0][2];
+ double d1 = matrix[0][3];
- // Remove scale from matrix
+ double a2 = matrix[1][0];
+ double b2 = matrix[1][1];
+ double c2 = matrix[1][2];
+ double d2 = matrix[1][3];
- m.scale(1.0 / sx, 1.0 / sy);
+ double a3 = matrix[2][0];
+ double b3 = matrix[2][1];
+ double c3 = matrix[2][2];
+ double d3 = matrix[2][3];
- // Compute rotation
+ double a4 = matrix[3][0];
+ double b4 = matrix[3][1];
+ double c4 = matrix[3][2];
+ double d4 = matrix[3][3];
- double angle = atan2(m.b(), m.a());
+ // Row column labeling reversed since we transpose rows & columns
+ result[0][0] = determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
+ result[1][0] = - determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
+ result[2][0] = determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
+ result[3][0] = - determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
+
+ result[0][1] = - determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
+ result[1][1] = determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
+ result[2][1] = - determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
+ result[3][1] = determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
+
+ result[0][2] = determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
+ result[1][2] = - determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
+ result[2][2] = determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
+ result[3][2] = - determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
+
+ result[0][3] = - determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
+ result[1][3] = determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
+ result[2][3] = - determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
+ result[3][3] = determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
+}
+
+// Returns false if the matrix is not invertible
+static bool inverse(const TransformationMatrix::Matrix4& matrix, TransformationMatrix::Matrix4& result)
+{
+ // Calculate the adjoint matrix
+ adjoint(matrix, result);
- // Remove rotation from matrix
+ // Calculate the 4x4 determinant
+ // If the determinant is zero,
+ // then the inverse matrix is not unique.
+ double det = determinant4x4(matrix);
- m.rotate(rad2deg(-angle));
+ if (fabs(det) < SMALL_NUMBER)
+ return false;
- // Return results
+ // Scale the adjoint matrix to get the inverse
- sr[0] = sx; sr[1] = sy; sr[2] = angle;
- sr[3] = m.a(); sr[4] = m.b();
- sr[5] = m.c(); sr[6] = m.d();
- sr[7] = m.e(); sr[8] = m.f();
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ result[i][j] = result[i][j] / det;
+
+ return true;
}
-static void affineTransformCompose(TransformationMatrix& m, const double sr[9])
+// End of code adapted from Matrix Inversion by Richard Carling
+
+// Perform a decomposition on the passed matrix, return false if unsuccessful
+// From Graphics Gems: unmatrix.c
+
+// Transpose rotation portion of matrix a, return b
+static void transposeMatrix4(const TransformationMatrix::Matrix4& a, TransformationMatrix::Matrix4& b)
{
- m.setA(sr[3]);
- m.setB(sr[4]);
- m.setC(sr[5]);
- m.setD(sr[6]);
- m.setE(sr[7]);
- m.setF(sr[8]);
- m.rotate(rad2deg(sr[2]));
- m.scale(sr[0], sr[1]);
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ b[i][j] = a[j][i];
}
-bool TransformationMatrix::isInvertible() const
+// Multiply a homogeneous point by a matrix and return the transformed point
+static void v4MulPointByMatrix(const Vector4 p, const TransformationMatrix::Matrix4& m, Vector4 result)
{
- return det() != 0.0;
+ result[0] = (p[0] * m[0][0]) + (p[1] * m[1][0]) +
+ (p[2] * m[2][0]) + (p[3] * m[3][0]);
+ result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) +
+ (p[2] * m[2][1]) + (p[3] * m[3][1]);
+ result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) +
+ (p[2] * m[2][2]) + (p[3] * m[3][2]);
+ result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) +
+ (p[2] * m[2][3]) + (p[3] * m[3][3]);
}
-TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix& other)
+static double v3Length(Vector3 a)
{
- return (*this) *= other;
+ return sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2]));
}
-TransformationMatrix& TransformationMatrix::scale(double s)
+static void v3Scale(Vector3 v, double desiredLength)
{
- return scale(s, s);
+ double len = v3Length(v);
+ if (len != 0) {
+ double l = desiredLength / len;
+ v[0] *= l;
+ v[1] *= l;
+ v[2] *= l;
+ }
}
-TransformationMatrix& TransformationMatrix::scaleNonUniform(double sx, double sy)
+static double v3Dot(const Vector3 a, const Vector3 b)
{
- return scale(sx, sy);
+ return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
+}
+
+// Make a linear combination of two vectors and return the result.
+// result = (a * ascl) + (b * bscl)
+static void v3Combine(const Vector3 a, const Vector3 b, Vector3 result, double ascl, double bscl)
+{
+ result[0] = (ascl * a[0]) + (bscl * b[0]);
+ result[1] = (ascl * a[1]) + (bscl * b[1]);
+ result[2] = (ascl * a[2]) + (bscl * b[2]);
+}
+
+// Return the cross product result = a cross b */
+static void v3Cross(const Vector3 a, const Vector3 b, Vector3 result)
+{
+ result[0] = (a[1] * b[2]) - (a[2] * b[1]);
+ result[1] = (a[2] * b[0]) - (a[0] * b[2]);
+ result[2] = (a[0] * b[1]) - (a[1] * b[0]);
+}
+
+static bool decompose(const TransformationMatrix::Matrix4& mat, TransformationMatrix::DecomposedType& result)
+{
+ TransformationMatrix::Matrix4 localMatrix;
+ memcpy(localMatrix, mat, sizeof(TransformationMatrix::Matrix4));
+
+ // Normalize the matrix.
+ if (localMatrix[3][3] == 0)
+ return false;
+
+ int i, j;
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ localMatrix[i][j] /= localMatrix[3][3];
+
+ // perspectiveMatrix is used to solve for perspective, but it also provides
+ // an easy way to test for singularity of the upper 3x3 component.
+ TransformationMatrix::Matrix4 perspectiveMatrix;
+ memcpy(perspectiveMatrix, localMatrix, sizeof(TransformationMatrix::Matrix4));
+ for (i = 0; i < 3; i++)
+ perspectiveMatrix[i][3] = 0;
+ perspectiveMatrix[3][3] = 1;
+
+ if (determinant4x4(perspectiveMatrix) == 0)
+ return false;
+
+ // First, isolate perspective. This is the messiest.
+ if (localMatrix[0][3] != 0 || localMatrix[1][3] != 0 || localMatrix[2][3] != 0) {
+ // rightHandSide is the right hand side of the equation.
+ Vector4 rightHandSide;
+ rightHandSide[0] = localMatrix[0][3];
+ rightHandSide[1] = localMatrix[1][3];
+ rightHandSide[2] = localMatrix[2][3];
+ rightHandSide[3] = localMatrix[3][3];
+
+ // Solve the equation by inverting perspectiveMatrix and multiplying
+ // rightHandSide by the inverse. (This is the easiest way, not
+ // necessarily the best.)
+ TransformationMatrix::Matrix4 inversePerspectiveMatrix, transposedInversePerspectiveMatrix;
+ inverse(perspectiveMatrix, inversePerspectiveMatrix);
+ transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix);
+
+ Vector4 perspectivePoint;
+ v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint);
+
+ result.perspectiveX = perspectivePoint[0];
+ result.perspectiveY = perspectivePoint[1];
+ result.perspectiveZ = perspectivePoint[2];
+ result.perspectiveW = perspectivePoint[3];
+
+ // Clear the perspective partition
+ localMatrix[0][3] = localMatrix[1][3] = localMatrix[2][3] = 0;
+ localMatrix[3][3] = 1;
+ } else {
+ // No perspective.
+ result.perspectiveX = result.perspectiveY = result.perspectiveZ = 0;
+ result.perspectiveW = 1;
+ }
+
+ // Next take care of translation (easy).
+ result.translateX = localMatrix[3][0];
+ localMatrix[3][0] = 0;
+ result.translateY = localMatrix[3][1];
+ localMatrix[3][1] = 0;
+ result.translateZ = localMatrix[3][2];
+ localMatrix[3][2] = 0;
+
+ // Vector4 type and functions need to be added to the common set.
+ Vector3 row[3], pdum3;
+
+ // Now get scale and shear.
+ for (i = 0; i < 3; i++) {
+ row[i][0] = localMatrix[i][0];
+ row[i][1] = localMatrix[i][1];
+ row[i][2] = localMatrix[i][2];
+ }
+
+ // Compute X scale factor and normalize first row.
+ result.scaleX = v3Length(row[0]);
+ v3Scale(row[0], 1.0);
+
+ // Compute XY shear factor and make 2nd row orthogonal to 1st.
+ result.skewXY = v3Dot(row[0], row[1]);
+ v3Combine(row[1], row[0], row[1], 1.0, -result.skewXY);
+
+ // Now, compute Y scale and normalize 2nd row.
+ result.scaleY = v3Length(row[1]);
+ v3Scale(row[1], 1.0);
+ result.skewXY /= result.scaleY;
+
+ // Compute XZ and YZ shears, orthogonalize 3rd row.
+ result.skewXZ = v3Dot(row[0], row[2]);
+ v3Combine(row[2], row[0], row[2], 1.0, -result.skewXZ);
+ result.skewYZ = v3Dot(row[1], row[2]);
+ v3Combine(row[2], row[1], row[2], 1.0, -result.skewYZ);
+
+ // Next, get Z scale and normalize 3rd row.
+ result.scaleZ = v3Length(row[2]);
+ v3Scale(row[2], 1.0);
+ result.skewXZ /= result.scaleZ;
+ result.skewYZ /= result.scaleZ;
+
+ // At this point, the matrix (in rows[]) is orthonormal.
+ // Check for a coordinate system flip. If the determinant
+ // is -1, then negate the matrix and the scaling factors.
+ v3Cross(row[1], row[2], pdum3);
+ if (v3Dot(row[0], pdum3) < 0) {
+ for (i = 0; i < 3; i++) {
+ result.scaleX *= -1;
+ row[i][0] *= -1;
+ row[i][1] *= -1;
+ row[i][2] *= -1;
+ }
+ }
+
+ // Now, get the rotations out, as described in the gem.
+
+ // FIXME - Add the ability to return either quaternions (which are
+ // easier to recompose with) or Euler angles (rx, ry, rz), which
+ // are easier for authors to deal with. The latter will only be useful
+ // when we fix https://bugs.webkit.org/show_bug.cgi?id=23799, so I
+ // will leave the Euler angle code here for now.
+
+ // ret.rotateY = asin(-row[0][2]);
+ // if (cos(ret.rotateY) != 0) {
+ // ret.rotateX = atan2(row[1][2], row[2][2]);
+ // ret.rotateZ = atan2(row[0][1], row[0][0]);
+ // } else {
+ // ret.rotateX = atan2(-row[2][0], row[1][1]);
+ // ret.rotateZ = 0;
+ // }
+
+ double s, t, x, y, z, w;
+
+ t = row[0][0] + row[1][1] + row[2][2] + 1.0;
+
+ if (t > 1e-4) {
+ s = 0.5 / sqrt(t);
+ w = 0.25 / s;
+ x = (row[2][1] - row[1][2]) * s;
+ y = (row[0][2] - row[2][0]) * s;
+ z = (row[1][0] - row[0][1]) * s;
+ } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) {
+ s = sqrt (1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx
+ x = 0.25 * s;
+ y = (row[0][1] + row[1][0]) / s;
+ z = (row[0][2] + row[2][0]) / s;
+ w = (row[2][1] - row[1][2]) / s;
+ } else if (row[1][1] > row[2][2]) {
+ s = sqrt (1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy
+ x = (row[0][1] + row[1][0]) / s;
+ y = 0.25 * s;
+ z = (row[1][2] + row[2][1]) / s;
+ w = (row[0][2] - row[2][0]) / s;
+ } else {
+ s = sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz
+ x = (row[0][2] + row[2][0]) / s;
+ y = (row[1][2] + row[2][1]) / s;
+ z = 0.25 * s;
+ w = (row[1][0] - row[0][1]) / s;
+ }
+
+ result.quaternionX = x;
+ result.quaternionY = y;
+ result.quaternionZ = z;
+ result.quaternionW = w;
+
+ return true;
+}
+
+// Perform a spherical linear interpolation between the two
+// passed quaternions with 0 <= t <= 1
+static void slerp(double qa[4], const double qb[4], double t)
+{
+ double ax, ay, az, aw;
+ double bx, by, bz, bw;
+ double cx, cy, cz, cw;
+ double angle;
+ double th, invth, scale, invscale;
+
+ ax = qa[0]; ay = qa[1]; az = qa[2]; aw = qa[3];
+ bx = qb[0]; by = qb[1]; bz = qb[2]; bw = qb[3];
+
+ angle = ax * bx + ay * by + az * bz + aw * bw;
+
+ if (angle < 0.0) {
+ ax = -ax; ay = -ay;
+ az = -az; aw = -aw;
+ angle = -angle;
+ }
+
+ if (angle + 1.0 > .05) {
+ if (1.0 - angle >= .05) {
+ th = acos (angle);
+ invth = 1.0 / sin (th);
+ scale = sin (th * (1.0 - t)) * invth;
+ invscale = sin (th * t) * invth;
+ } else {
+ scale = 1.0 - t;
+ invscale = t;
+ }
+ } else {
+ bx = -ay;
+ by = ax;
+ bz = -aw;
+ bw = az;
+ scale = sin(piDouble * (.5 - t));
+ invscale = sin (piDouble * t);
+ }
+
+ cx = ax * scale + bx * invscale;
+ cy = ay * scale + by * invscale;
+ cz = az * scale + bz * invscale;
+ cw = aw * scale + bw * invscale;
+
+ qa[0] = cx; qa[1] = cy; qa[2] = cz; qa[3] = cw;
+}
+
+// End of Supporting Math Functions
+
+TransformationMatrix& TransformationMatrix::scale(double s)
+{
+ return scaleNonUniform(s, s);
}
TransformationMatrix& TransformationMatrix::rotateFromVector(double x, double y)
@@ -113,93 +505,574 @@ TransformationMatrix& TransformationMatrix::rotateFromVector(double x, double y)
TransformationMatrix& TransformationMatrix::flipX()
{
- return scale(-1.0f, 1.0f);
+ return scaleNonUniform(-1.0f, 1.0f);
}
TransformationMatrix& TransformationMatrix::flipY()
{
- return scale(1.0f, -1.0f);
+ return scaleNonUniform(1.0f, -1.0f);
}
-TransformationMatrix& TransformationMatrix::skew(double angleX, double angleY)
+FloatPoint TransformationMatrix::projectPoint(const FloatPoint& p) const
{
- return shear(tan(deg2rad(angleX)), tan(deg2rad(angleY)));
+ // This is basically raytracing. We have a point in the destination
+ // plane with z=0, and we cast a ray parallel to the z-axis from that
+ // point to find the z-position at which it intersects the z=0 plane
+ // with the transform applied. Once we have that point we apply the
+ // inverse transform to find the corresponding point in the source
+ // space.
+ //
+ // Given a plane with normal Pn, and a ray starting at point R0 and
+ // with direction defined by the vector Rd, we can find the
+ // intersection point as a distance d from R0 in units of Rd by:
+ //
+ // d = -dot (Pn', R0) / dot (Pn', Rd)
+
+ double x = p.x();
+ double y = p.y();
+ double z = -(m13() * x + m23() * y + m43()) / m33();
+
+ double outX = x * m11() + y * m21() + z * m31() + m41();
+ double outY = x * m12() + y * m22() + z * m32() + m42();
+
+ double w = x * m14() + y * m24() + z * m34() + m44();
+ if (w != 1 && w != 0) {
+ outX /= w;
+ outY /= w;
+ }
+
+ return FloatPoint(static_cast<float>(outX), static_cast<float>(outY));
}
-TransformationMatrix& TransformationMatrix::skewX(double angle)
+FloatQuad TransformationMatrix::projectQuad(const FloatQuad& q) const
{
- return shear(tan(deg2rad(angle)), 0.0f);
+ FloatQuad projectedQuad;
+ projectedQuad.setP1(projectPoint(q.p1()));
+ projectedQuad.setP2(projectPoint(q.p2()));
+ projectedQuad.setP3(projectPoint(q.p3()));
+ projectedQuad.setP4(projectPoint(q.p4()));
+ return projectedQuad;
}
-TransformationMatrix& TransformationMatrix::skewY(double angle)
+FloatPoint TransformationMatrix::mapPoint(const FloatPoint& p) const
{
- return shear(0.0f, tan(deg2rad(angle)));
+ double x, y;
+ multVecMatrix(p.x(), p.y(), x, y);
+ return FloatPoint(static_cast<float>(x), static_cast<float>(y));
}
-TransformationMatrix makeMapBetweenRects(const FloatRect& source, const FloatRect& dest)
+FloatPoint3D TransformationMatrix::mapPoint(const FloatPoint3D& p) const
{
- TransformationMatrix transform;
- transform.translate(dest.x() - source.x(), dest.y() - source.y());
- transform.scale(dest.width() / source.width(), dest.height() / source.height());
- return transform;
+ double x, y, z;
+ multVecMatrix(p.x(), p.y(), p.z(), x, y, z);
+ return FloatPoint3D(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z));
}
IntPoint TransformationMatrix::mapPoint(const IntPoint& point) const
{
- double x2, y2;
- map(point.x(), point.y(), &x2, &y2);
+ double x, y;
+ multVecMatrix(point.x(), point.y(), x, y);
// Round the point.
- return IntPoint(lround(x2), lround(y2));
+ return IntPoint(lround(x), lround(y));
+}
+
+IntRect TransformationMatrix::mapRect(const IntRect &rect) const
+{
+ return enclosingIntRect(mapRect(FloatRect(rect)));
}
-FloatPoint TransformationMatrix::mapPoint(const FloatPoint& point) const
+FloatRect TransformationMatrix::mapRect(const FloatRect& r) const
{
- double x2, y2;
- map(point.x(), point.y(), &x2, &y2);
+ FloatQuad resultQuad = mapQuad(FloatQuad(r));
+ return resultQuad.boundingBox();
+}
- return FloatPoint(static_cast<float>(x2), static_cast<float>(y2));
+FloatQuad TransformationMatrix::mapQuad(const FloatQuad& q) const
+{
+ FloatQuad result;
+ result.setP1(mapPoint(q.p1()));
+ result.setP2(mapPoint(q.p2()));
+ result.setP3(mapPoint(q.p3()));
+ result.setP4(mapPoint(q.p4()));
+ return result;
}
-FloatQuad TransformationMatrix::mapQuad(const FloatQuad& quad) const
+TransformationMatrix& TransformationMatrix::scaleNonUniform(double sx, double sy)
{
- // FIXME: avoid 4 seperate library calls. Point mapping really needs
- // to be platform-independent code.
- return FloatQuad(mapPoint(quad.p1()),
- mapPoint(quad.p2()),
- mapPoint(quad.p3()),
- mapPoint(quad.p4()));
+ TransformationMatrix mat;
+ mat.m_matrix[0][0] = sx;
+ mat.m_matrix[1][1] = sy;
+
+ multLeft(mat);
+ return *this;
}
-void TransformationMatrix::blend(const TransformationMatrix& from, double progress)
+TransformationMatrix& TransformationMatrix::scale3d(double sx, double sy, double sz)
+{
+ TransformationMatrix mat;
+ mat.m_matrix[0][0] = sx;
+ mat.m_matrix[1][1] = sy;
+ mat.m_matrix[2][2] = sz;
+
+ multLeft(mat);
+ return *this;
+}
+
+TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double z, double angle)
+{
+ // angles are in degrees. Switch to radians
+ angle = deg2rad(angle);
+
+ angle /= 2.0f;
+ double sinA = sin(angle);
+ double cosA = cos(angle);
+ double sinA2 = sinA * sinA;
+
+ // normalize
+ double length = sqrt(x * x + y * y + z * z);
+ if (length == 0) {
+ // bad vector, just use something reasonable
+ x = 0;
+ y = 0;
+ z = 1;
+ } else if (length != 1) {
+ x /= length;
+ y /= length;
+ z /= length;
+ }
+
+ TransformationMatrix mat;
+
+ // optimize case where axis is along major axis
+ if (x == 1.0f && y == 0.0f && z == 0.0f) {
+ mat.m_matrix[0][0] = 1.0f;
+ mat.m_matrix[0][1] = 0.0f;
+ mat.m_matrix[0][2] = 0.0f;
+ mat.m_matrix[1][0] = 0.0f;
+ mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[1][2] = 2.0f * sinA * cosA;
+ mat.m_matrix[2][0] = 0.0f;
+ mat.m_matrix[2][1] = -2.0f * sinA * cosA;
+ mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+ } else if (x == 0.0f && y == 1.0f && z == 0.0f) {
+ mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][1] = 0.0f;
+ mat.m_matrix[0][2] = -2.0f * sinA * cosA;
+ mat.m_matrix[1][0] = 0.0f;
+ mat.m_matrix[1][1] = 1.0f;
+ mat.m_matrix[1][2] = 0.0f;
+ mat.m_matrix[2][0] = 2.0f * sinA * cosA;
+ mat.m_matrix[2][1] = 0.0f;
+ mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+ } else if (x == 0.0f && y == 0.0f && z == 1.0f) {
+ mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][1] = 2.0f * sinA * cosA;
+ mat.m_matrix[0][2] = 0.0f;
+ mat.m_matrix[1][0] = -2.0f * sinA * cosA;
+ mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[1][2] = 0.0f;
+ mat.m_matrix[2][0] = 0.0f;
+ mat.m_matrix[2][1] = 0.0f;
+ mat.m_matrix[2][2] = 1.0f;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+ } else {
+ double x2 = x*x;
+ double y2 = y*y;
+ double z2 = z*z;
+
+ mat.m_matrix[0][0] = 1.0f - 2.0f * (y2 + z2) * sinA2;
+ mat.m_matrix[0][1] = 2.0f * (x * y * sinA2 + z * sinA * cosA);
+ mat.m_matrix[0][2] = 2.0f * (x * z * sinA2 - y * sinA * cosA);
+ mat.m_matrix[1][0] = 2.0f * (y * x * sinA2 - z * sinA * cosA);
+ mat.m_matrix[1][1] = 1.0f - 2.0f * (z2 + x2) * sinA2;
+ mat.m_matrix[1][2] = 2.0f * (y * z * sinA2 + x * sinA * cosA);
+ mat.m_matrix[2][0] = 2.0f * (z * x * sinA2 + y * sinA * cosA);
+ mat.m_matrix[2][1] = 2.0f * (z * y * sinA2 - x * sinA * cosA);
+ mat.m_matrix[2][2] = 1.0f - 2.0f * (x2 + y2) * sinA2;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+ }
+ multLeft(mat);
+ return *this;
+}
+
+TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, double rz)
+{
+ // angles are in degrees. Switch to radians
+ rx = deg2rad(rx);
+ ry = deg2rad(ry);
+ rz = deg2rad(rz);
+
+ TransformationMatrix mat;
+
+ rz /= 2.0f;
+ double sinA = sin(rz);
+ double cosA = cos(rz);
+ double sinA2 = sinA * sinA;
+
+ mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][1] = 2.0f * sinA * cosA;
+ mat.m_matrix[0][2] = 0.0f;
+ mat.m_matrix[1][0] = -2.0f * sinA * cosA;
+ mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[1][2] = 0.0f;
+ mat.m_matrix[2][0] = 0.0f;
+ mat.m_matrix[2][1] = 0.0f;
+ mat.m_matrix[2][2] = 1.0f;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+
+ TransformationMatrix rmat(mat);
+
+ ry /= 2.0f;
+ sinA = sin(ry);
+ cosA = cos(ry);
+ sinA2 = sinA * sinA;
+
+ mat.m_matrix[0][0] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][1] = 0.0f;
+ mat.m_matrix[0][2] = -2.0f * sinA * cosA;
+ mat.m_matrix[1][0] = 0.0f;
+ mat.m_matrix[1][1] = 1.0f;
+ mat.m_matrix[1][2] = 0.0f;
+ mat.m_matrix[2][0] = 2.0f * sinA * cosA;
+ mat.m_matrix[2][1] = 0.0f;
+ mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+
+ rmat.multLeft(mat);
+
+ rx /= 2.0f;
+ sinA = sin(rx);
+ cosA = cos(rx);
+ sinA2 = sinA * sinA;
+
+ mat.m_matrix[0][0] = 1.0f;
+ mat.m_matrix[0][1] = 0.0f;
+ mat.m_matrix[0][2] = 0.0f;
+ mat.m_matrix[1][0] = 0.0f;
+ mat.m_matrix[1][1] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[1][2] = 2.0f * sinA * cosA;
+ mat.m_matrix[2][0] = 0.0f;
+ mat.m_matrix[2][1] = -2.0f * sinA * cosA;
+ mat.m_matrix[2][2] = 1.0f - 2.0f * sinA2;
+ mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0f;
+ mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0f;
+ mat.m_matrix[3][3] = 1.0f;
+
+ rmat.multLeft(mat);
+
+ multLeft(rmat);
+ return *this;
+}
+
+TransformationMatrix& TransformationMatrix::translate(double tx, double ty)
+{
+ // FIXME: optimize to avoid matrix copy
+ TransformationMatrix mat;
+ mat.m_matrix[3][0] = tx;
+ mat.m_matrix[3][1] = ty;
+
+ multLeft(mat);
+ return *this;
+}
+
+TransformationMatrix& TransformationMatrix::translate3d(double tx, double ty, double tz)
{
- double srA[9], srB[9];
+ // FIXME: optimize to avoid matrix copy
+ TransformationMatrix mat;
+ mat.m_matrix[3][0] = tx;
+ mat.m_matrix[3][1] = ty;
+ mat.m_matrix[3][2] = tz;
- affineTransformDecompose(from, srA);
- affineTransformDecompose(*this, srB);
+ multLeft(mat);
+ return *this;
+}
- // If x-axis of one is flipped, and y-axis of the other, convert to an unflipped rotation.
- if ((srA[0] < 0.0 && srB[1] < 0.0) || (srA[1] < 0.0 && srB[0] < 0.0)) {
- srA[0] = -srA[0];
- srA[1] = -srA[1];
- srA[2] += srA[2] < 0 ? piDouble : -piDouble;
+TransformationMatrix& TransformationMatrix::translateRight(double tx, double ty)
+{
+ if (tx != 0) {
+ m_matrix[0][0] += m_matrix[0][3] * tx;
+ m_matrix[1][0] += m_matrix[1][3] * tx;
+ m_matrix[2][0] += m_matrix[2][3] * tx;
+ m_matrix[3][0] += m_matrix[3][3] * tx;
}
- // Don't rotate the long way around.
- srA[2] = fmod(srA[2], 2.0 * piDouble);
- srB[2] = fmod(srB[2], 2.0 * piDouble);
+ if (ty != 0) {
+ m_matrix[0][1] += m_matrix[0][3] * ty;
+ m_matrix[1][1] += m_matrix[1][3] * ty;
+ m_matrix[2][1] += m_matrix[2][3] * ty;
+ m_matrix[3][1] += m_matrix[3][3] * ty;
+ }
- if (fabs(srA[2] - srB[2]) > piDouble) {
- if (srA[2] > srB[2])
- srA[2] -= piDouble * 2.0;
- else
- srB[2] -= piDouble * 2.0;
+ return *this;
+}
+
+TransformationMatrix& TransformationMatrix::translateRight3d(double tx, double ty, double tz)
+{
+ translateRight(tx, ty);
+ if (tz != 0) {
+ m_matrix[0][2] += m_matrix[0][3] * tz;
+ m_matrix[1][2] += m_matrix[1][3] * tz;
+ m_matrix[2][2] += m_matrix[2][3] * tz;
+ m_matrix[3][2] += m_matrix[3][3] * tz;
}
- for (int i = 0; i < 9; i++)
- srA[i] = srA[i] + progress * (srB[i] - srA[i]);
+ return *this;
+}
+
+TransformationMatrix& TransformationMatrix::skew(double sx, double sy)
+{
+ // angles are in degrees. Switch to radians
+ sx = deg2rad(sx);
+ sy = deg2rad(sy);
+
+ TransformationMatrix mat;
+ mat.m_matrix[0][1] = tan(sy); // note that the y shear goes in the first row
+ mat.m_matrix[1][0] = tan(sx); // and the x shear in the second row
+
+ multLeft(mat);
+ return *this;
+}
- affineTransformCompose(*this, srA);
+TransformationMatrix& TransformationMatrix::applyPerspective(double p)
+{
+ TransformationMatrix mat;
+ if (p != 0)
+ mat.m_matrix[2][3] = -1/p;
+
+ multLeft(mat);
+ return *this;
+}
+
+//
+// *this = mat * *this
+//
+TransformationMatrix& TransformationMatrix::multLeft(const TransformationMatrix& mat)
+{
+ Matrix4 tmp;
+
+ tmp[0][0] = (mat.m_matrix[0][0] * m_matrix[0][0] + mat.m_matrix[0][1] * m_matrix[1][0]
+ + mat.m_matrix[0][2] * m_matrix[2][0] + mat.m_matrix[0][3] * m_matrix[3][0]);
+ tmp[0][1] = (mat.m_matrix[0][0] * m_matrix[0][1] + mat.m_matrix[0][1] * m_matrix[1][1]
+ + mat.m_matrix[0][2] * m_matrix[2][1] + mat.m_matrix[0][3] * m_matrix[3][1]);
+ tmp[0][2] = (mat.m_matrix[0][0] * m_matrix[0][2] + mat.m_matrix[0][1] * m_matrix[1][2]
+ + mat.m_matrix[0][2] * m_matrix[2][2] + mat.m_matrix[0][3] * m_matrix[3][2]);
+ tmp[0][3] = (mat.m_matrix[0][0] * m_matrix[0][3] + mat.m_matrix[0][1] * m_matrix[1][3]
+ + mat.m_matrix[0][2] * m_matrix[2][3] + mat.m_matrix[0][3] * m_matrix[3][3]);
+
+ tmp[1][0] = (mat.m_matrix[1][0] * m_matrix[0][0] + mat.m_matrix[1][1] * m_matrix[1][0]
+ + mat.m_matrix[1][2] * m_matrix[2][0] + mat.m_matrix[1][3] * m_matrix[3][0]);
+ tmp[1][1] = (mat.m_matrix[1][0] * m_matrix[0][1] + mat.m_matrix[1][1] * m_matrix[1][1]
+ + mat.m_matrix[1][2] * m_matrix[2][1] + mat.m_matrix[1][3] * m_matrix[3][1]);
+ tmp[1][2] = (mat.m_matrix[1][0] * m_matrix[0][2] + mat.m_matrix[1][1] * m_matrix[1][2]
+ + mat.m_matrix[1][2] * m_matrix[2][2] + mat.m_matrix[1][3] * m_matrix[3][2]);
+ tmp[1][3] = (mat.m_matrix[1][0] * m_matrix[0][3] + mat.m_matrix[1][1] * m_matrix[1][3]
+ + mat.m_matrix[1][2] * m_matrix[2][3] + mat.m_matrix[1][3] * m_matrix[3][3]);
+
+ tmp[2][0] = (mat.m_matrix[2][0] * m_matrix[0][0] + mat.m_matrix[2][1] * m_matrix[1][0]
+ + mat.m_matrix[2][2] * m_matrix[2][0] + mat.m_matrix[2][3] * m_matrix[3][0]);
+ tmp[2][1] = (mat.m_matrix[2][0] * m_matrix[0][1] + mat.m_matrix[2][1] * m_matrix[1][1]
+ + mat.m_matrix[2][2] * m_matrix[2][1] + mat.m_matrix[2][3] * m_matrix[3][1]);
+ tmp[2][2] = (mat.m_matrix[2][0] * m_matrix[0][2] + mat.m_matrix[2][1] * m_matrix[1][2]
+ + mat.m_matrix[2][2] * m_matrix[2][2] + mat.m_matrix[2][3] * m_matrix[3][2]);
+ tmp[2][3] = (mat.m_matrix[2][0] * m_matrix[0][3] + mat.m_matrix[2][1] * m_matrix[1][3]
+ + mat.m_matrix[2][2] * m_matrix[2][3] + mat.m_matrix[2][3] * m_matrix[3][3]);
+
+ tmp[3][0] = (mat.m_matrix[3][0] * m_matrix[0][0] + mat.m_matrix[3][1] * m_matrix[1][0]
+ + mat.m_matrix[3][2] * m_matrix[2][0] + mat.m_matrix[3][3] * m_matrix[3][0]);
+ tmp[3][1] = (mat.m_matrix[3][0] * m_matrix[0][1] + mat.m_matrix[3][1] * m_matrix[1][1]
+ + mat.m_matrix[3][2] * m_matrix[2][1] + mat.m_matrix[3][3] * m_matrix[3][1]);
+ tmp[3][2] = (mat.m_matrix[3][0] * m_matrix[0][2] + mat.m_matrix[3][1] * m_matrix[1][2]
+ + mat.m_matrix[3][2] * m_matrix[2][2] + mat.m_matrix[3][3] * m_matrix[3][2]);
+ tmp[3][3] = (mat.m_matrix[3][0] * m_matrix[0][3] + mat.m_matrix[3][1] * m_matrix[1][3]
+ + mat.m_matrix[3][2] * m_matrix[2][3] + mat.m_matrix[3][3] * m_matrix[3][3]);
+
+ setMatrix(tmp);
+ return *this;
+}
+
+void TransformationMatrix::multVecMatrix(double x, double y, double& resultX, double& resultY) const
+{
+ resultX = m_matrix[3][0] + x * m_matrix[0][0] + y * m_matrix[1][0];
+ resultY = m_matrix[3][1] + x * m_matrix[0][1] + y * m_matrix[1][1];
+ double w = m_matrix[3][3] + x * m_matrix[0][3] + y * m_matrix[1][3];
+ if (w != 1 && w != 0) {
+ resultX /= w;
+ resultY /= w;
+ }
+}
+
+void TransformationMatrix::multVecMatrix(double x, double y, double z, double& resultX, double& resultY, double& resultZ) const
+{
+ resultX = m_matrix[3][0] + x * m_matrix[0][0] + y * m_matrix[1][0] + z * m_matrix[2][0];
+ resultY = m_matrix[3][1] + x * m_matrix[0][1] + y * m_matrix[1][1] + z * m_matrix[2][1];
+ resultZ = m_matrix[3][2] + x * m_matrix[0][2] + y * m_matrix[1][2] + z * m_matrix[2][2];
+ double w = m_matrix[3][3] + x * m_matrix[0][3] + y * m_matrix[1][3] + z * m_matrix[2][3];
+ if (w != 1 && w != 0) {
+ resultX /= w;
+ resultY /= w;
+ resultZ /= w;
+ }
+}
+
+bool TransformationMatrix::isInvertible() const
+{
+ double det = WebCore::determinant4x4(m_matrix);
+
+ if (fabs(det) < SMALL_NUMBER)
+ return false;
+
+ return true;
+}
+
+TransformationMatrix TransformationMatrix::inverse() const
+{
+ TransformationMatrix invMat;
+
+ bool inverted = WebCore::inverse(m_matrix, invMat.m_matrix);
+ if (!inverted)
+ return TransformationMatrix();
+
+ return invMat;
+}
+
+void TransformationMatrix::makeAffine()
+{
+ m_matrix[0][2] = 0;
+ m_matrix[0][3] = 0;
+
+ m_matrix[1][2] = 0;
+ m_matrix[1][3] = 0;
+
+ m_matrix[2][0] = 0;
+ m_matrix[2][1] = 0;
+ m_matrix[2][2] = 1;
+ m_matrix[2][3] = 0;
+
+ m_matrix[3][2] = 0;
+ m_matrix[3][3] = 1;
+}
+
+static inline void blendFloat(double& from, double to, double progress)
+{
+ if (from != to)
+ from = from + (to - from) * progress;
+}
+
+void TransformationMatrix::blend(const TransformationMatrix& from, double progress)
+{
+ if (from.isIdentity() && isIdentity())
+ return;
+
+ // decompose
+ DecomposedType fromDecomp;
+ DecomposedType toDecomp;
+ from.decompose(fromDecomp);
+ decompose(toDecomp);
+
+ // interpolate
+ blendFloat(fromDecomp.scaleX, toDecomp.scaleX, progress);
+ blendFloat(fromDecomp.scaleY, toDecomp.scaleY, progress);
+ blendFloat(fromDecomp.scaleZ, toDecomp.scaleZ, progress);
+ blendFloat(fromDecomp.skewXY, toDecomp.skewXY, progress);
+ blendFloat(fromDecomp.skewXZ, toDecomp.skewXZ, progress);
+ blendFloat(fromDecomp.skewYZ, toDecomp.skewYZ, progress);
+ blendFloat(fromDecomp.translateX, toDecomp.translateX, progress);
+ blendFloat(fromDecomp.translateY, toDecomp.translateY, progress);
+ blendFloat(fromDecomp.translateZ, toDecomp.translateZ, progress);
+ blendFloat(fromDecomp.perspectiveX, toDecomp.perspectiveX, progress);
+ blendFloat(fromDecomp.perspectiveY, toDecomp.perspectiveY, progress);
+ blendFloat(fromDecomp.perspectiveZ, toDecomp.perspectiveZ, progress);
+ blendFloat(fromDecomp.perspectiveW, toDecomp.perspectiveW, progress);
+
+ slerp(&fromDecomp.quaternionX, &toDecomp.quaternionX, progress);
+
+ // recompose
+ recompose(fromDecomp);
+}
+
+bool TransformationMatrix::decompose(DecomposedType& decomp) const
+{
+ if (isIdentity()) {
+ memset(&decomp, 0, sizeof(decomp));
+ decomp.perspectiveW = 1;
+ decomp.scaleX = 1;
+ decomp.scaleY = 1;
+ decomp.scaleZ = 1;
+ }
+
+ if (!WebCore::decompose(m_matrix, decomp))
+ return false;
+ return true;
+}
+
+void TransformationMatrix::recompose(const DecomposedType& decomp)
+{
+ makeIdentity();
+
+ // first apply perspective
+ m_matrix[0][3] = (float) decomp.perspectiveX;
+ m_matrix[1][3] = (float) decomp.perspectiveY;
+ m_matrix[2][3] = (float) decomp.perspectiveZ;
+ m_matrix[3][3] = (float) decomp.perspectiveW;
+
+ // now translate
+ translate3d((float) decomp.translateX, (float) decomp.translateY, (float) decomp.translateZ);
+
+ // apply rotation
+ double xx = decomp.quaternionX * decomp.quaternionX;
+ double xy = decomp.quaternionX * decomp.quaternionY;
+ double xz = decomp.quaternionX * decomp.quaternionZ;
+ double xw = decomp.quaternionX * decomp.quaternionW;
+ double yy = decomp.quaternionY * decomp.quaternionY;
+ double yz = decomp.quaternionY * decomp.quaternionZ;
+ double yw = decomp.quaternionY * decomp.quaternionW;
+ double zz = decomp.quaternionZ * decomp.quaternionZ;
+ double zw = decomp.quaternionZ * decomp.quaternionW;
+
+ // Construct a composite rotation matrix from the quaternion values
+ TransformationMatrix rotationMatrix(1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0,
+ 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0,
+ 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0,
+ 0, 0, 0, 1);
+
+ multLeft(rotationMatrix);
+
+ // now apply skew
+ if (decomp.skewYZ) {
+ TransformationMatrix tmp;
+ tmp.setM32((float) decomp.skewYZ);
+ multLeft(tmp);
+ }
+
+ if (decomp.skewXZ) {
+ TransformationMatrix tmp;
+ tmp.setM31((float) decomp.skewXZ);
+ multLeft(tmp);
+ }
+
+ if (decomp.skewXY) {
+ TransformationMatrix tmp;
+ tmp.setM21((float) decomp.skewXY);
+ multLeft(tmp);
+ }
+
+ // finally, apply scale
+ scale3d((float) decomp.scaleX, (float) decomp.scaleY, (float) decomp.scaleZ);
}
}
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.h b/WebCore/platform/graphics/transforms/TransformationMatrix.h
index db121d1..62e4eb8 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -28,112 +28,293 @@
#if PLATFORM(CG)
#include <CoreGraphics/CGAffineTransform.h>
-typedef CGAffineTransform PlatformTransformationMatrix;
-#elif PLATFORM(QT)
-#include <QMatrix>
-typedef QMatrix PlatformTransformationMatrix;
#elif PLATFORM(CAIRO)
#include <cairo.h>
-typedef cairo_matrix_t PlatformTransformationMatrix;
+#elif PLATFORM(QT)
+#include <QTransform>
#elif PLATFORM(SKIA) || PLATFORM(SGL)
-#include "SkMatrix.h"
-typedef SkMatrix PlatformTransformationMatrix;
+#include <SkMatrix.h>
#elif PLATFORM(WX) && USE(WXGC)
-#include <wx/defs.h>
#include <wx/graphics.h>
-typedef wxGraphicsMatrix PlatformTransformationMatrix;
#endif
+#include <string.h> //for memcpy
+
namespace WebCore {
class IntPoint;
class IntRect;
class FloatPoint;
+class FloatPoint3D;
class FloatRect;
class FloatQuad;
class TransformationMatrix {
public:
- TransformationMatrix();
- TransformationMatrix(double a, double b, double c, double d, double e, double f);
-#if !PLATFORM(WX) || USE(WXGC)
- TransformationMatrix(const PlatformTransformationMatrix&);
-#endif
+ typedef double Matrix4[4][4];
- void setMatrix(double a, double b, double c, double d, double e, double f);
- void map(double x, double y, double *x2, double *y2) const;
+ TransformationMatrix() { makeIdentity(); }
+ TransformationMatrix(const TransformationMatrix& t) { *this = t; }
+ TransformationMatrix(double a, double b, double c, double d, double e, double f) { setMatrix(a, b, c, d, e, f); }
+ TransformationMatrix(double m11, double m12, double m13, double m14,
+ double m21, double m22, double m23, double m24,
+ double m31, double m32, double m33, double m34,
+ double m41, double m42, double m43, double m44)
+ {
+ setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
+ }
- // Rounds the mapped point to the nearest integer value.
- IntPoint mapPoint(const IntPoint&) const;
+ void setMatrix(double a, double b, double c, double d, double e, double f)
+ {
+ m_matrix[0][0] = a; m_matrix[0][1] = b; m_matrix[0][2] = 0; m_matrix[0][3] = 0;
+ m_matrix[1][0] = c; m_matrix[1][1] = d; m_matrix[1][2] = 0; m_matrix[1][3] = 0;
+ m_matrix[2][0] = 0; m_matrix[2][1] = 0; m_matrix[2][2] = 1; m_matrix[2][3] = 0;
+ m_matrix[3][0] = e; m_matrix[3][1] = f; m_matrix[3][2] = 0; m_matrix[3][3] = 1;
+ }
+
+ void setMatrix(double m11, double m12, double m13, double m14,
+ double m21, double m22, double m23, double m24,
+ double m31, double m32, double m33, double m34,
+ double m41, double m42, double m43, double m44)
+ {
+ m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13; m_matrix[0][3] = m14;
+ m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23; m_matrix[1][3] = m24;
+ m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33; m_matrix[2][3] = m34;
+ m_matrix[3][0] = m41; m_matrix[3][1] = m42; m_matrix[3][2] = m43; m_matrix[3][3] = m44;
+ }
+
+ TransformationMatrix& operator =(const TransformationMatrix &t)
+ {
+ setMatrix(t.m_matrix);
+ return *this;
+ }
+
+ TransformationMatrix& makeIdentity()
+ {
+ setMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+ return *this;
+ }
+
+ bool isIdentity() const
+ {
+ return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 &&
+ m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 &&
+ m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 &&
+ m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0 && m_matrix[3][3] == 1;
+ }
+
+ // This form preserves the double math from input to output
+ void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x, y, x2, y2); }
+ // Map a 3D point through the transform, returning a 3D point.
+ FloatPoint3D mapPoint(const FloatPoint3D&) const;
+
+ // Map a 2D point through the transform, returning a 2D point.
+ // Note that this ignores the z component, effectively projecting the point into the z=0 plane.
FloatPoint mapPoint(const FloatPoint&) const;
+ // Like the version above, except that it rounds the mapped point to the nearest integer value.
+ IntPoint mapPoint(const IntPoint&) const;
+
+ // If the matrix has 3D components, the z component of the result is
+ // dropped, effectively projecting the rect into the z=0 plane
+ FloatRect mapRect(const FloatRect&) const;
+
// Rounds the resulting mapped rectangle out. This is helpful for bounding
// box computations but may not be what is wanted in other contexts.
IntRect mapRect(const IntRect&) const;
- FloatRect mapRect(const FloatRect&) const;
-
+ // If the matrix has 3D components, the z component of the result is
+ // dropped, effectively projecting the quad into the z=0 plane
FloatQuad mapQuad(const FloatQuad&) const;
- bool isIdentity() const;
+ // Map a point on the z=0 plane into a point on
+ // the plane with with the transform applied, by extending
+ // a ray perpendicular to the source plane and computing
+ // the local x,y position of the point where that ray intersects
+ // with the destination plane.
+ FloatPoint projectPoint(const FloatPoint&) const;
+ // Projects the four corners of the quad
+ FloatQuad projectQuad(const FloatQuad&) const;
- double a() const;
- void setA(double a);
+ double m11() const { return m_matrix[0][0]; }
+ void setM11(double f) { m_matrix[0][0] = f; }
+ double m12() const { return m_matrix[0][1]; }
+ void setM12(double f) { m_matrix[0][1] = f; }
+ double m13() const { return m_matrix[0][2]; }
+ void setM13(double f) { m_matrix[0][2] = f; }
+ double m14() const { return m_matrix[0][3]; }
+ void setM14(double f) { m_matrix[0][3] = f; }
+ double m21() const { return m_matrix[1][0]; }
+ void setM21(double f) { m_matrix[1][0] = f; }
+ double m22() const { return m_matrix[1][1]; }
+ void setM22(double f) { m_matrix[1][1] = f; }
+ double m23() const { return m_matrix[1][2]; }
+ void setM23(double f) { m_matrix[1][2] = f; }
+ double m24() const { return m_matrix[1][3]; }
+ void setM24(double f) { m_matrix[1][3] = f; }
+ double m31() const { return m_matrix[2][0]; }
+ void setM31(double f) { m_matrix[2][0] = f; }
+ double m32() const { return m_matrix[2][1]; }
+ void setM32(double f) { m_matrix[2][1] = f; }
+ double m33() const { return m_matrix[2][2]; }
+ void setM33(double f) { m_matrix[2][2] = f; }
+ double m34() const { return m_matrix[2][3]; }
+ void setM34(double f) { m_matrix[2][3] = f; }
+ double m41() const { return m_matrix[3][0]; }
+ void setM41(double f) { m_matrix[3][0] = f; }
+ double m42() const { return m_matrix[3][1]; }
+ void setM42(double f) { m_matrix[3][1] = f; }
+ double m43() const { return m_matrix[3][2]; }
+ void setM43(double f) { m_matrix[3][2] = f; }
+ double m44() const { return m_matrix[3][3]; }
+ void setM44(double f) { m_matrix[3][3] = f; }
+
+ double a() const { return m_matrix[0][0]; }
+ void setA(double a) { m_matrix[0][0] = a; }
- double b() const;
- void setB(double b);
+ double b() const { return m_matrix[0][1]; }
+ void setB(double b) { m_matrix[0][1] = b; }
- double c() const;
- void setC(double c);
+ double c() const { return m_matrix[1][0]; }
+ void setC(double c) { m_matrix[1][0] = c; }
- double d() const;
- void setD(double d);
+ double d() const { return m_matrix[1][1]; }
+ void setD(double d) { m_matrix[1][1] = d; }
- double e() const;
- void setE(double e);
+ double e() const { return m_matrix[3][0]; }
+ void setE(double e) { m_matrix[3][0] = e; }
- double f() const;
- void setF(double f);
+ double f() const { return m_matrix[3][1]; }
+ void setF(double f) { m_matrix[3][1] = f; }
- void reset();
+ // this = this * mat
+ TransformationMatrix& multiply(const TransformationMatrix& t) { return *this *= t; }
- TransformationMatrix& multiply(const TransformationMatrix&);
+ // this = mat * this
+ TransformationMatrix& multLeft(const TransformationMatrix& mat);
+
TransformationMatrix& scale(double);
- TransformationMatrix& scale(double sx, double sy);
TransformationMatrix& scaleNonUniform(double sx, double sy);
- TransformationMatrix& rotate(double d);
+ TransformationMatrix& scale3d(double sx, double sy, double sz);
+
+ TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); }
TransformationMatrix& rotateFromVector(double x, double y);
+ TransformationMatrix& rotate3d(double rx, double ry, double rz);
+
+ // The vector (x,y,z) is normalized if it's not already. A vector of
+ // (0,0,0) uses a vector of (0,0,1).
+ TransformationMatrix& rotate3d(double x, double y, double z, double angle);
+
TransformationMatrix& translate(double tx, double ty);
- TransformationMatrix& shear(double sx, double sy);
+ TransformationMatrix& translate3d(double tx, double ty, double tz);
+
+ // translation added with a post-multiply
+ TransformationMatrix& translateRight(double tx, double ty);
+ TransformationMatrix& translateRight3d(double tx, double ty, double tz);
+
TransformationMatrix& flipX();
TransformationMatrix& flipY();
TransformationMatrix& skew(double angleX, double angleY);
- TransformationMatrix& skewX(double angle);
- TransformationMatrix& skewY(double angle);
+ TransformationMatrix& skewX(double angle) { return skew(angle, 0); }
+ TransformationMatrix& skewY(double angle) { return skew(0, angle); }
+
+ TransformationMatrix& applyPerspective(double p);
+ bool hasPerspective() const { return m_matrix[2][3] != 0.0f; }
- double det() const;
bool isInvertible() const;
+
+ // This method returns the identity matrix if it is not invertible.
+ // Use isInvertible() before calling this if you need to know.
TransformationMatrix inverse() const;
+ // decompose the matrix into its component parts
+ typedef struct {
+ double scaleX, scaleY, scaleZ;
+ double skewXY, skewXZ, skewYZ;
+ double quaternionX, quaternionY, quaternionZ, quaternionW;
+ double translateX, translateY, translateZ;
+ double perspectiveX, perspectiveY, perspectiveZ, perspectiveW;
+ } DecomposedType;
+
+ bool decompose(DecomposedType& decomp) const;
+ void recompose(const DecomposedType& decomp);
+
void blend(const TransformationMatrix& from, double progress);
-#if !PLATFORM(WX) || USE(WXGC)
- operator PlatformTransformationMatrix() const;
-#endif
+ bool isAffine() const
+ {
+ return (m13() == 0 && m14() == 0 && m23() == 0 && m24() == 0 &&
+ m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() == 0 && m44() == 1);
+ }
+
+ // Throw away the non-affine parts of the matrix (lossy!)
+ void makeAffine();
+
+ bool operator==(const TransformationMatrix& m2) const
+ {
+ return (m_matrix[0][0] == m2.m_matrix[0][0] &&
+ m_matrix[0][1] == m2.m_matrix[0][1] &&
+ m_matrix[0][2] == m2.m_matrix[0][2] &&
+ m_matrix[0][3] == m2.m_matrix[0][3] &&
+ m_matrix[1][0] == m2.m_matrix[1][0] &&
+ m_matrix[1][1] == m2.m_matrix[1][1] &&
+ m_matrix[1][2] == m2.m_matrix[1][2] &&
+ m_matrix[1][3] == m2.m_matrix[1][3] &&
+ m_matrix[2][0] == m2.m_matrix[2][0] &&
+ m_matrix[2][1] == m2.m_matrix[2][1] &&
+ m_matrix[2][2] == m2.m_matrix[2][2] &&
+ m_matrix[2][3] == m2.m_matrix[2][3] &&
+ m_matrix[3][0] == m2.m_matrix[3][0] &&
+ m_matrix[3][1] == m2.m_matrix[3][1] &&
+ m_matrix[3][2] == m2.m_matrix[3][2] &&
+ m_matrix[3][3] == m2.m_matrix[3][3]);
+ }
- bool operator==(const TransformationMatrix&) const;
bool operator!=(const TransformationMatrix& other) const { return !(*this == other); }
- TransformationMatrix& operator*=(const TransformationMatrix&);
- TransformationMatrix operator*(const TransformationMatrix&);
+
+ // *this = *this * t (i.e., a multRight)
+ TransformationMatrix& operator*=(const TransformationMatrix& t)
+ {
+ *this = *this * t;
+ return *this;
+ }
+
+ // result = *this * t (i.e., a multRight)
+ TransformationMatrix operator*(const TransformationMatrix& t)
+ {
+ TransformationMatrix result = t;
+ result.multLeft(*this);
+ return result;
+ }
-private:
-#if !PLATFORM(WX) || USE(WXGC)
- PlatformTransformationMatrix m_transform;
+#if PLATFORM(CG)
+ operator CGAffineTransform() const;
+#elif PLATFORM(CAIRO)
+ operator cairo_matrix_t() const;
+#elif PLATFORM(QT)
+ operator QTransform() const;
+#elif PLATFORM(SKIA) || PLATFORM(SGL)
+ operator SkMatrix() const;
+#elif PLATFORM(WX) && USE(WXGC)
+ operator wxGraphicsMatrix() const;
#endif
-};
-TransformationMatrix makeMapBetweenRects(const FloatRect& source, const FloatRect& dest);
+private:
+ // multiply passed 2D point by matrix (assume z=0)
+ void multVecMatrix(double x, double y, double& dstX, double& dstY) const;
+
+ // multiply passed 3D point by matrix
+ void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const;
+
+ void setMatrix(const Matrix4 m)
+ {
+ if (m && m != m_matrix)
+ memcpy(m_matrix, m, sizeof(Matrix4));
+ }
+
+ Matrix4 m_matrix;
+};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp b/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
index 47471c4..a8ad131 100644
--- a/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
+++ b/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
@@ -30,12 +30,15 @@ PassRefPtr<TransformOperation> TranslateTransformOperation::blend(const Transfor
return this;
if (blendToIdentity)
- return TranslateTransformOperation::create(Length(m_x.type()).blend(m_x, progress), Length(m_y.type()).blend(m_y, progress), m_type);
+ return TranslateTransformOperation::create(Length(m_x.type()).blend(m_x, progress),
+ Length(m_y.type()).blend(m_y, progress),
+ Length(m_z.type()).blend(m_z, progress), m_type);
const TranslateTransformOperation* fromOp = static_cast<const TranslateTransformOperation*>(from);
Length fromX = fromOp ? fromOp->m_x : Length(m_x.type());
Length fromY = fromOp ? fromOp->m_y : Length(m_y.type());
- return TranslateTransformOperation::create(m_x.blend(fromX, progress), m_y.blend(fromY, progress), m_type);
+ Length fromZ = fromOp ? fromOp->m_z : Length(m_z.type());
+ return TranslateTransformOperation::create(m_x.blend(fromX, progress), m_y.blend(fromY, progress), m_z.blend(fromZ, progress), m_type);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/transforms/TranslateTransformOperation.h b/WebCore/platform/graphics/transforms/TranslateTransformOperation.h
index 61ccbcc..a66cc3d 100644
--- a/WebCore/platform/graphics/transforms/TranslateTransformOperation.h
+++ b/WebCore/platform/graphics/transforms/TranslateTransformOperation.h
@@ -34,10 +34,21 @@ class TranslateTransformOperation : public TransformOperation {
public:
static PassRefPtr<TranslateTransformOperation> create(const Length& tx, const Length& ty, OperationType type)
{
- return adoptRef(new TranslateTransformOperation(tx, ty, type));
+ return adoptRef(new TranslateTransformOperation(tx, ty, Length(0, Fixed), type));
}
- virtual bool isIdentity() const { return m_x.calcFloatValue(1) == 0 && m_y.calcFloatValue(1) == 0; }
+ static PassRefPtr<TranslateTransformOperation> create(const Length& tx, const Length& ty, const Length& tz, OperationType type)
+ {
+ return adoptRef(new TranslateTransformOperation(tx, ty, tz, type));
+ }
+
+ double x(const IntSize& borderBoxSize) const { return m_x.calcFloatValue(borderBoxSize.width()); }
+ double y(const IntSize& borderBoxSize) const { return m_y.calcFloatValue(borderBoxSize.height()); }
+ double z(const IntSize&) const { return m_z.calcFloatValue(1); }
+
+private:
+ virtual bool isIdentity() const { return m_x.calcFloatValue(1) == 0 && m_y.calcFloatValue(1) == 0 && m_z.calcFloatValue(1) == 0; }
+
virtual OperationType getOperationType() const { return m_type; }
virtual bool isSameType(const TransformOperation& o) const { return o.getOperationType() == m_type; }
@@ -46,27 +57,29 @@ public:
if (!isSameType(o))
return false;
const TranslateTransformOperation* t = static_cast<const TranslateTransformOperation*>(&o);
- return m_x == t->m_x && m_y == t->m_y;
+ return m_x == t->m_x && m_y == t->m_y && m_z == t->m_z;
}
virtual bool apply(TransformationMatrix& transform, const IntSize& borderBoxSize) const
{
- transform.translate(m_x.calcFloatValue(borderBoxSize.width()), m_y.calcFloatValue(borderBoxSize.height()));
+ transform.translate3d(x(borderBoxSize), y(borderBoxSize), z(borderBoxSize));
return m_x.type() == Percent || m_y.type() == Percent;
}
virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
-private:
- TranslateTransformOperation(const Length& tx, const Length& ty, OperationType type)
+ TranslateTransformOperation(const Length& tx, const Length& ty, const Length& tz, OperationType type)
: m_x(tx)
, m_y(ty)
+ , m_z(tz)
, m_type(type)
{
+ ASSERT(type == TRANSLATE_X || type == TRANSLATE_Y || type == TRANSLATE_Z || type == TRANSLATE || type == TRANSLATE_3D);
}
Length m_x;
Length m_y;
+ Length m_z;
OperationType m_type;
};
diff --git a/WebCore/platform/graphics/win/FontCGWin.cpp b/WebCore/platform/graphics/win/FontCGWin.cpp
index 9ca95f3..feeb2ae 100644
--- a/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -223,8 +223,6 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
}
} else {
- RetainPtr<CGMutablePathRef> path(AdoptCF, CGPathCreateMutable());
-
XFORM xform;
GetWorldTransform(hdc, &xform);
TransformationMatrix hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy);
@@ -233,16 +231,8 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0));
initialGlyphTransform.tx = 0;
initialGlyphTransform.ty = 0;
- CGAffineTransform glyphTranslation = CGAffineTransformIdentity;
-
- for (unsigned i = 0; i < numGlyphs; ++i) {
- RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
- CGAffineTransform glyphTransform = CGAffineTransformConcat(initialGlyphTransform, glyphTranslation);
- CGPathAddPath(path.get(), &glyphTransform, glyphPath.get());
- glyphTranslation = CGAffineTransformTranslate(glyphTranslation, gdiAdvances[i], 0);
- }
-
CGContextRef cgContext = graphicsContext->platformContext();
+
CGContextSaveGState(cgContext);
BOOL fontSmoothingEnabled = false;
@@ -252,26 +242,36 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
CGContextScaleCTM(cgContext, 1.0, -1.0);
CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height()));
- if (drawingMode & cTextFill) {
- CGContextAddPath(cgContext, path.get());
- CGContextFillPath(cgContext);
- if (font->m_syntheticBoldOffset) {
- CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
- CGContextAddPath(cgContext, path.get());
+ for (unsigned i = 0; i < numGlyphs; ++i) {
+ RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
+ CGContextSaveGState(cgContext);
+ CGContextConcatCTM(cgContext, initialGlyphTransform);
+
+ if (drawingMode & cTextFill) {
+ CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
- CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
+ if (font->m_syntheticBoldOffset) {
+ CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
+ CGContextAddPath(cgContext, glyphPath.get());
+ CGContextFillPath(cgContext);
+ CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
+ }
}
- }
- if (drawingMode & cTextStroke) {
- CGContextAddPath(cgContext, path.get());
- CGContextStrokePath(cgContext);
- if (font->m_syntheticBoldOffset) {
- CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
- CGContextAddPath(cgContext, path.get());
+ if (drawingMode & cTextStroke) {
+ CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
- CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
+ if (font->m_syntheticBoldOffset) {
+ CGContextTranslateCTM(cgContext, font->m_syntheticBoldOffset, 0);
+ CGContextAddPath(cgContext, glyphPath.get());
+ CGContextStrokePath(cgContext);
+ CGContextTranslateCTM(cgContext, -font->m_syntheticBoldOffset, 0);
+ }
}
+
+ CGContextRestoreGState(cgContext);
+ CGContextTranslateCTM(cgContext, gdiAdvances[i], 0);
}
+
CGContextRestoreGState(cgContext);
}
@@ -298,8 +298,7 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
if (font->platformData().useGDI()) {
- static bool canUsePlatformNativeGlyphs = wkCanUsePlatformNativeGlyphs();
- if (!canUsePlatformNativeGlyphs || !shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) {
+ if (!shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}
diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp
index 9acc5a0..887bf79 100644
--- a/WebCore/platform/graphics/win/FontCacheWin.cpp
+++ b/WebCore/platform/graphics/win/FontCacheWin.cpp
@@ -422,7 +422,24 @@ static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool
matchData.m_chosen.lfQuality = DEFAULT_QUALITY;
matchData.m_chosen.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
- return CreateFontIndirect(&matchData.m_chosen);
+ HFONT result = CreateFontIndirect(&matchData.m_chosen);
+ if (!result)
+ return 0;
+
+ HDC dc = GetDC(0);
+ SaveDC(dc);
+ SelectObject(dc, result);
+ WCHAR actualName[LF_FACESIZE];
+ GetTextFace(dc, LF_FACESIZE, actualName);
+ RestoreDC(dc, -1);
+ ReleaseDC(0, dc);
+
+ if (wcsicmp(matchData.m_chosen.lfFaceName, actualName)) {
+ DeleteObject(result);
+ result = 0;
+ }
+
+ return result;
}
struct TraitsInFamilyProcData {
diff --git a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
index ba8afe7..1ac3359 100644
--- a/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
@@ -65,10 +65,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
ASSERT(m_fontReference);
ASSERT(T2embedLibrary());
- static bool canUsePlatformNativeGlyphs = wkCanUsePlatformNativeGlyphs();
- LOGFONT _logFont;
-
- LOGFONT& logFont = canUsePlatformNativeGlyphs ? *static_cast<LOGFONT*>(malloc(sizeof(LOGFONT))) : _logFont;
+ LOGFONT& logFont = *static_cast<LOGFONT*>(malloc(sizeof(LOGFONT)));
if (m_name.isNull())
TTGetNewFontName(&m_fontReference, logFont.lfFaceName, LF_FACESIZE, 0, 0);
else
@@ -90,8 +87,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
logFont.lfWeight = bold ? 700 : 400;
HFONT hfont = CreateFontIndirect(&logFont);
- if (canUsePlatformNativeGlyphs)
- wkSetFontPlatformInfo(m_cgFont, &logFont, free);
+ wkSetFontPlatformInfo(m_cgFont, &logFont, free);
return FontPlatformData(hfont, m_cgFont, size, bold, italic, renderingMode == AlternateRenderingMode);
}
@@ -120,7 +116,7 @@ size_t getBytesWithOffset(void *info, void* buffer, size_t offset, size_t count)
// Streams the concatenation of a header and font data.
class EOTStream {
public:
- EOTStream(const Vector<UInt8, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
+ EOTStream(const Vector<uint8_t, 512>& eotHeader, const SharedBuffer* fontData, size_t overlayDst, size_t overlaySrc, size_t overlayLength)
: m_eotHeader(eotHeader)
, m_fontData(fontData)
, m_overlayDst(overlayDst)
@@ -134,7 +130,7 @@ public:
size_t read(void* buffer, size_t count);
private:
- const Vector<UInt8, 512>& m_eotHeader;
+ const Vector<uint8_t, 512>& m_eotHeader;
const SharedBuffer* m_fontData;
size_t m_overlayDst;
size_t m_overlaySrc;
@@ -210,7 +206,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
// TTLoadEmbeddedFont works only with Embedded OpenType (.eot) data, so we need to create an EOT header
// and prepend it to the font data.
- Vector<UInt8, 512> eotHeader;
+ Vector<uint8_t, 512> eotHeader;
size_t overlayDst;
size_t overlaySrc;
size_t overlayLength;
diff --git a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
index c7e59ab..59f7e5c 100644
--- a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp
@@ -120,7 +120,7 @@ void FontPlatformData::platformDataInit(HFONT font, float size, HDC hdc, WCHAR*
ASSERT(m_cgFont);
}
}
- if (m_useGDI && wkCanUsePlatformNativeGlyphs()) {
+ if (m_useGDI) {
LOGFONT* logfont = static_cast<LOGFONT*>(malloc(sizeof(LOGFONT)));
GetObject(font, sizeof(*logfont), logfont);
wkSetFontPlatformInfo(m_cgFont.get(), logfont, free);
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index dccbe6c..da5b503 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -76,8 +76,6 @@ GraphicsContext::GraphicsContext(HDC hdc, bool hasAlpha)
}
}
-bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
-
// FIXME: Is it possible to merge getWindowsContext and createWindowsBitmap into a single API
// suitable for all clients?
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
@@ -173,16 +171,6 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
m_data->restore();
}
-void GraphicsContext::setShouldIncludeChildWindows(bool include)
-{
- m_data->m_shouldIncludeChildWindows = include;
-}
-
-bool GraphicsContext::shouldIncludeChildWindows() const
-{
- return m_data->m_shouldIncludeChildWindows;
-}
-
GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size)
: m_hdc(0)
, m_size(size)
@@ -265,7 +253,7 @@ void GraphicsContext::drawFocusRing(const Color& color)
float radius = (focusRingWidth() - 1) / 2.0f;
int offset = radius + focusRingOffset();
- CGColorRef colorRef = color.isValid() ? cgColor(color) : 0;
+ CGColorRef colorRef = color.isValid() ? createCGColor(color) : 0;
CGMutablePathRef focusRingPath = CGPathCreateMutable();
const Vector<IntRect>& rects = focusRingRects();
diff --git a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
index 892d24a..1980d18 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
@@ -87,8 +87,6 @@ HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlpha
return hdc;
}
-bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
-
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
{
// FIXME: We aren't really doing anything with the 'mayCreateBitmap' flag. This needs
diff --git a/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index b3ebcb0..e4c5b04 100644
--- a/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -43,6 +43,18 @@ namespace WebCore {
class SVGResourceImage;
+bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
+
+void GraphicsContext::setShouldIncludeChildWindows(bool include)
+{
+ m_data->m_shouldIncludeChildWindows = include;
+}
+
+bool GraphicsContext::shouldIncludeChildWindows() const
+{
+ return m_data->m_shouldIncludeChildWindows;
+}
+
void GraphicsContextPlatformPrivate::save()
{
if (!m_hdc)
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
index 1b09e1f..c293f49 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp
@@ -32,7 +32,10 @@
#include "KURL.h"
#include "QTMovieWin.h"
#include "ScrollView.h"
+#include "StringHash.h"
+#include <wtf/HashSet.h>
#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
#if DRAW_FRAME_RATE
#include "Font.h"
@@ -48,16 +51,25 @@ using namespace std;
namespace WebCore {
-static const double endPointTimerInterval = 0.020;
-
+MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player)
+{
+ return new MediaPlayerPrivate(player);
+}
+
+void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
+{
+ if (isAvailable())
+ registrar(create, getSupportedTypes, supportsType);
+}
+
MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
: m_player(player)
, m_seekTo(-1)
, m_endTime(numeric_limits<float>::infinity())
, m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired)
- , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired)
, m_networkState(MediaPlayer::Empty)
- , m_readyState(MediaPlayer::DataUnavailable)
+ , m_readyState(MediaPlayer::HaveNothing)
+ , m_enabledTrackCount(0)
, m_startedPlaying(false)
, m_isStreaming(false)
#if DRAW_FRAME_RATE
@@ -75,7 +87,8 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
void MediaPlayerPrivate::load(const String& url)
{
if (!QTMovieWin::initializeQuickTime()) {
- m_networkState = MediaPlayer::LoadFailed;
+ // FIXME: is this the right error to return?
+ m_networkState = MediaPlayer::DecodeError;
m_player->networkStateChanged();
return;
}
@@ -84,17 +97,16 @@ void MediaPlayerPrivate::load(const String& url)
m_networkState = MediaPlayer::Loading;
m_player->networkStateChanged();
}
- if (m_readyState != MediaPlayer::DataUnavailable) {
- m_readyState = MediaPlayer::DataUnavailable;
+ if (m_readyState != MediaPlayer::HaveNothing) {
+ m_readyState = MediaPlayer::HaveNothing;
m_player->readyStateChanged();
}
cancelSeek();
- m_endPointTimer.stop();
m_qtMovie.set(new QTMovieWin(this));
m_qtMovie->load(url.characters(), url.length());
- m_qtMovie->setVolume(m_player->m_volume);
- m_qtMovie->setVisible(m_player->m_visible);
+ m_qtMovie->setVolume(m_player->volume());
+ m_qtMovie->setVisible(m_player->visible());
}
void MediaPlayerPrivate::play()
@@ -107,7 +119,6 @@ void MediaPlayerPrivate::play()
#endif
m_qtMovie->play();
- startEndPointTimerIfNeeded();
}
void MediaPlayerPrivate::pause()
@@ -119,7 +130,6 @@ void MediaPlayerPrivate::pause()
m_timeStoppedPlaying = GetTickCount();
#endif
m_qtMovie->pause();
- m_endPointTimer.stop();
}
float MediaPlayerPrivate::duration() const
@@ -156,11 +166,12 @@ void MediaPlayerPrivate::seek(float time)
void MediaPlayerPrivate::doSeek()
{
float oldRate = m_qtMovie->rate();
- m_qtMovie->setRate(0);
+ if (oldRate)
+ m_qtMovie->setRate(0);
m_qtMovie->setCurrentTime(m_seekTo);
float timeAfterSeek = currentTime();
// restore playback only if not at end, othewise QTMovie will loop
- if (timeAfterSeek < duration() && timeAfterSeek < m_endTime)
+ if (oldRate && timeAfterSeek < duration() && timeAfterSeek < m_endTime)
m_qtMovie->setRate(oldRate);
cancelSeek();
}
@@ -195,22 +206,6 @@ void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*)
void MediaPlayerPrivate::setEndTime(float time)
{
m_endTime = time;
- startEndPointTimerIfNeeded();
-}
-
-void MediaPlayerPrivate::startEndPointTimerIfNeeded()
-{
- if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive())
- m_endPointTimer.startRepeating(endPointTimerInterval);
-}
-
-void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*)
-{
- float time = currentTime();
- if (time >= m_endTime) {
- pause();
- didEnd();
- }
}
bool MediaPlayerPrivate::paused() const
@@ -325,42 +320,44 @@ void MediaPlayerPrivate::updateStates()
long loadState = m_qtMovie ? m_qtMovie->loadState() : QTMovieLoadStateError;
- if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData && !m_player->inMediaDocument()) {
- unsigned enabledTrackCount;
- m_qtMovie->disableUnsupportedTracks(enabledTrackCount);
- // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692>
- if (!enabledTrackCount)
+ if (loadState >= QTMovieLoadStateLoaded && m_readyState < MediaPlayer::HaveMetadata && !m_player->inMediaDocument()) {
+ m_qtMovie->disableUnsupportedTracks(m_enabledTrackCount);
+ if (!m_enabledTrackCount)
loadState = QTMovieLoadStateError;
}
// "Loaded" is reserved for fully buffered movies, never the case when streaming
if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) {
- if (m_networkState < MediaPlayer::Loaded)
- m_networkState = MediaPlayer::Loaded;
- m_readyState = MediaPlayer::CanPlayThrough;
+ m_networkState = MediaPlayer::Loaded;
+ m_readyState = MediaPlayer::HaveEnoughData;
} else if (loadState >= QTMovieLoadStatePlaythroughOK) {
- if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
- m_networkState = MediaPlayer::LoadedFirstFrame;
- m_readyState = MediaPlayer::CanPlayThrough;
+ m_readyState = MediaPlayer::HaveEnoughData;
} else if (loadState >= QTMovieLoadStatePlayable) {
- if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking())
- m_networkState = MediaPlayer::LoadedFirstFrame;
- m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::CanPlay : MediaPlayer::DataUnavailable;
+ // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967>
+ m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::HaveFutureData : MediaPlayer::HaveCurrentData;
} else if (loadState >= QTMovieLoadStateLoaded) {
- if (m_networkState < MediaPlayer::LoadedMetaData)
- m_networkState = MediaPlayer::LoadedMetaData;
- m_readyState = MediaPlayer::DataUnavailable;
+ m_readyState = MediaPlayer::HaveMetadata;
} else if (loadState > QTMovieLoadStateError) {
- if (m_networkState < MediaPlayer::Loading)
- m_networkState = MediaPlayer::Loading;
- m_readyState = MediaPlayer::DataUnavailable;
+ m_networkState = MediaPlayer::Loading;
+ m_readyState = MediaPlayer::HaveNothing;
} else {
- m_networkState = MediaPlayer::LoadFailed;
- m_readyState = MediaPlayer::DataUnavailable;
+ float loaded = maxTimeLoaded();
+ if (!loaded)
+ m_readyState = MediaPlayer::HaveNothing;
+
+ if (!m_enabledTrackCount)
+ m_networkState = MediaPlayer::FormatError;
+ else {
+ // FIXME: We should differentiate between load/network errors and decode errors <rdar://problem/5605692>
+ if (loaded > 0)
+ m_networkState = MediaPlayer::DecodeError;
+ else
+ m_readyState = MediaPlayer::HaveNothing;
+ }
}
if (seeking())
- m_readyState = MediaPlayer::DataUnavailable;
+ m_readyState = MediaPlayer::HaveNothing;
if (m_networkState != oldNetworkState)
m_player->networkStateChanged();
@@ -371,7 +368,6 @@ void MediaPlayerPrivate::updateStates()
void MediaPlayerPrivate::didEnd()
{
- m_endPointTimer.stop();
m_startedPlaying = false;
#if DRAW_FRAME_RATE
m_timeStoppedPlaying = GetTickCount();
@@ -380,10 +376,10 @@ void MediaPlayerPrivate::didEnd()
m_player->timeChanged();
}
-void MediaPlayerPrivate::setRect(const IntRect& r)
+void MediaPlayerPrivate::setSize(const IntSize& size)
{
if (m_qtMovie)
- m_qtMovie->setSize(r.width(), r.height());
+ m_qtMovie->setSize(size.width(), size.height());
}
void MediaPlayerPrivate::setVisible(bool b)
@@ -403,7 +399,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
#if DRAW_FRAME_RATE
if (m_frameCountWhilePlaying > 10) {
- Frame* frame = m_player->m_frameView ? m_player->m_frameView->frame() : NULL;
+ Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL;
Document* document = frame ? frame->document() : NULL;
RenderObject* renderer = document ? document->renderer() : NULL;
RenderStyle* styleToUse = renderer ? renderer->style() : NULL;
@@ -427,16 +423,30 @@ void MediaPlayerPrivate::paint(GraphicsContext* p, const IntRect& r)
#endif
}
-void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+static HashSet<String> mimeTypeCache()
{
- unsigned count = QTMovieWin::countSupportedTypes();
- for (unsigned n = 0; n < count; n++) {
- const UChar* character;
- unsigned len;
- QTMovieWin::getSupportedType(n, character, len);
- if (len)
- types.add(String(character, len));
+ DEFINE_STATIC_LOCAL(HashSet<String>, typeCache, ());
+ static bool typeListInitialized = false;
+
+ if (!typeListInitialized) {
+ unsigned count = QTMovieWin::countSupportedTypes();
+ for (unsigned n = 0; n < count; n++) {
+ const UChar* character;
+ unsigned len;
+ QTMovieWin::getSupportedType(n, character, len);
+ if (len)
+ typeCache.add(String(character, len));
+ }
+
+ typeListInitialized = true;
}
+
+ return typeCache;
+}
+
+void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+{
+ types = mimeTypeCache();
}
bool MediaPlayerPrivate::isAvailable()
@@ -444,6 +454,13 @@ bool MediaPlayerPrivate::isAvailable()
return QTMovieWin::initializeQuickTime();
}
+MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
+{
+ // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an
+ // extended MIME type
+ return mimeTypeCache().contains(type) ? (!codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;
+}
+
void MediaPlayerPrivate::movieEnded(QTMovieWin* movie)
{
ASSERT(m_qtMovie.get() == movie);
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
index c4c893c..63aa62b 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,7 +28,7 @@
#if ENABLE(VIDEO)
-#include "MediaPlayer.h"
+#include "MediaPlayerPrivate.h"
#include "Timer.h"
#include <QTMovieWin.h>
#include <wtf/OwnPtr.h>
@@ -44,9 +44,10 @@ class IntSize;
class IntRect;
class String;
-class MediaPlayerPrivate : QTMovieWinClient, Noncopyable {
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface, public QTMovieWinClient {
public:
- MediaPlayerPrivate(MediaPlayer*);
+ static void registerMediaEngine(MediaEngineRegistrar);
+
~MediaPlayerPrivate();
IntSize naturalSize() const;
@@ -81,38 +82,42 @@ public:
unsigned totalBytes() const;
void setVisible(bool);
- void setRect(const IntRect&);
+ void setSize(const IntSize&);
void loadStateChanged();
void didEnd();
void paint(GraphicsContext*, const IntRect&);
- static void getSupportedTypes(HashSet<String>& types);
- static bool isAvailable();
private:
+ MediaPlayerPrivate(MediaPlayer*);
+
void updateStates();
void doSeek();
void cancelSeek();
void seekTimerFired(Timer<MediaPlayerPrivate>*);
- void endPointTimerFired(Timer<MediaPlayerPrivate>*);
float maxTimeLoaded() const;
- void startEndPointTimerIfNeeded();
virtual void movieEnded(QTMovieWin*);
virtual void movieLoadStateChanged(QTMovieWin*);
virtual void movieTimeChanged(QTMovieWin*);
virtual void movieNewImageAvailable(QTMovieWin*);
-
+
+ // engine support
+ static MediaPlayerPrivateInterface* create(MediaPlayer*);
+ static void getSupportedTypes(HashSet<String>& types);
+ static MediaPlayer::SupportsType supportsType(const String& type, const String& codecs);
+ static bool isAvailable();
+
MediaPlayer* m_player;
OwnPtr<QTMovieWin> m_qtMovie;
float m_seekTo;
float m_endTime;
Timer<MediaPlayerPrivate> m_seekTimer;
- Timer<MediaPlayerPrivate> m_endPointTimer;
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
+ unsigned m_enabledTrackCount;
bool m_startedPlaying;
bool m_isStreaming;
#if DRAW_FRAME_RATE
diff --git a/WebCore/platform/graphics/win/QTMovieWin.cpp b/WebCore/platform/graphics/win/QTMovieWin.cpp
index 32aecd3..3f23698 100644
--- a/WebCore/platform/graphics/win/QTMovieWin.cpp
+++ b/WebCore/platform/graphics/win/QTMovieWin.cpp
@@ -658,6 +658,12 @@ void QTMovieWin::disableUnsupportedTracks(unsigned& enabledTrackCount)
continue;
if (!allowedTrackTypes->contains(mediaType)) {
+
+ // Different mpeg variants import as different track types so check for the "mpeg
+ // characteristic" instead of hard coding the (current) list of mpeg media types.
+ if (GetMovieIndTrackType(m_private->m_movie, 1, 'mpeg', movieTrackCharacteristic | movieTrackEnabledOnly))
+ continue;
+
SetTrackEnabled(currentTrack, false);
--enabledTrackCount;
}
diff --git a/WebCore/platform/graphics/win/QTMovieWinTimer.cpp b/WebCore/platform/graphics/win/QTMovieWinTimer.cpp
index d0aa3e6..f6103ea 100644
--- a/WebCore/platform/graphics/win/QTMovieWinTimer.cpp
+++ b/WebCore/platform/graphics/win/QTMovieWinTimer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,6 +51,9 @@ static LRESULT CALLBACK TimerWindowWndProc(HWND hWnd, UINT message, WPARAM wPara
processingCustomTimerMessage = true;
sharedTimerFiredFunction();
processingCustomTimerMessage = false;
+ } else if (message == WM_TIMER && wParam == timerID) {
+ stopSharedTimer();
+ sharedTimerFiredFunction();
} else
return DefWindowProc(hWnd, message, wParam, lParam);
return 0;
@@ -79,11 +82,6 @@ void setSharedTimerFiredFunction(void (*f)())
sharedTimerFiredFunction = f;
}
-static void CALLBACK timerFired(HWND, UINT, UINT_PTR, DWORD)
-{
- sharedTimerFiredFunction();
-}
-
void setSharedTimerFireDelay(double interval)
{
ASSERT(sharedTimerFiredFunction);
@@ -99,29 +97,27 @@ void setSharedTimerFireDelay(double interval)
intervalInMS = (unsigned)interval;
}
- if (timerID) {
- KillTimer(0, timerID);
- timerID = 0;
- }
+ stopSharedTimer();
+ initializeOffScreenTimerWindow();
// We don't allow nested PostMessages, since the custom messages will effectively starve
// painting and user input. (Win32 has a tri-level queue with application messages >
// user input > WM_PAINT/WM_TIMER.)
// In addition, if the queue contains input events that have been there since the last call to
// GetQueueStatus, PeekMessage or GetMessage we favor timers.
- if (intervalInMS < USER_TIMER_MINIMUM && processingCustomTimerMessage &&
- !LOWORD(::GetQueueStatus(QS_ALLINPUT))) {
+ if (intervalInMS < USER_TIMER_MINIMUM
+ && !processingCustomTimerMessage
+ && !LOWORD(::GetQueueStatus(QS_ALLINPUT))) {
// Windows SetTimer does not allow timeouts smaller than 10ms (USER_TIMER_MINIMUM)
- initializeOffScreenTimerWindow();
PostMessage(timerWindowHandle, timerFiredMessage, 0, 0);
} else
- timerID = SetTimer(0, 0, intervalInMS, timerFired);
+ timerID = SetTimer(timerWindowHandle, timerFiredMessage, intervalInMS, 0);
}
void stopSharedTimer()
{
if (timerID) {
- KillTimer(0, timerID);
+ KillTimer(timerWindowHandle, timerID);
timerID = 0;
}
}
diff --git a/WebCore/platform/graphics/wx/FontPlatformData.h b/WebCore/platform/graphics/wx/FontPlatformData.h
index d2394dc..c77968a 100644
--- a/WebCore/platform/graphics/wx/FontPlatformData.h
+++ b/WebCore/platform/graphics/wx/FontPlatformData.h
@@ -30,41 +30,59 @@
#define FontPlatformData_H
#include "FontDescription.h"
-#include "CString.h"
#include "AtomicString.h"
+#include "CString.h"
#include "StringImpl.h"
+#include <wtf/RefPtr.h>
#include <wx/defs.h>
#include <wx/font.h>
namespace WebCore {
+class FontHolder: public WTF::RefCounted<FontHolder>
+{
+public:
+ FontHolder()
+ : m_font(0)
+ {}
+
+ FontHolder(wxFont* font)
+ : m_font(font)
+ {}
+
+ wxFont* font() { return m_font; }
+
+private:
+ wxFont* m_font;
+};
+
class FontPlatformData {
public:
enum FontState { UNINITIALIZED, DELETED, VALID };
FontPlatformData(WTF::HashTableDeletedValueType)
- : m_fontState(DELETED)
+ : m_fontState(DELETED),
+ m_font(0)
{ }
~FontPlatformData();
- FontPlatformData(wxFont f)
- : m_font(f)
- , m_fontState(VALID)
+ FontPlatformData(const FontDescription&, const AtomicString&);
+ FontPlatformData(float size, bool bold, bool italic)
+ : m_fontState(UNINITIALIZED)
+ , m_font(0)
{
- m_fontHash = computeHash();
}
- FontPlatformData(const FontDescription&, const AtomicString&);
-
FontPlatformData()
: m_fontState(UNINITIALIZED)
+ , m_font(0)
{
}
- wxFont font() const {
- return m_font;
+ wxFont* font() const {
+ return m_font->font();
}
unsigned hash() const {
@@ -78,32 +96,26 @@ public:
}
}
+ unsigned computeHash() const;
+
bool operator==(const FontPlatformData& other) const
{
- if (m_fontState == VALID)
- return other.m_fontState == VALID && m_font.IsOk() && other.m_font.IsOk() && m_font.IsSameAs(other.m_font);
+ if (m_font && m_fontState == VALID && other.m_fontState == VALID && other.m_font) {
+ wxFont* thisFont = m_font->font();
+ wxFont* otherFont = other.m_font->font();
+ return thisFont->IsOk() && otherFont->IsOk() && thisFont->IsSameAs(*otherFont);
+ }
else
return m_fontState == other.m_fontState;
}
bool isHashTableDeletedValue() const { return m_fontState == DELETED; }
- unsigned computeHash() const {
- ASSERT(m_font.IsOk());
-
- // make a hash that is unique for this font, but not globally unique - that is,
- // a font whose properties are equal should generate the same hash
- uintptr_t hashCodes[6] = { m_font.GetPointSize(), m_font.GetFamily(), m_font.GetStyle(),
- m_font.GetWeight(), m_font.GetUnderlined(),
- StringImpl::computeHash(m_font.GetFaceName().mb_str(wxConvUTF8)) };
-
- return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
- }
+
private:
- wxFont m_font;
- FontState m_fontState;
- unsigned m_fontHash;
+ WTF::RefPtr<FontHolder> m_font;
+ FontState m_fontState;
};
}
diff --git a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
index 7162eab..ce5e40e 100644
--- a/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
+++ b/WebCore/platform/graphics/wx/FontPlatformDataWx.cpp
@@ -58,6 +58,9 @@ static wxFontWeight fontWeightToWxFontWeight(FontWeight weight)
{
if (weight >= FontWeight600)
return wxFONTWEIGHT_BOLD;
+
+ if (weight <= FontWeight300)
+ return wxFONTWEIGHT_LIGHT;
return wxFONTWEIGHT_NORMAL;
}
@@ -78,30 +81,45 @@ FontPlatformData::FontPlatformData(const FontDescription& desc, const AtomicStri
// this is a moot issue on Linux and Mac as they only accept the point argument. So,
// we use the pixel size constructor on Windows, but we use point size on Linux and Mac.
#if __WXMSW__
- m_font = wxFont( wxSize(0, -desc.computedPixelSize()),
+ m_font = new FontHolder(new wxFont( wxSize(0, -desc.computedPixelSize()),
fontFamilyToWxFontFamily(desc.genericFamily()),
italicToWxFontStyle(desc.italic()),
fontWeightToWxFontWeight(desc.weight()),
false,
family.string()
- );
+ )
+ );
#else
- m_font = wxFont( desc.computedPixelSize(),
+ m_font = new FontHolder(new wxFont( desc.computedPixelSize(),
fontFamilyToWxFontFamily(desc.genericFamily()),
italicToWxFontStyle(desc.italic()),
fontWeightToWxFontWeight(desc.weight()),
false,
family.string()
- );
+ )
+ );
#endif
m_fontState = VALID;
- m_fontHash = computeHash();
}
-
+
+unsigned FontPlatformData::computeHash() const {
+ wxFont* thisFont = m_font->font();
+ ASSERT(thisFont && thisFont->IsOk());
+
+ // make a hash that is unique for this font, but not globally unique - that is,
+ // a font whose properties are equal should generate the same hash
+ uintptr_t hashCodes[6] = { thisFont->GetPointSize(), thisFont->GetFamily(), thisFont->GetStyle(),
+ thisFont->GetWeight(), thisFont->GetUnderlined(),
+ StringImpl::computeHash(thisFont->GetFaceName().mb_str(wxConvUTF8)) };
+
+ return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));
+}
+
FontPlatformData::~FontPlatformData()
{
m_fontState = UNINITIALIZED;
+ m_font = 0;
}
}
diff --git a/WebCore/platform/graphics/wx/ImageSourceWx.cpp b/WebCore/platform/graphics/wx/ImageSourceWx.cpp
index d523354..fc8ce71 100644
--- a/WebCore/platform/graphics/wx/ImageSourceWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageSourceWx.cpp
@@ -170,7 +170,7 @@ void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer*
delete m_decoder;
m_decoder = 0;
if (data)
- setData(data, allDataReceived);
+ setData(data, allDataReceived);
}
NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
diff --git a/WebCore/platform/graphics/wx/ImageWx.cpp b/WebCore/platform/graphics/wx/ImageWx.cpp
index e52e9ff..e1d435e 100644
--- a/WebCore/platform/graphics/wx/ImageWx.cpp
+++ b/WebCore/platform/graphics/wx/ImageWx.cpp
@@ -237,7 +237,7 @@ void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, c
void BitmapImage::checkForSolidColor()
{
-
+ m_checkedForSolidColor = true;
}
void BitmapImage::invalidatePlatformData()
diff --git a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index a509933..ab50518 100644
--- a/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -45,14 +45,16 @@ namespace WebCore
void SimpleFontData::platformInit()
{
- wxFont font = m_font.font();
- wxFontProperties props = wxFontProperties(&font);
- m_ascent = props.GetAscent();
- m_descent = props.GetDescent();
- m_lineSpacing = props.GetLineSpacing();
- m_xHeight = props.GetXHeight();
- m_unitsPerEm = 1; // FIXME!
- m_lineGap = props.GetLineGap();
+ wxFont *font = m_font.font();
+ if (font && font->IsOk()) {
+ wxFontProperties props = wxFontProperties(font);
+ m_ascent = props.GetAscent();
+ m_descent = props.GetDescent();
+ m_lineSpacing = props.GetLineSpacing();
+ m_xHeight = props.GetXHeight();
+ m_unitsPerEm = 1; // FIXME!
+ m_lineGap = props.GetLineGap();
+ }
}
void SimpleFontData::platformDestroy()
@@ -79,8 +81,8 @@ bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
void SimpleFontData::determinePitch()
{
- if (m_font.font().Ok())
- m_treatAsFixedPitch = m_font.font().IsFixedWidth();
+ if (m_font.font() && m_font.font()->Ok())
+ m_treatAsFixedPitch = m_font.font()->IsFixedWidth();
else
m_treatAsFixedPitch = false;
}
@@ -89,7 +91,7 @@ float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
// TODO: fix this! Make GetTextExtents a method of wxFont in 2.9
int width = 10;
- GetTextExtent(m_font.font(), (wxChar)glyph, &width, NULL);
+ GetTextExtent(*m_font.font(), (wxChar)glyph, &width, NULL);
return width;
}
diff --git a/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp b/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp
index e6a02b8..f21dc17 100644
--- a/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp
+++ b/WebCore/platform/graphics/wx/TransformationMatrixWx.cpp
@@ -37,235 +37,14 @@
namespace WebCore {
#if USE(WXGC)
-TransformationMatrix::TransformationMatrix(const PlatformTransformationMatrix& matrix)
-{
- m_transform = matrix;
-}
-#endif
-
-TransformationMatrix::TransformationMatrix(double a, double b, double c, double d, double e, double f)
-{
-#if USE(WXGC)
- wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer();
- m_transform = renderer->CreateMatrix();
-#endif
- setMatrix(a, b, c, d, e, f);
-}
-
-TransformationMatrix::TransformationMatrix()
-{
- // NB: If we ever support using Cairo backend on Win/Mac, this will need to be
- // changed somehow (though I'm not sure how as we don't have a reference to the
- // graphics context here.
-#if USE(WXGC)
- wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer();
- m_transform = renderer->CreateMatrix();
-#endif
-}
-
-TransformationMatrix TransformationMatrix::inverse() const
-{
- notImplemented();
- return *this;
-}
-
-void TransformationMatrix::setMatrix(double a, double b, double c, double d, double e, double f)
-{
-#if USE(WXGC)
- m_transform.Set(a, b, c, d, e, f);
-#endif
-}
-
-void TransformationMatrix::map(double x, double y, double *x2, double *y2) const
-{
- notImplemented();
-}
-
-IntRect TransformationMatrix::mapRect(const IntRect &rect) const
-{
-#if USE(WXGC)
- double x, y, width, height;
- x = rect.x();
- y = rect.y();
- width = rect.width();
- height = rect.height();
-
- m_transform.TransformPoint(&x, &y);
- m_transform.TransformDistance(&width, &height);
- return IntRect(x, y, width, height);
-#endif
- return IntRect();
-}
-
-FloatRect TransformationMatrix::mapRect(const FloatRect &rect) const
-{
-#if USE(WXGC)
- double x, y, width, height;
- x = rect.x();
- y = rect.y();
- width = rect.width();
- height = rect.height();
-
- m_transform.TransformPoint(&x, &y);
- m_transform.TransformDistance(&width, &height);
- return FloatRect(x, y, width, height);
-#endif
- return FloatRect();
-}
-
-
-TransformationMatrix& TransformationMatrix::scale(double sx, double sy)
-{
-#if USE(WXGC)
- m_transform.Scale((wxDouble)sx, (wxDouble)sy);
-#endif
- return *this;
-}
-
-void TransformationMatrix::reset()
-{
- notImplemented();
-}
-
-TransformationMatrix& TransformationMatrix::rotate(double d)
-{
-#if USE(WXGC)
- m_transform.Rotate((wxDouble)d);
-#endif
- return *this;
-}
-
-TransformationMatrix& TransformationMatrix::translate(double tx, double ty)
-{
-#if USE(WXGC)
- m_transform.Translate((wxDouble)tx, (wxDouble)ty);
-#endif
- return *this;
-}
-
-TransformationMatrix& TransformationMatrix::shear(double sx, double sy)
-{
- notImplemented();
- return *this;
-}
-
-TransformationMatrix& TransformationMatrix::operator*=(const TransformationMatrix& other)
-{
- notImplemented();
- return *this;
-}
-
-bool TransformationMatrix::operator== (const TransformationMatrix &other) const
-{
-#if USE(WXGC)
- return m_transform.IsEqual((wxGraphicsMatrix)other);
-#else
- notImplemented();
- return true;
-#endif
-}
-
-TransformationMatrix TransformationMatrix::operator* (const TransformationMatrix &other)
-{
- notImplemented();
- return *this; //m_transform * other.m_transform;
-}
-
-double TransformationMatrix::det() const
-{
- notImplemented();
- return 0;
-}
-
-#if USE(WXGC)
TransformationMatrix::operator wxGraphicsMatrix() const
{
- return m_transform;
-}
-#endif
-
-double TransformationMatrix::a() const
-{
- double a = 0;
-#if USE(WXGC)
- m_transform.Get(&a);
-#endif
- return a;
-}
-
-void TransformationMatrix::setA(double a)
-{
- setMatrix(a, b(), c(), d(), e(), f());
-}
-
-double TransformationMatrix::b() const
-{
- double b = 0;
-#if USE(WXGC)
- m_transform.Get(&b);
-#endif
- return b;
-}
-
-void TransformationMatrix::setB(double b)
-{
- setMatrix(a(), b, c(), d(), e(), f());
-}
-
-double TransformationMatrix::c() const
-{
- double c = 0;
-#if USE(WXGC)
- m_transform.Get(&c);
-#endif
- return c;
-}
-
-void TransformationMatrix::setC(double c)
-{
- setMatrix(a(), b(), c, d(), e(), f());
-}
-
-double TransformationMatrix::d() const
-{
- double d = 0;
-#if USE(WXGC)
- m_transform.Get(&d);
-#endif
- return d;
-}
-
-void TransformationMatrix::setD(double d)
-{
- setMatrix(a(), b(), c(), d, e(), f());
-}
-
-double TransformationMatrix::e() const
-{
- double e = 0;
-#if USE(WXGC)
- m_transform.Get(&e);
-#endif
- return e;
-}
-
-void TransformationMatrix::setE(double e)
-{
- setMatrix(a(), b(), c(), d(), e, f());
+ wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer();
+ ASSERT(renderer);
+
+ wxGraphicsMatrix matrix = renderer->CreateMatrix(a(), b(), c(), d(), e(), f());
+ return matrix;
}
-
-double TransformationMatrix::f() const
-{
- double f = 0;
-#if USE(WXGC)
- m_transform.Get(&f);
#endif
- return f;
-}
-
-void TransformationMatrix::setF(double f)
-{
- setMatrix(a(), b(), c(), d(), e(), f);
-}
}
diff --git a/WebCore/platform/gtk/ContextMenuGtk.cpp b/WebCore/platform/gtk/ContextMenuGtk.cpp
index 2365379..210cfa6 100644
--- a/WebCore/platform/gtk/ContextMenuGtk.cpp
+++ b/WebCore/platform/gtk/ContextMenuGtk.cpp
@@ -39,12 +39,7 @@ ContextMenu::ContextMenu(const HitTestResult& result)
{
m_platformDescription = GTK_MENU(gtk_menu_new());
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink(G_OBJECT(m_platformDescription));
-#else
- g_object_ref(G_OBJECT(m_platformDescription));
- gtk_object_sink(GTK_OBJECT(m_platformDescription));
-#endif
}
ContextMenu::~ContextMenu()
diff --git a/WebCore/platform/gtk/ContextMenuItemGtk.cpp b/WebCore/platform/gtk/ContextMenuItemGtk.cpp
index 84f78c0..cf34640 100644
--- a/WebCore/platform/gtk/ContextMenuItemGtk.cpp
+++ b/WebCore/platform/gtk/ContextMenuItemGtk.cpp
@@ -232,12 +232,7 @@ void ContextMenuItem::setSubMenu(ContextMenu* menu)
m_platformDescription.subMenu = menu->releasePlatformDescription();
m_platformDescription.type = SubmenuType;
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink(G_OBJECT(m_platformDescription.subMenu));
-#else
- g_object_ref(G_OBJECT(m_platformDescription.subMenu));
- gtk_object_sink(GTK_OBJECT(m_platformDescription.subMenu));
-#endif
}
void ContextMenuItem::setChecked(bool shouldCheck)
diff --git a/WebCore/platform/gtk/FileSystemGtk.cpp b/WebCore/platform/gtk/FileSystemGtk.cpp
index 4f0ae01..94e06db 100644
--- a/WebCore/platform/gtk/FileSystemGtk.cpp
+++ b/WebCore/platform/gtk/FileSystemGtk.cpp
@@ -229,7 +229,7 @@ CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
if (!isHandleValid(fileDescriptor)) {
LOG_ERROR("Can't create a temporary file.");
g_free(tempPath);
- return 0;
+ return CString();
}
CString tempFilePath = tempPath;
g_free(tempPath);
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.cpp b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
index 0c80dd6..cc69d44 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.cpp
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.cpp
@@ -20,6 +20,21 @@
#include "config.h"
#include "GeolocationServiceGtk.h"
+#include "CString.h"
+#include "GOwnPtr.h"
+#include "NotImplemented.h"
+#include "PositionOptions.h"
+
+namespace WTF {
+ template<> void freeOwnedGPtr<GeoclueAccuracy>(GeoclueAccuracy* accuracy)
+ {
+ if (!accuracy)
+ return;
+
+ geoclue_accuracy_free(accuracy);
+ }
+}
+
namespace WebCore {
GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
@@ -29,33 +44,170 @@ GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
GeolocationServiceGtk::GeolocationServiceGtk(GeolocationServiceClient* client)
: GeolocationService(client)
-{}
+ , m_geoclueClient(0)
+ , m_geocluePosition(0)
+ , m_latitude(0.0)
+ , m_longitude(0.0)
+ , m_altitude(0.0)
+ , m_altitudeAccuracy(0.0)
+ , m_timestamp(0)
+{
+}
-bool GeolocationServiceGtk::startUpdating(PositionOptions*)
+GeolocationServiceGtk::~GeolocationServiceGtk()
{
- return false;
+ if (m_geoclueClient)
+ g_object_unref(m_geoclueClient);
+
+ if (m_geocluePosition)
+ g_object_unref(m_geocluePosition);
+}
+
+//
+// 1.) Initialize Geoclue with our requirements
+// 2.) Try to get a GeocluePosition
+// 3.) Update the Information and get the current position
+//
+// TODO: Also get GeoclueVelocity but there is no master client
+// API for that.
+//
+bool GeolocationServiceGtk::startUpdating(PositionOptions* options)
+{
+ ASSERT(!m_geoclueClient);
+
+ m_lastPosition = 0;
+ m_lastError = 0;
+
+ GOwnPtr<GError> error;
+ GeoclueMaster* master = geoclue_master_get_default();
+ GeoclueMasterClient* client = geoclue_master_create_client(master, 0, 0);
+ g_object_unref(master);
+
+ if (!client) {
+ setError(PositionError::UNKNOWN_ERROR, "Could not connect to location provider.");
+ return false;
+ }
+
+ GeoclueAccuracyLevel accuracyLevel = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ int timeout = 0;
+ if (options) {
+ accuracyLevel = options->enableHighAccuracy() ? GEOCLUE_ACCURACY_LEVEL_DETAILED : GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ timeout = options->timeout();
+ }
+
+ gboolean result = geoclue_master_client_set_requirements(client, accuracyLevel, timeout,
+ true, GEOCLUE_RESOURCE_ALL, &error.outPtr());
+
+ if (!result) {
+ setError(PositionError::UNKNOWN_ERROR, error->message);
+ g_object_unref(client);
+ return false;
+ }
+
+ m_geocluePosition = geoclue_master_client_create_position(client, &error.outPtr());
+ if (!m_geocluePosition) {
+ setError(PositionError::UNKNOWN_ERROR, error->message);
+ g_object_unref(client);
+ return false;
+ }
+
+ g_signal_connect(G_OBJECT(m_geocluePosition), "position-changed",
+ G_CALLBACK(position_changed), this);
+
+ m_geoclueClient = client;
+ updateLocationInformation();
+
+ return true;
}
void GeolocationServiceGtk::stopUpdating()
{
+ if (!m_geoclueClient)
+ return;
+
+ g_object_unref(m_geocluePosition);
+ g_object_unref(m_geoclueClient);
+
+ m_geocluePosition = 0;
+ m_geoclueClient = 0;
}
void GeolocationServiceGtk::suspend()
{
+ // not available with geoclue
+ notImplemented();
}
void GeolocationServiceGtk::resume()
{
+ // not available with geoclue
+ notImplemented();
}
Geoposition* GeolocationServiceGtk::lastPosition() const
{
- return 0;
+ return m_lastPosition.get();
}
PositionError* GeolocationServiceGtk::lastError() const
{
- return 0;
+ return m_lastError.get();
+}
+
+void GeolocationServiceGtk::updateLocationInformation()
+{
+ ASSERT(m_geocluePosition);
+
+ GOwnPtr<GError> error;
+ GOwnPtr<GeoclueAccuracy> accuracy;
+
+ GeocluePositionFields fields = geoclue_position_get_position(m_geocluePosition, &m_timestamp,
+ &m_latitude, &m_longitude,
+ &m_altitude, &accuracy.outPtr(),
+ &error.outPtr());
+ if (error) {
+ setError(PositionError::POSITION_UNAVAILABLE, error->message);
+ return;
+ } else if (!(fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+ setError(PositionError::POSITION_UNAVAILABLE, "Position could not be determined.");
+ return;
+ }
+
+
+}
+
+void GeolocationServiceGtk::updatePosition()
+{
+ m_lastError = 0;
+
+ RefPtr<Coordinates> coordinates = Coordinates::create(m_latitude, m_longitude,
+ m_altitude, m_accuracy,
+ m_altitudeAccuracy, 0.0, 0.0);
+ m_lastPosition = Geoposition::create(coordinates.release(), m_timestamp * 1000.0);
+ positionChanged();
+}
+
+void GeolocationServiceGtk::position_changed(GeocluePosition*, GeocluePositionFields fields, int timestamp, double latitude, double longitude, double altitude, GeoclueAccuracy* accuracy, GeolocationServiceGtk* that)
+{
+ if (!(fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+ that->setError(PositionError::POSITION_UNAVAILABLE, "Position could not be determined.");
+ return;
+ }
+
+ that->m_timestamp = timestamp;
+ that->m_latitude = latitude;
+ that->m_longitude = longitude;
+ that->m_altitude = altitude;
+
+ GeoclueAccuracyLevel level;
+ geoclue_accuracy_get_details(accuracy, &level, &that->m_accuracy, &that->m_altitudeAccuracy);
+ that->updatePosition();
+}
+
+void GeolocationServiceGtk::setError(PositionError::ErrorCode errorCode, const char* message)
+{
+ m_lastPosition = 0;
+ m_lastError = PositionError::create(errorCode, String::fromUTF8(message));
}
}
diff --git a/WebCore/platform/gtk/GeolocationServiceGtk.h b/WebCore/platform/gtk/GeolocationServiceGtk.h
index 02aff2d..90699ad 100644
--- a/WebCore/platform/gtk/GeolocationServiceGtk.h
+++ b/WebCore/platform/gtk/GeolocationServiceGtk.h
@@ -21,11 +21,18 @@
#define GeolocationServiceGtk_h
#include "GeolocationService.h"
+#include "Geoposition.h"
+#include "PositionError.h"
+#include "RefPtr.h"
+
+#include <geoclue/geoclue-master.h>
+#include <geoclue/geoclue-position.h>
namespace WebCore {
class GeolocationServiceGtk : public GeolocationService {
public:
GeolocationServiceGtk(GeolocationServiceClient*);
+ ~GeolocationServiceGtk();
virtual bool startUpdating(PositionOptions*);
virtual void stopUpdating();
@@ -35,6 +42,29 @@ namespace WebCore {
Geoposition* lastPosition() const;
PositionError* lastError() const;
+
+ private:
+ void updateLocationInformation();
+ void setError(PositionError::ErrorCode, const char* message);
+ void updatePosition();
+
+ static void position_changed(GeocluePosition*, GeocluePositionFields, int, double, double, double, GeoclueAccuracy*, GeolocationServiceGtk*);
+
+ private:
+ RefPtr<Geoposition> m_lastPosition;
+ RefPtr<PositionError> m_lastError;
+
+ // state objects
+ GeoclueMasterClient* m_geoclueClient;
+ GeocluePosition* m_geocluePosition;
+
+ // Error and Position state
+ double m_latitude;
+ double m_longitude;
+ double m_altitude;
+ double m_accuracy;
+ double m_altitudeAccuracy;
+ int m_timestamp;
};
}
diff --git a/WebCore/platform/gtk/LoggingGtk.cpp b/WebCore/platform/gtk/LoggingGtk.cpp
index 5bc1559..c46364c 100644
--- a/WebCore/platform/gtk/LoggingGtk.cpp
+++ b/WebCore/platform/gtk/LoggingGtk.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -20,12 +21,93 @@
#include "config.h"
#include "Logging.h"
+#include <glib.h>
+#include <string.h>
+
namespace WebCore {
+// Inspired by the code used by the Qt port
+
+static WTFLogChannel* getChannelFromName(const char* channelName)
+{
+ if (strlen(channelName) < 3)
+ return 0;
+
+ if (!g_ascii_strcasecmp(channelName, "BackForward"))
+ return &LogBackForward;
+ if (!g_ascii_strcasecmp(channelName, "Editing"))
+ return &LogEditing;
+ if (!g_ascii_strcasecmp(channelName, "Events"))
+ return &LogEvents;
+ if (!g_ascii_strcasecmp(channelName, "Frames"))
+ return &LogFrames;
+ if (!g_ascii_strcasecmp(channelName, "FTP"))
+ return &LogFTP;
+ if (!g_ascii_strcasecmp(channelName, "History"))
+ return &LogHistory;
+ if (!g_ascii_strcasecmp(channelName, "IconDatabase"))
+ return &LogIconDatabase;
+ if (!g_ascii_strcasecmp(channelName, "Loading"))
+ return &LogLoading;
+ if (!g_ascii_strcasecmp(channelName, "Media"))
+ return &LogMedia;
+ if (!g_ascii_strcasecmp(channelName, "Network"))
+ return &LogNetwork;
+ if (!g_ascii_strcasecmp(channelName, "NotYetImplemented"))
+ return &LogNotYetImplemented;
+ if (!g_ascii_strcasecmp(channelName, "PageCache"))
+ return &LogPageCache;
+ if (!g_ascii_strcasecmp(channelName, "PlatformLeaks"))
+ return &LogPlatformLeaks;
+ if (!g_ascii_strcasecmp(channelName, "Plugin"))
+ return &LogPlugin;
+ if (!g_ascii_strcasecmp(channelName, "PopupBlocking"))
+ return &LogPopupBlocking;
+ if (!g_ascii_strcasecmp(channelName, "SpellingAndGrammar"))
+ return &LogSpellingAndGrammar;
+ if (!g_ascii_strcasecmp(channelName, "SQLDatabase"))
+ return &LogSQLDatabase;
+ if (!g_ascii_strcasecmp(channelName, "StorageAPI"))
+ return &LogStorageAPI;
+ if (!g_ascii_strcasecmp(channelName, "TextConversion"))
+ return &LogTextConversion;
+ if (!g_ascii_strcasecmp(channelName, "Threading"))
+ return &LogThreading;
+
+ return 0;
+}
+
void InitializeLoggingChannelsIfNecessary()
{
- // FIXME: Add a way for the user to specify which
- // logs he/she would like turned on.
+ static bool didInitializeLoggingChannels = false;
+ if (didInitializeLoggingChannels)
+ return;
+
+ didInitializeLoggingChannels = true;
+
+ char* logEnv = getenv("WEBKIT_DEBUG");
+ if (!logEnv)
+ return;
+
+ // we set up the logs anyway because some of our logging, such as
+ // soup's is available in release builds
+#if defined(NDEBUG)
+ g_warning("WEBKIT_DEBUG is not empty, but this is a release build. Notice that many log messages will only appear in a debug build.");
+#endif
+
+ char** logv = g_strsplit(logEnv, " ", -1);
+
+ for (int i = 0; logv[i]; i++) {
+ WTFLogChannel* channel = getChannelFromName(logv[i]);
+ if (!channel)
+ continue;
+ channel->state = WTFLogChannelOn;
+ }
+
+ g_strfreev(logv);
+
+ // to disable logging notImplemented set the DISABLE_NI_WARNING
+ // environment variable to 1
LogNotYetImplemented.state = WTFLogChannelOn;
}
diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp
index 85c5aa0..54b41ab 100644
--- a/WebCore/platform/gtk/PopupMenuGtk.cpp
+++ b/WebCore/platform/gtk/PopupMenuGtk.cpp
@@ -52,12 +52,7 @@ void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
if (!m_popup) {
m_popup = GTK_MENU(gtk_menu_new());
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink(G_OBJECT(m_popup));
-#else
- g_object_ref(G_OBJECT(m_popup));
- gtk_object_sink(GTK_OBJECT(m_popup));
-#endif
g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmapped), this);
} else
gtk_container_foreach(GTK_CONTAINER(m_popup), reinterpret_cast<GtkCallback>(menuRemoveItem), this);
diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp
index e1316ee..b3b6dd9 100644
--- a/WebCore/platform/gtk/ScrollViewGtk.cpp
+++ b/WebCore/platform/gtk/ScrollViewGtk.cpp
@@ -154,7 +154,7 @@ bool ScrollView::platformHandleHorizontalAdjustment(const IntSize& scroll)
m_horizontalAdjustment->upper = contentsWidth();
gtk_adjustment_changed(m_horizontalAdjustment);
- if (m_scrollOffset.width() != scroll.width()) {
+ if (m_horizontalAdjustment->value != scroll.width()) {
m_horizontalAdjustment->value = scroll.width();
gtk_adjustment_value_changed(m_horizontalAdjustment);
}
@@ -173,7 +173,7 @@ bool ScrollView::platformHandleVerticalAdjustment(const IntSize& scroll)
m_verticalAdjustment->upper = contentsHeight();
gtk_adjustment_changed(m_verticalAdjustment);
- if (m_scrollOffset.height() != scroll.height()) {
+ if (m_verticalAdjustment->value != scroll.height()) {
m_verticalAdjustment->value = scroll.height();
gtk_adjustment_value_changed(m_verticalAdjustment);
}
diff --git a/WebCore/platform/gtk/ScrollbarGtk.cpp b/WebCore/platform/gtk/ScrollbarGtk.cpp
index df165e3..7543e23 100644
--- a/WebCore/platform/gtk/ScrollbarGtk.cpp
+++ b/WebCore/platform/gtk/ScrollbarGtk.cpp
@@ -44,19 +44,18 @@ static gboolean gtkScrollEventCallback(GtkWidget* widget, GdkEventScroll* event,
}
ScrollbarGtk::ScrollbarGtk(ScrollbarClient* client, ScrollbarOrientation orientation,
- ScrollbarControlSize controlSize)
+ 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)))
{
- GtkScrollbar* scrollBar = orientation == HorizontalScrollbar ?
- GTK_SCROLLBAR(::gtk_hscrollbar_new(m_adjustment)) :
- GTK_SCROLLBAR(::gtk_vscrollbar_new(m_adjustment));
- gtk_widget_show(GTK_WIDGET(scrollBar));
- g_object_ref(G_OBJECT(scrollBar));
- g_signal_connect(G_OBJECT(scrollBar), "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
- g_signal_connect(G_OBJECT(scrollBar), "scroll-event", G_CALLBACK(gtkScrollEventCallback), this);
+ GtkWidget* scrollBar = orientation == HorizontalScrollbar ?
+ gtk_hscrollbar_new(m_adjustment):
+ gtk_vscrollbar_new(m_adjustment);
+ gtk_widget_show(scrollBar);
+ g_signal_connect(scrollBar, "value-changed", G_CALLBACK(ScrollbarGtk::gtkValueChanged), this);
+ g_signal_connect(scrollBar, "scroll-event", G_CALLBACK(gtkScrollEventCallback), this);
- setPlatformWidget(GTK_WIDGET(scrollBar));
+ setPlatformWidget(scrollBar);
/*
* assign a sane default width and height to the Scrollbar, otherwise
@@ -66,22 +65,24 @@ ScrollbarGtk::ScrollbarGtk(ScrollbarClient* client, ScrollbarOrientation orienta
ScrollbarTheme::nativeTheme()->scrollbarThickness());
}
-ScrollbarGtk::~ScrollbarGtk()
+IntPoint ScrollbarGtk::getLocationInParentWindow(const IntRect& rect)
{
- /*
- * the Widget does not take over ownership.
- */
- g_signal_handlers_disconnect_by_func(G_OBJECT(platformWidget()), (gpointer)ScrollbarGtk::gtkValueChanged, this);
- g_signal_handlers_disconnect_by_func(G_OBJECT(platformWidget()), (gpointer)gtkScrollEventCallback, this);
- g_object_unref(G_OBJECT(platformWidget()));
+ IntPoint loc;
+
+ if (parent()->isScrollViewScrollbar(this))
+ loc = parent()->convertToContainingWindow(rect.location());
+ else
+ loc = parent()->contentsToWindow(rect.location());
+
+ return loc;
}
void ScrollbarGtk::frameRectsChanged()
{
- if (!parent() || !parent()->isScrollViewScrollbar(this))
+ if (!parent())
return;
- IntPoint loc = parent()->convertToContainingWindow(frameRect().location());
+ IntPoint loc = getLocationInParentWindow(frameRect());
// Don't allow the allocation size to be negative
IntSize sz = frameRect().size();
@@ -129,5 +130,44 @@ void ScrollbarGtk::setEnabled(bool shouldEnable)
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 GTK_NO_WINDOW is set 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_NO_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();
+
+ event->expose.region = gdk_region_rectangle(&event->expose.area);
+
+ /*
+ * 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.
+ */
+ if (!gdk_region_empty(event->expose.region))
+ gtk_widget_send_expose(widget, event);
+
+ gdk_event_free(event);
+}
diff --git a/WebCore/platform/gtk/ScrollbarGtk.h b/WebCore/platform/gtk/ScrollbarGtk.h
index 11ff079..1ef4c49 100644
--- a/WebCore/platform/gtk/ScrollbarGtk.h
+++ b/WebCore/platform/gtk/ScrollbarGtk.h
@@ -37,9 +37,8 @@ class ScrollbarGtk : public Scrollbar {
public:
friend class Scrollbar;
- virtual ~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; }
@@ -58,6 +57,7 @@ protected:
private:
static void gtkValueChanged(GtkAdjustment*, ScrollbarGtk*);
+ IntPoint getLocationInParentWindow(const IntRect&);
GtkAdjustment* m_adjustment;
};
diff --git a/WebCore/platform/gtk/WheelEventGtk.cpp b/WebCore/platform/gtk/WheelEventGtk.cpp
index 64ec65a..075bed2 100644
--- a/WebCore/platform/gtk/WheelEventGtk.cpp
+++ b/WebCore/platform/gtk/WheelEventGtk.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#include "PlatformWheelEvent.h"
+#include "Scrollbar.h"
#include <gdk/gdk.h>
@@ -52,16 +53,18 @@ PlatformWheelEvent::PlatformWheelEvent(GdkEventScroll* event)
m_deltaY = -delta;
break;
case GDK_SCROLL_LEFT:
- m_deltaX = -delta;
+ m_deltaX = delta;
break;
case GDK_SCROLL_RIGHT:
- m_deltaX = delta;
+ m_deltaX = -delta;
break;
}
+ m_wheelTicksX = m_deltaX;
+ m_wheelTicksY = m_deltaY;
- m_position = IntPoint((int)event->x, (int)event->y);
- m_globalPosition = IntPoint((int)event->x_root, (int)event->y_root);
- m_granularity = ScrollByLineWheelEvent;
+ m_position = IntPoint(static_cast<int>(event->x), static_cast<int>(event->y));
+ m_globalPosition = IntPoint(static_cast<int>(event->x_root), static_cast<int>(event->y_root));
+ m_granularity = ScrollByPixelWheelEvent;
m_isAccepted = false;
m_shiftKey = event->state & GDK_SHIFT_MASK;
m_ctrlKey = event->state & GDK_CONTROL_MASK;
@@ -74,8 +77,8 @@ PlatformWheelEvent::PlatformWheelEvent(GdkEventScroll* event)
#endif
// FIXME: retrieve the user setting for the number of lines to scroll on each wheel event
- m_deltaX *= horizontalLineMultiplier();
- m_deltaY *= verticalLineMultiplier();
+ m_deltaX *= static_cast<float>(cScrollbarPixelsPerLineStep);
+ m_deltaY *= static_cast<float>(cScrollbarPixelsPerLineStep);
}
}
diff --git a/WebCore/platform/gtk/WidgetGtk.cpp b/WebCore/platform/gtk/WidgetGtk.cpp
index 82fed74..4f09e77 100644
--- a/WebCore/platform/gtk/WidgetGtk.cpp
+++ b/WebCore/platform/gtk/WidgetGtk.cpp
@@ -41,23 +41,17 @@
namespace WebCore {
-class WidgetPrivate {
-public:
- GdkCursor* cursor;
-};
+static GdkCursor* lastSetCursor;
Widget::Widget(PlatformWidget widget)
- : m_data(new WidgetPrivate)
{
init(widget);
- m_data->cursor = 0;
}
Widget::~Widget()
{
ASSERT(!parent());
releasePlatformWidget();
- delete m_data;
}
void Widget::setFocus()
@@ -65,11 +59,6 @@ void Widget::setFocus()
gtk_widget_grab_focus(platformWidget() ? platformWidget() : GTK_WIDGET(root()->hostWindow()->platformWindow()));
}
-Cursor Widget::cursor()
-{
- return Cursor(m_data->cursor);
-}
-
static GdkDrawable* gdkDrawable(PlatformWidget widget)
{
return widget ? widget->window : 0;
@@ -77,7 +66,7 @@ static GdkDrawable* gdkDrawable(PlatformWidget widget)
void Widget::setCursor(const Cursor& cursor)
{
- GdkCursor* pcur = cursor.impl();
+ GdkCursor* platformCursor = cursor.impl();
// http://bugs.webkit.org/show_bug.cgi?id=16388
// [GTK] Widget::setCursor() gets called frequently
@@ -85,11 +74,11 @@ void Widget::setCursor(const Cursor& cursor)
// gdk_window_set_cursor() in certain GDK backends seems to be an
// expensive operation, so avoid it if possible.
- if (pcur == m_data->cursor)
+ if (platformCursor == lastSetCursor)
return;
- gdk_window_set_cursor(gdkDrawable(platformWidget()) ? GDK_WINDOW(gdkDrawable(platformWidget())) : GTK_WIDGET(root()->hostWindow()->platformWindow())->window, pcur);
- m_data->cursor = pcur;
+ gdk_window_set_cursor(gdkDrawable(platformWidget()) ? GDK_WINDOW(gdkDrawable(platformWidget())) : GTK_WIDGET(root()->hostWindow()->platformWindow())->window, platformCursor);
+ lastSetCursor = platformCursor;
}
void Widget::show()
@@ -106,41 +95,8 @@ void Widget::hide()
gtk_widget_hide(platformWidget());
}
-/*
- * Strategy to painting a Widget:
- * 1.) do not paint if there is no GtkWidget set
- * 2.) We assume that GTK_NO_WINDOW is set and that frameRectsChanged positioned
- * the widget correctly. ATM we do not honor the GraphicsContext translation.
- */
-void Widget::paint(GraphicsContext* context, const IntRect&)
+void Widget::paint(GraphicsContext* context, const IntRect& rect)
{
- if (!platformWidget())
- return;
-
- if (!context->gdkExposeEvent())
- return;
-
- GtkWidget* widget = platformWidget();
- ASSERT(GTK_WIDGET_NO_WINDOW(widget));
-
- GdkEvent* event = gdk_event_new(GDK_EXPOSE);
- event->expose = *context->gdkExposeEvent();
- event->expose.region = gtk_widget_region_intersect(widget, event->expose.region);
-
- /*
- * 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.
- */
- if (!gdk_region_empty(event->expose.region)) {
- gdk_region_get_clipbox(event->expose.region, &event->expose.area);
- gtk_widget_send_expose(widget, event);
- }
-
- gdk_event_free(event);
}
void Widget::setIsSelected(bool)
@@ -169,12 +125,7 @@ void Widget::retainPlatformWidget()
{
if (!platformWidget())
return;
-#if GLIB_CHECK_VERSION(2,10,0)
g_object_ref_sink(platformWidget());
-#else
- g_object_ref(platformWidget());
- gtk_object_sink(GTK_OBJECT(platformWidget()));
-#endif
}
}
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index e21ddcf..17756ac 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -57,12 +57,11 @@ public:
void clear() {
m_bytes.clear();
- m_rect = IntRect();
- m_height = 0;
m_status = FrameEmpty;
- m_duration = 0;
- m_disposalMethod = DisposeNotSpecified;
- m_hasAlpha = false;
+ // NOTE: Do not reset other members here; clearFrameBufferCache() calls
+ // this to free the bitmap data, but other functions like
+ // initFrameBuffer() and frameComplete() may still need to read other
+ // metadata out of this frame later.
}
const RGBA32Array& bytes() const { return m_bytes; }
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index 843e65a..5b4b675 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -188,7 +188,8 @@ void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
// In some cases, like if the decoder was destroyed while animating, we
// can be asked to clear more frames than we currently have.
if (m_frameBufferCache.isEmpty())
- return; // Nothing to do.
+ return; // Nothing to do.
+
// The "-1" here is tricky. It does not mean that |clearBeforeFrame| is the
// last frame we wish to preserve, but rather that we never want to clear
// the very last frame in the cache: it's empty (so clearing it is
@@ -199,21 +200,36 @@ void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
// this case.
clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1);
const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);
- for (Vector<RGBA32Buffer>::iterator i(m_frameBufferCache.begin()); i != end; ++i) {
- if (i->status() == RGBA32Buffer::FrameEmpty)
- continue; // Nothing to do.
-
- // The layout of frames is:
- // [empty frames][complete frames][partial frame][empty frames]
- // ...where each of these groups may be empty. We should not clear a
- // partial frame since that's what's being decoded right now, and we
- // also should not clear the last complete frame, since it may be needed
- // when constructing the next frame. Note that "i + 1" is safe since
- // i < end < m_frameBufferCache.end().
- if ((i->status() == RGBA32Buffer::FramePartial) || ((i + 1)->status() != RGBA32Buffer::FrameComplete))
- break;
-
- i->clear();
+
+ // We need to preserve frames such that:
+ // * We don't clear |end|
+ // * We don't clear the frame we're currently decoding
+ // * We don't clear any frame from which a future initFrameBuffer() call
+ // will copy bitmap data
+ // All other frames can be cleared. Because of the constraints on when
+ // ImageSource::clear() can be called (see ImageSource.h), we're guaranteed
+ // not to have non-empty frames after the frame we're currently decoding.
+ // So, scan backwards from |end| as follows:
+ // * If the frame is empty, we're still past any frames we care about.
+ // * If the frame is complete, but is DisposeOverwritePrevious, we'll
+ // skip over it in future initFrameBuffer() calls. We can clear it
+ // unless it's |end|, and keep scanning. For any other disposal method,
+ // stop scanning, as we've found the frame initFrameBuffer() will need
+ // next.
+ // * If the frame is partial, we're decoding it, so don't clear it; if it
+ // has a disposal method other than DisposeOverwritePrevious, stop
+ // scanning, as we'll only need this frame when decoding the next one.
+ Vector<RGBA32Buffer>::iterator i(end);
+ for (; (i != m_frameBufferCache.begin()) && ((i->status() == RGBA32Buffer::FrameEmpty) || (i->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) {
+ if ((i->status() == RGBA32Buffer::FrameComplete) && (i != end))
+ i->clear();
+ }
+
+ // Now |i| holds the last frame we need to preserve; clear prior frames.
+ for (Vector<RGBA32Buffer>::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
+ ASSERT(j->status() != RGBA32Buffer::FramePartial);
+ if (j->status() != RGBA32Buffer::FrameEmpty)
+ j->clear();
}
}
diff --git a/WebCore/platform/image-decoders/skia/ImageDecoder.h b/WebCore/platform/image-decoders/skia/ImageDecoder.h
index b983315..cddb69b 100644
--- a/WebCore/platform/image-decoders/skia/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/skia/ImageDecoder.h
@@ -132,10 +132,11 @@ namespace WebCore {
void clear()
{
m_bitmapRef = RefCountedNativeImageSkia::create();
- m_rect = IntRect();
m_status = FrameEmpty;
- m_duration = 0;
- m_disposalMethod = DisposeNotSpecified;
+ // NOTE: Do not reset other members here; clearFrameBufferCache()
+ // calls this to free the bitmap data, but other functions like
+ // initFrameBuffer() and frameComplete() may still need to read
+ // other metadata out of this frame later.
}
// This function creates a new copy of the image data in |other|, so the
diff --git a/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp b/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
new file mode 100644
index 0000000..aa20c62
--- /dev/null
+++ b/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2006-2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "IntSize.h"
+#include "OwnArrayPtr.h"
+#include "PNGImageEncoder.h"
+#include "Vector.h"
+
+#include "SkBitmap.h"
+
+extern "C" {
+#include "png.h"
+}
+
+namespace WebCore {
+
+// Converts BGRA->RGBA and RGBA->BGRA.
+static void convertBetweenBGRAandRGBA(const unsigned char* input, int numberOfPixels,
+ unsigned char* output)
+{
+ for (int x = 0; x < numberOfPixels; x++) {
+ const unsigned char* pixelIn = &input[x * 4];
+ unsigned char* pixelOut = &output[x * 4];
+ pixelOut[0] = pixelIn[2];
+ pixelOut[1] = pixelIn[1];
+ pixelOut[2] = pixelIn[0];
+ pixelOut[3] = pixelIn[3];
+ }
+}
+
+// Encoder --------------------------------------------------------------------
+//
+// This section of the code is based on nsPNGEncoder.cpp in Mozilla
+// (Copyright 2005 Google Inc.)
+
+// Passed around as the io_ptr in the png structs so our callbacks know where
+// to write data.
+struct PNGEncoderState {
+ PNGEncoderState(Vector<unsigned char>* o) : m_out(o) {}
+ Vector<unsigned char>* m_out;
+};
+
+// Called by libpng to flush its internal buffer to ours.
+void encoderWriteCallback(png_structp png, png_bytep data, png_size_t size)
+{
+ PNGEncoderState* state = static_cast<PNGEncoderState*>(png_get_io_ptr(png));
+ ASSERT(state->m_out);
+
+ size_t oldSize = state->m_out->size();
+ state->m_out->resize(oldSize + size);
+ memcpy(&(*state->m_out)[oldSize], data, size);
+}
+
+// Automatically destroys the given write structs on destruction to make
+// cleanup and error handling code cleaner.
+class PNGWriteStructDestroyer {
+public:
+ PNGWriteStructDestroyer(png_struct** ps, png_info** pi)
+ : m_pngStruct(ps)
+ , m_pngInfo(pi) {
+ }
+
+ ~PNGWriteStructDestroyer() {
+ png_destroy_write_struct(m_pngStruct, m_pngInfo);
+ }
+
+private:
+ png_struct** m_pngStruct;
+ png_info** m_pngInfo;
+};
+
+// static
+bool PNGImageEncoder::encode(const SkBitmap& image, Vector<unsigned char>* output)
+{
+ if (image.config() != SkBitmap::kARGB_8888_Config)
+ return false; // Only support ARGB at 8 bpp now.
+
+ image.lockPixels();
+ bool result = PNGImageEncoder::encode(static_cast<unsigned char*>(
+ image.getPixels()), IntSize(image.width(), image.height()),
+ image.rowBytes(), output);
+ image.unlockPixels();
+ return result;
+}
+
+// static
+bool PNGImageEncoder::encode(const unsigned char* input, const IntSize& size,
+ int bytesPerRow,
+ Vector<unsigned char>* output)
+{
+ int inputColorComponents = 4;
+ int outputColorComponents = 4;
+ int pngOutputColorType = PNG_COLOR_TYPE_RGB_ALPHA;
+ IntSize imageSize(size);
+ imageSize.clampNegativeToZero();
+
+ // Row stride should be at least as long as the length of the data.
+ if (inputColorComponents * imageSize.width() > bytesPerRow) {
+ ASSERT(false);
+ return false;
+ }
+
+ png_struct* pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+ png_voidp_NULL,
+ png_error_ptr_NULL,
+ png_error_ptr_NULL);
+ if (!pngPtr)
+ return false;
+
+ png_info* infoPtr = png_create_info_struct(pngPtr);
+ if (!infoPtr) {
+ png_destroy_write_struct(&pngPtr, NULL);
+ return false;
+ }
+ PNGWriteStructDestroyer destroyer(&pngPtr, &infoPtr);
+
+ if (setjmp(png_jmpbuf(pngPtr))) {
+ // The destroyer will ensure that the structures are cleaned up in this
+ // case, even though we may get here as a jump from random parts of the
+ // PNG library called below.
+ return false;
+ }
+
+ // Set our callback for libpng to give us the data.
+ PNGEncoderState state(output);
+ png_set_write_fn(pngPtr, &state, encoderWriteCallback, NULL);
+
+ png_set_IHDR(pngPtr, infoPtr, imageSize.width(), imageSize.height(), 8, pngOutputColorType,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+ png_write_info(pngPtr, infoPtr);
+
+ OwnArrayPtr<unsigned char> rowPixels(new unsigned char[imageSize.width() * outputColorComponents]);
+ for (int y = 0; y < imageSize.height(); y ++) {
+ convertBetweenBGRAandRGBA(&input[y * bytesPerRow], imageSize.width(), rowPixels.get());
+ png_write_row(pngPtr, rowPixels.get());
+ }
+
+ png_write_end(pngPtr, infoPtr);
+ return true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/image-encoders/skia/PNGImageEncoder.h b/WebCore/platform/image-encoders/skia/PNGImageEncoder.h
new file mode 100644
index 0000000..b5865d2
--- /dev/null
+++ b/WebCore/platform/image-encoders/skia/PNGImageEncoder.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006-2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PNGImageEncoder_h
+#define PNGImageEncoder_h
+
+#include "Vector.h"
+
+class IntSize;
+class SkBitmap;
+
+namespace WebCore {
+
+ // Interface for encoding PNG data. This is a wrapper around libpng.
+ class PNGImageEncoder {
+ public:
+ // Encodes the specific SkBitmap into the supplied vector.
+ static bool encode(const SkBitmap&, WTF::Vector<unsigned char>* output);
+
+ // Encodes the specified image data into the supplied vector.
+ // w, h give the size of the image and bytes_per_row gives the bytes
+ // per row.
+ static bool encode(const unsigned char* input, const IntSize& size, int bytesPerRow, WTF::Vector<unsigned char>* output);
+ };
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/mac/FoundationExtras.h b/WebCore/platform/mac/FoundationExtras.h
index 51a7df0..85ce8d7 100644
--- a/WebCore/platform/mac/FoundationExtras.h
+++ b/WebCore/platform/mac/FoundationExtras.h
@@ -23,6 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#import <CoreFoundation/CFBase.h>
+#import <Foundation/NSObject.h>
+
// nil-checked CFRetain/CFRelease covers for Objective-C ids
// Use CFRetain, CFRelease, HardRetain, or HardRelease instead of
diff --git a/WebCore/platform/mac/GeolocationServiceMac.h b/WebCore/platform/mac/GeolocationServiceMac.h
new file mode 100644
index 0000000..d0342e7
--- /dev/null
+++ b/WebCore/platform/mac/GeolocationServiceMac.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationServiceMac_h
+#define GeolocationServiceMac_h
+
+#if ENABLE(GEOLOCATION)
+
+#include "GeolocationService.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
+
+#ifdef __OBJC__
+@class CLLocationManager;
+@class WebCoreCoreLocationObserver;
+#else
+class CLLocationManager;
+class WebCoreCoreLocationObserver;
+#endif
+
+namespace WebCore {
+
+class GeolocationServiceMac : public GeolocationService {
+public:
+ GeolocationServiceMac(GeolocationServiceClient*);
+ virtual ~GeolocationServiceMac();
+
+ virtual bool startUpdating(PositionOptions*);
+ virtual void stopUpdating();
+
+ virtual void suspend();
+ virtual void resume();
+
+ virtual Geoposition* lastPosition() const { return m_lastPosition.get(); }
+ virtual PositionError* lastError() const { return m_lastError.get(); }
+
+ void positionChanged(PassRefPtr<Geoposition>);
+ void errorOccurred(PassRefPtr<PositionError>);
+
+private:
+ RetainPtr<CLLocationManager> m_locationManager;
+ RetainPtr<WebCoreCoreLocationObserver> m_objcObserver;
+
+ RefPtr<Geoposition> m_lastPosition;
+ RefPtr<PositionError> m_lastError;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(GEOLOCATION)
+
+#endif // GeolocationServiceMac_h
diff --git a/WebCore/platform/mac/GeolocationServiceMac.mm b/WebCore/platform/mac/GeolocationServiceMac.mm
new file mode 100644
index 0000000..c21b02c
--- /dev/null
+++ b/WebCore/platform/mac/GeolocationServiceMac.mm
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+
+#if ENABLE(GEOLOCATION)
+
+#import "GeolocationServiceMac.h"
+
+#import "Geoposition.h"
+#import "PositionError.h"
+#import "PositionOptions.h"
+#import "SoftLinking.h"
+#import <CoreLocation/CoreLocation.h>
+#import <objc/objc-runtime.h>
+#import <wtf/RefPtr.h>
+#import <wtf/UnusedParam.h>
+
+SOFT_LINK_FRAMEWORK(CoreLocation)
+
+SOFT_LINK_CLASS(CoreLocation, CLLocationManager)
+SOFT_LINK_CLASS(CoreLocation, CLLocation)
+
+SOFT_LINK_CONSTANT(CoreLocation, kCLLocationAccuracyBest, double)
+SOFT_LINK_CONSTANT(CoreLocation, kCLLocationAccuracyHundredMeters, double)
+
+#define kCLLocationAccuracyBest getkCLLocationAccuracyBest()
+#define kCLLocationAccuracyHundredMeters getkCLLocationAccuracyHundredMeters()
+
+using namespace WebCore;
+
+@interface WebCoreCoreLocationObserver : NSObject<CLLocationManagerDelegate>
+{
+ GeolocationServiceMac* m_callback;
+}
+
+- (id)initWithCallback:(GeolocationServiceMac*)callback;
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
+
+@end
+
+namespace WebCore {
+
+GeolocationService* GeolocationService::create(GeolocationServiceClient* client)
+{
+ return new GeolocationServiceMac(client);
+}
+
+GeolocationServiceMac::GeolocationServiceMac(GeolocationServiceClient* client)
+ : GeolocationService(client)
+ , m_objcObserver(AdoptNS, [[WebCoreCoreLocationObserver alloc] initWithCallback:this])
+{
+}
+
+GeolocationServiceMac::~GeolocationServiceMac()
+{
+ [m_locationManager.get() stopUpdatingLocation];
+ m_locationManager.get().delegate = nil;
+}
+
+bool GeolocationServiceMac::startUpdating(PositionOptions* options)
+{
+ #define CLLocationManager getCLLocationManagerClass()
+ if (!m_locationManager.get()) {
+ m_locationManager.adoptNS([[CLLocationManager alloc] init]);
+ m_locationManager.get().delegate = m_objcObserver.get();
+ }
+
+ if (!m_locationManager.get().locationServicesEnabled)
+ return false;
+
+ if (options) {
+ // CLLocationAccuracy values suggested by Ron Huang.
+ CLLocationAccuracy accuracy = options->enableHighAccuracy() ? kCLLocationAccuracyBest : kCLLocationAccuracyHundredMeters;
+ m_locationManager.get().desiredAccuracy = accuracy;
+ }
+
+ // This can safely be called multiple times.
+ [m_locationManager.get() startUpdatingLocation];
+
+ return true;
+ #undef CLLocationManager
+}
+
+void GeolocationServiceMac::stopUpdating()
+{
+ [m_locationManager.get() stopUpdatingLocation];
+}
+
+void GeolocationServiceMac::suspend()
+{
+ [m_locationManager.get() stopUpdatingLocation];
+}
+
+void GeolocationServiceMac::resume()
+{
+ [m_locationManager.get() startUpdatingLocation];
+}
+
+void GeolocationServiceMac::positionChanged(PassRefPtr<Geoposition> position)
+{
+ m_lastPosition = position;
+ GeolocationService::positionChanged();
+}
+
+void GeolocationServiceMac::errorOccurred(PassRefPtr<PositionError> error)
+{
+ m_lastError = error;
+ GeolocationService::errorOccurred();
+}
+
+} // namespace WebCore
+
+@implementation WebCoreCoreLocationObserver
+
+- (id)initWithCallback:(GeolocationServiceMac *)callback
+{
+ self = [super init];
+ if (self)
+ m_callback = callback;
+ return self;
+}
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
+{
+ ASSERT(m_callback);
+ ASSERT(newLocation);
+ UNUSED_PARAM(manager);
+ UNUSED_PARAM(oldLocation);
+
+ // Normalize
+ double altitude = newLocation.altitude;
+ double altitudeAccuracy = newLocation.verticalAccuracy;
+ if (altitudeAccuracy < 0.0) {
+ altitudeAccuracy = 0.0;
+ altitude = 0.0;
+ }
+ double speed = newLocation.speed;
+ if (speed < 0.0)
+ speed = 0.0;
+ double heading = newLocation.course;
+ if (heading < 0.0)
+ heading = 0.0;
+
+ WTF::RefPtr<WebCore::Coordinates> newCoordinates = WebCore::Coordinates::create(
+ newLocation.coordinate.latitude,
+ newLocation.coordinate.longitude,
+ altitude,
+ newLocation.horizontalAccuracy,
+ altitudeAccuracy,
+ heading,
+ speed);
+ WTF::RefPtr<WebCore::Geoposition> newPosition = WebCore::Geoposition::create(
+ newCoordinates.release(),
+ [newLocation.timestamp timeIntervalSince1970] * 1000.0); // seconds -> milliseconds
+
+ m_callback->positionChanged(newPosition.release());
+}
+
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
+{
+ ASSERT(m_callback);
+ ASSERT(error);
+
+ UNUSED_PARAM(manager);
+
+ PositionError::ErrorCode code;
+ switch ([error code]) {
+ case kCLErrorDenied:
+ code = PositionError::PERMISSION_DENIED;
+ break;
+ case kCLErrorLocationUnknown:
+ code = PositionError::POSITION_UNAVAILABLE;
+ break;
+ default:
+ code = PositionError::POSITION_UNAVAILABLE;
+ break;
+ }
+
+ m_callback->errorOccurred(PositionError::create(code, [error localizedDescription]));
+}
+
+@end
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/platform/mac/LocalCurrentGraphicsContext.h b/WebCore/platform/mac/LocalCurrentGraphicsContext.h
index 856cf52..1c5cae7 100644
--- a/WebCore/platform/mac/LocalCurrentGraphicsContext.h
+++ b/WebCore/platform/mac/LocalCurrentGraphicsContext.h
@@ -19,7 +19,11 @@
#include <wtf/Noncopyable.h>
+#ifdef __OBJC__
+@class NSGraphicsContext;
+#else
class NSGraphicsContext;
+#endif
namespace WebCore {
diff --git a/WebCore/platform/mac/PasteboardMac.mm b/WebCore/platform/mac/PasteboardMac.mm
index de369fc..36b00f6 100644
--- a/WebCore/platform/mac/PasteboardMac.mm
+++ b/WebCore/platform/mac/PasteboardMac.mm
@@ -278,7 +278,7 @@ void Pasteboard::writeImage(Node* node, const KURL& url, const String& title)
ASSERT(cocoaURL);
ASSERT(node->renderer() && node->renderer()->isImage());
- RenderImage* renderer = static_cast<RenderImage*>(node->renderer());
+ RenderImage* renderer = toRenderImage(node->renderer());
CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage());
ASSERT(cachedImage);
@@ -310,7 +310,7 @@ String Pasteboard::plainText(Frame* frame)
NSArray *types = [m_pasteboard.get() types];
if ([types containsObject:NSStringPboardType])
- return [m_pasteboard.get() stringForType:NSStringPboardType];
+ return [[m_pasteboard.get() stringForType:NSStringPboardType] precomposedStringWithCanonicalMapping];
NSAttributedString *attributedString = nil;
NSString *string;
@@ -320,13 +320,13 @@ String Pasteboard::plainText(Frame* frame)
if (attributedString == nil && [types containsObject:NSRTFPboardType])
attributedString = [[NSAttributedString alloc] initWithRTF:[m_pasteboard.get() dataForType:NSRTFPboardType] documentAttributes:NULL];
if (attributedString != nil) {
- string = [[attributedString string] copy];
+ string = [[attributedString string] precomposedStringWithCanonicalMapping];
[attributedString release];
- return [string autorelease];
+ return string;
}
if ([types containsObject:NSFilenamesPboardType]) {
- string = [[m_pasteboard.get() propertyListForType:NSFilenamesPboardType] componentsJoinedByString:@"\n"];
+ string = [[[m_pasteboard.get() propertyListForType:NSFilenamesPboardType] componentsJoinedByString:@"\n"] precomposedStringWithCanonicalMapping];
if (string != nil)
return string;
}
@@ -338,7 +338,7 @@ String Pasteboard::plainText(Frame* frame)
// helper code that should either be done in a separate patch or figured out in another way.
string = frame->editor()->client()->userVisibleString(url);
if ([string length] > 0)
- return string;
+ return [string precomposedStringWithCanonicalMapping];
}
diff --git a/WebCore/platform/mac/PlatformScreenMac.mm b/WebCore/platform/mac/PlatformScreenMac.mm
index 8f12df0..5dbfcf4 100644
--- a/WebCore/platform/mac/PlatformScreenMac.mm
+++ b/WebCore/platform/mac/PlatformScreenMac.mm
@@ -45,11 +45,7 @@ int screenDepthPerComponent(Widget*)
bool screenIsMonochrome(Widget*)
{
- NSString *colorSpace = NSColorSpaceFromDepth([[NSScreen deepestScreen] depth]);
- return colorSpace == NSCalibratedWhiteColorSpace
- || colorSpace == NSCalibratedBlackColorSpace
- || colorSpace == NSDeviceWhiteColorSpace
- || colorSpace == NSDeviceBlackColorSpace;
+ return false;
}
// These functions scale between screen and page coordinates because JavaScript/DOM operations
diff --git a/WebCore/platform/mac/SharedBufferMac.mm b/WebCore/platform/mac/SharedBufferMac.mm
index f1d9517..c4e7528 100644
--- a/WebCore/platform/mac/SharedBufferMac.mm
+++ b/WebCore/platform/mac/SharedBufferMac.mm
@@ -39,7 +39,7 @@ using namespace WebCore;
@interface WebCoreSharedBufferData : NSData
{
- SharedBuffer* sharedBuffer;
+ RefPtr<SharedBuffer> sharedBuffer;
}
- (id)initWithSharedBuffer:(SharedBuffer*)buffer;
@@ -59,16 +59,12 @@ using namespace WebCore;
{
if (WebCoreObjCScheduleDeallocateOnMainThread([WebCoreSharedBufferData class], self))
return;
-
- sharedBuffer->deref();
[super dealloc];
}
- (void)finalize
{
- sharedBuffer->deref();
-
[super finalize];
}
@@ -76,10 +72,8 @@ using namespace WebCore;
{
self = [super init];
- if (self) {
+ if (self)
sharedBuffer = buffer;
- sharedBuffer->ref();
- }
return self;
}
diff --git a/WebCore/platform/mac/ThreadCheck.mm b/WebCore/platform/mac/ThreadCheck.mm
index b862598..ddee05c 100644
--- a/WebCore/platform/mac/ThreadCheck.mm
+++ b/WebCore/platform/mac/ThreadCheck.mm
@@ -32,56 +32,74 @@
namespace WebCore {
-static ThreadViolationBehavior defaultThreadViolationBehavior = RaiseExceptionOnThreadViolation;
-
static bool didReadThreadViolationBehaviorFromUserDefaults = false;
-static bool threadViolationBehaviorIsDefault;
-static ThreadViolationBehavior threadViolationBehavior;
+static bool threadViolationBehaviorIsDefault = true;
+static ThreadViolationBehavior threadViolationBehavior[MaximumThreadViolationRound] = { RaiseExceptionOnThreadViolation, RaiseExceptionOnThreadViolation };
static void readThreadViolationBehaviorFromUserDefaults()
{
+ didReadThreadViolationBehaviorFromUserDefaults = true;
+
+ ThreadViolationBehavior newBehavior = LogOnFirstThreadViolation;
NSString *threadCheckLevel = [[NSUserDefaults standardUserDefaults] stringForKey:@"WebCoreThreadCheck"];
+ if (!threadCheckLevel)
+ return;
+
if ([threadCheckLevel isEqualToString:@"None"])
- threadViolationBehavior = NoThreadCheck;
+ newBehavior = NoThreadCheck;
else if ([threadCheckLevel isEqualToString:@"Exception"])
- threadViolationBehavior = RaiseExceptionOnThreadViolation;
+ newBehavior = RaiseExceptionOnThreadViolation;
else if ([threadCheckLevel isEqualToString:@"Log"])
- threadViolationBehavior = LogOnThreadViolation;
+ newBehavior = LogOnThreadViolation;
else if ([threadCheckLevel isEqualToString:@"LogOnce"])
- threadViolationBehavior = LogOnFirstThreadViolation;
- else {
- threadViolationBehavior = defaultThreadViolationBehavior;
- threadViolationBehaviorIsDefault = true;
- }
- didReadThreadViolationBehaviorFromUserDefaults = true;
+ newBehavior = LogOnFirstThreadViolation;
+ else
+ ASSERT_NOT_REACHED();
+
+ threadViolationBehaviorIsDefault = false;
+
+ for (unsigned i = 0; i < MaximumThreadViolationRound; ++i)
+ threadViolationBehavior[i] = newBehavior;
}
-void setDefaultThreadViolationBehavior(ThreadViolationBehavior behavior)
+void setDefaultThreadViolationBehavior(ThreadViolationBehavior behavior, ThreadViolationRound round)
{
- defaultThreadViolationBehavior = behavior;
+ ASSERT(round < MaximumThreadViolationRound);
+ if (round >= MaximumThreadViolationRound)
+ return;
+ if (!didReadThreadViolationBehaviorFromUserDefaults)
+ readThreadViolationBehaviorFromUserDefaults();
if (threadViolationBehaviorIsDefault)
- threadViolationBehavior = behavior;
+ threadViolationBehavior[round] = behavior;
}
-void reportThreadViolation(const char* function)
+void reportThreadViolation(const char* function, ThreadViolationRound round)
{
+ ASSERT(round < MaximumThreadViolationRound);
+ if (round >= MaximumThreadViolationRound)
+ return;
if (!didReadThreadViolationBehaviorFromUserDefaults)
- readThreadViolationBehaviorFromUserDefaults();
- if (threadViolationBehavior == NoThreadCheck)
+ readThreadViolationBehaviorFromUserDefaults();
+ if (threadViolationBehavior[round] == NoThreadCheck)
return;
if (pthread_main_np())
return;
- WebCoreReportThreadViolation(function);
+ WebCoreReportThreadViolation(function, round);
}
} // namespace WebCore
// Split out the actual reporting of the thread violation to make it easier to set a breakpoint
-void WebCoreReportThreadViolation(const char* function)
+void WebCoreReportThreadViolation(const char* function, WebCore::ThreadViolationRound round)
{
using namespace WebCore;
+
+ ASSERT(round < MaximumThreadViolationRound);
+ if (round >= MaximumThreadViolationRound)
+ return;
+
DEFINE_STATIC_LOCAL(HashSet<String>, loggedFunctions, ());
- switch (threadViolationBehavior) {
+ switch (threadViolationBehavior[round]) {
case NoThreadCheck:
break;
case LogOnFirstThreadViolation:
diff --git a/WebCore/platform/mac/WebCoreSystemInterface.h b/WebCore/platform/mac/WebCoreSystemInterface.h
index 14d1713..3feed69 100644
--- a/WebCore/platform/mac/WebCoreSystemInterface.h
+++ b/WebCore/platform/mac/WebCoreSystemInterface.h
@@ -40,12 +40,21 @@ typedef struct _NSRect NSRect;
#endif
#ifdef __OBJC__
+@class NSArray;
@class NSButtonCell;
@class NSData;
+@class NSDate;
@class NSEvent;
@class NSFont;
+@class NSImage;
+@class NSMenu;
@class NSMutableURLRequest;
+@class NSString;
+@class NSTextFieldCell;
+@class NSURLConnection;
@class NSURLRequest;
+@class NSURLResponse;
+@class NSView;
@class QTMovie;
@class QTMovieView;
#else
diff --git a/WebCore/platform/mac/WebCoreSystemInterface.mm b/WebCore/platform/mac/WebCoreSystemInterface.mm
index b629b4e..edd9d50 100644
--- a/WebCore/platform/mac/WebCoreSystemInterface.mm
+++ b/WebCore/platform/mac/WebCoreSystemInterface.mm
@@ -25,6 +25,7 @@
#import "config.h"
#import "WebCoreSystemInterface.h"
+#import <Foundation/Foundation.h>
void (*wkAdvanceDefaultButtonPulseAnimation)(NSButtonCell *);
BOOL (*wkCGContextGetShouldSmoothFonts)(CGContextRef);
diff --git a/WebCore/platform/mac/WebCoreTextRenderer.h b/WebCore/platform/mac/WebCoreTextRenderer.h
index 3e77434..73753bc 100644
--- a/WebCore/platform/mac/WebCoreTextRenderer.h
+++ b/WebCore/platform/mac/WebCoreTextRenderer.h
@@ -23,6 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#import <AppKit/NSFontManager.h>
+#import <CoreFoundation/CFString.h>
+
+#ifdef __OBJC__
+@class NSColor;
+@class NSFont;
+@class NSString;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/WebCore/platform/mac/WebCoreTextRenderer.mm b/WebCore/platform/mac/WebCoreTextRenderer.mm
index 0cd5967..ab053ef 100644
--- a/WebCore/platform/mac/WebCoreTextRenderer.mm
+++ b/WebCore/platform/mac/WebCoreTextRenderer.mm
@@ -31,6 +31,7 @@
#import "GraphicsContext.h"
#import "IntPoint.h"
#import "WebFontCache.h"
+#import <AppKit/AppKit.h>
using namespace WebCore;
diff --git a/WebCore/platform/mac/WebFontCache.h b/WebCore/platform/mac/WebFontCache.h
index b31a684..8d3e4dd 100644
--- a/WebCore/platform/mac/WebFontCache.h
+++ b/WebCore/platform/mac/WebFontCache.h
@@ -24,7 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <wtf/Vector.h>
+#import <AppKit/NSFontManager.h>
+#import <wtf/Vector.h>
// This interface exists so that third party products (like Silk) can patch in to an Obj-C method to manipulate WebKit's font caching/substitution.
@interface WebFontCache : NSObject
diff --git a/WebCore/platform/mac/WebFontCache.mm b/WebCore/platform/mac/WebFontCache.mm
index 6cf1ef4..ac70f06 100644
--- a/WebCore/platform/mac/WebFontCache.mm
+++ b/WebCore/platform/mac/WebFontCache.mm
@@ -31,6 +31,8 @@
#import "WebFontCache.h"
#import "FontTraitsMask.h"
+#import <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
#import <math.h>
using namespace WebCore;
diff --git a/WebCore/platform/mac/WheelEventMac.mm b/WebCore/platform/mac/WheelEventMac.mm
index 7b60494..5821139 100644
--- a/WebCore/platform/mac/WheelEventMac.mm
+++ b/WebCore/platform/mac/WheelEventMac.mm
@@ -27,6 +27,7 @@
#import "PlatformWheelEvent.h"
#import "PlatformMouseEvent.h"
+#import "Scrollbar.h"
#import "WebCoreSystemInterface.h"
namespace WebCore {
@@ -34,6 +35,7 @@ namespace WebCore {
PlatformWheelEvent::PlatformWheelEvent(NSEvent* event)
: m_position(pointForEvent(event))
, m_globalPosition(globalPointForEvent(event))
+ , m_granularity(ScrollByPixelWheelEvent)
, m_isAccepted(false)
, m_shiftKey([event modifierFlags] & NSShiftKeyMask)
, m_ctrlKey([event modifierFlags] & NSControlKeyMask)
@@ -42,10 +44,14 @@ PlatformWheelEvent::PlatformWheelEvent(NSEvent* event)
{
BOOL continuous;
wkGetWheelEventDeltas(event, &m_deltaX, &m_deltaY, &continuous);
- m_granularity = continuous ? ScrollByPixelWheelEvent : ScrollByLineWheelEvent;
- if (m_granularity == ScrollByLineWheelEvent) {
- m_deltaX *= horizontalLineMultiplier();
- m_deltaY *= verticalLineMultiplier();
+ if (continuous) {
+ m_wheelTicksX = m_deltaX / static_cast<float>(cScrollbarPixelsPerLineStep);
+ m_wheelTicksY = m_deltaY / static_cast<float>(cScrollbarPixelsPerLineStep);
+ } else {
+ m_wheelTicksX = m_deltaX;
+ m_wheelTicksY = m_deltaY;
+ m_deltaX *= static_cast<float>(cScrollbarPixelsPerLineStep);
+ m_deltaY *= static_cast<float>(cScrollbarPixelsPerLineStep);
}
}
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 3cac168..af3b7f0 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -29,7 +29,8 @@
namespace WebCore {
inline FormData::FormData()
- : m_hasGeneratedFiles(false)
+ : m_identifier(0)
+ , m_hasGeneratedFiles(false)
, m_alwaysStream(false)
{
}
@@ -37,6 +38,7 @@ inline FormData::FormData()
inline FormData::FormData(const FormData& data)
: RefCounted<FormData>()
, m_elements(data.m_elements)
+ , m_identifier(data.m_identifier)
, m_hasGeneratedFiles(false)
, m_alwaysStream(false)
{
@@ -98,7 +100,7 @@ PassRefPtr<FormData> FormData::deepCopy() const
formData->m_alwaysStream = m_alwaysStream;
size_t n = m_elements.size();
- formData->m_elements.reserveCapacity(n);
+ formData->m_elements.reserveInitialCapacity(n);
for (size_t i = 0; i < n; ++i) {
const FormDataElement& e = m_elements[i];
switch (e.m_type) {
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index 5998b1b..7278f2e 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -86,11 +86,17 @@ public:
bool alwaysStream() const { return m_alwaysStream; }
void setAlwaysStream(bool alwaysStream) { m_alwaysStream = alwaysStream; }
+ // Identifies a particular form submission instance. A value of 0 is used
+ // to indicate an unspecified identifier.
+ void setIdentifier(int64_t identifier) { m_identifier = identifier; }
+ int64_t identifier() const { return m_identifier; }
+
private:
FormData();
FormData(const FormData&);
-
+
Vector<FormDataElement> m_elements;
+ int64_t m_identifier;
bool m_hasGeneratedFiles;
bool m_alwaysStream;
};
diff --git a/WebCore/platform/network/HTTPHeaderMap.cpp b/WebCore/platform/network/HTTPHeaderMap.cpp
index aa9c5fa..ff470a0 100644
--- a/WebCore/platform/network/HTTPHeaderMap.cpp
+++ b/WebCore/platform/network/HTTPHeaderMap.cpp
@@ -41,7 +41,7 @@ namespace WebCore {
auto_ptr<CrossThreadHTTPHeaderMapData> HTTPHeaderMap::copyData() const
{
auto_ptr<CrossThreadHTTPHeaderMapData> data(new CrossThreadHTTPHeaderMapData());
- data->reserveCapacity(size());
+ data->reserveInitialCapacity(size());
HTTPHeaderMap::const_iterator end_it = end();
for (HTTPHeaderMap::const_iterator it = begin(); it != end_it; ++it) {
diff --git a/WebCore/platform/network/HTTPParsers.cpp b/WebCore/platform/network/HTTPParsers.cpp
index 0858fc9..f36e9fb 100644
--- a/WebCore/platform/network/HTTPParsers.cpp
+++ b/WebCore/platform/network/HTTPParsers.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -131,18 +132,18 @@ String filenameFromHTTPContentDisposition(const String& value)
String extractMIMETypeFromMediaType(const String& mediaType)
{
- String mimeType;
+ Vector<UChar, 64> mimeType;
unsigned length = mediaType.length();
+ mimeType.reserveCapacity(length);
for (unsigned offset = 0; offset < length; offset++) {
UChar c = mediaType[offset];
if (c == ';')
break;
else if (isSpaceOrNewline(c)) // FIXME: This seems wrong, " " is an invalid MIME type character according to RFC 2045. bug 8644
continue;
- // FIXME: This is a very slow way to build a string, given WebCore::String's implementation.
- mimeType += String(&c, 1);
+ mimeType.append(c);
}
- return mimeType;
+ return String(mimeType.data(), mimeType.size());
}
String extractCharsetFromMediaType(const String& mediaType)
diff --git a/WebCore/platform/network/ResourceErrorBase.cpp b/WebCore/platform/network/ResourceErrorBase.cpp
index 1ea35b0..370650f 100644
--- a/WebCore/platform/network/ResourceErrorBase.cpp
+++ b/WebCore/platform/network/ResourceErrorBase.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +29,20 @@
namespace WebCore {
+ResourceError ResourceErrorBase::copy() const
+{
+ lazyInit();
+
+ ResourceError errorCopy;
+ errorCopy.m_domain = m_domain.copy();
+ errorCopy.m_errorCode = m_errorCode;
+ errorCopy.m_failingURL = m_failingURL.copy();
+ errorCopy.m_localizedDescription = m_localizedDescription.copy();
+ errorCopy.m_isNull = m_isNull;
+ errorCopy.m_isCancellation = m_isCancellation;
+ return errorCopy;
+}
+
void ResourceErrorBase::lazyInit() const
{
const_cast<ResourceError*>(static_cast<const ResourceError*>(this))->platformLazyInit();
@@ -59,4 +74,4 @@ bool ResourceErrorBase::compare(const ResourceError& a, const ResourceError& b)
return platformCompare(a, b);
}
-}
+} // namespace WebCore
diff --git a/WebCore/platform/network/ResourceErrorBase.h b/WebCore/platform/network/ResourceErrorBase.h
index 4631324..237db9e 100644
--- a/WebCore/platform/network/ResourceErrorBase.h
+++ b/WebCore/platform/network/ResourceErrorBase.h
@@ -34,6 +34,9 @@ class ResourceError;
class ResourceErrorBase {
public:
+ // Makes a deep copy. Useful for when you need to use a ResourceError on another thread.
+ ResourceError copy() const;
+
bool isNull() const { return m_isNull; }
const String& domain() const { lazyInit(); return m_domain; }
@@ -44,7 +47,7 @@ public:
void setIsCancellation(bool isCancellation) { m_isCancellation = isCancellation; }
bool isCancellation() const { return m_isCancellation; }
- static bool compare(const ResourceError& a, const ResourceError& b);
+ static bool compare(const ResourceError&, const ResourceError&);
protected:
ResourceErrorBase()
@@ -85,4 +88,4 @@ inline bool operator!=(const ResourceError& a, const ResourceError& b) { return
} // namespace WebCore
-#endif // ResourceErrorBase_h_
+#endif // ResourceErrorBase_h
diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h
index c981483..e3038ca 100644
--- a/WebCore/platform/network/ResourceHandle.h
+++ b/WebCore/platform/network/ResourceHandle.h
@@ -30,6 +30,10 @@
#include "HTTPHeaderMap.h"
#include <wtf/OwnPtr.h>
+#if USE(SOUP)
+typedef struct _SoupSession SoupSession;
+#endif
+
#if PLATFORM(CF)
typedef const struct __CFData * CFDataRef;
#endif
@@ -79,7 +83,7 @@ class KURL;
class ResourceError;
class ResourceHandleClient;
class ResourceHandleInternal;
-class ResourceRequest;
+struct ResourceRequest;
class ResourceResponse;
class SchedulePair;
class SharedBuffer;
@@ -159,6 +163,10 @@ public:
ResourceHandleInternal* getInternal() { return d.get(); }
#endif
+#if USE(SOUP)
+ static SoupSession* defaultSession();
+#endif
+
// Used to work around the fact that you don't get any more NSURLConnection callbacks until you return from the one you're in.
static bool loadsBlocked();
@@ -179,7 +187,7 @@ private:
#if USE(SOUP)
bool startData(String urlString);
bool startHttp(String urlString);
- bool startGio(String urlString);
+ bool startGio(KURL url);
#endif
void scheduleFailure(FailureType);
diff --git a/WebCore/platform/network/ResourceHandleClient.h b/WebCore/platform/network/ResourceHandleClient.h
index 3668d88..54c27d2 100644
--- a/WebCore/platform/network/ResourceHandleClient.h
+++ b/WebCore/platform/network/ResourceHandleClient.h
@@ -32,6 +32,7 @@
#if USE(CFNETWORK)
#include <ConditionalMacros.h>
+#include <CFNetwork/CFURLCachePriv.h>
#include <CFNetwork/CFURLResponsePriv.h>
#endif
@@ -49,7 +50,7 @@ namespace WebCore {
class KURL;
class ResourceHandle;
class ResourceError;
- class ResourceRequest;
+ struct ResourceRequest;
class ResourceResponse;
enum CacheStoragePolicy {
@@ -86,6 +87,9 @@ namespace WebCore {
virtual NSCachedURLResponse* willCacheResponse(ResourceHandle*, NSCachedURLResponse* response) { return response; }
virtual void willStopBufferingData(ResourceHandle*, const char*, int) { }
#endif
+#if USE(CFNETWORK)
+ virtual bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef response) { return true; }
+#endif
};
}
diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
index cc90cc8..c592a1a 100644
--- a/WebCore/platform/network/ResourceHandleInternal.h
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -47,6 +47,7 @@
#if USE(SOUP)
#include <libsoup/soup.h>
+class Frame;
#endif
#if PLATFORM(QT)
@@ -116,13 +117,15 @@ namespace WebCore {
#if USE(SOUP)
, m_msg(0)
, m_cancelled(false)
+ , m_reportedHeaders(false)
, m_gfile(0)
- , m_input_stream(0)
+ , m_inputStream(0)
, m_cancellable(0)
, m_buffer(0)
- , m_bufsize(0)
+ , m_bufferSize(0)
, m_total(0)
, m_idleHandler(0)
+ , m_frame(0)
#endif
#if PLATFORM(QT)
, m_job(0)
@@ -190,12 +193,14 @@ namespace WebCore {
SoupMessage* m_msg;
ResourceResponse m_response;
bool m_cancelled;
+ bool m_reportedHeaders;
GFile* m_gfile;
- GInputStream* m_input_stream;
+ GInputStream* m_inputStream;
GCancellable* m_cancellable;
char* m_buffer;
- gsize m_bufsize, m_total;
+ gsize m_bufferSize, m_total;
guint m_idleHandler;
+ Frame* m_frame;
#endif
#if PLATFORM(QT)
#if QT_VERSION < 0x040400
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
index 15469a0..fd27718 100644
--- a/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -76,7 +76,7 @@ auto_ptr<CrossThreadResourceRequestData> ResourceRequestBase::copyData() const
data->m_httpMethod = httpMethod().copy();
data->m_httpHeaders.adopt(httpHeaderFields().copyData());
- data->m_responseContentDispositionEncodingFallbackArray.reserveCapacity(m_responseContentDispositionEncodingFallbackArray.size());
+ data->m_responseContentDispositionEncodingFallbackArray.reserveInitialCapacity(m_responseContentDispositionEncodingFallbackArray.size());
size_t encodingArraySize = m_responseContentDispositionEncodingFallbackArray.size();
for (size_t index = 0; index < encodingArraySize; ++index) {
data->m_responseContentDispositionEncodingFallbackArray.append(m_responseContentDispositionEncodingFallbackArray[index].copy());
@@ -130,7 +130,8 @@ void ResourceRequestBase::setCachePolicy(ResourceRequestCachePolicy cachePolicy)
m_cachePolicy = cachePolicy;
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
double ResourceRequestBase::timeoutInterval() const
@@ -146,7 +147,8 @@ void ResourceRequestBase::setTimeoutInterval(double timeoutInterval)
m_timeoutInterval = timeoutInterval;
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
const KURL& ResourceRequestBase::mainDocumentURL() const
@@ -178,7 +180,8 @@ void ResourceRequestBase::setHTTPMethod(const String& httpMethod)
m_httpMethod = httpMethod;
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
const HTTPHeaderMap& ResourceRequestBase::httpHeaderFields() const
@@ -201,7 +204,8 @@ void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const Str
m_httpHeaderFields.set(name, value);
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
@@ -216,7 +220,8 @@ void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(con
if (!encoding3.isNull())
m_responseContentDispositionEncodingFallbackArray.append(encoding3);
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
FormData* ResourceRequestBase::httpBody() const
@@ -232,7 +237,8 @@ void ResourceRequestBase::setHTTPBody(PassRefPtr<FormData> httpBody)
m_httpBody = httpBody;
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
bool ResourceRequestBase::allowHTTPCookies() const
@@ -248,7 +254,8 @@ void ResourceRequestBase::setAllowHTTPCookies(bool allowHTTPCookies)
m_allowHTTPCookies = allowHTTPCookies;
- m_platformRequestUpdated = false;
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
}
void ResourceRequestBase::addHTTPHeaderField(const AtomicString& name, const String& value)
diff --git a/WebCore/platform/network/ResourceRequestBase.h b/WebCore/platform/network/ResourceRequestBase.h
index 0f6bb47..4fd57e1 100644
--- a/WebCore/platform/network/ResourceRequestBase.h
+++ b/WebCore/platform/network/ResourceRequestBase.h
@@ -46,7 +46,7 @@ namespace WebCore {
const int unspecifiedTimeoutInterval = INT_MAX;
- class ResourceRequest;
+ struct ResourceRequest;
struct CrossThreadResourceRequestData;
// Do not use this type directly. Use ResourceRequest instead.
@@ -107,12 +107,18 @@ namespace WebCore {
void setAllowHTTPCookies(bool allowHTTPCookies);
bool isConditional() const;
-
+
+ // Whether the associated ResourceHandleClient needs to be notified of
+ // upload progress made for that resource.
+ bool reportUploadProgress() const { return m_reportUploadProgress; }
+ void setReportUploadProgress(bool reportUploadProgress) { m_reportUploadProgress = reportUploadProgress; }
+
protected:
// Used when ResourceRequest is initialized from a platform representation of the request
ResourceRequestBase()
: m_resourceRequestUpdated(false)
, m_platformRequestUpdated(true)
+ , m_reportUploadProgress(false)
{
}
@@ -124,6 +130,7 @@ namespace WebCore {
, m_allowHTTPCookies(true)
, m_resourceRequestUpdated(true)
, m_platformRequestUpdated(false)
+ , m_reportUploadProgress(false)
{
}
@@ -142,6 +149,7 @@ namespace WebCore {
bool m_allowHTTPCookies;
mutable bool m_resourceRequestUpdated;
mutable bool m_platformRequestUpdated;
+ bool m_reportUploadProgress;
private:
const ResourceRequest& asResourceRequest() const;
diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp
index 92ece8c..60c0097 100644
--- a/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/WebCore/platform/network/ResourceResponseBase.cpp
@@ -39,7 +39,7 @@ static void parseCacheControlDirectiveValues(const String& directives, Vector<St
auto_ptr<ResourceResponse> ResourceResponseBase::adopt(auto_ptr<CrossThreadResourceResponseData> data)
{
auto_ptr<ResourceResponse> response(new ResourceResponse());
- response->setUrl(data->m_url);
+ response->setURL(data->m_url);
response->setMimeType(data->m_mimeType);
response->setExpectedContentLength(data->m_expectedContentLength);
response->setTextEncodingName(data->m_textEncodingName);
@@ -94,7 +94,7 @@ const KURL& ResourceResponseBase::url() const
return m_url;
}
-void ResourceResponseBase::setUrl(const KURL& url)
+void ResourceResponseBase::setURL(const KURL& url)
{
lazyInit();
m_isNull = false;
diff --git a/WebCore/platform/network/ResourceResponseBase.h b/WebCore/platform/network/ResourceResponseBase.h
index c06f75b..ff34a26 100644
--- a/WebCore/platform/network/ResourceResponseBase.h
+++ b/WebCore/platform/network/ResourceResponseBase.h
@@ -49,7 +49,7 @@ public:
bool isHTTP() const;
const KURL& url() const;
- void setUrl(const KURL& url);
+ void setURL(const KURL& url);
const String& mimeType() const;
void setMimeType(const String& mimeType);
@@ -97,6 +97,13 @@ public:
return m_cacheControlContainsMustRevalidate;
}
+ // The ResourceResponse subclass may "shadow" this method to provide platform-specific memory usage information
+ unsigned memoryUsage() const
+ {
+ // average size, mostly due to URL and Header Map strings
+ return 1280;
+ }
+
static bool compare(const ResourceResponse& a, const ResourceResponse& b);
protected:
diff --git a/WebCore/platform/network/cf/FormDataStreamCFNet.cpp b/WebCore/platform/network/cf/FormDataStreamCFNet.cpp
index 71fbfe7..3414d90 100644
--- a/WebCore/platform/network/cf/FormDataStreamCFNet.cpp
+++ b/WebCore/platform/network/cf/FormDataStreamCFNet.cpp
@@ -317,8 +317,7 @@ static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, vo
void setHTTPBody(CFMutableURLRequestRef request, PassRefPtr<FormData> formData)
{
if (!formData) {
- if (wkCanAccessCFURLRequestHTTPBodyParts())
- wkCFURLRequestSetHTTPRequestBodyParts(request, 0);
+ wkCFURLRequestSetHTTPRequestBodyParts(request, 0);
return;
}
@@ -338,52 +337,20 @@ void setHTTPBody(CFMutableURLRequestRef request, PassRefPtr<FormData> formData)
}
}
- if (wkCanAccessCFURLRequestHTTPBodyParts()) {
- RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
-
- for (size_t i = 0; i < count; ++i) {
- const FormDataElement& element = formData->elements()[i];
- if (element.m_type == FormDataElement::data) {
- RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(0, reinterpret_cast<const UInt8*>(element.m_data.data()), element.m_data.size()));
- CFArrayAppendValue(array.get(), data.get());
- } else {
- RetainPtr<CFStringRef> filename(AdoptCF, element.m_filename.createCFString());
- CFArrayAppendValue(array.get(), filename.get());
- }
- }
+ RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
- wkCFURLRequestSetHTTPRequestBodyParts(request, array.get());
- return;
- }
-
- // Precompute the content length so CFURLConnection doesn't use chunked mode.
- bool haveLength = true;
- long long length = 0;
for (size_t i = 0; i < count; ++i) {
const FormDataElement& element = formData->elements()[i];
- if (element.m_type == FormDataElement::data)
- length += element.m_data.size();
- else {
- long long size;
- if (getFileSize(element.m_filename, size))
- length += size;
- else
- haveLength = false;
+ if (element.m_type == FormDataElement::data) {
+ RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(0, reinterpret_cast<const UInt8*>(element.m_data.data()), element.m_data.size()));
+ CFArrayAppendValue(array.get(), data.get());
+ } else {
+ RetainPtr<CFStringRef> filename(AdoptCF, element.m_filename.createCFString());
+ CFArrayAppendValue(array.get(), filename.get());
}
}
- if (haveLength) {
- CFStringRef lengthStr = CFStringCreateWithFormat(0, 0, CFSTR("%lld"), length);
- CFURLRequestSetHTTPHeaderFieldValue(request, CFSTR("Content-Length"), lengthStr);
- CFRelease(lengthStr);
- }
-
- static WCReadStreamCallBacks formDataStreamCallbacks =
- { 1, formCreate, formFinalize, 0, formOpen, 0, formRead, 0, formCanRead, formClose, 0, 0, 0, formSchedule, formUnschedule };
-
- CFReadStreamRef stream = CFReadStreamCreate(0, (CFReadStreamCallBacks *)&formDataStreamCallbacks, formData.releaseRef());
- CFURLRequestSetHTTPRequestBodyStream(request, stream);
- CFRelease(stream);
+ wkCFURLRequestSetHTTPRequestBodyParts(request, array.get());
}
PassRefPtr<FormData> httpBodyFromRequest(CFURLRequestRef request)
@@ -391,28 +358,23 @@ PassRefPtr<FormData> httpBodyFromRequest(CFURLRequestRef request)
if (RetainPtr<CFDataRef> bodyData = CFURLRequestCopyHTTPRequestBody(request))
return FormData::create(CFDataGetBytePtr(bodyData.get()), CFDataGetLength(bodyData.get()));
- if (wkCanAccessCFURLRequestHTTPBodyParts()) {
- if (RetainPtr<CFArrayRef> bodyParts = wkCFURLRequestCopyHTTPRequestBodyParts(request)) {
- RefPtr<FormData> formData = FormData::create();
-
- CFIndex count = CFArrayGetCount(bodyParts.get());
- for (CFIndex i = 0; i < count; i++) {
- CFTypeRef bodyPart = CFArrayGetValueAtIndex(bodyParts.get(), i);
- CFTypeID typeID = CFGetTypeID(bodyPart);
- if (typeID == CFStringGetTypeID()) {
- String filename = (CFStringRef)bodyPart;
- formData->appendFile(filename);
- } else if (typeID == CFDataGetTypeID()) {
- CFDataRef data = (CFDataRef)bodyPart;
- formData->appendData(CFDataGetBytePtr(data), CFDataGetLength(data));
- } else
- ASSERT_NOT_REACHED();
- }
- return formData.release();
+ if (RetainPtr<CFArrayRef> bodyParts = wkCFURLRequestCopyHTTPRequestBodyParts(request)) {
+ RefPtr<FormData> formData = FormData::create();
+
+ CFIndex count = CFArrayGetCount(bodyParts.get());
+ for (CFIndex i = 0; i < count; i++) {
+ CFTypeRef bodyPart = CFArrayGetValueAtIndex(bodyParts.get(), i);
+ CFTypeID typeID = CFGetTypeID(bodyPart);
+ if (typeID == CFStringGetTypeID()) {
+ String filename = (CFStringRef)bodyPart;
+ formData->appendFile(filename);
+ } else if (typeID == CFDataGetTypeID()) {
+ CFDataRef data = (CFDataRef)bodyPart;
+ formData->appendData(CFDataGetBytePtr(data), CFDataGetLength(data));
+ } else
+ ASSERT_NOT_REACHED();
}
- } else {
- if (RetainPtr<CFReadStreamRef> bodyStream = CFURLRequestCopyHTTPRequestBodyStream(request))
- return getStreamFormDatas().get(bodyStream.get());
+ return formData.release();
}
// FIXME: what to do about arbitrary body streams?
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index a4000a3..2dcbbed 100644
--- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,51 +53,6 @@
namespace WebCore {
-static HMODULE findCFNetworkModule()
-{
- if (HMODULE module = GetModuleHandleA("CFNetwork"))
- return module;
- return GetModuleHandleA("CFNetwork_debug");
-}
-
-static DWORD cfNetworkVersion()
-{
- HMODULE cfNetworkModule = findCFNetworkModule();
- WCHAR filename[MAX_PATH];
- GetModuleFileName(cfNetworkModule, filename, MAX_PATH);
- DWORD handle;
- DWORD versionInfoSize = GetFileVersionInfoSize(filename, &handle);
- Vector<BYTE> versionInfo(versionInfoSize);
- GetFileVersionInfo(filename, handle, versionInfoSize, versionInfo.data());
- VS_FIXEDFILEINFO* fixedFileInfo;
- UINT fixedFileInfoLength;
- VerQueryValue(versionInfo.data(), TEXT("\\"), reinterpret_cast<LPVOID*>(&fixedFileInfo), &fixedFileInfoLength);
- return fixedFileInfo->dwProductVersionMS;
-}
-
-static CFIndex highestSupportedCFURLConnectionClientVersion()
-{
- const DWORD firstCFNetworkVersionWithConnectionClientV2 = 0x000101a8; // 1.424
- const DWORD firstCFNetworkVersionWithConnectionClientV3 = 0x000101ad; // 1.429
-
-#ifndef _CFURLConnectionClientV2Present
- return 1;
-#else
-
- DWORD version = cfNetworkVersion();
- if (version < firstCFNetworkVersionWithConnectionClientV2)
- return 1;
-#ifndef _CFURLConnectionClientV3Present
- return 2;
-#else
-
- if (version < firstCFNetworkVersionWithConnectionClientV3)
- return 2;
- return 3;
-#endif // _CFURLConnectionClientV3Present
-#endif // _CFURLConnectionClientV2Present
-}
-
static HashSet<String>& allowsAnyHTTPSCertificateHosts()
{
static HashSet<String> hosts;
@@ -154,7 +109,6 @@ void didReceiveData(CFURLConnectionRef conn, CFDataRef data, CFIndex originalLen
handle->client()->didReceiveData(handle, (const char*)bytes, length, originalLength);
}
-#ifdef _CFURLConnectionClientV2Present
static void didSendBodyData(CFURLConnectionRef conn, CFIndex bytesWritten, CFIndex totalBytesWritten, CFIndex totalBytesExpectedToWrite, const void *clientInfo)
{
ResourceHandle* handle = (ResourceHandle*)clientInfo;
@@ -162,9 +116,7 @@ static void didSendBodyData(CFURLConnectionRef conn, CFIndex bytesWritten, CFInd
return;
handle->client()->didSendData(handle, totalBytesWritten, totalBytesExpectedToWrite);
}
-#endif
-#ifdef _CFURLConnectionClientV3Present
static Boolean shouldUseCredentialStorageCallback(CFURLConnectionRef conn, const void* clientInfo)
{
ResourceHandle* handle = const_cast<ResourceHandle*>(static_cast<const ResourceHandle*>(clientInfo));
@@ -176,7 +128,6 @@ static Boolean shouldUseCredentialStorageCallback(CFURLConnectionRef conn, const
return handle->shouldUseCredentialStorage();
}
-#endif
void didFinishLoading(CFURLConnectionRef conn, const void* clientInfo)
{
@@ -202,6 +153,9 @@ CFCachedURLResponseRef willCacheResponse(CFURLConnectionRef conn, CFCachedURLRes
{
ResourceHandle* handle = (ResourceHandle*)clientInfo;
+ if (handle->client() && !handle->client()->shouldCacheResponse(handle, cachedResponse))
+ return 0;
+
CacheStoragePolicy policy = static_cast<CacheStoragePolicy>(CFCachedURLResponseGetStoragePolicy(cachedResponse));
if (handle->client())
@@ -297,7 +251,7 @@ void* runLoaderThread(void *unused)
CFRunLoopRef ResourceHandle::loaderRunLoop()
{
if (!loaderRL) {
- createThread(runLoaderThread, 0, "CFNetwork::Loader");
+ createThread(runLoaderThread, 0, "WebCore: CFNetwork Loader");
while (loaderRL == 0) {
// FIXME: sleep 10? that can't be right...
Sleep(10);
@@ -348,20 +302,9 @@ bool ResourceHandle::start(Frame* frame)
RetainPtr<CFURLRequestRef> request(AdoptCF, makeFinalRequest(d->m_request, d->m_shouldContentSniff));
- static CFIndex clientVersion = highestSupportedCFURLConnectionClientVersion();
- CFURLConnectionClient* client;
-#if defined(_CFURLConnectionClientV3Present)
- CFURLConnectionClient_V3 client_V3 = {clientVersion, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
- client = reinterpret_cast<CFURLConnectionClient*>(&client_V3);
-#elif defined(_CFURLConnectionClientV2Present)
- CFURLConnectionClient_V2 client_V2 = {clientVersion, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData};
- client = reinterpret_cast<CFURLConnectionClient*>(&client_V2);
-#else
- CFURLConnectionClient client_V1 = {1, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge};
- client = &client_V1;
-#endif
-
- d->m_connection.adoptCF(CFURLConnectionCreate(0, request.get(), client));
+ CFURLConnectionClient_V3 client = { 3, this, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
+
+ d->m_connection.adoptCF(CFURLConnectionCreate(0, request.get(), reinterpret_cast<CFURLConnectionClient*>(&client)));
CFURLConnectionScheduleWithCurrentMessageQueue(d->m_connection.get());
CFURLConnectionScheduleDownloadWithRunLoop(d->m_connection.get(), loaderRunLoop(), kCFRunLoopDefaultMode);
@@ -519,12 +462,22 @@ bool ResourceHandle::loadsBlocked()
return false;
}
-bool ResourceHandle::willLoadFromCache(ResourceRequest&)
+bool ResourceHandle::willLoadFromCache(ResourceRequest& request)
{
- // Not having this function means that we'll ask the user about re-posting a form
- // even when we go back to a page that's still in the cache.
- notImplemented();
- return false;
+ request.setCachePolicy(ReturnCacheDataDontLoad);
+
+ CFURLResponseRef cfResponse = 0;
+ CFErrorRef cfError = 0;
+ RetainPtr<CFURLRequestRef> cfRequest(AdoptCF, makeFinalRequest(request, true));
+ RetainPtr<CFDataRef> data(AdoptCF, CFURLConnectionSendSynchronousRequest(cfRequest.get(), &cfResponse, &cfError, request.timeoutInterval()));
+ bool cached = cfResponse && !cfError;
+
+ if (cfError)
+ CFRelease(cfError);
+ if (cfResponse)
+ CFRelease(cfResponse);
+
+ return cached;
}
} // namespace WebCore
diff --git a/WebCore/platform/network/cf/ResourceRequestCFNet.h b/WebCore/platform/network/cf/ResourceRequestCFNet.h
index e9ebe76..d26072d 100644
--- a/WebCore/platform/network/cf/ResourceRequestCFNet.h
+++ b/WebCore/platform/network/cf/ResourceRequestCFNet.h
@@ -30,7 +30,7 @@ typedef const struct _CFURLRequest* CFURLRequestRef;
namespace WebCore {
- class ResourceRequest;
+ struct ResourceRequest;
void getResourceRequest(ResourceRequest&, CFURLRequestRef);
CFURLRequestRef cfURLRequest(const ResourceRequest&);
diff --git a/WebCore/platform/network/cf/ResourceResponse.h b/WebCore/platform/network/cf/ResourceResponse.h
index e14c79e..04cc82c 100644
--- a/WebCore/platform/network/cf/ResourceResponse.h
+++ b/WebCore/platform/network/cf/ResourceResponse.h
@@ -52,6 +52,18 @@ public:
{
}
+ unsigned memoryUsage() const
+ {
+ // FIXME: Find some programmatic lighweight way to calculate ResourceResponse and associated classes.
+ // This is a rough estimate of resource overhead based on stats collected from the stress test.
+ return 3072;
+ /* 1280 * 2 + // average size of ResourceResponse. Doubled to account for the WebCore copy and the CF copy.
+ // Mostly due to the size of the hash maps, the Header Map strings and the URL.
+ 256 * 2 // Overhead from ResourceRequest, doubled to account for WebCore copy and CF copy.
+ // Mostly due to the URL and Header Map.
+ */
+ }
+
CFURLResponseRef cfURLResponse() const;
private:
diff --git a/WebCore/platform/network/chromium/ResourceRequest.h b/WebCore/platform/network/chromium/ResourceRequest.h
index 76b8b99..b14dba6 100644
--- a/WebCore/platform/network/chromium/ResourceRequest.h
+++ b/WebCore/platform/network/chromium/ResourceRequest.h
@@ -35,7 +35,7 @@ namespace WebCore {
class Frame;
- class ResourceRequest : public ResourceRequestBase {
+ struct ResourceRequest : public ResourceRequestBase {
public:
enum TargetType {
TargetIsMainFrame,
@@ -47,16 +47,16 @@ namespace WebCore {
ResourceRequest(const String& url)
: ResourceRequestBase(KURL(url), UseProtocolCachePolicy)
- , m_frame(0)
- , m_originPid(0)
+ , m_requestorID(0)
+ , m_requestorProcessID(0)
, m_targetType(TargetIsSubResource)
{
}
ResourceRequest(const KURL& url, const CString& securityInfo)
: ResourceRequestBase(url, UseProtocolCachePolicy)
- , m_frame(0)
- , m_originPid(0)
+ , m_requestorID(0)
+ , m_requestorProcessID(0)
, m_targetType(TargetIsSubResource)
, m_securityInfo(securityInfo)
{
@@ -64,16 +64,16 @@ namespace WebCore {
ResourceRequest(const KURL& url)
: ResourceRequestBase(url, UseProtocolCachePolicy)
- , m_frame(0)
- , m_originPid(0)
+ , m_requestorID(0)
+ , m_requestorProcessID(0)
, m_targetType(TargetIsSubResource)
{
}
ResourceRequest(const KURL& url, const String& referrer, ResourceRequestCachePolicy policy = UseProtocolCachePolicy)
: ResourceRequestBase(url, policy)
- , m_frame(0)
- , m_originPid(0)
+ , m_requestorID(0)
+ , m_requestorProcessID(0)
, m_targetType(TargetIsSubResource)
{
setHTTPReferrer(referrer);
@@ -81,26 +81,30 @@ namespace WebCore {
ResourceRequest()
: ResourceRequestBase(KURL(), UseProtocolCachePolicy)
- , m_frame(0)
- , m_originPid(0)
+ , m_requestorID(0)
+ , m_requestorProcessID(0)
, m_targetType(TargetIsSubResource)
{
}
- // Provides context for the resource request.
- Frame* frame() const { return m_frame; }
- void setFrame(Frame* frame) { m_frame = frame; }
+ // Allows the request to be matched up with its requestor.
+ int requestorID() const { return m_requestorID; }
+ void setRequestorID(int requestorID) { m_requestorID = requestorID; }
// What this request is for.
- void setTargetType(TargetType type) { m_targetType = type; }
TargetType targetType() const { return m_targetType; }
-
- // The origin pid is the process id of the process from which this
- // request originated. In the case of out-of-process plugins, this
- // allows to link back the request to the plugin process (as it is
- // processed through a render view process).
- int originPid() const { return m_originPid; }
- void setOriginPid(int originPid) { m_originPid = originPid; }
+ void setTargetType(TargetType type) { m_targetType = type; }
+
+ // The document's policy base url.
+ KURL policyURL() const { return m_policyURL; }
+ void setPolicyURL(const KURL& policyURL) { m_policyURL = policyURL; }
+
+ // The process id of the process from which this request originated. In
+ // the case of out-of-process plugins, this allows to link back the
+ // request to the plugin process (as it is processed through a render
+ // view process).
+ int requestorProcessID() const { return m_requestorProcessID; }
+ void setRequestorProcessID(int requestorProcessID) { m_requestorProcessID = requestorProcessID; }
// Opaque buffer that describes the security state (including SSL
// connection state) for the resource that should be reported when the
@@ -117,10 +121,11 @@ namespace WebCore {
void doUpdatePlatformRequest() {}
void doUpdateResourceRequest() {}
- Frame* m_frame;
- int m_originPid;
+ int m_requestorID;
+ int m_requestorProcessID;
TargetType m_targetType;
CString m_securityInfo;
+ KURL m_policyURL;
};
} // namespace WebCore
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
index 6a44233..6f009db 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -126,7 +126,7 @@ static size_t writeCallback(void* ptr, size_t size, size_t nmemb, void* data)
if (!d->m_response.responseFired()) {
const char* hdr;
err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
- d->m_response.setUrl(KURL(hdr));
+ d->m_response.setURL(KURL(hdr));
if (d->client())
d->client()->didReceiveResponse(job, d->m_response);
d->m_response.setResponseFired(true);
@@ -180,7 +180,7 @@ static size_t headerCallback(char* ptr, size_t size, size_t nmemb, void* data)
const char* hdr;
err = curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &hdr);
- d->m_response.setUrl(KURL(hdr));
+ d->m_response.setURL(KURL(hdr));
long httpCode = 0;
err = curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &httpCode);
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
index b618949..94fdb25 100644
--- a/WebCore/platform/network/mac/FormDataStreamMac.mm
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -204,7 +204,7 @@ static void* formCreate(CFReadStreamRef stream, void* context)
// Append in reverse order since we remove elements from the end.
size_t size = formData->elements().size();
- newInfo->remainingElements.reserveCapacity(size);
+ newInfo->remainingElements.reserveInitialCapacity(size);
for (size_t i = 0; i < size; ++i)
newInfo->remainingElements.append(formData->elements()[size - i - 1]);
diff --git a/WebCore/platform/network/mac/ResourceErrorMac.mm b/WebCore/platform/network/mac/ResourceErrorMac.mm
index e59eadd..94c2124 100644
--- a/WebCore/platform/network/mac/ResourceErrorMac.mm
+++ b/WebCore/platform/network/mac/ResourceErrorMac.mm
@@ -26,6 +26,7 @@
#import "config.h"
#import "ResourceError.h"
+#import "BlockExceptions.h"
#import "KURL.h"
#import <Foundation/Foundation.h>
@@ -46,8 +47,12 @@ void ResourceError::platformLazyInit()
NSString* failingURLString = [[m_platformError.get() userInfo] valueForKey:@"NSErrorFailingURLStringKey"];
if (!failingURLString)
failingURLString = [[[m_platformError.get() userInfo] valueForKey:@"NSErrorFailingURLKey"] absoluteString];
-
+
+ // Workaround for <rdar://problem/6554067>
+ m_localizedDescription = failingURLString;
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
m_localizedDescription = [m_platformError.get() _web_localizedDescription];
+ END_BLOCK_OBJC_EXCEPTIONS;
m_dataIsUpToDate = true;
}
diff --git a/WebCore/platform/network/mac/ResourceRequestMac.mm b/WebCore/platform/network/mac/ResourceRequestMac.mm
index a9bbd40..92c37ee 100644
--- a/WebCore/platform/network/mac/ResourceRequestMac.mm
+++ b/WebCore/platform/network/mac/ResourceRequestMac.mm
@@ -119,8 +119,8 @@ void ResourceRequest::doUpdatePlatformRequest()
for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != end; ++it)
[nsRequest setValue:it->second forHTTPHeaderField:it->first];
- // The below check can be removed once we require a version of Foundation with -[NSMutableURLRequest setContentDispositionEncodingFallbackArray] method.
- static bool supportsContentDispositionEncodingFallbackArray = [NSMutableURLRequest instancesRespondToSelector:@selector(setContentDispositionEncodingFallbackArray)];
+ // The below check can be removed once we require a version of Foundation with -[NSMutableURLRequest setContentDispositionEncodingFallbackArray:] method.
+ static bool supportsContentDispositionEncodingFallbackArray = [NSMutableURLRequest instancesRespondToSelector:@selector(setContentDispositionEncodingFallbackArray:)];
if (supportsContentDispositionEncodingFallbackArray) {
NSMutableArray *encodingFallbacks = [NSMutableArray array];
unsigned count = m_responseContentDispositionEncodingFallbackArray.size();
diff --git a/WebCore/platform/network/mac/ResourceResponse.h b/WebCore/platform/network/mac/ResourceResponse.h
index b65760c..16b0cbf 100644
--- a/WebCore/platform/network/mac/ResourceResponse.h
+++ b/WebCore/platform/network/mac/ResourceResponse.h
@@ -57,6 +57,18 @@ public:
{
}
+ unsigned memoryUsage() const
+ {
+ // FIXME: Find some programmatic lighweight way to calculate ResourceResponse and associated classes.
+ // This is a rough estimate of resource overhead based on stats collected from the stress test.
+ return 3072;
+ /* 1280 * 2 + // average size of ResourceResponse. Doubled to account for the WebCore copy and the CF copy.
+ // Mostly due to the size of the hash maps, the Header Map strings and the URL.
+ 256 * 2 // Overhead from ResourceRequest, doubled to account for WebCore copy and CF copy.
+ // Mostly due to the URL and Header Map.
+ */
+ }
+
NSURLResponse *nsURLResponse() const;
private:
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 2de2125..2c730a6 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -269,8 +269,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
const bool isLocalFileReply = (m_reply->url().scheme() == QLatin1String("file"));
int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (!isLocalFileReply)
+ if (!isLocalFileReply) {
response.setHTTPStatusCode(statusCode);
+ response.setHTTPStatusText(m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray().constData());
+ }
else if (m_reply->error() == QNetworkReply::ContentNotFoundError)
response.setHTTPStatusCode(404);
diff --git a/WebCore/platform/network/soup/CookieJarSoup.cpp b/WebCore/platform/network/soup/CookieJarSoup.cpp
index 88109e8..e3064e1 100644
--- a/WebCore/platform/network/soup/CookieJarSoup.cpp
+++ b/WebCore/platform/network/soup/CookieJarSoup.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Xan Lopez <xan@gnome.org>
+ * Copyright (C) 2009 Igalia S.L.
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -25,15 +26,35 @@
namespace WebCore {
-SoupCookieJar* getCookieJar()
+static bool cookiesInitialized;
+static SoupCookieJar* cookieJar;
+
+SoupCookieJar* defaultCookieJar()
+{
+ if (!cookiesInitialized) {
+ cookiesInitialized = true;
+ setDefaultCookieJar(soup_cookie_jar_new());
+ }
+
+ return cookieJar;
+}
+
+void setDefaultCookieJar(SoupCookieJar* jar)
{
- static SoupCookieJar* jar = soup_cookie_jar_new();
- return jar;
+ cookiesInitialized = true;
+
+ if (cookieJar)
+ g_object_unref(cookieJar);
+
+ cookieJar = jar;
+
+ if (cookieJar)
+ g_object_ref(cookieJar);
}
void setCookies(Document* /*document*/, const KURL& url, const KURL& /*policyURL*/, const String& value)
{
- SoupCookieJar* jar = getCookieJar();
+ SoupCookieJar* jar = defaultCookieJar();
if (!jar)
return;
@@ -45,7 +66,7 @@ void setCookies(Document* /*document*/, const KURL& url, const KURL& /*policyURL
String cookies(const Document* /*document*/, const KURL& url)
{
- SoupCookieJar* jar = getCookieJar();
+ SoupCookieJar* jar = defaultCookieJar();
if (!jar)
return String();
@@ -61,7 +82,7 @@ String cookies(const Document* /*document*/, const KURL& url)
bool cookiesEnabled(const Document* /*document*/)
{
- return getCookieJar();
+ return defaultCookieJar();
}
}
diff --git a/WebCore/platform/network/soup/CookieJarSoup.h b/WebCore/platform/network/soup/CookieJarSoup.h
index 61179ae..ab1f95c 100644
--- a/WebCore/platform/network/soup/CookieJarSoup.h
+++ b/WebCore/platform/network/soup/CookieJarSoup.h
@@ -31,7 +31,8 @@
#include <libsoup/soup.h>
namespace WebCore {
- SoupCookieJar* getCookieJar();
+ SoupCookieJar* defaultCookieJar();
+ void setDefaultCookieJar(SoupCookieJar* jar);
}
#endif
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index da96873..1b91e32 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -3,6 +3,9 @@
* Copyright (C) 2008 Xan Lopez <xan@gnome.org>
* Copyright (C) 2008 Collabora Ltd.
* Copyright (C) 2009 Holger Hans Peter Freyther
+ * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org>
+ * Copyright (C) 2009 Christian Dywan <christian@imendio.com>
+ * Copyright (C) 2009 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,41 +24,109 @@
*/
#include "config.h"
-#include "CString.h"
#include "ResourceHandle.h"
#include "Base64.h"
#include "CookieJarSoup.h"
+#include "ChromeClient.h"
+#include "CString.h"
#include "DocLoader.h"
+#include "FileSystem.h"
#include "Frame.h"
#include "HTTPParsers.h"
+#include "Logging.h"
#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
+#include "Page.h"
#include "ResourceError.h"
#include "ResourceHandleClient.h"
#include "ResourceHandleInternal.h"
#include "ResourceResponse.h"
#include "TextEncoding.h"
+#include <errno.h>
+#include <fcntl.h>
#include <gio/gio.h>
+#include <gtk/gtk.h>
#include <libsoup/soup.h>
-#include <libsoup/soup-message.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#if PLATFORM(GTK)
- #if GLIB_CHECK_VERSION(2,12,0)
- #define USE_GLIB_BASE64
- #endif
+#define USE_GLIB_BASE64
#endif
namespace WebCore {
-static SoupSession* session = 0;
+class WebCoreSynchronousLoader : public ResourceHandleClient, Noncopyable {
+public:
+ WebCoreSynchronousLoader(ResourceError&, ResourceResponse &, Vector<char>&);
+ ~WebCoreSynchronousLoader();
+
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int lengthReceived);
+ virtual void didFinishLoading(ResourceHandle*);
+ virtual void didFail(ResourceHandle*, const ResourceError&);
+
+ void run();
+
+private:
+ ResourceError& m_error;
+ ResourceResponse& m_response;
+ Vector<char>& m_data;
+ bool m_finished;
+ GMainLoop* m_mainLoop;
+};
+
+WebCoreSynchronousLoader::WebCoreSynchronousLoader(ResourceError& error, ResourceResponse& response, Vector<char>& data)
+ : m_error(error)
+ , m_response(response)
+ , m_data(data)
+ , m_finished(false)
+{
+ m_mainLoop = g_main_loop_new(0, false);
+}
+
+WebCoreSynchronousLoader::~WebCoreSynchronousLoader()
+{
+ g_main_loop_unref(m_mainLoop);
+}
+
+void WebCoreSynchronousLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
+{
+ m_response = response;
+}
+
+void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, int length, int)
+{
+ m_data.append(data, length);
+}
+
+void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*)
+{
+ g_main_loop_quit(m_mainLoop);
+ m_finished = true;
+}
+
+void WebCoreSynchronousLoader::didFail(ResourceHandle* handle, const ResourceError& error)
+{
+ m_error = error;
+ didFinishLoading(handle);
+}
+
+void WebCoreSynchronousLoader::run()
+{
+ if (!m_finished)
+ g_main_loop_run(m_mainLoop);
+}
enum
{
ERROR_TRANSPORT,
ERROR_UNKNOWN_PROTOCOL,
- ERROR_BAD_NON_HTTP_METHOD
+ ERROR_BAD_NON_HTTP_METHOD,
+ ERROR_UNABLE_TO_OPEN_FILE,
};
static void cleanupGioOperation(ResourceHandleInternal* handle);
@@ -82,20 +153,47 @@ ResourceHandle::~ResourceHandle()
static void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response)
{
SoupMessageHeadersIter iter;
- const char* name = NULL;
- const char* value = NULL;
+ const char* name = 0;
+ const char* value = 0;
soup_message_headers_iter_init(&iter, msg->response_headers);
while (soup_message_headers_iter_next(&iter, &name, &value))
response->setHTTPHeaderField(name, value);
- String contentType = soup_message_headers_get(msg->response_headers, "Content-Type");
- char* uri = soup_uri_to_string(soup_message_get_uri(msg), FALSE);
- response->setUrl(KURL(uri));
- g_free(uri);
+ GHashTable* contentTypeParameters = 0;
+ String contentType = soup_message_headers_get_content_type(msg->response_headers, &contentTypeParameters);
+
+ // When the server sends multiple Content-Type headers, soup will
+ // give us their values concatenated with commas as a separator;
+ // we need to handle this and use only one value. We use the first
+ // value, and add all the parameters, afterwards, if any.
+ Vector<String> contentTypes;
+ contentType.split(',', true, contentTypes);
+ contentType = contentTypes[0];
+
+ if (contentTypeParameters) {
+ GHashTableIter hashTableIter;
+ gpointer hashKey;
+ gpointer hashValue;
+
+ g_hash_table_iter_init(&hashTableIter, contentTypeParameters);
+ while (g_hash_table_iter_next(&hashTableIter, &hashKey, &hashValue)) {
+ contentType += String("; ");
+ contentType += String(static_cast<char*>(hashKey));
+ contentType += String("=");
+ contentType += String(static_cast<char*>(hashValue));
+ }
+ g_hash_table_destroy(contentTypeParameters);
+ }
+
response->setMimeType(extractMIMETypeFromMediaType(contentType));
+
+ char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
+ response->setURL(KURL(KURL(), uri));
+ g_free(uri);
response->setTextEncodingName(extractCharsetFromMediaType(contentType));
response->setExpectedContentLength(soup_message_headers_get_content_length(msg->response_headers));
response->setHTTPStatusCode(msg->status_code);
+ response->setHTTPStatusText(msg->reason_phrase);
response->setSuggestedFilename(filenameFromHTTPContentDisposition(response->httpHeaderField("Content-Disposition")));
}
@@ -110,11 +208,20 @@ static void restartedCallback(SoupMessage* msg, gpointer data)
if (d->m_cancelled)
return;
- char* uri = soup_uri_to_string(soup_message_get_uri(msg), FALSE);
+ char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
String location = String(uri);
g_free(uri);
KURL newURL = KURL(handle->request().url(), location);
+ // FIXME: This is needed because some servers use broken URIs in
+ // their Location header, when redirecting, such as URIs with
+ // white spaces instead of %20; this should be fixed in soup, in
+ // the future, and this work-around removed.
+ // See http://bugzilla.gnome.org/show_bug.cgi?id=575378.
+ SoupURI* soup_uri = soup_uri_new(newURL.string().utf8().data());
+ soup_message_set_uri(msg, soup_uri);
+ soup_uri_free(soup_uri);
+
ResourceRequest request = handle->request();
ResourceResponse response;
request.setURL(newURL);
@@ -127,7 +234,32 @@ static void restartedCallback(SoupMessage* msg, gpointer data)
static void gotHeadersCallback(SoupMessage* msg, gpointer data)
{
- if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
+ // For 401, we will accumulate the resource body, and only use it
+ // in case authentication with the soup feature doesn't happen
+ if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
+ soup_message_body_set_accumulate(msg->response_body, TRUE);
+ return;
+ }
+
+ // For all the other responses, we handle each chunk ourselves,
+ // and we don't need msg->response_body to contain all of the data
+ // we got, when we finish downloading.
+ soup_message_body_set_accumulate(msg->response_body, FALSE);
+
+ // The 304 status code (SOUP_STATUS_NOT_MODIFIED) needs to be fed
+ // into WebCore, as opposed to other kinds of redirections, which
+ // are handled by soup directly, so we special-case it here and in
+ // gotChunk.
+ if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)
+ || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED)))
+ return;
+
+ // We still don't know anything about Content-Type, so we will try
+ // sniffing the contents of the file, and then report that we got
+ // headers; we will not do content sniffing for 304 responses,
+ // though, since they do not have a body.
+ if ((msg->status_code != SOUP_STATUS_NOT_MODIFIED)
+ && !soup_message_headers_get_content_type(msg->response_headers, NULL))
return;
ResourceHandle* handle = static_cast<ResourceHandle*>(data);
@@ -142,12 +274,14 @@ static void gotHeadersCallback(SoupMessage* msg, gpointer data)
fillResponseFromMessage(msg, &d->m_response);
client->didReceiveResponse(handle, d->m_response);
- soup_message_set_flags(msg, SOUP_MESSAGE_OVERWRITE_CHUNKS);
+ d->m_reportedHeaders = true;
}
static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
{
- if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
+ if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)
+ || (SOUP_STATUS_IS_REDIRECTION(msg->status_code) && (msg->status_code != SOUP_STATUS_NOT_MODIFIED))
+ || (msg->status_code == SOUP_STATUS_UNAUTHORIZED))
return;
ResourceHandle* handle = static_cast<ResourceHandle*>(data);
@@ -160,6 +294,17 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
if (!client)
return;
+ if (!d->m_reportedHeaders) {
+ gboolean uncertain;
+ char* contentType = g_content_type_guess(d->m_request.url().lastPathComponent().utf8().data(), reinterpret_cast<const guchar*>(chunk->data), chunk->length, &uncertain);
+ soup_message_headers_set_content_type(msg->response_headers, contentType, NULL);
+ g_free(contentType);
+
+ fillResponseFromMessage(msg, &d->m_response);
+ client->didReceiveResponse(handle, d->m_response);
+ d->m_reportedHeaders = true;
+ }
+
client->didReceiveData(handle, chunk->data, chunk->length, false);
}
@@ -167,7 +312,7 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
// Doesn't get called for redirects.
static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(data);
+ RefPtr<ResourceHandle>handle = adoptRef(static_cast<ResourceHandle*>(data));
// TODO: maybe we should run this code even if there's no client?
if (!handle)
return;
@@ -182,24 +327,26 @@ static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer da
return;
if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
- char* uri = soup_uri_to_string(soup_message_get_uri(msg), FALSE);
+ char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
ResourceError error("webkit-network-error", ERROR_TRANSPORT, uri, String::fromUTF8(msg->reason_phrase));
g_free(uri);
- client->didFail(handle, error);
+ client->didFail(handle.get(), error);
return;
- } else if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
+ }
+
+ if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
fillResponseFromMessage(msg, &d->m_response);
- client->didReceiveResponse(handle, d->m_response);
+ client->didReceiveResponse(handle.get(), d->m_response);
// WebCore might have cancelled the job in the while
if (d->m_cancelled)
return;
if (msg->response_body->data)
- client->didReceiveData(handle, msg->response_body->data, msg->response_body->length, true);
+ client->didReceiveData(handle.get(), msg->response_body->data, msg->response_body->length, true);
}
- client->didFinishLoading(handle);
+ client->didFinishLoading(handle.get());
}
// parseDataUrl() is taken from the CURL http backend.
@@ -212,7 +359,7 @@ static gboolean parseDataUrl(gpointer callback_data)
ASSERT(client);
if (!client)
- return FALSE;
+ return false;
String url = handle->request().url().string();
ASSERT(url.startsWith("data:", false));
@@ -220,14 +367,14 @@ static gboolean parseDataUrl(gpointer callback_data)
int index = url.find(',');
if (index == -1) {
client->cannotShowURL(handle);
- return FALSE;
+ return false;
}
String mediaType = url.substring(5, index - 5);
String data = url.substring(index + 1);
- bool base64 = mediaType.endsWith(";base64", false);
- if (base64)
+ bool isBase64 = mediaType.endsWith(";base64", false);
+ if (isBase64)
mediaType = mediaType.left(mediaType.length() - 7);
if (mediaType.isEmpty())
@@ -239,7 +386,7 @@ static gboolean parseDataUrl(gpointer callback_data)
ResourceResponse response;
response.setMimeType(mimeType);
- if (base64) {
+ if (isBase64) {
data = decodeURLEscapeSequences(data);
response.setTextEncodingName(charset);
client->didReceiveResponse(handle, response);
@@ -269,7 +416,7 @@ static gboolean parseDataUrl(gpointer callback_data)
client->didFinishLoading(handle);
- return FALSE;
+ return false;
}
bool ResourceHandle::startData(String urlString)
@@ -282,30 +429,44 @@ bool ResourceHandle::startData(String urlString)
return true;
}
-bool ResourceHandle::startHttp(String urlString)
+static SoupSession* createSoupSession()
{
- if (!session) {
- session = soup_session_async_new();
+ return soup_session_async_new();
+}
- soup_session_add_feature(session, SOUP_SESSION_FEATURE(getCookieJar()));
+static void ensureSessionIsInitialized(SoupSession* session)
+{
+ if (g_object_get_data(G_OBJECT(session), "webkit-init"))
+ return;
- const char* soup_debug = g_getenv("WEBKIT_SOUP_LOGGING");
- if (soup_debug) {
- int soup_debug_level = atoi(soup_debug);
+ SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));
+ if (!jar)
+ soup_session_add_feature(session, SOUP_SESSION_FEATURE(defaultCookieJar()));
+ else
+ setDefaultCookieJar(jar);
- SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(soup_debug_level), -1);
- soup_logger_attach(logger, session);
- g_object_unref(logger);
- }
+ if (!soup_session_get_feature(session, SOUP_TYPE_LOGGER) && LogNetwork.state == WTFLogChannelOn) {
+ SoupLogger* logger = soup_logger_new(static_cast<SoupLoggerLogLevel>(SOUP_LOGGER_LOG_BODY), -1);
+ soup_logger_attach(logger, session);
+ g_object_unref(logger);
}
+ g_object_set_data(G_OBJECT(session), "webkit-init", reinterpret_cast<void*>(0xdeadbeef));
+}
+
+bool ResourceHandle::startHttp(String urlString)
+{
+ SoupSession* session = defaultSession();
+ ensureSessionIsInitialized(session);
+
SoupMessage* msg;
msg = soup_message_new(request().httpMethod().utf8().data(), urlString.utf8().data());
g_signal_connect(msg, "restarted", G_CALLBACK(restartedCallback), this);
-
g_signal_connect(msg, "got-headers", G_CALLBACK(gotHeadersCallback), this);
g_signal_connect(msg, "got-chunk", G_CALLBACK(gotChunkCallback), this);
+ g_object_set_data(G_OBJECT(msg), "resourceHandle", reinterpret_cast<void*>(this));
+
HTTPHeaderMap customHeaders = d->m_request.httpHeaderFields();
if (!customHeaders.isEmpty()) {
HTTPHeaderMap::const_iterator end = customHeaders.end();
@@ -315,68 +476,130 @@ bool ResourceHandle::startHttp(String urlString)
FormData* httpBody = d->m_request.httpBody();
if (httpBody && !httpBody->isEmpty()) {
- // Making a copy of the request body isn't the most efficient way to
- // serialize it, but by far the most simple. Dealing with individual
- // FormData elements and shared buffers should be more memory
- // efficient.
- //
- // This possibly isn't handling file uploads/attachments, for which
- // shared buffers or streaming should definitely be used.
- Vector<char> body;
- httpBody->flatten(body);
- soup_message_set_request(msg, d->m_request.httpContentType().utf8().data(),
- SOUP_MEMORY_COPY, body.data(), body.size());
+ size_t numElements = httpBody->elements().size();
+
+ // handle the most common case (i.e. no file upload)
+ if (numElements < 2) {
+ Vector<char> body;
+ httpBody->flatten(body);
+ soup_message_set_request(msg, d->m_request.httpContentType().utf8().data(),
+ SOUP_MEMORY_COPY, body.data(), body.size());
+ } else {
+ /*
+ * we have more than one element to upload, and some may
+ * be (big) files, which we will want to mmap instead of
+ * copying into memory; TODO: support upload of non-local
+ * (think sftp://) files by using GIO?
+ */
+ soup_message_body_set_accumulate(msg->request_body, FALSE);
+ for (size_t i = 0; i < numElements; i++) {
+ const FormDataElement& element = httpBody->elements()[i];
+
+ if (element.m_type == FormDataElement::data)
+ soup_message_body_append(msg->request_body, SOUP_MEMORY_TEMPORARY, element.m_data.data(), element.m_data.size());
+ else {
+ /*
+ * mapping for uploaded files code inspired by technique used in
+ * libsoup's simple-httpd test
+ */
+ GError* error = 0;
+ gchar* fileName = filenameFromString(element.m_filename);
+ GMappedFile* fileMapping = g_mapped_file_new(fileName, false, &error);
+
+ g_free(fileName);
+
+ if (error) {
+ ResourceError resourceError("webkit-network-error", ERROR_UNABLE_TO_OPEN_FILE, urlString, error->message);
+ g_error_free(error);
+
+ d->client()->didFail(this, resourceError);
+
+ g_object_unref(msg);
+ return false;
+ }
+
+ SoupBuffer* soupBuffer = soup_buffer_new_with_owner(g_mapped_file_get_contents(fileMapping),
+ g_mapped_file_get_length(fileMapping),
+ fileMapping, reinterpret_cast<GDestroyNotify>(g_mapped_file_free));
+ soup_message_body_append_buffer(msg->request_body, soupBuffer);
+ soup_buffer_free(soupBuffer);
+ }
+ }
+ }
}
d->m_msg = static_cast<SoupMessage*>(g_object_ref(msg));
+ // balanced by a deref() in finishedCallback, which should always run
+ ref();
+
soup_session_queue_message(session, d->m_msg, finishedCallback, this);
return true;
}
+static gboolean reportUnknownProtocolError(gpointer callback_data)
+{
+ ResourceHandle* handle = static_cast<ResourceHandle*>(callback_data);
+ ResourceHandleInternal* d = handle->getInternal();
+ ResourceHandleClient* client = handle->client();
+
+ if (d->m_cancelled || !client) {
+ handle->deref();
+ return false;
+ }
+
+ KURL url = handle->request().url();
+ ResourceError error("webkit-network-error", ERROR_UNKNOWN_PROTOCOL, url.string(), url.protocol());
+ client->didFail(handle, error);
+
+ handle->deref();
+ return false;
+}
+
bool ResourceHandle::start(Frame* frame)
{
ASSERT(!d->m_msg);
- // If we are no longer attached to a Page, this must be an attempted load from an
- // onUnload handler, so let's just block it.
- if (!frame->page())
+
+ // The frame could be null if the ResourceHandle is not associated to any
+ // Frame, e.g. if we are downloading a file.
+ // If the frame is not null but the page is null this must be an attempted
+ // load from an onUnload handler, so let's just block it.
+ if (frame && !frame->page())
return false;
KURL url = request().url();
String urlString = url.string();
String protocol = url.protocol();
+ // Used to set the authentication dialog toplevel; may be NULL
+ d->m_frame = frame;
+
if (equalIgnoringCase(protocol, "data"))
return startData(urlString);
- else if ((equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) && SOUP_URI_VALID_FOR_HTTP(soup_uri_new(urlString.utf8().data())))
+
+ if ((equalIgnoringCase(protocol, "http") || equalIgnoringCase(protocol, "https")) && SOUP_URI_VALID_FOR_HTTP(soup_uri_new(urlString.utf8().data())))
return startHttp(urlString);
- else if (equalIgnoringCase(protocol, "file") || equalIgnoringCase(protocol, "ftp") || equalIgnoringCase(protocol, "ftps"))
+
+ if (equalIgnoringCase(protocol, "file") || equalIgnoringCase(protocol, "ftp") || equalIgnoringCase(protocol, "ftps"))
// FIXME: should we be doing any other protocols here?
- return startGio(urlString);
- else {
- // If we don't call didFail the job is not complete for webkit even false is returned.
- if (d->client()) {
- ResourceError error("webkit-network-error", ERROR_UNKNOWN_PROTOCOL, urlString, protocol);
- d->client()->didFail(this, error);
- }
- return false;
- }
+ return startGio(url);
+
+ // Error must not be reported immediately, but through an idle function.
+ // Despite error, we should return true so a proper handle is created,
+ // to which this failure can be reported.
+ ref();
+ d->m_idleHandler = g_idle_add(reportUnknownProtocolError, this);
+ return true;
}
void ResourceHandle::cancel()
{
d->m_cancelled = true;
- if (d->m_msg) {
- soup_session_cancel_message(session, d->m_msg, SOUP_STATUS_CANCELLED);
- // For re-entrancy troubles we call didFinishLoading when the message hasn't been handled yet.
- if (client())
- client()->didFinishLoading(this);
- } else if (d->m_cancellable) {
+ if (d->m_msg)
+ soup_session_cancel_message(defaultSession(), d->m_msg, SOUP_STATUS_CANCELLED);
+ else if (d->m_cancellable)
g_cancellable_cancel(d->m_cancellable);
- if (client())
- client()->didFinishLoading(this);
- }
}
PassRefPtr<SharedBuffer> ResourceHandle::bufferedData()
@@ -409,9 +632,13 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest&)
return false;
}
-void ResourceHandle::loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>&, Frame*)
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame)
{
- notImplemented();
+ WebCoreSynchronousLoader syncLoader(error, response, data);
+ ResourceHandle handle(request, &syncLoader, true, false, true);
+
+ handle.start(frame);
+ syncLoader.run();
}
// GIO-based loader
@@ -420,7 +647,7 @@ static inline ResourceError networkErrorForFile(GFile* file, GError* error)
{
// FIXME: Map gio errors to a more detailed error code when we have it in WebKit.
gchar* uri = g_file_get_uri(file);
- ResourceError resourceError("webkit-network-error", ERROR_TRANSPORT, uri, String::fromUTF8(error->message));
+ ResourceError resourceError("webkit-network-error", ERROR_TRANSPORT, uri, error ? String::fromUTF8(error->message) : String());
g_free(uri);
return resourceError;
}
@@ -430,20 +657,23 @@ static void cleanupGioOperation(ResourceHandleInternal* d)
if (d->m_gfile) {
g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0);
g_object_unref(d->m_gfile);
- d->m_gfile = NULL;
+ d->m_gfile = 0;
}
+
if (d->m_cancellable) {
g_object_unref(d->m_cancellable);
- d->m_cancellable = NULL;
+ d->m_cancellable = 0;
}
- if (d->m_input_stream) {
- g_object_set_data(G_OBJECT(d->m_input_stream), "webkit-resource", 0);
- g_object_unref(d->m_input_stream);
- d->m_input_stream = NULL;
+
+ if (d->m_inputStream) {
+ g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", 0);
+ g_object_unref(d->m_inputStream);
+ d->m_inputStream = 0;
}
+
if (d->m_buffer) {
g_free(d->m_buffer);
- d->m_buffer = NULL;
+ d->m_buffer = 0;
}
}
@@ -456,14 +686,15 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleInternal* d = handle->getInternal();
ResourceHandleClient* client = handle->client();
- g_input_stream_close_finish(d->m_input_stream, res, NULL);
+ g_input_stream_close_finish(d->m_inputStream, res, 0);
cleanupGioOperation(d);
client->didFinishLoading(handle);
}
static void readCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ // didReceiveData may cancel the load, which may release the last reference.
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -475,27 +706,34 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
return;
}
- gssize nread;
GError *error = 0;
- nread = g_input_stream_read_finish(d->m_input_stream, res, &error);
+ gssize bytesRead = g_input_stream_read_finish(d->m_inputStream, res, &error);
if (error) {
ResourceError resourceError = networkErrorForFile(d->m_gfile, error);
+ g_error_free(error);
cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ client->didFail(handle.get(), resourceError);
return;
- } else if (!nread) {
- g_input_stream_close_async(d->m_input_stream, G_PRIORITY_DEFAULT,
- NULL, closeCallback, NULL);
+ }
+
+ if (!bytesRead) {
+ g_input_stream_close_async(d->m_inputStream, G_PRIORITY_DEFAULT,
+ 0, closeCallback, 0);
return;
}
- d->m_total += nread;
- client->didReceiveData(handle, d->m_buffer, nread, d->m_total);
+ d->m_total += bytesRead;
+ client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
- g_input_stream_read_async(d->m_input_stream, d->m_buffer, d->m_bufsize,
+ if (d->m_cancelled) {
+ cleanupGioOperation(d);
+ return;
+ }
+
+ g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
G_PRIORITY_DEFAULT, d->m_cancellable,
- readCallback, NULL);
+ readCallback, 0);
}
static void openCallback(GObject* source, GAsyncResult* res, gpointer)
@@ -512,24 +750,24 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
return;
}
- GFileInputStream* in;
- GError *error = NULL;
- in = g_file_read_finish(G_FILE(source), res, &error);
+ GError *error = 0;
+ GFileInputStream* in = g_file_read_finish(G_FILE(source), res, &error);
if (error) {
ResourceError resourceError = networkErrorForFile(d->m_gfile, error);
+ g_error_free(error);
cleanupGioOperation(d);
client->didFail(handle, resourceError);
return;
}
- d->m_input_stream = G_INPUT_STREAM(in);
- d->m_bufsize = 8192;
- d->m_buffer = static_cast<char*>(g_malloc(d->m_bufsize));
+ d->m_inputStream = G_INPUT_STREAM(in);
+ d->m_bufferSize = 8192;
+ d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize));
d->m_total = 0;
- g_object_set_data(G_OBJECT(d->m_input_stream), "webkit-resource", handle);
- g_input_stream_read_async(d->m_input_stream, d->m_buffer, d->m_bufsize,
+ g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle);
+ g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
G_PRIORITY_DEFAULT, d->m_cancellable,
- readCallback, NULL);
+ readCallback, 0);
}
static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
@@ -549,10 +787,10 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceResponse response;
char* uri = g_file_get_uri(d->m_gfile);
- response.setUrl(KURL(uri));
+ response.setURL(KURL(KURL(), uri));
g_free(uri);
- GError *error = NULL;
+ GError *error = 0;
GFileInfo* info = g_file_query_info_finish(d->m_gfile, res, &error);
if (error) {
@@ -564,6 +802,7 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
// for a while).
ResourceError resourceError = networkErrorForFile(d->m_gfile, error);
+ g_error_free(error);
cleanupGioOperation(d);
client->didFail(handle, resourceError);
return;
@@ -573,7 +812,7 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
// FIXME: what if the URI points to a directory? Should we
// generate a listing? How? What do other backends do here?
- ResourceError resourceError = networkErrorForFile(d->m_gfile, error);
+ ResourceError resourceError = networkErrorForFile(d->m_gfile, 0);
cleanupGioOperation(d);
client->didFail(handle, resourceError);
return;
@@ -581,7 +820,6 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
response.setMimeType(g_file_info_get_content_type(info));
response.setExpectedContentLength(g_file_info_get_size(info));
- response.setHTTPStatusCode(SOUP_STATUS_OK);
GTimeVal tv;
g_file_info_get_modification_time(info, &tv);
@@ -590,23 +828,31 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
client->didReceiveResponse(handle, response);
g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable,
- openCallback, NULL);
+ openCallback, 0);
}
-bool ResourceHandle::startGio(String urlString)
+bool ResourceHandle::startGio(KURL url)
{
- if (request().httpMethod() != "GET") {
- ResourceError error("webkit-network-error", ERROR_BAD_NON_HTTP_METHOD, urlString, request().httpMethod());
+ if (request().httpMethod() != "GET" && request().httpMethod() != "POST") {
+ ResourceError error("webkit-network-error", ERROR_BAD_NON_HTTP_METHOD, url.string(), request().httpMethod());
d->client()->didFail(this, error);
return false;
}
- // Remove the fragment part of the URL since the file backend doesn't deal with it
- int fragPos;
- if ((fragPos = urlString.find("#")) != -1)
- urlString = urlString.left(fragPos);
-
- d->m_gfile = g_file_new_for_uri(urlString.utf8().data());
+ // GIO doesn't know how to handle refs and queries, so remove them
+ // TODO: use KURL.fileSystemPath after KURLGtk and FileSystemGtk are
+ // using GIO internally, and providing URIs instead of file paths
+ url.removeRef();
+ url.setQuery(String());
+ url.setPort(0);
+
+ // we avoid the escaping for local files, because
+ // g_filename_from_uri (used internally by GFile) has problems
+ // decoding strings with arbitrary percent signs
+ if (url.isLocalFile())
+ d->m_gfile = g_file_new_for_path(url.prettyURL().utf8().data() + sizeof("file://") - 1);
+ else
+ d->m_gfile = g_file_new_for_uri(url.string().utf8().data());
g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", this);
d->m_cancellable = g_cancellable_new();
g_file_query_info_async(d->m_gfile,
@@ -615,9 +861,16 @@ bool ResourceHandle::startGio(String urlString)
G_FILE_ATTRIBUTE_STANDARD_SIZE,
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT, d->m_cancellable,
- queryInfoCallback, NULL);
+ queryInfoCallback, 0);
return true;
}
+SoupSession* ResourceHandle::defaultSession()
+{
+ static SoupSession* session = createSoupSession();;
+
+ return session;
+}
+
}
diff --git a/WebCore/platform/network/win/CookieJarCFNetWin.cpp b/WebCore/platform/network/win/CookieJarCFNetWin.cpp
index 56d7265..7e64813 100644
--- a/WebCore/platform/network/win/CookieJarCFNetWin.cpp
+++ b/WebCore/platform/network/win/CookieJarCFNetWin.cpp
@@ -41,28 +41,6 @@ namespace WebCore {
static const CFStringRef s_setCookieKeyCF = CFSTR("Set-Cookie");
static const CFStringRef s_cookieCF = CFSTR("Cookie");
-typedef Boolean (*IsHTTPOnlyFunction)(CFHTTPCookieRef);
-
-static HMODULE findCFNetworkModule()
-{
- if (HMODULE module = GetModuleHandleA("CFNetwork"))
- return module;
- return GetModuleHandleA("CFNetwork_debug");
-}
-
-static IsHTTPOnlyFunction findIsHTTPOnlyFunction()
-{
- return reinterpret_cast<IsHTTPOnlyFunction>(GetProcAddress(findCFNetworkModule(), "CFHTTPCookieIsHTTPOnly"));
-}
-
-static bool isHTTPOnly(CFHTTPCookieRef cookie)
-{
- // Once we require a newer version of CFNetwork with the CFHTTPCookieIsHTTPOnly function,
- // we can change this to be a normal function call and eliminate findIsHTTPOnlyFunction.
- static IsHTTPOnlyFunction function = findIsHTTPOnlyFunction();
- return function && function(cookie);
-}
-
static RetainPtr<CFArrayRef> filterCookies(CFArrayRef unfilteredCookies)
{
CFIndex count = CFArrayGetCount(unfilteredCookies);
@@ -77,7 +55,7 @@ static RetainPtr<CFArrayRef> filterCookies(CFArrayRef unfilteredCookies)
if (!CFStringGetLength(CFHTTPCookieGetName(cookie)))
continue;
- if (isHTTPOnly(cookie))
+ if (CFHTTPCookieIsHTTPOnly(cookie))
continue;
CFArrayAppendValue(filteredCookies.get(), cookie);
diff --git a/WebCore/platform/qt/CookieJarQt.cpp b/WebCore/platform/qt/CookieJarQt.cpp
index 0d24c7e..4077407 100644
--- a/WebCore/platform/qt/CookieJarQt.cpp
+++ b/WebCore/platform/qt/CookieJarQt.cpp
@@ -80,7 +80,7 @@ void setCookies(Document* document, const KURL& url, const KURL& policyURL, cons
++it;
}
#endif
- jar->setCookiesFromUrl(cookies, p);
+ jar->setCookiesFromUrl(cookies, u);
#else
QCookieJar::cookieJar()->setCookies(u, p, (QString)value);
#endif
diff --git a/WebCore/platform/qt/FileSystemQt.cpp b/WebCore/platform/qt/FileSystemQt.cpp
index 6dbe464..8a272c1 100644
--- a/WebCore/platform/qt/FileSystemQt.cpp
+++ b/WebCore/platform/qt/FileSystemQt.cpp
@@ -124,7 +124,7 @@ CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
return String(temp->fileName()).utf8();
}
handle = invalidPlatformFileHandle;
- return 0;
+ return CString();
}
void closeFile(PlatformFileHandle& handle)
@@ -143,32 +143,24 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length)
return 0;
}
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
bool unloadModule(PlatformModule module)
{
+#if defined(Q_WS_MAC)
+ CFRelease(module);
+ return true;
+
+#elif defined(Q_OS_WIN)
+ return ::FreeLibrary(module);
+
+#else
if (module->unload()) {
delete module;
return true;
}
-
+
return false;
-}
-#endif
-
-#if defined(Q_WS_MAC)
-bool unloadModule(PlatformModule module)
-{
- CFRelease(module);
- return true;
-}
#endif
-
-#if defined(Q_OS_WIN)
-bool unloadModule(PlatformModule module)
-{
- return ::FreeLibrary(module);
}
-#endif
}
diff --git a/WebCore/platform/qt/KURLQt.cpp b/WebCore/platform/qt/KURLQt.cpp
index cdc4f48..0763fe0 100644
--- a/WebCore/platform/qt/KURLQt.cpp
+++ b/WebCore/platform/qt/KURLQt.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "KURL.h"
#include "CString.h"
+#include "TextEncoding.h"
#include "NotImplemented.h"
#include "qurl.h"
@@ -36,7 +37,7 @@ static inline char toHex(char c)
KURL::KURL(const QUrl& url)
{
- *this = KURL(url.toEncoded().constData());
+ *this = KURL(KURL(), url.toEncoded().constData(), UTF8Encoding());
}
KURL::operator QUrl() const
diff --git a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
index 76342ab..88cca5a 100644
--- a/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
+++ b/WebCore/platform/qt/PlatformKeyboardEventQt.cpp
@@ -192,6 +192,55 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode)
case Qt::Key_Alt:
return VK_MENU; // (12) ALT key
+ case Qt::Key_F1:
+ return VK_F1;
+ case Qt::Key_F2:
+ return VK_F2;
+ case Qt::Key_F3:
+ return VK_F3;
+ case Qt::Key_F4:
+ return VK_F4;
+ case Qt::Key_F5:
+ return VK_F5;
+ case Qt::Key_F6:
+ return VK_F6;
+ case Qt::Key_F7:
+ return VK_F7;
+ case Qt::Key_F8:
+ return VK_F8;
+ case Qt::Key_F9:
+ return VK_F9;
+ case Qt::Key_F10:
+ return VK_F11;
+ case Qt::Key_F11:
+ return VK_F11;
+ case Qt::Key_F12:
+ return VK_F12;
+ case Qt::Key_F13:
+ return VK_F13;
+ case Qt::Key_F14:
+ return VK_F14;
+ case Qt::Key_F15:
+ return VK_F15;
+ case Qt::Key_F16:
+ return VK_F16;
+ case Qt::Key_F17:
+ return VK_F17;
+ case Qt::Key_F18:
+ return VK_F18;
+ case Qt::Key_F19:
+ return VK_F19;
+ case Qt::Key_F20:
+ return VK_F20;
+ case Qt::Key_F21:
+ return VK_F21;
+ case Qt::Key_F22:
+ return VK_F22;
+ case Qt::Key_F23:
+ return VK_F23;
+ case Qt::Key_F24:
+ return VK_F24;
+
case Qt::Key_Pause:
return VK_PAUSE; // (13) PAUSE key
case Qt::Key_CapsLock:
diff --git a/WebCore/platform/qt/QWebPopup.cpp b/WebCore/platform/qt/QWebPopup.cpp
index d463ddf..4d57c9b 100644
--- a/WebCore/platform/qt/QWebPopup.cpp
+++ b/WebCore/platform/qt/QWebPopup.cpp
@@ -22,7 +22,9 @@
#include "QWebPopup.h"
#include "PopupMenuStyle.h"
-#include <QCoreApplication>
+#include <QAbstractItemView>
+#include <QApplication>
+#include <QInputContext>
#include <QMouseEvent>
namespace WebCore {
@@ -54,6 +56,16 @@ void QWebPopup::showPopup()
void QWebPopup::hidePopup()
{
+ QWidget* activeFocus = QApplication::focusWidget();
+ if (activeFocus && activeFocus == view()
+ && activeFocus->testAttribute(Qt::WA_InputMethodEnabled)) {
+ QInputContext* qic = activeFocus->inputContext();
+ if (qic) {
+ qic->reset();
+ qic->setFocusWidget(0);
+ }
+ }
+
QComboBox::hidePopup();
if (!m_popupVisible)
return;
diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp
index eee8c86..942e95b 100644
--- a/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/WebCore/platform/qt/RenderThemeQt.cpp
@@ -796,7 +796,7 @@ private:
HTMLMediaElement* RenderThemeQt::getMediaElementFromRenderObject(RenderObject* o) const
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return 0;
@@ -815,7 +815,7 @@ void RenderThemeQt::paintMediaBackground(QPainter* painter, const IntRect& r) co
QColor RenderThemeQt::getMediaControlForegroundColor(RenderObject* o) const
{
QColor fgColor = platformActiveSelectionBackgroundColor();
- if (o && o->element()->active())
+ if (o && o->node()->active())
fgColor = fgColor.lighter();
return fgColor;
}
diff --git a/WebCore/platform/qt/RenderThemeQt.h b/WebCore/platform/qt/RenderThemeQt.h
index 9a6cf0b..b4a5064 100644
--- a/WebCore/platform/qt/RenderThemeQt.h
+++ b/WebCore/platform/qt/RenderThemeQt.h
@@ -1,7 +1,7 @@
/*
* This file is part of the theme implementation for form controls in WebCore.
*
- * Copyright (C) 2007 Trolltech
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
diff --git a/WebCore/platform/qt/WheelEventQt.cpp b/WebCore/platform/qt/WheelEventQt.cpp
index cc8acd2..9534f20 100644
--- a/WebCore/platform/qt/WheelEventQt.cpp
+++ b/WebCore/platform/qt/WheelEventQt.cpp
@@ -21,7 +21,9 @@
#include "PlatformWheelEvent.h"
#include "PlatformMouseEvent.h"
+#include "Scrollbar.h"
+#include <qapplication.h>
#include <QWheelEvent>
namespace WebCore {
@@ -35,11 +37,7 @@ PlatformWheelEvent::PlatformWheelEvent(QWheelEvent* e)
#else
: m_position(e->pos())
, m_globalPosition(e->globalPos())
-#ifdef QT_MAC_USE_COCOA
, m_granularity(ScrollByPixelWheelEvent)
-#else
- , m_granularity(ScrollByLineWheelEvent)
-#endif
, m_isAccepted(false)
, m_shiftKey(e->modifiers() & Qt::ShiftModifier)
, m_ctrlKey(e->modifiers() & Qt::ControlModifier)
@@ -53,10 +51,14 @@ PlatformWheelEvent::PlatformWheelEvent(QWheelEvent* e)
m_deltaX = 0;
m_deltaY = (e->delta() / 120);
}
+ m_wheelTicksX = m_deltaX;
+ m_wheelTicksY = m_deltaY;
- // FIXME: retrieve the user setting for the number of lines to scroll on each wheel event
- m_deltaX *= horizontalLineMultiplier();
- m_deltaY *= verticalLineMultiplier();
+ // use the same single scroll step as QTextEdit (in
+ // QTextEditPrivate::init [h,v]bar->setSingleStep )
+ static const float cDefaultQtScrollStep = 20.f;
+ m_deltaX *= QApplication::wheelScrollLines() * cDefaultQtScrollStep;
+ m_deltaY *= QApplication::wheelScrollLines() * cDefaultQtScrollStep;
}
#endif // QT_NO_WHEELEVENT
diff --git a/WebCore/platform/text/AtomicString.cpp b/WebCore/platform/text/AtomicString.cpp
index 5f9abfd..d85f5ee 100644
--- a/WebCore/platform/text/AtomicString.cpp
+++ b/WebCore/platform/text/AtomicString.cpp
@@ -101,7 +101,7 @@ static inline bool equal(StringImpl* string, const UChar* characters, unsigned l
if (string->length() != length)
return false;
-#if PLATFORM(ARM)
+#if PLATFORM(ARM) || PLATFORM(SH4)
const UChar* stringCharacters = string->characters();
for (unsigned i = 0; i != length; ++i) {
if (*stringCharacters++ != *characters++)
diff --git a/WebCore/platform/text/Base64.cpp b/WebCore/platform/text/Base64.cpp
index 920fa89..be19164 100644
--- a/WebCore/platform/text/Base64.cpp
+++ b/WebCore/platform/text/Base64.cpp
@@ -97,8 +97,8 @@ void base64Encode(const Vector<char>& in, Vector<char>& out, bool insertLFs)
count += 4;
}
out[didx++] = base64EncMap[(data[sidx] >> 2) & 077];
- out[didx++] = base64EncMap[(data[sidx + 1] >> 4) & 017 | (data[sidx] << 4) & 077];
- out[didx++] = base64EncMap[(data[sidx + 2] >> 6) & 003 | (data[sidx + 1] << 2) & 077];
+ out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) | ((data[sidx] << 4) & 077)];
+ out[didx++] = base64EncMap[((data[sidx + 2] >> 6) & 003) | ((data[sidx + 1] << 2) & 077)];
out[didx++] = base64EncMap[data[sidx + 2] & 077];
sidx += 3;
}
@@ -110,7 +110,7 @@ void base64Encode(const Vector<char>& in, Vector<char>& out, bool insertLFs)
out[didx++] = base64EncMap[(data[sidx] >> 2) & 077];
if (sidx < len - 1) {
- out[didx++] = base64EncMap[(data[sidx + 1] >> 4) & 017 | (data[sidx] << 4) & 077];
+ out[didx++] = base64EncMap[((data[sidx + 1] >> 4) & 017) | ((data[sidx] << 4) & 077)];
out[didx++] = base64EncMap[(data[sidx + 1] << 2) & 077];
} else
out[didx++] = base64EncMap[(data[sidx] << 4) & 077];
diff --git a/WebCore/platform/text/BidiResolver.h b/WebCore/platform/text/BidiResolver.h
index ffd3d51..8288be4 100644
--- a/WebCore/platform/text/BidiResolver.h
+++ b/WebCore/platform/text/BidiResolver.h
@@ -254,7 +254,16 @@ template <class Iterator, class Run>
void BidiResolver<Iterator, Run>::appendRun()
{
if (!emptyRun && !eor.atEnd()) {
- addRun(new Run(sor.offset(), eor.offset() + 1, context(), m_direction));
+ unsigned startOffset = sor.offset();
+ unsigned endOffset = eor.offset();
+
+ if (!endOfLine.atEnd() && endOffset >= endOfLine.offset()) {
+ reachedEndOfLine = true;
+ endOffset = endOfLine.offset();
+ }
+
+ if (endOffset >= startOffset)
+ addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
eor.increment();
sor = eor;
@@ -352,8 +361,8 @@ void BidiResolver<Iterator, Run>::raiseExplicitEmbeddingLevel(WTF::Unicode::Dire
m_direction = LeftToRight;
}
} else if (m_status.eor == ArabicNumber
- || m_status.eor == EuropeanNumber && (m_status.lastStrong != LeftToRight || from == RightToLeft)
- || m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && from == RightToLeft) {
+ || (m_status.eor == EuropeanNumber && (m_status.lastStrong != LeftToRight || from == RightToLeft))
+ || (m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && from == RightToLeft)) {
appendRun();
m_direction = RightToLeft;
}
@@ -722,8 +731,8 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, boo
case WhiteSpaceNeutral:
case OtherNeutral:
if (m_status.eor == ArabicNumber
- || m_status.eor == EuropeanNumber && (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft)
- || m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && context()->dir() == RightToLeft) {
+ || (m_status.eor == EuropeanNumber && (m_status.lastStrong == RightToLeft || context()->dir() == RightToLeft))
+ || (m_status.eor != EuropeanNumber && m_status.lastStrong == LeftToRight && context()->dir() == RightToLeft)) {
// Terminate the run before the neutrals.
appendRun();
// Begin an R run for the neutrals.
diff --git a/WebCore/platform/text/CString.cpp b/WebCore/platform/text/CString.cpp
index 8e68628..90990f8 100644
--- a/WebCore/platform/text/CString.cpp
+++ b/WebCore/platform/text/CString.cpp
@@ -47,8 +47,8 @@ void CString::init(const char* str, unsigned length)
return;
m_buffer = CStringBuffer::create(length + 1);
- memcpy(m_buffer->data(), str, length);
- m_buffer->data()[length] = '\0';
+ memcpy(m_buffer->mutableData(), str, length);
+ m_buffer->mutableData()[length] = '\0';
}
const char* CString::data() const
@@ -61,7 +61,7 @@ char* CString::mutableData()
copyBufferIfNeeded();
if (!m_buffer)
return 0;
- return m_buffer->data();
+ return m_buffer->mutableData();
}
unsigned CString::length() const
@@ -73,7 +73,7 @@ CString CString::newUninitialized(size_t length, char*& characterBuffer)
{
CString result;
result.m_buffer = CStringBuffer::create(length + 1);
- char* bytes = result.m_buffer->data();
+ char* bytes = result.m_buffer->mutableData();
bytes[length] = '\0';
characterBuffer = bytes;
return result;
@@ -87,7 +87,7 @@ void CString::copyBufferIfNeeded()
int len = m_buffer->length();
RefPtr<CStringBuffer> m_temp = m_buffer;
m_buffer = CStringBuffer::create(len);
- memcpy(m_buffer->data(), m_temp->data(), len);
+ memcpy(m_buffer->mutableData(), m_temp->data(), len);
}
bool operator==(const CString& a, const CString& b)
@@ -99,17 +99,4 @@ bool operator==(const CString& a, const CString& b)
return !strncmp(a.data(), b.data(), min(a.length(), b.length()));
}
-PassRefPtr<SharedBuffer> CString::releaseBuffer()
-{
- if (!m_buffer)
- return 0;
-
- copyBufferIfNeeded();
-
- RefPtr<SharedBuffer> result = m_buffer->releaseBuffer();
- m_buffer = 0;
- return result.release();
-}
-
-
-}
+} // namespace WebCore
diff --git a/WebCore/platform/text/CString.h b/WebCore/platform/text/CString.h
index 09f112f..f084ddf 100644
--- a/WebCore/platform/text/CString.h
+++ b/WebCore/platform/text/CString.h
@@ -36,15 +36,15 @@ namespace WebCore {
class CStringBuffer : public RefCounted<CStringBuffer> {
public:
- static PassRefPtr<CStringBuffer> create(unsigned length) { return adoptRef(new CStringBuffer(length)); }
-
- char* data() { return m_vector.data(); }
- size_t length() const { return m_vector.size(); }
+ const char* data() { return m_vector.data(); }
+ size_t length() { return m_vector.size(); }
- PassRefPtr<SharedBuffer> releaseBuffer() { return SharedBuffer::adoptVector(m_vector); }
-
private:
+ friend class CString;
+
+ static PassRefPtr<CStringBuffer> create(unsigned length) { return adoptRef(new CStringBuffer(length)); }
CStringBuffer(unsigned length) : m_vector(length) { }
+ char* mutableData() { return m_vector.data(); }
Vector<char> m_vector;
};
@@ -56,6 +56,7 @@ namespace WebCore {
CString() { }
CString(const char*);
CString(const char*, unsigned length);
+ CString(CStringBuffer* buffer) : m_buffer(buffer) { }
static CString newUninitialized(size_t length, char*& characterBuffer);
const char* data() const;
@@ -63,8 +64,8 @@ namespace WebCore {
unsigned length() const;
bool isNull() const { return !m_buffer; }
-
- PassRefPtr<SharedBuffer> releaseBuffer();
+
+ CStringBuffer* buffer() const { return m_buffer.get(); }
private:
void copyBufferIfNeeded();
diff --git a/WebCore/platform/text/PlatformString.h b/WebCore/platform/text/PlatformString.h
index 35d3079..a1541d2 100644
--- a/WebCore/platform/text/PlatformString.h
+++ b/WebCore/platform/text/PlatformString.h
@@ -27,15 +27,18 @@
#include "StringImpl.h"
-#include <wtf/PassRefPtr.h>
+#ifdef __OBJC__
+#include <objc/objc.h>
+#endif
#if USE(JSC)
#include <runtime/Identifier.h>
#else
-// runtime/Identifier.h includes HashMap.h and HashSet.h. We explicitly include
-// them in the case of non-JSC builds to keep things consistent.
+// runtime/Identifier.h brings in a variety of wtf headers. We explicitly
+// include them in the case of non-JSC builds to keep things consistent.
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
#endif
#if PLATFORM(CF) || (PLATFORM(QT) && PLATFORM(DARWIN))
@@ -228,6 +231,9 @@ public:
static String fromUTF8(const char*, size_t);
static String fromUTF8(const char*);
+ // Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8.
+ static String fromUTF8WithLatin1Fallback(const char*, size_t);
+
// Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3.
WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; }
diff --git a/WebCore/platform/text/String.cpp b/WebCore/platform/text/String.cpp
index 638e45f..733b661 100644
--- a/WebCore/platform/text/String.cpp
+++ b/WebCore/platform/text/String.cpp
@@ -623,6 +623,15 @@ String String::fromUTF8(const char* string)
return UTF8Encoding().decode(string, strlen(string));
}
+String String::fromUTF8WithLatin1Fallback(const char* string, size_t size)
+{
+ String result = fromUTF8(string, size);
+ if (!result)
+ result = String(string, size);
+
+ return result;
+}
+
#if USE(JSC)
String::String(const Identifier& str)
{
diff --git a/WebCore/platform/text/StringImpl.cpp b/WebCore/platform/text/StringImpl.cpp
index 0556f8e..6bba990 100644
--- a/WebCore/platform/text/StringImpl.cpp
+++ b/WebCore/platform/text/StringImpl.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller ( mueller@kde.org )
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
*
* This library is free software; you can redistribute it and/or
@@ -54,6 +54,27 @@ static inline void deleteUCharVector(const UChar* p)
fastFree(const_cast<UChar*>(p));
}
+// Some of the factory methods create buffers using fastMalloc.
+// We must ensure that ll allocations of StringImpl are allocated using
+// fastMalloc so that we don't have mis-matched frees. We accomplish
+// this by overriding the new and delete operators.
+void* StringImpl::operator new(size_t size, void* address)
+{
+ if (address)
+ return address; // Allocating using an internal buffer
+ return fastMalloc(size);
+}
+
+void* StringImpl::operator new(size_t size)
+{
+ return fastMalloc(size);
+}
+
+void StringImpl::operator delete(void* address)
+{
+ fastFree(address);
+}
+
// This constructor is used only to create the empty string.
StringImpl::StringImpl()
: m_length(0)
@@ -61,6 +82,7 @@ StringImpl::StringImpl()
, m_hash(0)
, m_inTable(false)
, m_hasTerminatingNullCharacter(false)
+ , m_bufferIsInternal(false)
{
// Ensure that the hash is computed so that AtomicStringHash can call existingHash()
// with impunity. The empty string is special because it is never entered into
@@ -76,6 +98,7 @@ inline StringImpl::StringImpl(const UChar* characters, unsigned length)
, m_hash(0)
, m_inTable(false)
, m_hasTerminatingNullCharacter(false)
+ , m_bufferIsInternal(false)
{
UChar* data = newUCharVector(length);
memcpy(data, characters, length * sizeof(UChar));
@@ -87,6 +110,7 @@ inline StringImpl::StringImpl(const StringImpl& str, WithTerminatingNullCharacte
, m_hash(str.m_hash)
, m_inTable(false)
, m_hasTerminatingNullCharacter(true)
+ , m_bufferIsInternal(false)
{
UChar* data = newUCharVector(str.m_length + 1);
memcpy(data, str.m_data, str.m_length * sizeof(UChar));
@@ -99,6 +123,7 @@ inline StringImpl::StringImpl(const char* characters, unsigned length)
, m_hash(0)
, m_inTable(false)
, m_hasTerminatingNullCharacter(false)
+ , m_bufferIsInternal(false)
{
ASSERT(characters);
ASSERT(length);
@@ -117,6 +142,7 @@ inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer)
, m_hash(0)
, m_inTable(false)
, m_hasTerminatingNullCharacter(false)
+ , m_bufferIsInternal(false)
{
ASSERT(characters);
ASSERT(length);
@@ -128,6 +154,7 @@ StringImpl::StringImpl(const UChar* characters, unsigned length, unsigned hash)
, m_hash(hash)
, m_inTable(true)
, m_hasTerminatingNullCharacter(false)
+ , m_bufferIsInternal(false)
{
ASSERT(hash);
ASSERT(characters);
@@ -144,6 +171,7 @@ StringImpl::StringImpl(const char* characters, unsigned length, unsigned hash)
, m_hash(hash)
, m_inTable(true)
, m_hasTerminatingNullCharacter(false)
+ , m_bufferIsInternal(false)
{
ASSERT(hash);
ASSERT(characters);
@@ -161,7 +189,8 @@ StringImpl::~StringImpl()
{
if (m_inTable)
AtomicString::remove(this);
- deleteUCharVector(m_data);
+ if (!m_bufferIsInternal)
+ deleteUCharVector(m_data);
}
StringImpl* StringImpl::empty()
@@ -907,26 +936,8 @@ WTF::Unicode::Direction StringImpl::defaultWritingDirection()
}
// This is a hot function because it's used when parsing HTML.
-PassRefPtr<StringImpl> StringImpl::createStrippingNullCharacters(const UChar* characters, unsigned length)
+PassRefPtr<StringImpl> StringImpl::createStrippingNullCharactersSlowCase(const UChar* characters, unsigned length)
{
- ASSERT(characters);
- ASSERT(length);
-
- // Optimize for the case where there are no Null characters by quickly
- // searching for nulls, and then using StringImpl::create, which will
- // memcpy the whole buffer. This is faster than assigning character by
- // character during the loop.
-
- // Fast case.
- int foundNull = 0;
- for (unsigned i = 0; !foundNull && i < length; i++) {
- int c = characters[i]; // more efficient than using UChar here (at least on Intel Mac OS)
- foundNull |= !c;
- }
- if (!foundNull)
- return StringImpl::create(characters, length);
-
- // Slow case.
StringBuffer strippedCopy(length);
unsigned strippedLength = 0;
for (unsigned i = 0; i < length; i++) {
@@ -958,24 +969,44 @@ PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned leng
{
if (!characters || !length)
return empty();
- return adoptRef(new StringImpl(characters, length));
+
+ // Allocate a single buffer large enough to contain the StringImpl
+ // struct as well as the data which it contains. This removes one
+ // heap allocation from this call.
+ size_t size = sizeof(StringImpl) + length * sizeof(UChar);
+ char* buffer = static_cast<char*>(fastMalloc(size));
+ UChar* data = reinterpret_cast<UChar*>(buffer + sizeof(StringImpl));
+ memcpy(data, characters, length * sizeof(UChar));
+ StringImpl* string = new (buffer) StringImpl(data, length, AdoptBuffer());
+ string->m_bufferIsInternal = true;
+ return adoptRef(string);
}
PassRefPtr<StringImpl> StringImpl::create(const char* characters, unsigned length)
{
if (!characters || !length)
return empty();
- return adoptRef(new StringImpl(characters, length));
+
+ // Allocate a single buffer large enough to contain the StringImpl
+ // struct as well as the data which it contains. This removes one
+ // heap allocation from this call.
+ size_t size = sizeof(StringImpl) + length * sizeof(UChar);
+ char* buffer = static_cast<char*>(fastMalloc(size));
+ UChar* data = reinterpret_cast<UChar*>(buffer + sizeof(StringImpl));
+ for (unsigned i = 0; i != length; ++i) {
+ unsigned char c = characters[i];
+ data[i] = c;
+ }
+ StringImpl* string = new (buffer) StringImpl(data, length, AdoptBuffer());
+ string->m_bufferIsInternal = true;
+ return adoptRef(string);
}
PassRefPtr<StringImpl> StringImpl::create(const char* string)
{
if (!string)
return empty();
- unsigned length = strlen(string);
- if (!length)
- return empty();
- return adoptRef(new StringImpl(string, length));
+ return create(string, strlen(string));
}
PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string)
@@ -985,7 +1016,7 @@ PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const Stri
PassRefPtr<StringImpl> StringImpl::copy()
{
- return adoptRef(new StringImpl(m_data, m_length));
+ return create(m_data, m_length);
}
} // namespace WebCore
diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h
index 281aa37..1242f27 100644
--- a/WebCore/platform/text/StringImpl.h
+++ b/WebCore/platform/text/StringImpl.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,7 +24,7 @@
#include <limits.h>
#include <wtf/ASCIICType.h>
-#include <wtf/Forward.h>
+#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#include <wtf/unicode/Unicode.h>
@@ -166,12 +166,25 @@ public:
operator NSString*();
#endif
+ void operator delete(void*);
+
private:
+ // Allocation from a custom buffer is only allowed internally to avoid
+ // mismatched allocators. Callers should use create().
+ void* operator new(size_t size);
+ void* operator new(size_t size, void* address);
+
+ static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length);
+
unsigned m_length;
const UChar* m_data;
mutable unsigned m_hash;
bool m_inTable;
bool m_hasTerminatingNullCharacter;
+ // In some cases, we allocate the StringImpl struct and its data
+ // within a single heap buffer. In this case, the m_data pointer
+ // is an "internal buffer", and does not need to be deallocated.
+ bool m_bufferIsInternal;
};
bool equal(StringImpl*, StringImpl*);
@@ -274,6 +287,29 @@ static inline bool isSpaceOrNewline(UChar c)
return c <= 0x7F ? WTF::isASCIISpace(c) : WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral;
}
+// This is a hot function because it's used when parsing HTML.
+inline PassRefPtr<StringImpl> StringImpl::createStrippingNullCharacters(const UChar* characters, unsigned length)
+{
+ ASSERT(characters);
+ ASSERT(length);
+
+ // Optimize for the case where there are no Null characters by quickly
+ // searching for nulls, and then using StringImpl::create, which will
+ // memcpy the whole buffer. This is faster than assigning character by
+ // character during the loop.
+
+ // Fast case.
+ int foundNull = 0;
+ for (unsigned i = 0; !foundNull && i < length; i++) {
+ int c = characters[i]; // more efficient than using UChar here (at least on Intel Mac OS)
+ foundNull |= !c;
+ }
+ if (!foundNull)
+ return StringImpl::create(characters, length);
+
+ return StringImpl::createStrippingNullCharactersSlowCase(characters, length);
+}
+
}
namespace WTF {
diff --git a/WebCore/platform/text/TextBreakIterator.h b/WebCore/platform/text/TextBreakIterator.h
index 64717a4..7b3b963 100644
--- a/WebCore/platform/text/TextBreakIterator.h
+++ b/WebCore/platform/text/TextBreakIterator.h
@@ -29,7 +29,19 @@ namespace WebCore {
class TextBreakIterator;
// Note: The returned iterator is good only until you get another iterator.
+
+ // Iterates over "extended grapheme clusters", as defined in UAX #29.
+ // Note that platform implementations may be less sophisticated - e.g. ICU prior to
+ // version 4.0 only supports "legacy grapheme clusters".
+ // Use this for general text processing, e.g. string truncation.
TextBreakIterator* characterBreakIterator(const UChar*, int length);
+
+ // This is similar to character break iterator in most cases, but is subject to
+ // platform UI conventions. One notable example where this can be different
+ // from character break iterator is Thai prepend characters, see bug 24342.
+ // Use this for insertion point and selection manipulations.
+ TextBreakIterator* cursorMovementIterator(const UChar*, int length);
+
TextBreakIterator* wordBreakIterator(const UChar*, int length);
TextBreakIterator* lineBreakIterator(const UChar*, int length);
TextBreakIterator* sentenceBreakIterator(const UChar*, int length);
diff --git a/WebCore/platform/text/TextBreakIteratorICU.cpp b/WebCore/platform/text/TextBreakIteratorICU.cpp
index 9941f58..c4fc1b0 100644
--- a/WebCore/platform/text/TextBreakIteratorICU.cpp
+++ b/WebCore/platform/text/TextBreakIteratorICU.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "TextBreakIterator.h"
+#include "PlatformString.h"
#include "TextBreakIteratorInternalICU.h"
#include <unicode/ubrk.h>
@@ -114,4 +115,119 @@ bool isTextBreak(TextBreakIterator* bi, int pos)
return ubrk_isBoundary(bi, pos);
}
+#ifndef BUILDING_ON_TIGER
+static TextBreakIterator* setUpIteratorWithRules(bool& createdIterator, TextBreakIterator*& iterator,
+ const char* breakRules, const UChar* string, int length)
+{
+ if (!string)
+ return 0;
+
+ if (!createdIterator) {
+ UParseError parseStatus;
+ UErrorCode openStatus = U_ZERO_ERROR;
+ String rules(breakRules);
+ iterator = static_cast<TextBreakIterator*>(ubrk_openRules(rules.characters(), rules.length(), 0, 0, &parseStatus, &openStatus));
+ createdIterator = true;
+ ASSERT_WITH_MESSAGE(U_SUCCESS(openStatus), "ICU could not open a break iterator: %s (%d)", u_errorName(openStatus), openStatus);
+ }
+ if (!iterator)
+ return 0;
+
+ UErrorCode setTextStatus = U_ZERO_ERROR;
+ ubrk_setText(iterator, string, length, &setTextStatus);
+ if (U_FAILURE(setTextStatus))
+ return 0;
+
+ return iterator;
+}
+#endif // BUILDING_ON_TIGER
+
+TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
+{
+#ifdef BUILDING_ON_TIGER
+ // ICU 3.2 cannot compile the below rules.
+ return characterBreakIterator(string, length);
+#else
+ // This rule set is based on character-break iterator rules of ICU 4.0
+ // <http://source.icu-project.org/repos/icu/icu/tags/release-4-0/source/data/brkitr/char.txt>.
+ // The major differences from the original ones are listed below:
+ // * Replaced '[\p{Grapheme_Cluster_Break = SpacingMark}]' with '[\p{General_Category = Spacing Mark} - $Extend]' for ICU 3.8 or earlier;
+ // * Removed rules that prevent a cursor from moving after prepend characters (Bug 24342);
+ // * Added rules that prevent a cursor from moving after virama signs of Indic languages except Tamil (Bug 15790), and;
+ // * Added rules that prevent a cursor from moving before Japanese half-width katakara voiced marks.
+ static const char* kRules =
+ "$CR = [\\p{Grapheme_Cluster_Break = CR}];"
+ "$LF = [\\p{Grapheme_Cluster_Break = LF}];"
+ "$Control = [\\p{Grapheme_Cluster_Break = Control}];"
+ "$VoiceMarks = [\\uFF9E\\uFF9F];" // Japanese half-width katakana voiced marks
+ "$Extend = [\\p{Grapheme_Cluster_Break = Extend} $VoiceMarks];"
+ "$SpacingMark = [[\\p{General_Category = Spacing Mark}] - $Extend];"
+ "$L = [\\p{Grapheme_Cluster_Break = L}];"
+ "$V = [\\p{Grapheme_Cluster_Break = V}];"
+ "$T = [\\p{Grapheme_Cluster_Break = T}];"
+ "$LV = [\\p{Grapheme_Cluster_Break = LV}];"
+ "$LVT = [\\p{Grapheme_Cluster_Break = LVT}];"
+ "$Hin0 = [\\u0905-\\u0939];" // Devanagari Letter A,...,Ha
+ "$HinV = \\u094D;" // Devanagari Sign Virama
+ "$Hin1 = [\\u0915-\\u0939];" // Devanagari Letter Ka,...,Ha
+ "$Ben0 = [\\u0985-\\u09B9];" // Bengali Letter A,...,Ha
+ "$BenV = \\u09CD;" // Bengali Sign Virama
+ "$Ben1 = [\\u0995-\\u09B9];" // Bengali Letter Ka,...,Ha
+ "$Pan0 = [\\u0A05-\\u0A39];" // Gurmukhi Letter A,...,Ha
+ "$PanV = \\u0A4D;" // Gurmukhi Sign Virama
+ "$Pan1 = [\\u0A15-\\u0A39];" // Gurmukhi Letter Ka,...,Ha
+ "$Guj0 = [\\u0A85-\\u0AB9];" // Gujarati Letter A,...,Ha
+ "$GujV = \\u0ACD;" // Gujarati Sign Virama
+ "$Guj1 = [\\u0A95-\\u0AB9];" // Gujarati Letter Ka,...,Ha
+ "$Ori0 = [\\u0B05-\\u0B39];" // Oriya Letter A,...,Ha
+ "$OriV = \\u0B4D;" // Oriya Sign Virama
+ "$Ori1 = [\\u0B15-\\u0B39];" // Oriya Letter Ka,...,Ha
+ "$Tel0 = [\\u0C05-\\u0C39];" // Telugu Letter A,...,Ha
+ "$TelV = \\u0C4D;" // Telugu Sign Virama
+ "$Tel1 = [\\u0C14-\\u0C39];" // Telugu Letter Ka,...,Ha
+ "$Kan0 = [\\u0C85-\\u0CB9];" // Kannada Letter A,...,Ha
+ "$KanV = \\u0CCD;" // Kannada Sign Virama
+ "$Kan1 = [\\u0C95-\\u0CB9];" // Kannada Letter A,...,Ha
+ "$Mal0 = [\\u0D05-\\u0D39];" // Malayalam Letter A,...,Ha
+ "$MalV = \\u0D4D;" // Malayalam Sign Virama
+ "$Mal1 = [\\u0D15-\\u0D39];" // Malayalam Letter A,...,Ha
+ "!!chain;"
+ "!!forward;"
+ "$CR $LF;"
+ "$L ($L | $V | $LV | $LVT);"
+ "($LV | $V) ($V | $T);"
+ "($LVT | $T) $T;"
+ "[^$Control $CR $LF] $Extend;"
+ "[^$Control $CR $LF] $SpacingMark;"
+ "$Hin0 $HinV $Hin1;" // Devanagari Virama (forward)
+ "$Ben0 $BenV $Ben1;" // Bengali Virama (forward)
+ "$Pan0 $PanV $Pan1;" // Gurmukhi Virama (forward)
+ "$Guj0 $GujV $Guj1;" // Gujarati Virama (forward)
+ "$Ori0 $OriV $Ori1;" // Oriya Virama (forward)
+ "$Tel0 $TelV $Tel1;" // Telugu Virama (forward)
+ "$Kan0 $KanV $Kan1;" // Kannada Virama (forward)
+ "$Mal0 $MalV $Mal1;" // Malayalam Virama (forward)
+ "!!reverse;"
+ "$LF $CR;"
+ "($L | $V | $LV | $LVT) $L;"
+ "($V | $T) ($LV | $V);"
+ "$T ($LVT | $T);"
+ "$Extend [^$Control $CR $LF];"
+ "$SpacingMark [^$Control $CR $LF];"
+ "$Hin1 $HinV $Hin0;" // Devanagari Virama (backward)
+ "$Ben1 $BenV $Ben0;" // Bengali Virama (backward)
+ "$Pan1 $PanV $Pan0;" // Gurmukhi Virama (backward)
+ "$Guj1 $GujV $Guj0;" // Gujarati Virama (backward)
+ "$Ori1 $OriV $Ori0;" // Gujarati Virama (backward)
+ "$Tel1 $TelV $Tel0;" // Telugu Virama (backward)
+ "$Kan1 $KanV $Kan0;" // Kannada Virama (backward)
+ "$Mal1 $MalV $Mal0;" // Malayalam Virama (backward)
+ "!!safe_reverse;"
+ "!!safe_forward;";
+ static bool createdCursorMovementIterator = false;
+ static TextBreakIterator* staticCursorMovementIterator;
+ return setUpIteratorWithRules(createdCursorMovementIterator, staticCursorMovementIterator, kRules, string, length);
+#endif // BUILDING_ON_TIGER
+}
+
}
diff --git a/WebCore/platform/text/TextCodecICU.cpp b/WebCore/platform/text/TextCodecICU.cpp
index 72d45ad..72054fa 100644
--- a/WebCore/platform/text/TextCodecICU.cpp
+++ b/WebCore/platform/text/TextCodecICU.cpp
@@ -334,7 +334,7 @@ String TextCodecICU::decode(const char* bytes, size_t length, bool flush, bool s
// <http://bugs.webkit.org/show_bug.cgi?id=17014>
// Simplified Chinese pages use the code A3A0 to mean "full-width space", but ICU decodes it as U+E5E5.
- if (m_encoding == "GBK" || m_encoding == "gb18030")
+ if (strcmp(m_encoding.name(), "GBK") == 0 || strcasecmp(m_encoding.name(), "gb18030") == 0)
resultString.replace(0xE5E5, ideographicSpace);
return resultString;
diff --git a/WebCore/platform/text/TextDecoder.cpp b/WebCore/platform/text/TextDecoder.cpp
deleted file mode 100644
index e39a6b7..0000000
--- a/WebCore/platform/text/TextDecoder.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "TextDecoder.h"
-
-#include "TextEncodingRegistry.h"
-
-// FIXME: Would be nice to also handle BOM for UTF-7 and UTF-32.
-
-namespace WebCore {
-
-TextDecoder::TextDecoder(const TextEncoding& encoding)
- : m_encoding(encoding)
- , m_checkedForBOM(false)
- , m_numBufferedBytes(0)
-{
-}
-
-void TextDecoder::reset(const TextEncoding& encoding)
-{
- m_encoding = encoding;
- m_codec.clear();
- m_checkedForBOM = false;
- m_numBufferedBytes = 0;
-}
-
-String TextDecoder::checkForBOM(const char* data, size_t length, bool flush, bool stopOnError, bool& sawError)
-{
- ASSERT(!m_checkedForBOM);
-
- // Check to see if we found a BOM.
- size_t numBufferedBytes = m_numBufferedBytes;
- size_t buf1Len = numBufferedBytes;
- size_t buf2Len = length;
- const unsigned char* buf1 = m_bufferedBytes;
- const unsigned char* buf2 = reinterpret_cast<const unsigned char*>(data);
- unsigned char c1 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
- unsigned char c2 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
- unsigned char c3 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
- unsigned char c4 = buf2Len ? (--buf2Len, *buf2++) : 0;
-
- const TextEncoding* encodingConsideringBOM = &m_encoding;
- bool foundBOM = true;
- size_t lengthOfBOM = 0;
- if (c1 == 0xFF && c2 == 0xFE) {
- if (c3 != 0 || c4 != 0) {
- encodingConsideringBOM = &UTF16LittleEndianEncoding();
- lengthOfBOM = 2;
- } else if (numBufferedBytes + length > sizeof(m_bufferedBytes)) {
- encodingConsideringBOM = &UTF32LittleEndianEncoding();
- lengthOfBOM = 4;
- } else
- foundBOM = false;
- } else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) {
- encodingConsideringBOM = &UTF8Encoding();
- lengthOfBOM = 3;
- } else if (c1 == 0xFE && c2 == 0xFF) {
- encodingConsideringBOM = &UTF16BigEndianEncoding();
- lengthOfBOM = 2;
- } else if (c1 == 0 && c2 == 0 && c3 == 0xFE && c4 == 0xFF) {
- encodingConsideringBOM = &UTF32BigEndianEncoding();
- lengthOfBOM = 4;
- } else
- foundBOM = false;
-
- if (!foundBOM && numBufferedBytes + length <= sizeof(m_bufferedBytes) && !flush) {
- // Continue to look for the BOM.
- memcpy(&m_bufferedBytes[numBufferedBytes], data, length);
- m_numBufferedBytes += length;
- return "";
- }
-
- // Done checking for BOM.
- m_codec.set(newTextCodec(*encodingConsideringBOM).release());
- if (!m_codec)
- return String();
- m_checkedForBOM = true;
-
- // Skip the BOM.
- if (foundBOM) {
- ASSERT(numBufferedBytes < lengthOfBOM);
- size_t numUnbufferedBOMBytes = lengthOfBOM - numBufferedBytes;
- ASSERT(numUnbufferedBOMBytes <= length);
-
- data += numUnbufferedBOMBytes;
- length -= numUnbufferedBOMBytes;
- numBufferedBytes = 0;
- m_numBufferedBytes = 0;
- }
-
- // Handle case where we have some buffered bytes to deal with.
- if (numBufferedBytes) {
- char bufferedBytes[sizeof(m_bufferedBytes)];
- memcpy(bufferedBytes, m_bufferedBytes, numBufferedBytes);
- m_numBufferedBytes = 0;
-
- String bufferedResult = m_codec->decode(bufferedBytes, numBufferedBytes, false, stopOnError, sawError);
- if (stopOnError && sawError)
- return bufferedResult;
- return bufferedResult + m_codec->decode(data, length, flush, stopOnError, sawError);
- }
-
- return m_codec->decode(data, length, flush, stopOnError, sawError);
-}
-
-} // namespace WebCore
diff --git a/WebCore/platform/text/TextDecoder.h b/WebCore/platform/text/TextDecoder.h
deleted file mode 100644
index 171cb59..0000000
--- a/WebCore/platform/text/TextDecoder.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TextDecoder_h
-#define TextDecoder_h
-
-#include "PlatformString.h"
-#include "TextCodec.h"
-#include "TextEncoding.h"
-#include <wtf/OwnPtr.h>
-
-namespace WebCore {
-
- class TextCodec;
-
- class TextDecoder {
- public:
- TextDecoder(const TextEncoding&);
- void reset(const TextEncoding&);
- const TextEncoding& encoding() const { return m_encoding; };
-
- String decode(const char* data, size_t length, bool flush, bool stopOnError, bool& sawError)
- {
- if (!m_checkedForBOM)
- return checkForBOM(data, length, flush, stopOnError, sawError);
- return m_codec->decode(data, length, flush, stopOnError, sawError);
- }
-
- private:
- String checkForBOM(const char*, size_t length, bool flush, bool stopOnError, bool& sawError);
-
- TextEncoding m_encoding;
- OwnPtr<TextCodec> m_codec;
-
- bool m_checkedForBOM;
- unsigned char m_numBufferedBytes;
- unsigned char m_bufferedBytes[3];
- };
-
-} // namespace WebCore
-
-#endif // TextDecoder_h
diff --git a/WebCore/platform/text/TextEncoding.cpp b/WebCore/platform/text/TextEncoding.cpp
index 063d96b..ed58412 100644
--- a/WebCore/platform/text/TextEncoding.cpp
+++ b/WebCore/platform/text/TextEncoding.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,6 @@
#include "CString.h"
#include "PlatformString.h"
#include "TextCodec.h"
-#include "TextDecoder.h"
#include "TextEncodingRegistry.h"
#if USE(ICU_UNICODE)
#include <unicode/unorm.h>
@@ -73,7 +72,7 @@ String TextEncoding::decode(const char* data, size_t length, bool stopOnError, b
if (!m_name)
return String();
- return TextDecoder(*this).decode(data, length, true, stopOnError, sawError);
+ return newTextCodec(*this)->decode(data, length, true, stopOnError, sawError);
}
CString TextEncoding::encode(const UChar* characters, size_t length, UnencodableHandling handling) const
@@ -165,10 +164,23 @@ UChar TextEncoding::backslashAsCurrencySymbol() const
bool TextEncoding::isNonByteBasedEncoding() const
{
+ if (noExtendedTextEncodingNameUsed()) {
+ return *this == UTF16LittleEndianEncoding()
+ || *this == UTF16BigEndianEncoding();
+ }
+
return *this == UTF16LittleEndianEncoding()
- || *this == UTF16BigEndianEncoding()
- || *this == UTF32BigEndianEncoding()
- || *this == UTF32LittleEndianEncoding();
+ || *this == UTF16BigEndianEncoding()
+ || *this == UTF32BigEndianEncoding()
+ || *this == UTF32LittleEndianEncoding();
+}
+
+bool TextEncoding::isUTF7Encoding() const
+{
+ if (noExtendedTextEncodingNameUsed())
+ return false;
+
+ return *this == UTF7Encoding();
}
const TextEncoding& TextEncoding::closestByteBasedEquivalent() const
@@ -185,7 +197,7 @@ const TextEncoding& TextEncoding::closestByteBasedEquivalent() const
// but it's fraught with problems and we'd rather steer clear of it.
const TextEncoding& TextEncoding::encodingForFormSubmission() const
{
- if (isNonByteBasedEncoding() || *this == UTF7Encoding())
+ if (isNonByteBasedEncoding() || isUTF7Encoding())
return UTF8Encoding();
return *this;
}
diff --git a/WebCore/platform/text/TextEncoding.h b/WebCore/platform/text/TextEncoding.h
index b2bb816..b3909f7 100644
--- a/WebCore/platform/text/TextEncoding.h
+++ b/WebCore/platform/text/TextEncoding.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,12 +45,14 @@ namespace WebCore {
bool usesVisualOrdering() const;
bool isJapanese() const;
- PassRefPtr<StringImpl> displayString(PassRefPtr<StringImpl> str) const {
+ PassRefPtr<StringImpl> displayString(PassRefPtr<StringImpl> str) const
+ {
if (m_backslashAsCurrencySymbol == '\\' || !str)
return str;
return str->replace('\\', m_backslashAsCurrencySymbol);
}
- void displayBuffer(UChar* characters, unsigned len) const {
+ void displayBuffer(UChar* characters, unsigned len) const
+ {
if (m_backslashAsCurrencySymbol == '\\')
return;
for (unsigned i = 0; i < len; ++i) {
@@ -72,10 +74,11 @@ namespace WebCore {
private:
UChar backslashAsCurrencySymbol() const;
+ bool isNonByteBasedEncoding() const;
+ bool isUTF7Encoding() const;
const char* m_name;
UChar m_backslashAsCurrencySymbol;
- bool isNonByteBasedEncoding() const;
};
inline bool operator==(const TextEncoding& a, const TextEncoding& b) { return a.name() == b.name(); }
diff --git a/WebCore/platform/text/TextEncodingDetector.h b/WebCore/platform/text/TextEncodingDetector.h
new file mode 100644
index 0000000..9f16ab0
--- /dev/null
+++ b/WebCore/platform/text/TextEncodingDetector.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextEncodingDetector_h
+#define TextEncodingDetector_h
+
+namespace WebCore {
+
+ class TextEncoding;
+
+ // Given a sequence of bytes in |data| of length |len| and an optional
+ // hintEncodingName, detect the most likely character encoding.
+ // The way hintEncodingName is used is up to an implementation.
+ // Currently, the only caller sets it to the parent frame encoding.
+ bool detectTextEncoding(const char* data, size_t len,
+ const char* hintEncodingName,
+ TextEncoding* detectedEncoding);
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/text/TextEncodingDetectorICU.cpp b/WebCore/platform/text/TextEncodingDetectorICU.cpp
new file mode 100644
index 0000000..26c997e
--- /dev/null
+++ b/WebCore/platform/text/TextEncodingDetectorICU.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextEncodingDetector.h"
+
+#include "TextEncoding.h"
+#include "UnusedParam.h"
+
+#ifndef BUILDING_ON_TIGER
+#include "unicode/ucnv.h"
+#include "unicode/ucsdet.h"
+#endif
+
+namespace WebCore {
+
+bool detectTextEncoding(const char* data, size_t len,
+ const char* hintEncodingName,
+ TextEncoding* detectedEncoding)
+{
+ *detectedEncoding = TextEncoding();
+#ifdef BUILDING_ON_TIGER
+ // Tiger came with ICU 3.2 and does not have the encoding detector.
+ UNUSED_PARAM(data);
+ UNUSED_PARAM(len);
+ UNUSED_PARAM(hintEncodingName);
+ return false;
+#else
+ int matchesCount = 0;
+ UErrorCode status = U_ZERO_ERROR;
+ UCharsetDetector* detector = ucsdet_open(&status);
+ if (U_FAILURE(status))
+ return false;
+ ucsdet_enableInputFilter(detector, true);
+ ucsdet_setText(detector, data, static_cast<int32_t>(len), &status);
+ if (U_FAILURE(status))
+ return false;
+
+ // FIXME: A few things we can do other than improving
+ // the ICU detector itself.
+ // 1. Use ucsdet_detectAll and pick the most likely one given
+ // "the context" (parent-encoding, referrer encoding, etc).
+ // 2. 'Emulate' Firefox/IE's non-Universal detectors (e.g.
+ // Chinese, Japanese, Russian, Korean and Hebrew) by picking the
+ // encoding with a highest confidence among the detetctor-specific
+ // limited set of candidate encodings.
+ // Below is a partial implementation of the first part of what's outlined
+ // above.
+ const UCharsetMatch** matches = ucsdet_detectAll(detector, &matchesCount, &status);
+ if (U_FAILURE(status)) {
+ ucsdet_close(detector);
+ return false;
+ }
+
+ const char* encoding = 0;
+ if (hintEncodingName) {
+ TextEncoding hintEncoding(hintEncodingName);
+ // 10 is the minimum confidence value consistent with the codepoint
+ // allocation in a given encoding. The size of a chunk passed to
+ // us varies even for the same html file (apparently depending on
+ // the network load). When we're given a rather short chunk, we
+ // don't have a sufficiently reliable signal other than the fact that
+ // the chunk is consistent with a set of encodings. So, instead of
+ // setting an arbitrary threshold, we have to scan all the encodings
+ // consistent with the data.
+ const int32_t kThresold = 10;
+ for (int i = 0; i < matchesCount; ++i) {
+ int32_t confidence = ucsdet_getConfidence(matches[i], &status);
+ if (U_FAILURE(status)) {
+ status = U_ZERO_ERROR;
+ continue;
+ }
+ if (confidence < kThresold)
+ break;
+ const char* matchEncoding = ucsdet_getName(matches[i], &status);
+ if (U_FAILURE(status)) {
+ status = U_ZERO_ERROR;
+ continue;
+ }
+ if (TextEncoding(matchEncoding) == hintEncoding) {
+ encoding = hintEncodingName;
+ break;
+ }
+ }
+ }
+ // If no match is found so far, just pick the top match.
+ // This can happen, say, when a parent frame in EUC-JP refers to
+ // a child frame in Shift_JIS and both frames do NOT specify the encoding
+ // making us resort to auto-detection (when it IS turned on).
+ if (!encoding && matchesCount > 0)
+ encoding = ucsdet_getName(matches[0], &status);
+ if (U_SUCCESS(status)) {
+ *detectedEncoding = TextEncoding(encoding);
+ ucsdet_close(detector);
+ return true;
+ }
+ ucsdet_close(detector);
+ return false;
+#endif
+}
+
+}
diff --git a/WebCore/platform/text/TextEncodingDetectorNone.cpp b/WebCore/platform/text/TextEncodingDetectorNone.cpp
new file mode 100644
index 0000000..2655f08
--- /dev/null
+++ b/WebCore/platform/text/TextEncodingDetectorNone.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TextEncodingDetector.h"
+
+#include "TextEncoding.h"
+#include "UnusedParam.h"
+
+namespace WebCore {
+
+bool detectTextEncoding(const char* data, size_t len,
+ const char* hintEncodingName,
+ TextEncoding* detectedEncoding)
+{
+ UNUSED_PARAM(data)
+ UNUSED_PARAM(len)
+ UNUSED_PARAM(hintEncodingName)
+
+ *detectedEncoding = TextEncoding();
+ return false;
+}
+
+}
diff --git a/WebCore/platform/text/TextEncodingRegistry.h b/WebCore/platform/text/TextEncodingRegistry.h
index 5ca2039..d204734 100644
--- a/WebCore/platform/text/TextEncodingRegistry.h
+++ b/WebCore/platform/text/TextEncodingRegistry.h
@@ -34,11 +34,8 @@ namespace WebCore {
class TextCodec;
class TextEncoding;
- // Only TextEncoding and TextDecoder should use this function directly.
- // - Use TextDecoder::decode to decode, since it handles BOMs.
- // - Use TextEncoding::decode to decode if you have all the data at once.
- // It's implemented by calling TextDecoder::decode so works just as well.
- // - Use TextEncoding::encode to encode, since it takes care of normalization.
+ // Use TextResourceDecoder::decode to decode resources, since it handles BOMs.
+ // Use TextEncoding::encode to encode, since it takes care of normalization.
std::auto_ptr<TextCodec> newTextCodec(const TextEncoding&);
// Only TextEncoding should use this function directly.
diff --git a/WebCore/platform/text/cf/StringImplCF.cpp b/WebCore/platform/text/cf/StringImplCF.cpp
index ff595a5..8a2ae79 100644
--- a/WebCore/platform/text/cf/StringImplCF.cpp
+++ b/WebCore/platform/text/cf/StringImplCF.cpp
@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2006 Apple Computer, Inc.
+/*
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,14 +24,139 @@
#if PLATFORM(CF) || (PLATFORM(QT) && PLATFORM(DARWIN))
#include <CoreFoundation/CoreFoundation.h>
+#include <wtf/MainThread.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER)
+#include <objc/objc-auto.h>
+#endif
namespace WebCore {
+namespace StringWrapperCFAllocator {
+
+ static StringImpl* currentString;
+
+ static const void* retain(const void* info)
+ {
+ return info;
+ }
+
+ static void release(const void*)
+ {
+ ASSERT_NOT_REACHED();
+ }
+
+ static CFStringRef copyDescription(const void*)
+ {
+ return CFSTR("WebCore::String-based allocator");
+ }
+
+ static void* allocate(CFIndex size, CFOptionFlags, void*)
+ {
+ StringImpl* underlyingString = 0;
+ if (isMainThread()) {
+ underlyingString = currentString;
+ if (underlyingString) {
+ currentString = 0;
+ underlyingString->ref(); // Balanced by call to deref in deallocate below.
+ }
+ }
+ StringImpl** header = static_cast<StringImpl**>(fastMalloc(sizeof(StringImpl*) + size));
+ *header = underlyingString;
+ return header + 1;
+ }
+
+ static void* reallocate(void* pointer, CFIndex newSize, CFOptionFlags, void*)
+ {
+ size_t newAllocationSize = sizeof(StringImpl*) + newSize;
+ StringImpl** header = static_cast<StringImpl**>(pointer) - 1;
+ ASSERT(!*header);
+ header = static_cast<StringImpl**>(fastRealloc(header, newAllocationSize));
+ return header + 1;
+ }
+
+ static void deallocateOnMainThread(void* headerPointer)
+ {
+ StringImpl** header = static_cast<StringImpl**>(headerPointer);
+ StringImpl* underlyingString = *header;
+ ASSERT(underlyingString);
+ underlyingString->deref(); // Balanced by call to ref in allocate above.
+ fastFree(header);
+ }
+
+ static void deallocate(void* pointer, void*)
+ {
+ StringImpl** header = static_cast<StringImpl**>(pointer) - 1;
+ StringImpl* underlyingString = *header;
+ if (!underlyingString)
+ fastFree(header);
+ else {
+ if (!isMainThread())
+ callOnMainThread(deallocateOnMainThread, header);
+ else {
+ underlyingString->deref(); // Balanced by call to ref in allocate above.
+ fastFree(header);
+ }
+ }
+ }
+
+ static CFIndex preferredSize(CFIndex size, CFOptionFlags, void*)
+ {
+ // FIXME: If FastMalloc provided a "good size" callback, we'd want to use it here.
+ // Note that this optimization would help performance for strings created with the
+ // allocator that are mutable, and those typically are only created by callers who
+ // make a new string using the old string's allocator, such as some of the call
+ // sites in CFURL.
+ return size;
+ }
+
+ static CFAllocatorRef create()
+ {
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER)
+ // Since garbage collection isn't compatible with custom allocators, don't use this at all when garbage collection is active.
+ if (objc_collectingEnabled())
+ return 0;
+#endif
+ CFAllocatorContext context = { 0, 0, retain, release, copyDescription, allocate, reallocate, deallocate, preferredSize };
+ return CFAllocatorCreate(0, &context);
+ }
+
+ static CFAllocatorRef allocator()
+ {
+ static CFAllocatorRef allocator = create();
+ return allocator;
+ }
+
+}
+
CFStringRef StringImpl::createCFString()
{
- return CFStringCreateWithCharacters(NULL, reinterpret_cast<const UniChar*>(m_data), m_length);
+ CFAllocatorRef allocator = (m_length && isMainThread()) ? StringWrapperCFAllocator::allocator() : 0;
+ if (!allocator)
+ return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(m_data), m_length);
+
+ // Put pointer to the StringImpl in a global so the allocator can store it with the CFString.
+ ASSERT(!StringWrapperCFAllocator::currentString);
+ StringWrapperCFAllocator::currentString = this;
+
+ CFStringRef string = CFStringCreateWithCharactersNoCopy(allocator, reinterpret_cast<const UniChar*>(m_data), m_length, kCFAllocatorNull);
+
+ // The allocator cleared the global when it read it, but also clear it here just in case.
+ ASSERT(!StringWrapperCFAllocator::currentString);
+ StringWrapperCFAllocator::currentString = 0;
+
+ return string;
}
+// On StringImpl creation we could check if the allocator is the StringWrapperCFAllocator.
+// If it is, then we could find the original StringImpl and just return that. But to
+// do that we'd have to compute the offset from CFStringRef to the allocated block;
+// the CFStringRef is *not* at the start of an allocated block. Testing shows 1000x
+// more calls to createCFString than calls to the create functions with the appropriate
+// allocator, so it's probably not urgent optimize that case.
+
}
#endif // PLATFORM(CF) || (PLATFORM(QT) && PLATFORM(DARWIN))
diff --git a/WebCore/platform/text/mac/ShapeArabic.c b/WebCore/platform/text/mac/ShapeArabic.c
index 1e0d91b..dd61ce5 100644
--- a/WebCore/platform/text/mac/ShapeArabic.c
+++ b/WebCore/platform/text/mac/ShapeArabic.c
@@ -36,6 +36,8 @@
#include "ShapeArabic.h"
+#include <stdbool.h>
+#include <string.h>
#include <unicode/utypes.h>
#include <unicode/uchar.h>
#include <unicode/ustring.h>
diff --git a/WebCore/platform/text/mac/StringImplMac.mm b/WebCore/platform/text/mac/StringImplMac.mm
index 3e0731c..d14c6d8 100644
--- a/WebCore/platform/text/mac/StringImplMac.mm
+++ b/WebCore/platform/text/mac/StringImplMac.mm
@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2006 Apple Computer, Inc.
+/*
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,13 +21,13 @@
#include "config.h"
#include "StringImpl.h"
-#include <Foundation/Foundation.h>
+#include "FoundationExtras.h"
namespace WebCore {
StringImpl::operator NSString *()
{
- return [NSString stringWithCharacters:m_data length:m_length];
+ return HardAutorelease(createCFString());
}
}
diff --git a/WebCore/platform/text/mac/StringMac.mm b/WebCore/platform/text/mac/StringMac.mm
index 77942ea..758ae1d 100644
--- a/WebCore/platform/text/mac/StringMac.mm
+++ b/WebCore/platform/text/mac/StringMac.mm
@@ -20,6 +20,7 @@
#include "config.h"
#include "PlatformString.h"
+#include <CoreFoundation/CFString.h>
namespace WebCore {
diff --git a/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
index 88b9680..4dc23ee 100644
--- a/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
+++ b/WebCore/platform/text/qt/TextBreakIteratorQt.cpp
@@ -63,6 +63,11 @@ namespace WebCore {
return static_cast<TextBreakIterator*>(iterator);
}
+ TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
+ {
+ return characterBreakIterator(string, length);
+ }
+
TextBreakIterator* lineBreakIterator(const UChar* string, int length)
{
static QTextBoundaryFinder *iterator = 0;
@@ -250,6 +255,11 @@ TextBreakIterator* characterBreakIterator(const UChar* string, int length)
return iterator;
}
+TextBreakIterator* cursorMovementIterator(const UChar* string, int length)
+{
+ return characterBreakIterator(string, length);
+}
+
TextBreakIterator* lineBreakIterator(const UChar*, int)
{
// not yet implemented
diff --git a/WebCore/platform/win/FileSystemWin.cpp b/WebCore/platform/win/FileSystemWin.cpp
index 5671462..746fceb 100644
--- a/WebCore/platform/win/FileSystemWin.cpp
+++ b/WebCore/platform/win/FileSystemWin.cpp
@@ -191,11 +191,11 @@ CString openTemporaryFile(const char*, PlatformFileHandle& handle)
char tempPath[MAX_PATH];
int tempPathLength = ::GetTempPathA(_countof(tempPath), tempPath);
if (tempPathLength <= 0 || tempPathLength > _countof(tempPath))
- return 0;
+ return CString();
HCRYPTPROV hCryptProv = 0;
if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
- return 0;
+ return CString();
char proposedPath[MAX_PATH];
while (1) {
@@ -226,7 +226,7 @@ CString openTemporaryFile(const char*, PlatformFileHandle& handle)
CryptReleaseContext(hCryptProv, 0);
if (!isHandleValid(handle))
- return 0;
+ return CString();
return proposedPath;
}
diff --git a/WebCore/platform/win/PopupMenuWin.cpp b/WebCore/platform/win/PopupMenuWin.cpp
index 59ea563..52f2eb9 100644
--- a/WebCore/platform/win/PopupMenuWin.cpp
+++ b/WebCore/platform/win/PopupMenuWin.cpp
@@ -527,6 +527,8 @@ void PopupMenu::paint(const IntRect& damageRect, HDC hdc)
// Draw the item text
if (itemStyle.isVisible()) {
int textX = max(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
+ if (theme()->popupOptionSupportsTextIndent() && itemStyle.textDirection() == LTR)
+ textX += itemStyle.textIndent().calcMinValue(itemRect.width());
int textY = itemRect.y() + itemFont.ascent() + (itemRect.height() - itemFont.height()) / 2;
context.drawBidiText(itemFont, textRun, IntPoint(textX, textY));
}
@@ -683,6 +685,9 @@ static LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT message, WPARAM wParam, LPA
::SendMessage(popup->client()->hostWindow()->platformWindow(), message, wParam, lParam);
popup->client()->hidePopup();
break;
+ case VK_ESCAPE:
+ popup->client()->hidePopup();
+ break;
default:
if (isASCIIPrintable(wParam))
// Send the keydown to the WebView so it can be used for type-to-select.
diff --git a/WebCore/platform/win/WheelEventWin.cpp b/WebCore/platform/win/WheelEventWin.cpp
index d272ba7..e6670a4 100644
--- a/WebCore/platform/win/WheelEventWin.cpp
+++ b/WebCore/platform/win/WheelEventWin.cpp
@@ -46,23 +46,23 @@ static IntPoint globalPositionForEvent(HWND hWnd, LPARAM lParam)
return point;
}
-int PlatformWheelEvent::horizontalLineMultiplier() const
+static int horizontalScrollChars()
{
static ULONG scrollChars;
if (!scrollChars && !SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0))
- scrollChars = cLineMultiplier;
+ scrollChars = 1;
return scrollChars;
}
-int PlatformWheelEvent::verticalLineMultiplier() const
+static int verticalScrollLines()
{
static ULONG scrollLines;
if (!scrollLines && !SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0))
- scrollLines = cLineMultiplier;
+ scrollLines = 3;
return scrollLines;
}
-
-PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, WPARAM wParam, LPARAM lParam, bool isHorizontal)
+
+PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, WPARAM wParam, LPARAM lParam, bool isMouseHWheel)
: m_position(positionForEvent(hWnd, lParam))
, m_globalPosition(globalPositionForEvent(hWnd, lParam))
, m_isAccepted(false)
@@ -71,23 +71,40 @@ PlatformWheelEvent::PlatformWheelEvent(HWND hWnd, WPARAM wParam, LPARAM lParam,
, m_altKey(GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT)
, m_metaKey(m_altKey) // FIXME: We'll have to test other browsers
{
- static ULONG scrollLines, scrollChars;
- float delta = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
- if (isHorizontal) {
- // Windows sends a positive delta for scrolling right, while AppKit
- // sends a negative delta. EventHandler expects the AppKit values,
- // so we have to negate our horizontal delta to match.
- m_deltaX = -delta * horizontalLineMultiplier();
+ // How many pixels should we scroll per line? Gecko uses the height of the
+ // current line, which means scroll distance changes as you go through the
+ // page or go to different pages. IE 7 is ~50 px/line, although the value
+ // seems to vary slightly by page and zoom level. Since IE 7 has a
+ // smoothing algorithm on scrolling, it can get away with slightly larger
+ // scroll values without feeling jerky. Here we use 100 px per three lines
+ // (the default scroll amount on Windows is three lines per wheel tick).
+ static const float cScrollbarPixelsPerLine = 100.0f / 3.0f;
+ float delta = GET_WHEEL_DELTA_WPARAM(wParam) / static_cast<float>(WHEEL_DELTA);
+ if (isMouseHWheel) {
+ // Windows is <-- -/+ -->, WebKit wants <-- +/- -->, so we negate
+ // |delta| after saving the original value on the wheel tick member.
+ m_wheelTicksX = delta;
+ m_wheelTicksY = 0;
+ delta = -delta;
+ } else {
+ // Even though we use shift + vertical wheel to scroll horizontally in
+ // WebKit, we still note it as a vertical scroll on the wheel tick
+ // member, so that the DOM event we later construct will match the real
+ // hardware event better.
+ m_wheelTicksX = 0;
+ m_wheelTicksY = delta;
+ }
+ if (isMouseHWheel || m_shiftKey) {
+ m_deltaX = delta * static_cast<float>(horizontalScrollChars()) * cScrollbarPixelsPerLine;
m_deltaY = 0;
- m_granularity = ScrollByLineWheelEvent;
+ m_granularity = ScrollByPixelWheelEvent;
} else {
m_deltaX = 0;
m_deltaY = delta;
- int verticalMultiplier = verticalLineMultiplier();
- // A multiplier of -1 is used to mean that vertical wheel scrolling should be done by page.
- m_granularity = (verticalMultiplier == -1) ? ScrollByPageWheelEvent : ScrollByLineWheelEvent;
- if (m_granularity == ScrollByLineWheelEvent)
- m_deltaY *= verticalMultiplier;
+ int verticalMultiplier = verticalScrollLines();
+ m_granularity = (verticalMultiplier == WHEEL_PAGESCROLL) ? ScrollByPageWheelEvent : ScrollByPixelWheelEvent;
+ if (m_granularity == ScrollByPixelWheelEvent)
+ m_deltaY *= static_cast<float>(verticalMultiplier) * cScrollbarPixelsPerLine;
}
}
diff --git a/WebCore/platform/wx/MouseWheelEventWx.cpp b/WebCore/platform/wx/MouseWheelEventWx.cpp
index 154a710..9f3923d 100644
--- a/WebCore/platform/wx/MouseWheelEventWx.cpp
+++ b/WebCore/platform/wx/MouseWheelEventWx.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "PlatformWheelEvent.h"
+#include "Scrollbar.h"
#include <wx/defs.h>
#include <wx/event.h>
@@ -34,17 +35,19 @@ namespace WebCore {
PlatformWheelEvent::PlatformWheelEvent(const wxMouseEvent& event, const wxPoint& globalPoint)
: m_position(event.GetPosition())
, m_globalPosition(globalPoint)
- , m_granularity(ScrollByLineWheelEvent)
+ , m_granularity(ScrollByPixelWheelEvent)
, m_shiftKey(event.ShiftDown())
, m_ctrlKey(event.ControlDown())
, m_altKey(event.AltDown())
, m_metaKey(event.MetaDown()) // FIXME: We'll have to test other browsers
, m_deltaX(0) // wx doesn't support horizontal mouse wheel scrolling
, m_deltaY(event.GetWheelRotation() / event.GetWheelDelta())
+ , m_wheelTicksX(m_deltaX)
+ , m_wheelTicksY(m_deltaY)
, m_isAccepted(false)
{
// FIXME: retrieve the user setting for the number of lines to scroll on each wheel event
- m_deltaY *= horizontalLineMultiplier();
+ m_deltaY *= static_cast<float>(cScrollbarPixelsPerLineStep);
}
}
diff --git a/WebCore/platform/wx/wxcode/fontprops.h b/WebCore/platform/wx/wxcode/fontprops.h
index e6f0b16..7f38bcf 100644
--- a/WebCore/platform/wx/wxcode/fontprops.h
+++ b/WebCore/platform/wx/wxcode/fontprops.h
@@ -46,4 +46,5 @@ private:
float m_lineSpacing;
float m_xHeight;
-}; \ No newline at end of file
+};
+
diff --git a/WebCore/platform/wx/wxcode/gtk/fontprops.cpp b/WebCore/platform/wx/wxcode/gtk/fontprops.cpp
index 369fcc5..df14812 100644
--- a/WebCore/platform/wx/wxcode/gtk/fontprops.cpp
+++ b/WebCore/platform/wx/wxcode/gtk/fontprops.cpp
@@ -23,17 +23,42 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
+
#include <wx/defs.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/fontutil.h>
#include "fontprops.h"
+#include "non-kerned-drawing.h"
#include <gdk/gdk.h>
+#include <cairo.h>
+#include <pango/pango.h>
+#include <pango/pangocairo.h>
+
wxFontProperties::wxFontProperties(wxFont* font):
m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
{
+ ASSERT(font && font->Ok());
+
+#if USE(WXGC)
+ cairo_font_extents_t font_extents;
+ cairo_text_extents_t text_extents;
+ cairo_scaled_font_t* scaled_font = WebCore::createScaledFontForFont(font);
+
+ cairo_scaled_font_extents(scaled_font, &font_extents);
+ m_ascent = static_cast<int>(font_extents.ascent);
+ m_descent = static_cast<int>(font_extents.descent);
+ m_lineSpacing = static_cast<int>(font_extents.height);
+ cairo_scaled_font_text_extents(scaled_font, "x", &text_extents);
+ m_xHeight = text_extents.height;
+ cairo_scaled_font_text_extents(scaled_font, " ", &text_extents);
+ m_lineGap = m_lineSpacing - m_ascent - m_descent;
+
+ cairo_scaled_font_destroy(scaled_font);
+#else
PangoContext* context = gdk_pango_context_get_for_screen( gdk_screen_get_default() );
PangoLayout* layout = pango_layout_new(context);
// and use it if it's valid
@@ -64,6 +89,7 @@ m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
m_lineSpacing = m_ascent + m_descent;
pango_font_metrics_unref(metrics);
+#endif
}
void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height,
@@ -80,16 +106,34 @@ void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxC
if (str.empty())
return;
-
+
+// FIXME: Doesn't support height, descent or external leading, though we don't need this for WebKit
+// it will need to be implemented before merging into wx unless we craft a new API.
+#if USE(WXGC)
+ PangoFont* pangoFont = WebCore::createPangoFontForFont(&font);
+ PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(WebCore::pangoFontMap()));
+ PangoGlyph pangoGlyph = WebCore::pango_font_get_glyph(pangoFont, pangoContext, (gunichar)g_utf8_get_char(str.ToUTF8()));
+ cairo_glyph_t cglyph = { pangoGlyph, 0, 0 };
+ cairo_text_extents_t extents;
+ cairo_scaled_font_t* scaled_font = WebCore::createScaledFontForFont(&font);
+ cairo_scaled_font_glyph_extents(scaled_font, &cglyph, 1, &extents);
+
+ if (cairo_scaled_font_status(scaled_font) == CAIRO_STATUS_SUCCESS && extents.x_advance != 0)
+ *width = (wxCoord)extents.x_advance;
+
+ cairo_scaled_font_destroy(scaled_font);
+ g_object_unref(pangoContext);
+ g_object_unref(pangoFont);
+#else
PangoContext* context = gdk_pango_context_get_for_screen( gdk_screen_get_default() );
PangoLayout* m_layout = pango_layout_new(context);
// and use it if it's valid
- if ( font != wxNullFont )
+ if ( font && font->IsOk() )
{
pango_layout_set_font_description
(
m_layout,
- font.GetNativeFontInfo()->description
+ font->GetNativeFontInfo()->description
);
}
@@ -103,24 +147,19 @@ void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxC
pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) );
+ int h = 0;
+ pango_layout_get_pixel_size( m_layout, width, &h );
+
if (descent)
{
- int h;
- pango_layout_get_pixel_size( m_layout, width, &h );
PangoLayoutIter *iter = pango_layout_get_iter(m_layout);
int baseline = pango_layout_iter_get_baseline(iter);
pango_layout_iter_free(iter);
*descent = h - PANGO_PIXELS(baseline);
-
- if (height)
- *height = (wxCoord) h;
- }
- else
- {
- pango_layout_get_pixel_size( m_layout, width, height );
}
- // Reset old font description
- //if (font != wxNullFont)
- // pango_layout_set_font_description( m_layout, m_fontdesc );
-} \ No newline at end of file
+ if (height)
+ *height = (wxCoord) h;
+#endif
+}
+
diff --git a/WebCore/platform/wx/wxcode/gtk/non-kerned-drawing.cpp b/WebCore/platform/wx/wxcode/gtk/non-kerned-drawing.cpp
index ed8fb09..bf745e0 100644
--- a/WebCore/platform/wx/wxcode/gtk/non-kerned-drawing.cpp
+++ b/WebCore/platform/wx/wxcode/gtk/non-kerned-drawing.cpp
@@ -28,25 +28,201 @@
#include "GraphicsContext.h"
#include "SimpleFontData.h"
+#include <wx/dc.h>
#include <wx/dcgraph.h>
#include <wx/defs.h>
#include <wx/dcclient.h>
#include <wx/gdicmn.h>
#include <vector>
+#if USE(WXGC)
+#include <cairo.h>
+#include <assert.h>
+
+#include <pango/pango.h>
+#include <pango/pangocairo.h>
+
+// Use cairo-ft if a recent enough Pango version isn't available
+#if !PANGO_VERSION_CHECK(1,18,0)
+#include <cairo-ft.h>
+#include <pango/pangofc-fontmap.h>
+#endif
+
+#endif
+
+#include <gtk/gtk.h>
+
namespace WebCore {
+#if USE(WXGC)
+static PangoFontMap* g_fontMap;
+
+PangoFontMap* pangoFontMap()
+{
+ if (!g_fontMap)
+ g_fontMap = pango_cairo_font_map_get_default();
+
+ return g_fontMap;
+}
+
+PangoFont* createPangoFontForFont(const wxFont* wxfont)
+{
+ ASSERT(wxfont && wxfont->Ok());
+
+ const char* face = wxfont->GetFaceName().mb_str(wxConvUTF8);
+ char const* families[] = {
+ face,
+ 0
+ };
+
+ switch (wxfont->GetFamily()) {
+ case wxFONTFAMILY_ROMAN:
+ families[1] = "serif";
+ break;
+ case wxFONTFAMILY_SWISS:
+ families[1] = "sans";
+ break;
+ case wxFONTFAMILY_MODERN:
+ families[1] = "monospace";
+ break;
+ default:
+ families[1] = "sans";
+ }
+
+ PangoFontDescription* description = pango_font_description_new();
+ pango_font_description_set_absolute_size(description, wxfont->GetPointSize() * PANGO_SCALE);
+
+ PangoFont* pangoFont = 0;
+ PangoContext* pangoContext = 0;
+
+ switch (wxfont->GetWeight()) {
+ case wxFONTWEIGHT_LIGHT:
+ pango_font_description_set_weight(description, PANGO_WEIGHT_LIGHT);
+ break;
+ case wxFONTWEIGHT_NORMAL:
+ pango_font_description_set_weight(description, PANGO_WEIGHT_NORMAL);
+ break;
+ case wxFONTWEIGHT_BOLD:
+ pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
+ break;
+ }
+
+ switch (wxfont->GetStyle()) {
+ case wxFONTSTYLE_NORMAL:
+ pango_font_description_set_style(description, PANGO_STYLE_NORMAL);
+ break;
+ case wxFONTSTYLE_ITALIC:
+ pango_font_description_set_style(description, PANGO_STYLE_ITALIC);
+ break;
+ case wxFONTSTYLE_SLANT:
+ pango_font_description_set_style(description, PANGO_STYLE_OBLIQUE);
+ break;
+ }
+
+ PangoFontMap* fontMap = pangoFontMap();
+
+ pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(fontMap));
+ for (unsigned i = 0; !pangoFont && i < G_N_ELEMENTS(families); i++) {
+ pango_font_description_set_family(description, families[i]);
+ pango_context_set_font_description(pangoContext, description);
+ pangoFont = pango_font_map_load_font(fontMap, pangoContext, description);
+ }
+ pango_font_description_free(description);
+
+ return pangoFont;
+}
+
+cairo_scaled_font_t* createScaledFontForFont(const wxFont* wxfont)
+{
+ ASSERT(wxfont && wxfont->Ok());
+
+ cairo_scaled_font_t* scaledFont = NULL;
+ PangoFont* pangoFont = createPangoFontForFont(wxfont);
+
+#if PANGO_VERSION_CHECK(1,18,0)
+ if (pangoFont)
+ scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(pangoFont)));
+#endif
+
+ return scaledFont;
+}
+
+PangoGlyph pango_font_get_glyph(PangoFont* font, PangoContext* context, gunichar wc)
+{
+ PangoGlyph result = 0;
+ gchar buffer[7];
+
+ gint length = g_unichar_to_utf8(wc, buffer);
+ g_return_val_if_fail(length, 0);
+
+ GList* items = pango_itemize(context, buffer, 0, length, NULL, NULL);
+
+ if (g_list_length(items) == 1) {
+ PangoItem* item = static_cast<PangoItem*>(items->data);
+ PangoFont* tmpFont = item->analysis.font;
+ item->analysis.font = font;
+
+ PangoGlyphString* glyphs = pango_glyph_string_new();
+ pango_shape(buffer, length, &item->analysis, glyphs);
+
+ item->analysis.font = tmpFont;
+
+ if (glyphs->num_glyphs == 1)
+ result = glyphs->glyphs[0].glyph;
+ else
+ g_warning("didn't get 1 glyph but %d", glyphs->num_glyphs);
+
+ pango_glyph_string_free(glyphs);
+ }
+
+ g_list_foreach(items, (GFunc)pango_item_free, NULL);
+ g_list_free(items);
+
+ return result;
+}
+#endif // USE(WXGC)
+
+
void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* font, const wxColour& color, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point)
{
#if USE(WXGC)
wxGCDC* dc = static_cast<wxGCDC*>(graphicsContext->platformContext());
+ wxGraphicsContext* gc = dc->GetGraphicsContext();
+ gc->PushState();
+ cairo_t* cr = (cairo_t*)gc->GetNativeContext();
+
+ wxFont* wxfont = font->getWxFont();
+ PangoFont* pangoFont = createPangoFontForFont(wxfont);
+ PangoFontMap* fontMap = pangoFontMap();
+ PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(fontMap));
+ cairo_scaled_font_t* scaled_font = createScaledFontForFont(wxfont);
+ ASSERT(scaled_font);
+
+ cairo_glyph_t* glyphs = NULL;
+ glyphs = static_cast<cairo_glyph_t*>(malloc(sizeof(cairo_glyph_t) * numGlyphs));
+
+ float offset = point.x();
+
+ for (int i = 0; i < numGlyphs; i++) {
+ glyphs[i].index = pango_font_get_glyph(pangoFont, pangoContext, glyphBuffer.glyphAt(from + i));
+ glyphs[i].x = offset;
+ glyphs[i].y = point.y();
+ offset += glyphBuffer.advanceAt(from + i);
+ }
+
+ cairo_set_source_rgba(cr, color.Red()/255.0, color.Green()/255.0, color.Blue()/255.0, color.Alpha()/255.0);
+ cairo_set_scaled_font(cr, scaled_font);
+
+ cairo_show_glyphs(cr, glyphs, numGlyphs);
+
+ cairo_scaled_font_destroy(scaled_font);
+ gc->PopState();
#else
wxDC* dc = graphicsContext->platformContext();
-#endif
- wxFont wxfont = font->getWxFont();
- if (wxfont.IsOk())
- dc->SetFont(wxfont);
+ wxFont* wxfont = font->getWxFont();
+ if (wxfont && wxfont->IsOk())
+ dc->SetFont(*wxfont);
dc->SetTextForeground(color);
// convert glyphs to wxString
@@ -63,6 +239,7 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
wxCoord ypoint = (wxCoord) (point.y() - height);
dc->DrawText(text, (wxCoord)point.x(), ypoint);
+#endif
}
}
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp b/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp
index b649eb4..447a3d0 100644
--- a/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp
+++ b/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp
@@ -36,14 +36,19 @@ static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (c
wxFontProperties::wxFontProperties(wxFont* font):
m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
{
- ATSFontRef fontRef;
CGFontRef cgFont;
+
+#ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
+ cgFont = CTFontCopyGraphicsFont((CTFontRef)font->MacGetCTFont(), NULL);
+#else
+ ATSFontRef fontRef;
fontRef = FMGetATSFontRefFromFont(font->MacGetATSUFontID());
if (fontRef)
cgFont = CGFontCreateWithPlatformFont((void*)&fontRef);
-
+#endif
+
if (cgFont) {
int iAscent;
int iDescent;
@@ -89,7 +94,7 @@ void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxC
// we need the scale here ...
- Fixed atsuSize = IntToFixed( int( /*m_scaleY*/ 1 * font.MacGetFontSize()) ) ;
+ Fixed atsuSize = IntToFixed( int( /*m_scaleY*/ 1 * font.GetPointSize()) ) ;
//RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColor.GetPixel() ) ;
ATSUAttributeTag atsuTags[] =
{
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp b/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
index 126f7ec..6eaa765 100644
--- a/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
+++ b/WebCore/platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
@@ -30,6 +30,7 @@
#include <wx/defs.h>
#include <wx/dcclient.h>
+#include <wx/dcgraph.h>
#include <wx/gdicmn.h>
#include <vector>
@@ -43,9 +44,9 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
wxDC* dc = graphicsContext->platformContext();
#endif
- wxFont wxfont = font->getWxFont();
- if (wxfont.IsOk())
- dc->SetFont(wxfont);
+ wxFont* wxfont = font->getWxFont();
+ if (wxfont->IsOk())
+ dc->SetFont(*wxfont);
dc->SetTextForeground(color);
// convert glyphs to wxString
diff --git a/WebCore/platform/wx/wxcode/non-kerned-drawing.h b/WebCore/platform/wx/wxcode/non-kerned-drawing.h
index d005985..b995d37 100644
--- a/WebCore/platform/wx/wxcode/non-kerned-drawing.h
+++ b/WebCore/platform/wx/wxcode/non-kerned-drawing.h
@@ -27,10 +27,25 @@
#include "GlyphBuffer.h"
#include <wx/defs.h>
-#include <wx/dcclient.h>
+#include <wx/dcclient.h>
+
+#if __WXGTK__ && USE(WXGC)
+#include <cairo.h>
+#include <pango/pango.h>
+#include <pango/pangocairo.h>
+#endif
namespace WebCore {
extern void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* font, const wxColour& color, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point);
-
-}
+
+#if __WXGTK__ && USE(WXGC)
+PangoFontMap* pangoFontMap();
+
+PangoFont* createPangoFontForFont(const wxFont* wxfont);
+cairo_scaled_font_t* createScaledFontForFont(const wxFont* wxfont);
+PangoGlyph pango_font_get_glyph(PangoFont* font, PangoContext* context, gunichar wc);
+
+#endif
+}
+
diff --git a/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp b/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp
index f05923a..7d1e924 100644
--- a/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp
+++ b/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp
@@ -101,7 +101,9 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData*
for (unsigned i = 0; i < numGlyphs; ++i)
spacing[i] = advances[i].width();
- ::SelectObject(hdc, GetHfontOf(font->getWxFont()));
+ wxFont* wxfont = font->getWxFont();
+ if (wxfont && wxfont->IsOk())
+ ::SelectObject(hdc, GetHfontOf(*wxfont));
if (color.Ok())
::SetTextColor(hdc, color.GetPixel());
diff --git a/WebCore/plugins/wx/PluginDataWx.cpp b/WebCore/plugins/PluginDataNone.cpp
index 28e3967..28e3967 100644
--- a/WebCore/plugins/wx/PluginDataWx.cpp
+++ b/WebCore/plugins/PluginDataNone.cpp
diff --git a/WebCore/plugins/PluginPackage.cpp b/WebCore/plugins/PluginPackage.cpp
index 82daca7..747d937 100644
--- a/WebCore/plugins/PluginPackage.cpp
+++ b/WebCore/plugins/PluginPackage.cpp
@@ -97,7 +97,8 @@ int PluginPackage::compare(const PluginPackage& compareTo) const
if (diff)
return diff;
- if (diff = compareFileVersion(compareTo.version()))
+ diff = compareFileVersion(compareTo.version());
+ if (diff)
return diff;
return strcmp(parentDirectory().utf8().data(), compareTo.parentDirectory().utf8().data());
diff --git a/WebCore/plugins/wx/PluginPackageWx.cpp b/WebCore/plugins/PluginPackageNone.cpp
index b93ead2..3f43855 100644
--- a/WebCore/plugins/wx/PluginPackageWx.cpp
+++ b/WebCore/plugins/PluginPackageNone.cpp
@@ -35,7 +35,7 @@
namespace WebCore {
-void PluginPackage::determineQuirks(const String& mimeType)
+void PluginPackage::determineQuirks(const String&)
{
notImplemented();
}
@@ -59,13 +59,13 @@ unsigned PluginPackage::hash() const
return 0;
}
-bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
+bool PluginPackage::equal(const PluginPackage&, const PluginPackage&)
{
notImplemented();
return false;
}
-int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersion) const
+int PluginPackage::compareFileVersion(const PlatformModuleVersion&) const
{
notImplemented();
return 0;
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index ed867fc..60287f6 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -404,12 +404,12 @@ int32 PluginView::write(NPStream* stream, int32 len, void* buffer)
NPError PluginView::destroyStream(NPStream* stream, NPReason reason)
{
- PluginStream* browserStream = static_cast<PluginStream*>(stream->ndata);
-
if (!stream || PluginStream::ownerForStream(stream) != m_instance)
return NPERR_INVALID_INSTANCE_ERROR;
+ PluginStream* browserStream = static_cast<PluginStream*>(stream->ndata);
browserStream->cancelAndDestroyStream(reason);
+
return NPERR_NO_ERROR;
}
@@ -569,9 +569,6 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p
#if PLATFORM(GTK) || defined(Q_WS_X11)
, m_needsXEmbed(false)
#endif
-#if PLATFORM(QT)
- , m_isNPAPIPlugin(false)
-#endif
#if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API)
, m_pluginWndProc(0)
, m_lastMessage(0)
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index 5be7d1f..e895165 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -199,11 +199,6 @@ namespace WebCore {
static bool isCallingPlugin();
-#if PLATFORM(QT)
- bool isNPAPIPlugin() const { return m_isNPAPIPlugin; }
- void setIsNPAPIPlugin(bool b) { m_isNPAPIPlugin = b; }
-#endif
-
private:
PluginView(Frame* parentFrame, const IntSize&, PluginPackage*, Element*, const KURL&, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually);
@@ -284,10 +279,6 @@ namespace WebCore {
bool m_isTransparent;
bool m_haveInitialized;
-#if PLATFORM(QT)
- bool m_isNPAPIPlugin;
-#endif
-
#if PLATFORM(GTK) || defined(Q_WS_X11)
bool m_needsXEmbed;
#endif
@@ -330,6 +321,9 @@ private:
void nullEventTimerFired(Timer<PluginView>*);
Point globalMousePosForPlugin() const;
#endif
+#if PLATFORM(GTK) || defined(Q_WS_X11)
+ void setNPWindowIfNeeded();
+#endif
IntRect m_clipRect; // The clip rect to apply to a windowed plug-in
IntRect m_windowRect; // Our window rect.
diff --git a/WebCore/plugins/wx/PluginViewWx.cpp b/WebCore/plugins/PluginViewNone.cpp
index a95713a..2766a6b 100644
--- a/WebCore/plugins/wx/PluginViewWx.cpp
+++ b/WebCore/plugins/PluginViewNone.cpp
@@ -48,27 +48,27 @@ void PluginView::hide()
notImplemented();
}
-void PluginView::paint(GraphicsContext* context, const IntRect& rect)
+void PluginView::paint(GraphicsContext*, const IntRect&)
{
notImplemented();
}
-void PluginView::handleKeyboardEvent(KeyboardEvent* event)
+void PluginView::handleKeyboardEvent(KeyboardEvent*)
{
notImplemented();
}
-void PluginView::handleMouseEvent(MouseEvent* event)
+void PluginView::handleMouseEvent(MouseEvent*)
{
notImplemented();
}
-void PluginView::setParent(ScrollView* parent)
+void PluginView::setParent(ScrollView*)
{
notImplemented();
}
-void PluginView::setNPWindowRect(const IntRect& rect)
+void PluginView::setNPWindowRect(const IntRect&)
{
notImplemented();
}
@@ -84,20 +84,20 @@ const char* PluginView::userAgent()
return 0;
}
-NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32 len, const char* buf)
+NPError PluginView::handlePostReadFile(Vector<char>&, uint32, const char*)
{
notImplemented();
return 0;
}
-NPError PluginView::getValue(NPNVariable variable, void* value)
+NPError PluginView::getValue(NPNVariable, void*)
{
notImplemented();
return 0;
}
-void PluginView::invalidateRect(NPRect* rect)
+void PluginView::invalidateRect(NPRect*)
{
notImplemented();
}
@@ -107,7 +107,7 @@ void PluginView::invalidateRect(const IntRect&)
notImplemented();
}
-void PluginView::invalidateRegion(NPRegion region)
+void PluginView::invalidateRegion(NPRegion)
{
notImplemented();
}
diff --git a/WebCore/plugins/gtk/PluginPackageGtk.cpp b/WebCore/plugins/gtk/PluginPackageGtk.cpp
index 997583e..1337c31 100644
--- a/WebCore/plugins/gtk/PluginPackageGtk.cpp
+++ b/WebCore/plugins/gtk/PluginPackageGtk.cpp
@@ -29,6 +29,8 @@
#include "config.h"
#include "PluginPackage.h"
+#include <stdio.h>
+
#include "CString.h"
#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
diff --git a/WebCore/plugins/gtk/PluginViewGtk.cpp b/WebCore/plugins/gtk/PluginViewGtk.cpp
index 2b93e56..30be6b0 100644
--- a/WebCore/plugins/gtk/PluginViewGtk.cpp
+++ b/WebCore/plugins/gtk/PluginViewGtk.cpp
@@ -82,6 +82,23 @@ namespace WebCore {
using namespace HTMLNames;
+bool PluginView::dispatchNPEvent(NPEvent& event)
+{
+ // sanity check
+ if (!m_plugin->pluginFuncs()->event)
+ return false;
+
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+
+ bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event);
+
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
+ return accepted;
+}
+
void PluginView::updatePluginWidget()
{
if (!parent() || !m_isWindowed)
@@ -97,16 +114,8 @@ void PluginView::updatePluginWidget()
m_clipRect = windowClipRect();
m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
- GtkAllocation allocation = { m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height() };
- if (platformPluginWidget()) {
- gtk_widget_size_allocate(platformPluginWidget(), &allocation);
-#if PLATFORM(X11)
- if (!m_needsXEmbed) {
- gtk_xtbin_set_position(GTK_XTBIN(platformPluginWidget()), m_windowRect.x(), m_windowRect.y());
- gtk_xtbin_resize(platformPluginWidget(), m_windowRect.width(), m_windowRect.height());
- }
-#endif
- }
+ if (platformPluginWidget() && (m_windowRect != oldWindowRect || m_clipRect != oldClipRect))
+ setNPWindowIfNeeded();
}
void PluginView::setFocus()
@@ -144,7 +153,12 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
return;
}
- if (m_isWindowed || context->paintingDisabled())
+ if (context->paintingDisabled())
+ return;
+
+ setNPWindowIfNeeded();
+
+ if (m_isWindowed)
return;
NPEvent npEvent;
@@ -154,12 +168,8 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
ASSERT(parent()->isFrameView());
- if (m_plugin->pluginFuncs()->event) {
- JSC::JSLock::DropAllLocks dropAllLocks(false);
- m_plugin->pluginFuncs()->event(m_instance, &npEvent);
- }
-
- setNPWindowRect(frameRect());
+ if (!dispatchNPEvent(npEvent))
+ LOG(Events, "PluginView::paint(): Paint event not accepted");
}
void PluginView::handleKeyboardEvent(KeyboardEvent* event)
@@ -169,7 +179,7 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event)
/* FIXME: Synthesize an XEvent to pass through */
JSC::JSLock::DropAllLocks dropAllLocks(false);
- if (!m_plugin->pluginFuncs()->event(m_instance, &npEvent))
+ if (!dispatchNPEvent(npEvent))
event->setDefaultHandled();
}
@@ -184,7 +194,7 @@ void PluginView::handleMouseEvent(MouseEvent* event)
IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY()));
JSC::JSLock::DropAllLocks dropAllLocks(false);
- if (!m_plugin->pluginFuncs()->event(m_instance, &npEvent))
+ if (!dispatchNPEvent(npEvent))
event->setDefaultHandled();
}
@@ -200,40 +210,41 @@ void PluginView::setParent(ScrollView* parent)
}
}
-void PluginView::setNPWindowRect(const IntRect& rect)
+void PluginView::setNPWindowRect(const IntRect&)
{
- if (!m_isStarted || !parent())
- return;
-
- IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(rect.location());
- m_npWindow.x = p.x();
- m_npWindow.y = p.y();
-
- m_npWindow.width = rect.width();
- m_npWindow.height = rect.height();
-
- m_npWindow.clipRect.left = 0;
- m_npWindow.clipRect.top = 0;
- m_npWindow.clipRect.right = rect.width();
- m_npWindow.clipRect.bottom = rect.height();
+ setNPWindowIfNeeded();
+}
- if (m_npWindow.x < 0 || m_npWindow.y < 0 ||
- m_npWindow.width <= 0 || m_npWindow.height <= 0)
+void PluginView::setNPWindowIfNeeded()
+{
+ if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow)
return;
- if (m_plugin->pluginFuncs()->setwindow) {
- PluginView::setCurrentPluginView(this);
- JSC::JSLock::DropAllLocks dropAllLocks(false);
- setCallingPlugin(true);
- m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
- setCallingPlugin(false);
- PluginView::setCurrentPluginView(0);
+ m_npWindow.x = m_windowRect.x();
+ m_npWindow.y = m_windowRect.y();
+ m_npWindow.width = m_windowRect.width();
+ m_npWindow.height = m_windowRect.height();
- if (!m_isWindowed)
- return;
+ m_npWindow.clipRect.left = m_clipRect.x();
+ m_npWindow.clipRect.top = m_clipRect.y();
+ m_npWindow.clipRect.right = m_clipRect.width();
+ m_npWindow.clipRect.bottom = m_clipRect.height();
- ASSERT(platformPluginWidget());
+ GtkAllocation allocation = { m_windowRect.x(), m_windowRect.y(), m_windowRect.width(), m_windowRect.height() };
+ gtk_widget_size_allocate(platformPluginWidget(), &allocation);
+#if PLATFORM(X11)
+ if (!m_needsXEmbed) {
+ gtk_xtbin_set_position(GTK_XTBIN(platformPluginWidget()), m_windowRect.x(), m_windowRect.y());
+ gtk_xtbin_resize(platformPluginWidget(), m_windowRect.width(), m_windowRect.height());
}
+#endif
+
+ PluginView::setCurrentPluginView(this);
+ JSC::JSLock::DropAllLocks dropAllLocks(false);
+ setCallingPlugin(true);
+ m_plugin->pluginFuncs()->setwindow(m_instance, &m_npWindow);
+ setCallingPlugin(false);
+ PluginView::setCurrentPluginView(0);
}
void PluginView::setParentVisible(bool visible)
@@ -349,22 +360,22 @@ NPError PluginView::getValueStatic(NPNVariable variable, void* value)
switch (variable) {
case NPNVToolkit:
#if PLATFORM(GTK)
- *((uint32 *)value) = 2;
+ *static_cast<uint32*>(value) = 2;
#else
- *((uint32 *)value) = 0;
+ *static_cast<uint32*>(value) = 0;
#endif
return NPERR_NO_ERROR;
case NPNVSupportsXEmbedBool:
#if PLATFORM(X11)
- *((uint32 *)value) = true;
+ *static_cast<NPBool*>(value) = true;
#else
- *((uint32 *)value) = false;
+ *static_cast<NPBool*>(value) = false;
#endif
return NPERR_NO_ERROR;
case NPNVjavascriptEnabledBool:
- *((uint32 *)value) = true;
+ *static_cast<NPBool*>(value) = true;
return NPERR_NO_ERROR;
default:
@@ -576,10 +587,12 @@ void PluginView::init()
m_npWindow.window = 0;
}
+ // TODO remove in favor of null events, like mac port?
if (!(m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)))
- setNPWindowRect(frameRect());
+ updatePluginWidget(); // was: setNPWindowIfNeeded(), but this doesn't produce 0x0 rects at first go
m_status = PluginStatusLoadedSuccessfully;
}
} // namespace WebCore
+
diff --git a/WebCore/plugins/mac/PluginViewMac.cpp b/WebCore/plugins/mac/PluginViewMac.cpp
index 9e58906..a46aca6 100644
--- a/WebCore/plugins/mac/PluginViewMac.cpp
+++ b/WebCore/plugins/mac/PluginViewMac.cpp
@@ -158,8 +158,6 @@ void PluginView::init()
m_npWindow.clipRect.right = 0;
m_npWindow.clipRect.bottom = 0;
- setIsNPAPIPlugin(true);
-
show();
m_status = PluginStatusLoadedSuccessfully;
@@ -222,11 +220,11 @@ NPError PluginView::getValueStatic(NPNVariable variable, void* value)
switch (variable) {
case NPNVToolkit:
- *((uint32 *)value) = 0;
+ *static_cast<uint32*>(value) = 0;
return NPERR_NO_ERROR;
case NPNVjavascriptEnabledBool:
- *((uint32 *)value) = true;
+ *static_cast<NPBool*>(value) = true;
return NPERR_NO_ERROR;
default:
@@ -277,7 +275,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value)
}
case NPNVsupportsCoreGraphicsBool:
- *((uint32 *)value) = true;
+ *static_cast<NPBool*>(value) = true;
return NPERR_NO_ERROR;
default:
@@ -445,11 +443,8 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
void PluginView::invalidateRect(const IntRect& rect)
{
- if (platformPluginWidget()) {
- // TODO: optimize
- platformPluginWidget()->update();
- return;
- }
+ if (platformPluginWidget())
+ platformPluginWidget()->update(convertToContainingWindow(rect));
}
void PluginView::invalidateRect(NPRect* rect)
diff --git a/WebCore/plugins/npfunctions.h b/WebCore/plugins/npfunctions.h
index 21e2e15..beaa1fb 100644
--- a/WebCore/plugins/npfunctions.h
+++ b/WebCore/plugins/npfunctions.h
@@ -66,6 +66,10 @@ typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance);
typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP instance, NPBool enabled);
typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP instance);
typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP npp, void (*func)(void *), void *userData);
+typedef NPError (*NPN_GetValueForURLProcPtr)(NPP npp, NPNURLVariable variable, const char* url, char** value, uint32_t* len);
+typedef NPError (*NPN_SetValueForURLProcPtr)(NPP npp, NPNURLVariable variable, const char* url, const char* value, uint32_t* len);
+typedef NPError (*NPN_GetAuthenticationInfoPtr)(NPP npp, const char* protocol, const char* host, int32_t port, const char* scheme, const char *realm, char** username, uint32_t* ulen, char** password, uint32_t* plen);
+
typedef uint32 (*NPN_ScheduleTimerProcPtr)(NPP npp, uint32 interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32 timerID));
typedef void (*NPN_UnscheduleTimerProcPtr)(NPP npp, uint32 timerID);
typedef NPError (*NPN_PopUpContextMenuProcPtr)(NPP instance, NPMenu* menu);
@@ -161,6 +165,9 @@ typedef struct _NPNetscapeFuncs {
NPN_EnumerateProcPtr enumerate;
NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall;
NPN_ConstructProcPtr construct;
+ NPN_GetValueForURLProcPtr getvalueforurl;
+ NPN_SetValueForURLProcPtr setvalueforurl;
+ NPN_GetAuthenticationInfoPtr getauthenticationinfo;
NPN_ScheduleTimerProcPtr scheduletimer;
NPN_UnscheduleTimerProcPtr unscheduletimer;
NPN_PopUpContextMenuProcPtr popupcontextmenu;
diff --git a/WebCore/plugins/qt/PluginViewQt.cpp b/WebCore/plugins/qt/PluginViewQt.cpp
index 4982d08..c8dd0e5 100644
--- a/WebCore/plugins/qt/PluginViewQt.cpp
+++ b/WebCore/plugins/qt/PluginViewQt.cpp
@@ -301,15 +301,15 @@ NPError PluginView::getValueStatic(NPNVariable variable, void* value)
{
switch (variable) {
case NPNVToolkit:
- *((uint32 *)value) = 0;
+ *static_cast<uint32*>(value) = 0;
return NPERR_NO_ERROR;
case NPNVSupportsXEmbedBool:
- *((uint32 *)value) = true;
+ *static_cast<NPBool*>(value) = true;
return NPERR_NO_ERROR;
case NPNVjavascriptEnabledBool:
- *((uint32 *)value) = true;
+ *static_cast<NPBool*>(value) = true;
return NPERR_NO_ERROR;
default:
@@ -459,7 +459,6 @@ void PluginView::init()
if (m_needsXEmbed) {
setPlatformWidget(new QX11EmbedContainer(m_parentFrame->view()->hostWindow()->platformWindow()));
- setIsNPAPIPlugin(true);
} else {
notImplemented();
m_status = PluginStatusCanNotLoadPlugin;
diff --git a/WebCore/plugins/win/PluginPackageWin.cpp b/WebCore/plugins/win/PluginPackageWin.cpp
index fe9b544..0edcef3 100644
--- a/WebCore/plugins/win/PluginPackageWin.cpp
+++ b/WebCore/plugins/win/PluginPackageWin.cpp
@@ -68,6 +68,11 @@ int PluginPackage::compareFileVersion(const PlatformModuleVersion& compareVersio
bool PluginPackage::isPluginBlacklisted()
{
+ if (name() == "Citrix ICA Client") {
+ // The Citrix ICA Client plug-in requires a Mozilla-based browser; see <rdar://6418681>.
+ return true;
+ }
+
if (name() == "Silverlight Plug-In") {
// workaround for <rdar://5557379> Crash in Silverlight when opening microsoft.com.
// the latest 1.0 version of Silverlight does not reproduce this crash, so allow it
diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp
index fcce87d..db9a101 100644
--- a/WebCore/rendering/EllipsisBox.cpp
+++ b/WebCore/rendering/EllipsisBox.cpp
@@ -31,7 +31,7 @@ namespace WebCore {
void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
{
GraphicsContext* context = paintInfo.context;
- RenderStyle* style = m_object->style(m_firstLine);
+ RenderStyle* style = m_renderer->style(m_firstLine);
Color textColor = style->color();
if (textColor != context->fillColor())
context->setFillColor(textColor);
@@ -43,15 +43,15 @@ void EllipsisBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
}
const String& str = m_str;
- context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + m_baseline));
+ context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->font().ascent()));
if (setShadow)
context->clearShadow();
if (m_markupBox) {
// Paint the markup box
- tx += m_x + m_width - m_markupBox->xPos();
- ty += m_y + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline());
+ tx += m_x + m_width - m_markupBox->x();
+ ty += m_y + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent());
m_markupBox->paint(paintInfo, tx, ty);
}
}
@@ -63,16 +63,17 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Hit test the markup box.
if (m_markupBox) {
- int mtx = tx + m_width - m_markupBox->xPos();
- int mty = ty + m_baseline - (m_markupBox->yPos() + m_markupBox->baseline());
+ RenderStyle* style = m_renderer->style(m_firstLine);
+ int mtx = tx + m_width - m_markupBox->x();
+ int mty = ty + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent());
if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty)) {
- object()->updateHitTestResult(result, IntPoint(x - mtx, y - mty));
+ renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty));
return true;
}
}
if (visibleToHitTesting() && IntRect(tx, ty, m_width, m_height).contains(x, y)) {
- object()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
diff --git a/WebCore/rendering/EllipsisBox.h b/WebCore/rendering/EllipsisBox.h
index dbb30cd..9dbd27f 100644
--- a/WebCore/rendering/EllipsisBox.h
+++ b/WebCore/rendering/EllipsisBox.h
@@ -26,15 +26,15 @@
namespace WebCore {
+class HitTestRequest;
class HitTestResult;
-struct HitTestRequest;
-
class EllipsisBox : public InlineBox {
public:
EllipsisBox(RenderObject* obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
- int width, int y, int height, int baseline, bool firstLine, InlineBox* markupBox)
- : InlineBox(obj, 0, y, width, height, baseline, firstLine, true, false, false, 0, 0, parent)
+ int width, int height, int y, bool firstLine, InlineBox* markupBox)
+ : InlineBox(obj, 0, y, width, firstLine, true, false, false, 0, 0, parent)
+ , m_height(height)
, m_str(ellipsisStr)
, m_markupBox(markupBox)
{
@@ -44,6 +44,9 @@ public:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
private:
+ virtual int height() const { return m_height; }
+
+ int m_height;
AtomicString m_str;
InlineBox* m_markupBox;
};
diff --git a/WebCore/rendering/HitTestRequest.h b/WebCore/rendering/HitTestRequest.h
index 11dca4b..46dd7b8 100644
--- a/WebCore/rendering/HitTestRequest.h
+++ b/WebCore/rendering/HitTestRequest.h
@@ -2,6 +2,7 @@
* This file is part of the HTML rendering engine for KDE.
*
* Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,24 +20,35 @@
* Boston, MA 02110-1301, USA.
*
*/
+
#ifndef HitTestRequest_h
#define HitTestRequest_h
namespace WebCore {
-struct HitTestRequest {
- HitTestRequest(bool r, bool a, bool m = false, bool u = false)
- : readonly(r)
- , active(a)
- , mouseMove(m)
- , mouseUp(u)
- {
+class HitTestRequest {
+public:
+ enum RequestType {
+ ReadOnly = 0x1,
+ Active = 0x2,
+ MouseMove = 0x4,
+ MouseUp = 0x8,
+ IgnoreClipping = 0x10
+ };
+
+ HitTestRequest(int requestType)
+ : m_requestType(requestType)
+ {
}
- bool readonly;
- bool active;
- bool mouseMove;
- bool mouseUp;
+ bool readOnly() const { return m_requestType & ReadOnly; }
+ bool active() const { return m_requestType & Active; }
+ bool mouseMove() const { return m_requestType & MouseMove; }
+ bool mouseUp() const { return m_requestType & MouseUp; }
+ bool ignoreClipping() const { return m_requestType & IgnoreClipping; }
+
+private:
+ int m_requestType;
};
} // namespace WebCore
diff --git a/WebCore/rendering/InlineBox.cpp b/WebCore/rendering/InlineBox.cpp
index 6f7324a..89cd4b8 100644
--- a/WebCore/rendering/InlineBox.cpp
+++ b/WebCore/rendering/InlineBox.cpp
@@ -80,19 +80,24 @@ void InlineBox::operator delete(void* ptr, size_t sz)
#ifndef NDEBUG
void InlineBox::showTreeForThis() const
{
- if (m_object)
- m_object->showTreeForThis();
+ if (m_renderer)
+ m_renderer->showTreeForThis();
}
#endif
+int InlineBox::height() const
+{
+ return toRenderBox(m_renderer)->height();
+}
+
int InlineBox::caretMinOffset() const
{
- return m_object->caretMinOffset();
+ return m_renderer->caretMinOffset();
}
int InlineBox::caretMaxOffset() const
{
- return m_object->caretMaxOffset();
+ return m_renderer->caretMaxOffset();
}
unsigned InlineBox::caretMaxRenderedOffset() const
@@ -109,36 +114,38 @@ void InlineBox::dirtyLineBoxes()
void InlineBox::deleteLine(RenderArena* arena)
{
- if (!m_extracted)
- m_object->setInlineBoxWrapper(0);
+ if (!m_extracted && m_renderer->isBox())
+ toRenderBox(m_renderer)->setInlineBoxWrapper(0);
destroy(arena);
}
void InlineBox::extractLine()
{
m_extracted = true;
- m_object->setInlineBoxWrapper(0);
+ if (m_renderer->isBox())
+ toRenderBox(m_renderer)->setInlineBoxWrapper(0);
}
void InlineBox::attachLine()
{
m_extracted = false;
- m_object->setInlineBoxWrapper(this);
+ if (m_renderer->isBox())
+ toRenderBox(m_renderer)->setInlineBoxWrapper(this);
}
void InlineBox::adjustPosition(int dx, int dy)
{
m_x += dx;
m_y += dy;
- if (m_object->isReplaced()) {
- RenderBox* box = toRenderBox(m_object);
+ if (m_renderer->isReplaced()) {
+ RenderBox* box = toRenderBox(m_renderer);
box->move(dx, dy);
}
}
void InlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
{
- if (!object()->shouldPaintWithinRoot(paintInfo) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
+ if (!renderer()->shouldPaintWithinRoot(paintInfo) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
return;
// Paint all phases of replaced elements atomically, as though the replaced element established its
@@ -147,16 +154,16 @@ void InlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip;
RenderObject::PaintInfo info(paintInfo);
info.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
- object()->paint(info, tx, ty);
+ renderer()->paint(info, tx, ty);
if (!preservePhase) {
info.phase = PaintPhaseChildBlockBackgrounds;
- object()->paint(info, tx, ty);
+ renderer()->paint(info, tx, ty);
info.phase = PaintPhaseFloat;
- object()->paint(info, tx, ty);
+ renderer()->paint(info, tx, ty);
info.phase = PaintPhaseForeground;
- object()->paint(info, tx, ty);
+ renderer()->paint(info, tx, ty);
info.phase = PaintPhaseOutline;
- object()->paint(info, tx, ty);
+ renderer()->paint(info, tx, ty);
}
}
@@ -165,7 +172,15 @@ bool InlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
// Hit test all phases of replaced elements atomically, as though the replaced element established its
// own stacking context. (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
// specification.)
- return object()->hitTest(request, result, IntPoint(x, y), tx, ty);
+ return renderer()->hitTest(request, result, IntPoint(x, y), tx, ty);
+}
+
+const RootInlineBox* InlineBox::root() const
+{
+ if (m_parent)
+ return m_parent->root();
+ ASSERT(isRootInlineBox());
+ return static_cast<const RootInlineBox*>(this);
}
RootInlineBox* InlineBox::root()
@@ -228,13 +243,13 @@ InlineBox* InlineBox::prevLeafChild()
RenderObject::SelectionState InlineBox::selectionState()
{
- return object()->selectionState();
+ return renderer()->selectionState();
}
bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth)
{
// Non-replaced elements can always accommodate an ellipsis.
- if (!m_object || !m_object->isReplaced())
+ if (!m_renderer || !m_renderer->isReplaced())
return true;
IntRect boxRect(m_x, 0, m_width, 10);
diff --git a/WebCore/rendering/InlineBox.h b/WebCore/rendering/InlineBox.h
index e17b6e8..e66574a 100644
--- a/WebCore/rendering/InlineBox.h
+++ b/WebCore/rendering/InlineBox.h
@@ -21,27 +21,25 @@
#ifndef InlineBox_h
#define InlineBox_h
-#include "RenderBox.h"
+#include "RenderBoxModelObject.h"
#include "TextDirection.h"
namespace WebCore {
+class HitTestRequest;
class HitTestResult;
class RootInlineBox;
-struct HitTestRequest;
// InlineBox represents a rectangle that occurs on a line. It corresponds to
// some RenderObject (i.e., it represents a portion of that RenderObject).
class InlineBox {
public:
InlineBox(RenderObject* obj)
- : m_object(obj)
+ : m_renderer(obj)
, m_x(0)
, m_y(0)
, m_width(0)
- , m_height(0)
- , m_baseline(0)
, m_next(0)
, m_prev(0)
, m_parent(0)
@@ -50,9 +48,6 @@ public:
, m_bidiEmbeddingLevel(0)
, m_dirty(false)
, m_extracted(false)
- , m_includeLeftEdge(false)
- , m_includeRightEdge(false)
- , m_hasTextChildren(true)
, m_endsWithBreak(false)
, m_hasSelectedChildren(false)
, m_hasEllipsisBox(false)
@@ -69,14 +64,12 @@ public:
{
}
- InlineBox(RenderObject* obj, int x, int y, int width, int height, int baseline, bool firstLine, bool constructed,
+ InlineBox(RenderObject* obj, int x, int y, int width, bool firstLine, bool constructed,
bool dirty, bool extracted, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
- : m_object(obj)
+ : m_renderer(obj)
, m_x(x)
, m_y(y)
, m_width(width)
- , m_height(height)
- , m_baseline(baseline)
, m_next(next)
, m_prev(prev)
, m_parent(parent)
@@ -85,9 +78,6 @@ public:
, m_bidiEmbeddingLevel(0)
, m_dirty(dirty)
, m_extracted(extracted)
- , m_includeLeftEdge(false)
- , m_includeRightEdge(false)
- , m_hasTextChildren(true)
, m_endsWithBreak(false)
, m_hasSelectedChildren(false)
, m_hasEllipsisBox(false)
@@ -134,10 +124,9 @@ public:
void showTreeForThis() const;
#endif
virtual bool isInlineBox() { return false; }
- virtual bool isInlineFlowBox() { return false; }
- virtual bool isContainer() { return false; }
+ virtual bool isInlineFlowBox() const { return false; }
virtual bool isInlineTextBox() { return false; }
- virtual bool isRootInlineBox() { return false; }
+ virtual bool isRootInlineBox() const { return false; }
#if ENABLE(SVG)
virtual bool isSVGRootInlineBox() { return false; }
#endif
@@ -178,7 +167,7 @@ public:
InlineBox* nextLeafChild();
InlineBox* prevLeafChild();
- RenderObject* object() const { return m_object; }
+ RenderObject* renderer() const { return m_renderer; }
InlineFlowBox* parent() const
{
@@ -187,29 +176,24 @@ public:
}
void setParent(InlineFlowBox* par) { m_parent = par; }
+ const RootInlineBox* root() const;
RootInlineBox* root();
-
+
void setWidth(int w) { m_width = w; }
int width() const { return m_width; }
- void setXPos(int x) { m_x = x; }
- int xPos() const { return m_x; }
-
- void setYPos(int y) { m_y = y; }
- int yPos() const { return m_y; }
+ void setX(int x) { m_x = x; }
+ int x() const { return m_x; }
- void setHeight(int h) { m_height = h; }
- int height() const { return m_height; }
-
- void setBaseline(int b) { m_baseline = b; }
- int baseline() const { return m_baseline; }
+ void setY(int y) { m_y = y; }
+ int y() const { return m_y; }
- bool hasTextChildren() const { return m_hasTextChildren; }
+ virtual int height() const;
- virtual int topOverflow() { return yPos(); }
- virtual int bottomOverflow() { return yPos() + height(); }
- virtual int leftOverflow() { return xPos(); }
- virtual int rightOverflow() { return xPos() + width(); }
+ virtual int topOverflow() const { return y(); }
+ virtual int bottomOverflow() const { return y() + height(); }
+ virtual int leftOverflow() const { return x(); }
+ virtual int rightOverflow() const { return x() + width(); }
virtual int caretMinOffset() const;
virtual int caretMaxOffset() const;
@@ -237,19 +221,22 @@ public:
int toAdd() const { return m_toAdd; }
- bool visibleToHitTesting() const { return object()->style()->visibility() == VISIBLE && object()->style()->pointerEvents() != PE_NONE; }
+ bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
// Use with caution! The type is not checked!
- RenderBox* renderBox() const { return toRenderBox(m_object); }
+ RenderBoxModelObject* boxModelObject() const
+ {
+ if (!m_renderer->isText())
+ return static_cast<RenderBoxModelObject*>(m_renderer);
+ return 0;
+ }
public:
- RenderObject* m_object;
+ RenderObject* m_renderer;
int m_x;
int m_y;
int m_width;
- int m_height;
- int m_baseline;
private:
InlineBox* m_next; // The next element on the same line as us.
@@ -269,11 +256,6 @@ protected:
bool m_dirty : 1;
bool m_extracted : 1;
- // for InlineFlowBox
- bool m_includeLeftEdge : 1;
- bool m_includeRightEdge : 1;
- bool m_hasTextChildren : 1;
-
// for RootInlineBox
bool m_endsWithBreak : 1; // Whether the line ends with a <br>.
bool m_hasSelectedChildren : 1; // Whether we have any children selected (this bit will also be set if the <br> that terminates our line is selected).
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 74f4151..2e23bb6 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -28,7 +28,7 @@
#include "HitTestResult.h"
#include "RootInlineBox.h"
#include "RenderBlock.h"
-#include "RenderFlow.h"
+#include "RenderInline.h"
#include "RenderListMarker.h"
#include "RenderTableCell.h"
#include "RootInlineBox.h"
@@ -51,45 +51,19 @@ InlineFlowBox::~InlineFlowBox()
#endif
-RenderFlow* InlineFlowBox::flowObject()
+int InlineFlowBox::height() const
{
- return static_cast<RenderFlow*>(m_object);
-}
-
-int InlineFlowBox::marginLeft()
-{
- if (!includeLeftEdge())
- return 0;
-
- Length margin = object()->style()->marginLeft();
- if (margin.isAuto())
- return 0;
- if (margin.isFixed())
- return margin.value();
- return renderBox()->marginLeft();
-}
-
-int InlineFlowBox::marginRight()
-{
- if (!includeRightEdge())
- return 0;
-
- Length margin = object()->style()->marginRight();
- if (margin.isAuto())
- return 0;
- if (margin.isFixed())
- return margin.value();
- return renderBox()->marginRight();
-}
-
-int InlineFlowBox::marginBorderPaddingLeft()
-{
- return marginLeft() + borderLeft() + paddingLeft();
-}
-
-int InlineFlowBox::marginBorderPaddingRight()
-{
- return marginRight() + borderRight() + paddingRight();
+ const Font& font = renderer()->style(m_firstLine)->font();
+ int result = font.height();
+ bool strictMode = renderer()->document()->inStrictMode();
+ RenderBoxModelObject* box = boxModelObject();
+ result += box->borderTop() + box->paddingTop() + box->borderBottom() + box->paddingBottom();
+ if (!strictMode && !hasTextChildren() && !box->hasHorizontalBordersOrPadding()) {
+ int bottomOverflow = root()->bottomOverflow();
+ if (y() + result > bottomOverflow)
+ result = bottomOverflow - y();
+ }
+ return result;
}
int InlineFlowBox::getFlowSpacingWidth()
@@ -121,7 +95,7 @@ void InlineFlowBox::addToLine(InlineBox* child)
child->setFirstLineStyleBit(m_firstLine);
if (child->isText())
m_hasTextChildren = true;
- if (child->object()->selectionState() != RenderObject::SelectionNone)
+ if (child->renderer()->selectionState() != RenderObject::SelectionNone)
root()->setHasSelectedChildren(true);
checkConsistency();
@@ -168,26 +142,41 @@ void InlineFlowBox::deleteLine(RenderArena* arena)
m_lastChild = 0;
#endif
- static_cast<RenderFlow*>(m_object)->removeLineBox(this);
+ removeLineBoxFromRenderObject();
destroy(arena);
}
+void InlineFlowBox::removeLineBoxFromRenderObject()
+{
+ toRenderInline(renderer())->lineBoxes()->removeLineBox(this);
+}
+
void InlineFlowBox::extractLine()
{
if (!m_extracted)
- static_cast<RenderFlow*>(m_object)->extractLineBox(this);
+ extractLineBoxFromRenderObject();
for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
child->extractLine();
}
+void InlineFlowBox::extractLineBoxFromRenderObject()
+{
+ toRenderInline(renderer())->lineBoxes()->extractLineBox(this);
+}
+
void InlineFlowBox::attachLine()
{
if (m_extracted)
- static_cast<RenderFlow*>(m_object)->attachLineBox(this);
+ attachLineBoxToRenderObject();
for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
child->attachLine();
}
+void InlineFlowBox::attachLineBoxToRenderObject()
+{
+ toRenderInline(renderer())->lineBoxes()->attachLineBox(this);
+}
+
void InlineFlowBox::adjustPosition(int dx, int dy)
{
InlineRunBox::adjustPosition(dx, dy);
@@ -195,18 +184,23 @@ void InlineFlowBox::adjustPosition(int dx, int dy)
child->adjustPosition(dx, dy);
}
+RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const
+{
+ return toRenderInline(renderer())->lineBoxes();
+}
+
bool InlineFlowBox::onEndChain(RenderObject* endObject)
{
if (!endObject)
return false;
- if (endObject == object())
+ if (endObject == renderer())
return true;
RenderObject* curr = endObject;
RenderObject* parent = curr->parent();
while (parent && !parent->isRenderBlock()) {
- if (parent->lastChild() != curr || parent == object())
+ if (parent->lastChild() != curr || parent == renderer())
return false;
curr = parent;
@@ -223,19 +217,17 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en
bool includeLeftEdge = false;
bool includeRightEdge = false;
- RenderFlow* flow = static_cast<RenderFlow*>(object());
-
- if (!flow->firstChild())
- includeLeftEdge = includeRightEdge = true; // Empty inlines never split across lines.
- else if (parent()) { // The root inline box never has borders/margins/padding.
- bool ltr = flow->style()->direction() == LTR;
-
+ // The root inline box never has borders/margins/padding.
+ if (parent()) {
+ bool ltr = renderer()->style()->direction() == LTR;
+
// Check to see if all initial lines are unconstructed. If so, then
- // we know the inline began on this line.
- if (!flow->firstLineBox()->isConstructed()) {
- if (ltr && flow->firstLineBox() == this)
+ // we know the inline began on this line (unless we are a continuation).
+ RenderLineBoxList* lineBoxList = rendererLineBoxes();
+ if (!lineBoxList->firstLineBox()->isConstructed() && !renderer()->isInlineContinuation()) {
+ if (ltr && lineBoxList->firstLineBox() == this)
includeLeftEdge = true;
- else if (!ltr && flow->lastLineBox() == this)
+ else if (!ltr && lineBoxList->lastLineBox() == this)
includeRightEdge = true;
}
@@ -246,14 +238,15 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en
// reverse for rtl), then the inline has closed.
// (3) The line may end on the inline. If we are the last child (climbing up
// the end object's chain), then we just closed as well.
- if (!flow->lastLineBox()->isConstructed()) {
+ if (!lineBoxList->lastLineBox()->isConstructed()) {
+ RenderInline* inlineFlow = toRenderInline(renderer());
if (ltr) {
if (!nextLineBox() &&
- ((lastLine && !flow->continuation()) || nextOnLineExists() || onEndChain(endObject)))
+ ((lastLine && !inlineFlow->continuation()) || nextOnLineExists() || onEndChain(endObject)))
includeRightEdge = true;
} else {
if ((!prevLineBox() || prevLineBox()->isConstructed()) &&
- ((lastLine && !flow->continuation()) || prevOnLineExists() || onEndChain(endObject)))
+ ((lastLine && !inlineFlow->continuation()) || prevOnLineExists() || onEndChain(endObject)))
includeLeftEdge = true;
}
}
@@ -270,32 +263,32 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en
}
}
-int InlineFlowBox::placeBoxesHorizontally(int x, int& leftPosition, int& rightPosition, bool& needsWordSpacing)
+int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& rightPosition, bool& needsWordSpacing)
{
// Set our x position.
- setXPos(x);
+ setX(xPos);
int boxShadowLeft = 0;
int boxShadowRight = 0;
- for (ShadowData* boxShadow = object()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
+ for (ShadowData* boxShadow = renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
boxShadowLeft = min(boxShadow->x - boxShadow->blur, boxShadowLeft);
boxShadowRight = max(boxShadow->x + boxShadow->blur, boxShadowRight);
}
- leftPosition = min(x + boxShadowLeft, leftPosition);
+ leftPosition = min(xPos + boxShadowLeft, leftPosition);
- int startX = x;
- x += borderLeft() + paddingLeft();
+ int startX = xPos;
+ xPos += borderLeft() + paddingLeft();
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->object()->isText()) {
+ if (curr->renderer()->isText()) {
InlineTextBox* text = static_cast<InlineTextBox*>(curr);
- RenderText* rt = toRenderText(text->object());
+ RenderText* rt = toRenderText(text->renderer());
if (rt->textLength()) {
if (needsWordSpacing && isSpaceOrNewline(rt->characters()[text->start()]))
- x += rt->style(m_firstLine)->font().wordSpacing();
+ xPos += rt->style(m_firstLine)->font().wordSpacing();
needsWordSpacing = !isSpaceOrNewline(rt->characters()[text->end()]);
}
- text->setXPos(x);
+ text->setX(xPos);
int strokeOverflow = static_cast<int>(ceilf(rt->style()->textStrokeWidth() / 2.0f));
@@ -313,41 +306,41 @@ int InlineFlowBox::placeBoxesHorizontally(int x, int& leftPosition, int& rightPo
visualOverflowRight = max(visualOverflowRight, shadow->x + shadow->blur + rightGlyphOverflow);
}
- leftPosition = min(x + visualOverflowLeft, leftPosition);
- rightPosition = max(x + text->width() + visualOverflowRight, rightPosition);
- m_maxHorizontalVisualOverflow = max(max(visualOverflowRight, -visualOverflowLeft), m_maxHorizontalVisualOverflow);
- x += text->width();
+ leftPosition = min(xPos + visualOverflowLeft, leftPosition);
+ rightPosition = max(xPos + text->width() + visualOverflowRight, rightPosition);
+ m_maxHorizontalVisualOverflow = max(max(visualOverflowRight, -visualOverflowLeft), (int)m_maxHorizontalVisualOverflow);
+ xPos += text->width();
} else {
- if (curr->object()->isPositioned()) {
- if (curr->object()->parent()->style()->direction() == LTR)
- curr->setXPos(x);
+ if (curr->renderer()->isPositioned()) {
+ if (curr->renderer()->parent()->style()->direction() == LTR)
+ curr->setX(xPos);
else
// Our offset that we cache needs to be from the edge of the right border box and
// not the left border box. We have to subtract |x| from the width of the block
// (which can be obtained from the root line box).
- curr->setXPos(root()->block()->width()-x);
+ curr->setX(root()->block()->width() - xPos);
continue; // The positioned object has no effect on the width.
}
- if (curr->object()->isRenderInline()) {
+ if (curr->renderer()->isRenderInline()) {
InlineFlowBox* flow = static_cast<InlineFlowBox*>(curr);
- x += flow->marginLeft();
- x = flow->placeBoxesHorizontally(x, leftPosition, rightPosition, needsWordSpacing);
- x += flow->marginRight();
- } else if (!curr->object()->isListMarker() || static_cast<RenderListMarker*>(curr->object())->isInside()) {
- x += curr->renderBox()->marginLeft();
- curr->setXPos(x);
- leftPosition = min(x + curr->renderBox()->overflowLeft(false), leftPosition);
- rightPosition = max(x + curr->renderBox()->overflowWidth(false), rightPosition);
- x += curr->width() + curr->renderBox()->marginRight();
+ xPos += flow->marginLeft();
+ xPos = flow->placeBoxesHorizontally(xPos, leftPosition, rightPosition, needsWordSpacing);
+ xPos += flow->marginRight();
+ } else if (!curr->renderer()->isListMarker() || static_cast<RenderListMarker*>(curr->renderer())->isInside()) {
+ xPos += curr->boxModelObject()->marginLeft();
+ curr->setX(xPos);
+ leftPosition = min(xPos + toRenderBox(curr->renderer())->overflowLeft(false), leftPosition);
+ rightPosition = max(xPos + toRenderBox(curr->renderer())->overflowWidth(false), rightPosition);
+ xPos += curr->width() + curr->boxModelObject()->marginRight();
}
}
}
- x += borderRight() + paddingRight();
- setWidth(x - startX);
- rightPosition = max(xPos() + width() + boxShadowRight, rightPosition);
+ xPos += borderRight() + paddingRight();
+ setWidth(xPos - startX);
+ rightPosition = max(x() + width() + boxShadowRight, rightPosition);
- return x;
+ return xPos;
}
int InlineFlowBox::verticallyAlignBoxes(int heightOfBlock)
@@ -359,8 +352,8 @@ int InlineFlowBox::verticallyAlignBoxes(int heightOfBlock)
// Figure out if we're in strict mode. Note that we can't simply use !style()->htmlHacks(),
// because that would match almost strict mode as well.
- RenderObject* curr = object();
- while (curr && !curr->element())
+ RenderObject* curr = renderer();
+ while (curr && !curr->node())
curr = curr->container();
bool strictMode = (curr && curr->document()->inStrictMode());
@@ -378,10 +371,6 @@ int InlineFlowBox::verticallyAlignBoxes(int heightOfBlock)
setVerticalOverflowPositions(topPosition, bottomPosition);
setVerticalSelectionPositions(selectionTop, selectionBottom);
-
- // Shrink boxes with no text children in quirks and almost strict mode.
- if (!strictMode)
- shrinkBoxesWithNoTextChildren(topPosition, bottomPosition);
heightOfBlock += maxHeight;
@@ -394,16 +383,17 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
// The computed lineheight needs to be extended for the
// positioned elements
- if (curr->object()->isPositioned())
+ if (curr->renderer()->isPositioned())
continue; // Positioned placeholders don't affect calculations.
- if (curr->yPos() == PositionTop || curr->yPos() == PositionBottom) {
- if (curr->yPos() == PositionTop) {
- if (maxAscent + maxDescent < curr->height())
- maxDescent = curr->height() - maxAscent;
+ if (curr->y() == PositionTop || curr->y() == PositionBottom) {
+ int lineHeight = curr->renderer()->lineHeight(m_firstLine);
+ if (curr->y() == PositionTop) {
+ if (maxAscent + maxDescent < lineHeight)
+ maxDescent = lineHeight - maxAscent;
}
else {
- if (maxAscent + maxDescent < curr->height())
- maxAscent = curr->height() - maxDescent;
+ if (maxAscent + maxDescent < lineHeight)
+ maxAscent = lineHeight - maxDescent;
}
if (maxAscent + maxDescent >= max(maxPositionTop, maxPositionBottom))
@@ -415,22 +405,25 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
}
}
+static int verticalPositionForBox(InlineBox* curr, bool firstLine)
+{
+ if (curr->renderer()->isText())
+ return curr->parent()->y();
+ if (curr->renderer()->isBox())
+ return toRenderBox(curr->renderer())->verticalPosition(firstLine);
+ return toRenderInline(curr->renderer())->verticalPositionFromCache(firstLine);
+}
+
void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
int& maxAscent, int& maxDescent, bool strictMode)
{
if (isRootInlineBox()) {
// Examine our root box.
- setHeight(object()->lineHeight(m_firstLine, true));
- bool isTableCell = object()->isTableCell();
- if (isTableCell) {
- RenderTableCell* tableCell = static_cast<RenderTableCell*>(object());
- setBaseline(tableCell->RenderBlock::baselinePosition(m_firstLine, true));
- }
- else
- setBaseline(object()->baselinePosition(m_firstLine, true));
+ int lineHeight = renderer()->lineHeight(m_firstLine, true);
+ int baseline = renderer()->baselinePosition(m_firstLine, true);
if (hasTextChildren() || strictMode) {
- int ascent = baseline();
- int descent = height() - ascent;
+ int ascent = baseline;
+ int descent = lineHeight - ascent;
if (maxAscent < ascent)
maxAscent = ascent;
if (maxDescent < descent)
@@ -439,23 +432,25 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
}
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->object()->isPositioned())
+ if (curr->renderer()->isPositioned())
continue; // Positioned placeholders don't affect calculations.
- curr->setHeight(curr->object()->lineHeight(m_firstLine));
- curr->setBaseline(curr->object()->baselinePosition(m_firstLine));
- curr->setYPos(curr->object()->verticalPositionHint(m_firstLine));
- if (curr->yPos() == PositionTop) {
- if (maxPositionTop < curr->height())
- maxPositionTop = curr->height();
+ bool isInlineFlow = curr->isInlineFlowBox();
+
+ int lineHeight = curr->renderer()->lineHeight(m_firstLine);
+ int baseline = curr->renderer()->baselinePosition(m_firstLine);
+ curr->setY(verticalPositionForBox(curr, m_firstLine));
+ if (curr->y() == PositionTop) {
+ if (maxPositionTop < lineHeight)
+ maxPositionTop = lineHeight;
}
- else if (curr->yPos() == PositionBottom) {
- if (maxPositionBottom < curr->height())
- maxPositionBottom = curr->height();
+ else if (curr->y() == PositionBottom) {
+ if (maxPositionBottom < lineHeight)
+ maxPositionBottom = lineHeight;
}
- else if (curr->hasTextChildren() || curr->renderBox()->hasHorizontalBordersOrPadding() || strictMode) {
- int ascent = curr->baseline() - curr->yPos();
- int descent = curr->height() - ascent;
+ else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasHorizontalBordersOrPadding() || strictMode) {
+ int ascent = baseline - curr->y();
+ int descent = lineHeight - ascent;
if (maxAscent < ascent)
maxAscent = ascent;
if (maxDescent < descent)
@@ -467,135 +462,106 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
}
}
-void InlineFlowBox::placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode,
+void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, bool strictMode,
int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom)
{
if (isRootInlineBox())
- setYPos(y + maxAscent - baseline());// Place our root box.
+ setY(yPos + max(0, maxAscent - renderer()->baselinePosition(m_firstLine, true))); // Place our root box.
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->object()->isPositioned())
+ if (curr->renderer()->isPositioned())
continue; // Positioned placeholders don't affect calculations.
// Adjust boxes to use their real box y/height and not the logical height (as dictated by
// line-height).
- if (curr->isInlineFlowBox())
- static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(y, maxHeight, maxAscent, strictMode, topPosition, bottomPosition, selectionTop, selectionBottom);
+ bool isInlineFlow = curr->isInlineFlowBox();
+ if (isInlineFlow)
+ static_cast<InlineFlowBox*>(curr)->placeBoxesVertically(yPos, maxHeight, maxAscent, strictMode, topPosition, bottomPosition, selectionTop, selectionBottom);
bool childAffectsTopBottomPos = true;
- if (curr->yPos() == PositionTop)
- curr->setYPos(y);
- else if (curr->yPos() == PositionBottom)
- curr->setYPos(y + maxHeight - curr->height());
+ if (curr->y() == PositionTop)
+ curr->setY(yPos);
+ else if (curr->y() == PositionBottom)
+ curr->setY(yPos + maxHeight - curr->renderer()->lineHeight(m_firstLine));
else {
- if (!curr->hasTextChildren() && !curr->renderBox()->hasHorizontalBordersOrPadding() && !strictMode)
+ if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasHorizontalBordersOrPadding() && !strictMode)
childAffectsTopBottomPos = false;
- curr->setYPos(curr->yPos() + y + maxAscent - curr->baseline());
+ int posAdjust = maxAscent - curr->renderer()->baselinePosition(m_firstLine);
+ if (!childAffectsTopBottomPos)
+ posAdjust = max(0, posAdjust);
+ curr->setY(curr->y() + yPos + posAdjust);
}
- int newY = curr->yPos();
- int newHeight = curr->height();
- int newBaseline = curr->baseline();
+ int newY = curr->y();
int overflowTop = 0;
int overflowBottom = 0;
if (curr->isText() || curr->isInlineFlowBox()) {
- const Font& font = curr->object()->style(m_firstLine)->font();
- newBaseline = font.ascent();
- newY += curr->baseline() - newBaseline;
- newHeight = newBaseline + font.descent();
- for (ShadowData* shadow = curr->object()->style()->textShadow(); shadow; shadow = shadow->next) {
+ const Font& font = curr->renderer()->style(m_firstLine)->font();
+ newY += curr->renderer()->baselinePosition(m_firstLine) - font.ascent();
+ for (ShadowData* shadow = curr->renderer()->style()->textShadow(); shadow; shadow = shadow->next) {
overflowTop = min(overflowTop, shadow->y - shadow->blur);
overflowBottom = max(overflowBottom, shadow->y + shadow->blur);
}
- for (ShadowData* boxShadow = curr->object()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
+ for (ShadowData* boxShadow = curr->renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
overflowTop = min(overflowTop, boxShadow->y - boxShadow->blur);
overflowBottom = max(overflowBottom, boxShadow->y + boxShadow->blur);
}
- for (ShadowData* textShadow = curr->object()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) {
+ for (ShadowData* textShadow = curr->renderer()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) {
overflowTop = min(overflowTop, textShadow->y - textShadow->blur);
overflowBottom = max(overflowBottom, textShadow->y + textShadow->blur);
}
- if (curr->object()->hasReflection()) {
- overflowTop = min(overflowTop, curr->renderBox()->reflectionBox().y());
- overflowBottom = max(overflowBottom, curr->renderBox()->reflectionBox().bottom());
+ if (curr->renderer()->hasReflection()) {
+ RenderBox* box = toRenderBox(curr->renderer());
+ overflowTop = min(overflowTop, box->reflectionBox().y());
+ overflowBottom = max(overflowBottom, box->reflectionBox().bottom());
}
- if (curr->isInlineFlowBox()) {
- newHeight += curr->renderBox()->borderTop() + curr->renderBox()->paddingTop() +
- curr->renderBox()->borderBottom() + curr->renderBox()->paddingBottom();
- newY -= curr->renderBox()->borderTop() + curr->renderBox()->paddingTop();
- newBaseline += curr->renderBox()->borderTop() + curr->renderBox()->paddingTop();
- }
- } else if (!curr->object()->isBR()) {
- newY += curr->renderBox()->marginTop();
- newHeight = curr->height() - (curr->renderBox()->marginTop() + curr->renderBox()->marginBottom());
- overflowTop = curr->renderBox()->overflowTop(false);
- overflowBottom = curr->renderBox()->overflowHeight(false) - newHeight;
+ if (curr->isInlineFlowBox())
+ newY -= curr->boxModelObject()->borderTop() + curr->boxModelObject()->paddingTop();
+ } else if (!curr->renderer()->isBR()) {
+ RenderBox* box = toRenderBox(curr->renderer());
+ newY += box->marginTop();
+ overflowTop = box->overflowTop(false);
+ overflowBottom = box->overflowHeight(false) - box->height();
}
- curr->setYPos(newY);
- curr->setHeight(newHeight);
- curr->setBaseline(newBaseline);
+ curr->setY(newY);
if (childAffectsTopBottomPos) {
selectionTop = min(selectionTop, newY);
- selectionBottom = max(selectionBottom, newY + newHeight);
+ selectionBottom = max(selectionBottom, newY + curr->height());
topPosition = min(topPosition, newY + overflowTop);
- bottomPosition = max(bottomPosition, newY + newHeight + overflowBottom);
+ bottomPosition = max(bottomPosition, newY + curr->height() + overflowBottom);
}
}
if (isRootInlineBox()) {
- const Font& font = object()->style(m_firstLine)->font();
- setHeight(font.ascent() + font.descent());
- setYPos(yPos() + baseline() - font.ascent());
- setBaseline(font.ascent());
+ const Font& font = renderer()->style(m_firstLine)->font();
+ setY(y() + renderer()->baselinePosition(m_firstLine, true) - font.ascent());
if (hasTextChildren() || strictMode) {
- selectionTop = min(selectionTop, yPos());
- selectionBottom = max(selectionBottom, yPos() + height());
+ selectionTop = min(selectionTop, y());
+ selectionBottom = max(selectionBottom, y() + height());
}
}
}
-void InlineFlowBox::shrinkBoxesWithNoTextChildren(int topPos, int bottomPos)
-{
- // First shrink our kids.
- for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->object()->isPositioned())
- continue; // Positioned placeholders don't affect calculations.
-
- if (curr->isInlineFlowBox())
- static_cast<InlineFlowBox*>(curr)->shrinkBoxesWithNoTextChildren(topPos, bottomPos);
- }
-
- // See if we have text children. If not, then we need to shrink ourselves to fit on the line.
- if (!hasTextChildren() && !renderBox()->hasHorizontalBordersOrPadding()) {
- if (yPos() < topPos)
- setYPos(topPos);
- if (yPos() + height() > bottomPos)
- setHeight(bottomPos - yPos());
- if (baseline() > height())
- setBaseline(height());
- }
-}
-
bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty)
{
// Check children first.
for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) {
- if (!curr->object()->hasLayer() && curr->nodeAtPoint(request, result, x, y, tx, ty)) {
- object()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ if ((curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) && curr->nodeAtPoint(request, result, x, y, tx, ty)) {
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
}
// Now check ourselves.
- IntRect rect(tx + m_x, ty + m_y, m_width, m_height);
+ IntRect rect(tx + m_x, ty + m_y, m_width, height());
if (visibleToHitTesting() && rect.contains(x, y)) {
- object()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space.
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space.
return true;
}
@@ -604,15 +570,15 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
{
- int xPos = tx + m_x - object()->maximalOutlineSize(paintInfo.phase);
- int w = width() + 2 * object()->maximalOutlineSize(paintInfo.phase);
+ int xPos = tx + m_x - renderer()->maximalOutlineSize(paintInfo.phase);
+ int w = width() + 2 * renderer()->maximalOutlineSize(paintInfo.phase);
int shadowLeft = 0;
int shadowRight = 0;
- for (ShadowData* boxShadow = object()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
+ for (ShadowData* boxShadow = renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
shadowLeft = min(boxShadow->x - boxShadow->blur, shadowLeft);
shadowRight = max(boxShadow->x + boxShadow->blur, shadowRight);
}
- for (ShadowData* textShadow = object()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) {
+ for (ShadowData* textShadow = renderer()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) {
shadowLeft = min(textShadow->x - textShadow->blur, shadowLeft);
shadowRight = max(textShadow->x + textShadow->blur, shadowRight);
}
@@ -624,14 +590,15 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
// Add ourselves to the paint info struct's list of inlines that need to paint their
// outlines.
- if (object()->style()->visibility() == VISIBLE && object()->hasOutline() && !isRootInlineBox()) {
- if ((flowObject()->continuation() || object()->isInlineContinuation()) && !object()->hasLayer()) {
+ if (renderer()->style()->visibility() == VISIBLE && renderer()->hasOutline() && !isRootInlineBox()) {
+ RenderInline* inlineFlow = toRenderInline(renderer());
+ if ((inlineFlow->continuation() || inlineFlow->isInlineContinuation()) && !boxModelObject()->hasSelfPaintingLayer()) {
// Add ourselves to the containing block of the entire continuation so that it can
// paint us atomically.
- RenderBlock* block = object()->containingBlock()->containingBlock();
- block->addContinuationWithOutline(static_cast<RenderFlow*>(object()->element()->renderer()));
- } else if (!object()->isInlineContinuation())
- paintInfo.outlineObjects->add(flowObject());
+ RenderBlock* block = renderer()->containingBlock()->containingBlock();
+ block->addContinuationWithOutline(toRenderInline(renderer()->node()->renderer()));
+ } else if (!inlineFlow->isInlineContinuation())
+ paintInfo.outlineObjects->add(inlineFlow);
}
} else if (paintInfo.phase == PaintPhaseMask) {
paintMask(paintInfo, tx, ty);
@@ -651,12 +618,12 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
PaintPhase paintPhase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase;
RenderObject::PaintInfo childInfo(paintInfo);
childInfo.phase = paintPhase;
- childInfo.paintingRoot = object()->paintingRootForChildren(paintInfo);
+ childInfo.paintingRoot = renderer()->paintingRootForChildren(paintInfo);
// 3. Paint our children.
if (paintPhase != PaintPhaseSelfOutline) {
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (!curr->object()->hasLayer())
+ if (curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer())
curr->paint(childInfo, tx, ty);
}
}
@@ -679,9 +646,9 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con
int my, int mh, int tx, int ty, int w, int h, CompositeOperator op)
{
StyleImage* img = fillLayer->image();
- bool hasFillImage = img && img->canRender(object()->style()->effectiveZoom());
- if ((!hasFillImage && !object()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent())
- object()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, tx, ty, w, h, this, op);
+ bool hasFillImage = img && img->canRender(renderer()->style()->effectiveZoom());
+ if ((!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent())
+ boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, tx, ty, w, h, this, op);
else {
// We have a fill image that spans multiple lines.
// We need to adjust _tx and _ty by the width of all previous lines.
@@ -700,7 +667,7 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con
totalWidth += curr->width();
paintInfo.context->save();
paintInfo.context->clip(IntRect(tx, ty, width(), height()));
- object()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, startX, ty, totalWidth, h, this, op);
+ boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, startX, ty, totalWidth, h, this, op);
paintInfo.context->restore();
}
}
@@ -708,17 +675,17 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con
void InlineFlowBox::paintBoxShadow(GraphicsContext* context, RenderStyle* s, int tx, int ty, int w, int h)
{
if ((!prevLineBox() && !nextLineBox()) || !parent())
- object()->paintBoxShadow(context, tx, ty, w, h, s);
+ boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s);
else {
// FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't
// protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines
- object()->paintBoxShadow(context, tx, ty, w, h, s, includeLeftEdge(), includeRightEdge());
+ boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, includeLeftEdge(), includeRightEdge());
}
}
void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int tx, int ty)
{
- if (!object()->shouldPaintWithinRoot(paintInfo) || object()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
+ if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
return;
// Move x/y to our coordinates.
@@ -739,8 +706,8 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
// You can use p::first-line to specify a background. If so, the root line boxes for
// a line may actually have to paint a background.
- RenderStyle* styleToUse = object()->style(m_firstLine);
- if ((!parent() && m_firstLine && styleToUse != object()->style()) || (parent() && object()->hasBoxDecorations())) {
+ RenderStyle* styleToUse = renderer()->style(m_firstLine);
+ if ((!parent() && m_firstLine && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) {
// Shadow comes first and is behind the background and border.
if (styleToUse->boxShadow())
paintBoxShadow(context, styleToUse, tx, ty, w, h);
@@ -750,8 +717,8 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
// :first-line cannot be used to put borders on a line. Always paint borders with our
// non-first-line style.
- if (parent() && object()->style()->hasBorder()) {
- StyleImage* borderImage = object()->style()->borderImage().image();
+ if (parent() && renderer()->style()->hasBorder()) {
+ StyleImage* borderImage = renderer()->style()->borderImage().image();
bool hasBorderImage = borderImage && borderImage->canRender(styleToUse->effectiveZoom());
if (hasBorderImage && !borderImage->isLoaded())
return; // Don't paint anything while we wait for the image to load.
@@ -759,7 +726,7 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
// The simple case is where we either have no border image or we are the only box for this object. In those
// cases only a single call to draw is required.
if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
- object()->paintBorder(context, tx, ty, w, h, object()->style(), includeLeftEdge(), includeRightEdge());
+ boxModelObject()->paintBorder(context, tx, ty, w, h, renderer()->style(), includeLeftEdge(), includeRightEdge());
else {
// We have a border image that spans multiple lines.
// We need to adjust _tx and _ty by the width of all previous lines.
@@ -778,7 +745,7 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
totalWidth += curr->width();
context->save();
context->clip(IntRect(tx, ty, width(), height()));
- object()->paintBorder(context, startX, ty, totalWidth, h, object()->style());
+ boxModelObject()->paintBorder(context, startX, ty, totalWidth, h, renderer()->style());
context->restore();
}
}
@@ -787,7 +754,7 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int
void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty)
{
- if (!object()->shouldPaintWithinRoot(paintInfo) || object()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
+ if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
// Move x/y to our coordinates.
@@ -807,9 +774,9 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty
// Figure out if we need to push a transparency layer to render our mask.
bool pushTransparencyLayer = false;
- const NinePieceImage& maskNinePieceImage = object()->style()->maskBoxImage();
- StyleImage* maskBoxImage = object()->style()->maskBoxImage().image();
- if ((maskBoxImage && object()->style()->maskLayers()->hasImage()) || object()->style()->maskLayers()->next())
+ const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage();
+ StyleImage* maskBoxImage = renderer()->style()->maskBoxImage().image();
+ if ((maskBoxImage && renderer()->style()->maskLayers()->hasImage()) || renderer()->style()->maskLayers()->next())
pushTransparencyLayer = true;
CompositeOperator compositeOp = CompositeDestinationIn;
@@ -819,16 +786,16 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty
compositeOp = CompositeSourceOver;
}
- paintFillLayers(paintInfo, Color(), object()->style()->maskLayers(), my, mh, tx, ty, w, h, compositeOp);
+ paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), my, mh, tx, ty, w, h, compositeOp);
- bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(object()->style()->effectiveZoom());
+ bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer()->style()->effectiveZoom());
if (!hasBoxImage || !maskBoxImage->isLoaded())
return; // Don't paint anything while we wait for the image to load.
// The simple case is where we are the only box for this object. In those
// cases only a single call to draw is required.
if (!prevLineBox() && !nextLineBox()) {
- object()->paintNinePieceImage(paintInfo.context, tx, ty, w, h, object()->style(), maskNinePieceImage, compositeOp);
+ boxModelObject()->paintNinePieceImage(paintInfo.context, tx, ty, w, h, renderer()->style(), maskNinePieceImage, compositeOp);
} else {
// We have a mask image that spans multiple lines.
// We need to adjust _tx and _ty by the width of all previous lines.
@@ -841,7 +808,7 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty
totalWidth += curr->width();
paintInfo.context->save();
paintInfo.context->clip(IntRect(tx, ty, width(), height()));
- object()->paintNinePieceImage(paintInfo.context, startX, ty, totalWidth, h, object()->style(), maskNinePieceImage, compositeOp);
+ boxModelObject()->paintNinePieceImage(paintInfo.context, startX, ty, totalWidth, h, renderer()->style(), maskNinePieceImage, compositeOp);
paintInfo.context->restore();
}
@@ -857,7 +824,7 @@ static bool shouldDrawTextDecoration(RenderObject* obj)
if (curr->isText() && !curr->isBR()) {
if (!curr->style()->collapseWhiteSpace())
return true;
- Node* currElement = curr->element();
+ Node* currElement = curr->node();
if (!currElement)
return true;
if (!currElement->isTextNode())
@@ -873,8 +840,8 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
{
// Paint text decorations like underlines/overlines. We only do this if we aren't in quirks mode (i.e., in
// almost-strict mode or strict mode).
- if (object()->style()->htmlHacks() || !object()->shouldPaintWithinRoot(paintInfo) ||
- object()->style()->visibility() != VISIBLE)
+ if (renderer()->style()->htmlHacks() || !renderer()->shouldPaintWithinRoot(paintInfo) ||
+ renderer()->style()->visibility() != VISIBLE)
return;
// We don't want underlines or other decorations when we're trying to draw nothing but the selection as white text.
@@ -884,16 +851,16 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
GraphicsContext* context = paintInfo.context;
tx += m_x;
ty += m_y;
- RenderStyle* styleToUse = object()->style(m_firstLine);
+ RenderStyle* styleToUse = renderer()->style(m_firstLine);
int deco = parent() ? styleToUse->textDecoration() : styleToUse->textDecorationsInEffect();
if (deco != TDNONE &&
((!paintedChildren && ((deco & UNDERLINE) || (deco & OVERLINE))) || (paintedChildren && (deco & LINE_THROUGH))) &&
- shouldDrawTextDecoration(object())) {
+ shouldDrawTextDecoration(renderer())) {
int x = m_x + borderLeft() + paddingLeft();
int w = m_width - (borderLeft() + paddingLeft() + borderRight() + paddingRight());
RootInlineBox* rootLine = root();
if (rootLine->ellipsisBox()) {
- int ellipsisX = rootLine->ellipsisBox()->xPos();
+ int ellipsisX = rootLine->ellipsisBox()->x();
int ellipsisWidth = rootLine->ellipsisBox()->width();
// FIXME: Will need to work with RTL
@@ -914,9 +881,9 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
Color underline, overline, linethrough;
underline = overline = linethrough = styleToUse->color();
if (!parent())
- object()->getTextDecorationColors(deco, underline, overline, linethrough);
+ renderer()->getTextDecorationColors(deco, underline, overline, linethrough);
- bool isPrinting = object()->document()->printing();
+ bool isPrinting = renderer()->document()->printing();
context->setStrokeThickness(1.0f); // FIXME: We should improve this rule and not always just assume 1.
bool paintUnderline = deco & UNDERLINE && !paintedChildren;
@@ -925,13 +892,17 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
bool linesAreOpaque = !isPrinting && (!paintUnderline || underline.alpha() == 255) && (!paintOverline || overline.alpha() == 255) && (!paintLineThrough || linethrough.alpha() == 255);
+ int baselinePos = renderer()->style(m_firstLine)->font().ascent();
+ if (!isRootInlineBox())
+ baselinePos += borderTop() + paddingTop();
+
bool setClip = false;
int extraOffset = 0;
ShadowData* shadow = styleToUse->textShadow();
if (!linesAreOpaque && shadow && shadow->next) {
- IntRect clipRect(tx, ty, w, m_baseline + 2);
+ IntRect clipRect(tx, ty, w, baselinePos + 2);
for (ShadowData* s = shadow; s; s = s->next) {
- IntRect shadowRect(tx, ty, w, m_baseline + 2);
+ IntRect shadowRect(tx, ty, w, baselinePos + 2);
shadowRect.inflate(s->blur);
shadowRect.move(s->x, s->y);
clipRect.unite(shadowRect);
@@ -939,7 +910,7 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
}
context->save();
context->clip(clipRect);
- extraOffset += m_baseline + 2;
+ extraOffset += baselinePos + 2;
ty += extraOffset;
setClip = true;
}
@@ -959,16 +930,19 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int
if (paintUnderline) {
context->setStrokeColor(underline);
+ context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
- context->drawLineForText(IntPoint(tx, ty + m_baseline + 1), w, isPrinting);
+ context->drawLineForText(IntPoint(tx, ty + baselinePos + 1), w, isPrinting);
}
if (paintOverline) {
context->setStrokeColor(overline);
+ context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty), w, isPrinting);
}
if (paintLineThrough) {
context->setStrokeColor(linethrough);
- context->drawLineForText(IntPoint(tx, ty + 2 * m_baseline / 3), w, isPrinting);
+ context->setStrokeStyle(SolidStroke);
+ context->drawLineForText(IntPoint(tx, ty + 2 * baselinePos / 3), w, isPrinting);
}
} while (shadow);
diff --git a/WebCore/rendering/InlineFlowBox.h b/WebCore/rendering/InlineFlowBox.h
index 62f8f69..df75d06 100644
--- a/WebCore/rendering/InlineFlowBox.h
+++ b/WebCore/rendering/InlineFlowBox.h
@@ -25,9 +25,9 @@
namespace WebCore {
+class HitTestRequest;
class HitTestResult;
-
-struct HitTestRequest;
+class RenderLineBoxList;
class InlineFlowBox : public InlineRunBox {
public:
@@ -36,6 +36,9 @@ public:
, m_firstChild(0)
, m_lastChild(0)
, m_maxHorizontalVisualOverflow(0)
+ , m_includeLeftEdge(false)
+ , m_includeRightEdge(false)
+ , m_hasTextChildren(true)
#ifndef NDEBUG
, m_hasBadChildList(false)
#endif
@@ -52,9 +55,7 @@ public:
virtual ~InlineFlowBox();
#endif
- RenderFlow* flowObject();
-
- virtual bool isInlineFlowBox() { return true; }
+ virtual int height() const;
InlineFlowBox* prevFlowBox() const { return static_cast<InlineFlowBox*>(m_prevLine); }
InlineFlowBox* nextFlowBox() const { return static_cast<InlineFlowBox*>(m_nextLine); }
@@ -80,6 +81,10 @@ public:
virtual void attachLine();
virtual void adjustPosition(int dx, int dy);
+ virtual void extractLineBoxFromRenderObject();
+ virtual void attachLineBoxToRenderObject();
+ virtual void removeLineBoxFromRenderObject();
+
virtual void clearTruncation();
virtual void paintBoxDecorations(RenderObject::PaintInfo&, int tx, int ty);
@@ -93,17 +98,23 @@ public:
virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
- int marginBorderPaddingLeft();
- int marginBorderPaddingRight();
- int marginLeft();
- int marginRight();
- int borderLeft() { if (includeLeftEdge()) return renderBox()->borderLeft(); return 0; }
- int borderRight() { if (includeRightEdge()) return renderBox()->borderRight(); return 0; }
- int paddingLeft() { if (includeLeftEdge()) return renderBox()->paddingLeft(); return 0; }
- int paddingRight() { if (includeRightEdge()) return renderBox()->paddingRight(); return 0; }
-
- bool includeLeftEdge() { return m_includeLeftEdge; }
- bool includeRightEdge() { return m_includeRightEdge; }
+ virtual RenderLineBoxList* rendererLineBoxes() const;
+
+ int marginBorderPaddingLeft() const { return marginLeft() + borderLeft() + paddingLeft(); }
+ int marginBorderPaddingRight() const { return marginRight() + borderRight() + paddingRight(); }
+ int marginLeft() const { if (includeLeftEdge()) return boxModelObject()->marginLeft(); return 0; }
+ int marginRight() const { if (includeRightEdge()) return boxModelObject()->marginRight(); return 0; }
+ int borderLeft() const { if (includeLeftEdge()) return renderer()->style()->borderLeftWidth(); return 0; }
+ int borderRight() const { if (includeRightEdge()) return renderer()->style()->borderRightWidth(); return 0; }
+ int borderTop() const { return renderer()->style()->borderTopWidth(); }
+ int borderBottom() const { return renderer()->style()->borderBottomWidth(); }
+ int paddingLeft() const { if (includeLeftEdge()) return boxModelObject()->paddingLeft(); return 0; }
+ int paddingRight() const { if (includeRightEdge()) return boxModelObject()->paddingRight(); return 0; }
+ int paddingTop() const { return boxModelObject()->paddingTop(); }
+ int paddingBottom() const { return boxModelObject()->paddingBottom(); }
+
+ bool includeLeftEdge() const { return m_includeLeftEdge; }
+ bool includeRightEdge() const { return m_includeRightEdge; }
void setEdges(bool includeLeft, bool includeRight)
{
m_includeLeftEdge = includeLeft;
@@ -122,11 +133,10 @@ public:
int maxPositionTop, int maxPositionBottom);
void placeBoxesVertically(int y, int maxHeight, int maxAscent, bool strictMode,
int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom);
- void shrinkBoxesWithNoTextChildren(int topPosition, int bottomPosition);
virtual void setVerticalOverflowPositions(int /*top*/, int /*bottom*/) { }
virtual void setVerticalSelectionPositions(int /*top*/, int /*bottom*/) { }
- int maxHorizontalVisualOverflow() const { return m_maxHorizontalVisualOverflow; }
+ short maxHorizontalVisualOverflow() const { return m_maxHorizontalVisualOverflow; }
void removeChild(InlineBox* child);
@@ -135,13 +145,21 @@ public:
virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool&);
+ bool hasTextChildren() const { return m_hasTextChildren; }
+
void checkConsistency() const;
void setHasBadChildList();
private:
+ virtual bool isInlineFlowBox() const { return true; }
+
InlineBox* m_firstChild;
InlineBox* m_lastChild;
- int m_maxHorizontalVisualOverflow;
+ short m_maxHorizontalVisualOverflow;
+
+ bool m_includeLeftEdge : 1;
+ bool m_includeRightEdge : 1;
+ bool m_hasTextChildren : 1;
#ifndef NDEBUG
bool m_hasBadChildList;
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index ca965e9..809c071 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -41,6 +41,11 @@ using namespace std;
namespace WebCore {
+int InlineTextBox::height() const
+{
+ return m_treatAsText ? renderer()->style(m_firstLine)->font().height() : 0;
+}
+
int InlineTextBox::selectionTop()
{
return root()->selectionTop();
@@ -60,10 +65,10 @@ bool InlineTextBox::isSelected(int startPos, int endPos) const
RenderObject::SelectionState InlineTextBox::selectionState()
{
- RenderObject::SelectionState state = object()->selectionState();
+ RenderObject::SelectionState state = renderer()->selectionState();
if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
int startPos, endPos;
- object()->selectionStartEnd(startPos, endPos);
+ renderer()->selectionStartEnd(startPos, endPos);
// The position after a hard line break is considered to be past its end.
int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
@@ -92,7 +97,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
if (sPos >= ePos)
return IntRect();
- RenderText* textObj = textObject();
+ RenderText* textObj = textRenderer();
int selTop = selectionTop();
int selHeight = selectionHeight();
const Font& f = textObj->style(m_firstLine)->font();
@@ -108,7 +113,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
void InlineTextBox::deleteLine(RenderArena* arena)
{
- toRenderText(m_object)->removeTextBox(this);
+ toRenderText(renderer())->removeTextBox(this);
destroy(arena);
}
@@ -117,7 +122,7 @@ void InlineTextBox::extractLine()
if (m_extracted)
return;
- toRenderText(m_object)->extractTextBox(this);
+ toRenderText(renderer())->extractTextBox(this);
}
void InlineTextBox::attachLine()
@@ -125,7 +130,7 @@ void InlineTextBox::attachLine()
if (!m_extracted)
return;
- toRenderText(m_object)->attachTextBox(this);
+ toRenderText(renderer())->attachTextBox(this);
}
int InlineTextBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox)
@@ -137,36 +142,40 @@ int InlineTextBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth,
int ellipsisX = ltr ? blockEdge - ellipsisWidth : blockEdge + ellipsisWidth;
- // For LTR, if the left edge of the ellipsis is to the left of our text run, then we are the run that will get truncated.
- if (ltr) {
- if (ellipsisX <= m_x) {
- // Too far. Just set full truncation, but return -1 and let the ellipsis just be placed at the edge of the box.
- m_truncation = cFullTruncation;
- foundBox = true;
- return -1;
- }
+ // Criteria for full truncation:
+ // LTR: the left edge of the ellipsis is to the left of our text run.
+ // RTL: the right edge of the ellipsis is to the right of our text run.
+ bool ltrFullTruncation = ltr && ellipsisX <= m_x;
+ bool rtlFullTruncation = !ltr && ellipsisX >= (m_x + m_width);
+ if (ltrFullTruncation || rtlFullTruncation) {
+ // Too far. Just set full truncation, but return -1 and let the ellipsis just be placed at the edge of the box.
+ m_truncation = cFullTruncation;
+ foundBox = true;
+ return -1;
+ }
- if (ellipsisX < m_x + m_width) {
- if (direction() == RTL)
- return -1; // FIXME: Support LTR truncation when the last run is RTL someday.
+ bool ltrEllipsisWithinBox = ltr && (ellipsisX < m_x + m_width);
+ bool rtlEllipsisWithinBox = !ltr && (ellipsisX > m_x);
+ if (ltrEllipsisWithinBox || rtlEllipsisWithinBox) {
+ if ((ltr && direction() == RTL) || (!ltr && direction() == LTR))
+ return -1; // FIXME: Support cases in which the last run's directionality differs from the context.
- foundBox = true;
+ foundBox = true;
- int offset = offsetForPosition(ellipsisX, false);
- if (offset == 0) {
- // No characters should be rendered. Set ourselves to full truncation and place the ellipsis at the min of our start
- // and the ellipsis edge.
- m_truncation = cFullTruncation;
- return min(ellipsisX, m_x);
- }
-
- // Set the truncation index on the text run. The ellipsis needs to be placed just after the last visible character.
- m_truncation = offset;
- return m_x + toRenderText(m_object)->width(m_start, offset, textPos(), m_firstLine);
+ int offset = offsetForPosition(ellipsisX, false);
+ if (offset == 0) {
+ // No characters should be rendered. Set ourselves to full truncation and place the ellipsis at the min of our start
+ // and the ellipsis edge.
+ m_truncation = cFullTruncation;
+ return min(ellipsisX, m_x);
}
- }
- else {
- // FIXME: Support RTL truncation someday, including both modes (when the leftmost run on the line is either RTL or LTR)
+
+ // Set the truncation index on the text run. The ellipsis needs to be placed just after the last visible character.
+ m_truncation = offset;
+ if (ltr)
+ return m_x + toRenderText(renderer())->width(m_start, offset, textPos(), m_firstLine);
+ else
+ return m_x + (m_width - toRenderText(renderer())->width(m_start, offset, textPos(), m_firstLine)) - ellipsisWidth;
}
return -1;
}
@@ -216,7 +225,7 @@ void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, con
bool InlineTextBox::isLineBreak() const
{
- return object()->isBR() || (object()->style()->preserveNewline() && len() == 1 && (*textObject()->text())[start()] == '\n');
+ return renderer()->isBR() || (renderer()->style()->preserveNewline() && len() == 1 && (*textRenderer()->text())[start()] == '\n');
}
bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, int x, int y, int tx, int ty)
@@ -224,9 +233,9 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
if (isLineBreak())
return false;
- IntRect rect(tx + m_x, ty + m_y, m_width, m_height);
+ IntRect rect(tx + m_x, ty + m_y, m_width, height());
if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.contains(x, y)) {
- object()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
return false;
@@ -278,7 +287,7 @@ static void paintTextWithShadows(GraphicsContext* context, const Font& font, con
void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
{
- if (isLineBreak() || !object()->shouldPaintWithinRoot(paintInfo) || object()->style()->visibility() != VISIBLE ||
+ if (isLineBreak() || !renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE ||
m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline)
return;
@@ -289,7 +298,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (xPos >= paintInfo.rect.right() || xPos + w <= paintInfo.rect.x())
return;
- bool isPrinting = textObject()->document()->printing();
+ bool isPrinting = textRenderer()->document()->printing();
// Determine whether or not we're selected.
bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone;
@@ -300,11 +309,11 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
GraphicsContext* context = paintInfo.context;
// Determine whether or not we have composition underlines to draw.
- bool containsComposition = object()->document()->frame()->editor()->compositionNode() == object()->node();
- bool useCustomUnderlines = containsComposition && object()->document()->frame()->editor()->compositionUsesCustomUnderlines();
+ bool containsComposition = renderer()->node() && renderer()->document()->frame()->editor()->compositionNode() == renderer()->node();
+ bool useCustomUnderlines = containsComposition && renderer()->document()->frame()->editor()->compositionUsesCustomUnderlines();
// Set our font.
- RenderStyle* styleToUse = object()->style(m_firstLine);
+ RenderStyle* styleToUse = renderer()->style(m_firstLine);
int d = styleToUse->textDecorationsInEffect();
const Font& font = styleToUse->font();
@@ -319,8 +328,8 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
if (containsComposition && !useCustomUnderlines)
paintCompositionBackground(context, tx, ty, styleToUse, font,
- object()->document()->frame()->editor()->compositionStart(),
- object()->document()->frame()->editor()->compositionEnd());
+ renderer()->document()->frame()->editor()->compositionStart(),
+ renderer()->document()->frame()->editor()->compositionEnd());
paintDocumentMarkers(context, tx, ty, styleToUse, font, true);
@@ -367,14 +376,14 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
ShadowData* selectionShadow = textShadow;
if (haveSelection) {
// Check foreground color first.
- Color foreground = paintInfo.forceBlackText ? Color::black : object()->selectionForegroundColor();
+ Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor();
if (foreground.isValid() && foreground != selectionFillColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionFillColor = foreground;
}
- if (RenderStyle* pseudoStyle = object()->getCachedPseudoStyle(RenderStyle::SELECTION)) {
+ if (RenderStyle* pseudoStyle = renderer()->getCachedPseudoStyle(SELECTION)) {
ShadowData* shadow = paintInfo.forceBlackText ? 0 : pseudoStyle->textShadow();
if (shadow != selectionShadow) {
if (!paintSelectedTextOnly)
@@ -400,8 +409,9 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
}
}
- IntPoint textOrigin(m_x + tx, m_y + ty + m_baseline);
- TextRun textRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered());
+ int baseline = renderer()->style(m_firstLine)->font().ascent();
+ IntPoint textOrigin(m_x + tx, m_y + ty + baseline);
+ TextRun textRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || styleToUse->visuallyOrdered());
int sPos = 0;
int ePos = 0;
@@ -447,7 +457,7 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
paintDocumentMarkers(context, tx, ty, styleToUse, font, false);
if (useCustomUnderlines) {
- const Vector<CompositionUnderline>& underlines = object()->document()->frame()->editor()->customCompositionUnderlines();
+ const Vector<CompositionUnderline>& underlines = renderer()->document()->frame()->editor()->customCompositionUnderlines();
size_t numUnderlines = underlines.size();
for (size_t index = 0; index < numUnderlines; ++index) {
@@ -476,14 +486,14 @@ void InlineTextBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
{
int startPos, endPos;
- if (object()->selectionState() == RenderObject::SelectionInside) {
+ if (renderer()->selectionState() == RenderObject::SelectionInside) {
startPos = 0;
- endPos = textObject()->textLength();
+ endPos = textRenderer()->textLength();
} else {
- textObject()->selectionStartEnd(startPos, endPos);
- if (object()->selectionState() == RenderObject::SelectionStart)
- endPos = textObject()->textLength();
- else if (object()->selectionState() == RenderObject::SelectionEnd)
+ textRenderer()->selectionStartEnd(startPos, endPos);
+ if (renderer()->selectionState() == RenderObject::SelectionStart)
+ endPos = textRenderer()->textLength();
+ else if (renderer()->selectionState() == RenderObject::SelectionEnd)
startPos = 0;
}
@@ -500,7 +510,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, Ren
return;
Color textColor = style->color();
- Color c = object()->selectionBackgroundColor();
+ Color c = renderer()->selectionBackgroundColor();
if (!c.isValid() || c.alpha() == 0)
return;
@@ -514,7 +524,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, int tx, int ty, Ren
int y = selectionTop();
int h = selectionHeight();
context->clip(IntRect(m_x + tx, y + ty, m_width, h));
- context->drawHighlightForText(font, TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd,
+ context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
direction() == RTL, m_dirOverride || style->visuallyOrdered()),
IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);
context->restore();
@@ -537,7 +547,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx,
int y = selectionTop();
int h = selectionHeight();
- context->drawHighlightForText(font, TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd,
+ context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd,
direction() == RTL, m_dirOverride || style->visuallyOrdered()),
IntPoint(m_x + tx, y + ty), h, c, sPos, ePos);
context->restore();
@@ -547,7 +557,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, int tx,
void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& type)
{
- Frame* frame = object()->document()->frame();
+ Frame* frame = renderer()->document()->frame();
if (!frame)
return;
Page* page = frame->page();
@@ -555,10 +565,10 @@ void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& typ
return;
RootInlineBox* r = root();
- FloatRect rootRect(tx + r->xPos(), ty + selectionTop(), r->width(), selectionHeight());
- FloatRect textRect(tx + xPos(), rootRect.y(), width(), rootRect.height());
+ FloatRect rootRect(tx + r->x(), ty + selectionTop(), r->width(), selectionHeight());
+ FloatRect textRect(tx + x(), rootRect.y(), width(), rootRect.height());
- page->chrome()->client()->paintCustomHighlight(object()->node(), type, textRect, rootRect, true, false);
+ page->chrome()->client()->paintCustomHighlight(renderer()->node(), type, textRect, rootRect, true, false);
}
#endif
@@ -570,27 +580,33 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
if (m_truncation == cFullTruncation)
return;
-
- int width = (m_truncation == cNoTruncation) ? m_width
- : toRenderText(m_object)->width(m_start, m_truncation, textPos(), m_firstLine);
+
+ int width = m_width;
+ if (m_truncation != cNoTruncation) {
+ width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), m_firstLine);
+ if (direction() == RTL)
+ tx += (m_width - width);
+ }
// Get the text decoration colors.
Color underline, overline, linethrough;
- object()->getTextDecorationColors(deco, underline, overline, linethrough, true);
+ renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true);
// Use a special function for underlines to get the positioning exactly right.
- bool isPrinting = textObject()->document()->printing();
+ bool isPrinting = textRenderer()->document()->printing();
context->setStrokeThickness(1.0f); // FIXME: We should improve this rule and not always just assume 1.
bool linesAreOpaque = !isPrinting && (!(deco & UNDERLINE) || underline.alpha() == 255) && (!(deco & OVERLINE) || overline.alpha() == 255) && (!(deco & LINE_THROUGH) || linethrough.alpha() == 255);
+ int baseline = renderer()->style(m_firstLine)->font().ascent();
+
bool setClip = false;
int extraOffset = 0;
if (!linesAreOpaque && shadow && shadow->next) {
context->save();
- IntRect clipRect(tx, ty, width, m_baseline + 2);
+ IntRect clipRect(tx, ty, width, baseline + 2);
for (ShadowData* s = shadow; s; s = s->next) {
- IntRect shadowRect(tx, ty, width, m_baseline + 2);
+ IntRect shadowRect(tx, ty, width, baseline + 2);
shadowRect.inflate(s->blur);
shadowRect.move(s->x, s->y);
clipRect.unite(shadowRect);
@@ -598,12 +614,13 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
}
context->save();
context->clip(clipRect);
- extraOffset += m_baseline + 2;
+ extraOffset += baseline + 2;
ty += extraOffset;
setClip = true;
}
bool setShadow = false;
+
do {
if (shadow) {
if (!shadow->next) {
@@ -618,16 +635,19 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
if (deco & UNDERLINE) {
context->setStrokeColor(underline);
+ context->setStrokeStyle(SolidStroke);
// Leave one pixel of white between the baseline and the underline.
- context->drawLineForText(IntPoint(tx, ty + m_baseline + 1), width, isPrinting);
+ context->drawLineForText(IntPoint(tx, ty + baseline + 1), width, isPrinting);
}
if (deco & OVERLINE) {
context->setStrokeColor(overline);
+ context->setStrokeStyle(SolidStroke);
context->drawLineForText(IntPoint(tx, ty), width, isPrinting);
}
if (deco & LINE_THROUGH) {
context->setStrokeColor(linethrough);
- context->drawLineForText(IntPoint(tx, ty + 2 * m_baseline / 3), width, isPrinting);
+ context->setStrokeStyle(SolidStroke);
+ context->drawLineForText(IntPoint(tx, ty + 2 * baseline / 3), width, isPrinting);
}
} while (shadow);
@@ -640,7 +660,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, int tx, int ty, in
void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, int ty, DocumentMarker marker, RenderStyle* style, const Font& font, bool grammar)
{
// Never print spelling/grammar markers (5327887)
- if (textObject()->document()->printing())
+ if (textRenderer()->document()->printing())
return;
if (m_truncation == cFullTruncation)
@@ -667,7 +687,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
// Calculate start & width
IntPoint startPoint(tx + m_x, ty + selectionTop());
- TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
int h = selectionHeight();
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, startPosition, endPosition));
@@ -677,7 +697,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
// Store rendered rects for bad grammar markers, so we can hit-test against it elsewhere in order to
// display a toolTip. We don't do this for misspelling markers.
if (grammar)
- object()->document()->setRenderedRectForMarker(object()->node(), marker, markerRect);
+ renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
}
// IMPORTANT: The misspelling underline is not considered when calculating the text bounds, so we have to
@@ -687,14 +707,15 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, int tx, in
// So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
// we pin to two pixels under the baseline.
int lineThickness = cMisspellingLineThickness;
- int descent = m_height - m_baseline;
+ int baseline = renderer()->style(m_firstLine)->font().ascent();
+ int descent = height() - baseline;
int underlineOffset;
if (descent <= (2 + lineThickness)) {
- // place the underline at the very bottom of the text in small/medium fonts
- underlineOffset = m_height - lineThickness;
+ // Place the underline at the very bottom of the text in small/medium fonts.
+ underlineOffset = height() - lineThickness;
} else {
- // in larger fonts, tho, place the underline up near the baseline to prevent big gap
- underlineOffset = m_baseline + 2;
+ // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
+ underlineOffset = baseline + 2;
}
pt->drawLineForMisspellingOrBadGrammar(IntPoint(tx + m_x + start, ty + m_y + underlineOffset), width, grammar);
}
@@ -708,15 +729,15 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
int sPos = max(marker.startOffset - m_start, (unsigned)0);
int ePos = min(marker.endOffset - m_start, (unsigned)m_len);
- TextRun run(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
+ TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered());
IntPoint startPoint = IntPoint(m_x + tx, y + ty);
// Always compute and store the rect associated with this marker
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, h, sPos, ePos));
- object()->document()->setRenderedRectForMarker(object()->node(), marker, markerRect);
+ renderer()->document()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
// Optionally highlight the text
- if (object()->document()->frame()->markedTextMatchesAreHighlighted()) {
+ if (renderer()->document()->frame()->markedTextMatchesAreHighlighted()) {
Color color = theme()->platformTextSearchHighlightColor();
pt->save();
updateGraphicsContext(pt, color, color, 0); // Don't draw text at all!
@@ -728,7 +749,10 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, int tx, int ty, Do
void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, int tx, int ty, RenderStyle* style, const Font& font, bool background)
{
- Vector<DocumentMarker> markers = object()->document()->markersForNode(object()->node());
+ if (!renderer()->node())
+ return;
+
+ Vector<DocumentMarker> markers = renderer()->document()->markersForNode(renderer()->node());
Vector<DocumentMarker>::iterator markerIt = markers.begin();
// Give any document markers that touch this run a chance to draw before the text has been drawn.
@@ -797,7 +821,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int
if (paintStart <= underline.startOffset) {
paintStart = underline.startOffset;
useWholeWidth = false;
- start = toRenderText(m_object)->width(m_start, paintStart - m_start, textPos(), m_firstLine);
+ start = toRenderText(renderer())->width(m_start, paintStart - m_start, textPos(), m_firstLine);
}
if (paintEnd != underline.endOffset) { // end points at the last char, not past it
paintEnd = min(paintEnd, (unsigned)underline.endOffset);
@@ -808,14 +832,15 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int
useWholeWidth = false;
}
if (!useWholeWidth) {
- width = toRenderText(m_object)->width(paintStart, paintEnd - paintStart, textPos() + start, m_firstLine);
+ width = toRenderText(renderer())->width(paintStart, paintEnd - paintStart, textPos() + start, m_firstLine);
}
// Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.
// All other marked text underlines are 1px thick.
// If there's not enough space the underline will touch or overlap characters.
int lineThickness = 1;
- if (underline.thick && m_height - m_baseline >= 2)
+ int baseline = renderer()->style(m_firstLine)->font().ascent();
+ if (underline.thick && height() - baseline >= 2)
lineThickness = 2;
// We need to have some space between underlines of subsequent clauses, because some input methods do not use different underline styles for those.
@@ -825,7 +850,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, int tx, int
ctx->setStrokeColor(underline.color);
ctx->setStrokeThickness(lineThickness);
- ctx->drawLineForText(IntPoint(tx + start, ty + m_height - lineThickness), width, textObject()->document()->printing());
+ ctx->drawLineForText(IntPoint(tx + start, ty + height() - lineThickness), width, textRenderer()->document()->printing());
}
int InlineTextBox::caretMinOffset() const
@@ -845,12 +870,12 @@ unsigned InlineTextBox::caretMaxRenderedOffset() const
int InlineTextBox::textPos() const
{
- if (xPos() == 0)
+ if (x() == 0)
return 0;
- RenderBlock *blockElement = object()->containingBlock();
- return direction() == RTL ? xPos() - blockElement->borderRight() - blockElement->paddingRight()
- : xPos() - blockElement->borderLeft() - blockElement->paddingLeft();
+ RenderBlock *blockElement = renderer()->containingBlock();
+ return direction() == RTL ? x() - blockElement->borderRight() - blockElement->paddingRight()
+ : x() - blockElement->borderLeft() - blockElement->paddingLeft();
}
int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const
@@ -858,10 +883,10 @@ int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const
if (isLineBreak())
return 0;
- RenderText* text = toRenderText(m_object);
+ RenderText* text = toRenderText(renderer());
RenderStyle *style = text->style(m_firstLine);
const Font* f = &style->font();
- return f->offsetForPosition(TextRun(textObject()->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()),
+ return f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride || style->visuallyOrdered()),
_x - m_x, includePartialGlyphs);
}
@@ -873,12 +898,12 @@ int InlineTextBox::positionForOffset(int offset) const
if (isLineBreak())
return m_x;
- RenderText* text = toRenderText(m_object);
+ RenderText* text = toRenderText(renderer());
const Font& f = text->style(m_firstLine)->font();
int from = direction() == RTL ? offset - m_start : 0;
int to = direction() == RTL ? m_len : offset - m_start;
// FIXME: Do we need to add rightBearing here?
- return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textObject()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride),
+ return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_toAdd, direction() == RTL, m_dirOverride),
IntPoint(m_x, 0), 0, from, to)).right();
}
diff --git a/WebCore/rendering/InlineTextBox.h b/WebCore/rendering/InlineTextBox.h
index 0c2dd8a..222e973 100644
--- a/WebCore/rendering/InlineTextBox.h
+++ b/WebCore/rendering/InlineTextBox.h
@@ -24,7 +24,7 @@
#define InlineTextBox_h
#include "InlineRunBox.h"
-#include "RenderText.h" // so textObject() can be inline
+#include "RenderText.h" // so textRenderer() can be inline
namespace WebCore {
@@ -50,6 +50,8 @@ public:
InlineTextBox* nextTextBox() const { return static_cast<InlineTextBox*>(nextLineBox()); }
InlineTextBox* prevTextBox() const { return static_cast<InlineTextBox*>(prevLineBox()); }
+ virtual int height() const;
+
unsigned start() const { return m_start; }
unsigned end() const { return m_len ? m_start + m_len - 1 : m_start; }
unsigned len() const { return m_len; }
@@ -73,7 +75,7 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty);
public:
- RenderText* textObject() const;
+ RenderText* textRenderer() const;
private:
virtual void deleteLine(RenderArena*);
@@ -135,9 +137,9 @@ private:
void paintTextMatchMarker(GraphicsContext*, int tx, int ty, DocumentMarker, RenderStyle*, const Font&);
};
-inline RenderText* InlineTextBox::textObject() const
+inline RenderText* InlineTextBox::textRenderer() const
{
- return toRenderText(m_object);
+ return toRenderText(renderer());
}
} // namespace WebCore
diff --git a/WebCore/rendering/LayoutState.cpp b/WebCore/rendering/LayoutState.cpp
index 6c196ac..883f74d 100644
--- a/WebCore/rendering/LayoutState.cpp
+++ b/WebCore/rendering/LayoutState.cpp
@@ -27,6 +27,7 @@
#include "LayoutState.h"
#include "RenderArena.h"
+#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderView.h"
@@ -52,8 +53,10 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const IntSize&
if (renderer->hasLayer())
m_offset += renderer->layer()->relativePositionOffset();
} else if (renderer->isPositioned() && !fixed) {
- if (RenderObject* container = renderer->container())
- m_offset += renderer->offsetForPositionedInContainer(container);
+ if (RenderObject* container = renderer->container()) {
+ if (container->isRelPositioned() && container->isRenderInline())
+ m_offset += toRenderInline(container)->relativePositionedInlineOffset(renderer);
+ }
}
m_clipped = !fixed && prev->m_clipped;
diff --git a/WebCore/rendering/ListMarkerBox.cpp b/WebCore/rendering/ListMarkerBox.cpp
index 0455eae..6089ebd 100644
--- a/WebCore/rendering/ListMarkerBox.cpp
+++ b/WebCore/rendering/ListMarkerBox.cpp
@@ -39,7 +39,7 @@ ListMarkerBox::ListMarkerBox(RenderObject* obj)
bool ListMarkerBox::isText() const
{
- return static_cast<RenderListMarker*>(object())->isText();
+ return static_cast<RenderListMarker*>(renderer())->isText();
}
} // namespace WebCore
diff --git a/WebCore/rendering/MediaControlElements.cpp b/WebCore/rendering/MediaControlElements.cpp
index 8ad2bd6..d84e9ad 100644
--- a/WebCore/rendering/MediaControlElements.cpp
+++ b/WebCore/rendering/MediaControlElements.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -68,13 +68,22 @@ MediaControlShadowRootElement::MediaControlShadowRootElement(Document* doc, HTML
setInDocument(true);
}
+void MediaControlShadowRootElement::updateStyle()
+{
+ if (renderer()) {
+ RenderStyle* timelineContainerStyle = m_mediaElement->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER);
+ renderer()->setStyle(timelineContainerStyle);
+ }
+}
+
// ----------------------------
-MediaTextDisplayElement::MediaTextDisplayElement(Document* doc, RenderStyle::PseudoId pseudo, HTMLMediaElement* mediaElement)
+MediaTextDisplayElement::MediaTextDisplayElement(Document* doc, PseudoId pseudo, HTMLMediaElement* mediaElement)
: HTMLDivElement(divTag, doc)
, m_mediaElement(mediaElement)
+ , m_pseudoStyleId(pseudo)
{
- RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(pseudo);
+ RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId);
RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style);
if (renderer) {
setRenderer(renderer);
@@ -97,19 +106,28 @@ void MediaTextDisplayElement::update()
renderer()->updateFromElement();
}
+void MediaTextDisplayElement::updateStyle()
+{
+ if (renderer() && m_mediaElement->renderer()) {
+ RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId);
+ renderer()->setStyle(style);
+ }
+}
+
MediaTimeDisplayElement::MediaTimeDisplayElement(Document* doc, HTMLMediaElement* element, bool currentTime)
- : MediaTextDisplayElement(doc, currentTime ? RenderStyle::MEDIA_CONTROLS_CURRENT_TIME_DISPLAY : RenderStyle::MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, element)
+ : MediaTextDisplayElement(doc, currentTime ? MEDIA_CONTROLS_CURRENT_TIME_DISPLAY : MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, element)
{
}
// ----------------------------
-MediaControlInputElement::MediaControlInputElement(Document* doc, RenderStyle::PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement)
+MediaControlInputElement::MediaControlInputElement(Document* doc, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement)
: HTMLInputElement(inputTag, doc)
, m_mediaElement(mediaElement)
+ , m_pseudoStyleId(pseudo)
{
setInputType(type);
- RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(pseudo);
+ RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId);
RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style);
if (renderer) {
setRenderer(renderer);
@@ -131,6 +149,14 @@ void MediaControlInputElement::update()
renderer()->updateFromElement();
}
+void MediaControlInputElement::updateStyle()
+{
+ if (renderer() && m_mediaElement->renderer()) {
+ RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId);
+ renderer()->setStyle(style);
+ }
+}
+
bool MediaControlInputElement::hitTest(const IntPoint& absPoint)
{
if (renderer() && renderer()->style()->hasAppearance())
@@ -142,7 +168,7 @@ bool MediaControlInputElement::hitTest(const IntPoint& absPoint)
// ----------------------------
MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document* doc, HTMLMediaElement* element)
- : MediaControlInputElement(doc, RenderStyle::MEDIA_CONTROLS_MUTE_BUTTON, "button", element)
+ : MediaControlInputElement(doc, MEDIA_CONTROLS_MUTE_BUTTON, "button", element)
{
}
@@ -158,18 +184,14 @@ void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
// ----------------------------
MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document* doc, HTMLMediaElement* element)
- : MediaControlInputElement(doc, RenderStyle::MEDIA_CONTROLS_PLAY_BUTTON, "button", element)
+ : MediaControlInputElement(doc, MEDIA_CONTROLS_PLAY_BUTTON, "button", element)
{
}
void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == eventNames().clickEvent) {
- ExceptionCode ec;
- if (m_mediaElement->canPlay())
- m_mediaElement->play(ec);
- else
- m_mediaElement->pause(ec);
+ m_mediaElement->togglePlayState();
event->setDefaultHandled();
}
HTMLInputElement::defaultEventHandler(event);
@@ -178,7 +200,7 @@ void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
// ----------------------------
MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document* doc, HTMLMediaElement* element, bool forward)
- : MediaControlInputElement(doc, forward ? RenderStyle::MEDIA_CONTROLS_SEEK_FORWARD_BUTTON : RenderStyle::MEDIA_CONTROLS_SEEK_BACK_BUTTON, "button", element)
+ : MediaControlInputElement(doc, forward ? MEDIA_CONTROLS_SEEK_FORWARD_BUTTON : MEDIA_CONTROLS_SEEK_BACK_BUTTON, "button", element)
, m_forward(forward)
, m_seeking(false)
, m_capturing(false)
@@ -193,8 +215,7 @@ void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
m_capturing = true;
frame->eventHandler()->setCapturingMouseEventsNode(this);
}
- ExceptionCode ec;
- m_mediaElement->pause(ec);
+ m_mediaElement->pause();
m_seekTimer.startRepeating(cSeekRepeatDelay);
event->setDefaultHandled();
} else if (event->type() == eventNames().mouseupEvent) {
@@ -228,40 +249,34 @@ void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonE
// ----------------------------
MediaControlTimelineElement::MediaControlTimelineElement(Document* doc, HTMLMediaElement* element)
- : MediaControlInputElement(doc, RenderStyle::MEDIA_CONTROLS_TIMELINE, "range", element)
+ : MediaControlInputElement(doc, MEDIA_CONTROLS_TIMELINE, "range", element)
{
setAttribute(precisionAttr, "float");
}
void MediaControlTimelineElement::defaultEventHandler(Event* event)
{
- RenderSlider* slider = static_cast<RenderSlider*>(renderer());
- bool oldInDragMode = slider && slider->inDragMode();
- float oldTime = narrowPrecisionToFloat(value().toDouble());
- bool oldEnded = m_mediaElement->ended();
+ if (event->type() == eventNames().mousedownEvent)
+ m_mediaElement->beginScrubbing();
HTMLInputElement::defaultEventHandler(event);
- float time = narrowPrecisionToFloat(value().toDouble());
- if (oldTime != time || event->type() == eventNames().inputEvent) {
- ExceptionCode ec;
- m_mediaElement->setCurrentTime(time, ec);
+ if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent ) {
+ return;
}
- // Media element stays in non-paused state when it reaches end. If the slider is now dragged
- // to some other position the playback resumes which does not match usual media player UIs.
- // Get the expected behavior by pausing explicitly in this case.
- if (oldEnded && !m_mediaElement->ended() && !m_mediaElement->paused()) {
+ float time = narrowPrecisionToFloat(value().toDouble());
+ if (time != m_mediaElement->currentTime()) {
ExceptionCode ec;
- m_mediaElement->pause(ec);
+ m_mediaElement->setCurrentTime(time, ec);
}
- // Pause playback during drag, but do it without using DOM API which would generate events
- bool inDragMode = slider && slider->inDragMode();
- if (inDragMode != oldInDragMode)
- m_mediaElement->setPausedInternal(inDragMode);
- if (inDragMode)
+ RenderSlider* slider = static_cast<RenderSlider*>(renderer());
+ if (slider && slider->inDragMode())
static_cast<RenderMedia*>(m_mediaElement->renderer())->updateTimeDisplay();
+
+ if (event->type() == eventNames().mouseupEvent)
+ m_mediaElement->endScrubbing();
}
void MediaControlTimelineElement::update(bool updateDuration)
@@ -276,7 +291,7 @@ void MediaControlTimelineElement::update(bool updateDuration)
// ----------------------------
MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document* doc, HTMLMediaElement* element)
- : MediaControlInputElement(doc, RenderStyle::MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element)
+ : MediaControlInputElement(doc, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element)
{
}
diff --git a/WebCore/rendering/MediaControlElements.h b/WebCore/rendering/MediaControlElements.h
index c1c9574..fa0fb30 100644
--- a/WebCore/rendering/MediaControlElements.h
+++ b/WebCore/rendering/MediaControlElements.h
@@ -56,6 +56,8 @@ public:
virtual bool isShadowNode() const { return true; }
virtual Node* shadowParentNode() { return m_mediaElement; }
+
+ void updateStyle();
private:
HTMLMediaElement* m_mediaElement;
@@ -66,11 +68,13 @@ private:
class MediaTextDisplayElement : public HTMLDivElement
{
public:
- MediaTextDisplayElement(Document*, RenderStyle::PseudoId, HTMLMediaElement*);
+ MediaTextDisplayElement(Document*, PseudoId, HTMLMediaElement*);
void attachToParent(Element*);
void update();
+ void updateStyle();
protected:
HTMLMediaElement* m_mediaElement;
+ PseudoId m_pseudoStyleId;
};
// ----------------------------
@@ -84,12 +88,14 @@ public:
class MediaControlInputElement : public HTMLInputElement {
public:
- MediaControlInputElement(Document*, RenderStyle::PseudoId, const String& type, HTMLMediaElement*);
+ MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*);
void attachToParent(Element*);
void update();
+ void updateStyle();
bool hitTest(const IntPoint& absPoint);
protected:
HTMLMediaElement* m_mediaElement;
+ PseudoId m_pseudoStyleId;
};
// ----------------------------
diff --git a/WebCore/rendering/PointerEventsHitRules.h b/WebCore/rendering/PointerEventsHitRules.h
index e2dae3b..3d8939a 100644
--- a/WebCore/rendering/PointerEventsHitRules.h
+++ b/WebCore/rendering/PointerEventsHitRules.h
@@ -22,7 +22,7 @@
#ifndef PointerEventsHitRules_h
#define PointerEventsHitRules_h
-#include "RenderStyle.h"
+#include "RenderStyleConstants.h"
namespace WebCore {
diff --git a/WebCore/rendering/RenderBR.cpp b/WebCore/rendering/RenderBR.cpp
index 2532c5b..f407099 100644
--- a/WebCore/rendering/RenderBR.cpp
+++ b/WebCore/rendering/RenderBR.cpp
@@ -40,15 +40,6 @@ RenderBR::~RenderBR()
{
}
-InlineBox* RenderBR::createInlineBox(bool makePlaceholder, bool isRootLineBox, bool isOnlyRun)
-{
- // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
- // (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.)
- InlineTextBox* box = static_cast<InlineTextBox*>(RenderText::createInlineBox(makePlaceholder, isRootLineBox, isOnlyRun));
- box->setIsText(isOnlyRun || document()->inStrictMode());
- return box;
-}
-
int RenderBR::baselinePosition(bool firstLine, bool isRootLineBox) const
{
if (firstTextBox() && !firstTextBox()->isText())
@@ -82,7 +73,7 @@ int RenderBR::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
return m_lineHeight;
}
-void RenderBR::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderBR::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderText::styleDidChange(diff, oldStyle);
m_lineHeight = -1;
@@ -103,9 +94,9 @@ unsigned RenderBR::caretMaxRenderedOffset() const
return 1;
}
-VisiblePosition RenderBR::positionForCoordinates(int /*x*/, int /*y*/)
+VisiblePosition RenderBR::positionForPoint(const IntPoint&)
{
- return VisiblePosition(element(), 0, DOWNSTREAM);
+ return createVisiblePosition(0, DOWNSTREAM);
}
} // namespace WebCore
diff --git a/WebCore/rendering/RenderBR.h b/WebCore/rendering/RenderBR.h
index b65bb58..7eae8ea 100644
--- a/WebCore/rendering/RenderBR.h
+++ b/WebCore/rendering/RenderBR.h
@@ -40,7 +40,7 @@ public:
virtual const char* renderName() const { return "RenderBR"; }
- virtual IntRect selectionRect(bool) { return IntRect(); }
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/) { return IntRect(); }
virtual unsigned width(unsigned /*from*/, unsigned /*len*/, const Font&, int /*xpos*/) const { return 0; }
virtual unsigned width(unsigned /*from*/, unsigned /*len*/, int /*xpos*/, bool /*firstLine = false*/) const { return 0; }
@@ -49,18 +49,16 @@ public:
virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
// overrides
- virtual InlineBox* createInlineBox(bool, bool, bool isOnlyRun = false);
-
virtual bool isBR() const { return true; }
virtual int caretMinOffset() const;
virtual int caretMaxOffset() const;
virtual unsigned caretMaxRenderedOffset() const;
- virtual VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
mutable int m_lineHeight;
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 725bdb6..5b45501 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -25,6 +25,7 @@
#include "Document.h"
#include "Element.h"
+#include "FloatQuad.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
@@ -58,6 +59,12 @@ const int verticalLineClickFudgeFactor= 3;
using namespace HTMLNames;
+static void moveChild(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* from, RenderObjectChildList* fromChildList, RenderObject* child)
+{
+ ASSERT(from == child->parent());
+ toChildList->appendChildNode(to, fromChildList->removeChildNode(from, child, false), false);
+}
+
struct ColumnInfo {
ColumnInfo()
: m_desiredColumnWidth(0)
@@ -77,7 +84,7 @@ static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;
typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;
static PercentHeightContainerMap* gPercentHeightContainerMap = 0;
-typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderFlow*>*> ContinuationOutlineTableMap;
+typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;
// Our MarginInfo state used when laying out block children.
RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom)
@@ -114,15 +121,18 @@ RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom)
// -------------------------------------------------------------------------------------------------------
RenderBlock::RenderBlock(Node* node)
- : RenderFlow(node)
+ : RenderBox(node)
, m_floatingObjects(0)
, m_positionedObjects(0)
+ , m_inlineContinuation(0)
, m_maxMargin(0)
, m_overflowHeight(0)
, m_overflowWidth(0)
, m_overflowLeft(0)
, m_overflowTop(0)
+ , m_lineHeight(-1)
{
+ setChildrenInline(true);
}
RenderBlock::~RenderBlock()
@@ -131,7 +141,7 @@ RenderBlock::~RenderBlock()
delete m_positionedObjects;
delete m_maxMargin;
- if (m_hasColumns)
+ if (hasColumns())
delete gColumnInfoMap->take(this);
if (gPercentHeightDescendantsMap) {
@@ -154,11 +164,49 @@ RenderBlock::~RenderBlock()
}
}
-void RenderBlock::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderBlock::destroy()
+{
+ // Detach our continuation first.
+ if (m_inlineContinuation)
+ m_inlineContinuation->destroy();
+ m_inlineContinuation = 0;
+
+ // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
+ // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
+ children()->destroyLeftoverChildren();
+
+ if (!documentBeingDestroyed()) {
+ if (firstLineBox()) {
+ // We can't wait for RenderBox::destroy to clear the selection,
+ // because by then we will have nuked the line boxes.
+ // FIXME: The SelectionController should be responsible for this when it
+ // is notified of DOM mutations.
+ if (isSelectionBorder())
+ view()->clearSelection();
+
+ // If we are an anonymous block, then our line boxes might have children
+ // that will outlast this block. In the non-anonymous block case those
+ // children will be destroyed by the time we return from this function.
+ if (isAnonymousBlock()) {
+ for (InlineFlowBox* box = firstLineBox(); box; box = box->nextFlowBox()) {
+ while (InlineBox* childBox = box->firstChild())
+ childBox->remove();
+ }
+ }
+ } else if (isInline() && parent())
+ parent()->dirtyLinesFromChangedChild(this);
+ }
+
+ m_lineBoxes.deleteLineBoxes(renderArena());
+
+ RenderBox::destroy();
+}
+
+void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
setReplaced(newStyle->isDisplayReplacedType());
- if (style() && parent() && diff == RenderStyle::Layout && style()->position() != newStyle->position()) {
+ if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {
if (newStyle->position() == StaticPosition)
// Clear our positioned objects list. Our absolutely positioned descendants will be
// inserted into our containing block's positioned objects list during layout.
@@ -176,16 +224,16 @@ void RenderBlock::styleWillChange(RenderStyle::Diff diff, const RenderStyle* new
}
if (cb->isRenderBlock())
- static_cast<RenderBlock*>(cb)->removePositionedObjects(this);
+ toRenderBlock(cb)->removePositionedObjects(this);
}
}
- RenderFlow::styleWillChange(diff, newStyle);
+ RenderBox::styleWillChange(diff, newStyle);
}
-void RenderBlock::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- RenderFlow::styleDidChange(diff, oldStyle);
+ RenderBox::styleDidChange(diff, oldStyle);
// FIXME: We could save this call when the change only affected non-inherited properties
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
@@ -201,13 +249,21 @@ void RenderBlock::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldS
// Update pseudos for :before and :after now.
if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {
- updateBeforeAfterContent(RenderStyle::BEFORE);
- updateBeforeAfterContent(RenderStyle::AFTER);
+ updateBeforeAfterContent(BEFORE);
+ updateBeforeAfterContent(AFTER);
}
updateFirstLetter();
}
-void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
+void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId)
+{
+ // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
+ if (parent() && parent()->createsAnonymousWrapper())
+ return;
+ return children()->updateBeforeAfterContent(this, pseudoId);
+}
+
+void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
// Make sure we don't append things after :after-generated content if we have it.
if (!beforeChild && isAfterContent(lastChild()))
@@ -231,13 +287,13 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
beforeChild->parent()->addChild(newChild, beforeChild);
else
- addChildToFlow(newChild, beforeChild->parent());
+ addChild(newChild, beforeChild->parent());
return;
}
ASSERT(anonymousChild->isTable());
- if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP
- || newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION
+ if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
+ || (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
|| newChild->isTableSection()
|| newChild->isTableRow()
|| newChild->isTableCell()) {
@@ -253,7 +309,7 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
// A block has to either have all of its children inline, or all of its children as blocks.
// So, if our children are currently inline and a block child has to be inserted, we move all our
// inline children into anonymous block boxes.
- if (m_childrenInline && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
+ if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {
// This is a block with inline content. Wrap the inline content in anonymous blocks.
makeChildrenNonInline(beforeChild);
madeBoxesNonInline = true;
@@ -263,7 +319,7 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
ASSERT(beforeChild->isAnonymousBlock());
ASSERT(beforeChild->parent() == this);
}
- } else if (!m_childrenInline && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
+ } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {
// If we're inserting an inline child but all of our children are blocks, then we have to make sure
// it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise
// a new one is created and inserted into our list of children in the appropriate position.
@@ -277,17 +333,16 @@ void RenderBlock::addChildToFlow(RenderObject* newChild, RenderObject* beforeChi
if (newChild->isInline()) {
// No suitable existing anonymous box - create a new one.
RenderBlock* newBox = createAnonymousBlock();
- RenderContainer::addChild(newBox, beforeChild);
+ RenderBox::addChild(newBox, beforeChild);
newBox->addChild(newChild);
return;
}
}
- RenderContainer::addChild(newChild, beforeChild);
- // ### care about aligned stuff
+ RenderBox::addChild(newChild, beforeChild);
- if (madeBoxesNonInline && parent() && isAnonymousBlock())
- parent()->removeLeftoverAnonymousBlock(this);
+ if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())
+ toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
// this object may be dead here
}
@@ -333,14 +388,19 @@ static void getInlineRun(RenderObject* start, RenderObject* boundary,
void RenderBlock::deleteLineBoxTree()
{
- InlineFlowBox* line = m_firstLineBox;
- InlineFlowBox* nextLine;
- while (line) {
- nextLine = line->nextFlowBox();
- line->deleteLine(renderArena());
- line = nextLine;
- }
- m_firstLineBox = m_lastLineBox = 0;
+ m_lineBoxes.deleteLineBoxTree(renderArena());
+}
+
+RootInlineBox* RenderBlock::createRootBox()
+{
+ return new (renderArena()) RootInlineBox(this);
+}
+
+RootInlineBox* RenderBlock::createRootInlineBox()
+{
+ RootInlineBox* rootBox = createRootBox();
+ m_lineBoxes.appendLineBox(rootBox);
+ return rootBox;
}
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
@@ -355,7 +415,7 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
ASSERT(isInlineBlockOrInlineTable() || !isInline());
ASSERT(!insertionPoint || insertionPoint->parent() == this);
- m_childrenInline = false;
+ setChildrenInline(false);
RenderObject *child = firstChild();
if (!child)
@@ -372,16 +432,16 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
child = inlineRunEnd->nextSibling();
- RenderBlock* box = createAnonymousBlock();
- insertChildNode(box, inlineRunStart);
+ RenderBlock* block = createAnonymousBlock();
+ children()->insertChildNode(this, block, inlineRunStart);
RenderObject* o = inlineRunStart;
- while(o != inlineRunEnd)
- {
+ while (o != inlineRunEnd) {
RenderObject* no = o;
o = no->nextSibling();
- box->moveChildNode(no);
+
+ moveChild(block, block->children(), this, children(), no);
}
- box->moveChildNode(inlineRunEnd);
+ moveChild(block, block->children(), this, children(), inlineRunEnd);
}
#ifndef NDEBUG
@@ -392,7 +452,49 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
repaint();
}
-void RenderBlock::removeChild(RenderObject *oldChild)
+void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
+{
+ ASSERT(child->isAnonymousBlock());
+ ASSERT(!child->childrenInline());
+
+ if (child->inlineContinuation())
+ return;
+
+ RenderObject* firstAnChild = child->m_children.firstChild();
+ RenderObject* lastAnChild = child->m_children.lastChild();
+ if (firstAnChild) {
+ RenderObject* o = firstAnChild;
+ while (o) {
+ o->setParent(this);
+ o = o->nextSibling();
+ }
+ firstAnChild->setPreviousSibling(child->previousSibling());
+ lastAnChild->setNextSibling(child->nextSibling());
+ if (child->previousSibling())
+ child->previousSibling()->setNextSibling(firstAnChild);
+ if (child->nextSibling())
+ child->nextSibling()->setPreviousSibling(lastAnChild);
+ } else {
+ if (child->previousSibling())
+ child->previousSibling()->setNextSibling(child->nextSibling());
+ if (child->nextSibling())
+ child->nextSibling()->setPreviousSibling(child->previousSibling());
+ }
+ if (child == m_children.firstChild())
+ m_children.setFirstChild(firstAnChild);
+ if (child == m_children.lastChild())
+ m_children.setLastChild(lastAnChild);
+ child->setParent(0);
+ child->setPreviousSibling(0);
+ child->setNextSibling(0);
+
+ child->children()->setFirstChild(0);
+ child->m_next = 0;
+
+ child->destroy();
+}
+
+void RenderBlock::removeChild(RenderObject* oldChild)
{
// If this child is a block, and if our previous and next siblings are
// both anonymous blocks with inline content, then we can go ahead and
@@ -400,7 +502,7 @@ void RenderBlock::removeChild(RenderObject *oldChild)
RenderObject* prev = oldChild->previousSibling();
RenderObject* next = oldChild->nextSibling();
bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() &&
- !oldChild->virtualContinuation() &&
+ (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->inlineContinuation()) &&
(!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&
(!next || (next->isAnonymousBlock() && next->childrenInline()));
if (canDeleteAnonymousBlocks && prev && next) {
@@ -408,20 +510,22 @@ void RenderBlock::removeChild(RenderObject *oldChild)
// the |prev| block.
prev->setNeedsLayoutAndPrefWidthsRecalc();
RenderObject* o = next->firstChild();
+
+ RenderBlock* nextBlock = toRenderBlock(next);
+ RenderBlock* prevBlock = toRenderBlock(prev);
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- prev->moveChildNode(no);
+ moveChild(prevBlock, prevBlock->children(), nextBlock, nextBlock->children(), no);
}
- RenderBlock* nextBlock = static_cast<RenderBlock*>(next);
nextBlock->deleteLineBoxTree();
// Nuke the now-empty block.
next->destroy();
}
- RenderFlow::removeChild(oldChild);
+ RenderBox::removeChild(oldChild);
RenderObject* child = prev ? prev : next;
if (canDeleteAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {
@@ -429,13 +533,13 @@ void RenderBlock::removeChild(RenderObject *oldChild)
// box. We can go ahead and pull the content right back up into our
// box.
setNeedsLayoutAndPrefWidthsRecalc();
- RenderBlock* anonBlock = static_cast<RenderBlock*>(removeChildNode(child, false));
- m_childrenInline = true;
+ RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));
+ setChildrenInline(true);
RenderObject* o = anonBlock->firstChild();
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- moveChildNode(no);
+ moveChild(this, children(), anonBlock, anonBlock->children(), no);
}
// Delete the now-empty block's lines and nuke it.
@@ -615,15 +719,8 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
if (!relayoutChildren && layoutOnlyPositionedObjects())
return;
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = m_everHadLayout && checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
-
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), m_hasColumns || hasTransform() || hasReflection());
+ LayoutRepainter repainter(*this, m_everHadLayout && checkForRepaintDuringLayout());
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
int oldWidth = width();
int oldColumnWidth = desiredColumnWidth();
@@ -670,11 +767,11 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
if (!isCell) {
initMaxMarginValues();
- m_topMarginQuirk = style()->marginTop().quirk();
- m_bottomMarginQuirk = style()->marginBottom().quirk();
+ setTopMarginQuirk(style()->marginTop().quirk());
+ setBottomMarginQuirk(style()->marginBottom().quirk());
- Node* node = element();
- if (node && node->hasTagName(formTag) && static_cast<HTMLFormElement*>(node)->isMalformed()) {
+ Node* n = node();
+ if (n && n->hasTagName(formTag) && static_cast<HTMLFormElement*>(n)->isMalformed()) {
// See if this form is malformed (i.e., unclosed). If so, don't give the form
// a bottom margin.
setMaxBottomMargins(0, 0);
@@ -684,9 +781,9 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
// For overflow:scroll blocks, ensure we have both scrollbars in place always.
if (scrollsOverflow()) {
if (style()->overflowX() == OSCROLL)
- m_layer->setHasHorizontalScrollbar(true);
+ layer()->setHasHorizontalScrollbar(true);
if (style()->overflowY() == OSCROLL)
- m_layer->setHasVerticalScrollbar(true);
+ layer()->setHasVerticalScrollbar(true);
}
int repaintTop = 0;
@@ -714,7 +811,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
// One of our children's floats may have become an overhanging float for us. We need to look for it.
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isBlockFlow() && !child->isFloatingOrPositioned()) {
- RenderBlock* block = static_cast<RenderBlock*>(child);
+ RenderBlock* block = toRenderBlock(child);
if (block->floatBottom() + block->y() > height())
addOverhangingFloats(block, -block->x(), -block->y(), false);
}
@@ -762,12 +859,10 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
// Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
if (hasOverflowClip())
- m_layer->updateScrollInfoAfterLayout();
+ layer()->updateScrollInfoAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
- bool didFullRepaint = false;
- if (checkForRepaint)
- didFullRepaint = repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ bool didFullRepaint = repainter.repaintAfterLayout();
if (!didFullRepaint && repaintTop != repaintBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
IntRect repaintRect(m_overflowLeft, repaintTop, m_overflowWidth - m_overflowLeft, repaintBottom - repaintTop);
@@ -800,19 +895,19 @@ void RenderBlock::layoutBlock(bool relayoutChildren)
bool RenderBlock::expandsToEncloseOverhangingFloats() const
{
- return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || m_hasColumns || isTableCell() || isFieldset();
+ return isInlineBlockOrInlineTable() || isFloatingOrPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBox()) || hasColumns() || isTableCell() || isFieldset();
}
void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marginInfo)
{
- if (child->hasStaticX()) {
+ if (child->style()->hasStaticX()) {
if (style()->direction() == LTR)
- child->setStaticX(borderLeft() + paddingLeft());
+ child->layer()->setStaticX(borderLeft() + paddingLeft());
else
- child->setStaticX(borderRight() + paddingRight());
+ child->layer()->setStaticX(borderRight() + paddingRight());
}
- if (child->hasStaticY()) {
+ if (child->style()->hasStaticY()) {
int y = height();
if (!marginInfo.canCollapseWithTop()) {
child->calcVerticalMargins();
@@ -828,7 +923,7 @@ void RenderBlock::adjustPositionedBlock(RenderBox* child, const MarginInfo& marg
}
y += (collapsedTopPos - collapsedTopNeg) - marginTop;
}
- child->setStaticY(y);
+ child->layer()->setStaticY(y);
}
}
@@ -892,24 +987,27 @@ RenderBox* RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo&
return 0;
}
-RenderBox* RenderBlock::handleRunInChild(RenderBox* blockRunIn, bool& handled)
+RenderBox* RenderBlock::handleRunInChild(RenderBox* child, bool& handled)
{
// See if we have a run-in element with inline children. If the
// children aren't inline, then just treat the run-in as a normal
// block.
- if (blockRunIn->isRunIn() && (blockRunIn->childrenInline() || blockRunIn->isReplaced())) {
+ if (child->isRunIn() && (child->childrenInline() || child->isReplaced())) {
+ RenderBlock* blockRunIn = toRenderBlock(child);
// Get the next non-positioned/non-floating RenderBlock.
RenderObject* curr = blockRunIn->nextSibling();
while (curr && curr->isFloatingOrPositioned())
curr = curr->nextSibling();
if (curr && (curr->isRenderBlock() && curr->childrenInline() && !curr->isRunIn())) {
+ RenderBlock* currBlock = toRenderBlock(curr);
+
// The block acts like an inline, so just null out its
// position.
handled = true;
// Remove the old child.
RenderBox* next = blockRunIn->nextSiblingBox();
- removeChildNode(blockRunIn);
+ children()->removeChildNode(this, blockRunIn);
// Create an inline.
RenderInline* inlineRunIn = new (renderArena()) RenderInline(blockRunIn->node());
@@ -918,18 +1016,18 @@ RenderBox* RenderBlock::handleRunInChild(RenderBox* blockRunIn, bool& handled)
// Move the nodes from the old child to the new child, but skip any :before/:after content. It has already
// been regenerated by the new inline.
for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {
- if (runInChild->style()->styleType() != RenderStyle::BEFORE && runInChild->style()->styleType() != RenderStyle::AFTER) {
- blockRunIn->removeChildNode(runInChild, false);
+ if (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER) {
+ blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);
inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.
}
}
- // Now insert the new child under |curr|.
- curr->insertChildNode(inlineRunIn, curr->firstChild());
+ // Now insert the new child under |currBlock|.
+ currBlock->children()->insertChildNode(currBlock, inlineRunIn, currBlock->firstChild());
// If the run-in had an element, we need to set the new renderer.
- if (blockRunIn->element())
- blockRunIn->element()->setRenderer(inlineRunIn);
+ if (blockRunIn->node())
+ blockRunIn->node()->setRenderer(inlineRunIn);
// Destroy the block run-in.
blockRunIn->destroy();
@@ -940,7 +1038,7 @@ RenderBox* RenderBlock::handleRunInChild(RenderBox* blockRunIn, bool& handled)
return 0;
}
-void RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo, int yPosEstimate)
+int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
{
// Get our max pos and neg top margins.
int posTop = child->maxTopMargin(true);
@@ -969,7 +1067,7 @@ void RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo, int
// has an example of this, a <dt> with 0.8em author-specified inside
// a <dl> inside a <td>.
if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) {
- m_topMarginQuirk = false;
+ setTopMarginQuirk(false);
marginInfo.setDeterminedTopQuirk(true);
}
@@ -979,7 +1077,7 @@ void RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo, int
// This deals with the <td><div><p> case.
// Don't do this for a block that split two inlines though. You do
// still apply margins in this case.
- m_topMarginQuirk = true;
+ setTopMarginQuirk(true);
}
if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))
@@ -1028,34 +1126,15 @@ void RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo, int
marginInfo.setSelfCollapsingBlockClearedFloat(false);
}
-
- view()->addLayoutDelta(IntSize(0, yPosEstimate - ypos));
- child->setLocation(child->x(), ypos);
- if (ypos != yPosEstimate) {
- if (child->shrinkToAvoidFloats())
- // The child's width depends on the line width.
- // When the child shifts to clear an item, its width can
- // change (because it has more available line width).
- // So go ahead and mark the item as dirty.
- child->setChildNeedsLayout(true, false);
-
- if (!child->avoidsFloats() && child->containsFloats())
- static_cast<RenderBlock*>(child)->markAllDescendantsWithFloatsForLayout();
-
- // Our guess was wrong. Make the child lay itself out again.
- child->layoutIfNeeded();
- }
+
+ return ypos;
}
-void RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin)
+int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos)
{
- int heightIncrease = getClearDelta(child);
+ int heightIncrease = getClearDelta(child, yPos);
if (!heightIncrease)
- return;
-
- // The child needs to be lowered. Move the child so that it just clears the float.
- view()->addLayoutDelta(IntSize(0, -heightIncrease));
- child->setLocation(child->x(), child->y() + heightIncrease);
+ return yPos;
if (child->isSelfCollapsingBlock()) {
// For self-collapsing blocks that clear, they can still collapse their
@@ -1084,19 +1163,8 @@ void RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo,
setMaxTopMargins(oldTopPosMargin, oldTopNegMargin);
marginInfo.setAtTopOfBlock(false);
}
-
- // If our value of clear caused us to be repositioned vertically to be
- // underneath a float, we might have to do another layout to take into account
- // the extra space we now have available.
- if (child->shrinkToAvoidFloats())
- // The child's width depends on the line width.
- // When the child shifts to clear an item, its width can
- // change (because it has more available line width).
- // So go ahead and mark the item as dirty.
- child->setChildNeedsLayout(true, false);
- if (!child->avoidsFloats() && child->containsFloats())
- static_cast<RenderBlock*>(child)->markAllDescendantsWithFloatsForLayout();
- child->layoutIfNeeded();
+
+ return yPos + heightIncrease;
}
int RenderBlock::estimateVerticalPosition(RenderBox* child, const MarginInfo& marginInfo)
@@ -1108,6 +1176,7 @@ int RenderBlock::estimateVerticalPosition(RenderBox* child, const MarginInfo& ma
int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();
yPosEstimate += max(marginInfo.margin(), childMarginTop);
}
+ yPosEstimate += getClearDelta(child, yPosEstimate);
return yPosEstimate;
}
@@ -1122,7 +1191,7 @@ void RenderBlock::determineHorizontalPosition(RenderBox* child)
// Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need
// to shift over as necessary to dodge any floats that might get in the way.
if (child->avoidsFloats()) {
- int leftOff = leftOffset(height());
+ int leftOff = leftOffset(height(), false);
if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginLeft().type() != Auto) {
if (child->marginLeft() < 0)
leftOff += child->marginLeft();
@@ -1134,7 +1203,7 @@ void RenderBlock::determineHorizontalPosition(RenderBox* child)
// width computation will take into account the delta between |leftOff| and |xPos|
// so that we can just pass the content width in directly to the |calcHorizontalMargins|
// function.
- child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y()));
+ child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
chPos = leftOff + child->marginLeft();
}
}
@@ -1144,7 +1213,7 @@ void RenderBlock::determineHorizontalPosition(RenderBox* child)
int xPos = width() - borderRight() - paddingRight() - verticalScrollbarWidth();
int chPos = xPos - (child->width() + child->marginRight());
if (child->avoidsFloats()) {
- int rightOff = rightOffset(height());
+ int rightOff = rightOffset(height(), false);
if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginRight().type() != Auto) {
if (child->marginRight() < 0)
rightOff -= child->marginRight();
@@ -1155,7 +1224,7 @@ void RenderBlock::determineHorizontalPosition(RenderBox* child)
// width computation will take into account the delta between |rightOff| and |xPos|
// so that we can just pass the content width in directly to the |calcHorizontalMargins|
// function.
- toRenderBox(child)->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y()));
+ child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));
chPos = rightOff - child->marginRight() - child->width();
}
}
@@ -1172,13 +1241,13 @@ void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo)
setMaxBottomMargins(max(maxBottomPosMargin(), marginInfo.posMargin()), max(maxBottomNegMargin(), marginInfo.negMargin()));
if (!marginInfo.bottomQuirk())
- m_bottomMarginQuirk = false;
+ setBottomMarginQuirk(false);
if (marginInfo.bottomQuirk() && marginBottom() == 0)
// We have no bottom margin and our last child has a quirky margin.
// We will pick up this quirky margin and pass it through.
// This deals with the <td><div><p> case.
- m_bottomMarginQuirk = true;
+ setBottomMarginQuirk(true);
}
}
@@ -1304,21 +1373,22 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
child->setLocation(child->x(), yPosEstimate);
bool markDescendantsWithFloats = false;
- if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->containsFloats())
+ if (yPosEstimate != oldRect.y() && !child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
markDescendantsWithFloats = true;
else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) {
// If an element might be affected by the presence of floats, then always mark it for
// layout.
int fb = max(previousFloatBottom, floatBottom());
- if (fb > height() || fb > yPosEstimate)
+ if (fb > yPosEstimate)
markDescendantsWithFloats = true;
}
- if (markDescendantsWithFloats)
- static_cast<RenderBlock*>(child)->markAllDescendantsWithFloatsForLayout();
+ if (child->isRenderBlock()) {
+ if (markDescendantsWithFloats)
+ toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
- if (child->isRenderBlock())
- previousFloatBottom = max(previousFloatBottom, oldRect.y() + static_cast<RenderBlock*>(child)->floatBottom());
+ previousFloatBottom = max(previousFloatBottom, oldRect.y() + toRenderBlock(child)->floatBottom());
+ }
bool childHadLayout = child->m_everHadLayout;
bool childNeededLayout = child->needsLayout();
@@ -1327,10 +1397,28 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
// Now determine the correct ypos based off examination of collapsing margin
// values.
- collapseMargins(child, marginInfo, yPosEstimate);
+ int yBeforeClear = collapseMargins(child, marginInfo);
// Now check for clear.
- clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin);
+ int yAfterClear = clearFloatsIfNeeded(child, marginInfo, oldTopPosMargin, oldTopNegMargin, yBeforeClear);
+
+ view()->addLayoutDelta(IntSize(0, yPosEstimate - yAfterClear));
+ child->setLocation(child->x(), yAfterClear);
+
+ // Now we have a final y position. See if it really does end up being different from our estimate.
+ if (yAfterClear != yPosEstimate) {
+ if (child->shrinkToAvoidFloats()) {
+ // The child's width depends on the line width.
+ // When the child shifts to clear an item, its width can
+ // change (because it has more available line width).
+ // So go ahead and mark the item as dirty.
+ child->setChildNeedsLayout(true, false);
+ }
+ if (!child->avoidsFloats() && child->isBlockFlow() && toRenderBlock(child)->containsFloats())
+ toRenderBlock(child)->markAllDescendantsWithFloatsForLayout();
+ // Our guess was wrong. Make the child lay itself out again.
+ child->layoutIfNeeded();
+ }
// We are no longer at the top of the block if we encounter a non-empty child.
// This has to be done after checking for clear, so that margins can be reset if a clear occurred.
@@ -1348,7 +1436,8 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren, int& maxFloatBottom
}
// If the child has overhanging floats that intrude into following siblings (or possibly out
// of this block), then the parent gets notified of the floats now.
- maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(static_cast<RenderBlock*>(child), -child->x(), -child->y(), !childNeededLayout));
+ if (child->isBlockFlow() && toRenderBlock(child)->containsFloats())
+ maxFloatBottom = max(maxFloatBottom, addOverhangingFloats(toRenderBlock(child), -child->x(), -child->y(), !childNeededLayout));
// Update our overflow in case the child spills out the block.
m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false));
@@ -1384,7 +1473,7 @@ bool RenderBlock::layoutOnlyPositionedObjects()
if (!posChildNeedsLayout() || normalChildNeedsLayout() || selfNeedsLayout())
return false;
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), m_hasColumns || hasTransform() || hasReflection());
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasColumns() || hasTransform() || hasReflection());
if (needsPositionedMovementLayout()) {
tryLayoutDoingPositionedMovementOnly();
@@ -1398,7 +1487,7 @@ bool RenderBlock::layoutOnlyPositionedObjects()
statePusher.pop();
if (hasOverflowClip())
- m_layer->updateScrollInfoAfterLayout();
+ layer()->updateScrollInfoAfterLayout();
#ifdef ANDROID_FIX
// iframe flatten will call FrameView::layout() which calls performPostLayoutTasks,
@@ -1422,11 +1511,11 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren)
// non-positioned block. Rather than trying to detect all of these movement cases, we just always lay out positioned
// objects that are positioned implicitly like this. Such objects are rare, and so in typical DHTML menu usage (where everything is
// positioned explicitly) this should not incur a performance penalty.
- if (relayoutChildren || (r->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))
+ if (relayoutChildren || (r->style()->hasStaticY() && r->parent() != this && r->parent()->isBlockFlow()))
r->setChildNeedsLayout(true, false);
// If relayoutChildren is set and we have percentage padding, we also need to invalidate the child's pref widths.
- if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))
+ //if (relayoutChildren && (r->style()->paddingLeft().isPercent() || r->style()->paddingRight().isPercent()))
r->setPrefWidthsDirty(true, false);
// We don't have to do a full layout. We just have to update our position. Try that first. If we have shrink-to-fit width
@@ -1470,7 +1559,7 @@ void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
// Only repaint the object if it is overhanging, is not in its own layer, and
// is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
// condition is replaced with being a descendant of us.
- if (r->m_bottom > height() && (paintAllDescendants && r->m_renderer->isDescendantOf(this) || r->m_shouldPaint) && !r->m_renderer->hasLayer()) {
+ if (r->m_bottom > height() && ((paintAllDescendants && r->m_renderer->isDescendantOf(this)) || r->m_shouldPaint) && !r->m_renderer->hasSelfPaintingLayer()) {
r->m_renderer->repaint();
r->m_renderer->repaintOverhangingFloats();
}
@@ -1478,7 +1567,7 @@ void RenderBlock::repaintOverhangingFloats(bool paintAllDescendants)
view()->enableLayoutState();
}
}
-
+
void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
{
tx += x();
@@ -1497,52 +1586,69 @@ void RenderBlock::paint(PaintInfo& paintInfo, int tx, int ty)
return;
}
- bool useControlClip = phase != PaintPhaseBlockBackground && phase != PaintPhaseSelfOutline && phase != PaintPhaseMask && hasControlClip();
+ bool pushedClip = pushContentsClip(paintInfo, tx, ty);
+ paintObject(paintInfo, tx, ty);
+ if (pushedClip)
+ popContentsClip(paintInfo, phase, tx, ty);
- // Push a clip.
- if (useControlClip) {
- if (phase == PaintPhaseOutline)
- paintInfo.phase = PaintPhaseChildOutlines;
- else if (phase == PaintPhaseChildBlockBackground) {
- paintInfo.phase = PaintPhaseBlockBackground;
- paintObject(paintInfo, tx, ty);
- paintInfo.phase = PaintPhaseChildBlockBackgrounds;
- }
- IntRect clipRect(controlClipRect(tx, ty));
- if (clipRect.isEmpty())
- return;
- paintInfo.context->save();
- paintInfo.context->clip(clipRect);
- }
+ // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
+ // z-index. We paint after we painted the background/border, so that the scrollbars will
+ // sit above the background/border.
+ if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground))
+ layer()->paintOverflowControls(paintInfo.context, tx, ty, paintInfo.rect);
+}
- paintObject(paintInfo, tx, ty);
-
- // Pop the clip.
- if (useControlClip) {
- paintInfo.context->restore();
- if (phase == PaintPhaseOutline) {
- paintInfo.phase = PaintPhaseSelfOutline;
- paintObject(paintInfo, tx, ty);
- paintInfo.phase = phase;
- } else if (phase == PaintPhaseChildBlockBackground)
- paintInfo.phase = phase;
+void RenderBlock::paintColumnRules(PaintInfo& paintInfo, int tx, int ty)
+{
+ const Color& ruleColor = style()->columnRuleColor();
+ bool ruleTransparent = style()->columnRuleIsTransparent();
+ EBorderStyle ruleStyle = style()->columnRuleStyle();
+ int ruleWidth = style()->columnRuleWidth();
+ int colGap = columnGap();
+ bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
+ if (!renderRule)
+ return;
+
+ // We need to do multiple passes, breaking up our child painting into strips.
+ int currXOffset = 0;
+ int ruleAdd = borderLeft() + paddingLeft();
+ int ruleX = 0;
+ Vector<IntRect>* colRects = columnRects();
+ unsigned colCount = colRects->size();
+ 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);
+
+ // Move to the next position.
+ if (style()->direction() == LTR) {
+ ruleX += colRect.width() + colGap / 2;
+ currXOffset += colRect.width() + colGap;
+ } else {
+ ruleX -= (colRect.width() + colGap / 2);
+ currXOffset -= (colRect.width() + colGap);
+ }
+
+ // Now paint the column rule.
+ if (i < colCount - 1) {
+ int ruleStart = tx + ruleX - ruleWidth / 2 + ruleAdd;
+ int ruleEnd = ruleStart + ruleWidth;
+ int ruleTop = ty + borderTop() + paddingTop();
+ int ruleBottom = ruleTop + contentHeight();
+ drawLineForBoxSide(paintInfo.context, ruleStart, ruleTop, ruleEnd, ruleBottom,
+ style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
+ }
+
+ ruleX = currXOffset;
}
}
-void RenderBlock::paintColumns(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
+void RenderBlock::paintColumnContents(PaintInfo& paintInfo, int tx, int ty, bool paintingFloats)
{
// We need to do multiple passes, breaking up our child painting into strips.
GraphicsContext* context = paintInfo.context;
int currXOffset = 0;
int currYOffset = 0;
- int ruleAdd = borderLeft() + paddingLeft();
- int ruleX = 0;
int colGap = columnGap();
- const Color& ruleColor = style()->columnRuleColor();
- bool ruleTransparent = style()->columnRuleIsTransparent();
- EBorderStyle ruleStyle = style()->columnRuleStyle();
- int ruleWidth = style()->columnRuleWidth();
- bool renderRule = !paintingFloats && ruleStyle > BHIDDEN && !ruleTransparent && ruleWidth <= colGap;
Vector<IntRect>* colRects = columnRects();
unsigned colCount = colRects->size();
for (unsigned i = 0; i < colCount; i++) {
@@ -1568,27 +1674,14 @@ void RenderBlock::paintColumns(PaintInfo& paintInfo, int tx, int ty, bool painti
paintContents(info, finalX, finalY);
// Move to the next position.
- if (style()->direction() == LTR) {
- ruleX += colRect.width() + colGap / 2;
+ if (style()->direction() == LTR)
currXOffset += colRect.width() + colGap;
- } else {
- ruleX -= (colRect.width() + colGap / 2);
+ else
currXOffset -= (colRect.width() + colGap);
- }
-
+
currYOffset -= colRect.height();
context->restore();
-
- // Now paint the column rule.
- if (renderRule && paintInfo.phase == PaintPhaseForeground && i < colCount - 1) {
- int ruleStart = ruleX - ruleWidth / 2 + ruleAdd;
- int ruleEnd = ruleStart + ruleWidth;
- drawBorder(paintInfo.context, tx + ruleStart, ty + borderTop() + paddingTop(), tx + ruleEnd, ty + borderTop() + paddingTop() + contentHeight(),
- style()->direction() == LTR ? BSLeft : BSRight, ruleColor, style()->color(), ruleStyle, 0, 0);
- }
-
- ruleX = currXOffset;
}
}
@@ -1601,7 +1694,7 @@ void RenderBlock::paintContents(PaintInfo& paintInfo, int tx, int ty)
return;
if (childrenInline())
- paintLines(paintInfo, tx, ty);
+ m_lineBoxes.paint(this, paintInfo, tx, ty);
else
paintChildren(paintInfo, tx, ty);
}
@@ -1626,7 +1719,7 @@ void RenderBlock::paintChildren(PaintInfo& paintInfo, int tx, int ty)
return;
}
- if (!child->hasLayer() && !child->isFloating())
+ if (!child->hasSelfPaintingLayer() && !child->isFloating())
child->paint(info, tx, ty);
// Check for page-break-after: always, and if it's set, break and bail.
@@ -1662,9 +1755,11 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
PaintPhase paintPhase = paintInfo.phase;
// 1. paint background, borders etc
- if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) &&
- hasBoxDecorations() && style()->visibility() == VISIBLE) {
- paintBoxDecorations(paintInfo, tx, ty);
+ if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
+ if (hasBoxDecorations())
+ paintBoxDecorations(paintInfo, tx, ty);
+ if (hasColumns())
+ paintColumnRules(paintInfo, tx, ty);
}
if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
@@ -1680,12 +1775,12 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
int scrolledX = tx;
int scrolledY = ty;
if (hasOverflowClip())
- m_layer->subtractScrolledContentOffset(scrolledX, scrolledY);
+ layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
// 2. paint contents
if (paintPhase != PaintPhaseSelfOutline) {
- if (m_hasColumns)
- paintColumns(paintInfo, scrolledX, scrolledY);
+ if (hasColumns())
+ paintColumnContents(paintInfo, scrolledX, scrolledY);
else
paintContents(paintInfo, scrolledX, scrolledY);
}
@@ -1693,30 +1788,30 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, int tx, int ty)
// 3. paint selection
// FIXME: Make this work with multi column layouts. For now don't fill gaps.
bool isPrinting = document()->printing();
- if (!isPrinting && !m_hasColumns)
+ if (!isPrinting && !hasColumns())
paintSelection(paintInfo, scrolledX, scrolledY); // Fill in gaps in selection on lines and between blocks.
// 4. paint floats.
if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
- if (m_hasColumns)
- paintColumns(paintInfo, scrolledX, scrolledY, true);
+ if (hasColumns())
+ paintColumnContents(paintInfo, scrolledX, scrolledY, true);
else
paintFloats(paintInfo, scrolledX, scrolledY, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
}
// 5. paint outline.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
- RenderBox::paintOutline(paintInfo.context, tx, ty, width(), height(), style());
+ paintOutline(paintInfo.context, tx, ty, width(), height(), style());
// 6. paint continuation outlines.
if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
- if (continuation() && continuation()->hasOutline() && continuation()->style()->visibility() == VISIBLE) {
- RenderFlow* inlineFlow = static_cast<RenderFlow*>(continuation()->element()->renderer());
- if (!inlineFlow->hasLayer())
- containingBlock()->addContinuationWithOutline(inlineFlow);
- else if (!inlineFlow->firstLineBox())
- inlineFlow->paintOutline(paintInfo.context, tx - x() + inlineFlow->containingBlock()->x(),
- ty - y() + inlineFlow->containingBlock()->y());
+ if (inlineContinuation() && inlineContinuation()->hasOutline() && inlineContinuation()->style()->visibility() == VISIBLE) {
+ RenderInline* inlineRenderer = toRenderInline(inlineContinuation()->node()->renderer());
+ if (!inlineRenderer->hasSelfPaintingLayer())
+ containingBlock()->addContinuationWithOutline(inlineRenderer);
+ else if (!inlineRenderer->firstLineBox())
+ inlineRenderer->paintOutline(paintInfo.context, tx - x() + inlineRenderer->containingBlock()->x(),
+ ty - y() + inlineRenderer->containingBlock()->y());
}
paintContinuationOutlines(paintInfo, tx, ty);
}
@@ -1739,7 +1834,7 @@ void RenderBlock::paintFloats(PaintInfo& paintInfo, int tx, int ty, bool preserv
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for (; (r = it.current()); ++it) {
// Only paint the object if our m_shouldPaint flag is set.
- if (r->m_shouldPaint && !r->m_renderer->hasLayer()) {
+ if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
PaintInfo currentPaintInfo(paintInfo);
currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
int currentTX = tx + r->m_left - r->m_renderer->x() + r->m_renderer->marginLeft();
@@ -1767,8 +1862,8 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
if (style()->visibility() == VISIBLE && paintInfo.phase == PaintPhaseForeground) {
// We can check the first box and last box and avoid painting if we don't
// intersect.
- int yPos = ty + firstLineBox()->yPos();
- int h = lastLineBox()->yPos() + lastLineBox()->height() - firstLineBox()->yPos();
+ int yPos = ty + firstLineBox()->y();
+ int h = lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y();
if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
return;
@@ -1776,7 +1871,7 @@ void RenderBlock::paintEllipsisBoxes(PaintInfo& paintInfo, int tx, int ty)
// them. Note that boxes can easily overlap, so we can't make any assumptions
// based off positions of our first line box or our last line box.
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
- yPos = ty + curr->yPos();
+ yPos = ty + curr->y();
h = curr->height();
if (curr->ellipsisBox() && yPos < paintInfo.rect.bottom() && yPos + h > paintInfo.rect.y())
curr->paintEllipsisBox(paintInfo, tx, ty);
@@ -1790,16 +1885,16 @@ static ContinuationOutlineTableMap* continuationOutlineTable()
return &table;
}
-void RenderBlock::addContinuationWithOutline(RenderFlow* flow)
+void RenderBlock::addContinuationWithOutline(RenderInline* flow)
{
// We can't make this work if the inline is in a layer. We'll just rely on the broken
// way of painting.
- ASSERT(!flow->layer());
+ ASSERT(!flow->layer() && !flow->isInlineContinuation());
ContinuationOutlineTableMap* table = continuationOutlineTable();
- ListHashSet<RenderFlow*>* continuations = table->get(this);
+ ListHashSet<RenderInline*>* continuations = table->get(this);
if (!continuations) {
- continuations = new ListHashSet<RenderFlow*>;
+ continuations = new ListHashSet<RenderInline*>;
table->set(this, continuations);
}
@@ -1812,15 +1907,15 @@ void RenderBlock::paintContinuationOutlines(PaintInfo& info, int tx, int ty)
if (table->isEmpty())
return;
- ListHashSet<RenderFlow*>* continuations = table->get(this);
+ ListHashSet<RenderInline*>* continuations = table->get(this);
if (!continuations)
return;
// Paint each continuation outline.
- ListHashSet<RenderFlow*>::iterator end = continuations->end();
- for (ListHashSet<RenderFlow*>::iterator it = continuations->begin(); it != end; ++it) {
+ ListHashSet<RenderInline*>::iterator end = continuations->end();
+ for (ListHashSet<RenderInline*>::iterator it = continuations->begin(); it != end; ++it) {
// Need to add in the coordinates of the intervening blocks.
- RenderFlow* flow = *it;
+ RenderInline* flow = *it;
RenderBlock* block = flow->containingBlock();
for ( ; block && block != this; block = block->containingBlock()) {
tx += block->x();
@@ -1845,9 +1940,9 @@ void RenderBlock::setSelectionState(SelectionState s)
if ((s == SelectionStart && selectionState() == SelectionEnd) ||
(s == SelectionEnd && selectionState() == SelectionStart))
- m_selectionState = SelectionBoth;
+ RenderBox::setSelectionState(SelectionBoth);
else
- m_selectionState = s;
+ RenderBox::setSelectionState(s);
RenderBlock* cb = containingBlock();
if (cb && !cb->isRenderView())
@@ -1856,12 +1951,12 @@ void RenderBlock::setSelectionState(SelectionState s)
bool RenderBlock::shouldPaintSelectionGaps() const
{
- return m_selectionState != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
+ return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot();
}
bool RenderBlock::isSelectionRoot() const
{
- if (!element())
+ if (!node())
return false;
// FIXME: Eventually tables should have to learn how to fill gaps between cells, at least in simple non-spanning cases.
@@ -1874,22 +1969,22 @@ bool RenderBlock::isSelectionRoot() const
return true;
if (view() && view()->selectionStart()) {
- Node* startElement = view()->selectionStart()->element();
- if (startElement && startElement->rootEditableElement() == element())
+ Node* startElement = view()->selectionStart()->node();
+ if (startElement && startElement->rootEditableElement() == node())
return true;
}
return false;
}
-GapRects RenderBlock::selectionGapRects()
+GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* /*repaintContainer*/)
{
ASSERT(!needsLayout());
if (!shouldPaintSelectionGaps())
return GapRects();
- // FIXME: this is broken with transforms
+ // FIXME: this is broken with transforms and a non-null repaintContainer
FloatPoint absContentPoint = localToAbsolute(FloatPoint());
if (hasOverflowClip())
absContentPoint -= layer()->scrolledContentOffset();
@@ -1952,7 +2047,7 @@ GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int
if (!isBlockFlow()) // FIXME: Make multi-column selection gap filling work someday.
return result;
- if (m_hasColumns || hasTransform()) {
+ if (hasColumns() || hasTransform()) {
// FIXME: We should learn how to gap fill multiple columns and transforms eventually.
lastTop = (ty - blockY) + height();
lastLeft = leftSelectionOffset(rootBlock, height());
@@ -1966,7 +2061,7 @@ GapRects RenderBlock::fillSelectionGaps(RenderBlock* rootBlock, int blockX, int
result = fillBlockSelectionGaps(rootBlock, blockX, blockY, tx, ty, lastTop, lastLeft, lastRight, paintInfo);
// Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block.
- if (rootBlock == this && (m_selectionState != SelectionBoth && m_selectionState != SelectionEnd))
+ if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd))
result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + height(),
rootBlock, blockX, blockY, paintInfo));
return result;
@@ -2004,14 +2099,14 @@ GapRects RenderBlock::fillInlineSelectionGaps(RenderBlock* rootBlock, int blockX
result.uniteCenter(fillVerticalSelectionGap(lastTop, lastLeft, lastRight, ty + selTop,
rootBlock, blockX, blockY, paintInfo));
- if (!paintInfo || ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y())
+ if (!paintInfo || (ty + selTop < paintInfo->rect.bottom() && ty + selTop + selHeight > paintInfo->rect.y()))
result.unite(curr->fillLineSelectionGap(selTop, selHeight, rootBlock, blockX, blockY, tx, ty, paintInfo));
lastSelectedLine = curr;
}
if (containsStart && !lastSelectedLine)
- // Selection must start just after our last line.
+ // VisibleSelection must start just after our last line.
lastSelectedLine = lastRootBox();
if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) {
@@ -2079,7 +2174,7 @@ GapRects RenderBlock::fillBlockSelectionGaps(RenderBlock* rootBlock, int blockX,
lastRight = rightSelectionOffset(rootBlock, curr->y() + curr->height());
} else if (childState != SelectionNone)
// We must be a block that has some selected object inside it. Go ahead and recur.
- result.unite(static_cast<RenderBlock*>(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(),
+ result.unite(toRenderBlock(curr)->fillSelectionGaps(rootBlock, blockX, blockY, tx + curr->x(), ty + curr->y(),
lastTop, lastLeft, lastRight, paintInfo));
}
return result;
@@ -2161,7 +2256,7 @@ void RenderBlock::getHorizontalSelectionGapInfo(SelectionState state, bool& left
int RenderBlock::leftSelectionOffset(RenderBlock* rootBlock, int yPos)
{
- int left = leftOffset(yPos);
+ int left = leftOffset(yPos, false);
if (left == borderLeft() + paddingLeft()) {
if (rootBlock != this)
// The border can potentially be further extended by our containingBlock().
@@ -2181,7 +2276,7 @@ int RenderBlock::leftSelectionOffset(RenderBlock* rootBlock, int yPos)
int RenderBlock::rightSelectionOffset(RenderBlock* rootBlock, int yPos)
{
- int right = rightOffset(yPos);
+ int right = rightOffset(yPos, false);
if (right == (contentWidth() + (borderLeft() + paddingLeft()))) {
if (rootBlock != this)
// The border can potentially be further extended by our containingBlock().
@@ -2273,7 +2368,7 @@ void RenderBlock::insertFloatingObject(RenderBox* o)
newObj->m_top = -1;
newObj->m_bottom = -1;
newObj->m_width = o->width() + o->marginLeft() + o->marginRight();
- newObj->m_shouldPaint = !o->hasLayer(); // If a layer exists, the float will paint itself. Otherwise someone else will.
+ newObj->m_shouldPaint = !o->hasSelfPaintingLayer(); // If a layer exists, the float will paint itself. Otherwise someone else will.
newObj->m_isDescendant = true;
newObj->m_renderer = o;
@@ -2458,15 +2553,17 @@ void RenderBlock::removePercentHeightDescendant(RenderBox* descendant)
delete containerSet;
}
-int
-RenderBlock::leftOffset() const
+HashSet<RenderBox*>* RenderBlock::percentHeightDescendants() const
{
- return borderLeft()+paddingLeft();
+ return gPercentHeightDescendantsMap ? gPercentHeightDescendantsMap->get(this) : 0;
}
-int
-RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent,
- int *heightRemaining ) const
+int RenderBlock::leftOffset() const
+{
+ return borderLeft() + paddingLeft();
+}
+
+int RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
{
int left = fixedOffset;
if (m_floatingObjects) {
@@ -2484,7 +2581,7 @@ RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent,
}
}
- if (applyTextIndent && m_firstLine && style()->direction() == LTR) {
+ if (applyTextIndent && style()->direction() == LTR) {
int cw = 0;
if (style()->textIndent().isPercent())
cw = containingBlock()->availableWidth();
@@ -2494,15 +2591,12 @@ RenderBlock::leftRelOffset(int y, int fixedOffset, bool applyTextIndent,
return left;
}
-int
-RenderBlock::rightOffset() const
+int RenderBlock::rightOffset() const
{
return borderLeft() + paddingLeft() + availableWidth();
}
-int
-RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent,
- int *heightRemaining ) const
+int RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent, int* heightRemaining) const
{
int right = fixedOffset;
@@ -2521,7 +2615,7 @@ RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent,
}
}
- if (applyTextIndent && m_firstLine && style()->direction() == RTL) {
+ if (applyTextIndent && style()->direction() == RTL) {
int cw = 0;
if (style()->textIndent().isPercent())
cw = containingBlock()->availableWidth();
@@ -2532,9 +2626,9 @@ RenderBlock::rightRelOffset(int y, int fixedOffset, bool applyTextIndent,
}
int
-RenderBlock::lineWidth(int y) const
+RenderBlock::lineWidth(int y, bool firstLine) const
{
- int result = rightOffset(y) - leftOffset(y);
+ int result = rightOffset(y, firstLine) - leftOffset(y, firstLine);
return (result < 0) ? 0 : result;
}
@@ -2575,7 +2669,7 @@ IntRect RenderBlock::floatRect() const
FloatingObject* r;
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for (; (r = it.current()); ++it) {
- if (r->m_shouldPaint && !r->m_renderer->hasLayer()) {
+ if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
IntRect childRect = r->m_renderer->overflowRect(false);
childRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
result.unite(childRect);
@@ -2597,8 +2691,10 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
// a tiny rel div buried somewhere deep in our child tree. In this case we have to get to
// the abs div.
for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
- if (!c->isFloatingOrPositioned() && !c->isText() && !c->isRenderInline())
- bottom = max(bottom, toRenderBox(c)->y() + c->lowestPosition(false));
+ if (!c->isFloatingOrPositioned() && c->isBox()) {
+ RenderBox* childBox = toRenderBox(c);
+ bottom = max(bottom, childBox->y() + childBox->lowestPosition(false));
+ }
}
}
@@ -2631,7 +2727,7 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
}
}
- if (m_hasColumns) {
+ if (hasColumns()) {
Vector<IntRect>* colRects = columnRects();
for (unsigned i = 0; i < colRects->size(); i++)
bottom = max(bottom, colRects->at(i).bottom() + relativeOffset);
@@ -2642,16 +2738,30 @@ int RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf)
FloatingObject* r;
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for ( ; (r = it.current()); ++it ) {
- if (r->m_shouldPaint || r->m_renderer->hasLayer()) {
+ if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
int lp = r->m_top + r->m_renderer->marginTop() + r->m_renderer->lowestPosition(false);
bottom = max(bottom, lp + relativeOffset);
}
}
}
- if (!includeSelf && lastLineBox()) {
- int lp = lastLineBox()->yPos() + lastLineBox()->height();
- bottom = max(bottom, lp);
+ if (!includeSelf) {
+ bottom = max(bottom, borderTop() + paddingTop() + paddingBottom());
+ if (childrenInline()) {
+ if (lastLineBox()) {
+ int childBottomEdge = lastLineBox()->y() + lastLineBox()->height();
+ bottom = max(bottom, childBottomEdge + paddingBottom());
+ }
+ } else {
+ // Find the last normal flow child.
+ RenderBox* currBox = lastChildBox();
+ while (currBox && currBox->isFloatingOrPositioned())
+ currBox = currBox->previousSiblingBox();
+ if (currBox) {
+ int childBottomEdge = currBox->y() + currBox->height() + currBox->collapsedMarginBottom();
+ bottom = max(bottom, childBottomEdge + paddingBottom());
+ }
+ }
}
return bottom;
@@ -2670,8 +2780,10 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
// a tiny rel div buried somewhere deep in our child tree. In this case we have to get to
// the abs div.
for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
- if (!c->isFloatingOrPositioned() && c->isBox() && !c->isRenderInline())
- right = max(right, toRenderBox(c)->x() + c->rightmostPosition(false));
+ if (!c->isFloatingOrPositioned() && c->isBox()) {
+ RenderBox* childBox = toRenderBox(c);
+ right = max(right, childBox->x() + childBox->rightmostPosition(false));
+ }
}
}
@@ -2705,7 +2817,7 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
}
}
- if (m_hasColumns) {
+ if (hasColumns()) {
// This only matters for LTR
if (style()->direction() == LTR)
right = max(columnRects()->last().right() + relativeOffset, right);
@@ -2716,21 +2828,33 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
FloatingObject* r;
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for ( ; (r = it.current()); ++it ) {
- if (r->m_shouldPaint || r->m_renderer->hasLayer()) {
+ if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
int rp = r->m_left + r->m_renderer->marginLeft() + r->m_renderer->rightmostPosition(false);
right = max(right, rp + relativeOffset);
}
}
}
- if (!includeSelf && firstLineBox()) {
- for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
- int rp = currBox->xPos() + currBox->width();
- // If this node is a root editable element, then the rightmostPosition should account for a caret at the end.
- // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
- if (node()->isContentEditable() && node() == node()->rootEditableElement() && style()->direction() == LTR)
- rp += 1;
- right = max(right, rp);
+ if (!includeSelf) {
+ right = max(right, borderLeft() + paddingLeft() + paddingRight());
+ if (childrenInline()) {
+ for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox()) {
+ int childRightEdge = currBox->x() + currBox->width();
+
+ // If this node is a root editable element, then the rightmostPosition should account for a caret at the end.
+ // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
+ if (node() && node()->isContentEditable() && node() == node()->rootEditableElement() && style()->direction() == LTR && !paddingRight())
+ childRightEdge += 1;
+ right = max(right, childRightEdge + paddingRight());
+ }
+ } else {
+ // Walk all normal flow children.
+ for (RenderBox* currBox = firstChildBox(); currBox; currBox = currBox->nextSiblingBox()) {
+ if (currBox->isFloatingOrPositioned())
+ continue;
+ int childRightEdge = currBox->x() + currBox->width() + currBox->marginRight();
+ right = max(right, childRightEdge + paddingRight());
+ }
}
}
@@ -2749,8 +2873,10 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
// a tiny rel div buried somewhere deep in our child tree. In this case we have to get to
// the abs div.
for (RenderObject* c = firstChild(); c; c = c->nextSibling()) {
- if (!c->isFloatingOrPositioned() && c->isBox() && !c->isRenderInline())
- left = min(left, toRenderBox(c)->x() + c->leftmostPosition(false));
+ if (!c->isFloatingOrPositioned() && c->isBox()) {
+ RenderBox* childBox = toRenderBox(c);
+ left = min(left, childBox->x() + childBox->leftmostPosition(false));
+ }
}
}
@@ -2784,7 +2910,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
}
}
- if (m_hasColumns) {
+ if (hasColumns()) {
// This only matters for RTL
if (style()->direction() == RTL)
left = min(columnRects()->last().x() + relativeOffset, left);
@@ -2795,7 +2921,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
FloatingObject* r;
DeprecatedPtrListIterator<FloatingObject> it(*m_floatingObjects);
for ( ; (r = it.current()); ++it ) {
- if (r->m_shouldPaint || r->m_renderer->hasLayer()) {
+ if (r->m_shouldPaint || r->m_renderer->hasSelfPaintingLayer()) {
int lp = r->m_left + r->m_renderer->marginLeft() + r->m_renderer->leftmostPosition(false);
left = min(left, lp + relativeOffset);
}
@@ -2804,7 +2930,7 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
if (!includeSelf && firstLineBox()) {
for (InlineRunBox* currBox = firstLineBox(); currBox; currBox = currBox->nextLineBox())
- left = min(left, (int)currBox->xPos());
+ left = min(left, (int)currBox->x());
}
return left;
@@ -2882,7 +3008,7 @@ void RenderBlock::clearFloats()
// to avoid floats.
bool parentHasFloats = false;
RenderObject* prev = previousSibling();
- while (prev && (!prev->isBox() || !prev->isRenderBlock() || prev->avoidsFloats() || prev->isFloatingOrPositioned())) {
+ while (prev && (prev->isFloatingOrPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
if (prev->isFloating())
parentHasFloats = true;
prev = prev->previousSibling();
@@ -2891,7 +3017,7 @@ void RenderBlock::clearFloats()
// First add in floats from the parent.
int offset = y();
if (parentHasFloats) {
- RenderBlock* parentBlock = static_cast<RenderBlock *>(parent());
+ RenderBlock* parentBlock = toRenderBlock(parent());
addIntrudingFloats(parentBlock, parentBlock->borderLeft() + parentBlock->paddingLeft(), offset);
}
@@ -2907,7 +3033,7 @@ void RenderBlock::clearFloats()
if (!prev || !prev->isRenderBlock())
return;
- RenderBlock* block = static_cast<RenderBlock *>(prev);
+ RenderBlock* block = toRenderBlock(prev);
if (block->m_floatingObjects && block->floatBottom() > offset)
addIntrudingFloats(block, xoffset, offset);
@@ -2978,8 +3104,8 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo
// The nearest enclosing layer always paints the float (so that zindex and stacking
// behaves properly). We always want to propagate the desire to paint the float as
// far out as we can, to the outermost block that overlaps the float, stopping only
- // if we hit a layer boundary.
- if (r->m_renderer->enclosingLayer() == enclosingLayer())
+ // if we hit a self-painting layer boundary.
+ if (r->m_renderer->enclosingSelfPaintingLayer() == enclosingSelfPaintingLayer())
r->m_shouldPaint = false;
else
floatingObj->m_shouldPaint = false;
@@ -2991,7 +3117,8 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo
}
m_floatingObjects->append(floatingObj);
}
- } else if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasLayer() && r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingLayer() == child->enclosingLayer())
+ } else if (makeChildPaintOtherFloats && !r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer() &&
+ r->m_renderer->isDescendantOf(child) && r->m_renderer->enclosingLayer() == child->enclosingLayer())
// The float is not overhanging from this block, so if it is a descendant of the child, the child should
// paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing
// layer.
@@ -2999,7 +3126,7 @@ int RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff, bo
// it should paint.
r->m_shouldPaint = true;
- if (r->m_shouldPaint && !r->m_renderer->hasLayer()) {
+ if (r->m_shouldPaint && !r->m_renderer->hasSelfPaintingLayer()) {
IntRect floatOverflowRect = r->m_renderer->overflowRect(false);
floatOverflowRect.move(r->m_left + r->m_renderer->marginLeft(), r->m_top + r->m_renderer->marginTop());
floatsOverflowRect.unite(floatOverflowRect);
@@ -3059,7 +3186,7 @@ void RenderBlock::addIntrudingFloats(RenderBlock* prev, int xoff, int yoff)
bool RenderBlock::avoidsFloats() const
{
// Floats can't intrude into our box if we have a non-auto column count or width.
- return RenderFlow::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
+ return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
}
bool RenderBlock::containsFloat(RenderObject* o)
@@ -3085,14 +3212,16 @@ void RenderBlock::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove
// Iterate over our children and mark them as needed.
if (!childrenInline()) {
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isRenderBlock() && !child->isFloatingOrPositioned() &&
- ((floatToRemove ? child->containsFloat(floatToRemove) : child->containsFloats()) || child->shrinkToAvoidFloats()))
- static_cast<RenderBlock*>(child)->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
+ if ((!floatToRemove && child->isFloatingOrPositioned()) || !child->isRenderBlock())
+ continue;
+ RenderBlock* childBlock = toRenderBlock(child);
+ if ((floatToRemove ? childBlock->containsFloat(floatToRemove) : childBlock->containsFloats()) || childBlock->shrinkToAvoidFloats())
+ childBlock->markAllDescendantsWithFloatsForLayout(floatToRemove, inLayout);
}
}
}
-int RenderBlock::getClearDelta(RenderBox* child)
+int RenderBlock::getClearDelta(RenderBox* child, int yPos)
{
// There is no need to compute clearance if we have no floats.
if (!containsFloats())
@@ -3120,11 +3249,11 @@ int RenderBlock::getClearDelta(RenderBox* child)
// to fit) and not all (we should be using nextFloatBottomBelow and looping).
// Do not allow tables to wrap in quirks or even in almost strict mode
// (ebay on the PLT, finance.yahoo.com in the real world, versiontracker.com forces even almost strict mode not to work)
- int result = clearSet ? max(0, bottom - child->y()) : 0;
+ int result = clearSet ? max(0, bottom - yPos) : 0;
if (!result && child->avoidsFloats() && child->style()->width().isFixed() &&
- child->minPrefWidth() > lineWidth(child->y()) && child->minPrefWidth() <= availableWidth() &&
+ child->minPrefWidth() > lineWidth(yPos, false) && child->minPrefWidth() <= availableWidth() &&
document()->inStrictMode())
- result = max(0, floatBottom() - child->y());
+ result = max(0, floatBottom() - yPos);
return result;
}
@@ -3159,41 +3288,41 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
return false;
}
- if (isPointInOverflowControl(result, _x, _y, tx, ty)) {
- if (hitTestAction == HitTestBlockBackground) {
- updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
- return true;
- }
- return false;
+ if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
+ updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+ return true;
}
- // If we have lightweight control clipping, then we can't have any spillout.
- if (!hasControlClip() || controlClipRect(tx, ty).contains(_x, _y)) {
+ // If we have clipping, then we can't have any spillout.
+ bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
+ bool useClip = (hasControlClip() || useOverflowClip);
+ bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).contains(_x, _y) : overflowClipRect(tx, ty).contains(_x, _y));
+ if (checkChildren) {
// Hit test descendants first.
int scrolledX = tx;
int scrolledY = ty;
if (hasOverflowClip())
- m_layer->subtractScrolledContentOffset(scrolledX, scrolledY);
+ layer()->subtractScrolledContentOffset(scrolledX, scrolledY);
// Hit test contents if we don't have columns.
- if (!m_hasColumns && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
+ if (!hasColumns() && hitTestContents(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
return true;
// Hit test our columns if we do have them.
- if (m_hasColumns && hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
+ if (hasColumns() && hitTestColumns(request, result, _x, _y, scrolledX, scrolledY, hitTestAction))
return true;
// Hit test floats.
if (hitTestAction == HitTestFloat && m_floatingObjects) {
if (isRenderView()) {
- scrolledX += static_cast<RenderView*>(this)->frameView()->scrollX();
- scrolledY += static_cast<RenderView*>(this)->frameView()->scrollY();
+ 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->hasLayer()) {
+ 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)) {
@@ -3255,7 +3384,7 @@ bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult&
{
if (childrenInline() && !isTable()) {
// We have to hit-test our line boxes.
- if (hitTestLines(request, result, x, y, tx, ty, hitTestAction)) {
+ if (m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction)) {
updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
@@ -3264,10 +3393,8 @@ bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult&
HitTestAction childHitTest = hitTestAction;
if (hitTestAction == HitTestChildBlockBackgrounds)
childHitTest = HitTestChildBlockBackground;
- for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- // FIXME: We have to skip over inline flows, since they can show up inside RenderTables at the moment (a demoted inline <form> for example). If we ever implement a
- // table-specific hit-test method (which we should do for performance reasons anyway), then we can remove this check.
- if (!child->hasLayer() && !child->isFloating() && !child->isRenderInline() && child->nodeAtPoint(request, result, x, y, tx, ty, childHitTest)) {
+ for (RenderBox* child = lastChildBox(); child; child = child->previousSiblingBox()) {
+ if (!child->hasSelfPaintingLayer() && !child->isFloating() && child->nodeAtPoint(request, result, x, y, tx, ty, childHitTest)) {
updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
@@ -3282,156 +3409,153 @@ Position RenderBlock::positionForBox(InlineBox *box, bool start) const
if (!box)
return Position();
- if (!box->object()->element())
- return Position(element(), start ? caretMinOffset() : caretMaxOffset());
+ if (!box->renderer()->node())
+ return Position(node(), start ? caretMinOffset() : caretMaxOffset());
if (!box->isInlineTextBox())
- return Position(box->object()->element(), start ? box->object()->caretMinOffset() : box->object()->caretMaxOffset());
+ return Position(box->renderer()->node(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
InlineTextBox *textBox = static_cast<InlineTextBox *>(box);
- return Position(box->object()->element(), start ? textBox->start() : textBox->start() + textBox->len());
+ return Position(box->renderer()->node(), start ? textBox->start() : textBox->start() + textBox->len());
}
Position RenderBlock::positionForRenderer(RenderObject* renderer, bool start) const
{
if (!renderer)
- return Position(element(), 0);
+ return Position(node(), 0);
- Node* node = renderer->element() ? renderer->element() : element();
- if (!node)
+ Node* n = renderer->node() ? renderer->node() : node();
+ if (!n)
return Position();
- ASSERT(renderer == node->renderer());
+ ASSERT(renderer == n->renderer());
int offset = start ? renderer->caretMinOffset() : renderer->caretMaxOffset();
// FIXME: This was a runtime check that seemingly couldn't fail; changed it to an assertion for now.
- ASSERT(!node->isCharacterDataNode() || renderer->isText());
+ ASSERT(!n->isCharacterDataNode() || renderer->isText());
- return Position(node, offset);
+ return Position(n, offset);
}
-VisiblePosition RenderBlock::positionForCoordinates(int x, int y)
+// FIXME: This function should go on RenderObject as an instance method. Then
+// all cases in which positionForCoordinates recurs could call this instead to
+// prevent crossing editable boundaries. This would require many tests.
+static VisiblePosition positionForPointRespectingEditingBoundaries(RenderBox* parent, RenderBox* child, const IntPoint& parentCoords)
{
- if (isTable())
- return RenderFlow::positionForCoordinates(x, y);
+ int xInChildCoords = parentCoords.x() - child->x();
+ int yInChildCoords = parentCoords.y() - child->y();
- int top = borderTop();
- int bottom = top + paddingTop() + contentHeight() + paddingBottom();
+ // If this is an anonymous renderer, we just recur normally
+ Node* childNode = child->node();
+ if (!childNode)
+ return child->positionForCoordinates(xInChildCoords, yInChildCoords);
- int left = borderLeft();
- int right = left + paddingLeft() + contentWidth() + paddingRight();
+ // Otherwise, first make sure that the editability of the parent and child agree.
+ // If they don't agree, then we return a visible position just before or after the child
+ RenderObject* ancestor = parent;
+ while (ancestor && !ancestor->node())
+ ancestor = ancestor->parent();
- Node* n = element();
-
- int contentsX = x;
- int contentsY = y;
- offsetForContents(contentsX, contentsY);
+ // If we can't find an ancestor to check editability on, or editability is unchanged, we recur like normal
+ if (!ancestor || ancestor->node()->isContentEditable() == childNode->isContentEditable())
+ return child->positionForCoordinates(xInChildCoords, yInChildCoords);
- if (isReplaced()) {
- if (y < 0 || y < height() && x < 0)
- return VisiblePosition(n, caretMinOffset(), DOWNSTREAM);
- if (y >= height() || y >= 0 && x >= width())
- return VisiblePosition(n, caretMaxOffset(), DOWNSTREAM);
- }
+ // Otherwise return before or after the child, depending on if the click was left or right of the child
+ int childMidX = child->width() / 2;
+ if (xInChildCoords < childMidX)
+ return ancestor->createVisiblePosition(childNode->nodeIndex(), DOWNSTREAM);
+ return ancestor->createVisiblePosition(childNode->nodeIndex() + 1, UPSTREAM);
+}
- // If we start inside the shadow tree, we will stay inside (even if the point is above or below).
- if (!(n && n->isShadowNode()) && !childrenInline()) {
- // Don't return positions inside editable roots for coordinates outside those roots, except for coordinates outside
- // a document that is entirely editable.
- bool isEditableRoot = n && n->rootEditableElement() == n && !n->hasTagName(bodyTag) && !n->hasTagName(htmlTag);
-
- if (y < top || (isEditableRoot && (y < bottom && x < left))) {
- if (!isEditableRoot)
- if (RenderBox* c = firstChildBox()) { // FIXME: This code doesn't make any sense. This child could be an inline or a positioned element or a float, etc.
- VisiblePosition p = c->positionForCoordinates(contentsX - c->x(), contentsY - c->y());
- if (p.isNotNull())
- return p;
- }
- if (n) {
- if (Node* sp = n->shadowParentNode())
- n = sp;
- if (Node* p = n->parent())
- return VisiblePosition(p, n->nodeIndex(), DOWNSTREAM);
- }
- return VisiblePosition(n, 0, DOWNSTREAM);
- }
+static VisiblePosition positionForPointWithInlineChildren(RenderBlock* block, const IntPoint& pointInContents)
+{
+ ASSERT(block->childrenInline());
- if (y >= bottom || (isEditableRoot && (y >= top && x >= right))) {
- if (!isEditableRoot)
- if (RenderBox* c = lastChildBox()) { // FIXME: This code doesn't make any sense. This child could be an inline or a positioned element or a float, etc.
- VisiblePosition p = c->positionForCoordinates(contentsX - c->x(), contentsY - c->y());
- if (p.isNotNull())
- return p;
- }
- if (n) {
- if (Node* sp = n->shadowParentNode())
- n = sp;
- if (Node* p = n->parent())
- return VisiblePosition(p, n->nodeIndex() + 1, DOWNSTREAM);
- }
- return VisiblePosition(n, 0, DOWNSTREAM);
+ if (!block->firstRootBox())
+ return block->createVisiblePosition(0, DOWNSTREAM);
+
+ InlineBox* closestBox = 0;
+ // look for the closest line box in the root box which is at the passed-in y coordinate
+ for (RootInlineBox* root = block->firstRootBox(); root; root = root->nextRootBox()) {
+ int bottom;
+ // set the bottom based on whether there is a next root box
+ if (root->nextRootBox())
+ // FIXME: make the break point halfway between the bottom of the previous root box and the top of the next root box
+ bottom = root->nextRootBox()->topOverflow();
+ else
+ bottom = root->bottomOverflow() + verticalLineClickFudgeFactor;
+ // check if this root line box is located at this y coordinate
+ if (pointInContents.y() < bottom && root->firstChild()) {
+ closestBox = root->closestLeafChildForXPos(pointInContents.x());
+ if (closestBox)
+ // pass the box a y position that is inside it
+ break;
}
}
- if (childrenInline()) {
- if (!firstRootBox())
- return VisiblePosition(n, 0, DOWNSTREAM);
+ // y coordinate is below last root line box, pretend we hit it
+ if (!closestBox)
+ closestBox = block->lastRootBox()->closestLeafChildForXPos(pointInContents.x());
- if (contentsY < firstRootBox()->topOverflow() - verticalLineClickFudgeFactor)
- // y coordinate is above first root line box
- return VisiblePosition(positionForBox(firstRootBox()->firstLeafChild(), true), DOWNSTREAM);
-
- // look for the closest line box in the root box which is at the passed-in y coordinate
- for (RootInlineBox* root = firstRootBox(); root; root = root->nextRootBox()) {
- // set the bottom based on whether there is a next root box
- if (root->nextRootBox())
- // FIXME: make the break point halfway between the bottom of the previous root box and the top of the next root box
- bottom = root->nextRootBox()->topOverflow();
- else
- bottom = root->bottomOverflow() + verticalLineClickFudgeFactor;
- // check if this root line box is located at this y coordinate
- if (contentsY < bottom && root->firstChild()) {
- InlineBox* closestBox = root->closestLeafChildForXPos(x);
- if (closestBox)
- // pass the box a y position that is inside it
- return closestBox->object()->positionForCoordinates(contentsX, closestBox->m_y);
- }
- }
+ if (closestBox) {
+ // pass the box a y position that is inside it
+ return closestBox->renderer()->positionForCoordinates(pointInContents.x(), closestBox->m_y);
+ }
+
+ // Can't reach this. We have a root line box, but it has no kids.
+ // FIXME: This should ASSERT_NOT_REACHED(), but clicking on placeholder text
+ // seems to hit this codepath.
+ return block->createVisiblePosition(0, DOWNSTREAM);
+}
+
+VisiblePosition RenderBlock::positionForPoint(const IntPoint& point)
+{
+ if (isTable())
+ return RenderBox::positionForPoint(point);
+
+ int contentsX = point.x();
+ int contentsY = point.y();
+ offsetForContents(contentsX, contentsY);
+ IntPoint pointInContents(contentsX, contentsY);
- if (lastRootBox())
- // y coordinate is below last root line box
- return VisiblePosition(positionForBox(lastRootBox()->lastLeafChild(), false), DOWNSTREAM);
+ if (isReplaced()) {
+ if (point.y() < 0 || (point.y() < height() && point.x() < 0))
+ return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
+ if (point.y() >= height() || (point.y() >= 0 && point.x() >= width()))
+ return createVisiblePosition(caretMaxOffset(), DOWNSTREAM);
+ }
- return VisiblePosition(n, 0, DOWNSTREAM);
+ if (childrenInline()) {
+ return positionForPointWithInlineChildren(this, pointInContents);
}
-
- // See if any child blocks exist at this y coordinate.
+
+ // Check top/bottom child-margin/parent-padding for clicks and place them in the first/last child
+ // FIXME: This will not correctly handle first or last children being positioned or non-visible
if (firstChildBox() && contentsY < firstChildBox()->y())
- return VisiblePosition(n, 0, DOWNSTREAM);
- for (RenderBox* renderer = firstChildBox(); renderer; renderer = renderer->nextSiblingBox()) {
- if (renderer->height() == 0 || renderer->style()->visibility() != VISIBLE || renderer->isFloatingOrPositioned())
+ return positionForPointRespectingEditingBoundaries(this, firstChildBox(), pointInContents);
+ if (lastChildBox() && contentsY > lastChildBox()->y())
+ return positionForPointRespectingEditingBoundaries(this, lastChildBox(), pointInContents);
+
+ for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
+ if (childBox->height() == 0 || childBox->style()->visibility() != VISIBLE || childBox->isFloatingOrPositioned())
continue;
- RenderBox* next = renderer->nextSiblingBox();
- while (next && next->isFloatingOrPositioned())
- next = next->nextSiblingBox();
- if (next)
- bottom = next->y();
- else
- bottom = top + scrollHeight();
- if (contentsY >= renderer->y() && contentsY < bottom)
- return renderer->positionForCoordinates(contentsX - renderer->x(), contentsY - renderer->y());
+ // We hit this child if our click was above the bottom of its padding box (like IE6/7 and FF3)
+ if (contentsY < childBox->y() + childBox->height())
+ return positionForPointRespectingEditingBoundaries(this, childBox, pointInContents);
}
-
- return RenderFlow::positionForCoordinates(x, y);
+
+ // We only get here if there are no, or only floated/positioned, or only
+ // non-visible block children below the click.
+ return RenderBox::positionForPoint(point);
}
void RenderBlock::offsetForContents(int& tx, int& ty) const
{
if (hasOverflowClip())
- m_layer->addScrolledContentOffset(tx, ty);
+ layer()->addScrolledContentOffset(tx, ty);
- if (m_hasColumns) {
+ if (hasColumns()) {
IntPoint contentsPoint(tx, ty);
adjustPointToColumnContents(contentsPoint);
tx = contentsPoint.x();
@@ -3442,7 +3566,7 @@ void RenderBlock::offsetForContents(int& tx, int& ty) const
int RenderBlock::availableWidth() const
{
// If we have multiple columns, then the available width is reduced to our column width.
- if (m_hasColumns)
+ if (hasColumns())
return desiredColumnWidth();
return contentWidth();
}
@@ -3500,20 +3624,20 @@ void RenderBlock::calcColumnWidth()
void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
{
if (count == 1) {
- if (m_hasColumns) {
+ if (hasColumns()) {
delete gColumnInfoMap->take(this);
- m_hasColumns = false;
+ setHasColumns(false);
}
} else {
ColumnInfo* info;
- if (m_hasColumns)
+ if (hasColumns())
info = gColumnInfoMap->get(this);
else {
if (!gColumnInfoMap)
gColumnInfoMap = new ColumnInfoMap;
info = new ColumnInfo;
gColumnInfoMap->add(this, info);
- m_hasColumns = true;
+ setHasColumns(true);
}
info->m_desiredColumnCount = count;
info->m_desiredColumnWidth = width;
@@ -3522,21 +3646,21 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, int width)
int RenderBlock::desiredColumnWidth() const
{
- if (!m_hasColumns)
+ if (!hasColumns())
return contentWidth();
return gColumnInfoMap->get(this)->m_desiredColumnWidth;
}
unsigned RenderBlock::desiredColumnCount() const
{
- if (!m_hasColumns)
+ if (!hasColumns())
return 1;
return gColumnInfoMap->get(this)->m_desiredColumnCount;
}
Vector<IntRect>* RenderBlock::columnRects() const
{
- if (!m_hasColumns)
+ if (!hasColumns())
return 0;
return &gColumnInfoMap->get(this)->m_columnRects;
}
@@ -3544,7 +3668,7 @@ Vector<IntRect>* RenderBlock::columnRects() const
int RenderBlock::layoutColumns(int endOfContent)
{
// Don't do anything if we have no columns
- if (!m_hasColumns)
+ if (!hasColumns())
return -1;
ColumnInfo* info = gColumnInfoMap->get(this);
@@ -3596,9 +3720,9 @@ int RenderBlock::layoutColumns(int endOfContent)
GraphicsContext context((PlatformGraphicsContext*)0);
RenderObject::PaintInfo paintInfo(&context, pageRect, PaintPhaseForeground, false, 0, 0);
- m_hasColumns = false;
+ setHasColumns(false);
paintObject(paintInfo, 0, 0);
- m_hasColumns = true;
+ setHasColumns(true);
int adjustedBottom = v->bestTruncatedAt();
if (adjustedBottom <= currY)
@@ -3656,7 +3780,7 @@ int RenderBlock::layoutColumns(int endOfContent)
void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
{
// Just bail if we have no columns.
- if (!m_hasColumns)
+ if (!hasColumns())
return;
Vector<IntRect>* colRects = columnRects();
@@ -3685,7 +3809,7 @@ void RenderBlock::adjustPointToColumnContents(IntPoint& point) const
void RenderBlock::adjustRectForColumns(IntRect& r) const
{
// Just bail if we have no columns.
- if (!m_hasColumns)
+ if (!hasColumns())
return;
Vector<IntRect>* colRects = columnRects();
@@ -3742,7 +3866,7 @@ void RenderBlock::calcPrefWidths()
m_minPrefWidth = m_maxPrefWidth;
// A horizontal marquee with inline children has no minimum width.
- if (m_layer && m_layer->marquee() && m_layer->marquee()->isHorizontal())
+ if (layer() && layer()->marquee() && layer()->marquee()->isHorizontal())
m_minPrefWidth = 0;
}
@@ -3844,7 +3968,7 @@ static int getBPMWidth(int childValue, Length cssUnit)
return 0;
}
-static int getBorderPaddingMargin(const RenderBox* child, bool endOfInline)
+static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
{
RenderStyle* cstyle = child->style();
int result = 0;
@@ -3947,7 +4071,7 @@ void RenderBlock::calcInlinePrefWidths()
if (child->isRenderInline()) {
// Add in padding/border/margin from the appropriate side of
// the element.
- int bpm = getBorderPaddingMargin(static_cast<RenderFlow*>(child), childIterator.endOfInline);
+ int bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
childMin += bpm;
childMax += bpm;
@@ -3979,14 +4103,14 @@ void RenderBlock::calcInlinePrefWidths()
bool clearPreviousFloat;
if (child->isFloating()) {
clearPreviousFloat = (prevFloat
- && (prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT)
- || prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT)));
+ && ((prevFloat->style()->floating() == FLEFT && (child->style()->clear() & CLEFT))
+ || (prevFloat->style()->floating() == FRIGHT && (child->style()->clear() & CRIGHT))));
prevFloat = child;
} else
clearPreviousFloat = false;
bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
- if (canBreakReplacedElement && (autoWrap || oldAutoWrap) || clearPreviousFloat) {
+ if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
m_minPrefWidth = max(inlineMin, m_minPrefWidth);
inlineMin = 0;
}
@@ -4152,7 +4276,7 @@ void RenderBlock::calcBlockPrefWidths()
continue;
}
- if (child->isFloating() || child->avoidsFloats()) {
+ if (child->isFloating() || (child->isBox() && toRenderBox(child)->avoidsFloats())) {
int floatTotalWidth = floatLeftWidth + floatRightWidth;
if (child->style()->clear() & CLEFT) {
m_maxPrefWidth = max(floatTotalWidth, m_maxPrefWidth);
@@ -4186,7 +4310,7 @@ void RenderBlock::calcBlockPrefWidths()
w = child->maxPrefWidth() + margin;
if (!child->isFloating()) {
- if (child->avoidsFloats()) {
+ if (child->isBox() && toRenderBox(child)->avoidsFloats()) {
// Determine a left and right max value based off whether or not the floats can fit in the
// margins of the object. For negative margins, we will attempt to overlap the float if the negative margin
// is smaller than the float width.
@@ -4242,11 +4366,11 @@ void RenderBlock::calcBlockPrefWidths()
bool RenderBlock::hasLineIfEmpty() const
{
- return element() && (element()->isContentEditable() && element()->rootEditableElement() == element() ||
- element()->isShadowNode() && element()->shadowParentNode()->hasTagName(inputTag));
+ return node() && ((node()->isContentEditable() && node()->rootEditableElement() == node()) ||
+ (node()->isShadowNode() && node()->shadowParentNode()->hasTagName(inputTag)));
}
-int RenderBlock::lineHeight(bool b, bool isRootLineBox) const
+int RenderBlock::lineHeight(bool firstLine, bool isRootLineBox) const
{
// Inline blocks are replaced elements. Otherwise, just pass off to
// the base class. If we're being queried as though we're the root line
@@ -4254,7 +4378,17 @@ int RenderBlock::lineHeight(bool b, bool isRootLineBox) const
// just like a block.
if (isReplaced() && !isRootLineBox)
return height() + marginTop() + marginBottom();
- return RenderFlow::lineHeight(b, isRootLineBox);
+
+ if (firstLine && document()->usesFirstLineRules()) {
+ RenderStyle* s = style(firstLine);
+ if (s != style())
+ return s->computedLineHeight();
+ }
+
+ if (m_lineHeight == -1)
+ m_lineHeight = style()->computedLineHeight();
+
+ return m_lineHeight;
}
int RenderBlock::baselinePosition(bool b, bool isRootLineBox) const
@@ -4276,29 +4410,29 @@ int RenderBlock::baselinePosition(bool b, bool isRootLineBox) const
// We also give up on finding a baseline if we have a vertical scrollbar, or if we are scrolled
// vertically (e.g., an overflow:hidden block that has had scrollTop moved) or if the baseline is outside
// of our content box.
- int baselinePos = (m_layer && (m_layer->marquee() || m_layer->verticalScrollbar() || m_layer->scrollYOffset() != 0)) ? -1 : getBaselineOfLastLineBox();
+ int baselinePos = (layer() && (layer()->marquee() || layer()->verticalScrollbar() || layer()->scrollYOffset() != 0)) ? -1 : lastLineBoxBaseline();
if (baselinePos != -1 && baselinePos <= borderTop() + paddingTop() + contentHeight())
return marginTop() + baselinePos;
return height() + marginTop() + marginBottom();
}
- return RenderFlow::baselinePosition(b, isRootLineBox);
+ return RenderBox::baselinePosition(b, isRootLineBox);
}
-int RenderBlock::getBaselineOfFirstLineBox() const
+int RenderBlock::firstLineBoxBaseline() const
{
if (!isBlockFlow())
- return RenderFlow::getBaselineOfFirstLineBox();
+ return -1;
if (childrenInline()) {
if (firstLineBox())
- return firstLineBox()->yPos() + firstLineBox()->baseline();
+ return firstLineBox()->y() + style(true)->font().ascent();
else
return -1;
}
else {
for (RenderBox* curr = firstChildBox(); curr; curr = curr->nextSiblingBox()) {
if (!curr->isFloatingOrPositioned()) {
- int result = curr->getBaselineOfFirstLineBox();
+ int result = curr->firstLineBoxBaseline();
if (result != -1)
return curr->y() + result; // Translate to our coordinate space.
}
@@ -4308,16 +4442,16 @@ int RenderBlock::getBaselineOfFirstLineBox() const
return -1;
}
-int RenderBlock::getBaselineOfLastLineBox() const
+int RenderBlock::lastLineBoxBaseline() const
{
if (!isBlockFlow())
- return RenderFlow::getBaselineOfLastLineBox();
+ return -1;
if (childrenInline()) {
if (!firstLineBox() && hasLineIfEmpty())
- return RenderFlow::baselinePosition(true, true) + borderTop() + paddingTop();
+ return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
if (lastLineBox())
- return lastLineBox()->yPos() + lastLineBox()->baseline();
+ return lastLineBox()->y() + style(lastLineBox() == firstLineBox())->font().ascent();
return -1;
}
else {
@@ -4325,13 +4459,13 @@ int RenderBlock::getBaselineOfLastLineBox() const
for (RenderBox* curr = lastChildBox(); curr; curr = curr->previousSiblingBox()) {
if (!curr->isFloatingOrPositioned()) {
haveNormalFlowChild = true;
- int result = curr->getBaselineOfLastLineBox();
+ int result = curr->lastLineBoxBaseline();
if (result != -1)
return curr->y() + result; // Translate to our coordinate space.
}
}
if (!haveNormalFlowChild && hasLineIfEmpty())
- return RenderFlow::baselinePosition(true, true) + borderTop() + paddingTop();
+ return RenderBox::baselinePosition(true, true) + borderTop() + paddingTop();
}
return -1;
@@ -4353,7 +4487,7 @@ RenderBlock* RenderBlock::firstLineBlock() const
RenderBlock* firstLineBlock = const_cast<RenderBlock*>(this);
bool hasPseudo = false;
while (true) {
- hasPseudo = firstLineBlock->style()->hasPseudoStyle(RenderStyle::FIRST_LINE);
+ hasPseudo = firstLineBlock->style()->hasPseudoStyle(FIRST_LINE);
if (hasPseudo)
break;
RenderObject* parentBlock = firstLineBlock->parent();
@@ -4361,7 +4495,7 @@ RenderBlock* RenderBlock::firstLineBlock() const
!parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
break;
ASSERT(parentBlock->isRenderBlock());
- firstLineBlock = static_cast<RenderBlock*>(parentBlock);
+ firstLineBlock = toRenderBlock(parentBlock);
}
if (!hasPseudo)
@@ -4374,8 +4508,8 @@ void RenderBlock::updateFirstLetter()
{
if (!document()->usesFirstLetterRules())
return;
- // Don't recurse
- if (style()->styleType() == RenderStyle::FIRST_LETTER)
+ // Don't recur
+ if (style()->styleType() == FIRST_LETTER)
return;
// FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
@@ -4385,7 +4519,7 @@ void RenderBlock::updateFirstLetter()
while (true) {
// We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
// prevents form controls from honoring first-letter.
- hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(RenderStyle::FIRST_LETTER)
+ hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
&& firstLetterBlock->canHaveChildren();
if (hasPseudoStyle)
break;
@@ -4403,7 +4537,7 @@ void RenderBlock::updateFirstLetter()
RenderObject* currChild = firstLetterBlock->firstChild();
while (currChild && currChild->needsLayout() && (!currChild->isReplaced() || currChild->isFloatingOrPositioned()) && !currChild->isText()) {
if (currChild->isFloatingOrPositioned()) {
- if (currChild->style()->styleType() == RenderStyle::FIRST_LETTER)
+ if (currChild->style()->styleType() == FIRST_LETTER)
break;
currChild = currChild->nextSibling();
} else
@@ -4421,8 +4555,8 @@ void RenderBlock::updateFirstLetter()
// If the child already has style, then it has already been created, so we just want
// to update it.
- if (currChild->style()->styleType() == RenderStyle::FIRST_LETTER) {
- RenderStyle* pseudo = firstLetterBlock->getCachedPseudoStyle(RenderStyle::FIRST_LETTER,
+ if (currChild->style()->styleType() == FIRST_LETTER) {
+ RenderStyle* pseudo = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER,
firstLetterContainer->firstLineStyle());
currChild->setStyle(pseudo);
for (RenderObject* genChild = currChild->firstChild(); genChild; genChild = genChild->nextSibling()) {
@@ -4433,7 +4567,7 @@ void RenderBlock::updateFirstLetter()
}
// If the child does not already have style, we create it here.
- if (currChild->isText() && !currChild->isBR() && currChild->parent()->style()->styleType() != RenderStyle::FIRST_LETTER) {
+ if (currChild->isText() && !currChild->isBR() && currChild->parent()->style()->styleType() != FIRST_LETTER) {
// Our layout state is not valid for the repaints we are going to trigger by
// adding and removing children of firstLetterContainer.
view()->disableLayoutState();
@@ -4441,14 +4575,19 @@ void RenderBlock::updateFirstLetter()
RenderText* textObj = toRenderText(currChild);
// Create our pseudo style now that we have our firstLetterContainer determined.
- RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(RenderStyle::FIRST_LETTER,
+ RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER,
firstLetterContainer->firstLineStyle());
// Force inline display (except for floating first-letters)
- pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
- pseudoStyle->setPosition( StaticPosition ); // CSS2 says first-letter can't be positioned.
+ pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
+ pseudoStyle->setPosition(StaticPosition); // CSS2 says first-letter can't be positioned.
- RenderObject* firstLetter = RenderFlow::createAnonymousFlow(document(), pseudoStyle); // anonymous box
+ RenderObject* firstLetter = 0;
+ if (pseudoStyle->display() == INLINE)
+ firstLetter = new (renderArena()) RenderInline(document());
+ else
+ firstLetter = new (renderArena()) RenderBlock(document());
+ firstLetter->setStyle(pseudoStyle);
firstLetterContainer->addChild(firstLetter, currChild);
// The original string is going to be either a generated content string or a DOM node's
@@ -4470,10 +4609,10 @@ void RenderBlock::updateFirstLetter()
// construct text fragment for the text after the first letter
// NOTE: this might empty
RenderTextFragment* remainingText =
- new (renderArena()) RenderTextFragment(textObj->node(), oldText.get(), length, oldText->length() - length);
+ new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
remainingText->setStyle(textObj->style());
- if (remainingText->element())
- remainingText->element()->setRenderer(remainingText);
+ if (remainingText->node())
+ remainingText->node()->setRenderer(remainingText);
RenderObject* nextObj = textObj->nextSibling();
firstLetterContainer->removeChild(textObj);
@@ -4482,7 +4621,7 @@ void RenderBlock::updateFirstLetter()
// construct text fragment for the first letter
RenderTextFragment* letter =
- new (renderArena()) RenderTextFragment(remainingText->node(), oldText.get(), 0, length);
+ new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(pseudoStyle);
letter->setStyle(newStyle.release());
@@ -4526,7 +4665,7 @@ static RootInlineBox* getLineAtIndex(RenderBlock* block, int i, int& count)
else {
for (RenderObject* obj = block->firstChild(); obj; obj = obj->nextSibling()) {
if (shouldCheckLines(obj)) {
- RootInlineBox *box = getLineAtIndex(static_cast<RenderBlock*>(obj), i, count);
+ RootInlineBox *box = getLineAtIndex(toRenderBlock(obj), i, count);
if (box)
return box;
}
@@ -4549,7 +4688,7 @@ static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
RenderBox* normalFlowChildWithoutLines = 0;
for (RenderBox* obj = block->firstChildBox(); obj; obj = obj->nextSiblingBox()) {
if (shouldCheckLines(obj)) {
- int result = getHeightForLineCount(static_cast<RenderBlock*>(obj), l, false, count);
+ int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
if (result != -1)
return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
}
@@ -4580,7 +4719,7 @@ int RenderBlock::lineCount()
else
for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
if (shouldCheckLines(obj))
- count += static_cast<RenderBlock*>(obj)->lineCount();
+ count += toRenderBlock(obj)->lineCount();
}
return count;
}
@@ -4599,16 +4738,16 @@ void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
if (childrenInline()) {
for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
if (box->firstChild())
- left = min(left, x + box->firstChild()->xPos());
+ left = min(left, x + box->firstChild()->x());
if (box->lastChild())
- right = max(right, x + box->lastChild()->xPos() + box->lastChild()->width());
+ right = max(right, x + box->lastChild()->x() + box->lastChild()->width());
}
}
else {
for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox()) {
if (!obj->isFloatingOrPositioned()) {
if (obj->isBlockFlow() && !obj->hasOverflowClip())
- static_cast<RenderBlock*>(obj)->adjustForBorderFit(x + obj->x(), left, right);
+ toRenderBlock(obj)->adjustForBorderFit(x + obj->x(), left, right);
else if (obj->style()->visibility() == VISIBLE) {
// We are a replaced element or some kind of non-block-flow object.
left = min(left, x + obj->x());
@@ -4669,7 +4808,7 @@ void RenderBlock::clearTruncation()
else
for (RenderObject* obj = firstChild(); obj; obj = obj->nextSibling())
if (shouldCheckLines(obj))
- static_cast<RenderBlock*>(obj)->clearTruncation();
+ toRenderBlock(obj)->clearTruncation();
}
}
@@ -4695,6 +4834,218 @@ void RenderBlock::setMaxBottomMargins(int pos, int neg)
m_maxMargin->m_bottomNeg = neg;
}
+void RenderBlock::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel)
+{
+ // For blocks inside inlines, we go ahead and include margins so that we run right up to the
+ // inline boxes above and below us (thus getting merged with them to form a single irregular
+ // shape).
+ if (topLevel && inlineContinuation()) {
+ rects.append(IntRect(tx, ty - collapsedMarginTop(),
+ width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
+ inlineContinuation()->absoluteRects(rects,
+ tx - x() + inlineContinuation()->containingBlock()->x(),
+ ty - y() + inlineContinuation()->containingBlock()->y(), topLevel);
+ } else
+ rects.append(IntRect(tx, ty, width(), height()));
+}
+
+void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel)
+{
+ // For blocks inside inlines, we go ahead and include margins so that we run right up to the
+ // inline boxes above and below us (thus getting merged with them to form a single irregular
+ // shape).
+ if (topLevel && inlineContinuation()) {
+ FloatRect localRect(0, -collapsedMarginTop(),
+ width(), height() + collapsedMarginTop() + collapsedMarginBottom());
+ quads.append(localToAbsoluteQuad(localRect));
+ inlineContinuation()->absoluteQuads(quads, topLevel);
+ } else
+ quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
+}
+
+IntRect RenderBlock::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
+{
+ IntRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
+ if (inlineContinuation())
+ r.inflateY(collapsedMarginTop());
+ return r;
+}
+
+RenderObject* RenderBlock::hoverAncestor() const
+{
+ return inlineContinuation() ? inlineContinuation() : RenderBox::hoverAncestor();
+}
+
+void RenderBlock::updateDragState(bool dragOn)
+{
+ RenderBox::updateDragState(dragOn);
+ if (inlineContinuation())
+ inlineContinuation()->updateDragState(dragOn);
+}
+
+RenderStyle* RenderBlock::outlineStyleForRepaint() const
+{
+ return inlineContinuation() ? inlineContinuation()->style() : style();
+}
+
+void RenderBlock::childBecameNonInline(RenderObject*)
+{
+ makeChildrenNonInline();
+ if (isAnonymousBlock() && parent() && parent()->isRenderBlock())
+ toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);
+ // |this| may be dead here
+}
+
+void RenderBlock::updateHitTestResult(HitTestResult& result, const IntPoint& point)
+{
+ if (result.innerNode())
+ return;
+
+ Node* n = node();
+ if (inlineContinuation())
+ // We are in the margins of block elements that are part of a continuation. In
+ // this case we're actually still inside the enclosing inline element that was
+ // split. Go ahead and set our inner node accordingly.
+ n = inlineContinuation()->node();
+
+ if (n) {
+ result.setInnerNode(n);
+ if (!result.innerNonSharedNode())
+ result.setInnerNonSharedNode(n);
+ result.setLocalPoint(point);
+ }
+}
+
+IntRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
+{
+ // Do the normal calculation in most cases.
+ if (firstChild())
+ return RenderBox::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
+
+ // This is a special case:
+ // The element is not an inline element, and it's empty. So we have to
+ // calculate a fake position to indicate where objects are to be inserted.
+
+ // FIXME: This does not take into account either :first-line or :first-letter
+ // However, as soon as some content is entered, the line boxes will be
+ // constructed and this kludge is not called any more. So only the caret size
+ // of an empty :first-line'd block is wrong. I think we can live with that.
+ RenderStyle* currentStyle = firstLineStyle();
+ int height = lineHeight(true);
+
+ enum CaretAlignment { alignLeft, alignRight, alignCenter };
+
+ CaretAlignment alignment = alignLeft;
+
+ switch (currentStyle->textAlign()) {
+ case TAAUTO:
+ case JUSTIFY:
+ if (currentStyle->direction() == RTL)
+ alignment = alignRight;
+ break;
+ case LEFT:
+ case WEBKIT_LEFT:
+ break;
+ case CENTER:
+ case WEBKIT_CENTER:
+ alignment = alignCenter;
+ break;
+ case RIGHT:
+ case WEBKIT_RIGHT:
+ alignment = alignRight;
+ break;
+ }
+
+ int x = borderLeft() + paddingLeft();
+ int w = width();
+
+ switch (alignment) {
+ case alignLeft:
+ break;
+ case alignCenter:
+ x = (x + w - (borderRight() + paddingRight())) / 2;
+ break;
+ case alignRight:
+ x = w - (borderRight() + paddingRight());
+ break;
+ }
+
+ if (extraWidthToEndOfLine) {
+ if (isRenderBlock()) {
+ *extraWidthToEndOfLine = w - (x + caretWidth);
+ } else {
+ // FIXME: This code looks wrong.
+ // myRight and containerRight are set up, but then clobbered.
+ // So *extraWidthToEndOfLine will always be 0 here.
+
+ int myRight = x + caretWidth;
+ // FIXME: why call localToAbsoluteForContent() twice here, too?
+ FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
+
+ int containerRight = containingBlock()->x() + containingBlockWidthForContent();
+ FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
+
+ *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
+ }
+ }
+
+ int y = paddingTop() + borderTop();
+
+ return IntRect(x, y, caretWidth, height);
+}
+
+void RenderBlock::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
+{
+ // For blocks inside inlines, we go ahead and include margins so that we run right up to the
+ // inline boxes above and below us (thus getting merged with them to form a single irregular
+ // shape).
+ if (inlineContinuation()) {
+ // FIXME: This check really isn't accurate.
+ bool nextInlineHasLineBox = inlineContinuation()->firstLineBox();
+ // FIXME: This is wrong. The principal renderer may not be the continuation preceding this block.
+ bool prevInlineHasLineBox = toRenderInline(inlineContinuation()->node()->renderer())->firstLineBox();
+ int topMargin = prevInlineHasLineBox ? collapsedMarginTop() : 0;
+ int bottomMargin = nextInlineHasLineBox ? collapsedMarginBottom() : 0;
+ graphicsContext->addFocusRingRect(IntRect(tx, ty - topMargin,
+ width(), height() + topMargin + bottomMargin));
+ } else
+ graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
+
+ if (!hasOverflowClip() && !hasControlClip()) {
+ for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
+
+ for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+ if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
+ RenderBox* box = toRenderBox(curr);
+ FloatPoint pos;
+ // FIXME: This doesn't work correctly with transforms.
+ if (box->layer())
+ pos = curr->localToAbsolute();
+ else
+ pos = FloatPoint(tx + box->x(), ty + box->y());
+ box->addFocusRingRects(graphicsContext, pos.x(), pos.y());
+ }
+ }
+ }
+
+ if (inlineContinuation())
+ inlineContinuation()->addFocusRingRects(graphicsContext,
+ tx - x() + inlineContinuation()->containingBlock()->x(),
+ ty - y() + inlineContinuation()->containingBlock()->y());
+}
+
+RenderBlock* RenderBlock::createAnonymousBlock() const
+{
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(BLOCK);
+
+ RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
+ newBox->setStyle(newStyle.release());
+ return newBox;
+}
+
const char* RenderBlock::renderName() const
{
if (isBody())
diff --git a/WebCore/rendering/RenderBlock.h b/WebCore/rendering/RenderBlock.h
index 2e74e41..d7a26ef 100644
--- a/WebCore/rendering/RenderBlock.h
+++ b/WebCore/rendering/RenderBlock.h
@@ -27,7 +27,8 @@
#include "DeprecatedPtrList.h"
#include "GapRects.h"
-#include "RenderFlow.h"
+#include "RenderBox.h"
+#include "RenderLineBoxList.h"
#include "RootInlineBox.h"
#include <wtf/ListHashSet.h>
@@ -36,6 +37,7 @@ namespace WebCore {
class InlineIterator;
class BidiRun;
class Position;
+class RenderInline;
class RootInlineBox;
template <class Iterator, class Run> class BidiResolver;
@@ -43,11 +45,18 @@ typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
enum CaretType { CursorCaret, DragCaret };
-class RenderBlock : public RenderFlow {
+class RenderBlock : public RenderBox {
public:
RenderBlock(Node*);
virtual ~RenderBlock();
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
+ virtual void destroy();
+
virtual const char* renderName() const;
// These two functions are overridden for inline-block.
@@ -58,10 +67,17 @@ public:
virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
- virtual bool childrenInline() const { return m_childrenInline; }
- virtual void setChildrenInline(bool b) { m_childrenInline = b; }
void makeChildrenNonInline(RenderObject* insertionPoint = 0);
+ virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
+
+ RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
+ const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
+
+ InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
+ InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
+
void deleteLineBoxTree();
+ virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
// The height (and width) of a block when you include overflow spillage out of the bottom
// of the block (e.g., a <div style="height:25px"> that has a 100px tall image inside
@@ -77,8 +93,6 @@ public:
void addVisualOverflow(const IntRect&);
virtual bool isSelfCollapsingBlock() const;
- virtual bool isTopMarginQuirk() const { return m_topMarginQuirk; }
- virtual bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
virtual int maxTopMargin(bool positive) const { return positive ? maxTopPosMargin() : maxTopNegMargin(); }
virtual int maxBottomMargin(bool positive) const { return positive ? maxBottomPosMargin() : maxBottomNegMargin(); }
@@ -100,7 +114,7 @@ public:
}
}
- virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject*);
virtual void repaintOverhangingFloats(bool paintAllDescendants);
@@ -117,11 +131,16 @@ public:
void addPercentHeightDescendant(RenderBox*);
static void removePercentHeightDescendant(RenderBox*);
+ HashSet<RenderBox*>* percentHeightDescendants() const;
virtual void positionListMarker() { }
virtual void borderFitAdjust(int& x, int& w) const; // Shrink the box in which the border paints if border-fit is set.
+ virtual void updateBeforeAfterContent(PseudoId);
+
+ RootInlineBox* createRootInlineBox();
+
// Called to lay out the legend for a fieldset.
virtual RenderObject* layoutLegend(bool /*relayoutChildren*/) { return 0; }
@@ -138,7 +157,7 @@ public:
};
void bidiReorderLine(InlineBidiResolver&, const InlineIterator& end);
- RootInlineBox* determineStartPosition(bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
+ RootInlineBox* determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver&, Vector<FloatWithRect>& floats, unsigned& numCleanFloats);
RootInlineBox* determineEndPosition(RootInlineBox* startBox, InlineIterator& cleanLineStart,
BidiStatus& cleanLineBidiStatus,
int& yPos);
@@ -146,12 +165,12 @@ public:
RootInlineBox*& endLine, int& endYPos, int& repaintBottom, int& repaintTop);
bool generatesLineBoxesForInlineChild(RenderObject*);
void skipTrailingWhitespace(InlineIterator&);
- int skipLeadingWhitespace(InlineBidiResolver&);
- void fitBelowFloats(int widthToFit, int& availableWidth);
- InlineIterator findNextLineBreak(InlineBidiResolver&, EClear* clear = 0);
- RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool lastLine, RenderObject* endObject);
- InlineFlowBox* createLineBoxes(RenderObject*);
- void computeHorizontalPositionsForLine(RootInlineBox*, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd);
+ int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine);
+ void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
+ InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, EClear* clear = 0);
+ RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
+ InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
+ void computeHorizontalPositionsForLine(RootInlineBox*, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd);
void computeVerticalPositionsForLine(RootInlineBox*, BidiRun*);
void checkLinesForOverflow();
void deleteEllipsisLineBoxes();
@@ -162,7 +181,8 @@ public:
virtual void paintObject(PaintInfo&, int tx, int ty);
void paintFloats(PaintInfo&, int tx, int ty, bool preservePhase = false);
void paintContents(PaintInfo&, int tx, int ty);
- void paintColumns(PaintInfo&, int tx, int ty, bool paintFloats = false);
+ void paintColumnContents(PaintInfo&, int tx, int ty, bool paintFloats = false);
+ void paintColumnRules(PaintInfo&, int tx, int ty);
void paintChildren(PaintInfo&, int tx, int ty);
void paintEllipsisBoxes(PaintInfo&, int tx, int ty);
void paintSelection(PaintInfo&, int tx, int ty);
@@ -175,16 +195,16 @@ public:
// Returns ture if and only if it has positioned any floats.
bool positionNewFloats();
void clearFloats();
- int getClearDelta(RenderBox* child);
+ int getClearDelta(RenderBox* child, int yPos);
void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
void markPositionedObjectsForLayout();
- virtual bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
- virtual bool containsFloat(RenderObject*);
+ bool containsFloats() { return m_floatingObjects && !m_floatingObjects->isEmpty(); }
+ bool containsFloat(RenderObject*);
virtual bool avoidsFloats() const;
- virtual bool hasOverhangingFloats() { return !hasColumns() && floatBottom() > height(); }
+ bool hasOverhangingFloats() { return parent() && !hasColumns() && floatBottom() > height(); }
void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset);
int addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset, bool makeChildPaintOtherFloats);
@@ -194,18 +214,18 @@ public:
inline int rightBottom();
IntRect floatRect() const;
- virtual int lineWidth(int) const;
+ int lineWidth(int y, bool firstLine) const;
virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
int rightOffset() const;
int rightRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
- int rightOffset(int y) const { return rightRelOffset(y, rightOffset(), true); }
+ int rightOffset(int y, bool firstLine) const { return rightRelOffset(y, rightOffset(), firstLine); }
int leftOffset() const;
int leftRelOffset(int y, int fixedOffset, bool applyTextIndent = true, int* heightRemaining = 0) const;
- int leftOffset(int y) const { return leftRelOffset(y, leftOffset(), true); }
+ int leftOffset(int y, bool firstLine) const { return leftRelOffset(y, leftOffset(), firstLine); }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual bool hitTestColumns(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -213,7 +233,7 @@ public:
virtual bool isPointInOverflowControl(HitTestResult&, int x, int y, int tx, int ty);
- virtual VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
// Block flows subclass availableWidth to handle multi column layout (shrinking the width available to children when laying out.)
virtual int availableWidth() const;
@@ -222,8 +242,8 @@ public:
void calcInlinePrefWidths();
void calcBlockPrefWidths();
- virtual int getBaselineOfFirstLineBox() const;
- virtual int getBaselineOfLastLineBox() const;
+ virtual int firstLineBoxBaseline() const;
+ virtual int lastLineBoxBaseline() const;
RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
@@ -237,38 +257,22 @@ public:
bool inRootBlockContext() const;
- void setHasMarkupTruncation(bool b = true) { m_hasMarkupTruncation = b; }
- bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
+ virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
+ virtual RenderStyle* outlineStyleForRepaint() const;
+
+ virtual RenderObject* hoverAncestor() const;
+ virtual void updateDragState(bool dragOn);
+ virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
+
+ virtual void childBecameNonInline(RenderObject* child);
- virtual bool hasSelectedChildren() const { return m_selectionState != SelectionNone; }
- virtual SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); }
virtual void setSelectionState(SelectionState s);
- struct BlockSelectionInfo {
- RenderBlock* m_block;
- GapRects m_rects;
- SelectionState m_state;
-
- BlockSelectionInfo()
- : m_block(0)
- , m_state(SelectionNone)
- {
- }
-
- BlockSelectionInfo(RenderBlock* b)
- : m_block(b)
- , m_rects(b->needsLayout() ? GapRects() : b->selectionGapRects())
- , m_state(b->selectionState())
- {
- }
-
- RenderBlock* block() const { return m_block; }
- GapRects rects() const { return m_rects; }
- SelectionState state() const { return m_state; }
- };
-
- virtual IntRect selectionRect(bool) { return selectionGapRects(); }
- GapRects selectionGapRects();
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/)
+ {
+ return selectionGapRectsForRepaint(repaintContainer);
+ }
+ GapRects selectionGapRectsForRepaint(RenderBoxModelObject* repaintContainer);
virtual bool shouldPaintSelectionGaps() const;
bool isSelectionRoot() const;
GapRects fillSelectionGaps(RenderBlock* rootBlock, int blockX, int blockY, int tx, int ty,
@@ -289,6 +293,9 @@ public:
int leftSelectionOffset(RenderBlock* rootBlock, int y);
int rightSelectionOffset(RenderBlock* rootBlock, int y);
+ virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
+
// Helper methods for computing line counts and heights for line counts.
RootInlineBox* lineAtIndex(int);
int lineCount();
@@ -299,12 +306,24 @@ public:
unsigned desiredColumnCount() const;
Vector<IntRect>* columnRects() const;
void setDesiredColumnCountAndWidth(int count, int width);
+ int columnGap() const;
void adjustRectForColumns(IntRect&) const;
- void addContinuationWithOutline(RenderFlow*);
+ void addContinuationWithOutline(RenderInline*);
void paintContinuationOutlines(PaintInfo&, int tx, int ty);
+ RenderInline* inlineContinuation() const { return m_inlineContinuation; }
+ void setInlineContinuation(RenderInline* c) { m_inlineContinuation = c; }
+
+ virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
+
+ virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+
+ // This function is a convenience helper for creating an anonymous block that inherits its
+ // style from this RenderBlock.
+ RenderBlock* createAnonymousBlock() const;
+
private:
void adjustPointToColumnContents(IntPoint&) const;
void adjustForBorderFit(int x, int& left, int& right) const; // Helper function for borderFitAdjust
@@ -312,13 +331,15 @@ private:
void markLinesDirtyInVerticalRange(int top, int bottom);
protected:
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void newLine(EClear);
virtual bool hasLineIfEmpty() const;
bool layoutOnlyPositionedObjects();
+ virtual RootInlineBox* createRootBox(); // Subclassed by SVG.
+
private:
Position positionForBox(InlineBox*, bool start = true) const;
Position positionForRenderer(RenderObject*, bool start = true) const;
@@ -326,15 +347,6 @@ private:
// Adjust tx and ty from painting offsets to the local coords of this renderer
void offsetForContents(int& tx, int& ty) const;
- // columGap() is used by WebKit when hit-testing columns. It's called by
- // CacheBuilder when it duplicates the hit-testing logic.
-#ifdef ANDROID_EXPOSE_COLUMN_GAP
- public:
-#endif
- int columnGap() const;
-#ifdef ANDROID_EXPOSE_COLUMN_GAP
-private:
-#endif
void calcColumnWidth();
int layoutColumns(int endOfContent = -1);
@@ -443,8 +455,8 @@ protected:
RenderBox* handleFloatingChild(RenderBox* child, const MarginInfo&, bool& handled);
RenderBox* handlePositionedChild(RenderBox* child, const MarginInfo&, bool& handled);
RenderBox* handleRunInChild(RenderBox* child, bool& handled);
- void collapseMargins(RenderBox* child, MarginInfo&, int yPosEstimate);
- void clearFloatsIfNeeded(RenderBox* child, MarginInfo&, int oldTopPosMargin, int oldTopNegMargin);
+ int collapseMargins(RenderBox* child, MarginInfo&);
+ int clearFloatsIfNeeded(RenderBox* child, MarginInfo&, int oldTopPosMargin, int oldTopNegMargin, int yPos);
int estimateVerticalPosition(RenderBox* child, const MarginInfo&);
void determineHorizontalPosition(RenderBox* child);
void handleBottomOfBlock(int top, int bottom, MarginInfo&);
@@ -455,7 +467,13 @@ private:
typedef ListHashSet<RenderBox*>::const_iterator Iterator;
DeprecatedPtrList<FloatingObject>* m_floatingObjects;
ListHashSet<RenderBox*>* m_positionedObjects;
-
+
+ // An inline can be split with blocks occurring in between the inline content.
+ // When this occurs we need a pointer to our next object. We can basically be
+ // split into a sequence of inlines and blocks. The continuation will either be
+ // an anonymous block (that houses other blocks) or it will be an inline flow.
+ RenderInline* m_inlineContinuation;
+
// Allocated only when some of these fields have non-default values
struct MaxMargin {
MaxMargin(const RenderBlock* o)
@@ -480,13 +498,33 @@ private:
MaxMargin* m_maxMargin;
protected:
+ RenderObjectChildList m_children;
+ RenderLineBoxList m_lineBoxes; // All of the root line boxes created for this block flow. For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
+
// How much content overflows out of our block vertically or horizontally.
int m_overflowHeight;
int m_overflowWidth;
int m_overflowLeft;
int m_overflowTop;
+
+ mutable int m_lineHeight;
};
+inline RenderBlock* toRenderBlock(RenderObject* o)
+{
+ ASSERT(!o || o->isRenderBlock());
+ return static_cast<RenderBlock*>(o);
+}
+
+inline const RenderBlock* toRenderBlock(const RenderObject* o)
+{
+ ASSERT(!o || o->isRenderBlock());
+ return static_cast<const RenderBlock*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderBlock(const RenderBlock* o);
+
} // namespace WebCore
#endif // RenderBlock_h
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 7711f5e..5827f00 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -30,6 +30,7 @@
#include "Document.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "htmlediting.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "ImageBuffer.h"
@@ -40,13 +41,13 @@
#include "RenderFlexibleBox.h"
#include "RenderInline.h"
#include "RenderLayer.h"
-#include "RenderReplica.h"
#include "RenderTableCell.h"
#include "RenderTheme.h"
#ifdef ANDROID_LAYOUT
#include "Settings.h"
#endif
#include "RenderView.h"
+#include "TransformState.h"
#include <algorithm>
#include <math.h>
@@ -64,11 +65,10 @@ using namespace HTMLNames;
typedef WTF::HashMap<const RenderBox*, int> OverrideSizeMap;
static OverrideSizeMap* gOverrideSizeMap = 0;
-bool RenderBox::s_wasFloating = false;
bool RenderBox::s_hadOverflowClip = false;
RenderBox::RenderBox(Node* node)
- : RenderObject(node)
+ : RenderBoxModelObject(node)
#ifdef ANDROID_LAYOUT
, m_visibleWidth(0)
#endif
@@ -78,7 +78,6 @@ RenderBox::RenderBox(Node* node)
, m_marginBottom(0)
, m_minPrefWidth(-1)
, m_maxPrefWidth(-1)
- , m_layer(0)
, m_inlineBoxWrapper(0)
{
setIsBox();
@@ -96,51 +95,61 @@ void RenderBox::destroy()
if (hasOverrideSize())
gOverrideSizeMap->remove(this);
- // This must be done before we destroy the RenderObject.
- if (m_layer)
- m_layer->clearClipRects();
-
if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent()))
RenderBlock::removePercentHeightDescendant(this);
- RenderObject::destroy();
+ RenderBoxModelObject::destroy();
+}
+
+void RenderBox::removeFloatingOrPositionedChildFromBlockLists()
+{
+ ASSERT(isFloatingOrPositioned());
+
+ if (documentBeingDestroyed())
+ return;
+
+ if (isFloating()) {
+ RenderBlock* outermostBlock = containingBlock();
+ for (RenderBlock* p = outermostBlock; p && !p->isRenderView(); p = p->containingBlock()) {
+ if (p->containsFloat(this))
+ outermostBlock = p;
+ }
+
+ if (outermostBlock)
+ outermostBlock->markAllDescendantsWithFloatsForLayout(this, false);
+ }
+
+ if (isPositioned()) {
+ RenderObject* p;
+ for (p = parent(); p; p = p->parent()) {
+ if (p->isRenderBlock())
+ toRenderBlock(p)->removePositionedObject(this);
+ }
+ }
}
-void RenderBox::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
- s_wasFloating = isFloating();
s_hadOverflowClip = hasOverflowClip();
if (style()) {
- // If our z-index changes value or our visibility changes,
- // we need to dirty our stacking context's z-order list.
- if (newStyle) {
- if (hasLayer() && (style()->hasAutoZIndex() != newStyle->hasAutoZIndex() ||
- style()->zIndex() != newStyle->zIndex() ||
- style()->visibility() != newStyle->visibility())) {
- layer()->dirtyStackingContextZOrderLists();
- if (style()->hasAutoZIndex() != newStyle->hasAutoZIndex() || style()->visibility() != newStyle->visibility())
- layer()->dirtyZOrderLists();
- }
- }
-
// The background of the root element or the body element could propagate up to
// the canvas. Just dirty the entire canvas when our style changes substantially.
- if (diff >= RenderStyle::Repaint && element() &&
- (element()->hasTagName(htmlTag) || element()->hasTagName(bodyTag)))
+ if (diff >= StyleDifferenceRepaint && node() &&
+ (node()->hasTagName(htmlTag) || node()->hasTagName(bodyTag)))
view()->repaint();
else if (parent() && !isText()) {
// Do a repaint with the old style first, e.g., for example if we go from
// having an outline to not having an outline.
- if (diff == RenderStyle::RepaintLayer) {
+ if (diff == StyleDifferenceRepaintLayer) {
layer()->repaintIncludingDescendants();
if (!(style()->clip() == newStyle->clip()))
layer()->clearClipRectsIncludingDescendants();
- } else if (diff == RenderStyle::Repaint || newStyle->outlineSize() < style()->outlineSize())
+ } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < style()->outlineSize())
repaint();
}
- if (diff == RenderStyle::Layout) {
+ if (diff == StyleDifferenceLayout) {
// When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could
// end up being destroyed.
if (hasLayer()) {
@@ -165,26 +174,45 @@ void RenderBox::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newSt
if (style()->position() == StaticPosition)
repaint();
if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))
- removeFromObjectLists();
+ removeFloatingOrPositionedChildFromBlockLists();
}
}
}
- RenderObject::styleWillChange(diff, newStyle);
+ RenderBoxModelObject::styleWillChange(diff, newStyle);
}
-void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
- // during the style change (it's used by clippedOverflowRectForRepaint()).
- if (style()->outlineWidth() > 0 && style()->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
- static_cast<RenderView*>(document()->renderer())->setMaximalOutlineSize(style()->outlineSize());
-
- RenderObject::styleDidChange(diff, oldStyle);
+ RenderBoxModelObject::styleDidChange(diff, oldStyle);
if (needsLayout() && oldStyle && (oldStyle->height().isPercent() || oldStyle->minHeight().isPercent() || oldStyle->maxHeight().isPercent()))
RenderBlock::removePercentHeightDescendant(this);
+ // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
+ // new zoomed coordinate space.
+ if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {
+ int left = scrollLeft();
+ if (left) {
+ left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();
+ setScrollLeft(left);
+ }
+ int top = scrollTop();
+ if (top) {
+ top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();
+ setScrollTop(top);
+ }
+ }
+
+ // Set the text color if we're the body.
+ if (isBody())
+ document()->setTextColor(style()->color());
+}
+
+void RenderBox::updateBoxModelInfoFromStyle()
+{
+ RenderBoxModelObject::updateBoxModelInfoFromStyle();
+
bool isRootObject = isRoot();
bool isViewObject = isRenderView();
@@ -192,23 +220,8 @@ void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldSty
if (isRootObject || isViewObject)
setHasBoxDecorations(true);
- setInline(style()->isDisplayInlineType());
-
- switch (style()->position()) {
- case AbsolutePosition:
- case FixedPosition:
- setPositioned(true);
- break;
- default:
- setPositioned(false);
-
- if (style()->isFloating())
- setFloating(true);
-
- if (style()->position() == RelativePosition)
- setRelPositioned(true);
- break;
- }
+ setPositioned(style()->position() == AbsolutePosition || style()->position() == FixedPosition);
+ setFloating(!isPositioned() && style()->isFloating());
// We also handle <body> and <html>, whose overflow applies to the viewport.
if (style()->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) {
@@ -219,7 +232,7 @@ void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldSty
// (2) We are the primary <body> (can be checked by looking at document.body).
// (3) The root element has visible overflow.
if (document()->documentElement()->hasTagName(htmlTag) &&
- document()->body() == element() &&
+ document()->body() == node() &&
document()->documentElement()->renderer()->style()->overflowX() == OVISIBLE)
boxHasOverflowClip = false;
}
@@ -234,133 +247,28 @@ void RenderBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldSty
}
}
- setHasTransform(style()->hasTransform());
+ setHasTransform(style()->hasTransformRelatedProperty());
setHasReflection(style()->boxReflect());
-
- if (requiresLayer()) {
- if (!m_layer) {
- if (s_wasFloating && isFloating())
- setChildNeedsLayout(true);
- m_layer = new (renderArena()) RenderLayer(this);
- setHasLayer(true);
- m_layer->insertOnlyThisLayer();
- if (parent() && !needsLayout() && containingBlock())
- m_layer->updateLayerPositions();
- }
- } else if (m_layer && !isRootObject && !isViewObject) {
- ASSERT(m_layer->parent());
- RenderLayer* layer = m_layer;
- m_layer = 0;
- setHasLayer(false);
- setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
- setHasReflection(false);
- layer->removeOnlyThisLayer();
- if (s_wasFloating && isFloating())
- setChildNeedsLayout(true);
- }
-
- // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the
- // new zoomed coordinate space.
- if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {
- int left = scrollLeft();
- if (left) {
- left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();
- setScrollLeft(left);
- }
- int top = scrollTop();
- if (top) {
- top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();
- setScrollTop(top);
- }
- }
-
- if (m_layer)
- m_layer->styleChanged(diff, oldStyle);
-
- // Set the text color if we're the body.
- if (isBody())
- document()->setTextColor(style()->color());
}
-
-int RenderBox::offsetLeft() const
+void RenderBox::layout()
{
- RenderBox* offsetPar = offsetParent();
- if (!offsetPar)
- return 0;
- int xPos = x() - offsetPar->borderLeft();
- if (!isPositioned()) {
- if (isRelPositioned())
- xPos += relativePositionOffsetX();
- RenderObject* curr = parent();
- while (curr && curr != offsetPar) {
- // FIXME: What are we supposed to do inside SVG content?
- if (curr->isBox() && !curr->isTableRow())
- xPos += toRenderBox(curr)->x();
- curr = curr->parent();
- }
- if (offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
- xPos += offsetPar->x();
- }
- return xPos;
-}
+ ASSERT(needsLayout());
-int RenderBox::offsetTop() const
-{
- RenderBox* offsetPar = offsetParent();
- if (!offsetPar)
- return 0;
- int yPos = y() - offsetPar->borderTop();
- if (!isPositioned()) {
- if (isRelPositioned())
- yPos += relativePositionOffsetY();
- RenderObject* curr = parent();
- while (curr && curr != offsetPar) {
- // FIXME: What are we supposed to do inside SVG content?
- if (curr->isBox() && !curr->isTableRow())
- yPos += toRenderBox(curr)->y();
- curr = curr->parent();
- }
- if (offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
- yPos += offsetPar->y();
+ RenderObject* child = firstChild();
+ if (!child) {
+ setNeedsLayout(false);
+ return;
}
- return yPos;
-}
-
-RenderBox* RenderBox::offsetParent() const
-{
- // FIXME: It feels like this function could almost be written using containing blocks.
- if (isBody())
- return 0;
-
- bool skipTables = isPositioned() || isRelPositioned();
- float currZoom = style()->effectiveZoom();
- RenderObject* curr = parent();
- while (curr && (!curr->element() ||
- (!curr->isPositioned() && !curr->isRelPositioned() && !curr->isBody()))) {
- Node* element = curr->element();
- if (!skipTables && element) {
- bool isTableElement = element->hasTagName(tableTag) ||
- element->hasTagName(tdTag) ||
- element->hasTagName(thTag);
-
-#if ENABLE(WML)
- if (!isTableElement && element->isWMLElement())
- isTableElement = element->hasTagName(WMLNames::tableTag) ||
- element->hasTagName(WMLNames::tdTag);
-#endif
-
- if (isTableElement)
- break;
- }
- float newZoom = curr->style()->effectiveZoom();
- if (currZoom != newZoom)
- break;
- currZoom = newZoom;
- curr = curr->parent();
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ while (child) {
+ child->layoutIfNeeded();
+ ASSERT(!child->needsLayout());
+ child = child->nextSibling();
}
- return curr && curr->isBox() ? toRenderBox(curr) : 0;
+ statePusher.pop();
+ setNeedsLayout(false);
}
// More IE extensions. clientWidth and clientHeight represent the interior of an object
@@ -382,104 +290,47 @@ int RenderBox::clientHeight() const
int RenderBox::scrollWidth() const
{
if (hasOverflowClip())
- return m_layer->scrollWidth();
+ return layer()->scrollWidth();
return overflowWidth();
}
int RenderBox::scrollHeight() const
{
if (hasOverflowClip())
- return m_layer->scrollHeight();
+ return layer()->scrollHeight();
return overflowHeight();
}
int RenderBox::scrollLeft() const
{
- return hasOverflowClip() ? m_layer->scrollXOffset() : 0;
+ return hasOverflowClip() ? layer()->scrollXOffset() : 0;
}
int RenderBox::scrollTop() const
{
- return hasOverflowClip() ? m_layer->scrollYOffset() : 0;
+ return hasOverflowClip() ? layer()->scrollYOffset() : 0;
}
void RenderBox::setScrollLeft(int newLeft)
{
if (hasOverflowClip())
- m_layer->scrollToXOffset(newLeft);
+ layer()->scrollToXOffset(newLeft);
}
void RenderBox::setScrollTop(int newTop)
{
if (hasOverflowClip())
- m_layer->scrollToYOffset(newTop);
-}
-
-int RenderBox::paddingTop(bool) const
-{
- int w = 0;
- Length padding = style()->paddingTop();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
-}
-
-int RenderBox::paddingBottom(bool) const
-{
- int w = 0;
- Length padding = style()->paddingBottom();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
-}
-
-int RenderBox::paddingLeft(bool) const
-{
- int w = 0;
- Length padding = style()->paddingLeft();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
+ layer()->scrollToYOffset(newTop);
}
-int RenderBox::paddingRight(bool) const
+void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool)
{
- int w = 0;
- Length padding = style()->paddingRight();
- if (padding.isPercent())
- w = containingBlock()->availableWidth();
- return padding.calcMinValue(w);
+ rects.append(IntRect(tx, ty, width(), height()));
}
-void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel)
+void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool)
{
- // For blocks inside inlines, we go ahead and include margins so that we run right up to the
- // inline boxes above and below us (thus getting merged with them to form a single irregular
- // shape).
- RenderFlow* continuation = virtualContinuation();
- if (topLevel && continuation) {
- rects.append(IntRect(tx, ty - collapsedMarginTop(),
- width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
- continuation->absoluteRects(rects,
- tx - x() + continuation->containingBlock()->x(),
- ty - y() + continuation->containingBlock()->y(), topLevel);
- } else
- rects.append(IntRect(tx, ty, width(), height()));
-}
-
-void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel)
-{
- // For blocks inside inlines, we go ahead and include margins so that we run right up to the
- // inline boxes above and below us (thus getting merged with them to form a single irregular
- // shape).
- RenderFlow* continuation = virtualContinuation();
- if (topLevel && continuation) {
- FloatRect localRect(0, -collapsedMarginTop(),
- width(), height() + collapsedMarginTop() + collapsedMarginBottom());
- quads.append(localToAbsoluteQuad(localRect));
- continuation->absoluteQuads(quads, topLevel);
- } else
- quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
+ quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height())));
}
IntRect RenderBox::absoluteContentBox() const
@@ -497,7 +348,7 @@ FloatQuad RenderBox::absoluteContentQuad() const
}
-IntRect RenderBox::outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const
+IntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const
{
IntRect box = borderBoundingBox();
adjustRectForOutlineAndShadow(box);
@@ -514,17 +365,7 @@ IntRect RenderBox::outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) cons
void RenderBox::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
{
- // For blocks inside inlines, we go ahead and include margins so that we run right up to the
- // inline boxes above and below us (thus getting merged with them to form a single irregular
- // shape).
- RenderFlow* continuation = virtualContinuation();
- if (continuation) {
- graphicsContext->addFocusRingRect(IntRect(tx, ty - collapsedMarginTop(), width(), height() + collapsedMarginTop() + collapsedMarginBottom()));
- continuation->addFocusRingRects(graphicsContext,
- tx - x() + continuation->containingBlock()->x(),
- ty - y() + continuation->containingBlock()->y());
- } else
- graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
+ graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
}
@@ -709,11 +550,7 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
// Check kids first.
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- // FIXME: We have to skip over inline flows, since they can show up inside table rows
- // at the moment (a demoted inline <form> for example). If we ever implement a
- // table-specific hit-test method (which we should do for performance reasons anyway),
- // then we can remove this check.
- if (!child->hasLayer() && !child->isRenderInline() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ if (!child->hasLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
return true;
}
@@ -747,7 +584,7 @@ void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
{
const FillLayer* bgLayer = style()->backgroundLayers();
Color bgColor = style()->backgroundColor();
- if (!style()->hasBackground() && element() && element()->hasTagName(HTMLNames::htmlTag)) {
+ if (!style()->hasBackground() && node() && node()->hasTagName(HTMLNames::htmlTag)) {
// Locate the <body> element using the DOM. This is easier than trying
// to crawl around a render tree with potential :before/:after content and
// anonymous blocks created by inline <body> tags etc. We can locate the <body>
@@ -919,60 +756,20 @@ void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const
paintFillLayerExtended(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height, 0, op);
}
-IntSize RenderBox::calculateBackgroundSize(const FillLayer* bgLayer, int scaledWidth, int scaledHeight) const
-{
- StyleImage* bg = bgLayer->image();
- bg->setImageContainerSize(IntSize(scaledWidth, scaledHeight)); // Use the box established by background-origin.
-
- if (bgLayer->isSizeSet()) {
- int w = scaledWidth;
- int h = scaledHeight;
- Length bgWidth = bgLayer->size().width();
- Length bgHeight = bgLayer->size().height();
-
- if (bgWidth.isFixed())
- w = bgWidth.value();
- else if (bgWidth.isPercent())
- w = bgWidth.calcValue(scaledWidth);
-
- if (bgHeight.isFixed())
- h = bgHeight.value();
- else if (bgHeight.isPercent())
- h = bgHeight.calcValue(scaledHeight);
-
- // If one of the values is auto we have to use the appropriate
- // scale to maintain our aspect ratio.
- if (bgWidth.isAuto() && !bgHeight.isAuto())
- w = bg->imageSize(this, style()->effectiveZoom()).width() * h / bg->imageSize(this, style()->effectiveZoom()).height();
- else if (!bgWidth.isAuto() && bgHeight.isAuto())
- h = bg->imageSize(this, style()->effectiveZoom()).height() * w / bg->imageSize(this, style()->effectiveZoom()).width();
- else if (bgWidth.isAuto() && bgHeight.isAuto()) {
- // If both width and height are auto, we just want to use the image's
- // intrinsic size.
- w = bg->imageSize(this, style()->effectiveZoom()).width();
- h = bg->imageSize(this, style()->effectiveZoom()).height();
- }
-
- return IntSize(max(1, w), max(1, h));
- } else
- return bg->imageSize(this, style()->effectiveZoom());
-}
-
void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
{
if (!parent())
return;
- if (isRenderInline() || style()->borderImage().image() && style()->borderImage().image()->data() == image ||
- style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image) {
+ if ((style()->borderImage().image() && style()->borderImage().image()->data() == image) ||
+ (style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image)) {
repaint();
return;
}
bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLayers(), true);
- if (!didFullRepaint) {
+ if (!didFullRepaint)
repaintLayerRectsForImage(image, style()->maskLayers(), false);
- }
}
bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground)
@@ -992,7 +789,7 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
int rw;
int rh;
- if (FrameView* frameView = static_cast<RenderView*>(layerRenderer)->frameView()) {
+ if (FrameView* frameView = toRenderView(layerRenderer)->frameView()) {
rw = frameView->contentsWidth();
rh = frameView->contentsHeight();
} else {
@@ -1021,260 +818,6 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
return false;
}
-void RenderBox::calculateBackgroundImageGeometry(const FillLayer* bgLayer, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize)
-{
- int pw;
- int ph;
- int left = 0;
- int right = 0;
- int top = 0;
- int bottom = 0;
- int cx;
- int cy;
- int rw = 0;
- int rh = 0;
-
- // CSS2 chapter 14.2.1
-
- if (bgLayer->attachment()) {
- // Scroll
- if (bgLayer->origin() != BorderFillBox) {
- left = borderLeft();
- right = borderRight();
- top = borderTop();
- bottom = borderBottom();
- if (bgLayer->origin() == ContentFillBox) {
- left += paddingLeft();
- right += paddingRight();
- top += paddingTop();
- bottom += paddingBottom();
- }
- }
-
- // The background of the box generated by the root element covers the entire canvas including
- // its margins. Since those were added in already, we have to factor them out when computing the
- // box used by background-origin/size/position.
- if (isRoot()) {
- rw = width() - left - right;
- rh = height() - top - bottom;
- left += marginLeft();
- right += marginRight();
- top += marginTop();
- bottom += marginBottom();
- }
- cx = tx;
- cy = ty;
- pw = w - left - right;
- ph = h - top - bottom;
- } else {
- // Fixed
- IntRect vr = viewRect();
- cx = vr.x();
- cy = vr.y();
- pw = vr.width();
- ph = vr.height();
- }
-
- int sx = 0;
- int sy = 0;
- int cw;
- int ch;
-
- IntSize scaledImageSize;
- if (isRoot() && bgLayer->attachment())
- scaledImageSize = calculateBackgroundSize(bgLayer, rw, rh);
- else
- scaledImageSize = calculateBackgroundSize(bgLayer, pw, ph);
-
- int scaledImageWidth = scaledImageSize.width();
- int scaledImageHeight = scaledImageSize.height();
-
- EFillRepeat backgroundRepeat = bgLayer->repeat();
-
- int xPosition;
- if (isRoot() && bgLayer->attachment())
- xPosition = bgLayer->xPosition().calcMinValue(rw - scaledImageWidth, true);
- else
- xPosition = bgLayer->xPosition().calcMinValue(pw - scaledImageWidth, true);
- if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatXFill) {
- cw = pw + left + right;
- sx = scaledImageWidth ? scaledImageWidth - (xPosition + left) % scaledImageWidth : 0;
- } else {
- cx += max(xPosition + left, 0);
- sx = -min(xPosition + left, 0);
- cw = scaledImageWidth + min(xPosition + left, 0);
- }
-
- int yPosition;
- if (isRoot() && bgLayer->attachment())
- yPosition = bgLayer->yPosition().calcMinValue(rh - scaledImageHeight, true);
- else
- yPosition = bgLayer->yPosition().calcMinValue(ph - scaledImageHeight, true);
- if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatYFill) {
- ch = ph + top + bottom;
- sy = scaledImageHeight ? scaledImageHeight - (yPosition + top) % scaledImageHeight : 0;
- } else {
- cy += max(yPosition + top, 0);
- sy = -min(yPosition + top, 0);
- ch = scaledImageHeight + min(yPosition + top, 0);
- }
-
- if (!bgLayer->attachment()) {
- sx += max(tx - cx, 0);
- sy += max(ty - cy, 0);
- }
-
- destRect = IntRect(cx, cy, cw, ch);
- destRect.intersect(IntRect(tx, ty, w, h));
- phase = IntPoint(sx, sy);
- tileSize = IntSize(scaledImageWidth, scaledImageHeight);
-}
-
-void RenderBox::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, int clipY, int clipH,
- int tx, int ty, int w, int h, InlineFlowBox* box, CompositeOperator op)
-{
- GraphicsContext* context = paintInfo.context;
- bool includeLeftEdge = box ? box->includeLeftEdge() : true;
- bool includeRightEdge = box ? box->includeRightEdge() : true;
- int bLeft = includeLeftEdge ? borderLeft() : 0;
- int bRight = includeRightEdge ? borderRight() : 0;
- int pLeft = includeLeftEdge ? paddingLeft() : 0;
- int pRight = includeRightEdge ? paddingRight() : 0;
-
- bool clippedToBorderRadius = false;
- if (style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge)) {
- context->save();
- context->addRoundedRectClip(IntRect(tx, ty, w, h),
- includeLeftEdge ? style()->borderTopLeftRadius() : IntSize(),
- includeRightEdge ? style()->borderTopRightRadius() : IntSize(),
- includeLeftEdge ? style()->borderBottomLeftRadius() : IntSize(),
- includeRightEdge ? style()->borderBottomRightRadius() : IntSize());
- clippedToBorderRadius = true;
- }
-
- if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox) {
- // Clip to the padding or content boxes as necessary.
- bool includePadding = bgLayer->clip() == ContentFillBox;
- int x = tx + bLeft + (includePadding ? pLeft : 0);
- int y = ty + borderTop() + (includePadding ? paddingTop() : 0);
- int width = w - bLeft - bRight - (includePadding ? pLeft + pRight : 0);
- int height = h - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0);
- context->save();
- context->clip(IntRect(x, y, width, height));
- } else if (bgLayer->clip() == TextFillBox) {
- // We have to draw our text into a mask that can then be used to clip background drawing.
- // First figure out how big the mask has to be. It should be no bigger than what we need
- // to actually render, so we should intersect the dirty rect with the border box of the background.
- IntRect maskRect(tx, ty, w, h);
- maskRect.intersect(paintInfo.rect);
-
- // Now create the mask.
- auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
- if (!maskImage.get())
- return;
-
- GraphicsContext* maskImageContext = maskImage->context();
- maskImageContext->translate(-maskRect.x(), -maskRect.y());
-
- // Now add the text to the clip. We do this by painting using a special paint phase that signals to
- // InlineTextBoxes that they should just add their contents to the clip.
- PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, true, 0, 0);
- if (box)
- box->paint(info, tx - box->xPos(), ty - box->yPos());
- else
- paint(info, tx, ty);
-
- // The mask has been created. Now we just need to clip to it.
- context->save();
- context->clipToImageBuffer(maskRect, maskImage.get());
- }
-
- StyleImage* bg = bgLayer->image();
- bool shouldPaintBackgroundImage = bg && bg->canRender(style()->effectiveZoom());
- Color bgColor = c;
-
- // When this style flag is set, change existing background colors and images to a solid white background.
- // If there's no bg color or image, leave it untouched to avoid affecting transparency.
- // We don't try to avoid loading the background images, because this style flag is only set
- // when printing, and at that point we've already loaded the background images anyway. (To avoid
- // loading the background images we'd have to do this check when applying styles rather than
- // while rendering.)
- if (style()->forceBackgroundsToWhite()) {
- // Note that we can't reuse this variable below because the bgColor might be changed
- bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.isValid() && bgColor.alpha() > 0;
- if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) {
- bgColor = Color::white;
- shouldPaintBackgroundImage = false;
- }
- }
-
- // Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with
- // no background in the child document should show the parent's background.
- bool isTransparent = false;
- if (!bgLayer->next() && isRoot() && !(bgColor.isValid() && bgColor.alpha() > 0) && view()->frameView()) {
- Node* elt = document()->ownerElement();
- if (elt) {
- if (!elt->hasTagName(frameTag)) {
- // Locate the <body> element using the DOM. This is easier than trying
- // to crawl around a render tree with potential :before/:after content and
- // anonymous blocks created by inline <body> tags etc. We can locate the <body>
- // render object very easily via the DOM.
- HTMLElement* body = document()->body();
- isTransparent = !body || !body->hasLocalName(framesetTag); // Can't scroll a frameset document anyway.
- }
- } else
- isTransparent = view()->frameView()->isTransparent();
-
- // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
- if (isTransparent)
- view()->frameView()->setUseSlowRepaints(); // The parent must show behind the child.
- }
-
- // Paint the color first underneath all images.
- if (!bgLayer->next()) {
- IntRect rect(tx, clipY, w, clipH);
- // If we have an alpha and we are painting the root element, go ahead and blend with the base background color.
- if (isRoot() && (!bgColor.isValid() || bgColor.alpha() < 0xFF) && !isTransparent) {
- Color baseColor = view()->frameView()->baseBackgroundColor();
- if (baseColor.alpha() > 0) {
- context->save();
- context->setCompositeOperation(CompositeCopy);
- context->fillRect(rect, baseColor);
- context->restore();
-#ifdef ANDROID_ALLOW_TRANSPARENT_BACKGROUNDS
- }
-#else
- } else
- context->clearRect(rect);
-#endif
- }
-
- if (bgColor.isValid() && bgColor.alpha() > 0)
- context->fillRect(rect, bgColor);
- }
-
- // no progressive loading of the background image
- if (shouldPaintBackgroundImage) {
- IntRect destRect;
- IntPoint phase;
- IntSize tileSize;
-
- calculateBackgroundImageGeometry(bgLayer, tx, ty, w, h, destRect, phase, tileSize);
- if (!destRect.isEmpty()) {
- CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
- context->drawTiledImage(bg->image(this, tileSize), destRect, phase, tileSize, compositeOp);
- }
- }
-
- if (bgLayer->clip() != BorderFillBox)
- // Undo the background clip
- context->restore();
-
- if (clippedToBorderRadius)
- // Undo the border radius clip
- context->restore();
-}
-
#if PLATFORM(MAC)
void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, bool behindText)
@@ -1289,7 +832,7 @@ void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, b
InlineBox* boxWrap = inlineBoxWrapper();
RootInlineBox* r = boxWrap ? boxWrap->root() : 0;
if (r) {
- FloatRect rootRect(tx + r->xPos(), ty + r->selectionTop(), r->width(), r->selectionHeight());
+ FloatRect rootRect(tx + r->x(), ty + r->selectionTop(), r->width(), r->selectionHeight());
FloatRect imageRect(tx + x(), rootRect.y(), width(), rootRect.height());
page->chrome()->client()->paintCustomHighlight(node(), type, imageRect, rootRect, behindText, false);
} else {
@@ -1300,7 +843,50 @@ void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, b
#endif
-IntRect RenderBox::getOverflowClipRect(int tx, int ty)
+bool RenderBox::pushContentsClip(PaintInfo& paintInfo, int tx, int ty)
+{
+ if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseSelfOutline || paintInfo.phase == PaintPhaseMask)
+ return false;
+
+ bool isControlClip = hasControlClip();
+ bool isOverflowClip = hasOverflowClip() && !layer()->isSelfPaintingLayer();
+
+ if (!isControlClip && !isOverflowClip)
+ return false;
+
+ if (paintInfo.phase == PaintPhaseOutline)
+ paintInfo.phase = PaintPhaseChildOutlines;
+ else if (paintInfo.phase == PaintPhaseChildBlockBackground) {
+ paintInfo.phase = PaintPhaseBlockBackground;
+ paintObject(paintInfo, tx, ty);
+ paintInfo.phase = PaintPhaseChildBlockBackgrounds;
+ }
+ IntRect clipRect(isControlClip ? controlClipRect(tx, ty) : overflowClipRect(tx, ty));
+ paintInfo.context->save();
+ if (style()->hasBorderRadius())
+ paintInfo.context->addRoundedRectClip(clipRect, style()->borderTopLeftRadius(),
+ style()->borderTopRightRadius(),
+ style()->borderBottomLeftRadius(),
+ style()->borderBottomRightRadius());
+ else
+ paintInfo.context->clip(clipRect);
+ return true;
+}
+
+void RenderBox::popContentsClip(PaintInfo& paintInfo, PaintPhase originalPhase, int tx, int ty)
+{
+ ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer()));
+
+ paintInfo.context->restore();
+ if (originalPhase == PaintPhaseOutline) {
+ paintInfo.phase = PaintPhaseSelfOutline;
+ paintObject(paintInfo, tx, ty);
+ paintInfo.phase = originalPhase;
+ } else if (originalPhase == PaintPhaseChildBlockBackground)
+ paintInfo.phase = originalPhase;
+}
+
+IntRect RenderBox::overflowClipRect(int tx, int ty)
{
// FIXME: When overflow-clip (CSS3) is implemented, we'll obtain the property
// here.
@@ -1314,15 +900,15 @@ IntRect RenderBox::getOverflowClipRect(int tx, int ty)
int clipHeight = height() - bTop - borderBottom();
// Subtract out scrollbars if we have them.
- if (m_layer) {
- clipWidth -= m_layer->verticalScrollbarWidth();
- clipHeight -= m_layer->horizontalScrollbarHeight();
+ if (layer()) {
+ clipWidth -= layer()->verticalScrollbarWidth();
+ clipHeight -= layer()->horizontalScrollbarHeight();
}
return IntRect(clipX, clipY, clipWidth, clipHeight);
}
-IntRect RenderBox::getClipRect(int tx, int ty)
+IntRect RenderBox::clipRect(int tx, int ty)
{
int clipX = tx;
int clipY = ty;
@@ -1350,64 +936,28 @@ IntRect RenderBox::getClipRect(int tx, int ty)
return IntRect(clipX, clipY, clipWidth, clipHeight);
}
-int RenderBox::containingBlockWidth() const
+int RenderBox::containingBlockWidthForContent() const
{
RenderBlock* cb = containingBlock();
- if (!cb)
- return 0;
if (shrinkToAvoidFloats())
- return cb->lineWidth(y());
+ return cb->lineWidth(y(), false);
return cb->availableWidth();
}
-IntSize RenderBox::offsetForPositionedInContainer(RenderObject* container) const
+void RenderBox::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
{
- if (!container->isRelPositioned() || !container->isRenderInline())
- return IntSize();
-
- // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
- // box from the rest of the content, but only in the cases where we know we're positioned
- // relative to the inline itself.
-
- IntSize offset;
- RenderFlow* flow = static_cast<RenderFlow*>(container);
- int sx;
- int sy;
- if (flow->firstLineBox()) {
- sx = flow->firstLineBox()->xPos();
- sy = flow->firstLineBox()->yPos();
- } else {
- sx = flow->staticX();
- sy = flow->staticY();
- }
-
- if (!hasStaticX())
- offset.setWidth(sx);
- // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside
- // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct
- // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
- // do.
- else if (!style()->isOriginalDisplayInlineType())
- // Avoid adding in the left border/padding of the containing block twice. Subtract it out.
- offset.setWidth(sx - (containingBlock()->borderLeft() + containingBlock()->paddingLeft()));
-
- if (!hasStaticY())
- offset.setHeight(sy);
-
- return offset;
-}
+ if (repaintContainer == this)
+ return;
-FloatPoint RenderBox::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
-{
if (RenderView* v = view()) {
if (v->layoutStateEnabled()) {
LayoutState* layoutState = v->layoutState();
IntSize offset = layoutState->m_offset;
offset.expand(x(), y());
- localPoint += offset;
- if (style()->position() == RelativePosition && m_layer)
- localPoint += m_layer->relativePositionOffset();
- return localPoint;
+ if (style()->position() == RelativePosition && layer())
+ offset += layer()->relativePositionOffset();
+ transformState.move(offset);
+ return;
}
}
@@ -1415,21 +965,25 @@ FloatPoint RenderBox::localToAbsolute(FloatPoint localPoint, bool fixed, bool us
fixed = true;
RenderObject* o = container();
- if (o) {
- if (useTransforms && m_layer && m_layer->transform()) {
- fixed = false; // Elements with transforms act as a containing block for fixed position descendants
- localPoint = m_layer->transform()->mapPoint(localPoint);
- }
+ if (!o)
+ return;
- localPoint += offsetFromContainer(o);
+ bool hasTransform = hasLayer() && layer()->transform();
+ if (hasTransform)
+ fixed = false; // Elements with transforms act as a containing block for fixed position descendants
- return o->localToAbsolute(localPoint, fixed, useTransforms);
- }
-
- return FloatPoint();
+ IntSize containerOffset = offsetFromContainer(o);
+
+ bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
+ if (useTransforms && hasTransform)
+ transformState.applyTransform(transformFromContainer(o, containerOffset), preserve3D);
+ else
+ transformState.move(containerOffset.width(), containerOffset.height(), preserve3D);
+
+ o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
-FloatPoint RenderBox::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool useTransforms) const
+void RenderBox::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
{
// We don't expect absoluteToLocal() to be called during layout (yet)
ASSERT(!view() || !view()->layoutStateEnabled());
@@ -1437,41 +991,23 @@ FloatPoint RenderBox::absoluteToLocal(FloatPoint containerPoint, bool fixed, boo
if (style()->position() == FixedPosition)
fixed = true;
- if (useTransforms && m_layer && m_layer->transform())
- fixed = false;
+ bool hasTransform = hasLayer() && layer()->transform();
+ if (hasTransform)
+ fixed = false; // Elements with transforms act as a containing block for fixed position descendants
RenderObject* o = container();
- if (o) {
- FloatPoint localPoint = o->absoluteToLocal(containerPoint, fixed, useTransforms);
- localPoint -= offsetFromContainer(o);
- if (useTransforms && m_layer && m_layer->transform())
- localPoint = m_layer->transform()->inverse().mapPoint(localPoint);
- return localPoint;
- }
-
- return FloatPoint();
-}
+ if (!o)
+ return;
-FloatQuad RenderBox::localToContainerQuad(const FloatQuad& localQuad, RenderBox* repaintContainer, bool fixed) const
-{
- if (repaintContainer == this)
- return localQuad;
+ o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
- if (style()->position() == FixedPosition)
- fixed = true;
+ IntSize containerOffset = offsetFromContainer(o);
- RenderObject* o = container();
- if (o) {
- FloatQuad quad = localQuad;
- if (m_layer && m_layer->transform()) {
- fixed = false; // Elements with transforms act as a containing block for fixed position descendants
- quad = m_layer->transform()->mapQuad(quad);
- }
- quad += offsetFromContainer(o);
- return o->localToContainerQuad(quad, repaintContainer, fixed);
- }
-
- return FloatQuad();
+ bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D());
+ if (useTransforms && hasTransform)
+ transformState.applyTransform(transformFromContainer(o, containerOffset), preserve3D);
+ else
+ transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D);
}
IntSize RenderBox::offsetFromContainer(RenderObject* o) const
@@ -1485,7 +1021,7 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
if (!isInline() || isReplaced()) {
RenderBlock* cb;
if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition
- && (cb = static_cast<RenderBlock*>(o))->hasColumns()) {
+ && (cb = toRenderBlock(o))->hasColumns()) {
IntRect rect(x(), y(), 1, 1);
cb->adjustRectForColumns(rect);
offset.expand(rect.x(), rect.y());
@@ -1496,13 +1032,18 @@ IntSize RenderBox::offsetFromContainer(RenderObject* o) const
if (o->hasOverflowClip())
offset -= toRenderBox(o)->layer()->scrolledContentOffset();
- if (style()->position() == AbsolutePosition)
- offset += offsetForPositionedInContainer(o);
+ if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
+ offset += toRenderInline(o)->relativePositionedInlineOffset(this);
return offset;
}
-void RenderBox::dirtyLineBoxes(bool fullLayout, bool /*isRootLineBox*/)
+InlineBox* RenderBox::createInlineBox()
+{
+ return new (renderArena()) InlineBox(this);
+}
+
+void RenderBox::dirtyLineBoxes(bool fullLayout)
{
if (m_inlineBoxWrapper) {
if (fullLayout) {
@@ -1513,23 +1054,23 @@ void RenderBox::dirtyLineBoxes(bool fullLayout, bool /*isRootLineBox*/)
}
}
-void RenderBox::position(InlineBox* box)
+void RenderBox::positionLineBox(InlineBox* box)
{
if (isPositioned()) {
// Cache the x position only if we were an INLINE type originally.
bool wasInline = style()->isOriginalDisplayInlineType();
- if (wasInline && hasStaticX()) {
+ if (wasInline && style()->hasStaticX()) {
// The value is cached in the xPos of the box. We only need this value if
// our object was inline originally, since otherwise it would have ended up underneath
// the inlines.
- setStaticX(box->xPos());
+ layer()->setStaticX(box->x());
setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
- } else if (!wasInline && hasStaticY()) {
+ } else if (!wasInline && style()->hasStaticY()) {
// Our object was a block originally, so we make our normal flow position be
// just below the line box (as though all the inlines that came before us got
// wrapped in an anonymous block, which is what would have happened had we been
- // in flow). This value was cached in the yPos() of the box.
- setStaticY(box->yPos());
+ // in flow). This value was cached in the y() of the box.
+ layer()->setStaticY(box->y());
setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
}
@@ -1537,7 +1078,7 @@ void RenderBox::position(InlineBox* box)
box->remove();
box->destroy(renderArena());
} else if (isReplaced()) {
- setLocation(box->xPos(), box->yPos());
+ setLocation(box->x(), box->y());
m_inlineBoxWrapper = box;
}
}
@@ -1552,7 +1093,7 @@ void RenderBox::deleteLineBoxWrapper()
}
}
-IntRect RenderBox::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
return IntRect();
@@ -1578,18 +1119,18 @@ IntRect RenderBox::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
r.inflate(v->maximalOutlineSize());
}
}
- computeRectForRepaint(r, repaintContainer);
+ computeRectForRepaint(repaintContainer, r);
return r;
}
-void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer, bool fixed)
+void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
{
if (RenderView* v = view()) {
// LayoutState is only valid for root-relative repainting
if (v->layoutStateEnabled() && !repaintContainer) {
LayoutState* layoutState = v->layoutState();
- if (style()->position() == RelativePosition && m_layer)
- rect.move(m_layer->relativePositionOffset());
+ if (style()->position() == RelativePosition && layer())
+ rect.move(layer()->relativePositionOffset());
rect.move(x(), y());
rect.move(layoutState->m_offset);
@@ -1616,7 +1157,7 @@ void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer
fixed = true;
if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
- RenderBlock* cb = static_cast<RenderBlock*>(o);
+ RenderBlock* cb = toRenderBlock(o);
if (cb->hasColumns()) {
IntRect repaintRect(topLeft, rect.size());
cb->adjustRectForColumns(repaintRect);
@@ -1627,22 +1168,22 @@ void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer
// We are now in our parent container's coordinate space. Apply our transform to obtain a bounding box
// in the parent's coordinate space that encloses us.
- if (m_layer && m_layer->transform()) {
+ if (layer() && layer()->transform()) {
fixed = false;
- rect = m_layer->transform()->mapRect(rect);
+ rect = layer()->transform()->mapRect(rect);
// FIXME: this clobbers topLeft adjustment done for multicol above
topLeft = rect.location();
topLeft.move(x(), y());
}
- if (style()->position() == AbsolutePosition)
- topLeft += offsetForPositionedInContainer(o);
- else if (style()->position() == RelativePosition && m_layer) {
+ if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
+ topLeft += toRenderInline(o)->relativePositionedInlineOffset(this);
+ else if (style()->position() == RelativePosition && layer()) {
// Apply the relative position offset when invalidating a rectangle. The layer
// is translated, but the render box isn't, so we need to do this to get the
// right dirty rect. Since this is called from RenderObject::setStyle, the relative position
// flag on the RenderObject has been cleared, so use the one on the style().
- topLeft += m_layer->relativePositionOffset();
+ topLeft += layer()->relativePositionOffset();
}
// FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,
@@ -1663,7 +1204,7 @@ void RenderBox::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer
} else
rect.setLocation(topLeft);
- o->computeRectForRepaint(rect, repaintContainer, fixed);
+ o->computeRectForRepaint(repaintContainer, rect, fixed);
}
void RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect)
@@ -1684,30 +1225,6 @@ void RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect)
}
}
-int RenderBox::relativePositionOffsetX() const
-{
- if (!style()->left().isAuto()) {
- if (!style()->right().isAuto() && containingBlock()->style()->direction() == RTL)
- return -style()->right().calcValue(containingBlockWidth());
- return style()->left().calcValue(containingBlockWidth());
- }
- if (!style()->right().isAuto())
- return -style()->right().calcValue(containingBlockWidth());
- return 0;
-}
-
-int RenderBox::relativePositionOffsetY() const
-{
- if (!style()->top().isAuto()) {
- if (!style()->top().isPercent() || containingBlock()->style()->height().isFixed())
- return style()->top().calcValue(containingBlockHeight());
- } else if (!style()->bottom().isAuto()) {
- if (!style()->bottom().isPercent() || containingBlock()->style()->height().isFixed())
- return -style()->bottom().calcValue(containingBlockHeight());
- }
- return 0;
-}
-
void RenderBox::calcWidth()
{
#ifdef ANDROID_LAYOUT
@@ -1744,7 +1261,7 @@ void RenderBox::calcWidth()
Length w = (treatAsReplaced) ? Length(calcReplacedWidth(), Fixed) : style()->width();
RenderBlock* cb = containingBlock();
- int containerWidth = max(0, containingBlockWidth());
+ int containerWidth = max(0, containingBlockWidthForContent());
Length marginLeft = style()->marginLeft();
Length marginRight = style()->marginRight();
@@ -2110,7 +1627,7 @@ int RenderBox::calcReplacedWidthUsing(Length width) const
case Fixed:
return calcContentBoxWidth(width.value());
case Percent: {
- const int cw = isPositioned() ? containingBlockWidthForPositioned(container()) : containingBlockWidth();
+ const int cw = isPositioned() ? containingBlockWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockWidthForContent();
if (cw > 0)
return calcContentBoxWidth(width.calcMinValue(cw));
}
@@ -2139,12 +1656,12 @@ int RenderBox::calcReplacedHeightUsing(Length height) const
RenderObject* cb = isPositioned() ? container() : containingBlock();
while (cb->isAnonymous()) {
cb = cb->containingBlock();
- static_cast<RenderBlock*>(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
+ toRenderBlock(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
}
if (cb->isPositioned() && cb->style()->height().isAuto() && !(cb->style()->top().isAuto() || cb->style()->bottom().isAuto())) {
ASSERT(cb->isRenderBlock());
- RenderBlock* block = static_cast<RenderBlock*>(cb);
+ RenderBlock* block = toRenderBlock(cb);
int oldHeight = block->height();
block->calcHeight();
int newHeight = block->calcContentBoxHeight(block->contentHeight());
@@ -2152,7 +1669,7 @@ int RenderBox::calcReplacedHeightUsing(Length height) const
return calcContentBoxHeight(height.calcValue(newHeight));
}
- int availableHeight = isPositioned() ? containingBlockHeightForPositioned(cb) : toRenderBox(cb)->availableHeight();
+ int availableHeight = isPositioned() ? containingBlockHeightForPositioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableHeight();
// It is necessary to use the border-box to match WinIE's broken
// box model. This is essential for sizing inside
@@ -2183,7 +1700,7 @@ int RenderBox::availableHeightUsing(const Length& h) const
return calcContentBoxHeight(h.value());
if (isRenderView())
- return static_cast<const RenderView*>(this)->frameView()->visibleHeight();
+ return toRenderView(this)->frameView()->visibleHeight();
// We need to stop here, since we don't want to increase the height of the table
// artificially. We're going to rely on this cell getting expanded to some new
@@ -2195,7 +1712,7 @@ int RenderBox::availableHeightUsing(const Length& h) const
return calcContentBoxHeight(h.calcValue(containingBlock()->availableHeight()));
if (isRenderBlock() && isPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {
- RenderBlock* block = const_cast<RenderBlock*>(static_cast<const RenderBlock*>(this));
+ RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));
int oldHeight = block->height();
block->calcHeight();
int newHeight = block->calcContentBoxHeight(block->contentHeight());
@@ -2222,75 +1739,46 @@ void RenderBox::calcVerticalMargins()
m_marginBottom = style()->marginBottom().calcMinValue(cw);
}
-int RenderBox::staticX() const
-{
- return m_layer ? m_layer->staticX() : 0;
-}
-
-int RenderBox::staticY() const
-{
- return m_layer ? m_layer->staticY() : 0;
-}
-
-void RenderBox::setStaticX(int staticX)
+int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const
{
- ASSERT(isPositioned() || isRelPositioned());
- m_layer->setStaticX(staticX);
-}
-
-void RenderBox::setStaticY(int staticY)
-{
- ASSERT(isPositioned() || isRelPositioned());
-
- if (staticY == m_layer->staticY())
- return;
+ if (containingBlock->isBox()) {
+ const RenderBox* containingBlockBox = toRenderBox(containingBlock);
+ return containingBlockBox->width() - containingBlockBox->borderLeft() - containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth();
+ }
- m_layer->setStaticY(staticY);
- setChildNeedsLayout(true, false);
-}
-
-int RenderBox::containingBlockWidthForPositioned(const RenderObject* containingBlock) const
-{
- if (containingBlock->isRenderInline()) {
- ASSERT(containingBlock->isRelPositioned());
-
- const RenderFlow* flow = static_cast<const RenderFlow*>(containingBlock);
- InlineFlowBox* first = flow->firstLineBox();
- InlineFlowBox* last = flow->lastLineBox();
+ ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());
- // If the containing block is empty, return a width of 0.
- if (!first || !last)
- return 0;
+ const RenderInline* flow = toRenderInline(containingBlock);
+ InlineFlowBox* first = flow->firstLineBox();
+ InlineFlowBox* last = flow->lastLineBox();
- int fromLeft;
- int fromRight;
- if (containingBlock->style()->direction() == LTR) {
- fromLeft = first->xPos() + first->borderLeft();
- fromRight = last->xPos() + last->width() - last->borderRight();
- } else {
- fromRight = first->xPos() + first->width() - first->borderRight();
- fromLeft = last->xPos() + last->borderLeft();
- }
+ // If the containing block is empty, return a width of 0.
+ if (!first || !last)
+ return 0;
- return max(0, (fromRight - fromLeft));
+ int fromLeft;
+ int fromRight;
+ if (containingBlock->style()->direction() == LTR) {
+ fromLeft = first->x() + first->borderLeft();
+ fromRight = last->x() + last->width() - last->borderRight();
+ } else {
+ fromRight = first->x() + first->width() - first->borderRight();
+ fromLeft = last->x() + last->borderLeft();
}
- const RenderBox* containingBlockBox = toRenderBox(containingBlock);
- return containingBlockBox->width() - containingBlockBox->borderLeft() - containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth();
+ return max(0, (fromRight - fromLeft));
}
-int RenderBox::containingBlockHeightForPositioned(const RenderObject* containingBlock) const
-{
- const RenderBox* containingBlockBox = toRenderBox(containingBlock);
-
- int heightResult;
- if (containingBlock->isRenderInline()) {
+int RenderBox::containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const
+{
+ int heightResult = 0;
+ if (containingBlock->isBox())
+ heightResult = toRenderBox(containingBlock)->height();
+ else if (containingBlock->isRenderInline()) {
ASSERT(containingBlock->isRelPositioned());
- heightResult = static_cast<const RenderInline*>(containingBlock)->linesBoundingBox().height();
- } else
- heightResult = containingBlockBox->height();
-
- return heightResult - containingBlockBox->borderTop() - containingBlockBox->borderBottom();
+ heightResult = toRenderInline(containingBlock)->linesBoundingBox().height();
+ }
+ return heightResult - containingBlock->borderTop() - containingBlock->borderBottom();
}
void RenderBox::calcAbsoluteHorizontal()
@@ -2327,7 +1815,7 @@ void RenderBox::calcAbsoluteHorizontal()
// We don't use containingBlock(), since we may be positioned by an enclosing
// relative positioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerWidth = containingBlockWidthForPositioned(containerBlock);
@@ -2370,16 +1858,22 @@ void RenderBox::calcAbsoluteHorizontal()
if (left.isAuto() && right.isAuto()) {
if (containerDirection == LTR) {
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() - containerBlock->borderLeft();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox())
- staticPosition += po->x();
+ int staticPosition = layer()->staticX() - containerBlock->borderLeft();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition += toRenderBox(po)->x();
+ }
left.setValue(Fixed, staticPosition);
} else {
- RenderBox* po = parentBox();
+ RenderObject* po = parent();
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() + containerWidth + containerBlock->borderRight() - po->width();
- for (; po && po != containerBlock; po = po->parentBox())
- staticPosition -= po->x();
+ int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
+ if (po->isBox())
+ staticPosition -= toRenderBox(po)->width();
+ for (; po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition -= toRenderBox(po)->x();
+ }
right.setValue(Fixed, staticPosition);
}
}
@@ -2447,7 +1941,7 @@ void RenderBox::calcAbsoluteHorizontal()
setWidth(width() + bordersPlusPadding);
}
-void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBox* containerBlock, TextDirection containerDirection,
+void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
const int containerWidth, const int bordersPlusPadding,
const Length left, const Length right, const Length marginLeft, const Length marginRight,
int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos)
@@ -2603,15 +2097,15 @@ void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBox* cont
// Use computed values to calculate the horizontal position.
// FIXME: This hack is needed to calculate the xPos for a 'rtl' relatively
- // positioned, inline containing block because right now, it is using the xPos
+ // positioned, inline because right now, it is using the xPos
// of the first line box when really it should use the last line box. When
// this is fixed elsewhere, this block should be removed.
- if (containerBlock->isInline() && containerBlock->style()->direction() == RTL) {
- const RenderFlow* flow = static_cast<const RenderFlow*>(containerBlock);
+ if (containerBlock->isRenderInline() && containerBlock->style()->direction() == RTL) {
+ const RenderInline* flow = toRenderInline(containerBlock);
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- xPos = leftValue + marginLeftValue + lastLine->borderLeft() + (lastLine->xPos() - firstLine->xPos());
+ xPos = leftValue + marginLeftValue + lastLine->borderLeft() + (lastLine->x() - firstLine->x());
return;
}
}
@@ -2634,7 +2128,7 @@ void RenderBox::calcAbsoluteVertical()
// We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerHeight = containingBlockHeightForPositioned(containerBlock);
@@ -2665,10 +2159,10 @@ void RenderBox::calcAbsoluteVertical()
// Calculate the static distance if needed.
if (top.isAuto() && bottom.isAuto()) {
// staticY should already have been set through layout of the parent()
- int staticTop = staticY() - containerBlock->borderTop();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox()) {
- if (!po->isTableRow())
- staticTop += po->y();
+ int staticTop = layer()->staticY() - containerBlock->borderTop();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox() && !po->isTableRow())
+ staticTop += toRenderBox(po)->y();
}
top.setValue(Fixed, staticTop);
}
@@ -2728,7 +2222,7 @@ void RenderBox::calcAbsoluteVertical()
setHeight(h + bordersPlusPadding);
}
-void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBox* containerBlock,
+void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBoxModelObject* containerBlock,
const int containerHeight, const int bordersPlusPadding,
const Length top, const Length bottom, const Length marginTop, const Length marginBottom,
int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos)
@@ -2857,7 +2351,7 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// We don't use containingBlock(), since we may be positioned by an enclosing
// relative positioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerWidth = containingBlockWidthForPositioned(containerBlock);
@@ -2892,16 +2386,20 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// see FIXME 1
if (containerDirection == LTR) {
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() - containerBlock->borderLeft();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox())
- staticPosition += po->x();
+ int staticPosition = layer()->staticX() - containerBlock->borderLeft();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition += toRenderBox(po)->x();
+ }
left.setValue(Fixed, staticPosition);
} else {
- RenderBox* po = parentBox();
+ RenderObject* po = parent();
// 'staticX' should already have been set through layout of the parent.
- int staticPosition = staticX() + containerWidth + containerBlock->borderRight() - po->width();
- for (; po && po != containerBlock; po = po->parentBox())
- staticPosition -= po->x();
+ int staticPosition = layer()->staticX() + containerWidth + containerBlock->borderRight();
+ for ( ; po && po != containerBlock; po = po->parent()) {
+ if (po->isBox())
+ staticPosition += toRenderBox(po)->x();
+ }
right.setValue(Fixed, staticPosition);
}
}
@@ -3009,11 +2507,11 @@ void RenderBox::calcAbsoluteHorizontalReplaced()
// of the first line box when really it should use the last line box. When
// this is fixed elsewhere, this block should be removed.
if (containerBlock->isInline() && containerBlock->style()->direction() == RTL) {
- const RenderFlow* flow = static_cast<const RenderFlow*>(containerBlock);
+ const RenderInline* flow = toRenderInline(containerBlock);
InlineFlowBox* firstLine = flow->firstLineBox();
InlineFlowBox* lastLine = flow->lastLineBox();
if (firstLine && lastLine && firstLine != lastLine) {
- m_frameRect.setX(leftValue + m_marginLeft + lastLine->borderLeft() + (lastLine->xPos() - firstLine->xPos()));
+ m_frameRect.setX(leftValue + m_marginLeft + lastLine->borderLeft() + (lastLine->x() - firstLine->x()));
return;
}
}
@@ -3030,7 +2528,7 @@ void RenderBox::calcAbsoluteVerticalReplaced()
// the numbers correspond to numbers in spec)
// We don't use containingBlock(), since we may be positioned by an enclosing relpositioned inline.
- const RenderBox* containerBlock = toRenderBox(container());
+ const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const int containerHeight = containingBlockHeightForPositioned(containerBlock);
@@ -3058,10 +2556,10 @@ void RenderBox::calcAbsoluteVerticalReplaced()
// see FIXME 2
if (top.isAuto() && bottom.isAuto()) {
// staticY should already have been set through layout of the parent().
- int staticTop = staticY() - containerBlock->borderTop();
- for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->parentBox()) {
- if (!po->isTableRow())
- staticTop += po->y();
+ int staticTop = layer()->staticY() - containerBlock->borderTop();
+ for (RenderObject* po = parent(); po && po != containerBlock; po = po->parent()) {
+ if (po->isBox() && !po->isTableRow())
+ staticTop += toRenderBox(po)->y();
}
top.setValue(Fixed, staticTop);
}
@@ -3161,7 +2659,6 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid
// FIXME: Paint the carets inside empty blocks differently than the carets before/after elements.
// FIXME: What about border and padding?
- const int caretWidth = 1;
IntRect rect(x(), y(), caretWidth, height());
TextDirection direction = box ? box->direction() : style()->direction();
@@ -3184,7 +2681,7 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid
//
// FIXME: ignoring :first-line, missing good reason to take care of
int fontHeight = style()->font().height();
- if (fontHeight > rect.height() || !isReplaced() && !isTable())
+ if (fontHeight > rect.height() || (!isReplaced() && !isTable()))
rect.setHeight(fontHeight);
if (extraWidthToEndOfLine)
@@ -3225,6 +2722,118 @@ int RenderBox::leftmostPosition(bool /*includeOverflowInterior*/, bool includeSe
return left;
}
+bool RenderBox::isAfterContent(RenderObject* child) const
+{
+ return (child && child->style()->styleType() == AFTER && (!child->isText() || child->isBR()));
+}
+
+VisiblePosition RenderBox::positionForPoint(const IntPoint& point)
+{
+ // no children...return this render object's element, if there is one, and offset 0
+ if (!firstChild())
+ return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+
+ int xPos = point.x();
+ int yPos = point.y();
+
+ if (isTable() && node()) {
+ int right = contentWidth() + borderRight() + paddingRight() + borderLeft() + paddingLeft();
+ int bottom = contentHeight() + borderTop() + paddingTop() + borderBottom() + paddingBottom();
+
+ if (xPos < 0 || xPos > right || yPos < 0 || yPos > bottom) {
+ if (xPos <= right / 2)
+ return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+ return createVisiblePosition(lastDeepEditingPositionForNode(node()));
+ }
+ }
+
+ // Pass off to the closest child.
+ int minDist = INT_MAX;
+ RenderBox* closestRenderer = 0;
+ int newX = xPos;
+ int newY = yPos;
+ if (isTableRow()) {
+ newX += x();
+ newY += y();
+ }
+ for (RenderObject* renderObject = firstChild(); renderObject; renderObject = renderObject->nextSibling()) {
+ if ((!renderObject->firstChild() && !renderObject->isInline() && !renderObject->isBlockFlow() )
+ || renderObject->style()->visibility() != VISIBLE)
+ continue;
+
+ if (!renderObject->isBox())
+ continue;
+
+ RenderBox* renderer = toRenderBox(renderObject);
+
+ int top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? 0 : renderer->y());
+ int bottom = top + renderer->contentHeight();
+ int left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? 0 : renderer->x());
+ int right = left + renderer->contentWidth();
+
+ if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) {
+ if (renderer->isTableRow())
+ return renderer->positionForCoordinates(xPos + newX - renderer->x(), yPos + newY - renderer->y());
+ return renderer->positionForCoordinates(xPos - renderer->x(), yPos - renderer->y());
+ }
+
+ // Find the distance from (x, y) to the box. Split the space around the box into 8 pieces
+ // and use a different compare depending on which piece (x, y) is in.
+ IntPoint cmp;
+ if (xPos > right) {
+ if (yPos < top)
+ cmp = IntPoint(right, top);
+ else if (yPos > bottom)
+ cmp = IntPoint(right, bottom);
+ else
+ cmp = IntPoint(right, yPos);
+ } else if (xPos < left) {
+ if (yPos < top)
+ cmp = IntPoint(left, top);
+ else if (yPos > bottom)
+ cmp = IntPoint(left, bottom);
+ else
+ cmp = IntPoint(left, yPos);
+ } else {
+ if (yPos < top)
+ cmp = IntPoint(xPos, top);
+ else
+ cmp = IntPoint(xPos, bottom);
+ }
+
+ int x1minusx2 = cmp.x() - xPos;
+ int y1minusy2 = cmp.y() - yPos;
+
+ int dist = x1minusx2 * x1minusx2 + y1minusy2 * y1minusy2;
+ if (dist < minDist) {
+ closestRenderer = renderer;
+ minDist = dist;
+ }
+ }
+
+ if (closestRenderer)
+ return closestRenderer->positionForCoordinates(newX - closestRenderer->x(), newY - closestRenderer->y());
+
+ return createVisiblePosition(firstDeepEditingPositionForNode(node()));
+}
+
+bool RenderBox::shrinkToAvoidFloats() const
+{
+ // FIXME: Technically we should be able to shrink replaced elements on a line, but this is difficult to accomplish, since this
+ // involves doing a relayout during findNextLineBreak and somehow overriding the containingBlockWidth method to return the
+ // current remaining width on a line.
+ if ((isInline() && !isHTMLMarquee()) || !avoidsFloats())
+ return false;
+
+ // All auto-width objects that avoid floats should always use lineWidth.
+ return style()->width().isAuto();
+}
+
+bool RenderBox::avoidsFloats() const
+{
+ return isReplaced() || hasOverflowClip() || isHR();
+}
+
#if ENABLE(SVG)
TransformationMatrix RenderBox::localTransform() const
diff --git a/WebCore/rendering/RenderBox.h b/WebCore/rendering/RenderBox.h
index 33e7411..182d4e3 100644
--- a/WebCore/rendering/RenderBox.h
+++ b/WebCore/rendering/RenderBox.h
@@ -23,24 +23,26 @@
#ifndef RenderBox_h
#define RenderBox_h
-#include "RenderObject.h"
+#include "RenderBoxModelObject.h"
#include "ScrollTypes.h"
namespace WebCore {
enum WidthType { Width, MinWidth, MaxWidth };
-class RenderBox : public RenderObject {
+class RenderBox : public RenderBoxModelObject {
public:
RenderBox(Node*);
virtual ~RenderBox();
- virtual const char* renderName() const { return "RenderBox"; }
+ // Use this with caution! No type checking is done!
+ RenderBox* firstChildBox() const;
+ RenderBox* lastChildBox() const;
int x() const { return m_frameRect.x(); }
int y() const { return m_frameRect.y(); }
- int width() const { ASSERT(!isRenderInline()); return m_frameRect.width(); }
- int height() const { ASSERT(!isRenderInline()); return m_frameRect.height(); }
+ int width() const { return m_frameRect.width(); }
+ int height() const { return m_frameRect.height(); }
void setX(int x) { m_frameRect.setX(x); }
void setY(int y) { m_frameRect.setY(y); }
@@ -48,7 +50,7 @@ public:
void setHeight(int height) { m_frameRect.setHeight(height); }
IntPoint location() const { return m_frameRect.location(); }
- IntSize size() const { ASSERT(!isRenderInline()); return m_frameRect.size(); }
+ IntSize size() const { return m_frameRect.size(); }
void setLocation(const IntPoint& location) { m_frameRect.setLocation(location); }
void setLocation(int x, int y) { setLocation(IntPoint(x, y)); }
@@ -56,12 +58,12 @@ public:
void setSize(const IntSize& size) { m_frameRect.setSize(size); }
void move(int dx, int dy) { m_frameRect.move(dx, dy); }
- IntRect frameRect() const { ASSERT(!isRenderInline()); return m_frameRect; }
+ IntRect frameRect() const { return m_frameRect; }
void setFrameRect(const IntRect& rect) { m_frameRect = rect; }
IntRect borderBoxRect() const { return IntRect(0, 0, width(), height()); }
- virtual IntRect borderBoundingBox() const { return borderBoxRect(); } // This will work on inlines to return the bounding box of all of the lines' border boxes.
-
+ virtual IntRect borderBoundingBox() const { return borderBoxRect(); }
+
// The content area of the box (excludes padding and border).
IntRect contentBoxRect() const { return IntRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); }
// The content box in absolute coords. Ignores transforms.
@@ -70,7 +72,7 @@ public:
FloatQuad absoluteContentQuad() const;
// Bounds of the outline box in absolute coords. Respects transforms
- virtual IntRect outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const;
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const;
virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
// Use this with caution! No type checking is done!
@@ -96,9 +98,6 @@ public:
// to return the remaining width on a given line (and the height of a single line).
virtual int offsetWidth() const { return width(); }
virtual int offsetHeight() const { return height(); }
- virtual int offsetLeft() const;
- virtual int offsetTop() const;
- virtual RenderBox* offsetParent() const;
// More IE extensions. clientWidth and clientHeight represent the interior of an object
// excluding border and scrollbar. clientLeft/Top are just the borderLeftWidth and borderTopWidth.
@@ -119,26 +118,12 @@ public:
virtual void setScrollLeft(int);
virtual void setScrollTop(int);
- bool hasHorizontalBordersPaddingOrMargin() const { return hasHorizontalBordersOrPadding() || marginLeft() != 0 || marginRight() != 0; }
- bool hasHorizontalBordersOrPadding() const { return borderLeft() != 0 || borderRight() != 0 || paddingLeft() != 0 || paddingRight() != 0; }
-
- int marginTop() const { return m_marginTop; }
- int marginBottom() const { return m_marginBottom; }
- int marginLeft() const { return m_marginLeft; }
- int marginRight() const { return m_marginRight; }
+ virtual int marginTop() const { return m_marginTop; }
+ virtual int marginBottom() const { return m_marginBottom; }
+ virtual int marginLeft() const { return m_marginLeft; }
+ virtual int marginRight() const { return m_marginRight; }
- // Virtual since table cells override
- virtual int paddingTop(bool includeIntrinsicPadding = true) const;
- virtual int paddingBottom(bool includeIntrinsicPadding = true) const;
- virtual int paddingLeft(bool includeIntrinsicPadding = true) const;
- virtual int paddingRight(bool includeIntrinsicPadding = true) const;
-
- virtual int borderTop() const { return style()->borderTopWidth(); }
- virtual int borderBottom() const { return style()->borderBottomWidth(); }
- virtual int borderLeft() const { return style()->borderLeftWidth(); }
- virtual int borderRight() const { return style()->borderRightWidth(); }
-
- // The following seven functions are used to implement collapsing margins.
+ // The following five functions are used to implement collapsing margins.
// All objects know their maximal positive and negative margins. The
// formula for computing a collapsed margin is |maxPosMargin| - |maxNegmargin|.
// For a non-collapsing box, such as a leaf element, this formula will simply return
@@ -147,8 +132,6 @@ public:
virtual bool isSelfCollapsingBlock() const { return false; }
int collapsedMarginTop() const { return maxTopMargin(true) - maxTopMargin(false); }
int collapsedMarginBottom() const { return maxBottomMargin(true) - maxBottomMargin(false); }
- virtual bool isTopMarginQuirk() const { return false; }
- virtual bool isBottomMarginQuirk() const { return false; }
virtual int maxTopMargin(bool positive) const { return positive ? std::max(0, marginTop()) : -std::min(0, marginTop()); }
virtual int maxBottomMargin(bool positive) const { return positive ? std::max(0, marginBottom()) : -std::min(0, marginBottom()); }
@@ -160,6 +143,7 @@ public:
// Given a rect in the object's coordinate space, returns the corresponding rect in the reflection.
IntRect reflectedRect(const IntRect&) const;
+ virtual void layout();
virtual void paint(PaintInfo&, int tx, int ty);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
@@ -168,14 +152,11 @@ public:
virtual int minPrefWidth() const;
virtual int maxPrefWidth() const;
- virtual int overrideSize() const;
- virtual int overrideWidth() const;
- virtual int overrideHeight() const;
+ int overrideSize() const;
+ int overrideWidth() const;
+ int overrideHeight() const;
virtual void setOverrideSize(int);
- virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
- virtual FloatPoint absoluteToLocal(FloatPoint containerPoint, bool fixed = false, bool useTransforms = false) const;
-
virtual IntSize offsetFromContainer(RenderObject*) const;
int calcBorderBoxWidth(int width) const;
@@ -191,29 +172,28 @@ public:
// shifted. -dwh
void calcHorizontalMargins(const Length& marginLeft, const Length& marginRight, int containerWidth);
- virtual void position(InlineBox*);
+ void positionLineBox(InlineBox*);
- virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false);
+ virtual InlineBox* createInlineBox();
+ void dirtyLineBoxes(bool fullLayout);
// For inline replaced elements, this function returns the inline box that owns us. Enables
// the replaced RenderObject to quickly determine what line it is contained on and to easily
// iterate over structures on the line.
- virtual InlineBox* inlineBoxWrapper() const { return m_inlineBoxWrapper; }
- virtual void setInlineBoxWrapper(InlineBox* boxWrapper) { m_inlineBoxWrapper = boxWrapper; }
- virtual void deleteLineBoxWrapper();
+ InlineBox* inlineBoxWrapper() const { return m_inlineBoxWrapper; }
+ void setInlineBoxWrapper(InlineBox* boxWrapper) { m_inlineBoxWrapper = boxWrapper; }
+ void deleteLineBoxWrapper();
virtual int lowestPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
virtual int rightmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
virtual int leftmostPosition(bool includeOverflowInterior = true, bool includeSelf = true) const;
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
- virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false);
- IntSize offsetForPositionedInContainer(RenderObject*) const;
- virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const;
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
virtual void repaintDuringLayoutIfMoved(const IntRect&);
- virtual int containingBlockWidth() const;
+ virtual int containingBlockWidthForContent() const;
virtual void calcWidth();
virtual void calcHeight();
@@ -247,13 +227,6 @@ public:
void calcVerticalMargins();
- int relativePositionOffsetX() const;
- int relativePositionOffsetY() const;
- IntSize relativePositionOffset() const { return IntSize(relativePositionOffsetX(), relativePositionOffsetY()); }
-
- RenderLayer* layer() const { return m_layer; }
- virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); }
-
virtual int verticalScrollbarWidth() const;
int horizontalScrollbarHeight() const;
virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
@@ -269,18 +242,14 @@ public:
virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
- virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight,
- int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver);
- IntSize calculateBackgroundSize(const FillLayer*, int scaledWidth, int scaledHeight) const;
-
- virtual int staticX() const;
- virtual int staticY() const;
- virtual void setStaticX(int staticX);
- virtual void setStaticY(int staticY);
-
- virtual IntRect getOverflowClipRect(int tx, int ty);
- virtual IntRect getClipRect(int tx, int ty);
+ virtual IntRect overflowClipRect(int tx, int ty);
+ IntRect clipRect(int tx, int ty);
+ virtual bool hasControlClip() const { return false; }
+ virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const { return IntRect(); }
+ bool pushContentsClip(PaintInfo&, int tx, int ty);
+ void popContentsClip(PaintInfo&, PaintPhase originalPhase, int tx, int ty);
+ virtual void paintObject(PaintInfo&, int /*tx*/, int /*ty*/) { ASSERT_NOT_REACHED(); }
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
virtual void paintMask(PaintInfo& paintInfo, int tx, int ty);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
@@ -299,14 +268,25 @@ public:
}
IntRect maskClipRect();
+
+ virtual VisiblePosition positionForPoint(const IntPoint&);
+
+ void removeFloatingOrPositionedChildFromBlockLists();
+ virtual int firstLineBoxBaseline() const { return -1; }
+ virtual int lastLineBoxBaseline() const { return -1; }
+
+ bool shrinkToAvoidFloats() const;
+ virtual bool avoidsFloats() const;
+
#if ENABLE(SVG)
virtual TransformationMatrix localTransform() const;
#endif
protected:
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateBoxModelInfoFromStyle();
void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver);
void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight, int tx, int ty, int width, int height, CompositeOperator = CompositeSourceOver);
@@ -321,6 +301,9 @@ protected:
virtual bool shouldCalculateSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); }
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
+
private:
bool includeVerticalScrollbarSize() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || style()->overflowY() == OAUTO); }
bool includeHorizontalScrollbarSize() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || style()->overflowX() == OAUTO); }
@@ -328,18 +311,16 @@ private:
void paintRootBoxDecorations(PaintInfo&, int tx, int ty);
// Returns true if we did a full repaint
bool repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground);
-
- void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
-
- int containingBlockWidthForPositioned(const RenderObject* containingBlock) const;
- int containingBlockHeightForPositioned(const RenderObject* containingBlock) const;
+
+ int containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const;
+ int containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const;
void calcAbsoluteVertical();
- void calcAbsoluteHorizontalValues(Length width, const RenderBox* cb, TextDirection containerDirection,
+ void calcAbsoluteHorizontalValues(Length width, const RenderBoxModelObject* cb, TextDirection containerDirection,
int containerWidth, int bordersPlusPadding,
Length left, Length right, Length marginLeft, Length marginRight,
int& widthValue, int& marginLeftValue, int& marginRightValue, int& xPos);
- void calcAbsoluteVerticalValues(Length height, const RenderBox* cb,
+ void calcAbsoluteVerticalValues(Length height, const RenderBoxModelObject* cb,
int containerHeight, int bordersPlusPadding,
Length top, Length bottom, Length marginTop, Length marginBottom,
int& heightValue, int& marginTopValue, int& marginBottomValue, int& yPos);
@@ -350,7 +331,10 @@ private:
// This function calculates the minimum and maximum preferred widths for an object.
// These values are used in shrink-to-fit layout systems.
// These include tables, positioned objects, floats and flexible boxes.
- virtual void calcPrefWidths() = 0;
+ virtual void calcPrefWidths() { setPrefWidthsDirty(false); }
+
+protected:
+ bool isAfterContent(RenderObject* child) const;
private:
// The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent).
@@ -373,15 +357,11 @@ protected:
// The preferred width of the element if it never breaks any lines at all.
int m_maxPrefWidth;
- // A pointer to our layer if we have one.
- RenderLayer* m_layer;
-
// For inline replaced elements, the inline box that owns us.
InlineBox* m_inlineBoxWrapper;
private:
// Used to store state between styleWillChange and styleDidChange
- static bool s_wasFloating;
static bool s_hadOverflowClip;
};
@@ -397,6 +377,9 @@ inline const RenderBox* toRenderBox(const RenderObject* o)
return static_cast<const RenderBox*>(o);
}
+// This will catch anyone doing an unnecessary cast.
+void toRenderBox(const RenderBox*);
+
inline RenderBox* RenderBox::previousSiblingBox() const
{
return toRenderBox(previousSibling());
@@ -412,6 +395,16 @@ inline RenderBox* RenderBox::parentBox() const
return toRenderBox(parent());
}
+inline RenderBox* RenderBox::firstChildBox() const
+{
+ return toRenderBox(firstChild());
+}
+
+inline RenderBox* RenderBox::lastChildBox() const
+{
+ return toRenderBox(lastChild());
+}
+
} // namespace WebCore
#endif // RenderBox_h
diff --git a/WebCore/rendering/RenderBoxModelObject.cpp b/WebCore/rendering/RenderBoxModelObject.cpp
new file mode 100644
index 0000000..c79da7b
--- /dev/null
+++ b/WebCore/rendering/RenderBoxModelObject.cpp
@@ -0,0 +1,1111 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderBoxModelObject.h"
+
+#include "GraphicsContext.h"
+#include "HTMLElement.h"
+#include "HTMLNames.h"
+#include "ImageBuffer.h"
+#include "RenderBlock.h"
+#include "RenderInline.h"
+#include "RenderLayer.h"
+#include "RenderView.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+bool RenderBoxModelObject::s_wasFloating = false;
+
+RenderBoxModelObject::RenderBoxModelObject(Node* node)
+ : RenderObject(node)
+ , m_layer(0)
+{
+}
+
+RenderBoxModelObject::~RenderBoxModelObject()
+{
+ // Our layer should have been destroyed and cleared by now
+ ASSERT(!hasLayer());
+ ASSERT(!m_layer);
+}
+
+void RenderBoxModelObject::destroyLayer()
+{
+ ASSERT(hasLayer());
+ ASSERT(m_layer);
+ m_layer->destroy(renderArena());
+ m_layer = 0;
+ setHasLayer(false);
+}
+
+void RenderBoxModelObject::destroy()
+{
+ // This must be done before we destroy the RenderObject.
+ if (m_layer)
+ m_layer->clearClipRects();
+
+ // RenderObject::destroy calls back to destroyLayer() for layer destruction
+ RenderObject::destroy();
+}
+
+bool RenderBoxModelObject::hasSelfPaintingLayer() const
+{
+ return m_layer && m_layer->isSelfPaintingLayer();
+}
+
+void RenderBoxModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+{
+ s_wasFloating = isFloating();
+
+ // If our z-index changes value or our visibility changes,
+ // we need to dirty our stacking context's z-order list.
+ if (style() && newStyle) {
+ if (hasLayer() && (style()->hasAutoZIndex() != newStyle->hasAutoZIndex() ||
+ style()->zIndex() != newStyle->zIndex() ||
+ style()->visibility() != newStyle->visibility())) {
+ layer()->dirtyStackingContextZOrderLists();
+ if (style()->hasAutoZIndex() != newStyle->hasAutoZIndex() || style()->visibility() != newStyle->visibility())
+ layer()->dirtyZOrderLists();
+ }
+ }
+
+ RenderObject::styleWillChange(diff, newStyle);
+}
+
+void RenderBoxModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderObject::styleDidChange(diff, oldStyle);
+ updateBoxModelInfoFromStyle();
+
+ if (requiresLayer()) {
+ if (!layer()) {
+ if (s_wasFloating && isFloating())
+ setChildNeedsLayout(true);
+ m_layer = new (renderArena()) RenderLayer(this);
+ setHasLayer(true);
+ m_layer->insertOnlyThisLayer();
+ if (parent() && !needsLayout() && containingBlock())
+ m_layer->updateLayerPositions();
+ }
+ } else if (layer() && layer()->parent()) {
+ setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
+ setHasReflection(false);
+ m_layer->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
+ if (s_wasFloating && isFloating())
+ setChildNeedsLayout(true);
+ }
+
+ if (m_layer)
+ m_layer->styleChanged(diff, oldStyle);
+}
+
+void RenderBoxModelObject::updateBoxModelInfoFromStyle()
+{
+ // Set the appropriate bits for a box model object. Since all bits are cleared in styleWillChange,
+ // we only check for bits that could possibly be set to true.
+ setHasBoxDecorations(style()->hasBorder() || style()->hasBackground() || style()->hasAppearance() || style()->boxShadow());
+ setInline(style()->isDisplayInlineType());
+ setRelPositioned(style()->position() == RelativePosition);
+}
+
+int RenderBoxModelObject::relativePositionOffsetX() const
+{
+ if (!style()->left().isAuto()) {
+ if (!style()->right().isAuto() && containingBlock()->style()->direction() == RTL)
+ return -style()->right().calcValue(containingBlockWidthForContent());
+ return style()->left().calcValue(containingBlockWidthForContent());
+ }
+ if (!style()->right().isAuto())
+ return -style()->right().calcValue(containingBlockWidthForContent());
+ return 0;
+}
+
+int RenderBoxModelObject::relativePositionOffsetY() const
+{
+ if (!style()->top().isAuto())
+ return style()->top().calcValue(containingBlock()->availableHeight());
+ else if (!style()->bottom().isAuto())
+ return -style()->bottom().calcValue(containingBlock()->availableHeight());
+
+ return 0;
+}
+
+int RenderBoxModelObject::offsetLeft() const
+{
+ // If the element is the HTML body element or does not have an associated box
+ // return 0 and stop this algorithm.
+ if (isBody())
+ return 0;
+
+ RenderBoxModelObject* offsetPar = offsetParent();
+ int xPos = (isBox() ? toRenderBox(this)->x() : 0);
+
+ // If the offsetParent of the element is null, or is the HTML body element,
+ // return the distance between the canvas origin and the left border edge
+ // of the element and stop this algorithm.
+ if (offsetPar) {
+ if (offsetPar->isBox() && !offsetPar->isBody())
+ xPos -= toRenderBox(offsetPar)->borderLeft();
+ if (!isPositioned()) {
+ if (isRelPositioned())
+ xPos += relativePositionOffsetX();
+ RenderObject* curr = parent();
+ while (curr && curr != offsetPar) {
+ // FIXME: What are we supposed to do inside SVG content?
+ if (curr->isBox() && !curr->isTableRow())
+ xPos += toRenderBox(curr)->x();
+ curr = curr->parent();
+ }
+ if (offsetPar->isBox() && offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
+ xPos += toRenderBox(offsetPar)->x();
+ }
+ }
+
+ return xPos;
+}
+
+int RenderBoxModelObject::offsetTop() const
+{
+ // If the element is the HTML body element or does not have an associated box
+ // return 0 and stop this algorithm.
+ if (isBody())
+ return 0;
+
+ RenderBoxModelObject* offsetPar = offsetParent();
+ int yPos = (isBox() ? toRenderBox(this)->y() : 0);
+
+ // If the offsetParent of the element is null, or is the HTML body element,
+ // return the distance between the canvas origin and the top border edge
+ // of the element and stop this algorithm.
+ if (offsetPar) {
+ if (offsetPar->isBox() && !offsetPar->isBody())
+ yPos -= toRenderBox(offsetPar)->borderTop();
+ if (!isPositioned()) {
+ if (isRelPositioned())
+ yPos += relativePositionOffsetY();
+ RenderObject* curr = parent();
+ while (curr && curr != offsetPar) {
+ // FIXME: What are we supposed to do inside SVG content?
+ if (curr->isBox() && !curr->isTableRow())
+ yPos += toRenderBox(curr)->y();
+ curr = curr->parent();
+ }
+ if (offsetPar->isBox() && offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->isPositioned())
+ yPos += toRenderBox(offsetPar)->y();
+ }
+ }
+ return yPos;
+}
+
+int RenderBoxModelObject::paddingTop(bool) const
+{
+ int w = 0;
+ Length padding = style()->paddingTop();
+ if (padding.isPercent())
+ w = containingBlock()->availableWidth();
+ return padding.calcMinValue(w);
+}
+
+int RenderBoxModelObject::paddingBottom(bool) const
+{
+ int w = 0;
+ Length padding = style()->paddingBottom();
+ if (padding.isPercent())
+ w = containingBlock()->availableWidth();
+ return padding.calcMinValue(w);
+}
+
+int RenderBoxModelObject::paddingLeft(bool) const
+{
+ int w = 0;
+ Length padding = style()->paddingLeft();
+ if (padding.isPercent())
+ w = containingBlock()->availableWidth();
+ return padding.calcMinValue(w);
+}
+
+int RenderBoxModelObject::paddingRight(bool) const
+{
+ int w = 0;
+ Length padding = style()->paddingRight();
+ if (padding.isPercent())
+ w = containingBlock()->availableWidth();
+ return padding.calcMinValue(w);
+}
+
+
+void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& c, const FillLayer* bgLayer, int clipY, int clipH,
+ int tx, int ty, int w, int h, InlineFlowBox* box, CompositeOperator op)
+{
+ GraphicsContext* context = paintInfo.context;
+ bool includeLeftEdge = box ? box->includeLeftEdge() : true;
+ bool includeRightEdge = box ? box->includeRightEdge() : true;
+ int bLeft = includeLeftEdge ? borderLeft() : 0;
+ int bRight = includeRightEdge ? borderRight() : 0;
+ int pLeft = includeLeftEdge ? paddingLeft() : 0;
+ int pRight = includeRightEdge ? paddingRight() : 0;
+
+ bool clippedToBorderRadius = false;
+ if (style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge)) {
+ context->save();
+ context->addRoundedRectClip(IntRect(tx, ty, w, h),
+ includeLeftEdge ? style()->borderTopLeftRadius() : IntSize(),
+ includeRightEdge ? style()->borderTopRightRadius() : IntSize(),
+ includeLeftEdge ? style()->borderBottomLeftRadius() : IntSize(),
+ includeRightEdge ? style()->borderBottomRightRadius() : IntSize());
+ clippedToBorderRadius = true;
+ }
+
+ if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox) {
+ // Clip to the padding or content boxes as necessary.
+ bool includePadding = bgLayer->clip() == ContentFillBox;
+ int x = tx + bLeft + (includePadding ? pLeft : 0);
+ int y = ty + borderTop() + (includePadding ? paddingTop() : 0);
+ int width = w - bLeft - bRight - (includePadding ? pLeft + pRight : 0);
+ int height = h - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0);
+ context->save();
+ context->clip(IntRect(x, y, width, height));
+ } else if (bgLayer->clip() == TextFillBox) {
+ // We have to draw our text into a mask that can then be used to clip background drawing.
+ // First figure out how big the mask has to be. It should be no bigger than what we need
+ // to actually render, so we should intersect the dirty rect with the border box of the background.
+ IntRect maskRect(tx, ty, w, h);
+ maskRect.intersect(paintInfo.rect);
+
+ // Now create the mask.
+ auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
+ if (!maskImage.get())
+ return;
+
+ GraphicsContext* maskImageContext = maskImage->context();
+ maskImageContext->translate(-maskRect.x(), -maskRect.y());
+
+ // Now add the text to the clip. We do this by painting using a special paint phase that signals to
+ // InlineTextBoxes that they should just add their contents to the clip.
+ PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, true, 0, 0);
+ if (box)
+ box->paint(info, tx - box->x(), ty - box->y());
+ else
+ paint(info, tx, ty);
+
+ // The mask has been created. Now we just need to clip to it.
+ context->save();
+ context->clipToImageBuffer(maskRect, maskImage.get());
+ }
+
+ StyleImage* bg = bgLayer->image();
+ bool shouldPaintBackgroundImage = bg && bg->canRender(style()->effectiveZoom());
+ Color bgColor = c;
+
+ // When this style flag is set, change existing background colors and images to a solid white background.
+ // If there's no bg color or image, leave it untouched to avoid affecting transparency.
+ // We don't try to avoid loading the background images, because this style flag is only set
+ // when printing, and at that point we've already loaded the background images anyway. (To avoid
+ // loading the background images we'd have to do this check when applying styles rather than
+ // while rendering.)
+ if (style()->forceBackgroundsToWhite()) {
+ // Note that we can't reuse this variable below because the bgColor might be changed
+ bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.isValid() && bgColor.alpha() > 0;
+ if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) {
+ bgColor = Color::white;
+ shouldPaintBackgroundImage = false;
+ }
+ }
+
+ // Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with
+ // no background in the child document should show the parent's background.
+ bool isTransparent = false;
+ if (!bgLayer->next() && isRoot() && !(bgColor.isValid() && bgColor.alpha() > 0) && view()->frameView()) {
+ Node* elt = document()->ownerElement();
+ if (elt) {
+ if (!elt->hasTagName(frameTag)) {
+ // Locate the <body> element using the DOM. This is easier than trying
+ // to crawl around a render tree with potential :before/:after content and
+ // anonymous blocks created by inline <body> tags etc. We can locate the <body>
+ // render object very easily via the DOM.
+ HTMLElement* body = document()->body();
+ isTransparent = !body || !body->hasLocalName(framesetTag); // Can't scroll a frameset document anyway.
+ }
+ } else
+ isTransparent = view()->frameView()->isTransparent();
+
+ // FIXME: This needs to be dynamic. We should be able to go back to blitting if we ever stop being transparent.
+ if (isTransparent)
+ view()->frameView()->setUseSlowRepaints(); // The parent must show behind the child.
+ }
+
+ // Paint the color first underneath all images.
+ if (!bgLayer->next()) {
+ IntRect rect(tx, clipY, w, clipH);
+ // If we have an alpha and we are painting the root element, go ahead and blend with the base background color.
+ if (isRoot() && (!bgColor.isValid() || bgColor.alpha() < 0xFF) && !isTransparent) {
+ Color baseColor = view()->frameView()->baseBackgroundColor();
+ if (baseColor.alpha() > 0) {
+ context->save();
+ context->setCompositeOperation(CompositeCopy);
+ context->fillRect(rect, baseColor);
+ context->restore();
+#ifdef ANDROID_ALLOW_TRANSPARENT_BACKGROUNDS
+ }
+#else
+ } else
+ context->clearRect(rect);
+#endif
+ }
+
+ if (bgColor.isValid() && bgColor.alpha() > 0)
+ context->fillRect(rect, bgColor);
+ }
+
+ // no progressive loading of the background image
+ if (shouldPaintBackgroundImage) {
+ IntRect destRect;
+ IntPoint phase;
+ IntSize tileSize;
+
+ calculateBackgroundImageGeometry(bgLayer, tx, ty, w, h, destRect, phase, tileSize);
+ IntPoint destOrigin = destRect.location();
+ destRect.intersect(paintInfo.rect);
+ if (!destRect.isEmpty()) {
+ phase += destRect.location() - destOrigin;
+ CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
+ context->drawTiledImage(bg->image(this, tileSize), destRect, phase, tileSize, compositeOp);
+ }
+ }
+
+ if (bgLayer->clip() != BorderFillBox)
+ // Undo the background clip
+ context->restore();
+
+ if (clippedToBorderRadius)
+ // Undo the border radius clip
+ context->restore();
+}
+
+IntSize RenderBoxModelObject::calculateBackgroundSize(const FillLayer* bgLayer, int scaledWidth, int scaledHeight) const
+{
+ StyleImage* bg = bgLayer->image();
+ bg->setImageContainerSize(IntSize(scaledWidth, scaledHeight)); // Use the box established by background-origin.
+
+ if (bgLayer->isSizeSet()) {
+ int w = scaledWidth;
+ int h = scaledHeight;
+ Length bgWidth = bgLayer->size().width();
+ Length bgHeight = bgLayer->size().height();
+
+ if (bgWidth.isFixed())
+ w = bgWidth.value();
+ else if (bgWidth.isPercent())
+ w = bgWidth.calcValue(scaledWidth);
+
+ if (bgHeight.isFixed())
+ h = bgHeight.value();
+ else if (bgHeight.isPercent())
+ h = bgHeight.calcValue(scaledHeight);
+
+ // If one of the values is auto we have to use the appropriate
+ // scale to maintain our aspect ratio.
+ if (bgWidth.isAuto() && !bgHeight.isAuto())
+ w = bg->imageSize(this, style()->effectiveZoom()).width() * h / bg->imageSize(this, style()->effectiveZoom()).height();
+ else if (!bgWidth.isAuto() && bgHeight.isAuto())
+ h = bg->imageSize(this, style()->effectiveZoom()).height() * w / bg->imageSize(this, style()->effectiveZoom()).width();
+ else if (bgWidth.isAuto() && bgHeight.isAuto()) {
+ // If both width and height are auto, we just want to use the image's
+ // intrinsic size.
+ w = bg->imageSize(this, style()->effectiveZoom()).width();
+ h = bg->imageSize(this, style()->effectiveZoom()).height();
+ }
+
+ return IntSize(max(1, w), max(1, h));
+ } else
+ return bg->imageSize(this, style()->effectiveZoom());
+}
+
+void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* bgLayer, int tx, int ty, int w, int h,
+ IntRect& destRect, IntPoint& phase, IntSize& tileSize)
+{
+ int pw;
+ int ph;
+ int left = 0;
+ int right = 0;
+ int top = 0;
+ int bottom = 0;
+ int cx;
+ int cy;
+ int rw = 0;
+ int rh = 0;
+
+ // CSS2 chapter 14.2.1
+
+ if (bgLayer->attachment()) {
+ // Scroll
+ if (bgLayer->origin() != BorderFillBox) {
+ left = borderLeft();
+ right = borderRight();
+ top = borderTop();
+ bottom = borderBottom();
+ if (bgLayer->origin() == ContentFillBox) {
+ left += paddingLeft();
+ right += paddingRight();
+ top += paddingTop();
+ bottom += paddingBottom();
+ }
+ }
+
+ // The background of the box generated by the root element covers the entire canvas including
+ // its margins. Since those were added in already, we have to factor them out when computing the
+ // box used by background-origin/size/position.
+ if (isRoot()) {
+ rw = toRenderBox(this)->width() - left - right;
+ rh = toRenderBox(this)->height() - top - bottom;
+ left += marginLeft();
+ right += marginRight();
+ top += marginTop();
+ bottom += marginBottom();
+ }
+ cx = tx;
+ cy = ty;
+ pw = w - left - right;
+ ph = h - top - bottom;
+ } else {
+ // Fixed
+ IntRect vr = viewRect();
+ cx = vr.x();
+ cy = vr.y();
+ pw = vr.width();
+ ph = vr.height();
+ }
+
+ int sx = 0;
+ int sy = 0;
+ int cw;
+ int ch;
+
+ IntSize scaledImageSize;
+ if (isRoot() && bgLayer->attachment())
+ scaledImageSize = calculateBackgroundSize(bgLayer, rw, rh);
+ else
+ scaledImageSize = calculateBackgroundSize(bgLayer, pw, ph);
+
+ int scaledImageWidth = scaledImageSize.width();
+ int scaledImageHeight = scaledImageSize.height();
+
+ EFillRepeat backgroundRepeat = bgLayer->repeat();
+
+ int xPosition;
+ if (isRoot() && bgLayer->attachment())
+ xPosition = bgLayer->xPosition().calcMinValue(rw - scaledImageWidth, true);
+ else
+ xPosition = bgLayer->xPosition().calcMinValue(pw - scaledImageWidth, true);
+ if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatXFill) {
+ cw = pw + left + right;
+ sx = scaledImageWidth ? scaledImageWidth - (xPosition + left) % scaledImageWidth : 0;
+ } else {
+ cx += max(xPosition + left, 0);
+ sx = -min(xPosition + left, 0);
+ cw = scaledImageWidth + min(xPosition + left, 0);
+ }
+
+ int yPosition;
+ if (isRoot() && bgLayer->attachment())
+ yPosition = bgLayer->yPosition().calcMinValue(rh - scaledImageHeight, true);
+ else
+ yPosition = bgLayer->yPosition().calcMinValue(ph - scaledImageHeight, true);
+ if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatYFill) {
+ ch = ph + top + bottom;
+ sy = scaledImageHeight ? scaledImageHeight - (yPosition + top) % scaledImageHeight : 0;
+ } else {
+ cy += max(yPosition + top, 0);
+ sy = -min(yPosition + top, 0);
+ ch = scaledImageHeight + min(yPosition + top, 0);
+ }
+
+ if (!bgLayer->attachment()) {
+ sx += max(tx - cx, 0);
+ sy += max(ty - cy, 0);
+ }
+
+ destRect = IntRect(cx, cy, cw, ch);
+ destRect.intersect(IntRect(tx, ty, w, h));
+ phase = IntPoint(sx, sy);
+ tileSize = IntSize(scaledImageWidth, scaledImageHeight);
+}
+
+int RenderBoxModelObject::verticalPosition(bool firstLine) const
+{
+ // This method determines the vertical position for inline elements.
+ ASSERT(isInline());
+ if (!isInline())
+ return 0;
+
+ int vpos = 0;
+ EVerticalAlign va = style()->verticalAlign();
+ if (va == TOP)
+ vpos = PositionTop;
+ else if (va == BOTTOM)
+ vpos = PositionBottom;
+ else {
+ bool checkParent = parent()->isRenderInline() && parent()->style()->verticalAlign() != TOP && parent()->style()->verticalAlign() != BOTTOM;
+ vpos = checkParent ? toRenderInline(parent())->verticalPositionFromCache(firstLine) : 0;
+ // don't allow elements nested inside text-top to have a different valignment.
+ if (va == BASELINE)
+ return vpos;
+
+ const Font& f = parent()->style(firstLine)->font();
+ int fontsize = f.pixelSize();
+
+ if (va == SUB)
+ vpos += fontsize / 5 + 1;
+ else if (va == SUPER)
+ vpos -= fontsize / 3 + 1;
+ else if (va == TEXT_TOP)
+ vpos += baselinePosition(firstLine) - f.ascent();
+ else if (va == MIDDLE)
+ vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine);
+ else if (va == TEXT_BOTTOM) {
+ vpos += f.descent();
+ if (!isReplaced()) // lineHeight - baselinePosition is always 0 for replaced elements, so don't bother wasting time in that case.
+ vpos -= (lineHeight(firstLine) - baselinePosition(firstLine));
+ } else if (va == BASELINE_MIDDLE)
+ vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine);
+ else if (va == LENGTH)
+ vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine));
+ }
+
+ return vpos;
+}
+
+bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style,
+ const NinePieceImage& ninePieceImage, CompositeOperator op)
+{
+ StyleImage* styleImage = ninePieceImage.image();
+ if (!styleImage)
+ return false;
+
+ if (!styleImage->isLoaded())
+ return true; // Never paint a nine-piece image incrementally, but don't paint the fallback borders either.
+
+ if (!styleImage->canRender(style->effectiveZoom()))
+ return false;
+
+ // FIXME: border-image is broken with full page zooming when tiling has to happen, since the tiling function
+ // doesn't have any understanding of the zoom that is in effect on the tile.
+ styleImage->setImageContainerSize(IntSize(w, h));
+ IntSize imageSize = styleImage->imageSize(this, 1.0f);
+ int imageWidth = imageSize.width();
+ int imageHeight = imageSize.height();
+
+ int topSlice = min(imageHeight, ninePieceImage.m_slices.top().calcValue(imageHeight));
+ int bottomSlice = min(imageHeight, ninePieceImage.m_slices.bottom().calcValue(imageHeight));
+ int leftSlice = min(imageWidth, ninePieceImage.m_slices.left().calcValue(imageWidth));
+ int rightSlice = min(imageWidth, ninePieceImage.m_slices.right().calcValue(imageWidth));
+
+ ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
+ ENinePieceImageRule vRule = ninePieceImage.verticalRule();
+
+ bool fitToBorder = style->borderImage() == ninePieceImage;
+
+ int leftWidth = fitToBorder ? style->borderLeftWidth() : leftSlice;
+ int topWidth = fitToBorder ? style->borderTopWidth() : topSlice;
+ int rightWidth = fitToBorder ? style->borderRightWidth() : rightSlice;
+ int bottomWidth = fitToBorder ? style->borderBottomWidth() : bottomSlice;
+
+ bool drawLeft = leftSlice > 0 && leftWidth > 0;
+ bool drawTop = topSlice > 0 && topWidth > 0;
+ bool drawRight = rightSlice > 0 && rightWidth > 0;
+ bool drawBottom = bottomSlice > 0 && bottomWidth > 0;
+ bool drawMiddle = (imageWidth - leftSlice - rightSlice) > 0 && (w - leftWidth - rightWidth) > 0 &&
+ (imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0;
+
+ Image* image = styleImage->image(this, imageSize);
+
+ if (drawLeft) {
+ // Paint the top and bottom left corners.
+
+ // The top left corner rect is (tx, ty, leftWidth, topWidth)
+ // The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
+ if (drawTop)
+ graphicsContext->drawImage(image, IntRect(tx, ty, leftWidth, topWidth),
+ IntRect(0, 0, leftSlice, topSlice), op);
+
+ // The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
+ // The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
+ if (drawBottom)
+ graphicsContext->drawImage(image, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
+ IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op);
+
+ // Paint the left edge.
+ // Have to scale and tile into the border rect.
+ graphicsContext->drawTiledImage(image, IntRect(tx, ty + topWidth, leftWidth,
+ h - topWidth - bottomWidth),
+ IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice),
+ Image::StretchTile, (Image::TileRule)vRule, op);
+ }
+
+ if (drawRight) {
+ // Paint the top and bottom right corners
+ // The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
+ // The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
+ if (drawTop)
+ graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
+ IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op);
+
+ // The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
+ // The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
+ if (drawBottom)
+ graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
+ IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op);
+
+ // Paint the right edge.
+ graphicsContext->drawTiledImage(image, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
+ h - topWidth - bottomWidth),
+ IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice),
+ Image::StretchTile, (Image::TileRule)vRule, op);
+ }
+
+ // Paint the top edge.
+ if (drawTop)
+ graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
+ IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice),
+ (Image::TileRule)hRule, Image::StretchTile, op);
+
+ // Paint the bottom edge.
+ if (drawBottom)
+ graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + h - bottomWidth,
+ w - leftWidth - rightWidth, bottomWidth),
+ IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice),
+ (Image::TileRule)hRule, Image::StretchTile, op);
+
+ // Paint the middle.
+ if (drawMiddle)
+ graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
+ h - topWidth - bottomWidth),
+ IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice),
+ (Image::TileRule)hRule, (Image::TileRule)vRule, op);
+
+ return true;
+}
+
+void RenderBoxModelObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
+ const RenderStyle* style, bool begin, bool end)
+{
+ if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage()))
+ return;
+
+ const Color& tc = style->borderTopColor();
+ const Color& bc = style->borderBottomColor();
+ const Color& lc = style->borderLeftColor();
+ const Color& rc = style->borderRightColor();
+
+ bool tt = style->borderTopIsTransparent();
+ bool bt = style->borderBottomIsTransparent();
+ bool rt = style->borderRightIsTransparent();
+ bool lt = style->borderLeftIsTransparent();
+
+ EBorderStyle ts = style->borderTopStyle();
+ EBorderStyle bs = style->borderBottomStyle();
+ EBorderStyle ls = style->borderLeftStyle();
+ EBorderStyle rs = style->borderRightStyle();
+
+ bool renderTop = ts > BHIDDEN && !tt;
+ bool renderLeft = ls > BHIDDEN && begin && !lt;
+ bool renderRight = rs > BHIDDEN && end && !rt;
+ bool renderBottom = bs > BHIDDEN && !bt;
+
+ // Need sufficient width and height to contain border radius curves. Sanity check our border radii
+ // and our width/height values to make sure the curves can all fit. If not, then we won't paint
+ // any border radii.
+ bool renderRadii = false;
+ IntSize topLeft = style->borderTopLeftRadius();
+ IntSize topRight = style->borderTopRightRadius();
+ IntSize bottomLeft = style->borderBottomLeftRadius();
+ IntSize bottomRight = style->borderBottomRightRadius();
+
+ if (style->hasBorderRadius() &&
+ static_cast<unsigned>(w) >= static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) &&
+ static_cast<unsigned>(w) >= static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) &&
+ static_cast<unsigned>(h) >= static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) &&
+ static_cast<unsigned>(h) >= static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height()))
+ renderRadii = true;
+
+ // Clip to the rounded rectangle.
+ if (renderRadii) {
+ graphicsContext->save();
+ graphicsContext->addRoundedRectClip(IntRect(tx, ty, w, h), topLeft, topRight, bottomLeft, bottomRight);
+ }
+
+ int firstAngleStart, secondAngleStart, firstAngleSpan, secondAngleSpan;
+ float thickness;
+ bool upperLeftBorderStylesMatch = renderLeft && (ts == ls) && (tc == lc);
+ bool upperRightBorderStylesMatch = renderRight && (ts == rs) && (tc == rc) && (ts != OUTSET) && (ts != RIDGE) && (ts != INSET) && (ts != GROOVE);
+ bool lowerLeftBorderStylesMatch = renderLeft && (bs == ls) && (bc == lc) && (bs != OUTSET) && (bs != RIDGE) && (bs != INSET) && (bs != GROOVE);
+ bool lowerRightBorderStylesMatch = renderRight && (bs == rs) && (bc == rc);
+
+ if (renderTop) {
+ bool ignore_left = (renderRadii && topLeft.width() > 0) ||
+ (tc == lc && tt == lt && ts >= OUTSET &&
+ (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
+
+ bool ignore_right = (renderRadii && topRight.width() > 0) ||
+ (tc == rc && tt == rt && ts >= OUTSET &&
+ (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
+
+ int x = tx;
+ int x2 = tx + w;
+ if (renderRadii) {
+ x += topLeft.width();
+ x2 -= topRight.width();
+ }
+
+ drawLineForBoxSide(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
+ ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
+
+ if (renderRadii) {
+ int leftY = ty;
+
+ // We make the arc double thick and let the clip rect take care of clipping the extra off.
+ // We're doing this because it doesn't seem possible to match the curve of the clip exactly
+ // with the arc-drawing function.
+ thickness = style->borderTopWidth() * 2;
+
+ if (topLeft.width()) {
+ int leftX = tx;
+ // The inner clip clips inside the arc. This is especially important for 1px borders.
+ bool applyLeftInnerClip = (style->borderLeftWidth() < topLeft.width())
+ && (style->borderTopWidth() < topLeft.height())
+ && (ts != DOUBLE || style->borderTopWidth() > 6);
+ if (applyLeftInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, topLeft.width() * 2, topLeft.height() * 2),
+ style->borderTopWidth());
+ }
+
+ firstAngleStart = 90;
+ firstAngleSpan = upperLeftBorderStylesMatch ? 90 : 45;
+
+ // Draw upper left arc
+ drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, topLeft, firstAngleStart, firstAngleSpan,
+ BSTop, tc, style->color(), ts, true);
+ if (applyLeftInnerClip)
+ graphicsContext->restore();
+ }
+
+ if (topRight.width()) {
+ int rightX = tx + w - topRight.width() * 2;
+ bool applyRightInnerClip = (style->borderRightWidth() < topRight.width())
+ && (style->borderTopWidth() < topRight.height())
+ && (ts != DOUBLE || style->borderTopWidth() > 6);
+ if (applyRightInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(rightX, leftY, topRight.width() * 2, topRight.height() * 2),
+ style->borderTopWidth());
+ }
+
+ if (upperRightBorderStylesMatch) {
+ secondAngleStart = 0;
+ secondAngleSpan = 90;
+ } else {
+ secondAngleStart = 45;
+ secondAngleSpan = 45;
+ }
+
+ // Draw upper right arc
+ drawArcForBoxSide(graphicsContext, rightX, leftY, thickness, topRight, secondAngleStart, secondAngleSpan,
+ BSTop, tc, style->color(), ts, false);
+ if (applyRightInnerClip)
+ graphicsContext->restore();
+ }
+ }
+ }
+
+ if (renderBottom) {
+ bool ignore_left = (renderRadii && bottomLeft.width() > 0) ||
+ (bc == lc && bt == lt && bs >= OUTSET &&
+ (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
+
+ bool ignore_right = (renderRadii && bottomRight.width() > 0) ||
+ (bc == rc && bt == rt && bs >= OUTSET &&
+ (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
+
+ int x = tx;
+ int x2 = tx + w;
+ if (renderRadii) {
+ x += bottomLeft.width();
+ x2 -= bottomRight.width();
+ }
+
+ drawLineForBoxSide(graphicsContext, x, ty + h - style->borderBottomWidth(), x2, ty + h, BSBottom, bc, style->color(), bs,
+ ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
+
+ if (renderRadii) {
+ thickness = style->borderBottomWidth() * 2;
+
+ if (bottomLeft.width()) {
+ int leftX = tx;
+ int leftY = ty + h - bottomLeft.height() * 2;
+ bool applyLeftInnerClip = (style->borderLeftWidth() < bottomLeft.width())
+ && (style->borderBottomWidth() < bottomLeft.height())
+ && (bs != DOUBLE || style->borderBottomWidth() > 6);
+ if (applyLeftInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, bottomLeft.width() * 2, bottomLeft.height() * 2),
+ style->borderBottomWidth());
+ }
+
+ if (lowerLeftBorderStylesMatch) {
+ firstAngleStart = 180;
+ firstAngleSpan = 90;
+ } else {
+ firstAngleStart = 225;
+ firstAngleSpan = 45;
+ }
+
+ // Draw lower left arc
+ drawArcForBoxSide(graphicsContext, leftX, leftY, thickness, bottomLeft, firstAngleStart, firstAngleSpan,
+ BSBottom, bc, style->color(), bs, true);
+ if (applyLeftInnerClip)
+ graphicsContext->restore();
+ }
+
+ if (bottomRight.width()) {
+ int rightY = ty + h - bottomRight.height() * 2;
+ int rightX = tx + w - bottomRight.width() * 2;
+ bool applyRightInnerClip = (style->borderRightWidth() < bottomRight.width())
+ && (style->borderBottomWidth() < bottomRight.height())
+ && (bs != DOUBLE || style->borderBottomWidth() > 6);
+ if (applyRightInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(rightX, rightY, bottomRight.width() * 2, bottomRight.height() * 2),
+ style->borderBottomWidth());
+ }
+
+ secondAngleStart = 270;
+ secondAngleSpan = lowerRightBorderStylesMatch ? 90 : 45;
+
+ // Draw lower right arc
+ drawArcForBoxSide(graphicsContext, rightX, rightY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
+ BSBottom, bc, style->color(), bs, false);
+ if (applyRightInnerClip)
+ graphicsContext->restore();
+ }
+ }
+ }
+
+ if (renderLeft) {
+ bool ignore_top = (renderRadii && topLeft.height() > 0) ||
+ (tc == lc && tt == lt && ls >= OUTSET &&
+ (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
+
+ bool ignore_bottom = (renderRadii && bottomLeft.height() > 0) ||
+ (bc == lc && bt == lt && ls >= OUTSET &&
+ (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
+
+ int y = ty;
+ int y2 = ty + h;
+ if (renderRadii) {
+ y += topLeft.height();
+ y2 -= bottomLeft.height();
+ }
+
+ drawLineForBoxSide(graphicsContext, tx, y, tx + style->borderLeftWidth(), y2, BSLeft, lc, style->color(), ls,
+ ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
+
+ if (renderRadii && (!upperLeftBorderStylesMatch || !lowerLeftBorderStylesMatch)) {
+ int topX = tx;
+ thickness = style->borderLeftWidth() * 2;
+
+ if (!upperLeftBorderStylesMatch && topLeft.width()) {
+ int topY = ty;
+ bool applyTopInnerClip = (style->borderLeftWidth() < topLeft.width())
+ && (style->borderTopWidth() < topLeft.height())
+ && (ls != DOUBLE || style->borderLeftWidth() > 6);
+ if (applyTopInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(topX, topY, topLeft.width() * 2, topLeft.height() * 2),
+ style->borderLeftWidth());
+ }
+
+ firstAngleStart = 135;
+ firstAngleSpan = 45;
+
+ // Draw top left arc
+ drawArcForBoxSide(graphicsContext, topX, topY, thickness, topLeft, firstAngleStart, firstAngleSpan,
+ BSLeft, lc, style->color(), ls, true);
+ if (applyTopInnerClip)
+ graphicsContext->restore();
+ }
+
+ if (!lowerLeftBorderStylesMatch && bottomLeft.width()) {
+ int bottomY = ty + h - bottomLeft.height() * 2;
+ bool applyBottomInnerClip = (style->borderLeftWidth() < bottomLeft.width())
+ && (style->borderBottomWidth() < bottomLeft.height())
+ && (ls != DOUBLE || style->borderLeftWidth() > 6);
+ if (applyBottomInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(topX, bottomY, bottomLeft.width() * 2, bottomLeft.height() * 2),
+ style->borderLeftWidth());
+ }
+
+ secondAngleStart = 180;
+ secondAngleSpan = 45;
+
+ // Draw bottom left arc
+ drawArcForBoxSide(graphicsContext, topX, bottomY, thickness, bottomLeft, secondAngleStart, secondAngleSpan,
+ BSLeft, lc, style->color(), ls, false);
+ if (applyBottomInnerClip)
+ graphicsContext->restore();
+ }
+ }
+ }
+
+ if (renderRight) {
+ bool ignore_top = (renderRadii && topRight.height() > 0) ||
+ ((tc == rc) && (tt == rt) &&
+ (rs >= DOTTED || rs == INSET) &&
+ (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
+
+ bool ignore_bottom = (renderRadii && bottomRight.height() > 0) ||
+ ((bc == rc) && (bt == rt) &&
+ (rs >= DOTTED || rs == INSET) &&
+ (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
+
+ int y = ty;
+ int y2 = ty + h;
+ if (renderRadii) {
+ y += topRight.height();
+ y2 -= bottomRight.height();
+ }
+
+ drawLineForBoxSide(graphicsContext, tx + w - style->borderRightWidth(), y, tx + w, y2, BSRight, rc, style->color(), rs,
+ ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
+
+ if (renderRadii && (!upperRightBorderStylesMatch || !lowerRightBorderStylesMatch)) {
+ thickness = style->borderRightWidth() * 2;
+
+ if (!upperRightBorderStylesMatch && topRight.width()) {
+ int topX = tx + w - topRight.width() * 2;
+ int topY = ty;
+ bool applyTopInnerClip = (style->borderRightWidth() < topRight.width())
+ && (style->borderTopWidth() < topRight.height())
+ && (rs != DOUBLE || style->borderRightWidth() > 6);
+ if (applyTopInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(topX, topY, topRight.width() * 2, topRight.height() * 2),
+ style->borderRightWidth());
+ }
+
+ firstAngleStart = 0;
+ firstAngleSpan = 45;
+
+ // Draw top right arc
+ drawArcForBoxSide(graphicsContext, topX, topY, thickness, topRight, firstAngleStart, firstAngleSpan,
+ BSRight, rc, style->color(), rs, true);
+ if (applyTopInnerClip)
+ graphicsContext->restore();
+ }
+
+ if (!lowerRightBorderStylesMatch && bottomRight.width()) {
+ int bottomX = tx + w - bottomRight.width() * 2;
+ int bottomY = ty + h - bottomRight.height() * 2;
+ bool applyBottomInnerClip = (style->borderRightWidth() < bottomRight.width())
+ && (style->borderBottomWidth() < bottomRight.height())
+ && (rs != DOUBLE || style->borderRightWidth() > 6);
+ if (applyBottomInnerClip) {
+ graphicsContext->save();
+ graphicsContext->addInnerRoundedRectClip(IntRect(bottomX, bottomY, bottomRight.width() * 2, bottomRight.height() * 2),
+ style->borderRightWidth());
+ }
+
+ secondAngleStart = 315;
+ secondAngleSpan = 45;
+
+ // Draw bottom right arc
+ drawArcForBoxSide(graphicsContext, bottomX, bottomY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
+ BSRight, rc, style->color(), rs, false);
+ if (applyBottomInnerClip)
+ graphicsContext->restore();
+ }
+ }
+ }
+
+ if (renderRadii)
+ graphicsContext->restore();
+}
+
+void RenderBoxModelObject::paintBoxShadow(GraphicsContext* context, int tx, int ty, int w, int h, const RenderStyle* s, bool begin, bool end)
+{
+ // FIXME: Deal with border-image. Would be great to use border-image as a mask.
+
+ IntRect rect(tx, ty, w, h);
+ bool hasBorderRadius = s->hasBorderRadius();
+ bool hasOpaqueBackground = s->backgroundColor().isValid() && s->backgroundColor().alpha() == 255;
+ for (ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next) {
+ context->save();
+
+ IntSize shadowOffset(shadow->x, shadow->y);
+ int shadowBlur = shadow->blur;
+ IntRect fillRect(rect);
+
+ if (hasBorderRadius) {
+ IntRect shadowRect(rect);
+ shadowRect.inflate(shadowBlur);
+ shadowRect.move(shadowOffset);
+ context->clip(shadowRect);
+
+ // Move the fill just outside the clip, adding 1 pixel separation so that the fill does not
+ // bleed in (due to antialiasing) if the context is transformed.
+ IntSize extraOffset(w + max(0, shadowOffset.width()) + shadowBlur + 1, 0);
+ shadowOffset -= extraOffset;
+ fillRect.move(extraOffset);
+ }
+
+ context->setShadow(shadowOffset, shadowBlur, shadow->color);
+ if (hasBorderRadius) {
+ IntSize topLeft = begin ? s->borderTopLeftRadius() : IntSize();
+ IntSize topRight = end ? s->borderTopRightRadius() : IntSize();
+ IntSize bottomLeft = begin ? s->borderBottomLeftRadius() : IntSize();
+ IntSize bottomRight = end ? s->borderBottomRightRadius() : IntSize();
+ if (!hasOpaqueBackground)
+ context->clipOutRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
+ context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black);
+ } else {
+ if (!hasOpaqueBackground)
+ context->clipOut(rect);
+ context->fillRect(fillRect, Color::black);
+ }
+ context->restore();
+ }
+}
+
+int RenderBoxModelObject::containingBlockWidthForContent() const
+{
+ return containingBlock()->availableWidth();
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderBoxModelObject.h b/WebCore/rendering/RenderBoxModelObject.h
new file mode 100644
index 0000000..161e5d2
--- /dev/null
+++ b/WebCore/rendering/RenderBoxModelObject.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderBoxModelObject_h
+#define RenderBoxModelObject_h
+
+#include "RenderObject.h"
+
+namespace WebCore {
+
+// Values for vertical alignment.
+const int PositionTop = -0x7fffffff;
+const int PositionBottom = 0x7fffffff;
+const int PositionUndefined = 0x80000000;
+
+// This class is the base for all objects that adhere to the CSS box model as described
+// at http://www.w3.org/TR/CSS21/box.html
+
+class RenderBoxModelObject : public RenderObject {
+public:
+ RenderBoxModelObject(Node*);
+ virtual ~RenderBoxModelObject();
+
+ virtual void destroy();
+
+ int relativePositionOffsetX() const;
+ int relativePositionOffsetY() const;
+ IntSize relativePositionOffset() const { return IntSize(relativePositionOffsetX(), relativePositionOffsetY()); }
+
+ // IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow)
+ // to return the remaining width on a given line (and the height of a single line).
+ virtual int offsetLeft() const;
+ virtual int offsetTop() const;
+ virtual int offsetWidth() const = 0;
+ virtual int offsetHeight() const = 0;
+
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateBoxModelInfoFromStyle();
+
+ bool hasSelfPaintingLayer() const;
+ RenderLayer* layer() const { return m_layer; }
+ virtual bool requiresLayer() const { return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip() || hasTransform() || hasMask() || hasReflection(); }
+
+ // This will work on inlines to return the bounding box of all of the lines' border boxes.
+ virtual IntRect borderBoundingBox() const = 0;
+
+ // Virtual since table cells override
+ virtual int paddingTop(bool includeIntrinsicPadding = true) const;
+ virtual int paddingBottom(bool includeIntrinsicPadding = true) const;
+ virtual int paddingLeft(bool includeIntrinsicPadding = true) const;
+ virtual int paddingRight(bool includeIntrinsicPadding = true) const;
+
+ virtual int borderTop() const { return style()->borderTopWidth(); }
+ virtual int borderBottom() const { return style()->borderBottomWidth(); }
+ virtual int borderLeft() const { return style()->borderLeftWidth(); }
+ virtual int borderRight() const { return style()->borderRightWidth(); }
+
+ virtual int marginTop() const = 0;
+ virtual int marginBottom() const = 0;
+ virtual int marginLeft() const = 0;
+ virtual int marginRight() const = 0;
+
+ bool hasHorizontalBordersPaddingOrMargin() const { return hasHorizontalBordersOrPadding() || marginLeft() != 0 || marginRight() != 0; }
+ bool hasHorizontalBordersOrPadding() const { return borderLeft() != 0 || borderRight() != 0 || paddingLeft() != 0 || paddingRight() != 0; }
+
+ virtual int containingBlockWidthForContent() const;
+
+ virtual void childBecameNonInline(RenderObject* /*child*/) { }
+
+ void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true);
+ bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
+ void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true);
+ virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, int clipY, int clipHeight,
+ int tx, int ty, int width, int height, InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver);
+
+ // The difference between this inline's baseline position and the line's baseline position.
+ int verticalPosition(bool firstLine) const;
+
+ // Called by RenderObject::destroy() (and RenderWidget::destroy()) and is the only way layers should ever be destroyed
+ void destroyLayer();
+
+protected:
+ void calculateBackgroundImageGeometry(const FillLayer*, int tx, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize);
+ IntSize calculateBackgroundSize(const FillLayer*, int scaledWidth, int scaledHeight) const;
+
+private:
+ virtual bool isBoxModelObject() const { return true; }
+ friend class RenderView;
+
+ RenderLayer* m_layer;
+
+ // Used to store state between styleWillChange and styleDidChange
+ static bool s_wasFloating;
+};
+
+inline RenderBoxModelObject* toRenderBoxModelObject(RenderObject* o)
+{
+ ASSERT(!o || o->isBoxModelObject());
+ return static_cast<RenderBoxModelObject*>(o);
+}
+
+inline const RenderBoxModelObject* toRenderBoxModelObject(const RenderObject* o)
+{
+ ASSERT(!o || o->isBoxModelObject());
+ return static_cast<const RenderBoxModelObject*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderBoxModelObject(const RenderBoxModelObject*);
+
+} // namespace WebCore
+
+#endif // RenderBoxModelObject_h
diff --git a/WebCore/rendering/RenderButton.cpp b/WebCore/rendering/RenderButton.cpp
index f7ccd0c..d64d7c3 100644
--- a/WebCore/rendering/RenderButton.cpp
+++ b/WebCore/rendering/RenderButton.cpp
@@ -69,7 +69,7 @@ void RenderButton::removeChild(RenderObject* oldChild)
m_inner->removeChild(oldChild);
}
-void RenderButton::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderButton::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
if (m_inner) {
// RenderBlock::setStyle is going to apply a new style to the inner block, which
@@ -81,7 +81,7 @@ void RenderButton::styleWillChange(RenderStyle::Diff diff, const RenderStyle* ne
RenderBlock::styleWillChange(diff, newStyle);
}
-void RenderButton::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderButton::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
@@ -108,23 +108,26 @@ void RenderButton::setupInnerStyle(RenderStyle* innerStyle)
// RenderBlock::createAnonymousBlock creates a new RenderStyle, so this is
// safe to modify.
innerStyle->setBoxFlex(1.0f);
- if (style()->hasAppearance())
- theme()->adjustButtonInnerStyle(innerStyle);
+
+ innerStyle->setPaddingTop(Length(theme()->buttonInternalPaddingTop(), Fixed));
+ innerStyle->setPaddingRight(Length(theme()->buttonInternalPaddingRight(), Fixed));
+ innerStyle->setPaddingBottom(Length(theme()->buttonInternalPaddingBottom(), Fixed));
+ innerStyle->setPaddingLeft(Length(theme()->buttonInternalPaddingLeft(), Fixed));
}
void RenderButton::updateFromElement()
{
// If we're an input element, we may need to change our button text.
- if (element()->hasTagName(inputTag)) {
- HTMLInputElement* input = static_cast<HTMLInputElement*>(element());
+ if (node()->hasTagName(inputTag)) {
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
String value = input->valueWithDefault();
setText(value);
}
#if ENABLE(WML)
- else if (element()->hasTagName(WMLNames::doTag)) {
- WMLDoElement* doElement = static_cast<WMLDoElement*>(element());
+ else if (node()->hasTagName(WMLNames::doTag)) {
+ WMLDoElement* doElement = static_cast<WMLDoElement*>(node());
String value = doElement->label();
if (value.isEmpty())
@@ -140,7 +143,7 @@ bool RenderButton::canHaveChildren() const
// Input elements can't have children, but button elements can. We'll
// write the code assuming any other button types that might emerge in the future
// can also have children.
- return !element()->hasTagName(inputTag);
+ return !node()->hasTagName(inputTag);
}
void RenderButton::setText(const String& str)
@@ -161,12 +164,12 @@ void RenderButton::setText(const String& str)
}
}
-void RenderButton::updateBeforeAfterContent(RenderStyle::PseudoId type)
+void RenderButton::updateBeforeAfterContent(PseudoId type)
{
if (m_inner)
- m_inner->updateBeforeAfterContentForContainer(type, this);
+ m_inner->children()->updateBeforeAfterContent(m_inner, type, this);
else
- updateBeforeAfterContentForContainer(type, this);
+ children()->updateBeforeAfterContent(this, type);
}
IntRect RenderButton::controlClipRect(int tx, int ty) const
diff --git a/WebCore/rendering/RenderButton.h b/WebCore/rendering/RenderButton.h
index 24e4767..89f7cf8 100644
--- a/WebCore/rendering/RenderButton.h
+++ b/WebCore/rendering/RenderButton.h
@@ -39,6 +39,7 @@ public:
RenderButton(Node*);
virtual const char* renderName() const { return "RenderButton"; }
+ virtual bool isRenderButton() const { return true; }
virtual void addChild(RenderObject* newChild, RenderObject *beforeChild = 0);
virtual void removeChild(RenderObject*);
@@ -48,7 +49,7 @@ public:
void setupInnerStyle(RenderStyle*);
virtual void updateFromElement();
- virtual void updateBeforeAfterContent(RenderStyle::PseudoId);
+ virtual void updateBeforeAfterContent(PseudoId);
virtual bool hasControlClip() const { return true; }
virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const;
@@ -58,8 +59,8 @@ public:
virtual bool canHaveChildren() const;
protected:
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual bool hasLineIfEmpty() const { return true; }
@@ -72,6 +73,21 @@ protected:
bool m_default;
};
+inline RenderButton* toRenderButton(RenderObject* o)
+{
+ ASSERT(!o || o->isRenderButton());
+ return static_cast<RenderButton*>(o);
+}
+
+inline const RenderButton* toRenderButton(const RenderObject* o)
+{
+ ASSERT(!o || o->isRenderButton());
+ return static_cast<const RenderButton*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderButton(const RenderButton*);
+
} // namespace WebCore
#endif // RenderButton_h
diff --git a/WebCore/rendering/RenderContainer.cpp b/WebCore/rendering/RenderContainer.cpp
deleted file mode 100644
index dd39d9f..0000000
--- a/WebCore/rendering/RenderContainer.cpp
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "RenderContainer.h"
-
-#include "AXObjectCache.h"
-#include "Document.h"
-#include "RenderCounter.h"
-#include "RenderImageGeneratedContent.h"
-#include "RenderInline.h"
-#include "RenderLayer.h"
-#include "RenderListItem.h"
-#include "RenderTable.h"
-#include "RenderTextFragment.h"
-#include "RenderView.h"
-#include "htmlediting.h"
-
-namespace WebCore {
-
-RenderContainer::RenderContainer(Node* node)
- : RenderBox(node)
- , m_firstChild(0)
- , m_lastChild(0)
-{
-}
-
-RenderContainer::~RenderContainer()
-{
-}
-
-void RenderContainer::destroy()
-{
- destroyLeftoverChildren();
- RenderBox::destroy();
-}
-
-void RenderContainer::destroyLeftoverChildren()
-{
- while (m_firstChild) {
- if (m_firstChild->isListMarker() || (m_firstChild->style()->styleType() == RenderStyle::FIRST_LETTER && !m_firstChild->isText()))
- m_firstChild->remove(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
- else {
- // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
- if (m_firstChild->element())
- m_firstChild->element()->setRenderer(0);
- m_firstChild->destroy();
- }
- }
-}
-
-bool RenderContainer::canHaveChildren() const
-{
- return true;
-}
-
-static void updateListMarkerNumbers(RenderObject* child)
-{
- for (RenderObject* r = child; r; r = r->nextSibling())
- if (r->isListItem())
- static_cast<RenderListItem*>(r)->updateValue();
-}
-
-void RenderContainer::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
- bool needsTable = false;
-
- if (newChild->isListItem())
- updateListMarkerNumbers(beforeChild ? beforeChild : m_lastChild);
- else if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
- needsTable = !isTable();
- else if (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
- needsTable = !isTable();
- else if (newChild->isTableSection())
- needsTable = !isTable();
- else if (newChild->isTableRow())
- needsTable = !isTableSection();
- else if (newChild->isTableCell()) {
- needsTable = !isTableRow();
- // I'm not 100% sure this is the best way to fix this, but without this
- // change we recurse infinitely when trying to render the CSS2 test page:
- // http://www.bath.ac.uk/%7Epy8ieh/internet/eviltests/htmlbodyheadrendering2.html.
- // See Radar 2925291.
- if (needsTable && isTableCell() && !m_firstChild && !newChild->isTableCell())
- needsTable = false;
- }
-
- if (needsTable) {
- RenderTable* table;
- RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : m_lastChild;
- if (afterChild && afterChild->isAnonymous() && afterChild->isTable())
- table = static_cast<RenderTable*>(afterChild);
- else {
- table = new (renderArena()) RenderTable(document() /* is anonymous */);
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(style());
- newStyle->setDisplay(TABLE);
- table->setStyle(newStyle.release());
- addChild(table, beforeChild);
- }
- table->addChild(newChild);
- } else {
- // just add it...
- insertChildNode(newChild, beforeChild);
- }
-
- if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
- RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
- if (textToTransform)
- toRenderText(newChild)->setText(textToTransform.release(), true);
- }
-}
-
-RenderObject* RenderContainer::removeChildNode(RenderObject* oldChild, bool fullRemove)
-{
- ASSERT(oldChild->parent() == this);
-
- // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
- // that a positioned child got yanked). We also repaint, so that the area exposed when the child
- // disappears gets repainted properly.
- if (!documentBeingDestroyed() && fullRemove && oldChild->m_everHadLayout) {
- oldChild->setNeedsLayoutAndPrefWidthsRecalc();
- oldChild->repaint();
- }
-
- // If we have a line box wrapper, delete it.
- oldChild->deleteLineBoxWrapper();
-
- if (!documentBeingDestroyed() && fullRemove) {
- // if we remove visible child from an invisible parent, we don't know the layer visibility any more
- RenderLayer* layer = 0;
- if (m_style->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) {
- layer = enclosingLayer();
- layer->dirtyVisibleContentStatus();
- }
-
- // Keep our layer hierarchy updated.
- if (oldChild->firstChild() || oldChild->hasLayer()) {
- if (!layer) layer = enclosingLayer();
- oldChild->removeLayers(layer);
- }
-
- // renumber ordered lists
- if (oldChild->isListItem())
- updateListMarkerNumbers(oldChild->nextSibling());
-
- if (oldChild->isPositioned() && childrenInline())
- dirtyLinesFromChangedChild(oldChild);
- }
-
- // If oldChild is the start or end of the selection, then clear the selection to
- // avoid problems of invalid pointers.
- // FIXME: The SelectionController should be responsible for this when it
- // is notified of DOM mutations.
- if (!documentBeingDestroyed() && oldChild->isSelectionBorder())
- view()->clearSelection();
-
- // remove the child
- if (oldChild->previousSibling())
- oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
- if (oldChild->nextSibling())
- oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
-
- if (m_firstChild == oldChild)
- m_firstChild = oldChild->nextSibling();
- if (m_lastChild == oldChild)
- m_lastChild = oldChild->previousSibling();
-
- oldChild->setPreviousSibling(0);
- oldChild->setNextSibling(0);
- oldChild->setParent(0);
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->childrenChanged(this);
-
- return oldChild;
-}
-
-void RenderContainer::removeChild(RenderObject* oldChild)
-{
- // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode
- // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on
- // layout anyway).
- oldChild->removeFromObjectLists();
-
- removeChildNode(oldChild);
-}
-
-RenderObject* RenderContainer::beforeAfterContainer(RenderStyle::PseudoId type)
-{
- if (type == RenderStyle::BEFORE) {
- RenderObject* first = this;
- do {
- // Skip list markers.
- first = first->firstChild();
- while (first && first->isListMarker())
- first = first->nextSibling();
- } while (first && first->isAnonymous() && first->style()->styleType() == RenderStyle::NOPSEUDO);
- if (first && first->style()->styleType() != type)
- return 0;
- return first;
- }
- if (type == RenderStyle::AFTER) {
- RenderObject* last = this;
- do {
- last = last->lastChild();
- } while (last && last->isAnonymous() && last->style()->styleType() == RenderStyle::NOPSEUDO && !last->isListMarker());
- if (last && last->style()->styleType() != type)
- return 0;
- return last;
- }
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-void RenderContainer::updateBeforeAfterContent(RenderStyle::PseudoId type)
-{
- // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.
- if (parent() && parent()->createsAnonymousWrapper())
- return;
- updateBeforeAfterContentForContainer(type, this);
-}
-
-static RenderObject* findBeforeAfterParent(RenderObject* object)
-{
- // Only table parts need to search for the :before or :after parent
- if (!(object->isTable() || object->isTableSection() || object->isTableRow()))
- return object;
-
- RenderObject* beforeAfterParent = object;
- while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage()))
- beforeAfterParent = beforeAfterParent->firstChild();
- return beforeAfterParent;
-}
-
-void RenderContainer::updateBeforeAfterContentForContainer(RenderStyle::PseudoId type, RenderContainer* styledObject)
-{
- // Double check that the document did in fact use generated content rules. Otherwise we should not have been called.
- ASSERT(document()->usesBeforeAfterRules());
-
- // In CSS2, before/after pseudo-content cannot nest. Check this first.
- if (style()->styleType() == RenderStyle::BEFORE || style()->styleType() == RenderStyle::AFTER)
- return;
-
- RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
- RenderObject* child = beforeAfterContainer(type);
-
- // Whether or not we currently have generated content attached.
- bool oldContentPresent = child;
-
- // Whether or not we now want generated content.
- bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
-
- // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
- // :after content and not :before content.
- if (newContentWanted && type == RenderStyle::BEFORE && isInlineContinuation())
- newContentWanted = false;
-
- // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
- // then we don't generate the :after content.
- if (newContentWanted && type == RenderStyle::AFTER && isRenderInline() && static_cast<RenderInline*>(this)->continuation())
- newContentWanted = false;
-
- // If we don't want generated content any longer, or if we have generated content, but it's no longer
- // identical to the new content data we want to build render objects for, then we nuke all
- // of the old generated content.
- if (!newContentWanted || (oldContentPresent && Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) {
- // Nuke the child.
- if (child && child->style()->styleType() == type) {
- oldContentPresent = false;
- child->destroy();
- child = (type == RenderStyle::BEFORE) ? m_firstChild : m_lastChild;
- }
- }
-
- // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we
- // have no generated content and can now return.
- if (!newContentWanted)
- return;
-
- if (isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && pseudoElementStyle->floating() == FNONE &&
- !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementStyle->position() == FixedPosition))
- // According to the CSS2 spec (the end of section 12.1), the only allowed
- // display values for the pseudo style are NONE and INLINE for inline flows.
- // FIXME: CSS2.1 lifted this restriction, but block display types will crash.
- // For now we at least relax the restriction to allow all inline types like inline-block
- // and inline-table.
- pseudoElementStyle->setDisplay(INLINE);
-
- if (oldContentPresent) {
- if (child && child->style()->styleType() == type) {
- // We have generated content present still. We want to walk this content and update our
- // style information with the new pseudo-element style.
- child->setStyle(pseudoElementStyle);
-
- RenderObject* beforeAfterParent = findBeforeAfterParent(child);
- if (!beforeAfterParent)
- return;
-
- // Note that if we ever support additional types of generated content (which should be way off
- // in the future), this code will need to be patched.
- for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {
- if (genChild->isText())
- // Generated text content is a child whose style also needs to be set to the pseudo-element style.
- genChild->setStyle(pseudoElementStyle);
- else if (genChild->isImage()) {
- // Images get an empty style that inherits from the pseudo.
- RefPtr<RenderStyle> style = RenderStyle::create();
- style->inheritFrom(pseudoElementStyle);
- genChild->setStyle(style.release());
- } else
- // Must be a first-letter container. updateFirstLetter() will take care of it.
- ASSERT(genChild->style()->styleType() == RenderStyle::FIRST_LETTER);
- }
- }
- return; // We've updated the generated content. That's all we needed to do.
- }
-
- RenderObject* insertBefore = (type == RenderStyle::BEFORE) ? firstChild() : 0;
-
- // Generated content consists of a single container that houses multiple children (specified
- // by the content property). This generated content container gets the pseudo-element style set on it.
- RenderObject* generatedContentContainer = 0;
-
- // Walk our list of generated content and create render objects for each.
- for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->m_next) {
- RenderObject* renderer = 0;
- switch (content->m_type) {
- case CONTENT_NONE:
- break;
- case CONTENT_TEXT:
- renderer = new (renderArena()) RenderTextFragment(document() /* anonymous object */, content->m_content.m_text);
- renderer->setStyle(pseudoElementStyle);
- break;
- case CONTENT_OBJECT: {
- RenderImageGeneratedContent* image = new (renderArena()) RenderImageGeneratedContent(document()); // anonymous object
- RefPtr<RenderStyle> style = RenderStyle::create();
- style->inheritFrom(pseudoElementStyle);
- image->setStyle(style.release());
- if (StyleImage* styleImage = content->m_content.m_image)
- image->setStyleImage(styleImage);
- renderer = image;
- break;
- }
- case CONTENT_COUNTER:
- renderer = new (renderArena()) RenderCounter(document(), *content->m_content.m_counter);
- renderer->setStyle(pseudoElementStyle);
- break;
- }
-
- if (renderer) {
- if (!generatedContentContainer) {
- // Make a generated box that might be any display type now that we are able to drill down into children
- // to find the original content properly.
- generatedContentContainer = RenderObject::createObject(document(), pseudoElementStyle);
- generatedContentContainer->setStyle(pseudoElementStyle);
- addChild(generatedContentContainer, insertBefore);
- }
- generatedContentContainer->addChild(renderer);
- }
- }
-}
-
-bool RenderContainer::isAfterContent(RenderObject* child) const
-{
- if (!child)
- return false;
- if (child->style()->styleType() != RenderStyle::AFTER)
- return false;
- // Text nodes don't have their own styles, so ignore the style on a text node.
- if (child->isText() && !child->isBR())
- return false;
- return true;
-}
-
-static void invalidateCountersInContainer(RenderObject* container)
-{
- if (!container)
- return;
- container = findBeforeAfterParent(container);
- if (!container)
- return;
- for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) {
- if (content->isCounter())
- static_cast<RenderCounter*>(content)->invalidate();
- }
-}
-
-void RenderContainer::invalidateCounters()
-{
- if (documentBeingDestroyed())
- return;
-
- invalidateCountersInContainer(beforeAfterContainer(RenderStyle::BEFORE));
- invalidateCountersInContainer(beforeAfterContainer(RenderStyle::AFTER));
-}
-
-void RenderContainer::appendChildNode(RenderObject* newChild, bool fullAppend)
-{
- ASSERT(newChild->parent() == 0);
- ASSERT(!isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
-
- newChild->setParent(this);
- RenderObject* lChild = m_lastChild;
-
- if (lChild) {
- newChild->setPreviousSibling(lChild);
- lChild->setNextSibling(newChild);
- } else
- m_firstChild = newChild;
-
- m_lastChild = newChild;
-
- if (fullAppend) {
- // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
- // and don't have a layer attached to ourselves.
- RenderLayer* layer = 0;
- if (newChild->firstChild() || newChild->hasLayer()) {
- layer = enclosingLayer();
- newChild->addLayers(layer, newChild);
- }
-
- // if the new child is visible but this object was not, tell the layer it has some visible content
- // that needs to be drawn and layer visibility optimization can't be used
- if (style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
- if (!layer)
- layer = enclosingLayer();
- if (layer)
- layer->setHasVisibleContent(true);
- }
-
- if (!newChild->isFloatingOrPositioned() && childrenInline())
- dirtyLinesFromChangedChild(newChild);
- }
-
- newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
- if (!normalChildNeedsLayout())
- setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->childrenChanged(this);
-}
-
-void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild, bool fullInsert)
-{
- if (!beforeChild) {
- appendChildNode(child);
- return;
- }
-
- ASSERT(!child->parent());
- while (beforeChild->parent() != this && beforeChild->parent()->isAnonymousBlock())
- beforeChild = beforeChild->parent();
- ASSERT(beforeChild->parent() == this);
-
- ASSERT(!isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
-
- if (beforeChild == m_firstChild)
- m_firstChild = child;
-
- RenderObject* prev = beforeChild->previousSibling();
- child->setNextSibling(beforeChild);
- beforeChild->setPreviousSibling(child);
- if(prev) prev->setNextSibling(child);
- child->setPreviousSibling(prev);
-
- child->setParent(this);
-
- if (fullInsert) {
- // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
- // and don't have a layer attached to ourselves.
- RenderLayer* layer = 0;
- if (child->firstChild() || child->hasLayer()) {
- layer = enclosingLayer();
- child->addLayers(layer, child);
- }
-
- // if the new child is visible but this object was not, tell the layer it has some visible content
- // that needs to be drawn and layer visibility optimization can't be used
- if (style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
- if (!layer)
- layer = enclosingLayer();
- if (layer)
- layer->setHasVisibleContent(true);
- }
-
-
- if (!child->isFloating() && childrenInline())
- dirtyLinesFromChangedChild(child);
- }
-
- child->setNeedsLayoutAndPrefWidthsRecalc();
- if (!normalChildNeedsLayout())
- setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->childrenChanged(this);
-}
-
-void RenderContainer::layout()
-{
- ASSERT(needsLayout());
-
- LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
-
- RenderObject* child = m_firstChild;
- while (child) {
- child->layoutIfNeeded();
- ASSERT(child->isRenderInline() || !child->needsLayout());
- child = child->nextSibling();
- }
-
- statePusher.pop();
- setNeedsLayout(false);
-}
-
-void RenderContainer::removeLeftoverAnonymousBlock(RenderBlock* child)
-{
- ASSERT(child->isAnonymousBlock());
- ASSERT(!child->childrenInline());
-
- if (child->continuation())
- return;
-
- RenderObject* firstAnChild = child->firstChild();
- RenderObject* lastAnChild = child->lastChild();
- if (firstAnChild) {
- RenderObject* o = firstAnChild;
- while(o) {
- o->setParent(this);
- o = o->nextSibling();
- }
- firstAnChild->setPreviousSibling(child->previousSibling());
- lastAnChild->setNextSibling(child->nextSibling());
- if (child->previousSibling())
- child->previousSibling()->setNextSibling(firstAnChild);
- if (child->nextSibling())
- child->nextSibling()->setPreviousSibling(lastAnChild);
- } else {
- if (child->previousSibling())
- child->previousSibling()->setNextSibling(child->nextSibling());
- if (child->nextSibling())
- child->nextSibling()->setPreviousSibling(child->previousSibling());
- }
- if (child == m_firstChild)
- m_firstChild = firstAnChild;
- if (child == m_lastChild)
- m_lastChild = lastAnChild;
- child->setParent(0);
- child->setPreviousSibling(0);
- child->setNextSibling(0);
- if (!child->isText()) {
- RenderContainer *c = static_cast<RenderContainer*>(child);
- c->m_firstChild = 0;
- c->m_next = 0;
- }
- child->destroy();
-}
-
-VisiblePosition RenderContainer::positionForCoordinates(int xPos, int yPos)
-{
- // no children...return this render object's element, if there is one, and offset 0
- if (!m_firstChild)
- return VisiblePosition(element(), 0, DOWNSTREAM);
-
- if (isTable() && element()) {
- int right = contentWidth() + borderRight() + paddingRight() + borderLeft() + paddingLeft();
- int bottom = contentHeight() + borderTop() + paddingTop() + borderBottom() + paddingBottom();
-
- if (xPos < 0 || xPos > right || yPos < 0 || yPos > bottom) {
- if (xPos <= right / 2)
- return VisiblePosition(Position(element(), 0));
- else
- return VisiblePosition(Position(element(), maxDeepOffset(element())));
- }
- }
-
- // Pass off to the closest child.
- int minDist = INT_MAX;
- RenderBox* closestRenderer = 0;
- int newX = xPos;
- int newY = yPos;
- if (isTableRow()) {
- newX += x();
- newY += y();
- }
- for (RenderObject* renderObject = m_firstChild; renderObject; renderObject = renderObject->nextSibling()) {
- if (!renderObject->firstChild() && !renderObject->isInline() && !renderObject->isBlockFlow()
- || renderObject->style()->visibility() != VISIBLE)
- continue;
-
- if (!renderObject->isBox())
- continue;
-
- RenderBox* renderer = toRenderBox(renderObject);
-
- int top = borderTop() + paddingTop() + (isTableRow() ? 0 : renderer->y());
- int bottom = top + renderer->contentHeight();
- int left = borderLeft() + paddingLeft() + (isTableRow() ? 0 : renderer->x());
- int right = left + renderer->contentWidth();
-
- if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) {
- if (renderer->isTableRow())
- return renderer->positionForCoordinates(xPos + newX - renderer->x(), yPos + newY - renderer->y());
- return renderer->positionForCoordinates(xPos - renderer->x(), yPos - renderer->y());
- }
-
- // Find the distance from (x, y) to the box. Split the space around the box into 8 pieces
- // and use a different compare depending on which piece (x, y) is in.
- IntPoint cmp;
- if (xPos > right) {
- if (yPos < top)
- cmp = IntPoint(right, top);
- else if (yPos > bottom)
- cmp = IntPoint(right, bottom);
- else
- cmp = IntPoint(right, yPos);
- } else if (xPos < left) {
- if (yPos < top)
- cmp = IntPoint(left, top);
- else if (yPos > bottom)
- cmp = IntPoint(left, bottom);
- else
- cmp = IntPoint(left, yPos);
- } else {
- if (yPos < top)
- cmp = IntPoint(xPos, top);
- else
- cmp = IntPoint(xPos, bottom);
- }
-
- int x1minusx2 = cmp.x() - xPos;
- int y1minusy2 = cmp.y() - yPos;
-
- int dist = x1minusx2 * x1minusx2 + y1minusy2 * y1minusy2;
- if (dist < minDist) {
- closestRenderer = renderer;
- minDist = dist;
- }
- }
-
- if (closestRenderer)
- return closestRenderer->positionForCoordinates(newX - closestRenderer->x(), newY - closestRenderer->y());
-
- return VisiblePosition(element(), 0, DOWNSTREAM);
-}
-
-void RenderContainer::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigned end, bool)
-{
- if (!m_firstChild && (isInline() || isAnonymousBlock())) {
- FloatPoint absPos = localToAbsolute(FloatPoint());
- absoluteRects(rects, absPos.x(), absPos.y());
- return;
- }
-
- if (!m_firstChild)
- return;
-
- unsigned offset = start;
- for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset) {
- if (child->isText() || child->isInline() || child->isAnonymousBlock()) {
- FloatPoint absPos = child->localToAbsolute(FloatPoint());
- child->absoluteRects(rects, absPos.x(), absPos.y());
- }
- }
-}
-
-void RenderContainer::collectAbsoluteLineBoxQuads(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool /*useSelectionHeight*/)
-{
- if (!m_firstChild && (isInline() || isAnonymousBlock())) {
- absoluteQuads(quads);
- return;
- }
-
- if (!m_firstChild)
- return;
-
- unsigned offset = start;
- for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset) {
- if (child->isText() || child->isInline() || child->isAnonymousBlock())
- child->absoluteQuads(quads);
- }
-}
-
-#ifdef ANDROID_LAYOUT
-bool RenderContainer::hasChildTable() const
-{
- if (!firstChild())
- return false;
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isTable()) {
- return true;
- } else if (child->hasChildTable() == true) {
- return true;
- }
- }
- return false;
-}
-#endif
-
-#undef DEBUG_LAYOUT
-
-} // namespace WebCore
diff --git a/WebCore/rendering/RenderContainer.h b/WebCore/rendering/RenderContainer.h
deleted file mode 100644
index 8ae5296..0000000
--- a/WebCore/rendering/RenderContainer.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2001 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef RenderContainer_h
-#define RenderContainer_h
-
-#include "RenderBox.h"
-
-namespace WebCore {
-
-// Base class for rendering objects that can have children.
-class RenderContainer : public RenderBox {
-public:
- RenderContainer(Node*);
- virtual ~RenderContainer();
-
- virtual RenderObject* firstChild() const { return m_firstChild; }
- virtual RenderObject* lastChild() const { return m_lastChild; }
-
- // Use this with caution! No type checking is done!
- RenderBox* firstChildBox() const { ASSERT(!firstChild() || firstChild()->isBox()); return toRenderBox(m_firstChild); }
- RenderBox* lastChildBox() const { ASSERT(!lastChild() || lastChild()->isBox()); return toRenderBox(m_lastChild); }
-
- virtual bool canHaveChildren() const;
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject*);
-
- virtual void destroy();
- void destroyLeftoverChildren();
-
- virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
- virtual void appendChildNode(RenderObject*, bool fullAppend = true);
- virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
-
- // Designed for speed. Don't waste time doing a bunch of work like layer updating and repainting when we know that our
- // change in parentage is not going to affect anything.
- virtual void moveChildNode(RenderObject* child) { appendChildNode(child->parent()->removeChildNode(child, false), false); }
-
- virtual void layout();
- virtual void calcPrefWidths() { setPrefWidthsDirty(false); }
-
- virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
-
- RenderObject* beforeAfterContainer(RenderStyle::PseudoId);
- virtual void updateBeforeAfterContent(RenderStyle::PseudoId);
- void updateBeforeAfterContentForContainer(RenderStyle::PseudoId, RenderContainer*);
- bool isAfterContent(RenderObject* child) const;
- virtual void invalidateCounters();
-
- virtual VisiblePosition positionForCoordinates(int x, int y);
-#ifdef ANDROID_LAYOUT
- virtual bool hasChildTable() const;
-#endif
-
- virtual void addLineBoxRects(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
- virtual void collectAbsoluteLineBoxQuads(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
-
-protected:
- RenderObject* m_firstChild;
- RenderObject* m_lastChild;
-};
-
-} // namespace WebCore
-
-#endif // RenderContainer_h
diff --git a/WebCore/rendering/RenderCounter.cpp b/WebCore/rendering/RenderCounter.cpp
index 598f40d..fd6d80d 100644
--- a/WebCore/rendering/RenderCounter.cpp
+++ b/WebCore/rendering/RenderCounter.cpp
@@ -116,7 +116,7 @@ static bool planCounter(RenderObject* object, const AtomicString& counterName, b
isReset = false;
return true;
}
- if (Node* e = object->element()) {
+ if (Node* e = object->node()) {
if (e->hasTagName(olTag)) {
value = static_cast<HTMLOListElement*>(e)->start();
isReset = true;
@@ -251,13 +251,6 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
return text.impl();
}
-void RenderCounter::dirtyLineBoxes(bool fullLayout, bool dummy)
-{
- if (prefWidthsDirty())
- calcPrefWidths(0);
- RenderText::dirtyLineBoxes(fullLayout, dummy);
-}
-
void RenderCounter::calcPrefWidths(int lead)
{
setTextInternal(originalText());
@@ -278,7 +271,11 @@ static void destroyCounterNodeChildren(AtomicStringImpl* identifier, CounterNode
child->parent()->removeChild(child);
ASSERT(counterMaps().get(child->renderer())->get(identifier) == child);
counterMaps().get(child->renderer())->remove(identifier);
- child->renderer()->invalidateCounters();
+ if (!child->renderer()->documentBeingDestroyed()) {
+ RenderObjectChildList* children = child->renderer()->virtualChildren();
+ if (children)
+ children->invalidateCounters(child->renderer());
+ }
delete child;
}
}
diff --git a/WebCore/rendering/RenderCounter.h b/WebCore/rendering/RenderCounter.h
index 10be066..55aab73 100644
--- a/WebCore/rendering/RenderCounter.h
+++ b/WebCore/rendering/RenderCounter.h
@@ -37,7 +37,6 @@ public:
virtual bool isCounter() const;
virtual PassRefPtr<StringImpl> originalText() const;
- virtual void dirtyLineBoxes(bool, bool);
virtual void calcPrefWidths(int leadWidth);
void invalidate();
diff --git a/WebCore/rendering/RenderFieldset.cpp b/WebCore/rendering/RenderFieldset.cpp
index 5baca3e..310dbe4 100644
--- a/WebCore/rendering/RenderFieldset.cpp
+++ b/WebCore/rendering/RenderFieldset.cpp
@@ -107,10 +107,10 @@ RenderObject* RenderFieldset::layoutLegend(bool relayoutChildren)
RenderBox* RenderFieldset::findLegend() const
{
for (RenderObject* legend = firstChild(); legend; legend = legend->nextSibling()) {
- if (!legend->isFloatingOrPositioned() && legend->element() &&
- legend->element()->hasTagName(legendTag)
+ if (!legend->isFloatingOrPositioned() && legend->node() &&
+ legend->node()->hasTagName(legendTag)
#if ENABLE(WML)
- || legend->element()->hasTagName(WMLNames::insertedLegendTag)
+ || legend->node()->hasTagName(WMLNames::insertedLegendTag)
#endif
)
return toRenderBox(legend);
@@ -204,17 +204,17 @@ void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, in
if (render_t) {
if (lx >= borderLeftWidth)
- drawBorder(graphicsContext, tx, ty, tx + min(lx, w), ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
+ drawLineForBoxSide(graphicsContext, tx, ty, tx + min(lx, w), ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
(render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? borderLeftWidth : 0),
(lx >= w && render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? borderRightWidth : 0));
if (lx + lw <= w - borderRightWidth)
- drawBorder(graphicsContext, tx + max(0, lx + lw), ty, tx + w, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
+ drawLineForBoxSide(graphicsContext, tx + max(0, lx + lw), ty, tx + w, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
(lx + lw <= 0 && render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? borderLeftWidth : 0),
(render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? borderRightWidth : 0));
}
if (render_b)
- drawBorder(graphicsContext, tx, ty + h - style->borderBottomWidth(), tx + w, ty + h, BSBottom, bc, style->color(), bs,
+ drawLineForBoxSide(graphicsContext, tx, ty + h - style->borderBottomWidth(), tx + w, ty + h, BSBottom, bc, style->color(), bs,
(render_l && (ls == DOTTED || ls == DASHED || ls == DOUBLE) ? style->borderLeftWidth() : 0),
(render_r && (rs == DOTTED || rs == DASHED || rs == DOUBLE) ? style->borderRightWidth() : 0));
@@ -238,7 +238,7 @@ void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, in
startY = lb;
}
- drawBorder(graphicsContext, tx, startY, tx + borderLeftWidth, ty + h, BSLeft, lc, style->color(), ls,
+ drawLineForBoxSide(graphicsContext, tx, startY, tx + borderLeftWidth, ty + h, BSLeft, lc, style->color(), ls,
ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
}
@@ -262,12 +262,12 @@ void RenderFieldset::paintBorderMinusLegend(GraphicsContext* graphicsContext, in
startY = lb;
}
- drawBorder(graphicsContext, tx + w - borderRightWidth, startY, tx + w, ty + h, BSRight, rc, style->color(), rs,
+ drawLineForBoxSide(graphicsContext, tx + w - borderRightWidth, startY, tx + w, ty + h, BSRight, rc, style->color(), rs,
ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
}
}
-void RenderFieldset::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderFieldset::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
diff --git a/WebCore/rendering/RenderFieldset.h b/WebCore/rendering/RenderFieldset.h
index 38f3236..ed57d3a 100644
--- a/WebCore/rendering/RenderFieldset.h
+++ b/WebCore/rendering/RenderFieldset.h
@@ -46,7 +46,7 @@ public:
RenderBox* findLegend() const;
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
diff --git a/WebCore/rendering/RenderFileUploadControl.cpp b/WebCore/rendering/RenderFileUploadControl.cpp
index cbf1409..33ffd98 100644
--- a/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/WebCore/rendering/RenderFileUploadControl.cpp
@@ -22,6 +22,7 @@
#include "RenderFileUploadControl.h"
#include "FileList.h"
+#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLInputElement.h"
@@ -73,7 +74,7 @@ RenderFileUploadControl::~RenderFileUploadControl()
m_fileChooser->disconnectClient();
}
-void RenderFileUploadControl::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderFileUploadControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
if (m_button)
@@ -157,7 +158,7 @@ int RenderFileUploadControl::maxFilenameWidth() const
PassRefPtr<RenderStyle> RenderFileUploadControl::createButtonStyle(const RenderStyle* parentStyle) const
{
- RefPtr<RenderStyle> style = getCachedPseudoStyle(RenderStyle::FILE_UPLOAD_BUTTON);
+ RefPtr<RenderStyle> style = getCachedPseudoStyle(FILE_UPLOAD_BUTTON);
if (!style) {
style = RenderStyle::create();
if (parentStyle)
@@ -202,7 +203,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
else
textX = contentLeft + contentWidth() - buttonAndIconWidth - style()->font().width(textRun);
// We want to match the button's baseline
- RenderButton* buttonRenderer = static_cast<RenderButton*>(m_button->renderer());
+ RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
int textY = buttonRenderer->absoluteBoundingBoxRect().y()
+ buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
+ buttonRenderer->baselinePosition(true, false);
diff --git a/WebCore/rendering/RenderFileUploadControl.h b/WebCore/rendering/RenderFileUploadControl.h
index 60e7a7b..85bc09f 100644
--- a/WebCore/rendering/RenderFileUploadControl.h
+++ b/WebCore/rendering/RenderFileUploadControl.h
@@ -55,7 +55,7 @@ public:
bool allowsMultipleFiles();
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
int maxFilenameWidth() const;
diff --git a/WebCore/rendering/RenderFlexibleBox.cpp b/WebCore/rendering/RenderFlexibleBox.cpp
index e6dd91a..ff9dad4 100644
--- a/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/WebCore/rendering/RenderFlexibleBox.cpp
@@ -205,14 +205,7 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
if (!relayoutChildren && layoutOnlyPositionedObjects())
return;
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
-
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasTransform() || hasReflection());
int previousWidth = width();
@@ -248,9 +241,9 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
// For overflow:scroll blocks, ensure we have both scrollbars in place always.
if (scrollsOverflow()) {
if (style()->overflowX() == OSCROLL)
- m_layer->setHasHorizontalScrollbar(true);
+ layer()->setHasHorizontalScrollbar(true);
if (style()->overflowY() == OSCROLL)
- m_layer->setHasVerticalScrollbar(true);
+ layer()->setHasVerticalScrollbar(true);
}
if (isHorizontal())
@@ -316,11 +309,10 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
// Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
if (hasOverflowClip())
- m_layer->updateScrollInfoAfterLayout();
+ layer()->updateScrollInfoAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ repainter.repaintAfterLayout();
setNeedsLayout(false);
}
@@ -393,9 +385,10 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
// Update our height and overflow height.
if (style()->boxAlign() == BBASELINE) {
- int ascent = child->marginTop() + child->getBaselineOfFirstLineBox();
+ int ascent = child->firstLineBoxBaseline();
if (ascent == -1)
- ascent = child->marginTop() + child->height() + child->marginBottom();
+ ascent = child->height() + child->marginBottom();
+ ascent += child->marginTop();
int descent = (child->marginTop() + child->height() + child->marginBottom()) - ascent;
// Update our maximum ascent.
@@ -435,13 +428,13 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
while (child) {
if (child->isPositioned()) {
child->containingBlock()->insertPositionedObject(child);
- if (child->hasStaticX()) {
+ if (child->style()->hasStaticX()) {
if (style()->direction() == LTR)
- child->setStaticX(xPos);
- else child->setStaticX(width() - xPos);
+ child->layer()->setStaticX(xPos);
+ else child->layer()->setStaticX(width() - xPos);
}
- if (child->hasStaticY())
- child->setStaticY(yPos);
+ if (child->style()->hasStaticY())
+ child->layer()->setStaticY(yPos);
child = iterator.next();
continue;
}
@@ -450,7 +443,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
// fill the height of a containing box by default.
// Now do a layout.
int oldChildHeight = child->height();
- toRenderBox(child)->calcHeight();
+ child->calcHeight();
if (oldChildHeight != child->height())
child->setChildNeedsLayout(true, false);
child->layoutIfNeeded();
@@ -463,9 +456,10 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
childY += child->marginTop() + max(0, (contentHeight() - (child->height() + child->marginTop() + child->marginBottom()))/2);
break;
case BBASELINE: {
- int ascent = child->marginTop() + child->getBaselineOfFirstLineBox();
+ int ascent = child->firstLineBoxBaseline();
if (ascent == -1)
- ascent = child->marginTop() + child->height() + child->marginBottom();
+ ascent = child->height() + child->marginBottom();
+ ascent += child->marginTop();
childY += child->marginTop() + (maxAscent - ascent);
break;
}
@@ -480,7 +474,7 @@ void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
placeChild(child, xPos, childY);
if (child->isRenderBlock())
- static_cast<RenderBlock*>(child)->addVisualOverflow(static_cast<RenderBlock*>(child)->floatRect());
+ toRenderBlock(child)->addVisualOverflow(toRenderBlock(child)->floatRect());
m_overflowHeight = max(m_overflowHeight, childY + child->overflowHeight(false));
m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false));
@@ -719,13 +713,13 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
// Dirty all the positioned objects.
if (child->isRenderBlock()) {
- static_cast<RenderBlock*>(child)->markPositionedObjectsForLayout();
- static_cast<RenderBlock*>(child)->clearTruncation();
+ toRenderBlock(child)->markPositionedObjectsForLayout();
+ toRenderBlock(child)->clearTruncation();
}
}
child->layoutIfNeeded();
if (child->style()->height().isAuto() && child->isBlockFlow())
- maxLineCount = max(maxLineCount, static_cast<RenderBlock*>(child)->lineCount());
+ maxLineCount = max(maxLineCount, toRenderBlock(child)->lineCount());
}
child = iterator.next();
}
@@ -738,7 +732,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow())
continue;
- RenderBlock* blockChild = static_cast<RenderBlock*>(child);
+ RenderBlock* blockChild = toRenderBlock(child);
int lineCount = blockChild->lineCount();
if (lineCount <= numVisibleLines)
continue;
@@ -767,9 +761,9 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
InlineBox* anchorBox = lastLine->lastChild();
if (!anchorBox)
continue;
- if (!anchorBox->object()->element())
+ if (!anchorBox->renderer()->node())
continue;
- if (!anchorBox->object()->element()->isLink())
+ if (!anchorBox->renderer()->node()->isLink())
continue;
RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1);
@@ -786,8 +780,8 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
int totalWidth = ellipsisAndSpaceWidth + anchorBox->width();
// See if this width can be accommodated on the last visible line
- RenderBlock* destBlock = static_cast<RenderBlock*>(lastVisibleLine->object());
- RenderBlock* srcBlock = static_cast<RenderBlock*>(lastLine->object());
+ RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());
+ RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());
// FIXME: Directions of src/destBlock could be different from our direction and from one another.
if (srcBlock->style()->direction() != LTR)
@@ -795,9 +789,9 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (destBlock->style()->direction() != LTR)
continue;
- int blockEdge = destBlock->rightOffset(lastVisibleLine->yPos());
+ int blockEdge = destBlock->rightOffset(lastVisibleLine->y(), false);
if (!lastVisibleLine->canAccommodateEllipsis(true, blockEdge,
- lastVisibleLine->xPos() + lastVisibleLine->width(),
+ lastVisibleLine->x() + lastVisibleLine->width(),
totalWidth))
continue;
@@ -826,14 +820,14 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (child->isPositioned())
{
child->containingBlock()->insertPositionedObject(child);
- if (child->hasStaticX()) {
+ if (child->style()->hasStaticX()) {
if (style()->direction() == LTR)
- child->setStaticX(borderLeft()+paddingLeft());
+ child->layer()->setStaticX(borderLeft()+paddingLeft());
else
- child->setStaticX(borderRight()+paddingRight());
+ child->layer()->setStaticX(borderRight()+paddingRight());
}
- if (child->hasStaticY())
- child->setStaticY(height());
+ if (child->style()->hasStaticY())
+ child->layer()->setStaticY(height());
child = iterator.next();
continue;
}
@@ -873,7 +867,7 @@ void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren)
setHeight(height() + child->height() + child->marginBottom());
if (child->isRenderBlock())
- static_cast<RenderBlock*>(child)->addVisualOverflow(static_cast<RenderBlock*>(child)->floatRect());
+ toRenderBlock(child)->addVisualOverflow(toRenderBlock(child)->floatRect());
// See if this child has made our overflow need to grow.
m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth);
diff --git a/WebCore/rendering/RenderFlow.cpp b/WebCore/rendering/RenderFlow.cpp
deleted file mode 100644
index 94ec124..0000000
--- a/WebCore/rendering/RenderFlow.cpp
+++ /dev/null
@@ -1,744 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "RenderFlow.h"
-
-#include "Document.h"
-#include "GraphicsContext.h"
-#include "HTMLNames.h"
-#include "InlineTextBox.h"
-#include "RenderArena.h"
-#include "RenderInline.h"
-#include "RenderLayer.h"
-#include "RenderView.h"
-
-using namespace std;
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-#ifndef NDEBUG
-
-RenderFlow::~RenderFlow()
-{
- ASSERT(!m_firstLineBox);
- ASSERT(!m_lastLineBox);
-}
-
-#endif
-
-RenderFlow* RenderFlow::createAnonymousFlow(Document* doc, PassRefPtr<RenderStyle> style)
-{
- RenderFlow* result;
- if (style->display() == INLINE)
- result = new (doc->renderArena()) RenderInline(doc);
- else
- result = new (doc->renderArena()) RenderBlock(doc);
- result->setStyle(style);
- return result;
-}
-
-RenderFlow* RenderFlow::continuationBefore(RenderObject* beforeChild)
-{
- if (beforeChild && beforeChild->parent() == this)
- return this;
-
- RenderFlow* curr = continuation();
- RenderFlow* nextToLast = this;
- RenderFlow* last = this;
- while (curr) {
- if (beforeChild && beforeChild->parent() == curr) {
- if (curr->firstChild() == beforeChild)
- return last;
- return curr;
- }
-
- nextToLast = last;
- last = curr;
- curr = curr->continuation();
- }
-
- if (!beforeChild && !last->firstChild())
- return nextToLast;
- return last;
-}
-
-void RenderFlow::addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild)
-{
- if (beforeChild && (beforeChild->parent()->isTableRow() || beforeChild->parent()->isTableSection() || beforeChild->parent()->isTable())) {
- RenderObject* anonymousTablePart = beforeChild->parent();
- ASSERT(anonymousTablePart->isAnonymous());
- while (!anonymousTablePart->isTable()) {
- anonymousTablePart = anonymousTablePart->parent();
- ASSERT(anonymousTablePart->isAnonymous());
- }
- return anonymousTablePart->addChild(newChild, beforeChild);
- }
-
- RenderFlow* flow = continuationBefore(beforeChild);
- ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() ||
- beforeChild->parent()->isRenderInline());
- RenderFlow* beforeChildParent = beforeChild ? static_cast<RenderFlow*>(beforeChild->parent()) :
- (flow->continuation() ? flow->continuation() : flow);
-
- if (newChild->isFloatingOrPositioned())
- return beforeChildParent->addChildToFlow(newChild, beforeChild);
-
- // A continuation always consists of two potential candidates: an inline or an anonymous
- // block box holding block children.
- bool childInline = newChild->isInline();
- bool bcpInline = beforeChildParent->isInline();
- bool flowInline = flow->isInline();
-
- if (flow == beforeChildParent)
- return flow->addChildToFlow(newChild, beforeChild);
- else {
- // The goal here is to match up if we can, so that we can coalesce and create the
- // minimal # of continuations needed for the inline.
- if (childInline == bcpInline)
- return beforeChildParent->addChildToFlow(newChild, beforeChild);
- else if (flowInline == childInline)
- return flow->addChildToFlow(newChild, 0); // Just treat like an append.
- else
- return beforeChildParent->addChildToFlow(newChild, beforeChild);
- }
-}
-
-void RenderFlow::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
- if (continuation())
- return addChildWithContinuation(newChild, beforeChild);
- return addChildToFlow(newChild, beforeChild);
-}
-
-void RenderFlow::extractLineBox(InlineFlowBox* box)
-{
- checkConsistency();
-
- m_lastLineBox = box->prevFlowBox();
- if (box == m_firstLineBox)
- m_firstLineBox = 0;
- if (box->prevLineBox())
- box->prevLineBox()->setNextLineBox(0);
- box->setPreviousLineBox(0);
- for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
- curr->setExtracted();
-
- checkConsistency();
-}
-
-void RenderFlow::attachLineBox(InlineFlowBox* box)
-{
- checkConsistency();
-
- if (m_lastLineBox) {
- m_lastLineBox->setNextLineBox(box);
- box->setPreviousLineBox(m_lastLineBox);
- } else
- m_firstLineBox = box;
- InlineFlowBox* last = box;
- for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) {
- curr->setExtracted(false);
- last = curr;
- }
- m_lastLineBox = last;
-
- checkConsistency();
-}
-
-void RenderFlow::removeLineBox(InlineFlowBox* box)
-{
- checkConsistency();
-
- if (box == m_firstLineBox)
- m_firstLineBox = box->nextFlowBox();
- if (box == m_lastLineBox)
- m_lastLineBox = box->prevFlowBox();
- if (box->nextLineBox())
- box->nextLineBox()->setPreviousLineBox(box->prevLineBox());
- if (box->prevLineBox())
- box->prevLineBox()->setNextLineBox(box->nextLineBox());
-
- checkConsistency();
-}
-
-void RenderFlow::deleteLineBoxes()
-{
- if (m_firstLineBox) {
- RenderArena* arena = renderArena();
- InlineRunBox* next;
- for (InlineRunBox* curr = m_firstLineBox; curr; curr = next) {
- next = curr->nextLineBox();
- curr->destroy(arena);
- }
- m_firstLineBox = 0;
- m_lastLineBox = 0;
- }
-}
-
-void RenderFlow::destroy()
-{
- // Detach our continuation first.
- if (m_continuation)
- m_continuation->destroy();
- m_continuation = 0;
-
- // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
- // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
- RenderContainer::destroyLeftoverChildren();
-
- if (!documentBeingDestroyed()) {
- if (m_firstLineBox) {
- // We can't wait for RenderContainer::destroy to clear the selection,
- // because by then we will have nuked the line boxes.
- // FIXME: The SelectionController should be responsible for this when it
- // is notified of DOM mutations.
- if (isSelectionBorder())
- view()->clearSelection();
-
- // If line boxes are contained inside a root, that means we're an inline.
- // In that case, we need to remove all the line boxes so that the parent
- // lines aren't pointing to deleted children. If the first line box does
- // not have a parent that means they are either already disconnected or
- // root lines that can just be destroyed without disconnecting.
- if (m_firstLineBox->parent()) {
- for (InlineRunBox* box = m_firstLineBox; box; box = box->nextLineBox())
- box->remove();
- }
-
- // If we are an anonymous block, then our line boxes might have children
- // that will outlast this block. In the non-anonymous block case those
- // children will be destroyed by the time we return from this function.
- if (isAnonymousBlock()) {
- for (InlineFlowBox* box = m_firstLineBox; box; box = box->nextFlowBox()) {
- while (InlineBox* childBox = box->firstChild())
- childBox->remove();
- }
- }
- } else if (isInline() && parent())
- parent()->dirtyLinesFromChangedChild(this);
- }
-
- deleteLineBoxes();
-
- RenderContainer::destroy();
-}
-
-void RenderFlow::dirtyLinesFromChangedChild(RenderObject* child)
-{
- if (!parent() || (selfNeedsLayout() && !isRenderInline()) || isTable())
- return;
-
- // If we have no first line box, then just bail early.
- if (!firstLineBox()) {
- // For an empty inline, go ahead and propagate the check up to our parent, unless the parent
- // is already dirty.
- if (isInline() && !parent()->selfNeedsLayout())
- parent()->dirtyLinesFromChangedChild(this);
- return;
- }
-
- // Try to figure out which line box we belong in. First try to find a previous
- // line box by examining our siblings. If we didn't find a line box, then use our
- // parent's first line box.
- RootInlineBox* box = 0;
- RenderObject* curr = 0;
- for (curr = child->previousSibling(); curr; curr = curr->previousSibling()) {
- if (curr->isFloatingOrPositioned())
- continue;
-
- if (curr->isReplaced()) {
- InlineBox* wrapper = curr->inlineBoxWrapper();
- if (wrapper)
- box = wrapper->root();
- } else if (curr->isText()) {
- InlineTextBox* textBox = toRenderText(curr)->lastTextBox();
- if (textBox)
- box = textBox->root();
- } else if (curr->isRenderInline()) {
- InlineRunBox* runBox = static_cast<RenderFlow*>(curr)->lastLineBox();
- if (runBox)
- box = runBox->root();
- }
-
- if (box)
- break;
- }
- if (!box)
- box = firstLineBox()->root();
-
- // If we found a line box, then dirty it.
- if (box) {
- RootInlineBox* adjacentBox;
- box->markDirty();
-
- // dirty the adjacent lines that might be affected
- // NOTE: we dirty the previous line because RootInlineBox objects cache
- // the address of the first object on the next line after a BR, which we may be
- // invalidating here. For more info, see how RenderBlock::layoutInlineChildren
- // calls setLineBreakInfo with the result of findNextLineBreak. findNextLineBreak,
- // despite the name, actually returns the first RenderObject after the BR.
- // <rdar://problem/3849947> "Typing after pasting line does not appear until after window resize."
- adjacentBox = box->prevRootBox();
- if (adjacentBox)
- adjacentBox->markDirty();
- if (child->isBR() || (curr && curr->isBR())) {
- adjacentBox = box->nextRootBox();
- if (adjacentBox)
- adjacentBox->markDirty();
- }
- }
-}
-
-int RenderFlow::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
-{
- if (firstLine && document()->usesFirstLineRules()) {
- RenderStyle* s = style(firstLine);
- Length lh = s->lineHeight();
- if (lh.isNegative()) {
- if (s == style()) {
- if (m_lineHeight == -1)
- m_lineHeight = RenderObject::lineHeight(false);
- return m_lineHeight;
- }
- return s->font().lineSpacing();
- }
- if (lh.isPercent())
- return lh.calcMinValue(s->fontSize());
- return lh.value();
- }
-
- if (m_lineHeight == -1)
- m_lineHeight = RenderObject::lineHeight(false);
- return m_lineHeight;
-}
-
-void RenderFlow::dirtyLineBoxes(bool fullLayout, bool isRootLineBox)
-{
- if (!isRootLineBox && isReplaced())
- return RenderContainer::dirtyLineBoxes(fullLayout, isRootLineBox);
-
- if (fullLayout)
- deleteLineBoxes();
- else {
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
- curr->dirtyLineBoxes();
- }
-}
-
-InlineBox* RenderFlow::createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool /*isOnlyRun*/)
-{
- checkConsistency();
-
- if (!isRootLineBox &&
- (isReplaced() || makePlaceHolderBox)) // Inline tables and inline blocks
- return RenderContainer::createInlineBox(false, isRootLineBox); // (or positioned element placeholders).
-
- InlineFlowBox* flowBox = 0;
- if (isRenderInline())
- flowBox = new (renderArena()) InlineFlowBox(this);
- else
- flowBox = new (renderArena()) RootInlineBox(this);
-
- if (!m_firstLineBox)
- m_firstLineBox = m_lastLineBox = flowBox;
- else {
- m_lastLineBox->setNextLineBox(flowBox);
- flowBox->setPreviousLineBox(m_lastLineBox);
- m_lastLineBox = flowBox;
- }
-
- checkConsistency();
-
- return flowBox;
-}
-
-void RenderFlow::paintLines(PaintInfo& paintInfo, int tx, int ty)
-{
- // Only paint during the foreground/selection phases.
- if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline
- && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
- && paintInfo.phase != PaintPhaseMask)
- return;
-
- bool inlineFlow = isRenderInline();
- if (inlineFlow)
- ASSERT(m_layer); // The only way an inline could paint like this is if it has a layer.
-
- // If we have no lines then we have no work to do.
- if (!firstLineBox())
- return;
-
- // We can check the first box and last box and avoid painting if we don't
- // intersect. This is a quick short-circuit that we can take to avoid walking any lines.
- // FIXME: This check is flawed in the following extremely obscure way:
- // if some line in the middle has a huge overflow, it might actually extend below the last line.
- int yPos = firstLineBox()->root()->topOverflow() - maximalOutlineSize(paintInfo.phase);
- int h = maximalOutlineSize(paintInfo.phase) + lastLineBox()->root()->bottomOverflow() - yPos;
- yPos += ty;
- if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
- return;
-
- PaintInfo info(paintInfo);
- ListHashSet<RenderFlow*> outlineObjects;
- info.outlineObjects = &outlineObjects;
-
- // See if our root lines intersect with the dirty rect. If so, then we paint
- // them. Note that boxes can easily overlap, so we can't make any assumptions
- // based off positions of our first line box or our last line box.
- RenderView* v = view();
- bool usePrintRect = !v->printRect().isEmpty();
- for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) {
- if (usePrintRect) {
- // FIXME: This is a feeble effort to avoid splitting a line across two pages.
- // It is utterly inadequate, and this should not be done at paint time at all.
- // The whole way objects break across pages needs to be redone.
- // Try to avoid splitting a line vertically, but only if it's less than the height
- // of the entire page.
- if (curr->root()->bottomOverflow() - curr->root()->topOverflow() <= v->printRect().height()) {
- if (ty + curr->root()->bottomOverflow() > v->printRect().bottom()) {
- if (ty + curr->root()->topOverflow() < v->truncatedAt())
- v->setBestTruncatedAt(ty + curr->root()->topOverflow(), this);
- // If we were able to truncate, don't paint.
- if (ty + curr->root()->topOverflow() >= v->truncatedAt())
- break;
- }
- }
- }
-
- int top = min(curr->root()->topOverflow(), curr->root()->selectionTop()) - maximalOutlineSize(info.phase);
- int bottom = curr->root()->bottomOverflow() + maximalOutlineSize(info.phase);
- h = bottom - top;
- yPos = ty + top;
- if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
- curr->paint(info, tx, ty);
- }
-
- if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline || info.phase == PaintPhaseChildOutlines) {
- ListHashSet<RenderFlow*>::iterator end = info.outlineObjects->end();
- for (ListHashSet<RenderFlow*>::iterator it = info.outlineObjects->begin(); it != end; ++it) {
- RenderFlow* flow = *it;
- flow->paintOutline(info.context, tx, ty);
- }
- info.outlineObjects->clear();
- }
-}
-
-bool RenderFlow::hitTestLines(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
-{
- if (hitTestAction != HitTestForeground)
- return false;
-
- bool inlineFlow = isRenderInline();
- if (inlineFlow)
- ASSERT(m_layer); // The only way an inline can hit test like this is if it has a layer.
-
- // If we have no lines then we have no work to do.
- if (!firstLineBox())
- return false;
-
- // We can check the first box and last box and avoid hit testing if we don't
- // contain the point. This is a quick short-circuit that we can take to avoid walking any lines.
- // FIXME: This check is flawed in the following extremely obscure way:
- // if some line in the middle has a huge overflow, it might actually extend below the last line.
- if ((y >= ty + lastLineBox()->root()->bottomOverflow()) || (y < ty + firstLineBox()->root()->topOverflow()))
- return false;
-
- // See if our root lines contain the point. If so, then we hit test
- // them further. Note that boxes can easily overlap, so we can't make any assumptions
- // based off positions of our first line box or our last line box.
- for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) {
- if (y >= ty + curr->root()->topOverflow() && y < ty + curr->root()->bottomOverflow()) {
- bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
- if (inside) {
- updateHitTestResult(result, IntPoint(x - tx, y - ty));
- return true;
- }
- }
- }
-
- return false;
-}
-
-IntRect RenderFlow::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
-{
- // Do the normal calculation in most cases.
- if (firstChild() || style()->display() == INLINE)
- return RenderContainer::localCaretRect(inlineBox, caretOffset, extraWidthToEndOfLine);
-
- // This is a special case:
- // The element is not an inline element, and it's empty. So we have to
- // calculate a fake position to indicate where objects are to be inserted.
-
- // FIXME: This does not take into account either :first-line or :first-letter
- // However, as soon as some content is entered, the line boxes will be
- // constructed and this kludge is not called any more. So only the caret size
- // of an empty :first-line'd block is wrong. I think we can live with that.
- RenderStyle* currentStyle = firstLineStyle();
- int height = lineHeight(true);
- const int caretWidth = 1;
-
- enum CaretAlignment { alignLeft, alignRight, alignCenter };
-
- CaretAlignment alignment = alignLeft;
-
- switch (currentStyle->textAlign()) {
- case TAAUTO:
- case JUSTIFY:
- if (currentStyle->direction() == RTL)
- alignment = alignRight;
- break;
- case LEFT:
- case WEBKIT_LEFT:
- break;
- case CENTER:
- case WEBKIT_CENTER:
- alignment = alignCenter;
- break;
- case RIGHT:
- case WEBKIT_RIGHT:
- alignment = alignRight;
- break;
- }
-
- int x = borderLeft() + paddingLeft();
- int w = width();
-
- switch (alignment) {
- case alignLeft:
- break;
- case alignCenter:
- x = (x + w - (borderRight() + paddingRight())) / 2;
- break;
- case alignRight:
- x = w - (borderRight() + paddingRight());
- break;
- }
-
- if (extraWidthToEndOfLine) {
- if (isRenderBlock()) {
- *extraWidthToEndOfLine = w - (x + caretWidth);
- } else {
- // FIXME: This code looks wrong.
- // myRight and containerRight are set up, but then clobbered.
- // So *extraWidthToEndOfLine will always be 0 here.
-
- int myRight = x + caretWidth;
- // FIXME: why call localToAbsoluteForContent() twice here, too?
- FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
-
- int containerRight = containingBlock()->x() + containingBlockWidth();
- FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
-
- *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
- }
- }
-
- int y = paddingTop() + borderTop();
-
- return IntRect(x, y, caretWidth, height);
-}
-
-void RenderFlow::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
-{
- if (isRenderBlock()) {
- // Continuations should include their margins in the outline rect.
- if (continuation()) {
- bool nextInlineHasLineBox = continuation()->firstLineBox();
- bool prevInlineHasLineBox = static_cast<RenderFlow*>(continuation()->element()->renderer())->firstLineBox();
- int topMargin = prevInlineHasLineBox ? collapsedMarginTop() : 0;
- int bottomMargin = nextInlineHasLineBox ? collapsedMarginBottom() : 0;
- graphicsContext->addFocusRingRect(IntRect(tx, ty - topMargin,
- width(), height() + topMargin + bottomMargin));
- } else
- graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
- }
-
- if (!hasOverflowClip() && !hasControlClip()) {
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
- graphicsContext->addFocusRingRect(IntRect(tx + curr->xPos(), ty + curr->yPos(), curr->width(), curr->height()));
-
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
- if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
- RenderBox* box = toRenderBox(curr);
- FloatPoint pos;
- // FIXME: This doesn't work correctly with transforms.
- if (box->layer())
- pos = curr->localToAbsolute();
- else
- pos = FloatPoint(tx + box->x(), ty + box->y());
- box->addFocusRingRects(graphicsContext, pos.x(), pos.y());
- }
- }
-
- if (continuation()) {
- if (isInline())
- continuation()->addFocusRingRects(graphicsContext,
- tx - containingBlock()->x() + continuation()->x(),
- ty - containingBlock()->y() + continuation()->y());
- else
- continuation()->addFocusRingRects(graphicsContext,
- tx - x() + continuation()->containingBlock()->x(),
- ty - y() + continuation()->containingBlock()->y());
- }
-}
-
-void RenderFlow::paintOutline(GraphicsContext* graphicsContext, int tx, int ty)
-{
- if (!hasOutline())
- return;
-
- if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) {
- int ow = style()->outlineWidth();
- Color oc = style()->outlineColor();
- if (!oc.isValid())
- oc = style()->color();
-
- graphicsContext->initFocusRing(ow, style()->outlineOffset());
- addFocusRingRects(graphicsContext, tx, ty);
- if (style()->outlineStyleIsAuto())
- graphicsContext->drawFocusRing(oc);
- else
- addPDFURLRect(graphicsContext, graphicsContext->focusRingBoundingRect());
- graphicsContext->clearFocusRing();
- }
-
- if (style()->outlineStyleIsAuto() || style()->outlineStyle() == BNONE)
- return;
-
- Vector<IntRect> rects;
-
- rects.append(IntRect());
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
- rects.append(IntRect(curr->xPos(), curr->yPos(), curr->width(), curr->height()));
-
- rects.append(IntRect());
-
- for (unsigned i = 1; i < rects.size() - 1; i++)
- paintOutlineForLine(graphicsContext, tx, ty, rects.at(i - 1), rects.at(i), rects.at(i + 1));
-}
-
-void RenderFlow::paintOutlineForLine(GraphicsContext* graphicsContext, int tx, int ty,
- const IntRect& lastline, const IntRect& thisline, const IntRect& nextline)
-{
- int ow = style()->outlineWidth();
- EBorderStyle os = style()->outlineStyle();
- Color oc = style()->outlineColor();
- if (!oc.isValid())
- oc = style()->color();
-
- int offset = style()->outlineOffset();
-
- int t = ty + thisline.y() - offset;
- int l = tx + thisline.x() - offset;
- int b = ty + thisline.bottom() + offset;
- int r = tx + thisline.right() + offset;
-
- // left edge
- drawBorder(graphicsContext,
- l - ow,
- t - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : 0),
- l,
- b + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : 0),
- BSLeft,
- oc, style()->color(), os,
- (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : -ow),
- (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : -ow));
-
- // right edge
- drawBorder(graphicsContext,
- r,
- t - (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : 0),
- r + ow,
- b + (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : 0),
- BSRight,
- oc, style()->color(), os,
- (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : -ow),
- (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : -ow));
- // upper edge
- if (thisline.x() < lastline.x())
- drawBorder(graphicsContext,
- l - ow,
- t - ow,
- min(r+ow, (lastline.isEmpty() ? 1000000 : tx + lastline.x())),
- t ,
- BSTop, oc, style()->color(), os,
- ow,
- (!lastline.isEmpty() && tx + lastline.x() + 1 < r + ow) ? -ow : ow);
-
- if (lastline.right() < thisline.right())
- drawBorder(graphicsContext,
- max(lastline.isEmpty() ? -1000000 : tx + lastline.right(), l - ow),
- t - ow,
- r + ow,
- t ,
- BSTop, oc, style()->color(), os,
- (!lastline.isEmpty() && l - ow < tx + lastline.right()) ? -ow : ow,
- ow);
-
- // lower edge
- if (thisline.x() < nextline.x())
- drawBorder(graphicsContext,
- l - ow,
- b,
- min(r + ow, !nextline.isEmpty() ? tx + nextline.x() + 1 : 1000000),
- b + ow,
- BSBottom, oc, style()->color(), os,
- ow,
- (!nextline.isEmpty() && tx + nextline.x() + 1 < r + ow) ? -ow : ow);
-
- if (nextline.right() < thisline.right())
- drawBorder(graphicsContext,
- max(!nextline.isEmpty() ? tx + nextline.right() : -1000000, l - ow),
- b,
- r + ow,
- b + ow,
- BSBottom, oc, style()->color(), os,
- (!nextline.isEmpty() && l - ow < tx + nextline.right()) ? -ow : ow,
- ow);
-}
-
-void RenderFlow::calcMargins(int containerWidth)
-{
- m_marginLeft = style()->marginLeft().calcMinValue(containerWidth);
- m_marginRight = style()->marginRight().calcMinValue(containerWidth);
-}
-
-#ifndef NDEBUG
-
-void RenderFlow::checkConsistency() const
-{
-#ifdef CHECK_CONSISTENCY
- const InlineFlowBox* prev = 0;
- for (const InlineFlowBox* child = m_firstLineBox; child != 0; child = child->nextFlowBox()) {
- ASSERT(child->object() == this);
- ASSERT(child->prevFlowBox() == prev);
- prev = child;
- }
- ASSERT(prev == m_lastLineBox);
-#endif
-}
-
-#endif
-
-} // namespace WebCore
diff --git a/WebCore/rendering/RenderFlow.h b/WebCore/rendering/RenderFlow.h
deleted file mode 100644
index 897e40a..0000000
--- a/WebCore/rendering/RenderFlow.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef RenderFlow_h
-#define RenderFlow_h
-
-#include "RenderContainer.h"
-
-namespace WebCore {
-
-/**
- * all geometry managing stuff is only in the block elements.
- *
- * Inline elements don't layout themselves, but the whole paragraph
- * gets flowed by the surrounding block element. This is, because
- * one needs to know the whole paragraph to calculate bidirectional
- * behaviour of text, so putting the layouting routines in the inline
- * elements is impossible.
- */
-class RenderFlow : public RenderContainer {
-public:
- RenderFlow(Node* node)
- : RenderContainer(node)
- , m_continuation(0)
- , m_firstLineBox(0)
- , m_lastLineBox(0)
- , m_lineHeight(-1)
- , m_childrenInline(true)
- , m_firstLine(false)
- , m_topMarginQuirk(false)
- , m_bottomMarginQuirk(false)
- , m_hasMarkupTruncation(false)
- , m_selectionState(SelectionNone)
- , m_hasColumns(false)
- , m_isContinuation(false)
- , m_cellWidthChanged(false)
- {
- }
-#ifndef NDEBUG
- virtual ~RenderFlow();
-#endif
-
- virtual RenderFlow* virtualContinuation() const { return continuation(); }
- RenderFlow* continuation() const { return m_continuation; }
- void setContinuation(RenderFlow* c) { m_continuation = c; }
- RenderFlow* continuationBefore(RenderObject* beforeChild);
-
- void addChildWithContinuation(RenderObject* newChild, RenderObject* beforeChild);
- virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild) = 0;
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
-
- static RenderFlow* createAnonymousFlow(Document*, PassRefPtr<RenderStyle>);
-
- void extractLineBox(InlineFlowBox*);
- void attachLineBox(InlineFlowBox*);
- void removeLineBox(InlineFlowBox*);
- void deleteLineBoxes();
- virtual void destroy();
-
- virtual void dirtyLinesFromChangedChild(RenderObject* child);
-
- virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
-
- InlineFlowBox* firstLineBox() const { return m_firstLineBox; }
- InlineFlowBox* lastLineBox() const { return m_lastLineBox; }
-
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun=false);
- virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false);
-
- void paintLines(PaintInfo&, int tx, int ty);
- bool hitTestLines(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
-
- virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
-
- virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
- void paintOutlineForLine(GraphicsContext*, int tx, int ty, const IntRect& prevLine, const IntRect& thisLine, const IntRect& nextLine);
- void paintOutline(GraphicsContext*, int tx, int ty);
-
- virtual bool hasColumns() const { return m_hasColumns; }
-
- void calcMargins(int containerWidth);
-
- void checkConsistency() const;
-
-private:
- // An inline can be split with blocks occurring in between the inline content.
- // When this occurs we need a pointer to our next object. We can basically be
- // split into a sequence of inlines and blocks. The continuation will either be
- // an anonymous block (that houses other blocks) or it will be an inline flow.
- RenderFlow* m_continuation;
-
-protected:
- // For block flows, each box represents the root inline box for a line in the
- // paragraph.
- // For inline flows, each box represents a portion of that inline.
- InlineFlowBox* m_firstLineBox;
- InlineFlowBox* m_lastLineBox;
-
- mutable int m_lineHeight;
-
- // These bitfields are moved here from subclasses to pack them together
- // from RenderBlock
- bool m_childrenInline : 1;
- bool m_firstLine : 1;
- bool m_topMarginQuirk : 1;
- bool m_bottomMarginQuirk : 1;
- bool m_hasMarkupTruncation : 1;
- unsigned m_selectionState : 3; // SelectionState
- bool m_hasColumns : 1;
-
- // from RenderInline
- bool m_isContinuation : 1; // Whether or not we're a continuation of an inline.
-
- // from RenderTableCell
- bool m_cellWidthChanged : 1;
-};
-
-#ifdef NDEBUG
-inline void RenderFlow::checkConsistency() const
-{
-}
-#endif
-
-} // namespace WebCore
-
-#endif // RenderFlow_h
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index 523601c..0584c1c 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -40,7 +40,7 @@ RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
TransformationMatrix RenderForeignObject::translationForAttributes()
{
- SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(element());
+ SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
return TransformationMatrix().translate(foreign->x().value(foreign), foreign->y().value(foreign));
}
@@ -53,7 +53,7 @@ void RenderForeignObject::paint(PaintInfo& paintInfo, int parentX, int parentY)
paintInfo.context->concatCTM(TransformationMatrix().translate(parentX, parentY));
paintInfo.context->concatCTM(localTransform());
paintInfo.context->concatCTM(translationForAttributes());
- paintInfo.context->clip(getClipRect(parentX, parentY));
+ paintInfo.context->clip(clipRect(parentX, parentY));
float opacity = style()->opacity();
if (opacity < 1.0f)
@@ -70,18 +70,18 @@ void RenderForeignObject::paint(PaintInfo& paintInfo, int parentX, int parentY)
paintInfo.context->restore();
}
-void RenderForeignObject::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer, bool fixed)
+void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
{
TransformationMatrix transform = translationForAttributes() * localTransform();
rect = transform.mapRect(rect);
- RenderBlock::computeRectForRepaint(rect, repaintContainer, fixed);
+ RenderBlock::computeRectForRepaint(repaintContainer, rect, fixed);
}
bool RenderForeignObject::calculateLocalTransform()
{
TransformationMatrix oldTransform = m_localTransform;
- m_localTransform = static_cast<SVGForeignObjectElement*>(element())->animatedLocalTransform();
+ m_localTransform = static_cast<SVGForeignObjectElement*>(node())->animatedLocalTransform();
return (oldTransform != m_localTransform);
}
@@ -92,13 +92,8 @@ void RenderForeignObject::layout()
// Arbitrary affine transforms are incompatible with LayoutState.
view()->disableLayoutState();
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = m_absoluteBounds;
- oldOutlineBox = absoluteOutlineBounds();
- }
+ // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout(), &m_absoluteBounds);
calculateLocalTransform();
@@ -106,8 +101,7 @@ void RenderForeignObject::layout()
m_absoluteBounds = absoluteClippedOverflowRect();
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ repainter.repaintAfterLayout();
view()->enableLayoutState();
setNeedsLayout(false);
@@ -118,7 +112,7 @@ bool RenderForeignObject::nodeAtPoint(const HitTestRequest& request, HitTestResu
TransformationMatrix totalTransform = absoluteTransform();
totalTransform *= translationForAttributes();
double localX, localY;
- totalTransform.inverse().map(x, y, &localX, &localY);
+ totalTransform.inverse().map(x, y, localX, localY);
return RenderBlock::nodeAtPoint(request, result, static_cast<int>(localX), static_cast<int>(localY), tx, ty, hitTestAction);
}
diff --git a/WebCore/rendering/RenderForeignObject.h b/WebCore/rendering/RenderForeignObject.h
index 28f4ddb..ab96785 100644
--- a/WebCore/rendering/RenderForeignObject.h
+++ b/WebCore/rendering/RenderForeignObject.h
@@ -42,7 +42,7 @@ public:
virtual TransformationMatrix localTransform() const { return m_localTransform; }
virtual bool calculateLocalTransform();
- virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
virtual bool requiresLayer() const { return false; }
virtual void layout();
diff --git a/WebCore/rendering/RenderFrame.h b/WebCore/rendering/RenderFrame.h
index d7c8c5a..9050077 100644
--- a/WebCore/rendering/RenderFrame.h
+++ b/WebCore/rendering/RenderFrame.h
@@ -41,7 +41,7 @@ public:
#ifdef FLATTEN_FRAMESET
virtual void layout();
#endif
- HTMLFrameElement* element() const { return static_cast<HTMLFrameElement*>(RenderPart::element()); }
+ HTMLFrameElement* element() const { return static_cast<HTMLFrameElement*>(RenderPart::node()); }
FrameEdgeInfo edgeInfo() const;
diff --git a/WebCore/rendering/RenderFrameSet.cpp b/WebCore/rendering/RenderFrameSet.cpp
index f6cd4df..0353bb1 100644
--- a/WebCore/rendering/RenderFrameSet.cpp
+++ b/WebCore/rendering/RenderFrameSet.cpp
@@ -42,7 +42,7 @@
namespace WebCore {
RenderFrameSet::RenderFrameSet(HTMLFrameSetElement* frameSet)
- : RenderContainer(frameSet)
+ : RenderBox(frameSet)
, m_isResizing(false)
, m_isChildResizing(false)
#ifdef FLATTEN_FRAMESET
@@ -164,11 +164,11 @@ bool RenderFrameSet::nodeAtPoint(const HitTestRequest& request, HitTestResult& r
if (action != HitTestForeground)
return false;
- bool inside = RenderContainer::nodeAtPoint(request, result, x, y, tx, ty, action)
- || m_isResizing || canResize(IntPoint(x, y));
+ bool inside = RenderBox::nodeAtPoint(request, result, x, y, tx, ty, action)
+ || m_isResizing;
if (inside && frameSet()->noResize()
- && !request.readonly && !result.innerNode()) {
+ && !request.readOnly() && !result.innerNode()) {
result.setInnerNode(node());
result.setInnerNonSharedNode(node());
}
@@ -498,7 +498,7 @@ void RenderFrameSet::layout()
positionFrames();
- RenderContainer::layout();
+ RenderBox::layout();
computeEdgeInfo();
@@ -668,8 +668,8 @@ bool RenderFrameSet::userResize(MouseEvent* evt)
return false;
if (evt->type() == eventNames().mousedownEvent && evt->button() == LeftButton) {
FloatPoint pos = localToAbsolute();
- startResizing(m_cols, evt->pageX() - pos.x());
- startResizing(m_rows, evt->pageY() - pos.y());
+ startResizing(m_cols, evt->absoluteLocation().x() - pos.x());
+ startResizing(m_rows, evt->absoluteLocation().y() - pos.y());
if (m_cols.m_splitBeingResized != noSplit || m_rows.m_splitBeingResized != noSplit) {
setIsResizing(true);
return true;
@@ -678,8 +678,8 @@ bool RenderFrameSet::userResize(MouseEvent* evt)
} else {
if (evt->type() == eventNames().mousemoveEvent || (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton)) {
FloatPoint pos = localToAbsolute();
- continueResizing(m_cols, evt->pageX() - pos.x());
- continueResizing(m_rows, evt->pageY() - pos.y());
+ continueResizing(m_cols, evt->absoluteLocation().x() - pos.x());
+ continueResizing(m_rows, evt->absoluteLocation().y() - pos.y());
if (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton) {
setIsResizing(false);
return true;
@@ -710,11 +710,6 @@ bool RenderFrameSet::isResizingColumn() const
return m_isResizing && m_cols.m_splitBeingResized != noSplit;
}
-bool RenderFrameSet::canResize(const IntPoint& p) const
-{
- return hitTestSplit(m_cols, p.x()) != noSplit || hitTestSplit(m_rows, p.y()) != noSplit;
-}
-
bool RenderFrameSet::canResizeRow(const IntPoint& p) const
{
int r = hitTestSplit(m_rows, p.y());
diff --git a/WebCore/rendering/RenderFrameSet.h b/WebCore/rendering/RenderFrameSet.h
index 066dbab..0c80ad9 100644
--- a/WebCore/rendering/RenderFrameSet.h
+++ b/WebCore/rendering/RenderFrameSet.h
@@ -23,7 +23,7 @@
#ifndef RenderFrameSet_h
#define RenderFrameSet_h
-#include "RenderContainer.h"
+#include "RenderBox.h"
namespace WebCore {
@@ -53,11 +53,16 @@ private:
Vector<bool> m_allowBorder;
};
-class RenderFrameSet : public RenderContainer {
+class RenderFrameSet : public RenderBox {
public:
RenderFrameSet(HTMLFrameSetElement*);
virtual ~RenderFrameSet();
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
virtual const char* renderName() const { return "RenderFrameSet"; }
virtual bool isFrameSet() const { return true; }
@@ -97,7 +102,6 @@ private:
inline HTMLFrameSetElement* frameSet() const;
- bool canResize(const IntPoint&) const;
void setIsResizing(bool);
void layOutAxis(GridAxis&, const Length*, int availableSpace);
@@ -114,6 +118,8 @@ private:
void paintRowBorder(const PaintInfo& paintInfo, const IntRect& rect);
void paintColumnBorder(const PaintInfo& paintInfo, const IntRect& rect);
+ RenderObjectChildList m_children;
+
GridAxis m_rows;
GridAxis m_cols;
diff --git a/WebCore/rendering/RenderHTMLCanvas.cpp b/WebCore/rendering/RenderHTMLCanvas.cpp
index f4d88d8..1fc07f0 100644
--- a/WebCore/rendering/RenderHTMLCanvas.cpp
+++ b/WebCore/rendering/RenderHTMLCanvas.cpp
@@ -31,6 +31,7 @@
#include "HTMLCanvasElement.h"
#include "HTMLNames.h"
#include "RenderView.h"
+#include "FrameView.h"
namespace WebCore {
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index e67a4ca..f48a219 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -38,6 +38,7 @@
#include "Page.h"
#include "RenderView.h"
#include <wtf/CurrentTime.h>
+#include <wtf/UnusedParam.h>
#ifdef ANDROID_LAYOUT
#include "Settings.h"
@@ -315,9 +316,32 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
repaintRect = contentBoxRect();
repaintRectangle(repaintRect);
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (hasLayer()) {
+ // Tell any potential compositing layers that the image needs updating.
+ layer()->rendererContentChanged();
+ }
+#endif
}
}
+void RenderImage::notifyFinished(CachedResource* newImage)
+{
+ if (documentBeingDestroyed())
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if ((newImage == m_cachedImage) && hasLayer()) {
+ // tell any potential compositing layers
+ // that the image is done and they can reference it directly.
+ layer()->rendererContentChanged();
+ }
+#else
+ UNUSED_PARAM(newImage);
+#endif
+}
+
void RenderImage::resetAnimation()
{
if (m_cachedImage) {
@@ -406,7 +430,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
IntSize contentSize(cWidth, cHeight);
bool useLowQualityScaling = RenderImageScaleObserver::shouldImagePaintAtLowQuality(this, contentSize);
IntRect rect(IntPoint(tx + leftBorder + leftPad, ty + topBorder + topPad), contentSize);
- HTMLImageElement* imageElt = (element() && element()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(element()) : 0;
+ HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
context->drawImage(image(cWidth, cHeight), rect, compositeOperator, useLowQualityScaling);
}
@@ -419,41 +443,44 @@ int RenderImage::minimumReplacedHeight() const
HTMLMapElement* RenderImage::imageMap()
{
- HTMLImageElement* i = element() && element()->hasTagName(imgTag) ? static_cast<HTMLImageElement*>(element()) : 0;
+ HTMLImageElement* i = node() && node()->hasTagName(imgTag) ? static_cast<HTMLImageElement*>(node()) : 0;
return i ? i->document()->getImageMap(i->useMap()) : 0;
}
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
{
- bool inside = RenderReplaced::nodeAtPoint(request, result, _x, _y, _tx, _ty, hitTestAction);
+ HitTestResult tempResult(result.point());
+ bool inside = RenderReplaced::nodeAtPoint(request, tempResult, _x, _y, _tx, _ty, hitTestAction);
- if (inside && element()) {
+ if (inside && node()) {
int tx = _tx + x();
int ty = _ty + y();
HTMLMapElement* map = imageMap();
if (map) {
// we're a client side image map
- inside = map->mapMouseEvent(_x - tx, _y - ty, IntSize(contentWidth(), contentHeight()), result);
- result.setInnerNonSharedNode(element());
+ inside = map->mapMouseEvent(_x - tx, _y - ty, IntSize(contentWidth(), contentHeight()), tempResult);
+ tempResult.setInnerNonSharedNode(node());
}
}
+ if (inside)
+ result = tempResult;
return inside;
}
void RenderImage::updateAltText()
{
- if (!element())
+ if (!node())
return;
- if (element()->hasTagName(inputTag))
- m_altText = static_cast<HTMLInputElement*>(element())->altText();
- else if (element()->hasTagName(imgTag))
- m_altText = static_cast<HTMLImageElement*>(element())->altText();
+ if (node()->hasTagName(inputTag))
+ m_altText = static_cast<HTMLInputElement*>(node())->altText();
+ else if (node()->hasTagName(imgTag))
+ m_altText = static_cast<HTMLImageElement*>(node())->altText();
#if ENABLE(WML)
- else if (element()->hasTagName(WMLNames::imgTag))
- m_altText = static_cast<WMLImageElement*>(element())->altText();
+ else if (node()->hasTagName(WMLNames::imgTag))
+ m_altText = static_cast<WMLImageElement*>(node())->altText();
#endif
}
@@ -516,7 +543,7 @@ int RenderImage::calcReplacedWidth(bool includeMaxWidth) const
width = max(minW, min(width, maxW));
// in SSR mode, we will fit the image to its container width
if (document()->settings()->layoutAlgorithm() == Settings::kLayoutSSR) {
- int cw = containingBlockWidth();
+ int cw = containingBlockWidthForContent();
if (cw && width>cw)
width = cw;
}
@@ -555,7 +582,7 @@ int RenderImage::calcReplacedHeight() const
calcReplacedWidthUsing(style()->maxWidth());
width = max(minW, min(width, maxW));
- int cw = containingBlockWidth();
+ int cw = containingBlockWidthForContent();
if (cw && width && width>cw)
height = cw * height / width; // preserve aspect ratio
}
diff --git a/WebCore/rendering/RenderImage.h b/WebCore/rendering/RenderImage.h
index 71896d6..042452f 100644
--- a/WebCore/rendering/RenderImage.h
+++ b/WebCore/rendering/RenderImage.h
@@ -48,6 +48,7 @@ public:
virtual int minimumReplacedHeight() const;
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void notifyFinished(CachedResource*);
bool setImageSizeForAltText(CachedImage* newImage = 0);
@@ -102,6 +103,21 @@ protected:
friend class RenderImageScaleObserver;
};
+inline RenderImage* toRenderImage(RenderObject* o)
+{
+ ASSERT(!o || o->isRenderImage());
+ return static_cast<RenderImage*>(o);
+}
+
+inline const RenderImage* toRenderImage(const RenderObject* o)
+{
+ ASSERT(!o || o->isRenderImage());
+ return static_cast<const RenderImage*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderImage(const RenderImage*);
+
} // namespace WebCore
#endif // RenderImage_h
diff --git a/WebCore/rendering/RenderImageGeneratedContent.h b/WebCore/rendering/RenderImageGeneratedContent.h
index cab0192..9f8330d 100644
--- a/WebCore/rendering/RenderImageGeneratedContent.h
+++ b/WebCore/rendering/RenderImageGeneratedContent.h
@@ -27,16 +27,14 @@
#define RenderImageGeneratedContent_h
#include "RenderImage.h"
+#include "StyleImage.h"
#include <wtf/RefPtr.h>
-#include "RenderStyle.h"
-
namespace WebCore {
class StyleImage;
-class RenderImageGeneratedContent : public RenderImage
-{
+class RenderImageGeneratedContent : public RenderImage {
public:
RenderImageGeneratedContent(Node*);
virtual ~RenderImageGeneratedContent();
@@ -53,12 +51,14 @@ protected:
virtual bool imageHasRelativeWidth() const { return m_styleImage->imageHasRelativeWidth(); }
virtual bool imageHasRelativeHeight() const { return m_styleImage->imageHasRelativeHeight(); }
virtual IntSize imageSize(float multiplier) const { return m_styleImage->imageSize(this, multiplier); }
- virtual WrappedImagePtr imagePtr() const { return m_styleImage->data(); }
+
+ // |m_styleImage| can be 0 if we get a callback for a background image from RenderObject::setStyle.
+ virtual WrappedImagePtr imagePtr() const { return m_styleImage ? m_styleImage->data() : 0; }
private:
RefPtr<StyleImage> m_styleImage;
};
-}
+} // namespace WebCore
-#endif
+#endif // RenderImageGeneratedContent_h
diff --git a/WebCore/rendering/RenderInline.cpp b/WebCore/rendering/RenderInline.cpp
index 4f4412d..8f98427 100644
--- a/WebCore/rendering/RenderInline.cpp
+++ b/WebCore/rendering/RenderInline.cpp
@@ -26,28 +26,94 @@
#include "RenderInline.h"
#include "FloatQuad.h"
+#include "GraphicsContext.h"
+#include "HitTestResult.h"
+#include "Page.h"
#include "RenderArena.h"
#include "RenderBlock.h"
#include "RenderView.h"
#include "VisiblePosition.h"
+#if ENABLE(DASHBOARD_SUPPORT)
+#include "Frame.h"
+#endif
+
+using namespace std;
+
namespace WebCore {
RenderInline::RenderInline(Node* node)
- : RenderFlow(node)
+ : RenderBoxModelObject(node)
+ , m_continuation(0)
+ , m_lineHeight(-1)
+ , m_verticalPosition(PositionUndefined)
{
+ setChildrenInline(true);
}
RenderInline::~RenderInline()
{
}
-void RenderInline::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderInline::destroy()
{
- RenderFlow::styleDidChange(diff, oldStyle);
+ // Detach our continuation first.
+ if (m_continuation)
+ m_continuation->destroy();
+ m_continuation = 0;
+
+ // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will
+ // properly dirty line boxes that they are removed from. Effects that do :before/:after only on hover could crash otherwise.
+ children()->destroyLeftoverChildren();
+
+ if (!documentBeingDestroyed()) {
+ if (firstLineBox()) {
+ // We can't wait for RenderBoxModelObject::destroy to clear the selection,
+ // because by then we will have nuked the line boxes.
+ // FIXME: The SelectionController should be responsible for this when it
+ // is notified of DOM mutations.
+ if (isSelectionBorder())
+ view()->clearSelection();
+
+ // If line boxes are contained inside a root, that means we're an inline.
+ // In that case, we need to remove all the line boxes so that the parent
+ // lines aren't pointing to deleted children. If the first line box does
+ // not have a parent that means they are either already disconnected or
+ // root lines that can just be destroyed without disconnecting.
+ if (firstLineBox()->parent()) {
+ for (InlineRunBox* box = firstLineBox(); box; box = box->nextLineBox())
+ box->remove();
+ }
+ } else if (isInline() && parent())
+ parent()->dirtyLinesFromChangedChild(this);
+ }
- setInline(true);
- setHasReflection(false);
+ m_lineBoxes.deleteLineBoxes(renderArena());
+
+ RenderBoxModelObject::destroy();
+}
+
+RenderInline* RenderInline::inlineContinuation() const
+{
+ if (!m_continuation || m_continuation->isInline())
+ return toRenderInline(m_continuation);
+ return toRenderBlock(m_continuation)->inlineContinuation();
+}
+
+void RenderInline::updateBoxModelInfoFromStyle()
+{
+ RenderBoxModelObject::updateBoxModelInfoFromStyle();
+
+ setInline(true); // Needed for run-ins, since run-in is considered a block display type.
+
+ // FIXME: Support transforms and reflections on inline flows someday.
+ setHasTransform(false);
+ setHasReflection(false);
+}
+
+void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderBoxModelObject::styleDidChange(diff, oldStyle);
// Ensure that all of the split inlines pick up the new style. We
// only do this if we're an inline, since we don't want to propagate
@@ -55,36 +121,27 @@ void RenderInline::styleDidChange(RenderStyle::Diff diff, const RenderStyle* old
// e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before
// and after the block share the same style, but the block doesn't
// need to pass its style on to anyone else.
- RenderFlow* currCont = continuation();
- while (currCont) {
- if (currCont->isInline()) {
- RenderFlow* nextCont = currCont->continuation();
- currCont->setContinuation(0);
- currCont->setStyle(style());
- currCont->setContinuation(nextCont);
- }
- currCont = currCont->continuation();
+ for (RenderInline* currCont = inlineContinuation(); currCont; currCont = currCont->inlineContinuation()) {
+ RenderBoxModelObject* nextCont = currCont->continuation();
+ currCont->setContinuation(0);
+ currCont->setStyle(style());
+ currCont->setContinuation(nextCont);
}
m_lineHeight = -1;
// Update pseudos for :before and :after now.
if (!isAnonymous() && document()->usesBeforeAfterRules()) {
- updateBeforeAfterContent(RenderStyle::BEFORE);
- updateBeforeAfterContent(RenderStyle::AFTER);
+ children()->updateBeforeAfterContent(this, BEFORE);
+ children()->updateBeforeAfterContent(this, AFTER);
}
}
-bool RenderInline::isInlineContinuation() const
-{
- return m_isContinuation;
-}
-
static inline bool isAfterContent(RenderObject* child)
{
if (!child)
return false;
- if (child->style()->styleType() != RenderStyle::AFTER)
+ if (child->style()->styleType() != AFTER)
return false;
// Text nodes don't have their own styles, so ignore the style on a text node.
if (child->isText() && !child->isBR())
@@ -92,7 +149,46 @@ static inline bool isAfterContent(RenderObject* child)
return true;
}
-void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild)
+void RenderInline::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+ if (continuation())
+ return addChildToContinuation(newChild, beforeChild);
+ return addChildIgnoringContinuation(newChild, beforeChild);
+}
+
+static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
+{
+ if (renderer->isInline() && !renderer->isReplaced())
+ return toRenderInline(renderer)->continuation();
+ return toRenderBlock(renderer)->inlineContinuation();
+}
+
+RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild)
+{
+ if (beforeChild && beforeChild->parent() == this)
+ return this;
+
+ RenderBoxModelObject* curr = nextContinuation(this);
+ RenderBoxModelObject* nextToLast = this;
+ RenderBoxModelObject* last = this;
+ while (curr) {
+ if (beforeChild && beforeChild->parent() == curr) {
+ if (curr->firstChild() == beforeChild)
+ return last;
+ return curr;
+ }
+
+ nextToLast = last;
+ last = curr;
+ curr = nextContinuation(curr);
+ }
+
+ if (!beforeChild && !last->firstChild())
+ return nextToLast;
+ return last;
+}
+
+void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild)
{
// Make sure we don't append things after :after-generated content if we have it.
if (!beforeChild && isAfterContent(lastChild()))
@@ -109,7 +205,7 @@ void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeCh
RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
newBox->setStyle(newStyle.release());
- RenderFlow* oldContinuation = continuation();
+ RenderBoxModelObject* oldContinuation = continuation();
setContinuation(newBox);
// Someone may have put a <p> inside a <q>, causing a split. When this happens, the :after content
@@ -117,7 +213,7 @@ void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeCh
// content gets properly destroyed.
bool isLastChild = (beforeChild == lastChild());
if (document()->usesBeforeAfterRules())
- updateBeforeAfterContent(RenderStyle::AFTER);
+ children()->updateBeforeAfterContent(this, AFTER);
if (isLastChild && beforeChild != lastChild())
beforeChild = 0; // We destroyed the last child, so now we need to update our insertion
// point to be 0. It's just a straight append now.
@@ -126,22 +222,21 @@ void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeCh
return;
}
- RenderContainer::addChild(newChild, beforeChild);
+ RenderBoxModelObject::addChild(newChild, beforeChild);
newChild->setNeedsLayoutAndPrefWidthsRecalc();
}
-RenderInline* RenderInline::cloneInline(RenderFlow* src)
+RenderInline* RenderInline::cloneInline(RenderInline* src)
{
- RenderInline* o = new (src->renderArena()) RenderInline(src->element());
- o->m_isContinuation = true;
+ RenderInline* o = new (src->renderArena()) RenderInline(src->node());
o->setStyle(src->style());
return o;
}
void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
RenderBlock* middleBlock,
- RenderObject* beforeChild, RenderFlow* oldCont)
+ RenderObject* beforeChild, RenderBoxModelObject* oldCont)
{
// Create a clone of this inline.
RenderInline* clone = cloneInline(this);
@@ -153,18 +248,18 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
while (o) {
RenderObject* tmp = o;
o = tmp->nextSibling();
- clone->addChildToFlow(removeChildNode(tmp), 0);
+ clone->addChildIgnoringContinuation(children()->removeChildNode(this, tmp), 0);
tmp->setNeedsLayoutAndPrefWidthsRecalc();
}
// Hook |clone| up as the continuation of the middle block.
- middleBlock->setContinuation(clone);
+ middleBlock->setInlineContinuation(clone);
// We have been reparented and are now under the fromBlock. We need
// to walk up our inline parent chain until we hit the containing block.
// Once we hit the containing block we're done.
- RenderFlow* curr = static_cast<RenderFlow*>(parent());
- RenderFlow* currChild = this;
+ RenderBoxModelObject* curr = static_cast<RenderBoxModelObject*>(parent());
+ RenderBoxModelObject* currChild = this;
// FIXME: Because splitting is O(n^2) as tags nest pathologically, we cap the depth at which we're willing to clone.
// There will eventually be a better approach to this problem that will let us nest to a much
@@ -173,24 +268,26 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
unsigned splitDepth = 1;
const unsigned cMaxSplitDepth = 200;
while (curr && curr != fromBlock) {
+ ASSERT(curr->isRenderInline());
if (splitDepth < cMaxSplitDepth) {
// Create a new clone.
RenderInline* cloneChild = clone;
- clone = cloneInline(curr);
+ clone = cloneInline(toRenderInline(curr));
// Insert our child clone as the first child.
- clone->addChildToFlow(cloneChild, 0);
+ clone->addChildIgnoringContinuation(cloneChild, 0);
// Hook the clone up as a continuation of |curr|.
- RenderFlow* oldCont = curr->continuation();
- curr->setContinuation(clone);
+ RenderInline* inlineCurr = toRenderInline(curr);
+ oldCont = inlineCurr->continuation();
+ inlineCurr->setContinuation(clone);
clone->setContinuation(oldCont);
// Someone may have indirectly caused a <q> to split. When this happens, the :after content
// has to move into the inline continuation. Call updateBeforeAfterContent to ensure that the inline's :after
// content gets properly destroyed.
if (document()->usesBeforeAfterRules())
- curr->updateBeforeAfterContent(RenderStyle::AFTER);
+ inlineCurr->children()->updateBeforeAfterContent(this, AFTER);
// Now we need to take all of the children starting from the first child
// *after* currChild and append them all to the clone.
@@ -198,19 +295,19 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
while (o) {
RenderObject* tmp = o;
o = tmp->nextSibling();
- clone->addChildToFlow(curr->removeChildNode(tmp), 0);
+ clone->addChildIgnoringContinuation(inlineCurr->children()->removeChildNode(curr, tmp), 0);
tmp->setNeedsLayoutAndPrefWidthsRecalc();
}
}
// Keep walking up the chain.
currChild = curr;
- curr = static_cast<RenderFlow*>(curr->parent());
+ curr = static_cast<RenderBoxModelObject*>(curr->parent());
splitDepth++;
}
// Now we are at the block level. We need to put the clone into the toBlock.
- toBlock->appendChildNode(clone);
+ toBlock->children()->appendChildNode(toBlock, clone);
// Now take all the children after currChild and remove them from the fromBlock
// and put them in the toBlock.
@@ -218,12 +315,12 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
while (o) {
RenderObject* tmp = o;
o = tmp->nextSibling();
- toBlock->appendChildNode(fromBlock->removeChildNode(tmp));
+ toBlock->children()->appendChildNode(toBlock, fromBlock->children()->removeChildNode(fromBlock, tmp));
}
}
void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
- RenderObject* newChild, RenderFlow* oldCont)
+ RenderObject* newChild, RenderBoxModelObject* oldCont)
{
RenderBlock* pre = 0;
RenderBlock* block = containingBlock();
@@ -235,6 +332,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
// We can reuse this block and make it the preBlock of the next continuation.
pre = block;
+ pre->removePositionedObjects(0);
block = block->containingBlock();
} else {
// No anonymous block available for use. Make one.
@@ -246,9 +344,9 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
if (madeNewBeforeBlock)
- block->insertChildNode(pre, boxFirst);
- block->insertChildNode(newBlockBox, boxFirst);
- block->insertChildNode(post, boxFirst);
+ block->children()->insertChildNode(block, pre, boxFirst);
+ block->children()->insertChildNode(block, newBlockBox, boxFirst);
+ block->children()->insertChildNode(block, post, boxFirst);
block->setChildrenInline(false);
if (madeNewBeforeBlock) {
@@ -256,7 +354,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
while (o) {
RenderObject* no = o;
o = no->nextSibling();
- pre->appendChildNode(block->removeChildNode(no));
+ pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));
no->setNeedsLayoutAndPrefWidthsRecalc();
}
}
@@ -267,12 +365,10 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
// time in makeChildrenNonInline by just setting this explicitly up front.
newBlockBox->setChildrenInline(false);
- // We don't just call addChild, since it would pass things off to the
- // continuation, so we call addChildToFlow explicitly instead. We delayed
- // adding the newChild until now so that the |newBlockBox| would be fully
+ // We delayed adding the newChild until now so that the |newBlockBox| would be fully
// connected, thus allowing newChild access to a renderArena should it need
// to wrap itself in additional boxes (e.g., table construction).
- newBlockBox->addChildToFlow(newChild, 0);
+ newBlockBox->addChild(newChild);
// Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
// get deleted properly. Because objects moves from the pre block into the post block, we want to
@@ -282,41 +378,78 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
post->setNeedsLayoutAndPrefWidthsRecalc();
}
+void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
+{
+ RenderBoxModelObject* flow = continuationBefore(beforeChild);
+ ASSERT(!beforeChild || beforeChild->parent()->isRenderBlock() || beforeChild->parent()->isRenderInline());
+ RenderBoxModelObject* beforeChildParent = 0;
+ if (beforeChild)
+ beforeChildParent = static_cast<RenderBoxModelObject*>(beforeChild->parent());
+ else {
+ RenderBoxModelObject* cont = nextContinuation(flow);
+ if (cont)
+ beforeChildParent = cont;
+ else
+ beforeChildParent = flow;
+ }
+
+ if (newChild->isFloatingOrPositioned())
+ return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+
+ // A continuation always consists of two potential candidates: an inline or an anonymous
+ // block box holding block children.
+ bool childInline = newChild->isInline();
+ bool bcpInline = beforeChildParent->isInline();
+ bool flowInline = flow->isInline();
+
+ if (flow == beforeChildParent)
+ return flow->addChildIgnoringContinuation(newChild, beforeChild);
+ else {
+ // The goal here is to match up if we can, so that we can coalesce and create the
+ // minimal # of continuations needed for the inline.
+ if (childInline == bcpInline)
+ return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+ else if (flowInline == childInline)
+ return flow->addChildIgnoringContinuation(newChild, 0); // Just treat like an append.
+ else
+ return beforeChildParent->addChildIgnoringContinuation(newChild, beforeChild);
+ }
+}
+
void RenderInline::paint(PaintInfo& paintInfo, int tx, int ty)
{
- paintLines(paintInfo, tx, ty);
+ m_lineBoxes.paint(this, paintInfo, tx, ty);
}
void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel)
{
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
- rects.append(IntRect(tx + curr->xPos(), ty + curr->yPos(), curr->width(), curr->height()));
+ if (InlineRunBox* curr = firstLineBox()) {
+ for (; curr; curr = curr->nextLineBox())
+ rects.append(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
+ } else
+ rects.append(IntRect(tx, ty, 0, 0));
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
- if (curr->isBox()) {
- RenderBox* box = toRenderBox(curr);
- curr->absoluteRects(rects, tx + box->x(), ty + box->y(), false);
- }
+ if (continuation() && topLevel) {
+ if (continuation()->isBox()) {
+ RenderBox* box = toRenderBox(continuation());
+ continuation()->absoluteRects(rects,
+ tx - containingBlock()->x() + box->x(),
+ ty - containingBlock()->y() + box->y(),
+ topLevel);
+ } else
+ continuation()->absoluteRects(rects, tx - containingBlock()->x(), ty - containingBlock()->y(), topLevel);
}
-
- if (continuation() && topLevel)
- continuation()->absoluteRects(rects,
- tx - containingBlock()->x() + continuation()->x(),
- ty - containingBlock()->y() + continuation()->y(),
- topLevel);
}
void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel)
{
- for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
- FloatRect localRect(curr->xPos(), curr->yPos(), curr->width(), curr->height());
- quads.append(localToAbsoluteQuad(localRect));
- }
-
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
- if (!curr->isText())
- curr->absoluteQuads(quads, false);
- }
+ if (InlineRunBox* curr = firstLineBox()) {
+ for (; curr; curr = curr->nextLineBox()) {
+ FloatRect localRect(curr->x(), curr->y(), curr->width(), curr->height());
+ quads.append(localToAbsoluteQuad(localRect));
+ }
+ } else
+ quads.append(localToAbsoluteQuad(FloatRect()));
if (continuation() && topLevel)
continuation()->absoluteQuads(quads, topLevel);
@@ -324,20 +457,44 @@ void RenderInline::absoluteQuads(Vector<FloatQuad>& quads, bool topLevel)
int RenderInline::offsetLeft() const
{
- int x = RenderFlow::offsetLeft();
+ int x = RenderBoxModelObject::offsetLeft();
if (firstLineBox())
- x += firstLineBox()->xPos();
+ x += firstLineBox()->x();
return x;
}
int RenderInline::offsetTop() const
{
- int y = RenderFlow::offsetTop();
+ int y = RenderBoxModelObject::offsetTop();
if (firstLineBox())
- y += firstLineBox()->yPos();
+ y += firstLineBox()->y();
return y;
}
+int RenderInline::marginLeft() const
+{
+ Length margin = style()->marginLeft();
+ if (margin.isAuto())
+ return 0;
+ if (margin.isFixed())
+ return margin.value();
+ if (margin.isPercent())
+ return margin.calcMinValue(max(0, containingBlock()->availableWidth()));
+ return 0;
+}
+
+int RenderInline::marginRight() const
+{
+ Length margin = style()->marginRight();
+ if (margin.isAuto())
+ return 0;
+ if (margin.isFixed())
+ return margin.value();
+ if (margin.isPercent())
+ return margin.calcMinValue(max(0, containingBlock()->availableWidth()));
+ return 0;
+}
+
const char* RenderInline::renderName() const
{
if (isRelPositioned())
@@ -352,24 +509,31 @@ const char* RenderInline::renderName() const
bool RenderInline::nodeAtPoint(const HitTestRequest& request, HitTestResult& result,
int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
- return hitTestLines(request, result, x, y, tx, ty, hitTestAction);
+ return m_lineBoxes.hitTest(this, request, result, x, y, tx, ty, hitTestAction);
}
-VisiblePosition RenderInline::positionForCoordinates(int x, int y)
+VisiblePosition RenderInline::positionForPoint(const IntPoint& point)
{
- // Translate the coords from the pre-anonymous block to the post-anonymous block.
+ // FIXME: Does not deal with relative positioned inlines (should it?)
RenderBlock* cb = containingBlock();
- int parentBlockX = cb->x() + x;
- int parentBlockY = cb->y() + y;
- for (RenderFlow* c = continuation(); c; c = c->continuation()) {
- RenderFlow* contBlock = c;
- if (c->isInline())
- contBlock = c->containingBlock();
+ if (firstLineBox()) {
+ // This inline actually has a line box. We must have clicked in the border/padding of one of these boxes. We
+ // should try to find a result by asking our containing block.
+ return cb->positionForPoint(point);
+ }
+
+ // Translate the coords from the pre-anonymous block to the post-anonymous block.
+ int parentBlockX = cb->x() + point.x();
+ int parentBlockY = cb->y() + point.y();
+ RenderBoxModelObject* c = continuation();
+ while (c) {
+ RenderBox* contBlock = c->isInline() ? c->containingBlock() : toRenderBlock(c);
if (c->isInline() || c->firstChild())
return c->positionForCoordinates(parentBlockX - contBlock->x(), parentBlockY - contBlock->y());
+ c = toRenderBlock(c)->inlineContinuation();
}
-
- return RenderFlow::positionForCoordinates(x, y);
+
+ return RenderBoxModelObject::positionForPoint(point);
}
IntRect RenderInline::linesBoundingBox() const
@@ -385,21 +549,21 @@ IntRect RenderInline::linesBoundingBox() const
int leftSide = 0;
int rightSide = 0;
for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
- if (curr == firstLineBox() || curr->xPos() < leftSide)
- leftSide = curr->xPos();
- if (curr == firstLineBox() || curr->xPos() + curr->width() > rightSide)
- rightSide = curr->xPos() + curr->width();
+ if (curr == firstLineBox() || curr->x() < leftSide)
+ leftSide = curr->x();
+ if (curr == firstLineBox() || curr->x() + curr->width() > rightSide)
+ rightSide = curr->x() + curr->width();
}
result.setWidth(rightSide - leftSide);
result.setX(leftSide);
- result.setHeight(lastLineBox()->yPos() + lastLineBox()->height() - firstLineBox()->yPos());
- result.setY(firstLineBox()->yPos());
+ result.setHeight(lastLineBox()->y() + lastLineBox()->height() - firstLineBox()->y());
+ result.setY(firstLineBox()->y());
}
return result;
}
-IntRect RenderInline::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// Only run-ins are allowed in here during layout.
ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn());
@@ -421,7 +585,7 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInline() && inlineFlow != cb;
inlineFlow = inlineFlow->parent()) {
if (inlineFlow->style()->position() == RelativePosition && inlineFlow->hasLayer())
- toRenderBox(inlineFlow)->layer()->relativePositionOffset(left, top);
+ toRenderInline(inlineFlow)->layer()->relativePositionOffset(left, top);
}
IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2);
@@ -439,8 +603,11 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
IntRect repaintRect(x, y, r.width(), r.height());
r = intersection(repaintRect, boxRect);
}
- ASSERT(repaintContainer != this);
- cb->computeRectForRepaint(r, repaintContainer);
+
+ // FIXME: need to ensure that we compute the correct repaint rect when the repaint container
+ // is an inline.
+ if (repaintContainer != this)
+ cb->computeRectForRepaint(repaintContainer, r);
if (ow) {
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
@@ -459,4 +626,409 @@ IntRect RenderInline::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
return r;
}
+IntRect RenderInline::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
+{
+ IntRect r(RenderBoxModelObject::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
+ for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+ if (!curr->isText())
+ r.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineWidth));
+ }
+ return r;
+}
+
+void RenderInline::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
+{
+ if (RenderView* v = view()) {
+ // LayoutState is only valid for root-relative repainting
+ if (v->layoutStateEnabled() && !repaintContainer) {
+ LayoutState* layoutState = v->layoutState();
+ if (style()->position() == RelativePosition && layer())
+ rect.move(layer()->relativePositionOffset());
+ rect.move(layoutState->m_offset);
+ if (layoutState->m_clipped)
+ rect.intersect(layoutState->m_clipRect);
+ return;
+ }
+ }
+
+ if (repaintContainer == this)
+ return;
+
+ RenderObject* o = container();
+ if (!o)
+ return;
+
+ IntPoint topLeft = rect.location();
+
+ if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {
+ RenderBlock* cb = toRenderBlock(o);
+ if (cb->hasColumns()) {
+ IntRect repaintRect(topLeft, rect.size());
+ cb->adjustRectForColumns(repaintRect);
+ topLeft = repaintRect.location();
+ rect = repaintRect;
+ }
+ }
+
+ if (style()->position() == RelativePosition && layer()) {
+ // Apply the relative position offset when invalidating a rectangle. The layer
+ // is translated, but the render box isn't, so we need to do this to get the
+ // right dirty rect. Since this is called from RenderObject::setStyle, the relative position
+ // flag on the RenderObject has been cleared, so use the one on the style().
+ topLeft += layer()->relativePositionOffset();
+ }
+
+ // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,
+ // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer.
+ if (o->hasOverflowClip()) {
+ RenderBox* containerBox = toRenderBox(o);
+
+ // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the
+ // layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
+ // anyway if its size does change.
+ topLeft -= containerBox->layer()->scrolledContentOffset(); // For overflow:auto/scroll/hidden.
+
+ IntRect repaintRect(topLeft, rect.size());
+ IntRect boxRect(0, 0, containerBox->layer()->width(), containerBox->layer()->height());
+ rect = intersection(repaintRect, boxRect);
+ if (rect.isEmpty())
+ return;
+ } else
+ rect.setLocation(topLeft);
+
+ o->computeRectForRepaint(repaintContainer, rect, fixed);
+}
+
+void RenderInline::updateDragState(bool dragOn)
+{
+ RenderBoxModelObject::updateDragState(dragOn);
+ if (continuation())
+ continuation()->updateDragState(dragOn);
+}
+
+void RenderInline::childBecameNonInline(RenderObject* child)
+{
+ // We have to split the parent flow.
+ RenderBlock* newBox = containingBlock()->createAnonymousBlock();
+ RenderBoxModelObject* oldContinuation = continuation();
+ setContinuation(newBox);
+ RenderObject* beforeChild = child->nextSibling();
+ children()->removeChildNode(this, child);
+ splitFlow(beforeChild, newBox, child, oldContinuation);
+}
+
+void RenderInline::updateHitTestResult(HitTestResult& result, const IntPoint& point)
+{
+ if (result.innerNode())
+ return;
+
+ Node* n = node();
+ IntPoint localPoint(point);
+ if (n) {
+ if (isInlineContinuation()) {
+ // We're in the continuation of a split inline. Adjust our local point to be in the coordinate space
+ // of the principal renderer's containing block. This will end up being the innerNonSharedNode.
+ RenderBlock* firstBlock = n->renderer()->containingBlock();
+
+ // Get our containing block.
+ RenderBox* block = containingBlock();
+ localPoint.move(block->x() - firstBlock->x(), block->y() - firstBlock->y());
+ }
+
+ result.setInnerNode(n);
+ if (!result.innerNonSharedNode())
+ result.setInnerNonSharedNode(n);
+ result.setLocalPoint(localPoint);
+ }
+}
+
+void RenderInline::dirtyLineBoxes(bool fullLayout)
+{
+ if (fullLayout)
+ m_lineBoxes.deleteLineBoxes(renderArena());
+ else
+ m_lineBoxes.dirtyLineBoxes();
+}
+
+InlineFlowBox* RenderInline::createFlowBox()
+{
+ return new (renderArena()) InlineFlowBox(this);
+}
+
+InlineFlowBox* RenderInline::createInlineFlowBox()
+{
+ InlineFlowBox* flowBox = createFlowBox();
+ m_lineBoxes.appendLineBox(flowBox);
+ return flowBox;
+}
+
+int RenderInline::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
+{
+ if (firstLine && document()->usesFirstLineRules()) {
+ RenderStyle* s = style(firstLine);
+ if (s != style())
+ return s->computedLineHeight();
+ }
+
+ if (m_lineHeight == -1)
+ m_lineHeight = style()->computedLineHeight();
+
+ return m_lineHeight;
+}
+
+int RenderInline::verticalPositionFromCache(bool firstLine) const
+{
+ if (firstLine) // We're only really a first-line style if the document actually uses first-line rules.
+ firstLine = document()->usesFirstLineRules();
+ int vpos = m_verticalPosition;
+ if (m_verticalPosition == PositionUndefined || firstLine) {
+ vpos = verticalPosition(firstLine);
+ if (!firstLine)
+ m_verticalPosition = vpos;
+ }
+ return vpos;
+}
+
+IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) const
+{
+ ASSERT(isRelPositioned());
+ if (!isRelPositioned())
+ return IntSize();
+
+ // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
+ // box from the rest of the content, but only in the cases where we know we're positioned
+ // relative to the inline itself.
+
+ IntSize offset;
+ int sx;
+ int sy;
+ if (firstLineBox()) {
+ sx = firstLineBox()->x();
+ sy = firstLineBox()->y();
+ } else {
+ sx = layer()->staticX();
+ sy = layer()->staticY();
+ }
+
+ if (!child->style()->hasStaticX())
+ offset.setWidth(sx);
+ // This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside
+ // an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct
+ // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
+ // do.
+ else if (!child->style()->isOriginalDisplayInlineType())
+ // Avoid adding in the left border/padding of the containing block twice. Subtract it out.
+ offset.setWidth(sx - (child->containingBlock()->borderLeft() + child->containingBlock()->paddingLeft()));
+
+ if (!child->style()->hasStaticY())
+ offset.setHeight(sy);
+
+ return offset;
+}
+
+void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
+{
+ if (!parent())
+ return;
+
+ // FIXME: We can do better.
+ repaint();
+}
+
+void RenderInline::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
+{
+ for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ graphicsContext->addFocusRingRect(IntRect(tx + curr->x(), ty + curr->y(), curr->width(), curr->height()));
+
+ for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+ if (!curr->isText() && !curr->isListMarker()) {
+ FloatPoint pos(tx, ty);
+ // FIXME: This doesn't work correctly with transforms.
+ if (curr->hasLayer())
+ pos = curr->localToAbsolute();
+ else if (curr->isBox())
+ pos.move(toRenderBox(curr)->x(), toRenderBox(curr)->y());
+ curr->addFocusRingRects(graphicsContext, pos.x(), pos.y());
+ }
+ }
+
+ if (continuation()) {
+ if (continuation()->isInline())
+ continuation()->addFocusRingRects(graphicsContext,
+ tx - containingBlock()->x() + continuation()->containingBlock()->x(),
+ ty - containingBlock()->y() + continuation()->containingBlock()->y());
+ else
+ continuation()->addFocusRingRects(graphicsContext,
+ tx - containingBlock()->x() + toRenderBox(continuation())->x(),
+ ty - containingBlock()->y() + toRenderBox(continuation())->y());
+ }
+}
+
+void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty)
+{
+ if (!hasOutline())
+ return;
+
+ if (style()->outlineStyleIsAuto() || hasOutlineAnnotation()) {
+ int ow = style()->outlineWidth();
+ Color oc = style()->outlineColor();
+ if (!oc.isValid())
+ oc = style()->color();
+
+ graphicsContext->initFocusRing(ow, style()->outlineOffset());
+ addFocusRingRects(graphicsContext, tx, ty);
+ if (style()->outlineStyleIsAuto())
+ graphicsContext->drawFocusRing(oc);
+ else
+ addPDFURLRect(graphicsContext, graphicsContext->focusRingBoundingRect());
+ graphicsContext->clearFocusRing();
+ }
+
+ if (style()->outlineStyleIsAuto() || style()->outlineStyle() == BNONE)
+ return;
+
+ Vector<IntRect> rects;
+
+ rects.append(IntRect());
+ for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ rects.append(IntRect(curr->x(), curr->y(), curr->width(), curr->height()));
+
+ rects.append(IntRect());
+
+ for (unsigned i = 1; i < rects.size() - 1; i++)
+ paintOutlineForLine(graphicsContext, tx, ty, rects.at(i - 1), rects.at(i), rects.at(i + 1));
+}
+
+void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, int tx, int ty,
+ const IntRect& lastline, const IntRect& thisline, const IntRect& nextline)
+{
+ int ow = style()->outlineWidth();
+ EBorderStyle os = style()->outlineStyle();
+ Color oc = style()->outlineColor();
+ if (!oc.isValid())
+ oc = style()->color();
+
+ int offset = style()->outlineOffset();
+
+ int t = ty + thisline.y() - offset;
+ int l = tx + thisline.x() - offset;
+ int b = ty + thisline.bottom() + offset;
+ int r = tx + thisline.right() + offset;
+
+ // left edge
+ drawLineForBoxSide(graphicsContext,
+ l - ow,
+ t - (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : 0),
+ l,
+ b + (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : 0),
+ BSLeft,
+ oc, style()->color(), os,
+ (lastline.isEmpty() || thisline.x() < lastline.x() || (lastline.right() - 1) <= thisline.x() ? ow : -ow),
+ (nextline.isEmpty() || thisline.x() <= nextline.x() || (nextline.right() - 1) <= thisline.x() ? ow : -ow));
+
+ // right edge
+ drawLineForBoxSide(graphicsContext,
+ r,
+ t - (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : 0),
+ r + ow,
+ b + (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : 0),
+ BSRight,
+ oc, style()->color(), os,
+ (lastline.isEmpty() || lastline.right() < thisline.right() || (thisline.right() - 1) <= lastline.x() ? ow : -ow),
+ (nextline.isEmpty() || nextline.right() <= thisline.right() || (thisline.right() - 1) <= nextline.x() ? ow : -ow));
+ // upper edge
+ if (thisline.x() < lastline.x())
+ drawLineForBoxSide(graphicsContext,
+ l - ow,
+ t - ow,
+ min(r+ow, (lastline.isEmpty() ? 1000000 : tx + lastline.x())),
+ t ,
+ BSTop, oc, style()->color(), os,
+ ow,
+ (!lastline.isEmpty() && tx + lastline.x() + 1 < r + ow) ? -ow : ow);
+
+ if (lastline.right() < thisline.right())
+ drawLineForBoxSide(graphicsContext,
+ max(lastline.isEmpty() ? -1000000 : tx + lastline.right(), l - ow),
+ t - ow,
+ r + ow,
+ t ,
+ BSTop, oc, style()->color(), os,
+ (!lastline.isEmpty() && l - ow < tx + lastline.right()) ? -ow : ow,
+ ow);
+
+ // lower edge
+ if (thisline.x() < nextline.x())
+ drawLineForBoxSide(graphicsContext,
+ l - ow,
+ b,
+ min(r + ow, !nextline.isEmpty() ? tx + nextline.x() + 1 : 1000000),
+ b + ow,
+ BSBottom, oc, style()->color(), os,
+ ow,
+ (!nextline.isEmpty() && tx + nextline.x() + 1 < r + ow) ? -ow : ow);
+
+ if (nextline.right() < thisline.right())
+ drawLineForBoxSide(graphicsContext,
+ max(!nextline.isEmpty() ? tx + nextline.right() : -1000000, l - ow),
+ b,
+ r + ow,
+ b + ow,
+ BSBottom, oc, style()->color(), os,
+ (!nextline.isEmpty() && l - ow < tx + nextline.right()) ? -ow : ow,
+ ow);
+}
+
+#if ENABLE(DASHBOARD_SUPPORT)
+void RenderInline::addDashboardRegions(Vector<DashboardRegionValue>& regions)
+{
+ // Convert the style regions to absolute coordinates.
+ if (style()->visibility() != VISIBLE)
+ return;
+
+ const Vector<StyleDashboardRegion>& styleRegions = style()->dashboardRegions();
+ unsigned i, count = styleRegions.size();
+ for (i = 0; i < count; i++) {
+ StyleDashboardRegion styleRegion = styleRegions[i];
+
+ IntRect linesBoundingBox = this->linesBoundingBox();
+ int w = linesBoundingBox.width();
+ int h = linesBoundingBox.height();
+
+ DashboardRegionValue region;
+ region.label = styleRegion.label;
+ region.bounds = IntRect(linesBoundingBox.x() + styleRegion.offset.left().value(),
+ linesBoundingBox.y() + styleRegion.offset.top().value(),
+ w - styleRegion.offset.left().value() - styleRegion.offset.right().value(),
+ h - styleRegion.offset.top().value() - styleRegion.offset.bottom().value());
+ region.type = styleRegion.type;
+
+ RenderObject* container = containingBlock();
+ if (!container)
+ container = this;
+
+ region.clip = region.bounds;
+ container->computeAbsoluteRepaintRect(region.clip);
+ if (region.clip.height() < 0) {
+ region.clip.setHeight(0);
+ region.clip.setWidth(0);
+ }
+
+ FloatPoint absPos = container->localToAbsolute();
+ region.bounds.setX(absPos.x() + region.bounds.x());
+ region.bounds.setY(absPos.y() + region.bounds.y());
+
+ if (document()->frame()) {
+ float pageScaleFactor = document()->frame()->page()->chrome()->scaleFactor();
+ if (pageScaleFactor != 1.0f) {
+ region.bounds.scale(pageScaleFactor);
+ region.clip.scale(pageScaleFactor);
+ }
+ }
+
+ regions.append(region);
+ }
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderInline.h b/WebCore/rendering/RenderInline.h
index 83b8506..f3be72a 100644
--- a/WebCore/rendering/RenderInline.h
+++ b/WebCore/rendering/RenderInline.h
@@ -25,31 +25,39 @@
#ifndef RenderInline_h
#define RenderInline_h
-#include "RenderFlow.h"
+#include "RenderBoxModelObject.h"
+#include "RenderLineBoxList.h"
namespace WebCore {
class Position;
-class RenderInline : public RenderFlow {
+class RenderInline : public RenderBoxModelObject {
public:
RenderInline(Node*);
virtual ~RenderInline();
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
+ virtual void destroy();
+
virtual const char* renderName() const;
virtual bool isRenderInline() const { return true; }
- virtual bool childrenInline() const { return true; }
- virtual bool isInlineContinuation() const;
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
+ void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
+ virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual void addChildToFlow(RenderObject* newChild, RenderObject* beforeChild);
void splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
- RenderObject* beforeChild, RenderFlow* oldCont);
+ RenderObject* beforeChild, RenderBoxModelObject* oldCont);
void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
- RenderObject* newChild, RenderFlow* oldCont);
+ RenderObject* newChild, RenderBoxModelObject* oldCont);
- virtual void layout() { } // Do nothing for layout()
+ virtual void layout() { ASSERT_NOT_REACHED(); } // Do nothing for layout()
virtual void paint(PaintInfo&, int tx, int ty);
@@ -62,12 +70,20 @@ public:
virtual int offsetWidth() const { return linesBoundingBox().width(); }
virtual int offsetHeight() const { return linesBoundingBox().height(); }
- void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
+ // Just ignore top/bottom margins on RenderInlines.
+ virtual int marginTop() const { return 0; }
+ virtual int marginBottom() const { return 0; }
+ virtual int marginLeft() const;
+ virtual int marginRight() const;
+
+ virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed);
- virtual VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
IntRect linesBoundingBox() const;
@@ -77,13 +93,79 @@ public:
return IntRect(0, 0, boundingBox.width(), boundingBox.height());
}
+ InlineFlowBox* createInlineFlowBox();
+ void dirtyLineBoxes(bool fullLayout);
+ virtual void dirtyLinesFromChangedChild(RenderObject* child) { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
+
+ RenderLineBoxList* lineBoxes() { return &m_lineBoxes; }
+ const RenderLineBoxList* lineBoxes() const { return &m_lineBoxes; }
+
+ InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); }
+ InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); }
+
+ virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
+
+ RenderBoxModelObject* continuation() const { return m_continuation; }
+ RenderInline* inlineContinuation() const;
+ void setContinuation(RenderBoxModelObject* c) { m_continuation = c; }
+
+ virtual void updateDragState(bool dragOn);
+
+ virtual void childBecameNonInline(RenderObject* child);
+
+ virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
+
+ IntSize relativePositionedInlineOffset(const RenderBox* child) const;
+
+ virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
+ void paintOutline(GraphicsContext*, int tx, int ty);
+
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+
+ int verticalPositionFromCache(bool firstLine) const;
+ void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; }
+
+#if ENABLE(DASHBOARD_SUPPORT)
+ virtual void addDashboardRegions(Vector<DashboardRegionValue>&);
+#endif
+
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateBoxModelInfoFromStyle();
+ virtual InlineFlowBox* createFlowBox(); // Subclassed by SVG
+
+ static RenderInline* cloneInline(RenderInline* src);
- static RenderInline* cloneInline(RenderFlow* src);
+private:
+ void paintOutlineForLine(GraphicsContext*, int tx, int ty, const IntRect& prevLine, const IntRect& thisLine, const IntRect& nextLine);
+ RenderBoxModelObject* continuationBefore(RenderObject* beforeChild);
+protected:
+ RenderObjectChildList m_children;
+ RenderLineBoxList m_lineBoxes; // All of the line boxes created for this inline flow. For example, <i>Hello<br>world.</i> will have two <i> line boxes.
+
+private:
+ RenderBoxModelObject* m_continuation; // Can be either a block or an inline. <b><i><p>Hello</p></i></b>. In this example the <i> will have a block as its continuation but the
+ // <b> will just have an inline as its continuation.
+ mutable int m_lineHeight;
+ mutable int m_verticalPosition;
};
+inline RenderInline* toRenderInline(RenderObject* o)
+{
+ ASSERT(!o || o->isRenderInline());
+ return static_cast<RenderInline*>(o);
+}
+
+inline const RenderInline* toRenderInline(const RenderObject* o)
+{
+ ASSERT(!o || o->isRenderInline());
+ return static_cast<const RenderInline*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderInline(const RenderInline*);
+
} // namespace WebCore
#endif // RenderInline_h
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 1a538c6..fd88120 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -44,10 +44,13 @@
#include "config.h"
#include "RenderLayer.h"
+#include "CString.h"
#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
#include "Document.h"
#include "EventHandler.h"
#include "EventNames.h"
+#include "FloatPoint3D.h"
#include "FloatRect.h"
#include "FocusController.h"
#include "Frame.h"
@@ -73,8 +76,16 @@
#include "Scrollbar.h"
#include "ScrollbarTheme.h"
#include "SelectionController.h"
+#include "TransformationMatrix.h"
+#include "TransformState.h"
#include "TranslateTransformOperation.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerBacking.h"
+#include "RenderLayerCompositor.h"
+#endif
#if ENABLE(SVG)
#include "SVGNames.h"
@@ -88,12 +99,6 @@ namespace WebCore {
using namespace HTMLNames;
-const RenderLayer::ScrollAlignment RenderLayer::gAlignCenterIfNeeded = { RenderLayer::noScroll, RenderLayer::alignCenter, RenderLayer::alignToClosestEdge };
-const RenderLayer::ScrollAlignment RenderLayer::gAlignToEdgeIfNeeded = { RenderLayer::noScroll, RenderLayer::alignToClosestEdge, RenderLayer::alignToClosestEdge };
-const RenderLayer::ScrollAlignment RenderLayer::gAlignCenterAlways = { RenderLayer::alignCenter, RenderLayer::alignCenter, RenderLayer::alignCenter };
-const RenderLayer::ScrollAlignment RenderLayer::gAlignTopAlways = { RenderLayer::alignTop, RenderLayer::alignTop, RenderLayer::alignTop };
-const RenderLayer::ScrollAlignment RenderLayer::gAlignBottomAlways = { RenderLayer::alignBottom, RenderLayer::alignBottom, RenderLayer::alignBottom };
-
const int MinimumWidthWhileResizing = 100;
const int MinimumHeightWhileResizing = 40;
@@ -116,7 +121,7 @@ void ClipRects::destroy(RenderArena* renderArena)
renderArena->free(*(size_t *)this, this);
}
-RenderLayer::RenderLayer(RenderBox* renderer)
+RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
: m_renderer(renderer)
, m_parent(0)
, m_previous(0)
@@ -138,15 +143,15 @@ RenderLayer::RenderLayer(RenderBox* renderer)
, m_inResizeMode(false)
, m_posZOrderList(0)
, m_negZOrderList(0)
- , m_overflowList(0)
+ , m_normalFlowList(0)
, m_clipRects(0)
#ifndef NDEBUG
, m_clipRectsRoot(0)
#endif
, m_scrollDimensionsDirty(true)
, m_zOrderListsDirty(true)
- , m_overflowListDirty(true)
- , m_isOverflowOnly(shouldBeOverflowOnly())
+ , m_normalFlowListDirty(true)
+ , m_isNormalFlowOnly(shouldBeNormalFlowOnly())
, m_usedTransparency(false)
, m_paintingInsideReflection(false)
, m_inOverflowRelayout(false)
@@ -156,10 +161,15 @@ RenderLayer::RenderLayer(RenderBox* renderer)
, m_hasVisibleContent(false)
, m_visibleDescendantStatusDirty(false)
, m_hasVisibleDescendant(false)
+ , m_3DTransformedDescendantStatusDirty(true)
+ , m_has3DTransformedDescendant(false)
+#if USE(ACCELERATED_COMPOSITING)
+ , m_hasCompositingDescendant(false)
+ , m_mustOverlayCompositedLayers(false)
+#endif
, m_marquee(0)
, m_staticX(0)
, m_staticY(0)
- , m_transform(0)
, m_reflection(0)
, m_scrollCorner(0)
, m_resizer(0)
@@ -185,9 +195,13 @@ RenderLayer::~RenderLayer()
delete m_posZOrderList;
delete m_negZOrderList;
- delete m_overflowList;
+ delete m_normalFlowList;
delete m_marquee;
+#if USE(ACCELERATED_COMPOSITING)
+ clearBacking();
+#endif
+
// Make sure we have no lingering clip rects.
ASSERT(!m_clipRects);
@@ -204,11 +218,40 @@ RenderLayer::~RenderLayer()
m_resizer->destroy();
}
+#if USE(ACCELERATED_COMPOSITING)
+RenderLayerCompositor* RenderLayer::compositor() const
+{
+ ASSERT(renderer()->view());
+ return renderer()->view()->compositor();
+}
+
+void RenderLayer::rendererContentChanged()
+{
+ if (m_backing)
+ m_backing->rendererContentChanged();
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+void RenderLayer::setStaticY(int staticY)
+{
+ if (m_staticY == staticY)
+ return;
+ m_staticY = staticY;
+ renderer()->setChildNeedsLayout(true, false);
+}
+
void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
{
if (doFullRepaint) {
renderer()->repaint();
+#if USE(ACCELERATED_COMPOSITING)
+ checkForRepaint = false;
+ // We need the full repaint to propagate to child layers if we are hardware compositing.
+ if (!compositor()->inCompositingMode())
+ doFullRepaint = false;
+#else
checkForRepaint = doFullRepaint = false;
+#endif
}
updateLayerPosition(); // For relpositioned layers or non-positioned layers,
@@ -231,16 +274,17 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
// from updateScrollInfoAfterLayout().
ASSERT(!view->layoutStateEnabled());
- IntRect newRect = renderer()->absoluteClippedOverflowRect();
- IntRect newOutlineBox = renderer()->absoluteOutlineBounds();
+ RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ IntRect newRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
+ IntRect newOutlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
if (checkForRepaint) {
if (view && !view->printing()) {
if (m_needsFullRepaint) {
- view->repaintViewRectangle(m_repaintRect);
+ renderer()->repaintUsingContainer(repaintContainer, m_repaintRect);
if (newRect != m_repaintRect)
- view->repaintViewRectangle(newRect);
+ renderer()->repaintUsingContainer(repaintContainer, newRect);
} else
- renderer()->repaintAfterLayoutIfNeeded(m_repaintRect, m_outlineBox);
+ renderer()->repaintAfterLayoutIfNeeded(repaintContainer, m_repaintRect, m_outlineBox);
}
}
m_repaintRect = newRect;
@@ -258,6 +302,14 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
child->updateLayerPositions(doFullRepaint, checkForRepaint);
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (!parent())
+ compositor()->updateRootLayerPosition();
+
+ if (isComposited())
+ backing()->updateAfterLayout();
+#endif
// With all our children positioned, now update our marquee if we need to.
if (m_marquee)
@@ -266,7 +318,11 @@ void RenderLayer::updateLayerPositions(bool doFullRepaint, bool checkForRepaint)
void RenderLayer::updateTransform()
{
- bool hasTransform = renderer()->hasTransform();
+ // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
+ // so check style too.
+ bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform();
+ bool had3DTransform = has3DTransform();
+
bool hadTransform = m_transform;
if (hasTransform != hadTransform) {
if (hasTransform)
@@ -276,9 +332,33 @@ void RenderLayer::updateTransform()
}
if (hasTransform) {
- m_transform->reset();
- renderer()->style()->applyTransform(*m_transform, renderer()->borderBoxRect().size());
+ RenderBox* box = renderBox();
+ ASSERT(box);
+ m_transform->makeIdentity();
+ box->style()->applyTransform(*m_transform, box->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
+ makeMatrixRenderable(*m_transform);
}
+
+ if (had3DTransform != has3DTransform())
+ dirty3DTransformedDescendantStatus();
+}
+
+TransformationMatrix RenderLayer::currentTransform() const
+{
+ if (!m_transform)
+ return TransformationMatrix();
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (renderer()->style()->isRunningAcceleratedAnimation()) {
+ TransformationMatrix currTransform;
+ RefPtr<RenderStyle> style = renderer()->animation()->getAnimatedStyleForRenderer(renderer());
+ style->applyTransform(currTransform, renderBox()->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
+ makeMatrixRenderable(currTransform);
+ return currTransform;
+ }
+#endif
+
+ return *m_transform;
}
void RenderLayer::setHasVisibleContent(bool b)
@@ -288,9 +368,10 @@ void RenderLayer::setHasVisibleContent(bool b)
m_visibleContentStatusDirty = false;
m_hasVisibleContent = b;
if (m_hasVisibleContent) {
- m_repaintRect = renderer()->absoluteClippedOverflowRect();
- m_outlineBox = renderer()->absoluteOutlineBounds();
- if (!isOverflowOnly())
+ RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
+ m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
+ m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer);
+ if (!isNormalFlowOnly())
dirtyStackingContextZOrderLists();
}
if (parent())
@@ -372,38 +453,84 @@ void RenderLayer::updateVisibilityStatus()
}
}
+void RenderLayer::dirty3DTransformedDescendantStatus()
+{
+ RenderLayer* curr = stackingContext();
+ if (curr)
+ curr->m_3DTransformedDescendantStatusDirty = true;
+
+ // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
+ // Note that preserves3D() creates stacking context, so we can just run up the stacking contexts.
+ while (curr && curr->preserves3D()) {
+ curr->m_3DTransformedDescendantStatusDirty = true;
+ curr = curr->stackingContext();
+ }
+}
+
+// Return true if this layer or any preserve-3d descendants have 3d.
+bool RenderLayer::update3DTransformedDescendantStatus()
+{
+ if (m_3DTransformedDescendantStatusDirty) {
+ m_has3DTransformedDescendant = false;
+
+ // Transformed or preserve-3d descendants can only be in the z-order lists, not
+ // in the normal flow list, so we only need to check those.
+ if (m_posZOrderList) {
+ for (unsigned i = 0; i < m_posZOrderList->size(); ++i)
+ m_has3DTransformedDescendant |= m_posZOrderList->at(i)->update3DTransformedDescendantStatus();
+ }
+
+ // Now check our negative z-index children.
+ if (m_negZOrderList) {
+ for (unsigned i = 0; i < m_negZOrderList->size(); ++i)
+ m_has3DTransformedDescendant |= m_negZOrderList->at(i)->update3DTransformedDescendantStatus();
+ }
+ }
+
+ // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
+ // the m_has3DTransformedDescendant set.
+ if (preserves3D())
+ return has3DTransform() || m_has3DTransformedDescendant;
+
+ return has3DTransform();
+}
+
void RenderLayer::updateLayerPosition()
{
// Clear our cached clip rect information.
clearClipRects();
- int x = renderer()->x();
- int y = renderer()->y();
+ RenderBox* rendererBox = renderBox();
+
+ int x = rendererBox ? rendererBox->x() : 0;
+ int y = rendererBox ? rendererBox->y() : 0;
if (!renderer()->isPositioned() && renderer()->parent()) {
// We must adjust our position by walking up the render tree looking for the
// nearest enclosing object with a layer.
- RenderBox* curr = renderer()->parentBox();
+ RenderObject* curr = renderer()->parent();
while (curr && !curr->hasLayer()) {
- if (!curr->isTableRow()) {
+ if (curr->isBox() && !curr->isTableRow()) {
// Rows and cells share the same coordinate space (that of the section).
// Omit them when computing our xpos/ypos.
- x += curr->x();
- y += curr->y();
+ RenderBox* currBox = toRenderBox(curr);
+ x += currBox->x();
+ y += currBox->y();
}
- curr = curr->parentBox();
+ curr = curr->parent();
}
- if (curr->isTableRow()) {
+ if (curr->isBox() && curr->isTableRow()) {
// Put ourselves into the row coordinate space.
- x -= curr->x();
- y -= curr->y();
+ RenderBox* currBox = toRenderBox(curr);
+ x -= currBox->x();
+ y -= currBox->y();
}
}
m_relX = m_relY = 0;
if (renderer()->isRelPositioned()) {
- m_relX = toRenderBox(renderer())->relativePositionOffsetX();
- m_relY = toRenderBox(renderer())->relativePositionOffsetY();
+ m_relX = renderer()->relativePositionOffsetX();
+ m_relY = renderer()->relativePositionOffsetY();
x += m_relX; y += m_relY;
}
@@ -414,8 +541,8 @@ void RenderLayer::updateLayerPosition()
// For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
positionedParent->subtractScrolledContentOffset(x, y);
- if (renderer()->isPositioned()) {
- IntSize offset = toRenderBox(renderer())->offsetForPositionedInContainer(positionedParent->renderer());
+ if (renderer()->isPositioned() && positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
+ IntSize offset = toRenderInline(positionedParent->renderer())->relativePositionedInlineOffset(toRenderBox(renderer()));
x += offset.width();
y += offset.height();
}
@@ -424,33 +551,74 @@ void RenderLayer::updateLayerPosition()
// FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
- setPos(x, y);
+ setLocation(x, y);
if (renderer()->isRenderInline()) {
- RenderInline* inlineFlow = static_cast<RenderInline*>(renderer());
+ RenderInline* inlineFlow = toRenderInline(renderer());
IntRect lineBox = inlineFlow->linesBoundingBox();
setWidth(lineBox.width());
setHeight(lineBox.height());
- } else {
- setWidth(renderer()->width());
- setHeight(renderer()->height());
-
- if (!renderer()->hasOverflowClip()) {
- if (renderer()->overflowWidth() > renderer()->width())
- setWidth(renderer()->overflowWidth());
- if (renderer()->overflowHeight() > renderer()->height())
- setHeight(renderer()->overflowHeight());
+ } else if (RenderBox* box = renderBox()) {
+ setWidth(box->width());
+ setHeight(box->height());
+
+ if (!box->hasOverflowClip()) {
+ if (box->overflowWidth() > box->width())
+ setWidth(box->overflowWidth());
+ if (box->overflowHeight() > box->height())
+ setHeight(box->overflowHeight());
}
}
}
-RenderLayer *RenderLayer::stackingContext() const
+TransformationMatrix RenderLayer::perspectiveTransform() const
{
- RenderLayer* curr = parent();
- for ( ; curr && !curr->renderer()->isRenderView() && !curr->renderer()->isRoot() &&
- curr->renderer()->style()->hasAutoZIndex();
- curr = curr->parent()) { }
- return curr;
+ if (!renderer()->hasTransform())
+ return TransformationMatrix();
+
+ RenderStyle* style = renderer()->style();
+ if (!style->hasPerspective())
+ return TransformationMatrix();
+
+ // Maybe fetch the perspective from the backing?
+ const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
+ const float boxWidth = borderBox.width();
+ const float boxHeight = borderBox.height();
+
+ float perspectiveOriginX = style->perspectiveOriginX().calcFloatValue(boxWidth);
+ float perspectiveOriginY = style->perspectiveOriginY().calcFloatValue(boxHeight);
+
+ // A perspective origin of 0,0 makes the vanishing point in the center of the element.
+ // We want it to be in the top-left, so subtract half the height and width.
+ perspectiveOriginX -= boxWidth / 2.0f;
+ perspectiveOriginY -= boxHeight / 2.0f;
+
+ TransformationMatrix t;
+ t.translate(perspectiveOriginX, perspectiveOriginY);
+ t.applyPerspective(style->perspective());
+ t.translate(-perspectiveOriginX, -perspectiveOriginY);
+
+ return t;
+}
+
+FloatPoint RenderLayer::perspectiveOrigin() const
+{
+ if (!renderer()->hasTransform())
+ return FloatPoint();
+
+ const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
+ RenderStyle* style = renderer()->style();
+
+ return FloatPoint(style->perspectiveOriginX().calcFloatValue(borderBox.width()),
+ style->perspectiveOriginY().calcFloatValue(borderBox.height()));
+}
+
+RenderLayer* RenderLayer::stackingContext() const
+{
+ RenderLayer* layer = parent();
+ while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
+ layer = layer->parent();
+ return layer;
}
RenderLayer* RenderLayer::enclosingPositionedAncestor() const
@@ -469,6 +637,27 @@ RenderLayer* RenderLayer::enclosingTransformedAncestor() const
return curr;
}
+#if USE(ACCELERATED_COMPOSITING)
+RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
+{
+ if (includeSelf && isComposited())
+ return const_cast<RenderLayer*>(this);
+
+ // Compositing layers are parented according to stacking order and overflow list,
+ // so we have to check whether the parent is a stacking context, or whether
+ // the child is overflow-only.
+ bool inNormalFlowList = isNormalFlowOnly();
+ for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
+ if (curr->isComposited() && (inNormalFlowList || curr->isStackingContext()))
+ return curr;
+
+ inNormalFlowList = curr->isNormalFlowOnly();
+ }
+
+ return 0;
+}
+#endif
+
IntPoint RenderLayer::absoluteToContents(const IntPoint& absolutePoint) const
{
// We don't use convertToLayerCoords because it doesn't know about transforms
@@ -487,18 +676,24 @@ bool RenderLayer::requiresSlowRepaints() const
bool RenderLayer::isTransparent() const
{
#if ENABLE(SVG)
- if (renderer()->node()->namespaceURI() == SVGNames::svgNamespaceURI)
+ if (renderer()->node() && renderer()->node()->namespaceURI() == SVGNames::svgNamespaceURI)
return false;
#endif
return renderer()->isTransparent() || renderer()->hasMask();
}
-RenderLayer*
-RenderLayer::transparentAncestor()
+RenderLayer* RenderLayer::transparentPaintingAncestor()
{
- RenderLayer* curr = parent();
- for ( ; curr && !curr->isTransparent(); curr = curr->parent()) { }
- return curr;
+ if (isComposited())
+ return 0;
+
+ for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
+ if (curr->isComposited())
+ return 0;
+ if (curr->isTransparent())
+ return curr;
+ }
+ return 0;
}
static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransform, const RenderLayer* l, const RenderLayer* rootLayer)
@@ -507,16 +702,16 @@ static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransfor
// paintDirtyRect, and that should cut down on the amount we have to paint. Still it
// would be better to respect clips.
- TransformationMatrix* t = l->transform();
- if (t && rootLayer != l) {
+ if (rootLayer != l && l->paintsWithTransform()) {
// The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
// the transformed layer and all of its children.
int x = 0;
int y = 0;
l->convertToLayerCoords(rootLayer, x, y);
+
TransformationMatrix transform;
transform.translate(x, y);
- transform = *t * transform;
+ transform = *l->transform() * transform;
transform = transform * enclosingTransform;
// We now have a transform that will produce a rectangle in our view's space.
@@ -550,14 +745,14 @@ static IntRect transparencyClipBox(const TransformationMatrix& enclosingTransfor
void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer)
{
- if (p->paintingDisabled() || (isTransparent() && m_usedTransparency))
+ if (p->paintingDisabled() || (paintsWithTransparency() && m_usedTransparency))
return;
- RenderLayer* ancestor = transparentAncestor();
+ RenderLayer* ancestor = transparentPaintingAncestor();
if (ancestor)
ancestor->beginTransparencyLayers(p, rootLayer);
- if (isTransparent()) {
+ if (paintsWithTransparency()) {
m_usedTransparency = true;
p->save();
p->clip(transparencyClipBox(TransformationMatrix(), this, rootLayer));
@@ -577,7 +772,7 @@ void RenderLayer::operator delete(void* ptr, size_t sz)
}
void RenderLayer::destroy(RenderArena* renderArena)
-{
+{
delete this;
// Recover the size left there for us by operator delete and free the memory.
@@ -601,10 +796,10 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
child->setParent(this);
- if (child->isOverflowOnly())
- dirtyOverflowList();
+ if (child->isNormalFlowOnly())
+ dirtyNormalFlowList();
- if (!child->isOverflowOnly() || child->firstChild()) {
+ if (!child->isNormalFlowOnly() || child->firstChild()) {
// Dirty the z-order list in which we are contained. The stackingContext() can be null in the
// case where we're building up generated content layers. This is ok, since the lists will start
// off dirty in that case anyway.
@@ -614,10 +809,19 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
child->updateVisibilityStatus();
if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
childVisibilityChanged(true);
+
+#if USE(ACCELERATED_COMPOSITING)
+ compositor()->layerWasAdded(this, child);
+#endif
}
RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (!renderer()->documentBeingDestroyed())
+ compositor()->layerWillBeRemoved(this, oldChild);
+#endif
+
// remove the child
if (oldChild->previousSibling())
oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
@@ -629,9 +833,9 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
if (m_last == oldChild)
m_last = oldChild->previousSibling();
- if (oldChild->isOverflowOnly())
- dirtyOverflowList();
- if (!oldChild->isOverflowOnly() || oldChild->firstChild()) {
+ if (oldChild->isNormalFlowOnly())
+ dirtyNormalFlowList();
+ if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) {
// Dirty the z-order list in which we are contained. When called via the
// reattachment process in removeOnlyThisLayer, the layer may already be disconnected
// from the main layer tree, so we need to null-check the |stackingContext| value.
@@ -654,6 +858,10 @@ void RenderLayer::removeOnlyThisLayer()
if (!m_parent)
return;
+#if USE(ACCELERATED_COMPOSITING)
+ compositor()->layerWillBeRemoved(m_parent, this);
+#endif
+
// Dirty the clip rects.
clearClipRectsIncludingDescendants();
@@ -674,8 +882,8 @@ void RenderLayer::removeOnlyThisLayer()
current->updateLayerPositions();
current = next;
}
-
- destroy(renderer()->renderArena());
+
+ m_renderer->destroyLayer();
}
void RenderLayer::insertOnlyThisLayer()
@@ -684,21 +892,21 @@ void RenderLayer::insertOnlyThisLayer()
// We need to connect ourselves when our renderer() has a parent.
// Find our enclosingLayer and add ourselves.
RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
+ ASSERT(parentLayer);
RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
- if (parentLayer)
- parentLayer->addChild(this, beforeChild);
+ parentLayer->addChild(this, beforeChild);
}
-
+
// Remove all descendant layers from the hierarchy and add them to the new position.
for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
curr->moveLayers(m_parent, this);
-
+
// Clear out all the clip rects.
clearClipRectsIncludingDescendants();
}
void
-RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const
+RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, int& yPos) const
{
if (ancestorLayer == this)
return;
@@ -707,8 +915,8 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int&
// Add in the offset of the view. We can obtain this by calling
// localToAbsolute() on the RenderView.
FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
- x += absPos.x();
- y += absPos.y();
+ xPos += absPos.x();
+ yPos += absPos.y();
return;
}
@@ -720,10 +928,10 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int&
if (!parentLayer) return;
- parentLayer->convertToLayerCoords(ancestorLayer, x, y);
+ parentLayer->convertToLayerCoords(ancestorLayer, xPos, yPos);
- x += xPos();
- y += yPos();
+ xPos += x();
+ yPos += y();
}
void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
@@ -804,14 +1012,18 @@ RenderLayer::subtractScrolledContentOffset(int& x, int& y) const
void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
{
- if (renderer()->style()->overflowX() != OMARQUEE) {
+ RenderBox* box = renderBox();
+ if (!box)
+ return;
+
+ if (box->style()->overflowX() != OMARQUEE) {
if (x < 0) x = 0;
if (y < 0) y = 0;
// Call the scrollWidth/Height functions so that the dimensions will be computed if they need
// to be (for overflow:hidden blocks).
- int maxX = scrollWidth() - renderer()->clientWidth();
- int maxY = scrollHeight() - renderer()->clientHeight();
+ int maxX = scrollWidth() - box->clientWidth();
+ int maxY = scrollHeight() - box->clientHeight();
if (x > maxX) x = maxX;
if (y > maxY) y = maxY;
@@ -831,6 +1043,11 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// Update the positions of our child layers.
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
child->updateLayerPositions(false, false);
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (isComposited())
+ m_backing->updateGraphicsLayerGeometry();
+#endif
RenderView* view = renderer()->view();
@@ -865,7 +1082,7 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
// Schedule the scroll DOM event.
if (view) {
if (FrameView* frameView = view->frameView())
- frameView->scheduleEvent(Event::create(eventNames().scrollEvent, false, false), EventTargetNodeCast(renderer()->element()));
+ frameView->scheduleEvent(Event::create(eventNames().scrollEvent, false, false), renderer()->node());
}
}
@@ -890,10 +1107,12 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
// Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
// This will prevent us from revealing text hidden by the slider in Safari RSS.
- FloatPoint absPos = renderer()->localToAbsolute();
- absPos.move(renderer()->borderLeft(), renderer()->borderTop());
+ RenderBox* box = renderBox();
+ ASSERT(box);
+ FloatPoint absPos = box->localToAbsolute();
+ absPos.move(box->borderLeft(), box->borderTop());
- IntRect layerBounds = IntRect(absPos.x() + scrollXOffset(), absPos.y() + scrollYOffset(), renderer()->clientWidth(), renderer()->clientHeight());
+ IntRect layerBounds = IntRect(absPos.x() + scrollXOffset(), absPos.y() + scrollYOffset(), box->clientWidth(), box->clientHeight());
IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
@@ -912,7 +1131,7 @@ void RenderLayer::scrollRectToVisible(const IntRect &rect, bool scrollToAnchor,
newRect.setX(rect.x() - diffX);
newRect.setY(rect.y() - diffY);
}
- } else if (!parentLayer && renderer()->canBeProgramaticallyScrolled(scrollToAnchor)) {
+ } else if (!parentLayer && renderer()->isBox() && renderBox()->canBeProgramaticallyScrolled(scrollToAnchor)) {
if (frameView) {
if (renderer()->document() && renderer()->document()->ownerElement() && renderer()->document()->ownerElement()->renderer()) {
IntRect viewRect = frameView->visibleContentRect();
@@ -956,17 +1175,17 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
// If the rectangle is fully visible, use the specified visible behavior.
// If the rectangle is partially visible, but over a certain threshold,
// then treat it as fully visible to avoid unnecessary horizontal scrolling
- scrollX = getVisibleBehavior(alignX);
+ scrollX = ScrollAlignment::getVisibleBehavior(alignX);
else if (intersectWidth == visibleRect.width()) {
// If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
- scrollX = getVisibleBehavior(alignX);
+ scrollX = ScrollAlignment::getVisibleBehavior(alignX);
if (scrollX == alignCenter)
scrollX = noScroll;
} else if (intersectWidth > 0)
// If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
- scrollX = getPartialBehavior(alignX);
+ scrollX = ScrollAlignment::getPartialBehavior(alignX);
else
- scrollX = getHiddenBehavior(alignX);
+ scrollX = ScrollAlignment::getHiddenBehavior(alignX);
// If we're trying to align to the closest edge, and the exposeRect is further right
// than the visibleRect, and not bigger than the visible area, then align with the right.
if (scrollX == alignToClosestEdge && exposeRect.right() > visibleRect.right() && exposeRect.width() < visibleRect.width())
@@ -989,17 +1208,17 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
int intersectHeight = intersection(visibleRect, exposeRectY).height();
if (intersectHeight == exposeRect.height())
// If the rectangle is fully visible, use the specified visible behavior.
- scrollY = getVisibleBehavior(alignY);
+ scrollY = ScrollAlignment::getVisibleBehavior(alignY);
else if (intersectHeight == visibleRect.height()) {
// If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
- scrollY = getVisibleBehavior(alignY);
+ scrollY = ScrollAlignment::getVisibleBehavior(alignY);
if (scrollY == alignCenter)
scrollY = noScroll;
} else if (intersectHeight > 0)
// If the rectangle is partially visible, use the specified partial behavior
- scrollY = getPartialBehavior(alignY);
+ scrollY = ScrollAlignment::getPartialBehavior(alignY);
else
- scrollY = getHiddenBehavior(alignY);
+ scrollY = ScrollAlignment::getHiddenBehavior(alignY);
// If we're trying to align to the closest edge, and the exposeRect is further down
// than the visibleRect, and not bigger than the visible area, then align with the bottom.
if (scrollY == alignToClosestEdge && exposeRect.bottom() > visibleRect.bottom() && exposeRect.height() < visibleRect.height())
@@ -1032,12 +1251,13 @@ void RenderLayer::autoscroll()
frame->eventHandler()->updateSelectionForMouseDrag();
IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
- scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), false, gAlignToEdgeIfNeeded, gAlignToEdgeIfNeeded);
+ scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
}
void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset)
{
- if (!inResizeMode() || !renderer()->hasOverflowClip())
+ // FIXME: This should be possible on generated content but is not right now.
+ if (!inResizeMode() || !renderer()->hasOverflowClip() || !renderer()->node())
return;
// Set the width and height of the shadow ancestor node if there is one.
@@ -1073,7 +1293,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset
ExceptionCode ec;
if (difference.width()) {
- if (element && element->isControl()) {
+ if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
style->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false, ec);
style->setProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false, ec);
@@ -1085,7 +1305,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset
}
if (difference.height()) {
- if (element && element->isControl()) {
+ if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
style->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false, ec);
style->setProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false, ec);
@@ -1172,6 +1392,7 @@ static IntRect scrollCornerRect(const RenderLayer* layer, const IntRect& bounds)
static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds)
{
+ ASSERT(layer->renderer()->isBox());
if (layer->renderer()->style()->resize() == RESIZE_NONE)
return IntRect();
return cornerRect(layer, bounds);
@@ -1179,25 +1400,29 @@ static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds
bool RenderLayer::scrollbarCornerPresent() const
{
- return !scrollCornerRect(this, renderer()->borderBoxRect()).isEmpty();
+ ASSERT(renderer()->isBox());
+ return !scrollCornerRect(this, renderBox()->borderBoxRect()).isEmpty();
}
void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
{
IntRect scrollRect = rect;
+ RenderBox* box = renderBox();
+ ASSERT(box);
if (scrollbar == m_vBar.get())
- scrollRect.move(renderer()->width() - renderer()->borderRight() - scrollbar->width(), renderer()->borderTop());
+ scrollRect.move(box->width() - box->borderRight() - scrollbar->width(), box->borderTop());
else
- scrollRect.move(renderer()->borderLeft(), renderer()->height() - renderer()->borderBottom() - scrollbar->height());
+ scrollRect.move(box->borderLeft(), box->height() - box->borderBottom() - scrollbar->height());
renderer()->repaintRectangle(scrollRect);
}
PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
{
RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = renderer()->node()->shadowAncestorNode()->renderer()->style()->hasPseudoStyle(RenderStyle::SCROLLBAR);
+ RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
+ bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
- widget = RenderScrollbar::createCustomScrollbar(this, orientation, renderer()->node()->shadowAncestorNode()->renderBox());
+ widget = RenderScrollbar::createCustomScrollbar(this, orientation, toRenderBox(actualRenderer));
else
widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
renderer()->document()->view()->addChild(widget.get());
@@ -1287,19 +1512,23 @@ void RenderLayer::positionOverflowControls(int tx, int ty)
if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
return;
- IntRect borderBox = renderer()->borderBoxRect();
+ RenderBox* box = renderBox();
+ if (!box)
+ return;
+
+ IntRect borderBox = box->borderBoxRect();
IntRect scrollCorner(scrollCornerRect(this, borderBox));
IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height());
if (m_vBar)
- m_vBar->setFrameRect(IntRect(absBounds.right() - renderer()->borderRight() - m_vBar->width(),
- absBounds.y() + renderer()->borderTop(),
+ m_vBar->setFrameRect(IntRect(absBounds.right() - box->borderRight() - m_vBar->width(),
+ absBounds.y() + box->borderTop(),
m_vBar->width(),
- absBounds.height() - (renderer()->borderTop() + renderer()->borderBottom()) - scrollCorner.height()));
+ absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height()));
if (m_hBar)
- m_hBar->setFrameRect(IntRect(absBounds.x() + renderer()->borderLeft(),
- absBounds.bottom() - renderer()->borderBottom() - m_hBar->height(),
- absBounds.width() - (renderer()->borderLeft() + renderer()->borderRight()) - scrollCorner.width(),
+ m_hBar->setFrameRect(IntRect(absBounds.x() + box->borderLeft(),
+ absBounds.bottom() - box->borderBottom() - m_hBar->height(),
+ absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
m_hBar->height()));
if (m_scrollCorner)
@@ -1324,19 +1553,22 @@ int RenderLayer::scrollHeight()
void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
{
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
m_scrollDimensionsDirty = false;
bool ltr = renderer()->style()->direction() == LTR;
- int clientWidth = renderer()->clientWidth();
- int clientHeight = renderer()->clientHeight();
+ int clientWidth = box->clientWidth();
+ int clientHeight = box->clientHeight();
- m_scrollLeftOverflow = ltr ? 0 : min(0, renderer()->leftmostPosition(true, false) - renderer()->borderLeft());
+ m_scrollLeftOverflow = ltr ? 0 : min(0, box->leftmostPosition(true, false) - box->borderLeft());
int rightPos = ltr ?
- renderer()->rightmostPosition(true, false) - renderer()->borderLeft() :
+ box->rightmostPosition(true, false) - box->borderLeft() :
clientWidth - m_scrollLeftOverflow;
- int bottomPos = renderer()->lowestPosition(true, false) - renderer()->borderTop();
+ int bottomPos = box->lowestPosition(true, false) - box->borderTop();
m_scrollWidth = max(rightPos, clientWidth);
m_scrollHeight = max(bottomPos, clientHeight);
@@ -1368,7 +1600,7 @@ void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOve
if (FrameView* frameView = renderer()->document()->view()) {
frameView->scheduleEvent(OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow),
- EventTargetNodeCast(renderer()->element()));
+ renderer()->node());
}
}
}
@@ -1376,16 +1608,20 @@ void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOve
void
RenderLayer::updateScrollInfoAfterLayout()
{
+ RenderBox* box = renderBox();
+ if (!box)
+ return;
+
m_scrollDimensionsDirty = true;
bool horizontalOverflow, verticalOverflow;
computeScrollDimensions(&horizontalOverflow, &verticalOverflow);
- if (renderer()->style()->overflowX() != OMARQUEE) {
+ if (box->style()->overflowX() != OMARQUEE) {
// Layout may cause us to be in an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
- int newX = max(0, min(scrollXOffset(), scrollWidth() - renderer()->clientWidth()));
- int newY = max(0, min(m_scrollY, scrollHeight() - renderer()->clientHeight()));
+ int newX = max(0, min(scrollXOffset(), scrollWidth() - box->clientWidth()));
+ int newY = max(0, min(m_scrollY, scrollHeight() - box->clientHeight()));
if (newX != scrollXOffset() || newY != m_scrollY) {
RenderView* view = renderer()->view();
ASSERT(view);
@@ -1417,12 +1653,12 @@ RenderLayer::updateScrollInfoAfterLayout()
setHasVerticalScrollbar(false);
// overflow:auto may need to lay out again if scrollbars got added/removed.
- bool scrollbarsChanged = (renderer()->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) ||
- (renderer()->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);
+ bool scrollbarsChanged = (box->hasAutoHorizontalScrollbar() && haveHorizontalBar != horizontalOverflow) ||
+ (box->hasAutoVerticalScrollbar() && haveVerticalBar != verticalOverflow);
if (scrollbarsChanged) {
- if (renderer()->hasAutoHorizontalScrollbar())
+ if (box->hasAutoHorizontalScrollbar())
setHasHorizontalScrollbar(horizontalOverflow);
- if (renderer()->hasAutoVerticalScrollbar())
+ if (box->hasAutoVerticalScrollbar())
setHasVerticalScrollbar(verticalOverflow);
#if ENABLE(DASHBOARD_SUPPORT)
@@ -1439,7 +1675,7 @@ RenderLayer::updateScrollInfoAfterLayout()
m_inOverflowRelayout = true;
renderer()->setNeedsLayout(true, false);
if (renderer()->isRenderBlock())
- static_cast<RenderBlock*>(renderer())->layoutBlock(true);
+ toRenderBlock(renderer())->layoutBlock(true);
else
renderer()->layout();
m_inOverflowRelayout = false;
@@ -1448,14 +1684,14 @@ RenderLayer::updateScrollInfoAfterLayout()
}
// If overflow:scroll is turned into overflow:auto a bar might still be disabled (Bug 11985).
- if (m_hBar && renderer()->hasAutoHorizontalScrollbar())
+ if (m_hBar && box->hasAutoHorizontalScrollbar())
m_hBar->setEnabled(true);
- if (m_vBar && renderer()->hasAutoVerticalScrollbar())
+ if (m_vBar && box->hasAutoVerticalScrollbar())
m_vBar->setEnabled(true);
// Set up the range (and page step/line step).
if (m_hBar) {
- int clientWidth = renderer()->clientWidth();
+ int clientWidth = box->clientWidth();
int pageStep = (clientWidth - cAmountToKeepWhenPaging);
if (pageStep < 0) pageStep = clientWidth;
m_hBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
@@ -1463,14 +1699,14 @@ RenderLayer::updateScrollInfoAfterLayout()
m_hBar->setValue(scrollXOffset());
}
if (m_vBar) {
- int clientHeight = renderer()->clientHeight();
+ int clientHeight = box->clientHeight();
int pageStep = (clientHeight - cAmountToKeepWhenPaging);
if (pageStep < 0) pageStep = clientHeight;
m_vBar->setSteps(cScrollbarPixelsPerLineStep, pageStep);
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
- if (renderer()->element() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
+ if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(horizontalOverflow, verticalOverflow);
}
@@ -1501,7 +1737,10 @@ void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty
void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
{
- IntRect cornerRect = scrollCornerRect(this, renderer()->borderBoxRect());
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
+ IntRect cornerRect = scrollCornerRect(this, box->borderBoxRect());
IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
if (!absRect.intersects(damageRect))
return;
@@ -1524,7 +1763,10 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
if (renderer()->style()->resize() == RESIZE_NONE)
return;
- IntRect cornerRect = resizerCornerRect(this, renderer()->borderBoxRect());
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
+ IntRect cornerRect = resizerCornerRect(this, box->borderBoxRect());
IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
if (!absRect.intersects(damageRect))
return;
@@ -1548,6 +1790,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
// Clipping will exclude the right and bottom edges of this frame.
if (m_hBar || m_vBar) {
context->save();
+ context->clip(absRect);
IntRect largerCorner = absRect;
largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
context->setStrokeColor(Color(makeRGB(217, 217, 217)));
@@ -1563,9 +1806,12 @@ bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
if (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE)
return false;
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
IntPoint localPoint = absoluteToContents(absolutePoint);
- IntRect localBounds(0, 0, renderer()->width(), renderer()->height());
+ IntRect localBounds(0, 0, box->width(), box->height());
return resizerCornerRect(this, localBounds).contains(localPoint);
}
@@ -1574,10 +1820,13 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result)
if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
return false;
+ RenderBox* box = renderBox();
+ ASSERT(box);
+
int x = 0;
int y = 0;
convertToLayerCoords(root(), x, y);
- IntRect absBounds(x, y, renderer()->width(), renderer()->height());
+ IntRect absBounds(x, y, box->width(), box->height());
IntRect resizeControlRect;
if (renderer()->style()->resize() != RESIZE_NONE) {
@@ -1589,7 +1838,10 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result)
int resizeControlSize = max(resizeControlRect.height(), 0);
if (m_vBar) {
- IntRect vBarRect(absBounds.right() - renderer()->borderRight() - m_vBar->width(), absBounds.y() + renderer()->borderTop(), m_vBar->width(), absBounds.height() - (renderer()->borderTop() + renderer()->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
+ IntRect vBarRect(absBounds.right() - box->borderRight() - m_vBar->width(),
+ absBounds.y() + box->borderTop(),
+ m_vBar->width(),
+ absBounds.height() - (box->borderTop() + box->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
if (vBarRect.contains(result.point())) {
result.setScrollbar(m_vBar.get());
return true;
@@ -1598,7 +1850,10 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result)
resizeControlSize = max(resizeControlRect.width(), 0);
if (m_hBar) {
- IntRect hBarRect(absBounds.x() + renderer()->borderLeft(), absBounds.bottom() - renderer()->borderBottom() - m_hBar->height(), absBounds.width() - (renderer()->borderLeft() + renderer()->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize), m_hBar->height());
+ IntRect hBarRect(absBounds.x() + box->borderLeft(),
+ absBounds.bottom() - box->borderBottom() - m_hBar->height(),
+ absBounds.width() - (box->borderLeft() + box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
+ m_hBar->height());
if (hBarRect.contains(result.point())) {
result.setScrollbar(m_hBar.get());
return true;
@@ -1654,6 +1909,12 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
const IntRect& paintDirtyRect, bool haveTransparency, PaintRestriction paintRestriction,
RenderObject* paintingRoot, bool appliedTransform, bool temporaryClipRects)
{
+#if USE(ACCELERATED_COMPOSITING)
+ // Composited RenderLayers are painted via the backing's paintIntoLayer().
+ if (isComposited() && !backing()->paintingGoesToWindow())
+ return;
+#endif
+
// Avoid painting layers when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
// will do a full repaint().
@@ -1664,11 +1925,11 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (!renderer()->opacity())
return;
- if (isTransparent())
+ if (paintsWithTransparency())
haveTransparency = true;
// Apply a transform if we have one. A reflection is considered to be a transform, since it is a flip and a translate.
- if (m_transform && !appliedTransform) {
+ if (paintsWithTransform() && !appliedTransform) {
// If the transform can't be inverted, then don't paint anything.
if (!m_transform->isInvertible())
return;
@@ -1681,14 +1942,9 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Make sure the parent's clip rects have been calculated.
IntRect clipRect = paintDirtyRect;
if (parent()) {
- if (temporaryClipRects) {
- ClipRects parentClipRects;
- parent()->calculateClipRects(rootLayer, parentClipRects);
- clipRect = parentClipRects.overflowClipRect();
- } else {
- parent()->updateClipRects(rootLayer);
- clipRect = parent()->clipRects()->overflowClipRect();
- }
+ ClipRects parentRects;
+ parentClipRects(rootLayer, parentRects, temporaryClipRects);
+ clipRect = parentRects.overflowClipRect();
clipRect.intersect(paintDirtyRect);
}
@@ -1710,7 +1966,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Now do a paint with the root layer shifted to be us.
paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), haveTransparency, paintRestriction, paintingRoot, true, temporaryClipRects);
-
+
p->restore();
// Restore the clip.
@@ -1732,12 +1988,11 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, temporaryClipRects);
int x = layerBounds.x();
int y = layerBounds.y();
- int tx = x - renderer()->x();
- int ty = y - renderer()->y();
+ int tx = x - renderBoxX();
+ int ty = y - renderBoxY();
// Ensure our lists are up-to-date.
- updateZOrderLists();
- updateOverflowList();
+ updateLayerListsIfNeeded();
bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
@@ -1765,11 +2020,6 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
RenderObject::PaintInfo paintInfo(p, damageRect, PaintPhaseBlockBackground, false, paintingRootForRenderer, 0);
renderer()->paint(paintInfo, tx, ty);
- // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
- // z-index. We paint after we painted the background/border, so that the scrollbars will
- // sit above the background/border.
- paintOverflowControls(p, x, y, damageRect);
-
// Restore the clip.
restoreClip(p, paintDirtyRect, damageRect);
}
@@ -1813,10 +2063,12 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
}
// Paint any child layers that have overflow.
- if (m_overflowList)
- for (Vector<RenderLayer*>::iterator it = m_overflowList->begin(); it != m_overflowList->end(); ++it)
- it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
-
+ if (m_normalFlowList)
+ for (Vector<RenderLayer*>::iterator it = m_normalFlowList->begin(); it != m_normalFlowList->end(); ++it) {
+ if (it[0]->isSelfPaintingLayer())
+ it[0]->paintLayer(rootLayer, p, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot, false, temporaryClipRects);
+ }
+
// Now walk the sorted list of children with positive z-indices.
if (m_posZOrderList)
for (Vector<RenderLayer*>::iterator it = m_posZOrderList->begin(); it != m_posZOrderList->end(); ++it)
@@ -1834,7 +2086,7 @@ RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
}
// End our transparency layer
- if (isTransparent() && m_usedTransparency) {
+ if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
p->endTransparencyLayer();
p->restore();
m_usedTransparency = false;
@@ -1855,9 +2107,19 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
renderer()->document()->updateLayout();
IntRect boundsRect(m_x, m_y, width(), height());
- boundsRect.intersect(frameVisibleRect(renderer()));
-
- RenderLayer* insideLayer = hitTestLayer(this, request, result, boundsRect, result.point());
+ if (!request.ignoreClipping())
+ boundsRect.intersect(frameVisibleRect(renderer()));
+
+ RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, boundsRect, result.point(), false);
+ if (!insideLayer) {
+ // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
+ // return ourselves. We do this so mouse events continue getting delivered after a drag has
+ // exited the WebView, and so hit testing over a scrollbar hits the content document.
+ if ((request.active() || request.mouseUp()) && renderer()->isRenderView()) {
+ renderer()->updateHitTestResult(result, result.point());
+ insideLayer = this;
+ }
+ }
// Now determine if the result is inside an anchor; make sure an image map wins if
// it already set URLElement and only use the innermost.
@@ -1880,135 +2142,302 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
Node* RenderLayer::enclosingElement() const
{
for (RenderObject* r = renderer(); r; r = r->parent()) {
- if (Node* e = r->element())
+ if (Node* e = r->node())
return e;
}
ASSERT_NOT_REACHED();
return 0;
}
-RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
- const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform)
+// Compute the z-offset of the point in the transformState.
+// This is effectively projecting a ray normal to the plane of ancestor, finding where that
+// ray intersects target, and computing the z delta between those two points.
+static double computeZOffset(const HitTestingTransformState& transformState)
+{
+ // We got an affine transform, so no z-offset
+ if (transformState.m_accumulatedTransform.isAffine())
+ return 0;
+
+ // Flatten the point into the target plane
+ FloatPoint targetPoint = transformState.mappedPoint();
+
+ // Now map the point back through the transform, which computes Z.
+ FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
+ return backmappedPoint.z();
+}
+
+PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
+ const IntRect& hitTestRect, const IntPoint& hitTestPoint,
+ const HitTestingTransformState* containerTransformState) const
+{
+ RefPtr<HitTestingTransformState> transformState;
+ int offsetX = 0;
+ int offsetY = 0;
+ if (containerTransformState) {
+ // If we're already computing transform state, then it's relative to the container (which we know is non-null).
+ transformState = HitTestingTransformState::create(*containerTransformState);
+ convertToLayerCoords(containerLayer, offsetX, offsetY);
+ } else {
+ // If this is the first time we need to make transform state, then base it off of hitTestPoint,
+ // which is relative to rootLayer.
+ transformState = HitTestingTransformState::create(hitTestPoint, FloatQuad(hitTestRect));
+ convertToLayerCoords(rootLayer, offsetX, offsetY);
+ }
+
+ TransformationMatrix containerTransform = renderer()->transformFromContainer(containerLayer ? containerLayer->renderer() : 0, IntSize(offsetX, offsetY));
+ transformState->applyTransform(containerTransform, true);
+ return transformState;
+}
+
+
+static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
+{
+ if (!hitLayer)
+ return false;
+
+ // The hit layer is depth-sorting with other layers, so just say that it was hit.
+ if (canDepthSort)
+ return true;
+
+ // We need to look at z-depth to decide if this layer was hit.
+ if (zOffset) {
+ ASSERT(transformState);
+ // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
+ double childZOffset = computeZOffset(*transformState);
+ if (childZOffset > *zOffset) {
+ *zOffset = childZOffset;
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+// hitTestPoint and hitTestRect are relative to rootLayer.
+// A 'flattening' layer is one preserves3D() == false.
+// transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
+// transformState.m_lastPlanarPoint is the hitTestPoint in the plane of the containing flattening layer.
+// transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
+//
+// If zOffset is non-null (which indicates that the caller wants z offset information),
+// *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
+RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
+ const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform,
+ const HitTestingTransformState* transformState, double* zOffset)
{
+ // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
+
+ bool useTemporaryClipRects = false;
+#if USE(ACCELERATED_COMPOSITING)
+ useTemporaryClipRects = compositor()->inCompositingMode();
+#endif
+
// Apply a transform if we have one.
- if (m_transform && !appliedTransform) {
- // If the transform can't be inverted, then don't hit test this layer at all.
- if (!m_transform->isInvertible())
- return 0;
-
+ if (transform() && !appliedTransform) {
// Make sure the parent's clip rects have been calculated.
if (parent()) {
- parent()->updateClipRects(rootLayer);
-
+ ClipRects parentRects;
+ parentClipRects(rootLayer, parentRects, useTemporaryClipRects);
+ IntRect clipRect = parentRects.overflowClipRect();
// Go ahead and test the enclosing clip now.
- IntRect clipRect = parent()->clipRects()->overflowClipRect();
if (!clipRect.contains(hitTestPoint))
return 0;
}
- // Adjust the transform such that the renderer's upper left corner is at (0,0) in user space.
- // This involves subtracting out the position of the layer in our current coordinate space.
- int x = 0;
- int y = 0;
- convertToLayerCoords(rootLayer, x, y);
- TransformationMatrix transform;
- transform.translate(x, y);
- transform = *m_transform * transform;
-
- // Map the hit test point into the transformed space and then do a hit test with the root layer shifted to be us.
- return hitTestLayer(this, request, result, transform.inverse().mapRect(hitTestRect), transform.inverse().mapPoint(hitTestPoint), true);
+ // Create a transform state to accumulate this transform.
+ RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestPoint, transformState);
+
+ // If the transform can't be inverted, then don't hit test this layer at all.
+ if (!newTransformState->m_accumulatedTransform.isInvertible())
+ return 0;
+
+ // Compute the point and the hit test rect in the coords of this layer by using the values
+ // from the transformState, which store the point and quad in the coords of the last flattened
+ // layer, and the accumulated transform which lets up map through preserve-3d layers.
+ //
+ // We can't just map hitTestPoint and hitTestRect because they may have been flattened (losing z)
+ // by our container.
+ IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
+ IntRect localHitTestRect;
+#if USE(ACCELERATED_COMPOSITING)
+ if (isComposited()) {
+ // It doesn't make sense to project hitTestRect into the plane of this layer, so use the same bounds we use for painting.
+ localHitTestRect = compositor()->calculateCompositedBounds(this, this);
+ } else
+#endif
+ localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
+
+ // Now do a hit test with the root layer shifted to be us.
+ return hitTestLayer(this, containerLayer, request, result, localHitTestRect, localPoint, true, newTransformState.get(), zOffset);
}
+ // Ensure our lists and 3d status are up-to-date.
+ updateLayerListsIfNeeded();
+ update3DTransformedDescendantStatus();
+
+ RefPtr<HitTestingTransformState> localTransformState;
+ if (appliedTransform) {
+ // We computed the correct state in the caller (above code), so just reference it.
+ ASSERT(transformState);
+ localTransformState = const_cast<HitTestingTransformState*>(transformState);
+ } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
+ // We need transform state for the first time, or to offset the container state, so create it here.
+ localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestPoint, transformState);
+ }
+
+ // Check for hit test on backface if backface-visibility is 'hidden'
+ if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
+ TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
+ // If the z-vector of the matrix is negative, the back is facing towards the viewer.
+ if (invertedMatrix.m33() < 0)
+ return 0;
+ }
+
+ RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
+ if (localTransformState && !preserves3D()) {
+ // Keep a copy of the pre-flattening state, for computing z-offsets for the container
+ unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
+ // This layer is flattening, so flatten the state passed to descendants.
+ localTransformState->flatten();
+ }
+
// Calculate the clip rects we should use.
IntRect layerBounds;
IntRect bgRect;
IntRect fgRect;
IntRect outlineRect;
- calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect);
-
- // Ensure our lists are up-to-date.
- updateZOrderLists();
- updateOverflowList();
-
- // This variable tracks which layer the mouse ends up being inside. The minute we find an insideLayer,
- // we are done and can return it.
- RenderLayer* insideLayer = 0;
-
- // Begin by walking our list of positive layers from highest z-index down to the lowest
- // z-index.
+ calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects);
+
+ // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
+ // descendants.
+ double localZOffset = -numeric_limits<double>::infinity();
+ double* zOffsetForDescendantsPtr = 0;
+ double* zOffsetForContentsPtr = 0;
+
+ bool depthSortDescendants = false;
+ if (preserves3D()) {
+ depthSortDescendants = true;
+ // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
+ zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
+ zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
+ } else if (m_has3DTransformedDescendant) {
+ // Flattening layer with 3d children; use a local zOffset pointer to depth-test children and foreground.
+ depthSortDescendants = true;
+ zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
+ zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
+ } else if (zOffset) {
+ zOffsetForDescendantsPtr = 0;
+ // Container needs us to give back a z offset for the hit layer.
+ zOffsetForContentsPtr = zOffset;
+ }
+
+ // This variable tracks which layer the mouse ends up being inside.
+ RenderLayer* candidateLayer = 0;
+
+ // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
if (m_posZOrderList) {
for (int i = m_posZOrderList->size() - 1; i >= 0; --i) {
- insideLayer = m_posZOrderList->at(i)->hitTestLayer(rootLayer, request, result, hitTestRect, hitTestPoint);
- if (insideLayer)
- return insideLayer;
+ HitTestResult tempResult(result.point());
+ RenderLayer* hitLayer = m_posZOrderList->at(i)->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr);
+ if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) {
+ result = tempResult;
+ if (!depthSortDescendants)
+ return hitLayer;
+
+ candidateLayer = hitLayer;
+ }
}
}
// Now check our overflow objects.
- if (m_overflowList) {
- for (int i = m_overflowList->size() - 1; i >= 0; --i) {
- insideLayer = m_overflowList->at(i)->hitTestLayer(rootLayer, request, result, hitTestRect, hitTestPoint);
- if (insideLayer)
- return insideLayer;
+ if (m_normalFlowList) {
+ for (int i = m_normalFlowList->size() - 1; i >= 0; --i) {
+ RenderLayer* currLayer = m_normalFlowList->at(i);
+ if (!currLayer->isSelfPaintingLayer())
+ continue;
+
+ HitTestResult tempResult(result.point());
+ RenderLayer* hitLayer = currLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr);
+ if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) {
+ result = tempResult;
+ if (!depthSortDescendants)
+ return hitLayer;
+
+ candidateLayer = hitLayer;
+ }
}
}
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
- if (fgRect.contains(hitTestPoint) &&
- renderer()->hitTest(request, result, hitTestPoint,
- layerBounds.x() - renderer()->x(),
- layerBounds.y() - renderer()->y(),
- HitTestDescendants)) {
- // For positioned generated content, we might still not have a
- // node by the time we get to the layer level, since none of
- // the content in the layer has an element. So just walk up
- // the tree.
- if (!result.innerNode() || !result.innerNonSharedNode()) {
- Node* e = enclosingElement();
- if (!result.innerNode())
- result.setInnerNode(e);
- if (!result.innerNonSharedNode())
- result.setInnerNonSharedNode(e);
+ if (fgRect.contains(hitTestPoint)) {
+ // Hit test with a temporary HitTestResult, because we onlyl want to commit to 'result' if we know we're frontmost.
+ HitTestResult tempResult(result.point());
+ if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
+ isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
+ result = tempResult;
+ if (!depthSortDescendants)
+ return this;
+ // Foreground can depth-sort with descendant layers, so keep this as a candidate.
+ candidateLayer = this;
}
-
- return this;
}
-
+
// Now check our negative z-index children.
if (m_negZOrderList) {
for (int i = m_negZOrderList->size() - 1; i >= 0; --i) {
- insideLayer = m_negZOrderList->at(i)->hitTestLayer(rootLayer, request, result, hitTestRect, hitTestPoint);
- if (insideLayer)
- return insideLayer;
+ HitTestResult tempResult(result.point());
+ RenderLayer* hitLayer = m_negZOrderList->at(i)->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr);
+ if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) {
+ result = tempResult;
+ if (!depthSortDescendants)
+ return hitLayer;
+
+ candidateLayer = hitLayer;
+ }
}
}
+
+ // If we found a layer, return. Child layers, and foreground always render in front of background.
+ if (candidateLayer)
+ return candidateLayer;
- // Next we want to see if the mouse is inside this layer but not any of its children.
- if (bgRect.contains(hitTestPoint) &&
- renderer()->hitTest(request, result, hitTestPoint,
- layerBounds.x() - renderer()->x(),
- layerBounds.y() - renderer()->y(),
- HitTestSelf)) {
- if (!result.innerNode() || !result.innerNonSharedNode()) {
- Node* e = enclosingElement();
- if (!result.innerNode())
- result.setInnerNode(e);
- if (!result.innerNonSharedNode())
- result.setInnerNonSharedNode(e);
+ if (bgRect.contains(hitTestPoint)) {
+ HitTestResult tempResult(result.point());
+ if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) &&
+ isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
+ result = tempResult;
+ return this;
}
-
- return this;
}
+
+ return 0;
+}
- // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
- // return ourselves. We do this so mouse events continue getting delivered after a drag has
- // exited the WebView, and so hit testing over a scrollbar hits the content document.
- if ((request.active || request.mouseUp) && renderer()->isRenderView()) {
- renderer()->updateHitTestResult(result, hitTestPoint);
- return this;
+bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const IntRect& layerBounds, const IntPoint& hitTestPoint, HitTestFilter hitTestFilter) const
+{
+ if (!renderer()->hitTest(request, result, hitTestPoint,
+ layerBounds.x() - renderBoxX(),
+ layerBounds.y() - renderBoxY(),
+ hitTestFilter)) {
+ // It's wrong to set innerNode, but then claim that you didn't hit anything.
+ ASSERT(!result.innerNode());
+ return false;
}
- return 0;
+ // For positioned generated content, we might still not have a
+ // node by the time we get to the layer level, since none of
+ // the content in the layer has an element. So just walk up
+ // the tree.
+ if (!result.innerNode() || !result.innerNonSharedNode()) {
+ Node* e = enclosingElement();
+ if (!result.innerNode())
+ result.setInnerNode(e);
+ if (!result.innerNonSharedNode())
+ result.setInnerNonSharedNode(e);
+ }
+
+ return true;
}
void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
@@ -2039,10 +2468,9 @@ void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool useCached) const
{
- IntRect infiniteRect(INT_MIN/2, INT_MIN/2, INT_MAX, INT_MAX);
if (!parent()) {
// The root layer's clip rect is always infinite.
- clipRects.reset(infiniteRect);
+ clipRects.reset(ClipRects::infiniteRect());
return;
}
@@ -2058,7 +2486,7 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
parentLayer->calculateClipRects(rootLayer, clipRects);
}
else
- clipRects.reset(infiniteRect);
+ clipRects.reset(ClipRects::infiniteRect());
// A fixed object is essentially the root of its containing block hierarchy, so when
// we encounter such an object, we reset our clip rects to the fixedClipRect.
@@ -2086,13 +2514,13 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
}
if (renderer()->hasOverflowClip()) {
- IntRect newOverflowClip = renderer()->getOverflowClipRect(x,y);
+ IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(x,y);
clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
if (renderer()->isPositioned() || renderer()->isRelPositioned())
clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
}
if (renderer()->hasClip()) {
- IntRect newPosClip = renderer()->getClipRect(x,y);
+ IntRect newPosClip = toRenderBox(renderer())->clipRect(x,y);
clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect()));
@@ -2100,24 +2528,30 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
}
}
+void RenderLayer::parentClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool temporaryClipRects) const
+{
+ ASSERT(parent());
+ if (temporaryClipRects) {
+ parent()->calculateClipRects(rootLayer, clipRects);
+ return;
+ }
+
+ parent()->updateClipRects(rootLayer);
+ clipRects = *parent()->clipRects();
+}
+
void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds,
IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const
{
if (rootLayer != this && parent()) {
- ClipRects parentClipRects;
- if (temporaryClipRects)
- parent()->calculateClipRects(rootLayer, parentClipRects);
- else {
- parent()->updateClipRects(rootLayer);
- parentClipRects = *parent()->clipRects();
- }
-
- backgroundRect = renderer()->style()->position() == FixedPosition ? parentClipRects.fixedClipRect() :
- (renderer()->isPositioned() ? parentClipRects.posClipRect() :
- parentClipRects.overflowClipRect());
+ ClipRects parentRects;
+ parentClipRects(rootLayer, parentRects, temporaryClipRects);
+ backgroundRect = renderer()->style()->position() == FixedPosition ? parentRects.fixedClipRect() :
+ (renderer()->isPositioned() ? parentRects.posClipRect() :
+ parentRects.overflowClipRect());
RenderView* view = renderer()->view();
ASSERT(view);
- if (view && parentClipRects.fixed() && rootLayer->renderer() == view)
+ if (view && parentRects.fixed() && rootLayer->renderer() == view)
backgroundRect.move(view->frameView()->scrollX(), view->frameView()->scrollY());
backgroundRect.intersect(paintDirtyRect);
@@ -2136,10 +2570,10 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
// This layer establishes a clip of some kind.
if (renderer()->hasOverflowClip())
- foregroundRect.intersect(renderer()->getOverflowClipRect(x,y));
+ foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(x,y));
if (renderer()->hasClip()) {
// Clip applies to *us* as well, so go ahead and update the damageRect.
- IntRect newPosClip = renderer()->getClipRect(x,y);
+ IntRect newPosClip = toRenderBox(renderer())->clipRect(x,y);
backgroundRect.intersect(newPosClip);
foregroundRect.intersect(newPosClip);
outlineRect.intersect(newPosClip);
@@ -2202,7 +2636,7 @@ bool RenderLayer::intersectsDamageRect(const IntRect& layerBounds, const IntRect
return boundingBox(rootLayer).intersects(damageRect);
}
-IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
+IntRect RenderLayer::localBoundingBox() const
{
// There are three special cases we need to consider.
// (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
@@ -2216,56 +2650,64 @@ IntRect RenderLayer::boundingBox(const RenderLayer* rootLayer) const
IntRect result;
if (renderer()->isRenderInline()) {
// Go from our first line box to our last line box.
- RenderInline* inlineFlow = static_cast<RenderInline*>(renderer());
+ RenderInline* inlineFlow = toRenderInline(renderer());
InlineFlowBox* firstBox = inlineFlow->firstLineBox();
if (!firstBox)
return result;
int top = firstBox->root()->topOverflow();
int bottom = inlineFlow->lastLineBox()->root()->bottomOverflow();
- int left = firstBox->xPos();
+ int left = firstBox->x();
for (InlineRunBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
- left = min(left, curr->xPos());
- result = IntRect(m_x + left, m_y + (top - renderer()->y()), width(), bottom - top);
+ left = min(left, curr->x());
+ result = IntRect(left, top, width(), bottom - top);
} else if (renderer()->isTableRow()) {
// Our bounding box is just the union of all of our cells' border/overflow rects.
for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
IntRect bbox = toRenderBox(child)->borderBoxRect();
result.unite(bbox);
- IntRect overflowRect = renderer()->overflowRect(false);
+ IntRect overflowRect = renderBox()->overflowRect(false);
if (bbox != overflowRect)
result.unite(overflowRect);
}
}
- result.move(m_x, m_y);
} else {
- if (renderer()->hasMask())
- result = renderer()->maskClipRect();
+ RenderBox* box = renderBox();
+ ASSERT(box);
+ if (box->hasMask())
+ result = box->maskClipRect();
else {
- IntRect bbox = renderer()->borderBoxRect();
+ IntRect bbox = box->borderBoxRect();
result = bbox;
- IntRect overflowRect = renderer()->overflowRect(false);
+ IntRect overflowRect = box->overflowRect(false);
if (bbox != overflowRect)
result.unite(overflowRect);
}
-
- // We have to adjust the x/y of this result so that it is in the coordinate space of the layer.
- result.move(m_x, m_y);
}
-
- // Convert the bounding box to an absolute position. We can do this easily by looking at the delta
- // between the bounding box's xpos and our layer's xpos and then applying that to the absolute layerBounds
- // passed in.
- int absX = 0, absY = 0;
- convertToLayerCoords(rootLayer, absX, absY);
- result.move(absX - m_x, absY - m_y);
+
RenderView* view = renderer()->view();
ASSERT(view);
if (view)
- result.inflate(view->maximalOutlineSize());
+ result.inflate(view->maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
+
return result;
}
+IntRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
+{
+ IntRect result = localBoundingBox();
+
+ int deltaX = 0, deltaY = 0;
+ convertToLayerCoords(ancestorLayer, deltaX, deltaY);
+ result.move(deltaX, deltaY);
+ return result;
+}
+
+IntRect RenderLayer::absoluteBoundingBox() const
+{
+ return boundingBox(root());
+}
+
void RenderLayer::clearClipRectsIncludingDescendants()
{
if (!m_clipRects)
@@ -2288,6 +2730,38 @@ void RenderLayer::clearClipRects()
}
}
+#if USE(ACCELERATED_COMPOSITING)
+RenderLayerBacking* RenderLayer::ensureBacking()
+{
+ if (!m_backing)
+ m_backing.set(new RenderLayerBacking(this));
+ return m_backing.get();
+}
+
+void RenderLayer::clearBacking()
+{
+ m_backing.clear();
+}
+#endif
+
+void RenderLayer::setParent(RenderLayer* parent)
+{
+ if (parent == m_parent)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_parent && !renderer()->documentBeingDestroyed())
+ compositor()->layerWillBeRemoved(m_parent, this);
+#endif
+
+ m_parent = parent;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_parent && !renderer()->documentBeingDestroyed())
+ compositor()->layerWasAdded(m_parent, this);
+#endif
+}
+
static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
{
if (!obj1 || !obj2)
@@ -2303,28 +2777,28 @@ static RenderObject* commonAncestor(RenderObject* obj1, RenderObject* obj2)
void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestResult& result)
{
- // We don't update :hover/:active state when the result is marked as readonly.
- if (request.readonly)
+ // We don't update :hover/:active state when the result is marked as readOnly.
+ if (request.readOnly())
return;
Document* doc = renderer()->document();
Node* activeNode = doc->activeNode();
- if (activeNode && !request.active) {
+ if (activeNode && !request.active()) {
// We are clearing the :active chain because the mouse has been released.
for (RenderObject* curr = activeNode->renderer(); curr; curr = curr->parent()) {
- if (curr->element() && !curr->isText())
- curr->element()->setInActiveChain(false);
+ if (curr->node() && !curr->isText())
+ curr->node()->setInActiveChain(false);
}
doc->setActiveNode(0);
} else {
Node* newActiveNode = result.innerNode();
- if (!activeNode && newActiveNode && request.active) {
+ if (!activeNode && newActiveNode && request.active()) {
// We are setting the :active chain and freezing it. If future moves happen, they
// will need to reference this chain.
for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
- if (curr->element() && !curr->isText()) {
- curr->element()->setInActiveChain(true);
+ if (curr->node() && !curr->isText()) {
+ curr->node()->setInActiveChain(true);
}
}
doc->setActiveNode(newActiveNode);
@@ -2334,7 +2808,7 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
// If the mouse is down and if this is a mouse move event, we want to restrict changes in
// :hover/:active to only apply to elements that are in the :active chain that we froze
// at the time the mouse went down.
- bool mustBeInActiveChain = request.active && request.mouseMove;
+ bool mustBeInActiveChain = request.active() && request.mouseMove();
// Check to see if the hovered node has changed. If not, then we don't need to
// do anything.
@@ -2354,18 +2828,18 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
if (oldHoverObj != newHoverObj) {
// The old hover path only needs to be cleared up to (and not including) the common ancestor;
for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
- if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
- curr->element()->setActive(false);
- curr->element()->setHovered(false);
+ if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain())) {
+ curr->node()->setActive(false);
+ curr->node()->setHovered(false);
}
}
}
// Now set the hover state for our new object up to the root.
for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
- if (curr->element() && !curr->isText() && (!mustBeInActiveChain || curr->element()->inActiveChain())) {
- curr->element()->setActive(request.active);
- curr->element()->setHovered(true);
+ if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain())) {
+ curr->node()->setActive(request.active());
+ curr->node()->setHovered(true);
}
}
}
@@ -2383,6 +2857,11 @@ void RenderLayer::dirtyZOrderLists()
if (m_negZOrderList)
m_negZOrderList->clear();
m_zOrderListsDirty = true;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (!renderer()->documentBeingDestroyed())
+ compositor()->setCompositingLayersNeedUpdate();
+#endif
}
void RenderLayer::dirtyStackingContextZOrderLists()
@@ -2392,18 +2871,23 @@ void RenderLayer::dirtyStackingContextZOrderLists()
sc->dirtyZOrderLists();
}
-void RenderLayer::dirtyOverflowList()
+void RenderLayer::dirtyNormalFlowList()
{
- if (m_overflowList)
- m_overflowList->clear();
- m_overflowListDirty = true;
+ if (m_normalFlowList)
+ m_normalFlowList->clear();
+ m_normalFlowListDirty = true;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (!renderer()->documentBeingDestroyed())
+ compositor()->setCompositingLayersNeedUpdate();
+#endif
}
void RenderLayer::updateZOrderLists()
{
if (!isStackingContext() || !m_zOrderListsDirty)
return;
-
+
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
if (!m_reflection || reflectionLayer() != child)
child->collectLayers(m_posZOrderList, m_negZOrderList);
@@ -2411,27 +2895,28 @@ void RenderLayer::updateZOrderLists()
// Sort the two lists.
if (m_posZOrderList)
std::stable_sort(m_posZOrderList->begin(), m_posZOrderList->end(), compareZIndex);
+
if (m_negZOrderList)
std::stable_sort(m_negZOrderList->begin(), m_negZOrderList->end(), compareZIndex);
m_zOrderListsDirty = false;
}
-void RenderLayer::updateOverflowList()
+void RenderLayer::updateNormalFlowList()
{
- if (!m_overflowListDirty)
+ if (!m_normalFlowListDirty)
return;
for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
// Ignore non-overflow layers and reflections.
- if (child->isOverflowOnly() && (!m_reflection || reflectionLayer() != child)) {
- if (!m_overflowList)
- m_overflowList = new Vector<RenderLayer*>;
- m_overflowList->append(child);
+ if (child->isNormalFlowOnly() && (!m_reflection || reflectionLayer() != child)) {
+ if (!m_normalFlowList)
+ m_normalFlowList = new Vector<RenderLayer*>;
+ m_normalFlowList->append(child);
}
}
- m_overflowListDirty = false;
+ m_normalFlowListDirty = false;
}
void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderLayer*>*& negBuffer)
@@ -2439,7 +2924,7 @@ void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderL
updateVisibilityStatus();
// Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
- if ((m_hasVisibleContent || (m_hasVisibleDescendant && isStackingContext())) && !isOverflowOnly()) {
+ if ((m_hasVisibleContent || (m_hasVisibleDescendant && isStackingContext())) && !isNormalFlowOnly()) {
// Determine which buffer the child should be in.
Vector<RenderLayer*>*& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
@@ -2462,6 +2947,19 @@ void RenderLayer::collectLayers(Vector<RenderLayer*>*& posBuffer, Vector<RenderL
}
}
+void RenderLayer::updateLayerListsIfNeeded()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (compositor()->inCompositingMode()) {
+ if ((isStackingContext() && m_zOrderListsDirty) || m_normalFlowListDirty)
+ compositor()->updateCompositingLayers(this);
+ return;
+ }
+#endif
+ updateZOrderLists();
+ updateNormalFlowList();
+}
+
void RenderLayer::repaintIncludingDescendants()
{
renderer()->repaint();
@@ -2469,23 +2967,62 @@ void RenderLayer::repaintIncludingDescendants()
curr->repaintIncludingDescendants();
}
-bool RenderLayer::shouldBeOverflowOnly() const
+#if USE(ACCELERATED_COMPOSITING)
+void RenderLayer::setBackingNeedsRepaint()
+{
+ ASSERT(isComposited());
+ if (backing()->paintingGoesToWindow()) {
+ // If we're trying to repaint the placeholder document layer, propagate the
+ // repaint to the native view system.
+ RenderView* view = renderer()->view();
+ if (view)
+ view->repaintViewRectangle(absoluteBoundingBox());
+ } else
+ backing()->setContentsNeedDisplay();
+}
+
+void RenderLayer::setBackingNeedsRepaintInRect(const IntRect& r)
{
- return (renderer()->hasOverflowClip() || renderer()->hasReflection()) &&
+ ASSERT(isComposited());
+ if (backing()->paintingGoesToWindow()) {
+ // If we're trying to repaint the placeholder document layer, propagate the
+ // repaint to the native view system.
+ IntRect absRect(r);
+ int x = 0;
+ int y = 0;
+ convertToLayerCoords(root(), x, y);
+ absRect.move(x, y);
+
+ RenderView* view = renderer()->view();
+ if (view)
+ view->repaintViewRectangle(absRect);
+ } else
+ backing()->setContentsNeedDisplayInRect(r);
+}
+#endif
+
+bool RenderLayer::shouldBeNormalFlowOnly() const
+{
+ return (renderer()->hasOverflowClip() || renderer()->hasReflection() || renderer()->hasMask()) &&
!renderer()->isPositioned() &&
!renderer()->isRelPositioned() &&
!renderer()->hasTransform() &&
!isTransparent();
}
-void RenderLayer::styleChanged(RenderStyle::Diff, const RenderStyle*)
+bool RenderLayer::isSelfPaintingLayer() const
+{
+ return !isNormalFlowOnly() || renderer()->hasReflection() || renderer()->hasMask() || renderer()->isTableRow();
+}
+
+void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
{
- bool isOverflowOnly = shouldBeOverflowOnly();
- if (isOverflowOnly != m_isOverflowOnly) {
- m_isOverflowOnly = isOverflowOnly;
+ bool isNormalFlowOnly = shouldBeNormalFlowOnly();
+ if (isNormalFlowOnly != m_isNormalFlowOnly) {
+ m_isNormalFlowOnly = isNormalFlowOnly;
RenderLayer* p = parent();
if (p)
- p->dirtyOverflowList();
+ p->dirtyNormalFlowList();
dirtyStackingContextZOrderLists();
}
@@ -2516,12 +3053,21 @@ void RenderLayer::styleChanged(RenderStyle::Diff, const RenderStyle*)
updateScrollCornerStyle();
updateResizerStyle();
+
+#if USE(ACCELERATED_COMPOSITING)
+ updateTransform();
+
+ if (compositor()->updateLayerCompositingState(this, diff))
+ compositor()->setCompositingLayersNeedUpdate();
+#else
+ UNUSED_PARAM(diff);
+#endif
}
void RenderLayer::updateScrollCornerStyle()
{
- RenderObject* actualRenderer = renderer()->node()->isElementNode() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
- RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RenderStyle::SCROLLBAR_CORNER, actualRenderer->style()) : 0;
+ RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
+ RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, actualRenderer->style()) : 0;
if (corner) {
if (!m_scrollCorner) {
m_scrollCorner = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
@@ -2536,8 +3082,8 @@ void RenderLayer::updateScrollCornerStyle()
void RenderLayer::updateResizerStyle()
{
- RenderObject* actualRenderer = renderer()->node()->isElementNode() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
- RefPtr<RenderStyle> resizer = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RenderStyle::RESIZER, actualRenderer->style()) : 0;
+ RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
+ RefPtr<RenderStyle> resizer = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RESIZER, actualRenderer->style()) : 0;
if (resizer) {
if (!m_resizer) {
m_resizer = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h
index 54c15e9..6e70a4b 100644
--- a/WebCore/rendering/RenderLayer.h
+++ b/WebCore/rendering/RenderLayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 Apple Computer, Inc.
+ * Copyright (C) 2003, 2009 Apple Inc. All rights reserved.
*
* Portions are Copyright (C) 1998 Netscape Communications Corporation.
*
@@ -44,16 +44,18 @@
#ifndef RenderLayer_h
#define RenderLayer_h
-#include "ScrollbarClient.h"
#include "RenderBox.h"
+#include "ScrollBehavior.h"
+#include "ScrollbarClient.h"
#include "Timer.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
-class TransformationMatrix;
class CachedResource;
+class HitTestRequest;
class HitTestResult;
+class HitTestingTransformState;
class RenderFrameSet;
class RenderMarquee;
class RenderReplica;
@@ -63,8 +65,12 @@ class RenderTable;
class RenderText;
class RenderView;
class Scrollbar;
+class TransformationMatrix;
-struct HitTestRequest;
+#if USE(ACCELERATED_COMPOSITING)
+class RenderLayerBacking;
+class RenderLayerCompositor;
+#endif
class ClipRects {
public:
@@ -139,7 +145,9 @@ public:
m_fixed = other.fixed();
return *this;
}
-
+
+ static IntRect infiniteRect() { return IntRect(INT_MIN/2, INT_MIN/2, INT_MAX, INT_MAX); }
+
private:
// The normal operator new is disallowed on all render objects.
void* operator new(size_t) throw();
@@ -154,38 +162,13 @@ private:
class RenderLayer : public ScrollbarClient {
public:
- enum ScrollBehavior {
- noScroll,
- alignCenter,
- alignTop,
- alignBottom,
- alignLeft,
- alignRight,
- alignToClosestEdge
- };
-
- struct ScrollAlignment {
- ScrollBehavior m_rectVisible;
- ScrollBehavior m_rectHidden;
- ScrollBehavior m_rectPartial;
- };
-
friend class RenderReplica;
- static const ScrollAlignment gAlignCenterIfNeeded;
- static const ScrollAlignment gAlignToEdgeIfNeeded;
- static const ScrollAlignment gAlignCenterAlways;
- static const ScrollAlignment gAlignTopAlways;
- static const ScrollAlignment gAlignBottomAlways;
-
- static ScrollBehavior getVisibleBehavior(const ScrollAlignment& s) { return s.m_rectVisible; }
- static ScrollBehavior getPartialBehavior(const ScrollAlignment& s) { return s.m_rectPartial; }
- static ScrollBehavior getHiddenBehavior(const ScrollAlignment& s) { return s.m_rectHidden; }
-
- RenderLayer(RenderBox*);
+ RenderLayer(RenderBoxModelObject*);
~RenderLayer();
- RenderBox* renderer() const { return m_renderer; }
+ RenderBoxModelObject* renderer() const { return m_renderer; }
+ RenderBox* renderBox() const { return m_renderer && m_renderer->isBox() ? toRenderBox(m_renderer) : 0; }
RenderLayer* parent() const { return m_parent; }
RenderLayer* previousSibling() const { return m_previous; }
RenderLayer* nextSibling() const { return m_next; }
@@ -200,17 +183,25 @@ public:
void repaintIncludingDescendants();
- void styleChanged(RenderStyle::Diff, const RenderStyle*);
+#if USE(ACCELERATED_COMPOSITING)
+ // Indicate that the layer contents need to be repainted. Only has an effect
+ // if layer compositing is being used,
+ void setBackingNeedsRepaint();
+ void setBackingNeedsRepaintInRect(const IntRect& r); // r is in the coordinate space of the layer's render object
+#endif
+
+ void styleChanged(StyleDifference, const RenderStyle*);
RenderMarquee* marquee() const { return m_marquee; }
void suspendMarquees();
- bool isOverflowOnly() const { return m_isOverflowOnly; }
+ bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
+ bool isSelfPaintingLayer() const;
bool requiresSlowRepaints() const;
bool isTransparent() const;
- RenderLayer* transparentAncestor();
+ RenderLayer* transparentPaintingAncestor();
void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer);
bool hasReflection() const { return renderer()->hasReflection(); }
@@ -225,12 +216,12 @@ public:
return curr;
}
- int xPos() const { return m_x; }
- int yPos() const { return m_y; }
- void setPos(int xPos, int yPos)
+ int x() const { return m_x; }
+ int y() const { return m_y; }
+ void setLocation(int x, int y)
{
- m_x = xPos;
- m_y = yPos;
+ m_x = x;
+ m_y = y;
}
int width() const { return m_width; }
@@ -255,9 +246,9 @@ public:
void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
void scrollToYOffset(int y) { scrollToOffset(m_scrollX + m_scrollOriginX, y); }
- void scrollRectToVisible(const IntRect&, bool scrollToAnchor = false, const ScrollAlignment& alignX = gAlignCenterIfNeeded, const ScrollAlignment& alignY = gAlignCenterIfNeeded);
+ void scrollRectToVisible(const IntRect&, bool scrollToAnchor = false, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
- IntRect getRectToExpose(const IntRect& visibleRect, const IntRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
+ IntRect getRectToExpose(const IntRect& visibleRect, const IntRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
void setHasHorizontalScrollbar(bool);
void setHasVerticalScrollbar(bool);
@@ -288,6 +279,16 @@ public:
void resize(const PlatformMouseEvent&, const IntSize&);
bool inResizeMode() const { return m_inResizeMode; }
void setInResizeMode(bool b) { m_inResizeMode = b; }
+
+ bool isRootLayer() const { return renderer()->isRenderView(); }
+
+#if USE(ACCELERATED_COMPOSITING)
+ RenderLayerCompositor* compositor() const;
+
+ // Notification from the renderer that its content changed (e.g. current frame of image changed).
+ // Allows updates of layer content without repainting.
+ void rendererContentChanged();
+#endif
void updateLayerPosition();
void updateLayerPositions(bool doFullRepaint = false, bool checkForRepaint = true);
@@ -311,9 +312,9 @@ public:
Vector<RenderLayer*>* posZOrderList() const { return m_posZOrderList; }
Vector<RenderLayer*>* negZOrderList() const { return m_negZOrderList; }
- void dirtyOverflowList();
- void updateOverflowList();
- Vector<RenderLayer*>* overflowList() const { return m_overflowList; }
+ void dirtyNormalFlowList();
+ void updateNormalFlowList();
+ Vector<RenderLayer*>* normalFlowList() const { return m_normalFlowList; }
bool hasVisibleContent() const { return m_hasVisibleContent; }
void setHasVisibleContent(bool);
@@ -323,6 +324,13 @@ public:
// the <html> layer and the root layer).
RenderLayer* enclosingPositionedAncestor() const;
+#if USE(ACCELERATED_COMPOSITING)
+ // Enclosing compositing layer; if includeSelf is true, may return this.
+ RenderLayer* enclosingCompositingLayer(bool includeSelf = true) const;
+ // Ancestor compositing layer, excluding this.
+ RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(false); }
+#endif
+
void convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const;
bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); }
@@ -353,23 +361,39 @@ public:
bool intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect, const RenderLayer* rootLayer) const;
- // Returns a bounding box for this layer only.
+ // Bounding box relative to some ancestor layer.
IntRect boundingBox(const RenderLayer* rootLayer) const;
+ // Bounding box in the coordinates of this layer.
+ IntRect localBoundingBox() const;
+ // Bounding box relative to the root.
+ IntRect absoluteBoundingBox() const;
void updateHoverActiveState(const HitTestRequest&, HitTestResult&);
+ // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
IntRect repaintRect() const { return m_repaintRect; }
void setNeedsFullRepaint(bool f = true) { m_needsFullRepaint = f; }
int staticX() const { return m_staticX; }
int staticY() const { return m_staticY; }
void setStaticX(int staticX) { m_staticX = staticX; }
- void setStaticY(int staticY) { m_staticY = staticY; }
+ void setStaticY(int staticY);
bool hasTransform() const { return renderer()->hasTransform(); }
+ // Note that this transform has the transform-origin baked in.
TransformationMatrix* transform() const { return m_transform.get(); }
-
- void destroy(RenderArena*);
+ // currentTransform computes a transform which takes accelerated animations into account. The
+ // resulting transform has transform-origin baked in. If the layer does not have a transform,
+ // returns the identity matrix.
+ TransformationMatrix currentTransform() const;
+
+ // Get the perspective transform, which is applied to transformed sublayers.
+ // Returns true if the layer has a -webkit-perspective.
+ // Note that this transform has the perspective-origin baked in.
+ TransformationMatrix perspectiveTransform() const;
+ FloatPoint perspectiveOrigin() const;
+ bool preserves3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
+ bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
// Overloaded new operator. Derived classes must override operator new
// in order to allocate out of the RenderArena.
@@ -378,6 +402,25 @@ public:
// Overridden to prevent the normal delete from being called.
void operator delete(void*, size_t);
+#if USE(ACCELERATED_COMPOSITING)
+ bool isComposited() const { return m_backing != 0; }
+ RenderLayerBacking* backing() const { return m_backing.get(); }
+ RenderLayerBacking* ensureBacking();
+ void clearBacking();
+#else
+ bool isComposited() const { return false; }
+#endif
+
+ bool paintsWithTransparency() const
+ {
+ return isTransparent() && !isComposited();
+ }
+
+ bool paintsWithTransform() const
+ {
+ return transform() && !isComposited();
+ }
+
private:
// The normal operator new is disallowed on all render objects.
void* operator new(size_t) throw();
@@ -385,19 +428,34 @@ private:
private:
void setNextSibling(RenderLayer* next) { m_next = next; }
void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
- void setParent(RenderLayer* parent) { m_parent = parent; }
+ void setParent(RenderLayer* parent);
void setFirstChild(RenderLayer* first) { m_first = first; }
void setLastChild(RenderLayer* last) { m_last = last; }
+ int renderBoxX() const { return renderer()->isBox() ? toRenderBox(renderer())->x() : 0; }
+ int renderBoxY() const { return renderer()->isBox() ? toRenderBox(renderer())->y() : 0; }
+
void collectLayers(Vector<RenderLayer*>*&, Vector<RenderLayer*>*&);
+ void updateLayerListsIfNeeded();
+
void paintLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
bool haveTransparency, PaintRestriction, RenderObject* paintingRoot,
bool appliedTransform = false, bool temporaryClipRects = false);
- RenderLayer* hitTestLayer(RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&, const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform = false);
+
+ RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
+ const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform,
+ const HitTestingTransformState* transformState = 0, double* zOffset = 0);
+
+ PassRefPtr<HitTestingTransformState> createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
+ const IntRect& hitTestRect, const IntPoint& hitTestPoint,
+ const HitTestingTransformState* containerTransformState) const;
+
+ bool hitTestContents(const HitTestRequest&, HitTestResult&, const IntRect& layerBounds, const IntPoint& hitTestPoint, HitTestFilter) const;
+
void computeScrollDimensions(bool* needHBar = 0, bool* needVBar = 0);
- bool shouldBeOverflowOnly() const;
+ bool shouldBeNormalFlowOnly() const;
virtual void valueChanged(Scrollbar*);
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&);
@@ -410,11 +468,21 @@ private:
void dirtyVisibleDescendantStatus();
void updateVisibilityStatus();
+ // This flag is computed by RenderLayerCompositor, which knows more about 3d hierarchies than we do.
+ void setHas3DTransformedDescendant(bool b) { m_has3DTransformedDescendant = b; }
+ bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
+
+ void dirty3DTransformedDescendantStatus();
+ // Both updates the status, and returns true if descendants of this have 3d.
+ bool update3DTransformedDescendantStatus();
+
Node* enclosingElement() const;
void createReflection();
void updateReflectionStyle();
bool paintingInsideReflection() const { return m_paintingInsideReflection; }
+
+ void parentClipRects(const RenderLayer* rootLayer, ClipRects&, bool temporaryClipRects = false) const;
RenderLayer* enclosingTransformedAncestor() const;
@@ -424,8 +492,24 @@ private:
void updateScrollCornerStyle();
void updateResizerStyle();
-protected:
- RenderBox* m_renderer;
+#if USE(ACCELERATED_COMPOSITING)
+ bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
+ void setHasCompositingDescendant(bool b) { m_hasCompositingDescendant = b; }
+
+ bool mustOverlayCompositedLayers() const { return m_mustOverlayCompositedLayers; }
+ void setMustOverlayCompositedLayers(bool b) { m_mustOverlayCompositedLayers = b; }
+#endif
+
+private:
+ friend class RenderLayerBacking;
+ friend class RenderLayerCompositor;
+ friend class RenderBoxModelObject;
+
+ // Only safe to call from RenderBoxModelObject::destroyLayer(RenderArena*)
+ void destroy(RenderArena*);
+
+protected:
+ RenderBoxModelObject* m_renderer;
RenderLayer* m_parent;
RenderLayer* m_previous;
@@ -474,7 +558,7 @@ protected:
// This list contains child layers that cannot create stacking contexts. For now it is just
// overflow layers, but that may change in the future.
- Vector<RenderLayer*>* m_overflowList;
+ Vector<RenderLayer*>* m_normalFlowList;
ClipRects* m_clipRects; // Cached clip rects used when painting and hit testing.
#ifndef NDEBUG
@@ -483,8 +567,8 @@ protected:
bool m_scrollDimensionsDirty : 1;
bool m_zOrderListsDirty : 1;
- bool m_overflowListDirty: 1;
- bool m_isOverflowOnly : 1;
+ bool m_normalFlowListDirty: 1;
+ bool m_isNormalFlowOnly : 1;
bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
// we ended up painting this layer or any descendants (and therefore need to
@@ -501,6 +585,14 @@ protected:
bool m_visibleDescendantStatusDirty : 1;
bool m_hasVisibleDescendant : 1;
+ bool m_3DTransformedDescendantStatusDirty : 1;
+ bool m_has3DTransformedDescendant : 1; // Set on a stacking context layer that has 3D descendants anywhere
+ // in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
+#if USE(ACCELERATED_COMPOSITING)
+ bool m_hasCompositingDescendant : 1;
+ bool m_mustOverlayCompositedLayers : 1;
+#endif
+
RenderMarquee* m_marquee; // Used by layers with overflow:marquee
// Cached normal flow values for absolute positioned elements with static left/top values.
@@ -515,6 +607,10 @@ protected:
// Renderers to hold our custom scroll corner and resizer.
RenderScrollbarPart* m_scrollCorner;
RenderScrollbarPart* m_resizer;
+
+#if USE(ACCELERATED_COMPOSITING)
+ OwnPtr<RenderLayerBacking> m_backing;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
new file mode 100644
index 0000000..40805b5
--- /dev/null
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -0,0 +1,1067 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "AnimationController.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
+#include "FrameView.h"
+#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
+#include "HTMLNames.h"
+#include "RenderBox.h"
+#include "RenderImage.h"
+#include "RenderLayerCompositor.h"
+#include "RenderVideo.h"
+#include "RenderView.h"
+
+#include "RenderLayerBacking.h"
+
+using namespace std;
+
+namespace WebCore {
+
+RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
+ : m_owningLayer(layer)
+ , m_ancestorClippingLayer(0)
+ , m_graphicsLayer(0)
+ , m_contentsLayer(0)
+ , m_clippingLayer(0)
+ , m_isSimpleContainerCompositingLayer(false)
+ , m_simpleCompositingLayerStatusDirty(true)
+ , m_compositingContentOffsetDirty(true)
+{
+ createGraphicsLayer();
+}
+
+RenderLayerBacking::~RenderLayerBacking()
+{
+ updateClippingLayers(false, false);
+ updateContentsLayer(false);
+ destroyGraphicsLayer();
+}
+
+void RenderLayerBacking::createGraphicsLayer()
+{
+ m_graphicsLayer = GraphicsLayer::createGraphicsLayer(this);
+
+#ifndef NDEBUG
+ if (renderer()->node()->isDocumentNode())
+ m_graphicsLayer->setName("Document Node");
+ else {
+ if (renderer()->node()->isHTMLElement() && renderer()->node()->hasID())
+ m_graphicsLayer->setName(renderer()->renderName() + String(" ") + static_cast<HTMLElement*>(renderer()->node())->id());
+ else
+ m_graphicsLayer->setName(renderer()->renderName());
+ }
+#endif // NDEBUG
+
+ updateLayerOpacity();
+ updateLayerTransform();
+}
+
+void RenderLayerBacking::destroyGraphicsLayer()
+{
+ if (m_graphicsLayer)
+ m_graphicsLayer->removeFromParent();
+
+ delete m_graphicsLayer;
+ m_graphicsLayer = 0;
+
+ delete m_contentsLayer;
+ m_contentsLayer = 0;
+
+ delete m_clippingLayer;
+ m_clippingLayer = 0;
+}
+
+void RenderLayerBacking::updateLayerOpacity()
+{
+ m_graphicsLayer->setOpacity(compositingOpacity(renderer()->opacity()), 0, 0);
+}
+
+void RenderLayerBacking::updateLayerTransform()
+{
+ RenderStyle* style = renderer()->style();
+
+ // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
+ // baked into it, and we don't want that.
+ TransformationMatrix t;
+ if (m_owningLayer->hasTransform()) {
+ style->applyTransform(t, toRenderBox(renderer())->borderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
+ makeMatrixRenderable(t);
+ }
+
+ m_graphicsLayer->setTransform(t);
+}
+
+void RenderLayerBacking::updateAfterLayout()
+{
+ invalidateDrawingOptimizations();
+ detectDrawingOptimizations();
+
+ updateGraphicsLayerGeometry();
+}
+
+bool RenderLayerBacking::updateGraphicsLayers(bool needsContentsLayer, bool needsUpperClippingLayer, bool needsLowerClippingLayer, bool needsRepaint)
+{
+ bool layerConfigChanged = false;
+ if (updateContentsLayer(needsContentsLayer))
+ layerConfigChanged = true;
+
+ if (updateClippingLayers(needsUpperClippingLayer, needsLowerClippingLayer))
+ layerConfigChanged = true;
+
+ // See if we can now use any drawing optimizations.
+ bool didDrawContent = graphicsLayer()->drawsContent();
+ invalidateDrawingOptimizations();
+ detectDrawingOptimizations();
+ if (!didDrawContent && graphicsLayer()->drawsContent())
+ needsRepaint = true;
+
+ // Set opacity, if it is not animating.
+ if (!renderer()->animation()->isAnimatingPropertyOnRenderer(renderer(), CSSPropertyOpacity))
+ updateLayerOpacity();
+
+ RenderStyle* style = renderer()->style();
+ m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D);
+ m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
+
+ updateGraphicsLayerGeometry();
+
+ m_graphicsLayer->updateContentsRect();
+
+ if (needsRepaint) {
+ m_graphicsLayer->setNeedsDisplay();
+ if (m_contentsLayer)
+ m_contentsLayer->setNeedsDisplay();
+ }
+
+ return layerConfigChanged;
+}
+
+void RenderLayerBacking::updateGraphicsLayerGeometry()
+{
+ // If we haven't built z-order lists yet, wait until later.
+ if (m_owningLayer->isStackingContext() && m_owningLayer->m_zOrderListsDirty)
+ return;
+
+ // Set transform property, if it is not animating. We have to do this here because the transform
+ // is affected by the layer dimensions.
+ if (!renderer()->animation()->isAnimatingPropertyOnRenderer(renderer(), CSSPropertyWebkitTransform))
+ updateLayerTransform();
+
+ m_compositingContentOffsetDirty = true;
+
+ RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
+
+ // We compute everything relative to the enclosing compositing layer.
+ IntRect ancestorCompositingBounds;
+ if (compAncestor)
+ ancestorCompositingBounds = compositor()->calculateCompositedBounds(compAncestor, compAncestor);
+
+ IntRect localCompositingBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
+
+ IntRect relativeCompositingBounds(localCompositingBounds);
+ int deltaX = 0, deltaY = 0;
+ m_owningLayer->convertToLayerCoords(compAncestor, deltaX, deltaY);
+ relativeCompositingBounds.move(deltaX, deltaY);
+
+ IntPoint graphicsLayerParentLocation;
+ if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
+ // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
+ // position relative to it.
+ graphicsLayerParentLocation = toRenderBox(compAncestor->renderer())->overflowClipRect(0, 0).location();
+ } else
+ graphicsLayerParentLocation = ancestorCompositingBounds.location();
+
+ if (compAncestor && m_ancestorClippingLayer) {
+ // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
+ // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
+ // for a compositing layer, rootLayer is the layer itself.
+ ClipRects parentRects;
+ m_owningLayer->parentClipRects(compAncestor, parentRects, true);
+ IntRect parentClipRect = parentRects.overflowClipRect();
+
+ m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
+ m_ancestorClippingLayer->setSize(parentClipRect.size());
+
+ // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
+ IntSize rendererOffset(parentClipRect.location().x() - deltaX, parentClipRect.location().y() - deltaY);
+ m_ancestorClippingLayer->setOffsetFromRenderer(rendererOffset);
+
+ // The primary layer is then parented in, and positioned relative to this clipping layer.
+ graphicsLayerParentLocation = parentClipRect.location();
+ }
+
+ m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation));
+ m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - IntPoint());
+
+ FloatSize oldSize = m_graphicsLayer->size();
+ FloatSize newSize = relativeCompositingBounds.size();
+ if (oldSize != newSize) {
+ m_graphicsLayer->setSize(newSize);
+ // A bounds change will almost always require redisplay. Usually that redisplay
+ // will happen because of a repaint elsewhere, but not always:
+ // e.g. see RenderView::setMaximalOutlineSize()
+ m_graphicsLayer->setNeedsDisplay();
+ }
+
+ // If we have a layer that clips children, position it.
+ if (m_clippingLayer) {
+ IntRect clippingBox = toRenderBox(renderer())->overflowClipRect(0, 0);
+ m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
+ m_clippingLayer->setSize(clippingBox.size());
+ m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
+ }
+
+ if (m_owningLayer->hasTransform()) {
+ const IntRect borderBox = toRenderBox(renderer())->borderBoxRect();
+
+ IntRect layerBounds = IntRect(m_owningLayer->x(), m_owningLayer->y(), borderBox.width(), borderBox.height());
+ // Convert to absolute coords to match bbox.
+ int x = 0, y = 0;
+ m_owningLayer->convertToLayerCoords(compAncestor, x, y);
+ layerBounds.move(x - m_owningLayer->x(), y - m_owningLayer->y());
+
+ // Update properties that depend on layer dimensions
+ FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
+ // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
+ FloatPoint3D anchor(relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width() : 0.5f,
+ relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
+ transformOrigin.z());
+ m_graphicsLayer->setAnchorPoint(anchor);
+
+ RenderStyle* style = renderer()->style();
+ if (style->hasPerspective()) {
+ TransformationMatrix t = owningLayer()->perspectiveTransform();
+
+ if (m_clippingLayer) {
+ m_clippingLayer->setChildrenTransform(t);
+ m_graphicsLayer->setChildrenTransform(TransformationMatrix());
+ }
+ else
+ m_graphicsLayer->setChildrenTransform(t);
+ } else {
+ if (m_clippingLayer)
+ m_clippingLayer->setChildrenTransform(TransformationMatrix());
+ else
+ m_graphicsLayer->setChildrenTransform(TransformationMatrix());
+ }
+ } else {
+ m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
+ }
+
+ if (m_contentsLayer) {
+ // The contents layer is always coincidental with the graphicsLayer for now.
+ m_contentsLayer->setPosition(IntPoint(0, 0));
+ m_contentsLayer->setSize(newSize);
+ m_contentsLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
+ }
+
+ m_graphicsLayer->updateContentsRect();
+}
+
+void RenderLayerBacking::updateInternalHierarchy()
+{
+ // m_contentsLayer has to be inserted in the correct order with child layers,
+ // so it's not inserted here.
+ if (m_ancestorClippingLayer) {
+ m_ancestorClippingLayer->removeAllChildren();
+ m_graphicsLayer->removeFromParent();
+ m_ancestorClippingLayer->addChild(m_graphicsLayer);
+ }
+
+ if (m_clippingLayer) {
+ m_clippingLayer->removeFromParent();
+ m_graphicsLayer->addChild(m_clippingLayer);
+ }
+}
+
+// Return true if the layers changed.
+bool RenderLayerBacking::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
+{
+ bool layersChanged = false;
+
+ if (needsAncestorClip) {
+ if (!m_ancestorClippingLayer) {
+ m_ancestorClippingLayer = GraphicsLayer::createGraphicsLayer(this);
+#ifndef NDEBUG
+ m_ancestorClippingLayer->setName("Ancestor clipping Layer");
+#endif
+ m_ancestorClippingLayer->setMasksToBounds(true);
+ layersChanged = true;
+ }
+ } else if (m_ancestorClippingLayer) {
+ m_ancestorClippingLayer->removeFromParent();
+ delete m_ancestorClippingLayer;
+ m_ancestorClippingLayer = 0;
+ layersChanged = true;
+ }
+
+ if (needsDescendantClip) {
+ if (!m_clippingLayer) {
+ m_clippingLayer = GraphicsLayer::createGraphicsLayer(0);
+#ifndef NDEBUG
+ m_clippingLayer->setName("Child clipping Layer");
+#endif
+ m_clippingLayer->setMasksToBounds(true);
+ layersChanged = true;
+ }
+ } else if (m_clippingLayer) {
+ m_clippingLayer->removeFromParent();
+ delete m_clippingLayer;
+ m_clippingLayer = 0;
+ layersChanged = true;
+ }
+
+ if (layersChanged)
+ updateInternalHierarchy();
+
+ return layersChanged;
+}
+
+bool RenderLayerBacking::updateContentsLayer(bool needsContentsLayer)
+{
+ bool layerChanged = false;
+ if (needsContentsLayer) {
+ if (!m_contentsLayer) {
+ m_contentsLayer = GraphicsLayer::createGraphicsLayer(this);
+#ifndef NDEBUG
+ m_contentsLayer->setName("Contents");
+#endif
+ m_contentsLayer->setDrawsContent(true);
+ m_contentsLayer->setDrawingPhase(GraphicsLayerPaintForegroundMask);
+ m_graphicsLayer->setDrawingPhase(GraphicsLayerPaintBackgroundMask);
+ layerChanged = true;
+ }
+ } else if (m_contentsLayer) {
+ m_contentsLayer->removeFromParent();
+ delete m_contentsLayer;
+ m_contentsLayer = 0;
+ m_graphicsLayer->setDrawingPhase(GraphicsLayerPaintAllMask);
+ layerChanged = true;
+ }
+ return layerChanged;
+}
+
+float RenderLayerBacking::compositingOpacity(float rendererOpacity) const
+{
+ float finalOpacity = rendererOpacity;
+
+ for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
+ // We only care about parents that are stacking contexts.
+ // Recall that opacity creates stacking context.
+ if (!curr->isStackingContext())
+ continue;
+
+ // If we found a compositing layer, we want to compute opacity
+ // relative to it. So we can break here.
+ if (curr->isComposited())
+ break;
+
+ finalOpacity *= curr->renderer()->opacity();
+ }
+
+ return finalOpacity;
+}
+
+static bool hasBorderOutlineOrShadow(const RenderStyle* style)
+{
+ return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow();
+}
+
+static bool hasBoxDecorations(const RenderStyle* style)
+{
+ return hasBorderOutlineOrShadow(style) || style->hasBackground();
+}
+
+static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle* style)
+{
+ return hasBorderOutlineOrShadow(style) || style->hasBackgroundImage();
+}
+
+bool RenderLayerBacking::rendererHasBackground() const
+{
+ // FIXME: share more code here
+ if (renderer()->node()->isDocumentNode()) {
+ RenderObject* htmlObject = renderer()->firstChild();
+ if (!htmlObject)
+ return false;
+
+ RenderStyle* style = htmlObject->style();
+ if (style->hasBackground())
+ return true;
+
+ RenderObject* bodyObject = htmlObject->firstChild();
+ if (!bodyObject)
+ return false;
+
+ style = bodyObject->style();
+ return style->hasBackground();
+ }
+
+ return renderer()->style()->hasBackground();
+}
+
+const Color& RenderLayerBacking::rendererBackgroundColor() const
+{
+ // FIXME: share more code here
+ if (renderer()->node()->isDocumentNode()) {
+ RenderObject* htmlObject = renderer()->firstChild();
+ RenderStyle* style = htmlObject->style();
+ if (style->hasBackground())
+ return style->backgroundColor();
+
+ RenderObject* bodyObject = htmlObject->firstChild();
+ style = bodyObject->style();
+ return style->backgroundColor();
+ }
+
+ return renderer()->style()->backgroundColor();
+}
+
+bool RenderLayerBacking::canBeSimpleContainerCompositingLayer() const
+{
+ RenderObject* renderObject = renderer();
+ if (renderObject->isReplaced() || // replaced objects are not containers
+ renderObject->hasMask()) // masks require special treatment
+ return false;
+
+ RenderStyle* style = renderObject->style();
+
+ // Reject anything that has a border, a border-radius or outline,
+ // or any background (color or image).
+ // FIXME: we could optimize layers for simple backgrounds.
+ if (hasBoxDecorations(style))
+ return false;
+
+ // If we have got this far and the renderer has no children, then we're ok.
+ if (!renderObject->firstChild())
+ return true;
+
+ if (renderObject->node()->isDocumentNode()) {
+ // Look to see if the root object has a non-simple backgound
+ RenderObject* rootObject = renderObject->document()->documentElement()->renderer();
+ if (!rootObject)
+ return false;
+
+ style = rootObject->style();
+
+ // Reject anything that has a border, a border-radius or outline,
+ // or is not a simple background (no background, or solid color).
+ if (hasBoxDecorationsWithBackgroundImage(style))
+ return false;
+
+ // Now look at the body's renderer.
+ HTMLElement* body = renderObject->document()->body();
+ RenderObject* bodyObject = (body && body->hasLocalName(HTMLNames::bodyTag)) ? body->renderer() : 0;
+ if (!bodyObject)
+ return false;
+
+ style = bodyObject->style();
+
+ if (hasBoxDecorationsWithBackgroundImage(style))
+ return false;
+
+ // Ceck to see if all the body's children are compositing layers.
+ if (hasNonCompositingContent())
+ return false;
+
+ return true;
+ }
+
+ // Check to see if all the renderer's children are compositing layers.
+ if (hasNonCompositingContent())
+ return false;
+
+ return true;
+}
+
+bool RenderLayerBacking::hasNonCompositingContent() const
+{
+ // Conservative test for having no rendered children.
+
+ // Some HTML can cause whitespace text nodes to have renderers, like:
+ // <div>
+ // <img src=...>
+ // </div>
+ // so test for 0x0 RenderTexts here
+ for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
+ if (!child->hasLayer()) {
+ if (child->isRenderInline() || !child->isBox())
+ return true;
+
+ if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
+ return true;
+ }
+ }
+
+ // FIXME: test for overflow controls.
+ if (m_owningLayer->isStackingContext()) {
+ // Use the m_hasCompositingDescendant bit to optimize?
+ Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList();
+ if (negZOrderList && negZOrderList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (!curLayer->isComposited())
+ return true;
+ }
+ }
+
+ Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList();
+ if (posZOrderList && posZOrderList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (!curLayer->isComposited())
+ return true;
+ }
+ }
+ }
+
+ Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList();
+ if (normalFlowList && normalFlowList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (!curLayer->isComposited())
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// A layer can use direct compositing if the render layer's object is a replaced object and has no children.
+// This allows the GraphicsLayer to display the RenderLayer contents directly; it's used for images.
+bool RenderLayerBacking::canUseDirectCompositing() const
+{
+ RenderObject* renderObject = renderer();
+
+ // Reject anything that isn't an image
+ if (!renderObject->isImage())
+ return false;
+
+ if (renderObject->hasMask() || renderObject->hasReflection())
+ return false;
+
+ // Reject anything that would require the image to be drawn via the GraphicsContext,
+ // like border, shadows etc. Solid background color is OK.
+ return !hasBoxDecorationsWithBackgroundImage(renderObject->style());
+}
+
+// A "simple container layer" is a RenderLayer which has no visible content to render.
+// It may have no children, or all its children may be themselves composited.
+// This is a useful optimization, because it allows us to avoid allocating backing store.
+bool RenderLayerBacking::isSimpleContainerCompositingLayer()
+{
+ if (m_simpleCompositingLayerStatusDirty) {
+ m_isSimpleContainerCompositingLayer = canBeSimpleContainerCompositingLayer();
+ m_simpleCompositingLayerStatusDirty = false;
+ }
+
+ return m_isSimpleContainerCompositingLayer;
+}
+
+void RenderLayerBacking::detectDrawingOptimizations()
+{
+ bool drawsContent = true;
+
+ // Check if a replaced layer can be further simplified.
+ if (canUseDirectCompositing()) {
+ if (renderer()->isImage()) {
+ updateImageContents();
+ drawsContent = false;
+ }
+
+ if (rendererHasBackground())
+ m_graphicsLayer->setBackgroundColor(rendererBackgroundColor());
+ else
+ m_graphicsLayer->clearBackgroundColor();
+
+ } else {
+ m_graphicsLayer->clearBackgroundColor();
+ m_graphicsLayer->clearContents();
+
+ if (isSimpleContainerCompositingLayer())
+ drawsContent = false;
+ }
+
+ if (paintingGoesToWindow())
+ drawsContent = false;
+
+ m_graphicsLayer->setDrawsContent(drawsContent);
+}
+
+void RenderLayerBacking::invalidateDrawingOptimizations()
+{
+ m_simpleCompositingLayerStatusDirty = true;
+}
+
+void RenderLayerBacking::rendererContentChanged()
+{
+ if (canUseDirectCompositing() && renderer()->isImage())
+ updateImageContents();
+}
+
+void RenderLayerBacking::updateImageContents()
+{
+ ASSERT(renderer()->isImage());
+ RenderImage* imageRenderer = static_cast<RenderImage*>(renderer());
+
+ CachedImage* cachedImage = imageRenderer->cachedImage();
+ if (!cachedImage)
+ return;
+
+ Image* image = cachedImage->image();
+ if (!image)
+ return;
+
+ // We have to wait until the image is fully loaded before setting it on the layer.
+ if (!cachedImage->isLoaded())
+ return;
+
+ // This is a no-op if the layer doesn't have an inner layer for the image.
+ m_graphicsLayer->setContentsToImage(image);
+
+ // Image animation is "lazy", in that it automatically stops unless someone is drawing
+ // the image. So we have to kick the animation each time; this has the downside that the
+ // image will keep animating, even if its layer is not visible.
+ image->startAnimation();
+}
+
+FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const
+{
+ RenderStyle* style = renderer()->style();
+
+ FloatPoint3D origin;
+ origin.setX(style->transformOriginX().calcFloatValue(borderBox.width()));
+ origin.setY(style->transformOriginY().calcFloatValue(borderBox.height()));
+ origin.setZ(style->transformOriginZ());
+
+ return origin;
+}
+
+FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const
+{
+ RenderStyle* style = renderer()->style();
+
+ float boxWidth = borderBox.width();
+ float boxHeight = borderBox.height();
+
+ FloatPoint origin;
+ origin.setX(style->perspectiveOriginX().calcFloatValue(boxWidth));
+ origin.setY(style->perspectiveOriginY().calcFloatValue(boxHeight));
+
+ return origin;
+}
+
+// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
+IntSize RenderLayerBacking::contentOffsetInCompostingLayer()
+{
+ if (!m_compositingContentOffsetDirty)
+ return m_compositingContentOffset;
+
+ IntRect relativeCompositingBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
+ m_compositingContentOffset = IntSize(-relativeCompositingBounds.x(), -relativeCompositingBounds.y());
+ m_compositingContentOffsetDirty = false;
+
+ return m_compositingContentOffset;
+}
+
+IntRect RenderLayerBacking::contentsBox(const GraphicsLayer*)
+{
+ if (!renderer()->isBox())
+ return IntRect();
+
+ IntRect contentsRect = toRenderBox(renderer())->contentBoxRect();
+ IntSize contentOffset = contentOffsetInCompostingLayer();
+ contentsRect.move(contentOffset);
+ return contentsRect;
+}
+
+// Map the given point from coordinates in the GraphicsLayer to RenderLayer coordinates.
+FloatPoint RenderLayerBacking::graphicsLayerToContentsCoordinates(const GraphicsLayer* graphicsLayer, const FloatPoint& point)
+{
+ return point + FloatSize(graphicsLayer->offsetFromRenderer());
+}
+
+// Map the given point from coordinates in the RenderLayer to GraphicsLayer coordinates.
+FloatPoint RenderLayerBacking::contentsToGraphicsLayerCoordinates(const GraphicsLayer* graphicsLayer, const FloatPoint& point)
+{
+ return point - FloatSize(graphicsLayer->offsetFromRenderer());
+}
+
+bool RenderLayerBacking::paintingGoesToWindow() const
+{
+ return m_owningLayer->isRootLayer();
+}
+
+void RenderLayerBacking::setContentsNeedDisplay()
+{
+ if (m_graphicsLayer)
+ m_graphicsLayer->setNeedsDisplay();
+ if (m_contentsLayer)
+ m_contentsLayer->setNeedsDisplay();
+}
+
+// r is in the coordinate space of the layer's render object
+void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r)
+{
+ if (m_graphicsLayer) {
+ FloatPoint dirtyOrigin = contentsToGraphicsLayerCoordinates(m_graphicsLayer, FloatPoint(r.x(), r.y()));
+ FloatRect dirtyRect(dirtyOrigin, r.size());
+ FloatRect bounds(FloatPoint(), m_graphicsLayer->size());
+ if (bounds.intersects(dirtyRect))
+ m_graphicsLayer->setNeedsDisplayInRect(dirtyRect);
+ }
+
+ if (m_contentsLayer) {
+ // FIXME: do incremental repaint
+ m_contentsLayer->setNeedsDisplay();
+ }
+}
+
+static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
+{
+ if (paintDirtyRect == clipRect)
+ return;
+ p->save();
+ p->clip(clipRect);
+}
+
+static void restoreClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
+{
+ if (paintDirtyRect == clipRect)
+ return;
+ p->restore();
+}
+
+// Share this with RenderLayer::paintLayer, which would have to be educated about GraphicsLayerPaintingPhase?
+void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context,
+ const IntRect& paintDirtyRect, // in the coords of rootLayer
+ bool haveTransparency, PaintRestriction paintRestriction, GraphicsLayerPaintingPhase paintingPhase,
+ RenderObject* paintingRoot)
+{
+ if (paintingGoesToWindow()) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ m_owningLayer->updateLayerListsIfNeeded();
+
+ // Calculate the clip rects we should use.
+ IntRect layerBounds, damageRect, clipRectToApply, outlineRect;
+ m_owningLayer->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
+
+ int x = layerBounds.x(); // layerBounds is computed relative to rootLayer
+ int y = layerBounds.y();
+ int tx = x - m_owningLayer->renderBoxX();
+ int ty = y - m_owningLayer->renderBoxY();
+
+ // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
+ // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
+ // Else, our renderer tree may or may not contain the painting root, so we pass that root along
+ // so it will be tested against as we decend through the renderers.
+ RenderObject *paintingRootForRenderer = 0;
+ if (paintingRoot && !renderer()->isDescendantOf(paintingRoot))
+ paintingRootForRenderer = paintingRoot;
+
+ if (paintingPhase & GraphicsLayerPaintBackgroundMask) {
+ // If this is the root then we need to send in a bigger bounding box
+ // because we'll be painting the background as well (see RenderBox::paintRootBoxDecorations()).
+ IntRect paintBox = clipRectToApply;
+
+ // FIXME: do we need this code?
+ if (renderer()->node()->isDocumentNode() && renderer()->document()->isHTMLDocument()) {
+ RenderBox* box = toRenderBox(renderer());
+ int w = box->width();
+ int h = box->height();
+
+ int rw;
+ int rh;
+ if (box->view()->frameView()) {
+ rw = box->view()->frameView()->contentsWidth();
+ rh = box->view()->frameView()->contentsHeight();
+ } else {
+ rw = box->view()->width();
+ rh = box->view()->height();
+ }
+
+ int bx = tx - box->marginLeft();
+ int by = ty - box->marginTop();
+ int bw = max(w + box->marginLeft() + box->marginRight() + box->borderLeft() + box->borderRight(), rw);
+ int bh = max(h + box->marginTop() + box->marginBottom() + box->borderTop() + box->borderBottom(), rh);
+ paintBox = IntRect(bx, by, bw, bh);
+ }
+
+ // Paint our background first, before painting any child layers.
+ // Establish the clip used to paint our background.
+ setClip(context, paintDirtyRect, damageRect);
+
+ RenderObject::PaintInfo info(context, paintBox, PaintPhaseBlockBackground, false, paintingRootForRenderer, 0);
+ renderer()->paint(info, tx, ty);
+
+ // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
+ // z-index. We paint after we painted the background/border, so that the scrollbars will
+ // sit above the background/border.
+ m_owningLayer->paintOverflowControls(context, x, y, damageRect);
+
+ // Restore the clip.
+ restoreClip(context, paintDirtyRect, damageRect);
+ }
+
+ if (paintingPhase & GraphicsLayerPaintForegroundMask) {
+ // Now walk the sorted list of children with negative z-indices. Only RenderLayers without compositing layers will paint.
+ // FIXME: should these be painted as background?
+ Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList();
+ if (negZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it)
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ }
+
+ bool forceBlackText = paintRestriction == PaintRestrictionSelectionOnlyBlackText;
+ bool selectionOnly = paintRestriction == PaintRestrictionSelectionOnly || paintRestriction == PaintRestrictionSelectionOnlyBlackText;
+
+ // Set up the clip used when painting our children.
+ setClip(context, paintDirtyRect, clipRectToApply);
+ RenderObject::PaintInfo paintInfo(context, clipRectToApply,
+ selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
+ forceBlackText, paintingRootForRenderer, 0);
+ renderer()->paint(paintInfo, tx, ty);
+
+ if (!selectionOnly) {
+ paintInfo.phase = PaintPhaseFloat;
+ renderer()->paint(paintInfo, tx, ty);
+
+ paintInfo.phase = PaintPhaseForeground;
+ renderer()->paint(paintInfo, tx, ty);
+
+ paintInfo.phase = PaintPhaseChildOutlines;
+ renderer()->paint(paintInfo, tx, ty);
+ }
+
+ // Now restore our clip.
+ restoreClip(context, paintDirtyRect, clipRectToApply);
+
+ if (!outlineRect.isEmpty()) {
+ // Paint our own outline
+ RenderObject::PaintInfo paintInfo(context, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
+ setClip(context, paintDirtyRect, outlineRect);
+ renderer()->paint(paintInfo, tx, ty);
+ restoreClip(context, paintDirtyRect, outlineRect);
+ }
+
+ // Paint any child layers that have overflow.
+ Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList();
+ if (normalFlowList) {
+ for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it)
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ }
+
+ // Now walk the sorted list of children with positive z-indices.
+ Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList();
+ if (posZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it)
+ it[0]->paintLayer(rootLayer, context, paintDirtyRect, haveTransparency, paintRestriction, paintingRoot);
+ }
+
+ if (renderer()->hasMask() && !selectionOnly && !damageRect.isEmpty()) {
+ setClip(context, paintDirtyRect, damageRect);
+
+ // Paint the mask.
+ RenderObject::PaintInfo paintInfo(context, damageRect, PaintPhaseMask, false, paintingRootForRenderer, 0);
+ renderer()->paint(paintInfo, tx, ty);
+
+ // Restore the clip.
+ restoreClip(context, paintDirtyRect, damageRect);
+ }
+ }
+
+ ASSERT(!m_owningLayer->m_usedTransparency);
+}
+
+// Up-call from compositing layer drawing callback.
+void RenderLayerBacking::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase drawingPhase, const IntRect& clip)
+{
+ // We have to use the same root as for hit testing, because both methods
+ // can compute and cache clipRects.
+ IntRect enclosingBBox = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
+
+ IntRect clipRect(clip);
+
+ // Set up the coordinate space to be in the layer's rendering coordinates.
+ context.translate(-enclosingBBox.x(), -enclosingBBox.y());
+
+ // Offset the clip.
+ clipRect.move(enclosingBBox.x(), enclosingBBox.y());
+
+ // The dirtyRect is in the coords of the painting root.
+ IntRect dirtyRect = enclosingBBox;
+ dirtyRect.intersect(clipRect);
+
+ paintIntoLayer(m_owningLayer, &context, dirtyRect, false, PaintRestrictionNone, drawingPhase, renderer());
+}
+
+bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes)
+{
+ bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
+ bool hasTransform = keyframes.containsProperty(CSSPropertyWebkitTransform);
+
+ if (!hasOpacity && !hasTransform)
+ return false;
+
+ GraphicsLayer::TransformValueList transformVector;
+ GraphicsLayer::FloatValueList opacityVector;
+
+ for (Vector<KeyframeValue>::const_iterator it = keyframes.beginKeyframes(); it != keyframes.endKeyframes(); ++it) {
+ const RenderStyle* keyframeStyle = it->style();
+ float key = it->key();
+
+ if (!keyframeStyle)
+ continue;
+
+ // get timing function
+ const TimingFunction* tf = keyframeStyle->hasAnimations() ? &((*keyframeStyle->animations()).animation(0)->timingFunction()) : 0;
+
+ if (hasTransform)
+ transformVector.insert(key, &(keyframeStyle->transform()), tf);
+
+ if (hasOpacity)
+ opacityVector.insert(key, keyframeStyle->opacity(), tf);
+ }
+
+ bool didAnimateTransform = !hasTransform;
+ bool didAnimateOpacity = !hasOpacity;
+
+ if (hasTransform && m_graphicsLayer->animateTransform(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, beginTime, false))
+ didAnimateTransform = true;
+
+ if (hasOpacity && m_graphicsLayer->animateFloat(AnimatedPropertyOpacity, opacityVector, anim, beginTime))
+ didAnimateOpacity = true;
+
+ return didAnimateTransform && didAnimateOpacity;
+}
+
+bool RenderLayerBacking::startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
+{
+ bool didAnimate = false;
+ ASSERT(property != cAnimateAll);
+
+ if (property == (int)CSSPropertyOpacity) {
+ const Animation* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
+ if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
+ // If beginTime is not 0, we are restarting this transition, so first set the from value
+ // in case it was smashed by a previous animation.
+ if (beginTime > 0)
+ m_graphicsLayer->setOpacity(compositingOpacity(fromStyle->opacity()), 0, 0);
+
+ if (m_graphicsLayer->setOpacity(compositingOpacity(toStyle->opacity()), opacityAnim, beginTime))
+ didAnimate = true;
+ }
+ }
+
+ if (property == (int)CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) {
+ // We get a TransformOperation, which is a linked list of primitive operations and their arguments.
+ // Arguments can be floats or Length values, which need to be converted to numbers using
+ // val.calcFloatValue(renderer()->width()) (or height()).
+ const Animation* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
+ if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
+ GraphicsLayer::TransformValueList transformVector;
+ transformVector.insert(0, &fromStyle->transform(), 0);
+ transformVector.insert(1, &toStyle->transform(), 0);
+ if (m_graphicsLayer->animateTransform(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, beginTime, true))
+ didAnimate = true;
+ }
+ }
+
+ return didAnimate;
+}
+
+void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
+{
+ renderer()->animation()->notifyAnimationStarted(renderer(), time);
+}
+
+void RenderLayerBacking::animationFinished(const String& name, int index, bool reset)
+{
+ m_graphicsLayer->removeFinishedAnimations(name, index, reset);
+}
+
+void RenderLayerBacking::transitionFinished(int property)
+{
+ AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
+ if (animatedProperty != AnimatedPropertyInvalid)
+ m_graphicsLayer->removeFinishedTransitions(animatedProperty);
+}
+
+void RenderLayerBacking::suspendAnimations()
+{
+ m_graphicsLayer->suspendAnimations();
+}
+
+void RenderLayerBacking::resumeAnimations()
+{
+ m_graphicsLayer->resumeAnimations();
+}
+
+int RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
+{
+ int cssProperty = CSSPropertyInvalid;
+ switch (property) {
+ case AnimatedPropertyWebkitTransform:
+ cssProperty = CSSPropertyWebkitTransform;
+ break;
+ case AnimatedPropertyOpacity:
+ cssProperty = CSSPropertyOpacity;
+ break;
+ case AnimatedPropertyBackgroundColor:
+ cssProperty = CSSPropertyBackgroundColor;
+ break;
+ case AnimatedPropertyInvalid:
+ ASSERT_NOT_REACHED();
+ }
+ return cssProperty;
+}
+
+AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(int cssProperty)
+{
+ switch (cssProperty) {
+ case CSSPropertyWebkitTransform:
+ return AnimatedPropertyWebkitTransform;
+ case CSSPropertyOpacity:
+ return AnimatedPropertyOpacity;
+ case CSSPropertyBackgroundColor:
+ return AnimatedPropertyBackgroundColor;
+ // It's fine if we see other css properties here; they are just not accelerated.
+ }
+ return AnimatedPropertyInvalid;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
new file mode 100644
index 0000000..46b81ad
--- /dev/null
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderLayerBacking_h
+#define RenderLayerBacking_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "FloatPoint.h"
+#include "FloatPoint3D.h"
+#include "GraphicsLayer.h"
+#include "GraphicsLayerClient.h"
+#include "RenderLayer.h"
+#include "TransformationMatrix.h"
+
+namespace WebCore {
+
+class KeyframeList;
+class RenderLayerCompositor;
+
+// RenderLayerBacking controls the compositing behavior for a single RenderLayer.
+// It holds the various GraphicsLayers, and makes decisions about intra-layer rendering
+// optimizations.
+//
+// There is one RenderLayerBacking for each RenderLayer that is composited.
+
+class RenderLayerBacking : public GraphicsLayerClient {
+public:
+ RenderLayerBacking(RenderLayer*);
+ ~RenderLayerBacking();
+
+ RenderLayer* owningLayer() const { return m_owningLayer; }
+
+ void updateAfterLayout();
+
+ // Returns true if layer configuration changed.
+ bool updateGraphicsLayers(bool needsContentsLayer, bool needsUpperClippingLayer, bool needsLowerClippingLayer, bool needsRepaint);
+ void updateGraphicsLayerGeometry();
+ void updateInternalHierarchy();
+
+ GraphicsLayer* graphicsLayer() const { return m_graphicsLayer; }
+
+ // Layer to clip children
+ bool hasClippingLayer() const { return m_clippingLayer != 0; }
+ GraphicsLayer* clippingLayer() const { return m_clippingLayer; }
+
+ // Layer to get clipped by ancestor
+ bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer != 0; }
+ GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer; }
+
+ bool hasContentsLayer() const { return m_contentsLayer != 0; }
+ GraphicsLayer* contentsLayer() const { return m_contentsLayer; }
+
+ GraphicsLayer* parentForSublayers() const { return m_clippingLayer ? m_clippingLayer : m_graphicsLayer; }
+ GraphicsLayer* childForSuperlayers() const { return m_ancestorClippingLayer ? m_ancestorClippingLayer : m_graphicsLayer; }
+
+ // RenderLayers with backing normally short-circuit paintLayer() because
+ // their content is rendered via callbacks from GraphicsLayer. However, the document
+ // layer is special, because it has a GraphicsLayer to act as a container for the GraphicsLayers
+ // for descendants, but its contents usually render into the window (in which case this returns true).
+ // This returns false for other layers, and when the document layer actually needs to paint into its backing store
+ // for some reason.
+ bool paintingGoesToWindow() const;
+
+ void setContentsNeedDisplay();
+ // r is in the coordinate space of the layer's render object
+ void setContentsNeedDisplayInRect(const IntRect& r);
+
+ // Notification from the renderer that its content changed; used by RenderImage.
+ void rendererContentChanged();
+
+ // Interface to start, finish, suspend and resume animations and transitions
+ bool startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes);
+ bool startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle);
+ void animationFinished(const String& name, int index, bool reset);
+ void transitionFinished(int property);
+
+ void suspendAnimations();
+ void resumeAnimations();
+
+ FloatPoint graphicsLayerToContentsCoordinates(const GraphicsLayer*, const FloatPoint&);
+ FloatPoint contentsToGraphicsLayerCoordinates(const GraphicsLayer*, const FloatPoint&);
+
+ void detectDrawingOptimizations();
+ void invalidateDrawingOptimizations();
+
+ // GraphicsLayerClient interface
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double startTime);
+
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip);
+
+ virtual IntRect contentsBox(const GraphicsLayer*);
+
+private:
+ void createGraphicsLayer();
+ void destroyGraphicsLayer();
+
+ RenderBoxModelObject* renderer() const { return m_owningLayer->renderer(); }
+ RenderLayerCompositor* compositor() const { return m_owningLayer->compositor(); }
+
+ bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
+ bool updateContentsLayer(bool needsContentsLayer);
+
+ IntSize contentOffsetInCompostingLayer();
+ // Result is transform origin in pixels.
+ FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
+ // Result is perspective origin in pixels.
+ FloatPoint computePerspectiveOrigin(const IntRect& borderBox) const;
+
+ void updateLayerOpacity();
+ void updateLayerTransform();
+
+ // Return the opacity value that this layer should use for compositing.
+ float compositingOpacity(float rendererOpacity) const;
+
+ // Returns true if this RenderLayer only has content that can be rendered directly
+ // by the compositing layer, without drawing (e.g. solid background color).
+ bool isSimpleContainerCompositingLayer();
+ // Returns true if we can optimize the RenderLayer to draw the replaced content
+ // directly into a compositing buffer
+ bool canUseDirectCompositing() const;
+ void updateImageContents();
+
+ bool rendererHasBackground() const;
+ const Color& rendererBackgroundColor() const;
+
+ bool canBeSimpleContainerCompositingLayer() const;
+ bool hasNonCompositingContent() const;
+
+ void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
+ bool haveTransparency, PaintRestriction paintRestriction, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
+
+ static int graphicsLayerToCSSProperty(AnimatedPropertyID);
+ static AnimatedPropertyID cssToGraphicsLayerProperty(int);
+
+private:
+ RenderLayer* m_owningLayer;
+
+ GraphicsLayer* m_ancestorClippingLayer; // only used if we are clipped by an ancestor which is not a stacking context
+ GraphicsLayer* m_graphicsLayer;
+ GraphicsLayer* m_contentsLayer; // only used in cases where we need to draw the foreground separately
+ GraphicsLayer* m_clippingLayer; // only used if we have clipping on a stacking context, with compositing children
+
+ IntSize m_compositingContentOffset;
+
+ bool m_isSimpleContainerCompositingLayer : 1; // is this compositing layer able to be simplified
+ bool m_simpleCompositingLayerStatusDirty : 1; // set if the test for simple layers needs to be redone
+
+ bool m_compositingContentOffsetDirty: 1;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif // RenderLayerBacking_h
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
new file mode 100644
index 0000000..cbb3df7
--- /dev/null
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -0,0 +1,803 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+
+#include "AnimationController.h"
+#include "ChromeClient.h"
+#include "CSSPropertyNames.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "GraphicsLayer.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
+#include "Page.h"
+#include "RenderLayerBacking.h"
+#include "RenderView.h"
+
+#if PROFILE_LAYER_REBUILD
+#include <wtf/CurrentTime.h>
+#endif
+
+#ifndef NDEBUG
+#include "CString.h"
+#include "RenderTreeAsText.h"
+#endif
+
+#if ENABLE(3D_RENDERING)
+// This symbol is used to determine from a script whether 3D rendering is enabled (via 'nm').
+bool WebCoreHas3DRendering = true;
+#endif
+
+namespace WebCore {
+
+struct CompositingState {
+ CompositingState(RenderLayer* compAncestor)
+ : m_subtreeIsCompositing(false)
+ , m_compositingAncestor(compAncestor)
+#ifndef NDEBUG
+ , m_depth(0)
+#endif
+ {
+ }
+
+ bool m_subtreeIsCompositing;
+ RenderLayer* m_compositingAncestor;
+#ifndef NDEBUG
+ int m_depth;
+#endif
+};
+
+static TransformationMatrix flipTransform()
+{
+ TransformationMatrix flipper;
+ flipper.flipY();
+ return flipper;
+}
+
+RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
+ : m_renderView(renderView)
+ , m_rootPlatformLayer(0)
+ , m_compositing(false)
+ , m_rootLayerAttached(false)
+ , m_compositingLayersNeedUpdate(false)
+#if PROFILE_LAYER_REBUILD
+ , m_rootLayerUpdateCount(0)
+#endif // PROFILE_LAYER_REBUILD
+{
+}
+
+RenderLayerCompositor::~RenderLayerCompositor()
+{
+ ASSERT(!m_rootLayerAttached);
+ delete m_rootPlatformLayer;
+}
+
+void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
+{
+ if (enable != m_compositing) {
+ m_compositing = enable;
+
+ // We never go out of compositing mode for a given page,
+ // but if all the layers disappear, we'll just be left with
+ // the empty root layer, which has minimal overhead.
+ if (m_compositing)
+ ensureRootPlatformLayer();
+ }
+}
+
+void RenderLayerCompositor::setCompositingLayersNeedUpdate(bool needUpdate)
+{
+ if (inCompositingMode())
+ m_compositingLayersNeedUpdate = needUpdate;
+}
+
+void RenderLayerCompositor::updateCompositingLayers(RenderLayer* updateRoot)
+{
+ if (!m_compositingLayersNeedUpdate)
+ return;
+
+ ASSERT(inCompositingMode());
+
+ if (!updateRoot) {
+ // Only clear the flag if we're updating the entire hierarchy
+ m_compositingLayersNeedUpdate = false;
+ updateRoot = rootRenderLayer();
+ }
+
+#if PROFILE_LAYER_REBUILD
+ ++m_rootLayerUpdateCount;
+
+ double startTime = WTF::currentTime();
+#endif
+
+ // Go through the layers in presentation order, so that we can compute which
+ // RLs need compositing layers.
+ // FIXME: we could maybe do this in one pass, but the parenting logic would be more
+ // complex.
+ {
+ CompositingState compState(updateRoot);
+ computeCompositingRequirements(updateRoot, compState);
+ }
+
+ // Now create and parent the compositing layers.
+ {
+ CompositingState compState(updateRoot);
+ rebuildCompositingLayerTree(updateRoot, compState);
+ }
+
+#if PROFILE_LAYER_REBUILD
+ double endTime = WTF::currentTime();
+ if (!updateRoot)
+ fprintf(stderr, "Update %d: computeCompositingRequirements for the world took %fms\n"
+ m_rootLayerUpdateCount, 1000.0 * (endTime - startTime));
+#endif
+ ASSERT(updateRoot || !m_compositingLayersNeedUpdate);
+}
+
+bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, StyleDifference diff)
+{
+ bool needsLayer = needsToBeComposited(layer);
+ bool layerChanged = false;
+
+ RenderBoxModelObject* repaintContainer = 0;
+ IntRect repaintRect;
+
+ if (needsLayer) {
+ enableCompositingMode();
+ if (!layer->backing()) {
+ // Get the repaint container before we make backing for this layer
+ repaintContainer = layer->renderer()->containerForRepaint();
+ repaintRect = calculateCompositedBounds(layer, repaintContainer ? repaintContainer->layer() : layer->root());
+
+ layer->ensureBacking();
+ layerChanged = true;
+ }
+ } else {
+ if (layer->backing()) {
+ layer->clearBacking();
+ // Get the repaint container now that we've cleared the backing
+ repaintContainer = layer->renderer()->containerForRepaint();
+ repaintRect = calculateCompositedBounds(layer, repaintContainer ? repaintContainer->layer() : layer->root());
+ layerChanged = true;
+ }
+ }
+
+ if (layerChanged) {
+ // Invalidate the destination into which this layer used to render.
+ layer->renderer()->repaintUsingContainer(repaintContainer, repaintRect);
+
+ if (!repaintContainer || repaintContainer == m_renderView) {
+ // The contents of this layer may be moving between the window
+ // and a GraphicsLayer, so we need to make sure the window system
+ // synchronizes those changes on the screen.
+ m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
+ }
+ }
+
+ if (!needsLayer)
+ return layerChanged;
+
+ if (layer->backing()->updateGraphicsLayers(needsContentsCompositingLayer(layer),
+ clippedByAncestor(layer),
+ clipsCompositingDescendants(layer),
+ diff >= StyleDifferenceRepaint))
+ layerChanged = true;
+
+ return layerChanged;
+}
+
+// The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
+// RenderLayers that are rendered by the composited RenderLayer.
+IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, IntRect* layerBoundingBox)
+{
+ IntRect boundingBoxRect, unionBounds;
+ boundingBoxRect = unionBounds = layer->localBoundingBox();
+
+ ASSERT(layer->isStackingContext() || (!layer->m_posZOrderList || layer->m_posZOrderList->size() == 0));
+
+ Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();
+ if (negZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (!curLayer->isComposited()) {
+ IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
+ unionBounds.unite(childUnionBounds);
+ }
+ }
+ }
+
+ Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();
+ if (posZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (!curLayer->isComposited()) {
+ IntRect childUnionBounds = calculateCompositedBounds(curLayer, layer);
+ unionBounds.unite(childUnionBounds);
+ }
+ }
+ }
+
+ Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();
+ if (normalFlowList) {
+ for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (!curLayer->isComposited()) {
+ IntRect curAbsBounds = calculateCompositedBounds(curLayer, layer);
+ unionBounds.unite(curAbsBounds);
+ }
+ }
+ }
+
+ if (!layer->isComposited() && layer->transform()) {
+ TransformationMatrix* affineTrans = layer->transform();
+ boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
+ unionBounds = affineTrans->mapRect(unionBounds);
+ }
+
+ int ancestorRelX = 0, ancestorRelY = 0;
+ layer->convertToLayerCoords(ancestorLayer, ancestorRelX, ancestorRelY);
+ unionBounds.move(ancestorRelX, ancestorRelY);
+
+ if (layerBoundingBox) {
+ boundingBoxRect.move(ancestorRelX, ancestorRelY);
+ *layerBoundingBox = boundingBoxRect;
+ }
+
+ return unionBounds;
+}
+
+void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
+{
+ setCompositingLayersNeedUpdate();
+}
+
+void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
+{
+ if (child->isComposited())
+ setCompositingParent(child, 0);
+
+ // If the document is being torn down (document's renderer() is null), then there's
+ // no need to do any layer updating.
+ if (parent->renderer()->documentBeingDestroyed())
+ return;
+
+ RenderLayer* compLayer = parent->enclosingCompositingLayer();
+ if (compLayer) {
+ IntRect ancestorRect = calculateCompositedBounds(child, compLayer);
+ compLayer->setBackingNeedsRepaintInRect(ancestorRect);
+ // The contents of this layer may be moving from a GraphicsLayer to the window,
+ // so we need to make sure the window system synchronizes those changes on the screen.
+ m_renderView->frameView()->setNeedsOneShotDrawingSynchronization();
+ }
+
+ setCompositingLayersNeedUpdate();
+}
+
+RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
+{
+ for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
+ if (curr->isStackingContext())
+ return 0;
+
+ if (curr->renderer()->hasOverflowClip())
+ return curr;
+ }
+ return 0;
+}
+
+// Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
+// For the z-order children of a compositing layer:
+// If a child layers has a compositing layer, then all subsequent layers must
+// be compositing in order to render above that layer.
+//
+// If a child in the negative z-order list is compositing, then the layer itself
+// must be compositing so that its contents render over that child.
+// This implies that its positive z-index children must also be compositing.
+//
+void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, struct CompositingState& ioCompState)
+{
+ layer->updateLayerPosition();
+ layer->updateZOrderLists();
+ layer->updateNormalFlowList();
+
+ // Clear the flag
+ layer->setHasCompositingDescendant(false);
+ layer->setMustOverlayCompositedLayers(ioCompState.m_subtreeIsCompositing);
+
+ const bool isCompositingLayer = needsToBeComposited(layer);
+ ioCompState.m_subtreeIsCompositing = isCompositingLayer;
+
+ CompositingState childState = ioCompState;
+ if (isCompositingLayer)
+ childState.m_compositingAncestor = layer;
+
+ // The children of this stacking context don't need to composite, unless there is
+ // a compositing layer among them, so start by assuming false.
+ childState.m_subtreeIsCompositing = false;
+
+#ifndef NDEBUG
+ ++childState.m_depth;
+#endif
+
+ if (layer->isStackingContext()) {
+ ASSERT(!layer->m_zOrderListsDirty);
+ Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();
+ if (negZOrderList && negZOrderList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ computeCompositingRequirements(curLayer, childState);
+
+ // if we have to make a layer for this child, make one now so we can have a contents layer
+ // (since we need to ensure that the -ve z-order child renders underneath our contents)
+ if (childState.m_subtreeIsCompositing) {
+ // make |this| compositing
+ layer->setMustOverlayCompositedLayers(true);
+ childState.m_compositingAncestor = layer;
+ }
+ }
+ }
+ }
+
+ ASSERT(!layer->m_normalFlowListDirty);
+ Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();
+ if (normalFlowList && normalFlowList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ computeCompositingRequirements(curLayer, childState);
+ }
+ }
+
+ if (layer->isStackingContext()) {
+ Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();
+ if (posZOrderList && posZOrderList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ computeCompositingRequirements(curLayer, childState);
+ }
+ }
+ }
+
+ // If we have a software transform, and we have layers under us, we need to also
+ // be composited. Also, if we have opacity < 1, then we need to be a layer so that
+ // the child layers are opaque, then rendered with opacity on this layer.
+ if (childState.m_subtreeIsCompositing &&
+ (layer->renderer()->hasTransform() || layer->renderer()->style()->opacity() < 1))
+ layer->setMustOverlayCompositedLayers(true);
+
+ // Subsequent layers in the parent stacking context also need to composite.
+ if (childState.m_subtreeIsCompositing)
+ ioCompState.m_subtreeIsCompositing = true;
+
+ // Set the flag to say that this SC has compositing children.
+ // this can affect the answer to needsToBeComposited() when clipping,
+ // but that's ok here.
+ layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
+}
+
+void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
+{
+ ASSERT(childLayer->isComposited());
+ ASSERT(!parentLayer || parentLayer->isComposited());
+
+ if (parentLayer) {
+ GraphicsLayer* hostingLayer = parentLayer->backing()->parentForSublayers();
+ GraphicsLayer* hostedLayer = childLayer->backing()->childForSuperlayers();
+
+ hostingLayer->addChild(hostedLayer);
+ } else
+ childLayer->backing()->childForSuperlayers()->removeFromParent();
+
+ // FIXME: setCompositingParent() is only called at present by rebuildCompositingLayerTree(),
+ // which calls updateGraphicsLayerGeometry via updateLayerCompositingState(), so this should
+ // be optimized.
+ if (parentLayer)
+ childLayer->backing()->updateGraphicsLayerGeometry();
+}
+
+void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
+{
+ ASSERT(layer->isComposited());
+
+ GraphicsLayer* hostingLayer = layer->backing()->parentForSublayers();
+ hostingLayer->removeAllChildren();
+}
+
+void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer)
+{
+ ASSERT(layer->isComposited());
+
+ GraphicsLayer* layerAnchor = layer->backing()->childForSuperlayers();
+
+ if (layerAnchor->parent() != m_rootPlatformLayer) {
+ layerAnchor->removeFromParent();
+ if (m_rootPlatformLayer)
+ m_rootPlatformLayer->addChild(layerAnchor);
+ }
+}
+
+void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState& ioCompState)
+{
+ updateLayerCompositingState(layer, StyleDifferenceEqual);
+
+ // host the document layer in the RenderView's root layer
+ if (layer->isRootLayer())
+ parentInRootLayer(layer);
+
+ CompositingState childState = ioCompState;
+ if (layer->isComposited())
+ childState.m_compositingAncestor = layer;
+
+#ifndef NDEBUG
+ ++childState.m_depth;
+#endif
+
+ RenderLayerBacking* layerBacking = layer->backing();
+
+ // FIXME: make this more incremental
+ if (layer->isComposited()) {
+ layerBacking->parentForSublayers()->removeAllChildren();
+ layerBacking->updateInternalHierarchy();
+ }
+
+ // The children of this stacking context don't need to composite, unless there is
+ // a compositing layer among them, so start by assuming false.
+ childState.m_subtreeIsCompositing = false;
+
+ if (layer->isStackingContext()) {
+ ASSERT(!layer->m_zOrderListsDirty);
+
+ Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();
+ if (negZOrderList && negZOrderList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ rebuildCompositingLayerTree(curLayer, childState);
+ if (curLayer->isComposited())
+ setCompositingParent(curLayer, childState.m_compositingAncestor);
+ }
+ }
+
+ if (layerBacking && layerBacking->contentsLayer()) {
+ // we only have a contents layer if we have an m_layer
+ layerBacking->contentsLayer()->removeFromParent();
+
+ GraphicsLayer* hostingLayer = layerBacking->clippingLayer() ? layerBacking->clippingLayer() : layerBacking->graphicsLayer();
+ hostingLayer->addChild(layerBacking->contentsLayer());
+ }
+ }
+
+ ASSERT(!layer->m_normalFlowListDirty);
+ Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();
+ if (normalFlowList && normalFlowList->size() > 0) {
+ for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ rebuildCompositingLayerTree(curLayer, childState);
+ if (curLayer->isComposited())
+ setCompositingParent(curLayer, childState.m_compositingAncestor);
+ }
+ }
+
+ if (layer->isStackingContext()) {
+ Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();
+ if (posZOrderList && posZOrderList->size() > 0) {
+ for (Vector<RenderLayer*>::const_iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ rebuildCompositingLayerTree(curLayer, childState);
+ if (curLayer->isComposited())
+ setCompositingParent(curLayer, childState.m_compositingAncestor);
+ }
+ }
+ }
+}
+
+void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
+{
+ recursiveRepaintLayerRect(rootRenderLayer(), absRect);
+}
+
+void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
+{
+ if (layer->isComposited())
+ layer->setBackingNeedsRepaintInRect(rect);
+
+ if (layer->hasCompositingDescendant()) {
+ Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();
+ if (negZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ int x = 0, y = 0;
+ curLayer->convertToLayerCoords(layer, x, y);
+ IntRect childRect(rect);
+ childRect.move(-x, -y);
+ recursiveRepaintLayerRect(curLayer, childRect);
+ }
+ }
+
+ Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();
+ if (posZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ int x = 0, y = 0;
+ curLayer->convertToLayerCoords(layer, x, y);
+ IntRect childRect(rect);
+ childRect.move(-x, -y);
+ recursiveRepaintLayerRect(curLayer, childRect);
+ }
+ }
+
+ Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();
+ if (normalFlowList) {
+ for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ int x = 0, y = 0;
+ curLayer->convertToLayerCoords(layer, x, y);
+ IntRect childRect(rect);
+ childRect.move(-x, -y);
+ recursiveRepaintLayerRect(curLayer, childRect);
+ }
+ }
+ }
+}
+
+RenderLayer* RenderLayerCompositor::rootRenderLayer() const
+{
+ return m_renderView->layer();
+}
+
+GraphicsLayer* RenderLayerCompositor::rootPlatformLayer() const
+{
+ return m_rootPlatformLayer;
+}
+
+void RenderLayerCompositor::didMoveOnscreen()
+{
+ if (!m_rootPlatformLayer)
+ return;
+
+ Frame* frame = m_renderView->frameView()->frame();
+ Page* page = frame ? frame->page() : 0;
+ if (!page)
+ return;
+
+ page->chrome()->client()->attachRootGraphicsLayer(frame, m_rootPlatformLayer);
+ m_rootLayerAttached = true;
+}
+
+void RenderLayerCompositor::willMoveOffscreen()
+{
+ if (!m_rootPlatformLayer || !m_rootLayerAttached)
+ return;
+
+ Frame* frame = m_renderView->frameView()->frame();
+ Page* page = frame ? frame->page() : 0;
+ if (!page)
+ return;
+
+ page->chrome()->client()->attachRootGraphicsLayer(frame, 0);
+ m_rootLayerAttached = false;
+}
+
+void RenderLayerCompositor::updateRootLayerPosition()
+{
+ if (m_rootPlatformLayer)
+ m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
+}
+
+bool RenderLayerCompositor::has3DContent() const
+{
+ return layerHas3DContent(rootRenderLayer());
+}
+
+bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
+{
+ return requiresCompositingLayer(layer) || layer->mustOverlayCompositedLayers();
+}
+
+#define VERBOSE_COMPOSITINGLAYER 0
+
+// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
+// Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
+// static
+bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
+{
+ // FIXME: cache the result of these tests?
+#if VERBOSE_COMPOSITINGLAYER
+ bool gotReason = false;
+
+ if (!gotReason && inCompositingMode() && layer->isRootLayer()) {
+ fprintf(stderr, "RenderLayer %p requires compositing layer because: it's the document root\n", layer);
+ gotReason = true;
+ }
+
+ if (!gotReason && requiresCompositingForTransform(layer->renderer())) {
+ fprintf(stderr, "RenderLayer %p requires compositing layer because: it has 3d transform, perspective, backface, or animating transform\n", layer);
+ gotReason = true;
+ }
+
+ if (!gotReason && layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
+ fprintf(stderr, "RenderLayer %p requires compositing layer because: it has backface-visibility: hidden\n", layer);
+ gotReason = true;
+ }
+
+ if (!gotReason && clipsCompositingDescendants(layer)) {
+ fprintf(stderr, "RenderLayer %p requires compositing layer because: it has overflow clip\n", layer);
+ gotReason = true;
+ }
+
+ if (!gotReason && requiresCompositingForAnimation(layer->renderer())) {
+ fprintf(stderr, "RenderLayer %p requires compositing layer because: it has a running transition for opacity or transform\n", layer);
+ gotReason = true;
+ }
+
+ if (!gotReason)
+ fprintf(stderr, "RenderLayer %p does not require compositing layer\n", layer);
+#endif
+
+ // The root layer always has a compositing layer, but it may not have backing.
+ return (inCompositingMode() && layer->isRootLayer()) ||
+ requiresCompositingForTransform(layer->renderer()) ||
+ layer->renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden ||
+ clipsCompositingDescendants(layer) ||
+ requiresCompositingForAnimation(layer->renderer());
+}
+
+// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
+// up to the enclosing compositing ancestor. This is required because compositing layers are parented
+// according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
+// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
+// but a sibling in the z-order hierarchy.
+bool RenderLayerCompositor::clippedByAncestor(RenderLayer* layer) const
+{
+ if (!layer->isComposited() || !layer->parent())
+ return false;
+
+ RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
+ if (!compositingAncestor)
+ return false;
+
+ // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
+ // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
+ // and layer.
+ RenderLayer* computeClipRoot = 0;
+ RenderLayer* curr = layer;
+ while (curr) {
+ RenderLayer* next = curr->parent();
+ if (next == compositingAncestor) {
+ computeClipRoot = curr;
+ break;
+ }
+ curr = next;
+ }
+
+ if (!computeClipRoot || computeClipRoot == layer)
+ return false;
+
+ ClipRects parentRects;
+ layer->parentClipRects(computeClipRoot, parentRects, true);
+
+ return parentRects.overflowClipRect() != ClipRects::infiniteRect();
+}
+
+// Return true if the given layer is a stacking context and has compositing child
+// layers that it needs to clip. In this case we insert a clipping GraphicsLayer
+// into the hierarchy between this layer and its children in the z-order hierarchy.
+bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
+{
+ // FIXME: need to look at hasClip() too eventually
+ return layer->hasCompositingDescendant() &&
+ layer->renderer()->hasOverflowClip();
+}
+
+bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer)
+{
+ RenderStyle* style = renderer->style();
+ // Note that we ask the renderer if it has a transform, because the style may have transforms,
+ // but the renderer may be an inline that doesn't suppport them.
+ return renderer->hasTransform() && (style->transform().has3DOperation() || style->transformStyle3D() == TransformStyle3DPreserve3D || style->hasPerspective());
+}
+
+bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer)
+{
+ AnimationController* animController = renderer->animation();
+ if (animController)
+ return animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyOpacity) ||
+ animController->isAnimatingPropertyOnRenderer(renderer, CSSPropertyWebkitTransform);
+ return false;
+}
+
+// If an element has negative z-index children, those children render in front of the
+// layer background, so we need an extra 'contents' layer for the foreground of the layer
+// object.
+bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
+{
+ return (layer->m_negZOrderList && layer->m_negZOrderList->size() > 0);
+}
+
+void RenderLayerCompositor::ensureRootPlatformLayer()
+{
+ if (m_rootPlatformLayer)
+ return;
+
+ m_rootPlatformLayer = GraphicsLayer::createGraphicsLayer(0);
+ m_rootPlatformLayer->setSize(FloatSize(m_renderView->docWidth(), m_renderView->docHeight()));
+ m_rootPlatformLayer->setPosition(FloatPoint(0, 0));
+
+ if (GraphicsLayer::graphicsContextsFlipped())
+ m_rootPlatformLayer->setChildrenTransform(flipTransform());
+
+ // Need to clip to prevent transformed content showing outside this frame
+ m_rootPlatformLayer->setMasksToBounds(true);
+
+ didMoveOnscreen();
+}
+
+bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
+{
+ const RenderStyle* style = layer->renderer()->style();
+
+ if (style &&
+ (style->transformStyle3D() == TransformStyle3DPreserve3D ||
+ style->hasPerspective() ||
+ style->transform().has3DOperation()))
+ return true;
+
+ if (layer->isStackingContext()) {
+ Vector<RenderLayer*>* negZOrderList = layer->negZOrderList();
+ if (negZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = negZOrderList->begin(); it != negZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (layerHas3DContent(curLayer))
+ return true;
+ }
+ }
+
+ Vector<RenderLayer*>* posZOrderList = layer->posZOrderList();
+ if (posZOrderList) {
+ for (Vector<RenderLayer*>::iterator it = posZOrderList->begin(); it != posZOrderList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (layerHas3DContent(curLayer))
+ return true;
+ }
+ }
+ }
+
+ Vector<RenderLayer*>* normalFlowList = layer->normalFlowList();
+ if (normalFlowList) {
+ for (Vector<RenderLayer*>::iterator it = normalFlowList->begin(); it != normalFlowList->end(); ++it) {
+ RenderLayer* curLayer = (*it);
+ if (layerHas3DContent(curLayer))
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+
diff --git a/WebCore/rendering/RenderLayerCompositor.h b/WebCore/rendering/RenderLayerCompositor.h
new file mode 100644
index 0000000..dfceb1f
--- /dev/null
+++ b/WebCore/rendering/RenderLayerCompositor.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderLayerCompositor_h
+#define RenderLayerCompositor_h
+
+#include "RenderLayer.h"
+
+namespace WebCore {
+
+#define PROFILE_LAYER_REBUILD 0
+
+class GraphicsLayer;
+
+// RenderLayerCompositor manages the hierarchy of
+// composited RenderLayers. It determines which RenderLayers
+// become compositing, and creates and maintains a hierarchy of
+// GraphicsLayers based on the RenderLayer painting order.
+//
+// There is one RenderLayerCompositor per RenderView.
+
+class RenderLayerCompositor {
+public:
+
+ RenderLayerCompositor(RenderView*);
+ ~RenderLayerCompositor();
+
+ // Return true if this RenderView is in "compositing mode" (i.e. has one or more
+ // composited RenderLayers)
+ bool inCompositingMode() const { return m_compositing; }
+ // This will make a compositing layer at the root automatically, and hook up to
+ // the native view/window system.
+ void enableCompositingMode(bool enable = true);
+
+ void setCompositingLayersNeedUpdate(bool needUpdate = true);
+ bool compositingLayersNeedUpdate() const { return m_compositingLayersNeedUpdate; }
+
+ // Rebuild the tree of compositing layers
+ void updateCompositingLayers(RenderLayer* updateRoot = 0);
+
+ // Update the compositing state of the given layer. Returns true if that state changed
+ bool updateLayerCompositingState(RenderLayer*, StyleDifference);
+
+ // Return the bounding box required for compositing layer and its childern, relative to ancestorLayer.
+ // If layerBoundingBox is not 0, on return it contains the bounding box of this layer only.
+ IntRect calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer, IntRect* layerBoundingBox = 0);
+
+ // Notify us that a layer has been added or removed
+ void layerWasAdded(RenderLayer* parent, RenderLayer* child);
+ void layerWillBeRemoved(RenderLayer* parent, RenderLayer* child);
+
+ // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context
+ RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const;
+
+ // Repaint parts of all composited layers that intersect the given absolute rectangle.
+ void repaintCompositedLayersAbsoluteRect(const IntRect&);
+
+ RenderLayer* rootRenderLayer() const;
+ GraphicsLayer* rootPlatformLayer() const;
+
+ void didMoveOnscreen();
+ void willMoveOffscreen();
+
+ void updateRootLayerPosition();
+
+ // Walk the tree looking for layers with 3d transforms. Useful in case you need
+ // to know if there is non-affine content, e.g. for drawing into an image.
+ bool has3DContent() const;
+
+private:
+ // Whether the given RL needs a compositing layer.
+ bool needsToBeComposited(const RenderLayer*) const;
+ // Whether the layer has an intrinsic need for compositing layer.
+ bool requiresCompositingLayer(const RenderLayer*) const;
+
+ // Whether we need a graphics layer to do clipping by an ancestor (non-stacking-context parent with overflow).
+ bool clippedByAncestor(RenderLayer*) const;
+ // Whether we need a graphics layer to clip z-order children of the given layer.
+ bool clipsCompositingDescendants(const RenderLayer*) const;
+
+ // Whether the given layer needs an extra 'contents' layer.
+ bool needsContentsCompositingLayer(const RenderLayer*) const;
+
+ // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect.
+ void recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect);
+
+ void computeCompositingRequirements(RenderLayer*, struct CompositingState&);
+ void rebuildCompositingLayerTree(RenderLayer* layer, struct CompositingState&);
+
+ // Hook compositing layers together
+ void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
+ void removeCompositedChildren(RenderLayer*);
+
+ void parentInRootLayer(RenderLayer*);
+
+ bool layerHas3DContent(const RenderLayer*) const;
+
+ void ensureRootPlatformLayer();
+
+ // Whether a running transition or animation enforces the need for a compositing layer.
+ static bool requiresCompositingForAnimation(RenderObject*);
+ static bool requiresCompositingForTransform(RenderObject*);
+
+private:
+ RenderView* m_renderView;
+ GraphicsLayer* m_rootPlatformLayer;
+ bool m_compositing;
+ bool m_rootLayerAttached;
+ bool m_compositingLayersNeedUpdate;
+#if PROFILE_LAYER_REBUILD
+ int m_rootLayerUpdateCount;
+#endif
+};
+
+
+} // namespace WebCore
+
+#endif // RenderLayerCompositor_h
diff --git a/WebCore/rendering/RenderLegend.cpp b/WebCore/rendering/RenderLegend.cpp
deleted file mode 100644
index 1fac53f..0000000
--- a/WebCore/rendering/RenderLegend.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "RenderLegend.h"
-
-namespace WebCore {
-
-RenderLegend::RenderLegend(Node* element)
- : RenderBlock(element)
-{
-}
-
-} // namespace WebCore
diff --git a/WebCore/rendering/RenderLegend.h b/WebCore/rendering/RenderLegend.h
deleted file mode 100644
index 649f132..0000000
--- a/WebCore/rendering/RenderLegend.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This file is part of the DOM implementation for KDE.
- *
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef RenderLegend_h
-#define RenderLegend_h
-
-#include "RenderBlock.h"
-
-namespace WebCore {
-
- class RenderLegend : public RenderBlock {
- public:
- RenderLegend(Node*);
-
- virtual const char* renderName() const { return "RenderLegend"; }
- };
-
-} // namespace WebCore
-
-#endif // RenderLegend_h
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
new file mode 100644
index 0000000..00566b8
--- /dev/null
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderLineBoxList.h"
+
+#include "InlineTextBox.h"
+#include "RenderArena.h"
+#include "RenderInline.h"
+#include "RenderView.h"
+#include "RootInlineBox.h"
+
+using namespace std;
+
+namespace WebCore {
+
+#ifndef NDEBUG
+RenderLineBoxList::~RenderLineBoxList()
+{
+ ASSERT(!m_firstLineBox);
+ ASSERT(!m_lastLineBox);
+}
+#endif
+
+void RenderLineBoxList::appendLineBox(InlineFlowBox* box)
+{
+ checkConsistency();
+
+ if (!m_firstLineBox)
+ m_firstLineBox = m_lastLineBox = box;
+ else {
+ m_lastLineBox->setNextLineBox(box);
+ box->setPreviousLineBox(m_lastLineBox);
+ m_lastLineBox = box;
+ }
+
+ checkConsistency();
+}
+
+void RenderLineBoxList::deleteLineBoxTree(RenderArena* arena)
+{
+ InlineFlowBox* line = m_firstLineBox;
+ InlineFlowBox* nextLine;
+ while (line) {
+ nextLine = line->nextFlowBox();
+ line->deleteLine(arena);
+ line = nextLine;
+ }
+ m_firstLineBox = m_lastLineBox = 0;
+}
+
+void RenderLineBoxList::extractLineBox(InlineFlowBox* box)
+{
+ checkConsistency();
+
+ m_lastLineBox = box->prevFlowBox();
+ if (box == m_firstLineBox)
+ m_firstLineBox = 0;
+ if (box->prevLineBox())
+ box->prevLineBox()->setNextLineBox(0);
+ box->setPreviousLineBox(0);
+ for (InlineRunBox* curr = box; curr; curr = curr->nextLineBox())
+ curr->setExtracted();
+
+ checkConsistency();
+}
+
+void RenderLineBoxList::attachLineBox(InlineFlowBox* box)
+{
+ checkConsistency();
+
+ if (m_lastLineBox) {
+ m_lastLineBox->setNextLineBox(box);
+ box->setPreviousLineBox(m_lastLineBox);
+ } else
+ m_firstLineBox = box;
+ InlineFlowBox* last = box;
+ for (InlineFlowBox* curr = box; curr; curr = curr->nextFlowBox()) {
+ curr->setExtracted(false);
+ last = curr;
+ }
+ m_lastLineBox = last;
+
+ checkConsistency();
+}
+
+void RenderLineBoxList::removeLineBox(InlineFlowBox* box)
+{
+ checkConsistency();
+
+ if (box == m_firstLineBox)
+ m_firstLineBox = box->nextFlowBox();
+ if (box == m_lastLineBox)
+ m_lastLineBox = box->prevFlowBox();
+ if (box->nextLineBox())
+ box->nextLineBox()->setPreviousLineBox(box->prevLineBox());
+ if (box->prevLineBox())
+ box->prevLineBox()->setNextLineBox(box->nextLineBox());
+
+ checkConsistency();
+}
+
+void RenderLineBoxList::deleteLineBoxes(RenderArena* arena)
+{
+ if (m_firstLineBox) {
+ InlineRunBox* next;
+ for (InlineRunBox* curr = m_firstLineBox; curr; curr = next) {
+ next = curr->nextLineBox();
+ curr->destroy(arena);
+ }
+ m_firstLineBox = 0;
+ m_lastLineBox = 0;
+ }
+}
+
+void RenderLineBoxList::dirtyLineBoxes()
+{
+ for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
+ curr->dirtyLineBoxes();
+}
+
+void RenderLineBoxList::paint(RenderBoxModelObject* renderer, RenderObject::PaintInfo& paintInfo, int tx, int ty) const
+{
+ // Only paint during the foreground/selection phases.
+ if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseOutline
+ && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines && paintInfo.phase != PaintPhaseTextClip
+ && paintInfo.phase != PaintPhaseMask)
+ return;
+
+ ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could paint like this is if it has a layer.
+
+ // If we have no lines then we have no work to do.
+ if (!firstLineBox())
+ return;
+
+ // We can check the first box and last box and avoid painting if we don't
+ // intersect. This is a quick short-circuit that we can take to avoid walking any lines.
+ // FIXME: This check is flawed in the following extremely obscure way:
+ // if some line in the middle has a huge overflow, it might actually extend below the last line.
+ int yPos = firstLineBox()->root()->topOverflow() - renderer->maximalOutlineSize(paintInfo.phase);
+ int h = renderer->maximalOutlineSize(paintInfo.phase) + lastLineBox()->root()->bottomOverflow() - yPos;
+ yPos += ty;
+ if (yPos >= paintInfo.rect.bottom() || yPos + h <= paintInfo.rect.y())
+ return;
+
+ RenderObject::PaintInfo info(paintInfo);
+ ListHashSet<RenderInline*> outlineObjects;
+ info.outlineObjects = &outlineObjects;
+
+ // See if our root lines intersect with the dirty rect. If so, then we paint
+ // them. Note that boxes can easily overlap, so we can't make any assumptions
+ // based off positions of our first line box or our last line box.
+ RenderView* v = renderer->view();
+ bool usePrintRect = !v->printRect().isEmpty();
+ for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextFlowBox()) {
+ if (usePrintRect) {
+ // FIXME: This is a feeble effort to avoid splitting a line across two pages.
+ // It is utterly inadequate, and this should not be done at paint time at all.
+ // The whole way objects break across pages needs to be redone.
+ // Try to avoid splitting a line vertically, but only if it's less than the height
+ // of the entire page.
+ if (curr->root()->bottomOverflow() - curr->root()->topOverflow() <= v->printRect().height()) {
+ if (ty + curr->root()->bottomOverflow() > v->printRect().bottom()) {
+ if (ty + curr->root()->topOverflow() < v->truncatedAt())
+ v->setBestTruncatedAt(ty + curr->root()->topOverflow(), renderer);
+ // If we were able to truncate, don't paint.
+ if (ty + curr->root()->topOverflow() >= v->truncatedAt())
+ break;
+ }
+ }
+ }
+
+ int top = min(curr->root()->topOverflow(), curr->root()->selectionTop()) - renderer->maximalOutlineSize(info.phase);
+ int bottom = curr->root()->bottomOverflow() + renderer->maximalOutlineSize(info.phase);
+ h = bottom - top;
+ yPos = ty + top;
+ if (yPos < info.rect.bottom() && yPos + h > info.rect.y())
+ curr->paint(info, tx, ty);
+ }
+
+ if (info.phase == PaintPhaseOutline || info.phase == PaintPhaseSelfOutline || info.phase == PaintPhaseChildOutlines) {
+ ListHashSet<RenderInline*>::iterator end = info.outlineObjects->end();
+ for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects->begin(); it != end; ++it) {
+ RenderInline* flow = *it;
+ flow->paintOutline(info.context, tx, ty);
+ }
+ info.outlineObjects->clear();
+ }
+}
+
+
+bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) const
+{
+ if (hitTestAction != HitTestForeground)
+ return false;
+
+ ASSERT(renderer->isRenderBlock() || (renderer->isRenderInline() && renderer->hasLayer())); // The only way an inline could hit test like this is if it has a layer.
+
+ // If we have no lines then we have no work to do.
+ if (!firstLineBox())
+ return false;
+
+ // We can check the first box and last box and avoid hit testing if we don't
+ // contain the point. This is a quick short-circuit that we can take to avoid walking any lines.
+ // FIXME: This check is flawed in the following extremely obscure way:
+ // if some line in the middle has a huge overflow, it might actually extend below the last line.
+ if ((y >= ty + lastLineBox()->root()->bottomOverflow()) || (y < ty + firstLineBox()->root()->topOverflow()))
+ return false;
+
+ // See if our root lines contain the point. If so, then we hit test
+ // them further. Note that boxes can easily overlap, so we can't make any assumptions
+ // based off positions of our first line box or our last line box.
+ for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevFlowBox()) {
+ if (y >= ty + curr->root()->topOverflow() && y < ty + curr->root()->bottomOverflow()) {
+ bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
+ if (inside) {
+ renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, RenderObject* child)
+{
+ if (!container->parent() || (container->isRenderBlock() && (container->selfNeedsLayout() || !container->isBlockFlow())))
+ return;
+
+ // If we have no first line box, then just bail early.
+ if (!firstLineBox()) {
+ // For an empty inline, go ahead and propagate the check up to our parent, unless the parent
+ // is already dirty.
+ if (container->isInline() && !container->parent()->selfNeedsLayout())
+ container->parent()->dirtyLinesFromChangedChild(container);
+ return;
+ }
+
+ // Try to figure out which line box we belong in. First try to find a previous
+ // line box by examining our siblings. If we didn't find a line box, then use our
+ // parent's first line box.
+ RootInlineBox* box = 0;
+ RenderObject* curr = 0;
+ for (curr = child->previousSibling(); curr; curr = curr->previousSibling()) {
+ if (curr->isFloatingOrPositioned())
+ continue;
+
+ if (curr->isReplaced()) {
+ InlineBox* wrapper = toRenderBox(curr)->inlineBoxWrapper();
+ if (wrapper)
+ box = wrapper->root();
+ } else if (curr->isText()) {
+ InlineTextBox* textBox = toRenderText(curr)->lastTextBox();
+ if (textBox)
+ box = textBox->root();
+ } else if (curr->isRenderInline()) {
+ InlineRunBox* runBox = toRenderInline(curr)->lastLineBox();
+ if (runBox)
+ box = runBox->root();
+ }
+
+ if (box)
+ break;
+ }
+ if (!box)
+ box = firstLineBox()->root();
+
+ // If we found a line box, then dirty it.
+ if (box) {
+ RootInlineBox* adjacentBox;
+ box->markDirty();
+
+ // dirty the adjacent lines that might be affected
+ // NOTE: we dirty the previous line because RootInlineBox objects cache
+ // the address of the first object on the next line after a BR, which we may be
+ // invalidating here. For more info, see how RenderBlock::layoutInlineChildren
+ // calls setLineBreakInfo with the result of findNextLineBreak. findNextLineBreak,
+ // despite the name, actually returns the first RenderObject after the BR.
+ // <rdar://problem/3849947> "Typing after pasting line does not appear until after window resize."
+ adjacentBox = box->prevRootBox();
+ if (adjacentBox)
+ adjacentBox->markDirty();
+ if (child->isBR() || (curr && curr->isBR())) {
+ adjacentBox = box->nextRootBox();
+ if (adjacentBox)
+ adjacentBox->markDirty();
+ }
+ }
+}
+
+#ifndef NDEBUG
+
+void RenderLineBoxList::checkConsistency() const
+{
+#ifdef CHECK_CONSISTENCY
+ const InlineFlowBox* prev = 0;
+ for (const InlineFlowBox* child = m_firstLineBox; child != 0; child = child->nextFlowBox()) {
+ ASSERT(child->prevFlowBox() == prev);
+ prev = child;
+ }
+ ASSERT(prev == m_lastLineBox);
+#endif
+}
+
+#endif
+
+}
diff --git a/WebCore/rendering/RenderLineBoxList.h b/WebCore/rendering/RenderLineBoxList.h
new file mode 100644
index 0000000..52d7542
--- /dev/null
+++ b/WebCore/rendering/RenderLineBoxList.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 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 RenderLineBoxList_h
+#define RenderLineBoxList_h
+
+#include "RenderBox.h"
+
+namespace WebCore {
+
+class RenderLineBoxList {
+public:
+ RenderLineBoxList()
+ : m_firstLineBox(0)
+ , m_lastLineBox(0)
+ {
+ }
+
+#ifndef NDEBUG
+ ~RenderLineBoxList();
+#endif
+
+ InlineFlowBox* firstLineBox() const { return m_firstLineBox; }
+ InlineFlowBox* lastLineBox() const { return m_lastLineBox; }
+
+ void checkConsistency() const;
+
+ void appendLineBox(InlineFlowBox*);
+
+ void deleteLineBoxTree(RenderArena*);
+ void deleteLineBoxes(RenderArena*);
+
+ void extractLineBox(InlineFlowBox*);
+ void attachLineBox(InlineFlowBox*);
+ void removeLineBox(InlineFlowBox*);
+
+ void dirtyLineBoxes();
+ void dirtyLinesFromChangedChild(RenderObject* parent, RenderObject* child);
+
+ void paint(RenderBoxModelObject*, RenderObject::PaintInfo&, int x, int y) const;
+ bool hitTest(RenderBoxModelObject*, const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction) const;
+
+private:
+ // For block flows, each box represents the root inline box for a line in the
+ // paragraph.
+ // For inline flows, each box represents a portion of that inline.
+ InlineFlowBox* m_firstLineBox;
+ InlineFlowBox* m_lastLineBox;
+};
+
+
+#ifdef NDEBUG
+inline void RenderLineBoxList::checkConsistency() const
+{
+}
+#endif
+
+} // namespace WebCore
+
+#endif // RenderFlow_h
diff --git a/WebCore/rendering/RenderListBox.cpp b/WebCore/rendering/RenderListBox.cpp
index 3dddc13..50b406b 100644
--- a/WebCore/rendering/RenderListBox.cpp
+++ b/WebCore/rendering/RenderListBox.cpp
@@ -87,7 +87,7 @@ RenderListBox::~RenderListBox()
setHasVerticalScrollbar(false);
}
-void RenderListBox::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderListBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
setReplaced(isInline());
@@ -527,7 +527,7 @@ void RenderListBox::valueChanged(Scrollbar*)
m_indexOffset = newOffset;
repaint();
// Fire the scroll DOM event.
- EventTargetNodeCast(node())->dispatchEventForType(eventNames().scrollEvent, false, false);
+ node()->dispatchEventForType(eventNames().scrollEvent, false, false);
}
}
@@ -579,6 +579,29 @@ void RenderListBox::setScrollTop(int newTop)
m_vBar->setValue(index);
}
+bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
+{
+ if (!RenderBlock::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
+ return false;
+ const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(node())->listItems();
+ int size = numItems();
+ tx += this->x();
+ ty += this->y();
+ for (int i = 0; i < size; ++i) {
+ if (itemBoundingBoxRect(tx, ty, i).contains(x, y)) {
+ if (HTMLElement* node = listItems[i]) {
+ result.setInnerNode(node);
+ if (!result.innerNonSharedNode())
+ result.setInnerNonSharedNode(node);
+ result.setLocalPoint(IntPoint(x - tx, y - ty));
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
IntRect RenderListBox::controlClipRect(int tx, int ty) const
{
IntRect clipRect = contentBoxRect();
@@ -602,11 +625,11 @@ void RenderListBox::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect&
PassRefPtr<Scrollbar> RenderListBox::createScrollbar()
{
RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = style()->hasPseudoStyle(RenderStyle::SCROLLBAR);
+ bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
widget = RenderScrollbar::createCustomScrollbar(this, VerticalScrollbar, this);
else
- widget = Scrollbar::createNativeScrollbar(this, VerticalScrollbar, SmallScrollbar);
+ widget = Scrollbar::createNativeScrollbar(this, VerticalScrollbar, theme()->scrollbarControlSizeForPart(ListboxPart));
document()->view()->addChild(widget.get());
return widget.release();
}
diff --git a/WebCore/rendering/RenderListBox.h b/WebCore/rendering/RenderListBox.h
index b9cfcb1..acc313f 100644
--- a/WebCore/rendering/RenderListBox.h
+++ b/WebCore/rendering/RenderListBox.h
@@ -92,8 +92,10 @@ public:
virtual void setScrollLeft(int);
virtual void setScrollTop(int);
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
// ScrollbarClient interface.
diff --git a/WebCore/rendering/RenderListItem.cpp b/WebCore/rendering/RenderListItem.cpp
index 47158b6..fb965d2 100644
--- a/WebCore/rendering/RenderListItem.cpp
+++ b/WebCore/rendering/RenderListItem.cpp
@@ -49,7 +49,7 @@ RenderListItem::RenderListItem(Node* node)
setInline(false);
}
-void RenderListItem::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
@@ -153,11 +153,11 @@ static RenderObject* getParentOfFirstLineBox(RenderBlock* curr, RenderObject* ma
if (currChild->isTable() || !currChild->isRenderBlock())
break;
- if (curr->isListItem() && currChild->style()->htmlHacks() && currChild->element() &&
- (currChild->element()->hasTagName(ulTag)|| currChild->element()->hasTagName(olTag)))
+ if (curr->isListItem() && currChild->style()->htmlHacks() && currChild->node() &&
+ (currChild->node()->hasTagName(ulTag)|| currChild->node()->hasTagName(olTag)))
break;
- RenderObject* lineBox = getParentOfFirstLineBox(static_cast<RenderBlock*>(currChild), marker);
+ RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlock(currChild), marker);
if (lineBox)
return lineBox;
}
@@ -248,7 +248,7 @@ void RenderListItem::positionListMarker()
RootInlineBox* root = m_marker->inlineBoxWrapper()->root();
if (style()->direction() == LTR) {
- int leftLineOffset = leftRelOffset(yOffset, leftOffset(yOffset));
+ int leftLineOffset = leftRelOffset(yOffset, leftOffset(yOffset, false), false);
markerXPos = leftLineOffset - xOffset - paddingLeft() - borderLeft() + m_marker->marginLeft();
m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0);
if (markerXPos < root->leftOverflow()) {
@@ -256,7 +256,7 @@ void RenderListItem::positionListMarker()
adjustOverflow = true;
}
} else {
- int rightLineOffset = rightRelOffset(yOffset, rightOffset(yOffset));
+ int rightLineOffset = rightRelOffset(yOffset, rightOffset(yOffset, false), false);
markerXPos = rightLineOffset - xOffset + paddingRight() + borderRight() + m_marker->marginLeft();
m_marker->inlineBoxWrapper()->adjustPosition(markerXPos - markerOldX, 0);
if (markerXPos + m_marker->width() > root->rightOverflow()) {
@@ -271,7 +271,7 @@ void RenderListItem::positionListMarker()
do {
o = o->parentBox();
if (o->isRenderBlock())
- static_cast<RenderBlock*>(o)->addVisualOverflow(markerRect);
+ toRenderBlock(o)->addVisualOverflow(markerRect);
markerRect.move(-o->x(), -o->y());
} while (o != this);
}
diff --git a/WebCore/rendering/RenderListItem.h b/WebCore/rendering/RenderListItem.h
index d4dd675..91844f7 100644
--- a/WebCore/rendering/RenderListItem.h
+++ b/WebCore/rendering/RenderListItem.h
@@ -61,7 +61,7 @@ public:
const String& markerText() const;
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
void updateMarkerLocation();
diff --git a/WebCore/rendering/RenderListMarker.cpp b/WebCore/rendering/RenderListMarker.cpp
index 340db50..32b5999 100644
--- a/WebCore/rendering/RenderListMarker.cpp
+++ b/WebCore/rendering/RenderListMarker.cpp
@@ -159,7 +159,7 @@ static int toArmenianUnder10000(int number, bool upper, bool addCircumflex, UCha
int lowerOffset = upper ? 0 : 0x0030;
- if (int thousands = number / 1000)
+ if (int thousands = number / 1000) {
if (thousands == 7) {
letters[length++] = 0x0548 + lowerOffset;
letters[length++] = 0x0552 + lowerOffset;
@@ -170,6 +170,7 @@ static int toArmenianUnder10000(int number, bool upper, bool addCircumflex, UCha
if (addCircumflex)
letters[length++] = 0x0302;
}
+ }
if (int hundreds = (number / 100) % 10) {
letters[length++] = (0x0543 - 1 + lowerOffset) + hundreds;
@@ -472,7 +473,6 @@ String listMarkerText(EListStyleType type, int value)
RenderListMarker::RenderListMarker(RenderListItem* item)
: RenderBox(item->document())
, m_listItem(item)
- , m_selectionState(SelectionNone)
{
// init RenderObject attributes
setInline(true); // our object is Inline
@@ -485,7 +485,7 @@ RenderListMarker::~RenderListMarker()
m_image->removeClient(this);
}
-void RenderListMarker::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderListMarker::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
if (style() && (newStyle->listStylePosition() != style()->listStylePosition() || newStyle->listStyleType() != style()->listStyleType()))
setNeedsLayoutAndPrefWidthsRecalc();
@@ -493,7 +493,7 @@ void RenderListMarker::styleWillChange(RenderStyle::Diff diff, const RenderStyle
RenderBox::styleWillChange(diff, newStyle);
}
-void RenderListMarker::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderListMarker::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBox::styleDidChange(diff, oldStyle);
@@ -506,9 +506,8 @@ void RenderListMarker::styleDidChange(RenderStyle::Diff diff, const RenderStyle*
}
}
-InlineBox* RenderListMarker::createInlineBox(bool, bool unusedIsRootLineBox, bool)
+InlineBox* RenderListMarker::createInlineBox()
{
- ASSERT_UNUSED(unusedIsRootLineBox, !unusedIsRootLineBox);
ListMarkerBox* box = new (renderArena()) ListMarkerBox(this);
m_inlineBoxWrapper = box;
return box;
@@ -546,8 +545,10 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
paintCustomHighlight(tx, ty, style()->highlight(), true);
#endif
context->drawImage(m_image->image(this, marker.size()), marker.location());
- if (selectionState() != SelectionNone)
+ if (selectionState() != SelectionNone) {
+ // FIXME: selectionRect() is in absolute, not painting coordinates.
context->fillRect(selectionRect(), selectionBackgroundColor());
+ }
return;
}
@@ -557,8 +558,10 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
paintCustomHighlight(tx, ty, style()->highlight(), true);
#endif
- if (selectionState() != SelectionNone)
+ if (selectionState() != SelectionNone) {
+ // FIXME: selectionRect() is in absolute, not painting coordinates.
context->fillRect(selectionRect(), selectionBackgroundColor());
+ }
const Color color(style()->color());
context->setStrokeColor(color);
@@ -874,14 +877,14 @@ IntRect RenderListMarker::getRelativeMarkerRect()
void RenderListMarker::setSelectionState(SelectionState state)
{
- m_selectionState = state;
+ RenderBox::setSelectionState(state);
if (InlineBox* box = inlineBoxWrapper())
if (RootInlineBox* root = box->root())
root->setHasSelectedChildren(state != SelectionNone);
containingBlock()->setSelectionState(state);
}
-IntRect RenderListMarker::selectionRect(bool clipToVisibleContent)
+IntRect RenderListMarker::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
@@ -892,11 +895,9 @@ IntRect RenderListMarker::selectionRect(bool clipToVisibleContent)
IntRect rect(0, root->selectionTop() - y(), width(), root->selectionHeight());
if (clipToVisibleContent)
- computeAbsoluteRepaintRect(rect);
- else {
- FloatPoint absPos = localToAbsolute();
- rect.move(absPos.x(), absPos.y());
- }
+ computeRectForRepaint(repaintContainer, rect);
+ else
+ rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
return rect;
}
diff --git a/WebCore/rendering/RenderListMarker.h b/WebCore/rendering/RenderListMarker.h
index 738427c..57580a8 100644
--- a/WebCore/rendering/RenderListMarker.h
+++ b/WebCore/rendering/RenderListMarker.h
@@ -49,7 +49,7 @@ public:
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
- virtual InlineBox* createInlineBox(bool, bool, bool);
+ virtual InlineBox* createInlineBox();
virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
@@ -60,16 +60,15 @@ public:
bool isInside() const;
- virtual SelectionState selectionState() const { return m_selectionState; }
virtual void setSelectionState(SelectionState);
- virtual IntRect selectionRect(bool clipToVisibleContent = true);
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
virtual bool canBeSelectionLeaf() const { return true; }
void updateMargins();
protected:
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
IntRect getRelativeMarkerRect();
@@ -77,7 +76,6 @@ private:
String m_text;
RefPtr<StyleImage> m_image;
RenderListItem* m_listItem;
- SelectionState m_selectionState;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderMarquee.cpp b/WebCore/rendering/RenderMarquee.cpp
index 2b4dcfd..48659f7 100644
--- a/WebCore/rendering/RenderMarquee.cpp
+++ b/WebCore/rendering/RenderMarquee.cpp
@@ -68,9 +68,9 @@ RenderMarquee::RenderMarquee(RenderLayer* l)
int RenderMarquee::marqueeSpeed() const
{
int result = m_layer->renderer()->style()->marqueeSpeed();
- Node* elt = m_layer->renderer()->element();
- if (elt && elt->hasTagName(marqueeTag)) {
- HTMLMarqueeElement* marqueeElt = static_cast<HTMLMarqueeElement*>(elt);
+ Node* n = m_layer->renderer()->node();
+ if (n && n->hasTagName(marqueeTag)) {
+ HTMLMarqueeElement* marqueeElt = static_cast<HTMLMarqueeElement*>(n);
result = max(result, marqueeElt->minimumDelay());
}
return result;
@@ -105,17 +105,18 @@ bool RenderMarquee::isHorizontal() const
int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge)
{
- RenderBox* o = m_layer->renderer();
- RenderStyle* s = o->style();
+ RenderBox* box = m_layer->renderBox();
+ ASSERT(box);
+ RenderStyle* s = box->style();
if (isHorizontal()) {
bool ltr = s->direction() == LTR;
- int clientWidth = o->clientWidth();
- int contentWidth = ltr ? o->rightmostPosition(true, false) : o->leftmostPosition(true, false);
+ int clientWidth = box->clientWidth();
+ int contentWidth = ltr ? box->rightmostPosition(true, false) : box->leftmostPosition(true, false);
if (ltr)
- contentWidth += (o->paddingRight() - o->borderLeft());
+ contentWidth += (box->paddingRight() - box->borderLeft());
else {
- contentWidth = o->width() - contentWidth;
- contentWidth += (o->paddingLeft() - o->borderRight());
+ contentWidth = box->width() - contentWidth;
+ contentWidth += (box->paddingLeft() - box->borderRight());
}
if (dir == MRIGHT) {
if (stopAtContentEdge)
@@ -131,9 +132,9 @@ int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge
}
}
else {
- int contentHeight = m_layer->renderer()->lowestPosition(true, false) -
- m_layer->renderer()->borderTop() + m_layer->renderer()->paddingBottom();
- int clientHeight = m_layer->renderer()->clientHeight();
+ int contentHeight = box->lowestPosition(true, false) -
+ box->borderTop() + box->paddingBottom();
+ int clientHeight = box->clientHeight();
if (dir == MUP) {
if (stopAtContentEdge)
return min(contentHeight - clientHeight, 0);
@@ -283,7 +284,7 @@ void RenderMarquee::timerFired(Timer<RenderMarquee>*)
addIncrement = !addIncrement;
}
bool positive = range > 0;
- int clientSize = (isHorizontal() ? m_layer->renderer()->clientWidth() : m_layer->renderer()->clientHeight());
+ int clientSize = (isHorizontal() ? m_layer->renderBox()->clientWidth() : m_layer->renderBox()->clientHeight());
int increment = max(1, abs(m_layer->renderer()->style()->marqueeIncrement().calcValue(clientSize)));
int currentPos = (isHorizontal() ? m_layer->scrollXOffset() : m_layer->scrollYOffset());
newPos = currentPos + (addIncrement ? increment : -increment);
diff --git a/WebCore/rendering/RenderMarquee.h b/WebCore/rendering/RenderMarquee.h
index d9d20cd..886c343 100644
--- a/WebCore/rendering/RenderMarquee.h
+++ b/WebCore/rendering/RenderMarquee.h
@@ -44,7 +44,8 @@
#ifndef RenderMarquee_h
#define RenderMarquee_h
-#include "RenderStyle.h"
+#include "Length.h"
+#include "RenderStyleConstants.h"
#include "Timer.h"
namespace WebCore {
diff --git a/WebCore/rendering/RenderMedia.cpp b/WebCore/rendering/RenderMedia.cpp
index 80bf586..42cd709 100644
--- a/WebCore/rendering/RenderMedia.cpp
+++ b/WebCore/rendering/RenderMedia.cpp
@@ -39,7 +39,6 @@
#include "MediaControlElements.h"
#include "MouseEvent.h"
#include "MediaPlayer.h"
-#include "RenderSlider.h"
#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
@@ -89,6 +88,7 @@ void RenderMedia::destroy()
removeChild(m_controlsShadowRoot->renderer());
m_controlsShadowRoot->detach();
+ m_controlsShadowRoot = 0;
}
RenderReplaced::destroy();
}
@@ -103,6 +103,28 @@ MediaPlayer* RenderMedia::player() const
return mediaElement()->player();
}
+void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderReplaced::styleDidChange(diff, oldStyle);
+
+ if (m_controlsShadowRoot) {
+ if (m_panel->renderer())
+ m_panel->renderer()->setStyle(getCachedPseudoStyle(MEDIA_CONTROLS_PANEL));
+
+ if (m_timelineContainer->renderer())
+ m_timelineContainer->renderer()->setStyle(getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER));
+
+ m_muteButton->updateStyle();
+ m_playButton->updateStyle();
+ m_seekBackButton->updateStyle();
+ m_seekForwardButton->updateStyle();
+ m_timeline->updateStyle();
+ m_fullscreenButton->updateStyle();
+ m_currentTimeDisplay->updateStyle();
+ m_timeRemainingDisplay->updateStyle();
+ }
+}
+
void RenderMedia::layout()
{
IntSize oldSize = contentBoxRect().size();
@@ -123,16 +145,16 @@ void RenderMedia::layout()
}
}
-RenderObject* RenderMedia::firstChild() const
-{
- return m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0;
+const RenderObjectChildList* RenderMedia::children() const
+{
+ return m_controlsShadowRoot ? m_controlsShadowRoot->renderer()->virtualChildren() : 0;
}
-RenderObject* RenderMedia::lastChild() const
-{
- return m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0;
+RenderObjectChildList* RenderMedia::children()
+{
+ return m_controlsShadowRoot ? m_controlsShadowRoot->renderer()->virtualChildren() : 0;
}
-
+
void RenderMedia::removeChild(RenderObject* child)
{
ASSERT(m_controlsShadowRoot);
@@ -150,7 +172,7 @@ void RenderMedia::createControlsShadowRoot()
void RenderMedia::createPanel()
{
ASSERT(!m_panel);
- RenderStyle* style = getCachedPseudoStyle(RenderStyle::MEDIA_CONTROLS_PANEL);
+ RenderStyle* style = getCachedPseudoStyle(MEDIA_CONTROLS_PANEL);
m_panel = new HTMLDivElement(HTMLNames::divTag, document());
RenderObject* renderer = m_panel->createRenderer(renderArena(), style);
if (renderer) {
@@ -194,7 +216,7 @@ void RenderMedia::createSeekForwardButton()
void RenderMedia::createTimelineContainer()
{
ASSERT(!m_timelineContainer);
- RenderStyle* style = getCachedPseudoStyle(RenderStyle::MEDIA_CONTROLS_TIMELINE_CONTAINER);
+ RenderStyle* style = getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER);
m_timelineContainer = new HTMLDivElement(HTMLNames::divTag, document());
RenderObject* renderer = m_timelineContainer->createRenderer(renderArena(), style);
if (renderer) {
@@ -278,7 +300,7 @@ void RenderMedia::updateControls()
createFullscreenButton();
}
- if (media->paused() || media->ended() || media->networkState() < HTMLMediaElement::LOADED_METADATA) {
+ if (media->canPlay()) {
if (m_timeUpdateTimer.isActive())
m_timeUpdateTimer.stop();
} else if (style()->visibility() == VISIBLE && m_timeline && m_timeline->renderer() && m_timeline->renderer()->style()->display() != NONE ) {
@@ -350,11 +372,11 @@ void RenderMedia::updateControlVisibility()
// Don't fade for audio controls.
HTMLMediaElement* media = mediaElement();
- if (player() && !player()->hasVideo() || !media->isVideo())
+ if (!media->hasVideo())
return;
// do fading manually, css animations don't work well with shadow trees
- bool visible = style()->visibility() == VISIBLE && (m_mouseOver || media->paused() || media->ended() || media->networkState() < HTMLMediaElement::LOADED_METADATA);
+ bool visible = style()->visibility() == VISIBLE && (m_mouseOver || media->canPlay());
if (visible == (m_opacityAnimationTo > 0))
return;
@@ -403,7 +425,7 @@ void RenderMedia::forwardEvent(Event* event)
{
if (event->isMouseEvent() && m_controlsShadowRoot) {
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
- IntPoint point(mouseEvent->pageX(), mouseEvent->pageY());
+ IntPoint point(mouseEvent->absoluteLocation());
if (m_muteButton && m_muteButton->hitTest(point))
m_muteButton->defaultEventHandler(event);
@@ -427,8 +449,10 @@ void RenderMedia::forwardEvent(Event* event)
updateControlVisibility();
}
if (event->type() == eventNames().mouseoutEvent) {
- // FIXME: moving over scrollbar thumb generates mouseout for the ancestor media element for some reason
- m_mouseOver = absoluteBoundingBoxRect().contains(point);
+ // When the scrollbar thumb captures mouse events, we should treat the mouse as still being over our renderer if the new target is a descendant
+ Node* mouseOverNode = mouseEvent->relatedTarget() ? mouseEvent->relatedTarget()->toNode() : 0;
+ RenderObject* mouseOverRenderer = mouseOverNode ? mouseOverNode->renderer() : 0;
+ m_mouseOver = mouseOverRenderer && mouseOverRenderer->isDescendantOf(this);
updateControlVisibility();
}
}
@@ -440,7 +464,7 @@ int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf)
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return bottom;
- return max(bottom, m_controlsShadowRoot->renderBox()->y() + m_controlsShadowRoot->renderer()->lowestPosition(includeOverflowInterior, includeSelf));
+ return max(bottom, m_controlsShadowRoot->renderBox()->y() + m_controlsShadowRoot->renderBox()->lowestPosition(includeOverflowInterior, includeSelf));
}
int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
@@ -449,7 +473,7 @@ int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSel
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return right;
- return max(right, m_controlsShadowRoot->renderBox()->x() + m_controlsShadowRoot->renderer()->rightmostPosition(includeOverflowInterior, includeSelf));
+ return max(right, m_controlsShadowRoot->renderBox()->x() + m_controlsShadowRoot->renderBox()->rightmostPosition(includeOverflowInterior, includeSelf));
}
int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
@@ -458,7 +482,7 @@ int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf
if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer())
return left;
- return min(left, m_controlsShadowRoot->renderBox()->x() + m_controlsShadowRoot->renderer()->leftmostPosition(includeOverflowInterior, includeSelf));
+ return min(left, m_controlsShadowRoot->renderBox()->x() + m_controlsShadowRoot->renderBox()->leftmostPosition(includeOverflowInterior, includeSelf));
}
} // namespace WebCore
diff --git a/WebCore/rendering/RenderMedia.h b/WebCore/rendering/RenderMedia.h
index a4670e9..0e56dab 100644
--- a/WebCore/rendering/RenderMedia.h
+++ b/WebCore/rendering/RenderMedia.h
@@ -49,8 +49,11 @@ public:
RenderMedia(HTMLMediaElement*, const IntSize& intrinsicSize);
virtual ~RenderMedia();
- virtual RenderObject* firstChild() const;
- virtual RenderObject* lastChild() const;
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const;
+ RenderObjectChildList* children();
+
virtual void removeChild(RenderObject*);
virtual void destroy();
@@ -95,6 +98,8 @@ private:
void changeOpacity(HTMLElement*, float opacity);
void opacityAnimationTimerFired(Timer<RenderMedia>*);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+
RefPtr<HTMLElement> m_controlsShadowRoot;
RefPtr<HTMLElement> m_panel;
RefPtr<MediaControlMuteButtonElement> m_muteButton;
@@ -106,8 +111,8 @@ private:
RefPtr<HTMLElement> m_timelineContainer;
RefPtr<MediaTimeDisplayElement> m_currentTimeDisplay;
RefPtr<MediaTimeDisplayElement> m_timeRemainingDisplay;
- EventTargetNode* m_lastUnderNode;
- EventTargetNode* m_nodeUnderMouse;
+ Node* m_lastUnderNode;
+ Node* m_nodeUnderMouse;
Timer<RenderMedia> m_timeUpdateTimer;
Timer<RenderMedia> m_opacityAnimationTimer;
diff --git a/WebCore/rendering/RenderMenuList.cpp b/WebCore/rendering/RenderMenuList.cpp
index 71e9e15..d61c16b 100644
--- a/WebCore/rendering/RenderMenuList.cpp
+++ b/WebCore/rendering/RenderMenuList.cpp
@@ -115,7 +115,7 @@ void RenderMenuList::removeChild(RenderObject* oldChild)
m_innerBlock->removeChild(oldChild);
}
-void RenderMenuList::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderMenuList::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
@@ -143,7 +143,15 @@ void RenderMenuList::updateOptionsWidth()
continue;
String text = optionElement->textIndentedToRespectGroupLabel();
- if (!text.isEmpty())
+ if (theme()->popupOptionSupportsTextIndent()) {
+ // Add in the option's text indent. We can't calculate percentage values for now.
+ float optionWidth = 0;
+ if (RenderStyle* optionStyle = element->renderStyle())
+ optionWidth += optionStyle->textIndent().calcMinValue(0);
+ if (!text.isEmpty())
+ optionWidth += style()->font().floatWidth(text);
+ maxOptionWidth = max(maxOptionWidth, optionWidth);
+ } else if (!text.isEmpty())
maxOptionWidth = max(maxOptionWidth, style()->font().floatWidth(text));
}
@@ -315,9 +323,15 @@ bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
if (!element->hasTagName(optionTag))
return false;
bool groupEnabled = true;
- if (element->parentNode() && element->parentNode()->hasTagName(optgroupTag))
- groupEnabled = element->parentNode()->isEnabled();
- return element->isEnabled() && groupEnabled;
+ if (element->parentNode() && element->parentNode()->hasTagName(optgroupTag)) {
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(element->parentNode()));
+ groupEnabled = formControlElement->isEnabled();
+ }
+
+ if (!groupEnabled)
+ return false;
+
+ return toFormControlElement(element)->isEnabled();
}
PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
@@ -326,7 +340,7 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
HTMLElement* element = select->listItems()[listIndex];
RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle();
- return style ? PopupMenuStyle(style->color(), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE) : menuStyle();
+ return style ? PopupMenuStyle(style->color(), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->textIndent(), style->direction()) : menuStyle();
}
Color RenderMenuList::itemBackgroundColor(unsigned listIndex) const
@@ -354,7 +368,7 @@ PopupMenuStyle RenderMenuList::menuStyle() const
{
RenderStyle* s = m_innerBlock ? m_innerBlock->style() : style();
- return PopupMenuStyle(s->color(), s->backgroundColor(), s->font(), s->visibility() == VISIBLE);
+ return PopupMenuStyle(s->color(), s->backgroundColor(), s->font(), s->visibility() == VISIBLE, s->textIndent(), s->direction());
}
HostWindow* RenderMenuList::hostWindow() const
@@ -365,7 +379,7 @@ HostWindow* RenderMenuList::hostWindow() const
PassRefPtr<Scrollbar> RenderMenuList::createScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
{
RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = style()->hasPseudoStyle(RenderStyle::SCROLLBAR);
+ bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
widget = RenderScrollbar::createCustomScrollbar(client, orientation, this);
else
diff --git a/WebCore/rendering/RenderMenuList.h b/WebCore/rendering/RenderMenuList.h
index a7530fa..f16525e 100644
--- a/WebCore/rendering/RenderMenuList.h
+++ b/WebCore/rendering/RenderMenuList.h
@@ -72,7 +72,7 @@ public:
String text() const;
private:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
// PopupMenuClient methods
virtual String itemText(unsigned listIndex) const;
diff --git a/WebCore/rendering/RenderObject.cpp b/WebCore/rendering/RenderObject.cpp
index ea84f33..bb98c9f 100644
--- a/WebCore/rendering/RenderObject.cpp
+++ b/WebCore/rendering/RenderObject.cpp
@@ -28,6 +28,7 @@
#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
#include "FloatQuad.h"
+#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLNames.h"
@@ -44,12 +45,18 @@
#include "RenderTableRow.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "TransformState.h"
#include <algorithm>
#ifdef ANDROID_LAYOUT
#include "Settings.h"
#endif
#include <stdio.h>
#include <wtf/RefCountedLeakCounter.h>
+#include <wtf/UnusedParam.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+#endif
#if ENABLE(WML)
#include "WMLNames.h"
@@ -89,10 +96,10 @@ RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
// Works only if we have exactly one piece of content and it's a URL.
// Otherwise acts as if we didn't support this feature.
const ContentData* contentData = style->contentData();
- if (contentData && !contentData->m_next && contentData->m_type == CONTENT_OBJECT && doc != node) {
+ if (contentData && !contentData->next() && contentData->isImage() && doc != node) {
RenderImageGeneratedContent* image = new (arena) RenderImageGeneratedContent(node);
image->setStyle(style);
- if (StyleImage* styleImage = contentData->m_content.m_image)
+ if (StyleImage* styleImage = contentData->image())
image->setStyleImage(styleImage);
return image;
}
@@ -164,7 +171,6 @@ RenderObject::RenderObject(Node* node)
, m_hasAXObject(false)
, m_setNeedsLayoutForbidden(false)
#endif
- , m_verticalPosition(PositionUndefined)
, m_needsLayout(false)
, m_needsPositionedMovementLayout(false)
, m_normalChildNeedsLayout(false)
@@ -187,10 +193,19 @@ RenderObject::RenderObject(Node* node)
, m_hasOverrideSize(false)
, m_hasCounterNodeMap(false)
, m_everHadLayout(false)
+ , m_childrenInline(false)
+ , m_topMarginQuirk(false)
+ , m_bottomMarginQuirk(false)
+ , m_hasMarkupTruncation(false)
+ , m_selectionState(SelectionNone)
+ , m_hasColumns(false)
+ , m_cellWidthChanged(false)
+ , m_replacedHasOverflow(false)
{
#ifndef NDEBUG
renderObjectCounter.increment();
#endif
+ ASSERT(node);
}
RenderObject::~RenderObject()
@@ -213,58 +228,95 @@ bool RenderObject::isDescendantOf(const RenderObject* obj) const
bool RenderObject::isBody() const
{
- return node()->hasTagName(bodyTag);
+ return node() && node()->hasTagName(bodyTag);
}
bool RenderObject::isHR() const
{
- return element() && element()->hasTagName(hrTag);
+ return node() && node()->hasTagName(hrTag);
}
bool RenderObject::isHTMLMarquee() const
{
- return element() && element()->renderer() == this && element()->hasTagName(marqueeTag);
-}
-
-bool RenderObject::canHaveChildren() const
-{
- return false;
-}
-
-bool RenderObject::isInlineContinuation() const
-{
- return false;
+ return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);
}
-void RenderObject::addChild(RenderObject*, RenderObject*)
+static void updateListMarkerNumbers(RenderObject* child)
{
- ASSERT_NOT_REACHED();
+ for (RenderObject* r = child; r; r = r->nextSibling())
+ if (r->isListItem())
+ static_cast<RenderListItem*>(r)->updateValue();
}
-RenderObject* RenderObject::removeChildNode(RenderObject*, bool)
+void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-void RenderObject::removeChild(RenderObject*)
-{
- ASSERT_NOT_REACHED();
-}
+ RenderObjectChildList* children = virtualChildren();
+ ASSERT(children);
+ if (!children)
+ return;
-void RenderObject::moveChildNode(RenderObject*)
-{
- ASSERT_NOT_REACHED();
+ bool needsTable = false;
+
+ if (newChild->isListItem())
+ updateListMarkerNumbers(beforeChild ? beforeChild : children->lastChild());
+ else if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
+ needsTable = !isTable();
+ else if (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)
+ needsTable = !isTable();
+ else if (newChild->isTableSection())
+ needsTable = !isTable();
+ else if (newChild->isTableRow())
+ needsTable = !isTableSection();
+ else if (newChild->isTableCell()) {
+ needsTable = !isTableRow();
+ // I'm not 100% sure this is the best way to fix this, but without this
+ // change we recurse infinitely when trying to render the CSS2 test page:
+ // http://www.bath.ac.uk/%7Epy8ieh/internet/eviltests/htmlbodyheadrendering2.html.
+ // See Radar 2925291.
+ if (needsTable && isTableCell() && !children->firstChild() && !newChild->isTableCell())
+ needsTable = false;
+ }
+
+ if (needsTable) {
+ RenderTable* table;
+ RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children->lastChild();
+ if (afterChild && afterChild->isAnonymous() && afterChild->isTable())
+ table = static_cast<RenderTable*>(afterChild);
+ else {
+ table = new (renderArena()) RenderTable(document() /* is anonymous */);
+ RefPtr<RenderStyle> newStyle = RenderStyle::create();
+ newStyle->inheritFrom(style());
+ newStyle->setDisplay(TABLE);
+ table->setStyle(newStyle.release());
+ addChild(table, beforeChild);
+ }
+ table->addChild(newChild);
+ } else {
+ // Just add it...
+ children->insertChildNode(this, newChild, beforeChild);
+ }
+
+ if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
+ RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
+ if (textToTransform)
+ toRenderText(newChild)->setText(textToTransform.release(), true);
+ }
}
-void RenderObject::appendChildNode(RenderObject*, bool)
+void RenderObject::removeChild(RenderObject* oldChild)
{
- ASSERT_NOT_REACHED();
-}
+ RenderObjectChildList* children = virtualChildren();
+ ASSERT(children);
+ if (!children)
+ return;
-void RenderObject::insertChildNode(RenderObject*, RenderObject*, bool)
-{
- ASSERT_NOT_REACHED();
+ // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode
+ // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on
+ // layout anyway).
+ if (oldChild->isFloatingOrPositioned())
+ toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
+
+ children->removeChildNode(this, oldChild);
}
RenderObject* RenderObject::nextInPreOrder() const
@@ -336,20 +388,6 @@ RenderObject* RenderObject::childAt(unsigned index) const
return child;
}
-bool RenderObject::isEditable() const
-{
- RenderText* textRenderer = 0;
- if (isText())
- textRenderer = toRenderText(const_cast<RenderObject*>(this));
-
- return style()->visibility() == VISIBLE &&
- element() && element()->isContentEditable() &&
- ((isBlockFlow() && !firstChild()) ||
- isReplaced() ||
- isBR() ||
- (textRenderer && textRenderer->firstTextBox()));
-}
-
RenderObject* RenderObject::firstLeafChild() const
{
RenderObject* r = firstChild();
@@ -387,7 +425,7 @@ static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*
beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
newObject = 0;
}
- parentLayer->addChild(toRenderBox(obj)->layer(), beforeChild);
+ parentLayer->addChild(toRenderBoxModelObject(obj)->layer(), beforeChild);
return;
}
@@ -411,7 +449,7 @@ void RenderObject::removeLayers(RenderLayer* parentLayer)
return;
if (hasLayer()) {
- parentLayer->removeChild(toRenderBox(this)->layer());
+ parentLayer->removeChild(toRenderBoxModelObject(this)->layer());
return;
}
@@ -425,7 +463,7 @@ void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
return;
if (hasLayer()) {
- RenderLayer* layer = toRenderBox(this)->layer();
+ RenderLayer* layer = toRenderBoxModelObject(this)->layer();
if (oldParent)
oldParent->removeChild(layer);
newParent->addChild(layer);
@@ -444,7 +482,7 @@ RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject*
return 0;
// Step 1: If our layer is a child of the desired parent, then return our layer.
- RenderLayer* ourLayer = hasLayer() ? toRenderBox(this)->layer() : 0;
+ RenderLayer* ourLayer = hasLayer() ? toRenderBoxModelObject(this)->layer() : 0;
if (ourLayer && ourLayer->parent() == parentLayer)
return ourLayer;
@@ -476,7 +514,7 @@ RenderLayer* RenderObject::enclosingLayer() const
{
const RenderObject* curr = this;
while (curr) {
- RenderLayer* layer = curr->hasLayer() ? toRenderBox(curr)->layer() : 0;
+ RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0;
if (layer)
return layer;
curr = curr->parent();
@@ -484,6 +522,18 @@ RenderLayer* RenderObject::enclosingLayer() const
return 0;
}
+RenderLayer* RenderObject::enclosingSelfPaintingLayer() const
+{
+ const RenderObject* curr = this;
+ while (curr) {
+ RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0;
+ if (layer && layer->isSelfPaintingLayer())
+ return layer;
+ curr = curr->parent();
+ }
+ return 0;
+}
+
RenderBox* RenderObject::enclosingBox() const
{
RenderObject* curr = const_cast<RenderObject*>(this);
@@ -502,16 +552,6 @@ RenderBlock* RenderObject::firstLineBlock() const
return 0;
}
-bool RenderObject::hasStaticX() const
-{
- return (style()->left().isAuto() && style()->right().isAuto()) || style()->left().isStatic() || style()->right().isStatic();
-}
-
-bool RenderObject::hasStaticY() const
-{
- return (style()->top().isAuto() && style()->bottom().isAuto()) || style()->top().isStatic();
-}
-
void RenderObject::setPrefWidthsDirty(bool b, bool markParents)
{
bool alreadyDirty = m_prefWidthsDirty;
@@ -526,113 +566,25 @@ void RenderObject::invalidateContainerPrefWidths()
// in the chain that we mark dirty (even though they're kind of irrelevant).
RenderObject* o = isTableCell() ? containingBlock() : container();
while (o && !o->m_prefWidthsDirty) {
+ // Don't invalidate the outermost object of an unrooted subtree. That object will be
+ // invalidated when the subtree is added to the document.
+ RenderObject* container = o->isTableCell() ? o->containingBlock() : o->container();
+ if (!container && !o->isRenderView())
+ break;
+
o->m_prefWidthsDirty = true;
if (o->style()->position() == FixedPosition || o->style()->position() == AbsolutePosition)
// A positioned object has no effect on the min/max width of its containing block ever.
// We can optimize this case and not go up any further.
break;
- o = o->isTableCell() ? o->containingBlock() : o->container();
- }
-}
-
-void RenderObject::setNeedsLayout(bool b, bool markParents)
-{
- bool alreadyNeededLayout = m_needsLayout;
- m_needsLayout = b;
- if (b) {
- ASSERT(!isSetNeedsLayoutForbidden());
- if (!alreadyNeededLayout) {
- if (markParents)
- markContainingBlocksForLayout();
- if (hasLayer())
- toRenderBox(this)->layer()->setNeedsFullRepaint();
- }
- } else {
- m_everHadLayout = true;
- m_posChildNeedsLayout = false;
- m_normalChildNeedsLayout = false;
- m_needsPositionedMovementLayout = false;
- }
-}
-
-void RenderObject::setChildNeedsLayout(bool b, bool markParents)
-{
- bool alreadyNeededLayout = m_normalChildNeedsLayout;
- m_normalChildNeedsLayout = b;
- if (b) {
- ASSERT(!isSetNeedsLayoutForbidden());
- if (!alreadyNeededLayout && markParents)
- markContainingBlocksForLayout();
- } else {
- m_posChildNeedsLayout = false;
- m_normalChildNeedsLayout = false;
- m_needsPositionedMovementLayout = false;
- }
-}
-
-void RenderObject::setNeedsPositionedMovementLayout()
-{
- bool alreadyNeededLayout = needsLayout();
- m_needsPositionedMovementLayout = true;
- if (!alreadyNeededLayout) {
- markContainingBlocksForLayout();
- if (hasLayer())
- toRenderBox(this)->layer()->setNeedsFullRepaint();
+ o = container;
}
}
-static inline bool objectIsRelayoutBoundary(const RenderObject *obj)
+void RenderObject::setLayerNeedsFullRepaint()
{
- // FIXME: In future it may be possible to broaden this condition in order to improve performance.
- // Table cells are excluded because even when their CSS height is fixed, their height()
- // may depend on their contents.
- return obj->isTextField() || obj->isTextArea()
- || obj->hasOverflowClip() && !obj->style()->width().isIntrinsicOrAuto() && !obj->style()->height().isIntrinsicOrAuto() && !obj->style()->height().isPercent() && !obj->isTableCell()
-#if ENABLE(SVG)
- || obj->isSVGRoot()
-#endif
- ;
-}
-
-void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderObject* newRoot)
-{
- ASSERT(!scheduleRelayout || !newRoot);
-
- RenderObject* o = container();
- RenderObject* last = this;
-
- while (o) {
- if (!last->isText() && (last->style()->position() == FixedPosition || last->style()->position() == AbsolutePosition)) {
- if (last->hasStaticY()) {
- RenderObject* parent = last->parent();
- if (!parent->normalChildNeedsLayout()) {
- parent->setChildNeedsLayout(true, false);
- if (parent != newRoot)
- parent->markContainingBlocksForLayout(scheduleRelayout, newRoot);
- }
- }
- if (o->m_posChildNeedsLayout)
- return;
- o->m_posChildNeedsLayout = true;
- ASSERT(!o->isSetNeedsLayoutForbidden());
- } else {
- if (o->m_normalChildNeedsLayout)
- return;
- o->m_normalChildNeedsLayout = true;
- ASSERT(!o->isSetNeedsLayoutForbidden());
- }
-
- if (o == newRoot)
- return;
-
- last = o;
- if (scheduleRelayout && objectIsRelayoutBoundary(last))
- break;
- o = o->container();
- }
-
- if (scheduleRelayout)
- last->scheduleRelayout();
+ ASSERT(hasLayer());
+ toRenderBoxModelObject(this)->layer()->setNeedsFullRepaint(true);
}
RenderBlock* RenderObject::containingBlock() const
@@ -645,7 +597,7 @@ RenderBlock* RenderObject::containingBlock() const
}
if (isRenderView())
- return const_cast<RenderBlock*>(static_cast<const RenderBlock*>(this));
+ return const_cast<RenderView*>(toRenderView(this));
RenderObject* o = parent();
if (!isText() && m_style->position() == FixedPosition) {
@@ -675,19 +627,7 @@ RenderBlock* RenderObject::containingBlock() const
if (!o || !o->isRenderBlock())
return 0; // Probably doesn't happen any more, but leave just in case. -dwh
- return static_cast<RenderBlock*>(o);
-}
-
-int RenderObject::containingBlockWidth() const
-{
- // FIXME ?
- return containingBlock()->availableWidth();
-}
-
-int RenderObject::containingBlockHeight() const
-{
- // FIXME ?
- return containingBlock()->contentHeight();
+ return toRenderBlock(o);
}
static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer)
@@ -736,97 +676,9 @@ bool RenderObject::mustRepaintBackgroundOrBorder() const
return false;
}
-void RenderObject::drawBorderArc(GraphicsContext* graphicsContext, int x, int y, float thickness, IntSize radius,
- int angleStart, int angleSpan, BorderSide s, Color c, const Color& textColor,
- EBorderStyle style, bool firstCorner)
-{
- if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
- style = SOLID;
-
- if (!c.isValid()) {
- if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
- c.setRGB(238, 238, 238);
- else
- c = textColor;
- }
-
- switch (style) {
- case BNONE:
- case BHIDDEN:
- return;
- case DOTTED:
- case DASHED:
- graphicsContext->setStrokeColor(c);
- graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
- graphicsContext->setStrokeThickness(thickness);
- graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
- break;
- case DOUBLE: {
- float third = thickness / 3.0f;
- float innerThird = (thickness + 1.0f) / 6.0f;
- int shiftForInner = static_cast<int>(innerThird * 2.5f);
-
- int outerY = y;
- int outerHeight = radius.height() * 2;
- int innerX = x + shiftForInner;
- int innerY = y + shiftForInner;
- int innerWidth = (radius.width() - shiftForInner) * 2;
- int innerHeight = (radius.height() - shiftForInner) * 2;
- if (innerThird > 1 && (s == BSTop || (firstCorner && (s == BSLeft || s == BSRight)))) {
- outerHeight += 2;
- innerHeight += 2;
- }
-
- graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
- graphicsContext->setStrokeThickness(third);
- graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
- graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
- graphicsContext->strokeArc(IntRect(innerX, innerY, innerWidth, innerHeight), angleStart, angleSpan);
- break;
- }
- case GROOVE:
- case RIDGE: {
- Color c2;
- if ((style == RIDGE && (s == BSTop || s == BSLeft)) ||
- (style == GROOVE && (s == BSBottom || s == BSRight)))
- c2 = c.dark();
- else {
- c2 = c;
- c = c.dark();
- }
-
- graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
- graphicsContext->setStrokeThickness(thickness);
- graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
-
- float halfThickness = (thickness + 1.0f) / 4.0f;
- int shiftForInner = static_cast<int>(halfThickness * 1.5f);
- graphicsContext->setStrokeColor(c2);
- graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
- graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
- (radius.height() - shiftForInner) * 2), angleStart, angleSpan);
- break;
- }
- case INSET:
- if (s == BSTop || s == BSLeft)
- c = c.dark();
- case OUTSET:
- if (style == OUTSET && (s == BSBottom || s == BSRight))
- c = c.dark();
- case SOLID:
- graphicsContext->setStrokeStyle(SolidStroke);
- graphicsContext->setStrokeColor(c);
- graphicsContext->setStrokeThickness(thickness);
- graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
- break;
- }
-}
-
-void RenderObject::drawBorder(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
- BorderSide s, Color c, const Color& textcolor, EBorderStyle style,
- int adjbw1, int adjbw2)
+void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2,
+ BoxSide s, Color c, const Color& textcolor, EBorderStyle style,
+ int adjbw1, int adjbw2)
{
int width = (s == BSTop || s == BSBottom ? y2 - y1 : x2 - x1);
@@ -889,34 +741,34 @@ void RenderObject::drawBorder(GraphicsContext* graphicsContext, int x1, int y1,
switch (s) {
case BSTop:
- drawBorder(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
y1, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y1 + third,
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
- drawBorder(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
y2 - third, x2 - max((adjbw2 * 2 + 1) / 3, 0), y2,
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
case BSLeft:
- drawBorder(graphicsContext, x1, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x1, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
x1 + third, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
- drawBorder(graphicsContext, x2 - third, y1 + max((adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((adjbw1 * 2 + 1) / 3, 0),
x2, y2 - max((adjbw2 * 2 + 1) / 3, 0),
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
case BSBottom:
- drawBorder(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x1 + max((adjbw1 * 2 + 1) / 3, 0),
y1, x2 - max((adjbw2 * 2 + 1) / 3, 0), y1 + third,
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
- drawBorder(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x1 + max((-adjbw1 * 2 + 1) / 3, 0),
y2 - third, x2 - max((-adjbw2 * 2 + 1) / 3, 0), y2,
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
case BSRight:
- drawBorder(graphicsContext, x1, y1 + max((adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x1, y1 + max((adjbw1 * 2 + 1) / 3, 0),
x1 + third, y2 - max(( adjbw2 * 2 + 1) / 3, 0),
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
- drawBorder(graphicsContext, x2 - third, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
+ drawLineForBoxSide(graphicsContext, x2 - third, y1 + max((-adjbw1 * 2 + 1) / 3, 0),
x2, y2 - max((-adjbw2 * 2 + 1) / 3, 0),
s, c, textcolor, SOLID, adjbw1bigthird, adjbw2bigthird);
break;
@@ -944,27 +796,27 @@ void RenderObject::drawBorder(GraphicsContext* graphicsContext, int x1, int y1,
switch (s) {
case BSTop:
- drawBorder(graphicsContext, x1 + max(-adjbw1, 0) / 2, y1, x2 - max(-adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
+ drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1, 0) / 2, y1, x2 - max(-adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
- drawBorder(graphicsContext, x1 + max(adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjbw2 + 1, 0) / 2, y2,
+ drawLineForBoxSide(graphicsContext, x1 + max(adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(adjbw2 + 1, 0) / 2, y2,
s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
break;
case BSLeft:
- drawBorder(graphicsContext, x1, y1 + max(-adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjbw2, 0) / 2,
+ drawLineForBoxSide(graphicsContext, x1, y1 + max(-adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(-adjbw2, 0) / 2,
s, c, textcolor, s1, adjbw1bighalf, adjbw2bighalf);
- drawBorder(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjbw1 + 1, 0) / 2, x2, y2 - max(adjbw2 + 1, 0) / 2,
+ drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(adjbw1 + 1, 0) / 2, x2, y2 - max(adjbw2 + 1, 0) / 2,
s, c, textcolor, s2, adjbw1 / 2, adjbw2 / 2);
break;
case BSBottom:
- drawBorder(graphicsContext, x1 + max(adjbw1, 0) / 2, y1, x2 - max(adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
+ drawLineForBoxSide(graphicsContext, x1 + max(adjbw1, 0) / 2, y1, x2 - max(adjbw2, 0) / 2, (y1 + y2 + 1) / 2,
s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
- drawBorder(graphicsContext, x1 + max(-adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjbw2 + 1, 0) / 2, y2,
+ drawLineForBoxSide(graphicsContext, x1 + max(-adjbw1 + 1, 0) / 2, (y1 + y2 + 1) / 2, x2 - max(-adjbw2 + 1, 0) / 2, y2,
s, c, textcolor, s1, adjbw1/2, adjbw2/2);
break;
case BSRight:
- drawBorder(graphicsContext, x1, y1 + max(adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjbw2, 0) / 2,
+ drawLineForBoxSide(graphicsContext, x1, y1 + max(adjbw1, 0) / 2, (x1 + x2 + 1) / 2, y2 - max(adjbw2, 0) / 2,
s, c, textcolor, s2, adjbw1bighalf, adjbw2bighalf);
- drawBorder(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjbw1 + 1, 0) / 2, x2, y2 - max(-adjbw2 + 1, 0) / 2,
+ drawLineForBoxSide(graphicsContext, (x1 + x2 + 1) / 2, y1 + max(-adjbw1 + 1, 0) / 2, x2, y2 - max(-adjbw2 + 1, 0) / 2,
s, c, textcolor, s1, adjbw1/2, adjbw2/2);
break;
}
@@ -1020,516 +872,91 @@ void RenderObject::drawBorder(GraphicsContext* graphicsContext, int x1, int y1,
}
}
-bool RenderObject::paintNinePieceImage(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style,
- const NinePieceImage& ninePieceImage, CompositeOperator op)
-{
- StyleImage* styleImage = ninePieceImage.image();
- if (!styleImage || !styleImage->canRender(style->effectiveZoom()))
- return false;
-
- if (!styleImage->isLoaded())
- return true; // Never paint a nine-piece image incrementally, but don't paint the fallback borders either.
-
- // If we have a border radius, the image gets clipped to the rounded rect.
- bool clipped = false;
- if (style->hasBorderRadius()) {
- IntRect clipRect(tx, ty, w, h);
- graphicsContext->save();
- graphicsContext->addRoundedRectClip(clipRect, style->borderTopLeftRadius(), style->borderTopRightRadius(),
- style->borderBottomLeftRadius(), style->borderBottomRightRadius());
- clipped = true;
- }
-
- // FIXME: border-image is broken with full page zooming when tiling has to happen, since the tiling function
- // doesn't have any understanding of the zoom that is in effect on the tile.
- styleImage->setImageContainerSize(IntSize(w, h));
- IntSize imageSize = styleImage->imageSize(this, 1.0f);
- int imageWidth = imageSize.width();
- int imageHeight = imageSize.height();
-
- int topSlice = min(imageHeight, ninePieceImage.m_slices.top().calcValue(imageHeight));
- int bottomSlice = min(imageHeight, ninePieceImage.m_slices.bottom().calcValue(imageHeight));
- int leftSlice = min(imageWidth, ninePieceImage.m_slices.left().calcValue(imageWidth));
- int rightSlice = min(imageWidth, ninePieceImage.m_slices.right().calcValue(imageWidth));
-
- ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
- ENinePieceImageRule vRule = ninePieceImage.verticalRule();
-
- bool fitToBorder = style->borderImage() == ninePieceImage;
-
- int leftWidth = fitToBorder ? style->borderLeftWidth() : leftSlice;
- int topWidth = fitToBorder ? style->borderTopWidth() : topSlice;
- int rightWidth = fitToBorder ? style->borderRightWidth() : rightSlice;
- int bottomWidth = fitToBorder ? style->borderBottomWidth() : bottomSlice;
-
- bool drawLeft = leftSlice > 0 && leftWidth > 0;
- bool drawTop = topSlice > 0 && topWidth > 0;
- bool drawRight = rightSlice > 0 && rightWidth > 0;
- bool drawBottom = bottomSlice > 0 && bottomWidth > 0;
- bool drawMiddle = (imageWidth - leftSlice - rightSlice) > 0 && (w - leftWidth - rightWidth) > 0 &&
- (imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0;
-
- Image* image = styleImage->image(this, imageSize);
-
- if (drawLeft) {
- // Paint the top and bottom left corners.
-
- // The top left corner rect is (tx, ty, leftWidth, topWidth)
- // The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
- if (drawTop)
- graphicsContext->drawImage(image, IntRect(tx, ty, leftWidth, topWidth),
- IntRect(0, 0, leftSlice, topSlice), op);
-
- // The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
- // The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
- if (drawBottom)
- graphicsContext->drawImage(image, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
- IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op);
-
- // Paint the left edge.
- // Have to scale and tile into the border rect.
- graphicsContext->drawTiledImage(image, IntRect(tx, ty + topWidth, leftWidth,
- h - topWidth - bottomWidth),
- IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice),
- Image::StretchTile, (Image::TileRule)vRule, op);
- }
-
- if (drawRight) {
- // Paint the top and bottom right corners
- // The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
- // The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
- if (drawTop)
- graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
- IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op);
-
- // The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
- // The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
- if (drawBottom)
- graphicsContext->drawImage(image, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
- IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op);
-
- // Paint the right edge.
- graphicsContext->drawTiledImage(image, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
- h - topWidth - bottomWidth),
- IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice),
- Image::StretchTile, (Image::TileRule)vRule, op);
- }
-
- // Paint the top edge.
- if (drawTop)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
- IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice),
- (Image::TileRule)hRule, Image::StretchTile, op);
-
- // Paint the bottom edge.
- if (drawBottom)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + h - bottomWidth,
- w - leftWidth - rightWidth, bottomWidth),
- IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice),
- (Image::TileRule)hRule, Image::StretchTile, op);
-
- // Paint the middle.
- if (drawMiddle)
- graphicsContext->drawTiledImage(image, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
- h - topWidth - bottomWidth),
- IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice),
- (Image::TileRule)hRule, (Image::TileRule)vRule, op);
-
- // Clear the clip for the border radius.
- if (clipped)
- graphicsContext->restore();
-
- return true;
-}
-
-void RenderObject::paintBorder(GraphicsContext* graphicsContext, int tx, int ty, int w, int h,
- const RenderStyle* style, bool begin, bool end)
+void RenderObject::drawArcForBoxSide(GraphicsContext* graphicsContext, int x, int y, float thickness, IntSize radius,
+ int angleStart, int angleSpan, BoxSide s, Color c, const Color& textColor,
+ EBorderStyle style, bool firstCorner)
{
- if (paintNinePieceImage(graphicsContext, tx, ty, w, h, style, style->borderImage()))
- return;
-
- const Color& tc = style->borderTopColor();
- const Color& bc = style->borderBottomColor();
- const Color& lc = style->borderLeftColor();
- const Color& rc = style->borderRightColor();
-
- bool tt = style->borderTopIsTransparent();
- bool bt = style->borderBottomIsTransparent();
- bool rt = style->borderRightIsTransparent();
- bool lt = style->borderLeftIsTransparent();
-
- EBorderStyle ts = style->borderTopStyle();
- EBorderStyle bs = style->borderBottomStyle();
- EBorderStyle ls = style->borderLeftStyle();
- EBorderStyle rs = style->borderRightStyle();
-
- bool renderTop = ts > BHIDDEN && !tt;
- bool renderLeft = ls > BHIDDEN && begin && !lt;
- bool renderRight = rs > BHIDDEN && end && !rt;
- bool renderBottom = bs > BHIDDEN && !bt;
-
- // Need sufficient width and height to contain border radius curves. Sanity check our border radii
- // and our width/height values to make sure the curves can all fit. If not, then we won't paint
- // any border radii.
- bool renderRadii = false;
- IntSize topLeft = style->borderTopLeftRadius();
- IntSize topRight = style->borderTopRightRadius();
- IntSize bottomLeft = style->borderBottomLeftRadius();
- IntSize bottomRight = style->borderBottomRightRadius();
-
- if (style->hasBorderRadius() &&
- static_cast<unsigned>(w) >= static_cast<unsigned>(topLeft.width()) + static_cast<unsigned>(topRight.width()) &&
- static_cast<unsigned>(w) >= static_cast<unsigned>(bottomLeft.width()) + static_cast<unsigned>(bottomRight.width()) &&
- static_cast<unsigned>(h) >= static_cast<unsigned>(topLeft.height()) + static_cast<unsigned>(bottomLeft.height()) &&
- static_cast<unsigned>(h) >= static_cast<unsigned>(topRight.height()) + static_cast<unsigned>(bottomRight.height()))
- renderRadii = true;
-
- // Clip to the rounded rectangle.
- if (renderRadii) {
- graphicsContext->save();
- graphicsContext->addRoundedRectClip(IntRect(tx, ty, w, h), topLeft, topRight, bottomLeft, bottomRight);
- }
-
- int firstAngleStart, secondAngleStart, firstAngleSpan, secondAngleSpan;
- float thickness;
- bool upperLeftBorderStylesMatch = renderLeft && (ts == ls) && (tc == lc);
- bool upperRightBorderStylesMatch = renderRight && (ts == rs) && (tc == rc) && (ts != OUTSET) && (ts != RIDGE) && (ts != INSET) && (ts != GROOVE);
- bool lowerLeftBorderStylesMatch = renderLeft && (bs == ls) && (bc == lc) && (bs != OUTSET) && (bs != RIDGE) && (bs != INSET) && (bs != GROOVE);
- bool lowerRightBorderStylesMatch = renderRight && (bs == rs) && (bc == rc);
-
- if (renderTop) {
- bool ignore_left = (renderRadii && topLeft.width() > 0) ||
- (tc == lc && tt == lt && ts >= OUTSET &&
- (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
-
- bool ignore_right = (renderRadii && topRight.width() > 0) ||
- (tc == rc && tt == rt && ts >= OUTSET &&
- (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
-
- int x = tx;
- int x2 = tx + w;
- if (renderRadii) {
- x += topLeft.width();
- x2 -= topRight.width();
- }
-
- drawBorder(graphicsContext, x, ty, x2, ty + style->borderTopWidth(), BSTop, tc, style->color(), ts,
- ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
-
- if (renderRadii) {
- int leftY = ty;
-
- // We make the arc double thick and let the clip rect take care of clipping the extra off.
- // We're doing this because it doesn't seem possible to match the curve of the clip exactly
- // with the arc-drawing function.
- thickness = style->borderTopWidth() * 2;
-
- if (topLeft.width()) {
- int leftX = tx;
- // The inner clip clips inside the arc. This is especially important for 1px borders.
- bool applyLeftInnerClip = (style->borderLeftWidth() < topLeft.width())
- && (style->borderTopWidth() < topLeft.height())
- && (ts != DOUBLE || style->borderTopWidth() > 6);
- if (applyLeftInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, topLeft.width() * 2, topLeft.height() * 2),
- style->borderTopWidth());
- }
-
- firstAngleStart = 90;
- firstAngleSpan = upperLeftBorderStylesMatch ? 90 : 45;
-
- // Draw upper left arc
- drawBorderArc(graphicsContext, leftX, leftY, thickness, topLeft, firstAngleStart, firstAngleSpan,
- BSTop, tc, style->color(), ts, true);
- if (applyLeftInnerClip)
- graphicsContext->restore();
- }
-
- if (topRight.width()) {
- int rightX = tx + w - topRight.width() * 2;
- bool applyRightInnerClip = (style->borderRightWidth() < topRight.width())
- && (style->borderTopWidth() < topRight.height())
- && (ts != DOUBLE || style->borderTopWidth() > 6);
- if (applyRightInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(rightX, leftY, topRight.width() * 2, topRight.height() * 2),
- style->borderTopWidth());
- }
-
- if (upperRightBorderStylesMatch) {
- secondAngleStart = 0;
- secondAngleSpan = 90;
- } else {
- secondAngleStart = 45;
- secondAngleSpan = 45;
- }
-
- // Draw upper right arc
- drawBorderArc(graphicsContext, rightX, leftY, thickness, topRight, secondAngleStart, secondAngleSpan,
- BSTop, tc, style->color(), ts, false);
- if (applyRightInnerClip)
- graphicsContext->restore();
- }
- }
- }
-
- if (renderBottom) {
- bool ignore_left = (renderRadii && bottomLeft.width() > 0) ||
- (bc == lc && bt == lt && bs >= OUTSET &&
- (ls == DOTTED || ls == DASHED || ls == SOLID || ls == OUTSET));
-
- bool ignore_right = (renderRadii && bottomRight.width() > 0) ||
- (bc == rc && bt == rt && bs >= OUTSET &&
- (rs == DOTTED || rs == DASHED || rs == SOLID || rs == INSET));
-
- int x = tx;
- int x2 = tx + w;
- if (renderRadii) {
- x += bottomLeft.width();
- x2 -= bottomRight.width();
- }
-
- drawBorder(graphicsContext, x, ty + h - style->borderBottomWidth(), x2, ty + h, BSBottom, bc, style->color(), bs,
- ignore_left ? 0 : style->borderLeftWidth(), ignore_right ? 0 : style->borderRightWidth());
-
- if (renderRadii) {
- thickness = style->borderBottomWidth() * 2;
-
- if (bottomLeft.width()) {
- int leftX = tx;
- int leftY = ty + h - bottomLeft.height() * 2;
- bool applyLeftInnerClip = (style->borderLeftWidth() < bottomLeft.width())
- && (style->borderBottomWidth() < bottomLeft.height())
- && (bs != DOUBLE || style->borderBottomWidth() > 6);
- if (applyLeftInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(leftX, leftY, bottomLeft.width() * 2, bottomLeft.height() * 2),
- style->borderBottomWidth());
- }
-
- if (lowerLeftBorderStylesMatch) {
- firstAngleStart = 180;
- firstAngleSpan = 90;
- } else {
- firstAngleStart = 225;
- firstAngleSpan = 45;
- }
-
- // Draw lower left arc
- drawBorderArc(graphicsContext, leftX, leftY, thickness, bottomLeft, firstAngleStart, firstAngleSpan,
- BSBottom, bc, style->color(), bs, true);
- if (applyLeftInnerClip)
- graphicsContext->restore();
- }
-
- if (bottomRight.width()) {
- int rightY = ty + h - bottomRight.height() * 2;
- int rightX = tx + w - bottomRight.width() * 2;
- bool applyRightInnerClip = (style->borderRightWidth() < bottomRight.width())
- && (style->borderBottomWidth() < bottomRight.height())
- && (bs != DOUBLE || style->borderBottomWidth() > 6);
- if (applyRightInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(rightX, rightY, bottomRight.width() * 2, bottomRight.height() * 2),
- style->borderBottomWidth());
- }
-
- secondAngleStart = 270;
- secondAngleSpan = lowerRightBorderStylesMatch ? 90 : 45;
+ if ((style == DOUBLE && thickness / 2 < 3) || ((style == RIDGE || style == GROOVE) && thickness / 2 < 2))
+ style = SOLID;
- // Draw lower right arc
- drawBorderArc(graphicsContext, rightX, rightY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
- BSBottom, bc, style->color(), bs, false);
- if (applyRightInnerClip)
- graphicsContext->restore();
- }
- }
+ if (!c.isValid()) {
+ if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE)
+ c.setRGB(238, 238, 238);
+ else
+ c = textColor;
}
- if (renderLeft) {
- bool ignore_top = (renderRadii && topLeft.height() > 0) ||
- (tc == lc && tt == lt && ls >= OUTSET &&
- (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
-
- bool ignore_bottom = (renderRadii && bottomLeft.height() > 0) ||
- (bc == lc && bt == lt && ls >= OUTSET &&
- (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
-
- int y = ty;
- int y2 = ty + h;
- if (renderRadii) {
- y += topLeft.height();
- y2 -= bottomLeft.height();
- }
-
- drawBorder(graphicsContext, tx, y, tx + style->borderLeftWidth(), y2, BSLeft, lc, style->color(), ls,
- ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
-
- if (renderRadii && (!upperLeftBorderStylesMatch || !lowerLeftBorderStylesMatch)) {
- int topX = tx;
- thickness = style->borderLeftWidth() * 2;
-
- if (!upperLeftBorderStylesMatch && topLeft.width()) {
- int topY = ty;
- bool applyTopInnerClip = (style->borderLeftWidth() < topLeft.width())
- && (style->borderTopWidth() < topLeft.height())
- && (ls != DOUBLE || style->borderLeftWidth() > 6);
- if (applyTopInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(topX, topY, topLeft.width() * 2, topLeft.height() * 2),
- style->borderLeftWidth());
- }
-
- firstAngleStart = 135;
- firstAngleSpan = 45;
-
- // Draw top left arc
- drawBorderArc(graphicsContext, topX, topY, thickness, topLeft, firstAngleStart, firstAngleSpan,
- BSLeft, lc, style->color(), ls, true);
- if (applyTopInnerClip)
- graphicsContext->restore();
- }
-
- if (!lowerLeftBorderStylesMatch && bottomLeft.width()) {
- int bottomY = ty + h - bottomLeft.height() * 2;
- bool applyBottomInnerClip = (style->borderLeftWidth() < bottomLeft.width())
- && (style->borderBottomWidth() < bottomLeft.height())
- && (ls != DOUBLE || style->borderLeftWidth() > 6);
- if (applyBottomInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(topX, bottomY, bottomLeft.width() * 2, bottomLeft.height() * 2),
- style->borderLeftWidth());
- }
-
- secondAngleStart = 180;
- secondAngleSpan = 45;
+ switch (style) {
+ case BNONE:
+ case BHIDDEN:
+ return;
+ case DOTTED:
+ case DASHED:
+ graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeStyle(style == DOTTED ? DottedStroke : DashedStroke);
+ graphicsContext->setStrokeThickness(thickness);
+ graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
+ break;
+ case DOUBLE: {
+ float third = thickness / 3.0f;
+ float innerThird = (thickness + 1.0f) / 6.0f;
+ int shiftForInner = static_cast<int>(innerThird * 2.5f);
- // Draw bottom left arc
- drawBorderArc(graphicsContext, topX, bottomY, thickness, bottomLeft, secondAngleStart, secondAngleSpan,
- BSLeft, lc, style->color(), ls, false);
- if (applyBottomInnerClip)
- graphicsContext->restore();
+ int outerY = y;
+ int outerHeight = radius.height() * 2;
+ int innerX = x + shiftForInner;
+ int innerY = y + shiftForInner;
+ int innerWidth = (radius.width() - shiftForInner) * 2;
+ int innerHeight = (radius.height() - shiftForInner) * 2;
+ if (innerThird > 1 && (s == BSTop || (firstCorner && (s == BSLeft || s == BSRight)))) {
+ outerHeight += 2;
+ innerHeight += 2;
}
- }
- }
- if (renderRight) {
- bool ignore_top = (renderRadii && topRight.height() > 0) ||
- ((tc == rc) && (tt == rt) &&
- (rs >= DOTTED || rs == INSET) &&
- (ts == DOTTED || ts == DASHED || ts == SOLID || ts == OUTSET));
-
- bool ignore_bottom = (renderRadii && bottomRight.height() > 0) ||
- ((bc == rc) && (bt == rt) &&
- (rs >= DOTTED || rs == INSET) &&
- (bs == DOTTED || bs == DASHED || bs == SOLID || bs == INSET));
-
- int y = ty;
- int y2 = ty + h;
- if (renderRadii) {
- y += topRight.height();
- y2 -= bottomRight.height();
+ graphicsContext->setStrokeStyle(SolidStroke);
+ graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeThickness(third);
+ graphicsContext->strokeArc(IntRect(x, outerY, radius.width() * 2, outerHeight), angleStart, angleSpan);
+ graphicsContext->setStrokeThickness(innerThird > 2 ? innerThird - 1 : innerThird);
+ graphicsContext->strokeArc(IntRect(innerX, innerY, innerWidth, innerHeight), angleStart, angleSpan);
+ break;
}
-
- drawBorder(graphicsContext, tx + w - style->borderRightWidth(), y, tx + w, y2, BSRight, rc, style->color(), rs,
- ignore_top ? 0 : style->borderTopWidth(), ignore_bottom ? 0 : style->borderBottomWidth());
-
- if (renderRadii && (!upperRightBorderStylesMatch || !lowerRightBorderStylesMatch)) {
- thickness = style->borderRightWidth() * 2;
-
- if (!upperRightBorderStylesMatch && topRight.width()) {
- int topX = tx + w - topRight.width() * 2;
- int topY = ty;
- bool applyTopInnerClip = (style->borderRightWidth() < topRight.width())
- && (style->borderTopWidth() < topRight.height())
- && (rs != DOUBLE || style->borderRightWidth() > 6);
- if (applyTopInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(topX, topY, topRight.width() * 2, topRight.height() * 2),
- style->borderRightWidth());
- }
-
- firstAngleStart = 0;
- firstAngleSpan = 45;
-
- // Draw top right arc
- drawBorderArc(graphicsContext, topX, topY, thickness, topRight, firstAngleStart, firstAngleSpan,
- BSRight, rc, style->color(), rs, true);
- if (applyTopInnerClip)
- graphicsContext->restore();
- }
-
- if (!lowerRightBorderStylesMatch && bottomRight.width()) {
- int bottomX = tx + w - bottomRight.width() * 2;
- int bottomY = ty + h - bottomRight.height() * 2;
- bool applyBottomInnerClip = (style->borderRightWidth() < bottomRight.width())
- && (style->borderBottomWidth() < bottomRight.height())
- && (rs != DOUBLE || style->borderRightWidth() > 6);
- if (applyBottomInnerClip) {
- graphicsContext->save();
- graphicsContext->addInnerRoundedRectClip(IntRect(bottomX, bottomY, bottomRight.width() * 2, bottomRight.height() * 2),
- style->borderRightWidth());
- }
-
- secondAngleStart = 315;
- secondAngleSpan = 45;
-
- // Draw bottom right arc
- drawBorderArc(graphicsContext, bottomX, bottomY, thickness, bottomRight, secondAngleStart, secondAngleSpan,
- BSRight, rc, style->color(), rs, false);
- if (applyBottomInnerClip)
- graphicsContext->restore();
+ case GROOVE:
+ case RIDGE: {
+ Color c2;
+ if ((style == RIDGE && (s == BSTop || s == BSLeft)) ||
+ (style == GROOVE && (s == BSBottom || s == BSRight)))
+ c2 = c.dark();
+ else {
+ c2 = c;
+ c = c.dark();
}
- }
- }
-
- if (renderRadii)
- graphicsContext->restore();
-}
-void RenderObject::paintBoxShadow(GraphicsContext* context, int tx, int ty, int w, int h, const RenderStyle* s, bool begin, bool end)
-{
- // FIXME: Deal with border-image. Would be great to use border-image as a mask.
-
- IntRect rect(tx, ty, w, h);
- bool hasBorderRadius = s->hasBorderRadius();
- bool hasOpaqueBackground = s->backgroundColor().isValid() && s->backgroundColor().alpha() == 255;
- for (ShadowData* shadow = s->boxShadow(); shadow; shadow = shadow->next) {
- context->save();
-
- IntSize shadowOffset(shadow->x, shadow->y);
- int shadowBlur = shadow->blur;
- IntRect fillRect(rect);
-
- if (hasBorderRadius) {
- IntRect shadowRect(rect);
- shadowRect.inflate(shadowBlur);
- shadowRect.move(shadowOffset);
- context->clip(shadowRect);
-
- // Move the fill just outside the clip, adding 1 pixel separation so that the fill does not
- // bleed in (due to antialiasing) if the context is transformed.
- IntSize extraOffset(w + max(0, shadowOffset.width()) + shadowBlur + 1, 0);
- shadowOffset -= extraOffset;
- fillRect.move(extraOffset);
- }
+ graphicsContext->setStrokeStyle(SolidStroke);
+ graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeThickness(thickness);
+ graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
- context->setShadow(shadowOffset, shadowBlur, shadow->color);
- if (hasBorderRadius) {
- IntSize topLeft = begin ? s->borderTopLeftRadius() : IntSize();
- IntSize topRight = end ? s->borderTopRightRadius() : IntSize();
- IntSize bottomLeft = begin ? s->borderBottomLeftRadius() : IntSize();
- IntSize bottomRight = end ? s->borderBottomRightRadius() : IntSize();
- if (!hasOpaqueBackground)
- context->clipOutRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight);
- context->fillRoundedRect(fillRect, topLeft, topRight, bottomLeft, bottomRight, Color::black);
- } else {
- if (!hasOpaqueBackground)
- context->clipOut(rect);
- context->fillRect(fillRect, Color::black);
+ float halfThickness = (thickness + 1.0f) / 4.0f;
+ int shiftForInner = static_cast<int>(halfThickness * 1.5f);
+ graphicsContext->setStrokeColor(c2);
+ graphicsContext->setStrokeThickness(halfThickness > 2 ? halfThickness - 1 : halfThickness);
+ graphicsContext->strokeArc(IntRect(x + shiftForInner, y + shiftForInner, (radius.width() - shiftForInner) * 2,
+ (radius.height() - shiftForInner) * 2), angleStart, angleSpan);
+ break;
}
- context->restore();
+ case INSET:
+ if (s == BSTop || s == BSLeft)
+ c = c.dark();
+ case OUTSET:
+ if (style == OUTSET && (s == BSBottom || s == BSRight))
+ c = c.dark();
+ case SOLID:
+ graphicsContext->setStrokeStyle(SolidStroke);
+ graphicsContext->setStrokeColor(c);
+ graphicsContext->setStrokeThickness(thickness);
+ graphicsContext->strokeArc(IntRect(x, y, radius.width() * 2, radius.height() * 2), angleStart, angleSpan);
+ break;
}
}
@@ -1537,13 +964,13 @@ void RenderObject::addPDFURLRect(GraphicsContext* context, const IntRect& rect)
{
if (rect.isEmpty())
return;
- Node* node = element();
- if (!node || !node->isLink() || !node->isElementNode())
+ Node* n = node();
+ if (!n || !n->isLink() || !n->isElementNode())
return;
- const AtomicString& href = static_cast<Element*>(node)->getAttribute(hrefAttr);
+ const AtomicString& href = static_cast<Element*>(n)->getAttribute(hrefAttr);
if (href.isNull())
return;
- context->setURLForRect(node->document()->completeURL(href), rect);
+ context->setURLForRect(n->document()->completeURL(href), rect);
}
void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty, int w, int h, const RenderStyle* style)
@@ -1564,11 +991,11 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
if (!theme()->supportsFocusRing(style)) {
// Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
graphicsContext->initFocusRing(ow, offset);
+ addFocusRingRects(graphicsContext, tx, ty);
if (style->outlineStyleIsAuto())
- addFocusRingRects(graphicsContext, tx, ty);
+ graphicsContext->drawFocusRing(oc);
else
addPDFURLRect(graphicsContext, graphicsContext->focusRingBoundingRect());
- graphicsContext->drawFocusRing(oc);
graphicsContext->clearFocusRing();
}
}
@@ -1584,21 +1011,52 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
if (h < 0 || w < 0)
return;
- drawBorder(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow,
+ drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx, ty + h + ow,
BSLeft, Color(oc), style->color(), os, ow, ow);
- drawBorder(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty,
+ drawLineForBoxSide(graphicsContext, tx - ow, ty - ow, tx + w + ow, ty,
BSTop, Color(oc), style->color(), os, ow, ow);
- drawBorder(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow,
+ drawLineForBoxSide(graphicsContext, tx + w, ty - ow, tx + w + ow, ty + h + ow,
BSRight, Color(oc), style->color(), os, ow, ow);
- drawBorder(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow,
+ drawLineForBoxSide(graphicsContext, tx - ow, ty + h, tx + w + ow, ty + h + ow,
BSBottom, Color(oc), style->color(), os, ow, ow);
}
-void RenderObject::addLineBoxRects(Vector<IntRect>&, unsigned, unsigned, bool)
+
+void RenderObject::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool)
{
+ if (!firstChild()) {
+ if ((isInline() || isAnonymousBlock())) {
+ FloatPoint absPos = localToAbsolute(FloatPoint());
+ absoluteRects(rects, absPos.x(), absPos.y());
+ }
+ return;
+ }
+
+ unsigned offset = start;
+ for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset) {
+ if (child->isText() || child->isInline() || child->isAnonymousBlock()) {
+ FloatPoint absPos = child->localToAbsolute(FloatPoint());
+ child->absoluteRects(rects, absPos.x(), absPos.y());
+ }
+ }
+}
+
+void RenderObject::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool)
+{
+ if (!firstChild()) {
+ if (isInline() || isAnonymousBlock())
+ absoluteQuads(quads);
+ return;
+ }
+
+ unsigned offset = start;
+ for (RenderObject* child = childAt(start); child && offset < end; child = child->nextSibling(), ++offset) {
+ if (child->isText() || child->isInline() || child->isAnonymousBlock())
+ child->absoluteQuads(quads);
+ }
}
IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms)
@@ -1652,58 +1110,80 @@ void RenderObject::paint(PaintInfo& /*paintInfo*/, int /*tx*/, int /*ty*/)
{
}
-RenderBox* RenderObject::containerForRepaint() const
+RenderBoxModelObject* RenderObject::containerForRepaint() const
{
- // For now, all repaints are root-relative.
+#if USE(ACCELERATED_COMPOSITING)
+ if (RenderView* v = view()) {
+ if (v->usesCompositing()) {
+ RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayer();
+ return compLayer ? compLayer->renderer() : 0;
+ }
+ }
+#endif
+ // Do root-relative repaint.
return 0;
}
+void RenderObject::repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect& r, bool immediate)
+{
+ if (!repaintContainer || repaintContainer->isRenderView()) {
+ RenderView* v = repaintContainer ? toRenderView(repaintContainer) : view();
+ v->repaintViewRectangle(r, immediate);
+ } else {
+#if USE(ACCELERATED_COMPOSITING)
+ RenderView* v = view();
+ if (v->usesCompositing()) {
+ ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited());
+ repaintContainer->layer()->setBackingNeedsRepaintInRect(r);
+ }
+#else
+ ASSERT_NOT_REACHED();
+#endif
+ }
+}
+
void RenderObject::repaint(bool immediate)
{
- // Can't use view(), since we might be unrooted.
- RenderObject* o = this;
- while (o->parent())
- o = o->parent();
- if (!o->isRenderView())
+ // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
+ RenderView* view;
+ if (!isRooted(&view))
return;
- RenderView* view = static_cast<RenderView*>(o);
if (view->printing())
return; // Don't repaint if we're printing.
- view->repaintViewRectangle(absoluteClippedOverflowRect(), immediate);
+ RenderBoxModelObject* repaintContainer = containerForRepaint();
+ repaintUsingContainer(repaintContainer ? repaintContainer : view, clippedOverflowRectForRepaint(repaintContainer), immediate);
}
void RenderObject::repaintRectangle(const IntRect& r, bool immediate)
{
- // Can't use view(), since we might be unrooted.
- RenderObject* o = this;
- while (o->parent())
- o = o->parent();
- if (!o->isRenderView())
+ // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
+ RenderView* view;
+ if (!isRooted(&view))
return;
- RenderView* view = static_cast<RenderView*>(o);
if (view->printing())
return; // Don't repaint if we're printing.
- IntRect absRect(r);
+ IntRect dirtyRect(r);
// FIXME: layoutDelta needs to be applied in parts before/after transforms and
// repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
- absRect.move(view->layoutDelta());
+ dirtyRect.move(view->layoutDelta());
- computeAbsoluteRepaintRect(absRect);
- view->repaintViewRectangle(absRect, immediate);
+ RenderBoxModelObject* repaintContainer = containerForRepaint();
+ computeRectForRepaint(repaintContainer, dirtyRect);
+ repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);
}
-bool RenderObject::repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const IntRect& oldOutlineBox)
+bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox)
{
RenderView* v = view();
if (v->printing())
return false; // Don't repaint if we're printing.
- IntRect newBounds = absoluteClippedOverflowRect();
+ IntRect newBounds = clippedOverflowRectForRepaint(repaintContainer);
IntRect newOutlineBox;
bool fullRepaint = selfNeedsLayout();
@@ -1711,14 +1191,18 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const In
if (!fullRepaint && style()->borderFit() == BorderFitLines)
fullRepaint = true;
if (!fullRepaint) {
- newOutlineBox = absoluteOutlineBounds();
+ newOutlineBox = outlineBoundsForRepaint(repaintContainer);
if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
fullRepaint = true;
}
+
+ if (!repaintContainer)
+ repaintContainer = v;
+
if (fullRepaint) {
- v->repaintViewRectangle(oldBounds);
+ repaintUsingContainer(repaintContainer, oldBounds);
if (newBounds != oldBounds)
- v->repaintViewRectangle(newBounds);
+ repaintUsingContainer(repaintContainer, newBounds);
return true;
}
@@ -1727,35 +1211,34 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const In
int deltaLeft = newBounds.x() - oldBounds.x();
if (deltaLeft > 0)
- v->repaintViewRectangle(IntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
+ repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
else if (deltaLeft < 0)
- v->repaintViewRectangle(IntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
+ repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
int deltaRight = newBounds.right() - oldBounds.right();
if (deltaRight > 0)
- v->repaintViewRectangle(IntRect(oldBounds.right(), newBounds.y(), deltaRight, newBounds.height()));
+ repaintUsingContainer(repaintContainer, IntRect(oldBounds.right(), newBounds.y(), deltaRight, newBounds.height()));
else if (deltaRight < 0)
- v->repaintViewRectangle(IntRect(newBounds.right(), oldBounds.y(), -deltaRight, oldBounds.height()));
+ repaintUsingContainer(repaintContainer, IntRect(newBounds.right(), oldBounds.y(), -deltaRight, oldBounds.height()));
int deltaTop = newBounds.y() - oldBounds.y();
if (deltaTop > 0)
- v->repaintViewRectangle(IntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
+ repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
else if (deltaTop < 0)
- v->repaintViewRectangle(IntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
+ repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
int deltaBottom = newBounds.bottom() - oldBounds.bottom();
if (deltaBottom > 0)
- v->repaintViewRectangle(IntRect(newBounds.x(), oldBounds.bottom(), newBounds.width(), deltaBottom));
+ repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), oldBounds.bottom(), newBounds.width(), deltaBottom));
else if (deltaBottom < 0)
- v->repaintViewRectangle(IntRect(oldBounds.x(), newBounds.bottom(), oldBounds.width(), -deltaBottom));
+ repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), newBounds.bottom(), oldBounds.width(), -deltaBottom));
if (newOutlineBox == oldOutlineBox)
return false;
// We didn't move, but we did change size. Invalidate the delta, which will consist of possibly
// two rectangles (but typically only one).
- RenderFlow* continuation = virtualContinuation();
- RenderStyle* outlineStyle = !isInline() && continuation ? continuation->style() : style();
+ RenderStyle* outlineStyle = outlineStyleForRepaint();
int ow = outlineStyle->outlineSize();
ShadowData* boxShadow = style()->boxShadow();
int width = abs(newOutlineBox.width() - oldOutlineBox.width());
@@ -1773,7 +1256,7 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const In
int right = min(newBounds.right(), oldBounds.right());
if (rightRect.x() < right) {
rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
- v->repaintViewRectangle(rightRect);
+ repaintUsingContainer(repaintContainer, rightRect);
}
}
int height = abs(newOutlineBox.height() - oldOutlineBox.height());
@@ -1791,7 +1274,7 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const In
int bottom = min(newBounds.bottom(), oldBounds.bottom());
if (bottomRect.y() < bottom) {
bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
- v->repaintViewRectangle(bottomRect);
+ repaintUsingContainer(repaintContainer, bottomRect);
}
}
return false;
@@ -1813,39 +1296,27 @@ bool RenderObject::checkForRepaintDuringLayout() const
return !document()->view()->needsFullRepaint() && !hasLayer();
}
-IntRect RenderObject::rectWithOutlineForRepaint(RenderBox* repaintContainer, int outlineWidth)
+IntRect RenderObject::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth)
{
IntRect r(clippedOverflowRectForRepaint(repaintContainer));
r.inflate(outlineWidth);
-
- if (virtualContinuation() && !isInline())
- r.inflateY(toRenderBox(this)->collapsedMarginTop());
-
- if (isRenderInline()) {
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
- if (!curr->isText())
- r.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineWidth));
- }
- }
-
return r;
}
-IntRect RenderObject::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderObject::clippedOverflowRectForRepaint(RenderBoxModelObject*)
{
- if (parent())
- return parent()->clippedOverflowRectForRepaint(repaintContainer);
+ ASSERT_NOT_REACHED();
return IntRect();
}
-void RenderObject::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer, bool fixed)
+void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
{
if (repaintContainer == this)
return;
if (RenderObject* o = parent()) {
if (o->isBlockFlow()) {
- RenderBlock* cb = static_cast<RenderBlock*>(o);
+ RenderBlock* cb = toRenderBlock(o);
if (cb->hasColumns())
cb->adjustRectForColumns(rect);
}
@@ -1866,7 +1337,7 @@ void RenderObject::computeRectForRepaint(IntRect& rect, RenderBox* repaintContai
return;
}
- o->computeRectForRepaint(rect, repaintContainer, fixed);
+ o->computeRectForRepaint(repaintContainer, rect, fixed);
}
}
@@ -1878,8 +1349,8 @@ void RenderObject::dirtyLinesFromChangedChild(RenderObject*)
void RenderObject::showTreeForThis() const
{
- if (element())
- element()->showTreeForThis();
+ if (node())
+ node()->showTreeForThis();
}
#endif // NDEBUG
@@ -1888,7 +1359,7 @@ Color RenderObject::selectionBackgroundColor() const
{
Color color;
if (style()->userSelect() != SELECT_NONE) {
- RenderStyle* pseudoStyle = getCachedPseudoStyle(RenderStyle::SELECTION);
+ RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION);
if (pseudoStyle && pseudoStyle->backgroundColor().isValid())
color = pseudoStyle->backgroundColor().blendWithWhite();
else
@@ -1906,7 +1377,7 @@ Color RenderObject::selectionForegroundColor() const
if (style()->userSelect() == SELECT_NONE)
return color;
- if (RenderStyle* pseudoStyle = getCachedPseudoStyle(RenderStyle::SELECTION)) {
+ if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) {
color = pseudoStyle->textFillColor();
if (!color.isValid())
color = pseudoStyle->color();
@@ -1924,7 +1395,7 @@ Node* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& d
return 0;
for (const RenderObject* curr = this; curr; curr = curr->parent()) {
- Node* elt = curr->element();
+ Node* elt = curr->node();
if (elt && elt->nodeType() == Node::TEXT_NODE) {
// Since there's no way for the author to address the -webkit-user-drag style for a text node,
// we use our own judgement.
@@ -1958,17 +1429,6 @@ void RenderObject::selectionStartEnd(int& spos, int& epos) const
view()->selectionStartEnd(spos, epos);
}
-RenderBlock* RenderObject::createAnonymousBlock()
-{
- RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(m_style.get());
- newStyle->setDisplay(BLOCK);
-
- RenderBlock* newBox = new (renderArena()) RenderBlock(document() /* anonymous box */);
- newBox->setStyle(newStyle.release());
- return newBox;
-}
-
void RenderObject::handleDynamicFloatPositionChange()
{
// We have gone from not affecting the inline status of the parent flow to suddenly
@@ -1976,30 +1436,14 @@ void RenderObject::handleDynamicFloatPositionChange()
// childrenInline() state and our state.
setInline(style()->isDisplayInlineType());
if (isInline() != parent()->childrenInline()) {
- if (!isInline()) {
- if (parent()->isRenderInline()) {
- // We have to split the parent flow.
- RenderInline* parentInline = static_cast<RenderInline*>(parent());
- RenderBlock* newBox = parentInline->createAnonymousBlock();
-
- RenderFlow* oldContinuation = parentInline->continuation();
- parentInline->setContinuation(newBox);
-
- RenderObject* beforeChild = nextSibling();
- parent()->removeChildNode(this);
- parentInline->splitFlow(beforeChild, newBox, this, oldContinuation);
- } else if (parent()->isRenderBlock()) {
- RenderBlock* o = static_cast<RenderBlock*>(parent());
- o->makeChildrenNonInline();
- if (o->isAnonymousBlock() && o->parent())
- o->parent()->removeLeftoverAnonymousBlock(o);
- // o may be dead here
- }
- } else {
+ if (!isInline())
+ toRenderBoxModelObject(parent())->childBecameNonInline(this);
+ else {
// An anonymous block must be made to wrap this inline.
- RenderBlock* box = createAnonymousBlock();
- parent()->insertChildNode(box, this);
- box->appendChildNode(parent()->removeChildNode(this));
+ RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock();
+ RenderObjectChildList* childlist = parent()->virtualChildren();
+ childlist->insertChildNode(parent(), block, this);
+ block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this));
}
}
}
@@ -2012,18 +1456,48 @@ void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
setStyle(style);
}
+StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ // If transform changed, and we are not composited, need to do a layout.
+ if (contextSensitiveProperties & ContextSensitivePropertyTransform)
+ // Text nodes share style with their parents but transforms don't apply to them,
+ // hence the !isText() check.
+ // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
+ if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
+ diff = StyleDifferenceLayout;
+ else if (diff < StyleDifferenceRecompositeLayer)
+ diff = StyleDifferenceRecompositeLayer;
+
+ // If opacity changed, and we are not composited, need to repaint (also
+ // ignoring text nodes)
+ if (contextSensitiveProperties & ContextSensitivePropertyOpacity)
+ if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited()))
+ diff = StyleDifferenceRepaintLayer;
+ else if (diff < StyleDifferenceRecompositeLayer)
+ diff = StyleDifferenceRecompositeLayer;
+#else
+ UNUSED_PARAM(contextSensitiveProperties);
+#endif
+
+ // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
+ if (diff == StyleDifferenceRepaintLayer && !hasLayer())
+ diff = StyleDifferenceRepaint;
+
+ return diff;
+}
+
void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
{
if (m_style == style)
return;
- RenderStyle::Diff diff = RenderStyle::Equal;
+ StyleDifference diff = StyleDifferenceEqual;
+ unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
if (m_style)
- diff = m_style->diff(style.get());
+ diff = m_style->diff(style.get(), contextSensitiveProperties);
- // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
- if (diff == RenderStyle::RepaintLayer && !hasLayer())
- diff = RenderStyle::Repaint;
+ diff = adjustStyleDifference(diff, contextSensitiveProperties);
styleWillChange(diff, style.get());
@@ -2036,7 +1510,32 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
+ // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
+ // during styleDidChange (it's used by clippedOverflowRectForRepaint()).
+ if (m_style->outlineWidth() > 0 && m_style->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
+ toRenderView(document()->renderer())->setMaximalOutlineSize(m_style->outlineSize());
+
styleDidChange(diff, oldStyle.get());
+
+ if (!m_parent || isText())
+ return;
+
+ // Now that the layer (if any) has been updated, we need to adjust the diff again,
+ // check whether we should layout now, and decide if we need to repaint.
+ StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
+
+ if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
+ if (updatedDiff == StyleDifferenceLayout)
+ setNeedsLayoutAndPrefWidthsRecalc();
+ else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
+ setNeedsPositionedMovementLayout();
+ }
+
+ if (updatedDiff == StyleDifferenceRepaintLayer || updatedDiff == StyleDifferenceRepaint) {
+ // Do a repaint with the new style now, e.g., for example if we go from
+ // not having an outline to having an outline.
+ repaint();
+ }
}
void RenderObject::setStyleInternal(PassRefPtr<RenderStyle> style)
@@ -2044,7 +1543,7 @@ void RenderObject::setStyleInternal(PassRefPtr<RenderStyle> style)
m_style = style;
}
-void RenderObject::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
if (m_style) {
// If our z-index changes value or our visibility changes,
@@ -2064,30 +1563,30 @@ void RenderObject::styleWillChange(RenderStyle::Diff diff, const RenderStyle* ne
l->setHasVisibleContent(true);
else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) {
l->dirtyVisibleContentStatus();
- if (diff > RenderStyle::RepaintLayer)
+ if (diff > StyleDifferenceRepaintLayer)
repaint();
}
}
}
}
- if (m_parent && (diff == RenderStyle::Repaint || newStyle->outlineSize() < m_style->outlineSize()))
+ if (m_parent && (diff == StyleDifferenceRepaint || newStyle->outlineSize() < m_style->outlineSize()))
repaint();
if (isFloating() && (m_style->floating() != newStyle->floating()))
// For changes in float styles, we need to conceivably remove ourselves
// from the floating objects list.
- removeFromObjectLists();
+ toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
else if (isPositioned() && (newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition))
// For changes in positioning styles, we need to conceivably remove ourselves
// from the positioned objects list.
- removeFromObjectLists();
+ toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
s_affectsParentBlock = isFloatingOrPositioned() &&
(!newStyle->isFloating() && newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition)
&& parent() && (parent()->isBlockFlow() || parent()->isRenderInline());
// reset style flags
- if (diff == RenderStyle::Layout || diff == RenderStyle::LayoutPositionedMovementOnly) {
+ if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
m_floating = false;
m_positioned = false;
m_relPositioned = false;
@@ -2113,24 +1612,21 @@ void RenderObject::styleWillChange(RenderStyle::Diff diff, const RenderStyle* ne
}
}
-void RenderObject::styleDidChange(RenderStyle::Diff diff, const RenderStyle*)
+void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle*)
{
- setHasBoxDecorations(m_style->hasBorder() || m_style->hasBackground() || m_style->hasAppearance() || m_style->boxShadow());
-
if (s_affectsParentBlock)
handleDynamicFloatPositionChange();
if (!m_parent)
return;
- if (diff == RenderStyle::Layout)
+ if (diff == StyleDifferenceLayout)
setNeedsLayoutAndPrefWidthsRecalc();
- else if (diff == RenderStyle::LayoutPositionedMovementOnly)
+ else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
setNeedsPositionedMovementLayout();
- else if (diff == RenderStyle::RepaintLayer || diff == RenderStyle::Repaint)
- // Do a repaint with the new style now, e.g., for example if we go from
- // not having an outline to having an outline.
- repaint();
+
+ // Don't check for repaint here; we need to wait until the layer has been
+ // updated by subclasses before we know if we have to repaint (in setStyle()).
}
void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
@@ -2163,42 +1659,82 @@ IntRect RenderObject::viewRect() const
FloatPoint RenderObject::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
{
- RenderObject* o = parent();
- if (o) {
- if (o->hasOverflowClip())
- localPoint -= toRenderBox(o)->layer()->scrolledContentOffset();
- return o->localToAbsolute(localPoint, fixed, useTransforms);
- }
-
- return FloatPoint();
+ TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
+ mapLocalToContainer(0, fixed, useTransforms, transformState);
+ transformState.flatten();
+
+ return transformState.lastPlanarPoint();
}
FloatPoint RenderObject::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool useTransforms) const
{
- RenderObject* o = parent();
- if (o) {
- FloatPoint localPoint = o->absoluteToLocal(containerPoint, fixed, useTransforms);
- if (o->hasOverflowClip())
- localPoint += toRenderBox(o)->layer()->scrolledContentOffset();
- return localPoint;
- }
- return FloatPoint();
+ TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint);
+ mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
+ transformState.flatten();
+
+ return transformState.lastPlanarPoint();
}
-FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBox* repaintContainer, bool fixed) const
+void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
{
if (repaintContainer == this)
- return localQuad;
+ return;
RenderObject* o = parent();
+ if (!o)
+ return;
+
+ if (o->hasOverflowClip())
+ transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset());
+
+ o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
+}
+
+void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
+{
+ RenderObject* o = parent();
if (o) {
- FloatQuad quad = localQuad;
+ o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
if (o->hasOverflowClip())
- quad -= toRenderBox(o)->layer()->scrolledContentOffset();
- return o->localToContainerQuad(quad, repaintContainer, fixed);
+ transformState.move(toRenderBox(o)->layer()->scrolledContentOffset());
}
+}
- return FloatQuad();
+TransformationMatrix RenderObject::transformFromContainer(const RenderObject* containerObject, const IntSize& offsetInContainer) const
+{
+ TransformationMatrix containerTransform;
+ containerTransform.translate(offsetInContainer.width(), offsetInContainer.height());
+ RenderLayer* layer;
+ if (hasLayer() && (layer = toRenderBox(this)->layer()) && layer->transform())
+ containerTransform.multLeft(layer->currentTransform());
+
+#if ENABLE(3D_RENDERING)
+ if (containerObject && containerObject->style()->hasPerspective()) {
+ // Perpsective on the container affects us, so we have to factor it in here.
+ ASSERT(containerObject->hasLayer());
+ FloatPoint perspectiveOrigin = toRenderBox(containerObject)->layer()->perspectiveOrigin();
+
+ TransformationMatrix perspectiveMatrix;
+ perspectiveMatrix.applyPerspective(containerObject->style()->perspective());
+
+ containerTransform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0);
+ containerTransform.multiply(perspectiveMatrix);
+ containerTransform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0);
+ }
+#else
+ UNUSED_PARAM(containerObject);
+#endif
+
+ return containerTransform;
+}
+
+FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed) const
+{
+ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint(), &localQuad);
+ mapLocalToContainer(repaintContainer, fixed, true, transformState);
+ transformState.flatten();
+
+ return transformState.lastPlanarQuad();
}
IntSize RenderObject::offsetFromContainer(RenderObject* o) const
@@ -2222,12 +1758,27 @@ IntRect RenderObject::localCaretRect(InlineBox*, int, int* extraWidthToEndOfLine
RenderView* RenderObject::view() const
{
- return static_cast<RenderView*>(document()->renderer());
+ return toRenderView(document()->renderer());
+}
+
+bool RenderObject::isRooted(RenderView** view)
+{
+ RenderObject* o = this;
+ while (o->parent())
+ o = o->parent();
+
+ if (!o->isRenderView())
+ return false;
+
+ if (view)
+ *view = toRenderView(o);
+
+ return true;
}
bool RenderObject::hasOutlineAnnotation() const
{
- return element() && element()->isLink() && document()->printing();
+ return node() && node()->isLink() && document()->printing();
}
RenderObject* RenderObject::container() const
@@ -2269,51 +1820,19 @@ RenderObject* RenderObject::container() const
return o;
}
-// This code has been written to anticipate the addition of CSS3-::outside and ::inside generated
-// content (and perhaps XBL). That's why it uses the render tree and not the DOM tree.
-RenderObject* RenderObject::hoverAncestor() const
-{
- return (!isInline() && virtualContinuation()) ? virtualContinuation() : parent();
-}
-
bool RenderObject::isSelectionBorder() const
{
SelectionState st = selectionState();
return st == SelectionStart || st == SelectionEnd || st == SelectionBoth;
}
-void RenderObject::removeFromObjectLists()
-{
- if (documentBeingDestroyed())
- return;
-
- if (isFloating()) {
- RenderBlock* outermostBlock = containingBlock();
- for (RenderBlock* p = outermostBlock; p && !p->isRenderView(); p = p->containingBlock()) {
- if (p->containsFloat(this))
- outermostBlock = p;
- }
-
- if (outermostBlock)
- outermostBlock->markAllDescendantsWithFloatsForLayout(toRenderBox(this), false);
- }
-
- if (isPositioned()) {
- RenderObject* p;
- for (p = parent(); p; p = p->parent()) {
- if (p->isRenderBlock())
- static_cast<RenderBlock*>(p)->removePositionedObject(toRenderBox(this));
- }
- }
-}
-
-bool RenderObject::documentBeingDestroyed() const
-{
- return !document()->renderer();
-}
-
void RenderObject::destroy()
{
+ // Destroy any leftover anonymous children.
+ RenderObjectChildList* children = virtualChildren();
+ if (children)
+ children->destroyLeftoverChildren();
+
// If this renderer is being autoscrolled, stop the autoscroll timer
if (document()->frame() && document()->frame()->eventHandler()->autoscrollRenderer() == this)
document()->frame()->eventHandler()->stopAutoscrollTimer(true);
@@ -2333,12 +1852,11 @@ void RenderObject::destroy()
remove();
- // FIXME: Would like to do this in RenderBox, but the timing is so complicated that this can't easily
- // be moved into RenderBox::destroy.
- RenderArena* arena = renderArena();
+ // FIXME: Would like to do this in RenderBoxModelObject, but the timing is so complicated that this can't easily
+ // be moved into RenderBoxModelObject::destroy.
if (hasLayer())
- toRenderBox(this)->layer()->destroy(arena);
- arenaDelete(arena, this);
+ toRenderBoxModelObject(this)->destroyLayer();
+ arenaDelete(renderArena(), this);
}
void RenderObject::arenaDelete(RenderArena* arena, void* base)
@@ -2374,14 +1892,14 @@ void RenderObject::arenaDelete(RenderArena* arena, void* base)
arena->free(*(size_t*)base, base);
}
-VisiblePosition RenderObject::positionForCoordinates(int, int)
+VisiblePosition RenderObject::positionForCoordinates(int x, int y)
{
- return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM);
+ return positionForPoint(IntPoint(x, y));
}
-VisiblePosition RenderObject::positionForPoint(const IntPoint& point)
+VisiblePosition RenderObject::positionForPoint(const IntPoint&)
{
- return positionForCoordinates(point.x(), point.y());
+ return createVisiblePosition(caretMinOffset(), DOWNSTREAM);
}
void RenderObject::updateDragState(bool dragOn)
@@ -2389,12 +1907,9 @@ void RenderObject::updateDragState(bool dragOn)
bool valueChanged = (dragOn != m_isDragging);
m_isDragging = dragOn;
if (valueChanged && style()->affectedByDragRules())
- element()->setChanged();
+ node()->setChanged();
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
curr->updateDragState(dragOn);
- RenderFlow* continuation = virtualContinuation();
- if (continuation)
- continuation->updateDragState(dragOn);
}
bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const IntPoint& point, int tx, int ty, HitTestFilter hitTestFilter)
@@ -2425,34 +1940,12 @@ void RenderObject::updateHitTestResult(HitTestResult& result, const IntPoint& po
if (result.innerNode())
return;
- Node* node = element();
- IntPoint localPoint(point);
- if (isRenderView())
- node = document()->documentElement();
- else if (!isInline() && virtualContinuation())
- // We are in the margins of block elements that are part of a continuation. In
- // this case we're actually still inside the enclosing inline element that was
- // split. Go ahead and set our inner node accordingly.
- node = virtualContinuation()->element();
-
- if (node) {
- if (node->renderer() && node->renderer()->virtualContinuation() && node->renderer() != this) {
- // We're in the continuation of a split inline. Adjust our local point to be in the coordinate space
- // of the principal renderer's containing block. This will end up being the innerNonSharedNode.
- RenderBlock* firstBlock = node->renderer()->containingBlock();
-
- // Get our containing block.
- RenderBox* block = toRenderBox(this);
- if (isInline())
- block = containingBlock();
-
- localPoint.move(block->x() - firstBlock->x(), block->y() - firstBlock->y());
- }
-
- result.setInnerNode(node);
+ Node* n = node();
+ if (n) {
+ result.setInnerNode(n);
if (!result.innerNonSharedNode())
- result.setInnerNonSharedNode(node);
- result.setLocalPoint(localPoint);
+ result.setInnerNonSharedNode(n);
+ result.setLocalPoint(point);
}
}
@@ -2461,78 +1954,9 @@ bool RenderObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int /*x*/,
return false;
}
-int RenderObject::verticalPositionHint(bool firstLine) const
-{
- if (firstLine) // We're only really a first-line style if the document actually uses first-line rules.
- firstLine = document()->usesFirstLineRules();
- int vpos = m_verticalPosition;
- if (m_verticalPosition == PositionUndefined || firstLine) {
- vpos = getVerticalPosition(firstLine);
- if (!firstLine)
- m_verticalPosition = vpos;
- }
-
- return vpos;
-}
-
-int RenderObject::getVerticalPosition(bool firstLine) const
-{
- if (!isInline())
- return 0;
-
- // This method determines the vertical position for inline elements.
- int vpos = 0;
- EVerticalAlign va = style()->verticalAlign();
- if (va == TOP)
- vpos = PositionTop;
- else if (va == BOTTOM)
- vpos = PositionBottom;
- else {
- bool checkParent = parent()->isInline() && !parent()->isInlineBlockOrInlineTable() && parent()->style()->verticalAlign() != TOP && parent()->style()->verticalAlign() != BOTTOM;
- vpos = checkParent ? parent()->verticalPositionHint(firstLine) : 0;
- // don't allow elements nested inside text-top to have a different valignment.
- if (va == BASELINE)
- return vpos;
-
- const Font& f = parent()->style(firstLine)->font();
- int fontsize = f.pixelSize();
-
- if (va == SUB)
- vpos += fontsize / 5 + 1;
- else if (va == SUPER)
- vpos -= fontsize / 3 + 1;
- else if (va == TEXT_TOP)
- vpos += baselinePosition(firstLine) - f.ascent();
- else if (va == MIDDLE)
- vpos += -static_cast<int>(f.xHeight() / 2) - lineHeight(firstLine) / 2 + baselinePosition(firstLine);
- else if (va == TEXT_BOTTOM) {
- vpos += f.descent();
- if (!isReplaced())
- vpos -= style(firstLine)->font().descent();
- } else if (va == BASELINE_MIDDLE)
- vpos += -lineHeight(firstLine) / 2 + baselinePosition(firstLine);
- else if (va == LENGTH)
- vpos -= style()->verticalAlignLength().calcValue(lineHeight(firstLine));
- }
-
- return vpos;
-}
-
int RenderObject::lineHeight(bool firstLine, bool /*isRootLineBox*/) const
{
- RenderStyle* s = style(firstLine);
-
- Length lh = s->lineHeight();
-
- // its "unset", choose nice default
- if (lh.isNegative())
- return s->font().lineSpacing();
-
- if (lh.isPercent())
- return lh.calcMinValue(s->fontSize());
-
- // its fixed
- return lh.value();
+ return style(firstLine)->computedLineHeight();
}
int RenderObject::baselinePosition(bool firstLine, bool isRootLineBox) const
@@ -2544,7 +1968,7 @@ int RenderObject::baselinePosition(bool firstLine, bool isRootLineBox) const
void RenderObject::scheduleRelayout()
{
if (isRenderView()) {
- FrameView* view = static_cast<RenderView*>(this)->frameView();
+ FrameView* view = toRenderView(this)->frameView();
if (view)
view->scheduleRelayout();
} else if (parent()) {
@@ -2554,59 +1978,42 @@ void RenderObject::scheduleRelayout()
}
}
-void RenderObject::removeLeftoverAnonymousBlock(RenderBlock*)
-{
-}
-
-InlineBox* RenderObject::createInlineBox(bool, bool unusedIsRootLineBox, bool)
-{
- ASSERT_UNUSED(unusedIsRootLineBox, !unusedIsRootLineBox);
- return new (renderArena()) InlineBox(this);
-}
-
-void RenderObject::dirtyLineBoxes(bool, bool)
-{
-}
-
-InlineBox* RenderObject::inlineBoxWrapper() const
-{
- return 0;
-}
-
-void RenderObject::setInlineBoxWrapper(InlineBox*)
-{
-}
-
-void RenderObject::deleteLineBoxWrapper()
+void RenderObject::layout()
{
+ ASSERT(needsLayout());
+ RenderObject* child = firstChild();
+ while (child) {
+ child->layoutIfNeeded();
+ ASSERT(!child->needsLayout());
+ child = child->nextSibling();
+ }
+ setNeedsLayout(false);
}
-RenderStyle* RenderObject::firstLineStyle() const
+RenderStyle* RenderObject::firstLineStyleSlowCase() const
{
- if (!document()->usesFirstLineRules())
- return m_style.get();
+ ASSERT(document()->usesFirstLineRules());
- RenderStyle* s = m_style.get();
- const RenderObject* obj = isText() ? parent() : this;
- if (obj->isBlockFlow()) {
- RenderBlock* firstLineBlock = obj->firstLineBlock();
- if (firstLineBlock)
- s = firstLineBlock->getCachedPseudoStyle(RenderStyle::FIRST_LINE, style());
- } else if (!obj->isAnonymous() && obj->isRenderInline()) {
- RenderStyle* parentStyle = obj->parent()->firstLineStyle();
- if (parentStyle != obj->parent()->style()) {
- // A first-line style is in effect. We need to cache a first-line style
- // for ourselves.
- style()->setHasPseudoStyle(RenderStyle::FIRST_LINE_INHERITED);
- s = obj->getCachedPseudoStyle(RenderStyle::FIRST_LINE_INHERITED, parentStyle);
+ RenderStyle* style = m_style.get();
+ const RenderObject* renderer = isText() ? parent() : this;
+ if (renderer->isBlockFlow()) {
+ if (RenderBlock* firstLineBlock = renderer->firstLineBlock())
+ style = firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);
+ } else if (!renderer->isAnonymous() && renderer->isRenderInline()) {
+ RenderStyle* parentStyle = renderer->parent()->firstLineStyle();
+ if (parentStyle != renderer->parent()->style()) {
+ // A first-line style is in effect. Cache a first-line style for ourselves.
+ style->setHasPseudoStyle(FIRST_LINE_INHERITED);
+ style = renderer->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);
}
}
- return s;
+
+ return style;
}
-RenderStyle* RenderObject::getCachedPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle) const
+RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
{
- if (pseudo < RenderStyle::FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
+ if (pseudo < FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
return 0;
RenderStyle* cachedStyle = style()->getCachedPseudoStyle(pseudo);
@@ -2619,26 +2026,26 @@ RenderStyle* RenderObject::getCachedPseudoStyle(RenderStyle::PseudoId pseudo, Re
return 0;
}
-PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle) const
+PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(PseudoId pseudo, RenderStyle* parentStyle) const
{
- if (pseudo < RenderStyle::FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
+ if (pseudo < FIRST_INTERNAL_PSEUDOID && !style()->hasPseudoStyle(pseudo))
return 0;
if (!parentStyle)
parentStyle = style();
- Node* node = element();
- while (node && !node->isElementNode())
- node = node->parentNode();
- if (!node)
+ Node* n = node();
+ while (n && !n->isElementNode())
+ n = n->parentNode();
+ if (!n)
return 0;
RefPtr<RenderStyle> result;
- if (pseudo == RenderStyle::FIRST_LINE_INHERITED) {
- result = document()->styleSelector()->styleForElement(static_cast<Element*>(node), parentStyle, false);
- result->setStyleType(RenderStyle::FIRST_LINE_INHERITED);
+ if (pseudo == FIRST_LINE_INHERITED) {
+ result = document()->styleSelector()->styleForElement(static_cast<Element*>(n), parentStyle, false);
+ result->setStyleType(FIRST_LINE_INHERITED);
} else
- result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<Element*>(node), parentStyle);
+ result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<Element*>(n), parentStyle);
return result.release();
}
@@ -2681,10 +2088,10 @@ void RenderObject::getTextDecorationColors(int decorations, Color& underline, Co
}
}
curr = curr->parent();
- if (curr && curr->isRenderBlock() && curr->virtualContinuation())
- curr = curr->virtualContinuation();
- } while (curr && decorations && (!quirksMode || !curr->element() ||
- (!curr->element()->hasTagName(aTag) && !curr->element()->hasTagName(fontTag))));
+ if (curr && curr->isRenderBlock() && toRenderBlock(curr)->inlineContinuation())
+ curr = toRenderBlock(curr)->inlineContinuation();
+ } while (curr && decorations && (!quirksMode || !curr->node() ||
+ (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
// If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
if (decorations && curr) {
@@ -2697,10 +2104,6 @@ void RenderObject::getTextDecorationColors(int decorations, Color& underline, Co
}
}
-void RenderObject::updateWidgetPosition()
-{
-}
-
#if ENABLE(DASHBOARD_SUPPORT)
void RenderObject::addDashboardRegions(Vector<DashboardRegionValue>& regions)
{
@@ -2762,23 +2165,6 @@ void RenderObject::collectDashboardRegions(Vector<DashboardRegionValue>& regions
}
#endif
-bool RenderObject::avoidsFloats() const
-{
- return isReplaced() || hasOverflowClip() || isHR();
-}
-
-bool RenderObject::shrinkToAvoidFloats() const
-{
- // FIXME: Technically we should be able to shrink replaced elements on a line, but this is difficult to accomplish, since this
- // involves doing a relayout during findNextLineBreak and somehow overriding the containingBlockWidth method to return the
- // current remaining width on a line.
- if (isInline() && !isHTMLMarquee() || !avoidsFloats())
- return false;
-
- // All auto-width objects that avoid floats should always use lineWidth.
- return style()->width().isAuto();
-}
-
bool RenderObject::willRenderImage(CachedImage*)
{
// Without visibility we won't render (and therefore don't care about animation).
@@ -2794,7 +2180,7 @@ int RenderObject::maximalOutlineSize(PaintPhase p) const
{
if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
return 0;
- return static_cast<RenderView*>(document()->renderer())->maximalOutlineSize();
+ return toRenderView(document()->renderer())->maximalOutlineSize();
}
int RenderObject::caretMinOffset() const
@@ -2805,7 +2191,7 @@ int RenderObject::caretMinOffset() const
int RenderObject::caretMaxOffset() const
{
if (isReplaced())
- return element() ? max(1U, element()->childNodeCount()) : 1;
+ return node() ? max(1U, node()->childNodeCount()) : 1;
if (isHR())
return 1;
return 0;
@@ -2821,6 +2207,11 @@ int RenderObject::previousOffset(int current) const
return current - 1;
}
+int RenderObject::previousOffsetForBackwardDeletion(int current) const
+{
+ return current - 1;
+}
+
int RenderObject::nextOffset(int current) const
{
return current + 1;
@@ -2828,7 +2219,7 @@ int RenderObject::nextOffset(int current) const
void RenderObject::adjustRectForOutlineAndShadow(IntRect& rect) const
{
- int outlineSize = !isInline() && virtualContinuation() ? virtualContinuation()->style()->outlineSize() : style()->outlineSize();
+ int outlineSize = outlineStyleForRepaint()->outlineSize();
if (ShadowData* boxShadow = style()->boxShadow()) {
int shadowLeft = 0;
int shadowRight = 0;
@@ -2861,6 +2252,107 @@ void RenderObject::imageChanged(CachedImage* image, const IntRect* rect)
imageChanged(static_cast<WrappedImagePtr>(image), rect);
}
+RenderBoxModelObject* RenderObject::offsetParent() const
+{
+ // If any of the following holds true return null and stop this algorithm:
+ // A is the root element.
+ // A is the HTML body element.
+ // The computed value of the position property for element A is fixed.
+ if (isRoot() || isBody() || (isPositioned() && style()->position() == FixedPosition))
+ return 0;
+
+ // If A is an area HTML element which has a map HTML element somewhere in the ancestor
+ // chain return the nearest ancestor map HTML element and stop this algorithm.
+ // FIXME: Implement!
+
+ // Return the nearest ancestor element of A for which at least one of the following is
+ // true and stop this algorithm if such an ancestor is found:
+ // * The computed value of the position property is not static.
+ // * It is the HTML body element.
+ // * The computed value of the position property of A is static and the ancestor
+ // is one of the following HTML elements: td, th, or table.
+ // * Our own extension: if there is a difference in the effective zoom
+ bool skipTables = isPositioned() || isRelPositioned();
+ float currZoom = style()->effectiveZoom();
+ RenderObject* curr = parent();
+ while (curr && (!curr->node() ||
+ (!curr->isPositioned() && !curr->isRelPositioned() && !curr->isBody()))) {
+ Node* element = curr->node();
+ if (!skipTables && element) {
+ bool isTableElement = element->hasTagName(tableTag) ||
+ element->hasTagName(tdTag) ||
+ element->hasTagName(thTag);
+
+#if ENABLE(WML)
+ if (!isTableElement && element->isWMLElement())
+ isTableElement = element->hasTagName(WMLNames::tableTag) ||
+ element->hasTagName(WMLNames::tdTag);
+#endif
+
+ if (isTableElement)
+ break;
+ }
+
+ float newZoom = curr->style()->effectiveZoom();
+ if (currZoom != newZoom)
+ break;
+ currZoom = newZoom;
+ curr = curr->parent();
+ }
+ return curr && curr->isBoxModelObject() ? toRenderBoxModelObject(curr) : 0;
+}
+
+VisiblePosition RenderObject::createVisiblePosition(int offset, EAffinity affinity)
+{
+ // If is is a non-anonymous renderer, then it's simple.
+ if (Node* node = this->node())
+ return VisiblePosition(node, offset, affinity);
+
+ // We don't want to cross the boundary between editable and non-editable
+ // regions of the document, but that is either impossible or at least
+ // extremely unlikely in any normal case because we stop as soon as we
+ // find a single non-anonymous renderer.
+
+ // Find a nearby non-anonymous renderer.
+ RenderObject* child = this;
+ while (RenderObject* parent = child->parent()) {
+ // Find non-anonymous content after.
+ RenderObject* renderer = child;
+ while ((renderer = renderer->nextInPreOrder(parent))) {
+ if (Node* node = renderer->node())
+ return VisiblePosition(node, 0, DOWNSTREAM);
+ }
+
+ // Find non-anonymous content before.
+ renderer = child;
+ while ((renderer = renderer->previousInPreOrder())) {
+ if (renderer == parent)
+ break;
+ if (Node* node = renderer->node())
+ return VisiblePosition(node, numeric_limits<int>::max(), DOWNSTREAM);
+ }
+
+ // Use the parent itself unless it too is anonymous.
+ if (Node* node = parent->node())
+ return VisiblePosition(node, 0, DOWNSTREAM);
+
+ // Repeat at the next level up.
+ child = parent;
+ }
+
+ // Everything was anonymous. Give up.
+ return VisiblePosition();
+}
+
+VisiblePosition RenderObject::createVisiblePosition(const Position& position)
+{
+ if (position.isNotNull())
+ return VisiblePosition(position);
+
+ ASSERT(!node());
+ return createVisiblePosition(0, DOWNSTREAM);
+}
+
#if ENABLE(SVG)
FloatRect RenderObject::relativeBBox(bool) const
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 889ce9b..a601962 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -28,7 +28,11 @@
#include "CachedResourceClient.h"
#include "FloatQuad.h"
#include "Document.h"
+#include "RenderObjectChildList.h"
#include "RenderStyle.h"
+#include "TextAffinity.h"
+#include "TransformationMatrix.h"
+#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -36,9 +40,13 @@ class AnimationController;
class HitTestResult;
class InlineBox;
class InlineFlowBox;
+class Position;
+class RenderBoxModelObject;
+class RenderInline;
class RenderBlock;
class RenderFlow;
class RenderLayer;
+class TransformState;
class VisiblePosition;
/*
@@ -85,10 +93,16 @@ enum HitTestAction {
HitTestForeground
};
-// Values for verticalPosition.
-const int PositionTop = -0x7fffffff;
-const int PositionBottom = 0x7fffffff;
-const int PositionUndefined = 0x80000000;
+// Sides used when drawing borders and outlines. This is in RenderObject rather than RenderBoxModelObject since outlines can
+// be drawn by SVG around bounding boxes.
+enum BoxSide {
+ BSTop,
+ BSBottom,
+ BSLeft,
+ BSRight
+};
+
+const int caretWidth = 1;
#if ENABLE(DASHBOARD_SUPPORT)
struct DashboardRegionValue {
@@ -110,8 +124,10 @@ struct DashboardRegionValue {
// Base class for all rendering tree objects.
class RenderObject : public CachedResourceClient {
- friend class RenderContainer;
+ friend class RenderBlock;
+ friend class RenderBox;
friend class RenderLayer;
+ friend class RenderObjectChildList;
friend class RenderSVGContainer;
public:
// Anonymous objects should pass the document as their node, and they will then automatically be
@@ -119,7 +135,7 @@ public:
RenderObject(Node*);
virtual ~RenderObject();
- virtual const char* renderName() const { return "RenderObject"; }
+ virtual const char* renderName() const = 0;
RenderObject* parent() const { return m_parent; }
bool isDescendantOf(const RenderObject*) const;
@@ -127,8 +143,20 @@ public:
RenderObject* previousSibling() const { return m_previous; }
RenderObject* nextSibling() const { return m_next; }
- virtual RenderObject* firstChild() const { return 0; }
- virtual RenderObject* lastChild() const { return 0; }
+ RenderObject* firstChild() const
+ {
+ if (const RenderObjectChildList* children = virtualChildren())
+ return children->firstChild();
+ return 0;
+ }
+ RenderObject* lastChild() const
+ {
+ if (const RenderObjectChildList* children = virtualChildren())
+ return children->lastChild();
+ return 0;
+ }
+ virtual RenderObjectChildList* virtualChildren() { return 0; }
+ virtual const RenderObjectChildList* virtualChildren() const { return 0; }
RenderObject* nextInPreOrder() const;
RenderObject* nextInPreOrder(RenderObject* stayWithin) const;
@@ -140,10 +168,11 @@ public:
RenderObject* firstLeafChild() const;
RenderObject* lastLeafChild() const;
- // The following five functions are used when the render tree hierarchy changes to make sure layers get
+ // The following six functions are used when the render tree hierarchy changes to make sure layers get
// properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
// can contain a mixture of boxes and other object types, these functions need to be in the base class.
RenderLayer* enclosingLayer() const;
+ RenderLayer* enclosingSelfPaintingLayer() const;
void addLayers(RenderLayer* parentLayer, RenderObject* newObject);
void removeLayers(RenderLayer* parentLayer);
void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
@@ -152,18 +181,8 @@ public:
// Convenience function for getting to the nearest enclosing box of a RenderObject.
RenderBox* enclosingBox() const;
- virtual IntRect getOverflowClipRect(int /*tx*/, int /*ty*/) { return IntRect(0, 0, 0, 0); }
- virtual IntRect getClipRect(int /*tx*/, int /*ty*/) { return IntRect(0, 0, 0, 0); }
- bool hasClip() { return isPositioned() && style()->hasClip(); }
-
- virtual int getBaselineOfFirstLineBox() const { return -1; }
- virtual int getBaselineOfLastLineBox() const { return -1; }
-
virtual bool isEmpty() const { return firstChild() == 0; }
- virtual bool isEdited() const { return false; }
- virtual void setEdited(bool) { }
-
#ifndef NDEBUG
void setHasAXObject(bool flag) { m_hasAXObject = flag; }
bool hasAXObject() const { return m_hasAXObject; }
@@ -179,35 +198,15 @@ public:
// again. We have to make sure the render tree updates as needed to accommodate the new
// normal flow object.
void handleDynamicFloatPositionChange();
-
- // This function is a convenience helper for creating an anonymous block that inherits its
- // style from this RenderObject.
- RenderBlock* createAnonymousBlock();
-
- // Whether or not a positioned element requires normal flow x/y to be computed
- // to determine its position.
- bool hasStaticX() const;
- bool hasStaticY() const;
- virtual void setStaticX(int /*staticX*/) { }
- virtual void setStaticY(int /*staticY*/) { }
- virtual int staticX() const { return 0; }
- virtual int staticY() const { return 0; }
-
+
// RenderObject tree manipulation
//////////////////////////////////////////
- virtual bool canHaveChildren() const;
+ virtual bool canHaveChildren() const { return virtualChildren(); }
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const { return true; }
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
+ virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
virtual void removeChild(RenderObject*);
virtual bool createsAnonymousWrapper() const { return false; }
-
- // raw tree manipulation
- virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
- virtual void appendChildNode(RenderObject*, bool fullAppend = true);
- virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
- // Designed for speed. Don't waste time doing a bunch of work like layer updating and repainting when we know that our
- // change in parentage is not going to affect anything.
- virtual void moveChildNode(RenderObject*);
//////////////////////////////////////////
protected:
@@ -219,6 +218,7 @@ protected:
//////////////////////////////////////////
private:
void addAbsoluteRectForLayer(IntRect& result);
+ void setLayerNeedsFullRepaint();
public:
#ifndef NDEBUG
@@ -244,19 +244,20 @@ public:
virtual bool isApplet() const { return false; }
virtual bool isBR() const { return false; }
virtual bool isBlockFlow() const { return false; }
+ virtual bool isBoxModelObject() const { return false; }
virtual bool isCounter() const { return false; }
virtual bool isFieldset() const { return false; }
virtual bool isFrame() const { return false; }
virtual bool isFrameSet() const { return false; }
virtual bool isImage() const { return false; }
virtual bool isInlineBlockOrInlineTable() const { return false; }
- virtual bool isInlineContinuation() const;
virtual bool isListBox() const { return false; }
virtual bool isListItem() const { return false; }
virtual bool isListMarker() const { return false; }
virtual bool isMedia() const { return false; }
virtual bool isMenuList() const { return false; }
virtual bool isRenderBlock() const { return false; }
+ virtual bool isRenderButton() const { return false; }
virtual bool isRenderImage() const { return false; }
virtual bool isRenderInline() const { return false; }
virtual bool isRenderPart() const { return false; }
@@ -267,20 +268,23 @@ public:
virtual bool isTableCol() const { return false; }
virtual bool isTableRow() const { return false; }
virtual bool isTableSection() const { return false; }
+ virtual bool isTextControl() const { return false; }
virtual bool isTextArea() const { return false; }
virtual bool isTextField() const { return false; }
virtual bool isWidget() const { return false; }
- bool isRoot() const { return document()->documentElement() == node(); }
+ bool isRoot() const { return document()->documentElement() == m_node; }
bool isBody() const;
bool isHR() const;
bool isHTMLMarquee() const;
- virtual bool childrenInline() const { return false; }
- virtual void setChildrenInline(bool) { }
-
- virtual RenderFlow* virtualContinuation() const { return 0; }
+ bool childrenInline() const { return m_childrenInline; }
+ void setChildrenInline(bool b = true) { m_childrenInline = b; }
+ bool hasColumns() const { return m_hasColumns; }
+ void setHasColumns(bool b = true) { m_hasColumns = b; }
+ bool cellWidthChanged() const { return m_cellWidthChanged; }
+ void setCellWidthChanged(bool b = true) { m_cellWidthChanged = b; }
#if ENABLE(SVG)
virtual bool isSVGRoot() const { return false; }
@@ -295,15 +299,13 @@ public:
virtual TransformationMatrix absoluteTransform() const;
#endif
- virtual bool isEditable() const;
-
bool isAnonymous() const { return m_isAnonymous; }
void setIsAnonymous(bool b) { m_isAnonymous = b; }
bool isAnonymousBlock() const
{
- return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == RenderStyle::NOPSEUDO && !isListMarker();
+ return m_isAnonymous && style()->display() == BLOCK && style()->styleType() == NOPSEUDO && !isListMarker();
}
-
+ bool isInlineContinuation() const { return (node() ? node()->renderer() != this : false) && isRenderInline(); }
bool isFloating() const { return m_floating; }
bool isPositioned() const { return m_positioned; } // absolute or fixed positioning
bool isRelPositioned() const { return m_relPositioned; } // relative positioning
@@ -318,7 +320,7 @@ public:
bool hasBoxDecorations() const { return m_paintBackground; }
bool mustRepaintBackgroundOrBorder() const;
-
+
bool needsLayout() const { return m_needsLayout || m_normalChildNeedsLayout || m_posChildNeedsLayout || m_needsPositionedMovementLayout; }
bool selfNeedsLayout() const { return m_needsLayout; }
bool needsPositionedMovementLayout() const { return m_needsPositionedMovementLayout; }
@@ -330,28 +332,33 @@ public:
bool isSelectionBorder() const;
+ bool hasClip() const { return isPositioned() && style()->hasClip(); }
bool hasOverflowClip() const { return m_hasOverflowClip; }
- virtual bool hasControlClip() const { return false; }
- virtual IntRect controlClipRect(int /*tx*/, int /*ty*/) const { return IntRect(); }
bool hasTransform() const { return m_hasTransform; }
bool hasMask() const { return style() && style()->hasMask(); }
+ void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
+ Color, const Color& textcolor, EBorderStyle, int adjbw1, int adjbw2);
+ void drawArcForBoxSide(GraphicsContext*, int x, int y, float thickness, IntSize radius, int angleStart,
+ int angleSpan, BoxSide, Color, const Color& textcolor, EBorderStyle, bool firstCorner);
+
public:
// The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
// any pseudo classes (and therefore has no concept of changing state).
- RenderStyle* getCachedPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const;
- PassRefPtr<RenderStyle> getUncachedPseudoStyle(RenderStyle::PseudoId, RenderStyle* parentStyle = 0) const;
+ RenderStyle* getCachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const;
+ PassRefPtr<RenderStyle> getUncachedPseudoStyle(PseudoId, RenderStyle* parentStyle = 0) const;
- void updateDragState(bool dragOn);
+ virtual void updateDragState(bool dragOn);
RenderView* view() const;
- // don't even think about making this method virtual!
- Node* element() const { return m_isAnonymous ? 0 : m_node; }
+ // Returns true if this renderer is rooted, and optionally returns the hosting view (the root of the hierarchy).
+ bool isRooted(RenderView** = 0);
+
+ Node* node() const { return m_isAnonymous ? 0 : m_node; }
Document* document() const { return m_node->document(); }
void setNode(Node* node) { m_node = node; }
- Node* node() const { return m_node; }
bool hasOutlineAnnotation() const;
bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); }
@@ -361,7 +368,10 @@ public:
* positioned elements
*/
RenderObject* container() const;
- RenderObject* hoverAncestor() const;
+ virtual RenderObject* hoverAncestor() const { return parent(); }
+
+ // IE Extension that can be called on any RenderObject. See the implementation for the details.
+ RenderBoxModelObject* offsetParent() const;
void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0);
void setNeedsLayout(bool b, bool markParents = true);
@@ -369,7 +379,6 @@ public:
void setNeedsPositionedMovementLayout();
void setPrefWidthsDirty(bool, bool markParents = true);
void invalidateContainerPrefWidths();
- virtual void invalidateCounters() { }
void setNeedsLayoutAndPrefWidthsRecalc()
{
@@ -395,21 +404,9 @@ public:
void updateFillImages(const FillLayer*, const FillLayer*);
void updateImage(StyleImage*, StyleImage*);
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun = false);
- virtual void dirtyLineBoxes(bool fullLayout, bool isRootLineBox = false);
-
- // For inline replaced elements, this function returns the inline box that owns us. Enables
- // the replaced RenderObject to quickly determine what line it is contained on and to easily
- // iterate over structures on the line.
- virtual InlineBox* inlineBoxWrapper() const;
- virtual void setInlineBoxWrapper(InlineBox*);
- virtual void deleteLineBoxWrapper();
-
// for discussion of lineHeight see CSS2 spec
virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
// for the vertical-align property of inline elements
- // the difference between this objects baseline position and the lines baseline position.
- virtual int verticalPositionHint(bool firstLine) const;
// the offset of baseline from the top of the object.
virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
@@ -419,7 +416,7 @@ public:
*/
struct PaintInfo {
PaintInfo(GraphicsContext* newContext, const IntRect& newRect, PaintPhase newPhase, bool newForceBlackText,
- RenderObject* newPaintingRoot, ListHashSet<RenderFlow*>* newOutlineObjects)
+ RenderObject* newPaintingRoot, ListHashSet<RenderInline*>* newOutlineObjects)
: context(newContext)
, rect(newRect)
, phase(newPhase)
@@ -434,38 +431,13 @@ public:
PaintPhase phase;
bool forceBlackText;
RenderObject* paintingRoot; // used to draw just one element and its visual kids
- ListHashSet<RenderFlow*>* outlineObjects; // used to list outlines that should be painted by a block with inline children
+ ListHashSet<RenderInline*>* outlineObjects; // used to list outlines that should be painted by a block with inline children
};
virtual void paint(PaintInfo&, int tx, int ty);
- void paintBorder(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true);
- bool paintNinePieceImage(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, const NinePieceImage&, CompositeOperator = CompositeSourceOver);
- void paintBoxShadow(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*, bool begin = true, bool end = true);
-
- // RenderBox implements this.
- virtual void paintBoxDecorations(PaintInfo&, int /*tx*/, int /*ty*/) { }
- virtual void paintMask(PaintInfo&, int /*tx*/, int /*ty*/) { }
- virtual void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*,
- int /*clipY*/, int /*clipH*/, int /*tx*/, int /*ty*/, int /*width*/, int /*height*/,
- InlineFlowBox* = 0, CompositeOperator = CompositeSourceOver) { }
- /*
- * Calculates the actual width of the object (only for non inline
- * objects)
- */
- virtual void calcWidth() { }
-
- /*
- * This function should cause the Element to calculate its
- * width and height and the layout of its content
- *
- * when the Element calls setNeedsLayout(false), layout() is no
- * longer called during relayouts, as long as there is no
- * style sheet change. When that occurs, m_needsLayout will be
- * set to true and the Element receives layout() calls
- * again.
- */
- virtual void layout() = 0;
+ // Recursive function that computes the size and position of this object and all its descendants.
+ virtual void layout();
/* This function performs a layout only if one is needed. */
void layoutIfNeeded() { if (needsLayout()) layout(); }
@@ -478,19 +450,19 @@ public:
// repaint and do not need a relayout
virtual void updateFromElement() { }
- virtual void updateWidgetPosition();
-
#if ENABLE(DASHBOARD_SUPPORT)
- void addDashboardRegions(Vector<DashboardRegionValue>&);
+ virtual void addDashboardRegions(Vector<DashboardRegionValue>&);
void collectDashboardRegions(Vector<DashboardRegionValue>&);
#endif
bool hitTest(const HitTestRequest&, HitTestResult&, const IntPoint&, int tx, int ty, HitTestFilter = HitTestAll);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
- void updateHitTestResult(HitTestResult&, const IntPoint&);
+ virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
- virtual VisiblePosition positionForCoordinates(int x, int y);
- VisiblePosition positionForPoint(const IntPoint&);
+ VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
+ VisiblePosition createVisiblePosition(int offset, EAffinity);
+ VisiblePosition createVisiblePosition(const Position&);
virtual void dirtyLinesFromChangedChild(RenderObject*);
@@ -509,21 +481,10 @@ public:
// returns the containing block level element for this element.
RenderBlock* containingBlock() const;
- // return just the width of the containing block
- virtual int containingBlockWidth() const;
- // return just the height of the containing block
- virtual int containingBlockHeight() const;
-
- // used by flexible boxes to impose a flexed width/height override
- virtual int overrideSize() const { return 0; }
- virtual int overrideWidth() const { return 0; }
- virtual int overrideHeight() const { return 0; }
- virtual void setOverrideSize(int /*overrideSize*/) { }
-
// Convert the given local point to absolute coordinates
// FIXME: Temporary. If useTransforms is true, take transforms into account. Eventually localToAbsolute() will always be transform-aware.
- virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
- virtual FloatPoint absoluteToLocal(FloatPoint, bool fixed = false, bool useTransforms = false) const;
+ FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
+ FloatPoint absoluteToLocal(FloatPoint, bool fixed = false, bool useTransforms = false) const;
// Convert a local quad to absolute coordinates, taking transforms into account.
FloatQuad localToAbsoluteQuad(const FloatQuad& quad, bool fixed = false) const
@@ -531,19 +492,19 @@ public:
return localToContainerQuad(quad, 0, fixed);
}
// Convert a local quad into the coordinate system of container, taking transforms into account.
- virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const;
+ FloatQuad localToContainerQuad(const FloatQuad&, RenderBoxModelObject* repaintContainer, bool fixed = false) const;
// Return the offset from the container() renderer (excluding transforms)
virtual IntSize offsetFromContainer(RenderObject*) const;
- virtual void addLineBoxRects(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
+ virtual void absoluteRectsForRange(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
virtual void absoluteRects(Vector<IntRect>&, int, int, bool = true) { }
// FIXME: useTransforms should go away eventually
IntRect absoluteBoundingBoxRect(bool useTransforms = false);
// Build an array of quads in absolute coords for line boxes
- virtual void collectAbsoluteLineBoxQuads(Vector<FloatQuad>&, unsigned /*startOffset*/ = 0, unsigned /*endOffset*/ = UINT_MAX, bool /*useSelectionHeight*/ = false) { }
+ virtual void absoluteQuadsForRange(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
virtual void absoluteQuads(Vector<FloatQuad>&, bool /*topLevel*/ = true) { }
// the rect that will be painted if this object is passed as the paintingRoot
@@ -553,28 +514,23 @@ public:
virtual int maxPrefWidth() const { return 0; }
RenderStyle* style() const { return m_style.get(); }
- RenderStyle* firstLineStyle() const;
+ RenderStyle* firstLineStyle() const { return document()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); }
RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
-
+
+ // Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead.
+ // This is typically only relevant when repainting.
+ virtual RenderStyle* outlineStyleForRepaint() const { return style(); }
+
void getTextDecorationColors(int decorations, Color& underline, Color& overline,
Color& linethrough, bool quirksMode = false);
- enum BorderSide {
- BSTop,
- BSBottom,
- BSLeft,
- BSRight
- };
-
- void drawBorderArc(GraphicsContext*, int x, int y, float thickness, IntSize radius, int angleStart,
- int angleSpan, BorderSide, Color, const Color& textcolor, EBorderStyle, bool firstCorner);
- void drawBorder(GraphicsContext*, int x1, int y1, int x2, int y2, BorderSide,
- Color, const Color& textcolor, EBorderStyle, int adjbw1, int adjbw2);
-
// Return the RenderBox in the container chain which is responsible for painting this object, or 0
// if painting is root-relative. This is the container that should be passed to the 'forRepaint'
// methods.
- RenderBox* containerForRepaint() const;
+ RenderBoxModelObject* containerForRepaint() const;
+ // Actually do the repaint of rect r for this object which has been computed in the coordinate space
+ // of repaintContainer. If repaintContainer is 0, repaint via the view.
+ void repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect& r, bool immediate = false);
// Repaint the entire object. Called when, e.g., the color of a border changes, or when a border
// style changes.
@@ -584,7 +540,7 @@ public:
void repaintRectangle(const IntRect&, bool immediate = false);
// Repaint only if our old bounds and new bounds are different.
- bool repaintAfterLayoutIfNeeded(const IntRect& oldBounds, const IntRect& oldOutlineBox);
+ bool repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox);
// Repaint only if the object moved.
virtual void repaintDuringLayoutIfMoved(const IntRect& rect);
@@ -600,32 +556,22 @@ public:
{
return clippedOverflowRectForRepaint(0);
}
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
-
- IntRect rectWithOutlineForRepaint(RenderBox* repaintContainer, int outlineWidth);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual IntRect rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth);
// Given a rect in the object's coordinate space, compute a rect suitable for repainting
// that rect in view coordinates.
void computeAbsoluteRepaintRect(IntRect& r, bool fixed = false)
{
- return computeRectForRepaint(r, 0, fixed);
+ return computeRectForRepaint(0, r, fixed);
}
// Given a rect in the object's coordinate space, compute a rect suitable for repainting
// that rect in the coordinate space of repaintContainer.
- virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
virtual unsigned int length() const { return 1; }
bool isFloatingOrPositioned() const { return (isFloating() || isPositioned()); }
- virtual bool containsFloats() { return false; }
- virtual bool containsFloat(RenderObject*) { return false; }
- virtual bool hasOverhangingFloats() { return false; }
-
- virtual bool avoidsFloats() const;
- bool shrinkToAvoidFloats() const;
-
- // positioning of inline children (bidi)
- virtual void position(InlineBox*) { }
bool isTransparent() const { return style()->opacity() < 1.0f; }
float opacity() const { return style()->opacity(); }
@@ -635,6 +581,9 @@ public:
// Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
int maximalOutlineSize(PaintPhase) const;
+ void setHasMarkupTruncation(bool b = true) { m_hasMarkupTruncation = b; }
+ bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
+
enum SelectionState {
SelectionNone, // The object is not selected.
SelectionStart, // The object either contains the start of a selection run or is the start of a run
@@ -645,20 +594,21 @@ public:
// The current selection state for an object. For blocks, the state refers to the state of the leaf
// descendants (as described above in the SelectionState enum declaration).
- virtual SelectionState selectionState() const { return SelectionNone; }
+ SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState);; }
// Sets the selection state for an object.
- virtual void setSelectionState(SelectionState state) { if (parent()) parent()->setSelectionState(state); }
+ virtual void setSelectionState(SelectionState state) { m_selectionState = state; }
// A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest
// possible bounding box for the selection.
- virtual IntRect selectionRect(bool) { return IntRect(); }
+ IntRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); }
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return IntRect(); }
// Whether or not an object can be part of the leaf elements of the selection.
virtual bool canBeSelectionLeaf() const { return false; }
// Whether or not a block has selected children.
- virtual bool hasSelectedChildren() const { return false; }
+ bool hasSelectedChildren() const { return m_selectionState != SelectionNone; }
// Obtains the selection colors that should be used when painting a selection.
Color selectionBackgroundColor() const;
@@ -667,30 +617,6 @@ public:
// Whether or not a given block needs to paint selection gaps.
virtual bool shouldPaintSelectionGaps() const { return false; }
- // This struct is used when the selection changes to cache the old and new state of the selection for each RenderObject.
- struct SelectionInfo {
- SelectionInfo()
- : m_object(0)
- , m_state(SelectionNone)
- {
- }
-
- SelectionInfo(RenderObject* o, bool clipToVisibleContent)
- : m_object(o)
- , m_rect(o->needsLayout() ? IntRect() : o->selectionRect(clipToVisibleContent))
- , m_state(o->selectionState())
- {
- }
-
- RenderObject* object() const { return m_object; }
- IntRect rect() const { return m_rect; }
- SelectionState state() const { return m_state; }
-
- RenderObject* m_object;
- IntRect m_rect;
- SelectionState m_state;
- };
-
Node* draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const;
/**
@@ -701,12 +627,11 @@ public:
*/
virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
- virtual int lowestPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; }
- virtual int rightmostPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; }
- virtual int leftmostPosition(bool /*includeOverflowInterior*/ = true, bool /*includeSelf*/ = true) const { return 0; }
-
virtual void calcVerticalMargins() { }
- void removeFromObjectLists();
+ bool isTopMarginQuirk() const { return m_topMarginQuirk; }
+ bool isBottomMarginQuirk() const { return m_bottomMarginQuirk; }
+ void setTopMarginQuirk(bool b = true) { m_topMarginQuirk = b; }
+ void setBottomMarginQuirk(bool b = true) { m_bottomMarginQuirk = b; }
// When performing a global document tear-down, the renderer of the document is cleared. We use this
// as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
@@ -724,13 +649,14 @@ public:
virtual unsigned caretMaxRenderedOffset() const;
virtual int previousOffset(int current) const;
+ virtual int previousOffsetForBackwardDeletion(int current) const;
virtual int nextOffset(int current) const;
virtual void imageChanged(CachedImage*, const IntRect* = 0);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { }
virtual bool willRenderImage(CachedImage*);
- virtual void selectionStartEnd(int& spos, int& epos) const;
+ void selectionStartEnd(int& spos, int& epos) const;
RenderObject* paintingRootForChildren(PaintInfo& paintInfo) const
{
@@ -742,24 +668,22 @@ public:
{
return !paintInfo.paintingRoot || paintInfo.paintingRoot == this;
}
-#ifdef ANDROID_LAYOUT
- virtual bool hasChildTable() const { return false; }
-#endif
bool hasOverrideSize() const { return m_hasOverrideSize; }
void setHasOverrideSize(bool b) { m_hasOverrideSize = b; }
void remove() { if (parent()) parent()->removeChild(this); }
- void invalidateVerticalPosition() { m_verticalPosition = PositionUndefined; }
-
- virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
-
- virtual void capsLockStateMayHaveChanged() { }
-
AnimationController* animation() const;
bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE; }
+
+ // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use
+ // localToAbsolute/absoluteToLocal methods instead.
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
+
+ TransformationMatrix transformFromContainer(const RenderObject* container, const IntSize& offsetInContainer) const;
virtual void addFocusRingRects(GraphicsContext*, int /*tx*/, int /*ty*/) { };
@@ -768,28 +692,60 @@ public:
return outlineBoundsForRepaint(0);
}
+ bool replacedHasOverflow() const { return m_replacedHasOverflow; }
+ void setReplacedHasOverflow(bool b = true) { m_replacedHasOverflow = b; }
+
protected:
// Overrides should call the superclass at the end
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
// Overrides should call the superclass at the start
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
-
- virtual void printBoxDecorations(GraphicsContext*, int /*x*/, int /*y*/, int /*w*/, int /*h*/, int /*tx*/, int /*ty*/) { }
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void paintOutline(GraphicsContext*, int tx, int ty, int w, int h, const RenderStyle*);
void addPDFURLRect(GraphicsContext*, const IntRect&);
virtual IntRect viewRect() const;
- int getVerticalPosition(bool firstLine) const;
-
void adjustRectForOutlineAndShadow(IntRect&) const;
void arenaDelete(RenderArena*, void* objectBase);
- virtual IntRect outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const { return IntRect(); }
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const { return IntRect(); }
+ class LayoutRepainter {
+ public:
+ LayoutRepainter(RenderObject& object, bool checkForRepaint, const IntRect* oldBounds = 0)
+ : m_object(object)
+ , m_repaintContainer(0)
+ , m_checkForRepaint(checkForRepaint)
+ {
+ if (m_checkForRepaint) {
+ m_repaintContainer = m_object.containerForRepaint();
+ m_oldBounds = oldBounds ? *oldBounds : m_object.clippedOverflowRectForRepaint(m_repaintContainer);
+ m_oldOutlineBox = m_object.outlineBoundsForRepaint(m_repaintContainer);
+ }
+ }
+
+ // Return true if it repainted.
+ bool repaintAfterLayout()
+ {
+ return m_checkForRepaint ? m_object.repaintAfterLayoutIfNeeded(m_repaintContainer, m_oldBounds, m_oldOutlineBox) : false;
+ }
+
+ bool checkForRepaint() const { return m_checkForRepaint; }
+
+ private:
+ RenderObject& m_object;
+ RenderBoxModelObject* m_repaintContainer;
+ IntRect m_oldBounds;
+ IntRect m_oldOutlineBox;
+ bool m_checkForRepaint;
+ };
+
private:
+ RenderStyle* firstLineStyleSlowCase() const;
+ StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const;
+
RefPtr<RenderStyle> m_style;
Node* m_node;
@@ -802,8 +758,8 @@ private:
bool m_hasAXObject;
bool m_setNeedsLayoutForbidden : 1;
#endif
- mutable int m_verticalPosition;
+ // 32 bits have been used here. THERE ARE NO FREE BITS AVAILABLE.
bool m_needsLayout : 1;
bool m_needsPositionedMovementLayout :1;
bool m_normalChildNeedsLayout : 1;
@@ -835,10 +791,145 @@ public:
bool m_everHadLayout : 1;
private:
+ // These bitfields are moved here from subclasses to pack them together
+ // from RenderBlock
+ bool m_childrenInline : 1;
+ bool m_topMarginQuirk : 1;
+ bool m_bottomMarginQuirk : 1;
+ bool m_hasMarkupTruncation : 1;
+ unsigned m_selectionState : 3; // SelectionState
+ bool m_hasColumns : 1;
+
+ // from RenderTableCell
+ bool m_cellWidthChanged : 1;
+
+ // from RenderReplaced
+ bool m_replacedHasOverflow : 1;
+
+private:
// Store state between styleWillChange and styleDidChange
static bool s_affectsParentBlock;
};
+inline bool RenderObject::documentBeingDestroyed() const
+{
+ return !document()->renderer();
+}
+
+inline void RenderObject::setNeedsLayout(bool b, bool markParents)
+{
+ bool alreadyNeededLayout = m_needsLayout;
+ m_needsLayout = b;
+ if (b) {
+ ASSERT(!isSetNeedsLayoutForbidden());
+ if (!alreadyNeededLayout) {
+ if (markParents)
+ markContainingBlocksForLayout();
+ if (hasLayer())
+ setLayerNeedsFullRepaint();
+ }
+ } else {
+ m_everHadLayout = true;
+ m_posChildNeedsLayout = false;
+ m_normalChildNeedsLayout = false;
+ m_needsPositionedMovementLayout = false;
+ }
+}
+
+inline void RenderObject::setChildNeedsLayout(bool b, bool markParents)
+{
+ bool alreadyNeededLayout = m_normalChildNeedsLayout;
+ m_normalChildNeedsLayout = b;
+ if (b) {
+ ASSERT(!isSetNeedsLayoutForbidden());
+ if (!alreadyNeededLayout && markParents)
+ markContainingBlocksForLayout();
+ } else {
+ m_posChildNeedsLayout = false;
+ m_normalChildNeedsLayout = false;
+ m_needsPositionedMovementLayout = false;
+ }
+}
+
+inline void RenderObject::setNeedsPositionedMovementLayout()
+{
+ bool alreadyNeededLayout = needsLayout();
+ m_needsPositionedMovementLayout = true;
+ if (!alreadyNeededLayout) {
+ markContainingBlocksForLayout();
+ if (hasLayer())
+ setLayerNeedsFullRepaint();
+ }
+}
+
+inline bool objectIsRelayoutBoundary(const RenderObject *obj)
+{
+ // FIXME: In future it may be possible to broaden this condition in order to improve performance.
+ // Table cells are excluded because even when their CSS height is fixed, their height()
+ // may depend on their contents.
+ return obj->isTextControl()
+ || (obj->hasOverflowClip() && !obj->style()->width().isIntrinsicOrAuto() && !obj->style()->height().isIntrinsicOrAuto() && !obj->style()->height().isPercent() && !obj->isTableCell())
+#if ENABLE(SVG)
+ || obj->isSVGRoot()
+#endif
+ ;
+}
+
+inline void RenderObject::markContainingBlocksForLayout(bool scheduleRelayout, RenderObject* newRoot)
+{
+ ASSERT(!scheduleRelayout || !newRoot);
+
+ RenderObject* o = container();
+ RenderObject* last = this;
+
+ while (o) {
+ // Don't mark the outermost object of an unrooted subtree. That object will be
+ // marked when the subtree is added to the document.
+ RenderObject* container = o->container();
+ if (!container && !o->isRenderView())
+ return;
+ if (!last->isText() && (last->style()->position() == FixedPosition || last->style()->position() == AbsolutePosition)) {
+ if ((last->style()->top().isAuto() && last->style()->bottom().isAuto()) || last->style()->top().isStatic()) {
+ RenderObject* parent = last->parent();
+ if (!parent->normalChildNeedsLayout()) {
+ parent->setChildNeedsLayout(true, false);
+ if (parent != newRoot)
+ parent->markContainingBlocksForLayout(scheduleRelayout, newRoot);
+ }
+ }
+ if (o->m_posChildNeedsLayout)
+ return;
+ o->m_posChildNeedsLayout = true;
+ ASSERT(!o->isSetNeedsLayoutForbidden());
+ } else {
+ if (o->m_normalChildNeedsLayout)
+ return;
+ o->m_normalChildNeedsLayout = true;
+ ASSERT(!o->isSetNeedsLayoutForbidden());
+ }
+
+ if (o == newRoot)
+ return;
+
+ last = o;
+ if (scheduleRelayout && objectIsRelayoutBoundary(last))
+ break;
+ o = container;
+ }
+
+ if (scheduleRelayout)
+ last->scheduleRelayout();
+}
+
+inline void makeMatrixRenderable(TransformationMatrix& matrix)
+{
+#if !ENABLE(3D_RENDERING)
+ matrix.makeAffine();
+#else
+ UNUSED_PARAM(matrix);
+#endif
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/WebCore/rendering/RenderObjectChildList.cpp b/WebCore/rendering/RenderObjectChildList.cpp
new file mode 100644
index 0000000..32e856f
--- /dev/null
+++ b/WebCore/rendering/RenderObjectChildList.cpp
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RenderObjectChildList.h"
+
+#include "AXObjectCache.h"
+#include "RenderBlock.h"
+#include "RenderCounter.h"
+#include "RenderImageGeneratedContent.h"
+#include "RenderInline.h"
+#include "RenderLayer.h"
+#include "RenderListItem.h"
+#include "RenderStyle.h"
+#include "RenderTextFragment.h"
+#include "RenderView.h"
+
+namespace WebCore {
+
+static void updateListMarkerNumbers(RenderObject* child)
+{
+ for (RenderObject* r = child; r; r = r->nextSibling()) {
+ if (r->isListItem())
+ static_cast<RenderListItem*>(r)->updateValue();
+ }
+}
+
+
+void RenderObjectChildList::destroyLeftoverChildren()
+{
+ while (firstChild()) {
+ if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
+ firstChild()->remove(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
+ else {
+ // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
+ if (firstChild()->node())
+ firstChild()->node()->setRenderer(0);
+ firstChild()->destroy();
+ }
+ }
+}
+
+RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, RenderObject* oldChild, bool fullRemove)
+{
+ ASSERT(oldChild->parent() == owner);
+
+ // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
+ // that a positioned child got yanked). We also repaint, so that the area exposed when the child
+ // disappears gets repainted properly.
+ if (!owner->documentBeingDestroyed() && fullRemove && oldChild->m_everHadLayout) {
+ oldChild->setNeedsLayoutAndPrefWidthsRecalc();
+ oldChild->repaint();
+ }
+
+ // If we have a line box wrapper, delete it.
+ if (oldChild->isBox())
+ toRenderBox(oldChild)->deleteLineBoxWrapper();
+
+ if (!owner->documentBeingDestroyed() && fullRemove) {
+ // if we remove visible child from an invisible parent, we don't know the layer visibility any more
+ RenderLayer* layer = 0;
+ if (owner->style()->visibility() != VISIBLE && oldChild->style()->visibility() == VISIBLE && !oldChild->hasLayer()) {
+ layer = owner->enclosingLayer();
+ layer->dirtyVisibleContentStatus();
+ }
+
+ // Keep our layer hierarchy updated.
+ if (oldChild->firstChild() || oldChild->hasLayer()) {
+ if (!layer)
+ layer = owner->enclosingLayer();
+ oldChild->removeLayers(layer);
+ }
+
+ // renumber ordered lists
+ if (oldChild->isListItem())
+ updateListMarkerNumbers(oldChild->nextSibling());
+
+ if (oldChild->isPositioned() && owner->childrenInline())
+ owner->dirtyLinesFromChangedChild(oldChild);
+ }
+
+ // If oldChild is the start or end of the selection, then clear the selection to
+ // avoid problems of invalid pointers.
+ // FIXME: The SelectionController should be responsible for this when it
+ // is notified of DOM mutations.
+ if (!owner->documentBeingDestroyed() && oldChild->isSelectionBorder())
+ owner->view()->clearSelection();
+
+ // remove the child
+ if (oldChild->previousSibling())
+ oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
+ if (oldChild->nextSibling())
+ oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
+
+ if (firstChild() == oldChild)
+ setFirstChild(oldChild->nextSibling());
+ if (lastChild() == oldChild)
+ setLastChild(oldChild->previousSibling());
+
+ oldChild->setPreviousSibling(0);
+ oldChild->setNextSibling(0);
+ oldChild->setParent(0);
+
+ if (AXObjectCache::accessibilityEnabled())
+ owner->document()->axObjectCache()->childrenChanged(owner);
+
+ return oldChild;
+}
+
+void RenderObjectChildList::appendChildNode(RenderObject* owner, RenderObject* newChild, bool fullAppend)
+{
+ ASSERT(newChild->parent() == 0);
+ ASSERT(!owner->isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
+
+ newChild->setParent(owner);
+ RenderObject* lChild = lastChild();
+
+ if (lChild) {
+ newChild->setPreviousSibling(lChild);
+ lChild->setNextSibling(newChild);
+ } else
+ setFirstChild(newChild);
+
+ setLastChild(newChild);
+
+ if (fullAppend) {
+ // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
+ // and don't have a layer attached to ourselves.
+ RenderLayer* layer = 0;
+ if (newChild->firstChild() || newChild->hasLayer()) {
+ layer = owner->enclosingLayer();
+ newChild->addLayers(layer, newChild);
+ }
+
+ // if the new child is visible but this object was not, tell the layer it has some visible content
+ // that needs to be drawn and layer visibility optimization can't be used
+ if (owner->style()->visibility() != VISIBLE && newChild->style()->visibility() == VISIBLE && !newChild->hasLayer()) {
+ if (!layer)
+ layer = owner->enclosingLayer();
+ if (layer)
+ layer->setHasVisibleContent(true);
+ }
+
+ if (!newChild->isFloatingOrPositioned() && owner->childrenInline())
+ owner->dirtyLinesFromChangedChild(newChild);
+ }
+
+ newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
+ if (!owner->normalChildNeedsLayout())
+ owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+
+ if (AXObjectCache::accessibilityEnabled())
+ owner->document()->axObjectCache()->childrenChanged(owner);
+}
+
+void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* beforeChild, bool fullInsert)
+{
+ if (!beforeChild) {
+ appendChildNode(owner, child);
+ return;
+ }
+
+ ASSERT(!child->parent());
+ while (beforeChild->parent() != owner && beforeChild->parent()->isAnonymousBlock())
+ beforeChild = beforeChild->parent();
+ ASSERT(beforeChild->parent() == owner);
+
+ ASSERT(!owner->isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
+
+ if (beforeChild == firstChild())
+ setFirstChild(child);
+
+ RenderObject* prev = beforeChild->previousSibling();
+ child->setNextSibling(beforeChild);
+ beforeChild->setPreviousSibling(child);
+ if (prev)
+ prev->setNextSibling(child);
+ child->setPreviousSibling(prev);
+
+ child->setParent(owner);
+
+ if (fullInsert) {
+ // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
+ // and don't have a layer attached to ourselves.
+ RenderLayer* layer = 0;
+ if (child->firstChild() || child->hasLayer()) {
+ layer = owner->enclosingLayer();
+ child->addLayers(layer, child);
+ }
+
+ // if the new child is visible but this object was not, tell the layer it has some visible content
+ // that needs to be drawn and layer visibility optimization can't be used
+ if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) {
+ if (!layer)
+ layer = owner->enclosingLayer();
+ if (layer)
+ layer->setHasVisibleContent(true);
+ }
+
+
+ if (!child->isFloating() && owner->childrenInline())
+ owner->dirtyLinesFromChangedChild(child);
+ }
+
+ child->setNeedsLayoutAndPrefWidthsRecalc();
+ if (!owner->normalChildNeedsLayout())
+ owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
+
+ if (AXObjectCache::accessibilityEnabled())
+ owner->document()->axObjectCache()->childrenChanged(owner);
+}
+
+static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type)
+{
+ if (type == BEFORE) {
+ RenderObject* first = container;
+ do {
+ // Skip list markers.
+ first = first->firstChild();
+ while (first && first->isListMarker())
+ first = first->nextSibling();
+ } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO);
+ if (first && first->style()->styleType() != type)
+ return 0;
+ return first;
+ }
+ if (type == AFTER) {
+ RenderObject* last = container;
+ do {
+ last = last->lastChild();
+ } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker());
+ if (last && last->style()->styleType() != type)
+ return 0;
+ return last;
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+static RenderObject* findBeforeAfterParent(RenderObject* object)
+{
+ // Only table parts need to search for the :before or :after parent
+ if (!(object->isTable() || object->isTableSection() || object->isTableRow()))
+ return object;
+
+ RenderObject* beforeAfterParent = object;
+ while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage()))
+ beforeAfterParent = beforeAfterParent->firstChild();
+ return beforeAfterParent;
+}
+
+static void invalidateCountersInContainer(RenderObject* container)
+{
+ if (!container)
+ return;
+ container = findBeforeAfterParent(container);
+ if (!container)
+ return;
+ for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) {
+ if (content->isCounter())
+ static_cast<RenderCounter*>(content)->invalidate();
+ }
+}
+
+void RenderObjectChildList::invalidateCounters(RenderObject* owner)
+{
+ ASSERT(!owner->documentBeingDestroyed());
+ invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE));
+ invalidateCountersInContainer(beforeAfterContainer(owner, AFTER));
+}
+
+void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject)
+{
+ // Double check that the document did in fact use generated content rules. Otherwise we should not have been called.
+ ASSERT(owner->document()->usesBeforeAfterRules());
+
+ // In CSS2, before/after pseudo-content cannot nest. Check this first.
+ if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER)
+ return;
+
+ if (!styledObject)
+ styledObject = owner;
+
+ RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type);
+ RenderObject* child = beforeAfterContainer(owner, type);
+
+ // Whether or not we currently have generated content attached.
+ bool oldContentPresent = child;
+
+ // Whether or not we now want generated content.
+ bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE;
+
+ // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate
+ // :after content and not :before content.
+ if (newContentWanted && type == BEFORE && owner->isRenderInline() && toRenderInline(owner)->isInlineContinuation())
+ newContentWanted = false;
+
+ // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object,
+ // then we don't generate the :after content.
+ if (newContentWanted && type == AFTER && owner->isRenderInline() && toRenderInline(owner)->continuation())
+ newContentWanted = false;
+
+ // If we don't want generated content any longer, or if we have generated content, but it's no longer
+ // identical to the new content data we want to build render objects for, then we nuke all
+ // of the old generated content.
+ if (!newContentWanted || (oldContentPresent && Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) {
+ // Nuke the child.
+ if (child && child->style()->styleType() == type) {
+ oldContentPresent = false;
+ child->destroy();
+ child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild();
+ }
+ }
+
+ // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we
+ // have no generated content and can now return.
+ if (!newContentWanted)
+ return;
+
+ if (owner->isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && pseudoElementStyle->floating() == FNONE &&
+ !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementStyle->position() == FixedPosition))
+ // According to the CSS2 spec (the end of section 12.1), the only allowed
+ // display values for the pseudo style are NONE and INLINE for inline flows.
+ // FIXME: CSS2.1 lifted this restriction, but block display types will crash.
+ // For now we at least relax the restriction to allow all inline types like inline-block
+ // and inline-table.
+ pseudoElementStyle->setDisplay(INLINE);
+
+ if (oldContentPresent) {
+ if (child && child->style()->styleType() == type) {
+ // We have generated content present still. We want to walk this content and update our
+ // style information with the new pseudo-element style.
+ child->setStyle(pseudoElementStyle);
+
+ RenderObject* beforeAfterParent = findBeforeAfterParent(child);
+ if (!beforeAfterParent)
+ return;
+
+ // Note that if we ever support additional types of generated content (which should be way off
+ // in the future), this code will need to be patched.
+ for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) {
+ if (genChild->isText())
+ // Generated text content is a child whose style also needs to be set to the pseudo-element style.
+ genChild->setStyle(pseudoElementStyle);
+ else if (genChild->isImage()) {
+ // Images get an empty style that inherits from the pseudo.
+ RefPtr<RenderStyle> style = RenderStyle::create();
+ style->inheritFrom(pseudoElementStyle);
+ genChild->setStyle(style.release());
+ } else
+ // Must be a first-letter container. updateFirstLetter() will take care of it.
+ ASSERT(genChild->style()->styleType() == FIRST_LETTER);
+ }
+ }
+ return; // We've updated the generated content. That's all we needed to do.
+ }
+
+ RenderObject* insertBefore = (type == BEFORE) ? owner->virtualChildren()->firstChild() : 0;
+
+ // Generated content consists of a single container that houses multiple children (specified
+ // by the content property). This generated content container gets the pseudo-element style set on it.
+ RenderObject* generatedContentContainer = 0;
+
+ // Walk our list of generated content and create render objects for each.
+ for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->next()) {
+ RenderObject* renderer = 0;
+ switch (content->type()) {
+ case CONTENT_NONE:
+ break;
+ case CONTENT_TEXT:
+ renderer = new (owner->renderArena()) RenderTextFragment(owner->document() /* anonymous object */, content->text());
+ renderer->setStyle(pseudoElementStyle);
+ break;
+ case CONTENT_OBJECT: {
+ RenderImageGeneratedContent* image = new (owner->renderArena()) RenderImageGeneratedContent(owner->document()); // anonymous object
+ RefPtr<RenderStyle> style = RenderStyle::create();
+ style->inheritFrom(pseudoElementStyle);
+ image->setStyle(style.release());
+ if (StyleImage* styleImage = content->image())
+ image->setStyleImage(styleImage);
+ renderer = image;
+ break;
+ }
+ case CONTENT_COUNTER:
+ renderer = new (owner->renderArena()) RenderCounter(owner->document(), *content->counter());
+ renderer->setStyle(pseudoElementStyle);
+ break;
+ }
+
+ if (renderer) {
+ if (!generatedContentContainer) {
+ // Make a generated box that might be any display type now that we are able to drill down into children
+ // to find the original content properly.
+ generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle);
+ generatedContentContainer->setStyle(pseudoElementStyle);
+ owner->addChild(generatedContentContainer, insertBefore);
+ }
+ generatedContentContainer->addChild(renderer);
+ }
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderObjectChildList.h b/WebCore/rendering/RenderObjectChildList.h
new file mode 100644
index 0000000..bf8800a
--- /dev/null
+++ b/WebCore/rendering/RenderObjectChildList.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderObjectChildList_h
+#define RenderObjectChildList_h
+
+#include "RenderStyleConstants.h"
+
+namespace WebCore {
+
+class RenderObject;
+
+class RenderObjectChildList {
+public:
+ RenderObjectChildList()
+ : m_firstChild(0)
+ , m_lastChild(0)
+ {
+ }
+
+ RenderObject* firstChild() const { return m_firstChild; }
+ RenderObject* lastChild() const { return m_lastChild; }
+
+ // FIXME: Temporary while RenderBox still exists. Eventually this will just happen during insert/append/remove methods on the child list, and nobody
+ // will need to manipulate firstChild or lastChild directly.
+ void setFirstChild(RenderObject* child) { m_firstChild = child; }
+ void setLastChild(RenderObject* child) { m_lastChild = child; }
+
+ void destroyLeftoverChildren();
+
+ RenderObject* removeChildNode(RenderObject* owner, RenderObject*, bool fullRemove = true);
+ void appendChildNode(RenderObject* owner, RenderObject*, bool fullAppend = true);
+ void insertChildNode(RenderObject* owner, RenderObject* child, RenderObject* before, bool fullInsert = true);
+
+ void updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject = 0);
+ void invalidateCounters(RenderObject* owner);
+
+private:
+ RenderObject* m_firstChild;
+ RenderObject* m_lastChild;
+};
+
+} // namespace WebCore
+
+#endif // RenderObjectChildList_h
diff --git a/WebCore/rendering/RenderPart.cpp b/WebCore/rendering/RenderPart.cpp
index 6f79a00..71e5f4e 100644
--- a/WebCore/rendering/RenderPart.cpp
+++ b/WebCore/rendering/RenderPart.cpp
@@ -37,7 +37,7 @@ namespace WebCore {
using namespace HTMLNames;
-RenderPart::RenderPart(HTMLFrameOwnerElement* node)
+RenderPart::RenderPart(Element* node)
: RenderWidget(node)
{
// init RenderObject attributes
@@ -81,35 +81,4 @@ void RenderPart::deleteWidget()
delete m_widget;
}
-// FIXME: This should not be necessary. Remove this once WebKit knows to properly schedule
-// layouts using WebCore when objects resize.
-void RenderPart::updateWidgetPosition()
-{
- if (!m_widget)
- return;
-
- FloatPoint absPos = localToAbsolute();
- absPos.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
- int w = width() - borderLeft() - borderRight() - paddingLeft() - paddingRight();
- int h = height() - borderTop() - borderBottom() - paddingTop() - paddingBottom();
- IntRect newBounds(absPos.x(), absPos.y(), w, h);
- bool boundsChanged = newBounds != m_widget->frameRect();
- if (boundsChanged) {
- // The widget changed positions. Update the frame geometry.
- RenderArena *arena = ref();
- element()->ref();
- m_widget->setFrameRect(newBounds);
- element()->deref();
- deref(arena);
- }
-
- // if the frame bounds got changed, or if view needs layout (possibly indicating
- // content size is wrong) we have to do a layout to set the right widget size
- if (m_widget && m_widget->isFrameView()) {
- FrameView* frameView = static_cast<FrameView*>(m_widget);
- if (boundsChanged || frameView->needsLayout())
- frameView->layout();
- }
-}
-
}
diff --git a/WebCore/rendering/RenderPart.h b/WebCore/rendering/RenderPart.h
index e339468..5a7ba26 100644
--- a/WebCore/rendering/RenderPart.h
+++ b/WebCore/rendering/RenderPart.h
@@ -34,7 +34,7 @@ class HTMLFrameOwnerElement;
class RenderPart : public RenderWidget {
public:
- RenderPart(HTMLFrameOwnerElement*);
+ RenderPart(Element*);
virtual ~RenderPart();
virtual bool isRenderPart() const { return true; }
@@ -42,10 +42,6 @@ public:
virtual void setWidget(Widget*);
- // FIXME: This should not be necessary.
- // Remove this once WebKit knows to properly schedule layouts using WebCore when objects resize.
- virtual void updateWidgetPosition();
-
bool hasFallbackContent() const { return m_hasFallbackContent; }
virtual void viewCleared();
diff --git a/WebCore/rendering/RenderPartObject.cpp b/WebCore/rendering/RenderPartObject.cpp
index 4df631f..828026e 100644
--- a/WebCore/rendering/RenderPartObject.cpp
+++ b/WebCore/rendering/RenderPartObject.cpp
@@ -34,21 +34,21 @@
#include "HTMLNames.h"
#include "HTMLObjectElement.h"
#include "HTMLParamElement.h"
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#include "HTMLMediaElement.h"
+#include "HTMLVideoElement.h"
+#endif
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "PluginData.h"
#include "RenderView.h"
#include "Text.h"
-#ifdef FLATTEN_IFRAME
-#include "RenderView.h"
-#endif
-
namespace WebCore {
using namespace HTMLNames;
-RenderPartObject::RenderPartObject(HTMLFrameOwnerElement* element)
+RenderPartObject::RenderPartObject(Element* element)
: RenderPart(element)
{
// init RenderObject attributes
@@ -132,10 +132,17 @@ static String serviceTypeForClassId(const String& classId, const PluginData* plu
static inline bool shouldUseEmbedDescendant(HTMLObjectElement* objectElement, const PluginData* pluginData)
{
+#if PLATFORM(MAC)
+ UNUSED_PARAM(objectElement);
+ UNUSED_PARAM(pluginData);
+ // On Mac, we always want to use the embed descendant.
+ return true;
+#else
// If we have both an <object> and <embed>, we always want to use the <embed> except when we have
// an ActiveX plug-in and plan to use it.
return !(havePlugin(pluginData, activeXType())
&& serviceTypeForClassId(objectElement->classId(), pluginData) == activeXType());
+#endif
}
void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
@@ -146,8 +153,8 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
Vector<String> paramValues;
Frame* frame = m_view->frame();
- if (element()->hasTagName(objectTag)) {
- HTMLObjectElement* o = static_cast<HTMLObjectElement*>(element());
+ if (node()->hasTagName(objectTag)) {
+ HTMLObjectElement* o = static_cast<HTMLObjectElement*>(node());
o->setNeedWidgetUpdate(false);
if (!o->isFinishedParsingChildren())
@@ -261,8 +268,8 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
bool success = frame->loader()->requestObject(this, url, AtomicString(o->name()), serviceType, paramNames, paramValues);
if (!success && m_hasFallbackContent)
o->renderFallbackContent();
- } else if (element()->hasTagName(embedTag)) {
- HTMLEmbedElement *o = static_cast<HTMLEmbedElement*>(element());
+ } else if (node()->hasTagName(embedTag)) {
+ HTMLEmbedElement *o = static_cast<HTMLEmbedElement*>(node());
o->setNeedWidgetUpdate(false);
url = o->url();
serviceType = o->serviceType();
@@ -294,6 +301,30 @@ void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
}
+#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+ else if (node()->hasTagName(videoTag) || node()->hasTagName(audioTag)) {
+ HTMLMediaElement* o = static_cast<HTMLMediaElement*>(node());
+
+ o->setNeedWidgetUpdate(false);
+ if (node()->hasTagName(videoTag)) {
+ HTMLVideoElement* vid = static_cast<HTMLVideoElement*>(node());
+ String poster = vid->poster();
+ if (!poster.isEmpty()) {
+ paramNames.append("_media_element_poster_");
+ paramValues.append(poster);
+ }
+ }
+
+ url = o->initialURL();
+ if (!url.isEmpty()) {
+ paramNames.append("_media_element_src_");
+ paramValues.append(url);
+ }
+
+ serviceType = "application/x-media-element-proxy-plugin";
+ frame->loader()->requestObject(this, url, nullAtom, serviceType, paramNames, paramValues);
+ }
+#endif
}
void RenderPartObject::layout()
@@ -349,8 +380,8 @@ void RenderPartObject::layout()
calcWidth();
calcHeight();
#endif
-
- adjustOverflowForBoxShadow();
+
+ adjustOverflowForBoxShadowAndReflect();
RenderPart::layout();
@@ -416,12 +447,12 @@ void RenderPartObject::calcHeight() {
void RenderPartObject::viewCleared()
{
- if (element() && m_widget && m_widget->isFrameView()) {
+ if (node() && m_widget && m_widget->isFrameView()) {
FrameView* view = static_cast<FrameView*>(m_widget);
int marginw = -1;
int marginh = -1;
- if (element()->hasTagName(iframeTag)) {
- HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(element());
+ if (node()->hasTagName(iframeTag)) {
+ HTMLIFrameElement* frame = static_cast<HTMLIFrameElement*>(node());
marginw = frame->getMarginWidth();
marginh = frame->getMarginHeight();
}
diff --git a/WebCore/rendering/RenderPartObject.h b/WebCore/rendering/RenderPartObject.h
index 2b21644..9eb9f21 100644
--- a/WebCore/rendering/RenderPartObject.h
+++ b/WebCore/rendering/RenderPartObject.h
@@ -31,7 +31,7 @@ namespace WebCore {
class RenderPartObject : public RenderPart {
public:
- RenderPartObject(HTMLFrameOwnerElement*);
+ RenderPartObject(Element*);
virtual ~RenderPartObject();
virtual const char* renderName() const { return "RenderPartObject"; }
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index 1f73c70..1340694 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -81,7 +81,7 @@ FloatPoint RenderPath::mapAbsolutePointToLocal(const FloatPoint& point) const
// absolute transform?
double localX;
double localY;
- absoluteTransform().inverse().map(point.x(), point.y(), &localX, &localY);
+ absoluteTransform().inverse().map(point.x(), point.y(), localX, localY);
return FloatPoint::narrowPrecision(localX, localY);
}
@@ -150,33 +150,27 @@ const Path& RenderPath::path() const
bool RenderPath::calculateLocalTransform()
{
TransformationMatrix oldTransform = m_localTransform;
- m_localTransform = static_cast<SVGStyledTransformableElement*>(element())->animatedLocalTransform();
+ m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
return (m_localTransform != oldTransform);
}
void RenderPath::layout()
{
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout() && selfNeedsLayout();
- if (checkForRepaint) {
- oldBounds = m_absoluteBounds;
- oldOutlineBox = absoluteOutlineBounds();
- }
-
+ // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout(), &m_absoluteBounds);
+
calculateLocalTransform();
- setPath(static_cast<SVGStyledTransformableElement*>(element())->toPathData());
+ setPath(static_cast<SVGStyledTransformableElement*>(node())->toPathData());
m_absoluteBounds = absoluteClippedOverflowRect();
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ repainter.repaintAfterLayout();
setNeedsLayout(false);
}
-IntRect RenderPath::clippedOverflowRectForRepaint(RenderBox* /*repaintContainer*/)
+IntRect RenderPath::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/)
{
// FIXME: handle non-root repaintContainer
FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));
@@ -243,7 +237,7 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
paintInfo.context->setShouldAntialias(false);
fillAndStrokePath(m_path, paintInfo.context, style(), this);
- if (static_cast<SVGStyledElement*>(element())->supportsMarkers())
+ if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
m_markerBounds = drawMarkersIfNeeded(paintInfo.context, paintInfo.rect, m_path);
finishRenderSVGContent(this, paintInfo, boundingBox, filter, savedInfo.context);
@@ -418,7 +412,7 @@ FloatRect RenderPath::drawMarkersIfNeeded(GraphicsContext* context, const FloatR
{
Document* doc = document();
- SVGElement* svgElement = static_cast<SVGElement*>(element());
+ SVGElement* svgElement = static_cast<SVGElement*>(node());
ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
@@ -476,7 +470,7 @@ FloatRect RenderPath::drawMarkersIfNeeded(GraphicsContext* context, const FloatR
return bounds;
}
-IntRect RenderPath::outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const
+IntRect RenderPath::outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const
{
// FIXME: handle non-root repaintContainer
IntRect result = m_absoluteBounds;
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index 81b5c52..6157171 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -59,7 +59,7 @@ public:
virtual TransformationMatrix localTransform() const;
virtual void layout();
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual bool requiresLayer() const { return false; }
virtual int lineHeight(bool b, bool isRootLineBox = false) const;
virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
@@ -75,7 +75,7 @@ public:
private:
FloatPoint mapAbsolutePointToLocal(const FloatPoint&) const;
- virtual IntRect outlineBoundsForRepaint(RenderBox* repaintContainer) const;
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* repaintContainer) const;
mutable Path m_path;
mutable FloatRect m_fillBBox;
diff --git a/WebCore/rendering/RenderReplaced.cpp b/WebCore/rendering/RenderReplaced.cpp
index e74e227..783fc26 100644
--- a/WebCore/rendering/RenderReplaced.cpp
+++ b/WebCore/rendering/RenderReplaced.cpp
@@ -28,6 +28,7 @@
#include "RenderLayer.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "VisiblePosition.h"
using namespace std;
@@ -42,8 +43,6 @@ const int cDefaultHeight = 150;
RenderReplaced::RenderReplaced(Node* node)
: RenderBox(node)
, m_intrinsicSize(cDefaultWidth, cDefaultHeight)
- , m_selectionState(SelectionNone)
- , m_hasOverflow(false)
{
setReplaced(true);
}
@@ -51,19 +50,17 @@ RenderReplaced::RenderReplaced(Node* node)
RenderReplaced::RenderReplaced(Node* node, const IntSize& intrinsicSize)
: RenderBox(node)
, m_intrinsicSize(intrinsicSize)
- , m_selectionState(SelectionNone)
- , m_hasOverflow(false)
{
setReplaced(true);
}
RenderReplaced::~RenderReplaced()
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
gOverflowRectMap->remove(this);
}
-void RenderReplaced::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderReplaced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBox::styleDidChange(diff, oldStyle);
@@ -77,23 +74,16 @@ void RenderReplaced::layout()
{
ASSERT(needsLayout());
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
setHeight(minimumReplacedHeight());
calcWidth();
calcHeight();
- adjustOverflowForBoxShadow();
-
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ adjustOverflowForBoxShadowAndReflect();
+ repainter.repaintAfterLayout();
+
setNeedsLayout(false);
}
@@ -137,8 +127,24 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
drawSelectionTint = false;
}
+ bool clipToBorderRadius = style()->overflowX() != OVISIBLE && style()->hasBorderRadius();
+ if (clipToBorderRadius) {
+ // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
+ paintInfo.context->save();
+ paintInfo.context->addRoundedRectClip(IntRect(tx, ty, width(), height()),
+ style()->borderTopLeftRadius(),
+ style()->borderTopRightRadius(),
+ style()->borderBottomLeftRadius(),
+ style()->borderBottomRightRadius());
+ }
+
paintReplaced(paintInfo, tx, ty);
-
+
+ if (clipToBorderRadius)
+ paintInfo.context->restore();
+
+ // The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of
+ // surrounding content.
if (drawSelectionTint) {
IntRect selectionPaintingRect = localSelectionRect();
selectionPaintingRect.move(tx, ty);
@@ -215,11 +221,11 @@ unsigned RenderReplaced::caretMaxRenderedOffset() const
return 1;
}
-VisiblePosition RenderReplaced::positionForCoordinates(int xPos, int yPos)
+VisiblePosition RenderReplaced::positionForPoint(const IntPoint& point)
{
InlineBox* box = inlineBoxWrapper();
if (!box)
- return VisiblePosition(element(), 0, DOWNSTREAM);
+ return createVisiblePosition(0, DOWNSTREAM);
// FIXME: This code is buggy if the replaced element is relative positioned.
@@ -228,22 +234,22 @@ VisiblePosition RenderReplaced::positionForCoordinates(int xPos, int yPos)
int top = root->topOverflow();
int bottom = root->nextRootBox() ? root->nextRootBox()->topOverflow() : root->bottomOverflow();
- if (yPos + y() < top)
- return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM); // coordinates are above
+ if (point.y() + y() < top)
+ return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above
- if (yPos + y() >= bottom)
- return VisiblePosition(element(), caretMaxOffset(), DOWNSTREAM); // coordinates are below
+ if (point.y() + y() >= bottom)
+ return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); // coordinates are below
- if (element()) {
- if (xPos <= width() / 2)
- return VisiblePosition(element(), 0, DOWNSTREAM);
- return VisiblePosition(element(), 1, DOWNSTREAM);
+ if (node()) {
+ if (point.x() <= width() / 2)
+ return createVisiblePosition(0, DOWNSTREAM);
+ return createVisiblePosition(1, DOWNSTREAM);
}
- return RenderBox::positionForCoordinates(xPos, yPos);
+ return RenderBox::positionForPoint(point);
}
-IntRect RenderReplaced::selectionRect(bool clipToVisibleContent)
+IntRect RenderReplaced::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
@@ -252,11 +258,9 @@ IntRect RenderReplaced::selectionRect(bool clipToVisibleContent)
IntRect rect = localSelectionRect();
if (clipToVisibleContent)
- computeAbsoluteRepaintRect(rect);
- else {
- FloatPoint absPos = localToAbsolute(FloatPoint());
- rect.move(absPos.x(), absPos.y());
- }
+ computeRectForRepaint(repaintContainer, rect);
+ else
+ rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
return rect;
}
@@ -280,7 +284,7 @@ IntRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const
void RenderReplaced::setSelectionState(SelectionState s)
{
- m_selectionState = s;
+ RenderBox::setSelectionState(s);
if (m_inlineBoxWrapper) {
RootInlineBox* line = m_inlineBoxWrapper->root();
if (line)
@@ -303,7 +307,7 @@ bool RenderReplaced::isSelected() const
if (s == SelectionStart)
return selectionStart == 0;
- int end = element()->hasChildNodes() ? element()->childNodeCount() : 1;
+ int end = node()->hasChildNodes() ? node()->childNodeCount() : 1;
if (s == SelectionEnd)
return selectionEnd == end;
if (s == SelectionBoth)
@@ -323,7 +327,7 @@ void RenderReplaced::setIntrinsicSize(const IntSize& size)
m_intrinsicSize = size;
}
-void RenderReplaced::adjustOverflowForBoxShadow()
+void RenderReplaced::adjustOverflowForBoxShadowAndReflect()
{
IntRect overflow;
for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
@@ -333,21 +337,29 @@ void RenderReplaced::adjustOverflowForBoxShadow()
overflow.unite(shadow);
}
+ // Now that we have an overflow rect including shadow, let's make sure that
+ // the reflection (which can also include the shadow) is also included.
+ if (hasReflection()) {
+ if (overflow.isEmpty())
+ overflow = borderBoxRect();
+ overflow.unite(reflectedRect(overflow));
+ }
+
if (!overflow.isEmpty()) {
if (!gOverflowRectMap)
gOverflowRectMap = new OverflowRectMap();
overflow.unite(borderBoxRect());
gOverflowRectMap->set(this, overflow);
- m_hasOverflow = true;
- } else if (m_hasOverflow) {
+ setReplacedHasOverflow(true);
+ } else if (replacedHasOverflow()) {
gOverflowRectMap->remove(this);
- m_hasOverflow = false;
+ setReplacedHasOverflow(false);
}
}
int RenderReplaced::overflowHeight(bool) const
{
- if (m_hasOverflow) {
+ if (replacedHasOverflow()) {
IntRect *r = &gOverflowRectMap->find(this)->second;
return r->height() + r->y();
}
@@ -357,7 +369,7 @@ int RenderReplaced::overflowHeight(bool) const
int RenderReplaced::overflowWidth(bool) const
{
- if (m_hasOverflow) {
+ if (replacedHasOverflow()) {
IntRect *r = &gOverflowRectMap->find(this)->second;
return r->width() + r->x();
}
@@ -367,7 +379,7 @@ int RenderReplaced::overflowWidth(bool) const
int RenderReplaced::overflowLeft(bool) const
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
return gOverflowRectMap->get(this).x();
return 0;
@@ -375,7 +387,7 @@ int RenderReplaced::overflowLeft(bool) const
int RenderReplaced::overflowTop(bool) const
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
return gOverflowRectMap->get(this).y();
return 0;
@@ -383,20 +395,20 @@ int RenderReplaced::overflowTop(bool) const
IntRect RenderReplaced::overflowRect(bool) const
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
return gOverflowRectMap->find(this)->second;
return borderBoxRect();
}
-IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
return IntRect();
- // The selectionRect can project outside of the overflowRect, so use
- // that for repainting to avoid selection painting glitches
- IntRect r = localSelectionRect(false);
+ // The selectionRect can project outside of the overflowRect, so take their union
+ // for repainting to avoid selection painting glitches.
+ IntRect r = unionRect(localSelectionRect(false), overflowRect(false));
RenderView* v = view();
if (v) {
@@ -412,7 +424,7 @@ IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBox* repaintContaine
if (v)
r.inflate(style()->outlineSize());
}
- computeRectForRepaint(r, repaintContainer);
+ computeRectForRepaint(repaintContainer, r);
return r;
}
diff --git a/WebCore/rendering/RenderReplaced.h b/WebCore/rendering/RenderReplaced.h
index c87db58..4937446 100644
--- a/WebCore/rendering/RenderReplaced.h
+++ b/WebCore/rendering/RenderReplaced.h
@@ -34,6 +34,8 @@ public:
virtual const char* renderName() const { return "RenderReplaced"; }
+ virtual bool canHaveChildren() const { return false; }
+
virtual int lineHeight(bool firstLine, bool isRootLineBox = false) const;
virtual int baselinePosition(bool firstLine, bool isRootLineBox = false) const;
@@ -53,33 +55,29 @@ public:
virtual int overflowTop(bool includeInterior = true) const;
virtual IntRect overflowRect(bool includeInterior = true) const;
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual unsigned caretMaxRenderedOffset() const;
- virtual VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
virtual bool canBeSelectionLeaf() const { return true; }
- virtual SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); }
virtual void setSelectionState(SelectionState);
- virtual IntRect selectionRect(bool clipToVisibleContent = true);
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
bool isSelected() const;
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void setIntrinsicSize(const IntSize&);
virtual void intrinsicSizeChanged();
bool shouldPaint(PaintInfo&, int& tx, int& ty);
- void adjustOverflowForBoxShadow();
+ void adjustOverflowForBoxShadowAndReflect();
IntRect localSelectionRect(bool checkWhetherSelected = true) const;
private:
IntSize m_intrinsicSize;
-
- unsigned m_selectionState : 3; // SelectionState
- bool m_hasOverflow : 1;
};
}
diff --git a/WebCore/rendering/RenderReplica.cpp b/WebCore/rendering/RenderReplica.cpp
index 183dd2e..0eb9f8f 100644
--- a/WebCore/rendering/RenderReplica.cpp
+++ b/WebCore/rendering/RenderReplica.cpp
@@ -35,7 +35,13 @@ namespace WebCore {
RenderReplica::RenderReplica(Node* n)
: RenderBox(n)
-{}
+{
+ // This is a hack. Replicas are synthetic, and don't pick up the attributes of the
+ // renderers being replicated, so they always report that they are inline, non-replaced.
+ // However, we need transforms to be applied to replicas for reflections, so have to pass
+ // the if (!isInline() || isReplaced()) check before setHasTransform().
+ setReplaced(true);
+}
RenderReplica::~RenderReplica()
{}
diff --git a/WebCore/rendering/RenderSVGContainer.cpp b/WebCore/rendering/RenderSVGContainer.cpp
index 6e17c05..28c5672 100644
--- a/WebCore/rendering/RenderSVGContainer.cpp
+++ b/WebCore/rendering/RenderSVGContainer.cpp
@@ -39,8 +39,6 @@ namespace WebCore {
RenderSVGContainer::RenderSVGContainer(SVGStyledElement* node)
: RenderObject(node)
- , m_firstChild(0)
- , m_lastChild(0)
, m_width(0)
, m_height(0)
, m_drawsContents(true)
@@ -51,143 +49,6 @@ RenderSVGContainer::~RenderSVGContainer()
{
}
-bool RenderSVGContainer::canHaveChildren() const
-{
- return true;
-}
-
-void RenderSVGContainer::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
- insertChildNode(newChild, beforeChild);
-}
-
-void RenderSVGContainer::removeChild(RenderObject* oldChild)
-{
- // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode
- // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on
- // layout anyway).
- oldChild->removeFromObjectLists();
-
- removeChildNode(oldChild);
-}
-
-void RenderSVGContainer::destroy()
-{
- destroyLeftoverChildren();
- RenderObject::destroy();
-}
-
-void RenderSVGContainer::destroyLeftoverChildren()
-{
- while (m_firstChild) {
- // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
- if (m_firstChild->element())
- m_firstChild->element()->setRenderer(0);
-
- m_firstChild->destroy();
- }
-}
-
-RenderObject* RenderSVGContainer::removeChildNode(RenderObject* oldChild, bool fullRemove)
-{
- ASSERT(oldChild->parent() == this);
-
- // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
- // that a positioned child got yanked). We also repaint, so that the area exposed when the child
- // disappears gets repainted properly.
- if (!documentBeingDestroyed() && fullRemove) {
- oldChild->setNeedsLayoutAndPrefWidthsRecalc();
- oldChild->repaint();
- }
-
- // If we have a line box wrapper, delete it.
- oldChild->deleteLineBoxWrapper();
-
- if (!documentBeingDestroyed() && fullRemove) {
- // If oldChild is the start or end of the selection, then clear the selection to
- // avoid problems of invalid pointers.
- // FIXME: The SelectionController should be responsible for this when it
- // is notified of DOM mutations.
- if (oldChild->isSelectionBorder())
- view()->clearSelection();
- }
-
- // remove the child
- if (oldChild->previousSibling())
- oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
- if (oldChild->nextSibling())
- oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
-
- if (m_firstChild == oldChild)
- m_firstChild = oldChild->nextSibling();
- if (m_lastChild == oldChild)
- m_lastChild = oldChild->previousSibling();
-
- oldChild->setPreviousSibling(0);
- oldChild->setNextSibling(0);
- oldChild->setParent(0);
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->childrenChanged(this);
-
- return oldChild;
-}
-
-void RenderSVGContainer::appendChildNode(RenderObject* newChild, bool)
-{
- ASSERT(!newChild->parent());
- ASSERT(newChild->element()->isSVGElement());
-
- newChild->setParent(this);
- RenderObject* lChild = m_lastChild;
-
- if (lChild) {
- newChild->setPreviousSibling(lChild);
- lChild->setNextSibling(newChild);
- } else
- m_firstChild = newChild;
-
- m_lastChild = newChild;
-
- newChild->setNeedsLayoutAndPrefWidthsRecalc(); // Goes up the containing block hierarchy.
- if (!normalChildNeedsLayout())
- setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->childrenChanged(this);
-}
-
-void RenderSVGContainer::insertChildNode(RenderObject* child, RenderObject* beforeChild, bool)
-{
- if (!beforeChild) {
- appendChildNode(child);
- return;
- }
-
- ASSERT(!child->parent());
- ASSERT(beforeChild->parent() == this);
- ASSERT(child->element()->isSVGElement());
-
- if (beforeChild == m_firstChild)
- m_firstChild = child;
-
- RenderObject* prev = beforeChild->previousSibling();
- child->setNextSibling(beforeChild);
- beforeChild->setPreviousSibling(child);
- if (prev)
- prev->setNextSibling(child);
- child->setPreviousSibling(prev);
-
- child->setParent(this);
-
- child->setNeedsLayoutAndPrefWidthsRecalc();
- if (!normalChildNeedsLayout())
- setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child.
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->childrenChanged(this);
-}
-
bool RenderSVGContainer::drawsContents() const
{
return m_drawsContents;
@@ -226,13 +87,8 @@ void RenderSVGContainer::layout()
// Arbitrary affine transforms are incompatible with LayoutState.
view()->disableLayoutState();
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout() && selfWillPaint();
- if (checkForRepaint) {
- oldBounds = m_absoluteBounds;
- oldOutlineBox = absoluteOutlineBounds();
- }
+ // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfWillPaint(), &m_absoluteBounds);
calculateLocalTransform();
@@ -250,8 +106,7 @@ void RenderSVGContainer::layout()
calcBounds();
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ repainter.repaintAfterLayout();
view()->enableLayoutState();
setNeedsLayout(false);
@@ -264,7 +119,7 @@ int RenderSVGContainer::calcReplacedWidth() const
return max(0, style()->width().value());
case Percent:
{
- const int cw = containingBlockWidth();
+ const int cw = containingBlock()->availableWidth();
return cw > 0 ? max(0, style()->width().calcMinValue(cw)) : 0;
}
default:
@@ -357,7 +212,7 @@ TransformationMatrix RenderSVGContainer::viewportTransform() const
return TransformationMatrix();
}
-IntRect RenderSVGContainer::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderSVGContainer::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
FloatRect repaintRect;
@@ -425,7 +280,7 @@ bool RenderSVGContainer::nodeAtPoint(const HitTestRequest& request, HitTestResul
return false;
}
-IntRect RenderSVGContainer::outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const
+IntRect RenderSVGContainer::outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const
{
// FIXME: handle non-root repaintContainer
IntRect result = m_absoluteBounds;
diff --git a/WebCore/rendering/RenderSVGContainer.h b/WebCore/rendering/RenderSVGContainer.h
index e498a8a..2c1be65 100644
--- a/WebCore/rendering/RenderSVGContainer.h
+++ b/WebCore/rendering/RenderSVGContainer.h
@@ -37,29 +37,14 @@ public:
RenderSVGContainer(SVGStyledElement*);
~RenderSVGContainer();
- virtual RenderObject* firstChild() const { return m_firstChild; }
- virtual RenderObject* lastChild() const { return m_lastChild; }
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
int width() const { return m_width; }
int height() const { return m_height; }
- virtual bool canHaveChildren() const;
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject*);
-
- virtual void destroy();
- void destroyLeftoverChildren();
-
- virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
- virtual void appendChildNode(RenderObject*, bool fullAppend = true);
- virtual void insertChildNode(RenderObject* child, RenderObject* before, bool fullInsert = true);
-
- // Designed for speed. Don't waste time doing a bunch of work like layer updating and repainting when we know that our
- // change in parentage is not going to affect anything.
- virtual void moveChildNode(RenderObject* child) { appendChildNode(child->parent()->removeChildNode(child, false), false); }
-
- virtual void calcPrefWidths() { setPrefWidthsDirty(false); }
-
// Some containers do not want it's children
// to be drawn, because they may be 'referenced'
// Example: <marker> children in SVG
@@ -76,7 +61,7 @@ public:
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
@@ -95,14 +80,13 @@ protected:
void calcBounds();
- virtual IntRect outlineBoundsForRepaint(RenderBox* /*repaintContainer*/) const;
+ virtual IntRect outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const;
private:
int calcReplacedWidth() const;
int calcReplacedHeight() const;
- RenderObject* m_firstChild;
- RenderObject* m_lastChild;
+ RenderObjectChildList m_children;
int m_width;
int m_height;
diff --git a/WebCore/rendering/RenderSVGGradientStop.cpp b/WebCore/rendering/RenderSVGGradientStop.cpp
index d0dc881..b81e7f4 100644
--- a/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -42,7 +42,7 @@ RenderSVGGradientStop::~RenderSVGGradientStop()
{
}
-void RenderSVGGradientStop::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderObject::styleDidChange(diff, oldStyle);
@@ -61,7 +61,7 @@ void RenderSVGGradientStop::layout()
SVGGradientElement* RenderSVGGradientStop::gradientElement() const
{
- Node* parentNode = element()->parent();
+ Node* parentNode = node()->parent();
if (parentNode->hasTagName(linearGradientTag) || parentNode->hasTagName(radialGradientTag))
return static_cast<SVGGradientElement*>(parentNode);
return 0;
diff --git a/WebCore/rendering/RenderSVGGradientStop.h b/WebCore/rendering/RenderSVGGradientStop.h
index 86de6d0..7b7df5c 100644
--- a/WebCore/rendering/RenderSVGGradientStop.h
+++ b/WebCore/rendering/RenderSVGGradientStop.h
@@ -41,14 +41,13 @@ namespace WebCore {
virtual void layout();
- // This override is needed to prevent crashing on <svg><stop /></svg>
- // RenderObject's default impl asks the parent Object and RenderSVGRoot
- // asks all child RenderObjects for overflow rects, thus infinite loop.
+ // This override is needed to prevent an assert on <svg><stop /></svg>
+ // RenderObject's default impl asserts.
// https://bugs.webkit.org/show_bug.cgi?id=20400
- virtual IntRect absoluteClippedOverflowRect() { return IntRect(); }
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject*) { return IntRect(); }
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
SVGGradientElement* gradientElement() const;
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.cpp b/WebCore/rendering/RenderSVGHiddenContainer.cpp
index 23ae13e..dd76946 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.cpp
+++ b/WebCore/rendering/RenderSVGHiddenContainer.cpp
@@ -71,7 +71,7 @@ void RenderSVGHiddenContainer::paint(PaintInfo&, int, int)
// This subtree does not paint.
}
-IntRect RenderSVGHiddenContainer::clippedOverflowRectForRepaint(RenderBox* /*repaintContainer*/)
+IntRect RenderSVGHiddenContainer::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/)
{
return IntRect();
}
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.h b/WebCore/rendering/RenderSVGHiddenContainer.h
index 282e3f3..6568f3f 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.h
+++ b/WebCore/rendering/RenderSVGHiddenContainer.h
@@ -51,7 +51,7 @@ namespace WebCore {
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 503663a..a13ee03 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -129,7 +129,7 @@ void RenderSVGImage::adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& s
bool RenderSVGImage::calculateLocalTransform()
{
TransformationMatrix oldTransform = m_localTransform;
- m_localTransform = static_cast<SVGStyledTransformableElement*>(element())->animatedLocalTransform();
+ m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
return (m_localTransform != oldTransform);
}
@@ -137,13 +137,7 @@ void RenderSVGImage::layout()
{
ASSERT(needsLayout());
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
calculateLocalTransform();
@@ -158,9 +152,8 @@ void RenderSVGImage::layout()
calculateAbsoluteBounds();
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
-
+ repainter.repaintAfterLayout();
+
setNeedsLayout(false);
}
@@ -205,7 +198,7 @@ bool RenderSVGImage::nodeAtPoint(const HitTestRequest&, HitTestResult& result, i
bool isVisible = (style()->visibility() == VISIBLE);
if (isVisible || !hitRules.requireVisible) {
double localX, localY;
- absoluteTransform().inverse().map(_x, _y, &localX, &localY);
+ absoluteTransform().inverse().map(_x, _y, localX, localY);
if (hitRules.canHitFill) {
if (m_localBounds.contains(narrowPrecisionToFloat(localX), narrowPrecisionToFloat(localY))) {
@@ -228,7 +221,7 @@ void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
RenderImage::imageChanged(image, rect);
// We override to invalidate a larger rect, since SVG images can draw outside their "bounds"
- repaintRectangle(absoluteClippedOverflowRect());
+ repaintRectangle(absoluteClippedOverflowRect()); // FIXME: Isn't this just repaint()?
}
void RenderSVGImage::calculateAbsoluteBounds()
@@ -249,7 +242,7 @@ void RenderSVGImage::calculateAbsoluteBounds()
m_absoluteBounds = enclosingIntRect(absoluteRect);
}
-IntRect RenderSVGImage::clippedOverflowRectForRepaint(RenderBox* /*repaintContainer*/)
+IntRect RenderSVGImage::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/)
{
// FIXME: handle non-root repaintContainer
return m_absoluteBounds;
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index cb440d2..4aedfef 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -43,7 +43,7 @@ namespace WebCore {
virtual TransformationMatrix localTransform() const { return m_localTransform; }
virtual FloatRect relativeBBox(bool includeStroke = true) const;
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
diff --git a/WebCore/rendering/RenderSVGInline.cpp b/WebCore/rendering/RenderSVGInline.cpp
index 81e0924..a4016a1 100644
--- a/WebCore/rendering/RenderSVGInline.cpp
+++ b/WebCore/rendering/RenderSVGInline.cpp
@@ -36,28 +36,9 @@ RenderSVGInline::RenderSVGInline(Node* n)
{
}
-InlineBox* RenderSVGInline::createInlineBox(bool unusedMakePlaceHolderBox, bool unusedIsRootLineBox, bool)
+InlineFlowBox* RenderSVGInline::createFlowBox()
{
-#if ASSERT_DISABLED
- UNUSED_PARAM(unusedIsRootLineBox);
- UNUSED_PARAM(unusedMakePlaceHolderBox);
-#endif
-
- ASSERT(!(!unusedIsRootLineBox && (isReplaced() || unusedMakePlaceHolderBox)));
-
- ASSERT(isRenderInline());
-
- InlineFlowBox* flowBox = new (renderArena()) SVGInlineFlowBox(this);
-
- if (!m_firstLineBox)
- m_firstLineBox = m_lastLineBox = flowBox;
- else {
- m_lastLineBox->setNextLineBox(flowBox);
- flowBox->setPreviousLineBox(m_lastLineBox);
- m_lastLineBox = flowBox;
- }
-
- return flowBox;
+ return new (renderArena()) SVGInlineFlowBox(this);
}
}
diff --git a/WebCore/rendering/RenderSVGInline.h b/WebCore/rendering/RenderSVGInline.h
index 060ba58..cb8bf95 100644
--- a/WebCore/rendering/RenderSVGInline.h
+++ b/WebCore/rendering/RenderSVGInline.h
@@ -28,13 +28,17 @@
#include "RenderInline.h"
namespace WebCore {
+
class RenderSVGInline : public RenderInline {
public:
- RenderSVGInline(Node*);
- virtual const char* renderName() const { return "RenderSVGInline"; }
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun = false);
- virtual bool requiresLayer() const { return false; }
- };
+ RenderSVGInline(Node*);
+ virtual const char* renderName() const { return "RenderSVGInline"; }
+ virtual bool requiresLayer() const { return false; }
+
+private:
+ virtual InlineFlowBox* createFlowBox();
+};
+
}
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderSVGInlineText.cpp b/WebCore/rendering/RenderSVGInlineText.cpp
index 215e9fe..b98eba0 100644
--- a/WebCore/rendering/RenderSVGInlineText.cpp
+++ b/WebCore/rendering/RenderSVGInlineText.cpp
@@ -56,7 +56,7 @@ RenderSVGInlineText::RenderSVGInlineText(Node* n, PassRefPtr<StringImpl> str)
}
-void RenderSVGInlineText::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
// Skip RenderText's work.
RenderObject::styleDidChange(diff, oldStyle);
@@ -68,25 +68,24 @@ void RenderSVGInlineText::styleDidChange(RenderStyle::Diff diff, const RenderSty
void RenderSVGInlineText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
{
- rects.append(computeAbsoluteRectForRange(0, textLength()));
+ rects.append(computeRepaintRectForRange(0, 0, textLength()));
}
void RenderSVGInlineText::absoluteQuads(Vector<FloatQuad>& quads, bool)
{
- quads.append(FloatRect(computeAbsoluteRectForRange(0, textLength())));
+ quads.append(FloatRect(computeRepaintRectForRange(0, 0, textLength())));
}
-IntRect RenderSVGInlineText::selectionRect(bool)
+IntRect RenderSVGInlineText::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool /*clipToVisibleContent*/)
{
ASSERT(!needsLayout());
- IntRect rect;
if (selectionState() == SelectionNone)
- return rect;
+ return IntRect();
// Early exit if we're ie. a <text> within a <defs> section.
if (isChildOfHiddenContainer(this))
- return rect;
+ return IntRect();
// Now calculate startPos and endPos for painting selection.
// We include a selection while endPos > 0
@@ -104,23 +103,22 @@ IntRect RenderSVGInlineText::selectionRect(bool)
}
if (startPos == endPos)
- return rect;
+ return IntRect();
- return computeAbsoluteRectForRange(startPos, endPos);
+ return computeRepaintRectForRange(repaintContainer, startPos, endPos);
}
-IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPos)
+IntRect RenderSVGInlineText::computeRepaintRectForRange(RenderBoxModelObject* /*repaintContainer*/, int startPos, int endPos)
{
- IntRect rect;
-
RenderBlock* cb = containingBlock();
if (!cb || !cb->container())
- return rect;
+ return IntRect();
RenderSVGRoot* root = findSVGRootObject(parent());
if (!root)
- return rect;
+ return IntRect();
+ IntRect rect;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
rect.unite(box->selectionRect(0, 0, startPos, endPos));
@@ -129,15 +127,15 @@ IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPo
// Remove HTML parent translation offsets here! These need to be retrieved from the RenderSVGRoot object.
// But do take the containingBlocks's container position into account, ie. SVG text in scrollable <div>.
- TransformationMatrix htmlParentCtm = root->RenderContainer::absoluteTransform();
+ TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform();
- FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + absPos.x() - (firstTextBox() ? firstTextBox()->xPos() : 0) - htmlParentCtm.e()),
- narrowPrecisionToFloat(rect.y() + absPos.y() - (firstTextBox() ? firstTextBox()->yPos() : 0) - htmlParentCtm.f()), rect.width(), rect.height());
- // FIXME: broken with CSS transforms
+ FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + absPos.x() - htmlParentCtm.e()),
+ narrowPrecisionToFloat(rect.y() + absPos.y() - htmlParentCtm.f()), rect.width(), rect.height());
+ // FIXME: broken with CSS transforms, and non-zero repaintContainer
return enclosingIntRect(absoluteTransform().mapRect(fixedRect));
}
-InlineTextBox* RenderSVGInlineText::createInlineTextBox()
+InlineTextBox* RenderSVGInlineText::createTextBox()
{
return new (renderArena()) SVGInlineTextBox(this);
}
@@ -149,35 +147,41 @@ IntRect RenderSVGInlineText::localCaretRect(InlineBox*, int, int*)
return IntRect();
}
-VisiblePosition RenderSVGInlineText::positionForCoordinates(int x, int y)
+VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
{
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(firstTextBox());
if (!textBox || textLength() == 0)
- return VisiblePosition(element(), 0, DOWNSTREAM);
+ return createVisiblePosition(0, DOWNSTREAM);
SVGRootInlineBox* rootBox = textBox->svgRootInlineBox();
RenderBlock* object = rootBox ? rootBox->block() : 0;
if (!object)
- return VisiblePosition(element(), 0, DOWNSTREAM);
+ return createVisiblePosition(0, DOWNSTREAM);
- int offset = 0;
+ int closestOffsetInBox = 0;
+ // FIXME: This approach is wrong. The correct code would first find the
+ // closest SVGInlineTextBox to the point, and *then* ask only that inline box
+ // what the closest text offset to that point is. This code instead walks
+ // through all boxes in order, so when you click "near" a box, you'll actually
+ // end up returning the nearest offset in the last box, even if the
+ // nearest offset to your click is contained in another box.
for (SVGInlineTextBox* box = textBox; box; box = static_cast<SVGInlineTextBox*>(box->nextTextBox())) {
- if (box->svgCharacterHitsPosition(x + object->x(), y + object->y(), offset)) {
+ if (box->svgCharacterHitsPosition(point.x() + object->x(), point.y() + object->y(), closestOffsetInBox)) {
// If we're not at the end/start of the box, stop looking for other selected boxes.
if (box->direction() == LTR) {
- if (offset <= (int) box->end() + 1)
+ if (closestOffsetInBox <= (int) box->end() + 1)
break;
} else {
- if (offset > (int) box->start())
+ if (closestOffsetInBox > (int) box->start())
break;
}
}
}
- return VisiblePosition(element(), offset, DOWNSTREAM);
+ return createVisiblePosition(closestOffsetInBox, DOWNSTREAM);
}
void RenderSVGInlineText::destroy()
diff --git a/WebCore/rendering/RenderSVGInlineText.h b/WebCore/rendering/RenderSVGInlineText.h
index 55fd838..e7f776a 100644
--- a/WebCore/rendering/RenderSVGInlineText.h
+++ b/WebCore/rendering/RenderSVGInlineText.h
@@ -35,23 +35,23 @@ public:
RenderSVGInlineText(Node*, PassRefPtr<StringImpl>);
virtual const char* renderName() const { return "RenderSVGInlineText"; }
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle*);
+ virtual void styleDidChange(StyleDifference, const RenderStyle*);
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
virtual bool requiresLayer() const { return false; }
- virtual IntRect selectionRect(bool clipToVisibleContent = true);
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
virtual bool isSVGText() const { return true; }
- virtual InlineTextBox* createInlineTextBox();
virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
- virtual VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
virtual void destroy();
private:
- IntRect computeAbsoluteRectForRange(int startPos, int endPos);
+ virtual InlineTextBox* createTextBox();
+ IntRect computeRepaintRectForRange(RenderBoxModelObject* repaintContainer, int startPos, int endPos);
};
}
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 54a30df..658b92d 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -27,24 +27,23 @@
#include "RenderSVGRoot.h"
#include "GraphicsContext.h"
-#include "RenderPath.h"
#include "RenderSVGContainer.h"
#include "RenderView.h"
#include "SVGLength.h"
#include "SVGRenderSupport.h"
-#include "SVGResourceClipper.h"
-#include "SVGResourceFilter.h"
-#include "SVGResourceMasker.h"
#include "SVGSVGElement.h"
#include "SVGStyledElement.h"
-#include "SVGURIReference.h"
+
+#if ENABLE(SVG_FILTERS)
+#include "SVGResourceFilter.h"
+#endif
using namespace std;
namespace WebCore {
RenderSVGRoot::RenderSVGRoot(SVGStyledElement* node)
- : RenderContainer(node)
+ : RenderBox(node)
{
setReplaced(true);
}
@@ -91,17 +90,14 @@ void RenderSVGRoot::layout()
// Arbitrary affine transforms are incompatible with LayoutState.
view()->disableLayoutState();
- IntRect oldBounds = m_absoluteBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout() && selfNeedsLayout();
- if (checkForRepaint)
- oldOutlineBox = absoluteOutlineBounds();
+ // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout(), &m_absoluteBounds);
calcWidth();
calcHeight();
m_absoluteBounds = absoluteClippedOverflowRect();
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
setWidth(static_cast<int>(width() * svg->currentScale()));
setHeight(static_cast<int>(height() * svg->currentScale()));
@@ -113,8 +109,7 @@ void RenderSVGRoot::layout()
ASSERT(!child->needsLayout());
}
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ repainter.repaintAfterLayout();
view()->enableLayoutState();
setNeedsLayout(false);
@@ -135,10 +130,10 @@ void RenderSVGRoot::applyContentTransforms(PaintInfo& paintInfo, int parentX, in
}
// Respect scroll offset caused by html parents
- TransformationMatrix ctm = RenderContainer::absoluteTransform();
+ TransformationMatrix ctm = RenderBox::absoluteTransform();
paintInfo.rect.move(static_cast<int>(ctm.e()), static_cast<int>(ctm.f()));
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
paintInfo.context->concatCTM(TransformationMatrix().scale(svg->currentScale()));
if (!viewport().isEmpty()) {
@@ -158,7 +153,6 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
calcViewport();
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
// A value of zero disables rendering of the element.
if (viewport().width() <= 0. || viewport().height() <= 0.)
return;
@@ -186,16 +180,17 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
FloatRect boundingBox = relativeBBox(true);
if (childPaintInfo.phase == PaintPhaseForeground)
- prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
+ prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
childPaintInfo.context->concatCTM(svg->viewBoxToViewTransform(width(), height()));
- RenderContainer::paint(childPaintInfo, 0, 0);
+ RenderBox::paint(childPaintInfo, 0, 0);
if (childPaintInfo.phase == PaintPhaseForeground)
finishRenderSVGContent(this, childPaintInfo, boundingBox, filter, paintInfo.context);
childPaintInfo.context->restore();
-
+
if ((childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
paintOutline(childPaintInfo.context, m_absoluteBounds.x(), m_absoluteBounds.y(), m_absoluteBounds.width(), m_absoluteBounds.height(), style());
}
@@ -207,31 +202,24 @@ FloatRect RenderSVGRoot::viewport() const
void RenderSVGRoot::calcViewport()
{
- SVGElement* svgelem = static_cast<SVGElement*>(element());
- if (svgelem->hasTagName(SVGNames::svgTag)) {
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
- if (!selfNeedsLayout() && !svg->hasRelativeValues())
- return;
-
- float w, h;
- SVGLength width = svg->width();
- if (width.unitType() == LengthTypePercentage && svg->hasSetContainerSize())
- w = svg->relativeWidthValue();
- else
- w = width.value(svg);
-
- SVGLength height = svg->height();
- if (height.unitType() == LengthTypePercentage && svg->hasSetContainerSize())
- h = svg->relativeHeightValue();
- else
- h = height.value(svg);
+ if (!selfNeedsLayout() && !svg->hasRelativeValues())
+ return;
- m_viewport = FloatRect(0, 0, w, h);
+ SVGLength width = svg->width();
+ SVGLength height = svg->height();
+ if (!svg->hasSetContainerSize()) {
+ m_viewport = FloatRect(0, 0, width.value(svg), height.value(svg));
+ return;
}
+ m_viewport = FloatRect(0, 0, (width.unitType() == LengthTypePercentage) ?
+ svg->relativeWidthValue() : width.value(svg),
+ (height.unitType() == LengthTypePercentage) ?
+ svg->relativeHeightValue() : height.value(svg));
}
-IntRect RenderSVGRoot::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderSVGRoot::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
IntRect repaintRect;
@@ -267,9 +255,9 @@ void RenderSVGRoot::absoluteQuads(Vector<FloatQuad>& quads, bool)
TransformationMatrix RenderSVGRoot::absoluteTransform() const
{
- TransformationMatrix ctm = RenderContainer::absoluteTransform();
+ TransformationMatrix ctm = RenderBox::absoluteTransform();
ctm.translate(x(), y());
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
ctm.scale(svg->currentScale());
ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
ctm.translate(viewport().x(), viewport().y());
@@ -300,7 +288,7 @@ TransformationMatrix RenderSVGRoot::localTransform() const
bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
{
- TransformationMatrix ctm = RenderContainer::absoluteTransform();
+ TransformationMatrix ctm = RenderBox::absoluteTransform();
int sx = (_tx - static_cast<int>(ctm.e())); // scroll offset
int sy = (_ty - static_cast<int>(ctm.f())); // scroll offset
@@ -316,7 +304,7 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
overflowBox.move(tx, ty);
ctm.translate(viewport().x(), viewport().y());
double localX, localY;
- ctm.inverse().map(_x - _tx, _y - _ty, &localX, &localY);
+ ctm.inverse().map(_x - _tx, _y - _ty, localX, localY);
if (!overflowBox.contains((int)localX, (int)localY))
return false;
}
@@ -333,13 +321,6 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
return false;
}
-void RenderSVGRoot::position(InlineBox* box)
-{
- RenderContainer::position(box);
- if (m_absoluteBounds.isEmpty())
- setNeedsLayout(true, false);
-}
-
}
#endif // ENABLE(SVG)
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index 048fc8b..3d0a141 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -24,7 +24,7 @@
#define RenderSVGRoot_h
#if ENABLE(SVG)
-#include "RenderContainer.h"
+#include "RenderBox.h"
#include "FloatRect.h"
namespace WebCore {
@@ -32,11 +32,16 @@ namespace WebCore {
class SVGStyledElement;
class TransformationMatrix;
-class RenderSVGRoot : public RenderContainer {
+class RenderSVGRoot : public RenderBox {
public:
RenderSVGRoot(SVGStyledElement*);
~RenderSVGRoot();
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
virtual bool isSVGRoot() const { return true; }
virtual const char* renderName() const { return "RenderSVGRoot"; }
@@ -47,7 +52,7 @@ public:
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void absoluteRects(Vector<IntRect>& rects, int tx, int ty);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
@@ -63,13 +68,12 @@ public:
FloatRect viewport() const;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
-
- virtual void position(InlineBox*);
private:
void calcViewport();
void applyContentTransforms(PaintInfo&, int parentX, int parentY);
+ RenderObjectChildList m_children;
FloatRect m_viewport;
IntRect m_absoluteBounds;
};
diff --git a/WebCore/rendering/RenderSVGTSpan.cpp b/WebCore/rendering/RenderSVGTSpan.cpp
index 49c45df..d493c45 100644
--- a/WebCore/rendering/RenderSVGTSpan.cpp
+++ b/WebCore/rendering/RenderSVGTSpan.cpp
@@ -48,11 +48,11 @@ void RenderSVGTSpan::absoluteRects(Vector<IntRect>& rects, int, int, bool)
if (!object)
return;
- int xRef = object->x() + x();
- int yRef = object->y() + y();
+ int xRef = object->x();
+ int yRef = object->y();
for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
- FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
+ FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
// FIXME: broken with CSS transforms
rects.append(enclosingIntRect(absoluteTransform().mapRect(rect)));
}
@@ -68,11 +68,11 @@ void RenderSVGTSpan::absoluteQuads(Vector<FloatQuad>& quads, bool)
if (!object)
return;
- int xRef = object->x() + x();
- int yRef = object->y() + y();
+ int xRef = object->x();
+ int yRef = object->y();
for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
- FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
+ FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
// FIXME: broken with CSS transforms
quads.append(absoluteTransform().mapRect(rect));
}
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index ee5ab34..8fef1f3 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -49,7 +49,7 @@ RenderSVGText::RenderSVGText(SVGTextElement* node)
{
}
-IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBox* /*repaintContainer*/)
+IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/)
{
// FIXME: handle non-root repaintContainer
FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));
@@ -70,7 +70,7 @@ IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBox* /*repaintContain
bool RenderSVGText::calculateLocalTransform()
{
TransformationMatrix oldTransform = m_localTransform;
- m_localTransform = static_cast<SVGTextElement*>(element())->animatedLocalTransform();
+ m_localTransform = static_cast<SVGTextElement*>(node())->animatedLocalTransform();
return (oldTransform != m_localTransform);
}
@@ -81,16 +81,11 @@ void RenderSVGText::layout()
// FIXME: This is a hack to avoid the RenderBlock::layout() partial repainting code which is not (yet) SVG aware
setNeedsLayout(true);
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = m_absoluteBounds;
- oldOutlineBox = absoluteOutlineBounds();
- }
+ // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout(), &m_absoluteBounds);
// Best guess for a relative starting point
- SVGTextElement* text = static_cast<SVGTextElement*>(element());
+ SVGTextElement* text = static_cast<SVGTextElement*>(node());
int xOffset = (int)(text->x()->getFirst().value(text));
int yOffset = (int)(text->y()->getFirst().value(text));
setLocation(xOffset, yOffset);
@@ -101,27 +96,14 @@ void RenderSVGText::layout()
m_absoluteBounds = absoluteClippedOverflowRect();
- bool repainted = false;
- if (checkForRepaint)
- repainted = repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
-
+ repainter.repaintAfterLayout();
+
setNeedsLayout(false);
}
-InlineBox* RenderSVGText::createInlineBox(bool, bool, bool)
+RootInlineBox* RenderSVGText::createRootBox()
{
- ASSERT(!isRenderInline());
- InlineFlowBox* flowBox = new (renderArena()) SVGRootInlineBox(this);
-
- if (!m_firstLineBox)
- m_firstLineBox = m_lastLineBox = flowBox;
- else {
- m_lastLineBox->setNextLineBox(flowBox);
- flowBox->setPreviousLineBox(m_lastLineBox);
- m_lastLineBox = flowBox;
- }
-
- return flowBox;
+ return new (renderArena()) SVGRootInlineBox(this);
}
bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction)
@@ -133,7 +115,7 @@ bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
|| (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
TransformationMatrix totalTransform = absoluteTransform();
double localX, localY;
- totalTransform.inverse().map(_x, _y, &localX, &localY);
+ totalTransform.inverse().map(_x, _y, localX, localY);
FloatPoint hitPoint(_x, _y);
return RenderBlock::nodeAtPoint(request, result, (int)localX, (int)localY, _tx, _ty, hitTestAction);
}
@@ -150,7 +132,7 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
FloatPoint absPos = localToAbsolute();
- TransformationMatrix htmlParentCtm = root->RenderContainer::absoluteTransform();
+ TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform();
// Don't use relativeBBox here, as it's unites the selection rects. Makes it hard
// to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
@@ -159,7 +141,7 @@ void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool)
InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
- FloatRect boxRect(box->xPos(), box->yPos(), box->width(), box->height());
+ FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f()));
// FIXME: broken with CSS transforms
rects.append(enclosingIntRect(absoluteTransform().mapRect(boxRect)));
@@ -175,7 +157,7 @@ void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool)
FloatPoint absPos = localToAbsolute();
- TransformationMatrix htmlParentCtm = root->RenderContainer::absoluteTransform();
+ TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform();
// Don't use relativeBBox here, as it's unites the selection rects. Makes it hard
// to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.
@@ -184,7 +166,7 @@ void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool)
InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {
- FloatRect boxRect(box->xPos(), box->yPos(), box->width(), box->height());
+ FloatRect boxRect(box->x(), box->y(), box->width(), box->height());
boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f()));
// FIXME: broken with CSS transforms
quads.append(absoluteTransform().mapRect(boxRect));
@@ -208,7 +190,7 @@ FloatRect RenderSVGText::relativeBBox(bool includeStroke) const
InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);
for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())
- repaintRect.unite(FloatRect(box->xPos(), box->yPos(), box->width(), box->height()));
+ repaintRect.unite(FloatRect(box->x(), box->y(), box->width(), box->height()));
}
// SVG needs to include the strokeWidth(), not the textStrokeWidth().
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index 4592f4e..2cd71fa 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -53,12 +53,12 @@ public:
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual FloatRect relativeBBox(bool includeStroke = true) const;
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun = false);
-
private:
+ virtual RootInlineBox* createRootBox();
+
TransformationMatrix m_localTransform;
IntRect m_absoluteBounds;
};
diff --git a/WebCore/rendering/RenderSVGTextPath.cpp b/WebCore/rendering/RenderSVGTextPath.cpp
index 2d2894f..4ae29bf 100644
--- a/WebCore/rendering/RenderSVGTextPath.cpp
+++ b/WebCore/rendering/RenderSVGTextPath.cpp
@@ -45,7 +45,7 @@ RenderSVGTextPath::RenderSVGTextPath(Node* n)
Path RenderSVGTextPath::layoutPath() const
{
- SVGTextPathElement* textPathElement = static_cast<SVGTextPathElement*>(element());
+ SVGTextPathElement* textPathElement = static_cast<SVGTextPathElement*>(node());
String pathId = SVGURIReference::getTarget(textPathElement->href());
Element* targetElement = textPathElement->document()->getElementById(pathId);
if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
@@ -65,17 +65,17 @@ Path RenderSVGTextPath::layoutPath() const
float RenderSVGTextPath::startOffset() const
{
- return static_cast<SVGTextPathElement*>(element())->startOffset().valueAsPercentage();
+ return static_cast<SVGTextPathElement*>(node())->startOffset().valueAsPercentage();
}
bool RenderSVGTextPath::exactAlignment() const
{
- return static_cast<SVGTextPathElement*>(element())->spacing() == SVG_TEXTPATH_SPACINGTYPE_EXACT;
+ return static_cast<SVGTextPathElement*>(node())->spacing() == SVG_TEXTPATH_SPACINGTYPE_EXACT;
}
bool RenderSVGTextPath::stretchMethod() const
{
- return static_cast<SVGTextPathElement*>(element())->method() == SVG_TEXTPATH_METHODTYPE_STRETCH;
+ return static_cast<SVGTextPathElement*>(node())->method() == SVG_TEXTPATH_METHODTYPE_STRETCH;
}
void RenderSVGTextPath::absoluteRects(Vector<IntRect>& rects, int, int)
@@ -88,11 +88,11 @@ void RenderSVGTextPath::absoluteRects(Vector<IntRect>& rects, int, int)
if (!object)
return;
- int xRef = object->x() + x();
- int yRef = object->y() + y();
+ int xRef = object->x();
+ int yRef = object->y();
for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
- FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
+ FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
// FIXME: broken with CSS transforms
rects.append(enclosingIntRect(absoluteTransform().mapRect(rect)));
}
@@ -108,11 +108,11 @@ void RenderSVGTextPath::absoluteQuads(Vector<FloatQuad>& quads, bool)
if (!object)
return;
- int xRef = object->x() + x();
- int yRef = object->y() + y();
+ int xRef = object->x();
+ int yRef = object->y();
for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) {
- FloatRect rect(xRef + curr->xPos(), yRef + curr->yPos(), curr->width(), curr->height());
+ FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height());
// FIXME: broken with CSS transforms
quads.append(absoluteTransform().mapRect(rect));
}
diff --git a/WebCore/rendering/RenderSVGTransformableContainer.cpp b/WebCore/rendering/RenderSVGTransformableContainer.cpp
index 17d64f3..6d65b55 100644
--- a/WebCore/rendering/RenderSVGTransformableContainer.cpp
+++ b/WebCore/rendering/RenderSVGTransformableContainer.cpp
@@ -38,7 +38,7 @@ RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransf
bool RenderSVGTransformableContainer::calculateLocalTransform()
{
TransformationMatrix oldTransform = m_localTransform;
- m_localTransform = static_cast<SVGStyledTransformableElement*>(element())->animatedLocalTransform();
+ m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
return (m_localTransform != oldTransform);
}
diff --git a/WebCore/rendering/RenderSVGViewportContainer.cpp b/WebCore/rendering/RenderSVGViewportContainer.cpp
index 4282efc..7885c4c 100644
--- a/WebCore/rendering/RenderSVGViewportContainer.cpp
+++ b/WebCore/rendering/RenderSVGViewportContainer.cpp
@@ -52,12 +52,9 @@ void RenderSVGViewportContainer::layout()
// Arbitrary affine transforms are incompatible with LayoutState.
view()->disableLayoutState();
- IntRect oldBounds = m_absoluteBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout() && selfNeedsLayout();
- if (checkForRepaint)
- oldOutlineBox = absoluteOutlineBounds();
-
+ // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout(), &m_absoluteBounds);
+
calcBounds();
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
@@ -68,8 +65,7 @@ void RenderSVGViewportContainer::layout()
ASSERT(!child->needsLayout());
}
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ repainter.repaintAfterLayout();
view()->enableLayoutState();
setNeedsLayout(false);
@@ -109,9 +105,9 @@ FloatRect RenderSVGViewportContainer::viewport() const
void RenderSVGViewportContainer::calcViewport()
{
- SVGElement* svgelem = static_cast<SVGElement*>(element());
+ SVGElement* svgelem = static_cast<SVGElement*>(node());
if (svgelem->hasTagName(SVGNames::svgTag)) {
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
if (!selfNeedsLayout() && !svg->hasRelativeValues())
return;
@@ -125,7 +121,7 @@ void RenderSVGViewportContainer::calcViewport()
if (!selfNeedsLayout())
return;
- SVGMarkerElement* svg = static_cast<SVGMarkerElement*>(element());
+ SVGMarkerElement* svg = static_cast<SVGMarkerElement*>(node());
float w = svg->markerWidth().value(svg);
float h = svg->markerHeight().value(svg);
m_viewport = FloatRect(0, 0, w, h);
@@ -134,11 +130,11 @@ void RenderSVGViewportContainer::calcViewport()
TransformationMatrix RenderSVGViewportContainer::viewportTransform() const
{
- if (element()->hasTagName(SVGNames::svgTag)) {
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+ if (node()->hasTagName(SVGNames::svgTag)) {
+ SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
return svg->viewBoxToViewTransform(viewport().width(), viewport().height());
- } else if (element()->hasTagName(SVGNames::markerTag)) {
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(element());
+ } else if (node()->hasTagName(SVGNames::markerTag)) {
+ SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
return marker->viewBoxToViewTransform(viewport().width(), viewport().height());
}
@@ -163,7 +159,7 @@ bool RenderSVGViewportContainer::nodeAtPoint(const HitTestRequest& request, HitT
TransformationMatrix ctm = RenderObject::absoluteTransform();
ctm.translate(viewport().x(), viewport().y());
double localX, localY;
- ctm.inverse().map(_x - _tx, _y - _ty, &localX, &localY);
+ ctm.inverse().map(_x - _tx, _y - _ty, localX, localY);
if (!overflowBox.contains((int)localX, (int)localY))
return false;
}
@@ -173,7 +169,7 @@ bool RenderSVGViewportContainer::nodeAtPoint(const HitTestRequest& request, HitT
// Respect parent translation offset for non-outermost <svg> elements.
// Outermost <svg> element is handled by RenderSVGRoot.
- if (element()->hasTagName(SVGNames::svgTag)) {
+ if (node()->hasTagName(SVGNames::svgTag)) {
sx = _tx;
sy = _ty;
}
diff --git a/WebCore/rendering/RenderScrollbar.cpp b/WebCore/rendering/RenderScrollbar.cpp
index d6dd9cc..db24a06 100644
--- a/WebCore/rendering/RenderScrollbar.cpp
+++ b/WebCore/rendering/RenderScrollbar.cpp
@@ -117,7 +117,7 @@ ScrollbarPart RenderScrollbar::partForStyleResolve()
return s_styleResolvePart;
}
-PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, RenderStyle::PseudoId pseudoId)
+PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
{
s_styleResolvePart = partType;
s_styleResolveScrollbar = this;
@@ -158,23 +158,23 @@ void RenderScrollbar::updateScrollbarParts(bool destroy)
}
}
-static RenderStyle::PseudoId pseudoForScrollbarPart(ScrollbarPart part)
+static PseudoId pseudoForScrollbarPart(ScrollbarPart part)
{
switch (part) {
case BackButtonStartPart:
case ForwardButtonStartPart:
case BackButtonEndPart:
case ForwardButtonEndPart:
- return RenderStyle::SCROLLBAR_BUTTON;
+ return SCROLLBAR_BUTTON;
case BackTrackPart:
case ForwardTrackPart:
- return RenderStyle::SCROLLBAR_TRACK_PIECE;
+ return SCROLLBAR_TRACK_PIECE;
case ThumbPart:
- return RenderStyle::SCROLLBAR_THUMB;
+ return SCROLLBAR_THUMB;
case TrackBGPart:
- return RenderStyle::SCROLLBAR_TRACK;
+ return SCROLLBAR_TRACK;
default:
- return RenderStyle::SCROLLBAR;
+ return SCROLLBAR;
}
}
diff --git a/WebCore/rendering/RenderScrollbar.h b/WebCore/rendering/RenderScrollbar.h
index cc43a00..524c4e8 100644
--- a/WebCore/rendering/RenderScrollbar.h
+++ b/WebCore/rendering/RenderScrollbar.h
@@ -26,13 +26,14 @@
#ifndef RenderScrollbar_h
#define RenderScrollbar_h
+#include "RenderStyleConstants.h"
#include "Scrollbar.h"
-#include "RenderStyle.h"
#include <wtf/HashMap.h>
namespace WebCore {
class RenderBox;
+class RenderStyle;
class RenderScrollbarPart;
class RenderStyle;
@@ -71,7 +72,7 @@ public:
int minimumThumbLength();
private:
- PassRefPtr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, RenderStyle::PseudoId);
+ PassRefPtr<RenderStyle> getScrollbarPseudoStyle(ScrollbarPart, PseudoId);
void updateScrollbarPart(ScrollbarPart, bool destroy = false);
RenderBox* m_owner;
diff --git a/WebCore/rendering/RenderScrollbarPart.cpp b/WebCore/rendering/RenderScrollbarPart.cpp
index 6749d8c..0f29aeb 100644
--- a/WebCore/rendering/RenderScrollbarPart.cpp
+++ b/WebCore/rendering/RenderScrollbarPart.cpp
@@ -122,20 +122,20 @@ void RenderScrollbarPart::calcPrefWidths()
setPrefWidthsDirty(false);
}
-void RenderScrollbarPart::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
RenderBlock::styleWillChange(diff, newStyle);
setInline(false);
}
-void RenderScrollbarPart::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
setInline(false);
setPositioned(false);
setFloating(false);
setHasOverflowClip(false);
- if (oldStyle && m_scrollbar && m_part != NoPart && diff >= RenderStyle::Repaint)
+ if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
}
diff --git a/WebCore/rendering/RenderScrollbarPart.h b/WebCore/rendering/RenderScrollbarPart.h
index 7dae6e7..114bbff 100644
--- a/WebCore/rendering/RenderScrollbarPart.h
+++ b/WebCore/rendering/RenderScrollbarPart.h
@@ -48,8 +48,8 @@ public:
void paintIntoRect(GraphicsContext*, int tx, int ty, const IntRect&);
protected:
- virtual void styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference diff, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
private:
diff --git a/WebCore/rendering/RenderSelectionInfo.h b/WebCore/rendering/RenderSelectionInfo.h
new file mode 100644
index 0000000..e7b7b78
--- /dev/null
+++ b/WebCore/rendering/RenderSelectionInfo.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * (C) 2000 Antti Koivisto (koivisto@kde.org)
+ * (C) 2000 Dirk Mueller (mueller@kde.org)
+ * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SelectionInfo_h
+#define SelectionInfo_h
+
+#include "IntRect.h"
+#include "RenderBox.h"
+
+namespace WebCore {
+
+class RenderSelectionInfoBase {
+public:
+ RenderSelectionInfoBase()
+ : m_object(0)
+ , m_repaintContainer(0)
+ , m_state(RenderObject::SelectionNone)
+ {
+ }
+
+ RenderSelectionInfoBase(RenderObject* o)
+ : m_object(o)
+ , m_repaintContainer(o->containerForRepaint())
+ , m_state(o->selectionState())
+ {
+ }
+
+ RenderObject* object() const { return m_object; }
+ RenderBoxModelObject* repaintContainer() const { return m_repaintContainer; }
+ RenderObject::SelectionState state() const { return m_state; }
+
+protected:
+ RenderObject* m_object;
+ RenderBoxModelObject* m_repaintContainer;
+ RenderObject::SelectionState m_state;
+};
+
+// This struct is used when the selection changes to cache the old and new state of the selection for each RenderObject.
+class RenderSelectionInfo : public RenderSelectionInfoBase {
+public:
+ RenderSelectionInfo(RenderObject* o, bool clipToVisibleContent)
+ : RenderSelectionInfoBase(o)
+ , m_rect(o->needsLayout() ? IntRect() : o->selectionRectForRepaint(m_repaintContainer, clipToVisibleContent))
+ {
+ }
+
+ void repaint()
+ {
+ m_object->repaintUsingContainer(m_repaintContainer, m_rect);
+ }
+
+ IntRect rect() const { return m_rect; }
+
+private:
+ IntRect m_rect; // relative to repaint container
+};
+
+
+// This struct is used when the selection changes to cache the old and new state of the selection for each RenderBlock.
+class RenderBlockSelectionInfo : public RenderSelectionInfoBase {
+public:
+ RenderBlockSelectionInfo(RenderBlock* b)
+ : RenderSelectionInfoBase(b)
+ , m_rects(b->needsLayout() ? GapRects() : block()->selectionGapRectsForRepaint(m_repaintContainer))
+ {
+ }
+
+ void repaint()
+ {
+ m_object->repaintUsingContainer(m_repaintContainer, m_rects);
+ }
+
+ RenderBlock* block() const { return toRenderBlock(m_object); }
+ GapRects rects() const { return m_rects; }
+
+private:
+ GapRects m_rects; // relative to repaint container
+};
+
+} // namespace WebCore
+
+
+#endif // SelectionInfo_h
diff --git a/WebCore/rendering/RenderSlider.cpp b/WebCore/rendering/RenderSlider.cpp
index 25f3e40..08ebadf 100644
--- a/WebCore/rendering/RenderSlider.cpp
+++ b/WebCore/rendering/RenderSlider.cpp
@@ -1,6 +1,5 @@
-/**
- *
- * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc.
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,7 +32,9 @@
#include "HTMLNames.h"
#include "MediaControlElements.h"
#include "MouseEvent.h"
+#include "RenderLayer.h"
#include "RenderTheme.h"
+#include "RenderView.h"
#include <wtf/MathExtras.h>
#ifdef ANDROID_LAYOUT
@@ -46,44 +47,115 @@ namespace WebCore {
using namespace HTMLNames;
-const int defaultTrackLength = 129;
+static const int defaultTrackLength = 129;
+
+// FIXME: The SliderRange class and functions are entirely based on the DOM,
+// and could be put with HTMLInputElement (possibly with a new name) instead of here.
+struct SliderRange {
+ bool isIntegral;
+ double minimum;
+ double maximum;
+
+ explicit SliderRange(HTMLInputElement*);
+ double clampValue(double value);
+
+ // Map value into 0-1 range
+ double proportionFromValue(double value)
+ {
+ if (minimum == maximum)
+ return 0;
+
+ return (value - minimum) / (maximum - minimum);
+ }
+
+ // Map from 0-1 range to value
+ double valueFromProportion(double proportion)
+ {
+ return minimum + proportion * (maximum - minimum);
+ }
+
+ double valueFromElement(HTMLInputElement*, bool* wasClamped = 0);
+};
+
+SliderRange::SliderRange(HTMLInputElement* element)
+{
+ // FIXME: What's the right way to handle an integral range with non-integral minimum and maximum?
+ // Currently values are guaranteed to be integral but could be outside the range in that case.
+
+ isIntegral = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
-class HTMLSliderThumbElement : public HTMLDivElement {
+ // FIXME: This treats maximum strings that can't be parsed as 0, but perhaps 100 would be more appropriate.
+ const AtomicString& maxString = element->getAttribute(maxAttr);
+ maximum = maxString.isNull() ? 100.0 : maxString.toDouble();
+
+ // If the maximum is smaller, use it as the minimum.
+ minimum = min(element->getAttribute(minAttr).toDouble(), maximum);
+}
+
+double SliderRange::clampValue(double value)
+{
+ double clampedValue = max(minimum, min(value, maximum));
+ return isIntegral ? round(clampedValue) : clampedValue;
+}
+
+double SliderRange::valueFromElement(HTMLInputElement* element, bool* wasClamped)
+{
+ String valueString = element->value();
+ double oldValue = valueString.isNull() ? (minimum + maximum) / 2 : valueString.toDouble();
+ double newValue = clampValue(oldValue);
+
+ if (wasClamped)
+ *wasClamped = valueString.isNull() || newValue != oldValue;
+
+ return newValue;
+}
+
+// Returns a value between 0 and 1.
+// As with SliderRange, this could be on HTMLInputElement instead of here.
+static double sliderPosition(HTMLInputElement* element)
+{
+ SliderRange range(element);
+ return range.proportionFromValue(range.valueFromElement(element));
+}
+
+class SliderThumbElement : public HTMLDivElement {
public:
- HTMLSliderThumbElement(Document*, Node* shadowParent = 0);
-
+ SliderThumbElement(Document*, Node* shadowParent);
+
+ bool inDragMode() const { return m_inDragMode; }
+
virtual void defaultEventHandler(Event*);
+
+private:
virtual bool isShadowNode() const { return true; }
virtual Node* shadowParentNode() { return m_shadowParent; }
-
- bool inDragMode() const { return m_inDragMode; }
-private:
+
Node* m_shadowParent;
FloatPoint m_initialClickPoint; // initial click point in RenderSlider-local coordinates
int m_initialPosition;
bool m_inDragMode;
};
-HTMLSliderThumbElement::HTMLSliderThumbElement(Document* doc, Node* shadowParent)
- : HTMLDivElement(divTag, doc)
+SliderThumbElement::SliderThumbElement(Document* document, Node* shadowParent)
+ : HTMLDivElement(divTag, document)
, m_shadowParent(shadowParent)
- , m_initialClickPoint(IntPoint())
, m_initialPosition(0)
, m_inDragMode(false)
{
}
-void HTMLSliderThumbElement::defaultEventHandler(Event* event)
+void SliderThumbElement::defaultEventHandler(Event* event)
{
const AtomicString& eventType = event->type();
if (eventType == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
RenderSlider* slider;
- if (document()->frame() && renderer() && renderer()->parent() &&
+ if (document()->frame() && renderer() &&
(slider = static_cast<RenderSlider*>(renderer()->parent())) &&
slider->mouseEventIsInThumb(mouseEvent)) {
+
// Cache the initial point where the mouse down occurred, in slider coordinates
- m_initialClickPoint = slider->absoluteToLocal(FloatPoint(mouseEvent->pageX(), mouseEvent->pageY()), false, true);
+ m_initialClickPoint = slider->absoluteToLocal(mouseEvent->absoluteLocation(), false, true);
// Cache the initial position of the thumb.
m_initialPosition = slider->currentPosition();
m_inDragMode = true;
@@ -106,16 +178,11 @@ void HTMLSliderThumbElement::defaultEventHandler(Event* event)
// Move the slider
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
RenderSlider* slider = static_cast<RenderSlider*>(renderer()->parent());
- FloatPoint curPoint = slider->absoluteToLocal(FloatPoint(mouseEvent->pageX(), mouseEvent->pageY()), false, true);
- int newPosition = slider->positionForOffset(
- IntPoint(m_initialPosition + curPoint.x() - m_initialClickPoint.x()
- + (renderBox()->width() / 2),
- m_initialPosition + curPoint.y() - m_initialClickPoint.y()
- + (renderBox()->height() / 2)));
- if (slider->currentPosition() != newPosition) {
- slider->setCurrentPosition(newPosition);
- slider->valueChanged();
- }
+
+ FloatPoint curPoint = slider->absoluteToLocal(mouseEvent->absoluteLocation(), false, true);
+ IntPoint eventOffset(m_initialPosition + curPoint.x() - m_initialClickPoint.x() + renderBox()->width() / 2,
+ m_initialPosition + curPoint.y() - m_initialClickPoint.y() + renderBox()->height() / 2);
+ slider->setValueForPosition(slider->positionForOffset(eventOffset));
event->setDefaultHandled();
return;
}
@@ -126,7 +193,6 @@ void HTMLSliderThumbElement::defaultEventHandler(Event* event)
RenderSlider::RenderSlider(HTMLInputElement* element)
: RenderBlock(element)
- , m_thumb(0)
{
}
@@ -171,20 +237,20 @@ void RenderSlider::calcPrefWidths()
setPrefWidthsDirty(false);
}
-void RenderSlider::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderSlider::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
-
+
if (m_thumb)
- m_thumb->renderer()->setStyle(createThumbStyle(style(), m_thumb->renderer()->style()));
-
+ m_thumb->renderer()->setStyle(createThumbStyle(style()));
+
setReplaced(isInline());
}
-PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parentStyle, const RenderStyle* oldStyle)
+PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parentStyle)
{
RefPtr<RenderStyle> style;
- RenderStyle* pseudoStyle = getCachedPseudoStyle(RenderStyle::SLIDER_THUMB);
+ RenderStyle* pseudoStyle = getCachedPseudoStyle(SLIDER_THUMB);
if (pseudoStyle)
// We may be sharing style with another slider, but we must not share the thumb style.
style = RenderStyle::clone(pseudoStyle);
@@ -195,16 +261,11 @@ PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parent
style->inheritFrom(parentStyle);
style->setDisplay(BLOCK);
- style->setPosition(RelativePosition);
- if (oldStyle) {
- style->setLeft(oldStyle->left());
- style->setTop(oldStyle->top());
- }
if (parentStyle->appearance() == SliderVerticalPart)
- style->setAppearance(SliderThumbVerticalPart);
+ style->setAppearance(SliderThumbVerticalPart);
else if (parentStyle->appearance() == SliderHorizontalPart)
- style->setAppearance(SliderThumbHorizontalPart);
+ style->setAppearance(SliderThumbHorizontalPart);
else if (parentStyle->appearance() == MediaSliderPart)
style->setAppearance(MediaSliderThumbPart);
@@ -212,54 +273,97 @@ PassRefPtr<RenderStyle> RenderSlider::createThumbStyle(const RenderStyle* parent
}
void RenderSlider::layout()
-{
- bool relayoutChildren = false;
-
- if (m_thumb && m_thumb->renderer()) {
-
-#ifdef ANDROID_LAYOUT
- int oldVisibleWidth = m_visibleWidth;
-#endif
-
- int oldWidth = width();
- calcWidth();
- int oldHeight = height();
- calcHeight();
-
- if (oldWidth != width() || oldHeight != height())
- relayoutChildren = true;
+{
+ ASSERT(needsLayout());
-#ifdef ANDROID_LAYOUT
- const Settings* settings = document()->settings();
- ASSERT(settings);
- if (oldVisibleWidth != m_visibleWidth
- && settings->layoutAlgorithm() == Settings::kLayoutFitColumnToScreen)
- relayoutChildren = true;
-#endif
-
- // Allow the theme to set the size of the thumb
- if (m_thumb->renderer()->style()->hasAppearance())
- theme()->adjustSliderThumbSize(m_thumb->renderer());
+ RenderBox* thumb = m_thumb ? toRenderBox(m_thumb->renderer()) : 0;
+
+ IntSize baseSize(borderLeft() + paddingLeft() + paddingRight() + borderRight(),
+ borderTop() + paddingTop() + paddingBottom() + borderBottom());
+
+ if (thumb) {
+ // Allow the theme to set the size of the thumb.
+ if (thumb->style()->hasAppearance()) {
+ // FIXME: This should pass the style, not the renderer, to the theme.
+ theme()->adjustSliderThumbSize(thumb);
+ }
+
+ baseSize.expand(thumb->style()->width().calcMinValue(0), thumb->style()->height().calcMinValue(0));
+ }
+
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+
+ IntSize oldSize = size();
+
+ setSize(baseSize);
+ calcWidth();
+ calcHeight();
+
+ IntRect overflowRect(IntPoint(), size());
+ if (thumb) {
+ if (oldSize != size())
+ thumb->setChildNeedsLayout(true, false);
+
+ LayoutStateMaintainer statePusher(view(), this, size());
+
+ IntRect oldThumbRect = thumb->frameRect();
+
+ thumb->layoutIfNeeded();
+
+ IntRect thumbRect;
+
+ thumbRect.setWidth(thumb->style()->width().calcMinValue(contentWidth()));
+ thumbRect.setHeight(thumb->style()->height().calcMinValue(contentHeight()));
+
+ double fraction = sliderPosition(static_cast<HTMLInputElement*>(node()));
+ IntRect contentRect = contentBoxRect();
if (style()->appearance() == SliderVerticalPart) {
- // FIXME: Handle percentage widths correctly. See http://bugs.webkit.org/show_bug.cgi?id=12104
- m_thumb->renderer()->style()->setLeft(Length(contentWidth() / 2 - m_thumb->renderer()->style()->width().value() / 2, Fixed));
+ thumbRect.setX(contentRect.x() + (contentRect.width() - thumbRect.width()) / 2);
+ thumbRect.setY(contentRect.y() + static_cast<int>(nextafter((contentRect.height() - thumbRect.height()) + 1, 0) * (1 - fraction)));
} else {
- // FIXME: Handle percentage heights correctly. See http://bugs.webkit.org/show_bug.cgi?id=12104
- m_thumb->renderer()->style()->setTop(Length(contentHeight() / 2 - m_thumb->renderer()->style()->height().value() / 2, Fixed));
+ thumbRect.setX(contentRect.x() + static_cast<int>(nextafter((contentRect.width() - thumbRect.width()) + 1, 0) * fraction));
+ thumbRect.setY(contentRect.y() + (contentRect.height() - thumbRect.height()) / 2);
}
- if (relayoutChildren)
- setPositionFromValue(true);
+ thumb->setFrameRect(thumbRect);
+
+ if (thumb->checkForRepaintDuringLayout())
+ thumb->repaintDuringLayoutIfMoved(oldThumbRect);
+
+ statePusher.pop();
+
+ IntRect thumbOverflowRect = thumb->overflowRect();
+ thumbOverflowRect.move(thumb->x(), thumb->y());
+ overflowRect.unite(thumbOverflowRect);
}
- RenderBlock::layoutBlock(relayoutChildren);
+ // FIXME: m_overflowWidth and m_overflowHeight should be renamed
+ // m_overflowRight and m_overflowBottom.
+ m_overflowLeft = overflowRect.x();
+ m_overflowTop = overflowRect.y();
+ m_overflowWidth = overflowRect.right();
+ m_overflowHeight = overflowRect.bottom();
+
+ repainter.repaintAfterLayout();
+
+ setNeedsLayout(false);
}
void RenderSlider::updateFromElement()
{
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
+
+ // Send the value back to the element if the range changes it.
+ SliderRange range(element);
+ bool clamped;
+ double value = range.valueFromElement(element, &clamped);
+ if (clamped)
+ element->setValueFromRenderer(String::number(value));
+
+ // Layout will take care of the thumb's size and position.
if (!m_thumb) {
- m_thumb = new HTMLSliderThumbElement(document(), node());
+ m_thumb = new SliderThumbElement(document(), node());
RefPtr<RenderStyle> thumbStyle = createThumbStyle(style());
m_thumb->setRenderer(m_thumb->createRenderer(renderArena(), thumbStyle.get()));
m_thumb->renderer()->setStyle(thumbStyle.release());
@@ -267,8 +371,7 @@ void RenderSlider::updateFromElement()
m_thumb->setInDocument(true);
addChild(m_thumb->renderer());
}
- setPositionFromValue();
- setNeedsLayout(true, false);
+ setNeedsLayout(true);
}
bool RenderSlider::mouseEventIsInThumb(MouseEvent* evt)
@@ -279,92 +382,45 @@ bool RenderSlider::mouseEventIsInThumb(MouseEvent* evt)
#if ENABLE(VIDEO)
if (style()->appearance() == MediaSliderPart) {
MediaControlInputElement *sliderThumb = static_cast<MediaControlInputElement*>(m_thumb->renderer()->node());
- IntPoint absPoint(evt->pageX(), evt->pageY());
- return sliderThumb->hitTest(absPoint);
- } else
-#endif
- {
- FloatPoint localPoint = m_thumb->renderBox()->absoluteToLocal(FloatPoint(evt->pageX(), evt->pageY()), false, true);
- IntRect thumbBounds = m_thumb->renderBox()->borderBoxRect();
- return thumbBounds.contains(roundedIntPoint(localPoint));
+ return sliderThumb->hitTest(evt->absoluteLocation());
}
+#endif
+
+ FloatPoint localPoint = m_thumb->renderBox()->absoluteToLocal(evt->absoluteLocation(), false, true);
+ IntRect thumbBounds = m_thumb->renderBox()->borderBoxRect();
+ return thumbBounds.contains(roundedIntPoint(localPoint));
}
void RenderSlider::setValueForPosition(int position)
{
if (!m_thumb || !m_thumb->renderer())
return;
-
- const AtomicString& minStr = static_cast<HTMLInputElement*>(node())->getAttribute(minAttr);
- const AtomicString& maxStr = static_cast<HTMLInputElement*>(node())->getAttribute(maxAttr);
- const AtomicString& precision = static_cast<HTMLInputElement*>(node())->getAttribute(precisionAttr);
-
- double minVal = minStr.isNull() ? 0.0 : minStr.toDouble();
- double maxVal = maxStr.isNull() ? 100.0 : maxStr.toDouble();
- minVal = min(minVal, maxVal); // Make sure the range is sane.
-
- // Calculate the new value based on the position
- double factor = (double)position / (double)trackSize();
- if (style()->appearance() == SliderVerticalPart)
- factor = 1.0 - factor;
- double val = minVal + factor * (maxVal - minVal);
-
- val = max(minVal, min(val, maxVal)); // Make sure val is within min/max.
- // Force integer value if not float.
- if (!equalIgnoringCase(precision, "float"))
- val = lround(val);
+ HTMLInputElement* element = static_cast<HTMLInputElement*>(node());
- static_cast<HTMLInputElement*>(node())->setValueFromRenderer(String::number(val));
-
- if (position != currentPosition()) {
- setCurrentPosition(position);
- static_cast<HTMLInputElement*>(node())->onChange();
- }
-}
-
-double RenderSlider::setPositionFromValue(bool inLayout)
-{
- if (!m_thumb || !m_thumb->renderer())
- return 0;
-
- if (!inLayout)
- document()->updateLayout();
-
- String value = static_cast<HTMLInputElement*>(node())->value();
- const AtomicString& minStr = static_cast<HTMLInputElement*>(node())->getAttribute(minAttr);
- const AtomicString& maxStr = static_cast<HTMLInputElement*>(node())->getAttribute(maxAttr);
- const AtomicString& precision = static_cast<HTMLInputElement*>(node())->getAttribute(precisionAttr);
-
- double minVal = minStr.isNull() ? 0.0 : minStr.toDouble();
- double maxVal = maxStr.isNull() ? 100.0 : maxStr.toDouble();
- minVal = min(minVal, maxVal); // Make sure the range is sane.
-
- double oldVal = value.isNull() ? (maxVal + minVal)/2.0 : value.toDouble();
- double val = max(minVal, min(oldVal, maxVal)); // Make sure val is within min/max.
-
- // Force integer value if not float.
- if (!equalIgnoringCase(precision, "float"))
- val = lround(val);
-
- // Calculate the new position based on the value
- double factor = (val - minVal) / (maxVal - minVal);
+ // Calculate the new value based on the position, and send it to the element.
+ SliderRange range(element);
+ double fraction = static_cast<double>(position) / trackSize();
if (style()->appearance() == SliderVerticalPart)
- factor = 1.0 - factor;
+ fraction = 1 - fraction;
+ double value = range.clampValue(range.valueFromProportion(fraction));
+ element->setValueFromRenderer(String::number(value));
- setCurrentPosition((int)(factor * trackSize()));
-
- if (value.isNull() || val != oldVal)
- static_cast<HTMLInputElement*>(node())->setValueFromRenderer(String::number(val));
-
- return val;
+ // Also update the position if appropriate.
+ if (position != currentPosition()) {
+ setNeedsLayout(true);
+
+ // FIXME: It seems like this could send extra change events if the same value is set
+ // multiple times with no layout in between.
+ element->onChange();
+ }
}
int RenderSlider::positionForOffset(const IntPoint& p)
{
if (!m_thumb || !m_thumb->renderer())
return 0;
-
+
int position;
if (style()->appearance() == SliderVerticalPart)
position = p.y() - m_thumb->renderBox()->height() / 2;
@@ -374,55 +430,44 @@ int RenderSlider::positionForOffset(const IntPoint& p)
return max(0, min(position, trackSize()));
}
-void RenderSlider::valueChanged()
-{
- setValueForPosition(currentPosition());
- static_cast<HTMLInputElement*>(node())->onChange();
-}
-
int RenderSlider::currentPosition()
{
- if (!m_thumb || !m_thumb->renderer())
- return 0;
-
- if (style()->appearance() == SliderVerticalPart)
- return m_thumb->renderer()->style()->top().value();
- return m_thumb->renderer()->style()->left().value();
-}
-
-void RenderSlider::setCurrentPosition(int pos)
-{
- if (!m_thumb || !m_thumb->renderer())
- return;
+ ASSERT(m_thumb);
+ ASSERT(m_thumb->renderer());
if (style()->appearance() == SliderVerticalPart)
- m_thumb->renderer()->style()->setTop(Length(pos, Fixed));
- else
- m_thumb->renderer()->style()->setLeft(Length(pos, Fixed));
-
- m_thumb->renderBox()->layer()->updateLayerPosition();
- repaint();
- m_thumb->renderer()->repaint();
+ return toRenderBox(m_thumb->renderer())->y() - contentBoxRect().y();
+ return toRenderBox(m_thumb->renderer())->x() - contentBoxRect().x();
}
int RenderSlider::trackSize()
{
- if (!m_thumb || !m_thumb->renderer())
- return 0;
+ ASSERT(m_thumb);
+ ASSERT(m_thumb->renderer());
if (style()->appearance() == SliderVerticalPart)
return contentHeight() - m_thumb->renderBox()->height();
return contentWidth() - m_thumb->renderBox()->width();
}
-void RenderSlider::forwardEvent(Event* evt)
+void RenderSlider::forwardEvent(Event* event)
{
- m_thumb->defaultEventHandler(evt);
+ if (event->isMouseEvent()) {
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ if (event->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {
+ if (!mouseEventIsInThumb(mouseEvent)) {
+ IntPoint eventOffset = roundedIntPoint(absoluteToLocal(mouseEvent->absoluteLocation(), false, true));
+ setValueForPosition(positionForOffset(eventOffset));
+ }
+ }
+ }
+
+ m_thumb->defaultEventHandler(event);
}
bool RenderSlider::inDragMode() const
{
- return m_thumb->inDragMode();
+ return m_thumb && m_thumb->inDragMode();
}
} // namespace WebCore
diff --git a/WebCore/rendering/RenderSlider.h b/WebCore/rendering/RenderSlider.h
index 95ceb0b..f1eab9c 100644
--- a/WebCore/rendering/RenderSlider.h
+++ b/WebCore/rendering/RenderSlider.h
@@ -1,6 +1,5 @@
-/**
- *
- * Copyright (C) 2006 Apple Computer, Inc.
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,16 +25,19 @@
namespace WebCore {
- class HTMLDivElement;
class HTMLInputElement;
- class HTMLSliderThumbElement;
class MouseEvent;
+ class SliderThumbElement;
class RenderSlider : public RenderBlock {
public:
RenderSlider(HTMLInputElement*);
- ~RenderSlider();
+ virtual ~RenderSlider();
+
+ void forwardEvent(Event*);
+ bool inDragMode() const;
+ private:
virtual const char* renderName() const { return "RenderSlider"; }
virtual bool isSlider() const { return true; }
@@ -43,30 +45,25 @@ namespace WebCore {
virtual void calcPrefWidths();
virtual void layout();
virtual void updateFromElement();
-
- virtual bool mouseEventIsInThumb(MouseEvent*);
+
+ bool mouseEventIsInThumb(MouseEvent*);
void setValueForPosition(int position);
- double setPositionFromValue(bool inLayout = false);
+ void setPositionFromValue();
int positionForOffset(const IntPoint&);
- void valueChanged();
-
int currentPosition();
- void setCurrentPosition(int pos);
-
- void forwardEvent(Event*);
- bool inDragMode() const;
- protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
-
- private:
- PassRefPtr<RenderStyle> createThumbStyle(const RenderStyle* parentStyle, const RenderStyle* oldStyle = 0);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+
+ PassRefPtr<RenderStyle> createThumbStyle(const RenderStyle* parentStyle);
+
int trackSize();
- RefPtr<HTMLSliderThumbElement> m_thumb;
-};
+ RefPtr<SliderThumbElement> m_thumb;
+
+ friend class SliderThumbElement;
+ };
} // namespace WebCore
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index 784a59a..f4b1033 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -55,8 +55,6 @@ RenderTable::RenderTable(Node* node)
, m_firstBody(0)
, m_tableLayout(0)
, m_currentBorder(0)
- , m_frame(Void)
- , m_rules(None)
, m_hasColElements(false)
, m_needsSectionRecalc(0)
, m_hSpacing(0)
@@ -76,7 +74,7 @@ RenderTable::~RenderTable()
delete m_tableLayout;
}
-void RenderTable::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
@@ -116,8 +114,8 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
if (!beforeChild && isAfterContent(lastChild()))
beforeChild = lastChild();
- bool wrapInAnonymousSection = true;
- bool isTableElement = element() && element()->hasTagName(tableTag);
+ bool wrapInAnonymousSection = !child->isPositioned();
+ bool isTableElement = node() && node()->hasTagName(tableTag);
if (child->isRenderBlock() && child->style()->display() == TABLE_CAPTION) {
// First caption wins.
@@ -129,7 +127,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
m_caption = 0;
}
if (!m_caption)
- m_caption = static_cast<RenderBlock*>(child);
+ m_caption = toRenderBlock(child);
wrapInAnonymousSection = false;
} else if (child->isTableCol()) {
m_hasColElements = true;
@@ -172,21 +170,16 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
}
} else if (child->isTableCell() || child->isTableRow()) {
wrapInAnonymousSection = true;
- } else {
+ } else
// Allow a form to just sit at the top level.
- wrapInAnonymousSection = !isTableElement || !child->element() || !(child->element()->hasTagName(formTag) && document()->isHTMLDocument());
-
- // FIXME: Allow the delete button container element to sit at the top level. This is needed until http://bugs.webkit.org/show_bug.cgi?id=11363 is fixed.
- if (wrapInAnonymousSection && child->element() && child->element()->isHTMLElement() && static_cast<HTMLElement*>(child->element())->id() == DeleteButtonController::containerElementIdentifier)
- wrapInAnonymousSection = false;
- }
+ wrapInAnonymousSection = !isTableElement || !child->node() || !(child->node()->hasTagName(formTag) && document()->isHTMLDocument());
if (!wrapInAnonymousSection) {
// If the next renderer is actually wrapped in an anonymous table section, we need to go up and find that.
while (beforeChild && !beforeChild->isTableSection() && !beforeChild->isTableCol() && beforeChild->style()->display() != TABLE_CAPTION)
beforeChild = beforeChild->parent();
- RenderContainer::addChild(child, beforeChild);
+ RenderBox::addChild(child, beforeChild);
return;
}
@@ -214,6 +207,12 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
section->addChild(child);
}
+void RenderTable::removeChild(RenderObject* oldChild)
+{
+ RenderBox::removeChild(oldChild);
+ setNeedsSectionRecalc();
+}
+
void RenderTable::calcWidth()
{
#ifdef ANDROID_LAYOUT
@@ -240,7 +239,7 @@ void RenderTable::calcWidth()
} else {
// An auto width table should shrink to fit within the line width if necessary in order to
// avoid overlapping floats.
- availableWidth = cb->lineWidth(y());
+ availableWidth = cb->lineWidth(y(), false);
// Subtract out any fixed margins from our available width for auto width tables.
int marginTotal = 0;
@@ -278,14 +277,7 @@ void RenderTable::layout()
recalcSectionsIfNeeded();
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
-
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
setHeight(0);
@@ -308,17 +300,29 @@ void RenderTable::layout()
else if (document()->settings()->layoutAlgorithm() == Settings::kLayoutSSR) {
// if the width of a table is wider than its container width, or it has a nested table,
// we will render it with single column.
- int cw = containingBlockWidth();
- if (width() > cw || hasChildTable()) {
+ int cw = containingBlockWidthForContent();
+ bool shouldRenderAsSingleColumn = (width() > cw);
+ if (!shouldRenderAsSingleColumn) {
+ RenderObject* child = firstChild();
+ while (child) {
+ if (child->isTable()) {
+ shouldRenderAsSingleColumn = true;
+ break;
+ }
+ child = child->nextInPreOrder();
+ }
+ }
+
+ if (shouldRenderAsSingleColumn) {
m_singleColumn = true;
if (width() > cw)
- setWidth(cw);
+ setWidth(cw);
if (m_minPrefWidth > cw)
- m_minPrefWidth = cw;
- if (m_maxPrefWidth > cw)
- m_maxPrefWidth = cw;
+ m_minPrefWidth = cw;
+ if (m_maxPrefWidth > cw)
+ m_maxPrefWidth = cw;
}
- }
+ }
#endif
if (m_caption && width() != oldWidth)
m_caption->setNeedsLayout(true, false);
@@ -339,18 +343,18 @@ void RenderTable::layout()
bool collapsing = collapseBorders();
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- // FIXME: What about a form that has a display value that makes it a table section?
#ifdef ANDROID_LAYOUT
- if ((relayoutChildren || child->needsLayout()) &&
- !(child->element() && child->element()->hasTagName(formTag))) {
- child->setNeedsLayout(true);
- child->layout();
+ if (relayoutChildren) {
+ child->setNeedsLayout(true, false);
+ if (!child->isTableSection()) {
+ child->layoutIfNeeded();
+ continue;
+ }
+ // fall through
}
-#else
- if (child->needsLayout() && !(child->element() && child->element()->hasTagName(formTag) && !child->isTableSection()))
- child->layout();
#endif
if (child->isTableSection()) {
+ child->layoutIfNeeded();
RenderTableSection* section = static_cast<RenderTableSection*>(child);
calculatedHeight += section->calcRowHeight();
if (collapsing)
@@ -359,6 +363,10 @@ void RenderTable::layout()
}
}
+ // Only lay out one caption, since it's the only one we're going to end up painting.
+ if (m_caption)
+ m_caption->layoutIfNeeded();
+
m_overflowWidth = width() + (collapsing ? outerBorderRight() - borderRight() : 0);
m_overflowLeft = collapsing ? borderLeft() - outerBorderLeft() : 0;
@@ -480,10 +488,8 @@ void RenderTable::layout()
statePusher.pop();
- bool didFullRepaint = true;
+ bool didFullRepaint = repainter.repaintAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
- if (checkForRepaint)
- didFullRepaint = repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
if (!didFullRepaint && sectionMoved)
repaintRectangle(IntRect(m_overflowLeft, movedSectionTop, m_overflowWidth - m_overflowLeft, m_overflowHeight - movedSectionTop));
@@ -511,6 +517,15 @@ void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty)
if (tx + overflowLeft(false) >= paintInfo.rect.right() + os || tx + overflowWidth(false) <= paintInfo.rect.x() - os)
return;
+ bool pushedClip = pushContentsClip(paintInfo, tx, ty);
+ paintObject(paintInfo, tx, ty);
+ if (pushedClip)
+ popContentsClip(paintInfo, paintPhase, tx, ty);
+}
+
+void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty)
+{
+ PaintPhase paintPhase = paintInfo.phase;
if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasBoxDecorations() && style()->visibility() == VISIBLE)
paintBoxDecorations(paintInfo, tx, ty);
@@ -522,19 +537,20 @@ void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty)
// We're done. We don't bother painting any children.
if (paintPhase == PaintPhaseBlockBackground)
return;
-
+
// We don't paint our own background, but we do let the kids paint their backgrounds.
if (paintPhase == PaintPhaseChildBlockBackgrounds)
paintPhase = PaintPhaseChildBlockBackground;
+
PaintInfo info(paintInfo);
info.phase = paintPhase;
info.paintingRoot = paintingRootForChildren(paintInfo);
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->hasLayer() && (child->isTableSection() || child == m_caption))
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption))
child->paint(info, tx, ty);
}
-
+
if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
// Collect all the unique border styles that we want to paint in a sorted list. Once we
// have all the styles sorted, we then do individual passes, painting each style of border
@@ -717,7 +733,7 @@ void RenderTable::recalcSections() const
switch (child->style()->display()) {
case TABLE_CAPTION:
if (!m_caption && child->isRenderBlock()) {
- m_caption = static_cast<RenderBlock*>(child);
+ m_caption = toRenderBlock(child);
m_caption->setNeedsLayout(true);
}
break;
@@ -777,12 +793,6 @@ void RenderTable::recalcSections() const
m_needsSectionRecalc = false;
}
-RenderObject* RenderTable::removeChildNode(RenderObject* child, bool fullRemove)
-{
- setNeedsSectionRecalc();
- return RenderContainer::removeChildNode(child, fullRemove);
-}
-
int RenderTable::calcBorderLeft() const
{
if (collapseBorders()) {
@@ -1172,7 +1182,7 @@ void RenderTable::updateFirstLetter()
{
}
-int RenderTable::getBaselineOfFirstLineBox() const
+int RenderTable::firstLineBoxBaseline() const
{
RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot);
if (firstNonEmptySection && !firstNonEmptySection->numRows())
@@ -1181,12 +1191,12 @@ int RenderTable::getBaselineOfFirstLineBox() const
if (!firstNonEmptySection)
return -1;
- return firstNonEmptySection->y() + firstNonEmptySection->getBaselineOfFirstLineBox();
+ return firstNonEmptySection->y() + firstNonEmptySection->firstLineBoxBaseline();
}
-IntRect RenderTable::getOverflowClipRect(int tx, int ty)
+IntRect RenderTable::overflowClipRect(int tx, int ty)
{
- IntRect rect = RenderBlock::getOverflowClipRect(tx, ty);
+ IntRect rect = RenderBlock::overflowClipRect(tx, ty);
// If we have a caption, expand the clip to include the caption.
// FIXME: Technically this is wrong, but it's virtually impossible to fix this
@@ -1202,4 +1212,29 @@ IntRect RenderTable::getOverflowClipRect(int tx, int ty)
return rect;
}
+bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
+{
+ tx += x();
+ ty += y();
+
+ // Check kids first.
+ if (!hasOverflowClip() || overflowClipRect(tx, ty).contains(xPos, yPos)) {
+ for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption) &&
+ child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ return true;
+ }
+ }
+ }
+
+ // Check our bounds next.
+ if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ return true;
+ }
+
+ return false;
+}
+
}
diff --git a/WebCore/rendering/RenderTable.h b/WebCore/rendering/RenderTable.h
index e3168cb..2fb7a14 100644
--- a/WebCore/rendering/RenderTable.h
+++ b/WebCore/rendering/RenderTable.h
@@ -39,26 +39,6 @@ class TableLayout;
class RenderTable : public RenderBlock {
public:
- enum Rules {
- None = 0x00,
- RGroups = 0x01,
- CGroups = 0x02,
- Groups = 0x03,
- Rows = 0x05,
- Cols = 0x0a,
- All = 0x0f
- };
- enum Frame {
- Void = 0x00,
- Above = 0x01,
- Below = 0x02,
- Lhs = 0x04,
- Rhs = 0x08,
- Hsides = 0x03,
- Vsides = 0x0c,
- Box = 0x0f
- };
-
RenderTable(Node*);
~RenderTable();
@@ -79,8 +59,6 @@ public:
int borderTop() const;
int borderBottom() const;
- Rules getRules() const { return static_cast<Rules>(m_rules); }
-
const Color& bgColor() const { return style()->backgroundColor(); }
int outerBorderTop() const;
@@ -94,13 +72,17 @@ public:
// overrides
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* oldChild);
+
virtual void paint(PaintInfo&, int tx, int ty);
+ virtual void paintObject(PaintInfo&, int tx, int ty);
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
virtual void paintMask(PaintInfo& paintInfo, int tx, int ty);
virtual void layout();
virtual void calcPrefWidths();
-
- virtual int getBaselineOfFirstLineBox() const;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int xPos, int yPos, int tx, int ty, HitTestAction);
+
+ virtual int firstLineBoxBaseline() const;
virtual RenderBlock* firstLineBlock() const;
virtual void updateFirstLetter();
@@ -169,8 +151,6 @@ public:
setNeedsLayout(true);
}
- virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-
RenderTableSection* sectionAbove(const RenderTableSection*, bool skipEmptySections = false) const;
RenderTableSection* sectionBelow(const RenderTableSection*, bool skipEmptySections = false) const;
@@ -183,7 +163,7 @@ public:
bool hasSections() const { return m_head || m_foot || m_firstBody; }
- virtual IntRect getOverflowClipRect(int tx, int ty);
+ virtual IntRect overflowClipRect(int tx, int ty);
void recalcSectionsIfNeeded() const
{
@@ -197,7 +177,7 @@ public:
#endif
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
void recalcSections() const;
@@ -214,9 +194,6 @@ private:
const CollapsedBorderValue* m_currentBorder;
- unsigned m_frame : 4; // Frame
- unsigned m_rules : 4; // Rules
-
mutable bool m_hasColElements : 1;
mutable bool m_needsSectionRecalc : 1;
diff --git a/WebCore/rendering/RenderTableCell.cpp b/WebCore/rendering/RenderTableCell.cpp
index f5bf358..f5e6ae2 100644
--- a/WebCore/rendering/RenderTableCell.cpp
+++ b/WebCore/rendering/RenderTableCell.cpp
@@ -31,6 +31,7 @@
#include "HTMLTableCellElement.h"
#include "RenderTableCol.h"
#include "RenderView.h"
+#include "TransformState.h"
#ifdef ANDROID_LAYOUT
#include "Document.h"
@@ -68,9 +69,9 @@ void RenderTableCell::destroy()
void RenderTableCell::updateFromElement()
{
- Node* node = element();
- if (node && (node->hasTagName(tdTag) || node->hasTagName(thTag))) {
- HTMLTableCellElement* tc = static_cast<HTMLTableCellElement*>(node);
+ Node* n = node();
+ if (n && (n->hasTagName(tdTag) || n->hasTagName(thTag))) {
+ HTMLTableCellElement* tc = static_cast<HTMLTableCellElement*>(n);
int oldRSpan = m_rowSpan;
int oldCSpan = m_columnSpan;
@@ -110,10 +111,10 @@ void RenderTableCell::calcPrefWidths()
table()->recalcSectionsIfNeeded();
RenderBlock::calcPrefWidths();
- if (element() && style()->autoWrap()) {
+ if (node() && style()->autoWrap()) {
// See if nowrap was set.
Length w = styleOrColWidth();
- String nowrap = static_cast<Element*>(element())->getAttribute(nowrapAttr);
+ String nowrap = static_cast<Element*>(node())->getAttribute(nowrapAttr);
if (!nowrap.isNull() && w.isFixed())
// Nowrap is set, but we didn't actually use it because of the
// fixed width set on the cell. Even so, it is a WinIE/Moz trait
@@ -141,14 +142,14 @@ void RenderTableCell::updateWidth(int w)
{
if (w != width()) {
setWidth(w);
- m_cellWidthChanged = true;
+ setCellWidthChanged(true);
}
}
void RenderTableCell::layout()
{
- layoutBlock(m_cellWidthChanged);
- m_cellWidthChanged = false;
+ layoutBlock(cellWidthChanged());
+ setCellWidthChanged(false);
}
int RenderTableCell::paddingTop(bool includeIntrinsicPadding) const
@@ -167,7 +168,7 @@ void RenderTableCell::setOverrideSize(int size)
RenderBlock::setOverrideSize(size);
}
-IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// If the table grid is dirty, we cannot get reliable information about adjoining cells,
// so we ignore outside borders. This should not be a problem because it means that
@@ -182,13 +183,13 @@ IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBox* repaintContain
int right = max(borderHalfRight(true), outlineSize);
int top = max(borderHalfTop(true), outlineSize);
int bottom = max(borderHalfBottom(true), outlineSize);
- if (left && !rtl || right && rtl) {
+ if ((left && !rtl) || (right && rtl)) {
if (RenderTableCell* before = table()->cellBefore(this)) {
top = max(top, before->borderHalfTop(true));
bottom = max(bottom, before->borderHalfBottom(true));
}
}
- if (left && rtl || right && !rtl) {
+ if ((left && rtl) || (right && !rtl)) {
if (RenderTableCell* after = table()->cellAfter(this)) {
top = max(top, after->borderHalfTop(true));
bottom = max(bottom, after->borderHalfBottom(true));
@@ -215,11 +216,11 @@ IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBox* repaintContain
// repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
r.move(v->layoutDelta());
}
- computeRectForRepaint(r, repaintContainer);
+ computeRectForRepaint(repaintContainer, r);
return r;
}
-void RenderTableCell::computeRectForRepaint(IntRect& r, RenderBox* repaintContainer, bool fixed)
+void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& r, bool fixed)
{
if (repaintContainer == this)
return;
@@ -227,54 +228,48 @@ void RenderTableCell::computeRectForRepaint(IntRect& r, RenderBox* repaintContai
RenderView* v = view();
if ((!v || !v->layoutStateEnabled()) && parent())
r.move(-parentBox()->x(), -parentBox()->y()); // Rows are in the same coordinate space, so don't add their offset in.
- RenderBlock::computeRectForRepaint(r, repaintContainer, fixed);
+ RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
}
-FloatPoint RenderTableCell::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const
+void RenderTableCell::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
{
+ if (repaintContainer == this)
+ return;
+
RenderView* v = view();
if ((!v || !v->layoutStateEnabled()) && parent()) {
// Rows are in the same coordinate space, so don't add their offset in.
- localPoint.move(-parentBox()->x(), -parentBox()->y());
+ // FIXME: this is wrong with transforms
+ transformState.move(-parentBox()->x(), -parentBox()->y());
}
- return RenderBlock::localToAbsolute(localPoint, fixed, useTransforms);
+ RenderBlock::mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);
}
-FloatPoint RenderTableCell::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool useTransforms) const
+void RenderTableCell::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
{
- FloatPoint localPoint = RenderBlock::absoluteToLocal(containerPoint, fixed, useTransforms);
+ RenderBlock::mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);
if (parent()) {
// Rows are in the same coordinate space, so add their offset back in.
- localPoint.move(parentBox()->x(), parentBox()->y());
+ // FIXME: this is wrong with transforms
+ transformState.move(parentBox()->x(), parentBox()->y());
}
- return localPoint;
}
-FloatQuad RenderTableCell::localToContainerQuad(const FloatQuad& localQuad, RenderBox* repaintContainer, bool fixed) const
+int RenderTableCell::baselinePosition(bool firstLine, bool isRootLineBox) const
{
- if (repaintContainer == this)
- return localQuad;
-
- FloatQuad quad = localQuad;
- if (parent()) {
- // Rows are in the same coordinate space, so don't add their offset in.
- quad.move(-parentBox()->x(), -parentBox()->y());
- }
- return RenderBlock::localToContainerQuad(quad, repaintContainer, fixed);
-}
+ if (isRootLineBox)
+ return RenderBox::baselinePosition(firstLine, isRootLineBox);
-int RenderTableCell::baselinePosition(bool /*firstLine*/, bool /*isRootLineBox*/) const
-{
// <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: The baseline of a cell is the baseline of
// the first in-flow line box in the cell, or the first in-flow table-row in the cell, whichever comes first. If there
// is no such line box or table-row, the baseline is the bottom of content edge of the cell box.
- int firstLineBaseline = getBaselineOfFirstLineBox();
+ int firstLineBaseline = firstLineBoxBaseline();
if (firstLineBaseline != -1)
return firstLineBaseline;
return paddingTop() + borderTop() + contentHeight();
}
-void RenderTableCell::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderTableCell::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
if (parent() && section() && style() && style()->height() != newStyle->height())
section()->setNeedsCellRecalc();
@@ -284,7 +279,7 @@ void RenderTableCell::styleWillChange(RenderStyle::Diff diff, const RenderStyle*
RenderBlock::styleWillChange(diff, newStyle);
}
-void RenderTableCell::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderTableCell::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
setHasBoxDecorations(true);
@@ -660,22 +655,17 @@ int RenderTableCell::borderHalfBottom(bool outer) const
void RenderTableCell::paint(PaintInfo& paintInfo, int tx, int ty)
{
- tx += x();
- ty += y();
-
- // check if we need to do anything at all...
- int os = 2 * maximalOutlineSize(paintInfo.phase);
-
if (paintInfo.phase == PaintPhaseCollapsedTableBorders && style()->visibility() == VISIBLE) {
- if (ty - table()->outerBorderTop() >= paintInfo.rect.bottom() + os ||
- ty + height() + table()->outerBorderBottom() <= paintInfo.rect.y() - os)
- return;
- paintCollapsedBorder(paintInfo.context, tx, ty, width(), height());
- } else {
- if (ty + overflowTop(false) >= paintInfo.rect.bottom() + os || ty + overflowHeight(false) <= paintInfo.rect.y() - os)
- return;
- RenderBlock::paintObject(paintInfo, tx, ty);
- }
+ tx += x();
+ ty += y();
+ int os = 2 * maximalOutlineSize(paintInfo.phase);
+ if (ty - table()->outerBorderTop() < paintInfo.rect.bottom() + os &&
+ ty + height() + table()->outerBorderBottom() > paintInfo.rect.y() - os)
+ paintCollapsedBorder(paintInfo.context, tx, ty, width(), height());
+ return;
+ }
+
+ RenderBlock::paint(paintInfo, tx, ty);
}
static EBorderStyle collapsedBorderStyle(EBorderStyle style)
@@ -689,7 +679,7 @@ static EBorderStyle collapsedBorderStyle(EBorderStyle style)
struct CollapsedBorder {
CollapsedBorderValue borderValue;
- RenderObject::BorderSide side;
+ BoxSide side;
bool shouldPaint;
int x1;
int y1;
@@ -705,7 +695,7 @@ public:
{
}
- void addBorder(const CollapsedBorderValue& borderValue, RenderObject::BorderSide borderSide, bool shouldPaint,
+ void addBorder(const CollapsedBorderValue& borderValue, BoxSide borderSide, bool shouldPaint,
int x1, int y1, int x2, int y2, EBorderStyle borderStyle)
{
if (borderValue.exists() && shouldPaint) {
@@ -830,8 +820,8 @@ void RenderTableCell::paintCollapsedBorder(GraphicsContext* graphicsContext, int
for (CollapsedBorder* border = borders.nextBorder(); border; border = borders.nextBorder()) {
if (border->borderValue == *table()->currentBorderStyle())
- drawBorder(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
- border->borderValue.color(), style()->color(), border->style, 0, 0);
+ drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
+ border->borderValue.color(), style()->color(), border->style, 0, 0);
}
}
diff --git a/WebCore/rendering/RenderTableCell.h b/WebCore/rendering/RenderTableCell.h
index 97e2dda..4b09032 100644
--- a/WebCore/rendering/RenderTableCell.h
+++ b/WebCore/rendering/RenderTableCell.h
@@ -99,10 +99,8 @@ public:
void paintCollapsedBorder(GraphicsContext*, int x, int y, int w, int h);
void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
- virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false);
- virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
- virtual FloatPoint absoluteToLocal(FloatPoint containerPoint, bool fixed = false, bool useTransforms = false) const;
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
virtual int baselinePosition(bool firstLine = false, bool isRootLineBox = false) const;
@@ -120,10 +118,11 @@ public:
virtual void setOverrideSize(int);
protected:
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const;
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
private:
int m_row;
diff --git a/WebCore/rendering/RenderTableCol.cpp b/WebCore/rendering/RenderTableCol.cpp
index 19538fa..f17963c 100644
--- a/WebCore/rendering/RenderTableCol.cpp
+++ b/WebCore/rendering/RenderTableCol.cpp
@@ -37,7 +37,7 @@ namespace WebCore {
using namespace HTMLNames;
RenderTableCol::RenderTableCol(Node* node)
- : RenderContainer(node), m_span(1)
+ : RenderBox(node), m_span(1)
{
// init RenderObject attributes
setInline(true); // our object is not Inline
@@ -47,9 +47,9 @@ RenderTableCol::RenderTableCol(Node* node)
void RenderTableCol::updateFromElement()
{
int oldSpan = m_span;
- Node* node = element();
- if (node && (node->hasTagName(colTag) || node->hasTagName(colgroupTag))) {
- HTMLTableColElement* tc = static_cast<HTMLTableColElement*>(node);
+ Node* n = node();
+ if (n && (n->hasTagName(colTag) || n->hasTagName(colgroupTag))) {
+ HTMLTableColElement* tc = static_cast<HTMLTableColElement*>(n);
m_span = tc->span();
} else
m_span = !(style() && style()->display() == TABLE_COLUMN_GROUP);
@@ -69,7 +69,7 @@ bool RenderTableCol::canHaveChildren() const
return style()->display() == TABLE_COLUMN_GROUP;
}
-IntRect RenderTableCol::clippedOverflowRectForRepaint(RenderBox* /*repaintContainer*/)
+IntRect RenderTableCol::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// For now, just repaint the whole table.
// FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
@@ -79,7 +79,7 @@ IntRect RenderTableCol::clippedOverflowRectForRepaint(RenderBox* /*repaintContai
if (table && !table->isTable())
table = table->parent();
if (table && table->isTable())
- return table->absoluteClippedOverflowRect();
+ return table->clippedOverflowRectForRepaint(repaintContainer);
return IntRect();
}
diff --git a/WebCore/rendering/RenderTableCol.h b/WebCore/rendering/RenderTableCol.h
index 3472965..8c494b2 100644
--- a/WebCore/rendering/RenderTableCol.h
+++ b/WebCore/rendering/RenderTableCol.h
@@ -28,15 +28,20 @@
#ifndef RenderTableCol_h
#define RenderTableCol_h
-#include "RenderContainer.h"
+#include "RenderBox.h"
namespace WebCore {
-class RenderTableCol : public RenderContainer
+class RenderTableCol : public RenderBox
{
public:
RenderTableCol(Node*);
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
virtual const char* renderName() const { return "RenderTableCol"; }
virtual bool isTableCol() const { return true; }
virtual int lineHeight(bool) const { return 0; }
@@ -46,13 +51,14 @@ public:
virtual bool canHaveChildren() const;
virtual bool requiresLayer() const { return false; }
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
int span() const { return m_span; }
void setSpan(int s) { m_span = s; }
private:
+ RenderObjectChildList m_children;
int m_span;
};
diff --git a/WebCore/rendering/RenderTableRow.cpp b/WebCore/rendering/RenderTableRow.cpp
index 6b83769..c0603a2 100644
--- a/WebCore/rendering/RenderTableRow.cpp
+++ b/WebCore/rendering/RenderTableRow.cpp
@@ -42,7 +42,7 @@ namespace WebCore {
using namespace HTMLNames;
RenderTableRow::RenderTableRow(Node* node)
- : RenderContainer(node)
+ : RenderBox(node)
{
// init RenderObject attributes
setInline(false); // our object is not Inline
@@ -52,20 +52,20 @@ void RenderTableRow::destroy()
{
RenderTableSection* recalcSection = section();
- RenderContainer::destroy();
+ RenderBox::destroy();
if (recalcSection)
recalcSection->setNeedsCellRecalc();
}
-void RenderTableRow::styleWillChange(RenderStyle::Diff diff, const RenderStyle* newStyle)
+void RenderTableRow::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
if (section() && style() && style()->height() != newStyle->height())
section()->setNeedsCellRecalc();
ASSERT(newStyle->display() == TABLE_ROW);
- RenderContainer::styleWillChange(diff, newStyle);
+ RenderBox::styleWillChange(diff, newStyle);
}
void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
@@ -74,16 +74,16 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
if (!beforeChild && isAfterContent(lastChild()))
beforeChild = lastChild();
- bool isTableRow = element() && element()->hasTagName(trTag);
+ bool isTableRow = node() && node()->hasTagName(trTag);
#if ENABLE(WML)
- if (!isTableRow && element() && element()->isWMLElement())
- isTableRow = element()->hasTagName(WMLNames::trTag);
+ if (!isTableRow && node() && node()->isWMLElement())
+ isTableRow = node()->hasTagName(WMLNames::trTag);
#endif
if (!child->isTableCell()) {
- if (isTableRow && child->element() && child->element()->hasTagName(formTag) && document()->isHTMLDocument()) {
- RenderContainer::addChild(child, beforeChild);
+ if (isTableRow && child->node() && child->node()->hasTagName(formTag) && document()->isHTMLDocument()) {
+ RenderBox::addChild(child, beforeChild);
return;
}
@@ -121,8 +121,8 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
if (parent())
section()->addCell(cell, this);
- ASSERT(!beforeChild || beforeChild->isTableCell() || isTableRow && beforeChild->element() && beforeChild->element()->hasTagName(formTag) && document()->isHTMLDocument());
- RenderContainer::addChild(cell, beforeChild);
+ ASSERT(!beforeChild || beforeChild->isTableCell() || isTableRow && beforeChild->node() && beforeChild->node()->hasTagName(formTag) && document()->isHTMLDocument());
+ RenderBox::addChild(cell, beforeChild);
if (beforeChild || nextSibling())
section()->setNeedsCellRecalc();
@@ -148,7 +148,7 @@ void RenderTableRow::layout()
// We only ever need to repaint if our cells didn't, which menas that they didn't need
// layout, so we know that our bounds didn't change. This code is just making up for
// the fact that we did not repaint in setStyle() because we had a layout hint.
- // We cannot call repaint() because our absoluteClippedOverflowRect() is taken from the
+ // We cannot call repaint() because our clippedOverflowRectForRepaint() is taken from the
// parent table, and being mid-layout, that is invalid. Instead, we repaint our cells.
if (selfNeedsLayout() && checkForRepaintDuringLayout()) {
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
@@ -161,7 +161,7 @@ void RenderTableRow::layout()
setNeedsLayout(false);
}
-IntRect RenderTableRow::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderTableRow::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
// For now, just repaint the whole table.
// FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
@@ -183,7 +183,7 @@ bool RenderTableRow::nodeAtPoint(const HitTestRequest& request, HitTestResult& r
// at the moment (a demoted inline <form> for example). If we ever implement a
// table-specific hit-test method (which we should do for performance reasons anyway),
// then we can remove this check.
- if (!child->hasLayer() && !child->isRenderInline() && child->nodeAtPoint(request, result, x, y, tx, ty, action)) {
+ if (child->isTableCell() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, x, y, tx, ty, action)) {
updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
@@ -194,10 +194,9 @@ bool RenderTableRow::nodeAtPoint(const HitTestRequest& request, HitTestResult& r
void RenderTableRow::paint(PaintInfo& paintInfo, int tx, int ty)
{
- ASSERT(m_layer);
- if (!m_layer)
+ ASSERT(hasSelfPaintingLayer());
+ if (!layer())
return;
-
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
// Paint the row background behind the cell.
@@ -205,7 +204,7 @@ void RenderTableRow::paint(PaintInfo& paintInfo, int tx, int ty)
RenderTableCell* cell = static_cast<RenderTableCell*>(child);
cell->paintBackgroundsBehindCell(paintInfo, tx, ty, this);
}
- if (!child->hasLayer())
+ if (!toRenderBox(child)->hasSelfPaintingLayer())
child->paint(paintInfo, tx, ty);
}
}
diff --git a/WebCore/rendering/RenderTableRow.h b/WebCore/rendering/RenderTableRow.h
index 79d32d8..9622480 100644
--- a/WebCore/rendering/RenderTableRow.h
+++ b/WebCore/rendering/RenderTableRow.h
@@ -31,10 +31,15 @@
namespace WebCore {
-class RenderTableRow : public RenderContainer {
+class RenderTableRow : public RenderBox {
public:
RenderTableRow(Node*);
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
RenderTableSection* section() const { return static_cast<RenderTableSection*>(parent()); }
RenderTable* table() const { return static_cast<RenderTable*>(parent()->parent()); }
@@ -47,19 +52,21 @@ private:
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual int lineHeight(bool, bool) const { return 0; }
- virtual void position(InlineBox*) { }
virtual void layout();
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
// The only time rows get a layer is when they have transparency.
- virtual bool requiresLayer() const { return isTransparent() || hasOverflowClip(); }
+ virtual bool requiresLayer() const { return isTransparent() || hasOverflowClip() || hasTransform() || hasMask(); }
virtual void paint(PaintInfo&, int tx, int ty);
+
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle* newStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
+private:
+ RenderObjectChildList m_children;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index ad2bfaf..59fb324 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -47,7 +47,7 @@ namespace WebCore {
using namespace HTMLNames;
RenderTableSection::RenderTableSection(Node* node)
- : RenderContainer(node)
+ : RenderBox(node)
, m_gridRows(0)
, m_cCol(0)
, m_cRow(-1)
@@ -75,7 +75,7 @@ void RenderTableSection::destroy()
{
RenderTable* recalcTable = table();
- RenderContainer::destroy();
+ RenderBox::destroy();
// recalc cell info because RenderTable has unguarded pointers
// stored that point to this RenderTableSection.
@@ -89,11 +89,11 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
if (!beforeChild && isAfterContent(lastChild()))
beforeChild = lastChild();
- bool isTableSection = element() && (element()->hasTagName(theadTag) || element()->hasTagName(tbodyTag) || element()->hasTagName(tfootTag));
+ bool isTableSection = node() && (node()->hasTagName(theadTag) || node()->hasTagName(tbodyTag) || node()->hasTagName(tfootTag));
if (!child->isTableRow()) {
- if (isTableSection && child->element() && child->element()->hasTagName(formTag) && document()->isHTMLDocument()) {
- RenderContainer::addChild(child, beforeChild);
+ if (isTableSection && child->node() && child->node()->hasTagName(formTag) && document()->isHTMLDocument()) {
+ RenderBox::addChild(child, beforeChild);
return;
}
@@ -147,8 +147,14 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
while (beforeChild && beforeChild->parent() != this)
beforeChild = beforeChild->parent();
- ASSERT(!beforeChild || beforeChild->isTableRow() || isTableSection && beforeChild->element() && beforeChild->element()->hasTagName(formTag) && document()->isHTMLDocument());
- RenderContainer::addChild(child, beforeChild);
+ ASSERT(!beforeChild || beforeChild->isTableRow() || isTableSection && beforeChild->node() && beforeChild->node()->hasTagName(formTag) && document()->isHTMLDocument());
+ RenderBox::addChild(child, beforeChild);
+}
+
+void RenderTableSection::removeChild(RenderObject* oldChild)
+{
+ setNeedsCellRecalc();
+ RenderBox::removeChild(oldChild);
}
bool RenderTableSection::ensureRows(int numRows)
@@ -242,7 +248,7 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row)
for (int r = 0; r < rSpan; r++) {
CellStruct& c = cellAt(m_cRow + r, m_cCol);
- if (currentCell.cell && !c.cell)
+ if (!c.cell)
c.cell = currentCell.cell;
if (currentCell.inColSpan)
c.inColSpan = true;
@@ -252,10 +258,8 @@ void RenderTableSection::addCell(RenderTableCell* cell, RenderTableRow* row)
currentCell.cell = 0;
currentCell.inColSpan = true;
}
- if (cell) {
- cell->setRow(m_cRow);
- cell->setCol(table()->effColToCol(col));
- }
+ cell->setRow(m_cRow);
+ cell->setCol(table()->effColToCol(col));
}
void RenderTableSection::setCellWidths()
@@ -425,6 +429,21 @@ int RenderTableSection::calcRowHeight()
return m_rowPos[m_gridRows];
}
+void RenderTableSection::layout()
+{
+ ASSERT(needsLayout());
+
+ LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));
+ for (RenderObject* child = children()->firstChild(); child; child = child->nextSibling()) {
+ if (child->isTableRow()) {
+ child->layoutIfNeeded();
+ ASSERT(!child->needsLayout());
+ }
+ }
+ statePusher.pop();
+ setNeedsLayout(false);
+}
+
int RenderTableSection::layoutRows(int toAdd)
{
#ifndef NDEBUG
@@ -598,17 +617,37 @@ int RenderTableSection::layoutRows(int toAdd)
(!table()->style()->height().isAuto() && rHeight != cell->height());
for (RenderObject* o = cell->firstChild(); o; o = o->nextSibling()) {
- if (!o->isText() && o->style()->height().isPercent() && (o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()) || flexAllChildren)) {
+ if (!o->isText() && o->style()->height().isPercent() && (flexAllChildren || o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()))) {
// Tables with no sections do not flex.
if (!o->isTable() || static_cast<RenderTable*>(o)->hasSections()) {
o->setNeedsLayout(true, false);
- cell->setChildNeedsLayout(true, false);
cellChildrenFlex = true;
}
}
}
-
+
+ if (HashSet<RenderBox*>* percentHeightDescendants = cell->percentHeightDescendants()) {
+ HashSet<RenderBox*>::iterator end = percentHeightDescendants->end();
+ for (HashSet<RenderBox*>::iterator it = percentHeightDescendants->begin(); it != end; ++it) {
+ RenderBox* box = *it;
+ if (!box->isReplaced() && !box->scrollsOverflow() && !flexAllChildren)
+ continue;
+
+ while (box != cell) {
+ if (box->normalChildNeedsLayout())
+ break;
+ box->setChildNeedsLayout(true, false);
+ box = box->containingBlock();
+ ASSERT(box);
+ if (!box)
+ break;
+ }
+ cellChildrenFlex = true;
+ }
+ }
+
if (cellChildrenFlex) {
+ cell->setChildNeedsLayout(true, false);
// Alignment within a cell is based off the calculated
// height, which becomes irrelevant once the cell has
// been resized based off its percentage.
@@ -702,14 +741,16 @@ int RenderTableSection::layoutRows(int toAdd)
int RenderTableSection::lowestPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int bottom = RenderContainer::lowestPosition(includeOverflowInterior, includeSelf);
+ int bottom = RenderBox::lowestPosition(includeOverflowInterior, includeSelf);
if (!includeOverflowInterior && hasOverflowClip())
return bottom;
for (RenderObject* row = firstChild(); row; row = row->nextSibling()) {
- for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (cell->isTableCell())
- bottom = max(bottom, static_cast<RenderTableCell*>(cell)->y() + cell->lowestPosition(false));
+ for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) {
+ if (curr->isTableCell()) {
+ RenderTableCell* cell = static_cast<RenderTableCell*>(curr);
+ bottom = max(bottom, cell->y() + cell->lowestPosition(false));
+ }
}
}
@@ -718,14 +759,16 @@ int RenderTableSection::lowestPosition(bool includeOverflowInterior, bool includ
int RenderTableSection::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int right = RenderContainer::rightmostPosition(includeOverflowInterior, includeSelf);
+ int right = RenderBox::rightmostPosition(includeOverflowInterior, includeSelf);
if (!includeOverflowInterior && hasOverflowClip())
return right;
for (RenderObject* row = firstChild(); row; row = row->nextSibling()) {
- for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (cell->isTableCell())
- right = max(right, static_cast<RenderTableCell*>(cell)->x() + cell->rightmostPosition(false));
+ for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) {
+ if (curr->isTableCell()) {
+ RenderTableCell* cell = static_cast<RenderTableCell*>(curr);
+ right = max(right, cell->x() + cell->rightmostPosition(false));
+ }
}
}
@@ -734,14 +777,16 @@ int RenderTableSection::rightmostPosition(bool includeOverflowInterior, bool inc
int RenderTableSection::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const
{
- int left = RenderContainer::leftmostPosition(includeOverflowInterior, includeSelf);
+ int left = RenderBox::leftmostPosition(includeOverflowInterior, includeSelf);
if (!includeOverflowInterior && hasOverflowClip())
return left;
for (RenderObject* row = firstChild(); row; row = row->nextSibling()) {
- for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (cell->isTableCell())
- left = min(left, static_cast<RenderTableCell*>(cell)->x() + cell->leftmostPosition(false));
+ for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) {
+ if (curr->isTableCell()) {
+ RenderTableCell* cell = static_cast<RenderTableCell*>(curr);
+ left = min(left, cell->x() + cell->leftmostPosition(false));
+ }
}
}
@@ -957,7 +1002,7 @@ void RenderTableSection::recalcOuterBorder()
m_outerBorderRight = calcOuterBorderRight(rtl);
}
-int RenderTableSection::getBaselineOfFirstLineBox() const
+int RenderTableSection::firstLineBoxBaseline() const
{
if (!m_gridRows)
return -1;
@@ -994,8 +1039,20 @@ void RenderTableSection::paint(PaintInfo& paintInfo, int tx, int ty)
tx += x();
ty += y();
+ PaintPhase phase = paintInfo.phase;
+ bool pushedClip = pushContentsClip(paintInfo, tx, ty);
+ paintObject(paintInfo, tx, ty);
+ if (pushedClip)
+ popContentsClip(paintInfo, phase, tx, ty);
+}
+
+void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty)
+{
// Check which rows and cols are visible and only paint these.
// FIXME: Could use a binary search here.
+ unsigned totalRows = m_gridRows;
+ unsigned totalCols = table()->columns().size();
+
PaintPhase paintPhase = paintInfo.phase;
int x = paintInfo.rect.x();
int y = paintInfo.rect.y();
@@ -1102,10 +1159,10 @@ void RenderTableSection::paint(PaintInfo& paintInfo, int tx, int ty)
// Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for
// painting the row background for the cell.
- if (!row->hasLayer())
+ if (!row->hasSelfPaintingLayer())
cell->paintBackgroundsBehindCell(paintInfo, tx, ty, row);
}
- if ((!cell->hasLayer() && !row->hasLayer()) || paintInfo.phase == PaintPhaseCollapsedTableBorders)
+ if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer()) || paintInfo.phase == PaintPhaseCollapsedTableBorders)
cell->paint(paintInfo, tx, ty);
}
}
@@ -1190,12 +1247,6 @@ void RenderTableSection::splitColumn(int pos, int newSize)
}
}
-RenderObject* RenderTableSection::removeChildNode(RenderObject* child, bool fullRemove)
-{
- setNeedsCellRecalc();
- return RenderContainer::removeChildNode(child, fullRemove);
-}
-
// Hit Testing
bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
{
@@ -1204,12 +1255,15 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
tx += x();
ty += y();
+ if (hasOverflowClip() && !overflowClipRect(tx, ty).contains(xPos, yPos))
+ return false;
+
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
// FIXME: We have to skip over inline flows, since they can show up inside table rows
// at the moment (a demoted inline <form> for example). If we ever implement a
// table-specific hit-test method (which we should do for performance reasons anyway),
// then we can remove this check.
- if (!child->hasLayer() && !child->isRenderInline() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
return true;
}
diff --git a/WebCore/rendering/RenderTableSection.h b/WebCore/rendering/RenderTableSection.h
index 71839d1..5c57714 100644
--- a/WebCore/rendering/RenderTableSection.h
+++ b/WebCore/rendering/RenderTableSection.h
@@ -35,20 +35,28 @@ namespace WebCore {
class RenderTableCell;
class RenderTableRow;
-class RenderTableSection : public RenderContainer {
+class RenderTableSection : public RenderBox {
public:
RenderTableSection(Node*);
~RenderTableSection();
+ virtual RenderObjectChildList* virtualChildren() { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ const RenderObjectChildList* children() const { return &m_children; }
+ RenderObjectChildList* children() { return &m_children; }
+
virtual const char* renderName() const { return isAnonymous() ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
virtual bool isTableSection() const { return true; }
virtual void destroy();
+ virtual void layout();
+
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void removeChild(RenderObject* oldChild);
- virtual int getBaselineOfFirstLineBox() const;
+ virtual int firstLineBoxBaseline() const;
void addCell(RenderTableCell*, RenderTableRow* row);
@@ -99,6 +107,8 @@ public:
int outerBorderRight() const { return m_outerBorderRight; }
virtual void paint(PaintInfo&, int tx, int ty);
+ virtual void paintObject(PaintInfo&, int tx, int ty);
+
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
int numRows() const { return m_gridRows; }
@@ -119,17 +129,16 @@ public:
int getBaseline(int row) { return m_grid[row].baseline; }
- virtual RenderObject* removeChildNode(RenderObject*, bool fullRemove = true);
-
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
private:
virtual int lineHeight(bool, bool) const { return 0; }
- virtual void position(InlineBox*) { }
bool ensureRows(int);
void clearGrid();
+ RenderObjectChildList m_children;
+
Vector<RowStruct> m_grid;
int m_gridRows;
Vector<int> m_rowPos;
diff --git a/WebCore/rendering/RenderText.cpp b/WebCore/rendering/RenderText.cpp
index 084be71..2dfdb27 100644
--- a/WebCore/rendering/RenderText.cpp
+++ b/WebCore/rendering/RenderText.cpp
@@ -36,6 +36,7 @@
#include "RenderView.h"
#include "Text.h"
#include "TextBreakIterator.h"
+#include "VisiblePosition.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
@@ -60,7 +61,6 @@ RenderText::RenderText(Node* node, PassRefPtr<StringImpl> str)
, m_maxWidth(-1)
, m_beginMinWidth(0)
, m_endMinWidth(0)
- , m_selectionState(SelectionNone)
, m_hasTab(false)
, m_linesDirty(false)
, m_containsReversedText(false)
@@ -98,13 +98,13 @@ bool RenderText::isWordBreak() const
return false;
}
-void RenderText::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
// There is no need to ever schedule repaints from a style change of a text run, since
// we already did this for the parent of the text run.
// We do have to schedule layouts, though, since a style change can force us to
// need to relayout.
- if (diff == RenderStyle::Layout)
+ if (diff == StyleDifferenceLayout)
setNeedsLayoutAndPrefWidthsRecalc();
ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
@@ -200,17 +200,17 @@ void RenderText::deleteTextBoxes()
PassRefPtr<StringImpl> RenderText::originalText() const
{
- Node* e = element();
+ Node* e = node();
return e ? static_cast<Text*>(e)->string() : 0;
}
void RenderText::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool)
{
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
- rects.append(IntRect(tx + box->xPos(), ty + box->yPos(), box->width(), box->height()));
+ rects.append(IntRect(tx + box->x(), ty + box->y(), box->width(), box->height()));
}
-void RenderText::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight)
+void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, unsigned end, bool useSelectionHeight)
{
// Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
// to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
@@ -227,7 +227,7 @@ void RenderText::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigne
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
// Note: box->end() returns the index of the last character, not the index past it
if (start <= box->start() && box->end() < end) {
- IntRect r = IntRect(absPos.x() + box->xPos(), absPos.y() + box->yPos(), box->width(), box->height());
+ IntRect r = IntRect(absPos.x() + box->x(), absPos.y() + box->y(), box->width(), box->height());
if (useSelectionHeight) {
IntRect selectionRect = box->selectionRect(absPos.x(), absPos.y(), start, end);
r.setHeight(selectionRect.height());
@@ -241,7 +241,7 @@ void RenderText::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigne
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
r.setHeight(box->height());
- r.setY(absPos.y() + box->yPos());
+ r.setY(absPos.y() + box->y());
}
rects.append(r);
}
@@ -252,10 +252,10 @@ void RenderText::addLineBoxRects(Vector<IntRect>& rects, unsigned start, unsigne
void RenderText::absoluteQuads(Vector<FloatQuad>& quads, bool)
{
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
- quads.append(localToAbsoluteQuad(FloatRect(box->xPos(), box->yPos(), box->width(), box->height())));
+ quads.append(localToAbsoluteQuad(FloatRect(box->x(), box->y(), box->width(), box->height())));
}
-void RenderText::collectAbsoluteLineBoxQuads(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight)
+void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start, unsigned end, bool useSelectionHeight)
{
// Work around signed/unsigned issues. This function takes unsigneds, and is often passed UINT_MAX
// to mean "all the way to the end". InlineTextBox coordinates are unsigneds, so changing this
@@ -270,7 +270,7 @@ void RenderText::collectAbsoluteLineBoxQuads(Vector<FloatQuad>& quads, unsigned
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
// Note: box->end() returns the index of the last character, not the index past it
if (start <= box->start() && box->end() < end) {
- IntRect r = IntRect(box->xPos(), box->yPos(), box->width(), box->height());
+ IntRect r = IntRect(box->x(), box->y(), box->width(), box->height());
if (useSelectionHeight) {
IntRect selectionRect = box->selectionRect(0, 0, start, end);
r.setHeight(selectionRect.height());
@@ -284,7 +284,7 @@ void RenderText::collectAbsoluteLineBoxQuads(Vector<FloatQuad>& quads, unsigned
if (!useSelectionHeight) {
// change the height and y position because selectionRect uses selection-specific values
r.setHeight(box->height());
- r.setY(box->yPos());
+ r.setY(box->y());
}
quads.append(localToAbsoluteQuad(FloatRect(r)));
}
@@ -313,61 +313,61 @@ InlineTextBox* RenderText::findNextInlineTextBox(int offset, int& pos) const
return s;
}
-VisiblePosition RenderText::positionForCoordinates(int x, int y)
+VisiblePosition RenderText::positionForPoint(const IntPoint& point)
{
if (!firstTextBox() || textLength() == 0)
- return VisiblePosition(element(), 0, DOWNSTREAM);
+ return createVisiblePosition(0, DOWNSTREAM);
// Get the offset for the position, since this will take rtl text into account.
int offset;
// FIXME: We should be able to roll these special cases into the general cases in the loop below.
- if (firstTextBox() && y < firstTextBox()->root()->bottomOverflow() && x < firstTextBox()->m_x) {
+ if (firstTextBox() && point.y() < firstTextBox()->root()->bottomOverflow() && point.x() < firstTextBox()->m_x) {
// at the y coordinate of the first line or above
// and the x coordinate is to the left of the first text box left edge
- offset = firstTextBox()->offsetForPosition(x);
- return VisiblePosition(element(), offset + firstTextBox()->start(), DOWNSTREAM);
+ offset = firstTextBox()->offsetForPosition(point.x());
+ return createVisiblePosition(offset + firstTextBox()->start(), DOWNSTREAM);
}
- if (lastTextBox() && y >= lastTextBox()->root()->topOverflow() && x >= lastTextBox()->m_x + lastTextBox()->m_width) {
+ if (lastTextBox() && point.y() >= lastTextBox()->root()->topOverflow() && point.x() >= lastTextBox()->m_x + lastTextBox()->m_width) {
// at the y coordinate of the last line or below
// and the x coordinate is to the right of the last text box right edge
- offset = lastTextBox()->offsetForPosition(x);
- return VisiblePosition(element(), offset + lastTextBox()->start(), DOWNSTREAM);
+ offset = lastTextBox()->offsetForPosition(point.x());
+ return createVisiblePosition(offset + lastTextBox()->start(), DOWNSTREAM);
}
InlineTextBox* lastBoxAbove = 0;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
- if (y >= box->root()->topOverflow()) {
+ if (point.y() >= box->root()->topOverflow()) {
int bottom = box->root()->nextRootBox() ? box->root()->nextRootBox()->topOverflow() : box->root()->bottomOverflow();
- if (y < bottom) {
- offset = box->offsetForPosition(x);
+ if (point.y() < bottom) {
+ offset = box->offsetForPosition(point.x());
- if (x == box->m_x)
+ if (point.x() == box->m_x)
// the x coordinate is equal to the left edge of this box
// the affinity must be downstream so the position doesn't jump back to the previous line
- return VisiblePosition(element(), offset + box->start(), DOWNSTREAM);
+ return createVisiblePosition(offset + box->start(), DOWNSTREAM);
- if (x < box->m_x + box->m_width)
+ if (point.x() < box->m_x + box->m_width)
// and the x coordinate is to the left of the right edge of this box
// check to see if position goes in this box
- return VisiblePosition(element(), offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
+ return createVisiblePosition(offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
- if (!box->prevOnLine() && x < box->m_x)
+ if (!box->prevOnLine() && point.x() < box->m_x)
// box is first on line
// and the x coordinate is to the left of the first text box left edge
- return VisiblePosition(element(), offset + box->start(), DOWNSTREAM);
+ return createVisiblePosition(offset + box->start(), DOWNSTREAM);
if (!box->nextOnLine())
// box is last on line
// and the x coordinate is to the right of the last text box right edge
// generate VisiblePosition, use UPSTREAM affinity if possible
- return VisiblePosition(element(), offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
+ return createVisiblePosition(offset + box->start(), offset > 0 ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM);
}
lastBoxAbove = box;
}
}
- return VisiblePosition(element(), lastBoxAbove ? lastBoxAbove->start() + lastBoxAbove->len() : 0, DOWNSTREAM);
+ return createVisiblePosition(lastBoxAbove ? lastBoxAbove->start() + lastBoxAbove->len() : 0, DOWNSTREAM);
}
IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* extraWidthToEndOfLine)
@@ -386,7 +386,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
int left = box->positionForOffset(caretOffset);
- int rootLeft = box->root()->xPos();
+ int rootLeft = box->root()->x();
// FIXME: should we use the width of the root inline box or the
// width of the containing block for this?
if (extraWidthToEndOfLine)
@@ -394,14 +394,13 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
RenderBlock* cb = containingBlock();
if (style()->autoWrap()) {
- int availableWidth = cb->lineWidth(top);
+ int availableWidth = cb->lineWidth(top, false);
if (box->direction() == LTR)
left = min(left, rootLeft + availableWidth - 1);
else
left = max(left, rootLeft);
}
- const int caretWidth = 1;
return IntRect(left, top, caretWidth, height);
}
@@ -709,7 +708,7 @@ void RenderText::calcPrefWidths(int leadWidth)
}
}
- if (needsWordSpacing && len > 1 || ignoringSpaces && !firstWord)
+ if ((needsWordSpacing && len > 1) || (ignoringSpaces && !firstWord))
currMaxWidth += wordSpacing;
m_minWidth = max(currMinWidth, m_minWidth);
@@ -750,7 +749,7 @@ void RenderText::setSelectionState(SelectionState state)
{
InlineTextBox* box;
- m_selectionState = state;
+ RenderObject::setSelectionState(state);
if (state == SelectionStart || state == SelectionEnd || state == SelectionBoth) {
int startPos, endPos;
selectionStartEnd(startPos, endPos);
@@ -968,7 +967,7 @@ int RenderText::lineHeight(bool firstLine, bool) const
return parent()->lineHeight(firstLine, true);
}
-void RenderText::dirtyLineBoxes(bool fullLayout, bool)
+void RenderText::dirtyLineBoxes(bool fullLayout)
{
if (fullLayout)
deleteTextBoxes();
@@ -979,16 +978,14 @@ void RenderText::dirtyLineBoxes(bool fullLayout, bool)
m_linesDirty = false;
}
-InlineTextBox* RenderText::createInlineTextBox()
+InlineTextBox* RenderText::createTextBox()
{
return new (renderArena()) InlineTextBox(this);
}
-InlineBox* RenderText::createInlineBox(bool, bool unusedIsRootLineBox, bool)
+InlineTextBox* RenderText::createInlineTextBox()
{
- ASSERT_UNUSED(unusedIsRootLineBox, !unusedIsRootLineBox);
-
- InlineTextBox* textBox = createInlineTextBox();
+ InlineTextBox* textBox = createTextBox();
if (!m_firstTextBox)
m_firstTextBox = m_lastTextBox = textBox;
else {
@@ -999,7 +996,7 @@ InlineBox* RenderText::createInlineBox(bool, bool unusedIsRootLineBox, bool)
return textBox;
}
-void RenderText::position(InlineBox* box)
+void RenderText::positionLineBox(InlineBox* box)
{
InlineTextBox* s = static_cast<InlineTextBox*>(box);
@@ -1015,7 +1012,7 @@ void RenderText::position(InlineBox* box)
m_containsReversedText |= s->direction() == RTL;
}
-unsigned int RenderText::width(unsigned int from, unsigned int len, int xPos, bool firstLine) const
+unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine) const
{
if (from >= textLength())
return 0;
@@ -1026,14 +1023,12 @@ unsigned int RenderText::width(unsigned int from, unsigned int len, int xPos, bo
return width(from, len, style(firstLine)->font(), xPos);
}
-unsigned int RenderText::width(unsigned int from, unsigned int len, const Font& f, int xPos) const
+unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos) const
{
- if (!characters() || from > textLength())
+ ASSERT(from + len <= textLength());
+ if (!characters())
return 0;
- if (from + len > textLength())
- len = textLength() - from;
-
int w;
if (&f == &style()->font()) {
if (!style()->preserveNewline() && !from && len == textLength())
@@ -1056,36 +1051,35 @@ IntRect RenderText::linesBoundingBox() const
int leftSide = 0;
int rightSide = 0;
for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
- if (curr == firstTextBox() || curr->xPos() < leftSide)
- leftSide = curr->xPos();
- if (curr == firstTextBox() || curr->xPos() + curr->width() > rightSide)
- rightSide = curr->xPos() + curr->width();
+ if (curr == firstTextBox() || curr->x() < leftSide)
+ leftSide = curr->x();
+ if (curr == firstTextBox() || curr->x() + curr->width() > rightSide)
+ rightSide = curr->x() + curr->width();
}
result.setWidth(rightSide - leftSide);
result.setX(leftSide);
- result.setHeight(lastTextBox()->yPos() + lastTextBox()->height() - firstTextBox()->yPos());
- result.setY(firstTextBox()->yPos());
+ result.setHeight(lastTextBox()->y() + lastTextBox()->height() - firstTextBox()->y());
+ result.setY(firstTextBox()->y());
}
return result;
}
-IntRect RenderText::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
+IntRect RenderText::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
RenderObject* cb = containingBlock();
return cb->clippedOverflowRectForRepaint(repaintContainer);
}
-IntRect RenderText::selectionRect(bool clipToVisibleContent)
+IntRect RenderText::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
- IntRect rect;
if (selectionState() == SelectionNone)
- return rect;
+ return IntRect();
RenderBlock* cb = containingBlock();
if (!cb)
- return rect;
+ return IntRect();
// Now calculate startPos and endPos for painting selection.
// We include a selection while endPos > 0
@@ -1103,31 +1097,24 @@ IntRect RenderText::selectionRect(bool clipToVisibleContent)
}
if (startPos == endPos)
- return rect;
+ return IntRect();
+ IntRect rect;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
rect.unite(box->selectionRect(0, 0, startPos, endPos));
if (clipToVisibleContent)
- computeAbsoluteRepaintRect(rect);
+ computeRectForRepaint(repaintContainer, rect);
else {
if (cb->hasColumns())
cb->adjustRectForColumns(rect);
- // FIXME: This doesn't work correctly with transforms.
- FloatPoint absPos = localToAbsolute();
- rect.move(absPos.x(), absPos.y());
+
+ rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
}
return rect;
}
-int RenderText::verticalPositionHint(bool firstLine) const
-{
- if (parent()->isReplaced())
- return 0; // Treat inline blocks just like blocks. There can't be any vertical position hint.
- return parent()->verticalPositionHint(firstLine);
-}
-
int RenderText::caretMinOffset() const
{
InlineTextBox* box = firstTextBox();
@@ -1161,7 +1148,7 @@ unsigned RenderText::caretMaxRenderedOffset() const
int RenderText::previousOffset(int current) const
{
StringImpl* si = m_text.get();
- TextBreakIterator* iterator = characterBreakIterator(si->characters(), si->length());
+ TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
if (!iterator)
return current - 1;
@@ -1169,13 +1156,122 @@ int RenderText::previousOffset(int current) const
if (result == TextBreakDone)
result = current - 1;
+#ifdef BUILDING_ON_TIGER
+ // ICU 3.2 allows character breaks before a half-width Katakana voiced mark.
+ if (static_cast<unsigned>(result) < si->length()) {
+ UChar character = (*si)[result];
+ if (character == 0xFF9E || character == 0xFF9F)
+ --result;
+ }
+#endif
+
return result;
}
+#define HANGUL_CHOSEONG_START (0x1100)
+#define HANGUL_CHOSEONG_END (0x115F)
+#define HANGUL_JUNGSEONG_START (0x1160)
+#define HANGUL_JUNGSEONG_END (0x11A2)
+#define HANGUL_JONGSEONG_START (0x11A8)
+#define HANGUL_JONGSEONG_END (0x11F9)
+#define HANGUL_SYLLABLE_START (0xAC00)
+#define HANGUL_SYLLABLE_END (0xD7AF)
+#define HANGUL_JONGSEONG_COUNT (28)
+
+enum HangulState {
+ HangulStateL,
+ HangulStateV,
+ HangulStateT,
+ HangulStateLV,
+ HangulStateLVT,
+ HangulStateBreak
+};
+
+inline bool isHangulLVT(UChar32 character)
+{
+ return (character - HANGUL_SYLLABLE_START) % HANGUL_JONGSEONG_COUNT;
+}
+
+int RenderText::previousOffsetForBackwardDeletion(int current) const
+{
+#if PLATFORM(MAC)
+ UChar32 character;
+ while (current > 0) {
+ if (U16_IS_TRAIL((*m_text)[--current]))
+ --current;
+ if (current < 0)
+ break;
+
+ UChar32 character = m_text->characterStartingAt(current);
+
+ // We don't combine characters in Armenian ... Limbu range for backward deletion.
+ if ((character >= 0x0530) && (character < 0x1950))
+ break;
+
+ if (u_isbase(character) && (character != 0xFF9E) && (character != 0xFF9F))
+ break;
+ }
+
+ if (current <= 0)
+ return current;
+
+ // Hangul
+ character = m_text->characterStartingAt(current);
+ if (((character >= HANGUL_CHOSEONG_START) && (character <= HANGUL_JONGSEONG_END)) || ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))) {
+ HangulState state;
+ HangulState initialState;
+
+ if (character < HANGUL_JUNGSEONG_START)
+ state = HangulStateL;
+ else if (character < HANGUL_JONGSEONG_START)
+ state = HangulStateV;
+ else if (character < HANGUL_SYLLABLE_START)
+ state = HangulStateT;
+ else
+ state = isHangulLVT(character) ? HangulStateLVT : HangulStateLV;
+
+ initialState = state;
+
+ while (current > 0 && ((character = m_text->characterStartingAt(current - 1)) >= HANGUL_CHOSEONG_START) && (character <= HANGUL_SYLLABLE_END) && ((character <= HANGUL_JONGSEONG_END) || (character >= HANGUL_SYLLABLE_START))) {
+ switch (state) {
+ case HangulStateV:
+ if (character <= HANGUL_CHOSEONG_END)
+ state = HangulStateL;
+ else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END) && !isHangulLVT(character))
+ state = HangulStateLV;
+ else if (character > HANGUL_JUNGSEONG_END)
+ state = HangulStateBreak;
+ break;
+ case HangulStateT:
+ if ((character >= HANGUL_JUNGSEONG_START) && (character <= HANGUL_JUNGSEONG_END))
+ state = HangulStateV;
+ else if ((character >= HANGUL_SYLLABLE_START) && (character <= HANGUL_SYLLABLE_END))
+ state = (isHangulLVT(character) ? HangulStateLVT : HangulStateLV);
+ else if (character < HANGUL_JUNGSEONG_START)
+ state = HangulStateBreak;
+ break;
+ default:
+ state = (character < HANGUL_JUNGSEONG_START) ? HangulStateL : HangulStateBreak;
+ break;
+ }
+ if (state == HangulStateBreak)
+ break;
+
+ --current;
+ }
+ }
+
+ return current;
+#else
+ // Platforms other than Mac delete by one code point.
+ return current - 1;
+#endif
+}
+
int RenderText::nextOffset(int current) const
{
StringImpl* si = m_text.get();
- TextBreakIterator* iterator = characterBreakIterator(si->characters(), si->length());
+ TextBreakIterator* iterator = cursorMovementIterator(si->characters(), si->length());
if (!iterator)
return current + 1;
@@ -1183,6 +1279,15 @@ int RenderText::nextOffset(int current) const
if (result == TextBreakDone)
result = current + 1;
+#ifdef BUILDING_ON_TIGER
+ // ICU 3.2 allows character breaks before a half-width Katakana voiced mark.
+ if (static_cast<unsigned>(result) < si->length()) {
+ UChar character = (*si)[result];
+ if (character == 0xFF9E || character == 0xFF9F)
+ ++result;
+ }
+#endif
+
return result;
}
diff --git a/WebCore/rendering/RenderText.h b/WebCore/rendering/RenderText.h
index 6a09605..649f155 100644
--- a/WebCore/rendering/RenderText.h
+++ b/WebCore/rendering/RenderText.h
@@ -52,21 +52,20 @@ public:
StringImpl* text() const { return m_text.get(); }
- virtual InlineBox* createInlineBox(bool makePlaceHolderBox, bool isRootLineBox, bool isOnlyRun = false);
- virtual InlineTextBox* createInlineTextBox();
- virtual void dirtyLineBoxes(bool fullLayout, bool isRootInlineBox = false);
+ InlineTextBox* createInlineTextBox();
+ void dirtyLineBoxes(bool fullLayout);
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty, bool topLevel = true);
- virtual void addLineBoxRects(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
+ virtual void absoluteRectsForRange(Vector<IntRect>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
virtual void absoluteQuads(Vector<FloatQuad>&, bool topLevel = true);
- virtual void collectAbsoluteLineBoxQuads(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
+ virtual void absoluteQuadsForRange(Vector<FloatQuad>&, unsigned startOffset = 0, unsigned endOffset = UINT_MAX, bool useSelectionHeight = false);
- virtual VisiblePosition positionForCoordinates(int x, int y);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
const UChar* characters() const { return m_text->characters(); }
unsigned textLength() const { return m_text->length(); } // non virtual implementation of length()
- virtual void position(InlineBox*);
+ void positionLineBox(InlineBox*);
virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos) const;
virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false) const;
@@ -88,21 +87,18 @@ public:
int firstRunX() const;
int firstRunY() const;
- virtual int verticalPositionHint(bool firstLine) const;
-
void setText(PassRefPtr<StringImpl>, bool force = false);
void setTextWithOffset(PassRefPtr<StringImpl>, unsigned offset, unsigned len, bool force = false);
virtual bool canBeSelectionLeaf() const { return true; }
- virtual SelectionState selectionState() const { return static_cast<SelectionState>(m_selectionState); }
virtual void setSelectionState(SelectionState s);
- virtual IntRect selectionRect(bool clipToVisibleContent = true);
+ virtual IntRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
virtual IntRect localCaretRect(InlineBox*, int caretOffset, int* extraWidthToEndOfLine = 0);
virtual int marginLeft() const { return style()->marginLeft().calcMinValue(0); }
virtual int marginRight() const { return style()->marginRight().calcMinValue(0); }
- virtual IntRect clippedOverflowRectForRepaint(RenderBox* repaintContainer);
+ virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
InlineTextBox* firstTextBox() const { return m_firstTextBox; }
InlineTextBox* lastTextBox() const { return m_lastTextBox; }
@@ -112,6 +108,7 @@ public:
virtual unsigned caretMaxRenderedOffset() const;
virtual int previousOffset(int current) const;
+ virtual int previousOffsetForBackwardDeletion(int current) const;
virtual int nextOffset(int current) const;
bool containsReversedText() const { return m_containsReversedText; }
@@ -122,13 +119,16 @@ public:
void checkConsistency() const;
+ virtual void calcPrefWidths(int leadWidth);
+
protected:
- virtual void styleWillChange(RenderStyle::Diff, const RenderStyle*) { }
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle*) { }
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual void setTextInternal(PassRefPtr<StringImpl>);
- virtual void calcPrefWidths(int leadWidth);
virtual UChar previousCharacter();
+
+ virtual InlineTextBox* createTextBox(); // Subclassed by SVG.
private:
// Make length() private so that callers that have a RenderText*
@@ -155,7 +155,6 @@ private:
int m_beginMinWidth;
int m_endMinWidth;
- unsigned m_selectionState : 3; // enums on Windows are signed, so this needs to be unsigned to prevent it turning negative.
bool m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
bool m_hasBreak : 1; // Whether or not we have a hard break (e.g., <pre> with '\n').
bool m_hasTab : 1; // Whether or not we have a variable width tab character (e.g., <pre> with '\t').
@@ -181,6 +180,9 @@ inline const RenderText* toRenderText(const RenderObject* o)
return static_cast<const RenderText*>(o);
}
+// This will catch anyone doing an unnecessary cast.
+void toRenderText(const RenderText*);
+
#ifdef NDEBUG
inline void RenderText::checkConsistency() const
{
diff --git a/WebCore/rendering/RenderTextControl.cpp b/WebCore/rendering/RenderTextControl.cpp
index 642ef1f..38d689b 100644
--- a/WebCore/rendering/RenderTextControl.cpp
+++ b/WebCore/rendering/RenderTextControl.cpp
@@ -31,17 +31,14 @@
#include "HTMLFormControlElement.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
+#include "RenderLayer.h"
#include "RenderText.h"
#include "ScrollbarTheme.h"
#include "SelectionController.h"
-#include "TextControlInnerElements.h"
#include "Text.h"
+#include "TextControlInnerElements.h"
#include "TextIterator.h"
-#ifdef ANDROID_LAYOUT
-#include "FrameView.h"
-#endif
-
using namespace std;
namespace WebCore {
@@ -84,12 +81,12 @@ RenderTextControl::~RenderTextControl()
m_innerText->detach();
}
-void RenderTextControl::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
if (m_innerText) {
- RenderBlock* textBlockRenderer = static_cast<RenderBlock*>(m_innerText->renderer());
+ RenderBlock* textBlockRenderer = toRenderBlock(m_innerText->renderer());
RefPtr<RenderStyle> textBlockStyle = createInnerTextStyle(style());
// We may have set the width and the height in the old style in layout().
// Reset them now to avoid getting a spurious layout hint.
@@ -102,18 +99,34 @@ void RenderTextControl::styleDidChange(RenderStyle::Diff diff, const RenderStyle
}
}
- setHasOverflowClip(false);
setReplaced(isInline());
}
+static inline bool updateUserModifyProperty(Node* node, RenderStyle* style)
+{
+ bool isEnabled = true;
+ bool isReadOnlyControl = false;
+
+ if (node->isElementNode()) {
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(node));
+ ASSERT(formControlElement);
+
+ isEnabled = formControlElement->isEnabled();
+ isReadOnlyControl = formControlElement->isReadOnlyControl();
+ }
+
+ style->setUserModify((isReadOnlyControl || !isEnabled) ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
+ return !isEnabled;
+}
+
void RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, RenderStyle* textBlockStyle) const
{
// The inner block, if present, always has its direction set to LTR,
// so we need to inherit the direction from the element.
textBlockStyle->setDirection(style()->direction());
- textBlockStyle->setUserModify((node()->isReadOnlyControl() || !node()->isEnabled()) ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
- if (!node()->isEnabled())
+ bool disabled = updateUserModifyProperty(node(), textBlockStyle);
+ if (disabled)
textBlockStyle->setColor(disabledTextColor(textBlockStyle->color(), startStyle->backgroundColor()));
}
@@ -142,7 +155,7 @@ int RenderTextControl::textBlockWidth() const
void RenderTextControl::updateFromElement()
{
- m_innerText->renderer()->style()->setUserModify((node()->isReadOnlyControl() || !node()->isEnabled()) ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
+ updateUserModifyProperty(node(), m_innerText->renderer()->style());
}
void RenderTextControl::setInnerTextValue(const String& innerTextValue)
@@ -236,7 +249,7 @@ void RenderTextControl::setSelectionRange(int start, int end)
ASSERT(startPosition.isNotNull() && endPosition.isNotNull());
ASSERT(startPosition.deepEquivalent().node()->shadowAncestorNode() == node() && endPosition.deepEquivalent().node()->shadowAncestorNode() == node());
- Selection newSelection = Selection(startPosition, endPosition);
+ VisibleSelection newSelection = VisibleSelection(startPosition, endPosition);
if (Frame* frame = document()->frame())
frame->selection()->setSelection(newSelection);
@@ -247,10 +260,10 @@ void RenderTextControl::setSelectionRange(int start, int end)
frame->setSelectionGranularity(CharacterGranularity);
}
-Selection RenderTextControl::selection(int start, int end) const
+VisibleSelection RenderTextControl::selection(int start, int end) const
{
- return Selection(VisiblePosition(m_innerText.get(), start, VP_DEFAULT_AFFINITY),
- VisiblePosition(m_innerText.get(), end, VP_DEFAULT_AFFINITY));
+ return VisibleSelection(VisiblePosition(m_innerText.get(), start, VP_DEFAULT_AFFINITY),
+ VisiblePosition(m_innerText.get(), end, VP_DEFAULT_AFFINITY));
}
VisiblePosition RenderTextControl::visiblePositionForIndex(int index)
@@ -279,7 +292,7 @@ int RenderTextControl::indexForVisiblePosition(const VisiblePosition& pos)
RefPtr<Range> range = Range::create(document());
range->setStart(m_innerText.get(), 0, ec);
ASSERT(!ec);
- range->setEnd(indexPosition.node(), indexPosition.offset(), ec);
+ range->setEnd(indexPosition.node(), indexPosition.m_offset, ec);
ASSERT(!ec);
return TextIterator::rangeLength(range.get());
}
@@ -367,7 +380,7 @@ String RenderTextControl::textWithHardLineBreaks()
if (!renderer)
return "";
- InlineBox* box = renderer->isText() ? toRenderText(renderer)->firstTextBox() : renderer->inlineBoxWrapper();
+ InlineBox* box = renderer->isText() ? toRenderText(renderer)->firstTextBox() : toRenderBox(renderer)->inlineBoxWrapper();
if (!box)
return "";
@@ -434,15 +447,16 @@ void RenderTextControl::calcHeight()
setHeight(height() + paddingTop() + paddingBottom() + borderTop() + borderBottom());
// We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
- if (m_innerText->renderer()->style()->overflowX() == OSCROLL || (m_innerText->renderer()->style()->overflowX() == OAUTO && m_innerText->renderer()->style()->wordWrap() == NormalWordWrap))
+ if (style()->overflowX() == OSCROLL || (style()->overflowX() == OAUTO && m_innerText->renderer()->style()->wordWrap() == NormalWordWrap))
setHeight(height() + scrollbarThickness());
RenderBlock::calcHeight();
}
-void RenderTextControl::hitInnerTextBlock(HitTestResult& result, int xPos, int yPos, int tx, int ty)
+void RenderTextControl::hitInnerTextElement(HitTestResult& result, int xPos, int yPos, int tx, int ty)
{
result.setInnerNode(m_innerText.get());
+ result.setInnerNonSharedNode(m_innerText.get());
result.setLocalPoint(IntPoint(xPos - tx - x() - m_innerText->renderBox()->x(),
yPos - ty - y() - m_innerText->renderBox()->y()));
}
@@ -517,7 +531,7 @@ void RenderTextControl::selectionChanged(bool userTriggered)
if (Frame* frame = document()->frame()) {
if (frame->selection()->isRange() && userTriggered)
- static_cast<EventTargetNode*>(node())->dispatchEventForType(eventNames().selectEvent, true, false);
+ node()->dispatchEventForType(eventNames().selectEvent, true, false);
}
}
@@ -526,61 +540,6 @@ void RenderTextControl::addFocusRingRects(GraphicsContext* graphicsContext, int
graphicsContext->addFocusRingRect(IntRect(tx, ty, width(), height()));
}
-void RenderTextControl::autoscroll()
-{
- RenderLayer* layer = m_innerText->renderBox()->layer();
- if (layer)
- layer->autoscroll();
-}
-
-int RenderTextControl::scrollWidth() const
-{
- if (m_innerText)
- return m_innerText->scrollWidth();
- return RenderBlock::scrollWidth();
-}
-
-int RenderTextControl::scrollHeight() const
-{
- if (m_innerText)
- return m_innerText->scrollHeight();
- return RenderBlock::scrollHeight();
-}
-
-int RenderTextControl::scrollLeft() const
-{
- if (m_innerText)
- return m_innerText->scrollLeft();
- return RenderBlock::scrollLeft();
-}
-
-int RenderTextControl::scrollTop() const
-{
- if (m_innerText)
- return m_innerText->scrollTop();
- return RenderBlock::scrollTop();
-}
-
-void RenderTextControl::setScrollLeft(int newLeft)
-{
- if (m_innerText)
- m_innerText->setScrollLeft(newLeft);
-}
-
-void RenderTextControl::setScrollTop(int newTop)
-{
- if (m_innerText)
- m_innerText->setScrollTop(newTop);
-}
-
-bool RenderTextControl::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
-{
- RenderLayer* layer = m_innerText->renderBox()->layer();
- if (layer && layer->scroll(direction, granularity, multiplier))
- return true;
- return RenderBlock::scroll(direction, granularity, multiplier);
-}
-
HTMLElement* RenderTextControl::innerTextElement() const
{
return m_innerText.get();
diff --git a/WebCore/rendering/RenderTextControl.h b/WebCore/rendering/RenderTextControl.h
index 86d3f8a..e4f7747 100644
--- a/WebCore/rendering/RenderTextControl.h
+++ b/WebCore/rendering/RenderTextControl.h
@@ -27,7 +27,7 @@
namespace WebCore {
class FormControlElement;
-class Selection;
+class VisibleSelection;
class TextControlInnerElement;
class TextControlInnerTextElement;
@@ -36,6 +36,7 @@ public:
virtual ~RenderTextControl();
virtual const char* renderName() const { return "RenderTextControl"; }
+ virtual bool isTextControl() const { return true; }
virtual bool hasControlClip() const { return false; }
virtual IntRect controlClipRect(int tx, int ty) const;
virtual void calcHeight();
@@ -45,8 +46,8 @@ public:
virtual bool canHaveChildren() const { return false; }
virtual bool avoidsFloats() const { return true; }
- virtual bool isEdited() const { return m_edited; }
- virtual void setEdited(bool isEdited) { m_edited = isEdited; }
+ bool isEdited() const { return m_edited; }
+ void setEdited(bool isEdited) { m_edited = isEdited; }
bool isUserEdited() const { return m_userEdited; }
void setUserEdited(bool isUserEdited);
@@ -57,7 +58,7 @@ public:
void setSelectionEnd(int);
void select();
void setSelectionRange(int start, int end);
- Selection selection(int start, int end) const;
+ VisibleSelection selection(int start, int end) const;
virtual void subtreeHasChanged();
String text();
@@ -67,16 +68,6 @@ public:
virtual void addFocusRingRects(GraphicsContext*, int tx, int ty);
virtual bool canBeProgramaticallyScrolled(bool) const { return true; }
- virtual void autoscroll();
-
- // Subclassed to forward to our inner div.
- virtual int scrollLeft() const;
- virtual int scrollTop() const;
- virtual int scrollWidth() const;
- virtual int scrollHeight() const;
- virtual void setScrollLeft(int);
- virtual void setScrollTop(int);
- virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
VisiblePosition visiblePositionForIndex(int index);
int indexForVisiblePosition(const VisiblePosition&);
@@ -88,10 +79,10 @@ protected:
void adjustInnerTextStyle(const RenderStyle* startStyle, RenderStyle* textBlockStyle) const;
void setInnerTextValue(const String&);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void createSubtreeIfNeeded(TextControlInnerElement* innerBlock);
- void hitInnerTextBlock(HitTestResult&, int x, int y, int tx, int ty);
+ void hitInnerTextElement(HitTestResult&, int x, int y, int tx, int ty);
void forwardEvent(Event*);
int textBlockWidth() const;
@@ -115,6 +106,21 @@ private:
RefPtr<TextControlInnerTextElement> m_innerText;
};
+inline RenderTextControl* toRenderTextControl(RenderObject* o)
+{
+ ASSERT(!o || o->isTextControl());
+ return static_cast<RenderTextControl*>(o);
+}
+
+inline const RenderTextControl* toRenderTextControl(const RenderObject* o)
+{
+ ASSERT(!o || o->isTextControl());
+ return static_cast<const RenderTextControl*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderTextControl(const RenderTextControl*);
+
} // namespace WebCore
#endif // RenderTextControl_h
diff --git a/WebCore/rendering/RenderTextControlMultiLine.cpp b/WebCore/rendering/RenderTextControlMultiLine.cpp
index 253f53f..271fb12 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.cpp
+++ b/WebCore/rendering/RenderTextControlMultiLine.cpp
@@ -55,54 +55,15 @@ void RenderTextControlMultiLine::subtreeHasChanged()
frame->textDidChangeInTextArea(static_cast<Element*>(node()));
}
-void RenderTextControlMultiLine::layout()
-{
- int oldHeight = height();
- calcHeight();
-
-#ifdef ANDROID_LAYOUT
- int oldVisibleWidth = m_visibleWidth;
-#endif
-
- int oldWidth = width();
- calcWidth();
-
- bool relayoutChildren = oldHeight != height() || oldWidth != width();
-#ifdef ANDROID_LAYOUT
- if (oldVisibleWidth != m_visibleWidth
- && document()->settings()->layoutAlgorithm() == Settings::kLayoutFitColumnToScreen) {
- relayoutChildren = true;
- }
-#endif
-
- RenderBox* innerTextRenderer = innerTextElement()->renderBox();
-
- // Set the text block height
- int desiredHeight = textBlockHeight();
- if (desiredHeight != innerTextRenderer->height())
- relayoutChildren = true;
- innerTextRenderer->style()->setHeight(Length(desiredHeight, Fixed));
-
- // Set the text block width
- int desiredWidth = textBlockWidth();
- if (desiredWidth != innerTextRenderer->width())
- relayoutChildren = true;
- innerTextRenderer->style()->setWidth(Length(desiredWidth, Fixed));
-
- RenderBlock::layoutBlock(relayoutChildren);
-}
-
bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction))
return false;
- if (result.innerNode() == element()) {
- hitInnerTextBlock(result, x, y, tx, ty);
- return true;
- }
+ if (result.innerNode() == node() || result.innerNode() == innerTextElement())
+ hitInnerTextElement(result, x, y, tx, ty);
- return false;
+ return true;
}
void RenderTextControlMultiLine::forwardEvent(Event* event)
@@ -146,10 +107,9 @@ PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const R
adjustInnerTextStyle(startStyle, textBlockStyle.get());
- // Forward overflow properties.
- textBlockStyle->setOverflowX(startStyle->overflowX() == OVISIBLE ? OAUTO : startStyle->overflowX());
- textBlockStyle->setOverflowY(startStyle->overflowY() == OVISIBLE ? OAUTO : startStyle->overflowY());
-
+ // FIXME: This code should just map wrap into CSS in the DOM code.
+ // Then here we should set the textBlockStyle appropriately based off this
+ // object's style()->whiteSpace() and style->wordWrap().
// Set word wrap property based on wrap attribute.
if (static_cast<HTMLTextAreaElement*>(node())->shouldWrapText()) {
textBlockStyle->setWhiteSpace(PRE_WRAP);
diff --git a/WebCore/rendering/RenderTextControlMultiLine.h b/WebCore/rendering/RenderTextControlMultiLine.h
index 591a65d..579047d 100644
--- a/WebCore/rendering/RenderTextControlMultiLine.h
+++ b/WebCore/rendering/RenderTextControlMultiLine.h
@@ -33,7 +33,6 @@ public:
virtual bool isTextArea() const { return true; }
virtual void subtreeHasChanged();
- virtual void layout();
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
void forwardEvent(Event*);
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index fccea00..dd06501 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -174,8 +174,8 @@ void RenderTextControlSingleLine::subtreeHasChanged()
InputElement* input = inputElement();
input->setValueFromRenderer(input->constrainValue(text()));
- if (RenderObject* cancelButtonRenderer = m_cancelButton ? m_cancelButton->renderer() : 0)
- updateCancelButtonVisibility(cancelButtonRenderer->style());
+ if (m_cancelButton)
+ updateCancelButtonVisibility();
// If the incremental attribute is set, then dispatch the search event
if (input->searchEventsShouldBeDispatched())
@@ -281,12 +281,14 @@ bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, Hit
if (!RenderTextControl::nodeAtPoint(request, result, xPos, yPos, tx, ty, hitTestAction))
return false;
- if (result.innerNode() != element() && result.innerNode() != m_innerBlock.get())
- return false;
-
- hitInnerTextBlock(result, xPos, yPos, tx, ty);
+ // If we hit a node inside the inner text element, say that we hit that element,
+ // and if we hit our node (e.g. we're over the border or padding), also say that we hit the
+ // inner text element so that it gains focus.
+ if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == node())
+ hitInnerTextElement(result, xPos, yPos, tx, ty);
- if (!m_innerBlock)
+ // If we're not a search field, or we already found the results or cancel buttons, we're done.
+ if (!m_innerBlock || result.innerNode() == m_resultsButton || result.innerNode() == m_cancelButton)
return true;
Node* innerNode = 0;
@@ -334,7 +336,7 @@ void RenderTextControlSingleLine::forwardEvent(Event* event)
return;
}
- FloatPoint localPoint = innerTextRenderer->absoluteToLocal(FloatPoint(static_cast<MouseEvent*>(event)->pageX(), static_cast<MouseEvent*>(event)->pageY()), false, true);
+ FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true);
if (m_resultsButton && localPoint.x() < innerTextRenderer->borderBoxRect().x())
m_resultsButton->defaultEventHandler(event);
else if (m_cancelButton && localPoint.x() > innerTextRenderer->borderBoxRect().right())
@@ -343,7 +345,7 @@ void RenderTextControlSingleLine::forwardEvent(Event* event)
RenderTextControl::forwardEvent(event);
}
-void RenderTextControlSingleLine::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderTextControl::styleDidChange(diff, oldStyle);
@@ -360,6 +362,8 @@ void RenderTextControlSingleLine::styleDidChange(RenderStyle::Diff diff, const R
if (RenderObject* cancelRenderer = m_cancelButton ? m_cancelButton->renderer() : 0)
cancelRenderer->setStyle(createCancelButtonStyle(style()));
+
+ setHasOverflowClip(false);
}
void RenderTextControlSingleLine::capsLockStateMayHaveChanged()
@@ -425,7 +429,7 @@ int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineHeight)
{
if (RenderBox* resultsRenderer = m_resultsButton ? m_resultsButton->renderBox() : 0) {
- static_cast<RenderBlock*>(resultsRenderer)->calcHeight();
+ toRenderBlock(resultsRenderer)->calcHeight();
setHeight(max(height(),
resultsRenderer->borderTop() + resultsRenderer->borderBottom() +
resultsRenderer->paddingTop() + resultsRenderer->paddingBottom() +
@@ -434,7 +438,7 @@ void RenderTextControlSingleLine::adjustControlHeightBasedOnLineHeight(int lineH
}
if (RenderBox* cancelRenderer = m_cancelButton ? m_cancelButton->renderBox() : 0) {
- static_cast<RenderBlock*>(cancelRenderer)->calcHeight();
+ toRenderBlock(cancelRenderer)->calcHeight();
setHeight(max(height(),
cancelRenderer->borderTop() + cancelRenderer->borderBottom() +
cancelRenderer->paddingTop() + cancelRenderer->paddingBottom() +
@@ -482,8 +486,8 @@ void RenderTextControlSingleLine::updateFromElement()
bool placeholderVisibilityShouldChange = m_placeholderVisible != placeholderShouldBeVisible();
m_placeholderVisible = placeholderShouldBeVisible();
- if (RenderObject* cancelButtonRenderer = m_cancelButton ? m_cancelButton->renderer() : 0)
- updateCancelButtonVisibility(cancelButtonRenderer->style());
+ if (m_cancelButton)
+ updateCancelButtonVisibility();
if (m_placeholderVisible) {
ExceptionCode ec = 0;
@@ -505,7 +509,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
{
RefPtr<RenderStyle> textBlockStyle;
if (placeholderShouldBeVisible()) {
- RenderStyle* pseudoStyle = getCachedPseudoStyle(RenderStyle::INPUT_PLACEHOLDER);
+ RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER);
textBlockStyle = RenderStyle::clone(pseudoStyle);
} else {
textBlockStyle = RenderStyle::create();
@@ -562,11 +566,11 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createResultsButtonStyle(co
RefPtr<RenderStyle> resultsBlockStyle;
if (input->maxResults() < 0)
- resultsBlockStyle = getCachedPseudoStyle(RenderStyle::SEARCH_DECORATION);
+ resultsBlockStyle = getCachedPseudoStyle(SEARCH_DECORATION);
else if (!input->maxResults())
- resultsBlockStyle = getCachedPseudoStyle(RenderStyle::SEARCH_RESULTS_DECORATION);
+ resultsBlockStyle = getCachedPseudoStyle(SEARCH_RESULTS_DECORATION);
else
- resultsBlockStyle = getCachedPseudoStyle(RenderStyle::SEARCH_RESULTS_BUTTON);
+ resultsBlockStyle = getCachedPseudoStyle(SEARCH_RESULTS_BUTTON);
if (!resultsBlockStyle)
resultsBlockStyle = RenderStyle::create();
@@ -582,7 +586,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createCancelButtonStyle(con
ASSERT(node()->isHTMLElement());
RefPtr<RenderStyle> cancelBlockStyle;
- if (RefPtr<RenderStyle> pseudoStyle = getCachedPseudoStyle(RenderStyle::SEARCH_CANCEL_BUTTON))
+ if (RefPtr<RenderStyle> pseudoStyle = getCachedPseudoStyle(SEARCH_CANCEL_BUTTON))
// We may be sharing style with another search field, but we must not share the cancel button style.
cancelBlockStyle = RenderStyle::clone(pseudoStyle.get());
else
@@ -591,15 +595,30 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createCancelButtonStyle(con
if (startStyle)
cancelBlockStyle->inheritFrom(startStyle);
- updateCancelButtonVisibility(cancelBlockStyle.get());
+ cancelBlockStyle->setVisibility(visibilityForCancelButton());
return cancelBlockStyle.release();
}
-void RenderTextControlSingleLine::updateCancelButtonVisibility(RenderStyle* style) const
+void RenderTextControlSingleLine::updateCancelButtonVisibility() const
+{
+ if (!m_cancelButton->renderer())
+ return;
+
+ const RenderStyle* curStyle = m_cancelButton->renderer()->style();
+ EVisibility buttonVisibility = visibilityForCancelButton();
+ if (curStyle->visibility() == buttonVisibility)
+ return;
+
+ RefPtr<RenderStyle> cancelButtonStyle = RenderStyle::clone(curStyle);
+ cancelButtonStyle->setVisibility(buttonVisibility);
+ m_cancelButton->renderer()->setStyle(cancelButtonStyle);
+}
+
+EVisibility RenderTextControlSingleLine::visibilityForCancelButton() const
{
ASSERT(node()->isHTMLElement());
HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
- style->setVisibility(input->value().isEmpty() ? HIDDEN : VISIBLE);
+ return input->value().isEmpty() ? HIDDEN : VISIBLE;
}
const AtomicString& RenderTextControlSingleLine::autosaveName() const
@@ -684,7 +703,7 @@ PopupMenuStyle RenderTextControlSingleLine::itemStyle(unsigned) const
PopupMenuStyle RenderTextControlSingleLine::menuStyle() const
{
- return PopupMenuStyle(style()->color(), style()->backgroundColor(), style()->font(), style()->visibility() == VISIBLE);
+ return PopupMenuStyle(style()->color(), style()->backgroundColor(), style()->font(), style()->visibility() == VISIBLE, style()->textIndent(), style()->direction());
}
int RenderTextControlSingleLine::clientInsetLeft() const
@@ -768,10 +787,65 @@ HostWindow* RenderTextControlSingleLine::hostWindow() const
return document()->view()->hostWindow();
}
+void RenderTextControlSingleLine::autoscroll()
+{
+ RenderLayer* layer = innerTextElement()->renderBox()->layer();
+ if (layer)
+ layer->autoscroll();
+}
+
+int RenderTextControlSingleLine::scrollWidth() const
+{
+ if (innerTextElement())
+ return innerTextElement()->scrollWidth();
+ return RenderBlock::scrollWidth();
+}
+
+int RenderTextControlSingleLine::scrollHeight() const
+{
+ if (innerTextElement())
+ return innerTextElement()->scrollHeight();
+ return RenderBlock::scrollHeight();
+}
+
+int RenderTextControlSingleLine::scrollLeft() const
+{
+ if (innerTextElement())
+ return innerTextElement()->scrollLeft();
+ return RenderBlock::scrollLeft();
+}
+
+int RenderTextControlSingleLine::scrollTop() const
+{
+ if (innerTextElement())
+ return innerTextElement()->scrollTop();
+ return RenderBlock::scrollTop();
+}
+
+void RenderTextControlSingleLine::setScrollLeft(int newLeft)
+{
+ if (innerTextElement())
+ innerTextElement()->setScrollLeft(newLeft);
+}
+
+void RenderTextControlSingleLine::setScrollTop(int newTop)
+{
+ if (innerTextElement())
+ innerTextElement()->setScrollTop(newTop);
+}
+
+bool RenderTextControlSingleLine::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
+{
+ RenderLayer* layer = innerTextElement()->renderBox()->layer();
+ if (layer && layer->scroll(direction, granularity, multiplier))
+ return true;
+ return RenderBlock::scroll(direction, granularity, multiplier);
+}
+
PassRefPtr<Scrollbar> RenderTextControlSingleLine::createScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
{
RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = style()->hasPseudoStyle(RenderStyle::SCROLLBAR);
+ bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
widget = RenderScrollbar::createCustomScrollbar(client, orientation, this);
else
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index a7b58e1..23352b4 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -59,9 +59,20 @@ public:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
void forwardEvent(Event*);
-private:
- virtual void capsLockStateMayHaveChanged();
+ void capsLockStateMayHaveChanged();
+
+ virtual void autoscroll();
+ // Subclassed to forward to our inner div.
+ virtual int scrollLeft() const;
+ virtual int scrollTop() const;
+ virtual int scrollWidth() const;
+ virtual int scrollHeight() const;
+ virtual void setScrollLeft(int);
+ virtual void setScrollTop(int);
+ virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
+
+private:
int textBlockWidth() const;
virtual int preferredContentWidth(float charWidth) const;
virtual void adjustControlHeightBasedOnLineHeight(int lineHeight);
@@ -69,14 +80,15 @@ private:
void createSubtreeIfNeeded();
virtual void updateFromElement();
virtual void cacheSelection(int start, int end);
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const;
PassRefPtr<RenderStyle> createInnerBlockStyle(const RenderStyle* startStyle) const;
PassRefPtr<RenderStyle> createResultsButtonStyle(const RenderStyle* startStyle) const;
PassRefPtr<RenderStyle> createCancelButtonStyle(const RenderStyle* startStyle) const;
- void updateCancelButtonVisibility(RenderStyle*) const;
+ void updateCancelButtonVisibility() const;
+ EVisibility visibilityForCancelButton() const;
const AtomicString& autosaveName() const;
void startSearchEventTimer();
diff --git a/WebCore/rendering/RenderTextFragment.cpp b/WebCore/rendering/RenderTextFragment.cpp
index c8beba0..7da9e5a 100644
--- a/WebCore/rendering/RenderTextFragment.cpp
+++ b/WebCore/rendering/RenderTextFragment.cpp
@@ -46,7 +46,7 @@ RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str)
PassRefPtr<StringImpl> RenderTextFragment::originalText() const
{
- Node* e = element();
+ Node* e = node();
RefPtr<StringImpl> result = (e ? static_cast<Text*>(e)->string() : contentString());
if (result && (start() > 0 || start() < result->length()))
result = result->substring(start(), end());
@@ -75,7 +75,7 @@ void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
UChar RenderTextFragment::previousCharacter()
{
if (start()) {
- Node* e = element();
+ Node* e = node();
StringImpl* original = (e ? static_cast<Text*>(e)->string() : contentString());
if (original)
return (*original)[start() - 1];
diff --git a/WebCore/rendering/RenderTheme.cpp b/WebCore/rendering/RenderTheme.cpp
index e7fa5de..f82f48c 100644
--- a/WebCore/rendering/RenderTheme.cpp
+++ b/WebCore/rendering/RenderTheme.cpp
@@ -581,7 +581,7 @@ ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
bool RenderTheme::isActive(const RenderObject* o) const
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -598,28 +598,43 @@ bool RenderTheme::isActive(const RenderObject* o) const
bool RenderTheme::isChecked(const RenderObject* o) const
{
- if (!o->element())
+ if (!o->node() || !o->node()->isElementNode())
return false;
- return o->element()->isChecked();
+
+ InputElement* inputElement = toInputElement(static_cast<Element*>(o->node()));
+ if (!inputElement)
+ return false;
+
+ return inputElement->isChecked();
}
bool RenderTheme::isIndeterminate(const RenderObject* o) const
{
- if (!o->element())
+ if (!o->node() || !o->node()->isElementNode())
+ return false;
+
+ InputElement* inputElement = toInputElement(static_cast<Element*>(o->node()));
+ if (!inputElement)
return false;
- return o->element()->isIndeterminate();
+
+ return inputElement->isIndeterminate();
}
bool RenderTheme::isEnabled(const RenderObject* o) const
{
- if (!o->element())
+ if (!o->node() || !o->node()->isElementNode())
+ return true;
+
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(o->node()));
+ if (!formControlElement)
return true;
- return o->element()->isEnabled();
+
+ return formControlElement->isEnabled();
}
bool RenderTheme::isFocused(const RenderObject* o) const
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
Document* document = node->document();
@@ -629,23 +644,28 @@ bool RenderTheme::isFocused(const RenderObject* o) const
bool RenderTheme::isPressed(const RenderObject* o) const
{
- if (!o->element())
+ if (!o->node())
return false;
- return o->element()->active();
+ return o->node()->active();
}
bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
{
- if (!o->element())
+ if (!o->node() || !o->node()->isElementNode())
+ return false;
+
+ FormControlElement* formControlElement = toFormControlElement(static_cast<Element*>(o->node()));
+ if (!formControlElement)
return false;
- return o->element()->isReadOnlyControl();
+
+ return formControlElement->isReadOnlyControl();
}
bool RenderTheme::isHovered(const RenderObject* o) const
{
- if (!o->element())
+ if (!o->node())
return false;
- return o->element()->hovered();
+ return o->node()->hovered();
}
bool RenderTheme::isDefault(const RenderObject* o) const
@@ -721,10 +741,6 @@ void RenderTheme::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle*, Ele
{
}
-void RenderTheme::adjustButtonInnerStyle(RenderStyle*) const
-{
-}
-
void RenderTheme::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle*, Element*) const
{
}
diff --git a/WebCore/rendering/RenderTheme.h b/WebCore/rendering/RenderTheme.h
index 828e789..15a81fa 100644
--- a/WebCore/rendering/RenderTheme.h
+++ b/WebCore/rendering/RenderTheme.h
@@ -29,6 +29,7 @@
#else
#include "ThemeTypes.h"
#endif
+#include "ScrollTypes.h"
namespace WebCore {
@@ -128,14 +129,21 @@ public:
virtual int minimumMenuListSize(RenderStyle*) const { return 0; }
- virtual void adjustButtonInnerStyle(RenderStyle*) const;
virtual void adjustSliderThumbSize(RenderObject*) const;
virtual int popupInternalPaddingLeft(RenderStyle*) const { return 0; }
virtual int popupInternalPaddingRight(RenderStyle*) const { return 0; }
virtual int popupInternalPaddingTop(RenderStyle*) const { return 0; }
virtual int popupInternalPaddingBottom(RenderStyle*) const { return 0; }
-
+ virtual bool popupOptionSupportsTextIndent() const { return false; }
+
+ virtual int buttonInternalPaddingLeft() const { return 0; }
+ virtual int buttonInternalPaddingRight() const { return 0; }
+ virtual int buttonInternalPaddingTop() const { return 0; }
+ virtual int buttonInternalPaddingBottom() const { return 0; }
+
+ virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return RegularScrollbar; }
+
// Method for painting the caps lock indicator
virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) { return 0; };
diff --git a/WebCore/rendering/RenderThemeChromiumGtk.cpp b/WebCore/rendering/RenderThemeChromiumGtk.cpp
deleted file mode 100644
index 220ce07..0000000
--- a/WebCore/rendering/RenderThemeChromiumGtk.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.
- * Copyright (C) 2007 Alp Toker <alp@atoker.com>
- * Copyright (C) 2008 Collabora Ltd.
- * Copyright (C) 2008, 2009 Google Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "RenderThemeChromiumGtk.h"
-
-#include "ChromiumBridge.h"
-#include "CSSValueKeywords.h"
-#include "GraphicsContext.h"
-#include "NotImplemented.h"
-#include "PlatformContextSkia.h"
-#include "RenderObject.h"
-#include "ScrollbarTheme.h"
-#include "gtkdrawing.h"
-#include "GdkSkia.h"
-#include "TransformationMatrix.h"
-#include "UserAgentStyleSheets.h"
-
-#include <gdk/gdk.h>
-
-namespace WebCore {
-
-enum PaddingType {
- TopPadding,
- RightPadding,
- BottomPadding,
- LeftPadding
-};
-
-static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 };
-
-// The default variable-width font size. We use this as the default font
-// size for the "system font", and as a base size (which we then shrink) for
-// form control fonts.
-static float DefaultFontSize = 16.0;
-
-static Color makeColor(const GdkColor& c)
-{
- return Color(makeRGB(c.red >> 8, c.green >> 8, c.blue >> 8));
-}
-
-// We aim to match IE here.
-// -IE uses a font based on the encoding as the default font for form controls.
-// -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT),
-// which returns MS Shell Dlg)
-// -Safari uses Lucida Grande.
-//
-// FIXME: The only case where we know we don't match IE is for ANSI encodings.
-// IE uses MS Shell Dlg there, which we render incorrectly at certain pixel
-// sizes (e.g. 15px). So, for now we just use Arial.
-static const char* defaultGUIFont(Document* document)
-{
- return "Arial";
-}
-
-// Converts points to pixels. One point is 1/72 of an inch.
-static float pointsToPixels(float points)
-{
- static float pixelsPerInch = 0.0f;
- if (!pixelsPerInch) {
- GdkScreen* screen = gdk_screen_get_default();
- // FIXME: I'm getting floating point values of ~75 and ~100,
- // and it's making my fonts look all wrong. Figure this out.
-#if 0
- if (screen)
- pixelsPerInch = gdk_screen_get_resolution(screen);
- else
-#endif
- pixelsPerInch = 96.0f; // Match the default we set on Windows.
- }
-
- static const float pointsPerInch = 72.0f;
- return points / pointsPerInch * pixelsPerInch;
-}
-
-static void setSizeIfAuto(RenderStyle* style, const IntSize& size)
-{
- if (style->width().isIntrinsicOrAuto())
- style->setWidth(Length(size.width(), Fixed));
- if (style->height().isAuto())
- style->setHeight(Length(size.height(), Fixed));
-}
-
-static bool supportsFocus(ControlPart appearance)
-{
- switch (appearance) {
- case PushButtonPart:
- case ButtonPart:
- case TextFieldPart:
- case TextAreaPart:
- case SearchFieldPart:
- case MenulistPart:
- case RadioPart:
- case CheckboxPart:
- return true;
- default:
- return false;
- }
-}
-
-static GtkTextDirection gtkTextDirection(TextDirection direction)
-{
- switch (direction) {
- case RTL:
- return GTK_TEXT_DIR_RTL;
- case LTR:
- return GTK_TEXT_DIR_LTR;
- default:
- return GTK_TEXT_DIR_NONE;
- }
-}
-
-static void setMozState(RenderTheme* theme, GtkWidgetState* state, RenderObject* o)
-{
- state->active = theme->isPressed(o);
- state->focused = theme->isFocused(o);
- state->inHover = theme->isHovered(o);
- // FIXME: Disabled does not always give the correct appearance for ReadOnly
- state->disabled = !theme->isEnabled(o) || theme->isReadOnlyControl(o);
- state->isDefault = false;
- state->canDefault = false;
- state->depressed = false;
-}
-
-static bool paintMozWidget(RenderTheme* theme, GtkThemeWidgetType type, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- // Painting is disabled so just claim to have succeeded
- if (i.context->paintingDisabled())
- return false;
-
- GtkWidgetState mozState;
- setMozState(theme, &mozState, o);
-
- int flags;
-
- // We might want to make setting flags the caller's job at some point rather than doing it here.
- switch (type) {
- case MOZ_GTK_BUTTON:
- flags = GTK_RELIEF_NORMAL;
- break;
- case MOZ_GTK_CHECKBUTTON:
- case MOZ_GTK_RADIOBUTTON:
- flags = theme->isChecked(o);
- break;
- default:
- flags = 0;
- break;
- }
-
- PlatformContextSkia* pcs = i.context->platformContext();
- SkCanvas* canvas = pcs->canvas();
- if (!canvas)
- return false;
-
- GdkRectangle gdkRect;
- gdkRect.x = rect.x();
- gdkRect.y = rect.y();
- gdkRect.width = rect.width();
- gdkRect.height = rect.height();
-
- // getTotalClip returns the currently set clip region in device coordinates,
- // so we have to apply the current transform (actually we only support translations)
- // to get the page coordinates that our gtk widget rendering expects.
- // We invert it because we want to map from device coordinates to page coordinates.
- const SkIRect clipRegion = canvas->getTotalClip().getBounds();
- TransformationMatrix ctm = i.context->getCTM().inverse();
- IntPoint pos = ctm.mapPoint(IntPoint(SkScalarRound(clipRegion.fLeft), SkScalarRound(clipRegion.fTop)));
- GdkRectangle gdkClipRect;
- gdkClipRect.x = pos.x();
- gdkClipRect.y = pos.y();
- gdkClipRect.width = clipRegion.width();
- gdkClipRect.height = clipRegion.height();
-
- // moz_gtk_widget_paint will paint outside the bounds of gdkRect unless we further restrict |gdkClipRect|.
- gdk_rectangle_intersect(&gdkRect, &gdkClipRect, &gdkClipRect);
-
- GtkTextDirection direction = gtkTextDirection(o->style()->direction());
-
- return moz_gtk_widget_paint(type, pcs->gdk_skia(), &gdkRect, &gdkClipRect, &mozState, flags, direction) != MOZ_GTK_SUCCESS;
-}
-
-static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, RenderTheme* renderTheme)
-{
- // FIXME: Make sure this function doesn't get called many times for a single GTK+ style change signal.
- renderTheme->platformColorsDidChange();
-}
-
-static double querySystemBlinkInterval(double defaultInterval)
-{
- GtkSettings* settings = gtk_settings_get_default();
-
- gboolean shouldBlink;
- gint time;
-
- g_object_get(settings, "gtk-cursor-blink", &shouldBlink, "gtk-cursor-blink-time", &time, NULL);
-
- if (!shouldBlink)
- return 0;
-
- return time / 1000.0;
-}
-
-// Implement WebCore::theme() for getting the global RenderTheme.
-RenderTheme* theme()
-{
- static RenderThemeChromiumGtk gtkTheme;
- return &gtkTheme;
-}
-
-RenderThemeChromiumGtk::RenderThemeChromiumGtk()
- : m_gtkWindow(0)
- , m_gtkContainer(0)
- , m_gtkEntry(0)
- , m_gtkTreeView(0)
-{
-}
-
-// Use the Windows style sheets to match their metrics.
-String RenderThemeChromiumGtk::extraDefaultStyleSheet()
-{
- return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
-}
-
-String RenderThemeChromiumGtk::extraQuirksStyleSheet()
-{
- return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet));
-}
-
-bool RenderThemeChromiumGtk::supportsFocusRing(const RenderStyle* style) const
-{
- return supportsFocus(style->appearance());
-}
-
-Color RenderThemeChromiumGtk::platformActiveSelectionBackgroundColor() const
-{
- GtkWidget* widget = gtkEntry();
- return makeColor(widget->style->base[GTK_STATE_SELECTED]);
-}
-
-Color RenderThemeChromiumGtk::platformInactiveSelectionBackgroundColor() const
-{
- GtkWidget* widget = gtkEntry();
- return makeColor(widget->style->base[GTK_STATE_ACTIVE]);
-}
-
-Color RenderThemeChromiumGtk::platformActiveSelectionForegroundColor() const
-{
- GtkWidget* widget = gtkEntry();
- return makeColor(widget->style->text[GTK_STATE_SELECTED]);
-}
-
-Color RenderThemeChromiumGtk::platformInactiveSelectionForegroundColor() const
-{
- GtkWidget* widget = gtkEntry();
- return makeColor(widget->style->text[GTK_STATE_ACTIVE]);
-}
-
-Color RenderThemeChromiumGtk::platformTextSearchHighlightColor() const
-{
- return Color(255, 255, 150);
-}
-
-double RenderThemeChromiumGtk::caretBlinkInterval() const
-{
- // Disable the blinking caret in layout test mode, as it introduces
- // a race condition for the pixel tests. http://b/1198440
- if (ChromiumBridge::layoutTestMode())
- return 0;
-
- // We cache the interval so we don't have to repeatedly request it from gtk.
- static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval());
- return blinkInterval;
-}
-
-void RenderThemeChromiumGtk::systemFont(int propId, Document* document, FontDescription& fontDescription) const
-{
- const char* faceName = 0;
- float fontSize = 0;
- // FIXME: see also RenderThemeChromiumWin.cpp
- switch (propId) {
- case CSSValueMenu:
- case CSSValueStatusBar:
- case CSSValueSmallCaption:
- // triggered by LayoutTests/fast/css/css2-system-fonts.html
- notImplemented();
- break;
- case CSSValueWebkitMiniControl:
- case CSSValueWebkitSmallControl:
- case CSSValueWebkitControl:
- faceName = defaultGUIFont(document);
- // Why 2 points smaller? Because that's what Gecko does.
- fontSize = DefaultFontSize - pointsToPixels(2);
- break;
- default:
- faceName = defaultGUIFont(document);
- fontSize = DefaultFontSize;
- }
-
- // Only update if the size makes sense.
- if (fontSize > 0) {
- fontDescription.firstFamily().setFamily(faceName);
- fontDescription.setSpecifiedSize(fontSize);
- fontDescription.setIsAbsoluteSize(true);
- fontDescription.setGenericFamily(FontDescription::NoFamily);
- fontDescription.setWeight(FontWeightNormal);
- fontDescription.setItalic(false);
- }
-}
-
-int RenderThemeChromiumGtk::minimumMenuListSize(RenderStyle* style) const
-{
- return 0;
-}
-
-bool RenderThemeChromiumGtk::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect);
-}
-
-void RenderThemeChromiumGtk::setCheckboxSize(RenderStyle* style) const
-{
- // If the width and height are both specified, then we have nothing to do.
- if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
- return;
-
- // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for now. It matches Firefox.
- // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
- // the higher DPI. Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
- // metrics.
- const IntSize size(13, 13);
- setSizeIfAuto(style, size);
-}
-
-bool RenderThemeChromiumGtk::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect);
-}
-
-void RenderThemeChromiumGtk::setRadioSize(RenderStyle* style) const
-{
- // Use same sizing for radio box as checkbox.
- setCheckboxSize(style);
-}
-
-bool RenderThemeChromiumGtk::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_BUTTON, o, i, rect);
-}
-
-bool RenderThemeChromiumGtk::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_ENTRY, o, i, rect);
-}
-
-bool RenderThemeChromiumGtk::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintTextField(o, i, rect);
-}
-
-bool RenderThemeChromiumGtk::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
-}
-
-bool RenderThemeChromiumGtk::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_DROPDOWN_ARROW, o, i, rect);
-}
-
-bool RenderThemeChromiumGtk::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect);
-}
-
-void RenderThemeChromiumGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
-{
- // Height is locked to auto on all browsers.
- style->setLineHeight(RenderStyle::initialLineHeight());
-}
-
-bool RenderThemeChromiumGtk::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
-{
- return paintMozWidget(this, MOZ_GTK_DROPDOWN, o, i, rect);
-}
-
-void RenderThemeChromiumGtk::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
-{
- adjustMenuListStyle(selector, style, e);
-}
-
-// Used to paint styled menulists (i.e. with a non-default border)
-bool RenderThemeChromiumGtk::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
-{
- return paintMenuList(o, i, r);
-}
-
-int RenderThemeChromiumGtk::popupInternalPaddingLeft(RenderStyle* style) const
-{
- return menuListInternalPadding(style, LeftPadding);
-}
-
-int RenderThemeChromiumGtk::popupInternalPaddingRight(RenderStyle* style) const
-{
- return menuListInternalPadding(style, RightPadding);
-}
-
-int RenderThemeChromiumGtk::popupInternalPaddingTop(RenderStyle* style) const
-{
- return menuListInternalPadding(style, TopPadding);
-}
-
-int RenderThemeChromiumGtk::popupInternalPaddingBottom(RenderStyle* style) const
-{
- return menuListInternalPadding(style, BottomPadding);
-}
-
-void RenderThemeChromiumGtk::adjustButtonInnerStyle(RenderStyle* style) const
-{
- // This inner padding matches Firefox.
- style->setPaddingTop(Length(1, Fixed));
- style->setPaddingRight(Length(3, Fixed));
- style->setPaddingBottom(Length(1, Fixed));
- style->setPaddingLeft(Length(3, Fixed));
-}
-
-bool RenderThemeChromiumGtk::controlSupportsTints(const RenderObject* o) const
-{
- return isEnabled(o);
-}
-
-Color RenderThemeChromiumGtk::activeListBoxSelectionBackgroundColor() const
-{
- GtkWidget* widget = gtkTreeView();
- return makeColor(widget->style->base[GTK_STATE_SELECTED]);
-}
-
-Color RenderThemeChromiumGtk::activeListBoxSelectionForegroundColor() const
-{
- GtkWidget* widget = gtkTreeView();
- return makeColor(widget->style->text[GTK_STATE_SELECTED]);
-}
-
-Color RenderThemeChromiumGtk::inactiveListBoxSelectionBackgroundColor() const
-{
- GtkWidget* widget = gtkTreeView();
- return makeColor(widget->style->base[GTK_STATE_ACTIVE]);
-}
-
-Color RenderThemeChromiumGtk::inactiveListBoxSelectionForegroundColor() const
-{
- GtkWidget* widget = gtkTreeView();
- return makeColor(widget->style->text[GTK_STATE_ACTIVE]);
-}
-
-GtkWidget* RenderThemeChromiumGtk::gtkEntry() const
-{
- if (m_gtkEntry)
- return m_gtkEntry;
-
- m_gtkEntry = gtk_entry_new();
- g_signal_connect(m_gtkEntry, "style-set", G_CALLBACK(gtkStyleSetCallback), theme());
- gtk_container_add(gtkContainer(), m_gtkEntry);
- gtk_widget_realize(m_gtkEntry);
-
- return m_gtkEntry;
-}
-
-GtkWidget* RenderThemeChromiumGtk::gtkTreeView() const
-{
- if (m_gtkTreeView)
- return m_gtkTreeView;
-
- m_gtkTreeView = gtk_tree_view_new();
- g_signal_connect(m_gtkTreeView, "style-set", G_CALLBACK(gtkStyleSetCallback), theme());
- gtk_container_add(gtkContainer(), m_gtkTreeView);
- gtk_widget_realize(m_gtkTreeView);
-
- return m_gtkTreeView;
-}
-
-GtkContainer* RenderThemeChromiumGtk::gtkContainer() const
-{
- if (m_gtkContainer)
- return m_gtkContainer;
-
- m_gtkWindow = gtk_window_new(GTK_WINDOW_POPUP);
- m_gtkContainer = GTK_CONTAINER(gtk_fixed_new());
- gtk_container_add(GTK_CONTAINER(m_gtkWindow), GTK_WIDGET(m_gtkContainer));
- gtk_widget_realize(m_gtkWindow);
-
- return m_gtkContainer;
-}
-
-int RenderThemeChromiumGtk::menuListInternalPadding(RenderStyle* style, int paddingType) const
-{
- // This internal padding is in addition to the user-supplied padding.
- // Matches the FF behavior.
- int padding = styledMenuListInternalPadding[paddingType];
-
- // Reserve the space for right arrow here. The rest of the padding is
- // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from
- // RenderMenuList to lay out the individual items in the popup.
- // If the MenuList actually has appearance "NoAppearance", then that means
- // we don't draw a button, so don't reserve space for it.
- const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding;
- if (paddingType == bar_type && style->appearance() != NoControlPart)
- padding += ScrollbarTheme::nativeTheme()->scrollbarThickness();
-
- return padding;
-}
-
-} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumLinux.cpp b/WebCore/rendering/RenderThemeChromiumLinux.cpp
new file mode 100644
index 0000000..8c6874d
--- /dev/null
+++ b/WebCore/rendering/RenderThemeChromiumLinux.cpp
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2007 Apple Inc.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008, 2009 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderThemeChromiumLinux.h"
+
+#include "ChromiumBridge.h"
+#include "CSSValueKeywords.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include "NotImplemented.h"
+#include "PlatformContextSkia.h"
+#include "RenderObject.h"
+#include "ScrollbarTheme.h"
+#include "TransformationMatrix.h"
+#include "UserAgentStyleSheets.h"
+
+#include "SkShader.h"
+#include "SkGradientShader.h"
+
+namespace WebCore {
+
+enum PaddingType {
+ TopPadding,
+ RightPadding,
+ BottomPadding,
+ LeftPadding
+};
+
+static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 };
+
+// The default variable-width font size. We use this as the default font
+// size for the "system font", and as a base size (which we then shrink) for
+// form control fonts.
+static const float DefaultFontSize = 16.0;
+
+static bool supportsFocus(ControlPart appearance)
+{
+ // This causes WebKit to draw the focus rings for us.
+ return false;
+}
+
+static void setSizeIfAuto(RenderStyle* style, const IntSize& size)
+{
+ if (style->width().isIntrinsicOrAuto())
+ style->setWidth(Length(size.width(), Fixed));
+ if (style->height().isAuto())
+ style->setHeight(Length(size.height(), Fixed));
+}
+
+// We aim to match IE here.
+// -IE uses a font based on the encoding as the default font for form controls.
+// -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT),
+// which returns MS Shell Dlg)
+// -Safari uses Lucida Grande.
+//
+// FIXME: The only case where we know we don't match IE is for ANSI encodings.
+// IE uses MS Shell Dlg there, which we render incorrectly at certain pixel
+// sizes (e.g. 15px). So, for now we just use Arial.
+static const char* defaultGUIFont(Document* document)
+{
+ return "Arial";
+}
+
+RenderTheme* theme()
+{
+ static RenderThemeChromiumLinux theme;
+ return &theme;
+}
+
+RenderThemeChromiumLinux::RenderThemeChromiumLinux()
+{
+}
+
+// Use the Windows style sheets to match their metrics.
+String RenderThemeChromiumLinux::extraDefaultStyleSheet()
+{
+ return String(themeChromiumWinUserAgentStyleSheet, sizeof(themeChromiumWinUserAgentStyleSheet));
+}
+
+String RenderThemeChromiumLinux::extraQuirksStyleSheet()
+{
+ return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet));
+}
+
+bool RenderThemeChromiumLinux::supportsFocusRing(const RenderStyle* style) const
+{
+ return supportsFocus(style->appearance());
+}
+
+Color RenderThemeChromiumLinux::platformActiveSelectionBackgroundColor() const
+{
+ return Color(0x1e, 0x90, 0xff);
+}
+
+Color RenderThemeChromiumLinux::platformInactiveSelectionBackgroundColor() const
+{
+ return Color(0xc8, 0xc8, 0xc8);
+}
+
+Color RenderThemeChromiumLinux::platformActiveSelectionForegroundColor() const
+{
+ return Color(0, 0, 0);
+}
+
+Color RenderThemeChromiumLinux::platformInactiveSelectionForegroundColor() const
+{
+ return Color(0x32, 0x32, 0x32);
+}
+
+Color RenderThemeChromiumLinux::platformTextSearchHighlightColor() const
+{
+ return Color(0xff, 0xff, 0x96);
+}
+
+double RenderThemeChromiumLinux::caretBlinkInterval() const
+{
+ // Disable the blinking caret in layout test mode, as it introduces
+ // a race condition for the pixel tests. http://b/1198440
+ if (ChromiumBridge::layoutTestMode())
+ return 0;
+
+ // We cache the interval so we don't have to repeatedly request it from gtk.
+ return 0.5;
+}
+
+void RenderThemeChromiumLinux::systemFont(int propId, Document* document, FontDescription& fontDescription) const
+{
+ float fontSize = DefaultFontSize;
+
+ switch (propId) {
+ case CSSValueWebkitMiniControl:
+ case CSSValueWebkitSmallControl:
+ case CSSValueWebkitControl:
+ // Why 2 points smaller? Because that's what Gecko does. Note that we
+ // are assuming a 96dpi screen, which is the default that we use on
+ // Windows.
+ static const float pointsPerInch = 72.0f;
+ static const float pixelsPerInch = 96.0f;
+ fontSize -= (2.0f / pointsPerInch) * pixelsPerInch;
+ break;
+ }
+
+ fontDescription.firstFamily().setFamily(defaultGUIFont(NULL));
+ fontDescription.setSpecifiedSize(fontSize);
+ fontDescription.setIsAbsoluteSize(true);
+ fontDescription.setGenericFamily(FontDescription::NoFamily);
+ fontDescription.setWeight(FontWeightNormal);
+ fontDescription.setItalic(false);
+}
+
+int RenderThemeChromiumLinux::minimumMenuListSize(RenderStyle* style) const
+{
+ return 0;
+}
+
+bool RenderThemeChromiumLinux::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ static Image* const checkedImage = Image::loadPlatformResource("linuxCheckboxOn").releaseRef();
+ static Image* const uncheckedImage = Image::loadPlatformResource("linuxCheckboxOff").releaseRef();
+
+ Image* image = this->isChecked(o) ? checkedImage : uncheckedImage;
+ i.context->drawImage(image, rect);
+ return false;
+}
+
+void RenderThemeChromiumLinux::setCheckboxSize(RenderStyle* style) const
+{
+ // If the width and height are both specified, then we have nothing to do.
+ if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
+ return;
+
+ // FIXME: A hard-coded size of 13 is used. This is wrong but necessary
+ // for now. It matches Firefox. At different DPI settings on Windows,
+ // querying the theme gives you a larger size that accounts for the higher
+ // DPI. Until our entire engine honors a DPI setting other than 96, we
+ // can't rely on the theme's metrics.
+ const IntSize size(13, 13);
+ setSizeIfAuto(style, size);
+}
+
+bool RenderThemeChromiumLinux::paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ static Image* const checkedImage = Image::loadPlatformResource("linuxRadioOn").releaseRef();
+ static Image* const uncheckedImage = Image::loadPlatformResource("linuxRadioOff").releaseRef();
+
+ Image* image = this->isChecked(o) ? checkedImage : uncheckedImage;
+ i.context->drawImage(image, rect);
+ return false;
+}
+
+void RenderThemeChromiumLinux::setRadioSize(RenderStyle* style) const
+{
+ // Use same sizing for radio box as checkbox.
+ setCheckboxSize(style);
+}
+
+static void paintButtonLike(RenderTheme* theme, RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect) {
+ SkCanvas* const canvas = i.context->platformContext()->canvas();
+ SkPaint paint;
+ SkRect skrect;
+ const int right = rect.x() + rect.width();
+ const int bottom = rect.y() + rect.height();
+
+ // If the button is too small, fallback to drawing a single, solid color
+ if (rect.width() < 5 || rect.height() < 5) {
+ paint.setARGB(0xff, 0xe9, 0xe9, 0xe9);
+ skrect.set(rect.x(), rect.y(), right, bottom);
+ canvas->drawRect(skrect, paint);
+ return;
+ }
+
+ const int borderAlpha = theme->isHovered(o) ? 0x80 : 0x55;
+ paint.setARGB(borderAlpha, 0, 0, 0);
+ canvas->drawLine(rect.x() + 1, rect.y(), right - 1, rect.y(), paint);
+ canvas->drawLine(right - 1, rect.y() + 1, right - 1, bottom - 1, paint);
+ canvas->drawLine(rect.x() + 1, bottom - 1, right - 1, bottom - 1, paint);
+ canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), bottom - 1, paint);
+
+ paint.setARGB(0xff, 0, 0, 0);
+ SkPoint p[2];
+ const int lightEnd = theme->isPressed(o) ? 1 : 0;
+ const int darkEnd = !lightEnd;
+ p[lightEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y()));
+ p[darkEnd].set(SkIntToScalar(rect.x()), SkIntToScalar(bottom - 1));
+ SkColor colors[2];
+ colors[0] = SkColorSetARGB(0xff, 0xf8, 0xf8, 0xf8);
+ colors[1] = SkColorSetARGB(0xff, 0xdd, 0xdd, 0xdd);
+
+ SkShader* s = SkGradientShader::CreateLinear(
+ p, colors, NULL, 2, SkShader::kClamp_TileMode, NULL);
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setShader(s);
+ s->unref();
+
+ skrect.set(rect.x() + 1, rect.y() + 1, right - 1, bottom - 1);
+ canvas->drawRect(skrect, paint);
+
+ paint.setShader(NULL);
+ paint.setARGB(0xff, 0xce, 0xce, 0xce);
+ canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint);
+ canvas->drawPoint(right - 2, rect.y() + 1, paint);
+ canvas->drawPoint(rect.x() + 1, bottom - 2, paint);
+ canvas->drawPoint(right - 2, bottom - 2, paint);
+}
+
+bool RenderThemeChromiumLinux::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ paintButtonLike(this, o, i, rect);
+ return false;
+}
+
+bool RenderThemeChromiumLinux::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ return true;
+}
+
+bool RenderThemeChromiumLinux::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ return true;
+}
+
+bool RenderThemeChromiumLinux::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ return true;
+}
+
+bool RenderThemeChromiumLinux::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ return true;
+}
+
+bool RenderThemeChromiumLinux::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ return true;
+}
+
+void RenderThemeChromiumLinux::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
+{
+ // Height is locked to auto on all browsers.
+ style->setLineHeight(RenderStyle::initialLineHeight());
+}
+
+bool RenderThemeChromiumLinux::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ SkCanvas* const canvas = i.context->platformContext()->canvas();
+ const int right = rect.x() + rect.width();
+ const int middle = rect.y() + rect.height() / 2;
+
+ paintButtonLike(this, o, i, rect);
+
+ SkPaint paint;
+ paint.setARGB(0xff, 0, 0, 0);
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ SkPath path;
+ path.moveTo(right - 13, middle - 3);
+ path.rLineTo(6, 0);
+ path.rLineTo(-3, 6);
+ path.close();
+ canvas->drawPath(path, paint);
+
+ return false;
+}
+
+void RenderThemeChromiumLinux::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ adjustMenuListStyle(selector, style, e);
+}
+
+// Used to paint styled menulists (i.e. with a non-default border)
+bool RenderThemeChromiumLinux::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& rect)
+{
+ return paintMenuList(o, i, rect);
+}
+
+int RenderThemeChromiumLinux::popupInternalPaddingLeft(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, LeftPadding);
+}
+
+int RenderThemeChromiumLinux::popupInternalPaddingRight(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, RightPadding);
+}
+
+int RenderThemeChromiumLinux::popupInternalPaddingTop(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, TopPadding);
+}
+
+int RenderThemeChromiumLinux::popupInternalPaddingBottom(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, BottomPadding);
+}
+
+int RenderThemeChromiumLinux::buttonInternalPaddingLeft() const
+{
+ return 3;
+}
+
+int RenderThemeChromiumLinux::buttonInternalPaddingRight() const
+{
+ return 3;
+}
+
+int RenderThemeChromiumLinux::buttonInternalPaddingTop() const
+{
+ return 1;
+}
+
+int RenderThemeChromiumLinux::buttonInternalPaddingBottom() const
+{
+ return 1;
+}
+
+bool RenderThemeChromiumLinux::controlSupportsTints(const RenderObject* o) const
+{
+ return isEnabled(o);
+}
+
+Color RenderThemeChromiumLinux::activeListBoxSelectionBackgroundColor() const
+{
+ return Color(0x28, 0x28, 0x28);
+}
+
+Color RenderThemeChromiumLinux::activeListBoxSelectionForegroundColor() const
+{
+ return Color(0, 0, 0);
+}
+
+Color RenderThemeChromiumLinux::inactiveListBoxSelectionBackgroundColor() const
+{
+ return Color(0xc8, 0xc8, 0xc8);
+}
+
+Color RenderThemeChromiumLinux::inactiveListBoxSelectionForegroundColor() const
+{
+ return Color(0x32, 0x32, 0x32);
+}
+
+int RenderThemeChromiumLinux::menuListInternalPadding(RenderStyle* style, int paddingType) const
+{
+ // This internal padding is in addition to the user-supplied padding.
+ // Matches the FF behavior.
+ int padding = styledMenuListInternalPadding[paddingType];
+
+ // Reserve the space for right arrow here. The rest of the padding is
+ // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from
+ // RenderMenuList to lay out the individual items in the popup.
+ // If the MenuList actually has appearance "NoAppearance", then that means
+ // we don't draw a button, so don't reserve space for it.
+ const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding;
+ if (paddingType == bar_type && style->appearance() != NoControlPart)
+ padding += ScrollbarTheme::nativeTheme()->scrollbarThickness();
+
+ return padding;
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumGtk.h b/WebCore/rendering/RenderThemeChromiumLinux.h
index 77d927f..dbe8dcc 100644
--- a/WebCore/rendering/RenderThemeChromiumGtk.h
+++ b/WebCore/rendering/RenderThemeChromiumLinux.h
@@ -25,19 +25,17 @@
*
*/
-#ifndef RenderThemeChromiumGtk_h
-#define RenderThemeChromiumGtk_h
+#ifndef RenderThemeChromiumLinux_h
+#define RenderThemeChromiumLinux_h
#include "RenderTheme.h"
-#include <gtk/gtk.h>
-
namespace WebCore {
- class RenderThemeChromiumGtk : public RenderTheme {
+ class RenderThemeChromiumLinux : public RenderTheme {
public:
- RenderThemeChromiumGtk();
- ~RenderThemeChromiumGtk() { }
+ RenderThemeChromiumLinux();
+ ~RenderThemeChromiumLinux() { }
virtual String extraDefaultStyleSheet();
virtual String extraQuirksStyleSheet();
@@ -100,7 +98,10 @@ namespace WebCore {
virtual int popupInternalPaddingTop(RenderStyle*) const;
virtual int popupInternalPaddingBottom(RenderStyle*) const;
- virtual void adjustButtonInnerStyle(RenderStyle* style) const;
+ virtual int buttonInternalPaddingLeft() const;
+ virtual int buttonInternalPaddingRight() const;
+ virtual int buttonInternalPaddingTop() const;
+ virtual int buttonInternalPaddingBottom() const;
// A method asking if the control changes its tint when the window has focus or not.
virtual bool controlSupportsTints(const RenderObject*) const;
@@ -115,20 +116,7 @@ namespace WebCore {
virtual Color inactiveListBoxSelectionForegroundColor() const;
private:
- // Hold the state
- GtkWidget* gtkEntry() const;
- GtkWidget* gtkTreeView() const;
-
- // Unmapped GdkWindow having a container. This is holding all our fake widgets
- GtkContainer* gtkContainer() const;
-
- private:
int menuListInternalPadding(RenderStyle*, int paddingType) const;
-
- mutable GtkWidget* m_gtkWindow;
- mutable GtkContainer* m_gtkContainer;
- mutable GtkWidget* m_gtkEntry;
- mutable GtkWidget* m_gtkTreeView;
};
} // namespace WebCore
diff --git a/WebCore/rendering/RenderThemeChromiumMac.h b/WebCore/rendering/RenderThemeChromiumMac.h
index b750213..29286d8 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.h
+++ b/WebCore/rendering/RenderThemeChromiumMac.h
@@ -25,6 +25,7 @@
#define RenderThemeChromiumMac_h
#import "RenderTheme.h"
+#import <AppKit/AppKit.h>
#import <wtf/HashMap.h>
#import <wtf/RetainPtr.h>
@@ -77,6 +78,8 @@ namespace WebCore {
virtual int popupInternalPaddingTop(RenderStyle*) const;
virtual int popupInternalPaddingBottom(RenderStyle*) const;
+ virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; }
+
virtual bool paintCapsLockIndicator(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual Color systemColor(int cssValueId) const;
diff --git a/WebCore/rendering/RenderThemeChromiumMac.mm b/WebCore/rendering/RenderThemeChromiumMac.mm
index 6318fd9..1eef0cb 100644
--- a/WebCore/rendering/RenderThemeChromiumMac.mm
+++ b/WebCore/rendering/RenderThemeChromiumMac.mm
@@ -565,7 +565,7 @@ void RenderThemeChromiumMac::updateFocusedState(NSCell* cell, const RenderObject
void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject* o)
{
bool oldPressed = [cell isHighlighted];
- bool pressed = (o->element() && o->element()->active());
+ bool pressed = (o->node() && o->node()->active());
if (pressed != oldPressed)
[cell setHighlighted:pressed];
}
@@ -573,8 +573,13 @@ void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject
// FIXME: This used to be in the upstream version until it was converted to the new theme API in r37731.
int RenderThemeChromiumMac::baselinePosition(const RenderObject* o) const
{
- if (o->style()->appearance() == CheckboxPart || o->style()->appearance() == RadioPart)
- return o->marginTop() + o->height() - 2 * o->style()->effectiveZoom(); // The baseline is 2px up from the bottom of the checkbox/radio in AppKit.
+ if (!o->isBox())
+ return 0;
+
+ if (o->style()->appearance() == CheckboxPart || o->style()->appearance() == RadioPart) {
+ const RenderBox* box = toRenderBox(o);
+ return box->marginTop() + box->height() - 2 * o->style()->effectiveZoom(); // The baseline is 2px up from the bottom of the checkbox/radio in AppKit.
+ }
return RenderTheme::baselinePosition(o);
}
@@ -1311,7 +1316,11 @@ void RenderThemeChromiumMac::adjustMenuListStyle(CSSStyleSelector* selector, Ren
// Set the foreground color to black or gray when we have the aqua look.
// Cast to RGB32 is to work around a compiler bug.
- style->setColor(e->isEnabled() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
+ bool isEnabled = true;
+ if (FormControlElement* formControlElement = toFormControlElement(e))
+ isEnabled = formControlElement->isEnabled();
+
+ style->setColor(isEnabled ? static_cast<RGBA32>(Color::black) : Color::darkGray);
// Set the button's vertical size.
setSizeFromFont(style, menuListButtonSizes());
diff --git a/WebCore/rendering/RenderThemeChromiumWin.cpp b/WebCore/rendering/RenderThemeChromiumWin.cpp
index c304385..30f421b 100644
--- a/WebCore/rendering/RenderThemeChromiumWin.cpp
+++ b/WebCore/rendering/RenderThemeChromiumWin.cpp
@@ -35,9 +35,11 @@
#include "FontSelector.h"
#include "FontUtilsChromiumWin.h"
#include "GraphicsContext.h"
+#include "RenderBox.h"
+#include "RenderSlider.h"
#include "ScrollbarTheme.h"
#include "SkiaUtils.h"
-#include "ThemeHelperChromiumWin.h"
+#include "TransparencyWin.h"
#include "UserAgentStyleSheets.h"
#include "WindowsVersion.h"
@@ -52,6 +54,52 @@
namespace WebCore {
+namespace {
+
+bool canvasHasMultipleLayers(const SkCanvas* canvas)
+{
+ SkCanvas::LayerIter iter(const_cast<SkCanvas*>(canvas), false);
+ iter.next(); // There is always at least one layer.
+ return !iter.done(); // There is > 1 layer if the the iterator can stil advance.
+}
+
+class ThemePainter : public TransparencyWin {
+public:
+ ThemePainter(GraphicsContext* context, const IntRect& r)
+ {
+ TransformMode transformMode = getTransformMode(context->getCTM());
+ init(context, getLayerMode(context, transformMode), transformMode, r);
+ }
+
+ ~ThemePainter()
+ {
+ composite();
+ }
+
+private:
+ static LayerMode getLayerMode(GraphicsContext* context, TransformMode transformMode)
+ {
+ if (context->platformContext()->isDrawingToImageBuffer()) // Might have transparent background.
+ return WhiteLayer;
+ else if (canvasHasMultipleLayers(context->platformContext()->canvas())) // Needs antialiasing help.
+ return OpaqueCompositeLayer;
+ else // Nothing interesting.
+ return transformMode == KeepTransform ? NoLayer : OpaqueCompositeLayer;
+ }
+
+ static TransformMode getTransformMode(const TransformationMatrix& matrix)
+ {
+ if (matrix.b() != 0 || matrix.c() != 0) // Skew.
+ return Untransform;
+ else if (matrix.a() != 1.0 || matrix.d() != 1.0) // Scale.
+ return ScaleTransform;
+ else // Nothing interesting.
+ return KeepTransform;
+ }
+};
+
+} // namespace
+
static void getNonClientMetrics(NONCLIENTMETRICS* metrics) {
static UINT size = WebCore::isVistaOrNewer() ?
sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
@@ -89,6 +137,7 @@ static bool supportsFocus(ControlPart appearance)
case PushButtonPart:
case ButtonPart:
case DefaultButtonPart:
+ case SearchFieldPart:
case TextFieldPart:
case TextAreaPart:
return true;
@@ -212,7 +261,7 @@ RenderTheme* theme()
String RenderThemeChromiumWin::extraDefaultStyleSheet()
{
- return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
+ return String(themeChromiumWinUserAgentStyleSheet, sizeof(themeChromiumWinUserAgentStyleSheet));
}
String RenderThemeChromiumWin::extraQuirksStyleSheet()
@@ -347,6 +396,20 @@ int RenderThemeChromiumWin::minimumMenuListSize(RenderStyle* style) const
return 0;
}
+void RenderThemeChromiumWin::adjustSliderThumbSize(RenderObject* o) const
+{
+ // These sizes match what WinXP draws for various menus.
+ const int sliderThumbAlongAxis = 11;
+ const int sliderThumbAcrossAxis = 21;
+ if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == MediaSliderThumbPart) {
+ o->style()->setWidth(Length(sliderThumbAlongAxis, Fixed));
+ o->style()->setHeight(Length(sliderThumbAcrossAxis, Fixed));
+ } else if (o->style()->appearance() == SliderThumbVerticalPart) {
+ o->style()->setWidth(Length(sliderThumbAcrossAxis, Fixed));
+ o->style()->setHeight(Length(sliderThumbAlongAxis, Fixed));
+ }
+}
+
void RenderThemeChromiumWin::setCheckboxSize(RenderStyle* style) const
{
// If the width and height are both specified, then we have nothing to do.
@@ -372,12 +435,12 @@ bool RenderThemeChromiumWin::paintButton(RenderObject* o, const RenderObject::Pa
{
const ThemeData& themeData = getThemeData(o);
- WebCore::ThemeHelperWin helper(i.context, r);
- ChromiumBridge::paintButton(helper.context(),
+ WebCore::ThemePainter painter(i.context, r);
+ ChromiumBridge::paintButton(painter.context(),
themeData.m_part,
themeData.m_state,
themeData.m_classicState,
- helper.rect());
+ painter.drawRect());
return false;
}
@@ -386,6 +449,19 @@ bool RenderThemeChromiumWin::paintTextField(RenderObject* o, const RenderObject:
return paintTextFieldInternal(o, i, r, true);
}
+bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ const ThemeData& themeData = getThemeData(o);
+
+ WebCore::ThemePainter painter(i.context, r);
+ ChromiumBridge::paintTrackbar(painter.context(),
+ themeData.m_part,
+ themeData.m_state,
+ themeData.m_classicState,
+ painter.drawRect());
+ return false;
+}
+
bool RenderThemeChromiumWin::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
return paintTextField(o, i, r);
@@ -400,10 +476,14 @@ void RenderThemeChromiumWin::adjustMenuListStyle(CSSStyleSelector* selector, Ren
// Used to paint unstyled menulists (i.e. with the default border)
bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
{
- int borderRight = o->borderRight();
- int borderLeft = o->borderLeft();
- int borderTop = o->borderTop();
- int borderBottom = o->borderBottom();
+ if (!o->isBox())
+ return false;
+
+ const RenderBox* box = toRenderBox(o);
+ int borderRight = box->borderRight();
+ int borderLeft = box->borderLeft();
+ int borderTop = box->borderTop();
+ int borderBottom = box->borderBottom();
// If all the borders are 0, then tell skia not to paint the border on the
// textfield. FIXME: http://b/1210017 Figure out how to get Windows to not
@@ -418,10 +498,10 @@ bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const RenderObject::
// 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);
- int spacingLeft = borderLeft + o->paddingLeft();
- int spacingRight = borderRight + o->paddingRight();
- int spacingTop = borderTop + o->paddingTop();
- int spacingBottom = borderBottom + o->paddingBottom();
+ int spacingLeft = borderLeft + box->paddingLeft();
+ int spacingRight = borderRight + box->paddingRight();
+ int spacingTop = borderTop + box->paddingTop();
+ int spacingBottom = borderBottom + box->paddingBottom();
int buttonX;
if (r.right() - r.x() < buttonWidth)
@@ -436,12 +516,12 @@ bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const RenderObject::
r.height() - (spacingTop + spacingBottom));
// Get the correct theme data for a textfield and paint the menu.
- WebCore::ThemeHelperWin helper(i.context, rect);
- ChromiumBridge::paintMenuList(helper.context(),
+ WebCore::ThemePainter painter(i.context, rect);
+ ChromiumBridge::paintMenuList(painter.context(),
CP_DROPDOWNBUTTON,
determineState(o),
determineClassicState(o),
- helper.rect());
+ painter.drawRect());
return false;
}
@@ -476,13 +556,24 @@ int RenderThemeChromiumWin::popupInternalPaddingBottom(RenderStyle* style) const
return menuListInternalPadding(style, BottomPadding);
}
-void RenderThemeChromiumWin::adjustButtonInnerStyle(RenderStyle* style) const
+int RenderThemeChromiumWin::buttonInternalPaddingLeft() const
+{
+ return 3;
+}
+
+int RenderThemeChromiumWin::buttonInternalPaddingRight() const
+{
+ return 3;
+}
+
+int RenderThemeChromiumWin::buttonInternalPaddingTop() const
+{
+ return 1;
+}
+
+int RenderThemeChromiumWin::buttonInternalPaddingBottom() const
{
- // This inner padding matches Firefox.
- style->setPaddingTop(Length(1, Fixed));
- style->setPaddingRight(Length(3, Fixed));
- style->setPaddingBottom(Length(1, Fixed));
- style->setPaddingLeft(Length(3, Fixed));
+ return 1;
}
// static
@@ -499,7 +590,7 @@ unsigned RenderThemeChromiumWin::determineState(RenderObject* o)
ControlPart appearance = o->style()->appearance();
if (!isEnabled(o))
result = TS_DISABLED;
- else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPart == appearance))
+ else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPart == appearance || SearchFieldPart == appearance))
result = ETS_READONLY; // Readonly is supported on textfields.
else if (isPressed(o)) // Active overrides hover and focused.
result = TS_PRESSED;
@@ -512,6 +603,20 @@ unsigned RenderThemeChromiumWin::determineState(RenderObject* o)
return result;
}
+unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o)
+{
+ unsigned result = TUS_NORMAL;
+ if (!isEnabled(o->parent()))
+ result = TUS_DISABLED;
+ else if (supportsFocus(o->style()->appearance()) && isFocused(o->parent()))
+ result = TUS_FOCUSED;
+ else if (static_cast<RenderSlider*>(o->parent())->inDragMode())
+ result = TUS_PRESSED;
+ else if (isHovered(o))
+ result = TUS_HOT;
+ return result;
+}
+
unsigned RenderThemeChromiumWin::determineClassicState(RenderObject* o)
{
unsigned result = 0;
@@ -530,37 +635,57 @@ ThemeData RenderThemeChromiumWin::getThemeData(RenderObject* o)
{
ThemeData result;
switch (o->style()->appearance()) {
- case PushButtonPart:
- case ButtonPart:
- result.m_part = BP_PUSHBUTTON;
- result.m_classicState = DFCS_BUTTONPUSH;
- break;
case CheckboxPart:
result.m_part = BP_CHECKBOX;
+ result.m_state = determineState(o);
result.m_classicState = DFCS_BUTTONCHECK;
break;
case RadioPart:
result.m_part = BP_RADIOBUTTON;
+ result.m_state = determineState(o);
result.m_classicState = DFCS_BUTTONRADIO;
break;
+ case PushButtonPart:
+ case ButtonPart:
+ result.m_part = BP_PUSHBUTTON;
+ result.m_state = determineState(o);
+ result.m_classicState = DFCS_BUTTONPUSH;
+ break;
+ case SliderHorizontalPart:
+ result.m_part = TKP_TRACK;
+ result.m_state = TRS_NORMAL;
+ break;
+ case SliderVerticalPart:
+ result.m_part = TKP_TRACKVERT;
+ result.m_state = TRVS_NORMAL;
+ break;
+ case SliderThumbHorizontalPart:
+ result.m_part = TKP_THUMBBOTTOM;
+ result.m_state = determineSliderThumbState(o);
+ break;
+ case SliderThumbVerticalPart:
+ result.m_part = TKP_THUMBVERT;
+ result.m_state = determineSliderThumbState(o);
+ break;
case ListboxPart:
case MenulistPart:
+ case SearchFieldPart:
case TextFieldPart:
case TextAreaPart:
- result.m_part = ETS_NORMAL;
+ result.m_part = EP_EDITTEXT;
+ result.m_state = determineState(o);
break;
}
- result.m_state = determineState(o);
result.m_classicState |= determineClassicState(o);
return result;
}
bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o,
- const RenderObject::PaintInfo& i,
- const IntRect& r,
- bool drawEdges)
+ const RenderObject::PaintInfo& i,
+ const IntRect& r,
+ bool drawEdges)
{
// Nasty hack to make us not paint the border on text fields with a
// border-radius. Webkit paints elements with border-radius for us.
@@ -572,12 +697,12 @@ bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o,
const ThemeData& themeData = getThemeData(o);
- WebCore::ThemeHelperWin helper(i.context, r);
- ChromiumBridge::paintTextField(helper.context(),
+ WebCore::ThemePainter painter(i.context, r);
+ ChromiumBridge::paintTextField(painter.context(),
themeData.m_part,
themeData.m_state,
themeData.m_classicState,
- helper.rect(),
+ painter.drawRect(),
o->style()->backgroundColor(),
true,
drawEdges);
diff --git a/WebCore/rendering/RenderThemeChromiumWin.h b/WebCore/rendering/RenderThemeChromiumWin.h
index 2d335c2..f1ef306 100644
--- a/WebCore/rendering/RenderThemeChromiumWin.h
+++ b/WebCore/rendering/RenderThemeChromiumWin.h
@@ -70,6 +70,8 @@ namespace WebCore {
virtual int minimumMenuListSize(RenderStyle*) const;
+ virtual void adjustSliderThumbSize(RenderObject*) const;
+
virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintButton(o, i, r); }
virtual void setCheckboxSize(RenderStyle*) const;
@@ -82,6 +84,10 @@ namespace WebCore {
virtual bool paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); }
+ virtual bool paintSliderTrack(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+
+ virtual bool paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { return paintSliderTrack(o, i, r); }
+
virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
// MenuList refers to an unstyled menulist (meaning a menulist without
@@ -104,7 +110,10 @@ namespace WebCore {
virtual int popupInternalPaddingTop(RenderStyle*) const;
virtual int popupInternalPaddingBottom(RenderStyle*) const;
- virtual void adjustButtonInnerStyle(RenderStyle*) const;
+ virtual int buttonInternalPaddingLeft() const;
+ virtual int buttonInternalPaddingRight() const;
+ virtual int buttonInternalPaddingTop() const;
+ virtual int buttonInternalPaddingBottom() const;
// Provide a way to pass the default font size from the Settings object
// to the render theme. FIXME: http://b/1129186 A cleaner way would be
@@ -119,6 +128,7 @@ namespace WebCore {
private:
unsigned determineState(RenderObject*);
+ unsigned determineSliderThumbState(RenderObject*);
unsigned determineClassicState(RenderObject*);
ThemeData getThemeData(RenderObject*);
diff --git a/WebCore/rendering/RenderThemeMac.h b/WebCore/rendering/RenderThemeMac.h
index 0d31603..63f1d97 100644
--- a/WebCore/rendering/RenderThemeMac.h
+++ b/WebCore/rendering/RenderThemeMac.h
@@ -60,6 +60,8 @@ public:
virtual Color platformInactiveListBoxSelectionBackgroundColor() const;
virtual Color platformInactiveListBoxSelectionForegroundColor() const;
+ virtual ScrollbarControlSize scrollbarControlSizeForPart(ControlPart) { return SmallScrollbar; }
+
virtual void platformColorsDidChange();
// System fonts.
diff --git a/WebCore/rendering/RenderThemeMac.mm b/WebCore/rendering/RenderThemeMac.mm
index b2d320a..7d1a60e 100644
--- a/WebCore/rendering/RenderThemeMac.mm
+++ b/WebCore/rendering/RenderThemeMac.mm
@@ -548,7 +548,7 @@ void RenderThemeMac::updateFocusedState(NSCell* cell, const RenderObject* o)
void RenderThemeMac::updatePressedState(NSCell* cell, const RenderObject* o)
{
bool oldPressed = [cell isHighlighted];
- bool pressed = (o->element() && o->element()->active());
+ bool pressed = (o->node() && o->node()->active());
if (pressed != oldPressed)
[cell setHighlighted:pressed];
}
@@ -951,7 +951,11 @@ void RenderThemeMac::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle
// Set the foreground color to black or gray when we have the aqua look.
// Cast to RGB32 is to work around a compiler bug.
- style->setColor(e->isEnabled() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
+ bool isEnabled = true;
+ if (FormControlElement* formControlElement = toFormControlElement(e))
+ isEnabled = formControlElement->isEnabled();
+
+ style->setColor(isEnabled ? static_cast<RGBA32>(Color::black) : Color::darkGray);
// Set the button's vertical size.
setSizeFromFont(style, menuListButtonSizes());
@@ -1451,8 +1455,8 @@ void RenderThemeMac::adjustSliderThumbSize(RenderObject* o) const
height = size.height;
}
- o->style()->setWidth(Length(width, Fixed));
- o->style()->setHeight(Length(height, Fixed));
+ o->style()->setWidth(Length(static_cast<int>(width * zoomLevel), Fixed));
+ o->style()->setHeight(Length(static_cast<int>(height * zoomLevel), Fixed));
}
#endif
}
@@ -1462,7 +1466,7 @@ void RenderThemeMac::adjustSliderThumbSize(RenderObject* o) const
bool RenderThemeMac::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -1473,7 +1477,7 @@ bool RenderThemeMac::paintMediaFullscreenButton(RenderObject* o, const RenderObj
bool RenderThemeMac::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return false;
@@ -1489,7 +1493,7 @@ bool RenderThemeMac::paintMediaMuteButton(RenderObject* o, const RenderObject::P
bool RenderThemeMac::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return false;
@@ -1505,7 +1509,7 @@ bool RenderThemeMac::paintMediaPlayButton(RenderObject* o, const RenderObject::P
bool RenderThemeMac::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -1516,7 +1520,7 @@ bool RenderThemeMac::paintMediaSeekBackButton(RenderObject* o, const RenderObjec
bool RenderThemeMac::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -1527,7 +1531,7 @@ bool RenderThemeMac::paintMediaSeekForwardButton(RenderObject* o, const RenderOb
bool RenderThemeMac::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return false;
@@ -1551,7 +1555,7 @@ bool RenderThemeMac::paintMediaSliderTrack(RenderObject* o, const RenderObject::
bool RenderThemeMac::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -1562,7 +1566,7 @@ bool RenderThemeMac::paintMediaSliderThumb(RenderObject* o, const RenderObject::
bool RenderThemeMac::paintMediaTimelineContainer(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -1573,7 +1577,7 @@ bool RenderThemeMac::paintMediaTimelineContainer(RenderObject* o, const RenderOb
bool RenderThemeMac::paintMediaCurrentTime(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
@@ -1584,7 +1588,7 @@ bool RenderThemeMac::paintMediaCurrentTime(RenderObject* o, const RenderObject::
bool RenderThemeMac::paintMediaTimeRemaining(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
if (!node)
return false;
diff --git a/WebCore/rendering/RenderThemeSafari.cpp b/WebCore/rendering/RenderThemeSafari.cpp
index ef39a3e..cf73fdb 100644
--- a/WebCore/rendering/RenderThemeSafari.cpp
+++ b/WebCore/rendering/RenderThemeSafari.cpp
@@ -31,6 +31,7 @@
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "FormControlElement.h"
#include "HTMLInputElement.h"
#include "HTMLMediaElement.h"
#include "HTMLNames.h"
@@ -834,7 +835,7 @@ void RenderThemeSafari::adjustMenuListStyle(CSSStyleSelector* selector, RenderSt
// Set the foreground color to black or gray when we have the aqua look.
// Cast to RGB32 is to work around a compiler bug.
- style->setColor(e->isEnabled() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
+ style->setColor(e->isFormControlElement() && toFormControlElement(e)->isEnabled() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
// Set the button's vertical size.
setButtonSize(style);
@@ -1145,7 +1146,7 @@ bool RenderThemeSafari::paintMediaFullscreenButton(RenderObject* o, const Render
bool RenderThemeSafari::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return false;
@@ -1164,7 +1165,7 @@ bool RenderThemeSafari::paintMediaMuteButton(RenderObject* o, const RenderObject
bool RenderThemeSafari::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return false;
@@ -1203,7 +1204,7 @@ bool RenderThemeSafari::paintMediaSeekForwardButton(RenderObject* o, const Rende
bool RenderThemeSafari::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
{
- Node* node = o->element();
+ Node* node = o->node();
Node* mediaNode = node ? node->shadowAncestorNode() : 0;
if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !mediaNode->hasTagName(audioTag)))
return false;
diff --git a/WebCore/rendering/RenderThemeWin.cpp b/WebCore/rendering/RenderThemeWin.cpp
index e4717a1..0518ef0 100644
--- a/WebCore/rendering/RenderThemeWin.cpp
+++ b/WebCore/rendering/RenderThemeWin.cpp
@@ -712,28 +712,29 @@ void RenderThemeWin::adjustSliderThumbSize(RenderObject* o) const
}
}
-void RenderThemeWin::adjustButtonInnerStyle(RenderStyle* style) const
+int RenderThemeWin::buttonInternalPaddingLeft() const
{
- // This inner padding matches Firefox.
- style->setPaddingTop(Length(1, Fixed));
- style->setPaddingRight(Length(3, Fixed));
- style->setPaddingBottom(Length(1, Fixed));
- style->setPaddingLeft(Length(3, Fixed));
+ return 3;
}
-bool RenderThemeWin::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+int RenderThemeWin::buttonInternalPaddingRight() const
{
- return paintTextField(o, i, r);
+ return 3;
}
-void RenderThemeWin::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
-{
- // Override padding size to match AppKit text positioning.
- const int padding = 1;
- style->setPaddingLeft(Length(padding, Fixed));
- style->setPaddingRight(Length(padding, Fixed));
- style->setPaddingTop(Length(padding, Fixed));
- style->setPaddingBottom(Length(padding, Fixed));
+int RenderThemeWin::buttonInternalPaddingTop() const
+{
+ return 1;
+}
+
+int RenderThemeWin::buttonInternalPaddingBottom() const
+{
+ return 1;
+}
+
+bool RenderThemeWin::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ return paintTextField(o, i, r);
}
bool RenderThemeWin::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r)
diff --git a/WebCore/rendering/RenderThemeWin.h b/WebCore/rendering/RenderThemeWin.h
index 5d5bd4b..664094f 100644
--- a/WebCore/rendering/RenderThemeWin.h
+++ b/WebCore/rendering/RenderThemeWin.h
@@ -92,9 +92,13 @@ public:
virtual bool paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r);
virtual void adjustSliderThumbSize(RenderObject*) const;
- virtual void adjustButtonInnerStyle(RenderStyle*) const;
+ virtual bool popupOptionSupportsTextIndent() const { return true; }
+
+ virtual int buttonInternalPaddingLeft() const;
+ virtual int buttonInternalPaddingRight() const;
+ virtual int buttonInternalPaddingTop() const;
+ virtual int buttonInternalPaddingBottom() const;
- virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
diff --git a/WebCore/rendering/RenderTreeAsText.cpp b/WebCore/rendering/RenderTreeAsText.cpp
index cf7e027..2350491 100644
--- a/WebCore/rendering/RenderTreeAsText.cpp
+++ b/WebCore/rendering/RenderTreeAsText.cpp
@@ -170,13 +170,13 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
if (o.style() && o.style()->zIndex())
ts << " zI: " << o.style()->zIndex();
- if (o.element()) {
- String tagName = getTagName(o.element());
+ if (o.node()) {
+ String tagName = getTagName(o.node());
if (!tagName.isEmpty()) {
ts << " {" << tagName << "}";
// flag empty or unstyled AppleStyleSpan because we never
// want to leave them in the DOM
- if (isEmptyOrUnstyledAppleStyleSpan(o.element()))
+ if (isEmptyOrUnstyledAppleStyleSpan(o.node()))
ts << " *empty or unstyled AppleStyleSpan*";
}
}
@@ -192,21 +192,19 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
r = IntRect(text.firstRunX(), text.firstRunY(), linesBox.width(), linesBox.height());
if (adjustForTableCells && !text.firstTextBox())
adjustForTableCells = false;
- } else if (o.isBox()) {
- if (o.isRenderInline()) {
- // FIXME: Would be better not to just dump 0, 0 as the x and y here.
- const RenderInline& inlineFlow = static_cast<const RenderInline&>(o);
- r = IntRect(0, 0, inlineFlow.linesBoundingBox().width(), inlineFlow.linesBoundingBox().height());
- adjustForTableCells = false;
- } else if (o.isTableCell()) {
- // FIXME: Deliberately dump the "inner" box of table cells, since that is what current results reflect. We'd like
- // to clean up the results to dump both the outer box and the intrinsic padding so that both bits of information are
- // captured by the results.
- const RenderTableCell& cell = static_cast<const RenderTableCell&>(o);
- r = IntRect(cell.x(), cell.y() + cell.intrinsicPaddingTop(), cell.width(), cell.height() - cell.intrinsicPaddingTop() - cell.intrinsicPaddingBottom());
- } else
- r = toRenderBox(&o)->frameRect();
- }
+ } else if (o.isRenderInline()) {
+ // FIXME: Would be better not to just dump 0, 0 as the x and y here.
+ const RenderInline& inlineFlow = *toRenderInline(&o);
+ r = IntRect(0, 0, inlineFlow.linesBoundingBox().width(), inlineFlow.linesBoundingBox().height());
+ adjustForTableCells = false;
+ } else if (o.isTableCell()) {
+ // FIXME: Deliberately dump the "inner" box of table cells, since that is what current results reflect. We'd like
+ // to clean up the results to dump both the outer box and the intrinsic padding so that both bits of information are
+ // captured by the results.
+ const RenderTableCell& cell = static_cast<const RenderTableCell&>(o);
+ r = IntRect(cell.x(), cell.y() + cell.intrinsicPaddingTop(), cell.width(), cell.height() - cell.intrinsicPaddingTop() - cell.intrinsicPaddingBottom());
+ } else if (o.isBox())
+ r = toRenderBox(&o)->frameRect();
// FIXME: Temporary in order to ensure compatibility with existing layout test results.
if (adjustForTableCells)
@@ -237,10 +235,10 @@ static TextStream &operator<<(TextStream& ts, const RenderObject& o)
o.style()->textStrokeWidth() > 0)
ts << " [textStrokeWidth=" << o.style()->textStrokeWidth() << "]";
- if (!o.isBox())
+ if (!o.isBoxModelObject())
return ts;
- const RenderBox& box = *toRenderBox(&o);
+ const RenderBoxModelObject& box = *toRenderBoxModelObject(&o);
if (box.borderTop() || box.borderRight() || box.borderBottom() || box.borderLeft()) {
ts << " [border:";
@@ -405,7 +403,7 @@ void write(TextStream& ts, const RenderObject& o, int indent)
view->layout();
RenderLayer* l = root->layer();
if (l)
- writeLayers(ts, l, l, IntRect(l->xPos(), l->yPos(), l->width(), l->height()), indent + 1);
+ writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1);
}
}
}
@@ -433,9 +431,9 @@ static void write(TextStream& ts, RenderLayer& l,
ts << " scrollX " << l.scrollXOffset();
if (l.scrollYOffset())
ts << " scrollY " << l.scrollYOffset();
- if (l.renderer()->clientWidth() != l.scrollWidth())
+ if (l.renderBox() && l.renderBox()->clientWidth() != l.scrollWidth())
ts << " scrollWidth " << l.scrollWidth();
- if (l.renderer()->clientHeight() != l.scrollHeight())
+ if (l.renderBox() && l.renderBox()->clientHeight() != l.scrollHeight())
ts << " scrollHeight " << l.scrollHeight();
}
@@ -459,7 +457,7 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
// Ensure our lists are up-to-date.
l->updateZOrderLists();
- l->updateOverflowList();
+ l->updateNormalFlowList();
bool shouldPaint = l->intersectsDamageRect(layerBounds, damageRect, rootLayer);
Vector<RenderLayer*>* negList = l->negZOrderList();
@@ -474,10 +472,10 @@ static void writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLaye
if (shouldPaint)
write(ts, *l, layerBounds, damageRect, clipRectToApply, outlineRect, negList && negList->size() > 0, indent);
- Vector<RenderLayer*>* overflowList = l->overflowList();
- if (overflowList) {
- for (unsigned i = 0; i != overflowList->size(); ++i)
- writeLayers(ts, rootLayer, overflowList->at(i), paintDirtyRect, indent);
+ Vector<RenderLayer*>* normalFlowList = l->normalFlowList();
+ if (normalFlowList) {
+ for (unsigned i = 0; i != normalFlowList->size(); ++i)
+ writeLayers(ts, rootLayer, normalFlowList->at(i), paintDirtyRect, indent);
}
Vector<RenderLayer*>* posList = l->posZOrderList();
@@ -509,7 +507,7 @@ static String nodePosition(Node* node)
static void writeSelection(TextStream& ts, const RenderObject* o)
{
- Node* n = o->element();
+ Node* n = o->node();
if (!n || !n->isDocumentNode())
return;
@@ -518,15 +516,15 @@ static void writeSelection(TextStream& ts, const RenderObject* o)
if (!frame)
return;
- Selection selection = frame->selection()->selection();
+ VisibleSelection selection = frame->selection()->selection();
if (selection.isCaret()) {
- ts << "caret: position " << selection.start().offset() << " of " << nodePosition(selection.start().node());
+ ts << "caret: position " << selection.start().m_offset << " of " << nodePosition(selection.start().node());
if (selection.affinity() == UPSTREAM)
ts << " (upstream affinity)";
ts << "\n";
} else if (selection.isRange())
- ts << "selection start: position " << selection.start().offset() << " of " << nodePosition(selection.start().node()) << "\n"
- << "selection end: position " << selection.end().offset() << " of " << nodePosition(selection.end().node()) << "\n";
+ ts << "selection start: position " << selection.start().m_offset << " of " << nodePosition(selection.start().node()) << "\n"
+ << "selection end: position " << selection.end().m_offset << " of " << nodePosition(selection.end().node()) << "\n";
}
String externalRepresentation(RenderObject* o)
@@ -542,7 +540,7 @@ String externalRepresentation(RenderObject* o)
o->view()->frameView()->layout();
if (o->hasLayer()) {
RenderLayer* l = toRenderBox(o)->layer();
- writeLayers(ts, l, l, IntRect(l->xPos(), l->yPos(), l->width(), l->height()));
+ writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()));
writeSelection(ts, o);
}
return ts.release();
diff --git a/WebCore/rendering/RenderVideo.cpp b/WebCore/rendering/RenderVideo.cpp
index be75997..d6e98e7 100644
--- a/WebCore/rendering/RenderVideo.cpp
+++ b/WebCore/rendering/RenderVideo.cpp
@@ -125,12 +125,9 @@ void RenderVideo::updatePlayer()
return;
}
- // FIXME: This doesn't work correctly with transforms.
- FloatPoint absPos = localToAbsolute();
IntRect videoBounds = videoBox();
- videoBounds.move(absPos.x(), absPos.y());
mediaPlayer->setFrameView(document()->view());
- mediaPlayer->setRect(videoBounds);
+ mediaPlayer->setSize(IntSize(videoBounds.width(), videoBounds.height()));
mediaPlayer->setVisible(true);
}
diff --git a/WebCore/rendering/RenderView.cpp b/WebCore/rendering/RenderView.cpp
index 7ce4998..ab2f085 100644
--- a/WebCore/rendering/RenderView.cpp
+++ b/WebCore/rendering/RenderView.cpp
@@ -27,7 +27,15 @@
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "HitTestResult.h"
#include "RenderLayer.h"
+#include "RenderSelectionInfo.h"
+#include "RenderWidget.h"
+#include "TransformState.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
+#endif
#ifdef ANDROID_LAYOUT
#include "Settings.h"
@@ -139,39 +147,20 @@ void RenderView::layout()
setNeedsLayout(false);
}
-FloatPoint RenderView::localToAbsolute(FloatPoint localPoint, bool fixed, bool) const
-{
- // This disables the css position:fixed to the Browser window. Instead
- // the fixed element will be always fixed to the top page.
-#ifndef ANDROID_DISABLE_POSITION_FIXED
- if (fixed && m_frameView)
- localPoint += m_frameView->scrollOffset();
-#endif
- return localPoint;
-}
-
-FloatPoint RenderView::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool) const
-{
- // This disables the css position:fixed to the Browser window. Instead
- // the fixed element will be always fixed to the top page.
-#ifndef ANDROID_DISABLE_POSITION_FIXED
- if (fixed && m_frameView)
- containerPoint -= m_frameView->scrollOffset();
-#endif
- return containerPoint;
-}
-
-FloatQuad RenderView::localToContainerQuad(const FloatQuad& localQuad, RenderBox* repaintContainer, bool fixed) const
+void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool /*useTransforms*/, TransformState& transformState) const
{
// If a container was specified, and was not 0 or the RenderView,
// then we should have found it by now.
ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);
- FloatQuad quad = localQuad;
if (fixed && m_frameView)
- quad += m_frameView->scrollOffset();
+ transformState.move(m_frameView->scrollOffset());
+}
- return quad;
+void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool /*useTransforms*/, TransformState& transformState) const
+{
+ if (fixed && m_frameView)
+ transformState.move(-m_frameView->scrollOffset());
}
void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
@@ -230,12 +219,20 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int)
}
}
-void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
+bool RenderView::shouldRepaint(const IntRect& r) const
{
- if (printing() || ur.width() == 0 || ur.height() == 0)
- return;
+ if (printing() || r.width() == 0 || r.height() == 0)
+ return false;
if (!m_frameView)
+ return false;
+
+ return true;
+}
+
+void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
+{
+ if (!shouldRepaint(ur))
return;
// We always just invalidate the root view, since we could be an iframe that is clipped out
@@ -258,7 +255,25 @@ void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
}
}
-void RenderView::computeRectForRepaint(IntRect& rect, RenderBox* repaintContainer, bool fixed)
+void RenderView::repaintRectangleInViewAndCompositedLayers(const IntRect& ur, bool immediate)
+{
+ if (!shouldRepaint(ur))
+ return;
+
+ repaintViewRectangle(ur, immediate);
+
+#if USE(ACCELERATED_COMPOSITING)
+ // If we're a frame, repaintViewRectangle will have repainted via a RenderObject in the
+ // parent document.
+ if (document()->ownerElement())
+ return;
+
+ if (compositor()->inCompositingMode())
+ compositor()->repaintCompositedLayersAbsoluteRect(ur);
+#endif
+}
+
+void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
{
// If a container was specified, and was not 0 or the RenderView,
// then we should have found it by now.
@@ -294,21 +309,11 @@ static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset
return child ? child : object->nextInPreOrderAfterChildren();
}
-IntRect RenderView::selectionRect(bool clipToVisibleContent)
-{
- // The virtual selectionRect() should never be called on the RenderView.
- // We assert because there used to be ambiguity between
- // RenderView::selectionRect(bool) and
- // virtual RenderObject::selectionRect(bool) const
- ASSERT_NOT_REACHED();
- return RenderBlock::selectionRect(clipToVisibleContent);
-}
-
IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
{
document()->updateRendering();
- typedef HashMap<RenderObject*, SelectionInfo*> SelectionMap;
+ typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectionMap;
SelectionMap selectedObjects;
RenderObject* os = m_selectionStart;
@@ -316,13 +321,13 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
while (os && os != stop) {
if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
// Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
- selectedObjects.set(os, new SelectionInfo(os, clipToVisibleContent));
+ selectedObjects.set(os, new RenderSelectionInfo(os, clipToVisibleContent));
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- SelectionInfo* blockInfo = selectedObjects.get(cb);
+ RenderSelectionInfo* blockInfo = selectedObjects.get(cb);
if (blockInfo)
break;
- selectedObjects.set(cb, new SelectionInfo(cb, clipToVisibleContent));
+ selectedObjects.set(cb, new RenderSelectionInfo(cb, clipToVisibleContent));
cb = cb->containingBlock();
}
}
@@ -334,13 +339,28 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
IntRect selRect;
SelectionMap::iterator end = selectedObjects.end();
for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
- SelectionInfo* info = i->second;
+ RenderSelectionInfo* info = i->second;
selRect.unite(info->rect());
delete info;
}
return selRect;
}
+#if USE(ACCELERATED_COMPOSITING)
+// Compositing layer dimensions take outline size into account, so we have to recompute layer
+// bounds when it changes.
+// FIXME: This is ugly; it would be nice to have a better way to do this.
+void RenderView::setMaximalOutlineSize(int o)
+{
+ if (o != m_maximalOutlineSize) {
+ m_maximalOutlineSize = o;
+
+ if (m_frameView)
+ m_frameView->updateCompositingLayers(FrameView::ForcedCompositingUpdate);
+ }
+}
+#endif
+
void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos)
{
// Make sure both our start and end objects are defined.
@@ -359,14 +379,14 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
int oldEndPos = m_selectionEndPos;
// Objects each have a single selection rect to examine.
- typedef HashMap<RenderObject*, SelectionInfo*> SelectedObjectMap;
+ typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectedObjectMap;
SelectedObjectMap oldSelectedObjects;
SelectedObjectMap newSelectedObjects;
// Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
// In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
// the union of those rects might remain the same even when changes have occurred.
- typedef HashMap<RenderBlock*, BlockSelectionInfo*> SelectedBlockMap;
+ typedef HashMap<RenderBlock*, RenderBlockSelectionInfo*> SelectedBlockMap;
SelectedBlockMap oldSelectedBlocks;
SelectedBlockMap newSelectedBlocks;
@@ -375,13 +395,13 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
while (os && os != stop) {
if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
// Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
- oldSelectedObjects.set(os, new SelectionInfo(os, true));
+ oldSelectedObjects.set(os, new RenderSelectionInfo(os, true));
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- BlockSelectionInfo* blockInfo = oldSelectedBlocks.get(cb);
+ RenderBlockSelectionInfo* blockInfo = oldSelectedBlocks.get(cb);
if (blockInfo)
break;
- oldSelectedBlocks.set(cb, new BlockSelectionInfo(cb));
+ oldSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
cb = cb->containingBlock();
}
}
@@ -424,13 +444,13 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
o = start;
while (o && o != stop) {
if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
- newSelectedObjects.set(o, new SelectionInfo(o, true));
+ newSelectedObjects.set(o, new RenderSelectionInfo(o, true));
RenderBlock* cb = o->containingBlock();
while (cb && !cb->isRenderView()) {
- BlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
+ RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
if (blockInfo)
break;
- newSelectedBlocks.set(cb, new BlockSelectionInfo(cb));
+ newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
cb = cb->containingBlock();
}
}
@@ -451,14 +471,14 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
// Have any of the old selected objects changed compared to the new selection?
for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
RenderObject* obj = i->first;
- SelectionInfo* newInfo = newSelectedObjects.get(obj);
- SelectionInfo* oldInfo = i->second;
+ RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
+ RenderSelectionInfo* oldInfo = i->second;
if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
(m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
(m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
- repaintViewRectangle(oldInfo->rect());
+ oldInfo->repaint();
if (newInfo) {
- repaintViewRectangle(newInfo->rect());
+ newInfo->repaint();
newSelectedObjects.remove(obj);
delete newInfo;
}
@@ -469,8 +489,8 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
// Any new objects that remain were not found in the old objects dict, and so they need to be updated.
SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) {
- SelectionInfo* newInfo = i->second;
- repaintViewRectangle(newInfo->rect());
+ RenderSelectionInfo* newInfo = i->second;
+ newInfo->repaint();
delete newInfo;
}
@@ -478,12 +498,12 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
RenderBlock* block = i->first;
- BlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
- BlockSelectionInfo* oldInfo = i->second;
+ RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
+ RenderBlockSelectionInfo* oldInfo = i->second;
if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
- repaintViewRectangle(oldInfo->rects());
+ oldInfo->repaint();
if (newInfo) {
- repaintViewRectangle(newInfo->rects());
+ newInfo->repaint();
newSelectedBlocks.remove(block);
delete newInfo;
}
@@ -494,8 +514,8 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
// Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) {
- BlockSelectionInfo* newInfo = i->second;
- repaintViewRectangle(newInfo->rects());
+ RenderBlockSelectionInfo* newInfo = i->second;
+ newInfo->repaint();
delete newInfo;
}
}
@@ -518,17 +538,17 @@ bool RenderView::printing() const
void RenderView::updateWidgetPositions()
{
- RenderObjectSet::iterator end = m_widgets.end();
- for (RenderObjectSet::iterator it = m_widgets.begin(); it != end; ++it)
+ RenderWidgetSet::iterator end = m_widgets.end();
+ for (RenderWidgetSet::iterator it = m_widgets.begin(); it != end; ++it)
(*it)->updateWidgetPosition();
}
-void RenderView::addWidget(RenderObject* o)
+void RenderView::addWidget(RenderWidget* o)
{
m_widgets.add(o);
}
-void RenderView::removeWidget(RenderObject* o)
+void RenderView::removeWidget(RenderWidget* o)
{
m_widgets.remove(o);
}
@@ -598,9 +618,17 @@ int RenderView::viewWidth() const
return width;
}
+float RenderView::zoomFactor() const
+{
+ if (m_frameView->frame() && m_frameView->frame()->shouldApplyPageZoom())
+ return m_frameView->frame()->zoomFactor();
+
+ return 1.0f;
+}
+
// The idea here is to take into account what object is moving the pagination point, and
// thus choose the best place to chop it.
-void RenderView::setBestTruncatedAt(int y, RenderBox* forRenderer, bool forcedBreak)
+void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
{
// Nobody else can set a page break once we have a forced break.
if (m_forcedPageBreak)
@@ -613,9 +641,10 @@ void RenderView::setBestTruncatedAt(int y, RenderBox* forRenderer, bool forcedBr
return;
}
- // prefer the widest object who tries to move the pagination point
- if (forRenderer->width() > m_truncatorWidth) {
- m_truncatorWidth = forRenderer->width();
+ // Prefer the widest object that tries to move the pagination point
+ IntRect boundingBox = forRenderer->borderBoundingBox();
+ if (boundingBox.width() > m_truncatorWidth) {
+ m_truncatorWidth = boundingBox.width();
m_bestTruncatedAt = y;
}
}
@@ -629,4 +658,49 @@ void RenderView::pushLayoutState(RenderObject* root)
m_layoutState = new (renderArena()) LayoutState(root);
}
+void RenderView::updateHitTestResult(HitTestResult& result, const IntPoint& point)
+{
+ if (result.innerNode())
+ return;
+
+ Node* node = document()->documentElement();
+ if (node) {
+ result.setInnerNode(node);
+ if (!result.innerNonSharedNode())
+ result.setInnerNonSharedNode(node);
+ result.setLocalPoint(point);
+ }
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+bool RenderView::usesCompositing() const
+{
+ return m_compositor && m_compositor->inCompositingMode();
+}
+
+RenderLayerCompositor* RenderView::compositor()
+{
+ if (!m_compositor)
+ m_compositor.set(new RenderLayerCompositor(this));
+
+ return m_compositor.get();
+}
+#endif
+
+void RenderView::didMoveOnscreen()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_compositor)
+ m_compositor->didMoveOnscreen();
+#endif
+}
+
+void RenderView::willMoveOffscreen()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_compositor)
+ m_compositor->willMoveOffscreen();
+#endif
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/RenderView.h b/WebCore/rendering/RenderView.h
index 8e7bf95..1c6925c 100644
--- a/WebCore/rendering/RenderView.h
+++ b/WebCore/rendering/RenderView.h
@@ -25,12 +25,18 @@
#define RenderView_h
#include "FrameView.h"
-#include "Frame.h"
#include "LayoutState.h"
#include "RenderBlock.h"
+#include <wtf/OwnPtr.h>
namespace WebCore {
+class RenderWidget;
+
+#if USE(ACCELERATED_COMPOSITING)
+class RenderLayerCompositor;
+#endif
+
class RenderView : public RenderBlock {
public:
RenderView(Node*, FrameView*);
@@ -44,8 +50,6 @@ public:
virtual void calcWidth();
virtual void calcHeight();
virtual void calcPrefWidths();
- virtual FloatPoint localToAbsolute(FloatPoint localPoint = FloatPoint(), bool fixed = false, bool useTransforms = false) const;
- virtual FloatPoint absoluteToLocal(FloatPoint containerPoint, bool fixed = false, bool useTransforms = false) const;
int docHeight() const;
int docWidth() const;
@@ -54,14 +58,15 @@ public:
int viewHeight() const;
int viewWidth() const;
- float zoomFactor() const { return m_frameView->frame() && m_frameView->frame()->shouldApplyPageZoom() ? m_frameView->frame()->zoomFactor() : 1.0f; }
+ float zoomFactor() const;
FrameView* frameView() const { return m_frameView; }
- virtual bool hasOverhangingFloats() { return false; }
-
- virtual void computeRectForRepaint(IntRect&, RenderBox* repaintContainer, bool fixed = false);
+ virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
virtual void repaintViewRectangle(const IntRect&, bool immediate = false);
+ // Repaint the view, and all composited layers that intersect the given absolute rectangle.
+ // FIXME: ideally we'd never have to do this, if all repaints are container-relative.
+ virtual void repaintRectangleInViewAndCompositedLayers(const IntRect&, bool immediate = false);
virtual void paint(PaintInfo&, int tx, int ty);
virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
@@ -75,7 +80,7 @@ public:
void setPrintImages(bool enable) { m_printImages = enable; }
bool printImages() const { return m_printImages; }
void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_forcedPageBreak = false; }
- void setBestTruncatedAt(int y, RenderBox* forRenderer, bool forcedBreak = false);
+ void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
int bestTruncatedAt() const { return m_bestTruncatedAt; }
int truncatedAt() const { return m_truncatedAt; }
@@ -85,19 +90,23 @@ public:
IntRect selectionBounds(bool clipToVisibleContent = true) const;
+#if USE(ACCELERATED_COMPOSITING)
+ void setMaximalOutlineSize(int o);
+#else
void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; }
+#endif
int maximalOutlineSize() const { return m_maximalOutlineSize; }
virtual IntRect viewRect() const;
- virtual void selectionStartEnd(int& startPos, int& endPos) const;
+ void selectionStartEnd(int& startPos, int& endPos) const;
IntRect printRect() const { return m_printRect; }
void setPrintRect(const IntRect& r) { m_printRect = r; }
void updateWidgetPositions();
- void addWidget(RenderObject*);
- void removeWidget(RenderObject*);
+ void addWidget(RenderWidget*);
+ void removeWidget(RenderWidget*);
// layoutDelta is used transiently during layout to store how far an object has moved from its
// last layout location, in order to repaint correctly.
@@ -144,12 +153,24 @@ public:
void disableLayoutState() { m_layoutStateDisableCount++; }
void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
+ virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
+
+ // Notifications that this view became visible in a window, or will be
+ // removed from the window.
+ void didMoveOnscreen();
+ void willMoveOffscreen();
+
+#if USE(ACCELERATED_COMPOSITING)
+ RenderLayerCompositor* compositor();
+ bool usesCompositing() const;
+#endif
+
protected:
- virtual FloatQuad localToContainerQuad(const FloatQuad&, RenderBox* repaintContainer, bool fixed = false) const;
+ virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
+ virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
private:
- // selectionRect should never be called on a RenderView
- virtual IntRect selectionRect(bool);
+ bool shouldRepaint(const IntRect& r) const;
protected:
FrameView* m_frameView;
@@ -166,9 +187,9 @@ protected:
int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
IntRect m_printRect; // Used when printing.
- typedef HashSet<RenderObject*> RenderObjectSet;
+ typedef HashSet<RenderWidget*> RenderWidgetSet;
- RenderObjectSet m_widgets;
+ RenderWidgetSet m_widgets;
private:
int m_bestTruncatedAt;
@@ -176,8 +197,27 @@ private:
bool m_forcedPageBreak;
LayoutState* m_layoutState;
unsigned m_layoutStateDisableCount;
+#if USE(ACCELERATED_COMPOSITING)
+ OwnPtr<RenderLayerCompositor> m_compositor;
+#endif
};
+inline RenderView* toRenderView(RenderObject* o)
+{
+ ASSERT(!o || o->isRenderView());
+ return static_cast<RenderView*>(o);
+}
+
+inline const RenderView* toRenderView(const RenderObject* o)
+{
+ ASSERT(!o || o->isRenderView());
+ return static_cast<const RenderView*>(o);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderView(const RenderView*);
+
+
// Stack-based class to assist with LayoutState push/pop
class LayoutStateMaintainer : Noncopyable {
public:
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index 9bf8111..2f30c59 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -91,20 +91,19 @@ void RenderWidget::destroy()
if (hasOverrideSize())
setOverrideSize(-1);
- RenderLayer* layer = m_layer;
- RenderArena* arena = renderArena();
-
- if (layer)
- layer->clearClipRects();
-
if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent()))
RenderBlock::removePercentHeightDescendant(this);
+ if (hasLayer()) {
+ layer()->clearClipRects();
+ destroyLayer();
+ }
+
+ // Grab the arena from node()->document()->renderArena() before clearing the node pointer.
+ // Clear the node before deref-ing, as this may be deleted when deref is called.
+ RenderArena* arena = renderArena();
setNode(0);
deref(arena);
-
- if (layer)
- layer->destroy(arena);
}
RenderWidget::~RenderWidget()
@@ -115,9 +114,9 @@ RenderWidget::~RenderWidget()
void RenderWidget::setWidgetGeometry(const IntRect& frame)
{
- if (element() && m_widget->frameRect() != frame) {
+ if (node() && m_widget->frameRect() != frame) {
RenderArena* arena = ref();
- RefPtr<Node> protectedElement(element());
+ RefPtr<Node> protectedElement(node());
m_widget->setFrameRect(frame);
deref(arena);
}
@@ -157,7 +156,7 @@ void RenderWidget::layout()
setNeedsLayout(false);
}
-void RenderWidget::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderReplaced::styleDidChange(diff, oldStyle);
if (m_widget) {
@@ -192,6 +191,17 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
paintCustomHighlight(tx - x(), ty - y(), style()->highlight(), true);
#endif
+ bool clipToBorderRadius = style()->overflowX() != OVISIBLE && style()->hasBorderRadius();
+ if (clipToBorderRadius) {
+ // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
+ paintInfo.context->save();
+ paintInfo.context->addRoundedRectClip(IntRect(tx, ty, width(), height()),
+ style()->borderTopLeftRadius(),
+ style()->borderTopRightRadius(),
+ style()->borderBottomLeftRadius(),
+ style()->borderBottomRightRadius());
+ }
+
if (m_widget) {
// Move the widget if necessary. We normally move and resize widgets during layout, but sometimes
// widgets can move without layout occurring (most notably when you scroll a document that
@@ -203,9 +213,14 @@ void RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
m_widget->paint(paintInfo.context, paintInfo.rect);
}
+ if (clipToBorderRadius)
+ paintInfo.context->restore();
+
// Paint a partially transparent wash over selected widgets.
- if (isSelected() && !document()->printing())
+ if (isSelected() && !document()->printing()) {
+ // FIXME: selectionRect() is in absolute, not painting coordinates.
paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor());
+ }
}
void RenderWidget::deref(RenderArena *arena)
@@ -228,22 +243,22 @@ void RenderWidget::updateWidgetPosition()
IntRect newBounds(absPos.x(), absPos.y(), w, h);
IntRect oldBounds(m_widget->frameRect());
- if (newBounds != oldBounds) {
- // The widget changed positions. Update the frame geometry.
- if (checkForRepaintDuringLayout()) {
- RenderView* v = view();
- if (!v->printing()) {
- v->repaintViewRectangle(oldBounds);
- v->repaintViewRectangle(newBounds);
- }
- }
-
+ bool boundsChanged = newBounds != oldBounds;
+ if (boundsChanged) {
RenderArena* arena = ref();
- element()->ref();
+ node()->ref();
m_widget->setFrameRect(newBounds);
- element()->deref();
+ node()->deref();
deref(arena);
}
+
+ // if the frame bounds got changed, or if view needs layout (possibly indicating
+ // content size is wrong) we have to do a layout to set the right widget size
+ if (m_widget->isFrameView()) {
+ FrameView* frameView = static_cast<FrameView*>(m_widget);
+ if (boundsChanged || frameView->needsLayout())
+ frameView->layout();
+ }
}
void RenderWidget::setSelectionState(SelectionState state)
@@ -271,7 +286,7 @@ bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& res
bool inside = RenderReplaced::nodeAtPoint(request, result, x, y, tx, ty, action);
// Check to see if we are really over the widget itself (and not just in the border/padding area).
- if (inside && !hadResult && result.innerNode() == element())
+ if (inside && !hadResult && result.innerNode() == node())
result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
return inside;
}
diff --git a/WebCore/rendering/RenderWidget.h b/WebCore/rendering/RenderWidget.h
index a64bb54..cca2165 100644
--- a/WebCore/rendering/RenderWidget.h
+++ b/WebCore/rendering/RenderWidget.h
@@ -50,14 +50,14 @@ public:
virtual void setSelectionState(SelectionState);
- virtual void updateWidgetPosition();
+ void updateWidgetPosition();
virtual void setWidget(Widget*);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
protected:
- virtual void styleDidChange(RenderStyle::Diff, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
void setWidgetGeometry(const IntRect&);
diff --git a/WebCore/rendering/RootInlineBox.cpp b/WebCore/rendering/RootInlineBox.cpp
index 6d42aa7..e582e5e 100644
--- a/WebCore/rendering/RootInlineBox.cpp
+++ b/WebCore/rendering/RootInlineBox.cpp
@@ -74,10 +74,28 @@ void RootInlineBox::detachEllipsisBox(RenderArena* arena)
}
}
+int RootInlineBox::height() const
+{
+ const Font& font = renderer()->style(m_firstLine)->font();
+ int result = font.height();
+ bool strictMode = renderer()->document()->inStrictMode();
+ if (!strictMode && !hasTextChildren() && !boxModelObject()->hasHorizontalBordersOrPadding()) {
+ int bottom = bottomOverflow();
+ if (y() + result > bottom)
+ result = bottom - y();
+ }
+ return result;
+}
+
+RenderLineBoxList* RootInlineBox::rendererLineBoxes() const
+{
+ return block()->lineBoxes();
+}
+
void RootInlineBox::clearTruncation()
{
if (m_hasEllipsisBox) {
- detachEllipsisBox(m_object->renderArena());
+ detachEllipsisBox(renderer()->renderArena());
InlineFlowBox::clearTruncation();
}
}
@@ -98,9 +116,9 @@ void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr, bool ltr, in
InlineBox* markupBox)
{
// Create an ellipsis box.
- EllipsisBox* ellipsisBox = new (m_object->renderArena()) EllipsisBox(m_object, ellipsisStr, this,
- ellipsisWidth - (markupBox ? markupBox->width() : 0),
- yPos(), height(), baseline(), !prevRootBox(),
+ EllipsisBox* ellipsisBox = new (renderer()->renderArena()) EllipsisBox(renderer(), ellipsisStr, this,
+ ellipsisWidth - (markupBox ? markupBox->width() : 0), height(),
+ y(), !prevRootBox(),
markupBox);
if (!gEllipsisBoxMap)
@@ -108,8 +126,8 @@ void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr, bool ltr, in
gEllipsisBoxMap->add(this, ellipsisBox);
m_hasEllipsisBox = true;
- if (ltr && (xPos() + width() + ellipsisWidth) <= blockEdge) {
- ellipsisBox->m_x = xPos() + width();
+ if (ltr && (x() + width() + ellipsisWidth) <= blockEdge) {
+ ellipsisBox->m_x = x() + width();
return;
}
@@ -130,7 +148,7 @@ int RootInlineBox::placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth,
void RootInlineBox::paintEllipsisBox(RenderObject::PaintInfo& paintInfo, int tx, int ty) const
{
- if (m_hasEllipsisBox && object()->shouldPaintWithinRoot(paintInfo) && object()->style()->visibility() == VISIBLE &&
+ if (m_hasEllipsisBox && renderer()->shouldPaintWithinRoot(paintInfo) && renderer()->style()->visibility() == VISIBLE &&
paintInfo.phase == PaintPhaseForeground)
ellipsisBox()->paint(paintInfo, tx, ty);
}
@@ -139,7 +157,7 @@ void RootInlineBox::paintEllipsisBox(RenderObject::PaintInfo& paintInfo, int tx,
void RootInlineBox::addHighlightOverflow()
{
- Frame* frame = object()->document()->frame();
+ Frame* frame = renderer()->document()->frame();
if (!frame)
return;
Page* page = frame->page();
@@ -148,17 +166,17 @@ void RootInlineBox::addHighlightOverflow()
// Highlight acts as a selection inflation.
FloatRect rootRect(0, selectionTop(), width(), selectionHeight());
- IntRect inflatedRect = enclosingIntRect(page->chrome()->client()->customHighlightRect(object()->node(), object()->style()->highlight(), rootRect));
+ IntRect inflatedRect = enclosingIntRect(page->chrome()->client()->customHighlightRect(renderer()->node(), renderer()->style()->highlight(), rootRect));
setHorizontalOverflowPositions(min(leftOverflow(), inflatedRect.x()), max(rightOverflow(), inflatedRect.right()));
setVerticalOverflowPositions(min(topOverflow(), inflatedRect.y()), max(bottomOverflow(), inflatedRect.bottom()));
}
void RootInlineBox::paintCustomHighlight(RenderObject::PaintInfo& paintInfo, int tx, int ty, const AtomicString& highlightType)
{
- if (!object()->shouldPaintWithinRoot(paintInfo) || object()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
+ if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
return;
- Frame* frame = object()->document()->frame();
+ Frame* frame = renderer()->document()->frame();
if (!frame)
return;
Page* page = frame->page();
@@ -166,10 +184,10 @@ void RootInlineBox::paintCustomHighlight(RenderObject::PaintInfo& paintInfo, int
return;
// Get the inflated rect so that we can properly hit test.
- FloatRect rootRect(tx + xPos(), ty + selectionTop(), width(), selectionHeight());
- FloatRect inflatedRect = page->chrome()->client()->customHighlightRect(object()->node(), highlightType, rootRect);
+ FloatRect rootRect(tx + x(), ty + selectionTop(), width(), selectionHeight());
+ FloatRect inflatedRect = page->chrome()->client()->customHighlightRect(renderer()->node(), highlightType, rootRect);
if (inflatedRect.intersects(paintInfo.rect))
- page->chrome()->client()->paintCustomHighlight(object()->node(), highlightType, rootRect, rootRect, false, true);
+ page->chrome()->client()->paintCustomHighlight(renderer()->node(), highlightType, rootRect, rootRect, false, true);
}
#endif
@@ -179,7 +197,7 @@ void RootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
InlineFlowBox::paint(paintInfo, tx, ty);
paintEllipsisBox(paintInfo, tx, ty);
#if PLATFORM(MAC)
- RenderStyle* styleToUse = object()->style(m_firstLine);
+ RenderStyle* styleToUse = renderer()->style(m_firstLine);
if (styleToUse->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
paintCustomHighlight(paintInfo, tx, ty, styleToUse->highlight());
#endif
@@ -189,7 +207,7 @@ bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
{
if (m_hasEllipsisBox && visibleToHitTesting()) {
if (ellipsisBox()->nodeAtPoint(request, result, x, y, tx, ty)) {
- object()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
}
@@ -210,10 +228,10 @@ void RootInlineBox::adjustPosition(int dx, int dy)
void RootInlineBox::childRemoved(InlineBox* box)
{
- if (box->object() == m_lineBreakObj)
+ if (box->renderer() == m_lineBreakObj)
setLineBreakInfo(0, 0, BidiStatus());
- for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == box->object(); prev = prev->prevRootBox()) {
+ for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == box->renderer(); prev = prev->prevRootBox()) {
prev->setLineBreakInfo(0, 0, BidiStatus());
prev->markDirty();
}
@@ -232,12 +250,12 @@ GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBl
InlineBox* firstBox = firstSelectedBox();
InlineBox* lastBox = lastSelectedBox();
if (leftGap)
- result.uniteLeft(block()->fillLeftSelectionGap(firstBox->parent()->object(),
- firstBox->xPos(), selTop, selHeight,
+ result.uniteLeft(block()->fillLeftSelectionGap(firstBox->parent()->renderer(),
+ firstBox->x(), selTop, selHeight,
rootBlock, blockX, blockY, tx, ty, paintInfo));
if (rightGap)
- result.uniteRight(block()->fillRightSelectionGap(lastBox->parent()->object(),
- lastBox->xPos() + lastBox->width(), selTop, selHeight,
+ result.uniteRight(block()->fillRightSelectionGap(lastBox->parent()->renderer(),
+ lastBox->x() + lastBox->width(), selTop, selHeight,
rootBlock, blockX, blockY, tx, ty, paintInfo));
// When dealing with bidi text, a non-contiguous selection region is possible.
@@ -249,15 +267,15 @@ GapRects RootInlineBox::fillLineSelectionGap(int selTop, int selHeight, RenderBl
// We can see that the |bbb| run is not part of the selection while the runs around it are.
if (firstBox && firstBox != lastBox) {
// Now fill in any gaps on the line that occurred between two selected elements.
- int lastX = firstBox->xPos() + firstBox->width();
+ int lastX = firstBox->x() + firstBox->width();
bool isPreviousBoxSelected = firstBox->selectionState() != RenderObject::SelectionNone;
for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) {
if (box->selectionState() != RenderObject::SelectionNone) {
- if (isPreviousBoxSelected) // Selection may be non-contiguous, see comment above.
- result.uniteCenter(block()->fillHorizontalSelectionGap(box->parent()->object(),
+ if (isPreviousBoxSelected) // VisibleSelection may be non-contiguous, see comment above.
+ result.uniteCenter(block()->fillHorizontalSelectionGap(box->parent()->renderer(),
lastX + tx, selTop + ty,
- box->xPos() - lastX, selHeight, paintInfo));
- lastX = box->xPos() + box->width();
+ box->x() - lastX, selHeight, paintInfo));
+ lastX = box->x() + box->width();
}
if (box == lastBox)
break;
@@ -326,10 +344,10 @@ int RootInlineBox::selectionTop()
// This line has actually been moved further down, probably from a large line-height, but possibly because the
// line was forced to clear floats. If so, let's check the offsets, and only be willing to use the previous
// line's bottom overflow if the offsets are greater on both sides.
- int prevLeft = block()->leftOffset(prevBottom);
- int prevRight = block()->rightOffset(prevBottom);
- int newLeft = block()->leftOffset(selectionTop);
- int newRight = block()->rightOffset(selectionTop);
+ int prevLeft = block()->leftOffset(prevBottom, !prevRootBox());
+ int prevRight = block()->rightOffset(prevBottom, !prevRootBox());
+ int newLeft = block()->leftOffset(selectionTop, !prevRootBox());
+ int newRight = block()->rightOffset(selectionTop, !prevRootBox());
if (prevLeft > newLeft || prevRight < newRight)
return selectionTop;
}
@@ -339,12 +357,12 @@ int RootInlineBox::selectionTop()
RenderBlock* RootInlineBox::block() const
{
- return static_cast<RenderBlock*>(m_object);
+ return toRenderBlock(renderer());
}
static bool isEditableLeaf(InlineBox* leaf)
{
- return leaf && leaf->object() && leaf->object()->element() && leaf->object()->element()->isContentEditable();
+ return leaf && leaf->renderer() && leaf->renderer()->node() && leaf->renderer()->node()->isContentEditable();
}
InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves)
@@ -355,19 +373,19 @@ InlineBox* RootInlineBox::closestLeafChildForXPos(int x, bool onlyEditableLeaves
return firstLeaf;
// Avoid returning a list marker when possible.
- if (x <= firstLeaf->m_x && !firstLeaf->object()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
+ if (x <= firstLeaf->m_x && !firstLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
// The x coordinate is less or equal to left edge of the firstLeaf.
// Return it.
return firstLeaf;
- if (x >= lastLeaf->m_x + lastLeaf->m_width && !lastLeaf->object()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
+ if (x >= lastLeaf->m_x + lastLeaf->m_width && !lastLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
// The x coordinate is greater or equal to right edge of the lastLeaf.
// Return it.
return lastLeaf;
InlineBox* closestLeaf = 0;
for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChild()) {
- if (!leaf->object()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
+ if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
closestLeaf = leaf;
if (x < leaf->m_x + leaf->m_width)
// The x coordinate is less than the right edge of the box.
@@ -404,12 +422,28 @@ EllipsisBox* RootInlineBox::ellipsisBox() const
void RootInlineBox::setVerticalOverflowPositions(int top, int bottom)
{
if (!m_overflow) {
- if (top == m_y && bottom == m_y + m_height)
+ const Font& font = renderer()->style(m_firstLine)->font();
+ if (top == m_y && bottom == m_y + font.height())
return;
- m_overflow = new (m_object->renderArena()) Overflow(this);
+ m_overflow = new (renderer()->renderArena()) Overflow(this);
}
m_overflow->m_topOverflow = top;
m_overflow->m_bottomOverflow = bottom;
}
+void RootInlineBox::removeLineBoxFromRenderObject()
+{
+ block()->lineBoxes()->removeLineBox(this);
+}
+
+void RootInlineBox::extractLineBoxFromRenderObject()
+{
+ block()->lineBoxes()->extractLineBox(this);
+}
+
+void RootInlineBox::attachLineBoxToRenderObject()
+{
+ block()->lineBoxes()->attachLineBox(this);
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/RootInlineBox.h b/WebCore/rendering/RootInlineBox.h
index a16d1e5..e190a48 100644
--- a/WebCore/rendering/RootInlineBox.h
+++ b/WebCore/rendering/RootInlineBox.h
@@ -43,7 +43,9 @@ public:
{
}
- virtual bool isRootInlineBox() { return true; }
+ virtual bool isRootInlineBox() const { return true; }
+
+ virtual int height() const;
virtual void destroy(RenderArena*);
void detachEllipsisBox(RenderArena*);
@@ -53,16 +55,18 @@ public:
virtual void adjustPosition(int dx, int dy);
- virtual int topOverflow() { return m_overflow ? m_overflow->m_topOverflow : m_y; }
- virtual int bottomOverflow() { return m_overflow ? m_overflow->m_bottomOverflow : m_y + m_height; }
- virtual int leftOverflow() { return m_overflow ? m_overflow->m_leftOverflow : m_x; }
- virtual int rightOverflow() { return m_overflow ? m_overflow->m_rightOverflow : m_x + m_width; }
+ virtual int topOverflow() const { return m_overflow ? m_overflow->m_topOverflow : m_y; }
+ virtual int bottomOverflow() const { return m_overflow ? m_overflow->m_bottomOverflow : m_y + m_renderer->style(m_firstLine)->font().height(); }
+ virtual int leftOverflow() const { return m_overflow ? m_overflow->m_leftOverflow : m_x; }
+ virtual int rightOverflow() const { return m_overflow ? m_overflow->m_rightOverflow : m_x + m_width; }
virtual void setVerticalOverflowPositions(int top, int bottom);
void setHorizontalOverflowPositions(int left, int right);
virtual void setVerticalSelectionPositions(int top, int bottom);
+ virtual RenderLineBoxList* rendererLineBoxes() const;
+
#if ENABLE(SVG)
virtual void computePerCharacterLayoutInformation() { }
#endif
@@ -114,7 +118,7 @@ public:
RenderBlock* block() const;
int selectionTop();
- int selectionBottom() { return m_overflow ? m_overflow->m_selectionBottom : m_y + m_height; }
+ int selectionBottom() { return m_overflow ? m_overflow->m_selectionBottom : m_y + height(); }
int selectionHeight() { return max(0, selectionBottom() - selectionTop()); }
InlineBox* closestLeafChildForXPos(int x, bool onlyEditableLeaves = false);
@@ -123,12 +127,16 @@ public:
{
ASSERT(!isDirty());
if (!m_overflow)
- m_overflow = new (m_object->renderArena()) Overflow(this);
+ m_overflow = new (m_renderer->renderArena()) Overflow(this);
return m_overflow->floats;
}
Vector<RenderBox*>* floatsPtr() { ASSERT(!isDirty()); return m_overflow ? &m_overflow->floats : 0; }
+ virtual void extractLineBoxFromRenderObject();
+ virtual void attachLineBoxToRenderObject();
+ virtual void removeLineBoxFromRenderObject();
+
protected:
// Normally we are only as tall as the style on our block dictates, but we might have content
// that spills out above the height of our font (e.g, a tall image), or something that extends further
@@ -138,11 +146,11 @@ protected:
struct Overflow {
Overflow(RootInlineBox* box)
: m_topOverflow(box->m_y)
- , m_bottomOverflow(box->m_y + box->m_height)
+ , m_bottomOverflow(box->m_y + box->height())
, m_leftOverflow(box->m_x)
, m_rightOverflow(box->m_x + box->m_width)
, m_selectionTop(box->m_y)
- , m_selectionBottom(box->m_y + box->m_height)
+ , m_selectionBottom(box->m_y + box->height())
{
}
@@ -184,7 +192,7 @@ inline void RootInlineBox::setHorizontalOverflowPositions(int left, int right)
if (!m_overflow) {
if (left == m_x && right == m_x + m_width)
return;
- m_overflow = new (m_object->renderArena()) Overflow(this);
+ m_overflow = new (m_renderer->renderArena()) Overflow(this);
}
m_overflow->m_leftOverflow = left;
m_overflow->m_rightOverflow = right;
@@ -193,9 +201,10 @@ inline void RootInlineBox::setHorizontalOverflowPositions(int left, int right)
inline void RootInlineBox::setVerticalSelectionPositions(int top, int bottom)
{
if (!m_overflow) {
- if (top == m_y && bottom == m_y + m_height)
+ const Font& font = m_renderer->style(m_firstLine)->font();
+ if (top == m_y && bottom == m_y + font.height())
return;
- m_overflow = new (m_object->renderArena()) Overflow(this);
+ m_overflow = new (m_renderer->renderArena()) Overflow(this);
}
m_overflow->m_selectionTop = top;
m_overflow->m_selectionBottom = bottom;
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.cpp b/WebCore/rendering/SVGCharacterLayoutInfo.cpp
index 89bab2d..8871a75 100644
--- a/WebCore/rendering/SVGCharacterLayoutInfo.cpp
+++ b/WebCore/rendering/SVGCharacterLayoutInfo.cpp
@@ -274,7 +274,7 @@ void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float
angleStack.isEmpty() && baselineShiftStack.isEmpty() &&
curx == 0.0f && cury == 0.0f;
- RenderSVGTextPath* textPath = static_cast<RenderSVGTextPath*>(flowBox->object());
+ RenderSVGTextPath* textPath = static_cast<RenderSVGTextPath*>(flowBox->renderer());
Path path = textPath->layoutPath();
float baselineShift = calculateBaselineShift(textPath);
@@ -521,7 +521,7 @@ TransformationMatrix SVGChar::characterTransform() const
ctm.rotate(angle);
if (pathData) {
- ctm.scale(pathData->xScale, pathData->yScale);
+ ctm.scaleNonUniform(pathData->xScale, pathData->yScale);
ctm.translate(pathData->xShift, pathData->yShift);
ctm.rotate(pathData->orientationAngle);
}
diff --git a/WebCore/rendering/SVGInlineFlowBox.h b/WebCore/rendering/SVGInlineFlowBox.h
index bb31807..2742ca0 100644
--- a/WebCore/rendering/SVGInlineFlowBox.h
+++ b/WebCore/rendering/SVGInlineFlowBox.h
@@ -33,12 +33,19 @@ class SVGInlineFlowBox : public InlineFlowBox {
public:
SVGInlineFlowBox(RenderObject* obj)
: InlineFlowBox(obj)
+ , m_height(0)
{
}
+ virtual int height() const { return m_height; }
+ void setHeight(int h) { m_height = h; }
+
virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
virtual int placeBoxesHorizontally(int x, int& leftPosition, int& rightPosition, bool& needsWordSpacing);
virtual int verticallyAlignBoxes(int heightOfBlock);
+
+private:
+ int m_height;
};
} // namespace WebCore
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index 620aea5..f424ef2 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -44,6 +44,7 @@ namespace WebCore {
SVGInlineTextBox::SVGInlineTextBox(RenderObject* obj)
: InlineTextBox(obj)
+ , m_height(0)
{
}
@@ -77,7 +78,7 @@ SVGRootInlineBox* SVGInlineTextBox::svgRootInlineBox() const
float SVGInlineTextBox::calculateGlyphWidth(RenderStyle* style, int offset, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
{
ASSERT(style);
- return style->font().floatWidth(svgTextRunForInlineTextBox(textObject()->text()->characters() + offset, 1, style, this, 0), extraCharsAvailable, charsConsumed, glyphName);
+ return style->font().floatWidth(svgTextRunForInlineTextBox(textRenderer()->text()->characters() + offset, 1, style, this, 0), extraCharsAvailable, charsConsumed, glyphName);
}
float SVGInlineTextBox::calculateGlyphHeight(RenderStyle* style, int, int) const
@@ -125,14 +126,14 @@ struct SVGInlineTextBoxClosestCharacterToPositionWalker {
, m_distance(FLT_MAX)
, m_x(x)
, m_y(y)
- , m_offset(0)
+ , m_offsetOfHitCharacter(0)
{
}
void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
- RenderStyle* style = textBox->textObject()->style();
+ RenderStyle* style = textBox->textRenderer()->style();
Vector<SVGChar>::iterator closestCharacter = 0;
unsigned int closestOffset = UINT_MAX;
@@ -164,7 +165,7 @@ struct SVGInlineTextBoxClosestCharacterToPositionWalker {
if (closestOffset != UINT_MAX) {
// Record current chunk, if it contains the current closest character next to the mouse.
m_character = closestCharacter;
- m_offset = closestOffset;
+ m_offsetOfHitCharacter = closestOffset;
}
}
@@ -173,12 +174,12 @@ struct SVGInlineTextBoxClosestCharacterToPositionWalker {
return m_character;
}
- int offset() const
+ int offsetOfHitCharacter() const
{
if (!m_character)
return 0;
- return m_offset;
+ return m_offsetOfHitCharacter;
}
private:
@@ -187,7 +188,7 @@ private:
int m_x;
int m_y;
- int m_offset;
+ int m_offsetOfHitCharacter;
};
// Helper class for selectionRect()
@@ -199,7 +200,7 @@ struct SVGInlineTextBoxSelectionRectWalker {
void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
- RenderStyle* style = textBox->textObject()->style();
+ RenderStyle* style = textBox->textRenderer()->style();
for (Vector<SVGChar>::iterator it = start; it != end; ++it) {
if (it->isHidden())
@@ -221,7 +222,7 @@ private:
FloatRect m_selectionRect;
};
-SVGChar* SVGInlineTextBox::closestCharacterToPosition(int x, int y, int& offset) const
+SVGChar* SVGInlineTextBox::closestCharacterToPosition(int x, int y, int& offsetOfHitCharacter) const
{
SVGRootInlineBox* rootBox = svgRootInlineBox();
if (!rootBox)
@@ -232,25 +233,30 @@ SVGChar* SVGInlineTextBox::closestCharacterToPosition(int x, int y, int& offset)
rootBox->walkTextChunks(&walker, this);
- offset = walkerCallback.offset();
+ offsetOfHitCharacter = walkerCallback.offsetOfHitCharacter();
return walkerCallback.character();
}
-bool SVGInlineTextBox::svgCharacterHitsPosition(int x, int y, int& offset) const
+bool SVGInlineTextBox::svgCharacterHitsPosition(int x, int y, int& closestOffsetInBox) const
{
- SVGChar* charAtPosPtr = closestCharacterToPosition(x, y, offset);
+ int offsetOfHitCharacter = 0;
+ SVGChar* charAtPosPtr = closestCharacterToPosition(x, y, offsetOfHitCharacter);
if (!charAtPosPtr)
return false;
SVGChar& charAtPos = *charAtPosPtr;
- RenderStyle* style = textObject()->style(m_firstLine);
- FloatRect glyphRect = calculateGlyphBoundaries(style, offset, charAtPos);
+ RenderStyle* style = textRenderer()->style(m_firstLine);
+ FloatRect glyphRect = calculateGlyphBoundaries(style, offsetOfHitCharacter, charAtPos);
+ // FIXME: Why?
if (direction() == RTL)
- offset++;
+ offsetOfHitCharacter++;
- // FIXME: todo list
- // (#13910) This code does not handle bottom-to-top/top-to-bottom vertical text.
+ // The caller actually the closest offset before/after the hit char
+ // closestCharacterToPosition returns us offsetOfHitCharacter.
+ closestOffsetInBox = offsetOfHitCharacter;
+
+ // FIXME: (bug 13910) This code does not handle bottom-to-top/top-to-bottom vertical text.
// Check whether y position hits the current character
if (y < charAtPos.y - glyphRect.height() || y > charAtPos.y)
@@ -258,21 +264,21 @@ bool SVGInlineTextBox::svgCharacterHitsPosition(int x, int y, int& offset) const
// Check whether x position hits the current character
if (x < charAtPos.x) {
- if (offset > 0 && direction() == LTR)
+ if (closestOffsetInBox > 0 && direction() == LTR)
return true;
- else if (offset < (int) end() && direction() == RTL)
+ else if (closestOffsetInBox < (int) end() && direction() == RTL)
return true;
return false;
}
- // If we are past the last glyph of this box, don't mark it as 'hit' anymore.
- if (x >= charAtPos.x + glyphRect.width() && offset == (int) end())
- return false;
-
- // Snap to character at half of it's advance
+ // Adjust the closest offset to after the char if x was after the char midpoint
if (x >= charAtPos.x + glyphRect.width() / 2.0)
- offset += direction() == RTL ? -1 : 1;
+ closestOffsetInBox += direction() == RTL ? -1 : 1;
+
+ // If we are past the last glyph of this box, don't mark it as 'hit'
+ if (x >= charAtPos.x + glyphRect.width() && closestOffsetInBox == (int) end())
+ return false;
return true;
}
@@ -296,8 +302,8 @@ bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result,
ASSERT(!isLineBreak());
IntRect rect = selectionRect(0, 0, 0, len());
- if (object()->style()->visibility() == VISIBLE && rect.contains(x, y)) {
- object()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ if (renderer()->style()->visibility() == VISIBLE && rect.contains(x, y)) {
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
return true;
}
@@ -324,12 +330,12 @@ IntRect SVGInlineTextBox::selectionRect(int, int, int startPos, int endPos)
void SVGInlineTextBox::paintCharacters(RenderObject::PaintInfo& paintInfo, int tx, int ty, const SVGChar& svgChar, const UChar* chars, int length, SVGPaintServer* activePaintServer)
{
- if (object()->style()->visibility() != VISIBLE || paintInfo.phase == PaintPhaseOutline)
+ if (renderer()->style()->visibility() != VISIBLE || paintInfo.phase == PaintPhaseOutline)
return;
ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines);
- RenderText* text = textObject();
+ RenderText* text = textRenderer();
ASSERT(text);
bool isPrinting = text->document()->printing();
@@ -444,7 +450,7 @@ void SVGInlineTextBox::paintSelection(int boxStartOffset, const SVGChar& svgChar
return;
Color textColor = style->color();
- Color color = object()->selectionBackgroundColor();
+ Color color = renderer()->selectionBackgroundColor();
if (!color.isValid() || color.alpha() == 0)
return;
@@ -471,7 +477,7 @@ void SVGInlineTextBox::paintSelection(int boxStartOffset, const SVGChar& svgChar
p->save();
int adjust = startPos >= boxStartOffset ? boxStartOffset : 0;
- p->drawHighlightForText(font, svgTextRunForInlineTextBox(textObject()->text()->characters() + start() + boxStartOffset, length, style, this, svgChar.x),
+ p->drawHighlightForText(font, svgTextRunForInlineTextBox(textRenderer()->text()->characters() + start() + boxStartOffset, length, style, this, svgChar.x),
IntPoint((int) svgChar.x, (int) svgChar.y - font.ascent()),
font.ascent() + font.descent(), color, startPos - adjust, endPos - adjust);
@@ -496,7 +502,7 @@ static inline Path pathForDecoration(ETextDecoration decoration, RenderObject* o
void SVGInlineTextBox::paintDecoration(ETextDecoration decoration, GraphicsContext* context, int tx, int ty, int width, const SVGChar& svgChar, const SVGTextDecorationInfo& info)
{
- if (object()->style()->visibility() != VISIBLE)
+ if (renderer()->style()->visibility() != VISIBLE)
return;
// This function does NOT accept combinated text decorations. It's meant to be invoked for just one.
@@ -508,10 +514,11 @@ void SVGInlineTextBox::paintDecoration(ETextDecoration decoration, GraphicsConte
if (!isFilled && !isStroked)
return;
+ int baseline = renderer()->style(m_firstLine)->font().ascent();
if (decoration == UNDERLINE)
- ty += m_baseline;
+ ty += baseline;
else if (decoration == LINE_THROUGH)
- ty += 2 * m_baseline / 3;
+ ty += 2 * baseline / 3;
context->save();
context->beginPath();
diff --git a/WebCore/rendering/SVGInlineTextBox.h b/WebCore/rendering/SVGInlineTextBox.h
index 9882128..6287c81 100644
--- a/WebCore/rendering/SVGInlineTextBox.h
+++ b/WebCore/rendering/SVGInlineTextBox.h
@@ -37,6 +37,9 @@ namespace WebCore {
public:
SVGInlineTextBox(RenderObject* obj);
+ virtual int height() const { return m_height; }
+ void setHeight(int h) { m_height = h; }
+
virtual int selectionTop();
virtual int selectionHeight();
@@ -67,6 +70,8 @@ namespace WebCore {
private:
friend class RenderSVGInlineText;
bool svgCharacterHitsPosition(int x, int y, int& offset) const;
+
+ int m_height;
};
} // namespace WebCore
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 9ffc533..dd154c7 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -46,9 +46,9 @@ void prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& pa
UNUSED_PARAM(rootFilter);
#endif
- SVGElement* svgElement = static_cast<SVGElement*>(object->element());
- ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
ASSERT(object);
+ SVGElement* svgElement = static_cast<SVGElement*>(object->node());
+ ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
const RenderStyle* style = object->style();
@@ -160,7 +160,7 @@ void clampImageBufferSizeToViewport(RenderObject* object, IntSize& size)
if (!object || !object->isRenderView())
return;
- RenderView* view = static_cast<RenderView*>(object);
+ RenderView* view = toRenderView(object);
if (!view->frameView())
return;
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index 74a8af9..1f97c47 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -432,7 +432,7 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB
ts << " override";
}
- ts << ": " << quoteAndEscapeNonPrintables(String(textBox->textObject()->text()).substring(textBox->start() + range.startOffset, offset)) << "\n";
+ ts << ": " << quoteAndEscapeNonPrintables(String(textBox->textRenderer()->text()).substring(textBox->start() + range.startOffset, offset)) << "\n";
j++;
}
@@ -459,8 +459,8 @@ void write(TextStream& ts, const RenderSVGContainer& container, int indent)
writeIndent(ts, indent);
ts << container.renderName();
- if (container.element()) {
- String tagName = getTagName(static_cast<SVGStyledElement*>(container.element()));
+ if (container.node()) {
+ String tagName = getTagName(static_cast<SVGStyledElement*>(container.node()));
if (!tagName.isEmpty())
ts << " {" << tagName << "}";
}
@@ -476,8 +476,8 @@ void write(TextStream& ts, const RenderSVGRoot& root, int indent)
writeIndent(ts, indent);
ts << root.renderName();
- if (root.element()) {
- String tagName = getTagName(static_cast<SVGStyledElement*>(root.element()));
+ if (root.node()) {
+ String tagName = getTagName(static_cast<SVGStyledElement*>(root.node()));
if (!tagName.isEmpty())
ts << " {" << tagName << "}";
}
@@ -493,8 +493,8 @@ void write(TextStream& ts, const RenderSVGText& text, int indent)
writeIndent(ts, indent);
ts << text.renderName();
- if (text.element()) {
- String tagName = getTagName(static_cast<SVGStyledElement*>(text.element()));
+ if (text.node()) {
+ String tagName = getTagName(static_cast<SVGStyledElement*>(text.node()));
if (!tagName.isEmpty())
ts << " {" << tagName << "}";
}
@@ -510,8 +510,8 @@ void write(TextStream& ts, const RenderSVGInlineText& text, int indent)
writeIndent(ts, indent);
ts << text.renderName();
- if (text.element()) {
- String tagName = getTagName(static_cast<SVGStyledElement*>(text.element()));
+ if (text.node()) {
+ String tagName = getTagName(static_cast<SVGStyledElement*>(text.node()));
if (!tagName.isEmpty())
ts << " {" << tagName << "}";
}
@@ -527,8 +527,8 @@ void write(TextStream& ts, const RenderPath& path, int indent)
writeIndent(ts, indent);
ts << path.renderName();
- if (path.element()) {
- String tagName = getTagName(static_cast<SVGStyledElement*>(path.element()));
+ if (path.node()) {
+ String tagName = getTagName(static_cast<SVGStyledElement*>(path.node()));
if (!tagName.isEmpty())
ts << " {" << tagName << "}";
}
diff --git a/WebCore/rendering/SVGRootInlineBox.cpp b/WebCore/rendering/SVGRootInlineBox.cpp
index 62a8b04..88c7542 100644
--- a/WebCore/rendering/SVGRootInlineBox.cpp
+++ b/WebCore/rendering/SVGRootInlineBox.cpp
@@ -344,7 +344,7 @@ struct SVGRootInlineBoxPaintWalker {
, m_chunkStarted(false)
, m_paintInfo(paintInfo)
, m_savedInfo(paintInfo)
- , m_boundingBox(tx + rootBox->xPos(), ty + rootBox->yPos(), rootBox->width(), rootBox->height())
+ , m_boundingBox(tx + rootBox->x(), ty + rootBox->y(), rootBox->width(), rootBox->height())
, m_filter(0)
, m_rootFilter(rootFilter)
, m_fillPaintServer(0)
@@ -396,14 +396,14 @@ struct SVGRootInlineBoxPaintWalker {
InlineFlowBox* flowBox = box->parent();
// Initialize text rendering
- RenderObject* object = flowBox->object();
+ RenderObject* object = flowBox->renderer();
ASSERT(object);
m_savedInfo = m_paintInfo;
m_paintInfo.context->save();
if (!flowBox->isRootInlineBox())
- m_paintInfo.context->concatCTM(m_rootBox->object()->localTransform());
+ m_paintInfo.context->concatCTM(m_rootBox->renderer()->localTransform());
m_paintInfo.context->concatCTM(object->localTransform());
@@ -420,7 +420,7 @@ struct SVGRootInlineBoxPaintWalker {
InlineFlowBox* flowBox = box->parent();
- RenderObject* object = flowBox->object();
+ RenderObject* object = flowBox->renderer();
ASSERT(object);
// Clean up last used paint server
@@ -443,7 +443,7 @@ struct SVGRootInlineBoxPaintWalker {
InlineFlowBox* flowBox = box->parent();
// Setup fill paint server
- RenderObject* object = flowBox->object();
+ RenderObject* object = flowBox->renderer();
ASSERT(object);
ASSERT(!m_strokePaintServer);
@@ -464,7 +464,7 @@ struct SVGRootInlineBoxPaintWalker {
InlineFlowBox* flowBox = box->parent();
// Setup stroke paint server
- RenderObject* object = flowBox->object();
+ RenderObject* object = flowBox->renderer();
ASSERT(object);
// If we're both stroked & filled, teardown fill paint server before stroking.
@@ -485,7 +485,7 @@ struct SVGRootInlineBoxPaintWalker {
void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
- RenderText* text = textBox->textObject();
+ RenderText* text = textBox->textRenderer();
ASSERT(text);
RenderStyle* styleToUse = text->style(textBox->isFirstLineStyle());
@@ -581,12 +581,12 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
paintInfo.context->save();
SVGResourceFilter* filter = 0;
- FloatRect boundingBox(tx + xPos(), ty + yPos(), width(), height());
+ FloatRect boundingBox(tx + x(), ty + y(), width(), height());
// Initialize text rendering
- paintInfo.context->concatCTM(object()->localTransform());
- prepareToRenderSVGContent(object(), paintInfo, boundingBox, filter);
- paintInfo.context->concatCTM(object()->localTransform().inverse());
+ paintInfo.context->concatCTM(renderer()->localTransform());
+ prepareToRenderSVGContent(renderer(), paintInfo, boundingBox, filter);
+ paintInfo.context->concatCTM(renderer()->localTransform().inverse());
// Render text, chunk-by-chunk
SVGRootInlineBoxPaintWalker walkerCallback(this, filter, paintInfo, tx, ty);
@@ -600,7 +600,7 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
walkTextChunks(&walker);
// Finalize text rendering
- finishRenderSVGContent(object(), paintInfo, boundingBox, filter, savedInfo.context);
+ finishRenderSVGContent(renderer(), paintInfo, boundingBox, filter, savedInfo.context);
paintInfo.context->restore();
}
@@ -625,7 +625,7 @@ float cummulatedWidthOfInlineBoxCharacterRange(SVGInlineBoxCharacterRange& range
ASSERT(range.box->isInlineTextBox());
InlineTextBox* textBox = static_cast<InlineTextBox*>(range.box);
- RenderText* text = textBox->textObject();
+ RenderText* text = textBox->textRenderer();
RenderStyle* style = text->style();
return style->font().floatWidth(svgTextRunForInlineTextBox(text->characters() + textBox->start() + range.startOffset, range.endOffset - range.startOffset, style, textBox, 0));
@@ -638,7 +638,7 @@ float cummulatedHeightOfInlineBoxCharacterRange(SVGInlineBoxCharacterRange& rang
ASSERT(range.box->isInlineTextBox());
InlineTextBox* textBox = static_cast<InlineTextBox*>(range.box);
- RenderText* text = textBox->textObject();
+ RenderText* text = textBox->textRenderer();
const Font& font = text->style()->font();
return (range.endOffset - range.startOffset) * (font.ascent() + font.descent());
@@ -652,7 +652,7 @@ TextRun svgTextRunForInlineTextBox(const UChar* c, int len, RenderStyle* style,
TextRun run(c, len, false, static_cast<int>(xPos), textBox->toAdd(), textBox->direction() == RTL, textBox->m_dirOverride || style->visuallyOrdered());
#if ENABLE(SVG_FONTS)
- run.setReferencingRenderObject(textBox->textObject()->parent());
+ run.setReferencingRenderObject(textBox->textRenderer()->parent());
#endif
// We handle letter & word spacing ourselves
@@ -672,7 +672,7 @@ static float cummulatedWidthOrHeightOfTextChunk(SVGTextChunk& chunk, bool calcWi
SVGInlineBoxCharacterRange& range = *it;
SVGInlineTextBox* box = static_cast<SVGInlineTextBox*>(range.box);
- RenderStyle* style = box->object()->style();
+ RenderStyle* style = box->renderer()->style();
for (int i = range.startOffset; i < range.endOffset; ++i) {
ASSERT(charIt <= chunk.end);
@@ -791,13 +791,12 @@ static void applyTextAnchorToTextChunk(SVGTextChunk& chunk)
InlineBox* curBox = range.box;
ASSERT(curBox->isInlineTextBox());
- ASSERT(curBox->parent() && (curBox->parent()->isRootInlineBox() || curBox->parent()->isInlineFlowBox()));
// Move target box
if (chunk.isVerticalText)
- curBox->setYPos(curBox->yPos() + static_cast<int>(shift));
+ curBox->setY(curBox->y() + static_cast<int>(shift));
else
- curBox->setXPos(curBox->xPos() + static_cast<int>(shift));
+ curBox->setX(curBox->x() + static_cast<int>(shift));
}
}
@@ -820,9 +819,9 @@ static float calculateTextLengthCorrectionForTextChunk(SVGTextChunk& chunk, ELen
if (lengthAdjust == SVGTextContentElement::LENGTHADJUST_SPACINGANDGLYPHS) {
if (chunk.isVerticalText)
- chunk.ctm.scale(1.0f, chunk.textLength / computedLength);
+ chunk.ctm.scaleNonUniform(1.0f, chunk.textLength / computedLength);
else
- chunk.ctm.scale(chunk.textLength / computedLength, 1.0f);
+ chunk.ctm.scaleNonUniform(chunk.textLength / computedLength, 1.0f);
return 0.0f;
}
@@ -898,9 +897,9 @@ void SVGRootInlineBox::computePerCharacterLayoutInformation()
void SVGRootInlineBox::buildLayoutInformation(InlineFlowBox* start, SVGCharacterLayoutInfo& info)
{
if (start->isRootInlineBox()) {
- ASSERT(start->object()->element()->hasTagName(SVGNames::textTag));
+ ASSERT(start->renderer()->node()->hasTagName(SVGNames::textTag));
- SVGTextPositioningElement* positioningElement = static_cast<SVGTextPositioningElement*>(start->object()->element());
+ SVGTextPositioningElement* positioningElement = static_cast<SVGTextPositioningElement*>(start->renderer()->node());
ASSERT(positioningElement);
ASSERT(positioningElement->parentNode());
@@ -910,20 +909,20 @@ void SVGRootInlineBox::buildLayoutInformation(InlineFlowBox* start, SVGCharacter
LastGlyphInfo lastGlyph;
for (InlineBox* curr = start->firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->object()->isText())
+ if (curr->renderer()->isText())
buildLayoutInformationForTextBox(info, static_cast<InlineTextBox*>(curr), lastGlyph);
else {
ASSERT(curr->isInlineFlowBox());
InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(curr);
- if (!flowBox->object()->element())
+ if (!flowBox->renderer()->node())
continue; // Skip generated content.
- bool isAnchor = flowBox->object()->element()->hasTagName(SVGNames::aTag);
- bool isTextPath = flowBox->object()->element()->hasTagName(SVGNames::textPathTag);
+ bool isAnchor = flowBox->renderer()->node()->hasTagName(SVGNames::aTag);
+ bool isTextPath = flowBox->renderer()->node()->hasTagName(SVGNames::textPathTag);
if (!isTextPath && !isAnchor) {
- SVGTextPositioningElement* positioningElement = static_cast<SVGTextPositioningElement*>(flowBox->object()->element());
+ SVGTextPositioningElement* positioningElement = static_cast<SVGTextPositioningElement*>(flowBox->renderer()->node());
ASSERT(positioningElement);
ASSERT(positioningElement->parentNode());
@@ -933,13 +932,13 @@ void SVGRootInlineBox::buildLayoutInformation(InlineFlowBox* start, SVGCharacter
// Handle text-anchor/textLength on path, which is special.
SVGTextContentElement* textContent = 0;
- Node* node = flowBox->object()->element();
+ Node* node = flowBox->renderer()->node();
if (node && node->isSVGElement())
textContent = static_cast<SVGTextContentElement*>(node);
ASSERT(textContent);
ELengthAdjust lengthAdjust = (ELengthAdjust) textContent->lengthAdjust();
- ETextAnchor anchor = flowBox->object()->style()->svgStyle()->textAnchor();
+ ETextAnchor anchor = flowBox->renderer()->style()->svgStyle()->textAnchor();
float textAnchorStartOffset = 0.0f;
// Initialize sub-layout. We need to create text chunks from the textPath
@@ -1008,10 +1007,8 @@ void SVGRootInlineBox::layoutInlineBoxes()
void SVGRootInlineBox::layoutInlineBoxes(InlineFlowBox* start, Vector<SVGChar>::iterator& it, int& lowX, int& highX, int& lowY, int& highY)
{
for (InlineBox* curr = start->firstChild(); curr; curr = curr->nextOnLine()) {
- RenderStyle* style = curr->object()->style();
- const Font& font = style->font();
-
- if (curr->object()->isText()) {
+ RenderStyle* style = curr->renderer()->style();
+ if (curr->renderer()->isText()) {
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(curr);
unsigned length = textBox->len();
@@ -1039,12 +1036,11 @@ void SVGRootInlineBox::layoutInlineBoxes(InlineFlowBox* start, Vector<SVGChar>::
int minY = enclosedStringRect.y();
int maxY = minY + enclosedStringRect.height();
- curr->setXPos(minX - block()->x());
+ curr->setX(minX - block()->x());
curr->setWidth(enclosedStringRect.width());
- curr->setYPos(minY - block()->y());
- curr->setBaseline(font.ascent());
- curr->setHeight(enclosedStringRect.height());
+ curr->setY(minY - block()->y());
+ textBox->setHeight(enclosedStringRect.height());
if (minX < lowX)
lowX = minX;
@@ -1067,17 +1063,16 @@ void SVGRootInlineBox::layoutInlineBoxes(InlineFlowBox* start, Vector<SVGChar>::
InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(curr);
- if (!flowBox->object()->element())
+ if (!flowBox->renderer()->node())
continue; // Skip generated content.
layoutInlineBoxes(flowBox, it, minX, maxX, minY, maxY);
- curr->setXPos(minX - block()->x());
+ curr->setX(minX - block()->x());
curr->setWidth(maxX - minX);
- curr->setYPos(minY - block()->y());
- curr->setBaseline(font.ascent());
- curr->setHeight(maxY - minY);
+ curr->setY(minY - block()->y());
+ static_cast<SVGInlineFlowBox*>(curr)->setHeight(maxY - minY);
if (minX < lowX)
lowX = minX;
@@ -1093,15 +1088,15 @@ void SVGRootInlineBox::layoutInlineBoxes(InlineFlowBox* start, Vector<SVGChar>::
}
}
- if (start->isRootInlineBox()) {
+ if (start->isSVGRootInlineBox()) {
int top = lowY - block()->y();
int bottom = highY - block()->y();
- start->setXPos(lowX - block()->x());
- start->setYPos(top);
+ start->setX(lowX - block()->x());
+ start->setY(top);
start->setWidth(highX - lowX);
- start->setHeight(highY - lowY);
+ static_cast<SVGRootInlineBox*>(start)->setHeight(highY - lowY);
start->setVerticalOverflowPositions(top, bottom);
start->setVerticalSelectionPositions(top, bottom);
@@ -1110,7 +1105,7 @@ void SVGRootInlineBox::layoutInlineBoxes(InlineFlowBox* start, Vector<SVGChar>::
void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo& info, InlineTextBox* textBox, LastGlyphInfo& lastGlyph)
{
- RenderText* text = textBox->textObject();
+ RenderText* text = textBox->textRenderer();
ASSERT(text);
RenderStyle* style = text->style(textBox->isFirstLineStyle());
@@ -1141,11 +1136,11 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
if (textBox->direction() == RTL) {
glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->end() - i, extraCharsAvailable, charsConsumed, glyphName);
glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->end() - i, extraCharsAvailable);
- unicodeStr = String(textBox->textObject()->text()->characters() + textBox->end() - i, charsConsumed);
+ unicodeStr = String(textBox->textRenderer()->text()->characters() + textBox->end() - i, charsConsumed);
} else {
glyphWidth = svgTextBox->calculateGlyphWidth(style, textBox->start() + i, extraCharsAvailable, charsConsumed, glyphName);
glyphHeight = svgTextBox->calculateGlyphHeight(style, textBox->start() + i, extraCharsAvailable);
- unicodeStr = String(textBox->textObject()->text()->characters() + textBox->start() + i, charsConsumed);
+ unicodeStr = String(textBox->textRenderer()->text()->characters() + textBox->start() + i, charsConsumed);
}
bool assignedX = false;
@@ -1195,7 +1190,7 @@ void SVGRootInlineBox::buildLayoutInformationForTextBox(SVGCharacterLayoutInfo&
}
// Take letter & word spacing and kerning into account
- float spacing = font.letterSpacing() + calculateKerning(textBox->object()->element()->renderer());
+ float spacing = font.letterSpacing() + calculateKerning(textBox->renderer()->node()->renderer());
const UChar* currentCharacter = text->characters() + (textBox->direction() == RTL ? textBox->end() - i : textBox->start() + i);
const UChar* lastCharacter = 0;
@@ -1370,7 +1365,7 @@ void SVGRootInlineBox::buildTextChunks(Vector<SVGChar>& svgChars, InlineFlowBox*
#endif
for (InlineBox* curr = start->firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->object()->isText()) {
+ if (curr->renderer()->isText()) {
InlineTextBox* textBox = static_cast<InlineTextBox*>(curr);
unsigned length = textBox->len();
@@ -1382,12 +1377,12 @@ void SVGRootInlineBox::buildTextChunks(Vector<SVGChar>& svgChars, InlineFlowBox*
textBox, length, textBox->start(), textBox->end(), (int) info.handlingTextPath);
#endif
- RenderText* text = textBox->textObject();
+ RenderText* text = textBox->textRenderer();
ASSERT(text);
- ASSERT(text->element());
+ ASSERT(text->node());
SVGTextContentElement* textContent = 0;
- Node* node = text->element()->parent();
+ Node* node = text->node()->parent();
while (node && node->isSVGElement() && !textContent) {
if (static_cast<SVGElement*>(node)->isTextContent())
textContent = static_cast<SVGTextContentElement*>(node);
@@ -1525,10 +1520,10 @@ void SVGRootInlineBox::buildTextChunks(Vector<SVGChar>& svgChars, InlineFlowBox*
ASSERT(curr->isInlineFlowBox());
InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(curr);
- if (!flowBox->object()->element())
+ if (!flowBox->renderer()->node())
continue; // Skip generated content.
- bool isTextPath = flowBox->object()->element()->hasTagName(SVGNames::textPathTag);
+ bool isTextPath = flowBox->renderer()->node()->hasTagName(SVGNames::textPathTag);
#if DEBUG_CHUNK_BUILDING > 1
fprintf(stderr, " -> Handle inline flow box (%p), isTextPath=%i\n", flowBox, (int) isTextPath);
diff --git a/WebCore/rendering/SVGRootInlineBox.h b/WebCore/rendering/SVGRootInlineBox.h
index bfe9889..10c43ea 100644
--- a/WebCore/rendering/SVGRootInlineBox.h
+++ b/WebCore/rendering/SVGRootInlineBox.h
@@ -47,11 +47,15 @@ class SVGRootInlineBox : public RootInlineBox {
public:
SVGRootInlineBox(RenderObject* obj)
: RootInlineBox(obj)
+ , m_height(0)
{
}
virtual bool isSVGRootInlineBox() { return true; }
+ virtual int height() const { return m_height; }
+ void setHeight(int h) { m_height = h; }
+
virtual void paint(RenderObject::PaintInfo&, int tx, int ty);
virtual int placeBoxesHorizontally(int x, int& leftPosition, int& rightPosition, bool& needsWordSpacing);
@@ -80,6 +84,7 @@ private:
SVGTextDecorationInfo retrievePaintServersForTextDecoration(RenderObject* start);
private:
+ int m_height;
Vector<SVGChar> m_svgChars;
Vector<SVGTextChunk> m_svgTextChunks;
};
diff --git a/WebCore/rendering/ScrollBehavior.cpp b/WebCore/rendering/ScrollBehavior.cpp
new file mode 100644
index 0000000..232ea19
--- /dev/null
+++ b/WebCore/rendering/ScrollBehavior.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Portions are Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ * Robert O'Callahan <roc+@cs.cmu.edu>
+ * David Baron <dbaron@fas.harvard.edu>
+ * Christian Biesinger <cbiesinger@web.de>
+ * Randall Jesup <rjesup@wgate.com>
+ * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
+ * Josh Soref <timeless@mac.com>
+ * Boris Zbarsky <bzbarsky@mit.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "ScrollBehavior.h"
+
+namespace WebCore {
+
+const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { noScroll, alignCenter, alignToClosestEdge };
+const ScrollAlignment ScrollAlignment::alignToEdgeIfNeeded = { noScroll, alignToClosestEdge, alignToClosestEdge };
+const ScrollAlignment ScrollAlignment::alignCenterAlways = { alignCenter, alignCenter, alignCenter };
+const ScrollAlignment ScrollAlignment::alignTopAlways = { alignTop, alignTop, alignTop };
+const ScrollAlignment ScrollAlignment::alignBottomAlways = { alignBottom, alignBottom, alignBottom };
+
+}; // namespace WebCore
diff --git a/WebCore/rendering/ScrollBehavior.h b/WebCore/rendering/ScrollBehavior.h
new file mode 100644
index 0000000..390c68a
--- /dev/null
+++ b/WebCore/rendering/ScrollBehavior.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003, 2009 Apple Inc. All rights reserved.
+ *
+ * Portions are Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ * Robert O'Callahan <roc+@cs.cmu.edu>
+ * David Baron <dbaron@fas.harvard.edu>
+ * Christian Biesinger <cbiesinger@web.de>
+ * Randall Jesup <rjesup@wgate.com>
+ * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
+ * Josh Soref <timeless@mac.com>
+ * Boris Zbarsky <bzbarsky@mit.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#ifndef ScrollBehavior_h
+#define ScrollBehavior_h
+
+namespace WebCore {
+
+enum ScrollBehavior {
+ noScroll,
+ alignCenter,
+ alignTop,
+ alignBottom,
+ alignLeft,
+ alignRight,
+ alignToClosestEdge
+};
+
+struct ScrollAlignment {
+ static ScrollBehavior getVisibleBehavior(const ScrollAlignment& s) { return s.m_rectVisible; }
+ static ScrollBehavior getPartialBehavior(const ScrollAlignment& s) { return s.m_rectPartial; }
+ static ScrollBehavior getHiddenBehavior(const ScrollAlignment& s) { return s.m_rectHidden; }
+
+ static const ScrollAlignment alignCenterIfNeeded;
+ static const ScrollAlignment alignToEdgeIfNeeded;
+ static const ScrollAlignment alignCenterAlways;
+ static const ScrollAlignment alignTopAlways;
+ static const ScrollAlignment alignBottomAlways;
+
+ ScrollBehavior m_rectVisible;
+ ScrollBehavior m_rectHidden;
+ ScrollBehavior m_rectPartial;
+};
+
+
+}; // namespace WebCore
+
+#endif // ScrollBehavior_h
diff --git a/WebCore/rendering/TextControlInnerElements.cpp b/WebCore/rendering/TextControlInnerElements.cpp
index 452333c..cd067de 100644
--- a/WebCore/rendering/TextControlInnerElements.cpp
+++ b/WebCore/rendering/TextControlInnerElements.cpp
@@ -35,15 +35,19 @@
#include "HTMLNames.h"
#include "HTMLTextAreaElement.h"
#include "MouseEvent.h"
+#include "RenderLayer.h"
#include "RenderTextControlSingleLine.h"
namespace WebCore {
class RenderTextControlInnerBlock : public RenderBlock {
public:
- RenderTextControlInnerBlock(Node* node) : RenderBlock(node) { }
+ RenderTextControlInnerBlock(Node* node, bool isMultiLine) : RenderBlock(node), m_multiLine(isMultiLine) { }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
+ virtual VisiblePosition positionForPoint(const IntPoint&);
+ private:
+ bool m_multiLine;
};
bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
@@ -57,6 +61,22 @@ bool RenderTextControlInnerBlock::nodeAtPoint(const HitTestRequest& request, Hit
return RenderBlock::nodeAtPoint(request, result, x, y, tx, ty, placeholderIsVisible ? HitTestBlockBackground : hitTestAction);
}
+VisiblePosition RenderTextControlInnerBlock::positionForPoint(const IntPoint& point)
+{
+ int contentsX = point.x();
+ int contentsY = point.y();
+
+ // Multiline text controls have the scroll on shadowAncestorNode, so we need to take that
+ // into account here.
+ if (m_multiLine) {
+ RenderTextControl* renderer = static_cast<RenderTextControl*>(node()->shadowAncestorNode()->renderer());
+ if (renderer->hasOverflowClip())
+ renderer->layer()->addScrolledContentOffset(contentsX, contentsY);
+ }
+
+ return RenderBlock::positionForPoint(IntPoint(contentsX, contentsY));
+}
+
TextControlInnerElement::TextControlInnerElement(Document* doc, Node* shadowParent)
: HTMLDivElement(HTMLNames::divTag, doc)
, m_shadowParent(shadowParent)
@@ -98,14 +118,15 @@ void TextControlInnerTextElement::defaultEventHandler(Event* evt)
// FIXME: In the future, we should add a way to have default event listeners. Then we would add one to the text field's inner div, and we wouldn't need this subclass.
Node* shadowAncestor = shadowAncestorNode();
if (shadowAncestor && shadowAncestor->renderer()) {
- ASSERT(shadowAncestor->renderer()->isTextField() || shadowAncestor->renderer()->isTextArea());
- if (evt->isBeforeTextInsertedEvent())
+ ASSERT(shadowAncestor->renderer()->isTextControl());
+ if (evt->isBeforeTextInsertedEvent()) {
if (shadowAncestor->renderer()->isTextField())
static_cast<HTMLInputElement*>(shadowAncestor)->defaultEventHandler(evt);
else
static_cast<HTMLTextAreaElement*>(shadowAncestor)->defaultEventHandler(evt);
+ }
if (evt->type() == eventNames().webkitEditableContentChangedEvent)
- static_cast<RenderTextControl*>(shadowAncestor->renderer())->subtreeHasChanged();
+ toRenderTextControl(shadowAncestor->renderer())->subtreeHasChanged();
}
if (!evt->defaultHandled())
HTMLDivElement::defaultEventHandler(evt);
@@ -113,7 +134,13 @@ void TextControlInnerTextElement::defaultEventHandler(Event* evt)
RenderObject* TextControlInnerTextElement::createRenderer(RenderArena* arena, RenderStyle*)
{
- return new (arena) RenderTextControlInnerBlock(this);
+ bool multiLine = false;
+ Node* shadowAncestor = shadowAncestorNode();
+ if (shadowAncestor && shadowAncestor->renderer()) {
+ ASSERT(shadowAncestor->renderer()->isTextField() || shadowAncestor->renderer()->isTextArea());
+ multiLine = shadowAncestor->renderer()->isTextArea();
+ }
+ return new (arena) RenderTextControlInnerBlock(this, multiLine);
}
SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document* doc)
diff --git a/WebCore/rendering/TransformState.cpp b/WebCore/rendering/TransformState.cpp
new file mode 100644
index 0000000..5021d1f
--- /dev/null
+++ b/WebCore/rendering/TransformState.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TransformState.h"
+
+namespace WebCore {
+
+void TransformState::move(int x, int y, bool accumulateTransform)
+{
+ if (m_accumulatingTransform && m_accumulatedTransform) {
+ // If we're accumulating into an existing transform, apply the translation.
+ if (m_direction == ApplyTransformDirection)
+ m_accumulatedTransform->translateRight(x, y);
+ else
+ m_accumulatedTransform->translate(-x, -y); // We're unapplying, so negate
+
+ // Then flatten if necessary.
+ if (!accumulateTransform)
+ flatten();
+ } else {
+ // Just move the point and, optionally, the quad.
+ m_lastPlanarPoint.move(x, y);
+ if (m_mapQuad)
+ m_lastPlanarQuad.move(x, y);
+ }
+ m_accumulatingTransform = accumulateTransform;
+}
+
+void TransformState::applyTransform(const TransformationMatrix& transformFromContainer, bool accumulateTransform)
+{
+ // If we have an accumulated transform from last time, multiply in this transform
+ if (m_accumulatedTransform) {
+ if (m_direction == ApplyTransformDirection)
+ m_accumulatedTransform->multiply(transformFromContainer);
+ else
+ m_accumulatedTransform->multLeft(transformFromContainer);
+ } else if (accumulateTransform) {
+ // Make one if we started to accumulate
+ m_accumulatedTransform.set(new TransformationMatrix(transformFromContainer));
+ }
+
+ if (!accumulateTransform) {
+ const TransformationMatrix* finalTransform = m_accumulatedTransform ? m_accumulatedTransform.get() : &transformFromContainer;
+ flattenWithTransform(*finalTransform);
+ }
+ m_accumulatingTransform = accumulateTransform;
+}
+
+void TransformState::flatten()
+{
+ if (!m_accumulatedTransform) {
+ m_accumulatingTransform = false;
+ return;
+ }
+
+ flattenWithTransform(*m_accumulatedTransform);
+}
+
+FloatPoint TransformState::mappedPoint() const
+{
+ if (!m_accumulatedTransform)
+ return m_lastPlanarPoint;
+
+ if (m_direction == ApplyTransformDirection)
+ return m_accumulatedTransform->mapPoint(m_lastPlanarPoint);
+
+ return m_accumulatedTransform->inverse().projectPoint(m_lastPlanarPoint);
+}
+
+FloatQuad TransformState::mappedQuad() const
+{
+ if (!m_accumulatedTransform)
+ return m_lastPlanarQuad;
+
+ if (m_direction == ApplyTransformDirection)
+ return m_accumulatedTransform->mapQuad(m_lastPlanarQuad);
+
+ return m_accumulatedTransform->inverse().projectQuad(m_lastPlanarQuad);
+}
+
+void TransformState::flattenWithTransform(const TransformationMatrix& t)
+{
+ if (m_direction == ApplyTransformDirection) {
+ m_lastPlanarPoint = t.mapPoint(m_lastPlanarPoint);
+ if (m_mapQuad)
+ m_lastPlanarQuad = t.mapQuad(m_lastPlanarQuad);
+ } else {
+ TransformationMatrix inverseTransform = t.inverse();
+ m_lastPlanarPoint = inverseTransform.projectPoint(m_lastPlanarPoint);
+ if (m_mapQuad)
+ m_lastPlanarQuad = inverseTransform.projectQuad(m_lastPlanarQuad);
+ }
+
+ // We could throw away m_accumulatedTransform if we wanted to here, but that
+ // would cause thrash when traversing hierarachies with alternating
+ // preserve-3d and flat elements.
+ if (m_accumulatedTransform)
+ m_accumulatedTransform->makeIdentity();
+ m_accumulatingTransform = false;
+}
+
+// HitTestingTransformState methods
+void HitTestingTransformState::move(int x, int y)
+{
+ if (m_accumulatingTransform)
+ flatten();
+
+ m_lastPlanarPoint.move(x, y);
+ m_lastPlanarQuad.move(x, y);
+}
+
+void HitTestingTransformState::applyTransform(const TransformationMatrix& transformFromContainer, bool accumulateTransform)
+{
+ m_accumulatedTransform.multLeft(transformFromContainer);
+ if (!accumulateTransform)
+ flatten();
+
+ m_accumulatingTransform = accumulateTransform;
+}
+
+void HitTestingTransformState::flatten()
+{
+ m_lastPlanarPoint = mappedPoint();
+ m_lastPlanarQuad = mappedQuad();
+ m_accumulatedTransform.makeIdentity();
+ m_accumulatingTransform = false;
+}
+
+FloatPoint HitTestingTransformState::mappedPoint() const
+{
+ return m_accumulatedTransform.inverse().projectPoint(m_lastPlanarPoint);
+}
+
+FloatQuad HitTestingTransformState::mappedQuad() const
+{
+ return m_accumulatedTransform.inverse().projectQuad(m_lastPlanarQuad);
+}
+
+} // namespace WebCore
diff --git a/WebCore/rendering/TransformState.h b/WebCore/rendering/TransformState.h
new file mode 100644
index 0000000..5190118
--- /dev/null
+++ b/WebCore/rendering/TransformState.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TransformState_h
+#define TransformState_h
+
+#include "FloatPoint.h"
+#include "FloatQuad.h"
+#include "IntSize.h"
+#include "TransformationMatrix.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class TransformState : Noncopyable {
+public:
+ enum TransformDirection { ApplyTransformDirection, UnapplyInverseTransformDirection };
+ // If quad is non-null, it will be mapped
+ TransformState(TransformDirection mappingDirection, const FloatPoint& p, const FloatQuad* quad = 0)
+ : m_lastPlanarPoint(p)
+ , m_accumulatingTransform(false)
+ , m_mapQuad(quad != 0)
+ , m_direction(mappingDirection)
+ {
+ if (quad)
+ m_lastPlanarQuad = *quad;
+ }
+
+ void move(const IntSize& s, bool accumulateTransform = false)
+ {
+ move(s.width(), s.height(), accumulateTransform);
+ }
+
+ void move(int x, int y, bool accumulateTransform = false);
+ void applyTransform(const TransformationMatrix& transformFromContainer, bool accumulateTransform = false);
+ void flatten();
+
+ // Return the coords of the point or quad in the last flattened layer
+ FloatPoint lastPlanarPoint() const { return m_lastPlanarPoint; }
+ FloatQuad lastPlanarQuad() const { return m_lastPlanarQuad; }
+
+ // Return the point or quad mapped through the current transform
+ FloatPoint mappedPoint() const;
+ FloatQuad mappedQuad() const;
+
+private:
+ void flattenWithTransform(const TransformationMatrix&);
+
+ FloatPoint m_lastPlanarPoint;
+ FloatQuad m_lastPlanarQuad;
+
+ // We only allocate the transform if we need to
+ OwnPtr<TransformationMatrix> m_accumulatedTransform;
+ bool m_accumulatingTransform;
+ bool m_mapQuad;
+ TransformDirection m_direction;
+};
+
+class HitTestingTransformState : public RefCounted<HitTestingTransformState> {
+public:
+ static PassRefPtr<HitTestingTransformState> create(const FloatPoint& p, const FloatQuad& quad)
+ {
+ return adoptRef(new HitTestingTransformState(p, quad));
+ }
+
+ static PassRefPtr<HitTestingTransformState> create(const HitTestingTransformState& other)
+ {
+ return adoptRef(new HitTestingTransformState(other));
+ }
+
+ void move(const IntSize& s)
+ {
+ move(s.width(), s.height());
+ }
+
+ void move(int x, int y);
+ void applyTransform(const TransformationMatrix& transformFromContainer, bool accumulateTransform);
+ FloatPoint mappedPoint() const;
+ FloatQuad mappedQuad() const;
+ void flatten();
+
+ FloatPoint m_lastPlanarPoint;
+ FloatQuad m_lastPlanarQuad;
+ TransformationMatrix m_accumulatedTransform;
+ bool m_accumulatingTransform;
+
+private:
+ HitTestingTransformState(const FloatPoint& p, const FloatQuad& quad)
+ : m_lastPlanarPoint(p)
+ , m_lastPlanarQuad(quad)
+ , m_accumulatingTransform(false)
+ {
+ }
+
+ HitTestingTransformState(const HitTestingTransformState& other)
+ : RefCounted<HitTestingTransformState>()
+ , m_lastPlanarPoint(other.m_lastPlanarPoint)
+ , m_lastPlanarQuad(other.m_lastPlanarQuad)
+ , m_accumulatedTransform(other.m_accumulatedTransform)
+ , m_accumulatingTransform(other.m_accumulatingTransform)
+ {
+ }
+};
+
+} // namespace WebCore
+
+#endif // TransformState_h
diff --git a/WebCore/rendering/bidi.cpp b/WebCore/rendering/bidi.cpp
index 3b0e7c4..bfb5291 100644
--- a/WebCore/rendering/bidi.cpp
+++ b/WebCore/rendering/bidi.cpp
@@ -29,6 +29,7 @@
#include "InlineTextBox.h"
#include "Logging.h"
#include "RenderArena.h"
+#include "RenderInline.h"
#include "RenderLayer.h"
#include "RenderListMarker.h"
#include "RenderView.h"
@@ -95,7 +96,7 @@ static bool betweenMidpoints;
static bool isLineEmpty = true;
static bool previousLineBrokeCleanly = true;
-static int getBorderPaddingMargin(RenderBox* child, bool endOfInline)
+static int getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
{
bool leftSide = (child->style()->direction() == LTR) ? !endOfInline : endOfInline;
if (leftSide)
@@ -108,11 +109,11 @@ static int inlineWidth(RenderObject* child, bool start = true, bool end = true)
unsigned lineDepth = 1;
int extraWidth = 0;
RenderObject* parent = child->parent();
- while (parent->isBox() && parent->isInline() && !parent->isInlineBlockOrInlineTable() && lineDepth++ < cMaxLineDepth) {
- if (start && parent->firstChild() == child)
- extraWidth += getBorderPaddingMargin(toRenderBox(parent), false);
- if (end && parent->lastChild() == child)
- extraWidth += getBorderPaddingMargin(toRenderBox(parent), true);
+ while (parent->isInline() && !parent->isInlineBlockOrInlineTable() && lineDepth++ < cMaxLineDepth) {
+ if (start && !child->previousSibling())
+ extraWidth += getBorderPaddingMargin(toRenderBoxModelObject(parent), false);
+ if (end && !child->nextSibling())
+ extraWidth += getBorderPaddingMargin(toRenderBoxModelObject(parent), true);
child = parent;
parent = child->parent();
}
@@ -179,7 +180,7 @@ static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current,
while (current) {
next = 0;
- if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned()) {
+ if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) {
next = current->firstChild();
if (next && resolver && next->isRenderInline()) {
EUnicodeBidi ub = next->style()->unicodeBidi();
@@ -393,7 +394,7 @@ static void addMidpoint(const InlineIterator& midpoint)
static void appendRunsForObject(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
{
if (start > end || obj->isFloating() ||
- (obj->isPositioned() && !obj->hasStaticX() && !obj->hasStaticY() && !obj->container()->isRenderInline()))
+ (obj->isPositioned() && !obj->style()->hasStaticX() && !obj->style()->hasStaticY() && !obj->container()->isRenderInline()))
return;
bool haveNextMidpoint = (sCurrMidpoint < sNumMidpoints);
@@ -462,7 +463,37 @@ void InlineBidiResolver::appendRun()
m_status.eor = OtherNeutral;
}
-InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
+static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
+{
+ if (isRootLineBox)
+ return toRenderBlock(obj)->createRootInlineBox();
+
+ if (obj->isText()) {
+ InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
+ // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode
+ // (Note the use of strict mode. In "almost strict" mode, we don't treat the box for <br> as text.)
+ if (obj->isBR())
+ textBox->setIsText(isOnlyRun || obj->document()->inStrictMode());
+ return textBox;
+ }
+
+ if (obj->isBox())
+ return toRenderBox(obj)->createInlineBox();
+
+ return toRenderInline(obj)->createInlineFlowBox();
+}
+
+static inline void dirtyLineBoxesForRenderer(RenderObject* o, bool fullLayout)
+{
+ if (o->isText()) {
+ if (o->prefWidthsDirty() && o->isCounter())
+ toRenderText(o)->calcPrefWidths(0); // FIXME: Counters depend on this hack. No clue why. Should be investigated and removed.
+ toRenderText(o)->dirtyLineBoxes(fullLayout);
+ } else
+ toRenderInline(o)->dirtyLineBoxes(fullLayout);
+}
+
+InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj, bool firstLine)
{
// See if we have an unconstructed line box for this object that is also
// the last item on the line.
@@ -472,10 +503,9 @@ InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
InlineFlowBox* result = 0;
do {
ASSERT(obj->isRenderInline() || obj == this);
- RenderFlow* flow = static_cast<RenderFlow*>(obj);
-
+
// Get the last box we made for this render object.
- parentBox = flow->lastLineBox();
+ parentBox = obj->isRenderInline() ? toRenderInline(obj)->lastLineBox() : toRenderBlock(obj)->lastLineBox();
// If this box is constructed then it is from a previous line, and we need
// to make a new box for our line. If this box is unconstructed but it has
@@ -486,10 +516,10 @@ InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
if (!parentBox || parentBox->isConstructed() || parentBox->nextOnLine()) {
// We need to make a new box for this render object. Once
// made, we need to place it at the end of the current line.
- InlineBox* newBox = obj->createInlineBox(false, obj == this);
+ InlineBox* newBox = createInlineBoxForRenderer(obj, obj == this);
ASSERT(newBox->isInlineFlowBox());
parentBox = static_cast<InlineFlowBox*>(newBox);
- parentBox->setFirstLineStyleBit(m_firstLine);
+ parentBox->setFirstLineStyleBit(firstLine);
constructedNewBox = true;
}
@@ -516,7 +546,7 @@ InlineFlowBox* RenderBlock::createLineBoxes(RenderObject* obj)
return result;
}
-RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool lastLine, RenderObject* endObject)
+RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject)
{
ASSERT(firstRun);
@@ -527,16 +557,16 @@ RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun,
if (runCount == 2 && !r->m_object->isListMarker())
isOnlyRun = ((style()->direction() == RTL) ? lastRun : firstRun)->m_object->isListMarker();
- InlineBox* box = r->m_object->createInlineBox(r->m_object->isPositioned(), false, isOnlyRun);
+ InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun);
r->m_box = box;
if (box) {
// If we have no parent box yet, or if the run is not simply a sibling,
// then we need to construct inline boxes as necessary to properly enclose the
// run's inline box.
- if (!parentBox || parentBox->object() != r->m_object->parent())
+ if (!parentBox || parentBox->renderer() != r->m_object->parent())
// Create new inline boxes all the way back to the appropriate insertion point.
- parentBox = createLineBoxes(r->m_object->parent());
+ parentBox = createLineBoxes(r->m_object->parent(), firstLine);
// Append the inline box to this line.
parentBox->addToLine(box);
@@ -570,10 +600,10 @@ RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun,
return lastRootBox();
}
-void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd)
+void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd)
{
// First determine our total width.
- int availableWidth = lineWidth(height());
+ int availableWidth = lineWidth(height(), firstLine);
int totWidth = lineBox->getFlowSpacingWidth();
bool needsWordSpacing = false;
unsigned numSpaces = 0;
@@ -598,10 +628,10 @@ void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, Bidi
if (int length = rt->textLength()) {
if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characters()[r->m_start]))
- totWidth += rt->style(m_firstLine)->font().wordSpacing();
+ totWidth += rt->style(firstLine)->font().wordSpacing();
needsWordSpacing = !isSpaceOrNewline(rt->characters()[r->m_stop - 1]) && r->m_stop == length;
}
- r->m_box->setWidth(rt->width(r->m_start, r->m_stop - r->m_start, totWidth, m_firstLine));
+ r->m_box->setWidth(rt->width(r->m_start, r->m_stop - r->m_start, totWidth, firstLine));
} else if (!r->m_object->isRenderInline()) {
RenderBox* renderBox = toRenderBox(r->m_object);
renderBox->calcWidth();
@@ -616,7 +646,7 @@ void RenderBlock::computeHorizontalPositionsForLine(RootInlineBox* lineBox, Bidi
// we now examine our text-align property in order to determine where to position the
// objects horizontally. The total width of the line can be increased if we end up
// justifying text.
- int x = leftOffset(height());
+ int x = leftOffset(height(), firstLine);
switch(textAlign) {
case LEFT:
case WEBKIT_LEFT:
@@ -741,11 +771,14 @@ void RenderBlock::computeVerticalPositionsForLine(RootInlineBox* lineBox, BidiRu
// Align positioned boxes with the top of the line box. This is
// a reasonable approximation of an appropriate y position.
if (r->m_object->isPositioned())
- r->m_box->setYPos(height());
+ r->m_box->setY(height());
// Position is used to properly position both replaced elements and
// to update the static normal flow x/y of positioned elements.
- r->m_object->position(r->m_box);
+ if (r->m_object->isText())
+ toRenderText(r->m_object)->positionLineBox(r->m_box);
+ else if (r->m_object->isBox())
+ toRenderBox(r->m_object)->positionLineBox(r->m_box);
}
// Positioned objects and zero-length text nodes destroy their boxes in
// position(), which unnecessarily dirties the line.
@@ -772,8 +805,6 @@ static inline bool isCollapsibleSpace(UChar character, RenderText* renderer)
void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, int& repaintBottom)
{
bool useRepaintBounds = false;
-
- invalidateVerticalPosition();
m_overflowHeight = 0;
@@ -785,7 +816,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// FIXME: Do something better when floats are present.
bool fullLayout = !firstLineBox() || !firstChild() || selfNeedsLayout() || relayoutChildren;
if (fullLayout)
- deleteLineBoxes();
+ lineBoxes()->deleteLineBoxes(renderArena());
// Text truncation only kicks in if your overflow isn't visible and your text-overflow-mode isn't
// clip.
@@ -824,9 +855,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
bool endOfInline = false;
RenderObject* o = bidiFirst(this, 0, false);
Vector<FloatWithRect> floats;
- int containerWidth = max(0, containingBlockWidth());
while (o) {
- o->invalidateVerticalPosition();
if (o->isReplaced() || o->isFloating() || o->isPositioned()) {
RenderBox* box = toRenderBox(o);
@@ -842,27 +871,23 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
else {
#ifdef ANDROID_LAYOUT
// ignore text wrap for textField or menuList
- if (doTextWrap && (o->isTextField() || o->isMenuList()))
- doTextWrap = false;
+ if (doTextWrap && (o->isTextField() || o->isMenuList()))
+ doTextWrap = false;
#endif
if (o->isFloating())
floats.append(FloatWithRect(box));
else if (fullLayout || o->needsLayout()) // Replaced elements
- o->dirtyLineBoxes(fullLayout);
+ toRenderBox(o)->dirtyLineBoxes(fullLayout);
o->layoutIfNeeded();
}
} else if (o->isText() || (o->isRenderInline() && !endOfInline)) {
if (fullLayout || o->selfNeedsLayout())
- o->dirtyLineBoxes(fullLayout);
-
- // Calculate margins of inline flows so that they can be used later by line layout.
- if (o->isRenderInline())
- static_cast<RenderFlow*>(o)->calcMargins(containerWidth);
+ dirtyLineBoxesForRenderer(o, fullLayout);
o->setNeedsLayout(false);
#ifdef ANDROID_LAYOUT
if (doTextWrap && !hasTextToWrap && o->isText()) {
- Node* node = o->element();
+ Node* node = o->node();
// as it is very common for sites to use a serial of <a> or
// <li> as tabs, we don't force text to wrap if all the text
// are short and within an <a> or <li> tag, and only separated
@@ -880,6 +905,8 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
}
}
#endif
+ if (!o->isText())
+ toRenderInline(o)->invalidateVerticalPosition(); // FIXME: Should do better here and not always invalidate everything.
}
o = bidiNext(this, o, 0, false, &endOfInline);
}
@@ -921,18 +948,19 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// We want to skip ahead to the first dirty line
InlineBidiResolver resolver;
unsigned floatIndex;
- RootInlineBox* startLine = determineStartPosition(fullLayout, resolver, floats, floatIndex);
+ bool firstLine = true;
+ RootInlineBox* startLine = determineStartPosition(firstLine, fullLayout, resolver, floats, floatIndex);
if (fullLayout && !selfNeedsLayout()) {
setNeedsLayout(true, false); // Mark ourselves as needing a full layout. This way we'll repaint like
// we're supposed to.
RenderView* v = view();
- if (v && !v->doingFullRepaint() && m_layer) {
+ if (v && !v->doingFullRepaint() && hasLayer()) {
// Because we waited until we were already inside layout to discover
// that the block really needed a full layout, we missed our chance to repaint the layer
// before layout started. Luckily the layer has cached the repaint rect for its original
// position and size, and so we can use that to make a repaint happen now.
- v->repaintViewRectangle(m_layer->repaintRect());
+ repaintUsingContainer(containerForRepaint(), layer()->repaintRect());
}
}
@@ -974,9 +1002,9 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
// adjust the height accordingly.
// A line break can be either the first or the last object on a line, depending on its direction.
if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
- RenderObject* lastObject = lastLeafChild->object();
+ RenderObject* lastObject = lastLeafChild->renderer();
if (!lastObject->isBR())
- lastObject = lastRootBox()->firstLeafChild()->object();
+ lastObject = lastRootBox()->firstLeafChild()->renderer();
if (lastObject->isBR()) {
EClear clear = lastObject->style()->clear();
if (clear != CNONE)
@@ -999,7 +1027,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
isLineEmpty = true;
EClear clear = CNONE;
- end = findNextLineBreak(resolver, &clear);
+ end = findNextLineBreak(resolver, firstLine, &clear);
if (resolver.position().atEnd()) {
resolver.deleteRuns();
checkForFloatsFromLastLine = true;
@@ -1031,26 +1059,18 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
TextDirection direction = style()->direction();
bool shouldReorder = trailingSpaceRun != (direction == LTR ? resolver.lastRun() : resolver.firstRun());
if (firstSpace != trailingSpaceRun->start()) {
- ETextAlign textAlign = style()->textAlign();
- // If the trailing white space is at the right hand side of a left-aligned line, then computeHorizontalPositionsForLine()
- // does not care if trailingSpaceRun includes non-spaces at the beginning. In all other cases, trailingSpaceRun has to
- // contain only the spaces, either because we re-order them or because computeHorizontalPositionsForLine() needs to know
- // their width.
- bool shouldSeparateSpaces = textAlign != LEFT && textAlign != WEBKIT_LEFT && textAlign != TAAUTO || trailingSpaceRun->m_level % 2 || direction == RTL || shouldReorder;
- if (shouldSeparateSpaces) {
- BidiContext* baseContext = resolver.context();
- while (BidiContext* parent = baseContext->parent())
- baseContext = parent;
-
- BidiRun* newTrailingRun = new (renderArena()) BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);
- trailingSpaceRun->m_stop = firstSpace;
- if (direction == LTR)
- resolver.addRun(newTrailingRun);
- else
- resolver.prependRun(newTrailingRun);
- trailingSpaceRun = newTrailingRun;
- shouldReorder = false;
- }
+ BidiContext* baseContext = resolver.context();
+ while (BidiContext* parent = baseContext->parent())
+ baseContext = parent;
+
+ BidiRun* newTrailingRun = new (renderArena()) BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);
+ trailingSpaceRun->m_stop = firstSpace;
+ if (direction == LTR)
+ resolver.addRun(newTrailingRun);
+ else
+ resolver.prependRun(newTrailingRun);
+ trailingSpaceRun = newTrailingRun;
+ shouldReorder = false;
}
if (shouldReorder) {
if (direction == LTR) {
@@ -1072,12 +1092,12 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
RootInlineBox* lineBox = 0;
if (resolver.runCount()) {
- lineBox = constructLine(resolver.runCount(), resolver.firstRun(), resolver.lastRun(), !end.obj, end.obj && !end.pos ? end.obj : 0);
+ lineBox = constructLine(resolver.runCount(), resolver.firstRun(), resolver.lastRun(), firstLine, !end.obj, end.obj && !end.pos ? end.obj : 0);
if (lineBox) {
lineBox->setEndsWithBreak(previousLineBrokeCleanly);
// Now we position all of our text runs horizontally.
- computeHorizontalPositionsForLine(lineBox, resolver.firstRun(), trailingSpaceRun, end.atEnd());
+ computeHorizontalPositionsForLine(lineBox, firstLine, resolver.firstRun(), trailingSpaceRun, end.atEnd());
// Now position our text runs vertically.
computeVerticalPositionsForLine(lineBox, resolver.firstRun());
@@ -1105,7 +1125,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
}
}
- m_firstLine = false;
+ firstLine = false;
newLine(clear);
}
@@ -1208,7 +1228,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, int& repaintTop, i
checkLinesForTextOverflow();
}
-RootInlineBox* RenderBlock::determineStartPosition(bool& fullLayout, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats)
+RootInlineBox* RenderBlock::determineStartPosition(bool& firstLine, bool& fullLayout, InlineBidiResolver& resolver, Vector<FloatWithRect>& floats, unsigned& numCleanFloats)
{
RootInlineBox* curr = 0;
RootInlineBox* last = 0;
@@ -1264,7 +1284,7 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& fullLayout, InlineBidiR
// We have a dirty line.
if (RootInlineBox* prevRootBox = curr->prevRootBox()) {
// We have a previous line.
- if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength()))
+ if (!dirtiedByFloat && (!prevRootBox->endsWithBreak() || (prevRootBox->lineBreakObj()->isText() && prevRootBox->lineBreakPos() >= toRenderText(prevRootBox->lineBreakObj())->textLength())))
// The previous line didn't break cleanly or broke at a newline
// that has been deleted, so treat it as dirty too.
curr = prevRootBox;
@@ -1301,7 +1321,7 @@ RootInlineBox* RenderBlock::determineStartPosition(bool& fullLayout, InlineBidiR
setHeight(savedHeight);
}
- m_firstLine = !last;
+ firstLine = !last;
previousLineBrokeCleanly = !last || last->endsWithBreak();
RenderObject* startObj;
@@ -1470,12 +1490,12 @@ static inline bool shouldPreserveNewline(RenderObject* object)
return object->style()->preserveNewline();
}
-static bool inlineFlowRequiresLineBox(RenderBox* flow)
+static bool inlineFlowRequiresLineBox(RenderInline* flow)
{
// FIXME: Right now, we only allow line boxes for inlines that are truly empty.
// We need to fix this, though, because at the very least, inlines containing only
// ignorable whitespace should should also have line boxes.
- return flow->isRenderInline() && !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();
+ return !flow->firstChild() && flow->hasHorizontalBordersPaddingOrMargin();
}
static inline bool requiresLineBox(const InlineIterator& it)
@@ -1483,7 +1503,7 @@ static inline bool requiresLineBox(const InlineIterator& it)
if (it.obj->isFloatingOrPositioned())
return false;
- if (it.obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderBox(it.obj)))
+ if (it.obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(it.obj)))
return false;
if (!shouldCollapseWhiteSpace(it.obj->style()) || it.obj->isBR())
@@ -1524,33 +1544,34 @@ void RenderBlock::skipTrailingWhitespace(InlineIterator& iterator)
// A relative positioned inline encloses us. In this case, we also have to determine our
// position as though we were an inline. Set |staticX| and |staticY| on the relative positioned
// inline so that we can obtain the value later.
- c->setStaticX(style()->direction() == LTR ? leftOffset(height()) : rightOffset(height()));
- c->setStaticY(height());
+ toRenderInline(c)->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), false) : rightOffset(height(), false));
+ toRenderInline(c)->layer()->setStaticY(height());
}
- if (object->hasStaticX()) {
- if (object->style()->isOriginalDisplayInlineType())
- object->setStaticX(style()->direction() == LTR ? leftOffset(height()) : width() - rightOffset(height()));
+ RenderBox* box = toRenderBox(object);
+ if (box->style()->hasStaticX()) {
+ if (box->style()->isOriginalDisplayInlineType())
+ box->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), false) : width() - rightOffset(height(), false));
else
- object->setStaticX(style()->direction() == LTR ? borderLeft() + paddingLeft() : borderRight() + paddingRight());
+ box->layer()->setStaticX(style()->direction() == LTR ? borderLeft() + paddingLeft() : borderRight() + paddingRight());
}
- if (object->hasStaticY())
- object->setStaticY(height());
+ if (box->style()->hasStaticY())
+ box->layer()->setStaticY(height());
}
iterator.increment();
}
}
-int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver)
+int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver, bool firstLine)
{
- int availableWidth = lineWidth(height());
+ int availableWidth = lineWidth(height(), firstLine);
while (!resolver.position().atEnd() && !requiresLineBox(resolver.position())) {
RenderObject* object = resolver.position().obj;
if (object->isFloating()) {
insertFloatingObject(toRenderBox(object));
positionNewFloats();
- availableWidth = lineWidth(height());
+ availableWidth = lineWidth(height(), firstLine);
} else if (object->isPositioned()) {
// FIXME: The math here is actually not really right. It's a best-guess approximation that
// will work for the common cases
@@ -1559,19 +1580,20 @@ int RenderBlock::skipLeadingWhitespace(InlineBidiResolver& resolver)
// A relative positioned inline encloses us. In this case, we also have to determine our
// position as though we were an inline. Set |staticX| and |staticY| on the relative positioned
// inline so that we can obtain the value later.
- c->setStaticX(style()->direction() == LTR ? leftOffset(height()) : rightOffset(height()));
- c->setStaticY(height());
+ toRenderInline(c)->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), firstLine) : rightOffset(height(), firstLine));
+ toRenderInline(c)->layer()->setStaticY(height());
}
- if (object->hasStaticX()) {
- if (object->style()->isOriginalDisplayInlineType())
- object->setStaticX(style()->direction() == LTR ? leftOffset(height()) : width() - rightOffset(height()));
+ RenderBox* box = toRenderBox(object);
+ if (box->style()->hasStaticX()) {
+ if (box->style()->isOriginalDisplayInlineType())
+ box->layer()->setStaticX(style()->direction() == LTR ? leftOffset(height(), firstLine) : width() - rightOffset(height(), firstLine));
else
- object->setStaticX(style()->direction() == LTR ? borderLeft() + paddingLeft() : borderRight() + paddingRight());
+ box->layer()->setStaticX(style()->direction() == LTR ? borderLeft() + paddingLeft() : borderRight() + paddingRight());
}
- if (object->hasStaticY())
- object->setStaticY(height());
+ if (box->style()->hasStaticY())
+ box->layer()->setStaticY(height());
}
resolver.increment();
}
@@ -1596,7 +1618,7 @@ static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObjec
return false;
}
-void RenderBlock::fitBelowFloats(int widthToFit, int& availableWidth)
+void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth)
{
ASSERT(widthToFit > availableWidth);
@@ -1608,7 +1630,7 @@ void RenderBlock::fitBelowFloats(int widthToFit, int& availableWidth)
if (!floatBottom)
break;
- newLineWidth = lineWidth(floatBottom);
+ newLineWidth = lineWidth(floatBottom, firstLine);
lastFloatBottom = floatBottom;
if (newLineWidth >= widthToFit)
break;
@@ -1620,13 +1642,20 @@ void RenderBlock::fitBelowFloats(int widthToFit, int& availableWidth)
}
}
-InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, EClear* clear)
+static inline unsigned textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, int xPos, bool isFixedPitch, bool collapseWhiteSpace)
+{
+ if (isFixedPitch || (!from && len == text->textLength()))
+ return text->width(from, len, font, xPos);
+ return font.width(TextRun(text->characters() + from, len, !collapseWhiteSpace, xPos));
+}
+
+InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool firstLine, EClear* clear)
{
ASSERT(resolver.position().block == this);
bool appliedStartWidth = resolver.position().pos > 0;
- int width = skipLeadingWhitespace(resolver);
+ int width = skipLeadingWhitespace(resolver, firstLine);
int w = 0;
int tmpW = 0;
@@ -1715,16 +1744,17 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
// it after moving to next line (in newLine() func)
if (floatsFitOnLine && floatBox->width() + floatBox->marginLeft() + floatBox->marginRight() + w + tmpW <= width) {
positionNewFloats();
- width = lineWidth(height());
+ width = lineWidth(height(), firstLine);
} else
floatsFitOnLine = false;
} else if (o->isPositioned()) {
// If our original display wasn't an inline type, then we can
// go ahead and determine our static x position now.
- bool isInlineType = o->style()->isOriginalDisplayInlineType();
- bool needToSetStaticX = o->hasStaticX();
- if (o->hasStaticX() && !isInlineType) {
- o->setStaticX(o->parent()->style()->direction() == LTR ?
+ RenderBox* box = toRenderBox(o);
+ bool isInlineType = box->style()->isOriginalDisplayInlineType();
+ bool needToSetStaticX = box->style()->hasStaticX();
+ if (box->style()->hasStaticX() && !isInlineType) {
+ box->layer()->setStaticX(o->parent()->style()->direction() == LTR ?
borderLeft() + paddingLeft() :
borderRight() + paddingRight());
needToSetStaticX = false;
@@ -1732,9 +1762,9 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
// If our original display was an INLINE type, then we can go ahead
// and determine our static y position now.
- bool needToSetStaticY = o->hasStaticY();
- if (o->hasStaticY() && isInlineType) {
- o->setStaticY(height());
+ bool needToSetStaticY = box->style()->hasStaticY();
+ if (box->style()->hasStaticY() && isInlineType) {
+ box->layer()->setStaticY(height());
needToSetStaticY = false;
}
@@ -1760,7 +1790,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
// Right now, we should only encounter empty inlines here.
ASSERT(!o->firstChild());
- RenderBox* flowBox = toRenderBox(o);
+ RenderInline* flowBox = toRenderInline(o);
// Now that some inline flows have line boxes, if we are already ignoring spaces, we need
// to make sure that we stop to include this object and then start ignoring spaces again.
@@ -1827,7 +1857,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
int len = strlen - pos;
const UChar* str = t->characters();
- const Font& f = t->style(m_firstLine)->font();
+ const Font& f = t->style(firstLine)->font();
+ bool isFixedPitch = f.isFixedPitch();
int lastSpace = pos;
int wordSpacing = o->style()->wordSpacing();
@@ -1876,12 +1907,12 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
addMidpoint(beforeSoftHyphen);
// Add the width up to but not including the hyphen.
- tmpW += t->width(lastSpace, pos - lastSpace, f, w + tmpW) + lastSpaceWordSpacing;
+ tmpW += textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
// For wrapping text only, include the hyphen. We need to ensure it will fit
// on the line if it shows when we break.
if (autoWrap)
- tmpW += t->width(pos, 1, f, w + tmpW);
+ tmpW += textWidth(t, pos, 1, f, w + tmpW, isFixedPitch, collapseWhiteSpace);
InlineIterator afterSoftHyphen(0, o, pos);
afterSoftHyphen.increment();
@@ -1901,7 +1932,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
if ((breakAll || breakWords) && !midWordBreak) {
wrapW += charWidth;
- charWidth = t->width(pos, 1, f, w + wrapW);
+ charWidth = textWidth(t, pos, 1, f, w + wrapW, isFixedPitch, collapseWhiteSpace);
midWordBreak = w + wrapW + charWidth > width;
}
@@ -1926,7 +1957,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
}
}
- int additionalTmpW = t->width(lastSpace, pos - lastSpace, f, w+tmpW) + lastSpaceWordSpacing;
+ int additionalTmpW = textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
tmpW += additionalTmpW;
if (!appliedStartWidth) {
tmpW += inlineWidth(o, true, false);
@@ -1936,14 +1967,14 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
applyWordSpacing = wordSpacing && currentCharacterIsSpace && !previousCharacterIsSpace;
if (!w && autoWrap && tmpW > width)
- fitBelowFloats(tmpW, width);
+ fitBelowFloats(tmpW, firstLine, width);
if (autoWrap || breakWords) {
// If we break only after white-space, consider the current character
// as candidate width for this line.
bool lineWasTooWide = false;
if (w + tmpW <= width && currentCharacterIsWS && o->style()->breakOnlyAfterWhiteSpace() && !midWordBreak) {
- int charWidth = t->width(pos, 1, f, w + tmpW) + (applyWordSpacing ? wordSpacing : 0);
+ int charWidth = textWidth(t, pos, 1, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + (applyWordSpacing ? wordSpacing : 0);
// Check if line is too big even without the extra space
// at the end of the line. If it is not, do nothing.
// If the line needs the extra whitespace to be too long,
@@ -1973,7 +2004,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
tmpW -= additionalTmpW;
if (pos > 0 && str[pos-1] == softHyphen)
// Subtract the width of the soft hyphen out since we fit on a line.
- tmpW -= t->width(pos-1, 1, f, w+tmpW);
+ tmpW -= textWidth(t, pos - 1, 1, f, w + tmpW, isFixedPitch, collapseWhiteSpace);
}
}
@@ -2064,7 +2095,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
// IMPORTANT: pos is > length here!
if (!ignoringSpaces)
- tmpW += t->width(lastSpace, pos - lastSpace, f, w+tmpW) + lastSpaceWordSpacing;
+ tmpW += textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
tmpW += inlineWidth(o, !appliedStartWidth, true);
} else
ASSERT_NOT_REACHED();
@@ -2091,7 +2122,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
checkForBreak = true;
bool willFitOnLine = w + tmpW <= width;
if (!willFitOnLine && !w) {
- fitBelowFloats(tmpW, width);
+ fitBelowFloats(tmpW, firstLine, width);
willFitOnLine = tmpW <= width;
}
bool canPlaceOnLine = willFitOnLine || !autoWrapWasEverTrueOnLine;
@@ -2114,7 +2145,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
if (w)
goto end;
- fitBelowFloats(tmpW, width);
+ fitBelowFloats(tmpW, firstLine, width);
// |width| may have been adjusted because we got shoved down past a float (thus
// giving us more room), so we need to retest, and only jump to
@@ -2154,8 +2185,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, ECle
}
end:
-
- if (lBreak == resolver.position() && !lBreak.obj->isBR()) {
+ if (lBreak == resolver.position() && (!lBreak.obj || !lBreak.obj->isBR())) {
// we just add as much as possible
if (style()->whiteSpace() == PRE) {
// FIXME: Don't really understand this case.
@@ -2265,8 +2295,8 @@ void RenderBlock::checkLinesForTextOverflow()
// Include the scrollbar for overflow blocks, which means we want to use "contentWidth()"
bool ltr = style()->direction() == LTR;
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
- int blockEdge = ltr ? rightOffset(curr->yPos()) : leftOffset(curr->yPos());
- int lineBoxEdge = ltr ? curr->xPos() + curr->width() : curr->xPos();
+ int blockEdge = ltr ? rightOffset(curr->y(), curr == firstRootBox()) : leftOffset(curr->y(), curr == firstRootBox());
+ int lineBoxEdge = ltr ? curr->x() + curr->width() : curr->x();
if ((ltr && lineBoxEdge > blockEdge) || (!ltr && lineBoxEdge < blockEdge)) {
// This line spills out of our box in the appropriate direction. Now we need to see if the line
// can be truncated. In order for truncation to be possible, the line must have sufficient space to
diff --git a/WebCore/rendering/style/ContentData.cpp b/WebCore/rendering/style/ContentData.cpp
index b38cc49..410cad4 100644
--- a/WebCore/rendering/style/ContentData.cpp
+++ b/WebCore/rendering/style/ContentData.cpp
@@ -30,22 +30,9 @@ namespace WebCore {
void ContentData::clear()
{
- switch (m_type) {
- case CONTENT_NONE:
- break;
- case CONTENT_OBJECT:
- m_content.m_image->deref();
- break;
- case CONTENT_TEXT:
- m_content.m_text->deref();
- break;
- case CONTENT_COUNTER:
- delete m_content.m_counter;
- break;
- }
+ deleteContent();
ContentData* n = m_next;
- m_type = CONTENT_NONE;
m_next = 0;
// Reverse the list so we can delete without recursing.
@@ -63,4 +50,47 @@ void ContentData::clear()
}
}
+bool ContentData::dataEquivalent(const ContentData& other) const
+{
+ if (type() != other.type())
+ return false;
+
+ switch (type()) {
+ case CONTENT_NONE:
+ return true;
+ break;
+ case CONTENT_TEXT:
+ return equal(text(), other.text());
+ break;
+ case CONTENT_OBJECT:
+ return StyleImage::imagesEquivalent(image(), other.image());
+ break;
+ case CONTENT_COUNTER:
+ return *counter() == *other.counter();
+ break;
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+void ContentData::deleteContent()
+{
+ switch (m_type) {
+ case CONTENT_NONE:
+ break;
+ case CONTENT_OBJECT:
+ m_content.m_image->deref();
+ break;
+ case CONTENT_TEXT:
+ m_content.m_text->deref();
+ break;
+ case CONTENT_COUNTER:
+ delete m_content.m_counter;
+ break;
+ }
+
+ m_type = CONTENT_NONE;
+}
+
} // namespace WebCore
diff --git a/WebCore/rendering/style/ContentData.h b/WebCore/rendering/style/ContentData.h
index d924d1a..24d5f86 100644
--- a/WebCore/rendering/style/ContentData.h
+++ b/WebCore/rendering/style/ContentData.h
@@ -25,16 +25,18 @@
#ifndef ContentData_h
#define ContentData_h
+#include "PlatformString.h"
#include "RenderStyleConstants.h"
+#include "StringImpl.h"
+#include "StyleImage.h"
#include <wtf/Noncopyable.h>
namespace WebCore {
class CounterContent;
-class StringImpl;
-class StyleImage;
struct ContentData : Noncopyable {
+public:
ContentData()
: m_type(CONTENT_NONE)
, m_next(0)
@@ -48,7 +50,49 @@ struct ContentData : Noncopyable {
void clear();
- ContentType m_type;
+ bool isCounter() const { return m_type == CONTENT_COUNTER; }
+ bool isImage() const { return m_type == CONTENT_OBJECT; }
+ bool isNone() const { return m_type == CONTENT_NONE; }
+ bool isText() const { return m_type == CONTENT_TEXT; }
+
+ StyleContentType type() const { return m_type; }
+
+ bool dataEquivalent(const ContentData&) const;
+
+ StyleImage* image() const { return m_content.m_image; }
+ void setImage(PassRefPtr<StyleImage> image)
+ {
+ deleteContent();
+ m_type = CONTENT_OBJECT;
+ m_content.m_image = image.releaseRef();
+ }
+
+ StringImpl* text() const { return m_content.m_text; }
+ void setText(PassRefPtr<StringImpl> text)
+ {
+ deleteContent();
+ m_type = CONTENT_TEXT;
+ m_content.m_text = text.releaseRef();
+ }
+
+ CounterContent* counter() const { return m_content.m_counter; }
+ void setCounter(CounterContent* counter)
+ {
+ deleteContent();
+ m_type = CONTENT_COUNTER;
+ m_content.m_counter = counter;
+ }
+
+ ContentData* next() const { return m_next; }
+ void setNext(ContentData* next)
+ {
+ m_next = next;
+ }
+
+private:
+ void deleteContent();
+
+ StyleContentType m_type;
union {
StyleImage* m_image;
StringImpl* m_text;
diff --git a/WebCore/rendering/style/CounterContent.h b/WebCore/rendering/style/CounterContent.h
index 06440ad..cf11813 100644
--- a/WebCore/rendering/style/CounterContent.h
+++ b/WebCore/rendering/style/CounterContent.h
@@ -49,11 +49,11 @@ private:
AtomicString m_separator;
};
-static inline bool operator!=(const CounterContent& a, const CounterContent& b)
+static inline bool operator==(const CounterContent& a, const CounterContent& b)
{
- return a.identifier() != b.identifier()
- || a.listStyle() != b.listStyle()
- || a.separator() != b.separator();
+ return a.identifier() == b.identifier()
+ && a.listStyle() == b.listStyle()
+ && a.separator() == b.separator();
}
diff --git a/WebCore/rendering/style/RenderStyle.cpp b/WebCore/rendering/style/RenderStyle.cpp
index 09445b9..fe53d30 100644
--- a/WebCore/rendering/style/RenderStyle.cpp
+++ b/WebCore/rendering/style/RenderStyle.cpp
@@ -185,7 +185,7 @@ bool RenderStyle::isStyleAvailable() const
return this != CSSStyleSelector::styleNotYetAvailable();
}
-static inline int pseudoBit(RenderStyle::PseudoId pseudo)
+static inline int pseudoBit(PseudoId pseudo)
{
return 1 << (pseudo - 1);
}
@@ -271,14 +271,16 @@ static bool positionedObjectMoved(const LengthBox& a, const LengthBox& b)
optimisations are unimplemented, and currently result in the
worst case result causing a relayout of the containing block.
*/
-RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
+StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
{
+ changedContextSensitiveProperties = ContextSensitivePropertyNone;
+
#if ENABLE(SVG)
// This is horribly inefficient. Eventually we'll have to integrate
// this more directly by calling: Diff svgDiff = svgStyle->diff(other)
// and then checking svgDiff and returning from the appropriate places below.
if (m_svgStyle != other->m_svgStyle)
- return Layout;
+ return StyleDifferenceLayout;
#endif
if (box->width != other->box->width ||
@@ -287,19 +289,19 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
box->height != other->box->height ||
box->min_height != other->box->min_height ||
box->max_height != other->box->max_height)
- return Layout;
+ return StyleDifferenceLayout;
if (box->vertical_align != other->box->vertical_align || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
- return Layout;
+ return StyleDifferenceLayout;
if (box->boxSizing != other->box->boxSizing)
- return Layout;
+ return StyleDifferenceLayout;
if (surround->margin != other->surround->margin)
- return Layout;
+ return StyleDifferenceLayout;
if (surround->padding != other->surround->padding)
- return Layout;
+ return StyleDifferenceLayout;
if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance ||
@@ -307,30 +309,47 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
rareNonInheritedData->marginBottomCollapse != other->rareNonInheritedData->marginBottomCollapse ||
rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp ||
rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow)
- return Layout;
+ return StyleDifferenceLayout;
if (rareNonInheritedData->flexibleBox.get() != other->rareNonInheritedData->flexibleBox.get() &&
*rareNonInheritedData->flexibleBox.get() != *other->rareNonInheritedData->flexibleBox.get())
- return Layout;
+ return StyleDifferenceLayout;
if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
- return Layout;
+ return StyleDifferenceLayout;
if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get()))
- return Layout;
+ return StyleDifferenceLayout;
if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get() &&
*rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get())
- return Layout;
+ return StyleDifferenceLayout;
if (rareNonInheritedData->m_transform.get() != other->rareNonInheritedData->m_transform.get() &&
- *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get())
- return Layout;
+ *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get()) {
+#if USE(ACCELERATED_COMPOSITING)
+ changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
+ // Don't return; keep looking for another change
+#else
+ return StyleDifferenceLayout;
+#endif
+ }
+
+#if !USE(ACCELERATED_COMPOSITING)
+ if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
+ if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D ||
+ rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility ||
+ rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective ||
+ rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX ||
+ rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY)
+ return StyleDifferenceLayout;
+ }
+#endif
#if ENABLE(DASHBOARD_SUPPORT)
// If regions change, trigger a relayout to re-calc regions.
if (rareNonInheritedData->m_dashboardRegions != other->rareNonInheritedData->m_dashboardRegions)
- return Layout;
+ return StyleDifferenceLayout;
#endif
}
@@ -342,13 +361,13 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
rareInheritedData->nbspMode != other->rareInheritedData->nbspMode ||
rareInheritedData->khtmlLineBreak != other->rareInheritedData->khtmlLineBreak ||
rareInheritedData->textSecurity != other->rareInheritedData->textSecurity)
- return Layout;
+ return StyleDifferenceLayout;
if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
- return Layout;
+ return StyleDifferenceLayout;
if (textStrokeWidth() != other->textStrokeWidth())
- return Layout;
+ return StyleDifferenceLayout;
}
if (inherited->indent != other->inherited->indent ||
@@ -363,7 +382,7 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
noninherited_flags._position != other->noninherited_flags._position ||
noninherited_flags._floating != other->noninherited_flags._floating ||
noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
- return Layout;
+ return StyleDifferenceLayout;
if (((int)noninherited_flags._effectiveDisplay) >= TABLE) {
@@ -371,26 +390,26 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
inherited_flags._empty_cells != other->inherited_flags._empty_cells ||
inherited_flags._caption_side != other->inherited_flags._caption_side ||
noninherited_flags._table_layout != other->noninherited_flags._table_layout)
- return Layout;
+ return StyleDifferenceLayout;
// In the collapsing border model, 'hidden' suppresses other borders, while 'none'
// does not, so these style differences can be width differences.
if (inherited_flags._border_collapse &&
- (borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE ||
- borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN ||
- borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE ||
- borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN ||
- borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE ||
- borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN ||
- borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE ||
- borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN))
- return Layout;
+ ((borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE) ||
+ (borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN) ||
+ (borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE) ||
+ (borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN) ||
+ (borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE) ||
+ (borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN) ||
+ (borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE) ||
+ (borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN)))
+ return StyleDifferenceLayout;
}
if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
if (inherited_flags._list_style_type != other->inherited_flags._list_style_type ||
inherited_flags._list_style_position != other->inherited_flags._list_style_position)
- return Layout;
+ return StyleDifferenceLayout;
}
if (inherited_flags._text_align != other->inherited_flags._text_align ||
@@ -398,12 +417,12 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
inherited_flags._direction != other->inherited_flags._direction ||
inherited_flags._white_space != other->inherited_flags._white_space ||
noninherited_flags._clear != other->noninherited_flags._clear)
- return Layout;
+ return StyleDifferenceLayout;
// Overflow returns a layout hint.
if (noninherited_flags._overflowX != other->noninherited_flags._overflowX ||
noninherited_flags._overflowY != other->noninherited_flags._overflowY)
- return Layout;
+ return StyleDifferenceLayout;
// If our border widths change, then we need to layout. Other changes to borders
// only necessitate a repaint.
@@ -411,19 +430,19 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
borderTopWidth() != other->borderTopWidth() ||
borderBottomWidth() != other->borderBottomWidth() ||
borderRightWidth() != other->borderRightWidth())
- return Layout;
+ return StyleDifferenceLayout;
// If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get();
const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives.get();
if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
- return Layout;
+ return StyleDifferenceLayout;
if (visual->counterIncrement != other->visual->counterIncrement ||
visual->counterReset != other->visual->counterReset)
- return Layout;
+ return StyleDifferenceLayout;
if (inherited->m_effectiveZoom != other->inherited->m_effectiveZoom)
- return Layout;
+ return StyleDifferenceLayout;
// Make sure these left/top/right/bottom checks stay below all layout checks and above
// all visible checks.
@@ -431,7 +450,7 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
if (surround->offset != other->surround->offset) {
// Optimize for the case where a positioned layer is moving but not changing size.
if (position() == AbsolutePosition && positionedObjectMoved(surround->offset, other->surround->offset))
- return LayoutPositionedMovementOnly;
+ return StyleDifferenceLayoutPositionedMovementOnly;
// FIXME: We will need to do a bit of work in RenderObject/Box::setStyle before we
// can stop doing a layout when relative positioned objects move. In particular, we'll need
@@ -439,16 +458,24 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
//if (other->position() == RelativePosition)
// return RepaintLayer;
//else
- return Layout;
+ return StyleDifferenceLayout;
} else if (box->z_index != other->box->z_index || box->z_auto != other->box->z_auto ||
visual->clip != other->visual->clip || visual->hasClip != other->visual->hasClip)
- return RepaintLayer;
+ return StyleDifferenceRepaintLayer;
+ }
+
+ if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity) {
+#if USE(ACCELERATED_COMPOSITING)
+ changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
+ // Don't return; keep looking for another change.
+#else
+ return StyleDifferenceRepaintLayer;
+#endif
}
- if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity ||
- rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask ||
+ if (rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask ||
rareNonInheritedData->m_maskBoxImage != other->rareNonInheritedData->m_maskBoxImage)
- return RepaintLayer;
+ return StyleDifferenceRepaintLayer;
if (inherited->color != other->inherited->color ||
inherited_flags._visibility != other->inherited_flags._visibility ||
@@ -463,19 +490,30 @@ RenderStyle::Diff RenderStyle::diff(const RenderStyle* other) const
rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit ||
rareInheritedData->textFillColor != other->rareInheritedData->textFillColor ||
rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor)
- return Repaint;
+ return StyleDifferenceRepaint;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
+ if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D ||
+ rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility ||
+ rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective ||
+ rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX ||
+ rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY)
+ return StyleDifferenceRecompositeLayer;
+ }
+#endif
// Cursors are not checked, since they will be set appropriately in response to mouse events,
// so they don't need to cause any repaint or layout.
// Animations don't need to be checked either. We always set the new style on the RenderObject, so we will get a chance to fire off
// the resulting transition properly.
- return Equal;
+ return StyleDifferenceEqual;
}
void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
{
- StyleVisualData *data = visual.access();
+ StyleVisualData* data = visual.access();
data->clip.m_top = top;
data->clip.m_right = right;
data->clip.m_bottom = bottom;
@@ -503,39 +541,6 @@ void RenderStyle::clearCursorList()
inherited.access()->cursorData = 0;
}
-bool RenderStyle::contentDataEquivalent(const RenderStyle* otherStyle) const
-{
- ContentData* c1 = rareNonInheritedData->m_content.get();
- ContentData* c2 = otherStyle->rareNonInheritedData->m_content.get();
-
- while (c1 && c2) {
- if (c1->m_type != c2->m_type)
- return false;
-
- switch (c1->m_type) {
- case CONTENT_NONE:
- break;
- case CONTENT_TEXT:
- if (!equal(c1->m_content.m_text, c2->m_content.m_text))
- return false;
- break;
- case CONTENT_OBJECT:
- if (!StyleImage::imagesEquivalent(c1->m_content.m_image, c2->m_content.m_image))
- return false;
- break;
- case CONTENT_COUNTER:
- if (*c1->m_content.m_counter != *c2->m_content.m_counter)
- return false;
- break;
- }
-
- c1 = c1->m_next;
- c2 = c2->m_next;
- }
-
- return !c1 && !c2;
-}
-
void RenderStyle::clearContent()
{
if (rareNonInheritedData->m_content)
@@ -549,8 +554,8 @@ void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
ContentData* lastContent = content.get();
- while (lastContent && lastContent->m_next)
- lastContent = lastContent->m_next;
+ while (lastContent && lastContent->next())
+ lastContent = lastContent->next();
bool reuseContent = !add;
ContentData* newContentData;
@@ -561,34 +566,30 @@ void RenderStyle::setContent(PassRefPtr<StyleImage> image, bool add)
newContentData = new ContentData;
if (lastContent && !reuseContent)
- lastContent->m_next = newContentData;
+ lastContent->setNext(newContentData);
else
content.set(newContentData);
- newContentData->m_content.m_image = image.releaseRef();
- newContentData->m_type = CONTENT_OBJECT;
+ newContentData->setImage(image);
}
-void RenderStyle::setContent(StringImpl* s, bool add)
+void RenderStyle::setContent(PassRefPtr<StringImpl> s, bool add)
{
if (!s)
return; // The string is null. Nothing to do. Just bail.
OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
ContentData* lastContent = content.get();
- while (lastContent && lastContent->m_next)
- lastContent = lastContent->m_next;
+ while (lastContent && lastContent->next())
+ lastContent = lastContent->next();
bool reuseContent = !add;
if (add && lastContent) {
- if (lastContent->m_type == CONTENT_TEXT) {
+ if (lastContent->isText()) {
// We can augment the existing string and share this ContentData node.
- StringImpl* oldStr = lastContent->m_content.m_text;
- String newStr = oldStr;
- newStr.append(s);
- newStr.impl()->ref();
- oldStr->deref();
- lastContent->m_content.m_text = newStr.impl();
+ String newStr = lastContent->text();
+ newStr.append(s.get());
+ lastContent->setText(newStr.impl());
return;
}
}
@@ -601,13 +602,11 @@ void RenderStyle::setContent(StringImpl* s, bool add)
newContentData = new ContentData;
if (lastContent && !reuseContent)
- lastContent->m_next = newContentData;
+ lastContent->setNext(newContentData);
else
content.set(newContentData);
- newContentData->m_content.m_text = s;
- newContentData->m_content.m_text->ref();
- newContentData->m_type = CONTENT_TEXT;
+ newContentData->setText(s);
}
void RenderStyle::setContent(CounterContent* c, bool add)
@@ -617,8 +616,8 @@ void RenderStyle::setContent(CounterContent* c, bool add)
OwnPtr<ContentData>& content = rareNonInheritedData.access()->m_content;
ContentData* lastContent = content.get();
- while (lastContent && lastContent->m_next)
- lastContent = lastContent->m_next;
+ while (lastContent && lastContent->next())
+ lastContent = lastContent->next();
bool reuseContent = !add;
ContentData* newContentData = 0;
@@ -629,15 +628,14 @@ void RenderStyle::setContent(CounterContent* c, bool add)
newContentData = new ContentData;
if (lastContent && !reuseContent)
- lastContent->m_next = newContentData;
+ lastContent->setNext(newContentData);
else
content.set(newContentData);
- newContentData->m_content.m_counter = c;
- newContentData->m_type = CONTENT_COUNTER;
+ newContentData->setCounter(c);
}
-void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize& borderBoxSize, bool includeTransformOrigin) const
+void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
{
// transform-origin brackets the transform with translate operations.
// Optimize for the case where the only transform is a translation, since the transform-origin is irrelevant
@@ -645,26 +643,31 @@ void RenderStyle::applyTransform(TransformationMatrix& transform, const IntSize&
bool applyTransformOrigin = false;
unsigned s = rareNonInheritedData->m_transform->m_operations.operations().size();
unsigned i;
- if (includeTransformOrigin) {
+ if (applyOrigin == IncludeTransformOrigin) {
for (i = 0; i < s; i++) {
TransformOperation::OperationType type = rareNonInheritedData->m_transform->m_operations.operations()[i]->getOperationType();
if (type != TransformOperation::TRANSLATE_X &&
type != TransformOperation::TRANSLATE_Y &&
- type != TransformOperation::TRANSLATE) {
+ type != TransformOperation::TRANSLATE &&
+ type != TransformOperation::TRANSLATE_Z &&
+ type != TransformOperation::TRANSLATE_3D
+ ) {
applyTransformOrigin = true;
break;
}
}
}
- if (applyTransformOrigin)
- transform.translate(transformOriginX().calcFloatValue(borderBoxSize.width()), transformOriginY().calcFloatValue(borderBoxSize.height()));
+ if (applyTransformOrigin) {
+ transform.translate3d(transformOriginX().calcFloatValue(borderBoxSize.width()), transformOriginY().calcFloatValue(borderBoxSize.height()), transformOriginZ());
+ }
for (i = 0; i < s; i++)
rareNonInheritedData->m_transform->m_operations.operations()[i]->apply(transform, borderBoxSize);
- if (applyTransformOrigin)
- transform.translate(-transformOriginX().calcFloatValue(borderBoxSize.width()), -transformOriginY().calcFloatValue(borderBoxSize.height()));
+ if (applyTransformOrigin) {
+ transform.translate3d(-transformOriginX().calcFloatValue(borderBoxSize.width()), -transformOriginY().calcFloatValue(borderBoxSize.height()), -transformOriginZ());
+ }
}
#if ENABLE(XBL)
@@ -818,7 +821,7 @@ AnimationList* RenderStyle::accessTransitions()
return rareNonInheritedData->m_transitions.get();
}
-const Animation* RenderStyle::transitionForProperty(int property)
+const Animation* RenderStyle::transitionForProperty(int property) const
{
if (transitions()) {
for (size_t i = 0; i < transitions()->size(); ++i) {
diff --git a/WebCore/rendering/style/RenderStyle.h b/WebCore/rendering/style/RenderStyle.h
index fed3057..32c0cf4 100644
--- a/WebCore/rendering/style/RenderStyle.h
+++ b/WebCore/rendering/style/RenderStyle.h
@@ -106,17 +106,6 @@ class StyleImage;
class RenderStyle: public RefCounted<RenderStyle> {
friend class CSSStyleSelector;
-
-public:
- // static pseudo styles. Dynamic ones are produced on the fly.
- enum PseudoId { NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
- SLIDER_THUMB, SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL,
- MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER,
- MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, MEDIA_CONTROLS_SEEK_BACK_BUTTON,
- MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON,
- SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER };
- static const int FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON;
-
protected:
// !START SYNC!: Keep this in sync with the copy constructor in RenderStyle.cpp
@@ -335,6 +324,7 @@ public:
return true;
return background->m_background.hasImage();
}
+ bool hasBackgroundImage() const { return background->m_background.hasImage(); }
bool hasFixedBackgroundImage() const { return background->m_background.hasFixedImage(); }
bool hasAppearance() const { return appearance() != NoControlPart; }
@@ -356,6 +346,11 @@ public:
Length top() const { return surround->offset.top(); }
Length bottom() const { return surround->offset.bottom(); }
+ // Whether or not a positioned element requires normal flow x/y to be computed
+ // to determine its position.
+ bool hasStaticX() const { return (left().isAuto() && right().isAuto()) || left().isStatic() || right().isStatic(); }
+ bool hasStaticY() const { return (top().isAuto() && bottom().isAuto()) || top().isStatic(); }
+
EPosition position() const { return static_cast<EPosition>(noninherited_flags._position); }
EFloat floating() const { return static_cast<EFloat>(noninherited_flags._floating); }
@@ -446,6 +441,19 @@ public:
TextDirection direction() const { return static_cast<TextDirection>(inherited_flags._direction); }
Length lineHeight() const { return inherited->line_height; }
+ int computedLineHeight() const
+ {
+ Length lh = lineHeight();
+
+ // Negative value means the line height is not set. Use the font's built-in spacing.
+ if (lh.isNegative())
+ return font().lineSpacing();
+
+ if (lh.isPercent())
+ return lh.calcMinValue(fontSize());
+
+ return lh.value();
+ }
EWhiteSpace whiteSpace() const { return static_cast<EWhiteSpace>(inherited_flags._white_space); }
static bool autoWrap(EWhiteSpace ws)
@@ -628,8 +636,16 @@ public:
const TransformOperations& transform() const { return rareNonInheritedData->m_transform->m_operations; }
Length transformOriginX() const { return rareNonInheritedData->m_transform->m_x; }
Length transformOriginY() const { return rareNonInheritedData->m_transform->m_y; }
+ float transformOriginZ() const { return rareNonInheritedData->m_transform->m_z; }
bool hasTransform() const { return !rareNonInheritedData->m_transform->m_operations.operations().isEmpty(); }
- void applyTransform(TransformationMatrix&, const IntSize& borderBoxSize, bool includeTransformOrigin = true) const;
+
+ // Return true if any transform related property (currently transform, transformStyle3D or perspective)
+ // indicates that we are transforming
+ bool hasTransformRelatedProperty() const { return hasTransform() || preserves3D() || hasPerspective(); }
+
+ enum ApplyTransformOrigin { IncludeTransformOrigin, ExcludeTransformOrigin };
+ void applyTransform(TransformationMatrix&, const IntSize& borderBoxSize, ApplyTransformOrigin = IncludeTransformOrigin) const;
+
bool hasMask() const { return rareNonInheritedData->m_mask.hasImage() || rareNonInheritedData->m_maskBoxImage.hasImage(); }
// End CSS3 Getters
@@ -645,7 +661,21 @@ public:
bool hasTransitions() const { return rareNonInheritedData->m_transitions && rareNonInheritedData->m_transitions->size() > 0; }
// return the first found Animation (including 'all' transitions)
- const Animation* transitionForProperty(int property);
+ const Animation* transitionForProperty(int property) const;
+
+ ETransformStyle3D transformStyle3D() const { return rareNonInheritedData->m_transformStyle3D; }
+ bool preserves3D() const { return rareNonInheritedData->m_transformStyle3D == TransformStyle3DPreserve3D; }
+
+ EBackfaceVisibility backfaceVisibility() const { return rareNonInheritedData->m_backfaceVisibility; }
+ float perspective() const { return rareNonInheritedData->m_perspective; }
+ bool hasPerspective() const { return rareNonInheritedData->m_perspective > 0; }
+ Length perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; }
+ Length perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; }
+
+#if USE(ACCELERATED_COMPOSITING)
+ // When set, this ensures that styles compare as different. Used during accelerated animations.
+ bool isRunningAcceleratedAnimation() const { return rareNonInheritedData->m_runningAcceleratedAnimation; }
+#endif
int lineClamp() const { return rareNonInheritedData->lineClamp; }
bool textSizeAdjust() const { return rareInheritedData->textSizeAdjust; }
@@ -926,6 +956,7 @@ public:
void setTransform(const TransformOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_transform, m_operations, ops); }
void setTransformOriginX(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_x, l); }
void setTransformOriginY(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, l); }
+ void setTransformOriginZ(float f) { SET_VAR(rareNonInheritedData.access()->m_transform, m_z, f); }
// End CSS3 Setters
// Apple-specific property setters
@@ -946,6 +977,16 @@ public:
void adjustAnimations();
void adjustTransitions();
+ void setTransformStyle3D(ETransformStyle3D b) { SET_VAR(rareNonInheritedData, m_transformStyle3D, b); }
+ void setBackfaceVisibility(EBackfaceVisibility b) { SET_VAR(rareNonInheritedData, m_backfaceVisibility, b); }
+ void setPerspective(float p) { SET_VAR(rareNonInheritedData, m_perspective, p); }
+ void setPerspectiveOriginX(Length l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginX, l); }
+ void setPerspectiveOriginY(Length l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginY, l); }
+
+#if USE(ACCELERATED_COMPOSITING)
+ void setIsRunningAcceleratedAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_runningAcceleratedAnimation, b); }
+#endif
+
void setLineClamp(int c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
void setTextSizeAdjust(bool b) { SET_VAR(rareInheritedData, textSizeAdjust, b); }
void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); }
@@ -969,9 +1010,9 @@ public:
#endif
const ContentData* contentData() const { return rareNonInheritedData->m_content.get(); }
- bool contentDataEquivalent(const RenderStyle* otherStyle) const;
+ bool contentDataEquivalent(const RenderStyle* otherStyle) const { return const_cast<RenderStyle*>(this)->rareNonInheritedData->contentDataEquivalent(*const_cast<RenderStyle*>(otherStyle)->rareNonInheritedData); }
void clearContent();
- void setContent(StringImpl*, bool add = false);
+ void setContent(PassRefPtr<StringImpl>, bool add = false);
void setContent(PassRefPtr<StyleImage>, bool add = false);
void setContent(CounterContent*, bool add = false);
@@ -980,13 +1021,7 @@ public:
bool inheritedNotEqual(RenderStyle*) const;
- // The difference between two styles. The following values are used:
- // (1) Equal - The two styles are identical
- // (2) Repaint - The object just needs to be repainted.
- // (3) RepaintLayer - The layer and its descendant layers needs to be repainted.
- // (4) Layout - A layout is required.
- enum Diff { Equal, Repaint, RepaintLayer, LayoutPositionedMovementOnly, Layout };
- Diff diff(const RenderStyle*) const;
+ StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
bool isDisplayReplacedType() const
{
@@ -1119,6 +1154,12 @@ public:
static Length initialTransformOriginX() { return Length(50.0, Percent); }
static Length initialTransformOriginY() { return Length(50.0, Percent); }
static EPointerEvents initialPointerEvents() { return PE_AUTO; }
+ static float initialTransformOriginZ() { return 0; }
+ static ETransformStyle3D initialTransformStyle3D() { return TransformStyle3DFlat; }
+ static EBackfaceVisibility initialBackfaceVisibility() { return BackfaceVisibilityVisible; }
+ static float initialPerspective() { return 0; }
+ static Length initialPerspectiveOriginX() { return Length(50.0, Percent); }
+ static Length initialPerspectiveOriginY() { return Length(50.0, Percent); }
// Keep these at the end.
static int initialLineClamp() { return -1; }
diff --git a/WebCore/rendering/style/RenderStyleConstants.h b/WebCore/rendering/style/RenderStyleConstants.h
index 40ad3cc..405cf7c 100644
--- a/WebCore/rendering/style/RenderStyleConstants.h
+++ b/WebCore/rendering/style/RenderStyleConstants.h
@@ -36,6 +36,44 @@ namespace WebCore {
* and produce invalid results.
*/
+// The difference between two styles. The following values are used:
+// (1) StyleDifferenceEqual - The two styles are identical
+// (2) StyleDifferenceRecompositeLayer - The layer needs its position and transform updated, but no repaint
+// (3) StyleDifferenceRepaint - The object just needs to be repainted.
+// (4) StyleDifferenceRepaintLayer - The layer and its descendant layers needs to be repainted.
+// (5) StyleDifferenceLayout - A layout is required.
+enum StyleDifference {
+ StyleDifferenceEqual,
+#if USE(ACCELERATED_COMPOSITING)
+ StyleDifferenceRecompositeLayer,
+#endif
+ StyleDifferenceRepaint,
+ StyleDifferenceRepaintLayer,
+ StyleDifferenceLayoutPositionedMovementOnly,
+ StyleDifferenceLayout
+};
+
+// When some style properties change, different amounts of work have to be done depending on
+// context (e.g. whether the property is changing on an element which has a compositing layer).
+// A simple StyleDifference does not provide enough information so we return a bit mask of
+// StyleDifferenceContextSensitiveProperties from RenderStyle::diff() too.
+enum StyleDifferenceContextSensitiveProperty {
+ ContextSensitivePropertyNone = 0,
+ ContextSensitivePropertyTransform = (1 << 0),
+ ContextSensitivePropertyOpacity = (1 << 1)
+};
+
+// Static pseudo styles. Dynamic ones are produced on the fly.
+enum PseudoId {
+ NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR, FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
+ SLIDER_THUMB, SEARCH_CANCEL_BUTTON, SEARCH_DECORATION, SEARCH_RESULTS_DECORATION, SEARCH_RESULTS_BUTTON, MEDIA_CONTROLS_PANEL,
+ MEDIA_CONTROLS_PLAY_BUTTON, MEDIA_CONTROLS_MUTE_BUTTON, MEDIA_CONTROLS_TIMELINE, MEDIA_CONTROLS_TIMELINE_CONTAINER,
+ MEDIA_CONTROLS_CURRENT_TIME_DISPLAY, MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, MEDIA_CONTROLS_SEEK_BACK_BUTTON,
+ MEDIA_CONTROLS_SEEK_FORWARD_BUTTON, MEDIA_CONTROLS_FULLSCREEN_BUTTON,
+ SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
+
+ FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON
+};
// These have been defined in the order of their precedence for border-collapsing. Do
// not change this order!
@@ -163,7 +201,7 @@ enum EListStyleType {
HIRAGANA, KATAKANA, HIRAGANA_IROHA, KATAKANA_IROHA, LNONE
};
-enum ContentType {
+enum StyleContentType {
CONTENT_NONE, CONTENT_OBJECT, CONTENT_TEXT, CONTENT_COUNTER
};
@@ -171,11 +209,6 @@ enum EBorderFit { BorderFitBorder, BorderFitLines };
enum ETimingFunctionType { LinearTimingFunction, CubicBezierTimingFunction };
-enum EAnimPlayState {
- AnimPlayStatePlaying = 0x0,
- AnimPlayStatePaused = 0x1
-};
-
enum EWhiteSpace {
NORMAL, PRE, PRE_WRAP, PRE_LINE, NOWRAP, KHTML_NOWRAP
};
@@ -263,6 +296,14 @@ enum EPointerEvents {
PE_VISIBLE_STROKE, PE_VISIBLE_FILL, PE_VISIBLE_PAINTED, PE_ALL
};
+enum ETransformStyle3D {
+ TransformStyle3DFlat, TransformStyle3DPreserve3D
+};
+
+enum EBackfaceVisibility {
+ BackfaceVisibilityVisible, BackfaceVisibilityHidden
+};
+
} // namespace WebCore
#endif // RenderStyleConstants_h
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index 1749978..c5f0648 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -128,7 +128,7 @@ float SVGRenderStyle::cssPrimitiveToLength(const RenderObject* item, CSSValue* v
return defaultValue;
if (cssType == CSSPrimitiveValue::CSS_PERCENTAGE) {
- SVGStyledElement* element = static_cast<SVGStyledElement*>(item->element());
+ SVGStyledElement* element = static_cast<SVGStyledElement*>(item->node());
SVGElement* viewportElement = (element ? element->viewportElement() : 0);
if (viewportElement) {
float result = primitive->getFloatValue() / 100.0f;
diff --git a/WebCore/rendering/style/StyleInheritedData.cpp b/WebCore/rendering/style/StyleInheritedData.cpp
index 56d2686..f59c0c2 100644
--- a/WebCore/rendering/style/StyleInheritedData.cpp
+++ b/WebCore/rendering/style/StyleInheritedData.cpp
@@ -66,7 +66,7 @@ static bool cursorDataEquivalent(const CursorList* c1, const CursorList* c2)
{
if (c1 == c2)
return true;
- if (!c1 && c2 || c1 && !c2)
+ if ((!c1 && c2) || (c1 && !c2))
return false;
return (*c1 == *c2);
}
diff --git a/WebCore/rendering/style/StyleRareInheritedData.cpp b/WebCore/rendering/style/StyleRareInheritedData.cpp
index 2294568..f26baa6 100644
--- a/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -94,7 +94,7 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
{
- if (!textShadow && o.textShadow || textShadow && !o.textShadow)
+ if ((!textShadow && o.textShadow) || (textShadow && !o.textShadow))
return false;
if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
return false;
diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.cpp b/WebCore/rendering/style/StyleRareNonInheritedData.cpp
index e8ceeeb..401c04f 100644
--- a/WebCore/rendering/style/StyleRareNonInheritedData.cpp
+++ b/WebCore/rendering/style/StyleRareNonInheritedData.cpp
@@ -23,7 +23,10 @@
#include "StyleRareNonInheritedData.h"
#include "CSSStyleSelector.h"
+#include "ContentData.h"
+#include "RenderCounter.h"
#include "RenderStyle.h"
+#include "StyleImage.h"
namespace WebCore {
@@ -39,10 +42,18 @@ StyleRareNonInheritedData::StyleRareNonInheritedData()
, matchNearestMailBlockquoteColor(RenderStyle::initialMatchNearestMailBlockquoteColor())
, m_appearance(RenderStyle::initialAppearance())
, m_borderFit(RenderStyle::initialBorderFit())
+#if USE(ACCELERATED_COMPOSITING)
+ , m_runningAcceleratedAnimation(false)
+#endif
, m_boxShadow(0)
, m_animations(0)
, m_transitions(0)
, m_mask(FillLayer(MaskFillLayer))
+ , m_transformStyle3D(RenderStyle::initialTransformStyle3D())
+ , m_backfaceVisibility(RenderStyle::initialBackfaceVisibility())
+ , m_perspective(RenderStyle::initialPerspective())
+ , m_perspectiveOriginX(RenderStyle::initialPerspectiveOriginX())
+ , m_perspectiveOriginY(RenderStyle::initialPerspectiveOriginY())
#if ENABLE(XBL)
, bindingURI(0)
#endif
@@ -66,12 +77,20 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, matchNearestMailBlockquoteColor(o.matchNearestMailBlockquoteColor)
, m_appearance(o.m_appearance)
, m_borderFit(o.m_borderFit)
+#if USE(ACCELERATED_COMPOSITING)
+ , m_runningAcceleratedAnimation(o.m_runningAcceleratedAnimation)
+#endif
, m_boxShadow(o.m_boxShadow ? new ShadowData(*o.m_boxShadow) : 0)
, m_boxReflect(o.m_boxReflect)
, m_animations(o.m_animations ? new AnimationList(*o.m_animations) : 0)
, m_transitions(o.m_transitions ? new AnimationList(*o.m_transitions) : 0)
, m_mask(o.m_mask)
, m_maskBoxImage(o.m_maskBoxImage)
+ , m_transformStyle3D(o.m_transformStyle3D)
+ , m_backfaceVisibility(o.m_backfaceVisibility)
+ , m_perspective(o.m_perspective)
+ , m_perspectiveOriginX(o.m_perspectiveOriginX)
+ , m_perspectiveOriginY(o.m_perspectiveOriginY)
#if ENABLE(XBL)
, bindingURI(o.bindingURI ? o.bindingURI->copy() : 0)
#endif
@@ -105,7 +124,7 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& marquee == o.marquee
&& m_multiCol == o.m_multiCol
&& m_transform == o.m_transform
- && m_content == o.m_content
+ && contentDataEquivalent(o)
&& m_counterDirectives == o.m_counterDirectives
&& userDrag == o.userDrag
&& textOverflow == o.textOverflow
@@ -114,6 +133,9 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& matchNearestMailBlockquoteColor == o.matchNearestMailBlockquoteColor
&& m_appearance == o.m_appearance
&& m_borderFit == o.m_borderFit
+#if USE(ACCELERATED_COMPOSITING)
+ && !m_runningAcceleratedAnimation && !o.m_runningAcceleratedAnimation
+#endif
&& shadowDataEquivalent(o)
&& reflectionDataEquivalent(o)
&& animationDataEquivalent(o)
@@ -123,12 +145,32 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
#if ENABLE(XBL)
&& bindingsEquivalent(o)
#endif
+ && (m_transformStyle3D == o.m_transformStyle3D)
+ && (m_backfaceVisibility == o.m_backfaceVisibility)
+ && (m_perspective == o.m_perspective)
+ && (m_perspectiveOriginX == o.m_perspectiveOriginX)
+ && (m_perspectiveOriginY == o.m_perspectiveOriginY)
;
}
+bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInheritedData& o) const
+{
+ ContentData* c1 = m_content.get();
+ ContentData* c2 = o.m_content.get();
+
+ while (c1 && c2) {
+ if (!c1->dataEquivalent(*c2))
+ return false;
+ c1 = c1->next();
+ c2 = c2->next();
+ }
+
+ return !c1 && !c2;
+}
+
bool StyleRareNonInheritedData::shadowDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if (!m_boxShadow && o.m_boxShadow || m_boxShadow && !o.m_boxShadow)
+ if ((!m_boxShadow && o.m_boxShadow) || (m_boxShadow && !o.m_boxShadow))
return false;
if (m_boxShadow && o.m_boxShadow && (*m_boxShadow != *o.m_boxShadow))
return false;
@@ -148,7 +190,7 @@ bool StyleRareNonInheritedData::reflectionDataEquivalent(const StyleRareNonInher
bool StyleRareNonInheritedData::animationDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if (!m_animations && o.m_animations || m_animations && !o.m_animations)
+ if ((!m_animations && o.m_animations) || (m_animations && !o.m_animations))
return false;
if (m_animations && o.m_animations && (*m_animations != *o.m_animations))
return false;
@@ -157,7 +199,7 @@ bool StyleRareNonInheritedData::animationDataEquivalent(const StyleRareNonInheri
bool StyleRareNonInheritedData::transitionDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if (!m_transitions && o.m_transitions || m_transitions && !o.m_transitions)
+ if ((!m_transitions && o.m_transitions) || (m_transitions && !o.m_transitions))
return false;
if (m_transitions && o.m_transitions && (*m_transitions != *o.m_transitions))
return false;
diff --git a/WebCore/rendering/style/StyleRareNonInheritedData.h b/WebCore/rendering/style/StyleRareNonInheritedData.h
index 6ce6a33..8dd22b3 100644
--- a/WebCore/rendering/style/StyleRareNonInheritedData.h
+++ b/WebCore/rendering/style/StyleRareNonInheritedData.h
@@ -30,6 +30,7 @@
#include "DataRef.h"
#include "FillLayer.h"
#include "NinePieceImage.h"
+#include "StyleTransformData.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Vector.h>
@@ -69,7 +70,8 @@ public:
bool operator==(const StyleRareNonInheritedData&) const;
bool operator!=(const StyleRareNonInheritedData& o) const { return !(*this == o); }
-
+
+ bool contentDataEquivalent(const StyleRareNonInheritedData& o) const;
bool shadowDataEquivalent(const StyleRareNonInheritedData& o) const;
bool reflectionDataEquivalent(const StyleRareNonInheritedData& o) const;
bool animationDataEquivalent(const StyleRareNonInheritedData&) const;
@@ -96,6 +98,9 @@ public:
unsigned matchNearestMailBlockquoteColor : 1; // EMatchNearestMailBlockquoteColor, FIXME: This property needs to be eliminated. It should never have been added.
unsigned m_appearance : 6; // EAppearance
unsigned m_borderFit : 1; // EBorderFit
+#if USE(ACCELERATED_COMPOSITING)
+ bool m_runningAcceleratedAnimation : 1;
+#endif
OwnPtr<ShadowData> m_boxShadow; // For box-shadow decorations.
RefPtr<StyleReflection> m_boxReflect;
@@ -106,6 +111,12 @@ public:
FillLayer m_mask;
NinePieceImage m_maskBoxImage;
+ ETransformStyle3D m_transformStyle3D;
+ EBackfaceVisibility m_backfaceVisibility;
+ float m_perspective;
+ Length m_perspectiveOriginX;
+ Length m_perspectiveOriginY;
+
#if ENABLE(XBL)
OwnPtr<BindingURI> bindingURI; // The XBL binding URI list.
#endif
diff --git a/WebCore/rendering/style/StyleTransformData.cpp b/WebCore/rendering/style/StyleTransformData.cpp
index de20e77..2baebf9 100644
--- a/WebCore/rendering/style/StyleTransformData.cpp
+++ b/WebCore/rendering/style/StyleTransformData.cpp
@@ -30,6 +30,7 @@ StyleTransformData::StyleTransformData()
: m_operations(RenderStyle::initialTransform())
, m_x(RenderStyle::initialTransformOriginX())
, m_y(RenderStyle::initialTransformOriginY())
+ , m_z(RenderStyle::initialTransformOriginZ())
{
}
@@ -38,12 +39,13 @@ StyleTransformData::StyleTransformData(const StyleTransformData& o)
, m_operations(o.m_operations)
, m_x(o.m_x)
, m_y(o.m_y)
+ , m_z(o.m_z)
{
}
bool StyleTransformData::operator==(const StyleTransformData& o) const
{
- return m_x == o.m_x && m_y == o.m_y && m_operations == o.m_operations;
+ return m_x == o.m_x && m_y == o.m_y && m_z == o.m_z && m_operations == o.m_operations;
}
} // namespace WebCore
diff --git a/WebCore/rendering/style/StyleTransformData.h b/WebCore/rendering/style/StyleTransformData.h
index 157e600..6039824 100644
--- a/WebCore/rendering/style/StyleTransformData.h
+++ b/WebCore/rendering/style/StyleTransformData.h
@@ -46,6 +46,7 @@ public:
TransformOperations m_operations;
Length m_x;
Length m_y;
+ float m_z;
private:
StyleTransformData();
diff --git a/WebCore/storage/Database.cpp b/WebCore/storage/Database.cpp
index 93d87a7..941c49c 100644
--- a/WebCore/storage/Database.cpp
+++ b/WebCore/storage/Database.cpp
@@ -40,7 +40,6 @@
#include "FileSystem.h"
#include "Frame.h"
#include "InspectorController.h"
-#include "JSDOMWindow.h"
#include "Logging.h"
#include "NotImplemented.h"
#include "Page.h"
@@ -48,10 +47,14 @@
#include "SQLiteDatabase.h"
#include "SQLiteStatement.h"
#include "SQLResultSet.h"
-#include <runtime/InitializeThreading.h>
#include <wtf/MainThread.h>
#include <wtf/StdLibExtras.h>
+#if USE(JSC)
+#include "JSDOMWindow.h"
+#include <runtime/InitializeThreading.h>
+#endif
+
namespace WebCore {
static Mutex& guidMutex()
@@ -111,7 +114,7 @@ PassRefPtr<Database> Database::openDatabase(Document* document, const String& na
document->setHasOpenDatabases();
if (Page* page = document->frame()->page())
- page->inspectorController()->didOpenDatabase(database.get(), document->domain(), name, expectedVersion);
+ page->inspectorController()->didOpenDatabase(database.get(), document->securityOrigin()->host(), name, expectedVersion);
return database;
}
@@ -131,9 +134,11 @@ Database::Database(Document* document, const String& name, const String& expecte
if (m_name.isNull())
m_name = "";
+#if USE(JSC)
JSC::initializeThreading();
// Database code violates the normal JSCore contract by calling jsUnprotect from a secondary thread, and thus needs additional locking.
JSDOMWindow::commonJSGlobalData()->heap.setGCProtectNeedsLocking();
+#endif
m_guid = guidForOriginAndName(m_securityOrigin->toString(), name);
diff --git a/WebCore/storage/DatabaseThread.cpp b/WebCore/storage/DatabaseThread.cpp
index 191a476..de9fffb 100644
--- a/WebCore/storage/DatabaseThread.cpp
+++ b/WebCore/storage/DatabaseThread.cpp
@@ -54,7 +54,7 @@ bool DatabaseThread::start()
if (m_threadID)
return true;
- m_threadID = createThread(DatabaseThread::databaseThreadStart, this, "WebCore::Database");
+ m_threadID = createThread(DatabaseThread::databaseThreadStart, this, "WebCore: Database");
return m_threadID;
}
diff --git a/WebCore/storage/LocalStorageArea.cpp b/WebCore/storage/LocalStorageArea.cpp
index 56dc246..e0900e6 100644
--- a/WebCore/storage/LocalStorageArea.cpp
+++ b/WebCore/storage/LocalStorageArea.cpp
@@ -219,9 +219,8 @@ void LocalStorageArea::dispatchStorageEvent(const String& key, const String& old
HashSet<Page*>::const_iterator end = pages.end();
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (Document* document = frame->document())
- if (document->securityOrigin()->equal(securityOrigin()))
- frames.append(frame);
+ if (frame->document()->securityOrigin()->equal(securityOrigin()))
+ frames.append(frame);
}
}
diff --git a/WebCore/storage/LocalStorageThread.cpp b/WebCore/storage/LocalStorageThread.cpp
index 92aa43e..da50c90 100644
--- a/WebCore/storage/LocalStorageThread.cpp
+++ b/WebCore/storage/LocalStorageThread.cpp
@@ -50,7 +50,7 @@ bool LocalStorageThread::start()
if (m_threadID)
return true;
- m_threadID = createThread(LocalStorageThread::localStorageThreadStart, this, "WebCore::LocalStorage");
+ m_threadID = createThread(LocalStorageThread::localStorageThreadStart, this, "WebCore: LocalStorage");
return m_threadID;
}
diff --git a/WebCore/storage/SQLError.idl b/WebCore/storage/SQLError.idl
index 188b9db..5c9540f 100644
--- a/WebCore/storage/SQLError.idl
+++ b/WebCore/storage/SQLError.idl
@@ -29,7 +29,7 @@
module storage {
interface SQLError {
- readonly attribute unsigned int code;
+ readonly attribute unsigned long code;
readonly attribute DOMString message;
};
}
diff --git a/WebCore/storage/SQLResultSet.idl b/WebCore/storage/SQLResultSet.idl
index fbad936..e0d72c9 100644
--- a/WebCore/storage/SQLResultSet.idl
+++ b/WebCore/storage/SQLResultSet.idl
@@ -31,8 +31,8 @@ module storage {
interface SQLResultSet {
readonly attribute SQLResultSetRowList rows;
- readonly attribute int insertId
+ readonly attribute long insertId
getter raises(DOMException);
- readonly attribute int rowsAffected;
+ readonly attribute long rowsAffected;
};
}
diff --git a/WebCore/storage/SessionStorageArea.cpp b/WebCore/storage/SessionStorageArea.cpp
index 048c488..285922e 100644
--- a/WebCore/storage/SessionStorageArea.cpp
+++ b/WebCore/storage/SessionStorageArea.cpp
@@ -75,9 +75,8 @@ void SessionStorageArea::dispatchStorageEvent(const String& key, const String& o
// For SessionStorage events, each frame in the page's frametree with the same origin as this StorageArea needs to be notified of the change
Vector<RefPtr<Frame> > frames;
for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
- if (Document* document = frame->document())
- if (document->securityOrigin()->equal(securityOrigin()))
- frames.append(frame);
+ if (frame->document()->securityOrigin()->equal(securityOrigin()))
+ frames.append(frame);
}
for (unsigned i = 0; i < frames.size(); ++i) {
diff --git a/WebCore/svg/SVGAnimateMotionElement.cpp b/WebCore/svg/SVGAnimateMotionElement.cpp
index b6422f5..861f353 100644
--- a/WebCore/svg/SVGAnimateMotionElement.cpp
+++ b/WebCore/svg/SVGAnimateMotionElement.cpp
@@ -150,7 +150,7 @@ void SVGAnimateMotionElement::resetToBaseValue(const String&)
TransformationMatrix* transform = target->supplementalTransform();
if (!transform)
return;
- transform->reset();
+ transform->makeIdentity();
}
bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString)
@@ -179,7 +179,7 @@ void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned,
return;
if (!isAdditive())
- transform->reset();
+ transform->makeIdentity();
// FIXME: Implement accumulate.
diff --git a/WebCore/svg/SVGElementInstance.h b/WebCore/svg/SVGElementInstance.h
index 261d34a..f5c6ca9 100644
--- a/WebCore/svg/SVGElementInstance.h
+++ b/WebCore/svg/SVGElementInstance.h
@@ -55,7 +55,7 @@ namespace WebCore {
virtual ScriptExecutionContext* scriptExecutionContext() const;
- virtual EventTargetNode* toNode() { return shadowTreeElement(); }
+ virtual Node* toNode() { return shadowTreeElement(); }
virtual SVGElementInstance* toSVGElementInstance() { return this; }
virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
diff --git a/WebCore/svg/SVGFont.cpp b/WebCore/svg/SVGFont.cpp
index 3dae585..9b36f87 100644
--- a/WebCore/svg/SVGFont.cpp
+++ b/WebCore/svg/SVGFont.cpp
@@ -253,8 +253,8 @@ struct SVGTextRunWalker {
bool haveAltGlyph = false;
SVGGlyphIdentifier altGlyphIdentifier;
if (RenderObject* renderObject = run.referencingRenderObject()) {
- if (renderObject->element() && renderObject->element()->hasTagName(SVGNames::altGlyphTag)) {
- SVGGlyphElement* glyphElement = static_cast<SVGAltGlyphElement*>(renderObject->element())->glyphElement();
+ if (renderObject->node() && renderObject->node()->hasTagName(SVGNames::altGlyphTag)) {
+ SVGGlyphElement* glyphElement = static_cast<SVGAltGlyphElement*>(renderObject->node())->glyphElement();
if (glyphElement) {
haveAltGlyph = true;
altGlyphIdentifier = glyphElement->buildGlyphIdentifier();
@@ -407,7 +407,7 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun&
if (RenderObject* renderObject = run.referencingRenderObject()) {
isVerticalText = isVerticalWritingMode(renderObject->style()->svgStyle());
- if (SVGElement* element = static_cast<SVGElement*>(renderObject->element()))
+ if (SVGElement* element = static_cast<SVGElement*>(renderObject->node()))
language = element->getAttribute(XMLNames::langAttr);
}
@@ -496,7 +496,7 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
if (run.referencingRenderObject()) {
isVerticalText = isVerticalWritingMode(run.referencingRenderObject()->style()->svgStyle());
- if (SVGElement* element = static_cast<SVGElement*>(run.referencingRenderObject()->element()))
+ if (SVGElement* element = static_cast<SVGElement*>(run.referencingRenderObject()->node()))
language = element->getAttribute(XMLNames::langAttr);
}
diff --git a/WebCore/svg/SVGImageLoader.cpp b/WebCore/svg/SVGImageLoader.cpp
index 6e0915d..4b15acb 100644
--- a/WebCore/svg/SVGImageLoader.cpp
+++ b/WebCore/svg/SVGImageLoader.cpp
@@ -42,16 +42,12 @@ SVGImageLoader::~SVGImageLoader()
void SVGImageLoader::dispatchLoadEvent()
{
- if (!haveFiredLoadEvent() && image()) {
- setHaveFiredLoadEvent(true);
-
- if (image()->errorOccurred())
- element()->dispatchEventForType(eventNames().errorEvent, false, false);
- else {
- SVGImageElement* imageElement = static_cast<SVGImageElement*>(element());
- if (imageElement->externalResourcesRequiredBaseValue())
- imageElement->sendSVGLoadEventIfPossible(true);
- }
+ if (image()->errorOccurred())
+ element()->dispatchEventForType(eventNames().errorEvent, false, false);
+ else {
+ SVGImageElement* imageElement = static_cast<SVGImageElement*>(element());
+ if (imageElement->externalResourcesRequiredBaseValue())
+ imageElement->sendSVGLoadEventIfPossible(true);
}
}
diff --git a/WebCore/svg/SVGLength.cpp b/WebCore/svg/SVGLength.cpp
index d1b8856..ca3bac3 100644
--- a/WebCore/svg/SVGLength.cpp
+++ b/WebCore/svg/SVGLength.cpp
@@ -285,7 +285,7 @@ float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SV
Document* doc = context->document();
if (doc->documentElement() == context) {
// We have to ask the canvas for the full "canvas size"...
- RenderView* view = static_cast<RenderView*>(doc->renderer());
+ RenderView* view = toRenderView(doc->renderer());
if (view && view->frameView()) {
width = view->frameView()->visibleWidth(); // TODO: recheck!
height = view->frameView()->visibleHeight(); // TODO: recheck!
diff --git a/WebCore/svg/SVGLinearGradientElement.cpp b/WebCore/svg/SVGLinearGradientElement.cpp
index ac2b6b1..d2d1798 100644
--- a/WebCore/svg/SVGLinearGradientElement.cpp
+++ b/WebCore/svg/SVGLinearGradientElement.cpp
@@ -87,6 +87,7 @@ void SVGLinearGradientElement::buildGradient() const
FloatPoint endPoint = FloatPoint::narrowPrecision(attributes.x2(), attributes.y2());
RefPtr<Gradient> gradient = Gradient::create(startPoint, endPoint);
+ gradient->setSpreadMethod(attributes.spreadMethod());
Vector<SVGGradientStop> m_stops = attributes.stops();
float previousOffset = 0.0f;
@@ -107,7 +108,6 @@ void SVGLinearGradientElement::buildGradient() const
linearGradient->setGradientStops(attributes.stops());
// These should possibly be supported on Gradient
- linearGradient->setGradientSpreadMethod(attributes.spreadMethod());
linearGradient->setGradientTransform(attributes.gradientTransform());
linearGradient->setGradientStart(startPoint);
linearGradient->setGradientEnd(endPoint);
diff --git a/WebCore/svg/SVGPathSegList.idl b/WebCore/svg/SVGPathSegList.idl
index f55167e..8c67bd3 100644
--- a/WebCore/svg/SVGPathSegList.idl
+++ b/WebCore/svg/SVGPathSegList.idl
@@ -29,19 +29,19 @@ module svg {
interface [Conditional=SVG] SVGPathSegList {
readonly attribute unsigned long numberOfItems;
- [Custom] void clear()
+ [JSCCustom] void clear()
raises(DOMException);
- [Custom] SVGPathSeg initialize(in SVGPathSeg newItem)
+ [JSCCustom] SVGPathSeg initialize(in SVGPathSeg newItem)
raises(DOMException, SVGException);
- [Custom] SVGPathSeg getItem(in unsigned long index)
+ [JSCCustom] SVGPathSeg getItem(in unsigned long index)
raises(DOMException);
- [Custom] SVGPathSeg insertItemBefore(in SVGPathSeg newItem, in unsigned long index)
+ [JSCCustom] SVGPathSeg insertItemBefore(in SVGPathSeg newItem, in unsigned long index)
raises(DOMException, SVGException);
- [Custom] SVGPathSeg replaceItem(in SVGPathSeg newItem, in unsigned long index)
+ [JSCCustom] SVGPathSeg replaceItem(in SVGPathSeg newItem, in unsigned long index)
raises(DOMException, SVGException);
- [Custom] SVGPathSeg removeItem(in unsigned long index)
+ [JSCCustom] SVGPathSeg removeItem(in unsigned long index)
raises(DOMException);
- [Custom] SVGPathSeg appendItem(in SVGPathSeg newItem)
+ [JSCCustom] SVGPathSeg appendItem(in SVGPathSeg newItem)
raises(DOMException, SVGException);
};
diff --git a/WebCore/svg/SVGPointList.idl b/WebCore/svg/SVGPointList.idl
index 3ac8b1a..cf82dff 100644
--- a/WebCore/svg/SVGPointList.idl
+++ b/WebCore/svg/SVGPointList.idl
@@ -28,19 +28,19 @@ module svg {
interface [Conditional=SVG] SVGPointList {
readonly attribute unsigned long numberOfItems;
- [Custom] void clear()
+ [JSCCustom] void clear()
raises(DOMException);
- [Custom] SVGPoint initialize(in SVGPoint item)
+ [JSCCustom] SVGPoint initialize(in SVGPoint item)
raises(DOMException, SVGException);
- [Custom] SVGPoint getItem(in unsigned long index)
+ [JSCCustom] SVGPoint getItem(in unsigned long index)
raises(DOMException);
- [Custom] SVGPoint insertItemBefore(in SVGPoint item, in unsigned long index)
+ [JSCCustom] SVGPoint insertItemBefore(in SVGPoint item, in unsigned long index)
raises(DOMException, SVGException);
- [Custom] SVGPoint replaceItem(in SVGPoint item, in unsigned long index)
+ [JSCCustom] SVGPoint replaceItem(in SVGPoint item, in unsigned long index)
raises(DOMException, SVGException);
- [Custom] SVGPoint removeItem(in unsigned long index)
+ [JSCCustom] SVGPoint removeItem(in unsigned long index)
raises(DOMException);
- [Custom] SVGPoint appendItem(in SVGPoint item)
+ [JSCCustom] SVGPoint appendItem(in SVGPoint item)
raises(DOMException, SVGException);
};
diff --git a/WebCore/svg/SVGPreserveAspectRatio.cpp b/WebCore/svg/SVGPreserveAspectRatio.cpp
index 9c9e110..5793976 100644
--- a/WebCore/svg/SVGPreserveAspectRatio.cpp
+++ b/WebCore/svg/SVGPreserveAspectRatio.cpp
@@ -178,10 +178,10 @@ TransformationMatrix SVGPreserveAspectRatio::getCTM(double logicX, double logicY
double svgar = physWidth / physHeight;
if (align() == SVG_PRESERVEASPECTRATIO_NONE) {
- temp.scale(physWidth / logicWidth, physHeight / logicHeight);
+ temp.scaleNonUniform(physWidth / logicWidth, physHeight / logicHeight);
temp.translate(-logicX, -logicY);
} else if (vpar < svgar && (meetOrSlice() == SVG_MEETORSLICE_MEET) || vpar >= svgar && (meetOrSlice() == SVG_MEETORSLICE_SLICE)) {
- temp.scale(physHeight / logicHeight, physHeight / logicHeight);
+ temp.scaleNonUniform(physHeight / logicHeight, physHeight / logicHeight);
if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX)
temp.translate(-logicX, -logicY);
@@ -190,7 +190,7 @@ TransformationMatrix SVGPreserveAspectRatio::getCTM(double logicX, double logicY
else
temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
} else {
- temp.scale(physWidth / logicWidth, physWidth / logicWidth);
+ temp.scaleNonUniform(physWidth / logicWidth, physWidth / logicWidth);
if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN)
temp.translate(-logicX, -logicY);
diff --git a/WebCore/svg/SVGRadialGradientElement.cpp b/WebCore/svg/SVGRadialGradientElement.cpp
index 4f4fd8f..abc11fb 100644
--- a/WebCore/svg/SVGRadialGradientElement.cpp
+++ b/WebCore/svg/SVGRadialGradientElement.cpp
@@ -114,6 +114,7 @@ void SVGRadialGradientElement::buildGradient() const
0.f, // SVG does not support a "focus radius"
centerPoint,
narrowPrecisionToFloat(attributes.r()));
+ gradient->setSpreadMethod(attributes.spreadMethod());
Vector<SVGGradientStop> stops = attributes.stops();
float previousOffset = 0.0f;
@@ -129,7 +130,6 @@ void SVGRadialGradientElement::buildGradient() const
return;
radialGradient->setBoundingBoxMode(attributes.boundingBoxMode());
- radialGradient->setGradientSpreadMethod(attributes.spreadMethod());
radialGradient->setGradientTransform(attributes.gradientTransform());
radialGradient->setGradientCenter(centerPoint);
radialGradient->setGradientFocal(focalPoint);
diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp
index 27f11aa..e66a16e 100644
--- a/WebCore/svg/SVGSVGElement.cpp
+++ b/WebCore/svg/SVGSVGElement.cpp
@@ -125,8 +125,8 @@ FloatRect SVGSVGElement::viewport() const
TransformationMatrix viewBox = viewBoxToViewTransform(w, h);
double wDouble = w;
double hDouble = h;
- viewBox.map(_x, _y, &_x, &_y);
- viewBox.map(w, h, &wDouble, &hDouble);
+ viewBox.map(_x, _y, _x, _y);
+ viewBox.map(w, h, wDouble, hDouble);
return FloatRect::narrowPrecision(_x, _y, wDouble, hDouble);
}
@@ -387,7 +387,7 @@ TransformationMatrix SVGSVGElement::getCTM() const
if (!isOutermostSVG())
mat.translate(x().value(this), y().value(this));
- if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
+ if (attributes()->getAttributeItem(SVGNames::viewBoxAttr)) {
TransformationMatrix viewBox = viewBoxToViewTransform(width().value(this), height().value(this));
mat = viewBox * mat;
}
@@ -414,7 +414,7 @@ TransformationMatrix SVGSVGElement::getScreenCTM() const
TransformationMatrix mat = SVGStyledLocatableElement::getScreenCTM();
mat.translate(rootLocation.x(), rootLocation.y());
- if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
+ if (attributes()->getAttributeItem(SVGNames::viewBoxAttr)) {
TransformationMatrix viewBox = viewBoxToViewTransform(width().value(this), height().value(this));
mat = viewBox * mat;
}
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 466ce3c..76303a9 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -240,7 +240,7 @@ PassRefPtr<RenderStyle> SVGStyledElement::resolveStyle(RenderStyle* parentStyle)
PassRefPtr<CSSValue> SVGStyledElement::getPresentationAttribute(const String& name)
{
- Attribute* attr = mappedAttributes()->getAttributeItem(name, false);
+ Attribute* attr = mappedAttributes()->getAttributeItem(QualifiedName(nullAtom, name, nullAtom));
if (!attr || !attr->isMappedAttribute() || !attr->style())
return 0;
diff --git a/WebCore/svg/SVGTextContentElement.cpp b/WebCore/svg/SVGTextContentElement.cpp
index 6057da8..8b34c2c 100644
--- a/WebCore/svg/SVGTextContentElement.cpp
+++ b/WebCore/svg/SVGTextContentElement.cpp
@@ -65,7 +65,7 @@ static inline float cumulativeCharacterRangeLength(const Vector<SVGChar>::iterat
return 0.0f;
float textLength = 0.0f;
- RenderStyle* style = textBox->textObject()->style();
+ RenderStyle* style = textBox->textRenderer()->style();
bool usesFullRange = (startPosition == -1 && length == -1);
@@ -128,7 +128,7 @@ struct SVGInlineTextBoxQueryWalker {
void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix&,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
- RenderStyle* style = textBox->textObject()->style();
+ RenderStyle* style = textBox->textRenderer()->style();
bool isVerticalText = style->svgStyle()->writingMode() == WM_TBRL || style->svgStyle()->writingMode() == WM_TB;
switch (m_mode) {
@@ -309,7 +309,7 @@ static Vector<SVGInlineTextBox*> findInlineTextBoxInTextChunks(const SVGTextCont
for (; boxIt != boxEnd; ++boxIt) {
SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(boxIt->box);
- Node* textElement = textBox->textObject()->parent()->element();
+ Node* textElement = textBox->textRenderer()->parent()->node();
ASSERT(textElement);
if (textElement == element || textElement->parent() == element)
@@ -480,7 +480,7 @@ void SVGTextContentElement::selectSubString(long charnum, long nchars, Exception
for (long i = 0; i < nchars; ++i)
end = end.next();
- controller->setSelection(Selection(start, end));
+ controller->setSelection(VisibleSelection(start, end));
}
void SVGTextContentElement::parseMappedAttribute(MappedAttribute* attr)
diff --git a/WebCore/svg/SVGTransform.cpp b/WebCore/svg/SVGTransform.cpp
index fac88bd..17d9b8f 100644
--- a/WebCore/svg/SVGTransform.cpp
+++ b/WebCore/svg/SVGTransform.cpp
@@ -96,7 +96,7 @@ void SVGTransform::setTranslate(float tx, float ty)
m_type = SVG_TRANSFORM_TRANSLATE;
m_angle = 0;
- m_matrix.reset();
+ m_matrix.makeIdentity();
m_matrix.translate(tx, ty);
}
@@ -111,8 +111,8 @@ void SVGTransform::setScale(float sx, float sy)
m_angle = 0;
m_center = FloatPoint();
- m_matrix.reset();
- m_matrix.scale(sx, sy);
+ m_matrix.makeIdentity();
+ m_matrix.scaleNonUniform(sx, sy);
}
FloatSize SVGTransform::scale() const
@@ -127,7 +127,7 @@ void SVGTransform::setRotate(float angle, float cx, float cy)
m_center = FloatPoint(cx, cy);
// TODO: toString() implementation, which can show cx, cy (need to be stored?)
- m_matrix.reset();
+ m_matrix.makeIdentity();
m_matrix.translate(cx, cy);
m_matrix.rotate(angle);
m_matrix.translate(-cx, -cy);
@@ -138,7 +138,7 @@ void SVGTransform::setSkewX(float angle)
m_type = SVG_TRANSFORM_SKEWX;
m_angle = angle;
- m_matrix.reset();
+ m_matrix.makeIdentity();
m_matrix.skewX(angle);
}
@@ -147,7 +147,7 @@ void SVGTransform::setSkewY(float angle)
m_type = SVG_TRANSFORM_SKEWY;
m_angle = angle;
- m_matrix.reset();
+ m_matrix.makeIdentity();
m_matrix.skewY(angle);
}
diff --git a/WebCore/svg/SVGTransformDistance.cpp b/WebCore/svg/SVGTransformDistance.cpp
index b46370b..34adc63 100644
--- a/WebCore/svg/SVGTransformDistance.cpp
+++ b/WebCore/svg/SVGTransformDistance.cpp
@@ -79,7 +79,7 @@ SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform,
{
float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width();
float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height();
- m_transform.scale(scaleX, scaleY);
+ m_transform.scaleNonUniform(scaleX, scaleY);
return;
}
case SVGTransform::SVG_TRANSFORM_SKEWX:
@@ -188,7 +188,7 @@ void SVGTransformDistance::addSVGTransform(const SVGTransform& transform, bool a
{
float scaleX = absoluteValue ? fabsf(transform.scale().width()) : transform.scale().width();
float scaleY = absoluteValue ? fabsf(transform.scale().height()) : transform.scale().height();
- m_transform.scale(scaleX, scaleY);
+ m_transform.scaleNonUniform(scaleX, scaleY);
return;
}
case SVGTransform::SVG_TRANSFORM_SKEWX:
diff --git a/WebCore/svg/SVGTransformList.idl b/WebCore/svg/SVGTransformList.idl
index 67968ff..8c9c86e 100644
--- a/WebCore/svg/SVGTransformList.idl
+++ b/WebCore/svg/SVGTransformList.idl
@@ -29,19 +29,19 @@ module svg {
interface [Conditional=SVG] SVGTransformList {
readonly attribute unsigned long numberOfItems;
- [Custom] void clear()
+ [JSCCustom] void clear()
raises(DOMException);
- [Custom] SVGTransform initialize(in SVGTransform item)
+ [JSCCustom] SVGTransform initialize(in SVGTransform item)
raises(DOMException, SVGException);
- [Custom] SVGTransform getItem(in unsigned long index)
+ [JSCCustom] SVGTransform getItem(in unsigned long index)
raises(DOMException);
- [Custom] SVGTransform insertItemBefore(in SVGTransform item, in unsigned long index)
+ [JSCCustom] SVGTransform insertItemBefore(in SVGTransform item, in unsigned long index)
raises(DOMException, SVGException);
- [Custom] SVGTransform replaceItem(in SVGTransform item, in unsigned long index)
+ [JSCCustom] SVGTransform replaceItem(in SVGTransform item, in unsigned long index)
raises(DOMException, SVGException);
- [Custom] SVGTransform removeItem(in unsigned long index)
+ [JSCCustom] SVGTransform removeItem(in unsigned long index)
raises(DOMException);
- [Custom] SVGTransform appendItem(in SVGTransform item)
+ [JSCCustom] SVGTransform appendItem(in SVGTransform item)
raises(DOMException, SVGException);
SVGTransform createSVGTransformFromMatrix(in SVGMatrix matrix);
SVGTransform consolidate();
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 4eb2d9f..4ae0f5c 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -564,10 +564,10 @@ void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targ
if (isDisallowedElement(target))
return;
- RefPtr<Node> newChild = targetInstance->correspondingElement()->cloneNode(true);
+ RefPtr<Element> newChild = targetInstance->correspondingElement()->cloneElementWithChildren();
// We don't walk the target tree element-by-element, and clone each element,
- // but instead use cloneNode(deep=true). This is an optimization for the common
+ // but instead use cloneElementWithChildren(). This is an optimization for the common
// case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
// Though if there are disallowed elements in the subtree, we have to remove them.
// For instance: <use> on <g> containing <foreignObject> (indirect case).
@@ -643,10 +643,10 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
return;
}
- RefPtr<Node> newChild = target->cloneNode(true);
+ RefPtr<Element> newChild = target->cloneElementWithChildren();
// We don't walk the target tree element-by-element, and clone each element,
- // but instead use cloneNode(deep=true). This is an optimization for the common
+ // but instead use cloneElementWithChildren(). This is an optimization for the common
// case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
// Though if there are disallowed elements in the subtree, we have to remove them.
// For instance: <use> on <g> containing <foreignObject> (indirect case).
diff --git a/WebCore/svg/graphics/SVGImage.cpp b/WebCore/svg/graphics/SVGImage.cpp
index d315dfa..067f645 100644
--- a/WebCore/svg/graphics/SVGImage.cpp
+++ b/WebCore/svg/graphics/SVGImage.cpp
@@ -103,7 +103,7 @@ void SVGImage::setContainerSize(const IntSize& containerSize)
if (containerSize.width() <= 0 || containerSize.height() <= 0)
return;
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return;
SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
if (!rootElement)
@@ -114,7 +114,7 @@ void SVGImage::setContainerSize(const IntSize& containerSize)
bool SVGImage::usesContainerSize() const
{
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return false;
SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
if (!rootElement)
@@ -125,7 +125,7 @@ bool SVGImage::usesContainerSize() const
IntSize SVGImage::size() const
{
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return IntSize();
SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
@@ -151,7 +151,7 @@ IntSize SVGImage::size() const
bool SVGImage::hasRelativeWidth() const
{
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return false;
SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
if (!rootElement)
@@ -162,7 +162,7 @@ bool SVGImage::hasRelativeWidth() const
bool SVGImage::hasRelativeHeight() const
{
- if (!m_frame || !m_frame->document())
+ if (!m_frame)
return false;
SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement();
if (!rootElement)
diff --git a/WebCore/svg/graphics/SVGPaintServer.cpp b/WebCore/svg/graphics/SVGPaintServer.cpp
index 4e7a8cf..0fcd722 100644
--- a/WebCore/svg/graphics/SVGPaintServer.cpp
+++ b/WebCore/svg/graphics/SVGPaintServer.cpp
@@ -37,6 +37,10 @@
#include "SVGStyledElement.h"
#include "SVGURIReference.h"
+#if PLATFORM(SKIA)
+#include "PlatformContextSkia.h"
+#endif
+
namespace WebCore {
SVGPaintServer::SVGPaintServer()
@@ -82,7 +86,7 @@ SVGPaintServer* SVGPaintServer::fillPaintServer(const RenderStyle* style, const
AtomicString id(SVGURIReference::getTarget(fill->uri()));
fillPaintServer = getPaintServerById(item->document(), id);
- SVGElement* svgElement = static_cast<SVGElement*>(item->element());
+ SVGElement* svgElement = static_cast<SVGElement*>(item->node());
ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
if (item->isRenderPath() && fillPaintServer)
@@ -123,7 +127,7 @@ SVGPaintServer* SVGPaintServer::strokePaintServer(const RenderStyle* style, cons
AtomicString id(SVGURIReference::getTarget(stroke->uri()));
strokePaintServer = getPaintServerById(item->document(), id);
- SVGElement* svgElement = static_cast<SVGElement*>(item->element());
+ SVGElement* svgElement = static_cast<SVGElement*>(item->node());
ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
if (item->isRenderPath() && strokePaintServer)
@@ -179,9 +183,9 @@ void SVGPaintServer::renderPath(GraphicsContext*& context, const RenderObject* p
context->strokePath();
}
-void SVGPaintServer::teardown(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool) const
-{
#if PLATFORM(SKIA)
+void SVGPaintServer::teardown(GraphicsContext*& context, const RenderObject*, SVGPaintTargetType, bool) const
+{
// FIXME: Move this into the GraphicsContext
// WebKit implicitly expects us to reset the path.
// For example in fillAndStrokePath() of RenderPath.cpp the path is
@@ -190,8 +194,12 @@ void SVGPaintServer::teardown(GraphicsContext*&, const RenderObject*, SVGPaintTa
context->beginPath();
context->platformContext()->setGradient(0);
context->platformContext()->setPattern(0);
-#endif
}
+#else
+void SVGPaintServer::teardown(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool) const
+{
+}
+#endif
DashArray dashArrayFromRenderingStyle(const RenderStyle* style)
{
diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.cpp b/WebCore/svg/graphics/SVGPaintServerGradient.cpp
index b06eca1..eb0d80b 100644
--- a/WebCore/svg/graphics/SVGPaintServerGradient.cpp
+++ b/WebCore/svg/graphics/SVGPaintServerGradient.cpp
@@ -40,11 +40,6 @@
#include "SVGRenderSupport.h"
#include "SVGRenderTreeAsText.h"
-#if PLATFORM(CG)
-#include <wtf/MathExtras.h>
-#include <wtf/RetainPtr.h>
-#endif
-
using namespace std;
namespace WebCore {
@@ -76,10 +71,8 @@ static TextStream& operator<<(TextStream& ts, const Vector<SVGGradientStop>& l)
}
SVGPaintServerGradient::SVGPaintServerGradient(const SVGGradientElement* owner)
- : m_spreadMethod(SpreadMethodPad)
- , m_boundingBoxMode(true)
+ : m_boundingBoxMode(true)
, m_ownerElement(owner)
-
#if PLATFORM(CG)
, m_savedContext(0)
, m_imageBuffer(0)
@@ -102,16 +95,6 @@ void SVGPaintServerGradient::setGradient(PassRefPtr<Gradient> gradient)
m_gradient = gradient;
}
-GradientSpreadMethod SVGPaintServerGradient::spreadMethod() const
-{
- return m_spreadMethod;
-}
-
-void SVGPaintServerGradient::setGradientSpreadMethod(const GradientSpreadMethod& method)
-{
- m_spreadMethod = method;
-}
-
bool SVGPaintServerGradient::boundingBoxMode() const
{
return m_boundingBoxMode;
@@ -133,8 +116,6 @@ void SVGPaintServerGradient::setGradientTransform(const TransformationMatrix& tr
}
#if PLATFORM(CG)
-// Helper function for text painting in CG
-// This Cg specific code should move to GraphicsContext and Font* in a next step.
static inline const RenderObject* findTextRootObject(const RenderObject* start)
{
while (start && !start->isSVGText())
@@ -174,7 +155,7 @@ static inline bool createMaskAndSwapContextForTextGradient(
return true;
}
-static inline void clipToTextMask(GraphicsContext* context,
+static inline TransformationMatrix clipToTextMask(GraphicsContext* context,
OwnPtr<ImageBuffer>& imageBuffer, const RenderObject* object,
const SVGPaintServerGradient* gradientServer)
{
@@ -193,11 +174,13 @@ static inline void clipToTextMask(GraphicsContext* context,
context->clipToImageBuffer(textBoundary, imageBuffer.get());
context->concatCTM(transform);
+ TransformationMatrix matrix;
if (gradientServer->boundingBoxMode()) {
- context->translate(maskBBox.x(), maskBBox.y());
- context->scale(FloatSize(maskBBox.width(), maskBBox.height()));
+ matrix.translate(maskBBox.x(), maskBBox.y());
+ matrix.scaleNonUniform(maskBBox.width(), maskBBox.height());
}
- context->concatCTM(gradientServer->gradientTransform());
+ matrix.multiply(gradientServer->gradientTransform());
+ return matrix;
}
#endif
@@ -234,25 +217,29 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject
applyStrokeStyleToContext(context, object->style(), object);
}
+ TransformationMatrix matrix;
+ // CG platforms will handle the gradient space transform for text in
+ // teardown, so we don't apply it here. For non-CG platforms, we
+ // want the text bounding box applied to the gradient space transform now,
+ // so the gradient shader can use it.
+#if PLATFORM(CG)
if (boundingBoxMode() && !isPaintingText) {
+#else
+ if (boundingBoxMode()) {
+#endif
FloatRect bbox = object->relativeBBox(false);
- // Don't use gradientes for 1d objects like horizontal/vertical
+ // Don't use gradients for 1d objects like horizontal/vertical
// lines or rectangles without width or height.
if (bbox.width() == 0 || bbox.height() == 0) {
Color color(0, 0, 0);
context->setStrokeColor(color);
return true;
}
- context->translate(bbox.x(), bbox.y());
- context->scale(FloatSize(bbox.width(), bbox.height()));
-
- // With scaling the context, the strokeThickness is scaled too. We have to
- // undo this.
- float strokeThickness = std::max((context->strokeThickness() / ((bbox.width() + bbox.height()) / 2) - 0.001f), 0.f);
- context->setStrokeThickness(strokeThickness);
+ matrix.translate(bbox.x(), bbox.y());
+ matrix.scaleNonUniform(bbox.width(), bbox.height());
}
- context->concatCTM(gradientTransform());
- context->setSpreadMethod(spreadMethod());
+ matrix.multiply(gradientTransform());
+ m_gradient->setGradientSpaceTransform(matrix);
return true;
}
@@ -262,15 +249,19 @@ void SVGPaintServerGradient::teardown(GraphicsContext*& context, const RenderObj
#if PLATFORM(CG)
// renderPath() is not used when painting text, so we paint the gradient during teardown()
if (isPaintingText && m_savedContext) {
+
// Restore on-screen drawing context
context = m_savedContext;
m_savedContext = 0;
- clipToTextMask(context, m_imageBuffer, object, this);
+ TransformationMatrix matrix = clipToTextMask(context, m_imageBuffer, object, this);
+ m_gradient->setGradientSpaceTransform(matrix);
+ context->setFillGradient(m_gradient);
+
+ FloatRect maskBBox = const_cast<RenderObject*>(findTextRootObject(object))->relativeBBox(false);
+
+ context->fillRect(maskBBox);
- // finally fill the text clip with the shading
- CGContextDrawShading(context->platformContext(), m_gradient->platformGradient());
-
m_imageBuffer.clear(); // we're done with our text mask buffer
}
#endif
@@ -284,8 +275,8 @@ TextStream& SVGPaintServerGradient::externalRepresentation(TextStream& ts) const
// abstract, don't stream type
ts << "[stops=" << gradientStops() << "]";
- if (spreadMethod() != SpreadMethodPad)
- ts << "[method=" << spreadMethod() << "]";
+ if (m_gradient->spreadMethod() != SpreadMethodPad)
+ ts << "[method=" << m_gradient->spreadMethod() << "]";
if (!boundingBoxMode())
ts << " [bounding box mode=" << boundingBoxMode() << "]";
if (!gradientTransform().isIdentity())
diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.h b/WebCore/svg/graphics/SVGPaintServerGradient.h
index 16dab0b..b24c417 100644
--- a/WebCore/svg/graphics/SVGPaintServerGradient.h
+++ b/WebCore/svg/graphics/SVGPaintServerGradient.h
@@ -52,9 +52,6 @@ namespace WebCore {
void setGradient(PassRefPtr<Gradient>);
Gradient* gradient() const;
- GradientSpreadMethod spreadMethod() const;
- void setGradientSpreadMethod(const GradientSpreadMethod&);
-
// Gradient start and end points are percentages when used in boundingBox mode.
// For instance start point with value (0,0) is top-left and end point with
// value (100, 100) is bottom-right. BoundingBox mode is enabled by default.
@@ -78,7 +75,6 @@ namespace WebCore {
private:
Vector<SVGGradientStop> m_stops;
RefPtr<Gradient> m_gradient;
- GradientSpreadMethod m_spreadMethod;
bool m_boundingBoxMode;
TransformationMatrix m_gradientTransform;
const SVGGradientElement* m_ownerElement;
diff --git a/WebCore/svg/graphics/SVGPaintServerPattern.cpp b/WebCore/svg/graphics/SVGPaintServerPattern.cpp
index 5926aad..a2ac5df 100644
--- a/WebCore/svg/graphics/SVGPaintServerPattern.cpp
+++ b/WebCore/svg/graphics/SVGPaintServerPattern.cpp
@@ -115,8 +115,6 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject*
return false;
context->save();
- context->translate(patternBoundaries().x(), patternBoundaries().y());
- context->concatCTM(patternTransform());
ASSERT(!m_pattern);
@@ -160,6 +158,11 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject*
applyStrokeStyleToContext(context, object->style(), object);
}
+ TransformationMatrix matrix;
+ matrix.translate(patternBoundaries().x(), patternBoundaries().y());
+ matrix.multiply(patternTransform());
+ m_pattern->setPatternSpaceTransform(matrix);
+
if (isPaintingText) {
context->setTextDrawingMode(isFilled ? cTextFill : cTextStroke);
#if PLATFORM(CG)
diff --git a/WebCore/svg/graphics/SVGResourceClipper.cpp b/WebCore/svg/graphics/SVGResourceClipper.cpp
index 51bda0d..5998afb 100644
--- a/WebCore/svg/graphics/SVGResourceClipper.cpp
+++ b/WebCore/svg/graphics/SVGResourceClipper.cpp
@@ -72,7 +72,7 @@ void SVGResourceClipper::applyClip(GraphicsContext* context, const FloatRect& bo
if (clipData.bboxUnits) {
TransformationMatrix transform;
transform.translate(boundingBox.x(), boundingBox.y());
- transform.scale(boundingBox.width(), boundingBox.height());
+ transform.scaleNonUniform(boundingBox.width(), boundingBox.height());
clipPath.transform(transform);
}
context->addPath(clipPath);
diff --git a/WebCore/svg/graphics/SVGResourceMarker.cpp b/WebCore/svg/graphics/SVGResourceMarker.cpp
index c50f5e3..112e4d6 100644
--- a/WebCore/svg/graphics/SVGResourceMarker.cpp
+++ b/WebCore/svg/graphics/SVGResourceMarker.cpp
@@ -82,14 +82,14 @@ void SVGResourceMarker::draw(GraphicsContext* context, const FloatRect& rect, do
// the translation performed on the viewport itself.
TransformationMatrix viewportTransform;
if (m_useStrokeWidth)
- viewportTransform.scale(strokeWidth, strokeWidth);
+ viewportTransform.scaleNonUniform(strokeWidth, strokeWidth);
viewportTransform *= m_marker->viewportTransform();
double refX, refY;
- viewportTransform.map(m_refX, m_refY, &refX, &refY);
+ viewportTransform.map(m_refX, m_refY, refX, refY);
transform.translate(-refX, -refY);
if (m_useStrokeWidth)
- transform.scale(strokeWidth, strokeWidth);
+ transform.scaleNonUniform(strokeWidth, strokeWidth);
// FIXME: PaintInfo should be passed into this method instead of being created here
// FIXME: bounding box fractions are lost
diff --git a/WebCore/svg/graphics/SVGResourceMasker.cpp b/WebCore/svg/graphics/SVGResourceMasker.cpp
index 842f04f..8642e1e 100644
--- a/WebCore/svg/graphics/SVGResourceMasker.cpp
+++ b/WebCore/svg/graphics/SVGResourceMasker.cpp
@@ -28,9 +28,18 @@
#if ENABLE(SVG)
#include "SVGResourceMasker.h"
+#include "CanvasPixelArray.h"
+#include "Image.h"
#include "ImageBuffer.h"
+#include "ImageData.h"
+#include "GraphicsContext.h"
+#include "SVGMaskElement.h"
+#include "SVGRenderSupport.h"
+#include "SVGRenderStyle.h"
#include "TextStream.h"
+#include <wtf/ByteArray.h>
+
using namespace std;
namespace WebCore {
@@ -51,6 +60,44 @@ void SVGResourceMasker::invalidate()
m_mask.clear();
}
+void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox)
+{
+ if (!m_mask)
+ m_mask.set(m_ownerElement->drawMaskerContent(boundingBox, m_maskRect).release());
+
+ if (!m_mask)
+ return;
+
+ IntSize imageSize(m_mask->size());
+ IntRect intImageRect(0, 0, imageSize.width(), imageSize.height());
+
+ // Create new ImageBuffer to apply luminance
+ auto_ptr<ImageBuffer> luminancedImage(ImageBuffer::create(imageSize, false));
+ if (!luminancedImage.get())
+ return;
+
+ PassRefPtr<CanvasPixelArray> srcPixelArray(m_mask->getImageData(intImageRect)->data());
+ PassRefPtr<ImageData> destImageData(luminancedImage->getImageData(intImageRect));
+
+ for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset++) {
+ unsigned pixelByteOffset = pixelOffset * 4;
+
+ unsigned char r = 0, g = 0, b = 0, a = 0;
+ srcPixelArray->get(pixelByteOffset, r);
+ srcPixelArray->get(pixelByteOffset + 1, g);
+ srcPixelArray->get(pixelByteOffset + 2, b);
+ srcPixelArray->get(pixelByteOffset + 3, a);
+
+ double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
+
+ destImageData->data()->set(pixelByteOffset + 3, luma);
+ }
+
+ luminancedImage->putImageData(destImageData.get(), intImageRect, IntPoint(0, 0));
+
+ context->clipToImageBuffer(m_maskRect, luminancedImage.get());
+}
+
TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const
{
ts << "[type=MASKER]";
diff --git a/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp b/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp
deleted file mode 100644
index 1f690b5..0000000
--- a/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 Alp Toker <alp@atoker.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#if ENABLE(SVG)
-#include "SVGResourceMasker.h"
-#include "Image.h"
-#include "ImageBuffer.h"
-#include "GraphicsContext.h"
-
-#include <cairo.h>
-
-namespace WebCore {
-
-void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox)
-{
- if (!m_mask)
- return;
-
- cairo_t* cr = context->platformContext();
- cairo_surface_t* surface = m_mask->image()->nativeImageForCurrentFrame();
- if (!surface)
- return;
- cairo_pattern_t* mask = cairo_pattern_create_for_surface(surface);
- cairo_mask(cr, mask);
- cairo_pattern_destroy(mask);
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm b/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm
deleted file mode 100644
index 9793ba0..0000000
--- a/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2005, 2006 Alexander Kellett <lypanov@kde.org>
- * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(SVG)
-#import "SVGResourceMasker.h"
-
-#import "BlockExceptions.h"
-#import "GraphicsContext.h"
-#import "ImageBuffer.h"
-#import "SVGMaskElement.h"
-#import "SVGRenderSupport.h"
-#import "SVGRenderStyle.h"
-#import "SVGResourceFilter.h"
-#import <QuartzCore/CIFilter.h>
-#import <QuartzCore/CoreImage.h>
-
-using namespace std;
-
-namespace WebCore {
-
-static CIImage* applyLuminanceToAlphaFilter(CIImage* inputImage)
-{
- CIFilter* luminanceToAlpha = [CIFilter filterWithName:@"CIColorMatrix"];
- [luminanceToAlpha setDefaults];
- CGFloat alpha[4] = {0.2125f, 0.7154f, 0.0721f, 0.0f};
- CGFloat zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- [luminanceToAlpha setValue:inputImage forKey:@"inputImage"];
- [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputRVector"];
- [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputGVector"];
- [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBVector"];
- [luminanceToAlpha setValue:[CIVector vectorWithValues:alpha count:4] forKey:@"inputAVector"];
- [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBiasVector"];
- return [luminanceToAlpha valueForKey:@"outputImage"];
-}
-
-static CIImage* applyExpandAlphatoGrayscaleFilter(CIImage* inputImage)
-{
- CIFilter* alphaToGrayscale = [CIFilter filterWithName:@"CIColorMatrix"];
- CGFloat zero[4] = {0, 0, 0, 0};
- [alphaToGrayscale setDefaults];
- [alphaToGrayscale setValue:inputImage forKey:@"inputImage"];
- [alphaToGrayscale setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputRVector"];
- [alphaToGrayscale setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputGVector"];
- [alphaToGrayscale setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBVector"];
- [alphaToGrayscale setValue:[CIVector vectorWithX:0.0f Y:0.0f Z:0.0f W:1.0f] forKey:@"inputAVector"];
- [alphaToGrayscale setValue:[CIVector vectorWithX:1.0f Y:1.0f Z:1.0f W:0.0f] forKey:@"inputBiasVector"];
- return [alphaToGrayscale valueForKey:@"outputImage"];
-}
-
-static CIImage* transformImageIntoGrayscaleMask(CIImage* inputImage)
-{
- CIFilter* blackBackground = [CIFilter filterWithName:@"CIConstantColorGenerator"];
- [blackBackground setValue:[CIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f] forKey:@"inputColor"];
-
- CIFilter* layerOverBlack = [CIFilter filterWithName:@"CISourceOverCompositing"];
- [layerOverBlack setValue:[blackBackground valueForKey:@"outputImage"] forKey:@"inputBackgroundImage"];
- [layerOverBlack setValue:inputImage forKey:@"inputImage"];
-
- CIImage* luminanceAlpha = applyLuminanceToAlphaFilter([layerOverBlack valueForKey:@"outputImage"]);
- CIImage* luminanceAsGrayscale = applyExpandAlphatoGrayscaleFilter(luminanceAlpha);
- CIImage* alphaAsGrayscale = applyExpandAlphatoGrayscaleFilter(inputImage);
-
- CIFilter* multipliedGrayscale = [CIFilter filterWithName:@"CIMultiplyCompositing"];
- [multipliedGrayscale setValue:luminanceAsGrayscale forKey:@"inputBackgroundImage"];
- [multipliedGrayscale setValue:alphaAsGrayscale forKey:@"inputImage"];
- return [multipliedGrayscale valueForKey:@"outputImage"];
-}
-
-void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox)
-{
- if (!m_mask)
- m_mask.set(m_ownerElement->drawMaskerContent(boundingBox, m_maskRect).release());
-
- if (!m_mask)
- return;
-
- IntSize maskSize(static_cast<int>(m_maskRect.width()), static_cast<int>(m_maskRect.height()));
- clampImageBufferSizeToViewport(m_ownerElement->document()->renderer(), maskSize);
-
- // Create new graphics context in gray scale mode for image rendering
- auto_ptr<ImageBuffer> grayScaleImage(ImageBuffer::create(maskSize, true));
- if (!grayScaleImage.get())
- return;
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS
- CGContextRef grayScaleContext = grayScaleImage->context()->platformContext();
- CIContext* ciGrayscaleContext = [CIContext contextWithCGContext:grayScaleContext options:nil];
-
- // Transform colorized mask to gray scale
- CIImage* colorMask = [CIImage imageWithCGImage:m_mask->image()->getCGImageRef()];
- if (!colorMask)
- return;
-
- CIImage* grayScaleMask = transformImageIntoGrayscaleMask(colorMask);
- [ciGrayscaleContext drawImage:grayScaleMask atPoint:CGPointZero fromRect:CGRectMake(0, 0, maskSize.width(), maskSize.height())];
-
- CGContextClipToMask(context->platformContext(), m_maskRect, grayScaleImage->image()->getCGImageRef());
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(SVG)
diff --git a/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm
index 0f2eb75..399d4c1 100644
--- a/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm
+++ b/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm
@@ -59,7 +59,7 @@ CIVector* getVectorForChannel(ChannelSelectorType channel)
CIColor* ciColor(const Color& c)
{
- CGColorRef colorCG = cgColor(c);
+ CGColorRef colorCG = createCGColor(c);
CIColor* colorCI = [CIColor colorWithCGColor:colorCG];
CGColorRelease(colorCG);
return colorCI;
diff --git a/WebCore/svg/graphics/qt/SVGResourceMaskerQt.cpp b/WebCore/svg/graphics/qt/SVGResourceMaskerQt.cpp
deleted file mode 100644
index 2b89bac..0000000
--- a/WebCore/svg/graphics/qt/SVGResourceMaskerQt.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- Copyright (C) 2006 Nikolas Zimmermann <wildfox@kde.org>
-
- This file is part of the KDE project
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-
-#if ENABLE(SVG)
-#include "SVGResourceMasker.h"
-
-namespace WebCore {
-
-void SVGResourceMasker::applyMask(GraphicsContext*, const FloatRect&)
-{
- // FIXME: implement me :-)
-}
-
-} // namespace WebCore
-
-#endif
-
-// vim:ts=4:noet
diff --git a/WebCore/webcore-base.bkl b/WebCore/webcore-base.bkl
index 88d917f..f6095e5 100644
--- a/WebCore/webcore-base.bkl
+++ b/WebCore/webcore-base.bkl
@@ -67,6 +67,7 @@ wxWebCore port Bakefile project file.
<include>$(SRCDIR)/bridge/c</include>
<include>$(SRCDIR)/bridge/jni</include>
<include>$(SRCDIR)/css</include>
+ <include>$(SRCDIR)/DerivedSources/WebCore</include>
<include>$(SRCDIR)/dom</include>
<include>$(SRCDIR)/editing</include>
<include>$(SRCDIR)/history</include>
@@ -99,11 +100,8 @@ wxWebCore port Bakefile project file.
<include>$(SRCDIR)/rendering</include>
<include>$(SRCDIR)/rendering/style</include>
<include>$(SRCDIR)/storage</include>
+ <include>$(SRCDIR)/workers</include>
<include>$(SRCDIR)/xml</include>
- <!-- FIXME: this is below the other headers because there currently exists both
- WebCore/DerivedSources/HTMLElementFactory.h and WebCore/html/HTMLElementFactory.h
- and the latter is the one WebCore/dom/Document.cpp needs to compile. -->
- <include>$(SRCDIR)/DerivedSources/WebCore</include>
<include>$(WK_ROOT)</include>
<include>$(WK_ROOT)/JavaScriptCore</include>
<include>$(WK_ROOT)/JavaScriptCore/ForwardingHeaders</include>
diff --git a/WebCore/webcore-wx.bkl b/WebCore/webcore-wx.bkl
index 3ba06c2..09431ce 100644
--- a/WebCore/webcore-wx.bkl
+++ b/WebCore/webcore-wx.bkl
@@ -98,9 +98,9 @@ wxWebCore port Bakefile project file.
platform/network/curl/ResourceHandleCurl.cpp
platform/network/curl/ResourceHandleManager.cpp
- plugins/wx/PluginDataWx.cpp
- plugins/wx/PluginPackageWx.cpp
- plugins/wx/PluginViewWx.cpp
+ plugins/PluginDataNone.cpp
+ plugins/PluginPackageNone.cpp
+ plugins/PluginViewNone.cpp
</sources>
<!-- platform-dependent source files -->
@@ -110,7 +110,7 @@ wxWebCore port Bakefile project file.
platform/wx/wxcode/gtk/non-kerned-drawing.cpp
platform/wx/SharedTimerWx.cpp
</if>
- <if cond="WX_PORT=='mac'">
+ <if cond="PLATFORM_OS=='mac'">
platform/mac/PurgeableBufferMac.cpp
platform/wx/wxcode/mac/carbon/fontprops.cpp
platform/wx/wxcode/mac/carbon/non-kerned-drawing.cpp
diff --git a/WebCore/wml/WMLAElement.cpp b/WebCore/wml/WMLAElement.cpp
index 795c1fd..758be78 100644
--- a/WebCore/wml/WMLAElement.cpp
+++ b/WebCore/wml/WMLAElement.cpp
@@ -38,7 +38,7 @@
#include "HTMLNames.h"
#include "KeyboardEvent.h"
#include "MouseEvent.h"
-#include "RenderFlow.h"
+#include "RenderBox.h"
#include "WMLNames.h"
namespace WebCore {
@@ -101,15 +101,14 @@ bool WMLAElement::isKeyboardFocusable(KeyboardEvent* event) const
if (!document()->frame()->eventHandler()->tabsToLinks(event))
return false;
+ if (!renderer() || !renderer()->isBoxModelObject())
+ return false;
+
// Before calling absoluteRects, check for the common case where the renderer
- // or one of the continuations is non-empty, since this is a faster check and
- // almost always returns true.
- RenderBox* box = toRenderBox(renderer());
+ // is non-empty, since this is a faster check and almost always returns true.
+ RenderBoxModelObject* box = toRenderBoxModelObject(renderer());
if (!box->borderBoundingBox().isEmpty())
return true;
- for (RenderFlow* r = box->virtualContinuation(); r; r = r->continuation())
- if (!r->borderBoundingBox().isEmpty())
- return true;
Vector<IntRect> rects;
FloatPoint absPos = renderer()->localToAbsolute();
@@ -151,7 +150,7 @@ void WMLAElement::defaultEventHandler(Event* event)
if (!event->defaultPrevented() && document()->frame()) {
KURL url = document()->completeURL(parseURL(getAttribute(HTMLNames::hrefAttr)));
- document()->frame()->loader()->urlSelected(url, target(), event, false, true);
+ document()->frame()->loader()->urlSelected(url, target(), event, false, false, true);
}
event->setDefaultHandled();
diff --git a/WebCore/wml/WMLFormControlElement.cpp b/WebCore/wml/WMLFormControlElement.cpp
index 15c3f68..4e76cb8 100644
--- a/WebCore/wml/WMLFormControlElement.cpp
+++ b/WebCore/wml/WMLFormControlElement.cpp
@@ -23,6 +23,10 @@
#if ENABLE(WML)
#include "WMLFormControlElement.h"
+#include "RenderBox.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+
namespace WebCore {
// WMLFormControlElement
@@ -36,6 +40,22 @@ WMLFormControlElement::~WMLFormControlElement()
{
}
+bool WMLFormControlElement::isFocusable() const
+{
+ if (!renderer() || !renderer()->isBox())
+ return false;
+
+ if (toRenderBox(renderer())->size().isEmpty())
+ return false;
+
+ if (RenderStyle* style = renderer()->style()) {
+ if (style->visibility() != VISIBLE)
+ return false;
+ }
+
+ return true;
+}
+
// WMLFormControlElementWithState
WMLFormControlElementWithState::WMLFormControlElementWithState(const QualifiedName& tagName, Document* document)
: WMLFormControlElement(tagName, document)
diff --git a/WebCore/wml/WMLFormControlElement.h b/WebCore/wml/WMLFormControlElement.h
index 8afb676..449e512 100644
--- a/WebCore/wml/WMLFormControlElement.h
+++ b/WebCore/wml/WMLFormControlElement.h
@@ -33,13 +33,18 @@ public:
WMLFormControlElement(const QualifiedName& tagName, Document* document);
virtual ~WMLFormControlElement();
+ virtual bool isEnabled() const { return true; }
virtual bool isFormControlElement() const { return true; }
+ virtual bool isReadOnlyControl() const { return false; }
+ virtual bool isTextControl() const { return false; }
virtual bool valueMatchesRenderer() const { return m_valueMatchesRenderer; }
virtual void setValueMatchesRenderer(bool b = true) { m_valueMatchesRenderer = b; }
virtual const AtomicString& name() const { return emptyAtom; }
+ virtual bool isFocusable() const;
+
private:
bool m_valueMatchesRenderer;
};
diff --git a/WebCore/wml/WMLGoElement.cpp b/WebCore/wml/WMLGoElement.cpp
index 3e5c8bd..603a71d 100644
--- a/WebCore/wml/WMLGoElement.cpp
+++ b/WebCore/wml/WMLGoElement.cpp
@@ -131,7 +131,7 @@ void WMLGoElement::executeTask(Event*)
request.setCachePolicy(ReloadIgnoringCacheData);
}
- loader->load(request);
+ loader->load(request, false);
}
void WMLGoElement::preparePOSTRequest(ResourceRequest& request, bool inSameDeck, const String& cacheControl)
diff --git a/WebCore/wml/WMLImageElement.cpp b/WebCore/wml/WMLImageElement.cpp
index 05ed9a0..39d103d 100644
--- a/WebCore/wml/WMLImageElement.cpp
+++ b/WebCore/wml/WMLImageElement.cpp
@@ -70,7 +70,7 @@ void WMLImageElement::parseMappedAttribute(MappedAttribute* attr)
if (attrName == HTMLNames::altAttr) {
if (renderer() && renderer()->isImage())
- static_cast<RenderImage*>(renderer())->updateAltText();
+ toRenderImage(renderer())->updateAltText();
} else if (attrName == HTMLNames::srcAttr || attrName == localsrcAttr)
m_imageLoader.updateFromElementIgnoringPreviousError();
else if (attrName == HTMLNames::widthAttr)
@@ -94,7 +94,7 @@ void WMLImageElement::attach()
WMLElement::attach();
if (renderer() && renderer()->isImage()) {
- RenderImage* imageObj = static_cast<RenderImage*>(renderer());
+ RenderImage* imageObj = toRenderImage(renderer());
if (imageObj->hasImage())
return;
diff --git a/WebCore/wml/WMLImageLoader.cpp b/WebCore/wml/WMLImageLoader.cpp
index a1a020d..c77b511 100644
--- a/WebCore/wml/WMLImageLoader.cpp
+++ b/WebCore/wml/WMLImageLoader.cpp
@@ -45,10 +45,6 @@ WMLImageLoader::~WMLImageLoader()
void WMLImageLoader::dispatchLoadEvent()
{
// WML doesn't fire any events.
- if (haveFiredLoadEvent())
- return;
-
- setHaveFiredLoadEvent(true);
}
String WMLImageLoader::sourceURI(const AtomicString& attr) const
diff --git a/WebCore/wml/WMLInputElement.cpp b/WebCore/wml/WMLInputElement.cpp
index 05da2a7..9a44013 100644
--- a/WebCore/wml/WMLInputElement.cpp
+++ b/WebCore/wml/WMLInputElement.cpp
@@ -23,7 +23,6 @@
#if ENABLE(WML)
#include "WMLInputElement.h"
-#include "Document.h"
#include "EventNames.h"
#include "FormDataList.h"
#include "Frame.h"
@@ -31,6 +30,9 @@
#include "KeyboardEvent.h"
#include "RenderTextControlSingleLine.h"
#include "TextEvent.h"
+#include "WMLDocument.h"
+#include "WMLNames.h"
+#include "WMLPageState.h"
namespace WebCore {
@@ -38,6 +40,8 @@ WMLInputElement::WMLInputElement(const QualifiedName& tagName, Document* doc)
: WMLFormControlElementWithState(tagName, doc)
, m_data(this, this)
, m_isPasswordField(false)
+ , m_isEmptyOk(false)
+ , m_numOfCharsAllowedByMask(0)
{
}
@@ -47,30 +51,20 @@ WMLInputElement::~WMLInputElement()
document()->unregisterForDocumentActivationCallbacks(this);
}
-static inline bool isInputFocusable(RenderObject* renderer)
+static const AtomicString& formatCodes()
{
- if (!renderer || !renderer->isBox())
- return false;
-
- if (toRenderBox(renderer)->size().isEmpty())
- return false;
-
- if (RenderStyle* style = renderer->style()) {
- if (style->visibility() != VISIBLE)
- return false;
- }
-
- return true;
+ DEFINE_STATIC_LOCAL(AtomicString, codes, ("AaNnXxMm"));
+ return codes;
}
bool WMLInputElement::isKeyboardFocusable(KeyboardEvent*) const
{
- return isInputFocusable(renderer());
+ return WMLFormControlElementWithState::isFocusable();
}
bool WMLInputElement::isMouseFocusable() const
{
- return isInputFocusable(renderer());
+ return WMLFormControlElementWithState::isFocusable();
}
void WMLInputElement::dispatchFocusEvent()
@@ -81,6 +75,18 @@ void WMLInputElement::dispatchFocusEvent()
void WMLInputElement::dispatchBlurEvent()
{
+ // Firstly check if it is allowed to leave this input field
+ String val = value();
+ if ((!m_isEmptyOk && val.isEmpty()) || !isConformedToInputMask(val)) {
+ updateFocusAppearance(true);
+ return;
+ }
+
+ // update the name variable of WML input elmenet
+ String nameVariable = name();
+ if (!nameVariable.isEmpty())
+ wmlPageStateForDocument(document())->storeVariable(nameVariable, val);
+
InputElement::dispatchBlurEvent(m_data, document());
WMLElement::dispatchBlurEvent();
}
@@ -168,7 +174,7 @@ void WMLInputElement::restoreState(const String& state)
void WMLInputElement::select()
{
- if (RenderTextControl* r = static_cast<RenderTextControl*>(renderer()))
+ if (RenderTextControl* r = toRenderTextControl(renderer()))
r->select();
}
@@ -194,12 +200,14 @@ void WMLInputElement::parseMappedAttribute(MappedAttribute* attr)
InputElement::parseMaxLengthAttribute(m_data, attr);
else if (attr->name() == HTMLNames::sizeAttr)
InputElement::parseSizeAttribute(m_data, attr);
+ else if (attr->name() == WMLNames::formatAttr)
+ m_formatMask = validateInputMask(parseValueForbiddingVariableReferences(attr->value()));
+ else if (attr->name() == WMLNames::emptyokAttr)
+ m_isEmptyOk = (attr->value() == "true");
else
WMLElement::parseMappedAttribute(attr);
// FIXME: Handle 'accesskey' attribute
- // FIXME: Handle 'format' attribute
- // FIXME: Handle 'emptyok' attribute
// FIXME: Handle 'tabindex' attribute
// FIXME: Handle 'title' attribute
}
@@ -226,6 +234,13 @@ void WMLInputElement::attach()
// on the renderer.
if (renderer())
renderer()->updateFromElement();
+
+ // FIXME: maybe this is not a good place to do this since it is possible
+ // to cause unexpected several times initialise of <input> if we force the
+ // node to be reattached. But placing it here can ensure the run-webkit-tests
+ // get expected result,i.e. multiple-times initialise is expected when making
+ // layout test for WMLInputElement
+ init();
}
void WMLInputElement::detach()
@@ -252,8 +267,14 @@ void WMLInputElement::defaultEventHandler(Event* evt)
{
bool clickDefaultFormButton = false;
- if (evt->type() == eventNames().textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
- clickDefaultFormButton = true;
+ if (evt->type() == eventNames().textInputEvent && evt->isTextEvent()) {
+ TextEvent* textEvent = static_cast<TextEvent*>(evt);
+ if (textEvent->data() == "\n")
+ clickDefaultFormButton = true;
+ else if (renderer() && !isConformedToInputMask(textEvent->data()[0], toRenderTextControl(renderer())->text().length() + 1))
+ // If the inputed char doesn't conform to the input mask, stop handling
+ return;
+ }
if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
&& document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
@@ -338,6 +359,168 @@ void WMLInputElement::didMoveToNewOwnerDocument()
WMLElement::didMoveToNewOwnerDocument();
}
+void WMLInputElement::init()
+{
+ String nameVariable = name();
+ String variableValue;
+ WMLPageState* pageSate = wmlPageStateForDocument(document());
+ ASSERT(pageSate);
+ if (!nameVariable.isEmpty())
+ variableValue = pageSate->getVariable(nameVariable);
+
+ if (variableValue.isEmpty() || !isConformedToInputMask(variableValue)) {
+ String val = value();
+ if (isConformedToInputMask(val))
+ variableValue = val;
+ else
+ variableValue = "";
+
+ pageSate->storeVariable(nameVariable, variableValue);
+ }
+ setValue(variableValue);
+
+ if (!hasAttribute(WMLNames::emptyokAttr)) {
+ if (m_formatMask.isEmpty() ||
+ // check if the format codes is just "*f"
+ (m_formatMask.length() == 2 && m_formatMask[0] == '*' && formatCodes().find(m_formatMask[1]) != -1))
+ m_isEmptyOk = true;
+ }
+}
+
+String WMLInputElement::validateInputMask(const String& inputMask)
+{
+ bool isValid = true;
+ bool hasWildcard = false;
+ unsigned escapeCharCount = 0;
+ unsigned maskLength = inputMask.length();
+ UChar formatCode;
+
+ for (unsigned i = 0; i < maskLength; ++i) {
+ formatCode = inputMask[i];
+ if (formatCodes().find(formatCode) == -1) {
+ if (formatCode == '*' || (WTF::isASCIIDigit(formatCode) && formatCode != '0')) {
+ // validate codes which ends with '*f' or 'nf'
+ formatCode = inputMask[++i];
+ if ((i + 1 != maskLength) || formatCodes().find(formatCode) == -1) {
+ isValid = false;
+ break;
+ }
+ hasWildcard = true;
+ } else if (formatCode == '\\') {
+ //skip over the next mask character
+ ++i;
+ ++escapeCharCount;
+ } else {
+ isValid = false;
+ break;
+ }
+ }
+ }
+
+ if (!isValid)
+ return String();
+
+ // calculate the number of characters allowed to be entered by input mask
+ m_numOfCharsAllowedByMask = maskLength;
+
+ if (escapeCharCount)
+ m_numOfCharsAllowedByMask -= escapeCharCount;
+
+ if (hasWildcard) {
+ formatCode = inputMask[maskLength - 2];
+ if (formatCode == '*')
+ m_numOfCharsAllowedByMask = m_data.maxLength();
+ else {
+ unsigned leftLen = String(&formatCode).toInt();
+ m_numOfCharsAllowedByMask = leftLen + m_numOfCharsAllowedByMask - 2;
+ }
+ }
+
+ return inputMask;
+}
+
+bool WMLInputElement::isConformedToInputMask(const String& inputChars)
+{
+ for (unsigned i = 0; i < inputChars.length(); ++i)
+ if (!isConformedToInputMask(inputChars[i], i + 1, false))
+ return false;
+
+ return true;
+}
+
+bool WMLInputElement::isConformedToInputMask(UChar inChar, unsigned inputCharCount, bool isUserInput)
+{
+ if (m_formatMask.isEmpty())
+ return true;
+
+ if (inputCharCount > m_numOfCharsAllowedByMask)
+ return false;
+
+ unsigned maskIndex = 0;
+ if (isUserInput) {
+ unsigned cursorPosition = 0;
+ if (renderer())
+ cursorPosition = toRenderTextControl(renderer())->selectionStart();
+ else
+ cursorPosition = m_data.cachedSelectionStart();
+
+ maskIndex = cursorPositionToMaskIndex(cursorPosition);
+ } else
+ maskIndex = cursorPositionToMaskIndex(inputCharCount - 1);
+
+ bool ok = true;
+ UChar mask = m_formatMask[maskIndex];
+ // match the inputed character with input mask
+ switch (mask) {
+ case 'A':
+ ok = !WTF::isASCIIDigit(inChar) && !WTF::isASCIILower(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'a':
+ ok = !WTF::isASCIIDigit(inChar) && !WTF::isASCIIUpper(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'N':
+ ok = WTF::isASCIIDigit(inChar);
+ break;
+ case 'n':
+ ok = !WTF::isASCIIAlpha(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'X':
+ ok = !WTF::isASCIILower(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'x':
+ ok = !WTF::isASCIIUpper(inChar) && WTF::isASCIIPrintable(inChar);
+ break;
+ case 'M':
+ ok = WTF::isASCIIPrintable(inChar);
+ break;
+ case 'm':
+ ok = WTF::isASCIIPrintable(inChar);
+ break;
+ default:
+ ok = (mask == inChar);
+ break;
+ }
+
+ return ok;
+}
+
+unsigned WMLInputElement::cursorPositionToMaskIndex(unsigned cursorPosition)
+{
+ UChar mask;
+ int index = -1;
+ do {
+ mask = m_formatMask[++index];
+ if (mask == '\\')
+ ++index;
+ else if (mask == '*' || (WTF::isASCIIDigit(mask) && mask != '0')) {
+ index = m_formatMask.length() - 1;
+ break;
+ }
+ } while (cursorPosition--);
+
+ return index;
+}
+
}
#endif
diff --git a/WebCore/wml/WMLInputElement.h b/WebCore/wml/WMLInputElement.h
index 2b913df..a2c904f 100644
--- a/WebCore/wml/WMLInputElement.h
+++ b/WebCore/wml/WMLInputElement.h
@@ -43,6 +43,7 @@ public:
virtual bool shouldUseInputMethod() const { return !m_isPasswordField; }
virtual bool isChecked() const { return false; }
+ virtual bool isAutofilled() const { return false; }
virtual bool isIndeterminate() const { return false; }
virtual bool isTextControl() const { return true; }
virtual bool isRadioButton() const { return false; }
@@ -86,9 +87,19 @@ public:
virtual void willMoveToNewOwnerDocument();
virtual void didMoveToNewOwnerDocument();
+ bool isConformedToInputMask(const String&);
+ bool isConformedToInputMask(UChar, unsigned, bool isUserInput = true);
+
private:
+ void init();
+ String validateInputMask(const String&);
+ unsigned cursorPositionToMaskIndex(unsigned);
+
InputElementData m_data;
bool m_isPasswordField;
+ bool m_isEmptyOk;
+ String m_formatMask;
+ unsigned m_numOfCharsAllowedByMask;
};
}
diff --git a/WebCore/wml/WMLInsertedLegendElement.cpp b/WebCore/wml/WMLInsertedLegendElement.cpp
index 7decd77..1464e71 100644
--- a/WebCore/wml/WMLInsertedLegendElement.cpp
+++ b/WebCore/wml/WMLInsertedLegendElement.cpp
@@ -23,8 +23,6 @@
#if ENABLE(WML)
#include "WMLInsertedLegendElement.h"
-#include "RenderLegend.h"
-
namespace WebCore {
WMLInsertedLegendElement::WMLInsertedLegendElement(const QualifiedName& tagName, Document* doc)
@@ -36,11 +34,6 @@ WMLInsertedLegendElement::~WMLInsertedLegendElement()
{
}
-RenderObject* WMLInsertedLegendElement::createRenderer(RenderArena* arena, RenderStyle*)
-{
- return new (arena) RenderLegend(this);
-}
-
}
#endif
diff --git a/WebCore/wml/WMLInsertedLegendElement.h b/WebCore/wml/WMLInsertedLegendElement.h
index d758487..73392ad 100644
--- a/WebCore/wml/WMLInsertedLegendElement.h
+++ b/WebCore/wml/WMLInsertedLegendElement.h
@@ -30,8 +30,6 @@ class WMLInsertedLegendElement : public WMLElement {
public:
WMLInsertedLegendElement(const QualifiedName& tagName, Document*);
virtual ~WMLInsertedLegendElement();
-
- virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
};
}
diff --git a/WebCore/wml/WMLOptGroupElement.cpp b/WebCore/wml/WMLOptGroupElement.cpp
index 6d2ed52..3658cf6 100644
--- a/WebCore/wml/WMLOptGroupElement.cpp
+++ b/WebCore/wml/WMLOptGroupElement.cpp
@@ -25,6 +25,7 @@
#include "Document.h"
#include "HTMLNames.h"
+#include "NodeRenderStyle.h"
#include "RenderStyle.h"
#include "WMLNames.h"
diff --git a/WebCore/wml/WMLOptionElement.cpp b/WebCore/wml/WMLOptionElement.cpp
index f5d6785..dd1466f 100644
--- a/WebCore/wml/WMLOptionElement.cpp
+++ b/WebCore/wml/WMLOptionElement.cpp
@@ -24,6 +24,7 @@
#include "WMLOptionElement.h"
#include "HTMLNames.h"
+#include "NodeRenderStyle.h"
#include "RenderStyle.h"
#include "WMLNames.h"
diff --git a/WebCore/wml/WMLTableElement.cpp b/WebCore/wml/WMLTableElement.cpp
index f241f46..a305f97 100644
--- a/WebCore/wml/WMLTableElement.cpp
+++ b/WebCore/wml/WMLTableElement.cpp
@@ -66,7 +66,7 @@ void WMLTableElement::parseMappedAttribute(MappedAttribute* attr)
// Spec: This required attribute specifies the number of columns for the table.
// The user agent must create a table with exactly the number of columns specified
- // by the attribute value. It is an error to specify a value of zero (“0”).
+ // by the attribute value. It is an error to specify a value of zero ("0")
if (!m_columns || !isNumber)
reportWMLError(document(), WMLErrorInvalidColumnsNumberInTable);
} else if (attr->name() == HTMLNames::alignAttr)
diff --git a/WebCore/workers/GenericWorkerTask.h b/WebCore/workers/GenericWorkerTask.h
new file mode 100644
index 0000000..96b0e70
--- /dev/null
+++ b/WebCore/workers/GenericWorkerTask.h
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GenericWorkerTask_h
+#define GenericWorkerTask_h
+
+#if ENABLE(WORKERS)
+
+#include "CrossThreadCopier.h"
+#include "ScriptExecutionContext.h"
+#include <memory>
+#include <wtf/PassRefPtr.h>
+#include <wtf/TypeTraits.h>
+
+namespace WebCore {
+
+ // Traits for the GenericWorkerTask.
+ template<typename T> struct GenericWorkerTaskTraits {
+ typedef const T& ParamType;
+ };
+
+ template<typename T> struct GenericWorkerTaskTraits<T*> {
+ typedef T* ParamType;
+ };
+
+ template<typename T> struct GenericWorkerTaskTraits<std::auto_ptr<T> > {
+ typedef std::auto_ptr<T> ParamType;
+ };
+
+ template<typename T> struct GenericWorkerTaskTraits<PassRefPtr<T> > {
+ typedef PassRefPtr<T> ParamType;
+ };
+
+ template<typename P1, typename MP1>
+ class GenericWorkerTask1 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1);
+ typedef GenericWorkerTask1<P1, MP1> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1));
+ }
+
+ private:
+ GenericWorkerTask1(Method method, Param1 parameter1)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ };
+
+ template<typename P1, typename MP1, typename P2, typename MP2>
+ class GenericWorkerTask2 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1, MP2);
+ typedef GenericWorkerTask2<P1, MP1, P2, MP2> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+ typedef typename GenericWorkerTaskTraits<P2>::ParamType Param2;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1, Param2 parameter2)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1, parameter2));
+ }
+
+ private:
+ GenericWorkerTask2(Method method, Param1 parameter1, Param2 parameter2)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1, m_parameter2);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ };
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+ class GenericWorkerTask3 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3);
+ typedef GenericWorkerTask3<P1, MP1, P2, MP2, P3, MP3> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+ typedef typename GenericWorkerTaskTraits<P2>::ParamType Param2;
+ typedef typename GenericWorkerTaskTraits<P3>::ParamType Param3;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1, parameter2, parameter3));
+ }
+
+ private:
+ GenericWorkerTask3(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1, m_parameter2, m_parameter3);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+ };
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4>
+ class GenericWorkerTask4 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4);
+ typedef GenericWorkerTask4<P1, MP1, P2, MP2, P3, MP3, P4, MP4> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+ typedef typename GenericWorkerTaskTraits<P2>::ParamType Param2;
+ typedef typename GenericWorkerTaskTraits<P3>::ParamType Param3;
+ typedef typename GenericWorkerTaskTraits<P4>::ParamType Param4;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1, parameter2, parameter3, parameter4));
+ }
+
+ private:
+ GenericWorkerTask4(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ , m_parameter4(parameter4)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+ P4 m_parameter4;
+ };
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5>
+ class GenericWorkerTask5 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5);
+ typedef GenericWorkerTask5<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+ typedef typename GenericWorkerTaskTraits<P2>::ParamType Param2;
+ typedef typename GenericWorkerTaskTraits<P3>::ParamType Param3;
+ typedef typename GenericWorkerTaskTraits<P4>::ParamType Param4;
+ typedef typename GenericWorkerTaskTraits<P5>::ParamType Param5;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1, parameter2, parameter3, parameter4, parameter5));
+ }
+
+ private:
+ GenericWorkerTask5(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ , m_parameter4(parameter4)
+ , m_parameter5(parameter5)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+ P4 m_parameter4;
+ P5 m_parameter5;
+ };
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
+ class GenericWorkerTask6 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6);
+ typedef GenericWorkerTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+ typedef typename GenericWorkerTaskTraits<P2>::ParamType Param2;
+ typedef typename GenericWorkerTaskTraits<P3>::ParamType Param3;
+ typedef typename GenericWorkerTaskTraits<P4>::ParamType Param4;
+ typedef typename GenericWorkerTaskTraits<P5>::ParamType Param5;
+ typedef typename GenericWorkerTaskTraits<P6>::ParamType Param6;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6));
+ }
+
+ private:
+ GenericWorkerTask6(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ , m_parameter4(parameter4)
+ , m_parameter5(parameter5)
+ , m_parameter6(parameter6)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+ P4 m_parameter4;
+ P5 m_parameter5;
+ P6 m_parameter6;
+ };
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7>
+ class GenericWorkerTask7 : public ScriptExecutionContext::Task {
+ public:
+ typedef void (*Method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7);
+ typedef GenericWorkerTask7<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7> GenericWorkerTask;
+ typedef typename GenericWorkerTaskTraits<P1>::ParamType Param1;
+ typedef typename GenericWorkerTaskTraits<P2>::ParamType Param2;
+ typedef typename GenericWorkerTaskTraits<P3>::ParamType Param3;
+ typedef typename GenericWorkerTaskTraits<P4>::ParamType Param4;
+ typedef typename GenericWorkerTaskTraits<P5>::ParamType Param5;
+ typedef typename GenericWorkerTaskTraits<P6>::ParamType Param6;
+ typedef typename GenericWorkerTaskTraits<P7>::ParamType Param7;
+
+ static PassRefPtr<GenericWorkerTask> create(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6, Param7 parameter7)
+ {
+ return adoptRef(new GenericWorkerTask(method, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6, parameter7));
+ }
+
+ private:
+ GenericWorkerTask7(Method method, Param1 parameter1, Param2 parameter2, Param3 parameter3, Param4 parameter4, Param5 parameter5, Param6 parameter6, Param7 parameter7)
+ : m_method(method)
+ , m_parameter1(parameter1)
+ , m_parameter2(parameter2)
+ , m_parameter3(parameter3)
+ , m_parameter4(parameter4)
+ , m_parameter5(parameter5)
+ , m_parameter6(parameter6)
+ , m_parameter7(parameter7)
+ {
+ }
+
+ virtual void performTask(ScriptExecutionContext* context)
+ {
+ (*m_method)(context, m_parameter1, m_parameter2, m_parameter3, m_parameter4, m_parameter5, m_parameter6, m_parameter7);
+ }
+
+ private:
+ Method m_method;
+ P1 m_parameter1;
+ P2 m_parameter2;
+ P3 m_parameter3;
+ P4 m_parameter4;
+ P5 m_parameter5;
+ P6 m_parameter6;
+ P7 m_parameter7;
+ };
+
+ template<typename P1, typename MP1>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1),
+ const P1& parameter1)
+ {
+ return GenericWorkerTask1<typename CrossThreadCopier<P1>::Type, MP1>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1));
+ }
+
+ template<typename P1, typename MP1, typename P2, typename MP2>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1, MP2),
+ const P1& parameter1, const P2& parameter2)
+ {
+ return GenericWorkerTask2<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2));
+ }
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1, MP2, MP3),
+ const P1& parameter1, const P2& parameter2, const P3& parameter3)
+ {
+ return GenericWorkerTask3<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3));
+ }
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4),
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4)
+ {
+ return GenericWorkerTask4<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3,
+ typename CrossThreadCopier<P4>::Type, MP4>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4));
+ }
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5),
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5)
+ {
+ return GenericWorkerTask5<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3,
+ typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4),
+ CrossThreadCopier<P5>::copy(parameter5));
+ }
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6),
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6)
+ {
+ return GenericWorkerTask6<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3,
+ typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5, typename CrossThreadCopier<P6>::Type, MP6>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4),
+ CrossThreadCopier<P5>::copy(parameter5), CrossThreadCopier<P6>::copy(parameter6));
+ }
+
+ template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7>
+ PassRefPtr<ScriptExecutionContext::Task> createCallbackTask(
+ void (*method)(ScriptExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7),
+ const P1& parameter1, const P2& parameter2, const P3& parameter3, const P4& parameter4, const P5& parameter5, const P6& parameter6, const P7& parameter7)
+ {
+ return GenericWorkerTask7<typename CrossThreadCopier<P1>::Type, MP1, typename CrossThreadCopier<P2>::Type, MP2, typename CrossThreadCopier<P3>::Type, MP3,
+ typename CrossThreadCopier<P4>::Type, MP4, typename CrossThreadCopier<P5>::Type, MP5, typename CrossThreadCopier<P6>::Type, MP6,
+ typename CrossThreadCopier<P7>::Type, MP7>::create(
+ method,
+ CrossThreadCopier<P1>::copy(parameter1), CrossThreadCopier<P2>::copy(parameter2),
+ CrossThreadCopier<P3>::copy(parameter3), CrossThreadCopier<P4>::copy(parameter4),
+ CrossThreadCopier<P5>::copy(parameter5), CrossThreadCopier<P6>::copy(parameter6),
+ CrossThreadCopier<P7>::copy(parameter7));
+ }
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // GenericWorkerTask_h
diff --git a/WebCore/dom/Worker.cpp b/WebCore/workers/Worker.cpp
index 6889a42..85ba690 100644
--- a/WebCore/dom/Worker.cpp
+++ b/WebCore/workers/Worker.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,60 +43,57 @@
#include "FrameLoader.h"
#include "MessageEvent.h"
#include "SecurityOrigin.h"
-#include "WorkerContext.h"
-#include "WorkerMessagingProxy.h"
-#include "WorkerTask.h"
+#include "TextEncoding.h"
+#include "WorkerContextProxy.h"
#include "WorkerThread.h"
#include <wtf/MainThread.h>
namespace WebCore {
-Worker::Worker(const String& url, Document* doc, ExceptionCode& ec)
- : ActiveDOMObject(doc, this)
- , m_messagingProxy(new WorkerMessagingProxy(doc, this))
+Worker::Worker(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
+ : ActiveDOMObject(context, this)
+ , m_contextProxy(WorkerContextProxy::create(this))
{
- m_scriptURL = doc->completeURL(url);
+ m_scriptURL = context->completeURL(url);
if (url.isEmpty() || !m_scriptURL.isValid()) {
ec = SYNTAX_ERR;
return;
}
- if (!doc->securityOrigin()->canAccess(SecurityOrigin::create(m_scriptURL).get())) {
+ if (!context->securityOrigin()->canAccess(SecurityOrigin::create(m_scriptURL).get())) {
ec = SECURITY_ERR;
return;
}
- m_cachedScript = doc->docLoader()->requestScript(m_scriptURL, document()->charset());
+ // FIXME: Nested workers need loading support. Consider adopting ThreadableLoader here.
+ ASSERT(scriptExecutionContext()->isDocument());
+ Document* document = static_cast<Document*>(scriptExecutionContext());
+
+ m_cachedScript = document->docLoader()->requestScript(m_scriptURL, "UTF-8");
if (!m_cachedScript) {
dispatchErrorEvent();
return;
}
- setPendingActivity(this); // The worker context does not exist while loading, so we much ensure that the worker object is not collected, as well as its event listeners.
+ setPendingActivity(this); // The worker context does not exist while loading, so we must ensure that the worker object is not collected, as well as its event listeners.
m_cachedScript->addClient(this);
}
Worker::~Worker()
{
ASSERT(isMainThread());
- ASSERT(scriptExecutionContext()); // The context is protected by messaging proxy, so it cannot be destroyed while a Worker exists.
- m_messagingProxy->workerObjectDestroyed();
-}
-
-Document* Worker::document() const
-{
- ASSERT(scriptExecutionContext()->isDocument());
- return static_cast<Document*>(scriptExecutionContext());
+ ASSERT(scriptExecutionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
+ m_contextProxy->workerObjectDestroyed();
}
void Worker::postMessage(const String& message)
{
- m_messagingProxy->postMessageToWorkerContext(message);
+ m_contextProxy->postMessageToWorkerContext(message);
}
void Worker::terminate()
{
- m_messagingProxy->terminate();
+ m_contextProxy->terminateWorkerContext();
}
bool Worker::canSuspend() const
@@ -111,7 +109,7 @@ void Worker::stop()
bool Worker::hasPendingActivity() const
{
- return m_messagingProxy->workerThreadHasPendingActivity() || ActiveDOMObject::hasPendingActivity();
+ return m_contextProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
}
void Worker::notifyFinished(CachedResource* unusedResource)
@@ -120,12 +118,8 @@ void Worker::notifyFinished(CachedResource* unusedResource)
if (m_cachedScript->errorOccurred())
dispatchErrorEvent();
- else {
- String userAgent = document()->frame() ? document()->frame()->loader()->userAgent(m_scriptURL) : String();
- RefPtr<WorkerThread> thread = WorkerThread::create(m_scriptURL, userAgent, m_cachedScript->script(), m_messagingProxy);
- m_messagingProxy->workerThreadCreated(thread);
- thread->start();
- }
+ else
+ m_contextProxy->startWorkerContext(m_scriptURL, scriptExecutionContext()->userAgent(m_scriptURL), m_cachedScript->script());
m_cachedScript->removeClient(this);
m_cachedScript = 0;
@@ -198,6 +192,21 @@ bool Worker::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
return !event->defaultPrevented();
}
+void Worker::dispatchMessage(const String& message)
+{
+ RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, 0);
+
+ if (m_onMessageListener.get()) {
+ evt->setTarget(this);
+ evt->setCurrentTarget(this);
+ m_onMessageListener->handleEvent(evt.get(), false);
+ }
+
+ ExceptionCode ec = 0;
+ dispatchEvent(evt.release(), ec);
+ ASSERT(!ec);
+}
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/dom/Worker.h b/WebCore/workers/Worker.h
index 6a47bac..d05f9d5 100644
--- a/WebCore/dom/Worker.h
+++ b/WebCore/workers/Worker.h
@@ -43,21 +43,18 @@ namespace WebCore {
class CachedResource;
class CachedScript;
- class Document;
class ScriptExecutionContext;
class String;
- class WorkerMessagingProxy;
- class WorkerTask;
+ class WorkerContextProxy;
typedef int ExceptionCode;
class Worker : public RefCounted<Worker>, public ActiveDOMObject, private CachedResourceClient, public EventTarget {
public:
- static PassRefPtr<Worker> create(const String& url, Document* document, ExceptionCode& ec) { return adoptRef(new Worker(url, document, ec)); }
+ static PassRefPtr<Worker> create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec) { return adoptRef(new Worker(url, context, ec)); }
~Worker();
virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
- Document* document() const;
virtual Worker* toWorker() { return this; }
@@ -65,6 +62,9 @@ namespace WebCore {
void terminate();
+ void dispatchMessage(const String&);
+ void dispatchErrorEvent();
+
virtual bool canSuspend() const;
virtual void stop();
virtual bool hasPendingActivity() const;
@@ -87,19 +87,17 @@ namespace WebCore {
EventListener* onerror() const { return m_onErrorListener.get(); }
private:
- Worker(const String&, Document*, ExceptionCode&);
+ Worker(const String&, ScriptExecutionContext*, ExceptionCode&);
virtual void notifyFinished(CachedResource*);
- void dispatchErrorEvent();
-
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
KURL m_scriptURL;
CachedResourceHandle<CachedScript> m_cachedScript;
- WorkerMessagingProxy* m_messagingProxy; // The proxy outlives the worker to perform thread shutdown.
+ WorkerContextProxy* m_contextProxy; // The proxy outlives the worker to perform thread shutdown.
RefPtr<EventListener> m_onMessageListener;
RefPtr<EventListener> m_onErrorListener;
diff --git a/WebCore/dom/Worker.idl b/WebCore/workers/Worker.idl
index 2ef9b62..2ef9b62 100644
--- a/WebCore/dom/Worker.idl
+++ b/WebCore/workers/Worker.idl
diff --git a/WebCore/dom/WorkerContext.cpp b/WebCore/workers/WorkerContext.cpp
index fe4643e..69ef472 100644
--- a/WebCore/dom/WorkerContext.cpp
+++ b/WebCore/workers/WorkerContext.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,17 +32,23 @@
#include "WorkerContext.h"
#include "ActiveDOMObject.h"
+#include "DOMTimer.h"
#include "DOMWindow.h"
#include "Event.h"
#include "EventException.h"
-#include "GenericWorkerTask.h"
+#include "MessageEvent.h"
#include "NotImplemented.h"
+#include "ResourceRequest.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
#include "SecurityOrigin.h"
+#include "ThreadableLoader.h"
+#include "WorkerImportScriptsClient.h"
#include "WorkerLocation.h"
-#include "WorkerMessagingProxy.h"
#include "WorkerNavigator.h"
-#include "WorkerTask.h"
+#include "WorkerObjectProxy.h"
#include "WorkerThread.h"
+#include "XMLHttpRequestException.h"
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -60,7 +67,7 @@ WorkerContext::~WorkerContext()
{
ASSERT(currentThread() == m_thread->threadID());
- m_thread->messagingProxy()->workerContextDestroyed();
+ m_thread->workerObjectProxy()->workerContextDestroyed();
}
ScriptExecutionContext* WorkerContext::scriptExecutionContext() const
@@ -84,10 +91,15 @@ KURL WorkerContext::completeURL(const String& url) const
// FIXME: Should we change the KURL constructor to have this behavior?
if (url.isNull())
return KURL();
- // FIXME: does this need to provide a charset, like Document::completeURL does?
+ // Always use UTF-8 in Workers.
return KURL(m_location->url(), url);
}
+String WorkerContext::userAgent(const KURL&) const
+{
+ return m_userAgent;
+}
+
WorkerNavigator* WorkerContext::navigator() const
{
if (!m_navigator)
@@ -108,24 +120,21 @@ bool WorkerContext::hasPendingActivity() const
void WorkerContext::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
{
- m_thread->messagingProxy()->postWorkerException(errorMessage, lineNumber, sourceURL);
+ m_thread->workerObjectProxy()->postExceptionToWorkerObject(errorMessage, lineNumber, sourceURL);
}
-static void addMessageTask(ScriptExecutionContext* context, MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+void WorkerContext::addMessage(MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
{
- context->addMessage(destination, source, level, message, lineNumber, sourceURL);
+ m_thread->workerObjectProxy()->postConsoleMessageToWorkerObject(destination, source, level, message, lineNumber, sourceURL);
}
-void WorkerContext::addMessage(MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+void WorkerContext::resourceRetrievedByXMLHttpRequest(unsigned long, const ScriptString&)
{
- // createCallbackTask has to be a separate statement from postTaskToParentContext to make the destructor
- // for message.copy() get called before postTaskToParentContext. (If they are one statement, the destructor
- // gets called after postTaskToParentContext which causes a race condition.)
- RefPtr<Task> task = createCallbackTask(m_thread->messagingProxy(), &addMessageTask, destination, source, level, message.copy(), lineNumber, sourceURL.copy());
- postTaskToParentContext(task.release());
+ // FIXME: The implementation is pending the fixes in https://bugs.webkit.org/show_bug.cgi?id=23175
+ notImplemented();
}
-void WorkerContext::resourceRetrievedByXMLHttpRequest(unsigned long, const ScriptString&)
+void WorkerContext::scriptImported(unsigned long, const String&)
{
// FIXME: The implementation is pending the fixes in https://bugs.webkit.org/show_bug.cgi?id=23175
notImplemented();
@@ -133,7 +142,7 @@ void WorkerContext::resourceRetrievedByXMLHttpRequest(unsigned long, const Scrip
void WorkerContext::postMessage(const String& message)
{
- m_thread->messagingProxy()->postMessageToWorkerObject(message);
+ m_thread->workerObjectProxy()->postMessageToWorkerObject(message);
}
void WorkerContext::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool)
@@ -187,35 +196,72 @@ bool WorkerContext::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
return !event->defaultPrevented();
}
-class ScriptExecutionContextTaskWorkerTask : public WorkerTask {
-public:
- static PassRefPtr<ScriptExecutionContextTaskWorkerTask> create(PassRefPtr<ScriptExecutionContext::Task> task)
- {
- return adoptRef(new ScriptExecutionContextTaskWorkerTask(task));
- }
-
-private:
- ScriptExecutionContextTaskWorkerTask(PassRefPtr<ScriptExecutionContext::Task> task)
- : m_task(task)
- {
- }
+void WorkerContext::postTask(PassRefPtr<Task> task)
+{
+ thread()->runLoop().postTask(task);
+}
- virtual void performTask(WorkerContext* context)
- {
- m_task->performTask(context);
- }
+int WorkerContext::installTimeout(ScheduledAction* action, int timeout, bool singleShot)
+{
+ return DOMTimer::install(scriptExecutionContext(), action, timeout, singleShot);
+}
- RefPtr<ScriptExecutionContext::Task> m_task;
-};
+void WorkerContext::removeTimeout(int timeoutId)
+{
+ DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+}
-void WorkerContext::postTask(PassRefPtr<Task> task)
+void WorkerContext::dispatchMessage(const String& message)
{
- thread()->runLoop().postTask(ScriptExecutionContextTaskWorkerTask::create(task));
+ RefPtr<Event> evt = MessageEvent::create(message, "", "", 0, 0);
+
+ if (m_onmessageListener.get()) {
+ evt->setTarget(this);
+ evt->setCurrentTarget(this);
+ m_onmessageListener->handleEvent(evt.get(), false);
+ }
+
+ ExceptionCode ec = 0;
+ dispatchEvent(evt.release(), ec);
+ ASSERT(!ec);
}
-void WorkerContext::postTaskToParentContext(PassRefPtr<Task> task)
+void WorkerContext::importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode& ec)
{
- thread()->messagingProxy()->postTaskToParentContext(task);
+ ec = 0;
+ Vector<String>::const_iterator urlsEnd = urls.end();
+ Vector<KURL> completedURLs;
+ for (Vector<String>::const_iterator it = urls.begin(); it != urlsEnd; ++it) {
+ const KURL& url = scriptExecutionContext()->completeURL(*it);
+ if (!url.isValid()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ completedURLs.append(url);
+ }
+ String securityOrigin = scriptExecutionContext()->securityOrigin()->toString();
+ Vector<KURL>::const_iterator end = completedURLs.end();
+
+ for (Vector<KURL>::const_iterator it = completedURLs.begin(); it != end; ++it) {
+ ResourceRequest request(*it);
+ request.setHTTPMethod("GET");
+ request.setHTTPOrigin(securityOrigin);
+ WorkerImportScriptsClient client(scriptExecutionContext(), *it, callerURL, callerLine);
+ ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, client);
+
+ // If the fetching attempt failed, throw a NETWORK_ERR exception and abort all these steps.
+ if (client.failed()) {
+ ec = XMLHttpRequestException::NETWORK_ERR;
+ return;
+ }
+
+ ScriptValue exception;
+ m_script->evaluate(ScriptSourceCode(client.script(), *it), &exception);
+ if (!exception.hasNoValue()) {
+ m_script->setException(exception);
+ return;
+ }
+ }
}
} // namespace WebCore
diff --git a/WebCore/dom/WorkerContext.h b/WebCore/workers/WorkerContext.h
index 2e443d9..39a5b9b 100644
--- a/WebCore/dom/WorkerContext.h
+++ b/WebCore/workers/WorkerContext.h
@@ -41,6 +41,7 @@
namespace WebCore {
+ class ScheduledAction;
class WorkerLocation;
class WorkerNavigator;
class WorkerThread;
@@ -61,6 +62,8 @@ namespace WebCore {
const KURL& url() const { return m_url; }
KURL completeURL(const String&) const;
+ virtual String userAgent(const KURL&) const;
+
WorkerLocation* location() const { return m_location.get(); }
WorkerNavigator* navigator() const;
@@ -73,12 +76,17 @@ namespace WebCore {
virtual void reportException(const String& errorMessage, int lineNumber, const String& sourceURL);
virtual void addMessage(MessageDestination, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
virtual void resourceRetrievedByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString);
+ virtual void scriptImported(unsigned long identifier, const String& sourceString);
virtual WorkerContext* toWorkerContext() { return this; }
void postMessage(const String& message);
virtual void postTask(PassRefPtr<Task>); // Executes the task on context's thread asynchronously.
- void postTaskToParentContext(PassRefPtr<Task>); // Executes the task in the parent's context (and thread) asynchronously.
+
+ int installTimeout(ScheduledAction*, int timeout, bool singleShot);
+ void removeTimeout(int timeoutId);
+
+ void dispatchMessage(const String&);
virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
@@ -91,6 +99,8 @@ namespace WebCore {
typedef HashMap<AtomicString, ListenerVector> EventListenersMap;
EventListenersMap& eventListeners() { return m_eventListeners; }
+ void importScripts(const Vector<String>& urls, const String& callerURL, int callerLine, ExceptionCode&);
+
using RefCounted<WorkerContext>::ref;
using RefCounted<WorkerContext>::deref;
diff --git a/WebCore/dom/WorkerContext.idl b/WebCore/workers/WorkerContext.idl
index 6e7223c..bbfca63 100644
--- a/WebCore/dom/WorkerContext.idl
+++ b/WebCore/workers/WorkerContext.idl
@@ -40,6 +40,7 @@ module threads {
attribute EventListener onmessage;
void postMessage(in DOMString message);
+ [Custom] void importScripts(/* urls */);
attribute [Replaceable] WorkerLocation location;
attribute [Replaceable] WorkerNavigator navigator;
@@ -47,6 +48,15 @@ module threads {
attribute MessageEventConstructor MessageEvent;
attribute WorkerLocationConstructor WorkerLocation;
+ // Timers
+ [Custom] long setTimeout(in TimeoutHandler handler, in long timeout);
+ // [Custom] long setTimeout(in DOMString code, in long timeout);
+ [Custom] void clearTimeout(in long handle);
+
+ [Custom] long setInterval(in TimeoutHandler handler, in long timeout);
+ // [Custom] long setInterval(in DOMString code, in long timeout);
+ [Custom] void clearInterval(in long handle);
+
// EventTarget interface
[Custom] void addEventListener(in DOMString type,
in EventListener listener,
diff --git a/WebCore/dom/WorkerRunLoop.h b/WebCore/workers/WorkerContextProxy.h
index 03a746b..c8f5761 100644
--- a/WebCore/dom/WorkerRunLoop.h
+++ b/WebCore/workers/WorkerContextProxy.h
@@ -1,10 +1,10 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -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
@@ -28,37 +28,37 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WorkerRunLoop_h
-#define WorkerRunLoop_h
+#ifndef WorkerContextProxy_h
+#define WorkerContextProxy_h
#if ENABLE(WORKERS)
-#include "WorkerTask.h"
-#include <wtf/MessageQueue.h>
-#include <wtf/PassRefPtr.h>
-
namespace WebCore {
- class WorkerContext;
+ class KURL;
+ class String;
+ class Worker;
- class WorkerRunLoop {
+ // A proxy to talk to the worker context.
+ class WorkerContextProxy {
public:
- WorkerRunLoop() {}
-
- // Blocking call. Waits for tasks and timers, invokes the callbacks.
- void run(WorkerContext*);
-
- void terminate();
- bool terminated() { return m_messageQueue.killed(); }
+ static WorkerContextProxy* create(Worker*);
+
+ virtual ~WorkerContextProxy() {}
+
+ virtual void startWorkerContext(const KURL& scriptURL, const String& userAgent, const String& sourceCode) = 0;
+
+ virtual void terminateWorkerContext() = 0;
+
+ virtual void postMessageToWorkerContext(const String&) = 0;
+
+ virtual bool hasPendingActivity() const = 0;
- void postTask(PassRefPtr<WorkerTask>);
-
- private:
- MessageQueue<RefPtr<WorkerTask> > m_messageQueue;
+ virtual void workerObjectDestroyed() = 0;
};
} // namespace WebCore
#endif // ENABLE(WORKERS)
-#endif // WorkerRunLoop_h
+#endif // WorkerContextProxy_h
diff --git a/WebCore/workers/WorkerImportScriptsClient.cpp b/WebCore/workers/WorkerImportScriptsClient.cpp
new file mode 100644
index 0000000..7b8061b
--- /dev/null
+++ b/WebCore/workers/WorkerImportScriptsClient.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerImportScriptsClient.h"
+
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+void WorkerImportScriptsClient::didReceiveResponse(const ResourceResponse& response)
+{
+ if (response.httpStatusCode() / 100 != 2 && response.httpStatusCode() != 0) {
+ m_failed = true;
+ return;
+ }
+ m_responseEncoding = response.textEncodingName();
+}
+
+void WorkerImportScriptsClient::didReceiveData(const char* data, int len)
+{
+ if (m_failed)
+ return;
+
+ if (!m_decoder) {
+ if (!m_responseEncoding.isEmpty())
+ m_decoder = TextResourceDecoder::create("text/javascript", m_responseEncoding);
+ else
+ m_decoder = TextResourceDecoder::create("text/javascript", "UTF-8");
+ }
+
+ if (!len)
+ return;
+
+ if (len == -1)
+ len = strlen(data);
+
+ m_script += m_decoder->decode(data, len);
+}
+
+void WorkerImportScriptsClient::didFinishLoading(unsigned long identifier)
+{
+ if (m_failed)
+ return;
+
+ if (m_decoder)
+ m_script += m_decoder->flush();
+
+ m_scriptExecutionContext->scriptImported(identifier, m_script);
+ m_scriptExecutionContext->addMessage(InspectorControllerDestination, JSMessageSource, LogMessageLevel, "Worker script imported: \"" + m_url + "\".", m_callerLineNumber, m_callerURL);
+}
+
+void WorkerImportScriptsClient::didFail(const ResourceError&)
+{
+ m_failed = true;
+}
+
+void WorkerImportScriptsClient::didFailRedirectCheck()
+{
+ m_failed = true;
+}
+
+void WorkerImportScriptsClient::didReceiveAuthenticationCancellation(const ResourceResponse&)
+{
+ m_failed = true;
+}
+
+}
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/workers/WorkerImportScriptsClient.h b/WebCore/workers/WorkerImportScriptsClient.h
new file mode 100644
index 0000000..ec27054
--- /dev/null
+++ b/WebCore/workers/WorkerImportScriptsClient.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerImportScriptsClient_h
+#define WorkerImportScriptsClient_h
+
+#if ENABLE(WORKERS)
+
+#include "ResourceResponse.h"
+#include "ScriptString.h"
+#include "TextResourceDecoder.h"
+#include "ThreadableLoaderClient.h"
+
+namespace WebCore {
+
+ class ScriptExecutionContext;
+
+ class WorkerImportScriptsClient : public ThreadableLoaderClient {
+ public:
+ WorkerImportScriptsClient(ScriptExecutionContext* scriptExecutionContext, const String& url, const String& callerURL, int callerLineNumber)
+ : m_scriptExecutionContext(scriptExecutionContext)
+ , m_url(url)
+ , m_callerURL(callerURL)
+ , m_callerLineNumber(callerLineNumber)
+ , m_failed(false)
+ {
+ }
+
+ const String& script() const { return m_script; }
+ bool failed() const { return m_failed; }
+
+ virtual void didReceiveResponse(const ResourceResponse& response);
+ virtual void didReceiveData(const char* data, int lengthReceived);
+ virtual void didFinishLoading(unsigned long identifier);
+ virtual void didFail(const ResourceError&);
+ virtual void didFailRedirectCheck();
+ virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
+
+ private:
+ ScriptExecutionContext* m_scriptExecutionContext;
+ String m_url;
+ String m_callerURL;
+ int m_callerLineNumber;
+ String m_responseEncoding;
+ RefPtr<TextResourceDecoder> m_decoder;
+ String m_script;
+ bool m_failed;
+ };
+
+}
+
+#endif // ENABLE(WORKERS)
+#endif
+
diff --git a/WebCore/dom/WorkerLocation.cpp b/WebCore/workers/WorkerLocation.cpp
index 115a9ad..e84bf93 100644
--- a/WebCore/dom/WorkerLocation.cpp
+++ b/WebCore/workers/WorkerLocation.cpp
@@ -66,12 +66,12 @@ String WorkerLocation::pathname() const
String WorkerLocation::search() const
{
- return m_url.query();
+ return m_url.query().isEmpty() ? "" : "?" + m_url.query();
}
String WorkerLocation::hash() const
{
- return m_url.ref().isNull() ? "" : "#" + m_url.ref();
+ return m_url.ref().isEmpty() ? "" : "#" + m_url.ref();
}
String WorkerLocation::toString() const
diff --git a/WebCore/dom/WorkerLocation.h b/WebCore/workers/WorkerLocation.h
index 52c31ad..52c31ad 100644
--- a/WebCore/dom/WorkerLocation.h
+++ b/WebCore/workers/WorkerLocation.h
diff --git a/WebCore/dom/WorkerLocation.idl b/WebCore/workers/WorkerLocation.idl
index 5551f18..5551f18 100644
--- a/WebCore/dom/WorkerLocation.idl
+++ b/WebCore/workers/WorkerLocation.idl
diff --git a/WebCore/dom/WorkerMessagingProxy.cpp b/WebCore/workers/WorkerMessagingProxy.cpp
index b0d145e..4b34658 100644
--- a/WebCore/dom/WorkerMessagingProxy.cpp
+++ b/WebCore/workers/WorkerMessagingProxy.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,15 +33,16 @@
#include "DOMWindow.h"
#include "Document.h"
+#include "GenericWorkerTask.h"
#include "MessageEvent.h"
+#include "ScriptExecutionContext.h"
#include "Worker.h"
#include "WorkerContext.h"
-#include "WorkerTask.h"
#include "WorkerThread.h"
namespace WebCore {
-class MessageWorkerContextTask : public WorkerTask {
+class MessageWorkerContextTask : public ScriptExecutionContext::Task {
public:
static PassRefPtr<MessageWorkerContextTask> create(const String& message)
{
@@ -53,21 +55,14 @@ private:
{
}
- virtual void performTask(WorkerContext* context)
+ virtual void performTask(ScriptExecutionContext* scriptContext)
{
- RefPtr<Event> evt = MessageEvent::create(m_message, "", "", 0, 0);
+ ASSERT(scriptContext->isWorkerContext());
+ WorkerContext* context = static_cast<WorkerContext*>(scriptContext);
- if (context->onmessage()) {
- evt->setTarget(context);
- evt->setCurrentTarget(context);
- context->onmessage()->handleEvent(evt.get(), false);
- }
+ context->dispatchMessage(m_message);
- ExceptionCode ec = 0;
- context->dispatchEvent(evt.release(), ec);
- ASSERT(!ec);
-
- context->thread()->messagingProxy()->confirmWorkerThreadMessage(context->hasPendingActivity());
+ context->thread()->workerObjectProxy()->confirmMessageFromWorkerObject(context->hasPendingActivity());
}
private:
@@ -94,17 +89,7 @@ private:
if (!workerObject || m_messagingProxy->askedToTerminate())
return;
- RefPtr<Event> evt = MessageEvent::create(m_message, "", "", 0, 0);
-
- if (workerObject->onmessage()) {
- evt->setTarget(workerObject);
- evt->setCurrentTarget(workerObject);
- workerObject->onmessage()->handleEvent(evt.get(), false);
- }
-
- ExceptionCode ec = 0;
- workerObject->dispatchEvent(evt.release(), ec);
- ASSERT(!ec);
+ workerObject->dispatchMessage(m_message);
}
private:
@@ -178,7 +163,7 @@ private:
virtual void performTask(ScriptExecutionContext*)
{
- m_messagingProxy->reportWorkerThreadActivityInternal(m_confirmingMessage, m_hasPendingActivity);
+ m_messagingProxy->reportPendingActivityInternal(m_confirmingMessage, m_hasPendingActivity);
}
WorkerMessagingProxy* m_messagingProxy;
@@ -187,8 +172,15 @@ private:
};
-WorkerMessagingProxy::WorkerMessagingProxy(PassRefPtr<ScriptExecutionContext> scriptExecutionContext, Worker* workerObject)
- : m_scriptExecutionContext(scriptExecutionContext)
+#if !PLATFORM(CHROMIUM)
+WorkerContextProxy* WorkerContextProxy::create(Worker* worker)
+{
+ return new WorkerMessagingProxy(worker);
+}
+#endif
+
+WorkerMessagingProxy::WorkerMessagingProxy(Worker* workerObject)
+ : m_scriptExecutionContext(workerObject->scriptExecutionContext())
, m_workerObject(workerObject)
, m_unconfirmedMessageCount(0)
, m_workerThreadHadPendingActivity(false)
@@ -196,14 +188,21 @@ WorkerMessagingProxy::WorkerMessagingProxy(PassRefPtr<ScriptExecutionContext> sc
{
ASSERT(m_workerObject);
ASSERT((m_scriptExecutionContext->isDocument() && isMainThread())
- || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
+ || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
}
WorkerMessagingProxy::~WorkerMessagingProxy()
{
ASSERT(!m_workerObject);
ASSERT((m_scriptExecutionContext->isDocument() && isMainThread())
- || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
+ || (m_scriptExecutionContext->isWorkerContext() && currentThread() == static_cast<WorkerContext*>(m_scriptExecutionContext.get())->thread()->threadID()));
+}
+
+void WorkerMessagingProxy::startWorkerContext(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
+{
+ RefPtr<WorkerThread> thread = WorkerThread::create(scriptURL, userAgent, sourceCode, this);
+ workerThreadCreated(thread);
+ thread->start();
}
void WorkerMessagingProxy::postMessageToWorkerObject(const String& message)
@@ -223,15 +222,41 @@ void WorkerMessagingProxy::postMessageToWorkerContext(const String& message)
m_queuedEarlyTasks.append(MessageWorkerContextTask::create(message));
}
-void WorkerMessagingProxy::postTaskToParentContext(PassRefPtr<ScriptExecutionContext::Task> task)
+void WorkerMessagingProxy::postTaskToWorkerContext(PassRefPtr<ScriptExecutionContext::Task> task)
+{
+ postTaskForModeToWorkerContext(task, WorkerRunLoop::defaultMode());
+}
+
+void WorkerMessagingProxy::postTaskForModeToWorkerContext(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ if (m_askedToTerminate)
+ return;
+
+ ASSERT(m_workerThread);
+ m_workerThread->runLoop().postTaskForMode(task, mode);
+}
+
+void WorkerMessagingProxy::postTaskToWorkerObject(PassRefPtr<ScriptExecutionContext::Task> task)
{
m_scriptExecutionContext->postTask(task);
}
-void WorkerMessagingProxy::postWorkerException(const String& errorMessage, int lineNumber, const String& sourceURL)
+void WorkerMessagingProxy::postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL)
{
m_scriptExecutionContext->postTask(WorkerExceptionTask::create(errorMessage, lineNumber, sourceURL, this));
}
+
+static void postConsoleMessageTask(ScriptExecutionContext* context, WorkerMessagingProxy* messagingProxy, MessageDestination destination, MessageSource source, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL)
+{
+ if (messagingProxy->askedToTerminate())
+ return;
+ context->addMessage(destination, source, level, message, lineNumber, sourceURL);
+}
+
+void WorkerMessagingProxy::postConsoleMessageToWorkerObject(MessageDestination destination, MessageSource source, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
+{
+ m_scriptExecutionContext->postTask(createCallbackTask(&postConsoleMessageTask, this, destination, source, level, message, lineNumber, sourceURL));
+}
void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<WorkerThread> workerThread)
{
@@ -243,7 +268,8 @@ void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<WorkerThread> workerTh
} else {
unsigned taskCount = m_queuedEarlyTasks.size();
ASSERT(!m_unconfirmedMessageCount);
- m_unconfirmedMessageCount = taskCount + 1; // Worker initialization counts as a pending message.
+ m_unconfirmedMessageCount = taskCount;
+ m_workerThreadHadPendingActivity = true; // Worker initialization means a pending activity.
for (unsigned i = 0; i < taskCount; ++i)
m_workerThread->runLoop().postTask(m_queuedEarlyTasks[i]);
@@ -255,9 +281,9 @@ void WorkerMessagingProxy::workerObjectDestroyed()
{
m_workerObject = 0;
if (m_workerThread)
- terminate();
+ terminateWorkerContext();
else
- workerContextDestroyedInternal(); // It never existed, just do our cleanup.
+ workerContextDestroyedInternal();
}
void WorkerMessagingProxy::workerContextDestroyed()
@@ -270,11 +296,12 @@ void WorkerMessagingProxy::workerContextDestroyedInternal()
{
// WorkerContextDestroyedTask is always the last to be performed, so the proxy is not needed for communication
// in either side any more. However, the Worker object may still exist, and it assumes that the proxy exists, too.
+ m_workerThread = 0;
if (!m_workerObject)
delete this;
}
-void WorkerMessagingProxy::terminate()
+void WorkerMessagingProxy::terminateWorkerContext()
{
if (m_askedToTerminate)
return;
@@ -284,19 +311,19 @@ void WorkerMessagingProxy::terminate()
m_workerThread->stop();
}
-void WorkerMessagingProxy::confirmWorkerThreadMessage(bool hasPendingActivity)
+void WorkerMessagingProxy::confirmMessageFromWorkerObject(bool hasPendingActivity)
{
m_scriptExecutionContext->postTask(WorkerThreadActivityReportTask::create(this, true, hasPendingActivity));
- // Will execute reportWorkerThreadActivityInternal() on context's thread.
+ // Will execute reportPendingActivityInternal() on context's thread.
}
-void WorkerMessagingProxy::reportWorkerThreadActivity(bool hasPendingActivity)
+void WorkerMessagingProxy::reportPendingActivity(bool hasPendingActivity)
{
m_scriptExecutionContext->postTask(WorkerThreadActivityReportTask::create(this, false, hasPendingActivity));
- // Will execute reportWorkerThreadActivityInternal() on context's thread.
+ // Will execute reportPendingActivityInternal() on context's thread.
}
-void WorkerMessagingProxy::reportWorkerThreadActivityInternal(bool confirmingMessage, bool hasPendingActivity)
+void WorkerMessagingProxy::reportPendingActivityInternal(bool confirmingMessage, bool hasPendingActivity)
{
if (confirmingMessage && !m_askedToTerminate) {
ASSERT(m_unconfirmedMessageCount);
@@ -306,7 +333,7 @@ void WorkerMessagingProxy::reportWorkerThreadActivityInternal(bool confirmingMes
m_workerThreadHadPendingActivity = hasPendingActivity;
}
-bool WorkerMessagingProxy::workerThreadHasPendingActivity() const
+bool WorkerMessagingProxy::hasPendingActivity() const
{
return (m_unconfirmedMessageCount || m_workerThreadHadPendingActivity) && !m_askedToTerminate;
}
diff --git a/WebCore/dom/WorkerMessagingProxy.h b/WebCore/workers/WorkerMessagingProxy.h
index e7ba8a9..8d81deb 100644
--- a/WebCore/dom/WorkerMessagingProxy.h
+++ b/WebCore/workers/WorkerMessagingProxy.h
@@ -30,6 +30,8 @@
#if ENABLE(WORKERS)
#include "ScriptExecutionContext.h"
+#include "WorkerContextProxy.h"
+#include "WorkerObjectProxy.h"
#include <wtf/Noncopyable.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -40,42 +42,48 @@ namespace WebCore {
class ScriptExecutionContext;
class String;
class Worker;
- class WorkerTask;
class WorkerThread;
- class WorkerMessagingProxy : Noncopyable {
+ class WorkerMessagingProxy : public WorkerContextProxy, public WorkerObjectProxy, Noncopyable {
public:
- WorkerMessagingProxy(PassRefPtr<ScriptExecutionContext>, Worker*);
-
- void postMessageToWorkerObject(const String& message);
- void postMessageToWorkerContext(const String& message);
- void postTaskToParentContext(PassRefPtr<ScriptExecutionContext::Task>);
-
- void postWorkerException(const String& errorMessage, int lineNumber, const String& sourceURL);
+ WorkerMessagingProxy(Worker*);
+
+ // Implementations of WorkerContextProxy.
+ // (Only use these methods in the worker object thread.)
+ virtual void startWorkerContext(const KURL& scriptURL, const String& userAgent, const String& sourceCode);
+ virtual void terminateWorkerContext();
+ virtual void postMessageToWorkerContext(const String& message);
+ virtual bool hasPendingActivity() const;
+ virtual void workerObjectDestroyed();
+
+ // Implementations of WorkerObjectProxy.
+ // (Only use these methods in the worker context thread.)
+ virtual void postMessageToWorkerObject(const String& message);
+ virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL);
+ virtual void postConsoleMessageToWorkerObject(MessageDestination, MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL);
+ virtual void confirmMessageFromWorkerObject(bool hasPendingActivity);
+ virtual void reportPendingActivity(bool hasPendingActivity);
+ virtual void workerContextDestroyed();
+
+ void postTaskToWorkerObject(PassRefPtr<ScriptExecutionContext::Task>);
+ void postTaskToWorkerContext(PassRefPtr<ScriptExecutionContext::Task>);
+ void postTaskForModeToWorkerContext(PassRefPtr<ScriptExecutionContext::Task>, const String& mode);
void workerThreadCreated(PassRefPtr<WorkerThread>);
- void workerObjectDestroyed();
- void workerContextDestroyed();
-
- void terminate();
- void confirmWorkerThreadMessage(bool hasPendingActivity);
- void reportWorkerThreadActivity(bool hasPendingActivity);
- bool workerThreadHasPendingActivity() const;
+ // Only use this method on the worker object thread.
+ bool askedToTerminate() const { return m_askedToTerminate; }
private:
- friend class GenericWorkerTaskBase;
friend class MessageWorkerTask;
friend class WorkerContextDestroyedTask;
- friend class WorkerExceptionTask;
friend class WorkerThreadActivityReportTask;
- ~WorkerMessagingProxy();
+ virtual ~WorkerMessagingProxy();
void workerContextDestroyedInternal();
- void reportWorkerThreadActivityInternal(bool confirmingMessage, bool hasPendingActivity);
+ void reportPendingActivityInternal(bool confirmingMessage, bool hasPendingActivity);
Worker* workerObject() const { return m_workerObject; }
- bool askedToTerminate() { return m_askedToTerminate; }
RefPtr<ScriptExecutionContext> m_scriptExecutionContext;
Worker* m_workerObject;
@@ -86,7 +94,7 @@ namespace WebCore {
bool m_askedToTerminate;
- Vector<RefPtr<WorkerTask> > m_queuedEarlyTasks; // Tasks are queued here until there's a thread object created.
+ Vector<RefPtr<ScriptExecutionContext::Task> > m_queuedEarlyTasks; // Tasks are queued here until there's a thread object created.
};
} // namespace WebCore
diff --git a/WebCore/workers/WorkerObjectProxy.h b/WebCore/workers/WorkerObjectProxy.h
new file mode 100644
index 0000000..3b86028
--- /dev/null
+++ b/WebCore/workers/WorkerObjectProxy.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerObjectProxy_h
+#define WorkerObjectProxy_h
+
+#if ENABLE(WORKERS)
+
+#include "Console.h"
+
+namespace WebCore {
+
+ class String;
+
+ // A proxy to talk to the worker object.
+ class WorkerObjectProxy {
+ public:
+ virtual ~WorkerObjectProxy() {}
+
+ virtual void postMessageToWorkerObject(const String&) = 0;
+
+ virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL) = 0;
+
+ virtual void postConsoleMessageToWorkerObject(MessageDestination, MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL) = 0;
+
+ virtual void confirmMessageFromWorkerObject(bool hasPendingActivity) = 0;
+
+ virtual void reportPendingActivity(bool hasPendingActivity) = 0;
+
+ virtual void workerContextDestroyed() = 0;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerObjectProxy_h
diff --git a/WebCore/workers/WorkerRunLoop.cpp b/WebCore/workers/WorkerRunLoop.cpp
new file mode 100644
index 0000000..1e5e510
--- /dev/null
+++ b/WebCore/workers/WorkerRunLoop.cpp
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include "SharedTimer.h"
+#include "ThreadGlobalData.h"
+#include "ThreadTimers.h"
+#include "WorkerRunLoop.h"
+#include "WorkerContext.h"
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+class WorkerSharedTimer : public SharedTimer {
+public:
+ WorkerSharedTimer()
+ : m_sharedTimerFunction(0)
+ , m_nextFireTime(0)
+ {
+ }
+
+ // SharedTimer interface.
+ virtual void setFiredFunction(void (*function)()) { m_sharedTimerFunction = function; }
+ virtual void setFireTime(double fireTime) { m_nextFireTime = fireTime; }
+ virtual void stop() { m_nextFireTime = 0; }
+
+ bool isActive() { return m_sharedTimerFunction && m_nextFireTime; }
+ double fireTime() { return m_nextFireTime; }
+ void fire() { m_sharedTimerFunction(); }
+
+private:
+ void (*m_sharedTimerFunction)();
+ double m_nextFireTime;
+};
+
+class WorkerRunLoop::Task : public RefCounted<Task> {
+public:
+ static PassRefPtr<Task> create(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode)
+ {
+ return adoptRef(new Task(task, mode));
+ }
+
+ const String& mode() const { return m_mode; }
+ void performTask(ScriptExecutionContext* context) { m_task->performTask(context); }
+
+private:
+ Task(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode)
+ : m_task(task)
+ , m_mode(mode.copy())
+ {
+ }
+
+ RefPtr<ScriptExecutionContext::Task> m_task;
+ String m_mode;
+};
+
+class ModePredicate {
+public:
+ ModePredicate(const String& mode)
+ : m_mode(mode)
+ , m_defaultMode(mode == WorkerRunLoop::defaultMode())
+ {
+ }
+
+ bool isDefaultMode() const
+ {
+ return m_defaultMode;
+ }
+
+ bool operator()(PassRefPtr<WorkerRunLoop::Task> task) const
+ {
+ return m_defaultMode || m_mode == task->mode();
+ }
+
+private:
+ String m_mode;
+ bool m_defaultMode;
+};
+
+WorkerRunLoop::WorkerRunLoop()
+ : m_sharedTimer(new WorkerSharedTimer)
+ , m_nestedCount(0)
+ , m_uniqueId(0)
+{
+}
+
+WorkerRunLoop::~WorkerRunLoop()
+{
+ ASSERT(!m_nestedCount);
+}
+
+String WorkerRunLoop::defaultMode()
+{
+ return String();
+}
+
+class RunLoopSetup : Noncopyable
+{
+public:
+ RunLoopSetup(WorkerRunLoop& runLoop)
+ : m_runLoop(runLoop)
+ {
+ if (!m_runLoop.m_nestedCount)
+ threadGlobalData().threadTimers().setSharedTimer(m_runLoop.m_sharedTimer.get());
+ m_runLoop.m_nestedCount++;
+ }
+
+ ~RunLoopSetup()
+ {
+ m_runLoop.m_nestedCount--;
+ if (!m_runLoop.m_nestedCount)
+ threadGlobalData().threadTimers().setSharedTimer(0);
+ }
+private:
+ WorkerRunLoop& m_runLoop;
+};
+
+void WorkerRunLoop::run(WorkerContext* context)
+{
+ RunLoopSetup setup(*this);
+ ModePredicate modePredicate(defaultMode());
+ MessageQueueWaitResult result;
+ do {
+ result = runInMode(context, modePredicate);
+ } while (result != MessageQueueTerminated);
+}
+
+MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerContext* context, const String& mode)
+{
+ RunLoopSetup setup(*this);
+ ModePredicate modePredicate(mode);
+ MessageQueueWaitResult result = runInMode(context, modePredicate);
+ return result;
+}
+
+MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerContext* context, const ModePredicate& predicate)
+{
+ ASSERT(context);
+ ASSERT(context->thread());
+ ASSERT(context->thread()->threadID() == currentThread());
+
+ double absoluteTime = (predicate.isDefaultMode() && m_sharedTimer->isActive()) ? m_sharedTimer->fireTime() : MessageQueue<RefPtr<Task> >::infiniteTime();
+ RefPtr<Task> task;
+ MessageQueueWaitResult result = m_messageQueue.waitForMessageFilteredWithTimeout(task, predicate, absoluteTime);
+
+ switch (result) {
+ case MessageQueueTerminated:
+ break;
+
+ case MessageQueueMessageReceived:
+ task->performTask(context);
+ break;
+
+ case MessageQueueTimeout:
+ m_sharedTimer->fire();
+ break;
+ }
+
+ return result;
+}
+
+void WorkerRunLoop::terminate()
+{
+ m_messageQueue.kill();
+}
+
+void WorkerRunLoop::postTask(PassRefPtr<ScriptExecutionContext::Task> task)
+{
+ postTaskForMode(task, defaultMode());
+}
+
+void WorkerRunLoop::postTaskForMode(PassRefPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ m_messageQueue.append(Task::create(task, mode.copy()));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/workers/WorkerRunLoop.h b/WebCore/workers/WorkerRunLoop.h
new file mode 100644
index 0000000..5f74f01
--- /dev/null
+++ b/WebCore/workers/WorkerRunLoop.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerRunLoop_h
+#define WorkerRunLoop_h
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include <wtf/MessageQueue.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+ class ModePredicate;
+ class WorkerContext;
+ class WorkerSharedTimer;
+
+ class WorkerRunLoop {
+ public:
+ WorkerRunLoop();
+ ~WorkerRunLoop();
+
+ // Blocking call. Waits for tasks and timers, invokes the callbacks.
+ void run(WorkerContext*);
+
+ // Waits for a single task and returns.
+ MessageQueueWaitResult runInMode(WorkerContext*, const String& mode);
+
+ void terminate();
+ bool terminated() { return m_messageQueue.killed(); }
+
+ void postTask(PassRefPtr<ScriptExecutionContext::Task>);
+ void postTaskForMode(PassRefPtr<ScriptExecutionContext::Task>, const String& mode);
+
+ unsigned long createUniqueId() { return ++m_uniqueId; }
+
+ static String defaultMode();
+ class Task;
+ private:
+ friend class RunLoopSetup;
+ MessageQueueWaitResult runInMode(WorkerContext*, const ModePredicate&);
+
+ MessageQueue<RefPtr<Task> > m_messageQueue;
+ OwnPtr<WorkerSharedTimer> m_sharedTimer;
+ int m_nestedCount;
+ unsigned long m_uniqueId;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerRunLoop_h
diff --git a/WebCore/dom/WorkerThread.cpp b/WebCore/workers/WorkerThread.cpp
index a762e0b..d1026b1 100644
--- a/WebCore/dom/WorkerThread.cpp
+++ b/WebCore/workers/WorkerThread.cpp
@@ -34,10 +34,8 @@
#include "PlatformString.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
-#include "Worker.h"
#include "WorkerContext.h"
-#include "WorkerMessagingProxy.h"
-#include "WorkerTask.h"
+#include "WorkerObjectProxy.h"
#include <utility>
#include <wtf/Noncopyable.h>
@@ -64,14 +62,14 @@ WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const St
{
}
-PassRefPtr<WorkerThread> WorkerThread::create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy* messagingProxy)
+PassRefPtr<WorkerThread> WorkerThread::create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerObjectProxy* workerObjectProxy)
{
- return adoptRef(new WorkerThread(scriptURL, userAgent, sourceCode, messagingProxy));
+ return adoptRef(new WorkerThread(scriptURL, userAgent, sourceCode, workerObjectProxy));
}
-WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy* messagingProxy)
+WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerObjectProxy* workerObjectProxy)
: m_threadID(0)
- , m_messagingProxy(messagingProxy)
+ , m_workerObjectProxy(workerObjectProxy)
, m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode))
{
}
@@ -88,7 +86,7 @@ bool WorkerThread::start()
if (m_threadID)
return true;
- m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore::Worker");
+ m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: Worker");
return m_threadID;
}
@@ -117,13 +115,14 @@ void* WorkerThread::workerThread()
// WorkerThread::~WorkerThread happens on a different thread where it was created.
m_startupData.clear();
- m_messagingProxy->confirmWorkerThreadMessage(m_workerContext->hasPendingActivity()); // This wasn't really a message, but it counts as one for GC.
+ m_workerObjectProxy->reportPendingActivity(m_workerContext->hasPendingActivity());
// Blocks until terminated.
m_runLoop.run(m_workerContext.get());
ThreadIdentifier threadID = m_threadID;
+ m_workerContext->stopActiveDOMObjects();
m_workerContext->clearScript();
ASSERT(m_workerContext->hasOneRef());
// The below assignment will destroy the context, which will in turn notify messaging proxy.
diff --git a/WebCore/dom/WorkerThread.h b/WebCore/workers/WorkerThread.h
index 504db81..f1a8a52 100644
--- a/WebCore/dom/WorkerThread.h
+++ b/WebCore/workers/WorkerThread.h
@@ -29,7 +29,7 @@
#if ENABLE(WORKERS)
-#include <WorkerRunLoop.h>
+#include "WorkerRunLoop.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -39,13 +39,12 @@ namespace WebCore {
class KURL;
class String;
class WorkerContext;
- class WorkerMessagingProxy;
- class WorkerTask;
+ class WorkerObjectProxy;
struct WorkerThreadStartupData;
class WorkerThread : public RefCounted<WorkerThread> {
public:
- static PassRefPtr<WorkerThread> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy*);
+ static PassRefPtr<WorkerThread> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerObjectProxy*);
~WorkerThread();
bool start();
@@ -53,17 +52,17 @@ namespace WebCore {
ThreadIdentifier threadID() const { return m_threadID; }
WorkerRunLoop& runLoop() { return m_runLoop; }
- WorkerMessagingProxy* messagingProxy() const { return m_messagingProxy; }
+ WorkerObjectProxy* workerObjectProxy() const { return m_workerObjectProxy; }
private:
- WorkerThread(const KURL&, const String& userAgent, const String& sourceCode, WorkerMessagingProxy*);
+ WorkerThread(const KURL&, const String& userAgent, const String& sourceCode, WorkerObjectProxy*);
static void* workerThreadStart(void*);
void* workerThread();
ThreadIdentifier m_threadID;
WorkerRunLoop m_runLoop;
- WorkerMessagingProxy* m_messagingProxy;
+ WorkerObjectProxy* m_workerObjectProxy;
RefPtr<WorkerContext> m_workerContext;
Mutex m_threadCreationMutex;
@@ -76,3 +75,4 @@ namespace WebCore {
#endif // ENABLE(WORKERS)
#endif // WorkerThread_h
+
diff --git a/WebCore/xml/XMLHttpRequest.cpp b/WebCore/xml/XMLHttpRequest.cpp
index f16755a..dd3f361 100644
--- a/WebCore/xml/XMLHttpRequest.cpp
+++ b/WebCore/xml/XMLHttpRequest.cpp
@@ -23,6 +23,8 @@
#include "XMLHttpRequest.h"
#include "CString.h"
+#include "CrossOriginAccessControl.h"
+#include "CrossOriginPreflightResultCache.h"
#include "DOMImplementation.h"
#include "Document.h"
#include "Event.h"
@@ -31,23 +33,17 @@
#include "EventNames.h"
#include "File.h"
#include "HTTPParsers.h"
-#include "KURL.h"
-#include "KURLHash.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
-#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
#include "Settings.h"
-#include "SystemTime.h"
#include "TextResourceDecoder.h"
#include "ThreadableLoader.h"
#include "XMLHttpRequestException.h"
#include "XMLHttpRequestProgressEvent.h"
#include "XMLHttpRequestUpload.h"
#include "markup.h"
-#include <wtf/CurrentTime.h>
-#include <wtf/Noncopyable.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/Threading.h>
#if USE(JSC)
#include "JSDOMWindow.h"
@@ -55,14 +51,11 @@
namespace WebCore {
-typedef HashSet<String, CaseFoldingHash> HeadersSet;
-
struct XMLHttpRequestStaticData {
XMLHttpRequestStaticData();
String m_proxyHeaderPrefix;
String m_secHeaderPrefix;
HashSet<String, CaseFoldingHash> m_forbiddenRequestHeaders;
- HashSet<String, CaseFoldingHash> m_allowedCrossSiteResponseHeaders;
};
XMLHttpRequestStaticData::XMLHttpRequestStaticData()
@@ -71,76 +64,26 @@ XMLHttpRequestStaticData::XMLHttpRequestStaticData()
{
m_forbiddenRequestHeaders.add("accept-charset");
m_forbiddenRequestHeaders.add("accept-encoding");
+ m_forbiddenRequestHeaders.add("access-control-request-headers");
+ m_forbiddenRequestHeaders.add("access-control-request-method");
+ m_forbiddenRequestHeaders.add("authorization");
m_forbiddenRequestHeaders.add("connection");
m_forbiddenRequestHeaders.add("content-length");
m_forbiddenRequestHeaders.add("content-transfer-encoding");
+ m_forbiddenRequestHeaders.add("cookie");
+ m_forbiddenRequestHeaders.add("cookie2");
m_forbiddenRequestHeaders.add("date");
m_forbiddenRequestHeaders.add("expect");
m_forbiddenRequestHeaders.add("host");
m_forbiddenRequestHeaders.add("keep-alive");
+ m_forbiddenRequestHeaders.add("origin");
m_forbiddenRequestHeaders.add("referer");
m_forbiddenRequestHeaders.add("te");
m_forbiddenRequestHeaders.add("trailer");
m_forbiddenRequestHeaders.add("transfer-encoding");
m_forbiddenRequestHeaders.add("upgrade");
+ m_forbiddenRequestHeaders.add("user-agent");
m_forbiddenRequestHeaders.add("via");
-
- m_allowedCrossSiteResponseHeaders.add("cache-control");
- m_allowedCrossSiteResponseHeaders.add("content-language");
- m_allowedCrossSiteResponseHeaders.add("content-type");
- m_allowedCrossSiteResponseHeaders.add("expires");
- m_allowedCrossSiteResponseHeaders.add("last-modified");
- m_allowedCrossSiteResponseHeaders.add("pragma");
-}
-
-class PreflightResultCacheItem : Noncopyable {
-public:
- PreflightResultCacheItem(bool credentials)
- : m_absoluteExpiryTime(0)
- , m_credentials(credentials)
- {
- }
-
- bool parse(const ResourceResponse&);
- bool allowsCrossSiteMethod(const String&) const;
- bool allowsCrossSiteHeaders(const HTTPHeaderMap&) const;
- bool allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const;
-
-private:
- template<class HashType>
- static void addToAccessControlAllowList(const String& string, unsigned start, unsigned end, HashSet<String, HashType>&);
- template<class HashType>
- static bool parseAccessControlAllowList(const String& string, HashSet<String, HashType>&);
- static bool parseAccessControlMaxAge(const String& string, unsigned& expiryDelta);
-
- // FIXME: A better solution to holding onto the absolute expiration time might be
- // to start a timer for the expiration delta, that removes this from the cache when
- // it fires.
- double m_absoluteExpiryTime;
- bool m_credentials;
- HashSet<String> m_methods;
- HeadersSet m_headers;
-};
-
-class PreflightResultCache : Noncopyable {
-public:
- static PreflightResultCache& shared();
-
- void appendEntry(const String& origin, const KURL&, PreflightResultCacheItem*);
- bool canSkipPreflight(const String& origin, const KURL&, bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
-
-private:
- PreflightResultCache() { }
-
- typedef HashMap<std::pair<String, KURL>, PreflightResultCacheItem*> PreflightResultHashMap;
-
- PreflightResultHashMap m_preflightHashMap;
- Mutex m_mutex;
-};
-
-static bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name)
-{
- return equalIgnoringCase(name, "accept") || equalIgnoringCase(name, "accept-language") || equalIgnoringCase(name, "content-type");
}
// Determines if a string is a valid token, as defined by
@@ -177,131 +120,6 @@ static bool isSetCookieHeader(const AtomicString& name)
return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set-cookie2");
}
-template<class HashType>
-void PreflightResultCacheItem::addToAccessControlAllowList(const String& string, unsigned start, unsigned end, HashSet<String, HashType>& set)
-{
- StringImpl* stringImpl = string.impl();
- if (!stringImpl)
- return;
-
- // Skip white space from start.
- while (start <= end && isSpaceOrNewline((*stringImpl)[start]))
- start++;
-
- // only white space
- if (start > end)
- return;
-
- // Skip white space from end.
- while (end && isSpaceOrNewline((*stringImpl)[end]))
- end--;
-
- // substringCopy() is called on the strings because the cache is accessed on multiple threads.
- set.add(string.substringCopy(start, end - start + 1));
-}
-
-
-template<class HashType>
-bool PreflightResultCacheItem::parseAccessControlAllowList(const String& string, HashSet<String, HashType>& set)
-{
- int start = 0;
- int end;
- while ((end = string.find(',', start)) != -1) {
- if (start == end)
- return false;
-
- addToAccessControlAllowList(string, start, end - 1, set);
- start = end + 1;
- }
- if (start != static_cast<int>(string.length()))
- addToAccessControlAllowList(string, start, string.length() - 1, set);
-
- return true;
-}
-
-bool PreflightResultCacheItem::parseAccessControlMaxAge(const String& string, unsigned& expiryDelta)
-{
- // FIXME: this will not do the correct thing for a number starting with a '+'
- bool ok = false;
- expiryDelta = string.toUIntStrict(&ok);
- return ok;
-}
-
-bool PreflightResultCacheItem::parse(const ResourceResponse& response)
-{
- m_methods.clear();
- if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Methods"), m_methods))
- return false;
-
- m_headers.clear();
- if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Headers"), m_headers))
- return false;
-
- unsigned expiryDelta = 0;
- if (!parseAccessControlMaxAge(response.httpHeaderField("Access-Control-Max-Age"), expiryDelta))
- expiryDelta = 5;
-
- m_absoluteExpiryTime = currentTime() + expiryDelta;
- return true;
-}
-
-bool PreflightResultCacheItem::allowsCrossSiteMethod(const String& method) const
-{
- return m_methods.contains(method) || method == "GET" || method == "POST";
-}
-
-bool PreflightResultCacheItem::allowsCrossSiteHeaders(const HTTPHeaderMap& requestHeaders) const
-{
- HTTPHeaderMap::const_iterator end = requestHeaders.end();
- for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
- if (!m_headers.contains(it->first) && !isOnAccessControlSimpleRequestHeaderWhitelist(it->first))
- return false;
- }
- return true;
-}
-
-bool PreflightResultCacheItem::allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const
-{
- if (m_absoluteExpiryTime < currentTime())
- return false;
- if (includeCredentials && !m_credentials)
- return false;
- if (!allowsCrossSiteMethod(method))
- return false;
- if (!allowsCrossSiteHeaders(requestHeaders))
- return false;
- return true;
-}
-
-PreflightResultCache& PreflightResultCache::shared()
-{
- AtomicallyInitializedStatic(PreflightResultCache&, cache = *new PreflightResultCache);
- return cache;
-}
-
-void PreflightResultCache::appendEntry(const String& origin, const KURL& url, PreflightResultCacheItem* preflightResult)
-{
- MutexLocker lock(m_mutex);
- // Note that the entry may already be present in the HashMap if another thread is accessing the same location.
- m_preflightHashMap.set(std::make_pair(origin.copy(), url.copy()), preflightResult);
-}
-
-bool PreflightResultCache::canSkipPreflight(const String& origin, const KURL& url, bool includeCredentials,
- const String& method, const HTTPHeaderMap& requestHeaders)
-{
- MutexLocker lock(m_mutex);
- PreflightResultHashMap::iterator cacheIt = m_preflightHashMap.find(std::make_pair(origin, url));
- if (cacheIt == m_preflightHashMap.end())
- return false;
-
- if (cacheIt->second->allowsRequest(includeCredentials, method, requestHeaders))
- return true;
-
- delete cacheIt->second;
- m_preflightHashMap.remove(cacheIt);
- return false;
-}
-
static const XMLHttpRequestStaticData* staticData = 0;
static const XMLHttpRequestStaticData* createXMLHttpRequestStaticData()
@@ -330,6 +148,7 @@ XMLHttpRequest::XMLHttpRequest(ScriptExecutionContext* context)
, m_inPreflight(false)
, m_receivedLength(0)
, m_lastSendLineNumber(0)
+ , m_exceptionCode(0)
{
initializeXMLHttpRequestStaticData();
}
@@ -379,7 +198,7 @@ Document* XMLHttpRequest::responseXML() const
m_responseXML = document()->implementation()->createDocument(0);
m_responseXML->open();
m_responseXML->setURL(m_url);
- // FIXME: set Last-Modified and cookies (currently, those are only available for HTMLDocuments).
+ // FIXME: Set Last-Modified.
m_responseXML->write(String(m_responseText));
m_responseXML->finishParsing();
m_responseXML->close();
@@ -629,19 +448,28 @@ void XMLHttpRequest::send(File* body, ExceptionCode& ec)
void XMLHttpRequest::createRequest(ExceptionCode& ec)
{
+ // Upload event listeners should be disallowed for simple cross-origin requests, because POSTing to an URL that does not
+ // permit cross origin requests should look exactly like POSTing to an URL that does not respond at all. If a listener exists
+ // when creating the request, it will force preflight.
+ // Also, only async requests support upload progress events.
+ m_uploadEventsAllowed = false;
if (m_async) {
dispatchLoadStartEvent();
- if (m_requestEntityBody && m_upload)
+ if (m_requestEntityBody && m_upload) {
+ m_uploadEventsAllowed = m_upload->hasListeners();
m_upload->dispatchLoadStartEvent();
+ }
}
m_sameOriginRequest = scriptExecutionContext()->securityOrigin()->canRequest(m_url);
if (!m_sameOriginRequest) {
- makeCrossSiteAccessRequest(ec);
+ makeCrossOriginAccessRequest(ec);
return;
}
+ m_uploadEventsAllowed = true;
+
makeSameOriginRequest(ec);
}
@@ -654,6 +482,7 @@ void XMLHttpRequest::makeSameOriginRequest(ExceptionCode& ec)
if (m_requestEntityBody) {
ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
request.setHTTPBody(m_requestEntityBody.release());
}
@@ -666,33 +495,19 @@ void XMLHttpRequest::makeSameOriginRequest(ExceptionCode& ec)
loadRequestSynchronously(request, ec);
}
-bool XMLHttpRequest::isSimpleCrossSiteAccessRequest() const
-{
- if (m_method != "GET" && m_method != "POST")
- return false;
-
- HTTPHeaderMap::const_iterator end = m_requestHeaders.end();
- for (HTTPHeaderMap::const_iterator it = m_requestHeaders.begin(); it != end; ++it) {
- if (!isOnAccessControlSimpleRequestHeaderWhitelist(it->first))
- return false;
- }
-
- return true;
-}
-
-void XMLHttpRequest::makeCrossSiteAccessRequest(ExceptionCode& ec)
+void XMLHttpRequest::makeCrossOriginAccessRequest(ExceptionCode& ec)
{
ASSERT(!m_sameOriginRequest);
- if (isSimpleCrossSiteAccessRequest())
- makeSimpleCrossSiteAccessRequest(ec);
+ if (!m_uploadEventsAllowed && isSimpleCrossOriginAccessRequest(m_method, m_requestHeaders))
+ makeSimpleCrossOriginAccessRequest(ec);
else
- makeCrossSiteAccessRequestWithPreflight(ec);
+ makeCrossOriginAccessRequestWithPreflight(ec);
}
-void XMLHttpRequest::makeSimpleCrossSiteAccessRequest(ExceptionCode& ec)
+void XMLHttpRequest::makeSimpleCrossOriginAccessRequest(ExceptionCode& ec)
{
- ASSERT(isSimpleCrossSiteAccessRequest());
+ ASSERT(isSimpleCrossOriginAccessRequest(m_method, m_requestHeaders));
KURL url = m_url;
url.setUser(String());
@@ -706,20 +521,26 @@ void XMLHttpRequest::makeSimpleCrossSiteAccessRequest(ExceptionCode& ec)
if (m_requestHeaders.size() > 0)
request.addHTTPHeaderFields(m_requestHeaders);
+ if (m_requestEntityBody) {
+ ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
+ request.setHTTPBody(m_requestEntityBody.release());
+ }
+
if (m_async)
loadRequestAsynchronously(request);
else
loadRequestSynchronously(request, ec);
}
-void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
+void XMLHttpRequest::makeCrossOriginAccessRequestWithPreflight(ExceptionCode& ec)
{
String origin = scriptExecutionContext()->securityOrigin()->toString();
KURL url = m_url;
url.setUser(String());
url.setPass(String());
- if (!PreflightResultCache::shared().canSkipPreflight(origin, url, m_includeCredentials, m_method, m_requestHeaders)) {
+ if (!CrossOriginPreflightResultCache::shared().canSkipPreflight(origin, url, m_includeCredentials, m_method, m_requestHeaders)) {
m_inPreflight = true;
ResourceRequest preflightRequest(url);
preflightRequest.setHTTPMethod("OPTIONS");
@@ -744,6 +565,7 @@ void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
}
if (m_async) {
+ m_uploadEventsAllowed = true;
loadRequestAsynchronously(preflightRequest);
return;
}
@@ -766,10 +588,12 @@ void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
if (m_requestEntityBody) {
ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
request.setHTTPBody(m_requestEntityBody.release());
}
if (m_async) {
+ m_uploadEventsAllowed = true;
loadRequestAsynchronously(request);
return;
}
@@ -798,43 +622,30 @@ void XMLHttpRequest::handleAsynchronousPreflightResult()
if (m_requestEntityBody) {
ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
request.setHTTPBody(m_requestEntityBody.release());
}
+ m_uploadEventsAllowed = true;
loadRequestAsynchronously(request);
}
void XMLHttpRequest::loadRequestSynchronously(ResourceRequest& request, ExceptionCode& ec)
{
ASSERT(!m_async);
- Vector<char> data;
- ResourceError error;
- ResourceResponse response;
- unsigned long identifier = ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, error, response, data);
m_loader = 0;
-
- // No exception for file:/// resources, see <rdar://problem/4962298>.
- // Also, if we have an HTTP response, then it wasn't a network error in fact.
- if (error.isNull() || request.url().isLocalFile() || response.httpStatusCode() > 0) {
- processSyncLoadResults(identifier, data, response, ec);
- return;
- }
-
- if (error.isCancellation()) {
- abortError();
- ec = XMLHttpRequestException::ABORT_ERR;
- return;
- }
-
- networkError();
- ec = XMLHttpRequestException::NETWORK_ERR;
+ m_exceptionCode = 0;
+ ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, *this);
+ if (!m_exceptionCode && m_error)
+ m_exceptionCode = XMLHttpRequestException::NETWORK_ERR;
+ ec = m_exceptionCode;
}
-
void XMLHttpRequest::loadRequestAsynchronously(ResourceRequest& request)
{
ASSERT(m_async);
+ m_exceptionCode = 0;
// SubresourceLoader::create can return null here, for example if we're no longer attached to a page.
// This is true while running onunload handlers.
// FIXME: We need to be able to send XMLHttpRequests from onunload, <http://bugs.webkit.org/show_bug.cgi?id=10904>.
@@ -842,7 +653,11 @@ void XMLHttpRequest::loadRequestAsynchronously(ResourceRequest& request)
// We need to keep content sniffing enabled for local files due to CFNetwork not providing a MIME type
// for local files otherwise, <rdar://problem/5671813>.
LoadCallbacks callbacks = m_inPreflight ? DoNotSendLoadCallbacks : SendLoadCallbacks;
- ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
+ ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
+
+ if (m_upload)
+ request.setReportUploadProgress(true);
+
m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, callbacks, contentSniff);
if (m_loader) {
@@ -876,7 +691,7 @@ void XMLHttpRequest::abort()
dispatchAbortEvent();
if (!m_uploadComplete) {
m_uploadComplete = true;
- if (m_upload)
+ if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchAbortEvent();
}
}
@@ -931,9 +746,10 @@ void XMLHttpRequest::networkError()
dispatchErrorEvent();
if (!m_uploadComplete) {
m_uploadComplete = true;
- if (m_upload)
+ if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchErrorEvent();
}
+ internalAbort();
}
void XMLHttpRequest::abortError()
@@ -942,7 +758,7 @@ void XMLHttpRequest::abortError()
dispatchAbortEvent();
if (!m_uploadComplete) {
m_uploadComplete = true;
- if (m_upload)
+ if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchAbortEvent();
}
}
@@ -1081,11 +897,6 @@ String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionCode
return m_response.httpHeaderField(name);
}
-bool XMLHttpRequest::isOnAccessControlResponseHeaderWhitelist(const String& name) const
-{
- return staticData->m_allowedCrossSiteResponseHeaders.contains(name);
-}
-
String XMLHttpRequest::responseMIMEType() const
{
String mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride);
@@ -1122,54 +933,36 @@ int XMLHttpRequest::status(ExceptionCode& ec) const
String XMLHttpRequest::statusText(ExceptionCode& ec) const
{
- // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=3547> XMLHttpRequest.statusText returns always "OK".
- if (m_response.httpStatusCode())
- return "OK";
+ if (!m_response.httpStatusText().isNull())
+ return m_response.httpStatusText();
if (m_state == OPENED) {
- // See comments in getStatus() above.
+ // See comments in status() above.
ec = INVALID_STATE_ERR;
}
return String();
}
-void XMLHttpRequest::processSyncLoadResults(unsigned long identifier, const Vector<char>& data, const ResourceResponse& response, ExceptionCode& ec)
-{
- if (m_sameOriginRequest && !scriptExecutionContext()->securityOrigin()->canRequest(response.url())) {
- abort();
- return;
- }
-
- didReceiveResponse(response);
- changeState(HEADERS_RECEIVED);
-
- const char* bytes = static_cast<const char*>(data.data());
- int len = static_cast<int>(data.size());
- didReceiveData(bytes, len);
-
- didFinishLoading(identifier);
- if (m_error)
- ec = XMLHttpRequestException::NETWORK_ERR;
-}
-
-void XMLHttpRequest::didFail()
+void XMLHttpRequest::didFail(const ResourceError& error)
{
// If we are already in an error state, for instance we called abort(), bail out early.
if (m_error)
return;
- internalAbort();
+ if (error.isCancellation()) {
+ m_exceptionCode = XMLHttpRequestException::ABORT_ERR;
+ abortError();
+ return;
+ }
+
+ m_exceptionCode = XMLHttpRequestException::NETWORK_ERR;
networkError();
}
-void XMLHttpRequest::didGetCancelled()
+void XMLHttpRequest::didFailRedirectCheck()
{
- // If we are already in an error state, for instance we called abort(), bail out early.
- if (m_error)
- return;
-
- abortError();
+ networkError();
}
void XMLHttpRequest::didFinishLoading(unsigned long identifier)
@@ -1219,31 +1012,14 @@ void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long lon
if (!m_upload)
return;
- m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
+ if (m_uploadEventsAllowed)
+ m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
m_uploadComplete = true;
- m_upload->dispatchLoadEvent();
- }
-}
-
-bool XMLHttpRequest::accessControlCheck(const ResourceResponse& response)
-{
- const String& accessControlOriginString = response.httpHeaderField("Access-Control-Origin");
- if (accessControlOriginString == "*" && !m_includeCredentials)
- return true;
-
- RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);
- if (!accessControlOrigin->isSameSchemeHostPort(scriptExecutionContext()->securityOrigin()))
- return false;
-
- if (m_includeCredentials) {
- const String& accessControlCredentialsString = response.httpHeaderField("Access-Control-Credentials");
- if (accessControlCredentialsString != "true")
- return false;
+ if (m_uploadEventsAllowed)
+ m_upload->dispatchLoadEvent();
}
-
- return true;
}
void XMLHttpRequest::didReceiveResponse(const ResourceResponse& response)
@@ -1254,7 +1030,7 @@ void XMLHttpRequest::didReceiveResponse(const ResourceResponse& response)
}
if (!m_sameOriginRequest) {
- if (!accessControlCheck(response)) {
+ if (!passesAccessControlCheck(response, m_includeCredentials, scriptExecutionContext()->securityOrigin())) {
networkError();
return;
}
@@ -1271,20 +1047,20 @@ void XMLHttpRequest::didReceiveResponsePreflight(const ResourceResponse& respons
ASSERT(m_inPreflight);
ASSERT(!m_sameOriginRequest);
- if (!accessControlCheck(response)) {
+ if (!passesAccessControlCheck(response, m_includeCredentials, scriptExecutionContext()->securityOrigin())) {
networkError();
return;
}
- OwnPtr<PreflightResultCacheItem> preflightResult(new PreflightResultCacheItem(m_includeCredentials));
+ OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult(new CrossOriginPreflightResultCacheItem(m_includeCredentials));
if (!preflightResult->parse(response)
- || !preflightResult->allowsCrossSiteMethod(m_method)
- || !preflightResult->allowsCrossSiteHeaders(m_requestHeaders)) {
+ || !preflightResult->allowsCrossOriginMethod(m_method)
+ || !preflightResult->allowsCrossOriginHeaders(m_requestHeaders)) {
networkError();
return;
}
- PreflightResultCache::shared().appendEntry(scriptExecutionContext()->securityOrigin()->toString(), m_url, preflightResult.release());
+ CrossOriginPreflightResultCache::shared().appendEntry(scriptExecutionContext()->securityOrigin()->toString(), m_url, preflightResult.release());
}
void XMLHttpRequest::didReceiveAuthenticationCancellation(const ResourceResponse& failureResponse)
@@ -1294,7 +1070,7 @@ void XMLHttpRequest::didReceiveAuthenticationCancellation(const ResourceResponse
void XMLHttpRequest::didReceiveData(const char* data, int len)
{
- if (m_inPreflight)
+ if (m_inPreflight || m_error)
return;
if (m_state < HEADERS_RECEIVED)
@@ -1304,13 +1080,16 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
if (!m_responseEncoding.isEmpty())
m_decoder = TextResourceDecoder::create("text/plain", m_responseEncoding);
// allow TextResourceDecoder to look inside the m_response if it's XML or HTML
- else if (responseIsXML())
+ else if (responseIsXML()) {
m_decoder = TextResourceDecoder::create("application/xml");
- else if (responseMIMEType() == "text/html")
+ // Don't stop on encoding errors, unlike it is done for other kinds of XML resources. This matches the behavior of previous WebKit versions, Firefox and Opera.
+ m_decoder->useLenientXMLDecoding();
+ } else if (responseMIMEType() == "text/html")
m_decoder = TextResourceDecoder::create("text/html", "UTF-8");
else
m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");
}
+
if (!len)
return;
diff --git a/WebCore/xml/XMLHttpRequest.h b/WebCore/xml/XMLHttpRequest.h
index d7c0d36..544866a 100644
--- a/WebCore/xml/XMLHttpRequest.h
+++ b/WebCore/xml/XMLHttpRequest.h
@@ -34,7 +34,7 @@ namespace WebCore {
class Document;
class File;
-class ResourceRequest;
+struct ResourceRequest;
class TextResourceDecoder;
class ThreadableLoader;
@@ -129,15 +129,14 @@ private:
virtual void didReceiveResponse(const ResourceResponse&);
virtual void didReceiveData(const char* data, int lengthReceived);
virtual void didFinishLoading(unsigned long identifier);
- virtual void didFail();
- virtual void didGetCancelled();
+ virtual void didFail(const ResourceError&);
+ virtual void didFailRedirectCheck();
virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
// Special versions for the preflight
void didReceiveResponsePreflight(const ResourceResponse&);
void didFinishLoadingPreflight();
- void processSyncLoadResults(unsigned long identifier, const Vector<char>& data, const ResourceResponse&, ExceptionCode&);
void updateAndDispatchOnProgress(unsigned int len);
String responseMIMEType() const;
@@ -159,21 +158,15 @@ private:
void createRequest(ExceptionCode&);
void makeSameOriginRequest(ExceptionCode&);
- void makeCrossSiteAccessRequest(ExceptionCode&);
+ void makeCrossOriginAccessRequest(ExceptionCode&);
- void makeSimpleCrossSiteAccessRequest(ExceptionCode&);
- void makeCrossSiteAccessRequestWithPreflight(ExceptionCode&);
+ void makeSimpleCrossOriginAccessRequest(ExceptionCode&);
+ void makeCrossOriginAccessRequestWithPreflight(ExceptionCode&);
void handleAsynchronousPreflightResult();
void loadRequestSynchronously(ResourceRequest&, ExceptionCode&);
void loadRequestAsynchronously(ResourceRequest&);
- bool isOnAccessControlResponseHeaderWhitelist(const String&) const;
-
- bool isSimpleCrossSiteAccessRequest() const;
- String accessControlOrigin() const;
- bool accessControlCheck(const ResourceResponse&);
-
void genericError();
void networkError();
void abortError();
@@ -202,7 +195,7 @@ private:
RefPtr<FormData> m_requestEntityBody;
String m_mimeTypeOverride;
bool m_async;
- bool m_includeCredentials;
+ bool m_includeCredentials; // FIXME: Currently, setting this flag is not implemented, so it is always false.
RefPtr<ThreadableLoader> m_loader;
State m_state;
@@ -224,6 +217,7 @@ private:
bool m_error;
+ bool m_uploadEventsAllowed;
bool m_uploadComplete;
bool m_sameOriginRequest;
@@ -235,6 +229,7 @@ private:
unsigned m_lastSendLineNumber;
String m_lastSendURL;
+ ExceptionCode m_exceptionCode;
};
} // namespace WebCore
diff --git a/WebCore/xml/XMLHttpRequest.idl b/WebCore/xml/XMLHttpRequest.idl
index 315d95c..3187160 100644
--- a/WebCore/xml/XMLHttpRequest.idl
+++ b/WebCore/xml/XMLHttpRequest.idl
@@ -29,7 +29,8 @@
module xml {
interface [
- CustomMarkFunction
+ CustomMarkFunction,
+ NoStaticTables
] XMLHttpRequest {
// From XMLHttpRequestEventTarget
// event handler attributes
diff --git a/WebCore/xml/XMLHttpRequestException.idl b/WebCore/xml/XMLHttpRequestException.idl
index 2feb574..706beb2 100644
--- a/WebCore/xml/XMLHttpRequestException.idl
+++ b/WebCore/xml/XMLHttpRequestException.idl
@@ -29,7 +29,8 @@
module xml {
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
] XMLHttpRequestException {
readonly attribute unsigned short code;
diff --git a/WebCore/xml/XMLHttpRequestProgressEvent.idl b/WebCore/xml/XMLHttpRequestProgressEvent.idl
index 6de9690..549308b 100644
--- a/WebCore/xml/XMLHttpRequestProgressEvent.idl
+++ b/WebCore/xml/XMLHttpRequestProgressEvent.idl
@@ -26,7 +26,8 @@
module events {
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
// We should also inherit from LSProgressEvent when the idl is added.
] XMLHttpRequestProgressEvent : ProgressEvent {
readonly attribute unsigned long position;
diff --git a/WebCore/xml/XMLHttpRequestUpload.cpp b/WebCore/xml/XMLHttpRequestUpload.cpp
index a58c271..d8a76d5 100644
--- a/WebCore/xml/XMLHttpRequestUpload.cpp
+++ b/WebCore/xml/XMLHttpRequestUpload.cpp
@@ -30,7 +30,6 @@
#include "Event.h"
#include "EventException.h"
#include "EventNames.h"
-#include "Frame.h"
#include "XMLHttpRequest.h"
#include "XMLHttpRequestProgressEvent.h"
#include <wtf/Assertions.h>
@@ -42,6 +41,11 @@ XMLHttpRequestUpload::XMLHttpRequestUpload(XMLHttpRequest* xmlHttpRequest)
{
}
+bool XMLHttpRequestUpload::hasListeners() const
+{
+ return m_onAbortListener || m_onErrorListener || m_onLoadListener || m_onLoadStartListener || m_onProgressListener || !m_eventListeners.isEmpty();
+}
+
ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const
{
XMLHttpRequest* xmlHttpRequest = associatedXMLHttpRequest();
diff --git a/WebCore/xml/XMLHttpRequestUpload.h b/WebCore/xml/XMLHttpRequestUpload.h
index 93fa7f9..b4f40e0 100644
--- a/WebCore/xml/XMLHttpRequestUpload.h
+++ b/WebCore/xml/XMLHttpRequestUpload.h
@@ -48,6 +48,8 @@ namespace WebCore {
return adoptRef(new XMLHttpRequestUpload(xmlHttpRequest));
}
+ bool hasListeners() const;
+
virtual XMLHttpRequestUpload* toXMLHttpRequestUpload() { return this; }
XMLHttpRequest* associatedXMLHttpRequest() const { return m_xmlHttpRequest; }
diff --git a/WebCore/xml/XMLHttpRequestUpload.idl b/WebCore/xml/XMLHttpRequestUpload.idl
index c066710..3172f68 100644
--- a/WebCore/xml/XMLHttpRequestUpload.idl
+++ b/WebCore/xml/XMLHttpRequestUpload.idl
@@ -30,7 +30,8 @@ module xml {
interface [
GenerateConstructor,
- CustomMarkFunction
+ CustomMarkFunction,
+ NoStaticTables
] XMLHttpRequestUpload {
// From XMLHttpRequestEventTarget
// event handler attributes
diff --git a/WebCore/xml/XPathExpression.cpp b/WebCore/xml/XPathExpression.cpp
index 446a7ad..ecec79e 100644
--- a/WebCore/xml/XPathExpression.cpp
+++ b/WebCore/xml/XPathExpression.cpp
@@ -67,9 +67,7 @@ PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned sh
return 0;
}
- EventTargetNode* eventTarget = contextNode->ownerDocument()
- ? contextNode->ownerDocument()
- : static_cast<EventTargetNode*>(contextNode);
+ Node* eventTarget = contextNode->ownerDocument() ? contextNode->ownerDocument() : contextNode;
EvaluationContext& evaluationContext = Expression::evaluationContext();
evaluationContext.node = contextNode;
diff --git a/WebCore/xml/XPathFunctions.cpp b/WebCore/xml/XPathFunctions.cpp
index 841b436..3abd603 100644
--- a/WebCore/xml/XPathFunctions.cpp
+++ b/WebCore/xml/XPathFunctions.cpp
@@ -534,30 +534,30 @@ Value FunLang::evaluate() const
{
String lang = arg(0)->evaluate().toString();
- RefPtr<Node> langNode = 0;
+ Attribute* languageAttribute = 0;
Node* node = evaluationContext().node.get();
while (node) {
NamedAttrMap* attrs = node->attributes();
if (attrs)
- langNode = attrs->getNamedItemNS(XMLNames::xmlNamespaceURI, "lang");
- if (langNode)
+ languageAttribute = attrs->getAttributeItem(XMLNames::langAttr);
+ if (languageAttribute)
break;
node = node->parentNode();
}
- if (!langNode)
+ if (!languageAttribute)
return false;
- String langNodeValue = langNode->nodeValue();
+ String langValue = languageAttribute->value();
while (true) {
- if (equalIgnoringCase(langNodeValue, lang))
+ if (equalIgnoringCase(langValue, lang))
return true;
// Remove suffixes one by one.
- int index = langNodeValue.reverseFind('-');
+ int index = langValue.reverseFind('-');
if (index == -1)
break;
- langNodeValue = langNodeValue.left(index);
+ langValue = langValue.left(index);
}
return false;
diff --git a/WebCore/xml/XPathNodeSet.cpp b/WebCore/xml/XPathNodeSet.cpp
index e29c096..ba9423e 100644
--- a/WebCore/xml/XPathNodeSet.cpp
+++ b/WebCore/xml/XPathNodeSet.cpp
@@ -162,7 +162,7 @@ void NodeSet::sort() const
// It is not possible to just assign the result to m_nodes, because some nodes may get dereferenced and destroyed.
Vector<RefPtr<Node> > sortedNodes;
- sortedNodes.reserveCapacity(nodeCount);
+ sortedNodes.reserveInitialCapacity(nodeCount);
for (unsigned i = 0; i < nodeCount; ++i)
sortedNodes.append(parentMatrix[i][0]);
diff --git a/WebCore/xml/XPathResult.cpp b/WebCore/xml/XPathResult.cpp
index 285350e..a1c8a08 100644
--- a/WebCore/xml/XPathResult.cpp
+++ b/WebCore/xml/XPathResult.cpp
@@ -31,7 +31,7 @@
#include "EventListener.h"
#include "EventNames.h"
-#include "EventTargetNode.h"
+#include "Node.h"
#include "ExceptionCode.h"
#include "XPathEvaluator.h"
#include "XPathException.h"
@@ -50,7 +50,7 @@ private:
XPathResult* m_result;
};
-XPathResult::XPathResult(EventTargetNode* eventTarget, const Value& value)
+XPathResult::XPathResult(Node* eventTarget, const Value& value)
: m_value(value)
, m_eventTarget(eventTarget)
{
diff --git a/WebCore/xml/XPathResult.h b/WebCore/xml/XPathResult.h
index ecd5cac..03accc6 100644
--- a/WebCore/xml/XPathResult.h
+++ b/WebCore/xml/XPathResult.h
@@ -37,7 +37,7 @@ namespace WebCore {
typedef int ExceptionCode;
class EventListener;
- class EventTargetNode;
+ class Node;
class Node;
class String;
@@ -56,7 +56,7 @@ namespace WebCore {
FIRST_ORDERED_NODE_TYPE = 9
};
- static PassRefPtr<XPathResult> create(EventTargetNode* eventTarget, const XPath::Value& value) { return adoptRef(new XPathResult(eventTarget, value)); }
+ static PassRefPtr<XPathResult> create(Node* eventTarget, const XPath::Value& value) { return adoptRef(new XPathResult(eventTarget, value)); }
~XPathResult();
void convertTo(unsigned short type, ExceptionCode&);
@@ -76,14 +76,14 @@ namespace WebCore {
void invalidateIteratorState();
private:
- XPathResult(EventTargetNode*, const XPath::Value&);
+ XPathResult(Node*, const XPath::Value&);
XPath::Value m_value;
unsigned m_nodeSetPosition;
XPath::NodeSet m_nodeSet; // FIXME: why duplicate the node set stored in m_value?
unsigned short m_resultType;
bool m_invalidIteratorState;
- RefPtr<EventTargetNode> m_eventTarget;
+ RefPtr<Node> m_eventTarget;
RefPtr<EventListener> m_eventListener;
};
diff --git a/WebCore/xml/XPathStep.cpp b/WebCore/xml/XPathStep.cpp
index abdcba5..ae8d9c4 100644
--- a/WebCore/xml/XPathStep.cpp
+++ b/WebCore/xml/XPathStep.cpp
@@ -191,10 +191,10 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
if (!attrs)
return;
- for (unsigned long i = 0; i < attrs->length(); ++i) {
- RefPtr<Node> n = attrs->item(i);
- if (nodeMatches(n.get()))
- nodes.append(n.release());
+ for (unsigned i = 0; i < attrs->length(); ++i) {
+ RefPtr<Attr> attr = attrs->attributeItem(i)->createAttrIfNeeded(static_cast<Element*>(context));
+ if (nodeMatches(attr.get()))
+ nodes.append(attr.release());
}
return;
}
diff --git a/WebKit/android/RenderSkinCombo.cpp b/WebKit/android/RenderSkinCombo.cpp
index 902f2c0..a336257 100644
--- a/WebKit/android/RenderSkinCombo.cpp
+++ b/WebKit/android/RenderSkinCombo.cpp
@@ -27,6 +27,7 @@
#include "RenderSkinCombo.h"
#include "Document.h"
+#include "FormControlElement.h"
#include "Node.h"
#include "SkCanvas.h"
#include "SkNinePatch.h"
@@ -58,7 +59,12 @@ bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int wi
{
if (!s_decoded)
return true;
- State state = element && element->isEnabled() ? kNormal : kDisabled;
+ bool enabled = false;
+ if (FormControlElement* controlElement = toFormControlElement(static_cast<Element*>(element))) {
+ enabled = controlElement->isEnabled();
+ }
+
+ State state = enabled ? kNormal : kDisabled;
if (height < (s_margin<<1) + 1) {
height = (s_margin<<1) + 1;
}
diff --git a/WebKit/android/RenderSkinRadio.cpp b/WebKit/android/RenderSkinRadio.cpp
index 2fca175..7b55567 100644
--- a/WebKit/android/RenderSkinRadio.cpp
+++ b/WebKit/android/RenderSkinRadio.cpp
@@ -28,6 +28,8 @@
#include "android_graphics.h"
#include "Document.h"
+#include "FormControlElement.h"
+#include "InputElement.h"
#include "IntRect.h"
#include "Node.h"
#include "RenderSkinAndroid.h"
@@ -64,7 +66,13 @@ void RenderSkinRadio::Draw(SkCanvas* canvas, Node* element, const IntRect& ir,
android_setrect(&r, ir);
int saveLayerCount = 0;
int saveScaleCount = 0;
- if (!element->isEnabled()) {
+
+ bool enabled = false;
+ if (FormControlElement* control = toFormControlElement(static_cast<Element*>(element))) {
+ enabled = control->isEnabled();
+ }
+
+ if (!enabled) {
saveLayerCount = canvas->saveLayerAlpha(&r, 0x80);
}
SkScalar width = r.width();
@@ -72,7 +80,12 @@ void RenderSkinRadio::Draw(SkCanvas* canvas, Node* element, const IntRect& ir,
SkScalar scale = SkScalarDiv(width, SIZE);
saveScaleCount = canvas->scale(scale, scale);
}
- canvas->drawBitmap(s_bitmap[element->isChecked() + 2*(!isCheckBox)],
+ bool checked = false;
+ if (InputElement* inputElement = toInputElement(static_cast<Element*>(element))) {
+ checked = inputElement->isChecked();
+ }
+
+ canvas->drawBitmap(s_bitmap[checked + 2*(!isCheckBox)],
r.fLeft, r.fTop, NULL);
if (saveLayerCount != 0) {
canvas->restoreToCount(saveLayerCount);
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index a99fedd..3e821cc 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -37,6 +37,7 @@
// HTMLFormElement needed for a bad include
#include "HTMLFormElement.h"
#include "HTMLFrameOwnerElement.h"
+#include "HTMLPlugInElement.h"
#include "IconDatabase.h"
#include "MIMETypeRegistry.h"
#include "NotImplemented.h"
@@ -110,7 +111,7 @@ void FrameLoaderClientAndroid::makeRepresentation(DocumentLoader*) {
void FrameLoaderClientAndroid::forceLayout() {
ASSERT(m_frame);
- m_frame->forceLayout();
+ m_frame->view()->forceLayout();
// FIXME, should we adjust view size here?
m_frame->view()->adjustViewSize();
}
@@ -572,7 +573,7 @@ void FrameLoaderClientAndroid::updateGlobalHistory() {
m_webFrame->updateVisitedHistory(m_frame->loader()->documentLoader()->urlForHistory(), false);
}
-void FrameLoaderClientAndroid::updateGlobalHistoryForRedirectWithoutHistoryItem() {
+void FrameLoaderClientAndroid::updateGlobalHistoryRedirectLinks() {
// Note, do we need to do anything where there is no HistoryItem? If we call
// updateGlobalHistory(), we will add bunch of "data:xxx" urls for gmail.com
// which is not what we want. Opt to do nothing now.
@@ -676,7 +677,6 @@ String FrameLoaderClientAndroid::generatedMIMETypeForURLScheme(const String& URL
void FrameLoaderClientAndroid::frameLoadCompleted() {
// copied from Apple port, without this back with sub-frame will trigger ASSERT
ASSERT(m_frame);
- m_frame->loader()->setPreviousHistoryItem(0);
}
void FrameLoaderClientAndroid::saveViewStateToItem(HistoryItem* item) {
@@ -889,7 +889,7 @@ static bool isYouTubeUrl(const KURL& url, const String& mimeType)
Widget* FrameLoaderClientAndroid::createPlugin(
const IntSize& size,
- Element* element,
+ HTMLPlugInElement* element,
const KURL& url,
const WTF::Vector<String, 0u>& names,
const WTF::Vector<String, 0u>& values,
@@ -897,8 +897,7 @@ Widget* FrameLoaderClientAndroid::createPlugin(
bool loadManually) {
// Create an iframe for youtube urls.
if (isYouTubeUrl(url, mimeType)) {
- RefPtr<Frame> frame = createFrame(blankURL(), String(),
- static_cast<HTMLFrameOwnerElement*>(element),
+ RefPtr<Frame> frame = createFrame(blankURL(), String(), element,
String(), false, 0, 0);
if (frame) {
// grab everything after /v/
@@ -944,7 +943,7 @@ void FrameLoaderClientAndroid::redirectDataToPlugin(Widget* pluginWidget) {
notImplemented();
}
-Widget* FrameLoaderClientAndroid::createJavaAppletWidget(const IntSize&, Element*,
+Widget* FrameLoaderClientAndroid::createJavaAppletWidget(const IntSize&, HTMLAppletElement*,
const KURL& baseURL, const WTF::Vector<String>& paramNames,
const WTF::Vector<String>& paramValues) {
// don't support widget yet
@@ -1004,6 +1003,9 @@ void FrameLoaderClientAndroid::windowObjectCleared() {
m_webFrame->windowObjectCleared(m_frame);
}
+void FrameLoaderClientAndroid::documentElementAvailable() {
+}
+
// functions new to Jun-07 tip of tree merge:
ResourceError FrameLoaderClientAndroid::blockedError(ResourceRequest const& request) {
return ResourceError(String(), InternalErrorFileDoesNotExist, String(), String());
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h
index 9d71c9d..143537f 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.h
@@ -122,7 +122,7 @@ namespace android {
virtual void finishedLoading(DocumentLoader*);
virtual void updateGlobalHistory();
- virtual void updateGlobalHistoryForRedirectWithoutHistoryItem();
+ virtual void updateGlobalHistoryRedirectLinks();
virtual bool shouldGoToHistoryItem(HistoryItem*) const;
#ifdef ANDROID_HISTORY_CLIENT
@@ -168,17 +168,18 @@ namespace android {
virtual WTF::PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight);
- virtual Widget* createPlugin(const IntSize&, Element*, const KURL&,
+ virtual Widget* createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&,
const WTF::Vector<WebCore::String, 0u>&, const WTF::Vector<String, 0u>&,
const String&, bool);
virtual void redirectDataToPlugin(Widget* pluginWidget);
- virtual Widget* createJavaAppletWidget(const IntSize&, Element*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues);
+ virtual Widget* createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues);
virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType);
virtual String overrideMediaType() const;
virtual void windowObjectCleared();
+ virtual void documentElementAvailable();
virtual void didPerformFirstNavigation() const;
virtual void registerForIconNotification(bool listen = true);
diff --git a/WebKit/android/WebCoreSupport/InspectorClientAndroid.h b/WebKit/android/WebCoreSupport/InspectorClientAndroid.h
index 9eb85e5..2fb3d2a 100644
--- a/WebKit/android/WebCoreSupport/InspectorClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/InspectorClientAndroid.h
@@ -57,6 +57,7 @@ public:
virtual void populateSetting(const String&, InspectorController::Setting&) {}
virtual void storeSetting(const String&, const InspectorController::Setting&) {}
virtual void removeSetting(const String&) {}
+ virtual String hiddenPanels() { return String(); }
};
}
diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp
index 24ca71c..d62fd91 100644
--- a/WebKit/android/jni/JavaBridge.cpp
+++ b/WebKit/android/jni/JavaBridge.cpp
@@ -262,11 +262,6 @@ void JavaBridge::SetNetworkOnLine(JNIEnv* env, jobject obj, jboolean online)
WebCore::networkStateNotifier().networkStateChange(online);
}
-void JavaBridge::SetDeferringTimers(JNIEnv* env, jobject obj, jboolean defer)
-{
- WebCore::setDeferringTimers(defer);
-}
-
void JavaBridge::ServiceFuncPtrQueue(JNIEnv*)
{
JavaSharedClient::ServiceFunctionPtrQueue();
@@ -289,8 +284,6 @@ static JNINativeMethod gWebCoreJavaBridgeMethods[] = {
(void*) JavaBridge::SetCacheSize },
{ "setNetworkOnLine", "(Z)V",
(void*) JavaBridge::SetNetworkOnLine },
- { "setDeferringTimers", "(Z)V",
- (void*) JavaBridge::SetDeferringTimers },
{ "nativeServiceFuncPtrQueue", "()V",
(void*) JavaBridge::ServiceFuncPtrQueue },
};
diff --git a/WebKit/android/jni/WebHistory.cpp b/WebKit/android/jni/WebHistory.cpp
index cd6e0f1..01fd543 100644
--- a/WebKit/android/jni/WebHistory.cpp
+++ b/WebKit/android/jni/WebHistory.cpp
@@ -153,7 +153,6 @@ static void WebHistoryRestoreIndex(JNIEnv* env, jobject obj, jint frame, jint in
// Update the current and previous history item.
WebCore::FrameLoader* loader = pFrame->loader();
loader->setCurrentHistoryItem(currentItem);
- loader->setPreviousHistoryItem(list->backItem());
// load the current page with FrameLoadTypeIndexedBackForward so that it
// will use cache when it is possible
diff --git a/WebKit/android/jni/WebSettings.cpp b/WebKit/android/jni/WebSettings.cpp
index 407544a..a3701af 100644
--- a/WebKit/android/jni/WebSettings.cpp
+++ b/WebKit/android/jni/WebSettings.cpp
@@ -328,10 +328,6 @@ public:
#endif
flag = env->GetBooleanField(obj, gFieldIds->mShrinksStandaloneImagesToFit);
s->setShrinksStandaloneImagesToFit(flag);
-#if USE(LOW_BANDWIDTH_DISPLAY)
- flag = env->GetBooleanField(obj, gFieldIds->mUseDoubleTree);
- pFrame->loader()->setUseLowBandwidthDisplay(flag);
-#endif
}
};
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 7a60447..529fbdf 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -39,6 +39,7 @@
#include "EventHandler.h"
#include "EventNames.h"
#include "Font.h"
+#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClientAndroid.h"
#include "FrameTree.h"
@@ -793,7 +794,7 @@ void WebViewCore::setScrollOffset(int dx, int dy)
// testing work correctly.
m_mainFrame->view()->platformWidget()->setLocation(m_scrollOffsetX,
m_scrollOffsetY);
- m_mainFrame->sendScrollEvent();
+ m_mainFrame->eventHandler()->sendScrollEvent();
}
}
@@ -846,7 +847,7 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height,
}
}
r->setNeedsLayoutAndPrefWidthsRecalc();
- m_mainFrame->forceLayout();
+ m_mainFrame->view()->forceLayout();
// scroll to restore current screen center
if (!node)
return;
@@ -1797,8 +1798,7 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node
// so when attempting to get the default, the point chosen would be follow the wrong link.
if (nodePtr->hasTagName(WebCore::HTMLNames::areaTag)) {
webFrame->setUserInitiatedClick(true);
- WebCore::EventTargetNodeCast(nodePtr)->dispatchSimulatedClick(0,
- true, true);
+ nodePtr->dispatchSimulatedClick(0, true, true);
webFrame->setUserInitiatedClick(false);
return true;
}
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index b042ec7..44beffc 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -27,8 +27,8 @@
#include "CachedNode.h"
#include "CachedRoot.h"
#include "Document.h"
+#include "EventListener.h"
#include "EventNames.h"
-#include "EventTargetNode.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClientAndroid.h"
@@ -45,6 +45,7 @@
#include "InlineTextBox.h"
#include "KURL.h"
#include "PluginView.h"
+#include "RegisteredEventListener.h"
#include "RenderImage.h"
#include "RenderInline.h"
#include "RenderListBox.h"
@@ -88,8 +89,20 @@ Frame* CacheBuilder::FrameAnd(const CacheBuilder* cacheBuilder) {
return loader->getFrame();
}
+
#if DUMP_NAV_CACHE
+static bool hasEventListener(Node* node, const AtomicString& eventType) {
+ const RegisteredEventListenerVector& listeners = node->eventListeners();
+ size_t size = listeners.size();
+ for (size_t i = 0; i < size; ++i) {
+ const RegisteredEventListener& r = *listeners[i];
+ if (r.eventType() == eventType)
+ return true;
+ }
+ return false;
+}
+
#define DEBUG_BUFFER_SIZE 256
#define DEBUG_WRAP_SIZE 150
#define DEBUG_WRAP_MAX 170
@@ -345,24 +358,20 @@ void CacheBuilder::Debug::groups() {
DUMP_NAV_LOGD("static DebugTestNode TEST%s_RECTS[] = {\n", name);
do {
String properties;
- EventTargetNode* elementTarget = node->isEventTargetNode() ?
- (EventTargetNode*) node : NULL;
- if (elementTarget) {
- if (elementTarget->getEventListener(eventNames().clickEvent))
- properties.append("ONCLICK | ");
- if (elementTarget->getEventListener(eventNames().mousedownEvent))
- properties.append("MOUSEDOWN | ");
- if (elementTarget->getEventListener(eventNames().mouseupEvent))
- properties.append("MOUSEUP | ");
- if (elementTarget->getEventListener(eventNames().mouseoverEvent))
- properties.append("MOUSEOVER | ");
- if (elementTarget->getEventListener(eventNames().mouseoutEvent))
- properties.append("MOUSEOUT | ");
- if (elementTarget->getEventListener(eventNames().keydownEvent))
- properties.append("KEYDOWN | ");
- if (elementTarget->getEventListener(eventNames().keyupEvent))
- properties.append("KEYUP | ");
- }
+ if (hasEventListener(node, eventNames().clickEvent))
+ properties.append("ONCLICK | ");
+ if (hasEventListener(node, eventNames().mousedownEvent))
+ properties.append("MOUSEDOWN | ");
+ if (hasEventListener(node, eventNames().mouseupEvent))
+ properties.append("MOUSEUP | ");
+ if (hasEventListener(node, eventNames().mouseoverEvent))
+ properties.append("MOUSEOVER | ");
+ if (hasEventListener(node, eventNames().mouseoutEvent))
+ properties.append("MOUSEOUT | ");
+ if (hasEventListener(node, eventNames().keydownEvent))
+ properties.append("KEYDOWN | ");
+ if (hasEventListener(node, eventNames().keyupEvent))
+ properties.append("KEYUP | ");
if (CacheBuilder::HasFrame(node))
properties.append("FRAME | ");
if (focus == node) {
@@ -553,8 +562,6 @@ bool CacheBuilder::Debug::isFocusable(Node* node) {
return true;
if (node->isFocusable())
return true;
- if (node->isEventTargetNode())
- return true;
if (CacheBuilder::AnyIsClick(node))
return false;
if (CacheBuilder::HasTriggerEvent(node))
@@ -807,20 +814,35 @@ void CacheBuilder::adjustForColumns(const ClipColumnTracker& track,
}
}
+// Checks if a node has one of event listener types.
+bool CacheBuilder::NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length) {
+ const RegisteredEventListenerVector& listeners = node->eventListeners();
+ size_t size = listeners.size();
+ for (size_t i = 0; i < size; ++i) {
+ const RegisteredEventListener& r = *listeners[i];
+ for (int j = 0; j < length; ++j) {
+ if (r.eventType() == eventTypes[j])
+ return true;
+ }
+ }
+ return false;
+}
+
bool CacheBuilder::AnyChildIsClick(Node* node)
{
+ AtomicString eventTypes[5] = {
+ eventNames().clickEvent,
+ eventNames().mousedownEvent,
+ eventNames().mouseupEvent,
+ eventNames().keydownEvent,
+ eventNames().keyupEvent
+ };
+
Node* child = node->firstChild();
while (child != NULL) {
- if (child->isEventTargetNode()) {
- EventTargetNode* target = (EventTargetNode*) child;
- if (target->isFocusable() ||
- target->getEventListener(eventNames().clickEvent) ||
- target->getEventListener(eventNames().mousedownEvent) ||
- target->getEventListener(eventNames().mouseupEvent) ||
- target->getEventListener(eventNames().keydownEvent) ||
- target->getEventListener(eventNames().keyupEvent))
+ if (child->isFocusable() ||
+ NodeHasEventListeners(child, eventTypes, 5))
return true;
- }
if (AnyChildIsClick(child))
return true;
child = child->nextSibling();
@@ -832,18 +854,26 @@ bool CacheBuilder::AnyIsClick(Node* node)
{
if (node->hasTagName(HTMLNames::bodyTag))
return AnyChildIsClick(node);
- EventTargetNode* target = (EventTargetNode*) node;
- if (target->getEventListener(eventNames().mouseoverEvent) == NULL &&
- target->getEventListener(eventNames().mouseoutEvent) == NULL &&
- target->getEventListener(eventNames().keydownEvent) == NULL &&
- target->getEventListener(eventNames().keyupEvent) == NULL)
- return false;
- if (target->getEventListener(eventNames().clickEvent))
- return false;
- if (target->getEventListener(eventNames().mousedownEvent))
+
+ AtomicString eventTypeSetOne[4] = {
+ eventNames().mouseoverEvent,
+ eventNames().mouseoutEvent,
+ eventNames().keydownEvent,
+ eventNames().keyupEvent
+ };
+
+ if (!NodeHasEventListeners(node, eventTypeSetOne, 4))
return false;
- if (target->getEventListener(eventNames().mouseupEvent))
+
+ AtomicString eventTypeSetTwo[3] = {
+ eventNames().clickEvent,
+ eventNames().mousedownEvent,
+ eventNames().mouseupEvent
+ };
+
+ if (NodeHasEventListeners(node, eventTypeSetTwo, 3))
return false;
+
return AnyChildIsClick(node);
}
@@ -1162,10 +1192,9 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
(const HTMLAnchorElement*) node;
if (!anchorNode->isFocusable() && !HasTriggerEvent(node))
continue;
- EventTargetNode* target = (EventTargetNode*) node;
- if (target->disabled())
+ if (node->disabled())
continue;
- hasMouseOver = target->getEventListener(eventNames().mouseoverEvent);
+ hasMouseOver = NodeHasEventListeners(node, &eventNames().mouseoverEvent, 1);
isAnchor = true;
KURL href = anchorNode->href();
if (!href.isEmpty() && !href.protocolIs("javascript"))
@@ -1198,10 +1227,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
bool isFocusable = node->isKeyboardFocusable(NULL) ||
node->isMouseFocusable() || node->isFocusable();
if (isFocusable == false) {
- if (node->isEventTargetNode() == false)
- continue;
- EventTargetNode* eventTargetNode = (EventTargetNode*) node;
- if (eventTargetNode->disabled())
+ if (node->disabled())
continue;
bool overOrOut = HasOverOrOut(node);
bool hasTrigger = HasTriggerEvent(node);
@@ -1345,7 +1371,6 @@ bool CacheBuilder::CleanUpContainedNodes(CachedFrame* cachedFrame,
lastNode->isKeyboardFocusable(NULL) == false &&
lastNode->isMouseFocusable() == false &&
lastNode->isFocusable() == false &&
- lastNode->isEventTargetNode() == true &&
HasOverOrOut(lastNode) == true &&
HasTriggerEvent(lastNode) == false;
if (cachedFrame->focusIndex() == lastChildIndex)
@@ -2432,20 +2457,26 @@ Frame* CacheBuilder::HasFrame(Node* node)
bool CacheBuilder::HasOverOrOut(Node* node)
{
- EventTargetNode* target = (EventTargetNode*) node;
- return target->getEventListener(eventNames().mouseoverEvent) ||
- target->getEventListener(eventNames().mouseoutEvent);
+ // eventNames are thread-local data, I avoid using 'static' variable here.
+ AtomicString eventTypes[2] = {
+ eventNames().mouseoverEvent,
+ eventNames().mouseoutEvent
+ };
+ return NodeHasEventListeners(node, eventTypes, 2);
}
bool CacheBuilder::HasTriggerEvent(Node* node)
{
- EventTargetNode* target = (EventTargetNode*) node;
- return target->getEventListener(eventNames().clickEvent) ||
- target->getEventListener(eventNames().mousedownEvent) ||
- target->getEventListener(eventNames().mouseupEvent) ||
- target->getEventListener(eventNames().keydownEvent) ||
- target->getEventListener(eventNames().keyupEvent);
+ AtomicString eventTypes[5] = {
+ eventNames().clickEvent,
+ eventNames().mousedownEvent,
+ eventNames().mouseupEvent,
+ eventNames().keydownEvent,
+ eventNames().keyupEvent
+ };
+
+ return NodeHasEventListeners(node, eventTypes, 5);
}
// #define EMAIL_PATTERN "x@y.d" // where 'x' is letters, numbers, and '-', '.', '_' ; 'y' is 'x' without the underscore, and 'd' is a valid domain
@@ -2504,8 +2535,6 @@ Node* CacheBuilder::findByCenter(int x, int y) const
return node;
if (node->isFocusable())
return node;
- if (node->isEventTargetNode() == false)
- continue;
if (AnyIsClick(node))
continue;
if (HasTriggerEvent(node) == false)
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index 32ae0af..dbed6e8 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -39,7 +39,8 @@
using namespace WebCore;
namespace WebCore {
-
+
+class AtomicString;
class Document;
class Frame;
class HTMLAreaElement;
@@ -194,6 +195,7 @@ private:
WTF::Vector<IntRect>* result, IntRect* focusBounds);
static bool AnyIsClick(Node* node);
static bool AnyChildIsClick(Node* node);
+ static bool NodeHasEventListeners(Node* node, AtomicString* eventTypes, int length);
void BuildFrame(Frame* root, Frame* frame,
CachedRoot* cachedRoot, CachedFrame* cachedFrame);
bool CleanUpContainedNodes(CachedFrame* cachedFrame,