summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings')
-rw-r--r--WebCore/bindings/js/CachedScriptSourceProvider.h6
-rw-r--r--WebCore/bindings/js/DOMObjectWithSVGContext.h57
-rw-r--r--WebCore/bindings/js/GCController.cpp6
-rw-r--r--WebCore/bindings/js/GCController.h2
-rw-r--r--WebCore/bindings/js/JSAbstractWorkerCustom.cpp88
-rw-r--r--WebCore/bindings/js/JSAttrCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSAudioConstructor.cpp27
-rw-r--r--WebCore/bindings/js/JSAudioConstructor.h8
-rw-r--r--WebCore/bindings/js/JSCDATASectionCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSCSSRuleCustom.cpp23
-rw-r--r--WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSCSSValueCustom.cpp14
-rw-r--r--WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp27
-rw-r--r--WebCore/bindings/js/JSCustomPositionCallback.cpp11
-rw-r--r--WebCore/bindings/js/JSCustomPositionErrorCallback.cpp7
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementCallback.cpp7
-rw-r--r--WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp9
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp7
-rw-r--r--WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp5
-rw-r--r--WebCore/bindings/js/JSCustomVoidCallback.cpp2
-rw-r--r--WebCore/bindings/js/JSCustomXPathNSResolver.cpp4
-rw-r--r--WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp22
-rw-r--r--WebCore/bindings/js/JSDOMBinding.cpp55
-rw-r--r--WebCore/bindings/js/JSDOMBinding.h145
-rw-r--r--WebCore/bindings/js/JSDOMGlobalObject.cpp21
-rw-r--r--WebCore/bindings/js/JSDOMGlobalObject.h17
-rw-r--r--WebCore/bindings/js/JSDOMWindowBase.cpp97
-rw-r--r--WebCore/bindings/js/JSDOMWindowBase.h14
-rw-r--r--WebCore/bindings/js/JSDOMWindowCustom.cpp263
-rw-r--r--WebCore/bindings/js/JSDOMWindowCustom.h116
-rw-r--r--WebCore/bindings/js/JSDOMWindowShell.cpp10
-rw-r--r--WebCore/bindings/js/JSDOMWindowShell.h2
-rw-r--r--WebCore/bindings/js/JSDataGridColumnListCustom.cpp54
-rw-r--r--WebCore/bindings/js/JSDataGridDataSource.cpp (renamed from WebCore/bindings/js/JSDOMStringListCustom.cpp)28
-rw-r--r--WebCore/bindings/js/JSDataGridDataSource.h76
-rw-r--r--WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp51
-rw-r--r--WebCore/bindings/js/JSDocumentCustom.cpp21
-rw-r--r--WebCore/bindings/js/JSElementCustom.cpp16
-rw-r--r--WebCore/bindings/js/JSEventCustom.cpp42
-rw-r--r--WebCore/bindings/js/JSEventListener.cpp64
-rw-r--r--WebCore/bindings/js/JSEventListener.h3
-rw-r--r--WebCore/bindings/js/JSEventTarget.cpp45
-rw-r--r--WebCore/bindings/js/JSEventTarget.h3
-rw-r--r--WebCore/bindings/js/JSHTMLAllCollection.h4
-rw-r--r--WebCore/bindings/js/JSHTMLAppletElementCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSHTMLCollectionCustom.cpp39
-rw-r--r--WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp60
-rw-r--r--WebCore/bindings/js/JSHTMLElementCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSHTMLFormElementCustom.cpp7
-rw-r--r--WebCore/bindings/js/JSHTMLFrameElementCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSHTMLObjectElementCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp2
-rw-r--r--WebCore/bindings/js/JSHistoryCustom.cpp18
-rw-r--r--WebCore/bindings/js/JSImageConstructor.cpp27
-rw-r--r--WebCore/bindings/js/JSImageConstructor.h7
-rw-r--r--WebCore/bindings/js/JSImageDataCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSInspectorBackendCustom.cpp (renamed from WebCore/bindings/js/JSInspectorControllerCustom.cpp)71
-rw-r--r--WebCore/bindings/js/JSLazyEventListener.cpp10
-rw-r--r--WebCore/bindings/js/JSLocationCustom.cpp26
-rw-r--r--WebCore/bindings/js/JSMessageChannelConstructor.cpp22
-rw-r--r--WebCore/bindings/js/JSMessageChannelConstructor.h9
-rw-r--r--WebCore/bindings/js/JSMessageChannelCustom.cpp14
-rw-r--r--WebCore/bindings/js/JSMessagePortCustom.cpp24
-rw-r--r--WebCore/bindings/js/JSNamedNodesCollection.cpp6
-rw-r--r--WebCore/bindings/js/JSNamedNodesCollection.h4
-rw-r--r--WebCore/bindings/js/JSNavigatorCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSNodeCustom.cpp83
-rw-r--r--WebCore/bindings/js/JSNodeFilterCondition.cpp13
-rw-r--r--WebCore/bindings/js/JSNodeFilterCondition.h4
-rw-r--r--WebCore/bindings/js/JSNodeFilterCustom.cpp8
-rw-r--r--WebCore/bindings/js/JSNodeIteratorCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSOptionConstructor.cpp24
-rw-r--r--WebCore/bindings/js/JSOptionConstructor.h7
-rw-r--r--WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp12
-rw-r--r--WebCore/bindings/js/JSQuarantinedObjectWrapper.h4
-rw-r--r--WebCore/bindings/js/JSRGBColor.cpp85
-rw-r--r--WebCore/bindings/js/JSRGBColor.h59
-rw-r--r--WebCore/bindings/js/JSSVGElementInstanceCustom.cpp13
-rw-r--r--WebCore/bindings/js/JSSVGMatrixCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSSVGPathSegCustom.cpp42
-rw-r--r--WebCore/bindings/js/JSSVGPathSegListCustom.cpp12
-rw-r--r--WebCore/bindings/js/JSSVGPointListCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSSVGTransformListCustom.cpp6
-rw-r--r--WebCore/bindings/js/JSSharedWorkerConstructor.cpp85
-rw-r--r--WebCore/bindings/js/JSSharedWorkerConstructor.h56
-rw-r--r--WebCore/bindings/js/JSSharedWorkerContextCustom.cpp50
-rw-r--r--WebCore/bindings/js/JSSharedWorkerCustom.cpp57
-rw-r--r--WebCore/bindings/js/JSStorageCustom.cpp9
-rw-r--r--WebCore/bindings/js/JSStyleSheetCustom.cpp18
-rw-r--r--WebCore/bindings/js/JSTextCustom.cpp4
-rw-r--r--WebCore/bindings/js/JSTreeWalkerCustom.cpp10
-rw-r--r--WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp11
-rw-r--r--WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h4
-rw-r--r--WebCore/bindings/js/JSWebKitPointConstructor.cpp12
-rw-r--r--WebCore/bindings/js/JSWebKitPointConstructor.h4
-rw-r--r--WebCore/bindings/js/JSWebSocketConstructor.cpp92
-rw-r--r--WebCore/bindings/js/JSWebSocketConstructor.h50
-rw-r--r--WebCore/bindings/js/JSWebSocketCustom.cpp73
-rw-r--r--WebCore/bindings/js/JSWorkerConstructor.cpp20
-rw-r--r--WebCore/bindings/js/JSWorkerConstructor.h4
-rw-r--r--WebCore/bindings/js/JSWorkerContextBase.cpp39
-rw-r--r--WebCore/bindings/js/JSWorkerContextBase.h12
-rw-r--r--WebCore/bindings/js/JSWorkerContextCustom.cpp27
-rw-r--r--WebCore/bindings/js/JSWorkerCustom.cpp40
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp22
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestConstructor.h7
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestCustom.cpp22
-rw-r--r--WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp20
-rw-r--r--WebCore/bindings/js/JSXSLTProcessorConstructor.cpp11
-rw-r--r--WebCore/bindings/js/JSXSLTProcessorConstructor.h4
-rw-r--r--WebCore/bindings/js/ScheduledAction.cpp2
-rw-r--r--WebCore/bindings/js/ScriptArray.cpp108
-rw-r--r--WebCore/bindings/js/ScriptArray.h59
-rw-r--r--WebCore/bindings/js/ScriptCachedFrameData.cpp6
-rw-r--r--WebCore/bindings/js/ScriptController.cpp36
-rw-r--r--WebCore/bindings/js/ScriptController.h6
-rw-r--r--WebCore/bindings/js/ScriptControllerHaiku.cpp46
-rw-r--r--WebCore/bindings/js/ScriptControllerMac.mm2
-rw-r--r--WebCore/bindings/js/ScriptEventListener.cpp16
-rw-r--r--WebCore/bindings/js/ScriptFunctionCall.cpp14
-rw-r--r--WebCore/bindings/js/ScriptObject.cpp84
-rw-r--r--WebCore/bindings/js/ScriptObject.h23
-rw-r--r--WebCore/bindings/js/ScriptObjectQuarantine.cpp27
-rw-r--r--WebCore/bindings/js/ScriptSourceCode.h12
-rw-r--r--WebCore/bindings/js/ScriptSourceProvider.h48
-rw-r--r--WebCore/bindings/js/ScriptValue.cpp2
-rw-r--r--WebCore/bindings/js/StringSourceProvider.h6
-rw-r--r--WebCore/bindings/js/WorkerScriptController.cpp35
-rw-r--r--WebCore/bindings/js/WorkerScriptController.h2
-rw-r--r--WebCore/bindings/objc/DOM.mm17
-rw-r--r--WebCore/bindings/objc/DOMHTML.mm2
-rw-r--r--WebCore/bindings/objc/DOMInternal.mm10
-rw-r--r--WebCore/bindings/objc/DOMRGBColor.mm145
-rw-r--r--WebCore/bindings/objc/WebScriptObject.mm20
-rw-r--r--WebCore/bindings/scripts/CodeGenerator.pm37
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorCOM.pm24
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorJS.pm423
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorObjC.pm50
-rw-r--r--WebCore/bindings/scripts/CodeGeneratorV8.pm2228
-rw-r--r--WebCore/bindings/scripts/IDLParser.pm4
-rw-r--r--WebCore/bindings/v8/ChildThreadDOMData.cpp48
-rw-r--r--WebCore/bindings/v8/ChildThreadDOMData.h50
-rw-r--r--WebCore/bindings/v8/DOMData.cpp130
-rw-r--r--WebCore/bindings/v8/DOMData.h136
-rw-r--r--WebCore/bindings/v8/DOMDataStore.cpp199
-rw-r--r--WebCore/bindings/v8/DOMDataStore.h142
-rw-r--r--WebCore/bindings/v8/DOMObjectsInclude.h229
-rw-r--r--WebCore/bindings/v8/DerivedSourcesAllInOne.cpp338
-rw-r--r--WebCore/bindings/v8/MainThreadDOMData.cpp52
-rw-r--r--WebCore/bindings/v8/MainThreadDOMData.h51
-rw-r--r--WebCore/bindings/v8/NPV8Object.cpp509
-rw-r--r--WebCore/bindings/v8/NPV8Object.h60
-rw-r--r--WebCore/bindings/v8/OwnHandle.h82
-rw-r--r--WebCore/bindings/v8/ScheduledAction.cpp14
-rw-r--r--WebCore/bindings/v8/ScopedDOMDataStore.cpp59
-rw-r--r--WebCore/bindings/v8/ScopedDOMDataStore.h56
-rw-r--r--WebCore/bindings/v8/ScriptArray.cpp105
-rw-r--r--WebCore/bindings/v8/ScriptArray.h58
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.cpp3
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.h5
-rw-r--r--WebCore/bindings/v8/ScriptController.cpp93
-rw-r--r--WebCore/bindings/v8/ScriptController.h13
-rw-r--r--WebCore/bindings/v8/ScriptEventListener.cpp11
-rw-r--r--WebCore/bindings/v8/ScriptFunctionCall.cpp2
-rw-r--r--WebCore/bindings/v8/ScriptInstance.cpp4
-rw-r--r--WebCore/bindings/v8/ScriptObject.cpp41
-rw-r--r--WebCore/bindings/v8/ScriptObject.h24
-rw-r--r--WebCore/bindings/v8/ScriptObjectQuarantine.cpp30
-rw-r--r--WebCore/bindings/v8/ScriptScope.cpp2
-rw-r--r--WebCore/bindings/v8/ScriptValue.h8
-rw-r--r--WebCore/bindings/v8/StaticDOMDataStore.cpp55
-rw-r--r--WebCore/bindings/v8/StaticDOMDataStore.h63
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.cpp32
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.h13
-rw-r--r--WebCore/bindings/v8/V8Binding.cpp279
-rw-r--r--WebCore/bindings/v8/V8Binding.h137
-rw-r--r--WebCore/bindings/v8/V8Collection.cpp6
-rw-r--r--WebCore/bindings/v8/V8Collection.h46
-rw-r--r--WebCore/bindings/v8/V8ConsoleMessage.cpp128
-rw-r--r--WebCore/bindings/v8/V8ConsoleMessage.h90
-rw-r--r--WebCore/bindings/v8/V8DOMMap.cpp322
-rw-r--r--WebCore/bindings/v8/V8DOMMap.h36
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.cpp1465
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.h260
-rw-r--r--WebCore/bindings/v8/V8DataGridDataSource.cpp (renamed from WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp)45
-rw-r--r--WebCore/bindings/v8/V8DataGridDataSource.h81
-rw-r--r--WebCore/bindings/v8/V8EventListenerList.cpp10
-rw-r--r--WebCore/bindings/v8/V8EventListenerList.h26
-rw-r--r--WebCore/bindings/v8/V8GCController.cpp442
-rw-r--r--WebCore/bindings/v8/V8GCController.h85
-rw-r--r--WebCore/bindings/v8/V8Helpers.cpp59
-rw-r--r--WebCore/bindings/v8/V8Helpers.h49
-rw-r--r--WebCore/bindings/v8/V8HiddenPropertyName.cpp55
-rw-r--r--WebCore/bindings/v8/V8HiddenPropertyName.h49
-rw-r--r--WebCore/bindings/v8/V8Index.cpp425
-rw-r--r--WebCore/bindings/v8/V8Index.h535
-rw-r--r--WebCore/bindings/v8/V8IsolatedWorld.cpp126
-rw-r--r--WebCore/bindings/v8/V8IsolatedWorld.h98
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.cpp30
-rw-r--r--WebCore/bindings/v8/V8NPObject.cpp351
-rw-r--r--WebCore/bindings/v8/V8NPObject.h63
-rw-r--r--WebCore/bindings/v8/V8NPUtils.cpp130
-rw-r--r--WebCore/bindings/v8/V8NPUtils.h46
-rw-r--r--WebCore/bindings/v8/V8NodeFilterCondition.cpp8
-rw-r--r--WebCore/bindings/v8/V8ObjectEventListener.cpp21
-rw-r--r--WebCore/bindings/v8/V8ObjectEventListener.h2
-rw-r--r--WebCore/bindings/v8/V8Proxy.cpp1279
-rw-r--r--WebCore/bindings/v8/V8Proxy.h446
-rw-r--r--WebCore/bindings/v8/V8SVGPODTypeWrapper.h413
-rw-r--r--WebCore/bindings/v8/V8Utilities.cpp6
-rw-r--r--WebCore/bindings/v8/V8Utilities.h24
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.cpp58
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.h1
-rw-r--r--WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp2
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.cpp205
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.h45
-rw-r--r--WebCore/bindings/v8/WorkerScriptController.cpp27
-rw-r--r--WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp139
-rw-r--r--WebCore/bindings/v8/custom/V8AttrCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp152
-rw-r--r--WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8ClipboardCustom.cpp20
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.cpp122
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.h464
-rw-r--r--WebCore/bindings/v8/custom/V8CustomEventListener.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp93
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h63
-rw-r--r--WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp36
-rw-r--r--WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp124
-rw-r--r--WebCore/bindings/v8/custom/V8DataGridColumnListCustom.cpp75
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCustom.cpp41
-rw-r--r--WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp84
-rw-r--r--WebCore/bindings/v8/custom/V8DocumentCustom.cpp33
-rw-r--r--WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8ElementCustom.cpp56
-rw-r--r--WebCore/bindings/v8/custom/V8EventCustom.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp74
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLDataGridElementCustom.cpp70
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp23
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp14
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp24
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp22
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp (renamed from WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp)88
-rw-r--r--WebCore/bindings/v8/custom/V8LocationCustom.cpp64
-rw-r--r--WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp35
-rw-r--r--WebCore/bindings/v8/custom/V8MessagePortCustom.cpp101
-rw-r--r--WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8NavigatorCustom.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp115
-rw-r--r--WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp6
-rw-r--r--WebCore/bindings/v8/custom/V8NodeListCustom.cpp10
-rw-r--r--WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp17
-rw-r--r--WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp27
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp8
-rw-r--r--WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp12
-rw-r--r--WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp97
-rwxr-xr-xWebCore/bindings/v8/custom/V8StorageCustom.cpp13
-rw-r--r--WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp4
-rw-r--r--WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp8
-rwxr-xr-xWebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp2
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerContextCustom.cpp71
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerCustom.cpp114
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp64
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp38
-rw-r--r--WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp2
-rw-r--r--WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp26
-rw-r--r--WebCore/bindings/v8/npruntime.cpp442
-rw-r--r--WebCore/bindings/v8/npruntime_impl.h70
-rw-r--r--WebCore/bindings/v8/npruntime_internal.h41
-rw-r--r--WebCore/bindings/v8/npruntime_priv.h91
294 files changed, 17789 insertions, 2970 deletions
diff --git a/WebCore/bindings/js/CachedScriptSourceProvider.h b/WebCore/bindings/js/CachedScriptSourceProvider.h
index e943fa5..1cdd8aa 100644
--- a/WebCore/bindings/js/CachedScriptSourceProvider.h
+++ b/WebCore/bindings/js/CachedScriptSourceProvider.h
@@ -29,11 +29,12 @@
#include "CachedResourceClient.h"
#include "CachedResourceHandle.h"
#include "CachedScript.h"
+#include "ScriptSourceProvider.h"
#include <parser/SourceCode.h>
namespace WebCore {
- class CachedScriptSourceProvider : public JSC::SourceProvider, public CachedResourceClient {
+ class CachedScriptSourceProvider : public ScriptSourceProvider, public CachedResourceClient {
public:
static PassRefPtr<CachedScriptSourceProvider> create(CachedScript* cachedScript) { return adoptRef(new CachedScriptSourceProvider(cachedScript)); }
@@ -45,10 +46,11 @@ namespace WebCore {
JSC::UString getRange(int start, int end) const { return JSC::UString(m_cachedScript->script().characters() + start, end - start); }
const UChar* data() const { return m_cachedScript->script().characters(); }
int length() const { return m_cachedScript->script().length(); }
+ const String& source() const { return m_cachedScript->script(); }
private:
CachedScriptSourceProvider(CachedScript* cachedScript)
- : SourceProvider(cachedScript->url())
+ : ScriptSourceProvider(cachedScript->url())
, m_cachedScript(cachedScript)
{
m_cachedScript->addClient(this);
diff --git a/WebCore/bindings/js/DOMObjectWithSVGContext.h b/WebCore/bindings/js/DOMObjectWithSVGContext.h
new file mode 100644
index 0000000..570548d
--- /dev/null
+++ b/WebCore/bindings/js/DOMObjectWithSVGContext.h
@@ -0,0 +1,57 @@
+/*
+ * 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 THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMObjectWithSVGContext_h
+#define DOMObjectWithSVGContext_h
+
+#if ENABLE(SVG)
+
+#include "JSDOMBinding.h"
+#include "SVGElement.h"
+
+namespace WebCore {
+
+ // FIXME: This class (and file) should be removed once all SVG bindings
+ // have moved context() onto the various impl() pointers.
+ class DOMObjectWithSVGContext : public DOMObject {
+ public:
+ SVGElement* context() const { return m_context.get(); }
+
+ protected:
+ DOMObjectWithSVGContext(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject*, SVGElement* context)
+ : DOMObject(structure)
+ , m_context(context)
+ {
+ // No space to store the JSDOMGlobalObject w/o hitting the CELL_SIZE limit.
+ }
+
+ protected: // FIXME: Many custom bindings use m_context directly. Making this protected to temporariliy reduce code churn.
+ RefPtr<SVGElement> m_context;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // DOMObjectWithSVGContext_h
diff --git a/WebCore/bindings/js/GCController.cpp b/WebCore/bindings/js/GCController.cpp
index db295c2..59bcfa3 100644
--- a/WebCore/bindings/js/GCController.cpp
+++ b/WebCore/bindings/js/GCController.cpp
@@ -44,7 +44,7 @@ namespace WebCore {
static void* collect(void*)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSDOMWindow::commonJSGlobalData()->heap.collect();
return 0;
}
@@ -70,13 +70,13 @@ void GCController::garbageCollectSoon()
void GCController::gcTimerFired(Timer<GCController>*)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSDOMWindow::commonJSGlobalData()->heap.collect();
}
void GCController::garbageCollectNow()
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSDOMWindow::commonJSGlobalData()->heap.collect();
}
diff --git a/WebCore/bindings/js/GCController.h b/WebCore/bindings/js/GCController.h
index 452019a..4c25407 100644
--- a/WebCore/bindings/js/GCController.h
+++ b/WebCore/bindings/js/GCController.h
@@ -31,7 +31,7 @@
namespace WebCore {
- class GCController : Noncopyable {
+ class GCController : public Noncopyable {
friend GCController& gcController();
public:
diff --git a/WebCore/bindings/js/JSAbstractWorkerCustom.cpp b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
new file mode 100644
index 0000000..003f544
--- /dev/null
+++ b/WebCore/bindings/js/JSAbstractWorkerCustom.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR 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 "JSAbstractWorker.h"
+
+#include "AbstractWorker.h"
+#include "JSDOMGlobalObject.h"
+#include "JSEventListener.h"
+#include "JSEventTarget.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSAbstractWorker::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+
+ markIfNotNull(markStack, m_impl->onerror());
+
+ typedef AbstractWorker::EventListenersMap EventListenersMap;
+ typedef AbstractWorker::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)
+ (*vecIter)->markJSFunction(markStack);
+ }
+}
+
+JSValue JSAbstractWorker::addEventListener(ExecState* exec, const ArgList& args)
+{
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
+ if (!globalObject)
+ return jsUndefined();
+ RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1));
+ if (!listener)
+ return jsUndefined();
+ impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec));
+ return jsUndefined();
+}
+
+JSValue JSAbstractWorker::removeEventListener(ExecState* exec, const ArgList& args)
+{
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
+ if (!globalObject)
+ return jsUndefined();
+ JSEventListener* listener = globalObject->findJSEventListener(args.at(1));
+ if (!listener)
+ return jsUndefined();
+ impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec));
+ return jsUndefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSAttrCustom.cpp b/WebCore/bindings/js/JSAttrCustom.cpp
index 4f3c8ee..abd5ad5 100644
--- a/WebCore/bindings/js/JSAttrCustom.cpp
+++ b/WebCore/bindings/js/JSAttrCustom.cpp
@@ -47,7 +47,7 @@ void JSAttr::setValue(ExecState* exec, JSValue value)
Element* ownerElement = imp->ownerElement();
if (ownerElement && (ownerElement->hasTagName(iframeTag) || ownerElement->hasTagName(frameTag))) {
- if (equalIgnoringCase(imp->name(), "src") && protocolIsJavaScript(parseURL(attrValue))) {
+ if (equalIgnoringCase(imp->name(), "src") && protocolIsJavaScript(deprecatedParseURL(attrValue))) {
if (!checkNodeSecurity(exec, static_cast<HTMLFrameElementBase*>(ownerElement)->contentDocument()))
return;
}
diff --git a/WebCore/bindings/js/JSAudioConstructor.cpp b/WebCore/bindings/js/JSAudioConstructor.cpp
index 74bcad5..87a3880 100644
--- a/WebCore/bindings/js/JSAudioConstructor.cpp
+++ b/WebCore/bindings/js/JSAudioConstructor.cpp
@@ -42,35 +42,27 @@ namespace WebCore {
const ClassInfo JSAudioConstructor::s_info = { "AudioConstructor", 0, 0, 0 };
JSAudioConstructor::JSAudioConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
- : DOMObject(JSAudioConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
- , m_globalObject(globalObject)
+ : DOMConstructorWithDocument(JSAudioConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- ASSERT(globalObject->scriptExecutionContext());
- ASSERT(globalObject->scriptExecutionContext()->isDocument());
-
- putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSHTMLAudioElementPrototype::self(exec, globalObject), 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)
{
+ JSAudioConstructor* jsAudio = static_cast<JSAudioConstructor*>(constructor);
// FIXME: Why doesn't this need the call toJS on the document like JSImageConstructor?
-
- Document* document = static_cast<JSAudioConstructor*>(constructor)->document();
+ Document* document = jsAudio->document();
if (!document)
return throwError(exec, ReferenceError, "Audio constructor associated document is unavailable");
RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document);
+ audio->setAutobuffer(true);
if (args.size() > 0) {
audio->setSrc(args.at(0).toString(exec));
audio->scheduleLoad();
}
- return asObject(toJS(exec, audio.release()));
+ return asObject(toJS(exec, jsAudio->globalObject(), audio.release()));
}
ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData)
@@ -79,13 +71,6 @@ ConstructType JSAudioConstructor::getConstructData(ConstructData& constructData)
return ConstructTypeHost;
}
-void JSAudioConstructor::mark()
-{
- DOMObject::mark();
- if (!m_globalObject->marked())
- m_globalObject->mark();
-}
-
} // namespace WebCore
#endif // ENABLE(VIDEO)
diff --git a/WebCore/bindings/js/JSAudioConstructor.h b/WebCore/bindings/js/JSAudioConstructor.h
index 0a3a7ea..3496897 100644
--- a/WebCore/bindings/js/JSAudioConstructor.h
+++ b/WebCore/bindings/js/JSAudioConstructor.h
@@ -34,21 +34,15 @@
namespace WebCore {
- class JSAudioConstructor : public DOMObject {
+ class JSAudioConstructor : public DOMConstructorWithDocument {
public:
JSAudioConstructor(JSC::ExecState*, JSDOMGlobalObject*);
- Document* document() const;
-
static const JSC::ClassInfo s_info;
-
- virtual void mark();
private:
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
-
- JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSCDATASectionCustom.cpp b/WebCore/bindings/js/JSCDATASectionCustom.cpp
index 44a8957..c2738cc 100644
--- a/WebCore/bindings/js/JSCDATASectionCustom.cpp
+++ b/WebCore/bindings/js/JSCDATASectionCustom.cpp
@@ -32,12 +32,12 @@ using namespace JSC;
namespace WebCore {
-JSValue toJSNewlyCreated(ExecState* exec, CDATASection* section)
+JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, CDATASection* section)
{
if (!section)
return jsNull();
-
- return CREATE_DOM_NODE_WRAPPER(exec, CDATASection, section);
+
+ return CREATE_DOM_NODE_WRAPPER(exec, globalObject, CDATASection, section);
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSCSSRuleCustom.cpp b/WebCore/bindings/js/JSCSSRuleCustom.cpp
index 2c20431..1b96c06 100644
--- a/WebCore/bindings/js/JSCSSRuleCustom.cpp
+++ b/WebCore/bindings/js/JSCSSRuleCustom.cpp
@@ -49,46 +49,45 @@ using namespace JSC;
namespace WebCore {
-JSValue toJS(ExecState* exec, CSSRule* rule)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSRule* rule)
{
if (!rule)
return jsNull();
DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), rule);
-
if (wrapper)
return wrapper;
switch (rule->type()) {
case CSSRule::STYLE_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSStyleRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSStyleRule, rule);
break;
case CSSRule::MEDIA_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSMediaRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSMediaRule, rule);
break;
case CSSRule::FONT_FACE_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSFontFaceRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSFontFaceRule, rule);
break;
case CSSRule::PAGE_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSPageRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSPageRule, rule);
break;
case CSSRule::IMPORT_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSImportRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSImportRule, rule);
break;
case CSSRule::CHARSET_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSCharsetRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSCharsetRule, rule);
break;
case CSSRule::VARIABLES_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSVariablesRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSVariablesRule, rule);
break;
case CSSRule::WEBKIT_KEYFRAME_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSKeyframeRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitCSSKeyframeRule, rule);
break;
case CSSRule::WEBKIT_KEYFRAMES_RULE:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSKeyframesRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitCSSKeyframesRule, rule);
break;
default:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSRule, rule);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSRule, rule);
}
return wrapper;
diff --git a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
index b07f201..280ec93 100644
--- a/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
+++ b/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
@@ -125,7 +125,7 @@ bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*,
return isCSSPropertyName(propertyName);
}
-// FIXME: You can get these properties, and set them (see customPut below),
+// FIXME: You can get these properties, and set them (see putDelegate below),
// but you should also be able to enumerate them.
JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
@@ -156,7 +156,7 @@ JSValue JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& pro
}
-bool JSCSSStyleDeclaration::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
+bool JSCSSStyleDeclaration::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
{
if (!isCSSPropertyName(propertyName))
return false;
diff --git a/WebCore/bindings/js/JSCSSValueCustom.cpp b/WebCore/bindings/js/JSCSSValueCustom.cpp
index ad0cee1..87a5760 100644
--- a/WebCore/bindings/js/JSCSSValueCustom.cpp
+++ b/WebCore/bindings/js/JSCSSValueCustom.cpp
@@ -44,7 +44,7 @@ using namespace JSC;
namespace WebCore {
-JSValue toJS(ExecState* exec, CSSValue* value)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, CSSValue* value)
{
if (!value)
return jsNull();
@@ -55,19 +55,19 @@ JSValue toJS(ExecState* exec, CSSValue* value)
return wrapper;
if (value->isWebKitCSSTransformValue())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSTransformValue, value);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitCSSTransformValue, value);
else if (value->isValueList())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSValueList, value);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSValueList, value);
#if ENABLE(SVG)
else if (value->isSVGPaint())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, SVGPaint, value);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGPaint, value);
else if (value->isSVGColor())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, SVGColor, value);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGColor, value);
#endif
else if (value->isPrimitiveValue())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSPrimitiveValue, value);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSPrimitiveValue, value);
else
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSValue, value);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSValue, value);
return wrapper;
}
diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
index 76db871..398a6799 100644
--- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
+++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,11 +28,13 @@
#include "FloatRect.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
+#include "HTMLVideoElement.h"
#include "ImageData.h"
#include "JSCanvasGradient.h"
#include "JSCanvasPattern.h"
#include "JSHTMLCanvasElement.h"
#include "JSHTMLImageElement.h"
+#include "JSHTMLVideoElement.h"
#include "JSImageData.h"
#include <runtime/Error.h>
@@ -230,6 +232,29 @@ JSValue JSCanvasRenderingContext2D::drawImage(ExecState* exec, const ArgList& ar
default:
return throwError(exec, SyntaxError);
}
+#if ENABLE(VIDEO)
+ } else if (o->inherits(&JSHTMLVideoElement::s_info)) {
+ HTMLVideoElement* video = static_cast<HTMLVideoElement*>(static_cast<JSHTMLElement*>(o)->impl());
+ switch (args.size()) {
+ case 3:
+ context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec));
+ break;
+ case 5:
+ context->drawImage(video, args.at(1).toFloat(exec), args.at(2).toFloat(exec),
+ args.at(3).toFloat(exec), args.at(4).toFloat(exec), ec);
+ setDOMException(exec, ec);
+ break;
+ case 9:
+ context->drawImage(video, FloatRect(args.at(1).toFloat(exec), args.at(2).toFloat(exec),
+ args.at(3).toFloat(exec), args.at(4).toFloat(exec)),
+ FloatRect(args.at(5).toFloat(exec), args.at(6).toFloat(exec),
+ args.at(7).toFloat(exec), args.at(8).toFloat(exec)), ec);
+ setDOMException(exec, ec);
+ break;
+ default:
+ return throwError(exec, SyntaxError);
+ }
+#endif
} else {
setDOMException(exec, TYPE_MISMATCH_ERR);
}
diff --git a/WebCore/bindings/js/JSCustomPositionCallback.cpp b/WebCore/bindings/js/JSCustomPositionCallback.cpp
index 6d892f0..ec2d8e3 100644
--- a/WebCore/bindings/js/JSCustomPositionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionCallback.cpp
@@ -48,11 +48,12 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition)
if (!m_frame->script()->isEnabled())
return;
-
+
+ // FIXME: This is likely the wrong globalObject (for prototype chains at least)
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
CallData callData;
@@ -67,10 +68,10 @@ void JSCustomPositionCallback::handleEvent(Geoposition* geoposition)
}
RefPtr<JSCustomPositionCallback> protect(this);
-
+
MarkedArgumentBuffer args;
- args.append(toJS(exec, geoposition));
-
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), geoposition));
+
globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
globalObject->globalData()->timeoutChecker.stop();
diff --git a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
index cc6cd55..cda5738 100644
--- a/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomPositionErrorCallback.cpp
@@ -48,11 +48,12 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError)
if (!m_frame->script()->isEnabled())
return;
-
+
+ // FIXME: This is likely the wrong globalObject (for prototype chains at least)
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
CallData callData;
@@ -69,7 +70,7 @@ void JSCustomPositionErrorCallback::handleEvent(PositionError* positionError)
RefPtr<JSCustomPositionErrorCallback> protect(this);
MarkedArgumentBuffer args;
- args.append(toJS(exec, positionError));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), positionError));
globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
diff --git a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
index 107a491..d0943de 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementCallback.cpp
@@ -54,10 +54,11 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
if (!m_frame->script()->isEnabled())
return;
+ // FIXME: This is likely the wrong globalObject (for prototype chains at least)
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
CallData callData;
@@ -74,8 +75,8 @@ void JSCustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
RefPtr<JSCustomSQLStatementCallback> protect(this);
MarkedArgumentBuffer args;
- args.append(toJS(exec, transaction));
- args.append(toJS(exec, resultSet));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), resultSet));
globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
diff --git a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
index 018dabd..6c831ac 100644
--- a/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp
@@ -54,11 +54,12 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
if (!m_frame->script()->isEnabled())
return true;
-
+
+ // FIXME: This is likely the wrong globalObject (for prototype chains at least)
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent"));
CallData handleEventCallData;
@@ -77,8 +78,8 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
RefPtr<JSCustomSQLStatementErrorCallback> protect(this);
MarkedArgumentBuffer args;
- args.append(toJS(exec, transaction));
- args.append(toJS(exec, error));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error));
JSValue result;
globalObject->globalData()->timeoutChecker.start();
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
index a41ac78..3d42f81 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionCallback.cpp
@@ -94,11 +94,12 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
if (!m_data->frame()->script()->isEnabled())
return;
-
+
+ // FIXME: This is likely the wrong globalObject (for prototype chains at least)
JSGlobalObject* globalObject = m_data->frame()->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue handleEventFunction = m_data->callback()->get(exec, Identifier(exec, "handleEvent"));
CallData handleEventCallData;
@@ -117,7 +118,7 @@ void JSCustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
RefPtr<JSCustomSQLTransactionCallback> protect(this);
MarkedArgumentBuffer args;
- args.append(toJS(exec, transaction));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), transaction));
globalObject->globalData()->timeoutChecker.start();
if (handleEventCallType != CallTypeNone)
diff --git a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
index 324e2bb..2d41bb8 100644
--- a/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/js/JSCustomSQLTransactionErrorCallback.cpp
@@ -54,10 +54,11 @@ void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
if (!m_frame->script()->isEnabled())
return;
+ // FIXME: This is likely the wrong globalObject (for prototype chains at least)
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
CallData callData;
@@ -74,7 +75,7 @@ void JSCustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
RefPtr<JSCustomSQLTransactionErrorCallback> protect(this);
MarkedArgumentBuffer args;
- args.append(toJS(exec, error));
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), error));
globalObject->globalData()->timeoutChecker.start();
call(exec, function, callType, callData, m_callback, args);
diff --git a/WebCore/bindings/js/JSCustomVoidCallback.cpp b/WebCore/bindings/js/JSCustomVoidCallback.cpp
index f3f76c4..b4e525b 100644
--- a/WebCore/bindings/js/JSCustomVoidCallback.cpp
+++ b/WebCore/bindings/js/JSCustomVoidCallback.cpp
@@ -55,7 +55,7 @@ void JSCustomVoidCallback::handleEvent()
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSValue function = m_callback->get(exec, Identifier(exec, "handleEvent"));
CallData callData;
diff --git a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
index 6361e70..4476be5 100644
--- a/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
+++ b/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
@@ -72,7 +72,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
if (!m_frame->script()->isEnabled())
return String();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSGlobalObject* globalObject = m_frame->script()->globalObject();
ExecState* exec = globalObject->globalExec();
@@ -84,7 +84,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
callType = m_customResolver->getCallData(callData);
if (callType == CallTypeNone) {
// FIXME: Pass actual line number and source URL.
- m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String());
+ m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, "XPathNSResolver does not have a lookupNamespaceURI method.", 0, String());
return String();
}
function = m_customResolver;
diff --git a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
index 7e8d9ce..109308c 100644
--- a/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
@@ -42,25 +42,25 @@ using namespace JSC;
namespace WebCore {
-void JSDOMApplicationCache::mark()
+void JSDOMApplicationCache::markChildren(MarkStack& markStack)
{
- DOMObject::mark();
+ Base::markChildren(markStack);
- 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());
+ markIfNotNull(markStack, m_impl->onchecking());
+ markIfNotNull(markStack, m_impl->onerror());
+ markIfNotNull(markStack, m_impl->onnoupdate());
+ markIfNotNull(markStack, m_impl->ondownloading());
+ markIfNotNull(markStack, m_impl->onprogress());
+ markIfNotNull(markStack, m_impl->onupdateready());
+ markIfNotNull(markStack, m_impl->oncached());
+ markIfNotNull(markStack, 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)
- (*vecIter)->markJSFunction();
+ (*vecIter)->markJSFunction(markStack);
}
}
diff --git a/WebCore/bindings/js/JSDOMBinding.cpp b/WebCore/bindings/js/JSDOMBinding.cpp
index 4f58797..566b986 100644
--- a/WebCore/bindings/js/JSDOMBinding.cpp
+++ b/WebCore/bindings/js/JSDOMBinding.cpp
@@ -18,11 +18,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-// gcc 3.x can't handle including the HashMap pointer specialization in this file
-#if defined __GNUC__ && !defined __GLIBCXX__ // less than gcc 3.4
-#define HASH_MAP_PTR_SPEC_WORKAROUND 1
-#endif
-
#include "config.h"
#include "JSDOMBinding.h"
@@ -32,6 +27,7 @@
#include "EventException.h"
#include "ExceptionCode.h"
#include "Frame.h"
+#include "HTMLAudioElement.h"
#include "HTMLImageElement.h"
#include "HTMLScriptElement.h"
#include "HTMLNames.h"
@@ -288,23 +284,27 @@ static inline bool isObservableThroughDOM(JSNode* jsNode)
return true;
if (node->hasTagName(scriptTag) && !static_cast<HTMLScriptElement*>(node)->haveFiredLoadEvent())
return true;
+#if ENABLE(VIDEO)
+ if (node->hasTagName(audioTag) && !static_cast<HTMLAudioElement*>(node)->paused())
+ return true;
+#endif
}
return false;
}
-void markDOMNodesForDocument(Document* doc)
+void markDOMNodesForDocument(MarkStack& markStack, Document* doc)
{
JSWrapperCache& nodeDict = doc->wrapperCache();
JSWrapperCache::iterator nodeEnd = nodeDict.end();
for (JSWrapperCache::iterator nodeIt = nodeDict.begin(); nodeIt != nodeEnd; ++nodeIt) {
JSNode* jsNode = nodeIt->second;
- if (!jsNode->marked() && isObservableThroughDOM(jsNode))
- jsNode->mark();
+ if (isObservableThroughDOM(jsNode))
+ markStack.append(jsNode);
}
}
-void markActiveObjectsForContext(JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext)
+void markActiveObjectsForContext(MarkStack& markStack, JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext)
{
// If an element has pending activity that may result in event listeners being called
// (e.g. an XMLHttpRequest), we need to keep JS wrappers alive.
@@ -317,19 +317,19 @@ void markActiveObjectsForContext(JSGlobalData& globalData, ScriptExecutionContex
// Generally, an active object with pending activity must have a wrapper to mark its listeners.
// However, some ActiveDOMObjects don't have JS wrappers (timers created by setTimeout is one example).
// FIXME: perhaps need to make sure even timers have a markable 'wrapper'.
- if (wrapper && !wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
}
const HashSet<MessagePort*>& messagePorts = scriptExecutionContext->messagePorts();
HashSet<MessagePort*>::const_iterator portsEnd = messagePorts.end();
for (HashSet<MessagePort*>::const_iterator iter = messagePorts.begin(); iter != portsEnd; ++iter) {
- if ((*iter)->hasPendingActivity()) {
+ // If the message port is remotely entangled, then always mark it as in-use because we can't determine reachability across threads.
+ if (!(*iter)->locallyEntangledPort() || (*iter)->hasPendingActivity()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, *iter);
- // A port with pending activity must have a wrapper to mark its listeners, so no null check.
- if (!wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
}
}
@@ -346,14 +346,14 @@ void updateDOMNodeDocument(Node* node, Document* oldDocument, Document* newDocum
addWrapper(wrapper);
}
-void markDOMObjectWrapper(JSGlobalData& globalData, void* object)
+void markDOMObjectWrapper(MarkStack& markStack, JSGlobalData& globalData, void* object)
{
if (!object)
return;
DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, object);
- if (!wrapper || wrapper->marked())
+ if (!wrapper)
return;
- wrapper->mark();
+ markStack.append(wrapper);
}
JSValue jsStringOrNull(ExecState* exec, const String& s)
@@ -450,31 +450,36 @@ void setDOMException(ExecState* exec, ExceptionCode ec)
if (!ec || exec->hadException())
return;
+ // FIXME: All callers to setDOMException need to pass in the right global object
+ // for now, we're going to assume the lexicalGlobalObject. Which is wrong in cases like this:
+ // frames[0].document.createElement(null, null); // throws an exception which should have the subframes prototypes.
+ JSDOMGlobalObject* globalObject = deprecatedGlobalObjectForPrototype(exec);
+
ExceptionCodeDescription description;
getExceptionCodeDescription(ec, description);
JSValue errorObject;
switch (description.type) {
case DOMExceptionType:
- errorObject = toJS(exec, DOMCoreException::create(description));
+ errorObject = toJS(exec, globalObject, DOMCoreException::create(description));
break;
case RangeExceptionType:
- errorObject = toJS(exec, RangeException::create(description));
+ errorObject = toJS(exec, globalObject, RangeException::create(description));
break;
case EventExceptionType:
- errorObject = toJS(exec, EventException::create(description));
+ errorObject = toJS(exec, globalObject, EventException::create(description));
break;
case XMLHttpRequestExceptionType:
- errorObject = toJS(exec, XMLHttpRequestException::create(description));
+ errorObject = toJS(exec, globalObject, XMLHttpRequestException::create(description));
break;
#if ENABLE(SVG)
case SVGExceptionType:
- errorObject = toJS(exec, SVGException::create(description).get(), 0);
+ errorObject = toJS(exec, globalObject, SVGException::create(description).get(), 0);
break;
#endif
#if ENABLE(XPATH)
case XPathExceptionType:
- errorObject = toJS(exec, XPathException::create(description));
+ errorObject = toJS(exec, globalObject, XPathException::create(description));
break;
#endif
}
@@ -545,7 +550,7 @@ KURL completeURL(ExecState* exec, const String& relativeURL)
JSValue objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, objectProtoFuncToString);
}
Structure* getCachedDOMStructure(JSDOMGlobalObject* globalObject, const ClassInfo* classInfo)
diff --git a/WebCore/bindings/js/JSDOMBinding.h b/WebCore/bindings/js/JSDOMBinding.h
index 1378c91..64cfc3a 100644
--- a/WebCore/bindings/js/JSDOMBinding.h
+++ b/WebCore/bindings/js/JSDOMBinding.h
@@ -1,7 +1,8 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * 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.
* Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * 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 Lesser General Public
@@ -22,6 +23,7 @@
#define JSDOMBinding_h
#include "JSDOMGlobalObject.h"
+#include "Document.h" // For DOMConstructorWithDocument
#include <runtime/Completion.h>
#include <runtime/Lookup.h>
#include <runtime/JSFunction.h>
@@ -59,6 +61,72 @@ namespace WebCore {
#endif
};
+ // FIXME: This class should colapse into DOMObject once all DOMObjects are
+ // updated to store a globalObject pointer.
+ class DOMObjectWithGlobalPointer : public DOMObject {
+ public:
+ JSDOMGlobalObject* globalObject() const { return m_globalObject; }
+
+ ScriptExecutionContext* scriptExecutionContext() const
+ {
+ // FIXME: Should never be 0, but can be due to bug 27640.
+ return m_globalObject->scriptExecutionContext();
+ }
+
+ protected:
+ DOMObjectWithGlobalPointer(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
+ : DOMObject(structure)
+ , m_globalObject(globalObject)
+ {
+ // FIXME: This ASSERT is valid, but fires in fast/dom/gc-6.html when trying to create
+ // new JavaScript objects on detached windows due to DOMWindow::document()
+ // needing to reach through the frame to get to the Document*. See bug 27640.
+ // ASSERT(globalObject->scriptExecutionContext());
+ }
+ virtual ~DOMObjectWithGlobalPointer() {}
+
+ void markChildren(JSC::MarkStack& markStack)
+ {
+ DOMObject::markChildren(markStack);
+ markStack.append(m_globalObject);
+ }
+
+ private:
+ JSDOMGlobalObject* m_globalObject;
+ };
+
+ // Base class for all constructor objects in the JSC bindings.
+ class DOMConstructorObject : public DOMObjectWithGlobalPointer {
+ public:
+ static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::HasStandardGetOwnPropertySlot | JSC::ImplementsHasInstance));
+ }
+
+ protected:
+ DOMConstructorObject(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
+ : DOMObjectWithGlobalPointer(structure, globalObject)
+ {
+ }
+ };
+
+ // Constructors using this base class depend on being in a Document and
+ // can never be used from a WorkerContext.
+ class DOMConstructorWithDocument : public DOMConstructorObject {
+ public:
+ Document* document() const
+ {
+ return static_cast<Document*>(scriptExecutionContext());
+ }
+
+ protected:
+ DOMConstructorWithDocument(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(structure, globalObject)
+ {
+ ASSERT(globalObject->scriptExecutionContext()->isDocument());
+ }
+ };
+
DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle);
void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper);
void forgetDOMObject(JSC::JSGlobalData&, void* objectHandle);
@@ -68,9 +136,9 @@ namespace WebCore {
void forgetDOMNode(Document*, Node*);
void forgetAllDOMNodesForDocument(Document*);
void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument);
- void markDOMNodesForDocument(Document*);
- void markActiveObjectsForContext(JSC::JSGlobalData&, ScriptExecutionContext*);
- void markDOMObjectWrapper(JSC::JSGlobalData& globalData, void* object);
+ void markDOMNodesForDocument(JSC::MarkStack&, Document*);
+ void markActiveObjectsForContext(JSC::MarkStack&, JSC::JSGlobalData&, ScriptExecutionContext*);
+ void markDOMObjectWrapper(JSC::MarkStack&, JSC::JSGlobalData& globalData, void* object);
JSC::Structure* getCachedDOMStructure(JSDOMGlobalObject*, const JSC::ClassInfo*);
JSC::Structure* cacheDOMStructure(JSDOMGlobalObject*, PassRefPtr<JSC::Structure>, const JSC::ClassInfo*);
@@ -80,74 +148,86 @@ namespace WebCore {
JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*);
void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor);
+ inline JSDOMGlobalObject* deprecatedGlobalObjectForPrototype(JSC::ExecState* exec)
+ {
+ // FIXME: Callers to this function should be using the global object
+ // from which the object is being created, instead of assuming the lexical one.
+ // e.g. subframe.document.body should use the subframe's global object, not the lexical one.
+ return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
+ }
+
template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec, JSDOMGlobalObject* globalObject)
{
if (JSC::Structure* structure = getCachedDOMStructure(globalObject, &WrapperClass::s_info))
return structure;
return cacheDOMStructure(globalObject, WrapperClass::createStructure(WrapperClass::createPrototype(exec, globalObject)), &WrapperClass::s_info);
}
- template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec)
+ template<class WrapperClass> inline JSC::Structure* deprecatedGetDOMStructure(JSC::ExecState* exec)
{
- return getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()));
+ // FIXME: This function is wrong. It uses the wrong global object for creating the prototype structure.
+ return getDOMStructure<WrapperClass>(exec, deprecatedGlobalObjectForPrototype(exec));
}
template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject)
{
return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(globalObject))->storedPrototype()));
}
- #define CREATE_DOM_OBJECT_WRAPPER(exec, className, object) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object))
- template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object)
+ #define CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, className, object) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
+ template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object)
{
ASSERT(object);
ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object));
- WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), object);
+ // FIXME: new (exec) could use a different globalData than the globalData this wrapper is cached on.
+ WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object);
cacheDOMObjectWrapper(exec->globalData(), object, wrapper);
return wrapper;
}
- template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object)
+ template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object)
{
if (!object)
return JSC::jsNull();
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object))
return wrapper;
- return createDOMObjectWrapper<WrapperClass>(exec, object);
+ return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object);
}
#if ENABLE(SVG)
- #define CREATE_SVG_OBJECT_WRAPPER(exec, className, object, context) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object), context)
- template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context)
+ #define CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, className, object, context) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object), context)
+ template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context)
{
ASSERT(object);
ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object));
- WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), object, context);
+ WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object, context);
cacheDOMObjectWrapper(exec->globalData(), object, wrapper);
return wrapper;
}
- template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context)
+ template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context)
{
if (!object)
return JSC::jsNull();
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object))
return wrapper;
- return createDOMObjectWrapper<WrapperClass>(exec, object, context);
+ return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object, context);
}
#endif
- #define CREATE_DOM_NODE_WRAPPER(exec, className, object) createDOMNodeWrapper<JS##className>(exec, static_cast<className*>(object))
- template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node)
+ #define CREATE_DOM_NODE_WRAPPER(exec, globalObject, className, object) createDOMNodeWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
+ template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
ASSERT(node);
ASSERT(!getCachedDOMNodeWrapper(node->document(), node));
- WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec), node);
+ WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node);
+ // FIXME: The entire function can be removed, once we fix caching.
+ // This function is a one-off hack to make Nodes cache in the right global object.
cacheDOMNodeWrapper(node->document(), node, wrapper);
return wrapper;
}
- template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node)
+ template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
if (!node)
return JSC::jsNull();
if (JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node))
return wrapper;
- return createDOMNodeWrapper<WrapperClass>(exec, node);
+ return createDOMNodeWrapper<WrapperClass>(exec, globalObject, node);
}
const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable);
@@ -174,7 +254,28 @@ namespace WebCore {
JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null
JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined
- template <typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); }
+ // FIXME: These are a stop-gap until all toJS calls can be converted to pass a globalObject
+ template <typename T>
+ inline JSC::JSValue toJS(JSC::ExecState* exec, T* ptr)
+ {
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
+ }
+ template <typename T>
+ inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr)
+ {
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr.get());
+ }
+ template <typename T>
+ inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* exec, T* ptr)
+ {
+ return toJSNewlyCreated(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
+ }
+
+ template <typename T>
+ inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<T> ptr)
+ {
+ return toJS(exec, globalObject, ptr.get());
+ }
bool checkNodeSecurity(JSC::ExecState*, Node*);
diff --git a/WebCore/bindings/js/JSDOMGlobalObject.cpp b/WebCore/bindings/js/JSDOMGlobalObject.cpp
index a7f7b21..68a1db9 100644
--- a/WebCore/bindings/js/JSDOMGlobalObject.cpp
+++ b/WebCore/bindings/js/JSDOMGlobalObject.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
@@ -58,19 +58,17 @@ JSDOMGlobalObject::~JSDOMGlobalObject()
it->second->clearGlobalObject();
}
-void JSDOMGlobalObject::mark()
+void JSDOMGlobalObject::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
JSDOMStructureMap::iterator end = structures().end();
for (JSDOMStructureMap::iterator it = structures().begin(); it != end; ++it)
- it->second->mark();
+ it->second->markAggregate(markStack);
JSDOMConstructorMap::iterator end2 = constructors().end();
- for (JSDOMConstructorMap::iterator it2 = constructors().begin(); it2 != end2; ++it2) {
- if (!it2->second->marked())
- it2->second->mark();
- }
+ for (JSDOMConstructorMap::iterator it2 = constructors().begin(); it2 != end2; ++it2)
+ markStack.append(it2->second);
}
JSEventListener* JSDOMGlobalObject::findJSEventListener(JSValue val)
@@ -116,10 +114,15 @@ Event* JSDOMGlobalObject::currentEvent() const
return d()->evt;
}
+JSDOMGlobalObject* toJSDOMGlobalObject(Document* document)
+{
+ return toJSDOMWindow(document->frame());
+}
+
JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext* scriptExecutionContext)
{
if (scriptExecutionContext->isDocument())
- return toJSDOMWindow(static_cast<Document*>(scriptExecutionContext)->frame());
+ return toJSDOMGlobalObject(static_cast<Document*>(scriptExecutionContext));
#if ENABLE(WORKERS)
if (scriptExecutionContext->isWorkerContext())
diff --git a/WebCore/bindings/js/JSDOMGlobalObject.h b/WebCore/bindings/js/JSDOMGlobalObject.h
index 8e4e820..855691c 100644
--- a/WebCore/bindings/js/JSDOMGlobalObject.h
+++ b/WebCore/bindings/js/JSDOMGlobalObject.h
@@ -31,6 +31,7 @@
namespace WebCore {
+ class Document;
class Event;
class JSLazyEventListener;
class JSEventListener;
@@ -67,10 +68,13 @@ namespace WebCore {
JSListenersMap& jsEventListeners();
+ // Make binding code generation easier.
+ JSDOMGlobalObject* globalObject() { return this; }
+
void setCurrentEvent(Event*);
Event* currentEvent() const;
- virtual void mark();
+ virtual void markChildren(JSC::MarkStack&);
protected:
struct JSDOMGlobalObjectData : public JSC::JSGlobalObject::JSGlobalObjectData {
@@ -89,16 +93,6 @@ namespace WebCore {
};
template<class ConstructorClass>
- inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec)
- {
- if (JSC::JSObject* constructor = getCachedDOMConstructor(exec, &ConstructorClass::s_info))
- return constructor;
- JSC::JSObject* constructor = new (exec) ConstructorClass(exec);
- cacheDOMConstructor(exec, &ConstructorClass::s_info, constructor);
- return constructor;
- }
-
- template<class ConstructorClass>
inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec, const JSDOMGlobalObject* globalObject)
{
if (JSC::JSObject* constructor = globalObject->constructors().get(&ConstructorClass::s_info))
@@ -109,6 +103,7 @@ namespace WebCore {
return constructor;
}
+ JSDOMGlobalObject* toJSDOMGlobalObject(Document*);
JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*);
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp
index 4fd1139..df6068a 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.cpp
+++ b/WebCore/bindings/js/JSDOMWindowBase.cpp
@@ -26,13 +26,9 @@
#include "CString.h"
#include "Console.h"
#include "DOMWindow.h"
-#include "Element.h"
#include "Frame.h"
-#include "HTMLCollection.h"
-#include "HTMLDocument.h"
#include "InspectorController.h"
#include "JSDOMWindowCustom.h"
-#include "JSHTMLCollection.h"
#include "JSNode.h"
#include "Logging.h"
#include "Page.h"
@@ -67,7 +63,7 @@ void JSDOMWindowBase::updateDocument()
{
ASSERT(d()->impl->document());
ExecState* exec = globalExec();
- symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, d()->impl->document()), DontDelete | ReadOnly);
+ symbolTablePutWithAttributes(Identifier(exec, "document"), toJS(exec, this, d()->impl->document()), DontDelete | ReadOnly);
}
ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const
@@ -75,88 +71,6 @@ ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const
return d()->impl->document();
}
-JSValue JSDOMWindowBase::childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
-{
- return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow());
-}
-
-JSValue JSDOMWindowBase::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
-{
- return toJS(exec, static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow());
-}
-
-JSValue JSDOMWindowBase::namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
-{
- JSDOMWindowBase* thisObj = static_cast<JSDOMWindowBase*>(asObject(slot.slotBase()));
- Document* doc = thisObj->impl()->frame()->document();
- ASSERT(thisObj->allowsAccessFrom(exec));
- ASSERT(doc);
- ASSERT(doc->isHTMLDocument());
-
- RefPtr<HTMLCollection> collection = doc->windowNamedItems(propertyName);
- if (collection->length() == 1)
- return toJS(exec, collection->firstItem());
- return toJS(exec, collection.get());
-}
-
-bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
- // Check for child frames by name before built-in properties to
- // match Mozilla. This does not match IE, but some sites end up
- // naming frames things that conflict with window properties that
- // are in Moz but not IE. Since we have some of these, we have to do
- // it the Moz way.
- if (impl()->frame()->tree()->child(propertyName)) {
- slot.setCustom(this, childFrameGetter);
- return true;
- }
-
- // Do prototype lookup early so that functions and attributes in the prototype can have
- // precedence over the index and name getters.
- JSValue proto = prototype();
- if (proto.isObject()) {
- if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) {
- if (!allowsAccessFrom(exec))
- slot.setUndefined();
- return true;
- }
- }
-
- // FIXME: Search the whole frame hierachy somewhere around here.
- // We need to test the correct priority order.
-
- // allow window[1] or parent[1] etc. (#56983)
- bool ok;
- unsigned i = propertyName.toArrayIndex(&ok);
- if (ok && i < impl()->frame()->tree()->childCount()) {
- slot.setCustomIndex(this, i, indexGetter);
- return true;
- }
-
- if (!allowsAccessFrom(exec)) {
- slot.setUndefined();
- return true;
- }
-
- // Allow shortcuts like 'Image1' instead of document.images.Image1
- Document* document = impl()->frame()->document();
- if (document->isHTMLDocument()) {
- AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName);
- if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
- slot.setCustom(this, namedItemGetter);
- return true;
- }
- }
-
- return Base::getOwnPropertySlot(exec, propertyName, slot);
-}
-
-void JSDOMWindowBase::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
-{
- if (allowsAccessFrom(exec))
- Base::put(exec, propertyName, value, slot);
-}
-
String JSDOMWindowBase::crossDomainAccessErrorMessage(const JSGlobalObject* other) const
{
KURL originURL = asJSDOMWindow(other)->impl()->url();
@@ -185,7 +99,7 @@ void JSDOMWindowBase::printErrorMessage(const String& message) const
if (settings->privateBrowsingEnabled())
return;
- impl()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
+ impl()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, 1, String()); // FIXME: provide a real line number and source URL.
}
ExecState* JSDOMWindowBase::globalExec()
@@ -258,6 +172,13 @@ JSGlobalData* JSDOMWindowBase::commonJSGlobalData()
return globalData;
}
+// JSDOMGlobalObject* is ignored, accesing a window in any context will
+// use that DOMWindow's prototype chain.
+JSValue toJS(ExecState* exec, JSDOMGlobalObject*, DOMWindow* domWindow)
+{
+ return toJS(exec, domWindow);
+}
+
JSValue toJS(ExecState*, DOMWindow* domWindow)
{
if (!domWindow)
diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h
index 6d93196..84cc81f 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.h
+++ b/WebCore/bindings/js/JSDOMWindowBase.h
@@ -40,7 +40,6 @@ namespace WebCore {
class JSDOMWindowBasePrivate;
- // This is the only WebCore JS binding which does not inherit from DOMObject
class JSDOMWindowBase : public JSDOMGlobalObject {
typedef JSDOMGlobalObject Base;
protected:
@@ -52,9 +51,6 @@ namespace WebCore {
DOMWindow* impl() const { return d()->impl.get(); }
virtual ScriptExecutionContext* scriptExecutionContext() const;
- virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);
- virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
-
// Called just before removing this window from the JSDOMWindowShell.
void willRemoveFromWindowShell();
@@ -62,15 +58,12 @@ namespace WebCore {
static const JSC::ClassInfo s_info;
virtual JSC::ExecState* globalExec();
-
virtual bool supportsProfiling() const;
-
virtual bool shouldInterruptScript() const;
bool allowsAccessFrom(JSC::ExecState*) const;
bool allowsAccessFromNoErrorMessage(JSC::ExecState*) const;
bool allowsAccessFrom(JSC::ExecState*, String& message) const;
-
void printErrorMessage(const String&) const;
// Don't call this version of allowsAccessFrom -- it's a slightly incorrect implementation used only by WebScriptObject
@@ -89,10 +82,6 @@ namespace WebCore {
JSDOMWindowShell* shell;
};
- static JSC::JSValue childFrameGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);
- static JSC::JSValue indexGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);
- static JSC::JSValue namedItemGetter(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&);
-
bool allowsAccessFromPrivate(const JSC::JSGlobalObject*) const;
String crossDomainAccessErrorMessage(const JSC::JSGlobalObject*) const;
@@ -100,6 +89,9 @@ namespace WebCore {
};
// Returns a JSDOMWindow or jsNull()
+ // JSDOMGlobalObject* is ignored, accesing a window in any context will
+ // use that DOMWindow's prototype chain.
+ JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, DOMWindow*);
JSC::JSValue toJS(JSC::ExecState*, DOMWindow*);
// Returns JSDOMWindow or 0
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.cpp b/WebCore/bindings/js/JSDOMWindowCustom.cpp
index b8c30c7..9798972 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.cpp
+++ b/WebCore/bindings/js/JSDOMWindowCustom.cpp
@@ -31,17 +31,21 @@
#include "FrameLoader.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "HTMLCollection.h"
+#include "HTMLDocument.h"
#include "History.h"
#include "JSAudioConstructor.h"
#include "JSDOMWindowShell.h"
#include "JSEvent.h"
#include "JSEventListener.h"
+#include "JSHTMLCollection.h"
#include "JSHistory.h"
#include "JSImageConstructor.h"
#include "JSLocation.h"
#include "JSMessageChannelConstructor.h"
#include "JSMessagePort.h"
#include "JSOptionConstructor.h"
+#include "JSSharedWorkerConstructor.h"
#include "JSWebKitCSSMatrixConstructor.h"
#include "JSWebKitPointConstructor.h"
#include "JSWorkerConstructor.h"
@@ -58,40 +62,234 @@
#include "Settings.h"
#include "WindowFeatures.h"
#include <runtime/JSObject.h>
+#include <runtime/PrototypeFunction.h>
using namespace JSC;
namespace WebCore {
-void JSDOMWindow::mark()
+void JSDOMWindow::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
- markEventListeners(impl()->eventListeners());
+ markEventListeners(markStack, impl()->eventListeners());
JSGlobalData& globalData = *Heap::heap(this)->globalData();
- markDOMObjectWrapper(globalData, impl()->optionalConsole());
- markDOMObjectWrapper(globalData, impl()->optionalHistory());
- markDOMObjectWrapper(globalData, impl()->optionalLocationbar());
- markDOMObjectWrapper(globalData, impl()->optionalMenubar());
- markDOMObjectWrapper(globalData, impl()->optionalNavigator());
- markDOMObjectWrapper(globalData, impl()->optionalPersonalbar());
- markDOMObjectWrapper(globalData, impl()->optionalScreen());
- markDOMObjectWrapper(globalData, impl()->optionalScrollbars());
- markDOMObjectWrapper(globalData, impl()->optionalSelection());
- markDOMObjectWrapper(globalData, impl()->optionalStatusbar());
- markDOMObjectWrapper(globalData, impl()->optionalToolbar());
- markDOMObjectWrapper(globalData, impl()->optionalLocation());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalConsole());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalHistory());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalLocationbar());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalMenubar());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalPersonalbar());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalScreen());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalScrollbars());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalSelection());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalStatusbar());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalToolbar());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation());
#if ENABLE(DOM_STORAGE)
- markDOMObjectWrapper(globalData, impl()->optionalSessionStorage());
- markDOMObjectWrapper(globalData, impl()->optionalLocalStorage());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalSessionStorage());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalLocalStorage());
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
- markDOMObjectWrapper(globalData, impl()->optionalApplicationCache());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalApplicationCache());
#endif
}
+template<NativeFunction nativeFunction, int length>
+JSValue nonCachingStaticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
+{
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), length, propertyName, nativeFunction);
+}
+
+static JSValue childFrameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+{
+ return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(AtomicString(propertyName))->domWindow());
+}
+
+static JSValue indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+{
+ return toJS(exec, static_cast<JSDOMWindow*>(asObject(slot.slotBase()))->impl()->frame()->tree()->child(slot.index())->domWindow());
+}
+
+static JSValue namedItemGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+{
+ JSDOMWindowBase* thisObj = static_cast<JSDOMWindow*>(asObject(slot.slotBase()));
+ Document* document = thisObj->impl()->frame()->document();
+
+ ASSERT(thisObj->allowsAccessFrom(exec));
+ ASSERT(document);
+ ASSERT(document->isHTMLDocument());
+
+ RefPtr<HTMLCollection> collection = document->windowNamedItems(propertyName);
+ if (collection->length() == 1)
+ return toJS(exec, collection->firstItem());
+ return toJS(exec, collection.get());
+}
+
+bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+ // When accessing a Window cross-domain, functions are always the native built-in ones, and they
+ // are not affected by properties changed on the Window or anything in its prototype chain.
+ // This is consistent with the behavior of Firefox.
+
+ const HashEntry* entry;
+
+ // We don't want any properties other than "close" and "closed" on a closed window.
+ if (!impl()->frame()) {
+ // The following code is safe for cross-domain and same domain use.
+ // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype).
+ entry = s_info.propHashTable(exec)->entry(exec, propertyName);
+ if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) {
+ slot.setCustom(this, entry->propertyGetter());
+ return true;
+ }
+ entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
+ if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) {
+ slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
+ return true;
+ }
+
+ // FIXME: We should have a message here that explains why the property access/function call was
+ // not allowed.
+ slot.setUndefined();
+ return true;
+ }
+
+ // We need to check for cross-domain access here without printing the generic warning message
+ // because we always allow access to some function, just different ones depending whether access
+ // is allowed.
+ String errorMessage;
+ bool allowsAccess = allowsAccessFrom(exec, errorMessage);
+
+ // 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 JSDOMWindowBase will stop the search before we even get to the
+ // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot.
+ // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of
+ // what prototype is actually set on this object.
+ entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
+ if (entry) {
+ if (entry->attributes() & Function) {
+ if (entry->function() == jsDOMWindowPrototypeFunctionBlur) {
+ if (!allowsAccess) {
+ slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>);
+ return true;
+ }
+ } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) {
+ if (!allowsAccess) {
+ slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
+ return true;
+ }
+ } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) {
+ if (!allowsAccess) {
+ slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>);
+ return true;
+ }
+ } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) {
+ if (!allowsAccess) {
+ slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>);
+ return true;
+ }
+ } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) {
+ if (!DOMWindow::canShowModalDialog(impl()->frame())) {
+ slot.setUndefined();
+ return true;
+ }
+ }
+ }
+ } else {
+ // Allow access to toString() cross-domain, but always Object.prototype.toString.
+ if (propertyName == exec->propertyNames().toString) {
+ if (!allowsAccess) {
+ slot.setCustom(this, objectToStringFunctionGetter);
+ return true;
+ }
+ }
+ }
+
+ entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName);
+ if (entry) {
+ slot.setCustom(this, entry->propertyGetter());
+ return true;
+ }
+
+ // Check for child frames by name before built-in properties to
+ // match Mozilla. This does not match IE, but some sites end up
+ // naming frames things that conflict with window properties that
+ // are in Moz but not IE. Since we have some of these, we have to do
+ // it the Moz way.
+ if (impl()->frame()->tree()->child(propertyName)) {
+ slot.setCustom(this, childFrameGetter);
+ return true;
+ }
+
+ // Do prototype lookup early so that functions and attributes in the prototype can have
+ // precedence over the index and name getters.
+ JSValue proto = prototype();
+ if (proto.isObject()) {
+ if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) {
+ if (!allowsAccess) {
+ printErrorMessage(errorMessage);
+ slot.setUndefined();
+ }
+ return true;
+ }
+ }
+
+ // FIXME: Search the whole frame hierachy somewhere around here.
+ // We need to test the correct priority order.
+
+ // allow window[1] or parent[1] etc. (#56983)
+ bool ok;
+ unsigned i = propertyName.toArrayIndex(&ok);
+ if (ok && i < impl()->frame()->tree()->childCount()) {
+ slot.setCustomIndex(this, i, indexGetter);
+ return true;
+ }
+
+ if (!allowsAccess) {
+ printErrorMessage(errorMessage);
+ slot.setUndefined();
+ return true;
+ }
+
+ // Allow shortcuts like 'Image1' instead of document.images.Image1
+ Document* document = impl()->frame()->document();
+ if (document->isHTMLDocument()) {
+ AtomicStringImpl* atomicPropertyName = AtomicString::find(propertyName);
+ if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
+ slot.setCustom(this, namedItemGetter);
+ return true;
+ }
+ }
+
+ return Base::getOwnPropertySlot(exec, propertyName, slot);
+}
+
+void JSDOMWindow::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+{
+ if (!impl()->frame())
+ return;
+
+ // Optimization: access JavaScript global variables directly before involving the DOM.
+ if (JSGlobalObject::hasOwnPropertyForWrite(exec, propertyName)) {
+ if (allowsAccessFrom(exec))
+ JSGlobalObject::put(exec, propertyName, value, slot);
+ return;
+ }
+
+ if (lookupPut<JSDOMWindow>(exec, propertyName, value, s_info.propHashTable(exec), this))
+ return;
+
+ if (allowsAccessFrom(exec))
+ Base::put(exec, propertyName, value, slot);
+}
+
bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
// Only allow deleting properties by frames in the same origin.
@@ -100,15 +298,15 @@ bool JSDOMWindow::deleteProperty(ExecState* exec, const Identifier& propertyName
return Base::deleteProperty(exec, propertyName);
}
-bool JSDOMWindow::customGetPropertyNames(ExecState* exec, PropertyNameArray&)
+void JSDOMWindow::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
// Only allow the window to enumerated by frames in the same origin.
if (!allowsAccessFrom(exec))
- return true;
- return false;
+ return;
+ Base::getPropertyNames(exec, propertyNames);
}
-bool JSDOMWindow::getPropertyAttributes(JSC::ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
+bool JSDOMWindow::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
{
// Only allow getting property attributes properties by frames in the same origin.
if (!allowsAccessFrom(exec))
@@ -161,7 +359,8 @@ JSValue JSDOMWindow::history(ExecState* exec) const
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), history))
return wrapper;
- JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, const_cast<JSDOMWindow*>(this)), history);
+ JSDOMWindow* window = const_cast<JSDOMWindow*>(this);
+ JSHistory* jsHistory = new (exec) JSHistory(getDOMStructure<JSHistory>(exec, window), window, history);
cacheDOMObjectWrapper(exec->globalData(), history, jsHistory);
return jsHistory;
}
@@ -172,7 +371,8 @@ JSValue JSDOMWindow::location(ExecState* exec) const
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location))
return wrapper;
- JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, const_cast<JSDOMWindow*>(this)), location);
+ JSDOMWindow* window = const_cast<JSDOMWindow*>(this);
+ JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), window, location);
cacheDOMObjectWrapper(exec->globalData(), location, jsLocation);
return jsLocation;
}
@@ -245,12 +445,12 @@ JSValue JSDOMWindow::audio(ExecState* exec) const
JSValue JSDOMWindow::webKitPoint(ExecState* exec) const
{
- return getDOMConstructor<JSWebKitPointConstructor>(exec);
+ return getDOMConstructor<JSWebKitPointConstructor>(exec, this);
}
JSValue JSDOMWindow::webKitCSSMatrix(ExecState* exec) const
{
- return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec);
+ return getDOMConstructor<JSWebKitCSSMatrixConstructor>(exec, this);
}
JSValue JSDOMWindow::xmlHttpRequest(ExecState* exec) const
@@ -261,7 +461,7 @@ JSValue JSDOMWindow::xmlHttpRequest(ExecState* exec) const
#if ENABLE(XSLT)
JSValue JSDOMWindow::xsltProcessor(ExecState* exec) const
{
- return getDOMConstructor<JSXSLTProcessorConstructor>(exec);
+ return getDOMConstructor<JSXSLTProcessorConstructor>(exec, this);
}
#endif
@@ -275,7 +475,14 @@ JSValue JSDOMWindow::messageChannel(ExecState* exec) const
#if ENABLE(WORKERS)
JSValue JSDOMWindow::worker(ExecState* exec) const
{
- return getDOMConstructor<JSWorkerConstructor>(exec);
+ return getDOMConstructor<JSWorkerConstructor>(exec, this);
+}
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+JSValue JSDOMWindow::sharedWorker(ExecState* exec) const
+{
+ return getDOMConstructor<JSSharedWorkerConstructor>(exec, this);
}
#endif
diff --git a/WebCore/bindings/js/JSDOMWindowCustom.h b/WebCore/bindings/js/JSDOMWindowCustom.h
index 52ef4a0..a0e1b8f 100644
--- a/WebCore/bindings/js/JSDOMWindowCustom.h
+++ b/WebCore/bindings/js/JSDOMWindowCustom.h
@@ -21,7 +21,6 @@
#include "JSDOMWindow.h"
#include "JSDOMWindowShell.h"
-#include <runtime/PrototypeFunction.h>
#include <wtf/AlwaysInline.h>
namespace WebCore {
@@ -36,121 +35,6 @@ inline const JSDOMWindow* asJSDOMWindow(const JSC::JSGlobalObject* globalObject)
return static_cast<const JSDOMWindow*>(globalObject);
}
-template<JSC::NativeFunction nativeFunction, int length>
-JSC::JSValue nonCachingStaticFunctionGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, const JSC::PropertySlot&)
-{
- return new (exec) JSC::PrototypeFunction(exec, length, propertyName, nativeFunction);
-}
-
-ALWAYS_INLINE bool JSDOMWindow::customGetOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot)
-{
- // When accessing a Window cross-domain, functions are always the native built-in ones, and they
- // are not affected by properties changed on the Window or anything in its prototype chain.
- // This is consistent with the behavior of Firefox.
-
- const JSC::HashEntry* entry;
-
- // We don't want any properties other than "close" and "closed" on a closed window.
- if (!impl()->frame()) {
- // The following code is safe for cross-domain and same domain use.
- // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype).
- entry = s_info.propHashTable(exec)->entry(exec, propertyName);
- if (entry && !(entry->attributes() & JSC::Function) && entry->propertyGetter() == jsDOMWindowClosed) {
- slot.setCustom(this, entry->propertyGetter());
- return true;
- }
- entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
- if (entry && (entry->attributes() & JSC::Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) {
- slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
- return true;
- }
-
- // FIXME: We should have a message here that explains why the property access/function call was
- // not allowed.
- slot.setUndefined();
- return true;
- }
-
- // We need to check for cross-domain access here without printing the generic warning message
- // because we always allow access to some function, just different ones depending whether access
- // is allowed.
- bool allowsAccess = allowsAccessFromNoErrorMessage(exec);
-
- // 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.
- // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of
- // what prototype is actually set on this object.
- entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
- if (entry) {
- if (entry->attributes() & JSC::Function) {
- if (entry->function() == jsDOMWindowPrototypeFunctionBlur) {
- if (!allowsAccess) {
- slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>);
- return true;
- }
- } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) {
- if (!allowsAccess) {
- slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
- return true;
- }
- } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) {
- if (!allowsAccess) {
- slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>);
- return true;
- }
- } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) {
- if (!allowsAccess) {
- slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>);
- return true;
- }
- } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) {
- if (!DOMWindow::canShowModalDialog(impl()->frame())) {
- slot.setUndefined();
- return true;
- }
- }
- }
- } else {
- // Allow access to toString() cross-domain, but always Object.prototype.toString.
- if (propertyName == exec->propertyNames().toString) {
- if (!allowsAccess) {
- slot.setCustom(this, objectToStringFunctionGetter);
- return true;
- }
- }
- }
-
- return false;
-}
-
-inline bool JSDOMWindow::customPut(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot)
-{
- if (!impl()->frame())
- return true;
-
- // Optimization: access JavaScript global variables directly before involving the DOM.
- JSC::PropertySlot getSlot;
- bool slotIsWriteable;
- if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, getSlot, slotIsWriteable)) {
- if (allowsAccessFrom(exec)) {
- if (slotIsWriteable) {
- getSlot.putValue(value);
- if (getSlot.isCacheable())
- slot.setExistingProperty(this, getSlot.cachedOffset());
- } else
- JSGlobalObject::put(exec, propertyName, value, slot);
- }
- return true;
- }
-
- return false;
-}
-
inline bool JSDOMWindowBase::allowsAccessFrom(const JSGlobalObject* other) const
{
if (allowsAccessFromPrivate(other))
diff --git a/WebCore/bindings/js/JSDOMWindowShell.cpp b/WebCore/bindings/js/JSDOMWindowShell.cpp
index 1bf478b..efffd42 100644
--- a/WebCore/bindings/js/JSDOMWindowShell.cpp
+++ b/WebCore/bindings/js/JSDOMWindowShell.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
@@ -71,11 +71,11 @@ void JSDOMWindowShell::setWindow(PassRefPtr<DOMWindow> domWindow)
// JSObject methods
// ----
-void JSDOMWindowShell::mark()
+void JSDOMWindowShell::markChildren(MarkStack& markStack)
{
- Base::mark();
- if (m_window && !m_window->marked())
- m_window->mark();
+ Base::markChildren(markStack);
+ if (m_window)
+ markStack.append(m_window);
}
UString JSDOMWindowShell::className() const
diff --git a/WebCore/bindings/js/JSDOMWindowShell.h b/WebCore/bindings/js/JSDOMWindowShell.h
index 6f21892..0506283 100644
--- a/WebCore/bindings/js/JSDOMWindowShell.h
+++ b/WebCore/bindings/js/JSDOMWindowShell.h
@@ -64,7 +64,7 @@ namespace WebCore {
}
private:
- virtual void mark();
+ virtual void markChildren(JSC::MarkStack&);
virtual JSC::UString className() const;
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
diff --git a/WebCore/bindings/js/JSDataGridColumnListCustom.cpp b/WebCore/bindings/js/JSDataGridColumnListCustom.cpp
new file mode 100644
index 0000000..91b3d15
--- /dev/null
+++ b/WebCore/bindings/js/JSDataGridColumnListCustom.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(DATAGRID)
+
+#include "JSDataGridColumnList.h"
+
+#include "AtomicString.h"
+#include "DataGridColumn.h"
+#include "DataGridColumnList.h"
+#include "JSDataGridColumn.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+bool JSDataGridColumnList::canGetItemsForName(ExecState*, DataGridColumnList* impl, const Identifier& propertyName)
+{
+ return impl->itemWithName(propertyName);
+}
+
+JSValue JSDataGridColumnList::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+{
+ JSDataGridColumnList* thisObj = static_cast<JSDataGridColumnList*>(asObject(slot.slotBase()));
+ return toJS(exec, thisObj->globalObject(), thisObj->impl()->itemWithName(propertyName));
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/js/JSDOMStringListCustom.cpp b/WebCore/bindings/js/JSDataGridDataSource.cpp
index ac088af..02b4214 100644
--- a/WebCore/bindings/js/JSDOMStringListCustom.cpp
+++ b/WebCore/bindings/js/JSDataGridDataSource.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 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
@@ -24,26 +24,32 @@
*/
#include "config.h"
-#include "JSDOMStringList.h"
-#include "DOMStringList.h"
+#if ENABLE(DATAGRID)
+
+#include "JSDataGridDataSource.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "HTMLDataGridElement.h"
+#include "JSHTMLDataGridElement.h"
+#include "JSDOMWindowBase.h"
+#include <runtime/JSLock.h>
using namespace JSC;
namespace WebCore {
-JSValue JSDOMStringList::getByIndex(ExecState* exec, unsigned index)
+JSDataGridDataSource::JSDataGridDataSource(JSC::JSValue dataSource, Frame* frame)
+ : m_dataSource(dataSource)
+ , m_frame(frame)
{
- return jsString(exec, impl()->item(index));
}
-JSValue JSDOMStringList::item(ExecState* exec, const ArgList& args)
+JSDataGridDataSource::~JSDataGridDataSource()
{
- unsigned index = args.at(0).toUInt32(exec);
- if (index >= impl()->length())
- return jsNull();
-
- return jsString(exec, impl()->item(index));
}
} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/WebCore/bindings/js/JSDataGridDataSource.h b/WebCore/bindings/js/JSDataGridDataSource.h
new file mode 100644
index 0000000..077ef8f
--- /dev/null
+++ b/WebCore/bindings/js/JSDataGridDataSource.h
@@ -0,0 +1,76 @@
+/*
+ * 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 JSDataGridDataSource_h
+#define JSDataGridDataSource_h
+
+#if ENABLE(DATAGRID)
+
+#include "DataGridDataSource.h"
+#include <runtime/JSValue.h>
+#include <runtime/Protect.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+class HTMLDataGridElement;
+
+class JSDataGridDataSource : public DataGridDataSource {
+public:
+ static PassRefPtr<JSDataGridDataSource> create(JSC::JSValue dataSource, Frame* frame)
+ {
+ return adoptRef(new JSDataGridDataSource(dataSource, frame));
+ }
+
+ virtual ~JSDataGridDataSource();
+
+ virtual bool isJSDataGridDataSource() const { return true; }
+ JSC::JSValue jsDataSource() const { return m_dataSource.get(); }
+
+private:
+ JSDataGridDataSource(JSC::JSValue, Frame*);
+
+ JSC::ProtectedJSValue m_dataSource;
+ RefPtr<Frame> m_frame;
+};
+
+inline JSDataGridDataSource* asJSDataGridDataSource(DataGridDataSource* dataSource)
+{
+ ASSERT(dataSource->isJSDataGridDataSource());
+ return static_cast<JSDataGridDataSource*>(dataSource);
+}
+
+inline const JSDataGridDataSource* asJSDataGridDataSource(const DataGridDataSource* dataSource)
+{
+ ASSERT(dataSource->isJSDataGridDataSource());
+ return static_cast<const JSDataGridDataSource*>(dataSource);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
+#endif // JSDataGridDataSource_h
diff --git a/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp b/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp
new file mode 100644
index 0000000..657f9b3
--- /dev/null
+++ b/WebCore/bindings/js/JSDedicatedWorkerContextCustom.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR 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 "JSDedicatedWorkerContext.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSDedicatedWorkerContext::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+
+ markIfNotNull(markStack, impl()->onmessage());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSDocumentCustom.cpp b/WebCore/bindings/js/JSDocumentCustom.cpp
index 956327a..39a1fc5 100644
--- a/WebCore/bindings/js/JSDocumentCustom.cpp
+++ b/WebCore/bindings/js/JSDocumentCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -39,11 +39,11 @@ using namespace JSC;
namespace WebCore {
-void JSDocument::mark()
+void JSDocument::markChildren(MarkStack& markStack)
{
- JSNode::mark();
- markDOMNodesForDocument(impl());
- markActiveObjectsForContext(*Heap::heap(this)->globalData(), impl());
+ JSNode::markChildren(markStack);
+ markDOMNodesForDocument(markStack, impl());
+ markActiveObjectsForContext(markStack, *Heap::heap(this)->globalData(), impl());
}
JSValue JSDocument::location(ExecState* exec) const
@@ -56,8 +56,7 @@ JSValue JSDocument::location(ExecState* exec) const
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), location))
return wrapper;
- JSDOMWindow* window = static_cast<JSDOMWindow*>(exec->lexicalGlobalObject());
- JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, window), location);
+ JSLocation* jsLocation = new (exec) JSLocation(getDOMStructure<JSLocation>(exec, globalObject()), globalObject(), location);
cacheDOMObjectWrapper(exec->globalData(), location, jsLocation);
return jsLocation;
}
@@ -80,7 +79,7 @@ void JSDocument::setLocation(ExecState* exec, JSValue value)
frame->loader()->scheduleLocationChange(str, activeFrame->loader()->outgoingReferrer(), !activeFrame->script()->anyPageIsProcessingUserGesture(), false, userGesture);
}
-JSValue toJS(ExecState* exec, Document* document)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Document* document)
{
if (!document)
return jsNull();
@@ -90,13 +89,13 @@ JSValue toJS(ExecState* exec, Document* document)
return wrapper;
if (document->isHTMLDocument())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLDocument, document);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLDocument, document);
#if ENABLE(SVG)
else if (document->isSVGDocument())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, SVGDocument, document);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGDocument, document);
#endif
else
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, Document, document);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Document, document);
// Make sure the document is kept around by the window object, and works right with the
// back/forward cache.
diff --git a/WebCore/bindings/js/JSElementCustom.cpp b/WebCore/bindings/js/JSElementCustom.cpp
index b12c185..47793d0 100644
--- a/WebCore/bindings/js/JSElementCustom.cpp
+++ b/WebCore/bindings/js/JSElementCustom.cpp
@@ -53,7 +53,7 @@ using namespace HTMLNames;
static inline bool allowSettingSrcToJavascriptURL(ExecState* exec, Element* element, const String& name, const String& value)
{
- if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(parseURL(value))) {
+ if ((element->hasTagName(iframeTag) || element->hasTagName(frameTag)) && equalIgnoringCase(name, "src") && protocolIsJavaScript(deprecatedParseURL(value))) {
HTMLFrameElementBase* frame = static_cast<HTMLFrameElementBase*>(element);
if (!checkNodeSecurity(exec, frame->contentDocument()))
return false;
@@ -89,7 +89,7 @@ JSValue JSElement::setAttributeNode(ExecState* exec, const ArgList& args)
if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value()))
return jsUndefined();
- JSValue result = toJS(exec, WTF::getPtr(imp->setAttributeNode(newAttr, ec)));
+ JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setAttributeNode(newAttr, ec)));
setDOMException(exec, ec);
return result;
}
@@ -123,12 +123,12 @@ JSValue JSElement::setAttributeNodeNS(ExecState* exec, const ArgList& args)
if (!allowSettingSrcToJavascriptURL(exec, imp, newAttr->name(), newAttr->value()))
return jsUndefined();
- JSValue result = toJS(exec, WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec)));
+ JSValue result = toJS(exec, globalObject(), WTF::getPtr(imp->setAttributeNodeNS(newAttr, ec)));
setDOMException(exec, ec);
return result;
}
-JSValue toJSNewlyCreated(ExecState* exec, Element* element)
+JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Element* element)
{
if (!element)
return jsNull();
@@ -137,15 +137,15 @@ JSValue toJSNewlyCreated(ExecState* exec, Element* element)
JSNode* wrapper;
if (element->isHTMLElement())
- wrapper = createJSHTMLWrapper(exec, static_cast<HTMLElement*>(element));
+ wrapper = createJSHTMLWrapper(exec, globalObject, static_cast<HTMLElement*>(element));
#if ENABLE(SVG)
else if (element->isSVGElement())
- wrapper = createJSSVGWrapper(exec, static_cast<SVGElement*>(element));
+ wrapper = createJSSVGWrapper(exec, globalObject, static_cast<SVGElement*>(element));
#endif
else
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Element, element);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Element, element);
return wrapper;
}
-
+
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp
index a020d74..7f9030e 100644
--- a/WebCore/bindings/js/JSEventCustom.cpp
+++ b/WebCore/bindings/js/JSEventCustom.cpp
@@ -32,6 +32,7 @@
#include "Clipboard.h"
#include "Event.h"
#include "JSClipboard.h"
+#include "JSErrorEvent.h"
#include "JSKeyboardEvent.h"
#include "JSMessageEvent.h"
#include "JSMouseEvent.h"
@@ -44,6 +45,7 @@
#include "JSWebKitTransitionEvent.h"
#include "JSWheelEvent.h"
#include "JSXMLHttpRequestProgressEvent.h"
+#include "ErrorEvent.h"
#include "KeyboardEvent.h"
#include "MessageEvent.h"
#include "MouseEvent.h"
@@ -79,12 +81,12 @@ namespace WebCore {
JSValue JSEvent::clipboardData(ExecState* exec) const
{
- return impl()->isClipboardEvent() ? toJS(exec, impl()->clipboardData()) : jsUndefined();
+ return impl()->isClipboardEvent() ? toJS(exec, globalObject(), impl()->clipboardData()) : jsUndefined();
}
-JSValue toJS(ExecState* exec, Event* event)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
if (!event)
return jsNull();
@@ -95,45 +97,49 @@ JSValue toJS(ExecState* exec, Event* event)
if (event->isUIEvent()) {
if (event->isKeyboardEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, KeyboardEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, KeyboardEvent, event);
else if (event->isTextEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, TextEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, TextEvent, event);
else if (event->isMouseEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, MouseEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, MouseEvent, event);
else if (event->isWheelEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WheelEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WheelEvent, event);
#if ENABLE(SVG)
else if (event->isSVGZoomEvent())
- wrapper = CREATE_SVG_OBJECT_WRAPPER(exec, SVGZoomEvent, event, 0);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, SVGZoomEvent, event);
#endif
#if ENABLE(TOUCH_EVENTS) // Android
else if (event->isTouchEvent())
wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, TouchEvent, event);
#endif
else
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, UIEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, UIEvent, event);
} else if (event->isMutationEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, MutationEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, MutationEvent, event);
else if (event->isOverflowEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, OverflowEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, OverflowEvent, event);
else if (event->isMessageEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, MessageEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, MessageEvent, event);
else if (event->isProgressEvent()) {
if (event->isXMLHttpRequestProgressEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequestProgressEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, XMLHttpRequestProgressEvent, event);
else
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, ProgressEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ProgressEvent, event);
}
#if ENABLE(DOM_STORAGE)
else if (event->isStorageEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, StorageEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, StorageEvent, event);
#endif
else if (event->isWebKitAnimationEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitAnimationEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitAnimationEvent, event);
else if (event->isWebKitTransitionEvent())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, WebKitTransitionEvent, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, WebKitTransitionEvent, event);
+#if ENABLE(WORKERS)
+ else if (event->isErrorEvent())
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ErrorEvent, event);
+#endif
else
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, Event, event);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Event, event);
return wrapper;
}
diff --git a/WebCore/bindings/js/JSEventListener.cpp b/WebCore/bindings/js/JSEventListener.cpp
index b9ed685..42e0281 100644
--- a/WebCore/bindings/js/JSEventListener.cpp
+++ b/WebCore/bindings/js/JSEventListener.cpp
@@ -51,17 +51,17 @@ JSObject* JSEventListener::jsFunction() const
return m_jsFunction;
}
-void JSEventListener::markJSFunction()
+void JSEventListener::markJSFunction(MarkStack& markStack)
{
- if (m_jsFunction && !m_jsFunction->marked())
- m_jsFunction->mark();
- if (m_globalObject && !m_globalObject->marked())
- m_globalObject->mark();
+ if (m_jsFunction)
+ markStack.append(m_jsFunction);
+ if (m_globalObject)
+ markStack.append(m_globalObject);
}
void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSObject* jsFunction = this->jsFunction();
if (!jsFunction)
@@ -71,6 +71,7 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
// Null check as clearGlobalObject() can clear this and we still get called back by
// xmlhttprequest objects. See http://bugs.webkit.org/show_bug.cgi?id=13275
// FIXME: Is this check still necessary? Requests are supposed to be stopped before clearGlobalObject() is called.
+ ASSERT(globalObject);
if (!globalObject)
return;
@@ -107,7 +108,7 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
ref();
MarkedArgumentBuffer args;
- args.append(toJS(exec, event));
+ args.append(toJS(exec, globalObject, event));
Event* savedEvent = globalObject->currentEvent();
globalObject->setCurrentEvent(event);
@@ -127,7 +128,7 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
if (isWindowEvent)
thisValue = globalObject->toThisObject(exec);
else
- thisValue = toJS(exec, event->currentTarget());
+ thisValue = toJS(exec, globalObject, event->currentTarget());
globalObject->globalData()->timeoutChecker.start();
retval = call(exec, jsFunction, callType, callData, thisValue, args);
}
@@ -153,6 +154,53 @@ void JSEventListener::handleEvent(Event* event, bool isWindowEvent)
}
}
+bool JSEventListener::reportError(const String& message, const String& url, int lineNumber)
+{
+ JSLock lock(SilenceAssertionsOnly);
+
+ JSObject* jsFunction = this->jsFunction();
+ if (!jsFunction)
+ return false;
+
+ JSDOMGlobalObject* globalObject = m_globalObject;
+ if (!globalObject)
+ return false;
+
+ ExecState* exec = globalObject->globalExec();
+
+ CallData callData;
+ CallType callType = jsFunction->getCallData(callData);
+
+ if (callType == CallTypeNone)
+ return false;
+
+ MarkedArgumentBuffer args;
+ args.append(jsString(exec, message));
+ args.append(jsString(exec, url));
+ args.append(jsNumber(exec, lineNumber));
+
+ // If this event handler is the first JavaScript to execute, then the
+ // dynamic global object should be set to the global object of the
+ // window in which the event occurred.
+ JSGlobalData* globalData = globalObject->globalData();
+ DynamicGlobalObjectScope globalObjectScope(exec, globalData->dynamicGlobalObject ? globalData->dynamicGlobalObject : globalObject);
+
+ JSValue thisValue = globalObject->toThisObject(exec);
+
+ globalObject->globalData()->timeoutChecker.start();
+ JSValue returnValue = call(exec, jsFunction, callType, callData, thisValue, args);
+ globalObject->globalData()->timeoutChecker.stop();
+
+ // If an error occurs while handling the script error, it should be bubbled up.
+ if (exec->hadException()) {
+ exec->clearException();
+ return false;
+ }
+
+ bool bubbleEvent;
+ return returnValue.getBoolean(bubbleEvent) && !bubbleEvent;
+}
+
bool JSEventListener::virtualisAttribute() const
{
return m_isAttribute;
diff --git a/WebCore/bindings/js/JSEventListener.h b/WebCore/bindings/js/JSEventListener.h
index ce34832..7929169 100644
--- a/WebCore/bindings/js/JSEventListener.h
+++ b/WebCore/bindings/js/JSEventListener.h
@@ -43,8 +43,9 @@ namespace WebCore {
virtual JSC::JSObject* jsFunction() const;
private:
- virtual void markJSFunction();
+ virtual void markJSFunction(JSC::MarkStack&);
virtual void handleEvent(Event*, bool isWindowEvent);
+ virtual bool reportError(const String& message, const String& url, int lineNumber);
virtual bool virtualisAttribute() const;
void clearJSFunctionInline();
diff --git a/WebCore/bindings/js/JSEventTarget.cpp b/WebCore/bindings/js/JSEventTarget.cpp
index 2058098..c34e10e 100644
--- a/WebCore/bindings/js/JSEventTarget.cpp
+++ b/WebCore/bindings/js/JSEventTarget.cpp
@@ -33,9 +33,13 @@
#include "JSEventListener.h"
#include "JSMessagePort.h"
#include "JSNode.h"
+#include "JSSharedWorker.h"
+#include "JSSharedWorkerContext.h"
#include "JSXMLHttpRequest.h"
#include "JSXMLHttpRequestUpload.h"
#include "MessagePort.h"
+#include "SharedWorker.h"
+#include "SharedWorkerContext.h"
#include "XMLHttpRequest.h"
#include "XMLHttpRequestUpload.h"
@@ -50,17 +54,17 @@
#endif
#if ENABLE(WORKERS)
+#include "DedicatedWorkerContext.h"
+#include "JSDedicatedWorkerContext.h"
#include "JSWorker.h"
-#include "JSWorkerContext.h"
#include "Worker.h"
-#include "WorkerContext.h"
#endif
using namespace JSC;
namespace WebCore {
-JSValue toJS(ExecState* exec, EventTarget* target)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, EventTarget* target)
{
if (!target)
return jsNull();
@@ -68,36 +72,42 @@ JSValue toJS(ExecState* exec, EventTarget* target)
#if ENABLE(SVG)
// SVGElementInstance supports both toSVGElementInstance and toNode since so much mouse handling code depends on toNode returning a valid node.
if (SVGElementInstance* instance = target->toSVGElementInstance())
- return toJS(exec, instance);
+ return toJS(exec, globalObject, instance);
#endif
if (Node* node = target->toNode())
- return toJS(exec, node);
+ return toJS(exec, globalObject, node);
if (DOMWindow* domWindow = target->toDOMWindow())
- return toJS(exec, domWindow);
+ return toJS(exec, globalObject, domWindow);
if (XMLHttpRequest* xhr = target->toXMLHttpRequest())
- // XMLHttpRequest is always created via JS, so we don't need to use cacheDOMObject() here.
- return getCachedDOMObjectWrapper(exec->globalData(), xhr);
+ return toJS(exec, globalObject, xhr);
if (XMLHttpRequestUpload* upload = target->toXMLHttpRequestUpload())
- return toJS(exec, upload);
+ return toJS(exec, globalObject, upload);
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
if (DOMApplicationCache* cache = target->toDOMApplicationCache())
- // DOMApplicationCache is always created via JS, so we don't need to use cacheDOMObject() here.
- return getCachedDOMObjectWrapper(exec->globalData(), cache);
+ return toJS(exec, globalObject, cache);
#endif
if (MessagePort* messagePort = target->toMessagePort())
- return toJS(exec, messagePort);
+ return toJS(exec, globalObject, messagePort);
#if ENABLE(WORKERS)
if (Worker* worker = target->toWorker())
- return toJS(exec, worker);
+ return toJS(exec, globalObject, worker);
- if (WorkerContext* workerContext = target->toWorkerContext())
+ if (DedicatedWorkerContext* workerContext = target->toDedicatedWorkerContext())
+ return toJSDOMGlobalObject(workerContext);
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+ if (SharedWorker* sharedWorker = target->toSharedWorker())
+ return toJS(exec, globalObject, sharedWorker);
+
+ if (SharedWorkerContext* workerContext = target->toSharedWorkerContext())
return toJSDOMGlobalObject(workerContext);
#endif
@@ -129,7 +139,12 @@ EventTarget* toEventTarget(JSC::JSValue value)
#if ENABLE(WORKERS)
CONVERT_TO_EVENT_TARGET(Worker)
- CONVERT_TO_EVENT_TARGET(WorkerContext)
+ CONVERT_TO_EVENT_TARGET(DedicatedWorkerContext)
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+ CONVERT_TO_EVENT_TARGET(SharedWorker)
+ CONVERT_TO_EVENT_TARGET(SharedWorkerContext)
#endif
return 0;
diff --git a/WebCore/bindings/js/JSEventTarget.h b/WebCore/bindings/js/JSEventTarget.h
index 05df056..ddd8232 100644
--- a/WebCore/bindings/js/JSEventTarget.h
+++ b/WebCore/bindings/js/JSEventTarget.h
@@ -35,8 +35,9 @@ namespace JSC {
namespace WebCore {
class EventTarget;
+ class JSDOMGlobalObject;
- JSC::JSValue toJS(JSC::ExecState*, EventTarget*);
+ JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, EventTarget*);
EventTarget* toEventTarget(JSC::JSValue);
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSHTMLAllCollection.h b/WebCore/bindings/js/JSHTMLAllCollection.h
index d559d3b..7363e5c 100644
--- a/WebCore/bindings/js/JSHTMLAllCollection.h
+++ b/WebCore/bindings/js/JSHTMLAllCollection.h
@@ -35,8 +35,8 @@ namespace WebCore {
class JSHTMLAllCollection : public JSHTMLCollection {
public:
- JSHTMLAllCollection(PassRefPtr<JSC::Structure> structure, PassRefPtr<HTMLCollection> collection)
- : JSHTMLCollection(structure, collection)
+ JSHTMLAllCollection(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<HTMLCollection> collection)
+ : JSHTMLCollection(structure, globalObject, collection)
{
}
diff --git a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
index de6565d..37561af 100644
--- a/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLAppletElementCustom.cpp
@@ -33,12 +33,12 @@ namespace WebCore {
using namespace JSC;
-bool JSHTMLAppletElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSHTMLAppletElement::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this);
}
-bool JSHTMLAppletElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+bool JSHTMLAppletElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot);
}
diff --git a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
index 4100468..dd9af74 100644
--- a/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLCollectionCustom.cpp
@@ -35,18 +35,18 @@ using namespace JSC;
namespace WebCore {
-static JSValue getNamedItems(ExecState* exec, HTMLCollection* impl, const Identifier& propertyName)
+static JSValue getNamedItems(ExecState* exec, JSHTMLCollection* collection, const Identifier& propertyName)
{
Vector<RefPtr<Node> > namedItems;
- impl->namedItems(propertyName, namedItems);
+ collection->impl()->namedItems(propertyName, namedItems);
if (namedItems.isEmpty())
return jsUndefined();
if (namedItems.size() == 1)
- return toJS(exec, namedItems[0].get());
+ return toJS(exec, collection->globalObject(), namedItems[0].get());
- return new (exec) JSNamedNodesCollection(exec, namedItems);
+ return new (exec) JSNamedNodesCollection(exec, collection->globalObject(), namedItems);
}
// HTMLCollections are strange objects, they support both get and call,
@@ -57,7 +57,8 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct
return jsUndefined();
// Do not use thisObj here. It can be the JSHTMLDocument, in the document.forms(i) case.
- HTMLCollection* collection = static_cast<JSHTMLCollection*>(function)->impl();
+ JSHTMLCollection* jsCollection = static_cast<JSHTMLCollection*>(function);
+ HTMLCollection* collection = jsCollection->impl();
// Also, do we need the TypeError test here ?
@@ -67,10 +68,10 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct
UString string = args.at(0).toString(exec);
unsigned index = string.toUInt32(&ok, false);
if (ok)
- return toJS(exec, collection->item(index));
+ return toJS(exec, jsCollection->globalObject(), collection->item(index));
// Support for document.images('<name>') etc.
- return getNamedItems(exec, collection, Identifier(exec, string));
+ return getNamedItems(exec, jsCollection, Identifier(exec, string));
}
// The second arg, if set, is the index of the item we want
@@ -82,7 +83,7 @@ static JSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec, JSObject* funct
Node* node = collection->namedItem(pstr);
while (node) {
if (!index)
- return toJS(exec, node);
+ return toJS(exec, jsCollection->globalObject(), node);
node = collection->nextNamedItem(pstr);
--index;
}
@@ -97,15 +98,17 @@ CallType JSHTMLCollection::getCallData(CallData& callData)
return CallTypeHost;
}
-bool JSHTMLCollection::canGetItemsForName(ExecState* exec, HTMLCollection* thisObj, const Identifier& propertyName)
+bool JSHTMLCollection::canGetItemsForName(ExecState*, HTMLCollection* collection, const Identifier& propertyName)
{
- return !getNamedItems(exec, thisObj, propertyName).isUndefined();
+ Vector<RefPtr<Node> > namedItems;
+ collection->namedItems(propertyName, namedItems);
+ return !namedItems.isEmpty();
}
JSValue JSHTMLCollection::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slot.slotBase()));
- return getNamedItems(exec, thisObj->impl(), propertyName);
+ return getNamedItems(exec, thisObj, propertyName);
}
JSValue JSHTMLCollection::item(ExecState* exec, const ArgList& args)
@@ -113,16 +116,16 @@ JSValue JSHTMLCollection::item(ExecState* exec, const ArgList& args)
bool ok;
uint32_t index = args.at(0).toString(exec).toUInt32(&ok, false);
if (ok)
- return toJS(exec, impl()->item(index));
- return getNamedItems(exec, impl(), Identifier(exec, args.at(0).toString(exec)));
+ return toJS(exec, globalObject(), impl()->item(index));
+ return getNamedItems(exec, this, Identifier(exec, args.at(0).toString(exec)));
}
JSValue JSHTMLCollection::namedItem(ExecState* exec, const ArgList& args)
{
- return getNamedItems(exec, impl(), Identifier(exec, args.at(0).toString(exec)));
+ return getNamedItems(exec, this, Identifier(exec, args.at(0).toString(exec)));
}
-JSValue toJS(ExecState* exec, HTMLCollection* collection)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, HTMLCollection* collection)
{
if (!collection)
return jsNull();
@@ -134,14 +137,14 @@ JSValue toJS(ExecState* exec, HTMLCollection* collection)
switch (collection->type()) {
case SelectOptions:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLOptionsCollection, collection);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLOptionsCollection, collection);
break;
case DocAll:
typedef HTMLCollection HTMLAllCollection;
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLAllCollection, collection);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLAllCollection, collection);
break;
default:
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, HTMLCollection, collection);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLCollection, collection);
break;
}
diff --git a/WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp b/WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp
new file mode 100644
index 0000000..a30f5e4
--- /dev/null
+++ b/WebCore/bindings/js/JSHTMLDataGridElementCustom.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(DATAGRID)
+
+#include "JSHTMLDataGridElement.h"
+
+#include "Document.h"
+#include "HTMLDataGridElement.h"
+#include "JSDataGridDataSource.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+JSValue JSHTMLDataGridElement::dataSource(ExecState*) const
+{
+ DataGridDataSource* dataSource = static_cast<HTMLDataGridElement*>(impl())->dataSource();
+ if (dataSource && dataSource->isJSDataGridDataSource())
+ return asJSDataGridDataSource(dataSource)->jsDataSource();
+ return jsNull();
+}
+
+void JSHTMLDataGridElement::setDataSource(ExecState*, JSValue value)
+{
+ if (value.isNull()) {
+ static_cast<HTMLDataGridElement*>(impl())->setDataSource(0);
+ return;
+ }
+
+ static_cast<HTMLDataGridElement*>(impl())->setDataSource(JSDataGridDataSource::create(value, impl()->document()->frame()));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/WebCore/bindings/js/JSHTMLElementCustom.cpp b/WebCore/bindings/js/JSHTMLElementCustom.cpp
index 3345764..4194657 100644
--- a/WebCore/bindings/js/JSHTMLElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLElementCustom.cpp
@@ -38,14 +38,14 @@ void JSHTMLElement::pushEventHandlerScope(ExecState* exec, ScopeChain& scope) co
HTMLElement* element = impl();
// The document is put on first, fall back to searching it only after the element and form.
- scope.push(asObject(toJS(exec, element->ownerDocument())));
+ scope.push(asObject(toJS(exec, globalObject(), element->ownerDocument())));
// The form is next, searched before the document, but after the element itself.
if (HTMLFormElement* form = element->form())
- scope.push(asObject(toJS(exec, form)));
+ scope.push(asObject(toJS(exec, globalObject(), form)));
// The element is on top, searched first.
- scope.push(asObject(toJS(exec, element)));
+ scope.push(asObject(toJS(exec, globalObject(), element)));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
index 19aae86..2570bc6 100644
--- a/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLEmbedElementCustom.cpp
@@ -33,12 +33,12 @@ namespace WebCore {
using namespace JSC;
-bool JSHTMLEmbedElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSHTMLEmbedElement::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this);
}
-bool JSHTMLEmbedElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+bool JSHTMLEmbedElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot);
}
diff --git a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
index 8bf543c..ffa2d57 100644
--- a/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLFormElementCustom.cpp
@@ -45,7 +45,8 @@ bool JSHTMLFormElement::canGetItemsForName(ExecState*, HTMLFormElement* form, co
JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
- HTMLFormElement* form = static_cast<HTMLFormElement*>(static_cast<JSHTMLElement*>(asObject(slot.slotBase()))->impl());
+ JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slot.slotBase()));
+ HTMLFormElement* form = static_cast<HTMLFormElement*>(jsForm->impl());
Vector<RefPtr<Node> > namedItems;
form->getNamedElements(propertyName, namedItems);
@@ -53,7 +54,7 @@ JSValue JSHTMLFormElement::nameGetter(ExecState* exec, const Identifier& propert
if (namedItems.size() == 1)
return toJS(exec, namedItems[0].get());
if (namedItems.size() > 1)
- return new (exec) JSNamedNodesCollection(exec, namedItems);
+ return new (exec) JSNamedNodesCollection(exec, jsForm->globalObject(), namedItems);
return jsUndefined();
}
@@ -62,7 +63,7 @@ JSValue JSHTMLFormElement::submit(ExecState* exec, const ArgList&)
Frame* activeFrame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
if (!activeFrame)
return jsUndefined();
- static_cast<HTMLFormElement*>(impl())->submit(0, false, !activeFrame->script()->anyPageIsProcessingUserGesture(), false);
+ static_cast<HTMLFormElement*>(impl())->submit(0, false, !activeFrame->script()->anyPageIsProcessingUserGesture());
return jsUndefined();
}
diff --git a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp
index 0a5d1f1..c8aea9f 100644
--- a/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLFrameElementCustom.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
static inline bool allowSettingJavascriptURL(ExecState* exec, HTMLFrameElement* imp, const String& value)
{
- if (protocolIsJavaScript(parseURL(value))) {
+ if (protocolIsJavaScript(deprecatedParseURL(value))) {
if (!checkNodeSecurity(exec, imp->contentDocument()))
return false;
}
diff --git a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp
index afff977..8e32381 100644
--- a/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLIFrameElementCustom.cpp
@@ -44,7 +44,7 @@ void JSHTMLIFrameElement::setSrc(ExecState* exec, JSValue value)
String srcValue = valueToStringWithNullCheck(exec, value);
- if (protocolIsJavaScript(parseURL(srcValue))) {
+ if (protocolIsJavaScript(deprecatedParseURL(srcValue))) {
if (!checkNodeSecurity(exec, imp->contentDocument()))
return;
}
diff --git a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
index f7f12b9..a99e46c 100644
--- a/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLObjectElementCustom.cpp
@@ -33,12 +33,12 @@ namespace WebCore {
using namespace JSC;
-bool JSHTMLObjectElement::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSHTMLObjectElement::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
return runtimeObjectCustomGetOwnPropertySlot(exec, propertyName, slot, this);
}
-bool JSHTMLObjectElement::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+bool JSHTMLObjectElement::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
return runtimeObjectCustomPut(exec, propertyName, value, impl(), slot);
}
diff --git a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp
index 460ba08..7bca2db 100644
--- a/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp
+++ b/WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp
@@ -91,7 +91,7 @@ JSValue JSHTMLOptionsCollection::add(ExecState* exec, const ArgList& args)
JSValue JSHTMLOptionsCollection::remove(ExecState* exec, const ArgList& args)
{
HTMLOptionsCollection* imp = static_cast<HTMLOptionsCollection*>(impl());
- JSHTMLSelectElement* base = static_cast<JSHTMLSelectElement*>(asObject(toJS(exec, imp->base())));
+ JSHTMLSelectElement* base = static_cast<JSHTMLSelectElement*>(asObject(toJS(exec, globalObject(), imp->base())));
return base->remove(exec, args);
}
diff --git a/WebCore/bindings/js/JSHistoryCustom.cpp b/WebCore/bindings/js/JSHistoryCustom.cpp
index 998a364..a3b15e1 100644
--- a/WebCore/bindings/js/JSHistoryCustom.cpp
+++ b/WebCore/bindings/js/JSHistoryCustom.cpp
@@ -39,23 +39,23 @@ namespace WebCore {
static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 0, propertyName, jsHistoryPrototypeFunctionBack);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionBack);
}
static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 0, propertyName, jsHistoryPrototypeFunctionForward);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsHistoryPrototypeFunctionForward);
}
static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 1, propertyName, jsHistoryPrototypeFunctionGo);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsHistoryPrototypeFunctionGo);
}
-bool JSHistory::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSHistory::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
// When accessing History cross-domain, functions are always the native built-in ones.
- // See JSDOMWindow::customGetOwnPropertySlot for additional details.
+ // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
// Our custom code is only needed to implement the Window cross-domain scheme, so if access is
// allowed, return false so the normal lookup will take place.
@@ -92,7 +92,7 @@ bool JSHistory::customGetOwnPropertySlot(ExecState* exec, const Identifier& prop
return true;
}
-bool JSHistory::customPut(ExecState* exec, const Identifier&, JSValue, PutPropertySlot&)
+bool JSHistory::putDelegate(ExecState* exec, const Identifier&, JSValue, PutPropertySlot&)
{
// Only allow putting by frames in the same origin.
if (!allowsAccessFromFrame(exec, impl()->frame()))
@@ -108,12 +108,12 @@ bool JSHistory::deleteProperty(ExecState* exec, const Identifier& propertyName)
return Base::deleteProperty(exec, propertyName);
}
-bool JSHistory::customGetPropertyNames(ExecState* exec, PropertyNameArray&)
+void JSHistory::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
// Only allow the history object to enumerated by frames in the same origin.
if (!allowsAccessFromFrame(exec, impl()->frame()))
- return true;
- return false;
+ return;
+ Base::getPropertyNames(exec, propertyNames);
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSImageConstructor.cpp b/WebCore/bindings/js/JSImageConstructor.cpp
index 4a27bb4..faaaf41 100644
--- a/WebCore/bindings/js/JSImageConstructor.cpp
+++ b/WebCore/bindings/js/JSImageConstructor.cpp
@@ -35,18 +35,9 @@ ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor);
const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", 0, 0, 0 };
JSImageConstructor::JSImageConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
- : DOMObject(JSImageConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
- , m_globalObject(globalObject)
+ : DOMConstructorWithDocument(JSImageConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- ASSERT(globalObject->scriptExecutionContext());
- ASSERT(globalObject->scriptExecutionContext()->isDocument());
-
- putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec, exec->lexicalGlobalObject()), None);
-}
-
-Document* JSImageConstructor::document() const
-{
- return static_cast<Document*>(m_globalObject->scriptExecutionContext());
+ putDirect(exec->propertyNames().prototype, JSHTMLImageElementPrototype::self(exec, globalObject), None);
}
static JSObject* constructImage(ExecState* exec, JSObject* constructor, const ArgList& args)
@@ -64,21 +55,22 @@ static JSObject* constructImage(ExecState* exec, JSObject* constructor, const Ar
height = args.at(1).toInt32(exec);
}
- Document* document = static_cast<JSImageConstructor*>(constructor)->document();
+ JSImageConstructor* jsConstructor = static_cast<JSImageConstructor*>(constructor);
+ Document* document = jsConstructor->document();
if (!document)
return throwError(exec, ReferenceError, "Image constructor associated document is unavailable");
// Calling toJS on the document causes the JS document wrapper to be
// added to the window object. This is done to ensure that JSDocument::mark
// will be called (which will cause the image element to be marked if necessary).
- toJS(exec, document);
+ toJS(exec, jsConstructor->globalObject(), document);
RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, document);
if (widthSet)
image->setWidth(width);
if (heightSet)
image->setHeight(height);
- return asObject(toJS(exec, image.release()));
+ return asObject(toJS(exec, jsConstructor->globalObject(), image.release()));
}
ConstructType JSImageConstructor::getConstructData(ConstructData& constructData)
@@ -87,11 +79,4 @@ ConstructType JSImageConstructor::getConstructData(ConstructData& constructData)
return ConstructTypeHost;
}
-void JSImageConstructor::mark()
-{
- DOMObject::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 8dc7add..0525f5e 100644
--- a/WebCore/bindings/js/JSImageConstructor.h
+++ b/WebCore/bindings/js/JSImageConstructor.h
@@ -25,19 +25,14 @@
namespace WebCore {
- class JSImageConstructor : public DOMObject {
+ class JSImageConstructor : public DOMConstructorWithDocument {
public:
JSImageConstructor(JSC::ExecState*, JSDOMGlobalObject*);
- Document* document() const;
static const JSC::ClassInfo s_info;
-
- virtual void mark();
private:
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
-
- JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSImageDataCustom.cpp b/WebCore/bindings/js/JSImageDataCustom.cpp
index 32fe58b..fa3b1d5 100644
--- a/WebCore/bindings/js/JSImageDataCustom.cpp
+++ b/WebCore/bindings/js/JSImageDataCustom.cpp
@@ -36,7 +36,7 @@ using namespace JSC;
namespace WebCore {
-JSValue toJS(ExecState* exec, ImageData* imageData)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, ImageData* imageData)
{
if (!imageData)
return jsNull();
@@ -45,7 +45,7 @@ JSValue toJS(ExecState* exec, ImageData* imageData)
if (wrapper)
return wrapper;
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, ImageData, imageData);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, ImageData, imageData);
Identifier dataName(exec, "data");
DEFINE_STATIC_LOCAL(RefPtr<Structure>, cpaStructure, (JSByteArray::createStructure(jsNull())));
static const ClassInfo cpaClassInfo = { "CanvasPixelArray", 0, 0, 0 };
diff --git a/WebCore/bindings/js/JSInspectorControllerCustom.cpp b/WebCore/bindings/js/JSInspectorBackendCustom.cpp
index b06c9e9..b2eb2d1 100644
--- a/WebCore/bindings/js/JSInspectorControllerCustom.cpp
+++ b/WebCore/bindings/js/JSInspectorBackendCustom.cpp
@@ -31,7 +31,7 @@
*/
#include "config.h"
-#include "JSInspectorController.h"
+#include "JSInspectorBackend.h"
#include "Console.h"
#if ENABLE(DATABASE)
@@ -41,6 +41,7 @@
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "InspectorBackend.h"
#include "InspectorController.h"
#include "InspectorResource.h"
#include "JSDOMWindow.h"
@@ -69,7 +70,7 @@ using namespace JSC;
namespace WebCore {
-JSValue JSInspectorController::highlightDOMNode(JSC::ExecState*, const JSC::ArgList& args)
+JSValue JSInspectorBackend::highlightDOMNode(JSC::ExecState*, const JSC::ArgList& args)
{
if (args.size() < 1)
return jsUndefined();
@@ -87,34 +88,7 @@ JSValue JSInspectorController::highlightDOMNode(JSC::ExecState*, const JSC::ArgL
return jsUndefined();
}
-JSValue JSInspectorController::getResourceDocumentNode(ExecState* exec, const ArgList& args)
-{
- if (args.size() < 1)
- return jsUndefined();
-
- bool ok = false;
- unsigned identifier = args.at(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();
- Document* document = frame->document();
-
- if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument())
- return jsUndefined();
-
- ExecState* resourceExec = toJSDOMWindowShell(frame)->window()->globalExec();
-
- JSLock lock(false);
- return JSInspectedObjectWrapper::wrap(resourceExec, toJS(resourceExec, document));
-}
-
-JSValue JSInspectorController::search(ExecState* exec, const ArgList& args)
+JSValue JSInspectorBackend::search(ExecState* exec, const ArgList& args)
{
if (args.size() < 2)
return jsUndefined();
@@ -151,7 +125,7 @@ JSValue JSInspectorController::search(ExecState* exec, const ArgList& args)
}
#if ENABLE(DATABASE)
-JSValue JSInspectorController::databaseTableNames(ExecState* exec, const ArgList& args)
+JSValue JSInspectorBackend::databaseTableNames(ExecState* exec, const ArgList& args)
{
if (args.size() < 1)
return jsUndefined();
@@ -175,13 +149,16 @@ JSValue JSInspectorController::databaseTableNames(ExecState* exec, const ArgList
}
#endif
-JSValue JSInspectorController::inspectedWindow(ExecState*, const ArgList&)
+JSValue JSInspectorBackend::inspectedWindow(ExecState*, const ArgList&)
{
- JSDOMWindow* inspectedWindow = toJSDOMWindow(impl()->inspectedPage()->mainFrame());
+ InspectorController* ic = impl()->inspectorController();
+ if (!ic)
+ return jsUndefined();
+ JSDOMWindow* inspectedWindow = toJSDOMWindow(ic->inspectedPage()->mainFrame());
return JSInspectedObjectWrapper::wrap(inspectedWindow->globalExec(), inspectedWindow);
}
-JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args)
+JSValue JSInspectorBackend::setting(ExecState* exec, const ArgList& args)
{
if (args.size() < 1)
return jsUndefined();
@@ -190,7 +167,10 @@ JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args)
if (exec->hadException())
return jsUndefined();
- const InspectorController::Setting& setting = impl()->setting(key);
+ InspectorController* ic = impl()->inspectorController();
+ if (!ic)
+ return jsUndefined();
+ const InspectorController::Setting& setting = ic->setting(key);
switch (setting.type()) {
default:
@@ -215,7 +195,7 @@ JSValue JSInspectorController::setting(ExecState* exec, const ArgList& args)
}
}
-JSValue JSInspectorController::setSetting(ExecState* exec, const ArgList& args)
+JSValue JSInspectorBackend::setSetting(ExecState* exec, const ArgList& args)
{
if (args.size() < 2)
return jsUndefined();
@@ -253,12 +233,14 @@ JSValue JSInspectorController::setSetting(ExecState* exec, const ArgList& args)
if (exec->hadException())
return jsUndefined();
- impl()->setSetting(key, setting);
+ InspectorController* ic = impl()->inspectorController();
+ if (ic)
+ ic->setSetting(key, setting);
return jsUndefined();
}
-JSValue JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args)
+JSValue JSInspectorBackend::wrapCallback(ExecState* exec, const ArgList& args)
{
if (args.size() < 1)
return jsUndefined();
@@ -268,7 +250,7 @@ JSValue JSInspectorController::wrapCallback(ExecState* exec, const ArgList& args
#if ENABLE(JAVASCRIPT_DEBUGGER)
-JSValue JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&)
+JSValue JSInspectorBackend::currentCallFrame(ExecState* exec, const ArgList&)
{
JavaScriptCallFrame* callFrame = impl()->currentCallFrame();
if (!callFrame || !callFrame->isValid())
@@ -277,15 +259,18 @@ JSValue JSInspectorController::currentCallFrame(ExecState* exec, const ArgList&)
// FIXME: I am not sure if this is actually needed. Can we just use exec?
ExecState* globalExec = callFrame->scopeChain()->globalObject()->globalExec();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
return JSInspectedObjectWrapper::wrap(globalExec, toJS(exec, callFrame));
}
-JSValue JSInspectorController::profiles(JSC::ExecState* exec, const JSC::ArgList&)
+JSValue JSInspectorBackend::profiles(JSC::ExecState* exec, const JSC::ArgList&)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
MarkedArgumentBuffer result;
- const Vector<RefPtr<Profile> >& profiles = impl()->profiles();
+ InspectorController* ic = impl()->inspectorController();
+ if (!ic)
+ return jsUndefined();
+ const Vector<RefPtr<Profile> >& profiles = ic->profiles();
for (size_t i = 0; i < profiles.size(); ++i)
result.append(toJS(exec, profiles[i].get()));
diff --git a/WebCore/bindings/js/JSLazyEventListener.cpp b/WebCore/bindings/js/JSLazyEventListener.cpp
index f7c74ae..7caff2b 100644
--- a/WebCore/bindings/js/JSLazyEventListener.cpp
+++ b/WebCore/bindings/js/JSLazyEventListener.cpp
@@ -77,7 +77,11 @@ void JSLazyEventListener::parseCode() const
if (m_parsed)
return;
- if (m_globalObject->scriptExecutionContext()->isDocument()) {
+ ScriptExecutionContext* executionContext = m_globalObject->scriptExecutionContext();
+ ASSERT(executionContext);
+ if (!executionContext)
+ return;
+ if (executionContext->isDocument()) {
JSDOMWindow* window = static_cast<JSDOMWindow*>(m_globalObject);
Frame* frame = window->impl()->frame();
if (!frame)
@@ -93,7 +97,7 @@ void JSLazyEventListener::parseCode() const
ExecState* exec = m_globalObject->globalExec();
MarkedArgumentBuffer args;
- UString sourceURL(m_globalObject->scriptExecutionContext()->url().string());
+ UString sourceURL(executionContext->url().string());
args.append(jsNontrivialString(exec, m_eventParameterName));
args.append(jsString(exec, m_code));
@@ -113,7 +117,7 @@ void JSLazyEventListener::parseCode() const
// (and the document, and the form - see JSHTMLElement::eventHandlerScope)
ScopeChain scope = listenerAsFunction->scope();
- JSValue thisObj = toJS(exec, m_originalNode);
+ JSValue thisObj = toJS(exec, m_globalObject, m_originalNode);
if (thisObj.isObject()) {
static_cast<JSNode*>(asObject(thisObj))->pushEventHandlerScope(exec, scope);
listenerAsFunction->setScope(scope);
diff --git a/WebCore/bindings/js/JSLocationCustom.cpp b/WebCore/bindings/js/JSLocationCustom.cpp
index 9c5a834..d7d32f4 100644
--- a/WebCore/bindings/js/JSLocationCustom.cpp
+++ b/WebCore/bindings/js/JSLocationCustom.cpp
@@ -39,20 +39,20 @@ namespace WebCore {
static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionReplace);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace);
}
static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 0, propertyName, jsLocationPrototypeFunctionReload);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload);
}
static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new (exec) PrototypeFunction(exec, 1, propertyName, jsLocationPrototypeFunctionAssign);
+ return new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign);
}
-bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSLocation::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
Frame* frame = impl()->frame();
if (!frame) {
@@ -61,7 +61,7 @@ bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& pro
}
// When accessing Location cross-domain, functions are always the native built-in ones.
- // See JSDOMWindow::customGetOwnPropertySlot for additional details.
+ // See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
// Our custom code is only needed to implement the Window cross-domain scheme, so if access is
// allowed, return false so the normal lookup will take place.
@@ -93,7 +93,7 @@ bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& pro
return true;
}
-bool JSLocation::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+bool JSLocation::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
Frame* frame = impl()->frame();
if (!frame)
@@ -128,12 +128,12 @@ bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName)
return Base::deleteProperty(exec, propertyName);
}
-bool JSLocation::customGetPropertyNames(ExecState* exec, PropertyNameArray&)
+void JSLocation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
// Only allow the location object to enumerated by frames in the same origin.
if (!allowsAccessFromFrame(exec, impl()->frame()))
- return true;
- return false;
+ return;
+ Base::getPropertyNames(exec, propertyNames);
}
void JSLocation::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
@@ -245,13 +245,13 @@ void JSLocation::setHash(ExecState* exec, JSValue value)
ASSERT(frame);
KURL url = frame->loader()->url();
- String oldRef = url.ref();
+ String oldFragmentIdentifier = url.fragmentIdentifier();
String str = value.toString(exec);
if (str.startsWith("#"))
str = str.substring(1);
- if (oldRef == str || (oldRef.isNull() && str.isEmpty()))
+ if (equalIgnoringNullity(oldFragmentIdentifier, str))
return;
- url.setRef(str);
+ url.setFragmentIdentifier(str);
navigateIfAllowed(exec, frame, url, !frame->script()->anyPageIsProcessingUserGesture(), false);
}
@@ -311,7 +311,7 @@ JSValue JSLocation::toString(ExecState* exec, const ArgList&)
return jsString(exec, impl()->toString());
}
-bool JSLocationPrototype::customPut(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&)
+bool JSLocationPrototype::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&)
{
return (propertyName == exec->propertyNames().toString || propertyName == exec->propertyNames().valueOf);
}
diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.cpp b/WebCore/bindings/js/JSMessageChannelConstructor.cpp
index 495bd53..25a5cb2 100644
--- a/WebCore/bindings/js/JSMessageChannelConstructor.cpp
+++ b/WebCore/bindings/js/JSMessageChannelConstructor.cpp
@@ -38,21 +38,15 @@ namespace WebCore {
const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstructor", 0, 0, 0 };
JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
- : DOMObject(JSMessageChannelConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
- , m_globalObject(globalObject)
+ : DOMConstructorObject(JSMessageChannelConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec, globalObject), None);
}
JSMessageChannelConstructor::~JSMessageChannelConstructor()
{
}
-ScriptExecutionContext* JSMessageChannelConstructor::scriptExecutionContext() const
-{
- return m_globalObject->scriptExecutionContext();
-}
-
ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& constructData)
{
constructData.native.function = construct;
@@ -61,18 +55,12 @@ ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& const
JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* constructor, const ArgList&)
{
- ScriptExecutionContext* context = static_cast<JSMessageChannelConstructor*>(constructor)->scriptExecutionContext();
+ JSMessageChannelConstructor* jsConstructor = static_cast<JSMessageChannelConstructor*>(constructor);
+ ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
if (!context)
return throwError(exec, ReferenceError, "MessageChannel constructor associated document is unavailable");
- return asObject(toJS(exec, MessageChannel::create(context)));
-}
-
-void JSMessageChannelConstructor::mark()
-{
- DOMObject::mark();
- if (!m_globalObject->marked())
- m_globalObject->mark();
+ return asObject(toJS(exec, jsConstructor->globalObject(), MessageChannel::create(context)));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSMessageChannelConstructor.h b/WebCore/bindings/js/JSMessageChannelConstructor.h
index 90c29a3..d958760 100644
--- a/WebCore/bindings/js/JSMessageChannelConstructor.h
+++ b/WebCore/bindings/js/JSMessageChannelConstructor.h
@@ -30,23 +30,16 @@
namespace WebCore {
- class JSMessageChannelConstructor : public DOMObject {
+ class JSMessageChannelConstructor : public DOMConstructorObject {
public:
JSMessageChannelConstructor(JSC::ExecState*, JSDOMGlobalObject*);
virtual ~JSMessageChannelConstructor();
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
static const JSC::ClassInfo s_info;
- ScriptExecutionContext* scriptExecutionContext() const;
-
virtual bool implementsHasInstance() const { return true; }
static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&);
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
-
- virtual void mark();
-
- private:
- JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSMessageChannelCustom.cpp b/WebCore/bindings/js/JSMessageChannelCustom.cpp
index 70329e2..574e28a 100644
--- a/WebCore/bindings/js/JSMessageChannelCustom.cpp
+++ b/WebCore/bindings/js/JSMessageChannelCustom.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
@@ -32,20 +32,20 @@ using namespace JSC;
namespace WebCore {
-void JSMessageChannel::mark()
+void JSMessageChannel::markChildren(MarkStack& markStack)
{
- DOMObject::mark();
+ Base::markChildren(markStack);
if (MessagePort* port = m_impl->port1()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port);
- if (wrapper && !wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
if (MessagePort* port = m_impl->port2()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port);
- if (wrapper && !wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
}
diff --git a/WebCore/bindings/js/JSMessagePortCustom.cpp b/WebCore/bindings/js/JSMessagePortCustom.cpp
index f4809ae..c3316c5 100644
--- a/WebCore/bindings/js/JSMessagePortCustom.cpp
+++ b/WebCore/bindings/js/JSMessagePortCustom.cpp
@@ -38,17 +38,17 @@ using namespace JSC;
namespace WebCore {
-void JSMessagePort::mark()
+void JSMessagePort::markChildren(MarkStack& markStack)
{
- DOMObject::mark();
+ Base::markChildren(markStack);
- markIfNotNull(m_impl->onmessage());
- markIfNotNull(m_impl->onclose());
+ markIfNotNull(markStack, m_impl->onmessage());
- if (MessagePortProxy* entangledPort = m_impl->entangledPort()) {
+ // If we have a locally entangled port, we can directly mark it as reachable. Ports that are remotely entangled are marked in-use by markActiveObjectsForContext().
+ if (MessagePort* entangledPort = m_impl->locallyEntangledPort()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), entangledPort);
- if (wrapper && !wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
typedef MessagePort::EventListenersMap EventListenersMap;
@@ -56,18 +56,10 @@ void JSMessagePort::mark()
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)
- (*vecIter)->markJSFunction();
+ (*vecIter)->markJSFunction(markStack);
}
}
-JSValue JSMessagePort::startConversation(ExecState* exec, const ArgList& args)
-{
- JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
- const UString& message = args.at(0).toString(exec);
-
- return toJS(exec, impl()->startConversation(globalObject->scriptExecutionContext(), message).get());
-}
-
JSValue JSMessagePort::addEventListener(ExecState* exec, const ArgList& args)
{
JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
diff --git a/WebCore/bindings/js/JSNamedNodesCollection.cpp b/WebCore/bindings/js/JSNamedNodesCollection.cpp
index 93a8937..f36a7d6 100644
--- a/WebCore/bindings/js/JSNamedNodesCollection.cpp
+++ b/WebCore/bindings/js/JSNamedNodesCollection.cpp
@@ -42,8 +42,8 @@ const ClassInfo JSNamedNodesCollection::s_info = { "Collection", 0, 0, 0 };
// Such a collection is usually very short-lived, it only exists
// for constructs like document.forms.<name>[1],
// so it shouldn't be a problem that it's storing all the nodes (with the same name). (David)
-JSNamedNodesCollection::JSNamedNodesCollection(ExecState* exec, const Vector<RefPtr<Node> >& nodes)
- : DOMObject(getDOMStructure<JSNamedNodesCollection>(exec))
+JSNamedNodesCollection::JSNamedNodesCollection(ExecState* exec, JSDOMGlobalObject* globalObject, const Vector<RefPtr<Node> >& nodes)
+ : DOMObjectWithGlobalPointer(getDOMStructure<JSNamedNodesCollection>(exec, globalObject), globalObject)
, m_nodes(new Vector<RefPtr<Node> >(nodes))
{
}
@@ -86,7 +86,7 @@ bool JSNamedNodesCollection::getOwnPropertySlot(ExecState* exec, const Identifie
}
}
- return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
+ return DOMObjectWithGlobalPointer::getOwnPropertySlot(exec, propertyName, slot);
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSNamedNodesCollection.h b/WebCore/bindings/js/JSNamedNodesCollection.h
index 3bbc102..cd6c2cb 100644
--- a/WebCore/bindings/js/JSNamedNodesCollection.h
+++ b/WebCore/bindings/js/JSNamedNodesCollection.h
@@ -35,9 +35,9 @@ namespace WebCore {
// Internal class, used for the collection return by e.g. document.forms.myinput
// when multiple nodes have the same name.
- class JSNamedNodesCollection : public DOMObject {
+ class JSNamedNodesCollection : public DOMObjectWithGlobalPointer {
public:
- JSNamedNodesCollection(JSC::ExecState*, const Vector<RefPtr<Node> >&);
+ JSNamedNodesCollection(JSC::ExecState*, JSDOMGlobalObject*, const Vector<RefPtr<Node> >&);
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);
diff --git a/WebCore/bindings/js/JSNavigatorCustom.cpp b/WebCore/bindings/js/JSNavigatorCustom.cpp
index ea6cceb..c023931 100644
--- a/WebCore/bindings/js/JSNavigatorCustom.cpp
+++ b/WebCore/bindings/js/JSNavigatorCustom.cpp
@@ -29,13 +29,13 @@ namespace WebCore {
using namespace JSC;
-void JSNavigator::mark()
+void JSNavigator::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
JSGlobalData& globalData = *Heap::heap(this)->globalData();
- markDOMObjectWrapper(globalData, impl()->optionalGeolocation());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalGeolocation());
}
}
diff --git a/WebCore/bindings/js/JSNodeCustom.cpp b/WebCore/bindings/js/JSNodeCustom.cpp
index 79ac6b7..cf884b9 100644
--- a/WebCore/bindings/js/JSNodeCustom.cpp
+++ b/WebCore/bindings/js/JSNodeCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -110,7 +110,7 @@ JSValue JSNode::appendChild(ExecState* exec, const ArgList& args)
JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args)
{
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->document());
if (!globalObject)
return jsUndefined();
@@ -122,7 +122,7 @@ JSValue JSNode::addEventListener(ExecState* exec, const ArgList& args)
JSValue JSNode::removeEventListener(ExecState* exec, const ArgList& args)
{
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
+ JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->document());
if (!globalObject)
return jsUndefined();
@@ -136,22 +136,21 @@ void JSNode::pushEventHandlerScope(ExecState*, ScopeChain&) const
{
}
-void JSNode::mark()
+void JSNode::markChildren(MarkStack& markStack)
{
- ASSERT(!marked());
-
Node* node = m_impl.get();
+ Base::markChildren(markStack);
+ markEventListeners(markStack, node->eventListeners());
+
// Nodes in the document are kept alive by JSDocument::mark, so, if we're in
// the document, we need to mark the document, but we don't need to explicitly
// mark any other nodes.
if (node->inDocument()) {
- DOMObject::mark();
- markEventListeners(node->eventListeners());
- if (Document* doc = node->ownerDocument())
+ if (Document* doc = node->ownerDocument()) {
if (DOMObject* docWrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), doc))
- if (!docWrapper->marked())
- docWrapper->mark();
+ markStack.append(docWrapper);
+ }
return;
}
@@ -163,36 +162,20 @@ void JSNode::mark()
// Nodes in a subtree are marked by the tree's root, so, if the root is already
// marking the tree, we don't need to explicitly mark any other nodes.
- if (root->inSubtreeMark()) {
- DOMObject::mark();
- markEventListeners(node->eventListeners());
+ if (root->inSubtreeMark())
return;
- }
// Mark the whole tree subtree.
root->setInSubtreeMark(true);
for (Node* nodeToMark = root; nodeToMark; nodeToMark = nodeToMark->traverseNextNode()) {
JSNode* wrapper = getCachedDOMNodeWrapper(m_impl->document(), nodeToMark);
- if (wrapper) {
- if (!wrapper->marked())
- wrapper->mark();
- } else if (nodeToMark == node) {
- // This is the case where the map from the document to wrappers has
- // been cleared out, but a wrapper is being marked. For now, we'll
- // let the rest of the tree of wrappers get collected, because we have
- // no good way of finding them. Later we should test behavior of other
- // browsers and see if we need to preserve other wrappers in this case.
- if (!marked())
- mark();
- }
+ if (wrapper)
+ markStack.append(wrapper);
}
root->setInSubtreeMark(false);
-
- // Double check that we actually ended up marked. This assert caught problems in the past.
- ASSERT(marked());
}
-static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, Node* node)
+static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
ASSERT(node);
ASSERT(!getCachedDOMNodeWrapper(node->document(), node));
@@ -201,63 +184,63 @@ static ALWAYS_INLINE JSValue createWrapper(ExecState* exec, Node* node)
switch (node->nodeType()) {
case Node::ELEMENT_NODE:
if (node->isHTMLElement())
- wrapper = createJSHTMLWrapper(exec, static_cast<HTMLElement*>(node));
+ wrapper = createJSHTMLWrapper(exec, globalObject, static_cast<HTMLElement*>(node));
#if ENABLE(SVG)
else if (node->isSVGElement())
- wrapper = createJSSVGWrapper(exec, static_cast<SVGElement*>(node));
+ wrapper = createJSSVGWrapper(exec, globalObject, static_cast<SVGElement*>(node));
#endif
else
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Element, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Element, node);
break;
case Node::ATTRIBUTE_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Attr, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Attr, node);
break;
case Node::TEXT_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Text, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Text, node);
break;
case Node::CDATA_SECTION_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, CDATASection, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, CDATASection, node);
break;
case Node::ENTITY_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Entity, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Entity, node);
break;
case Node::PROCESSING_INSTRUCTION_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, ProcessingInstruction, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, ProcessingInstruction, node);
break;
case Node::COMMENT_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Comment, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Comment, node);
break;
case Node::DOCUMENT_NODE:
// we don't want to cache the document itself in the per-document dictionary
- return toJS(exec, static_cast<Document*>(node));
+ return toJS(exec, globalObject, static_cast<Document*>(node));
case Node::DOCUMENT_TYPE_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, DocumentType, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentType, node);
break;
case Node::NOTATION_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Notation, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Notation, node);
break;
case Node::DOCUMENT_FRAGMENT_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, DocumentFragment, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, DocumentFragment, node);
break;
case Node::ENTITY_REFERENCE_NODE:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, EntityReference, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, EntityReference, node);
break;
default:
- wrapper = CREATE_DOM_NODE_WRAPPER(exec, Node, node);
+ wrapper = CREATE_DOM_NODE_WRAPPER(exec, globalObject, Node, node);
}
return wrapper;
}
-JSValue toJSNewlyCreated(ExecState* exec, Node* node)
+JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
if (!node)
return jsNull();
- return createWrapper(exec, node);
+ return createWrapper(exec, globalObject, node);
}
-JSValue toJS(ExecState* exec, Node* node)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Node* node)
{
if (!node)
return jsNull();
@@ -266,7 +249,7 @@ JSValue toJS(ExecState* exec, Node* node)
if (wrapper)
return wrapper;
- return createWrapper(exec, node);
+ return createWrapper(exec, globalObject, node);
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp
index f5d4d5c..a199417 100644
--- a/WebCore/bindings/js/JSNodeFilterCondition.cpp
+++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -36,15 +36,14 @@ JSNodeFilterCondition::JSNodeFilterCondition(JSValue filter)
{
}
-void JSNodeFilterCondition::mark()
+void JSNodeFilterCondition::markAggregate(MarkStack& markStack)
{
- if (!m_filter.marked())
- m_filter.mark();
+ markStack.append(m_filter);
}
short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) const
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
CallData callData;
CallType callType = m_filter.getCallData(callData);
@@ -61,7 +60,9 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode)
return NodeFilter::FILTER_REJECT;
MarkedArgumentBuffer args;
- args.append(toJS(exec, filterNode));
+ // FIXME: The node should have the prototype chain that came from its document, not
+ // whatever prototype chain might be on the window this filter came from. Bug 27662
+ args.append(toJS(exec, deprecatedGlobalObjectForPrototype(exec), filterNode));
if (exec->hadException())
return NodeFilter::FILTER_REJECT;
diff --git a/WebCore/bindings/js/JSNodeFilterCondition.h b/WebCore/bindings/js/JSNodeFilterCondition.h
index 3d591c6..b96534a 100644
--- a/WebCore/bindings/js/JSNodeFilterCondition.h
+++ b/WebCore/bindings/js/JSNodeFilterCondition.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 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
@@ -39,7 +39,7 @@ namespace WebCore {
JSNodeFilterCondition(JSC::JSValue filter);
virtual short acceptNode(ScriptState*, Node*) const;
- virtual void mark();
+ virtual void markAggregate(JSC::MarkStack&);
mutable JSC::JSValue m_filter;
};
diff --git a/WebCore/bindings/js/JSNodeFilterCustom.cpp b/WebCore/bindings/js/JSNodeFilterCustom.cpp
index ecc12d5..09fd110 100644
--- a/WebCore/bindings/js/JSNodeFilterCustom.cpp
+++ b/WebCore/bindings/js/JSNodeFilterCustom.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
@@ -35,10 +35,10 @@ using namespace JSC;
namespace WebCore {
-void JSNodeFilter::mark()
+void JSNodeFilter::markChildren(MarkStack& markStack)
{
- impl()->mark();
- DOMObject::mark();
+ Base::markChildren(markStack);
+ impl()->markAggregate(markStack);
}
JSValue JSNodeFilter::acceptNode(ExecState* exec, const ArgList& args)
diff --git a/WebCore/bindings/js/JSNodeIteratorCustom.cpp b/WebCore/bindings/js/JSNodeIteratorCustom.cpp
index 8fff82e..6a09abf 100644
--- a/WebCore/bindings/js/JSNodeIteratorCustom.cpp
+++ b/WebCore/bindings/js/JSNodeIteratorCustom.cpp
@@ -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
@@ -29,12 +29,12 @@ using namespace JSC;
namespace WebCore {
-void JSNodeIterator::mark()
+void JSNodeIterator::markChildren(MarkStack& markStack)
{
+ Base::markChildren(markStack);
+
if (NodeFilter* filter = m_impl->filter())
- filter->mark();
-
- DOMObject::mark();
+ filter->markAggregate(markStack);
}
JSValue JSNodeIterator::nextNode(ExecState* exec, const ArgList&)
diff --git a/WebCore/bindings/js/JSOptionConstructor.cpp b/WebCore/bindings/js/JSOptionConstructor.cpp
index 9e818ff..2b8bd5d 100644
--- a/WebCore/bindings/js/JSOptionConstructor.cpp
+++ b/WebCore/bindings/js/JSOptionConstructor.cpp
@@ -35,24 +35,16 @@ ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor);
const ClassInfo JSOptionConstructor::s_info = { "OptionConstructor", 0, 0, 0 };
JSOptionConstructor::JSOptionConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
- : DOMObject(JSOptionConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
- , m_globalObject(globalObject)
+ : DOMConstructorWithDocument(JSOptionConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- ASSERT(globalObject->scriptExecutionContext());
- ASSERT(globalObject->scriptExecutionContext()->isDocument());
-
- putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSHTMLOptionElementPrototype::self(exec, globalObject), 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();
+ JSOptionConstructor* jsConstructor = static_cast<JSOptionConstructor*>(constructor);
+ Document* document = jsConstructor->document();
if (!document)
return throwError(exec, ReferenceError, "Option constructor associated document is unavailable");
@@ -76,7 +68,7 @@ static JSObject* constructHTMLOptionElement(ExecState* exec, JSObject* construct
return 0;
}
- return asObject(toJS(exec, element.release()));
+ return asObject(toJS(exec, jsConstructor->globalObject(), element.release()));
}
ConstructType JSOptionConstructor::getConstructData(ConstructData& constructData)
@@ -85,11 +77,5 @@ ConstructType JSOptionConstructor::getConstructData(ConstructData& constructData
return ConstructTypeHost;
}
-void JSOptionConstructor::mark()
-{
- DOMObject::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 3c87c28..246e7fa 100644
--- a/WebCore/bindings/js/JSOptionConstructor.h
+++ b/WebCore/bindings/js/JSOptionConstructor.h
@@ -26,19 +26,14 @@
namespace WebCore {
- class JSOptionConstructor : public DOMObject {
+ class JSOptionConstructor : public DOMConstructorWithDocument {
public:
JSOptionConstructor(JSC::ExecState*, JSDOMGlobalObject*);
- Document* document() const;
static const JSC::ClassInfo s_info;
-
- virtual void mark();
private:
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
-
- JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp b/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
index ad1e556..5f4dfd4 100644
--- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp
+++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.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
@@ -92,14 +92,12 @@ void JSQuarantinedObjectWrapper::transferExceptionToExecState(ExecState* exec) c
exec->setException(wrapOutgoingValue(unwrappedExecState(), exception));
}
-void JSQuarantinedObjectWrapper::mark()
+void JSQuarantinedObjectWrapper::markChildren(MarkStack& markStack)
{
- JSObject::mark();
+ JSObject::markChildren(markStack);
- if (!m_unwrappedObject->marked())
- m_unwrappedObject->mark();
- if (!m_unwrappedGlobalObject->marked())
- m_unwrappedGlobalObject->mark();
+ markStack.append(m_unwrappedObject);
+ markStack.append(m_unwrappedGlobalObject);
}
bool JSQuarantinedObjectWrapper::getOwnPropertySlot(ExecState* exec, const Identifier& identifier, PropertySlot& slot)
diff --git a/WebCore/bindings/js/JSQuarantinedObjectWrapper.h b/WebCore/bindings/js/JSQuarantinedObjectWrapper.h
index bf8fddb..08935e7 100644
--- a/WebCore/bindings/js/JSQuarantinedObjectWrapper.h
+++ b/WebCore/bindings/js/JSQuarantinedObjectWrapper.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
@@ -53,7 +53,7 @@ namespace WebCore {
protected:
JSQuarantinedObjectWrapper(JSC::ExecState* unwrappedExec, JSC::JSObject* unwrappedObject, PassRefPtr<JSC::Structure>);
- virtual void mark();
+ virtual void markChildren(JSC::MarkStack&);
private:
virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);
diff --git a/WebCore/bindings/js/JSRGBColor.cpp b/WebCore/bindings/js/JSRGBColor.cpp
deleted file mode 100644
index f7c87e2..0000000
--- a/WebCore/bindings/js/JSRGBColor.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 James G. Speth (speth@end.com)
- * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
- *
- * 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 "JSRGBColor.h"
-
-#include "CSSPrimitiveValue.h"
-#include "JSCSSPrimitiveValue.h"
-
-using namespace JSC;
-
-static JSValue jsRGBColorRed(ExecState*, const Identifier&, const PropertySlot&);
-static JSValue jsRGBColorGreen(ExecState*, const Identifier&, const PropertySlot&);
-static JSValue jsRGBColorBlue(ExecState*, const Identifier&, const PropertySlot&);
-
-/*
-@begin JSRGBColorTable
- red jsRGBColorRed DontDelete|ReadOnly
- green jsRGBColorGreen DontDelete|ReadOnly
- blue jsRGBColorBlue DontDelete|ReadOnly
-@end
-*/
-
-#include "JSRGBColor.lut.h"
-
-namespace WebCore {
-
-ASSERT_CLASS_FITS_IN_CELL(JSRGBColor);
-
-const ClassInfo JSRGBColor::s_info = { "RGBColor", 0, &JSRGBColorTable, 0 };
-
-JSRGBColor::JSRGBColor(ExecState* exec, unsigned color)
- : DOMObject(getDOMStructure<JSRGBColor>(exec))
- , m_color(color)
-{
-}
-
-bool JSRGBColor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
- return getStaticValueSlot<JSRGBColor, DOMObject>(exec, &JSRGBColorTable, this, propertyName, slot);
-}
-
-JSValue getJSRGBColor(ExecState* exec, unsigned color)
-{
- return new (exec) JSRGBColor(exec, color);
-}
-
-} // namespace WebCore
-
-using namespace WebCore;
-
-JSValue jsRGBColorRed(ExecState* exec, const Identifier&, const PropertySlot& slot)
-{
- return toJS(exec, CSSPrimitiveValue::create((static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() >> 16) & 0xFF, CSSPrimitiveValue::CSS_NUMBER));
-}
-
-JSValue jsRGBColorGreen(ExecState* exec, const Identifier&, const PropertySlot& slot)
-{
- return toJS(exec, CSSPrimitiveValue::create((static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() >> 8) & 0xFF, CSSPrimitiveValue::CSS_NUMBER));
-}
-
-JSValue jsRGBColorBlue(ExecState* exec, const Identifier&, const PropertySlot& slot)
-{
- return toJS(exec, CSSPrimitiveValue::create(static_cast<JSRGBColor*>(asObject(slot.slotBase()))->impl() & 0xFF, CSSPrimitiveValue::CSS_NUMBER));
-}
-
diff --git a/WebCore/bindings/js/JSRGBColor.h b/WebCore/bindings/js/JSRGBColor.h
deleted file mode 100644
index cc2870f..0000000
--- a/WebCore/bindings/js/JSRGBColor.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU 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 JSRGBColor_h
-#define JSRGBColor_h
-
-#include "Color.h"
-#include "JSDOMBinding.h"
-
-namespace WebCore {
-
- // FIXME: JSRGBColor should have a proper prototype and a constructor.
- class JSRGBColor : public DOMObject {
- public:
- JSRGBColor(JSC::ExecState*, unsigned color);
-
- virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);
-
- virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
- static const JSC::ClassInfo s_info;
-
- unsigned impl() const { return m_color; }
-
- static JSC::ObjectPrototype* createPrototype(JSC::ExecState*, JSC::JSGlobalObject* globalObject)
- {
- return globalObject->objectPrototype();
- }
-
- static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
- {
- return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));
- }
-
- private:
- unsigned m_color;
- };
-
- JSC::JSValue getJSRGBColor(JSC::ExecState*, unsigned color);
-
-} // namespace WebCore
-
-#endif // JSRGBColor_h
diff --git a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
index 2922740..6e77f9b 100644
--- a/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
+++ b/WebCore/bindings/js/JSSVGElementInstanceCustom.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * 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
@@ -37,14 +38,14 @@ using namespace JSC;
namespace WebCore {
-void JSSVGElementInstance::mark()
+void JSSVGElementInstance::markChildren(MarkStack& markStack)
{
- DOMObject::mark();
+ Base::markChildren(markStack);
// Mark the wrapper for our corresponding element, so it can mark its event handlers.
JSNode* correspondingWrapper = getCachedDOMNodeWrapper(impl()->correspondingElement()->document(), impl()->correspondingElement());
- if (correspondingWrapper && !correspondingWrapper->marked())
- correspondingWrapper->mark();
+ if (correspondingWrapper)
+ markStack.append(correspondingWrapper);
}
JSValue JSSVGElementInstance::addEventListener(ExecState* exec, const ArgList& args)
@@ -75,9 +76,9 @@ void JSSVGElementInstance::pushEventHandlerScope(ExecState*, ScopeChain&) const
{
}
-JSC::JSValue toJS(JSC::ExecState* exec, SVGElementInstance* object)
+JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, SVGElementInstance* object)
{
- JSValue result = getDOMObjectWrapper<JSSVGElementInstance>(exec, object);
+ JSValue result = getDOMObjectWrapper<JSSVGElementInstance>(exec, globalObject, object);
// Ensure that our corresponding element has a JavaScript wrapper to keep its event handlers alive.
if (object)
diff --git a/WebCore/bindings/js/JSSVGMatrixCustom.cpp b/WebCore/bindings/js/JSSVGMatrixCustom.cpp
index fc1e266..35390b2 100644
--- a/WebCore/bindings/js/JSSVGMatrixCustom.cpp
+++ b/WebCore/bindings/js/JSSVGMatrixCustom.cpp
@@ -32,7 +32,7 @@ namespace WebCore {
JSValue JSSVGMatrix::inverse(ExecState* exec, const ArgList&)
{
TransformationMatrix imp(*impl());
- JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.inverse()).get(), m_context.get());
if (!imp.isInvertible())
setDOMException(exec, SVGException::SVG_MATRIX_NOT_INVERTABLE);
@@ -47,7 +47,7 @@ JSValue JSSVGMatrix::rotateFromVector(ExecState* exec, const ArgList& args)
float x = args.at(0).toFloat(exec);
float y = args.at(1).toFloat(exec);
- JSC::JSValue result = toJS(exec, JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<TransformationMatrix>::create(imp.rotateFromVector(x, y)).get(), m_context.get());
if (x == 0.0 || y == 0.0)
setDOMException(exec, SVGException::SVG_INVALID_VALUE_ERR);
diff --git a/WebCore/bindings/js/JSSVGPathSegCustom.cpp b/WebCore/bindings/js/JSSVGPathSegCustom.cpp
index cb4687c..42fa878 100644
--- a/WebCore/bindings/js/JSSVGPathSegCustom.cpp
+++ b/WebCore/bindings/js/JSSVGPathSegCustom.cpp
@@ -59,7 +59,7 @@ using namespace JSC;
namespace WebCore {
-JSValue toJS(ExecState* exec, SVGPathSeg* object, SVGElement* context)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, SVGPathSeg* object, SVGElement* context)
{
if (!object)
return jsNull();
@@ -69,46 +69,46 @@ JSValue toJS(ExecState* exec, SVGPathSeg* object, SVGElement* context)
switch (object->pathSegType()) {
case SVGPathSeg::PATHSEG_CLOSEPATH:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegClosePath, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegClosePath, object, context);
case SVGPathSeg::PATHSEG_MOVETO_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegMovetoAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegMovetoAbs, object, context);
case SVGPathSeg::PATHSEG_MOVETO_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegMovetoRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegMovetoRel, object, context);
case SVGPathSeg::PATHSEG_LINETO_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoAbs, object, context);
case SVGPathSeg::PATHSEG_LINETO_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoRel, object, context);
case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicAbs, object, context);
case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicRel, object, context);
case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticAbs, object, context);
case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticRel, object, context);
case SVGPathSeg::PATHSEG_ARC_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegArcAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegArcAbs, object, context);
case SVGPathSeg::PATHSEG_ARC_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegArcRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegArcRel, object, context);
case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoHorizontalAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoHorizontalAbs, object, context);
case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoHorizontalRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoHorizontalRel, object, context);
case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoVerticalAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoVerticalAbs, object, context);
case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegLinetoVerticalRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegLinetoVerticalRel, object, context);
case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicSmoothAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicSmoothAbs, object, context);
case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoCubicSmoothRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoCubicSmoothRel, object, context);
case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticSmoothAbs, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticSmoothAbs, object, context);
case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSegCurvetoQuadraticSmoothRel, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSegCurvetoQuadraticSmoothRel, object, context);
case SVGPathSeg::PATHSEG_UNKNOWN:
default:
- return CREATE_SVG_OBJECT_WRAPPER(exec, SVGPathSeg, object, context);
+ return CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, SVGPathSeg, object, context);
}
}
diff --git a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp
index b6fc116..b71f3a6 100644
--- a/WebCore/bindings/js/JSSVGPathSegListCustom.cpp
+++ b/WebCore/bindings/js/JSSVGPathSegListCustom.cpp
@@ -57,7 +57,7 @@ JSValue JSSVGPathSegList::initialize(ExecState* exec, const ArgList& args)
SVGPathSeg* obj = WTF::getPtr(imp->initialize(newItem, ec));
- JSC::JSValue result = toJS(exec, obj, m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj, m_context.get());
setDOMException(exec, ec);
m_context->svgAttributeChanged(imp->associatedAttributeName());
@@ -78,7 +78,7 @@ JSValue JSSVGPathSegList::getItem(ExecState* exec, const ArgList& args)
SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl());
SVGPathSeg* obj = WTF::getPtr(imp->getItem(index, ec));
- JSC::JSValue result = toJS(exec, obj, m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj, m_context.get());
setDOMException(exec, ec);
return result;
}
@@ -97,7 +97,7 @@ JSValue JSSVGPathSegList::insertItemBefore(ExecState* exec, const ArgList& args)
SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl());
- JSC::JSValue result = toJS(exec, WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->insertItemBefore(newItem, index, ec)), m_context.get());
setDOMException(exec, ec);
m_context->svgAttributeChanged(imp->associatedAttributeName());
@@ -118,7 +118,7 @@ JSValue JSSVGPathSegList::replaceItem(ExecState* exec, const ArgList& args)
SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl());
- JSC::JSValue result = toJS(exec, WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->replaceItem(newItem, index, ec)), m_context.get());
setDOMException(exec, ec);
m_context->svgAttributeChanged(imp->associatedAttributeName());
@@ -140,7 +140,7 @@ JSValue JSSVGPathSegList::removeItem(ExecState* exec, const ArgList& args)
RefPtr<SVGPathSeg> obj(imp->removeItem(index, ec));
- JSC::JSValue result = toJS(exec, obj.get(), m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), obj.get(), m_context.get());
setDOMException(exec, ec);
m_context->svgAttributeChanged(imp->associatedAttributeName());
@@ -154,7 +154,7 @@ JSValue JSSVGPathSegList::appendItem(ExecState* exec, const ArgList& args)
SVGPathSegList* imp = static_cast<SVGPathSegList*>(impl());
- JSC::JSValue result = toJS(exec, WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get());
+ JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), WTF::getPtr(imp->appendItem(newItem, ec)), m_context.get());
setDOMException(exec, ec);
m_context->svgAttributeChanged(imp->associatedAttributeName());
diff --git a/WebCore/bindings/js/JSSVGPointListCustom.cpp b/WebCore/bindings/js/JSSVGPointListCustom.cpp
index a18c2a2..1969fe2 100644
--- a/WebCore/bindings/js/JSSVGPointListCustom.cpp
+++ b/WebCore/bindings/js/JSSVGPointListCustom.cpp
@@ -39,7 +39,7 @@ static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont
setDOMException(exec, ec);
return jsUndefined();
}
- return toJS(exec, JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), list->associatedAttributeName()).get(), context);
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), list->associatedAttributeName()).get(), context);
}
static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem > item)
@@ -50,7 +50,7 @@ static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont
}
const QualifiedName& attributeName = list->associatedAttributeName();
context->svgAttributeChanged(attributeName);
- return toJS(exec, JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), attributeName).get(), context);
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<FloatPoint>::create(item.get(), attributeName).get(), context);
}
static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGPointList* list, PassRefPtr<PODListItem> item)
@@ -60,7 +60,7 @@ static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SV
return jsUndefined();
}
context->svgAttributeChanged(list->associatedAttributeName());
- return toJS(exec, JSSVGStaticPODTypeWrapper<FloatPoint>::create(*item).get(), context);
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<FloatPoint>::create(*item).get(), context);
}
JSValue JSSVGPointList::clear(ExecState* exec, const ArgList&)
diff --git a/WebCore/bindings/js/JSSVGTransformListCustom.cpp b/WebCore/bindings/js/JSSVGTransformListCustom.cpp
index 58b25ad..1a9110a 100644
--- a/WebCore/bindings/js/JSSVGTransformListCustom.cpp
+++ b/WebCore/bindings/js/JSSVGTransformListCustom.cpp
@@ -39,7 +39,7 @@ static JSValue finishGetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont
setDOMException(exec, ec);
return jsUndefined();
}
- return toJS(exec, JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), list->associatedAttributeName()).get(), context);
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), list->associatedAttributeName()).get(), context);
}
static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item)
@@ -50,7 +50,7 @@ static JSValue finishSetter(ExecState* exec, ExceptionCode& ec, SVGElement* cont
}
const QualifiedName& attributeName = list->associatedAttributeName();
context->svgAttributeChanged(attributeName);
- return toJS(exec, JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), attributeName).get(), context);
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGPODTypeWrapperCreatorForList<SVGTransform>::create(item.get(), attributeName).get(), context);
}
static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SVGElement* context, SVGTransformList* list, PassRefPtr<PODListItem> item)
@@ -60,7 +60,7 @@ static JSValue finishSetterReadOnlyResult(ExecState* exec, ExceptionCode& ec, SV
return jsUndefined();
}
context->svgAttributeChanged(list->associatedAttributeName());
- return toJS(exec, JSSVGStaticPODTypeWrapper<SVGTransform>::create(*item).get(), context);
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<SVGTransform>::create(*item).get(), context);
}
JSValue JSSVGTransformList::clear(ExecState* exec, const ArgList&)
diff --git a/WebCore/bindings/js/JSSharedWorkerConstructor.cpp b/WebCore/bindings/js/JSSharedWorkerConstructor.cpp
new file mode 100644
index 0000000..e2f1136
--- /dev/null
+++ b/WebCore/bindings/js/JSSharedWorkerConstructor.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"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "JSSharedWorkerConstructor.h"
+
+#include "JSDOMWindowCustom.h"
+#include "JSSharedWorker.h"
+#include "SharedWorker.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+const ClassInfo JSSharedWorkerConstructor::s_info = { "SharedWorkerConstructor", 0, 0, 0 };
+
+JSSharedWorkerConstructor::JSSharedWorkerConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(JSSharedWorkerConstructor::createStructure(globalObject->objectPrototype()), globalObject)
+{
+ putDirect(exec->propertyNames().prototype, JSSharedWorkerPrototype::self(exec, globalObject), None);
+ // Host functions have a length property describing the number of expected arguments.
+ putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum);
+}
+
+static JSObject* constructSharedWorker(ExecState* exec, JSObject* constructor, const ArgList& args)
+{
+ JSSharedWorkerConstructor* jsConstructor = static_cast<JSSharedWorkerConstructor*>(constructor);
+
+ if (args.size() < 2)
+ return throwError(exec, SyntaxError, "Not enough arguments");
+
+ UString scriptURL = args.at(0).toString(exec);
+ UString name = args.at(1).toString(exec);
+ if (exec->hadException())
+ return 0;
+
+ // FIXME: We need to use both the dynamic scope and the lexical scope (dynamic scope for resolving the worker URL)
+ DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
+ ExceptionCode ec = 0;
+ RefPtr<SharedWorker> worker = SharedWorker::create(scriptURL, name, window->document(), ec);
+ setDOMException(exec, ec);
+
+ return asObject(toJS(exec, jsConstructor->globalObject(), worker.release()));
+}
+
+ConstructType JSSharedWorkerConstructor::getConstructData(ConstructData& constructData)
+{
+ constructData.native.function = constructSharedWorker;
+ return ConstructTypeHost;
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/WebCore/bindings/js/JSSharedWorkerConstructor.h b/WebCore/bindings/js/JSSharedWorkerConstructor.h
new file mode 100644
index 0000000..87baa38
--- /dev/null
+++ b/WebCore/bindings/js/JSSharedWorkerConstructor.h
@@ -0,0 +1,56 @@
+/*
+ * 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 JSSharedWorkerConstructor_h
+#define JSSharedWorkerConstructor_h
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "JSDOMBinding.h"
+
+namespace WebCore {
+
+ class JSSharedWorkerConstructor : public DOMConstructorObject {
+ public:
+ JSSharedWorkerConstructor(JSC::ExecState*, JSDOMGlobalObject*);
+
+ static const JSC::ClassInfo s_info;
+
+ private:
+ virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
+
+ virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
+
+#endif // JSSharedWorkerConstructor_h
diff --git a/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp b/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp
new file mode 100644
index 0000000..dca3536
--- /dev/null
+++ b/WebCore/bindings/js/JSSharedWorkerContextCustom.cpp
@@ -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.
+ */
+
+#include "config.h"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "JSSharedWorkerContext.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSSharedWorkerContext::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+
+ markIfNotNull(markStack, impl()->onconnect());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/WebCore/bindings/js/JSSharedWorkerCustom.cpp b/WebCore/bindings/js/JSSharedWorkerCustom.cpp
new file mode 100644
index 0000000..f21f50c
--- /dev/null
+++ b/WebCore/bindings/js/JSSharedWorkerCustom.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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(SHARED_WORKERS)
+
+#include "JSSharedWorker.h"
+
+#include "JSDOMGlobalObject.h"
+#include "SharedWorker.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSSharedWorker::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+
+ if (MessagePort* port = impl()->port()) {
+ DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), port);
+ if (wrapper)
+ markStack.append(wrapper);
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/WebCore/bindings/js/JSStorageCustom.cpp b/WebCore/bindings/js/JSStorageCustom.cpp
index bc43d79..07cf2f8 100644
--- a/WebCore/bindings/js/JSStorageCustom.cpp
+++ b/WebCore/bindings/js/JSStorageCustom.cpp
@@ -64,17 +64,16 @@ bool JSStorage::deleteProperty(ExecState* exec, const Identifier& propertyName)
return true;
}
-bool JSStorage::customGetPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
+void JSStorage::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
- ExceptionCode ec;
unsigned length = m_impl->length();
for (unsigned i = 0; i < length; ++i)
- propertyNames.add(Identifier(exec, m_impl->key(i, ec)));
+ propertyNames.add(Identifier(exec, m_impl->key(i)));
- return false;
+ Base::getPropertyNames(exec, propertyNames);
}
-bool JSStorage::customPut(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
+bool JSStorage::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
{
// Only perform the custom put if the object doesn't have a native property by this name.
// Since hasProperty() would end up calling canGetItemsForName() and be fooled, we need to check
diff --git a/WebCore/bindings/js/JSStyleSheetCustom.cpp b/WebCore/bindings/js/JSStyleSheetCustom.cpp
index f8146bd..43249dc 100644
--- a/WebCore/bindings/js/JSStyleSheetCustom.cpp
+++ b/WebCore/bindings/js/JSStyleSheetCustom.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
@@ -35,7 +35,7 @@ using namespace JSC;
namespace WebCore {
-JSValue toJS(ExecState* exec, StyleSheet* styleSheet)
+JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, StyleSheet* styleSheet)
{
if (!styleSheet)
return jsNull();
@@ -45,16 +45,16 @@ JSValue toJS(ExecState* exec, StyleSheet* styleSheet)
return wrapper;
if (styleSheet->isCSSStyleSheet())
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, CSSStyleSheet, styleSheet);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CSSStyleSheet, styleSheet);
else
- wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, StyleSheet, styleSheet);
+ wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, StyleSheet, styleSheet);
return wrapper;
}
-void JSStyleSheet::mark()
+void JSStyleSheet::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
// This prevents us from having a style sheet with a dangling ownerNode pointer.
// A better solution would be to handle this on the DOM side -- if the style sheet
@@ -62,10 +62,8 @@ void JSStyleSheet::mark()
// be to make ref/deref on the style sheet ref/deref the node instead, but there's
// a lot of disentangling of the CSS DOM objects that would need to happen first.
if (Node* ownerNode = impl()->ownerNode()) {
- if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode)) {
- if (!ownerNodeWrapper->marked())
- ownerNodeWrapper->mark();
- }
+ if (JSNode* ownerNodeWrapper = getCachedDOMNodeWrapper(ownerNode->document(), ownerNode))
+ markStack.append(ownerNodeWrapper);
}
}
diff --git a/WebCore/bindings/js/JSTextCustom.cpp b/WebCore/bindings/js/JSTextCustom.cpp
index 9e66826..2dc886d 100644
--- a/WebCore/bindings/js/JSTextCustom.cpp
+++ b/WebCore/bindings/js/JSTextCustom.cpp
@@ -32,12 +32,12 @@ using namespace JSC;
namespace WebCore {
-JSValue toJSNewlyCreated(ExecState* exec, Text* text)
+JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Text* text)
{
if (!text)
return jsNull();
- return CREATE_DOM_NODE_WRAPPER(exec, Text, text);
+ return CREATE_DOM_NODE_WRAPPER(exec, globalObject, Text, text);
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSTreeWalkerCustom.cpp b/WebCore/bindings/js/JSTreeWalkerCustom.cpp
index 6369017..f879cf4 100644
--- a/WebCore/bindings/js/JSTreeWalkerCustom.cpp
+++ b/WebCore/bindings/js/JSTreeWalkerCustom.cpp
@@ -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
@@ -29,12 +29,12 @@ using namespace JSC;
namespace WebCore {
-void JSTreeWalker::mark()
+void JSTreeWalker::markChildren(MarkStack& markStack)
{
+ Base::markChildren(markStack);
+
if (NodeFilter* filter = m_impl->filter())
- filter->mark();
-
- DOMObject::mark();
+ filter->markAggregate(markStack);
}
JSValue JSTreeWalker::parentNode(ExecState* exec, const ArgList&)
diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
index c7fe4a5..bc05250 100644
--- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
+++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.cpp
@@ -35,15 +35,16 @@ namespace WebCore {
const ClassInfo JSWebKitCSSMatrixConstructor::s_info = { "WebKitCSSMatrixConstructor", 0, 0, 0 };
-JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec)
- : DOMObject(JSWebKitCSSMatrixConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+JSWebKitCSSMatrixConstructor::JSWebKitCSSMatrixConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(JSWebKitCSSMatrixConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSWebKitCSSMatrixPrototype::self(exec, globalObject), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
-static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject*, const ArgList& args)
+static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject* constructor, const ArgList& args)
{
+ JSWebKitCSSMatrixConstructor* jsConstructor = static_cast<JSWebKitCSSMatrixConstructor*>(constructor);
String s;
if (args.size() >= 1)
s = args.at(0).toString(exec);
@@ -51,7 +52,7 @@ static JSObject* constructWebKitCSSMatrix(ExecState* exec, JSObject*, const ArgL
ExceptionCode ec = 0;
RefPtr<WebKitCSSMatrix> matrix = WebKitCSSMatrix::create(s, ec);
setDOMException(exec, ec);
- return CREATE_DOM_OBJECT_WRAPPER(exec, WebKitCSSMatrix, matrix.get());
+ return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), WebKitCSSMatrix, matrix.get());
}
ConstructType JSWebKitCSSMatrixConstructor::getConstructData(ConstructData& constructData)
diff --git a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h
index d0e0bd1..65b9050 100644
--- a/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h
+++ b/WebCore/bindings/js/JSWebKitCSSMatrixConstructor.h
@@ -31,9 +31,9 @@
namespace WebCore {
-class JSWebKitCSSMatrixConstructor : public DOMObject {
+class JSWebKitCSSMatrixConstructor : public DOMConstructorObject {
public:
- JSWebKitCSSMatrixConstructor(JSC::ExecState*);
+ JSWebKitCSSMatrixConstructor(JSC::ExecState*, JSDOMGlobalObject*);
static const JSC::ClassInfo s_info;
private:
diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.cpp b/WebCore/bindings/js/JSWebKitPointConstructor.cpp
index c7d4e36..27cc1db 100644
--- a/WebCore/bindings/js/JSWebKitPointConstructor.cpp
+++ b/WebCore/bindings/js/JSWebKitPointConstructor.cpp
@@ -36,15 +36,17 @@ using namespace JSC;
const ClassInfo JSWebKitPointConstructor::s_info = { "WebKitPointConstructor", 0, 0, 0 };
-JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec)
- : DOMObject(JSWebKitPointConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+JSWebKitPointConstructor::JSWebKitPointConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(JSWebKitPointConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSWebKitPointPrototype::self(exec, globalObject), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly|DontDelete|DontEnum);
}
-static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList& args)
+static JSObject* constructWebKitPoint(ExecState* exec, JSObject* constructor, const ArgList& args)
{
+ JSWebKitPointConstructor* jsConstructor = static_cast<JSWebKitPointConstructor*>(constructor);
+
float x = 0;
float y = 0;
if (args.size() >= 2) {
@@ -55,7 +57,7 @@ static JSObject* constructWebKitPoint(ExecState* exec, JSObject*, const ArgList&
if (isnan(y))
y = 0;
}
- return asObject(toJS(exec, WebKitPoint::create(x, y)));
+ return asObject(toJS(exec, jsConstructor->globalObject(), WebKitPoint::create(x, y)));
}
JSC::ConstructType JSWebKitPointConstructor::getConstructData(JSC::ConstructData& constructData)
diff --git a/WebCore/bindings/js/JSWebKitPointConstructor.h b/WebCore/bindings/js/JSWebKitPointConstructor.h
index a5bb5c1..44c253d 100644
--- a/WebCore/bindings/js/JSWebKitPointConstructor.h
+++ b/WebCore/bindings/js/JSWebKitPointConstructor.h
@@ -31,9 +31,9 @@
namespace WebCore {
-class JSWebKitPointConstructor : public DOMObject {
+class JSWebKitPointConstructor : public DOMConstructorObject {
public:
- JSWebKitPointConstructor(JSC::ExecState*);
+ JSWebKitPointConstructor(JSC::ExecState*, JSDOMGlobalObject*);
static const JSC::ClassInfo s_info;
private:
diff --git a/WebCore/bindings/js/JSWebSocketConstructor.cpp b/WebCore/bindings/js/JSWebSocketConstructor.cpp
new file mode 100644
index 0000000..ca2e104
--- /dev/null
+++ b/WebCore/bindings/js/JSWebSocketConstructor.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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(WEB_SOCKETS)
+
+#include "JSWebSocketConstructor.h"
+
+#include "JSWebSocket.h"
+#include "ScriptExecutionContext.h"
+#include "WebSocket.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+ASSERT_CLASS_FITS_IN_CELL(JSWebSocketConstructor);
+
+const ClassInfo JSWebSocketConstructor::s_info = { "WebSocketConstructor", 0, 0, 0 };
+
+JSWebSocketConstructor::JSWebSocketConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(JSWebSocketConstructor::createStructure(globalObject->objectPrototype()), globalObject)
+{
+ putDirect(exec->propertyNames().prototype, JSWebSocketPrototype::self(exec, globalObject), None);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
+}
+
+static JSObject* constructWebSocket(ExecState* exec, JSObject* constructor, const ArgList& args)
+{
+ JSWebSocketConstructor* jsConstructor = static_cast<JSWebSocketConstructor*>(constructor);
+ ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
+ if (!context)
+ return throwError(exec, ReferenceError, "WebSocket constructor associated document is unavailable");
+
+ if (args.size() == 0)
+ return throwError(exec, SyntaxError, "Not enough arguments");
+
+ const String& urlString = args.at(0).toString(exec);
+ if (exec->hadException())
+ return throwError(exec, SyntaxError, "wrong URL");
+ const KURL& url = context->completeURL(urlString);
+ RefPtr<WebSocket> webSocket = WebSocket::create(context);
+ ExceptionCode ec = 0;
+ if (args.size() < 2)
+ webSocket->connect(url, ec);
+ else {
+ const String& protocol = args.at(1).toString(exec);
+ if (exec->hadException())
+ return 0;
+ webSocket->connect(url, protocol, ec);
+ }
+ setDOMException(exec, ec);
+ return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), WebSocket, webSocket.get());
+}
+
+ConstructType JSWebSocketConstructor::getConstructData(ConstructData& constructData)
+{
+ constructData.native.function = constructWebSocket;
+ return ConstructTypeHost;
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/js/JSWebSocketConstructor.h b/WebCore/bindings/js/JSWebSocketConstructor.h
new file mode 100644
index 0000000..069647a
--- /dev/null
+++ b/WebCore/bindings/js/JSWebSocketConstructor.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 JSWebSocketConstructor_h
+#define JSWebSocketConstructor_h
+
+#include "JSDOMBinding.h"
+
+namespace WebCore {
+
+class JSWebSocketConstructor : public DOMConstructorObject {
+ public:
+ JSWebSocketConstructor(JSC::ExecState*, JSDOMGlobalObject*);
+ static const JSC::ClassInfo s_info;
+
+ private:
+ virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
+ virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
+};
+
+} // namespace WebCore
+
+#endif // JSWebSocketConstructor_h
diff --git a/WebCore/bindings/js/JSWebSocketCustom.cpp b/WebCore/bindings/js/JSWebSocketCustom.cpp
new file mode 100644
index 0000000..3aa4b8b
--- /dev/null
+++ b/WebCore/bindings/js/JSWebSocketCustom.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Apple, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_SOCKETS)
+
+#include "JSWebSocket.h"
+
+#include "KURL.h"
+#include "WebSocket.h"
+#include "NotImplemented.h"
+
+using namespace JSC;
+
+namespace WebCore {
+
+void JSWebSocket::markChildren(MarkStack& markStack)
+{
+ Base::markChildren(markStack);
+ if (m_impl->readyState() != WebSocket::CLOSED)
+ markIfNotNull(markStack, m_impl->onmessage());
+ // FIXME: mark if EventListeners is registered.
+}
+
+// Custom functions
+JSValue JSWebSocket::send(ExecState* exec, const ArgList& args)
+{
+ if (args.size() < 1)
+ return throwError(exec, SyntaxError, "Not enough arguments");
+
+ const String& msg = args.at(0).toString(exec);
+ if (exec->hadException())
+ return throwError(exec, SyntaxError, "bad message data.");
+ ExceptionCode ec = 0;
+ JSValue ret = jsBoolean(impl()->send(msg, ec));
+ setDOMException(exec, ec);
+ return ret;
+}
+
+// FIXME: implement addEventListener/removeEventListener.
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/bindings/js/JSWorkerConstructor.cpp b/WebCore/bindings/js/JSWorkerConstructor.cpp
index 8ea6718..9943cfb 100644
--- a/WebCore/bindings/js/JSWorkerConstructor.cpp
+++ b/WebCore/bindings/js/JSWorkerConstructor.cpp
@@ -41,15 +41,17 @@ namespace WebCore {
const ClassInfo JSWorkerConstructor::s_info = { "WorkerConstructor", 0, 0, 0 };
-JSWorkerConstructor::JSWorkerConstructor(ExecState* exec)
- : DOMObject(JSWorkerConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+JSWorkerConstructor::JSWorkerConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(JSWorkerConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSWorkerPrototype::self(exec, globalObject), None);
putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
-static JSObject* constructWorker(ExecState* exec, JSObject*, const ArgList& args)
+static JSObject* constructWorker(ExecState* exec, JSObject* constructor, const ArgList& args)
{
+ JSWorkerConstructor* jsConstructor = static_cast<JSWorkerConstructor*>(constructor);
+
if (args.size() == 0)
return throwError(exec, SyntaxError, "Not enough arguments");
@@ -57,13 +59,17 @@ static JSObject* constructWorker(ExecState* exec, JSObject*, const ArgList& args
if (exec->hadException())
return 0;
+ // See section 4.8.2 step 14 of WebWorkers for why this is the lexicalGlobalObject.
DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
-
+
ExceptionCode ec = 0;
RefPtr<Worker> worker = Worker::create(scriptURL, window->document(), ec);
- setDOMException(exec, ec);
+ if (ec) {
+ setDOMException(exec, ec);
+ return 0;
+ }
- return asObject(toJS(exec, worker.release()));
+ return asObject(toJS(exec, jsConstructor->globalObject(), worker.release()));
}
ConstructType JSWorkerConstructor::getConstructData(ConstructData& constructData)
diff --git a/WebCore/bindings/js/JSWorkerConstructor.h b/WebCore/bindings/js/JSWorkerConstructor.h
index d1df7eb..c845fa6 100644
--- a/WebCore/bindings/js/JSWorkerConstructor.h
+++ b/WebCore/bindings/js/JSWorkerConstructor.h
@@ -32,9 +32,9 @@
namespace WebCore {
- class JSWorkerConstructor : public DOMObject {
+ class JSWorkerConstructor : public DOMConstructorObject {
public:
- JSWorkerConstructor(JSC::ExecState*);
+ JSWorkerConstructor(JSC::ExecState*, JSDOMGlobalObject*);
static const JSC::ClassInfo s_info;
diff --git a/WebCore/bindings/js/JSWorkerContextBase.cpp b/WebCore/bindings/js/JSWorkerContextBase.cpp
index c71f45b..1e4df42 100644
--- a/WebCore/bindings/js/JSWorkerContextBase.cpp
+++ b/WebCore/bindings/js/JSWorkerContextBase.cpp
@@ -31,6 +31,8 @@
#include "JSWorkerContextBase.h"
+#include "JSDedicatedWorkerContext.h"
+#include "JSSharedWorkerContext.h"
#include "JSWorkerContext.h"
#include "WorkerContext.h"
@@ -57,6 +59,11 @@ ScriptExecutionContext* JSWorkerContextBase::scriptExecutionContext() const
return m_impl.get();
}
+JSValue toJS(ExecState* exec, JSDOMGlobalObject*, WorkerContext* workerContext)
+{
+ return toJS(exec, workerContext);
+}
+
JSValue toJS(ExecState*, WorkerContext* workerContext)
{
if (!workerContext)
@@ -67,6 +74,38 @@ JSValue toJS(ExecState*, WorkerContext* workerContext)
return script->workerContextWrapper();
}
+JSDedicatedWorkerContext* toJSDedicatedWorkerContext(JSValue value)
+{
+ if (!value.isObject())
+ return 0;
+ const ClassInfo* classInfo = asObject(value)->classInfo();
+ if (classInfo == &JSDedicatedWorkerContext::s_info)
+ return static_cast<JSDedicatedWorkerContext*>(asObject(value));
+ return 0;
+}
+
+#if ENABLE(SHARED_WORKERS)
+JSSharedWorkerContext* toJSSharedWorkerContext(JSValue value)
+{
+ if (!value.isObject())
+ return 0;
+ const ClassInfo* classInfo = asObject(value)->classInfo();
+ if (classInfo == &JSSharedWorkerContext::s_info)
+ return static_cast<JSSharedWorkerContext*>(asObject(value));
+ return 0;
+}
+#endif
+
+JSWorkerContext* toJSWorkerContext(JSValue value)
+{
+ JSWorkerContext* context = toJSDedicatedWorkerContext(value);
+#if ENABLE(SHARED_WORKERS)
+ if (!context)
+ context = toJSSharedWorkerContext(value);
+#endif
+ return context;
+}
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSWorkerContextBase.h b/WebCore/bindings/js/JSWorkerContextBase.h
index dcbc5c3..a9a6e63 100644
--- a/WebCore/bindings/js/JSWorkerContextBase.h
+++ b/WebCore/bindings/js/JSWorkerContextBase.h
@@ -33,6 +33,9 @@
namespace WebCore {
+ class JSDedicatedWorkerContext;
+ class JSSharedWorkerContext;
+ class JSWorkerContext;
class WorkerContext;
class JSWorkerContextBase : public JSDOMGlobalObject {
@@ -52,8 +55,17 @@ namespace WebCore {
};
// Returns a JSWorkerContext or jsNull()
+ // Always ignores the execState and passed globalObject, WorkerContext is itself a globalObject and will always use its own prototype chain.
+ JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, WorkerContext*);
JSC::JSValue toJS(JSC::ExecState*, WorkerContext*);
+ JSDedicatedWorkerContext* toJSDedicatedWorkerContext(JSC::JSValue);
+ JSWorkerContext* toJSWorkerContext(JSC::JSValue);
+
+#if ENABLE(SHARED_WORKERS)
+ JSSharedWorkerContext* toJSSharedWorkerContext(JSC::JSValue);
+#endif
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp
index 6824914..919c81f 100644
--- a/WebCore/bindings/js/JSWorkerContextCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp
@@ -30,7 +30,10 @@
#include "JSWorkerContext.h"
#include "JSDOMBinding.h"
+#include "JSDOMGlobalObject.h"
#include "JSEventListener.h"
+#include "JSMessageChannelConstructor.h"
+#include "JSMessagePort.h"
#include "JSWorkerLocation.h"
#include "JSWorkerNavigator.h"
#include "JSXMLHttpRequestConstructor.h"
@@ -44,29 +47,29 @@ using namespace JSC;
namespace WebCore {
-void JSWorkerContext::mark()
+void JSWorkerContext::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
JSGlobalData& globalData = *this->globalData();
- markActiveObjectsForContext(globalData, scriptExecutionContext());
+ markActiveObjectsForContext(markStack, globalData, scriptExecutionContext());
- markDOMObjectWrapper(globalData, impl()->optionalLocation());
- markDOMObjectWrapper(globalData, impl()->optionalNavigator());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalLocation());
+ markDOMObjectWrapper(markStack, globalData, impl()->optionalNavigator());
- markIfNotNull(impl()->onmessage());
+ markIfNotNull(markStack, impl()->onerror());
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)
- (*vecIter)->markJSFunction();
+ (*vecIter)->markJSFunction(markStack);
}
}
-bool JSWorkerContext::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool JSWorkerContext::getOwnPropertySlotDelegate(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
// Look for overrides before looking at any of our own properties.
if (JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot))
@@ -138,6 +141,14 @@ JSValue JSWorkerContext::setInterval(ExecState* exec, const ArgList& args)
return jsNumber(exec, impl()->setInterval(action, delay));
}
+
+#if ENABLE(CHANNEL_MESSAGING)
+JSValue JSWorkerContext::messageChannel(ExecState* exec) const
+{
+ return getDOMConstructor<JSMessageChannelConstructor>(exec, this);
+}
+#endif
+
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/js/JSWorkerCustom.cpp b/WebCore/bindings/js/JSWorkerCustom.cpp
index f4d3033..f5c394b 100644
--- a/WebCore/bindings/js/JSWorkerCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerCustom.cpp
@@ -30,51 +30,17 @@
#include "JSWorker.h"
#include "JSDOMGlobalObject.h"
-#include "JSEventListener.h"
#include "Worker.h"
using namespace JSC;
namespace WebCore {
-void JSWorker::mark()
+void JSWorker::markChildren(MarkStack& markStack)
{
- DOMObject::mark();
+ Base::markChildren(markStack);
- 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)
- (*vecIter)->markJSFunction();
- }
-}
-
-JSValue JSWorker::addEventListener(ExecState* exec, const ArgList& args)
-{
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
- if (!globalObject)
- return jsUndefined();
- RefPtr<JSEventListener> listener = globalObject->findOrCreateJSEventListener(args.at(1));
- if (!listener)
- return jsUndefined();
- impl()->addEventListener(args.at(0).toString(exec), listener.release(), args.at(2).toBoolean(exec));
- return jsUndefined();
-}
-
-JSValue JSWorker::removeEventListener(ExecState* exec, const ArgList& args)
-{
- JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(impl()->scriptExecutionContext());
- if (!globalObject)
- return jsUndefined();
- JSEventListener* listener = globalObject->findJSEventListener(args.at(1));
- if (!listener)
- return jsUndefined();
- impl()->removeEventListener(args.at(0).toString(exec), listener, args.at(2).toBoolean(exec));
- return jsUndefined();
+ markIfNotNull(markStack, static_cast<Worker*>(impl())->onmessage());
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
index 65cdfc2..a644c9e 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
@@ -33,25 +33,20 @@ ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor);
const ClassInfo JSXMLHttpRequestConstructor::s_info = { "XMLHttpRequestConstructor", 0, 0, 0 };
JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
- : DOMObject(JSXMLHttpRequestConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
- , m_globalObject(globalObject)
+ : DOMConstructorObject(JSXMLHttpRequestConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec, exec->lexicalGlobalObject()), None);
-}
-
-ScriptExecutionContext* JSXMLHttpRequestConstructor::scriptExecutionContext() const
-{
- return m_globalObject->scriptExecutionContext();
+ putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec, globalObject), None);
}
static JSObject* constructXMLHttpRequest(ExecState* exec, JSObject* constructor, const ArgList&)
{
- ScriptExecutionContext* context = static_cast<JSXMLHttpRequestConstructor*>(constructor)->scriptExecutionContext();
+ JSXMLHttpRequestConstructor* jsConstructor = static_cast<JSXMLHttpRequestConstructor*>(constructor);
+ ScriptExecutionContext* context = jsConstructor->scriptExecutionContext();
if (!context)
return throwError(exec, ReferenceError, "XMLHttpRequest constructor associated document is unavailable");
RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
- return CREATE_DOM_OBJECT_WRAPPER(exec, XMLHttpRequest, xmlHttpRequest.get());
+ return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), XMLHttpRequest, xmlHttpRequest.get());
}
ConstructType JSXMLHttpRequestConstructor::getConstructData(ConstructData& constructData)
@@ -60,11 +55,4 @@ ConstructType JSXMLHttpRequestConstructor::getConstructData(ConstructData& const
return ConstructTypeHost;
}
-void JSXMLHttpRequestConstructor::mark()
-{
- DOMObject::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 978a9f0..2cc4fcf 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestConstructor.h
+++ b/WebCore/bindings/js/JSXMLHttpRequestConstructor.h
@@ -24,18 +24,13 @@
namespace WebCore {
-class JSXMLHttpRequestConstructor : public DOMObject {
+class JSXMLHttpRequestConstructor : public DOMConstructorObject {
public:
JSXMLHttpRequestConstructor(JSC::ExecState*, JSDOMGlobalObject*);
- ScriptExecutionContext* scriptExecutionContext() const;
static const JSC::ClassInfo s_info;
-
- virtual void mark();
private:
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
-
- JSDOMGlobalObject* m_globalObject;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
index 06a5817..a591fae 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
@@ -49,29 +49,29 @@ using namespace JSC;
namespace WebCore {
-void JSXMLHttpRequest::mark()
+void JSXMLHttpRequest::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
if (XMLHttpRequestUpload* upload = m_impl->optionalUpload()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), upload);
- if (wrapper && !wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
- markIfNotNull(m_impl->onreadystatechange());
- markIfNotNull(m_impl->onabort());
- markIfNotNull(m_impl->onerror());
- markIfNotNull(m_impl->onload());
- markIfNotNull(m_impl->onloadstart());
- markIfNotNull(m_impl->onprogress());
+ markIfNotNull(markStack, m_impl->onreadystatechange());
+ markIfNotNull(markStack, m_impl->onabort());
+ markIfNotNull(markStack, m_impl->onerror());
+ markIfNotNull(markStack, m_impl->onload());
+ markIfNotNull(markStack, m_impl->onloadstart());
+ markIfNotNull(markStack, 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)
- (*vecIter)->markJSFunction();
+ (*vecIter)->markJSFunction(markStack);
}
}
diff --git a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
index 597010c..cb6d5f2 100644
--- a/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/js/JSXMLHttpRequestUploadCustom.cpp
@@ -41,28 +41,28 @@ using namespace JSC;
namespace WebCore {
-void JSXMLHttpRequestUpload::mark()
+void JSXMLHttpRequestUpload::markChildren(MarkStack& markStack)
{
- Base::mark();
+ Base::markChildren(markStack);
if (XMLHttpRequest* xmlHttpRequest = m_impl->associatedXMLHttpRequest()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(*Heap::heap(this)->globalData(), xmlHttpRequest);
- if (wrapper && !wrapper->marked())
- wrapper->mark();
+ if (wrapper)
+ markStack.append(wrapper);
}
- markIfNotNull(m_impl->onabort());
- markIfNotNull(m_impl->onerror());
- markIfNotNull(m_impl->onload());
- markIfNotNull(m_impl->onloadstart());
- markIfNotNull(m_impl->onprogress());
+ markIfNotNull(markStack, m_impl->onabort());
+ markIfNotNull(markStack, m_impl->onerror());
+ markIfNotNull(markStack, m_impl->onload());
+ markIfNotNull(markStack, m_impl->onloadstart());
+ markIfNotNull(markStack, 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)
- (*vecIter)->markJSFunction();
+ (*vecIter)->markJSFunction(markStack);
}
}
diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
index 807b017..07fec72 100644
--- a/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
+++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
@@ -41,15 +41,16 @@ ASSERT_CLASS_FITS_IN_CELL(JSXSLTProcessorConstructor);
const ClassInfo JSXSLTProcessorConstructor::s_info = { "XSLTProcessorConsructor", 0, 0, 0 };
-JSXSLTProcessorConstructor::JSXSLTProcessorConstructor(ExecState* exec)
- : DOMObject(JSXSLTProcessorConstructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+JSXSLTProcessorConstructor::JSXSLTProcessorConstructor(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(JSXSLTProcessorConstructor::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, JSXSLTProcessorPrototype::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, JSXSLTProcessorPrototype::self(exec, globalObject), None);
}
-static JSObject* constructXSLTProcessor(ExecState* exec, JSObject*, const ArgList&)
+static JSObject* constructXSLTProcessor(ExecState* exec, JSObject* constructor, const ArgList&)
{
- return CREATE_DOM_OBJECT_WRAPPER(exec, XSLTProcessor, XSLTProcessor::create().get());
+ JSXSLTProcessorConstructor* jsConstructor = static_cast<JSXSLTProcessorConstructor*>(constructor);
+ return CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), XSLTProcessor, XSLTProcessor::create().get());
}
ConstructType JSXSLTProcessorConstructor::getConstructData(ConstructData& constructData)
diff --git a/WebCore/bindings/js/JSXSLTProcessorConstructor.h b/WebCore/bindings/js/JSXSLTProcessorConstructor.h
index 64ef944..96fa607 100644
--- a/WebCore/bindings/js/JSXSLTProcessorConstructor.h
+++ b/WebCore/bindings/js/JSXSLTProcessorConstructor.h
@@ -32,9 +32,9 @@
namespace WebCore {
- class JSXSLTProcessorConstructor : public DOMObject {
+ class JSXSLTProcessorConstructor : public DOMConstructorObject {
public:
- JSXSLTProcessorConstructor(JSC::ExecState*);
+ JSXSLTProcessorConstructor(JSC::ExecState*, JSDOMGlobalObject*);
static const JSC::ClassInfo s_info;
private:
diff --git a/WebCore/bindings/js/ScheduledAction.cpp b/WebCore/bindings/js/ScheduledAction.cpp
index 91bece7..9e64bce 100644
--- a/WebCore/bindings/js/ScheduledAction.cpp
+++ b/WebCore/bindings/js/ScheduledAction.cpp
@@ -87,7 +87,7 @@ void ScheduledAction::execute(ScriptExecutionContext* context)
void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSValue thisValue)
{
ASSERT(m_function);
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
CallData callData;
CallType callType = m_function.get().getCallData(callData);
diff --git a/WebCore/bindings/js/ScriptArray.cpp b/WebCore/bindings/js/ScriptArray.cpp
new file mode 100644
index 0000000..2c4075a
--- /dev/null
+++ b/WebCore/bindings/js/ScriptArray.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "ScriptArray.h"
+
+#include <runtime/JSLock.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+ScriptArray::ScriptArray(ScriptState* scriptState, JSArray* object)
+ : ScriptObject(scriptState, object)
+{
+}
+
+static bool handleException(ScriptState* scriptState)
+{
+ if (!scriptState->hadException())
+ return true;
+
+ reportException(scriptState, scriptState->exception());
+ return false;
+}
+
+bool ScriptArray::set(unsigned index, const ScriptObject& value)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ jsArray()->put(m_scriptState, index, value.jsObject());
+ return handleException(m_scriptState);
+}
+
+bool ScriptArray::set(unsigned index, const String& value)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ jsArray()->put(m_scriptState, index, jsString(m_scriptState, value));
+ return handleException(m_scriptState);
+}
+
+bool ScriptArray::set(unsigned index, double value)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ jsArray()->put(m_scriptState, index, jsNumber(m_scriptState, value));
+ return handleException(m_scriptState);
+}
+
+bool ScriptArray::set(unsigned index, long long value)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ jsArray()->put(m_scriptState, index, jsNumber(m_scriptState, value));
+ return handleException(m_scriptState);
+}
+
+bool ScriptArray::set(unsigned index, int value)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ jsArray()->put(m_scriptState, index, jsNumber(m_scriptState, value));
+ return handleException(m_scriptState);
+}
+
+bool ScriptArray::set(unsigned index, bool value)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ jsArray()->put(m_scriptState, index, jsBoolean(value));
+ return handleException(m_scriptState);
+}
+
+unsigned ScriptArray::length()
+{
+ JSLock lock(SilenceAssertionsOnly);
+ return jsArray()->length();
+}
+
+ScriptArray ScriptArray::createNew(ScriptState* scriptState)
+{
+ JSLock lock(SilenceAssertionsOnly);
+ return ScriptArray(scriptState, constructEmptyArray(scriptState));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptArray.h b/WebCore/bindings/js/ScriptArray.h
new file mode 100644
index 0000000..9240368
--- /dev/null
+++ b/WebCore/bindings/js/ScriptArray.h
@@ -0,0 +1,59 @@
+/*
+ * 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 ScriptArray_h
+#define ScriptArray_h
+
+#include "ScriptObject.h"
+#include "ScriptState.h"
+
+#include <runtime/JSArray.h>
+
+namespace WebCore {
+
+ class ScriptArray : public ScriptObject {
+ public:
+ ScriptArray(ScriptState*, JSC::JSArray*);
+ ScriptArray() {}
+ JSC::JSArray* jsArray() const { return asArray(jsValue()); }
+
+ bool set(unsigned index, const ScriptObject&);
+ bool set(unsigned index, const String&);
+ bool set(unsigned index, double);
+ bool set(unsigned index, long long);
+ bool set(unsigned index, int);
+ bool set(unsigned index, bool);
+ unsigned length();
+
+ static ScriptArray createNew(ScriptState*);
+ };
+}
+
+#endif // ScriptArray_h
diff --git a/WebCore/bindings/js/ScriptCachedFrameData.cpp b/WebCore/bindings/js/ScriptCachedFrameData.cpp
index 213c708..8852611 100644
--- a/WebCore/bindings/js/ScriptCachedFrameData.cpp
+++ b/WebCore/bindings/js/ScriptCachedFrameData.cpp
@@ -45,7 +45,7 @@ namespace WebCore {
ScriptCachedFrameData::ScriptCachedFrameData(Frame* frame)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
ScriptController* scriptController = frame->script();
if (scriptController->haveWindowShell()) {
@@ -67,7 +67,7 @@ void ScriptCachedFrameData::restore(Frame* frame)
{
Page* page = frame->page();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
ScriptController* scriptController = frame->script();
if (scriptController->haveWindowShell()) {
@@ -84,7 +84,7 @@ void ScriptCachedFrameData::restore(Frame* frame)
void ScriptCachedFrameData::clear()
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
if (!m_window) {
m_window = 0;
diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp
index 2f676c0..8908155 100644
--- a/WebCore/bindings/js/ScriptController.cpp
+++ b/WebCore/bindings/js/ScriptController.cpp
@@ -33,6 +33,7 @@
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "Settings.h"
+#include "XSSAuditor.h"
#include "npruntime_impl.h"
#include "runtime_root.h"
#include <debugger/Debugger.h>
@@ -55,6 +56,7 @@ ScriptController::ScriptController(Frame* frame)
#if PLATFORM(MAC)
, m_windowScriptObject(0)
#endif
+ , m_XSSAuditor(new XSSAuditor(frame))
{
#if PLATFORM(MAC) && ENABLE(MAC_JAVA_BRIDGE)
static bool initializedJavaJSBindings;
@@ -79,10 +81,21 @@ ScriptController::~ScriptController()
ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
+ const SourceCode& jsSourceCode = sourceCode.jsSourceCode();
+ String sourceURL = jsSourceCode.provider()->url();
+
+ if (sourceURL.isNull() && !m_XSSAuditor->canEvaluateJavaScriptURL(sourceCode.source())) {
+ // This JavaScript URL is not safe to be evaluated.
+ return JSValue();
+ }
+
+ if (!sourceURL.isNull() && !m_XSSAuditor->canEvaluate(sourceCode.source())) {
+ // This script is not safe to be evaluated.
+ return JSValue();
+ }
+
// evaluate code. Returns the JS return value or 0
// if there was none, an error occured or the type couldn't be converted.
-
- const SourceCode& jsSourceCode = sourceCode.jsSourceCode();
initScriptIfNeeded();
// inlineCode is true for <a href="javascript:doSomething()">
@@ -91,10 +104,9 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
// See smart window.open policy for where this is used.
ExecState* exec = m_windowShell->window()->globalExec();
const String* savedSourceURL = m_sourceURL;
- String sourceURL = jsSourceCode.provider()->url();
m_sourceURL = &sourceURL;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
RefPtr<Frame> protect = m_frame;
@@ -123,7 +135,7 @@ void ScriptController::clearWindowShell()
if (!m_windowShell)
return;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
// Clear the debugger from the current window before setting the new window.
attachDebugger(0);
@@ -145,7 +157,7 @@ void ScriptController::initScript()
if (m_windowShell)
return;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
m_windowShell = new JSDOMWindowShell(m_frame->domWindow());
m_windowShell->window()->updateDocument();
@@ -242,7 +254,7 @@ void ScriptController::updateDocument()
if (!m_frame->document())
return;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
if (m_windowShell)
m_windowShell->window()->updateDocument();
}
@@ -258,7 +270,7 @@ Bindings::RootObject* ScriptController::bindingRootObject()
return 0;
if (!m_bindingRootObject) {
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
m_bindingRootObject = Bindings::RootObject::create(0, globalObject());
}
return m_bindingRootObject.get();
@@ -284,7 +296,7 @@ NPObject* ScriptController::windowScriptNPObject()
if (isEnabled()) {
// JavaScript is enabled, so there is a JavaScript window object.
// Return an NPObject bound to the window object.
- JSC::JSLock lock(false);
+ JSC::JSLock lock(SilenceAssertionsOnly);
JSObject* win = windowShell()->window();
ASSERT(win);
Bindings::RootObject* root = bindingRootObject();
@@ -318,9 +330,9 @@ JSObject* ScriptController::jsObjectForPluginElement(HTMLPlugInElement* plugin)
return 0;
// Create a JSObject bound to this element
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
ExecState* exec = globalObject()->globalExec();
- JSValue jsElementValue = toJS(exec, plugin);
+ JSValue jsElementValue = toJS(exec, globalObject(), plugin);
if (!jsElementValue || !jsElementValue.isObject())
return 0;
@@ -352,7 +364,7 @@ void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
void ScriptController::clearScriptObjects()
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
RootObjectMap::const_iterator end = m_rootObjects.end();
for (RootObjectMap::const_iterator it = m_rootObjects.begin(); it != end; ++it)
diff --git a/WebCore/bindings/js/ScriptController.h b/WebCore/bindings/js/ScriptController.h
index f700cd9..4528495 100644
--- a/WebCore/bindings/js/ScriptController.h
+++ b/WebCore/bindings/js/ScriptController.h
@@ -58,6 +58,7 @@ class ScriptSourceCode;
class ScriptValue;
class String;
class Widget;
+class XSSAuditor;
typedef HashMap<void*, RefPtr<JSC::Bindings::RootObject> > RootObjectMap;
@@ -132,6 +133,8 @@ public:
NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*);
NPObject* windowScriptNPObject();
#endif
+
+ XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); }
private:
void initScriptIfNeeded()
@@ -164,6 +167,9 @@ private:
#if PLATFORM(MAC)
RetainPtr<WebScriptObject> m_windowScriptObject;
#endif
+
+ // The XSSAuditor associated with this ScriptController.
+ OwnPtr<XSSAuditor> m_XSSAuditor;
};
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptControllerHaiku.cpp b/WebCore/bindings/js/ScriptControllerHaiku.cpp
new file mode 100644
index 0000000..b573b97
--- /dev/null
+++ b/WebCore/bindings/js/ScriptControllerHaiku.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 "ScriptController.h"
+
+#include "PluginView.h"
+#include "runtime_root.h"
+#include "runtime.h"
+
+
+namespace WebCore {
+
+PassRefPtr<JSC::Bindings::Instance> ScriptController::createScriptInstanceForWidget(Widget* widget)
+{
+ if (!widget->isPluginView())
+ return 0;
+
+ return static_cast<PluginView*>(widget)->bindingInstance();
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/bindings/js/ScriptControllerMac.mm b/WebCore/bindings/js/ScriptControllerMac.mm
index 502a504..e6a654f 100644
--- a/WebCore/bindings/js/ScriptControllerMac.mm
+++ b/WebCore/bindings/js/ScriptControllerMac.mm
@@ -112,7 +112,7 @@ WebScriptObject* ScriptController::windowScriptObject()
return 0;
if (!m_windowScriptObject) {
- JSC::JSLock lock(false);
+ JSC::JSLock lock(JSC::SilenceAssertionsOnly);
JSC::Bindings::RootObject* root = bindingRootObject();
m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(windowShell()) originRootObject:root rootObject:root];
}
diff --git a/WebCore/bindings/js/ScriptEventListener.cpp b/WebCore/bindings/js/ScriptEventListener.cpp
index 0ce7bca..878c535 100644
--- a/WebCore/bindings/js/ScriptEventListener.cpp
+++ b/WebCore/bindings/js/ScriptEventListener.cpp
@@ -35,6 +35,7 @@
#include "Document.h"
#include "JSNode.h"
#include "Frame.h"
+#include "XSSAuditor.h"
#include <runtime/JSLock.h>
@@ -61,12 +62,18 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribu
if (!scriptController->isEnabled())
return 0;
+ if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+ // This script is not safe to execute.
+ return 0;
+ }
+
JSDOMWindow* globalObject = scriptController->globalObject();
// Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating.
{
- JSLock lock(false);
- toJS(globalObject->globalExec(), node);
+ JSLock lock(SilenceAssertionsOnly);
+ // FIXME: Should pass the global object associated with the node
+ toJS(globalObject->globalExec(), globalObject, node);
}
return JSLazyEventListener::create(attr->localName().string(), eventParameterName(node->isSVGElement()), attr->value(), globalObject, node, scriptController->eventHandlerLineNumber());
@@ -80,6 +87,11 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attri
ScriptController* scriptController = frame->script();
if (!scriptController->isEnabled())
return 0;
+
+ if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+ // This script is not safe to execute.
+ return 0;
+ }
// 'globalObject' is the JavaScript wrapper that will mark the event listener we're creating.
JSDOMWindow* globalObject = scriptController->globalObject();
diff --git a/WebCore/bindings/js/ScriptFunctionCall.cpp b/WebCore/bindings/js/ScriptFunctionCall.cpp
index 1122931..46e80ac 100644
--- a/WebCore/bindings/js/ScriptFunctionCall.cpp
+++ b/WebCore/bindings/js/ScriptFunctionCall.cpp
@@ -66,7 +66,7 @@ void ScriptFunctionCall::appendArgument(const ScriptValue& argument)
void ScriptFunctionCall::appendArgument(const String& argument)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
m_arguments.append(jsString(m_exec, argument));
}
@@ -82,19 +82,19 @@ void ScriptFunctionCall::appendArgument(JSC::JSValue argument)
void ScriptFunctionCall::appendArgument(long long argument)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
m_arguments.append(jsNumber(m_exec, argument));
}
void ScriptFunctionCall::appendArgument(unsigned int argument)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
m_arguments.append(jsNumber(m_exec, argument));
}
void ScriptFunctionCall::appendArgument(int argument)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
m_arguments.append(jsNumber(m_exec, argument));
}
@@ -107,7 +107,7 @@ ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
{
JSObject* thisObject = m_thisObject.jsObject();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSValue function = thisObject->get(m_exec, Identifier(m_exec, m_name));
if (m_exec->hadException()) {
@@ -145,7 +145,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept
{
JSObject* thisObject = m_thisObject.jsObject();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, m_name)));
if (m_exec->hadException()) {
@@ -170,7 +170,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept
return ScriptObject();
}
- return ScriptObject(asObject(result));
+ return ScriptObject(m_exec, asObject(result));
}
} // namespace WebCore
diff --git a/WebCore/bindings/js/ScriptObject.cpp b/WebCore/bindings/js/ScriptObject.cpp
index 44337bd..c5fa399 100644
--- a/WebCore/bindings/js/ScriptObject.cpp
+++ b/WebCore/bindings/js/ScriptObject.cpp
@@ -32,10 +32,14 @@
#include "ScriptObject.h"
#include "JSDOMBinding.h"
+#ifdef MANUAL_MERGE_REQUIRED
#if ENABLE(JAVASCRIPT_DEBUGGER)
#include "JSInspectorController.h"
#endif
+#else // MANUAL_MERGE_REQUIRED
+#include "JSInspectorBackend.h"
+#endif // MANUAL_MERGE_REQUIRED
#include <runtime/JSLock.h>
@@ -43,8 +47,9 @@ using namespace JSC;
namespace WebCore {
-ScriptObject::ScriptObject(JSObject* object)
+ScriptObject::ScriptObject(ScriptState* scriptState, JSObject* object)
: ScriptValue(object)
+ , m_scriptState(scriptState)
{
}
@@ -57,87 +62,92 @@ static bool handleException(ScriptState* scriptState)
return false;
}
-bool ScriptObject::set(ScriptState* scriptState, const String& name, const String& value)
+bool ScriptObject::set(const String& name, const String& value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), jsString(scriptState, value), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsString(m_scriptState, value), slot);
+ return handleException(m_scriptState);
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value)
+bool ScriptObject::set(const char* name, const ScriptObject& value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), value.jsObject(), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), value.jsObject(), slot);
+ return handleException(m_scriptState);
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, const String& value)
+bool ScriptObject::set(const char* name, const String& value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), jsString(scriptState, value), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsString(m_scriptState, value), slot);
+ return handleException(m_scriptState);
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, double value)
+bool ScriptObject::set(const char* name, double value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot);
+ return handleException(m_scriptState);
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, long long value)
+bool ScriptObject::set(const char* name, long long value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot);
+ return handleException(m_scriptState);
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, int value)
+bool ScriptObject::set(const char* name, int value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), jsNumber(scriptState, value), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsNumber(m_scriptState, value), slot);
+ return handleException(m_scriptState);
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, bool value)
+bool ScriptObject::set(const char* name, bool value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
- jsObject()->put(scriptState, Identifier(scriptState, name), jsBoolean(value), slot);
- return handleException(scriptState);
+ jsObject()->put(m_scriptState, Identifier(m_scriptState, name), jsBoolean(value), slot);
+ return handleException(m_scriptState);
}
ScriptObject ScriptObject::createNew(ScriptState* scriptState)
{
- JSLock lock(false);
- return ScriptObject(constructEmptyObject(scriptState));
+ JSLock lock(SilenceAssertionsOnly);
+ return ScriptObject(scriptState, constructEmptyObject(scriptState));
}
bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
scriptState->lexicalGlobalObject()->putDirect(Identifier(scriptState, name), value.jsObject());
return handleException(scriptState);
}
+#ifdef MANUAL_MERGE_REQUIRED
#if ENABLE(JAVASCRIPT_DEBUGGER)
bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorController* value)
+#else // MANUAL_MERGE_REQUIRED
+bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorBackend* value)
+#endif // MANUAL_MERGE_REQUIRED
{
- JSLock lock(false);
- scriptState->lexicalGlobalObject()->putDirect(Identifier(scriptState, name), toJS(scriptState, value));
+ JSLock lock(SilenceAssertionsOnly);
+ JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
+ globalObject->putDirect(Identifier(scriptState, name), toJS(scriptState, globalObject, value));
return handleException(scriptState);
}
#endif
bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSValue jsValue = scriptState->lexicalGlobalObject()->get(scriptState, Identifier(scriptState, name));
if (!jsValue)
return false;
@@ -145,13 +155,13 @@ bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptO
if (!jsValue.isObject())
return false;
- value = ScriptObject(asObject(jsValue));
+ value = ScriptObject(scriptState, asObject(jsValue));
return true;
}
bool ScriptGlobalObject::remove(ScriptState* scriptState, const char* name)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
scriptState->lexicalGlobalObject()->deleteProperty(scriptState, Identifier(scriptState, name));
return handleException(scriptState);
}
diff --git a/WebCore/bindings/js/ScriptObject.h b/WebCore/bindings/js/ScriptObject.h
index ed86659..50b63ad 100644
--- a/WebCore/bindings/js/ScriptObject.h
+++ b/WebCore/bindings/js/ScriptObject.h
@@ -38,29 +38,32 @@
#include <runtime/Protect.h>
namespace WebCore {
- class InspectorController;
+ class InspectorBackend;
class ScriptObject : public ScriptValue {
public:
- ScriptObject(JSC::JSObject*);
+ ScriptObject(ScriptState*, JSC::JSObject*);
ScriptObject() {}
JSC::JSObject* jsObject() const { return asObject(jsValue()); }
- bool set(ScriptState*, const String& name, const String&);
- bool set(ScriptState*, const char* name, const ScriptObject&);
- bool set(ScriptState*, const char* name, const String&);
- bool set(ScriptState*, const char* name, double);
- bool set(ScriptState*, const char* name, long long);
- bool set(ScriptState*, const char* name, int);
- bool set(ScriptState*, const char* name, bool);
+ bool set(const String& name, const String&);
+ bool set(const char* name, const ScriptObject&);
+ bool set(const char* name, const String&);
+ bool set(const char* name, double);
+ bool set(const char* name, long long);
+ bool set(const char* name, int);
+ bool set(const char* name, bool);
static ScriptObject createNew(ScriptState*);
+
+ protected:
+ ScriptState* m_scriptState;
};
class ScriptGlobalObject {
public:
static bool set(ScriptState*, const char* name, const ScriptObject&);
- static bool set(ScriptState*, const char* name, InspectorController*);
+ static bool set(ScriptState*, const char* name, InspectorBackend*);
static bool get(ScriptState*, const char* name, ScriptObject&);
static bool remove(ScriptState*, const char* name);
private:
diff --git a/WebCore/bindings/js/ScriptObjectQuarantine.cpp b/WebCore/bindings/js/ScriptObjectQuarantine.cpp
index 13e180a..89553ef 100644
--- a/WebCore/bindings/js/ScriptObjectQuarantine.cpp
+++ b/WebCore/bindings/js/ScriptObjectQuarantine.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "ScriptObjectQuarantine.h"
-#include "Database.h"
#include "Document.h"
#include "Frame.h"
#include "JSDOMBinding.h"
@@ -43,6 +42,7 @@
#include <runtime/JSLock.h>
#if ENABLE(DATABASE)
+#include "Database.h"
#include "JSDatabase.h"
#endif
@@ -56,7 +56,7 @@ namespace WebCore {
ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value)
{
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
return ScriptValue(JSInspectedObjectWrapper::wrap(scriptState, value.jsValue()));
}
@@ -69,10 +69,11 @@ bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObj
if (!frame)
return false;
- ExecState* exec = toJSDOMWindow(frame)->globalExec();
+ JSDOMGlobalObject* globalObject = toJSDOMWindow(frame);
+ ExecState* exec = globalObject->globalExec();
- JSLock lock(false);
- quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, database))));
+ JSLock lock(SilenceAssertionsOnly);
+ quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, database))));
return true;
}
@@ -84,10 +85,11 @@ bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& qu
ASSERT(frame);
ASSERT(storage);
- ExecState* exec = toJSDOMWindow(frame)->globalExec();
+ JSDOMGlobalObject* globalObject = toJSDOMWindow(frame);
+ ExecState* exec = globalObject->globalExec();
- JSLock lock(false);
- quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, storage))));
+ JSLock lock(SilenceAssertionsOnly);
+ quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, globalObject, storage))));
return true;
}
@@ -99,8 +101,9 @@ bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject)
if (!exec)
return false;
- JSLock lock(false);
- quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, node))));
+ JSLock lock(SilenceAssertionsOnly);
+ // FIXME: Should use some sort of globalObjectFromNode()
+ quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, toJS(exec, deprecatedGlobalObjectForPrototype(exec), node))));
return true;
}
@@ -112,8 +115,8 @@ bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedO
JSDOMWindow* window = toJSDOMWindow(domWindow->frame());
ExecState* exec = window->globalExec();
- JSLock lock(false);
- quarantinedObject = ScriptObject(asObject(JSInspectedObjectWrapper::wrap(exec, window)));
+ JSLock lock(SilenceAssertionsOnly);
+ quarantinedObject = ScriptObject(exec, asObject(JSInspectedObjectWrapper::wrap(exec, window)));
return true;
}
diff --git a/WebCore/bindings/js/ScriptSourceCode.h b/WebCore/bindings/js/ScriptSourceCode.h
index 4a2403d..1b05ded 100644
--- a/WebCore/bindings/js/ScriptSourceCode.h
+++ b/WebCore/bindings/js/ScriptSourceCode.h
@@ -32,20 +32,24 @@
#define ScriptSourceCode_h
#include "CachedScriptSourceProvider.h"
+#include "ScriptSourceProvider.h"
#include "StringSourceProvider.h"
#include "KURL.h"
+#include <wtf/RefPtr.h>
namespace WebCore {
class ScriptSourceCode {
public:
ScriptSourceCode(const String& source, const KURL& url = KURL(), int startLine = 1)
- : m_code(makeSource(source, url.isNull() ? String() : url.string(), startLine))
+ : m_provider(StringSourceProvider::create(source, url.isNull() ? String() : url.string()))
+ , m_code(m_provider, startLine)
{
}
ScriptSourceCode(CachedScript* cs)
- : m_code(makeSource(cs))
+ : m_provider(CachedScriptSourceProvider::create(cs))
+ , m_code(m_provider)
{
}
@@ -53,7 +57,11 @@ public:
const JSC::SourceCode& jsSourceCode() const { return m_code; }
+ const String& source() const { return m_provider->source(); }
+
private:
+ RefPtr<ScriptSourceProvider> m_provider;
+
JSC::SourceCode m_code;
};
diff --git a/WebCore/bindings/js/ScriptSourceProvider.h b/WebCore/bindings/js/ScriptSourceProvider.h
new file mode 100644
index 0000000..3fe3584
--- /dev/null
+++ b/WebCore/bindings/js/ScriptSourceProvider.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Daniel Bates (dbates@intudata.com)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the 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 ScriptSourceProvider_h
+#define ScriptSourceProvider_h
+
+#include <parser/SourceProvider.h>
+
+namespace WebCore {
+
+ class String;
+
+ class ScriptSourceProvider : public JSC::SourceProvider {
+ public:
+ ScriptSourceProvider(const JSC::UString& url, JSC::SourceBOMPresence hasBOMs = JSC::SourceCouldHaveBOMs)
+ : SourceProvider(url, hasBOMs)
+ {
+ }
+
+ virtual const String& source() const = 0;
+ };
+
+} // namespace WebCore
+
+#endif // ScriptSourceProvider_h
diff --git a/WebCore/bindings/js/ScriptValue.cpp b/WebCore/bindings/js/ScriptValue.cpp
index dfb46da..d427cee 100644
--- a/WebCore/bindings/js/ScriptValue.cpp
+++ b/WebCore/bindings/js/ScriptValue.cpp
@@ -44,7 +44,7 @@ bool ScriptValue::getString(String& result) const
{
if (!m_value)
return false;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
UString ustring;
if (!m_value.get().getString(ustring))
return false;
diff --git a/WebCore/bindings/js/StringSourceProvider.h b/WebCore/bindings/js/StringSourceProvider.h
index ab37a56..770c4fc 100644
--- a/WebCore/bindings/js/StringSourceProvider.h
+++ b/WebCore/bindings/js/StringSourceProvider.h
@@ -29,21 +29,23 @@
#ifndef StringSourceProvider_h
#define StringSourceProvider_h
+#include "ScriptSourceProvider.h"
#include <parser/SourceCode.h>
namespace WebCore {
- class StringSourceProvider : public JSC::SourceProvider {
+ class StringSourceProvider : public ScriptSourceProvider {
public:
static PassRefPtr<StringSourceProvider> create(const String& source, const String& url) { return adoptRef(new StringSourceProvider(source, url)); }
JSC::UString getRange(int start, int end) const { return JSC::UString(m_source.characters() + start, end - start); }
const UChar* data() const { return m_source.characters(); }
int length() const { return m_source.length(); }
+ const String& source() const { return m_source; }
private:
StringSourceProvider(const String& source, const String& url)
- : SourceProvider(url)
+ : ScriptSourceProvider(url)
, m_source(source)
{
}
diff --git a/WebCore/bindings/js/WorkerScriptController.cpp b/WebCore/bindings/js/WorkerScriptController.cpp
index bcf107b..3590dad 100644
--- a/WebCore/bindings/js/WorkerScriptController.cpp
+++ b/WebCore/bindings/js/WorkerScriptController.cpp
@@ -31,7 +31,8 @@
#include "WorkerScriptController.h"
#include "JSDOMBinding.h"
-#include "JSWorkerContext.h"
+#include "JSDedicatedWorkerContext.h"
+#include "JSSharedWorkerContext.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "WorkerContext.h"
@@ -66,16 +67,30 @@ void WorkerScriptController::initScript()
{
ASSERT(!m_workerContextWrapper);
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
// 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());
- 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);
+ RefPtr<Structure> workerContextPrototypeStructure = JSWorkerContextPrototype::createStructure(jsNull());
+ ProtectedPtr<JSWorkerContextPrototype> workerContextPrototype = new (m_globalData.get()) JSWorkerContextPrototype(workerContextPrototypeStructure.release());
+
+ if (m_workerContext->isDedicatedWorkerContext()) {
+ RefPtr<Structure> dedicatedContextPrototypeStructure = JSDedicatedWorkerContextPrototype::createStructure(workerContextPrototype);
+ ProtectedPtr<JSDedicatedWorkerContextPrototype> dedicatedContextPrototype = new (m_globalData.get()) JSDedicatedWorkerContextPrototype(dedicatedContextPrototypeStructure.release());
+ RefPtr<Structure> structure = JSDedicatedWorkerContext::createStructure(dedicatedContextPrototype);
+
+ m_workerContextWrapper = new (m_globalData.get()) JSDedicatedWorkerContext(structure.release(), m_workerContext->toDedicatedWorkerContext());
+#if ENABLE(SHARED_WORKERS)
+ } else {
+ ASSERT(m_workerContext->isSharedWorkerContext());
+ RefPtr<Structure> sharedContextPrototypeStructure = JSSharedWorkerContextPrototype::createStructure(workerContextPrototype);
+ ProtectedPtr<JSSharedWorkerContextPrototype> sharedContextPrototype = new (m_globalData.get()) JSSharedWorkerContextPrototype(sharedContextPrototypeStructure.release());
+ RefPtr<Structure> structure = JSSharedWorkerContext::createStructure(sharedContextPrototype);
+
+ m_workerContextWrapper = new (m_globalData.get()) JSSharedWorkerContext(structure.release(), m_workerContext->toSharedWorkerContext());
+#endif
+ }
}
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
@@ -88,7 +103,7 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
ScriptValue exception;
ScriptValue result = evaluate(sourceCode, &exception);
if (exception.jsValue()) {
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
reportException(m_workerContextWrapper->globalExec(), exception.jsValue());
}
return result;
@@ -103,15 +118,13 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode,
}
initScriptIfNeeded();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
ExecState* exec = m_workerContextWrapper->globalExec();
m_workerContextWrapper->globalData()->timeoutChecker.start();
Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper);
m_workerContextWrapper->globalData()->timeoutChecker.stop();
- m_workerContext->thread()->workerObjectProxy().reportPendingActivity(m_workerContext->hasPendingActivity());
-
if (comp.complType() == Normal || comp.complType() == ReturnValue)
return comp.value();
diff --git a/WebCore/bindings/js/WorkerScriptController.h b/WebCore/bindings/js/WorkerScriptController.h
index 0454721..bb33f60 100644
--- a/WebCore/bindings/js/WorkerScriptController.h
+++ b/WebCore/bindings/js/WorkerScriptController.h
@@ -45,7 +45,7 @@ namespace WebCore {
class String;
class WorkerContext;
- class WorkerScriptController : Noncopyable {
+ class WorkerScriptController : public Noncopyable {
public:
WorkerScriptController(WorkerContext*);
~WorkerScriptController();
diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm
index 3fd28d1..62bf1de 100644
--- a/WebCore/bindings/objc/DOM.mm
+++ b/WebCore/bindings/objc/DOM.mm
@@ -468,7 +468,7 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
ASSERT(name);
WebCore::Element* element = core(self);
ASSERT(element);
- return element->document()->completeURL(parseURL(element->getAttribute(name)));
+ return element->document()->completeURL(deprecatedParseURL(element->getAttribute(name)));
}
- (BOOL)isFocused
@@ -503,6 +503,21 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
@end
//------------------------------------------------------------------------------------------
+// DOMRGBColor
+
+@implementation DOMRGBColor (WebPrivate)
+
+// FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
+// calls to the public method - (NSColor *)color.
+- (NSColor *)_color
+{
+ return [self color];
+}
+
+@end
+
+
+//------------------------------------------------------------------------------------------
// DOMNodeFilter
DOMNodeFilter *kit(WebCore::NodeFilter* impl)
diff --git a/WebCore/bindings/objc/DOMHTML.mm b/WebCore/bindings/objc/DOMHTML.mm
index 8c0d30b..1043d8e 100644
--- a/WebCore/bindings/objc/DOMHTML.mm
+++ b/WebCore/bindings/objc/DOMHTML.mm
@@ -70,7 +70,7 @@
- (DOMDocumentFragment *)_createDocumentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString
{
- NSURL *baseURL = core(self)->completeURL(WebCore::parseURL(baseURLString));
+ NSURL *baseURL = core(self)->completeURL(WebCore::deprecatedParseURL(baseURLString));
return [self createDocumentFragmentWithMarkupString:markupString baseURL:baseURL];
}
diff --git a/WebCore/bindings/objc/DOMInternal.mm b/WebCore/bindings/objc/DOMInternal.mm
index eb98a8a..9b26e59 100644
--- a/WebCore/bindings/objc/DOMInternal.mm
+++ b/WebCore/bindings/objc/DOMInternal.mm
@@ -123,11 +123,13 @@ void removeDOMWrapper(DOMObjectInternal* impl)
frame = document->frame();
if (!frame)
return;
-
- JSC::ExecState *exec = frame->script()->globalObject()->globalExec();
-
+
+ // The global object which should own this node.
+ WebCore::JSDOMGlobalObject* globalObject = frame->script()->globalObject();
+ JSC::ExecState *exec = globalObject->globalExec();
+
// Get (or create) a cached JS object for the DOM node.
- JSC::JSObject *scriptImp = asObject(WebCore::toJS(exec, nodeImpl));
+ JSC::JSObject *scriptImp = asObject(WebCore::toJS(exec, globalObject, nodeImpl));
JSC::Bindings::RootObject* rootObject = frame->script()->bindingRootObject();
diff --git a/WebCore/bindings/objc/DOMRGBColor.mm b/WebCore/bindings/objc/DOMRGBColor.mm
deleted file mode 100644
index 27f8966..0000000
--- a/WebCore/bindings/objc/DOMRGBColor.mm
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "DOMInternal.h" // import first to make the private/public trick work
-#import "DOMRGBColorInternal.h"
-
-#import "CSSPrimitiveValue.h"
-#import "ColorMac.h"
-#import "DOMCSSPrimitiveValueInternal.h"
-#import "WebCoreObjCExtras.h"
-#import "WebScriptObjectPrivate.h"
-#import <runtime/InitializeThreading.h>
-
-static NSMapTable* RGBColorWrapperCache;
-
-static id getWrapperForRGB(WebCore::RGBA32 value)
-{
- if (!RGBColorWrapperCache)
- return nil;
- return static_cast<id>(NSMapGet(RGBColorWrapperCache, reinterpret_cast<const void*>(value)));
-}
-
-static void setWrapperForRGB(id wrapper, WebCore::RGBA32 value)
-{
- if (!RGBColorWrapperCache)
- // No need to retain/free either impl key, or id value. Items will be removed
- // from the cache in dealloc methods.
- RGBColorWrapperCache = createWrapperCacheWithIntegerKeys();
- NSMapInsert(RGBColorWrapperCache, reinterpret_cast<const void*>(value), wrapper);
-}
-
-static void removeWrapperForRGB(WebCore::RGBA32 value)
-{
- if (!RGBColorWrapperCache)
- return;
- NSMapRemove(RGBColorWrapperCache, reinterpret_cast<const void*>(value));
-}
-
-@implementation DOMRGBColor
-
-+ (void)initialize
-{
- JSC::initializeThreading();
-#ifndef BUILDING_ON_TIGER
- WebCoreObjCFinalizeOnMainThread(self);
-#endif
-}
-
-- (void)dealloc
-{
- if (WebCoreObjCScheduleDeallocateOnMainThread([DOMRGBColor class], self))
- return;
-
- removeWrapperForRGB(reinterpret_cast<uintptr_t>(_internal));
- _internal = 0;
- [super dealloc];
-}
-
-- (DOMCSSPrimitiveValue *)red
-{
- WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal);
- int value = (rgb >> 16) & 0xFF;
- return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get());
-}
-
-- (DOMCSSPrimitiveValue *)green
-{
- WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal);
- int value = (rgb >> 8) & 0xFF;
- return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get());
-}
-
-- (DOMCSSPrimitiveValue *)blue
-{
- WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal);
- int value = rgb & 0xFF;
- return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get());
-}
-
-- (DOMCSSPrimitiveValue *)alpha
-{
- WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal);
- float value = static_cast<float>(WebCore::Color(rgb).alpha()) / 0xFF;
- return kit(WebCore::CSSPrimitiveValue::create(value, WebCore::CSSPrimitiveValue::CSS_NUMBER).get());
-
-}
-
-- (NSColor *)color
-{
- WebCore::RGBA32 rgb = reinterpret_cast<uintptr_t>(_internal);
- return WebCore::nsColor(WebCore::Color(rgb));
-}
-
-@end
-
-@implementation DOMRGBColor (WebPrivate)
-
-// FIXME: this should be removed once all internal Apple uses of it have been replaced with
-// calls to the public method, color without the leading underscore.
-- (NSColor *)_color
-{
- return [self color];
-}
-
-@end
-
-WebCore::RGBA32 core(DOMRGBColor *color)
-{
- return color ? static_cast<WebCore::RGBA32>(reinterpret_cast<uintptr_t>(color->_internal)) : 0;
-}
-
-DOMRGBColor *kit(WebCore::RGBA32 value)
-{
- if (DOMRGBColor *wrapper = getWrapperForRGB(value))
- return [[wrapper retain] autorelease];
-
- DOMRGBColor *wrapper = [[DOMRGBColor alloc] _init];
- wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(value);
- setWrapperForRGB(wrapper, value);
- return [wrapper autorelease];
-}
diff --git a/WebCore/bindings/objc/WebScriptObject.mm b/WebCore/bindings/objc/WebScriptObject.mm
index 8889eac..1086204 100644
--- a/WebCore/bindings/objc/WebScriptObject.mm
+++ b/WebCore/bindings/objc/WebScriptObject.mm
@@ -280,7 +280,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
if (![self _isSafeScript])
return nil;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
// Look up the function object.
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
@@ -325,7 +325,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ASSERT(!exec->hadException());
JSValue result;
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
[self _rootObject]->globalObject()->globalData()->timeoutChecker.start();
Completion completion = JSC::evaluate([self _rootObject]->globalObject()->globalExec(), [self _rootObject]->globalObject()->globalScopeChain(), makeSource(String(script)));
@@ -360,7 +360,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
ASSERT(!exec->hadException());
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
PutPropertySlot slot;
[self _imp]->put(exec, Identifier(exec, String(key)), convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), slot);
@@ -386,7 +386,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
// Need to scope this lock to ensure that we release the lock before calling
// [super valueForKey:key] which might throw an exception and bypass the JSLock destructor,
// leaving the lock permanently held
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSValue result = [self _imp]->get(exec, Identifier(exec, String(key)));
@@ -402,7 +402,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
if ([resultObj isKindOfClass:[WebUndefined class]])
resultObj = [super valueForKey:key]; // defaults to throwing an exception
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
_didExecute(self);
return resultObj;
@@ -416,7 +416,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
ASSERT(!exec->hadException());
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
[self _imp]->deleteProperty(exec, Identifier(exec, String(key)));
if (exec->hadException()) {
@@ -434,7 +434,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
return @"Undefined";
}
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
id result = convertValueToObjcValue(exec, [self _imp], ObjcObjectType).objectValue;
@@ -454,7 +454,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
ASSERT(!exec->hadException());
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
JSValue result = [self _imp]->get(exec, index);
if (exec->hadException()) {
@@ -478,7 +478,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
ExecState* exec = [self _rootObject]->globalObject()->globalExec();
ASSERT(!exec->hadException());
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
[self _imp]->put(exec, index, convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]));
if (exec->hadException()) {
@@ -509,7 +509,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
if (value.isObject()) {
JSObject* object = asObject(value);
ExecState* exec = rootObject->globalObject()->globalExec();
- JSLock lock(false);
+ JSLock lock(SilenceAssertionsOnly);
if (object->classInfo() != &RuntimeObjectImp::s_info) {
JSValue runtimeObject = object->get(exec, Identifier(exec, "__apple_runtime_object"));
diff --git a/WebCore/bindings/scripts/CodeGenerator.pm b/WebCore/bindings/scripts/CodeGenerator.pm
index d217c37..341c607 100644
--- a/WebCore/bindings/scripts/CodeGenerator.pm
+++ b/WebCore/bindings/scripts/CodeGenerator.pm
@@ -40,7 +40,7 @@ my %primitiveTypeHash = ("int" => 1, "short" => 1, "long" => 1, "long long" => 1
"float" => 1, "double" => 1,
"boolean" => 1, "void" => 1);
-my %podTypeHash = ("RGBColor" => 1, "SVGNumber" => 1, "SVGTransform" => 1);
+my %podTypeHash = ("SVGNumber" => 1, "SVGTransform" => 1);
my %podTypesWithWritablePropertiesHash = ("SVGLength" => 1, "SVGMatrix" => 1, "SVGPoint" => 1, "SVGRect" => 1);
my %stringTypeHash = ("DOMString" => 1, "AtomicString" => 1);
@@ -116,6 +116,41 @@ sub ProcessDocument
$codeGenerator->finish();
}
+# Necessary for V8 bindings to determine whether an interface is descendant from Node.
+# Node descendants are treated differently by DOMMap and this allows inferring the
+# type statically. See more at the original change: http://codereview.chromium.org/3195.
+# FIXME: Figure out a way to eliminate this JS bindings dichotomy.
+sub FindParentsRecursively
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my @parents = ($dataNode->name);
+ foreach (@{$dataNode->parents}) {
+ my $interface = $object->StripModule($_);
+
+ $endCondition = 0;
+ $foundFilename = "";
+ foreach (@{$useDirectories}) {
+ $object->ScanDirectory("$interface.idl", $_, $_, 0) if ($foundFilename eq "");
+ }
+
+ if ($foundFilename ne "") {
+ print " | |> Parsing parent IDL \"$foundFilename\" for interface \"$interface\"\n" if $verbose;
+
+ # Step #2: Parse the found IDL file (in quiet mode).
+ my $parser = IDLParser->new(1);
+ my $document = $parser->Parse($foundFilename, $defines, $preprocessor, 1);
+
+ foreach my $class (@{$document->classes}) {
+ @parents = (@parents, FindParentsRecursively($object, $class));
+ }
+ } else {
+ die("Could NOT find specified parent interface \"$interface\"!\n")
+ }
+ }
+ return @parents;
+}
+
sub AddMethodsConstantsAndAttributesFromParentClasses
{
# For the passed interface, recursively parse all parent
diff --git a/WebCore/bindings/scripts/CodeGeneratorCOM.pm b/WebCore/bindings/scripts/CodeGeneratorCOM.pm
index 7e80a17..6641305 100644
--- a/WebCore/bindings/scripts/CodeGeneratorCOM.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorCOM.pm
@@ -596,9 +596,15 @@ sub GenerateCPPAttribute
# FIXME: CHECK EXCEPTION AND DO SOMETHING WITH IT
- my $setterCall = " impl${implementationClassWithoutNamespace}()->${setterName}(" . join(", ", @setterParams) . ");\n";
-
- push(@setterImplementation, $setterCall);
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $CPPImplementationWebCoreIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL);
+ push(@setterImplementation, " impl${implementationClassWithoutNamespace}()->setAttribute(WebCore::HTMLNames::${contentAttributeName}Attr, " . join(", ", @setterParams) . ");\n");
+ } else {
+ push(@setterImplementation, " impl${implementationClassWithoutNamespace}()->${setterName}(" . join(", ", @setterParams) . ");\n");
+ }
push(@setterImplementation, " return S_OK;\n");
push(@setterImplementation, "}\n\n");
@@ -611,7 +617,17 @@ sub GenerateCPPAttribute
push(@getterImplementation, " if (!result)\n");
push(@getterImplementation, " return E_POINTER;\n\n");
- my $implementationGetter = "impl${implementationClassWithoutNamespace}()->" . $codeGenerator->WK_lcfirst($attributeName) . "(" . ($hasGetterException ? "ec" : ""). ")";
+ my $implementationGetter;
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL);
+ my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
+ $implementationGetter = "impl${implementationClassWithoutNamespace}()->${getAttributeFunctionName}(WebCore::HTMLNames::${contentAttributeName}Attr)";
+ } else {
+ $implementationGetter = "impl${implementationClassWithoutNamespace}()->" . $codeGenerator->WK_lcfirst($attributeName) . "(" . ($hasGetterException ? "ec" : ""). ")";
+ }
push(@getterImplementation, " WebCore::ExceptionCode ec = 0;\n") if $hasGetterException;
diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 4563018..1918aef 100644
--- a/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -34,7 +34,6 @@ my %headerIncludes = ();
my @implContentHeader = ();
my @implContent = ();
my %implIncludes = ();
-my %implKJSIncludes = ();
# Default .h template
my $headerTemplate = << "EOF";
@@ -120,7 +119,15 @@ sub GetParentClassName
my $dataNode = shift;
return $dataNode->extendedAttributes->{"LegacyParent"} if $dataNode->extendedAttributes->{"LegacyParent"};
- return "DOMObject" if @{$dataNode->parents} eq 0;
+ if (@{$dataNode->parents} eq 0) {
+ # FIXME: SVG types requiring a context() pointer do not have enough
+ # space to hold a globalObject pointer as well w/o hitting the CELL_SIZE limit.
+ # This could be fixed by moving context() into the various impl() classes.
+ # Until then, we special case these SVG bindings and allow them to return
+ # the wrong prototypes and constructors during x-frame access. See bug 27088.
+ return "DOMObjectWithSVGContext" if IsSVGTypeNeedingContextParameter($dataNode->name);
+ return "DOMObjectWithGlobalPointer";
+ }
return "JS" . $codeGenerator->StripModule($dataNode->parents(0));
}
@@ -141,14 +148,6 @@ sub AvoidInclusionOfType
return 0;
}
-sub UsesManualToJSImplementation
-{
- my $type = shift;
-
- return 1 if $type eq "Node" or $type eq "Document" or $type eq "HTMLCollection" or $type eq "SVGPathSeg" or $type eq "StyleSheet" or $type eq "CSSRule" or $type eq "CSSValue" or $type eq "Event" or $type eq "ImageData" or $type eq "Element" or $type eq "Text" or $type eq "SVGElementInstance";
- return 0;
-}
-
sub IndexGetterReturnsStrings
{
my $type = shift;
@@ -174,7 +173,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 "Array") {
+ or $type eq "DOMString" or $type eq "DOMObject" or $type eq "Array") {
} elsif ($type =~ /SVGPathSeg/) {
$joinedName = $type;
$joinedName =~ s/Abs|Rel//;
@@ -220,7 +219,7 @@ sub AddClassForwardIfNeeded
{
my $implClassName = shift;
- # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
+ # SVGAnimatedLength/Number/etc. are typedefs to SVGAnimatedTemplate, so don't use class forwards for them!
push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
}
@@ -228,11 +227,13 @@ sub IsSVGTypeNeedingContextParameter
{
my $implClassName = shift;
- if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
- return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
+ return 0 unless $implClassName =~ /SVG/;
+ return 0 if $implClassName =~ /Element/;
+ my @noContextNeeded = ("SVGPaint", "SVGColor", "SVGDocument", "SVGZoomEvent");
+ foreach (@noContextNeeded) {
+ return 0 if $implClassName eq $_;
}
-
- return 0;
+ return 1;
}
sub HashValueForClassAndName
@@ -328,8 +329,8 @@ sub GenerateGetOwnPropertySlotBody
&$manualLookupGetterGeneration();
}
- if ($dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) {
- push(@getOwnPropertySlotImpl, " if (customGetOwnPropertySlot(exec, propertyName, slot))\n");
+ if ($dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"}) {
+ push(@getOwnPropertySlotImpl, " if (getOwnPropertySlotDelegate(exec, propertyName, slot))\n");
push(@getOwnPropertySlotImpl, " return true;\n");
}
@@ -367,6 +368,7 @@ sub GenerateHeader
my $hasParent = $hasLegacyParent || $hasRealParent;
my $parentClassName = GetParentClassName($dataNode);
my $conditional = $dataNode->extendedAttributes->{"Conditional"};
+ my $needsSVGContext = IsSVGTypeNeedingContextParameter($interfaceName);
# - Add default header template
@headerContentHeader = split("\r", $headerTemplate);
@@ -378,36 +380,39 @@ sub GenerateHeader
my $conditionalString;
if ($conditional) {
$conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
- push(@headerContentHeader, "\n#if ${conditionalString}\n\n");
+ push(@headerContentHeader, "#if ${conditionalString}\n\n");
}
if ($hasParent) {
- push(@headerContentHeader, "#include \"$parentClassName.h\"\n");
+ $headerIncludes{"$parentClassName.h"} = 1;
} else {
- push(@headerContentHeader, "#include \"JSDOMBinding.h\"\n");
- push(@headerContentHeader, "#include <runtime/JSGlobalObject.h>\n");
- push(@headerContentHeader, "#include <runtime/ObjectPrototype.h>\n");
+ $headerIncludes{"DOMObjectWithSVGContext.h"} = $needsSVGContext;
+ $headerIncludes{"JSDOMBinding.h"} = !$needsSVGContext;
+ $headerIncludes{"<runtime/JSGlobalObject.h>"} = 1;
+ $headerIncludes{"<runtime/ObjectPrototype.h>"} = 1;
}
if ($dataNode->extendedAttributes->{"CustomCall"}) {
- push(@headerContentHeader, "#include <runtime/CallData.h>\n");
+ $headerIncludes{"<runtime/CallData.h>"} = 1;
}
if ($dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"}) {
- push(@headerContentHeader, "#include <runtime/Lookup.h>\n");
- push(@headerContentHeader, "#include <wtf/AlwaysInline.h>\n");
+ $headerIncludes{"<runtime/Lookup.h>"} = 1;
+ $headerIncludes{"<wtf/AlwaysInline.h>"} = 1;
}
if ($hasParent && $dataNode->extendedAttributes->{"GenerateNativeConverter"}) {
- push(@headerContentHeader, "#include \"${implClassName}.h\"");
+ $headerIncludes{"$implClassName.h"} = 1;
}
+ $headerIncludes{"SVGElement.h"} = 1 if $className =~ /^JSSVG/;
+
# Get correct pass/store types respecting PODType flag
my $podType = $dataNode->extendedAttributes->{"PODType"};
my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName;
- push(@headerContentHeader, "#include \"$podType.h\"\n") if $podType and $podType ne "float";
+ $headerIncludes{"$podType.h"} = 1 if $podType and $podType ne "float";
- push(@headerContentHeader, "#include \"JSSVGPODTypeWrapper.h\"\n") if $podType;
+ $headerIncludes{"JSSVGPODTypeWrapper.h"} = 1 if $podType;
my $numConstants = @{$dataNode->constants};
my $numAttributes = @{$dataNode->attributes};
@@ -427,10 +432,12 @@ sub GenerateHeader
# Constructor
if ($interfaceName eq "DOMWindow") {
push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>, JSDOMWindowShell*);\n");
+ } elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
+ push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>);\n");
} elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
- push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>, SVGElement* context);\n");
+ push(@headerContent, " $className(PassRefPtr<JSC::Structure>, JSDOMGlobalObject*, PassRefPtr<$implType>, SVGElement* context);\n");
} else {
- push(@headerContent, " $className(PassRefPtr<JSC::Structure>, PassRefPtr<$implType>);\n");
+ push(@headerContent, " $className(PassRefPtr<JSC::Structure>, JSDOMGlobalObject*, PassRefPtr<$implType>);\n");
}
# Destructor
@@ -439,13 +446,14 @@ sub GenerateHeader
# Prototype
push(@headerContent, " static JSC::JSObject* createPrototype(JSC::ExecState*, JSC::JSGlobalObject*);\n") unless ($dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"});
- $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"};
+ $implIncludes{"${className}Custom.h"} = 1 if $dataNode->extendedAttributes->{"CustomHeader"} || $dataNode->extendedAttributes->{"CustomPutFunction"} || $dataNode->extendedAttributes->{"DelegatingPutFunction"};
my $hasGetter = $numAttributes > 0
|| $dataNode->extendedAttributes->{"GenerateConstructor"}
|| $dataNode->extendedAttributes->{"HasIndexGetter"}
|| $dataNode->extendedAttributes->{"HasCustomIndexGetter"}
|| $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}
+ || $dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"}
|| $dataNode->extendedAttributes->{"HasNameGetter"}
|| $dataNode->extendedAttributes->{"HasOverridingNameGetter"};
@@ -453,7 +461,7 @@ sub GenerateHeader
if ($hasGetter) {
push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);\n");
push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);\n") if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) && !$dataNode->extendedAttributes->{"HasOverridingNameGetter"};
- push(@headerContent, " bool customGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"};
+ push(@headerContent, " bool getOwnPropertySlotDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"};
}
# Check if we have any writable properties
@@ -466,13 +474,14 @@ sub GenerateHeader
my $hasSetter = $hasReadWriteProperties
|| $dataNode->extendedAttributes->{"CustomPutFunction"}
+ || $dataNode->extendedAttributes->{"DelegatingPutFunction"}
|| $dataNode->extendedAttributes->{"HasCustomIndexSetter"};
# Getters
if ($hasSetter) {
push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n");
push(@headerContent, " virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);\n") if $dataNode->extendedAttributes->{"HasCustomIndexSetter"};
- push(@headerContent, " bool customPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomPutFunction"};
+ push(@headerContent, " bool putDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n") if $dataNode->extendedAttributes->{"DelegatingPutFunction"};
}
# Class info
@@ -495,7 +504,7 @@ sub GenerateHeader
}
# Custom mark function
- push(@headerContent, " virtual void mark();\n\n") if $dataNode->extendedAttributes->{"CustomMarkFunction"};
+ push(@headerContent, " virtual void markChildren(JSC::MarkStack&);\n\n") if $dataNode->extendedAttributes->{"CustomMarkFunction"};
# Custom pushEventHandlerScope function
push(@headerContent, " virtual void pushEventHandlerScope(JSC::ExecState*, JSC::ScopeChain&) const;\n\n") if $dataNode->extendedAttributes->{"CustomPushEventHandlerScope"};
@@ -508,7 +517,6 @@ sub GenerateHeader
# Custom getPropertyNames function
push(@headerContent, " virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"});
- push(@headerContent, " bool customGetPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);\n") if $dataNode->extendedAttributes->{"CustomGetPropertyNames"};
# Custom getPropertyAttributes function
push(@headerContent, " virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned& attributes) const;\n") if $dataNode->extendedAttributes->{"CustomGetPropertyAttributes"};
@@ -526,7 +534,7 @@ sub GenerateHeader
push(@headerContent, " virtual JSC::JSValue lookupSetter(JSC::ExecState*, const JSC::Identifier& propertyName);\n") if $dataNode->extendedAttributes->{"CustomLookupSetter"};
# Constructor object getter
- push(@headerContent, " static JSC::JSValue getConstructor(JSC::ExecState*);\n") if $dataNode->extendedAttributes->{"GenerateConstructor"};
+ push(@headerContent, " static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);\n") if $dataNode->extendedAttributes->{"GenerateConstructor"};
my $numCustomFunctions = 0;
my $numCustomAttributes = 0;
@@ -575,23 +583,11 @@ sub GenerateHeader
}
if (!$hasParent) {
- if ($podType) {
- push(@headerContent, " JSSVGPODTypeWrapper<$podType>* impl() const { return m_impl.get(); }\n");
- push(@headerContent, " SVGElement* context() const { return m_context.get(); }\n\n");
- push(@headerContent, "private:\n");
- push(@headerContent, " RefPtr<SVGElement> m_context;\n");
- push(@headerContent, " RefPtr<JSSVGPODTypeWrapper<$podType> > m_impl;\n");
- } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
- push(@headerContent, " $implClassName* impl() const { return m_impl.get(); }\n");
- push(@headerContent, " SVGElement* context() const { return m_context.get(); }\n\n");
- push(@headerContent, "private:\n");
- push(@headerContent, " RefPtr<SVGElement> m_context;\n");
- push(@headerContent, " RefPtr<$implClassName > m_impl;\n");
- } else {
- push(@headerContent, " $implClassName* impl() const { return m_impl.get(); }\n\n");
- push(@headerContent, "private:\n");
- push(@headerContent, " RefPtr<$implClassName> m_impl;\n");
- }
+ # Extra space after JSSVGPODTypeWrapper<> to make RefPtr<Wrapper<> > compile.
+ my $implType = $podType ? "JSSVGPODTypeWrapper<$podType> " : $implClassName;
+ push(@headerContent, " $implType* impl() const { return m_impl.get(); }\n\n");
+ push(@headerContent, "private:\n");
+ push(@headerContent, " RefPtr<$implType> m_impl;\n");
} elsif ($dataNode->extendedAttributes->{"GenerateNativeConverter"}) {
push(@headerContent, " $implClassName* impl() const\n");
push(@headerContent, " {\n");
@@ -620,20 +616,20 @@ sub GenerateHeader
push(@headerContent, "};\n\n");
- if ($dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"}) {
+ if ($dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"} && !$dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) {
push(@headerContent, "ALWAYS_INLINE bool ${className}::getOwnPropertySlot(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertySlot& slot)\n");
push(@headerContent, "{\n");
push(@headerContent, GenerateGetOwnPropertySlotBody($dataNode, $interfaceName, $className, $implClassName, $numAttributes > 0, 1));
push(@headerContent, "}\n\n");
}
- if (!$hasParent || $dataNode->extendedAttributes->{"GenerateToJS"}) {
+ if (!$hasParent || $dataNode->extendedAttributes->{"GenerateToJS"} || $dataNode->extendedAttributes->{"CustomToJS"}) {
if ($podType) {
- push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSSVGPODTypeWrapper<$podType>*, SVGElement* context);\n");
+ push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, JSSVGPODTypeWrapper<$podType>*, SVGElement* context);\n");
} elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
- push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, $implType*, SVGElement* context);\n");
+ push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, $implType*, SVGElement* context);\n");
} else {
- push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, $implType*);\n");
+ push(@headerContent, "JSC::JSValue toJS(JSC::ExecState*, JSDOMGlobalObject*, $implType*);\n");
}
}
if (!$hasParent || $dataNode->extendedAttributes->{"GenerateNativeConverter"}) {
@@ -646,7 +642,7 @@ sub GenerateHeader
}
}
if ($interfaceName eq "Node" or $interfaceName eq "Element" or $interfaceName eq "Text" or $interfaceName eq "CDATASection") {
- push(@headerContent, "JSC::JSValue toJSNewlyCreated(JSC::ExecState*, $interfaceName*);\n");
+ push(@headerContent, "JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, $interfaceName*);\n");
}
push(@headerContent, "\n");
@@ -657,16 +653,16 @@ sub GenerateHeader
push(@headerContent, "public:\n");
if ($interfaceName eq "DOMWindow") {
push(@headerContent, " void* operator new(size_t);\n");
- } elsif ($interfaceName eq "WorkerContext") {
+ } elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
push(@headerContent, " void* operator new(size_t, JSC::JSGlobalData*);\n");
} else {
push(@headerContent, " static JSC::JSObject* self(JSC::ExecState*, JSC::JSGlobalObject*);\n");
}
push(@headerContent, " virtual const JSC::ClassInfo* classInfo() const { return &s_info; }\n");
push(@headerContent, " static const JSC::ClassInfo s_info;\n");
- if ($numFunctions > 0 || $numConstants > 0 || $dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}) {
+ if ($numFunctions > 0 || $numConstants > 0 || $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}) {
push(@headerContent, " virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n");
- push(@headerContent, " bool customGetOwnPropertySlot(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"};
+ push(@headerContent, " bool getOwnPropertySlotDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::PropertySlot&);\n") if $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"};
push(@headerContent,
" static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)\n" .
@@ -674,9 +670,9 @@ sub GenerateHeader
" return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType));\n" .
" }\n");
}
- if ($dataNode->extendedAttributes->{"CustomPrototypePutFunction"}) {
+ if ($dataNode->extendedAttributes->{"DelegatingPrototypePutFunction"}) {
push(@headerContent, " virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n");
- push(@headerContent, " bool customPut(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n");
+ push(@headerContent, " bool putDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n");
}
# Custom defineGetter function
@@ -741,25 +737,19 @@ sub GenerateImplementation
# - Add default header template
@implContentHeader = split("\r", $headerTemplate);
- push(@implContentHeader, "\n#include \"config.h\"\n\n");
+
+ push(@implContentHeader, "\n#include \"config.h\"\n");
my $conditionalString;
if ($conditional) {
$conditionalString = "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
push(@implContentHeader, "\n#if ${conditionalString}\n\n");
}
-
- if ($className =~ /^JSSVG/) {
- push(@implContentHeader, "#include \"SVGElement.h\"\n");
-
- if ($className =~ /^JSSVGAnimated/) {
- AddIncludesForSVGAnimatedType($interfaceName);
- }
- }
-
push(@implContentHeader, "#include \"$className.h\"\n\n");
- push(@implContentHeader, "#include <wtf/GetPtr.h>\n\n");
- push(@implContentHeader, "#include <runtime/PropertyNameArray.h>\n") if $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"};
+ AddIncludesForSVGAnimatedType($interfaceName) if $className =~ /^JSSVGAnimated/;
+
+ $implIncludes{"<wtf/GetPtr.h>"} = 1;
+ $implIncludes{"<runtime/PropertyNameArray.h>"} = 1 if $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"};
AddIncludesForType($interfaceName);
@@ -913,7 +903,7 @@ sub GenerateImplementation
push(@implContent, "{\n");
push(@implContent, " return JSDOMWindow::commonJSGlobalData()->heap.allocate(size);\n");
push(@implContent, "}\n\n");
- } elsif ($interfaceName eq "WorkerContext") {
+ } elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
push(@implContent, "void* ${className}Prototype::operator new(size_t size, JSGlobalData* globalData)\n");
push(@implContent, "{\n");
push(@implContent, " return globalData->heap.allocate(size);\n");
@@ -924,12 +914,12 @@ sub GenerateImplementation
push(@implContent, " return getDOMPrototype<${className}>(exec, globalObject);\n");
push(@implContent, "}\n\n");
}
- if ($numConstants > 0 || $numFunctions > 0 || $dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}) {
+ if ($numConstants > 0 || $numFunctions > 0 || $dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}) {
push(@implContent, "bool ${className}Prototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
push(@implContent, "{\n");
- if ($dataNode->extendedAttributes->{"CustomPrototypeGetOwnPropertySlot"}) {
- push(@implContent, " if (customGetOwnPropertySlot(exec, propertyName, slot))\n");
+ if ($dataNode->extendedAttributes->{"DelegatingPrototypeGetOwnPropertySlot"}) {
+ push(@implContent, " if (getOwnPropertySlotDelegate(exec, propertyName, slot))\n");
push(@implContent, " return true;\n");
}
@@ -945,10 +935,10 @@ sub GenerateImplementation
push(@implContent, "}\n\n");
}
- if ($dataNode->extendedAttributes->{"CustomPrototypePutFunction"}) {
+ if ($dataNode->extendedAttributes->{"DelegatingPrototypePutFunction"}) {
push(@implContent, "void ${className}Prototype::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)\n");
push(@implContent, "{\n");
- push(@implContent, " if (customPut(exec, propertyName, value, slot))\n");
+ push(@implContent, " if (putDelegate(exec, propertyName, value, slot))\n");
push(@implContent, " return;\n");
push(@implContent, " Base::put(exec, propertyName, value, slot);\n");
push(@implContent, "}\n\n");
@@ -992,22 +982,18 @@ sub GenerateImplementation
AddIncludesForType("JSDOMWindowShell");
push(@implContent, "${className}::$className(PassRefPtr<Structure> structure, PassRefPtr<$implType> impl, JSDOMWindowShell* shell)\n");
push(@implContent, " : $parentClassName(structure, impl, shell)\n");
+ } elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
+ AddIncludesForType($interfaceName);
+ push(@implContent, "${className}::$className(PassRefPtr<Structure> structure, PassRefPtr<$implType> impl)\n");
+ push(@implContent, " : $parentClassName(structure, impl)\n");
} else {
- my $contextArg = "";
- if ($needsSVGContext) {
- if ($hasParent && !$parentNeedsSVGContext) {
- $contextArg = ", SVGElement*";
- } else {
- $contextArg = ", SVGElement* context";
- }
- }
- push(@implContent, "${className}::$className(PassRefPtr<Structure> structure, PassRefPtr<$implType> impl$contextArg)\n");
+ my $contextArg = $needsSVGContext ? ", SVGElement* context" : "";
+ push(@implContent, "${className}::$className(PassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<$implType> impl$contextArg)\n");
if ($hasParent) {
- push(@implContent, " : $parentClassName(structure, impl" . ($parentNeedsSVGContext ? ", context" : "") . ")\n");
+ push(@implContent, " : $parentClassName(structure, globalObject, impl" . ($parentNeedsSVGContext ? ", context" : "") . ")\n");
} else {
- push(@implContent, " : $parentClassName(structure)\n");
- push(@implContent, " , m_context(context)\n") if $needsSVGContext;
- push(@implContent, " , m_impl(impl)\n");
+ push(@implContent, " : $parentClassName(structure, globalObject" . ($needsSVGContext ? ", context" : "") . ")\n");
+ push(@implContent, " , m_impl(impl)\n");
}
}
push(@implContent, "{\n");
@@ -1063,13 +1049,14 @@ sub GenerateImplementation
|| $dataNode->extendedAttributes->{"GenerateConstructor"}
|| $dataNode->extendedAttributes->{"HasIndexGetter"}
|| $dataNode->extendedAttributes->{"HasCustomIndexGetter"}
+ || $dataNode->extendedAttributes->{"DelegatingGetOwnPropertySlot"}
|| $dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}
|| $dataNode->extendedAttributes->{"HasNameGetter"}
|| $dataNode->extendedAttributes->{"HasOverridingNameGetter"};
# Attributes
if ($hasGetter) {
- if (!$dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"}) {
+ if (!$dataNode->extendedAttributes->{"InlineGetOwnPropertySlot"} && !$dataNode->extendedAttributes->{"CustomGetOwnPropertySlot"}) {
push(@implContent, "bool ${className}::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\n");
push(@implContent, "{\n");
push(@implContent, GenerateGetOwnPropertySlotBody($dataNode, $interfaceName, $className, $implClassName, $numAttributes > 0, 0));
@@ -1107,6 +1094,7 @@ sub GenerateImplementation
push(@implContent, "JSValue ${getFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
push(@implContent, "{\n");
+ push(@implContent, " ${className}* castedThis = static_cast<$className*>(asObject(slot.slotBase()));\n");
my $implClassNameForValueConversion = "";
if (!$podType and ($codeGenerator->IsSVGAnimatedType($implClassName) or $attribute->type !~ /^readonly/)) {
@@ -1116,25 +1104,25 @@ sub GenerateImplementation
if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} &&
!$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurity"} &&
!$attribute->signature->extendedAttributes->{"DoNotCheckDomainSecurityOnGet"}) {
- push(@implContent, " if (!static_cast<$className*>(asObject(slot.slotBase()))->allowsAccessFrom(exec))\n");
+ push(@implContent, " if (!castedThis->allowsAccessFrom(exec))\n");
push(@implContent, " return jsUndefined();\n");
}
if ($attribute->signature->extendedAttributes->{"Custom"} || $attribute->signature->extendedAttributes->{"JSCCustom"} || $attribute->signature->extendedAttributes->{"CustomGetter"} || $attribute->signature->extendedAttributes->{"JSCCustomGetter"}) {
- push(@implContent, " return static_cast<$className*>(asObject(slot.slotBase()))->$implGetterFunctionName(exec);\n");
+ push(@implContent, " return castedThis->$implGetterFunctionName(exec);\n");
} elsif ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
$implIncludes{"JSDOMBinding.h"} = 1;
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
- push(@implContent, " return checkNodeSecurity(exec, imp->$implGetterFunctionName()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "static_cast<$className*>(asObject(slot.slotBase()))") . " : jsUndefined();\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n");
+ push(@implContent, " return checkNodeSecurity(exec, imp->$implGetterFunctionName()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "castedThis") . " : jsUndefined();\n");
} elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
$implIncludes{"Document.h"} = 1;
$implIncludes{"JSDOMBinding.h"} = 1;
- 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");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n");
+ push(@implContent, " return checkNodeSecurity(exec, imp->contentDocument()) ? " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "castedThis") . " : jsUndefined();\n");
} elsif ($type eq "EventListener") {
$implIncludes{"EventListener.h"} = 1;
push(@implContent, " UNUSED_PARAM(exec);\n");
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n");
push(@implContent, " if (EventListener* listener = imp->$implGetterFunctionName()) {\n");
push(@implContent, " if (JSObject* jsFunction = listener->jsFunction())\n");
push(@implContent, " return jsFunction;\n");
@@ -1143,36 +1131,47 @@ sub GenerateImplementation
} elsif ($attribute->signature->type =~ /Constructor$/) {
my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
$constructorType =~ s/Constructor$//;
- push(@implContent, " UNUSED_PARAM(slot);\n");
- push(@implContent, " return JS" . $constructorType . "::getConstructor(exec);\n");
+ # Constructor attribute is only used by DOMWindow.idl, so it's correct to pass castedThis as the global object
+ # Once DOMObjects have a back-pointer to the globalObject we can pass castedThis->globalObject()
+ push(@implContent, " return JS" . $constructorType . "::getConstructor(exec, castedThis);\n");
} elsif (!@{$attribute->getterExceptions}) {
push(@implContent, " UNUSED_PARAM(exec);\n");
if ($podType) {
- push(@implContent, " $podType imp(*static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
+ push(@implContent, " $podType imp(*castedThis->impl());\n");
if ($podType eq "float") { # Special case for JSSVGNumber
- push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n");
+ push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp", "castedThis") . ";\n");
} else {
- push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName()", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n");
+ push(@implContent, " return " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName()", "castedThis") . ";\n");
}
} else {
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
- my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName()", "static_cast<$className*>(asObject(slot.slotBase()))");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n");
+ my $value;
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $name : ($reflect || $reflectURL);
+ my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
+ $value = "imp->$getAttributeFunctionName(HTMLNames::${contentAttributeName}Attr)"
+ } else {
+ $value = "imp->$implGetterFunctionName()";
+ }
+ my $jsType = NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, $value, "castedThis");
if ($codeGenerator->IsSVGAnimatedType($type)) {
push(@implContent, " RefPtr<$type> obj = $jsType;\n");
- push(@implContent, " return toJS(exec, obj.get(), imp);\n");
+ push(@implContent, " return toJS(exec, castedThis->globalObject(), obj.get(), imp);\n");
} else {
push(@implContent, " return $jsType;\n");
}
}
} else {
- push(@implContent, " ExceptionCode ec = 0;\n");
-
+ push(@implContent, " ExceptionCode ec = 0;\n");
if ($podType) {
- push(@implContent, " $podType imp(*static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
- push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName(ec)", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n");
+ push(@implContent, " $podType imp(*castedThis->impl());\n");
+ push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, "", "imp.$implGetterFunctionName(ec)", "castedThis") . ";\n");
} else {
- push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(asObject(slot.slotBase()))->impl());\n");
- push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName(ec)", "static_cast<$className*>(asObject(slot.slotBase()))") . ";\n");
+ push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(castedThis->impl());\n");
+ push(@implContent, " JSC::JSValue result = " . NativeToJSValue($attribute->signature, 0, $implClassName, $implClassNameForValueConversion, "imp->$implGetterFunctionName(ec)", "castedThis") . ";\n");
}
push(@implContent, " setDOMException(exec, ec);\n");
@@ -1193,7 +1192,15 @@ sub GenerateImplementation
push(@implContent, "JSValue ${constructorFunctionName}(ExecState* exec, const Identifier&, const PropertySlot& slot)\n");
push(@implContent, "{\n");
- push(@implContent, " return static_cast<$className*>(asObject(slot.slotBase()))->getConstructor(exec);\n");
+ if (IsSVGTypeNeedingContextParameter($interfaceName)) {
+ # FIXME: SVG bindings with a context pointer have no space to store a globalObject
+ # so we use deprecatedGlobalObjectForPrototype instead.
+ push(@implContent, " UNUSED_PARAM(slot);\n");
+ push(@implContent, " return ${className}::getConstructor(exec, deprecatedGlobalObjectForPrototype(exec));\n");
+ } else {
+ push(@implContent, " ${className}* domObject = static_cast<$className*>(asObject(slot.slotBase()));\n");
+ push(@implContent, " return ${className}::getConstructor(exec, domObject->globalObject());\n");
+ }
push(@implContent, "}\n");
}
}
@@ -1205,31 +1212,33 @@ sub GenerateImplementation
}
my $hasSetter = $hasReadWriteProperties
- || $dataNode->extendedAttributes->{"CustomPutFunction"}
+ || $dataNode->extendedAttributes->{"DelegatingPutFunction"}
|| $dataNode->extendedAttributes->{"HasCustomIndexSetter"};
if ($hasSetter) {
- push(@implContent, "void ${className}::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)\n");
- push(@implContent, "{\n");
- if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
- push(@implContent, " bool ok;\n");
- push(@implContent, " unsigned index = propertyName.toUInt32(&ok, false);\n");
- push(@implContent, " if (ok) {\n");
- push(@implContent, " indexSetter(exec, index, value);\n");
- push(@implContent, " return;\n");
- push(@implContent, " }\n");
- }
- if ($dataNode->extendedAttributes->{"CustomPutFunction"}) {
- push(@implContent, " if (customPut(exec, propertyName, value, slot))\n");
- push(@implContent, " return;\n");
- }
+ if (!$dataNode->extendedAttributes->{"CustomPutFunction"}) {
+ push(@implContent, "void ${className}::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)\n");
+ push(@implContent, "{\n");
+ if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
+ push(@implContent, " bool ok;\n");
+ push(@implContent, " unsigned index = propertyName.toUInt32(&ok, false);\n");
+ push(@implContent, " if (ok) {\n");
+ push(@implContent, " indexSetter(exec, index, value);\n");
+ push(@implContent, " return;\n");
+ push(@implContent, " }\n");
+ }
+ if ($dataNode->extendedAttributes->{"DelegatingPutFunction"}) {
+ push(@implContent, " if (putDelegate(exec, propertyName, value, slot))\n");
+ push(@implContent, " return;\n");
+ }
- if ($hasReadWriteProperties) {
- push(@implContent, " lookupPut<$className, Base>(exec, propertyName, value, " . hashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, slot);\n");
- } else {
- push(@implContent, " Base::put(exec, propertyName, value, slot);\n");
+ if ($hasReadWriteProperties) {
+ push(@implContent, " lookupPut<$className, Base>(exec, propertyName, value, " . hashTableAccessor($dataNode->extendedAttributes->{"NoStaticTables"}, $className) . ", this, slot);\n");
+ } else {
+ push(@implContent, " Base::put(exec, propertyName, value, slot);\n");
+ }
+ push(@implContent, "}\n\n");
}
- push(@implContent, "}\n\n");
if ($dataNode->extendedAttributes->{"HasCustomIndexSetter"}) {
push(@implContent, "void ${className}::put(ExecState* exec, unsigned propertyName, JSValue value)\n");
@@ -1295,8 +1304,17 @@ sub GenerateImplementation
push(@implContent, " static_cast<$className*>(thisObject)->impl()->commitChange(imp, static_cast<$className*>(thisObject)->context());\n");
} else {
push(@implContent, " $implClassName* imp = static_cast<$implClassName*>(static_cast<$className*>(thisObject)->impl());\n");
+ my $nativeValue = JSValueToNative($attribute->signature, "value");
push(@implContent, " ExceptionCode ec = 0;\n") if @{$attribute->setterExceptions};
- push(@implContent, " imp->set$implSetterFunctionName(" . JSValueToNative($attribute->signature, "value"));
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $name : ($reflect || $reflectURL);
+ push(@implContent, " imp->setAttribute(HTMLNames::${contentAttributeName}Attr, $nativeValue");
+ } else {
+ push(@implContent, " imp->set$implSetterFunctionName($nativeValue");
+ }
push(@implContent, ", ec") if @{$attribute->setterExceptions};
push(@implContent, ");\n");
push(@implContent, " setDOMException(exec, ec);\n") if @{$attribute->setterExceptions};
@@ -1315,13 +1333,9 @@ sub GenerateImplementation
}
}
- if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"} || $dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
+ if (($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) && !$dataNode->extendedAttributes->{"CustomGetPropertyNames"}) {
push(@implContent, "void ${className}::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)\n");
push(@implContent, "{\n");
- if ($dataNode->extendedAttributes->{"CustomGetPropertyNames"}) {
- push(@implContent, " if (customGetPropertyNames(exec, propertyNames))\n");
- push(@implContent, " return;\n");
- }
if ($dataNode->extendedAttributes->{"HasIndexGetter"} || $dataNode->extendedAttributes->{"HasCustomIndexGetter"}) {
push(@implContent, " for (unsigned i = 0; i < static_cast<${implClassName}*>(impl())->length(); ++i)\n");
push(@implContent, " propertyNames.add(Identifier::from(exec, i));\n");
@@ -1331,8 +1345,8 @@ sub GenerateImplementation
}
if ($dataNode->extendedAttributes->{"GenerateConstructor"}) {
- push(@implContent, "JSValue ${className}::getConstructor(ExecState* exec)\n{\n");
- push(@implContent, " return getDOMConstructor<${className}Constructor>(exec);\n");
+ push(@implContent, "JSValue ${className}::getConstructor(ExecState* exec, JSGlobalObject* globalObject)\n{\n");
+ push(@implContent, " return getDOMConstructor<${className}Constructor>(exec, static_cast<JSDOMGlobalObject*>(globalObject));\n");
push(@implContent, "}\n\n");
}
@@ -1348,12 +1362,16 @@ sub GenerateImplementation
push(@implContent, "{\n");
push(@implContent, " UNUSED_PARAM(args);\n");
- $implKJSInclude{"Error.h"} = 1;
+ $implIncludes{"<runtime/Error.h>"} = 1;
if ($interfaceName eq "DOMWindow") {
push(@implContent, " $className* castedThisObj = toJSDOMWindow(thisValue.toThisObject(exec));\n");
push(@implContent, " if (!castedThisObj)\n");
push(@implContent, " return throwError(exec, TypeError);\n");
+ } elsif ($dataNode->extendedAttributes->{"IsWorkerContext"}) {
+ push(@implContent, " $className* castedThisObj = to${className}(thisValue.toThisObject(exec));\n");
+ push(@implContent, " if (!castedThisObj)\n");
+ push(@implContent, " return throwError(exec, TypeError);\n");
} else {
push(@implContent, " if (!thisValue.isObject(&${className}::s_info))\n");
push(@implContent, " return throwError(exec, TypeError);\n");
@@ -1481,7 +1499,7 @@ sub GenerateImplementation
$implIncludes{"KURL.h"} = 1;
push(@implContent, " return jsStringOrNull(exec, thisObj->impl()->item(slot.index()));\n");
} else {
- push(@implContent, " return toJS(exec, static_cast<$implClassName*>(thisObj->impl())->item(slot.index()));\n");
+ push(@implContent, " return toJS(exec, thisObj->globalObject(), static_cast<$implClassName*>(thisObj->impl())->item(slot.index()));\n");
}
push(@implContent, "}\n");
if ($interfaceName eq "HTMLCollection") {
@@ -1490,22 +1508,22 @@ sub GenerateImplementation
}
}
- if ((!$hasParent or $dataNode->extendedAttributes->{"GenerateToJS"}) and !UsesManualToJSImplementation($implClassName)) {
+ if ((!$hasParent or $dataNode->extendedAttributes->{"GenerateToJS"}) and !$dataNode->extendedAttributes->{"CustomToJS"}) {
if ($podType) {
- push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSSVGPODTypeWrapper<$podType>* object, SVGElement* context)\n");
+ push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, JSSVGPODTypeWrapper<$podType>* object, SVGElement* context)\n");
} elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
- push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, $implType* object, SVGElement* context)\n");
+ push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, $implType* object, SVGElement* context)\n");
} else {
- push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, $implType* object)\n");
+ push(@implContent, "JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, $implType* object)\n");
}
push(@implContent, "{\n");
if ($podType) {
- push(@implContent, " return getDOMObjectWrapper<$className, JSSVGPODTypeWrapper<$podType> >(exec, object, context);\n");
+ push(@implContent, " return getDOMObjectWrapper<$className, JSSVGPODTypeWrapper<$podType> >(exec, globalObject, object, context);\n");
} elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
- push(@implContent, " return getDOMObjectWrapper<$className>(exec, object, context);\n");
+ push(@implContent, " return getDOMObjectWrapper<$className>(exec, globalObject, object, context);\n");
} else {
- push(@implContent, " return getDOMObjectWrapper<$className>(exec, object);\n");
+ push(@implContent, " return getDOMObjectWrapper<$className>(exec, globalObject, object);\n");
}
push(@implContent, "}\n");
}
@@ -1664,7 +1682,7 @@ sub NativeToJSValue
return "jsBoolean($value)" if $type eq "boolean";
if ($codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType" or $type eq "DOMTimeStamp") {
- $implKJSInclude{"JSNumberCell.h"} = 1;
+ $implIncludes{"<runtime/JSNumberCell.h>"} = 1;
return "jsNumber(exec, $value)";
}
@@ -1678,14 +1696,12 @@ sub NativeToJSValue
die "Unknown value for ConvertNullStringTo extended attribute";
}
- $implKJSInclude{"JSString.h"} = 1;
+ $implIncludes{"<runtime/JSString.h>"} = 1;
return "jsString(exec, $value)";
}
-
- if ($type eq "RGBColor") {
- $implIncludes{"JS$type.h"} = 1;
- return "getJSRGBColor(exec, $value)";
- }
+
+ # Some SVG bindings don't have space to store a globalObject pointer, for those, we use the deprecatedGlobalObjectForPrototype hack for now.
+ my $globalObject = IsSVGTypeNeedingContextParameter($implClassName) ? "deprecatedGlobalObjectForPrototype(exec)" : "$thisValue->globalObject()";
if ($codeGenerator->IsPodType($type)) {
$implIncludes{"JS$type.h"} = 1;
@@ -1704,24 +1720,25 @@ sub NativeToJSValue
and $codeGenerator->IsPodTypeWithWriteableProperties($type)
and not defined $signature->extendedAttributes->{"Immutable"}) {
if ($codeGenerator->IsPodType($implClassName)) {
- return "toJS(exec, JSSVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($value, $thisValue->impl()).get(), $thisValue->context())";
+ return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($value, $thisValue->impl()).get(), $thisValue->context())";
} else {
- return "toJS(exec, JSSVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter).get(), imp)";
+ return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter).get(), imp)";
}
}
if ($implClassNameForValueConversion eq "") {
- if (IsSVGTypeNeedingContextParameter($implClassName)) {
- return "toJS(exec, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), castedThisObj->context())" if $inFunctionCall eq 1;
+ # SVGZoomEvent has no context() pointer, and is also not an SVGElement.
+ # This is not a problem, because SVGZoomEvent has no read/write properties.
+ return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), 0)" if $implClassName eq "SVGZoomEvent";
- # Special case: SVGZoomEvent - it doesn't have a context, but it's no problem, as there are no readwrite props
- return "toJS(exec, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), 0)" if $implClassName eq "SVGZoomEvent";
- return "toJS(exec, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), $thisValue->context())";
+ if (IsSVGTypeNeedingContextParameter($implClassName)) {
+ return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), castedThisObj->context())" if $inFunctionCall;
+ return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), $thisValue->context())";
} else {
- return "toJS(exec, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), imp)";
+ return "toJS(exec, $globalObject, JSSVGStaticPODTypeWrapper<$nativeType>::create($value).get(), imp)";
}
} else { # These classes, always have a m_context pointer!
- return "toJS(exec, JSSVGDynamicPODTypeWrapperCache<$nativeType, $implClassNameForValueConversion>::lookupOrCreateWrapper(imp, &${implClassNameForValueConversion}::$getter, &${implClassNameForValueConversion}::$setter).get(), $thisValue->context())";
+ return "toJS(exec, $globalObject, JSSVGDynamicPODTypeWrapperCache<$nativeType, $implClassNameForValueConversion>::lookupOrCreateWrapper(imp, &${implClassNameForValueConversion}::$getter, &${implClassNameForValueConversion}::$setter).get(), $thisValue->context())";
}
}
@@ -1754,18 +1771,15 @@ sub NativeToJSValue
return $value if $codeGenerator->IsSVGAnimatedType($type);
if (IsSVGTypeNeedingContextParameter($type)) {
- if (IsSVGTypeNeedingContextParameter($implClassName)) {
- return "toJS(exec, WTF::getPtr($value), $thisValue->context())";
- } else {
- return "toJS(exec, WTF::getPtr($value), imp)";
- }
+ my $contextPtr = IsSVGTypeNeedingContextParameter($implClassName) ? "$thisValue->context()" : "imp";
+ return "toJS(exec, $globalObject, WTF::getPtr($value), $contextPtr)";
}
if ($signature->extendedAttributes->{"ReturnsNew"}) {
- return "toJSNewlyCreated(exec, WTF::getPtr($value))";
+ return "toJSNewlyCreated(exec, $globalObject, WTF::getPtr($value))";
}
- return "toJS(exec, WTF::getPtr($value))";
+ return "toJS(exec, $globalObject, WTF::getPtr($value))";
}
sub ceilingToPowerOf2
@@ -1895,7 +1909,7 @@ tableSizeLoop:
push(@implContent, "};\n\n");
my $perfectSizeMask = $perfectSize - 1;
my $compactSizeMask = $numEntries - 1;
- push(@implContent, "static const HashTable $name =\n");
+ push(@implContent, "static JSC_CONST_HASHTABLE HashTable $name =\n");
push(@implContent, "#if ENABLE(PERFECT_HASH_SIZE)\n");
push(@implContent, " { $perfectSizeMask, $nameEntries, 0 };\n");
push(@implContent, "#else\n");
@@ -1964,17 +1978,17 @@ sub WriteData
# Write content to file.
print $IMPL @implContentHeader;
- foreach my $implInclude (sort keys(%implIncludes)) {
- my $checkType = $implInclude;
+ my @includes = ();
+ foreach my $include (keys %implIncludes) {
+ my $checkType = $include;
$checkType =~ s/\.h//;
+ next if $codeGenerator->IsSVGAnimatedType($checkType);
- print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ $include = "\"$include\"" unless $include =~ /^["<]/; # "
+ push @includes, $include;
}
-
- print $IMPL "\n";
-
- foreach my $implKJSInclude (sort keys(%implKJSInclude)) {
- print $IMPL "#include <runtime/$implKJSInclude>\n";
+ foreach my $include (sort @includes) {
+ print $IMPL "#include $include\n";
}
print $IMPL @implContent;
@@ -1984,15 +1998,19 @@ sub WriteData
@implContentHeader = ();
@implContent = ();
%implIncludes = ();
- %implKJSIncludes = ();
}
if (defined($HEADER)) {
# Write content to file.
print $HEADER @headerContentHeader;
- foreach my $headerInclude (sort keys(%headerIncludes)) {
- print $HEADER "#include \"$headerInclude\"\n";
+ my @includes = ();
+ foreach my $include (keys %headerIncludes) {
+ $include = "\"$include\"" unless $include =~ /^["<]/; # "
+ push @includes, $include;
+ }
+ foreach my $include (sort @includes) {
+ print $HEADER "#include $include\n";
}
print $HEADER @headerContent;
@@ -2012,14 +2030,15 @@ sub constructorFor
my $interfaceName = shift;
my $visibleClassName = shift;
my $canConstruct = shift;
+ my $constructorClassName = "${className}Constructor";
my $implContent = << "EOF";
-class ${className}Constructor : public DOMObject {
+class ${constructorClassName} : public DOMConstructorObject {
public:
- ${className}Constructor(ExecState* exec)
- : DOMObject(${className}Constructor::createStructure(exec->lexicalGlobalObject()->objectPrototype()))
+ ${constructorClassName}(ExecState* exec, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(${constructorClassName}::createStructure(globalObject->objectPrototype()), globalObject)
{
- putDirect(exec->propertyNames().prototype, ${protoClassName}::self(exec, exec->lexicalGlobalObject()), None);
+ putDirect(exec->propertyNames().prototype, ${protoClassName}::self(exec, globalObject), None);
}
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual const ClassInfo* classInfo() const { return &s_info; }
@@ -2033,13 +2052,13 @@ EOF
if ($canConstruct) {
$implContent .= << "EOF";
- static JSObject* construct(ExecState* exec, JSObject*, const ArgList&)
+ static JSObject* construct${interfaceName}(ExecState* exec, JSObject* constructor, const ArgList&)
{
- return asObject(toJS(exec, ${interfaceName}::create()));
+ return asObject(toJS(exec, static_cast<${constructorClassName}*>(constructor)->globalObject(), ${interfaceName}::create()));
}
virtual ConstructType getConstructData(ConstructData& constructData)
{
- constructData.native.function = construct;
+ constructData.native.function = construct${interfaceName};
return ConstructTypeHost;
}
EOF
@@ -2048,16 +2067,16 @@ EOF
$implContent .= << "EOF";
};
-const ClassInfo ${className}Constructor::s_info = { "${visibleClassName}Constructor", 0, &${className}ConstructorTable, 0 };
+const ClassInfo ${constructorClassName}::s_info = { "${visibleClassName}Constructor", 0, &${constructorClassName}Table, 0 };
-bool ${className}Constructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+bool ${constructorClassName}::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
- return getStaticValueSlot<${className}Constructor, DOMObject>(exec, &${className}ConstructorTable, this, propertyName, slot);
+ return getStaticValueSlot<${constructorClassName}, DOMObject>(exec, &${constructorClassName}Table, this, propertyName, slot);
}
EOF
- $implKJSInclude{"JSNumberCell.h"} = 1;
+ $implJSCInclude{"JSNumberCell.h"} = 1; # FIXME: What is this for?
return $implContent;
}
diff --git a/WebCore/bindings/scripts/CodeGeneratorObjC.pm b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
index fc265f9..f449e19 100644
--- a/WebCore/bindings/scripts/CodeGeneratorObjC.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorObjC.pm
@@ -515,15 +515,17 @@ sub AddIncludesForType
{
my $type = $codeGenerator->StripModule(shift);
- return if $codeGenerator->IsNonPointerType($type) or IsNativeObjCType($type);
+ return if $codeGenerator->IsNonPointerType($type);
- if ($codeGenerator->IsStringType($type)) {
- $implIncludes{"KURL.h"} = 1;
+ if (IsNativeObjCType($type)) {
+ if ($type eq "Color") {
+ $implIncludes{"ColorMac.h"} = 1;
+ }
return;
}
- if ($type eq "RGBColor") {
- $implIncludes{"DOMRGBColorInternal.h"} = 1;
+ if ($codeGenerator->IsStringType($type)) {
+ $implIncludes{"KURL.h"} = 1;
return;
}
@@ -924,8 +926,6 @@ sub GenerateHeader
if ($codeGenerator->IsSVGAnimatedType($interfaceName)) {
push(@internalHeaderContent, "#import <WebCore/SVGAnimatedTemplate.h>\n\n");
- } elsif ($interfaceName eq "RGBColor") {
- push(@internalHeaderContent, "#import <WebCore/Color.h>\n\n");
} else {
push(@internalHeaderContent, "namespace WebCore {\n");
$startedNamespace = 1;
@@ -1059,9 +1059,12 @@ sub GenerateImplementation
# Only generate 'dealloc' and 'finalize' methods for direct subclasses of DOMObject.
if ($parentImplClassName eq "Object") {
+ $implIncludes{"WebCoreObjCExtras.h"} = 1;
push(@implContent, "- (void)dealloc\n");
push(@implContent, "{\n");
- push(@implContent, " $assertMainThread\n");
+ push(@implContent, " if (WebCoreObjCScheduleDeallocateOnMainThread([$className class], self))\n");
+ push(@implContent, " return;\n");
+ push(@implContent, "\n");
if ($interfaceName eq "NodeIterator") {
push(@implContent, " if (_internal) {\n");
push(@implContent, " [self detach];\n");
@@ -1129,7 +1132,17 @@ sub GenerateImplementation
# - GETTER
my $getterSig = "- ($attributeType)$attributeInterfaceName\n";
my $hasGetterException = @{$attribute->getterExceptions};
- my $getterContentHead = "IMPL->" . $codeGenerator->WK_lcfirst($attributeName) . "(";
+ my $getterContentHead;
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL);
+ my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
+ $getterContentHead = "IMPL->${getAttributeFunctionName}(WebCore::HTMLNames::${contentAttributeName}Attr";
+ } else {
+ $getterContentHead = "IMPL->" . $codeGenerator->WK_lcfirst($attributeName) . "(";
+ }
my $getterContentTail = ")";
# Special case for DOMSVGNumber
@@ -1188,6 +1201,9 @@ sub GenerateImplementation
} elsif (IsProtocolType($idlType) and $idlType ne "EventTarget") {
$getterContentHead = "kit($getterContentHead";
$getterContentTail .= ")";
+ } elsif ($idlType eq "Color") {
+ $getterContentHead = "WebCore::nsColor($getterContentHead";
+ $getterContentTail .= ")";
} elsif (ConversionNeeded($attribute->signature->type)) {
$getterContentHead = "kit(WTF::getPtr($getterContentHead";
$getterContentTail .= "))";
@@ -1226,7 +1242,7 @@ sub GenerateImplementation
# Exception handling
my $hasSetterException = @{$attribute->setterExceptions};
- $attributeName = "set" . $codeGenerator->WK_ucfirst($attributeName);
+ my $coreSetterName = "set" . $codeGenerator->WK_ucfirst($attributeName);
my $setterName = "set" . ucfirst($attributeInterfaceName);
my $argName = "new" . ucfirst($attributeInterfaceName);
my $arg = GetObjCTypeGetter($argName, $idlType);
@@ -1252,14 +1268,22 @@ sub GenerateImplementation
if ($podType eq "float") {
push(@implContent, " *IMPL = $arg;\n");
} else {
- push(@implContent, " IMPL->$attributeName($arg);\n");
+ push(@implContent, " IMPL->$coreSetterName($arg);\n");
}
} elsif ($hasSetterException) {
push(@implContent, " $exceptionInit\n");
- push(@implContent, " IMPL->$attributeName($arg, ec);\n");
+ push(@implContent, " IMPL->$coreSetterName($arg, ec);\n");
push(@implContent, " $exceptionRaiseOnError\n");
} else {
- push(@implContent, " IMPL->$attributeName($arg);\n");
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = (($reflect || $reflectURL) eq "1") ? $attributeName : ($reflect || $reflectURL);
+ push(@implContent, " IMPL->setAttribute(WebCore::HTMLNames::${contentAttributeName}Attr, $arg);\n");
+ } else {
+ push(@implContent, " IMPL->$coreSetterName($arg);\n");
+ }
}
push(@implContent, "}\n\n");
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
new file mode 100644
index 0000000..f696e9f
--- /dev/null
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -0,0 +1,2228 @@
+
+# Copyright (C) 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
+# Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
+# Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+# Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
+# Copyright (C) 2006 Apple Computer, Inc.
+# Copyright (C) 2007, 2008, 2009 Google Inc.
+#
+# 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+package CodeGeneratorV8;
+
+use File::stat;
+use Digest::MD5;
+
+my $module = "";
+my $outputDir = "";
+
+my @headerContent = ();
+my @implContentHeader = ();
+my @implFixedHeader = ();
+my @implContent = ();
+my @implContentDecls = ();
+my %implIncludes = ();
+
+my @allParents = ();
+
+# Default .h template
+my $headerTemplate = << "EOF";
+/*
+ This file is part of the WebKit open source project.
+ This file has been generated by generate-bindings.pl. DO NOT MODIFY!
+
+ 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+EOF
+
+# Default constructor
+sub new
+{
+ my $object = shift;
+ my $reference = { };
+
+ $codeGenerator = shift;
+ $outputDir = shift;
+
+ bless($reference, $object);
+ return $reference;
+}
+
+sub finish
+{
+ my $object = shift;
+
+ # Commit changes!
+ $object->WriteData();
+}
+
+sub leftShift($$) {
+ my ($value, $distance) = @_;
+ return (($value << $distance) & 0xFFFFFFFF);
+}
+
+# Uppercase the first letter, while respecting WebKit style guidelines.
+# E.g., xmlEncoding becomes XMLEncoding, but xmlllang becomes Xmllang.
+sub WK_ucfirst
+{
+ my $param = shift;
+ my $ret = ucfirst($param);
+ $ret =~ s/Xml/XML/ if $ret =~ /^Xml[^a-z]/;
+ return $ret;
+}
+
+# Lowercase the first letter while respecting WebKit style guidelines.
+# URL becomes url, but SetURL becomes setURL.
+sub WK_lcfirst
+{
+ my $param = shift;
+ my $ret = lcfirst($param);
+ $ret =~ s/uRL/url/;
+ return $ret;
+}
+
+# Workaround for V8 bindings difference where RGBColor is not a POD type.
+sub IsPodType
+{
+ my $type = shift;
+ return $codeGenerator->IsPodType($type);
+}
+
+# Params: 'domClass' struct
+sub GenerateInterface
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my $defines = shift;
+
+ # Start actual generation
+ $object->GenerateHeader($dataNode);
+ $object->GenerateImplementation($dataNode);
+
+ my $name = $dataNode->name;
+
+ # Open files for writing
+ my $headerFileName = "$outputDir/V8$name.h";
+ my $implFileName = "$outputDir/V8$name.cpp";
+
+ open($IMPL, ">$implFileName") || die "Couldn't open file $implFileName";
+ open($HEADER, ">$headerFileName") || die "Couldn't open file $headerFileName";
+}
+
+# Params: 'idlDocument' struct
+sub GenerateModule
+{
+ my $object = shift;
+ my $dataNode = shift;
+
+ $module = $dataNode->module;
+}
+
+sub GetLegacyHeaderIncludes
+{
+ my $legacyParent = shift;
+
+ die "Don't know what headers to include for module $module";
+}
+
+sub AvoidInclusionOfType
+{
+ my $type = shift;
+
+ # Special case: SVGRect.h / SVGPoint.h / SVGNumber.h / SVGMatrix.h do not exist.
+ return 1 if $type eq "SVGRect" or $type eq "SVGPoint" or $type eq "SVGNumber" or $type eq "SVGMatrix";
+ return 0;
+}
+
+sub UsesManualToJSImplementation
+{
+ my $type = shift;
+
+ return 1 if $type eq "SVGPathSeg";
+ return 0;
+}
+
+sub AddIncludesForType
+{
+ my $type = $codeGenerator->StripModule(shift);
+
+ # 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)) {
+ } elsif ($type =~ /SVGPathSeg/) {
+ $joinedName = $type;
+ $joinedName =~ s/Abs|Rel//;
+ $implIncludes{"${joinedName}.h"} = 1;
+ } else {
+ # default, include the same named file
+ $implIncludes{GetImplementationFileName(${type})} = 1;
+ }
+
+ # additional includes (things needed to compile the bindings but not the header)
+
+ if ($type eq "CanvasRenderingContext2D") {
+ $implIncludes{"CanvasGradient.h"} = 1;
+ $implIncludes{"CanvasPattern.h"} = 1;
+ $implIncludes{"CanvasStyle.h"} = 1;
+ }
+
+ if ($type eq "CanvasGradient" or $type eq "XPathNSResolver") {
+ $implIncludes{"PlatformString.h"} = 1;
+ }
+
+ if ($type eq "CSSStyleDeclaration") {
+ $implIncludes{"CSSMutableStyleDeclaration.h"} = 1;
+ }
+
+ if ($type eq "Plugin" or $type eq "PluginArray" or $type eq "MimeTypeArray") {
+ # So we can get String -> AtomicString conversion for namedItem().
+ $implIncludes{"AtomicString.h"} = 1;
+ }
+}
+
+sub AddIncludesForSVGAnimatedType
+{
+ my $type = shift;
+ $type =~ s/SVGAnimated//;
+
+ if ($type eq "Point" or $type eq "Rect") {
+ $implIncludes{"Float$type.h"} = 1;
+ } elsif ($type eq "String") {
+ $implIncludes{"PlatformString.h"} = 1;
+ }
+
+ $implIncludes{"SVGAnimatedTemplate.h"} = 1;
+}
+
+sub AddClassForwardIfNeeded
+{
+ my $implClassName = shift;
+
+ # SVGAnimatedLength/Number/etc.. are typedefs to SVGAnimtatedTemplate, so don't use class forwards for them!
+ push(@headerContent, "class $implClassName;\n\n") unless $codeGenerator->IsSVGAnimatedType($implClassName);
+}
+
+sub GetImplementationFileName
+{
+ my $iface = shift;
+ return "HTMLCollection.h" if $iface eq "HTMLAllCollection";
+ return "Event.h" if $iface eq "DOMTimeStamp";
+ return "NamedAttrMap.h" if $iface eq "NamedNodeMap";
+ return "NameNodeList.h" if $iface eq "NodeList";
+ return "XMLHttpRequest.h" if $iface eq "XMLHttpRequest";
+
+ return "${iface}.h";
+}
+
+# If the node has a [Conditional=XXX] attribute, returns an "ENABLE(XXX)" string for use in an #if.
+sub GenerateConditionalString
+{
+ my $node = shift;
+ my $conditional = $node->extendedAttributes->{"Conditional"};
+ if ($conditional) {
+ return "ENABLE(" . join(") && ENABLE(", split(/&/, $conditional)) . ")";
+ } else {
+ return "";
+ }
+}
+
+sub GenerateHeader
+{
+ my $object = shift;
+ my $dataNode = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $className = "V8$interfaceName";
+ my $implClassName = $interfaceName;
+
+ # Copy contents of parent classes except the first parent or if it is
+ # EventTarget.
+ $codeGenerator->AddMethodsConstantsAndAttributesFromParentClasses($dataNode);
+
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $conditionalString = GenerateConditionalString($dataNode);
+
+ # - Add default header template
+ @headerContent = split("\r", $headerTemplate);
+
+ push(@headerContent, "\n#if ${conditionalString}\n\n") if $conditionalString;
+ push(@headerContent, "\n#ifndef $className" . "_H");
+ push(@headerContent, "\n#define $className" . "_H\n\n");
+
+ # Get correct pass/store types respecting PODType flag
+ my $podType = $dataNode->extendedAttributes->{"PODType"};
+ my $passType = $podType ? "JSSVGPODTypeWrapper<$podType>*" : "$implClassName*";
+
+ push(@headerContent, "#include \"$podType.h\"\n") if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
+
+ push(@headerContent, "#include <v8.h>\n");
+ push(@headerContent, "#include <wtf/HashMap.h>\n");
+ push(@headerContent, "#include \"StringHash.h\"\n");
+
+ push(@headerContent, "\nnamespace WebCore {\n\n");
+ push(@headerContent, "class V8ClassIndex;\n");
+ push(@headerContent, "\nclass $className {\n");
+ push(@headerContent, <<END);
+
+ public:
+ static bool HasInstance(v8::Handle<v8::Value> value);
+ static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
+END
+
+ if ($implClassName eq "DOMWindow") {
+ push(@headerContent, <<END);
+ static v8::Persistent<v8::ObjectTemplate> GetShadowObjectTemplate();
+END
+ }
+
+ push(@headerContent, <<END);
+
+ private:
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+
+ friend class V8ClassIndex;
+};
+
+END
+
+ push(@headerContent, "}\n\n");
+ push(@headerContent, "#endif // $className" . "_H\n");
+
+ push(@headerContent, "#endif // ${conditionalString}\n\n") if $conditionalString;
+}
+
+
+sub GenerateSetDOMException
+{
+ my $indent = shift;
+ my $result = "";
+
+ $result .= $indent . "if (ec) {\n";
+ $result .= $indent . " V8Proxy::setDOMException(ec);\n";
+ $result .= $indent . " return v8::Handle<v8::Value>();\n";
+ $result .= $indent . "}\n";
+
+ return $result;
+}
+
+sub IsNodeSubType
+{
+ my $dataNode = shift;
+ return 1 if ($dataNode->name eq "Node");
+ foreach (@allParents) {
+ my $parent = $codeGenerator->StripModule($_);
+ return 1 if $parent eq "Node";
+ }
+ return 0;
+}
+
+sub HolderToNative
+{
+ my $dataNode = shift;
+ my $implClassName = shift;
+ my $classIndex = shift;
+
+ if (IsNodeSubType($dataNode)) {
+ push(@implContentDecls, <<END);
+ $implClassName* imp = V8DOMWrapper::convertDOMWrapperToNode<$implClassName>(holder);
+END
+
+ } else {
+ push(@implContentDecls, <<END);
+ $implClassName* imp = V8DOMWrapper::convertToNativeObject<$implClassName>(V8ClassIndex::$classIndex, holder);
+END
+
+ }
+}
+
+sub GenerateDomainSafeFunctionGetter
+{
+ my $function = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $className = "V8" . $dataNode->name;
+ my $funcName = $function->signature->name;
+
+ my $signature = "v8::Signature::New(" . $className . "::GetRawTemplate())";
+ if ($function->signature->extendedAttributes->{"V8DoNotCheckSignature"}) {
+ $signature = "v8::Local<v8::Signature>()";
+ }
+
+ my $newTemplateString = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+
+ $implIncludes{"V8Proxy.h"} = 1;
+
+ push(@implContentDecls, <<END);
+ static v8::Handle<v8::Value> ${funcName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+ INC_STATS(\"DOM.$implClassName.$funcName._get\");
+ static v8::Persistent<v8::FunctionTemplate> private_template =
+ v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ if (holder.IsEmpty()) {
+ // can only reach here by 'object.__proto__.func', and it should passed
+ // domain security check already
+
+ return private_template->GetFunction();
+ }
+END
+
+ HolderToNative($dataNode, $implClassName, $classIndex);
+
+ push(@implContentDecls, <<END);
+ if (!V8Proxy::canAccessFrame(imp->frame(), false)) {
+ static v8::Persistent<v8::FunctionTemplate> shared_template =
+ v8::Persistent<v8::FunctionTemplate>::New($newTemplateString);
+ return shared_template->GetFunction();
+
+ } else {
+ return private_template->GetFunction();
+ }
+ }
+
+END
+}
+
+sub GenerateConstructorGetter
+{
+ my $implClassName = shift;
+ my $classIndex = shift;
+
+ push(@implContentDecls, <<END);
+ static v8::Handle<v8::Value> ${implClassName}ConstructorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+ INC_STATS(\"DOM.$implClassName.constructors._get\");
+ v8::Handle<v8::Value> data = info.Data();
+ ASSERT(data->IsNumber());
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::FromInt(data->Int32Value());
+END
+
+ if ($classIndex eq "DOMWINDOW") {
+ push(@implContentDecls, <<END);
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
+ // Get the proxy corresponding to the DOMWindow if possible to
+ // make sure that the constructor function is constructed in the
+ // context of the DOMWindow and not in the context of the caller.
+ return V8DOMWrapper::getConstructor(type, window);
+END
+ } elsif ($classIndex eq "DEDICATEDWORKERCONTEXT" or $classIndex eq "WORKERCONTEXT" or $classIndex eq "SHAREDWORKERCONTEXT") {
+ $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
+ push(@implContentDecls, <<END);
+ WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
+ return V8DOMWrapper::getConstructor(type, workerContext);
+END
+ } else {
+ push(@implContentDecls, " return v8::Undefined();");
+ }
+
+ push(@implContentDecls, <<END);
+
+ }
+
+END
+}
+
+sub GenerateNormalAttrGetter
+{
+ my $attribute = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ my $attrName = $attribute->signature->name;
+ $implIncludes{"V8Proxy.h"} = 1;
+
+ my $attrType = GetTypeFromSignature($attribute->signature);
+ my $attrIsPodType = IsPodType($attrType);
+
+ my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
+ my $isPodType = IsPodType($implClassName);
+ my $skipContext = 0;
+
+
+ if ($isPodType) {
+ $implClassName = GetNativeType($implClassName);
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+ }
+
+ # Special case: SVGZoomEvent's attributes are all read-only
+ if ($implClassName eq "SVGZoomEvent") {
+ $attrIsPodType = 0;
+ $skipContext = 1;
+ }
+
+ # Special case: SVGSVGEelement::viewport is read-only
+ if (($implClassName eq "SVGSVGElement") and ($attrName eq "viewport")) {
+ $attrIsPodType = 0;
+ $skipContext = 1;
+ }
+
+ # Special case for SVGColor
+ if (($implClassName eq "SVGColor") and ($attrName eq "rgbColor")) {
+ $attrIsPodType = 0;
+ }
+
+ my $getterStringUsesImp = $implClassName ne "double";
+
+ # Getter
+ push(@implContentDecls, <<END);
+ static v8::Handle<v8::Value> ${attrName}AttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) {
+ INC_STATS(\"DOM.$implClassName.$attrName._get\");
+END
+
+ if ($isPodType) {
+ push(@implContentDecls, <<END);
+ V8SVGPODTypeWrapper<$implClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());
+ $implClassName imp_instance = *imp_wrapper;
+END
+ if ($getterStringUsesImp) {
+ push(@implContentDecls, <<END);
+ $implClassName* imp = &imp_instance;
+END
+ }
+
+ } elsif ($attrExt->{"v8OnProto"} || $attrExt->{"V8DisallowShadowing"}) {
+ # perform lookup first
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ if (holder.IsEmpty()) return v8::Undefined();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ } else {
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = info.Holder();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ }
+
+ # Generate security checks if necessary
+ if ($attribute->signature->extendedAttributes->{"CheckNodeSecurity"}) {
+ push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->$attrName())) return v8::Undefined();\n\n");
+ } elsif ($attribute->signature->extendedAttributes->{"CheckFrameSecurity"}) {
+ push(@implContentDecls, " if (!V8Proxy::checkNodeSecurity(imp->contentDocument())) return v8::Undefined();\n\n");
+ }
+
+ my $useExceptions = 1 if @{$attribute->getterExceptions} and !($isPodType);
+ if ($useExceptions) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ }
+
+ if ($attribute->signature->extendedAttributes->{"v8referenceattr"}) {
+ $attrName = $attribute->signature->extendedAttributes->{"v8referenceattr"};
+ }
+
+ my $getterFunc = WK_lcfirst($attrName);
+ $getterFunc .= "Animated" if $codeGenerator->IsSVGAnimatedType($attribute->signature->type);
+
+ my $returnType = GetTypeFromSignature($attribute->signature);
+
+ my $getterString;
+ if ($getterStringUsesImp) {
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
+ my $getAttributeFunctionName = $reflectURL ? "getURLAttribute" : "getAttribute";
+ $getterString = "imp->$getAttributeFunctionName(HTMLNames::${contentAttributeName}Attr";
+ } else {
+ $getterString = "imp->$getterFunc(";
+ }
+ $getterString .= "ec" if $useExceptions;
+ $getterString .= ")";
+ if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $getterString .= ".toInt()";
+ }
+ } else {
+ $getterString = "imp_instance";
+ }
+
+ if ($nativeType eq "String") {
+ $getterString = "toString($getterString)";
+ }
+
+ my $result;
+ my $wrapper;
+
+ if ($attrIsPodType) {
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+
+ my $getter = $getterString;
+ $getter =~ s/imp->//;
+ $getter =~ s/\(\)//;
+ my $setter = "set" . WK_ucfirst($getter);
+
+ my $implClassIsAnimatedType = $codeGenerator->IsSVGAnimatedType($implClassName);
+ if (not $implClassIsAnimatedType and $codeGenerator->IsPodTypeWithWriteableProperties($attrType) and not defined $attribute->signature->extendedAttributes->{"Immutable"}) {
+ if (IsPodType($implClassName)) {
+ my $wrapper = "V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName>::create($getterString, imp_wrapper)";
+ push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithPODTypeParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
+ } else {
+ my $wrapper = "V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName>::create(imp, &${implClassName}::$getter, &${implClassName}::$setter)";
+ push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapperWithParent<$nativeType, $implClassName> > wrapper = $wrapper;\n");
+ }
+ } else {
+ if ($implClassIsAnimatedType) {
+ # We can't hash member function pointers, so instead generate
+ # some hashing material based on the names of the methods.
+ my $hashhex = substr(Digest::MD5::md5_hex("${implClassName}::$getter ${implClassName}::$setter)"), 0, 8);
+ my $wrapper = "V8SVGDynamicPODTypeWrapperCache<$nativeType, $implClassName>::lookupOrCreateWrapper(imp, &${implClassName}::$getter, &${implClassName}::$setter, 0x$hashhex)";
+ push(@implContentDecls, " RefPtr<V8SVGPODTypeWrapper<" . $nativeType . "> > wrapper = $wrapper;\n");
+ } else {
+ my $wrapper = GenerateSVGStaticPodTypeWrapper($returnType, $getterString);
+ push(@implContentDecls, " RefPtr<V8SVGStaticPODTypeWrapper<" . $nativeType . "> > wrapper = $wrapper;\n");
+ }
+ }
+
+ } else {
+ push(@implContentDecls, " $nativeType v = ");
+
+ push(@implContentDecls, "$getterString;\n");
+
+ if ($useExceptions) {
+ push(@implContentDecls, GenerateSetDOMException(" "));
+ }
+
+ $result = "v";
+ }
+
+ if (IsSVGTypeNeedingContextParameter($attrType) && !$skipContext) {
+ my $resultObject = $result;
+ if ($attrIsPodType) {
+ $resultObject = "wrapper";
+ }
+ $resultObject = "WTF::getPtr(" . $resultObject . ")";
+ push(@implContentDecls, GenerateSVGContextAssignment($implClassName, $resultObject, " "));
+ }
+
+ if ($attrIsPodType) {
+ my $classIndex = uc($attrType);
+ push(@implContentDecls, " return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n");
+ } else {
+ $result .= ".release()" if (IsRefPtrType($attrType));
+ push(@implContentDecls, " " . ReturnNativeToJSValue($attribute->signature, $result, " ").";\n");
+ }
+
+ push(@implContentDecls, " }\n\n"); # end of getter
+}
+
+
+sub GenerateReplaceableAttrSetter
+{
+ my $implClassName = shift;
+
+ $implIncludes{"V8Proxy.h"} = 1;
+
+ push(@implContentDecls,
+ " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
+ " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
+
+ push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
+
+ push(@implContentDecls, " v8::Local<v8::String> ${attrName}_string = v8::String::New(\"${attrName}\");\n");
+ push(@implContentDecls, " info.Holder()->Delete(${attrName}_string);\n");
+ push(@implContentDecls, " info.This()->Set(${attrName}_string, value);\n");
+ push(@implContentDecls, " }\n\n");
+}
+
+
+sub GenerateNormalAttrSetter
+{
+ my $attribute = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ $implIncludes{"V8Proxy.h"} = 1;
+
+ push(@implContentDecls,
+ " static void ${attrName}AttrSetter(v8::Local<v8::String> name," .
+ " v8::Local<v8::Value> value, const v8::AccessorInfo& info) {\n");
+
+ push(@implContentDecls, " INC_STATS(\"DOM.$implClassName.$attrName._set\");\n");
+
+ my $isPodType = IsPodType($implClassName);
+
+ if ($isPodType) {
+ $implClassName = GetNativeType($implClassName);
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$implClassName>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$implClassName> >(V8ClassIndex::$classIndex, info.Holder());\n");
+ push(@implContentDecls, " $implClassName imp_instance = *wrapper;\n");
+ push(@implContentDecls, " $implClassName* imp = &imp_instance;\n");
+
+ } elsif ($attrExt->{"v8OnProto"}) {
+ # perform lookup first
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::$classIndex, info.This());
+ if (holder.IsEmpty()) return v8::Undefined();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ } else {
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = info.Holder();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ }
+
+ my $nativeType = GetNativeTypeFromSignature($attribute->signature, 0);
+ push(@implContentDecls, " $nativeType v = " . JSValueToNative($attribute->signature, "value") . ";\n");
+
+ my $result = "";
+ if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $result .= "WebCore::String::number(";
+ }
+ $result .= "v";
+ if ($nativeType eq "int" and $attribute->signature->extendedAttributes->{"ConvertFromString"}) {
+ $result .= ")";
+ }
+ my $returnType = GetTypeFromSignature($attribute->signature);
+ if (IsRefPtrType($returnType)) {
+ $result = "WTF::getPtr(" . $result . ")";
+ }
+
+ my $useExceptions = 1 if @{$attribute->setterExceptions} and !($isPodType);
+
+ if ($useExceptions) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ }
+
+ if ($implClassName eq "double") {
+ push(@implContentDecls, " *imp = $result;\n");
+ } else {
+ my $implSetterFunctionName = WK_ucfirst($attrName);
+ my $reflect = $attribute->signature->extendedAttributes->{"Reflect"};
+ my $reflectURL = $attribute->signature->extendedAttributes->{"ReflectURL"};
+ if ($reflect || $reflectURL) {
+ $implIncludes{"HTMLNames.h"} = 1;
+ my $contentAttributeName = ($reflect || $reflectURL) eq "1" ? $attrName : ($reflect || $reflectURL);
+ push(@implContentDecls, " imp->setAttribute(HTMLNames::${contentAttributeName}Attr, $result");
+ } else {
+ push(@implContentDecls, " imp->set$implSetterFunctionName(" . $result);
+ }
+ push(@implContentDecls, ", ec") if $useExceptions;
+ push(@implContentDecls, ");\n");
+ }
+
+ if ($useExceptions) {
+ push(@implContentDecls, " V8Proxy::setDOMException(ec);\n");
+ }
+
+ if ($isPodType) {
+ push(@implContentDecls, " wrapper->commitChange(*imp, V8Proxy::svgContext(wrapper));\n");
+ } elsif (IsSVGTypeNeedingContextParameter($implClassName)) {
+ $implIncludes{"SVGElement.h"} = 1;
+
+ my $currentObject = "imp";
+ if ($isPodType) {
+ $currentObject = "wrapper";
+ }
+
+ push(@implContentDecls, " if (SVGElement* context = V8Proxy::svgContext($currentObject)) {\n");
+ push(@implContentDecls, " context->svgAttributeChanged(imp->associatedAttributeName());\n");
+ push(@implContentDecls, " }\n");
+ }
+
+ push(@implContentDecls, " return;\n");
+ push(@implContentDecls, " }\n\n"); # end of setter
+}
+
+sub GenerateNewFunctionTemplate
+{
+ $function = shift;
+ $dataNode = shift;
+ $signature = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $name = $function->signature->name;
+
+ if ($function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ if ($function->signature->extendedAttributes->{"Custom"} &&
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ die "Custom and V8Custom should be mutually exclusive!"
+ }
+ my $customFunc = $function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"};
+ if ($customFunc eq 1) {
+ $customFunc = $interfaceName . WK_ucfirst($name);
+ }
+ return "v8::FunctionTemplate::New(V8Custom::v8${customFunc}Callback, v8::Handle<v8::Value>(), $signature)";
+ } else {
+ return "v8::FunctionTemplate::New(${interfaceName}Internal::${name}Callback, v8::Handle<v8::Value>(), $signature)";
+ }
+}
+
+sub GenerateFunctionCallback
+{
+ my $function = shift;
+ my $dataNode = shift;
+ my $classIndex = shift;
+ my $implClassName = shift;
+
+ my $interfaceName = $dataNode->name;
+ my $name = $function->signature->name;
+
+ push(@implContentDecls,
+" static v8::Handle<v8::Value> ${name}Callback(const v8::Arguments& args) {\n" .
+" INC_STATS(\"DOM.$implClassName.$name\");\n");
+
+ my $numParameters = @{$function->parameters};
+
+ if ($function->signature->extendedAttributes->{"RequiresAllArguments"}) {
+ push(@implContentDecls,
+ " if (args.Length() < $numParameters) return v8::Undefined();\n");
+ }
+
+ if (IsPodType($implClassName)) {
+ my $nativeClassName = GetNativeType($implClassName);
+ push(@implContentDecls, " V8SVGPODTypeWrapper<$nativeClassName>* imp_wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<$nativeClassName> >(V8ClassIndex::$classIndex, args.Holder());\n");
+ push(@implContentDecls, " $nativeClassName imp_instance = *imp_wrapper;\n");
+ push(@implContentDecls, " $nativeClassName* imp = &imp_instance;\n");
+ } else {
+ push(@implContentDecls, <<END);
+ v8::Handle<v8::Object> holder = args.Holder();
+END
+ HolderToNative($dataNode, $implClassName, $classIndex);
+ }
+
+ # Check domain security if needed
+ if (($dataNode->extendedAttributes->{"CheckDomainSecurity"}
+ || $interfaceName eq "DOMWindow")
+ && !$function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
+ # We have not find real use cases yet.
+ push(@implContentDecls,
+" if (!V8Proxy::canAccessFrame(imp->frame(), true)) {\n".
+" return v8::Undefined();\n" .
+" }\n");
+ }
+
+
+ if (@{$function->raisesExceptions}) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls, " ExceptionCode ec = 0;\n");
+ }
+
+ if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
+ push(@implContentDecls, " ScriptCallStack callStack(args, $numParameters);\n");
+ $implIncludes{"ScriptCallStack.h"} = 1;
+ }
+
+ my $paramIndex = 0;
+ foreach my $parameter (@{$function->parameters}) {
+ TranslateParameter($parameter);
+
+ my $parameterName = $parameter->name;
+
+ if ($parameter->extendedAttributes->{"Optional"}) {
+ # Generate early call if there are not enough parameters.
+ push(@implContentDecls, " if (args.Length() <= $paramIndex) {\n");
+ my $functionCall = GenerateFunctionCallString($function, $paramIndex, " " x 2, $implClassName);
+ push(@implContentDecls, $functionCall);
+ push(@implContentDecls, " }\n");
+ }
+
+ if (BasicTypeCanFailConversion($parameter)) {
+ push(@implContentDecls, " bool ${parameterName}Ok;\n");
+ }
+
+ push(@implContentDecls, " " . GetNativeTypeFromSignature($parameter, 1) . " $parameterName = ");
+ push(@implContentDecls, JSValueToNative($parameter, "args[$paramIndex]",
+ BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ";\n");
+
+ if (TypeCanFailConversion($parameter)) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls,
+" if (!$parameterName" . (BasicTypeCanFailConversion($parameter) ? "Ok" : "") . ") {\n" .
+" V8Proxy::setDOMException(TYPE_MISMATCH_ERR);\n" .
+" return v8::Handle<v8::Value>();\n" .
+" }\n");
+ }
+
+ if ($parameter->extendedAttributes->{"IsIndex"}) {
+ $implIncludes{"ExceptionCode.h"} = 1;
+ push(@implContentDecls,
+" if ($parameterName < 0) {\n" .
+" V8Proxy::setDOMException(INDEX_SIZE_ERR);\n" .
+" return v8::Handle<v8::Value>();\n" .
+" }\n");
+ }
+
+ $paramIndex++;
+ }
+
+ # Build the function call string.
+ my $callString = GenerateFunctionCallString($function, $paramIndex, " ", $implClassName);
+ push(@implContentDecls, "$callString");
+ push(@implContentDecls, " }\n\n");
+}
+
+sub GenerateBatchedAttributeData
+{
+ my $interfaceName = shift;
+ my $attributes = shift;
+
+ foreach my $attribute (@$attributes) {
+ my $attrName = $attribute->signature->name;
+ my $attrExt = $attribute->signature->extendedAttributes;
+
+ my $accessControl = "v8::DEFAULT";
+ if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
+ $accessControl = "v8::ALL_CAN_READ";
+ } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
+ $accessControl = "v8::ALL_CAN_WRITE";
+ } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
+ $accessControl = "v8::ALL_CAN_READ";
+ if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
+ $accessControl .= "|v8::ALL_CAN_WRITE";
+ }
+ }
+ if ($attrExt->{"V8DisallowShadowing"}) {
+ $accessControl .= "|v8::PROHIBITS_OVERWRITING";
+ }
+ $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
+
+ my $customAccessor =
+ $attrExt->{"Custom"} ||
+ $attrExt->{"CustomSetter"} ||
+ $attrExt->{"CustomGetter"} ||
+ $attrExt->{"V8Custom"} ||
+ $attrExt->{"V8CustomSetter"} ||
+ $attrExt->{"V8CustomGetter"} ||
+ "";
+ if ($customAccessor eq 1) {
+ # use the naming convension, interface + (capitalize) attr name
+ $customAccessor = $interfaceName . WK_ucfirst($attrName);
+ }
+
+ my $getter;
+ my $setter;
+ my $propAttr = "v8::None";
+ my $hasCustomSetter = 0;
+
+ # Check attributes.
+ if ($attrExt->{"DontEnum"}) {
+ $propAttr .= "|v8::DontEnum";
+ }
+ if ($attrExt->{"V8DisallowShadowing"}) {
+ $propAttr .= "|v8::DontDelete";
+ }
+
+ my $on_proto = "0 /* on instance */";
+ my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
+
+ # Constructor
+ if ($attribute->signature->type =~ /Constructor$/) {
+ my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
+ $constructorType =~ s/Constructor$//;
+ my $constructorIndex = uc($constructorType);
+ $data = "V8ClassIndex::${constructorIndex}";
+ $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
+ $setter = "0";
+ $propAttr = "v8::ReadOnly";
+
+ # EventListeners
+ } elsif ($attribute->signature->type eq "EventListener") {
+ if ($interfaceName eq "DOMWindow") {
+ $getter = "V8Custom::v8DOMWindowEventHandlerAccessorGetter";
+ $setter = "V8Custom::v8DOMWindowEventHandlerAccessorSetter";
+ } elsif ($interfaceName eq "Element" || $interfaceName eq "Document" || $interfaceName eq "HTMLBodyElement" || $interfaceName eq "SVGElementInstance" || $interfaceName eq "HTMLFrameSetElement") {
+ $getter = "V8Custom::v8NodeEventHandlerAccessorGetter";
+ $setter = "V8Custom::v8NodeEventHandlerAccessorSetter";
+ } elsif ($interfaceName eq "DOMApplicationCache") {
+ $getter = "V8Custom::v8DOMApplicationCacheEventHandlerAccessorGetter";
+ $setter = "V8Custom::v8DOMApplicationCacheEventHandlerAccessorSetter";
+ } else {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
+ $setter = "0";
+ $propAttr = "v8::ReadOnly";
+ } else {
+ $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+ }
+ }
+
+ # Custom Getter and Setter
+ } elsif ($attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ if ($interfaceName eq "WorkerContext" and $attrName eq "self") {
+ $setter = "0";
+ $propAttr = "v8::ReadOnly";
+ } else {
+ $hasCustomSetter = 1;
+ $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+ }
+
+ # Custom Setter
+ } elsif ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"}) {
+ $hasCustomSetter = 1;
+ $getter = "${interfaceName}Internal::${attrName}AttrGetter";
+ $setter = "V8Custom::v8${customAccessor}AccessorSetter";
+
+ # Custom Getter
+ } elsif ($attrExt->{"CustomGetter"}) {
+ $getter = "V8Custom::v8${customAccessor}AccessorGetter";
+ $setter = "${interfaceName}Internal::${attrName}AttrSetter";
+
+ # Replaceable
+ } elsif ($attrExt->{"Replaceable"}) {
+ # Replaceable accessor is put on instance template with ReadOnly attribute.
+ $getter = "${interfaceName}Internal::${attrName}AttrGetter";
+ $setter = "0";
+
+ # Mark to avoid duplicate v8::ReadOnly flags in output.
+ $hasCustomSetter = 1;
+
+ # Handle the special case of window.top being marked upstream as Replaceable.
+ # FIXME: Investigate why [Replaceable] is not marked as ReadOnly
+ # upstream and reach parity.
+ if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
+ $propAttr .= "|v8::ReadOnly";
+ }
+
+ # Normal
+ } else {
+ $getter = "${interfaceName}Internal::${attrName}AttrGetter";
+ $setter = "${interfaceName}Internal::${attrName}AttrSetter";
+ }
+
+ if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
+ $setter = "0";
+ $propAttr .= "|v8::ReadOnly";
+ }
+
+ # Read only attributes
+ if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
+ $setter = "0";
+ }
+
+ # An accessor can be installed on the proto
+ if ($attrExt->{"v8OnProto"}) {
+ $on_proto = "1 /* on proto */";
+ }
+
+ my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
+ "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
+
+ my $conditionalString = GenerateConditionalString($attribute->signature);
+ push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
+
+ push(@implContent, <<END);
+ // $commentInfo
+ { "$attrName",
+ $getter,
+ $setter,
+ $data,
+ $accessControl,
+ static_cast<v8::PropertyAttribute>($propAttr),
+ $on_proto },
+END
+ push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+ }
+}
+
+
+sub GenerateImplementation
+{
+ my $object = shift;
+ my $dataNode = shift;
+ my $interfaceName = $dataNode->name;
+ my $className = "V8$interfaceName";
+ my $implClassName = $interfaceName;
+ my $classIndex = uc($codeGenerator->StripModule($interfaceName));
+
+ my $hasLegacyParent = $dataNode->extendedAttributes->{"LegacyParent"};
+ my $conditionalString = GenerateConditionalString($dataNode);
+
+ @allParents = $codeGenerator->FindParentsRecursively($dataNode);
+
+ # - Add default header template
+ @implContentHeader = split("\r", $headerTemplate);
+
+ push(@implFixedHeader,
+ "#include \"config.h\"\n" .
+ "#include \"V8Proxy.h\"\n" .
+ "#include \"V8Binding.h\"\n\n" .
+ "#undef LOG\n\n");
+
+ push(@implFixedHeader, "\n#if ${conditionalString}\n\n") if $conditionalString;
+
+ if ($className =~ /^V8SVGAnimated/) {
+ AddIncludesForSVGAnimatedType($interfaceName);
+ }
+
+ $implIncludes{"${className}.h"} = 1;
+
+ AddIncludesForType($interfaceName);
+ $implIncludes{"V8Proxy.h"} = 1;
+
+ push(@implContentDecls, "namespace WebCore {\n");
+ push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
+ push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
+
+ my $hasConstructors = 0;
+
+ # Generate property accessors for attributes.
+ for ($index = 0; $index < @{$dataNode->attributes}; $index++) {
+ $attribute = @{$dataNode->attributes}[$index];
+ $attrName = $attribute->signature->name;
+ $attrType = $attribute->signature->type;
+
+ # Generate special code for the constructor attributes.
+ if ($attrType =~ /Constructor$/) {
+ $hasConstructors = 1;
+ next;
+ }
+
+ # Make EventListeners always custom.
+ # FIXME: make the perl code capable of generating the
+ # event setters/getters. For now, WebKit has started removing the
+ # [Custom] attribute, so just automatically insert it to avoid forking
+ # other files. This should be okay because we can't generate stubs
+ # for any event getter/setters anyway.
+ if ($attrType eq "EventListener") {
+ $attribute->signature->extendedAttributes->{"Custom"} = 1;
+ $implIncludes{"V8CustomBinding.h"} = 1;
+ next;
+ }
+
+ # Do not generate accessor if this is a custom attribute. The
+ # call will be forwarded to a hand-written accessor
+ # implementation.
+ if ($attribute->signature->extendedAttributes->{"Custom"} ||
+ $attribute->signature->extendedAttributes->{"V8Custom"}) {
+ $implIncludes{"V8CustomBinding.h"} = 1;
+ next;
+ }
+
+ # Generate the accessor.
+ if ($attribute->signature->extendedAttributes->{"CustomGetter"}) {
+ $implIncludes{"V8CustomBinding.h"} = 1;
+ } else {
+ GenerateNormalAttrGetter($attribute, $dataNode, $classIndex, $implClassName);
+ }
+ if ($attribute->signature->extendedAttributes->{"CustomSetter"} ||
+ $attribute->signature->extendedAttributes->{"V8CustomSetter"}) {
+ $implIncludes{"V8CustomBinding.h"} = 1;
+ } elsif ($attribute->signature->extendedAttributes->{"Replaceable"}) {
+ $dataNode->extendedAttributes->{"ExtendsDOMGlobalObject"} || die "Replaceable attribute can only be used in interface that defines ExtendsDOMGlobalObject attribute!";
+ # GenerateReplaceableAttrSetter($implClassName);
+ } elsif ($attribute->type !~ /^readonly/ && !$attribute->signature->extendedAttributes->{"V8ReadOnly"}) {
+ GenerateNormalAttrSetter($attribute, $dataNode, $classIndex, $implClassName);
+ }
+ }
+
+ if ($hasConstructors) {
+ GenerateConstructorGetter($implClassName, $classIndex);
+ }
+
+ # Generate methods for functions.
+ foreach my $function (@{$dataNode->functions}) {
+ # hack for addEventListener/RemoveEventListener
+ # FIXME: avoid naming conflict
+ if ($function->signature->extendedAttributes->{"Custom"} || $function->signature->extendedAttributes->{"V8Custom"}) {
+ $implIncludes{"V8CustomBinding.h"} = 1;
+ } else {
+ GenerateFunctionCallback($function, $dataNode, $classIndex, $implClassName);
+ }
+
+ # If the function does not need domain security check, we need to
+ # generate an access getter that returns different function objects
+ # for different calling context.
+ if (($dataNode->extendedAttributes->{"CheckDomainSecurity"} || ($interfaceName eq "DOMWindow")) && $function->signature->extendedAttributes->{"DoNotCheckDomainSecurity"}) {
+ GenerateDomainSafeFunctionGetter($function, $dataNode, $classIndex, $implClassName);
+ }
+ }
+
+ # Attributes
+ my $attributes = $dataNode->attributes;
+
+ # For the DOMWindow interface we partition the attributes into the
+ # ones that disallows shadowing and the rest.
+ my @disallows_shadowing;
+ my @normal;
+ if ($interfaceName eq "DOMWindow") {
+ foreach my $attribute (@$attributes) {
+ if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
+ push(@disallows_shadowing, $attribute);
+ } else {
+ push(@normal, $attribute);
+ }
+ }
+ # Put the attributes that disallow shadowing on the shadow object.
+ $attributes = \@normal;
+ push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
+ GenerateBatchedAttributeData($interfaceName, \@disallows_shadowing);
+ push(@implContent, "};\n");
+ }
+
+ my $has_attributes = 0;
+ if (@$attributes) {
+ $has_attributes = 1;
+ push(@implContent, "static const BatchedAttribute ${interfaceName}_attrs[] = {\n");
+ GenerateBatchedAttributeData($interfaceName, $attributes);
+ push(@implContent, "};\n");
+ }
+
+ # Setup constants
+ my $has_constants = 0;
+ if (@{$dataNode->constants}) {
+ $has_constants = 1;
+ push(@implContent, "static const BatchedConstant ${interfaceName}_consts[] = {\n");
+ }
+ foreach my $constant (@{$dataNode->constants}) {
+ my $name = $constant->name;
+ my $value = $constant->value;
+ # FIXME: we need the static_cast here only because of one constant, NodeFilter.idl
+ # defines "const unsigned long SHOW_ALL = 0xFFFFFFFF". It would be better if we
+ # handled this here, and converted it to a -1 constant in the c++ output.
+ push(@implContent, <<END);
+ { "${name}", static_cast<signed int>($value) },
+END
+ }
+ if ($has_constants) {
+ push(@implContent, "};\n");
+ }
+
+ push(@implContentDecls, "} // namespace ${interfaceName}Internal\n\n");
+
+ my $access_check = "/* no access check */";
+ if ($dataNode->extendedAttributes->{"CheckDomainSecurity"} && !($interfaceName eq "DOMWindow")) {
+ $access_check = "instance->SetAccessCheckCallbacks(V8Custom::v8${interfaceName}NamedSecurityCheck, V8Custom::v8${interfaceName}IndexedSecurityCheck, v8::Integer::New(V8ClassIndex::ToInt(V8ClassIndex::${classIndex})));";
+ }
+
+ # For the DOMWindow interface, generate the shadow object template
+ # configuration method.
+ if ($implClassName eq "DOMWindow") {
+ push(@implContent, <<END);
+static v8::Persistent<v8::ObjectTemplate> ConfigureShadowObjectTemplate(v8::Persistent<v8::ObjectTemplate> templ) {
+ batchConfigureAttributes(templ,
+ v8::Handle<v8::ObjectTemplate>(),
+ shadow_attrs,
+ sizeof(shadow_attrs)/sizeof(*shadow_attrs));
+ return templ;
+}
+END
+ }
+
+ # Generate the template configuration method
+ push(@implContent, <<END);
+static v8::Persistent<v8::FunctionTemplate> Configure${className}Template(v8::Persistent<v8::FunctionTemplate> desc) {
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+END
+ if (IsNodeSubType($dataNode)) {
+ push(@implContent, <<END);
+ instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
+END
+ } else {
+ push(@implContent, <<END);
+ instance->SetInternalFieldCount(V8Custom::kDefaultWrapperInternalFieldCount);
+END
+ }
+
+ push(@implContent, <<END);
+ v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
+ v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
+ $access_check
+END
+
+
+ # Set up our attributes if we have them
+ if ($has_attributes) {
+ push(@implContent, <<END);
+ batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs));
+END
+ }
+
+ # Define our functions with Set() or SetAccessor()
+ foreach my $function (@{$dataNode->functions}) {
+ my $attrExt = $function->signature->extendedAttributes;
+ my $name = $function->signature->name;
+
+ my $property_attributes = "v8::DontDelete";
+ if ($attrExt->{"DontEnum"}) {
+ $property_attributes .= "|v8::DontEnum";
+ }
+ if ($attrExt->{"V8ReadOnly"}) {
+ $property_attributes .= "|v8::ReadOnly";
+ }
+
+ my $commentInfo = "Function '$name' (ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
+
+ my $template = "proto";
+ if ($attrExt->{"V8OnInstance"}) {
+ $template = "instance";
+ }
+
+ if ($attrExt->{"DoNotCheckDomainSecurity"} &&
+ ($dataNode->extendedAttributes->{"CheckDomainSecurity"} || $interfaceName eq "DOMWindow")) {
+ # Mark the accessor as ReadOnly and set it on the proto object so
+ # it can be shadowed. This is really a hack to make it work.
+ # There are several sceneria to call into the accessor:
+ # 1) from the same domain: "window.open":
+ # the accessor finds the DOM wrapper in the proto chain;
+ # 2) from the same domain: "window.__proto__.open":
+ # the accessor will NOT find a DOM wrapper in the prototype chain
+ # 3) from another domain: "window.open":
+ # the access find the DOM wrapper in the prototype chain
+ # "window.__proto__.open" from another domain will fail when
+ # accessing '__proto__'
+ #
+ # The solution is very hacky and fragile, it really needs to be replaced
+ # by a better solution.
+ $property_attributes .= "|v8::ReadOnly";
+ push(@implContent, <<END);
+
+ // $commentInfo
+ $template->SetAccessor(
+ v8::String::New("$name"),
+ ${interfaceName}Internal::${name}AttrGetter,
+ 0,
+ v8::Handle<v8::Value>(),
+ v8::ALL_CAN_READ,
+ static_cast<v8::PropertyAttribute>($property_attributes));
+END
+ next;
+ }
+
+ my $signature = "default_signature";
+ if ($attrExt->{"V8DoNotCheckSignature"}){
+ $signature = "v8::Local<v8::Signature>()";
+ }
+
+ if (RequiresCustomSignature($function)) {
+ $signature = "${name}_signature";
+ push(@implContent, "\n // Custom Signature '$name'\n", CreateCustomSignature($function));
+ }
+
+ # Normal function call is a template
+ my $templateFunction = GenerateNewFunctionTemplate($function, $dataNode, $signature);
+
+
+ push(@implContent, <<END);
+
+ // $commentInfo
+ ${template}->Set(
+ v8::String::New("$name"),
+ $templateFunction,
+ static_cast<v8::PropertyAttribute>($property_attributes));
+END
+ }
+
+ # set the super descriptor
+ foreach (@{$dataNode->parents}) {
+ my $parent = $codeGenerator->StripModule($_);
+ if ($parent eq "EventTarget") { next; }
+ $implIncludes{"V8${parent}.h"} = 1;
+ my $parentClassIndex = uc($codeGenerator->StripModule($parent));
+ push(@implContent, " desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::${parentClassIndex}));\n");
+ last;
+ }
+
+ # Set the class name. This is used when printing objects.
+ push(@implContent, " desc->SetClassName(v8::String::New(\"" . GetClassName(${interfaceName}) . "\"));\n");
+
+ if ($has_constants) {
+ push(@implContent, <<END);
+ batchConfigureConstants(desc, proto, ${interfaceName}_consts, sizeof(${interfaceName}_consts)/sizeof(*${interfaceName}_consts));
+END
+ }
+
+ push(@implContent, <<END);
+ return desc;
+}
+
+v8::Persistent<v8::FunctionTemplate> ${className}::GetRawTemplate() {
+ static v8::Persistent<v8::FunctionTemplate> ${className}_raw_cache_;
+ if (${className}_raw_cache_.IsEmpty()) {
+ v8::HandleScope scope;
+ v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal);
+ ${className}_raw_cache_ = v8::Persistent<v8::FunctionTemplate>::New(result);
+ }
+ return ${className}_raw_cache_;
+}
+
+v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate() {
+ static v8::Persistent<v8::FunctionTemplate> ${className}_cache_;
+ if (${className}_cache_.IsEmpty())
+ ${className}_cache_ = Configure${className}Template(GetRawTemplate());
+ return ${className}_cache_;
+}
+
+bool ${className}::HasInstance(v8::Handle<v8::Value> value) {
+ return GetRawTemplate()->HasInstance(value);
+}
+
+END
+
+ if ($implClassName eq "DOMWindow") {
+ push(@implContent, <<END);
+v8::Persistent<v8::ObjectTemplate> V8DOMWindow::GetShadowObjectTemplate() {
+ static v8::Persistent<v8::ObjectTemplate> V8DOMWindowShadowObject_cache_;
+ if (V8DOMWindowShadowObject_cache_.IsEmpty()) {
+ V8DOMWindowShadowObject_cache_ = v8::Persistent<v8::ObjectTemplate>::New(v8::ObjectTemplate::New());
+ ConfigureShadowObjectTemplate(V8DOMWindowShadowObject_cache_);
+ }
+ return V8DOMWindowShadowObject_cache_;
+}
+END
+ }
+
+ push(@implContent, <<END);
+} // namespace WebCore
+END
+
+ push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
+}
+
+
+sub GenerateFunctionCallString()
+{
+ my $function = shift;
+ my $numberOfParameters = shift;
+ my $indent = shift;
+ my $implClassName = shift;
+
+ my $name = $function->signature->name;
+ my $isPodType = IsPodType($implClassName);
+ my $returnType = GetTypeFromSignature($function->signature);
+ my $returnsPodType = IsPodType($returnType);
+ my $nativeReturnType = GetNativeType($returnType, 0);
+ my $result = "";
+
+ # Special case: SVG matrix transform methods should not mutate
+ # the matrix but return a copy
+ my $copyFirst = 0;
+ if ($implClassName eq "SVGMatrix" && $function->signature->type eq "SVGMatrix") {
+ $copyFirst = 1;
+ }
+
+ if ($function->signature->extendedAttributes->{"v8implname"}) {
+ $name = $function->signature->extendedAttributes->{"v8implname"};
+ }
+
+ if ($function->signature->extendedAttributes->{"ImplementationFunction"}) {
+ $name = $function->signature->extendedAttributes->{"ImplementationFunction"};
+ }
+
+ my $functionString = "imp->${name}(";
+
+ if ($copyFirst) {
+ $functionString = "result.${name}(";
+ }
+
+ my $returnsListItemPodType = 0;
+ # SVG lists functions that return POD types require special handling
+ if (IsSVGListTypeNeedingSpecialHandling($implClassName) && IsSVGListMethod($name) && $returnsPodType) {
+ $returnsListItemPodType = 1;
+ $result .= $indent . "SVGList<RefPtr<SVGPODListItem<$nativeReturnType> > >* listImp = imp;\n";
+ $functionString = "listImp->${name}(";
+ }
+
+ my $first = 1;
+ my $index = 0;
+ my $nodeToReturn = 0;
+
+ foreach my $parameter (@{$function->parameters}) {
+ if ($index eq $numberOfParameters) {
+ last;
+ }
+ if ($first) { $first = 0; }
+ else { $functionString .= ", "; }
+ my $paramName = $parameter->name;
+ my $paramType = $parameter->type;
+
+ # This is a bit of a hack... we need to convert parameters to methods on SVG lists
+ # of POD types which are items in the list to appropriate SVGList<> instances
+ if ($returnsListItemPodType && $paramType . "List" eq $implClassName) {
+ $paramName = "SVGPODListItem<" . GetNativeType($paramType, 1) . ">::copy($paramName)";
+ }
+
+ if ($parameter->type eq "NodeFilter") {
+ $functionString .= "$paramName.get()";
+ } else {
+ $functionString .= $paramName;
+ }
+
+ if ($parameter->extendedAttributes->{"Return"}) {
+ $nodeToReturn = $parameter->name;
+ }
+ $index++;
+ }
+
+ if ($function->signature->extendedAttributes->{"CustomArgumentHandling"}) {
+ $functionString .= ", " if not $first;
+ $functionString .= "&callStack";
+ if ($first) { $first = 0; }
+ }
+
+ if (@{$function->raisesExceptions}) {
+ $functionString .= ", " if not $first;
+ $functionString .= "ec";
+ }
+ $functionString .= ")";
+
+ if ($nodeToReturn) {
+ # Special case for insertBefore, replaceChild, removeChild and
+ # appendChild functions from Node.
+ $result .= $indent . "bool success = $functionString;\n";
+ if (@{$function->raisesExceptions}) {
+ $result .= GenerateSetDOMException($indent);
+ }
+ $result .= $indent . "if (success)\n";
+ $result .= $indent . " " .
+ "return V8DOMWrapper::convertNodeToV8Object($nodeToReturn);\n";
+ $result .= $indent . "return v8::Null();\n";
+ return $result;
+ } elsif ($returnType eq "void") {
+ $result .= $indent . "$functionString;\n";
+ } elsif ($copyFirst) {
+ $result .=
+ $indent . GetNativeType($returnType, 0) . " result = *imp;\n" .
+ $indent . "$functionString;\n";
+ } elsif ($returnsListItemPodType) {
+ $result .= $indent . "RefPtr<SVGPODListItem<$nativeReturnType> > result = $functionString;\n";
+ } else {
+ $result .= $indent . $nativeReturnType . " result = $functionString;\n";
+ }
+
+ if (@{$function->raisesExceptions}) {
+ $result .= GenerateSetDOMException($indent);
+ }
+
+ my $return = "result";
+
+ # If the return type is a POD type, separate out the wrapper generation
+ if ($returnsListItemPodType) {
+ $result .= $indent . "RefPtr<V8SVGPODTypeWrapper<" . $nativeReturnType . "> > wrapper = ";
+ $result .= "V8SVGPODTypeWrapperCreatorForList<" . $nativeReturnType . ">::create($return, imp->associatedAttributeName());\n";
+ $return = "wrapper";
+ } elsif ($returnsPodType) {
+ $result .= $indent . "RefPtr<V8SVGPODTypeWrapper<" . $nativeReturnType . "> > wrapper = ";
+ $result .= GenerateSVGStaticPodTypeWrapper($returnType, $return) . ";\n";
+ $return = "wrapper";
+ }
+
+ my $generatedSVGContextRetrieval = 0;
+ # If the return type needs an SVG context, output it
+ if (IsSVGTypeNeedingContextParameter($returnType)) {
+ $result .= GenerateSVGContextAssignment($implClassName, $return . ".get()", $indent);
+ $generatedSVGContextRetrieval = 1;
+ }
+
+ if (IsSVGTypeNeedingContextParameter($implClassName) && $implClassName =~ /List$/ && IsSVGListMutator($name)) {
+ if (!$generatedSVGContextRetrieval) {
+ $result .= GenerateSVGContextRetrieval($implClassName, $indent);
+ $generatedSVGContextRetrieval = 1;
+ }
+
+ $result .= $indent . "context->svgAttributeChanged(imp->associatedAttributeName());\n";
+ $implIncludes{"SVGElement.h"} = 1;
+ }
+
+ # If the implementing class is a POD type, commit changes
+ if ($isPodType) {
+ if (!$generatedSVGContextRetrieval) {
+ $result .= GenerateSVGContextRetrieval($implClassName, $indent);
+ $generatedSVGContextRetrieval = 1;
+ }
+
+ $result .= $indent . "imp_wrapper->commitChange(imp_instance, context);\n";
+ }
+
+ if ($returnsPodType) {
+ my $classIndex = uc($returnType);
+ $result .= $indent . "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, wrapper.release());\n";
+ } else {
+ $return .= ".release()" if (IsRefPtrType($returnType));
+ $result .= $indent . ReturnNativeToJSValue($function->signature, $return, $indent) . ";\n";
+ }
+
+ return $result;
+}
+
+
+# Get the class name used for printing javascript DOM-object wrappers.
+sub GetClassName
+{
+ my $type = shift;
+ return "HTMLCollection" if $type eq "HTMLAllCollection";
+ return $type;
+}
+
+
+sub GetTypeFromSignature
+{
+ my $signature = shift;
+
+ my $type = $codeGenerator->StripModule($signature->type);
+ if (($type eq "DOMString") && $signature->extendedAttributes->{"V8Custom"}) {
+ $type = "AtomicString";
+ }
+
+ return $type;
+}
+
+
+sub GetNativeTypeFromSignature
+{
+ my $signature = shift;
+ my $isParameter = shift;
+
+ my $type = GetTypeFromSignature($signature);
+
+ return GetNativeType($type, $isParameter);
+}
+
+sub IsRefPtrType
+{
+ my $type = shift;
+ return 1 if $type eq "Attr";
+ return 1 if $type eq "CanvasGradient";
+ return 1 if $type eq "ClientRect";
+ return 1 if $type eq "ClientRectList";
+ return 1 if $type eq "CDATASection";
+ return 1 if $type eq "Comment";
+ return 1 if $type eq "CSSRule";
+ return 1 if $type eq "CSSStyleRule";
+ return 1 if $type eq "CSSCharsetRule";
+ return 1 if $type eq "CSSImportRule";
+ return 1 if $type eq "CSSMediaRule";
+ return 1 if $type eq "CSSFontFaceRule";
+ return 1 if $type eq "CSSPageRule";
+ return 1 if $type eq "CSSPrimitiveValue";
+ return 1 if $type eq "CSSStyleSheet";
+ return 1 if $type eq "CSSStyleDeclaration";
+ return 1 if $type eq "CSSValue";
+ return 1 if $type eq "CSSRuleList";
+ return 1 if $type eq "Database";
+ return 1 if $type eq "Document";
+ return 1 if $type eq "DocumentFragment";
+ return 1 if $type eq "DocumentType";
+ return 1 if $type eq "Element";
+ return 1 if $type eq "EntityReference";
+ return 1 if $type eq "Event";
+ return 1 if $type eq "FileList";
+ return 1 if $type eq "HTMLCollection";
+ return 1 if $type eq "HTMLDocument";
+ return 1 if $type eq "HTMLElement";
+ return 1 if $type eq "HTMLOptionsCollection";
+ return 1 if $type eq "ImageData";
+ return 1 if $type eq "Media";
+ return 1 if $type eq "MediaError";
+ return 1 if $type eq "MimeType";
+ return 1 if $type eq "Node";
+ return 1 if $type eq "NodeList";
+ return 1 if $type eq "NodeFilter";
+ return 1 if $type eq "NodeIterator";
+ return 1 if $type eq "NSResolver";
+ return 1 if $type eq "Plugin";
+ return 1 if $type eq "ProcessingInstruction";
+ return 1 if $type eq "Range";
+ return 1 if $type eq "Text";
+ return 1 if $type eq "TextMetrics";
+ return 1 if $type eq "TimeRanges";
+ return 1 if $type eq "TreeWalker";
+ return 1 if $type eq "WebKitCSSMatrix";
+ return 1 if $type eq "WebKitPoint";
+ return 1 if $type eq "XPathExpression";
+ return 1 if $type eq "XPathNSResolver";
+ return 1 if $type eq "XPathResult";
+
+ return 1 if $type eq "SVGAngle";
+ return 1 if $type eq "SVGElementInstance";
+ return 1 if $type eq "SVGElementInstanceList";
+ return 1 if $type =~ /^SVGPathSeg/;
+
+ return 1 if $type =~ /^SVGAnimated/;
+
+ return 0;
+}
+
+sub IsVideoClassName
+{
+ my $class = shift;
+ return 1 if $class eq "V8HTMLAudioElement";
+ return 1 if $class eq "V8HTMLMediaElement";
+ return 1 if $class eq "V8HTMLSourceElement";
+ return 1 if $class eq "V8HTMLVideoElement";
+ return 1 if $class eq "V8MediaError";
+ return 1 if $class eq "V8TimeRanges";
+
+ return 0;
+}
+
+sub IsWorkerClassName
+{
+ my $class = shift;
+ return 1 if $class eq "V8Worker";
+ return 1 if $class eq "V8WorkerContext";
+ return 1 if $class eq "V8WorkerLocation";
+ return 1 if $class eq "V8WorkerNavigator";
+
+ return 0;
+}
+
+sub GetNativeType
+{
+ my $type = shift;
+ my $isParameter = shift;
+
+ if ($type eq "float" or $type eq "AtomicString" or $type eq "double") {
+ return $type;
+ }
+
+ return "int" if $type eq "int";
+ return "int" if $type eq "short" or $type eq "unsigned short";
+ return "int" if $type eq "long" or $type eq "unsigned long";
+ return "unsigned long long" if $type eq "unsigned long long";
+ return "bool" if $type eq "boolean";
+ return "String" if $type eq "DOMString";
+ return "Range::CompareHow" if $type eq "CompareHow";
+ return "FloatRect" if $type eq "SVGRect";
+ return "FloatPoint" if $type eq "SVGPoint";
+ return "TransformationMatrix" if $type eq "SVGMatrix";
+ return "SVGTransform" if $type eq "SVGTransform";
+ return "SVGLength" if $type eq "SVGLength";
+ return "double" if $type eq "SVGNumber";
+ return "SVGPaint::SVGPaintType" if $type eq "SVGPaintType";
+ return "DOMTimeStamp" if $type eq "DOMTimeStamp";
+ return "unsigned" if $type eq "unsigned int";
+ return "Node*" if $type eq "EventTarget" and $isParameter;
+
+ return "String" if $type eq "DOMUserData"; # FIXME: Temporary hack?
+
+ # temporary hack
+ return "RefPtr<NodeFilter>" if $type eq "NodeFilter";
+
+ return "RefPtr<${type}>" if IsRefPtrType($type) and not $isParameter;
+
+ # Default, assume native type is a pointer with same type name as idl type
+ return "${type}*";
+}
+
+
+my %typeCanFailConversion = (
+ "AtomicString" => 0,
+ "Attr" => 1,
+ "CompareHow" => 0,
+ "DataGridColumn" => 0,
+ "DOMString" => 0,
+ "DOMWindow" => 0,
+ "DocumentType" => 0,
+ "Element" => 0,
+ "Event" => 0,
+ "EventListener" => 0,
+ "EventTarget" => 0,
+ "HTMLElement" => 0,
+ "HTMLOptionElement" => 0,
+ "Node" => 0,
+ "NodeFilter" => 0,
+ "MessagePort" => 0,
+ "NSResolver" => 0,
+ "Range" => 0,
+ "SQLResultSet" => 0,
+ "Storage" => 0,
+ "SVGAngle" => 0,
+ "SVGElement" => 0,
+ "SVGLength" => 1,
+ "SVGMatrix" => 1,
+ "SVGNumber" => 0,
+ "SVGPaintType" => 0,
+ "SVGPathSeg" => 0,
+ "SVGPoint" => 1,
+ "SVGRect" => 1,
+ "SVGTransform" => 1,
+ "VoidCallback" => 1,
+ "WebKitCSSMatrix" => 0,
+ "WebKitPoint" => 0,
+ "XPathEvaluator" => 0,
+ "XPathNSResolver" => 0,
+ "XPathResult" => 0,
+ "boolean" => 0,
+ "double" => 0,
+ "float" => 0,
+ "long" => 0,
+ "unsigned long" => 0,
+ "unsigned short" => 0,
+);
+
+
+sub TranslateParameter
+{
+ my $signature = shift;
+
+ # The IDL uses some pseudo-types which don't really exist.
+ if ($signature->type eq "TimeoutHandler") {
+ $signature->type("DOMString");
+ }
+}
+
+sub BasicTypeCanFailConversion
+{
+ my $signature = shift;
+ my $type = GetTypeFromSignature($signature);
+
+ return 1 if $type eq "SVGLength";
+ return 1 if $type eq "SVGMatrix";
+ return 1 if $type eq "SVGPoint";
+ return 1 if $type eq "SVGRect";
+ return 1 if $type eq "SVGTransform";
+ return 0;
+}
+
+sub TypeCanFailConversion
+{
+ my $signature = shift;
+
+ my $type = GetTypeFromSignature($signature);
+
+ $implIncludes{"ExceptionCode.h"} = 1 if $type eq "Attr";
+
+ return $typeCanFailConversion{$type} if exists $typeCanFailConversion{$type};
+
+ die "Don't know whether a JS value can fail conversion to type $type.";
+}
+
+sub JSValueToNative
+{
+ my $signature = shift;
+ my $value = shift;
+ my $okParam = shift;
+ my $maybeOkParam = $okParam ? ", ${okParam}" : "";
+
+ my $type = GetTypeFromSignature($signature);
+
+ return "$value" if $type eq "JSObject";
+ return "$value->BooleanValue()" if $type eq "boolean";
+ return "static_cast<$type>($value->NumberValue())" if $type eq "float" or $type eq "double";
+ return "$value->NumberValue()" if $type eq "SVGNumber";
+
+ return "toInt32($value${maybeOkParam})" if $type eq "unsigned long" or $type eq "unsigned short" or $type eq "long";
+ return "static_cast<Range::CompareHow>($value->Int32Value())" if $type eq "CompareHow";
+ return "static_cast<SVGPaint::SVGPaintType>($value->ToInt32()->Int32Value())" if $type eq "SVGPaintType";
+
+ return "v8ValueToAtomicWebCoreString($value)" if $type eq "AtomicString";
+ return "toWebCoreString($value)" if $type eq "DOMUserData";
+ if ($type eq "DOMString") {
+ return "toWebCoreStringWithNullCheck($value)" if $signature->extendedAttributes->{"ConvertNullToNullString"};
+ return "toWebCoreStringWithNullOrUndefinedCheck($value)" if $signature->extendedAttributes->{"ConvertUndefinedOrNullToNullString"};
+ return "toWebCoreString($value)";
+ }
+
+ if ($type eq "NodeFilter") {
+ return "V8DOMWrapper::wrapNativeNodeFilter($value)";
+ }
+
+ if ($type eq "SVGRect") {
+ $implIncludes{"FloatRect.h"} = 1;
+ }
+
+ if ($type eq "SVGPoint") {
+ $implIncludes{"FloatPoint.h"} = 1;
+ }
+
+ # Default, assume autogenerated type conversion routines
+ $implIncludes{"V8Proxy.h"} = 1;
+ if ($type eq "EventTarget") {
+ $implIncludes{"V8Node.h"} = 1;
+
+ # EventTarget is not in DOM hierarchy, but all Nodes are EventTarget.
+ return "V8Node::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast($value)) : 0";
+ }
+
+ AddIncludesForType($type);
+ # $implIncludes{"$type.h"} = 1 unless AvoidInclusionOfType($type);
+
+ if (IsDOMNodeType($type)) {
+ $implIncludes{"V8${type}.h"} = 1;
+
+ # Perform type checks on the parameter, if it is expected Node type,
+ # return NULL.
+ return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertDOMWrapperToNode<${type}>(v8::Handle<v8::Object>::Cast($value)) : 0";
+ } else {
+ # TODO: Temporary to avoid Window name conflict.
+ my $classIndex = uc($type);
+ my $implClassName = ${type};
+
+ $implIncludes{"V8$type.h"} = 1;
+
+ if (IsPodType($type)) {
+ my $nativeType = GetNativeType($type);
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+
+ return "V8SVGPODTypeUtil::toSVGPODType<${nativeType}>(V8ClassIndex::${classIndex}, $value${maybeOkParam})"
+ }
+
+ $implIncludes{"V8${type}.h"} = 1;
+
+ # Perform type checks on the parameter, if it is expected Node type,
+ # return NULL.
+ return "V8${type}::HasInstance($value) ? V8DOMWrapper::convertToNativeObject<${implClassName}>(V8ClassIndex::${classIndex}, v8::Handle<v8::Object>::Cast($value)) : 0";
+ }
+}
+
+
+sub GetV8HeaderName
+{
+ my $type = shift;
+ return "V8" . GetImplementationFileName($type);
+}
+
+
+sub CreateCustomSignature
+{
+ my $function = shift;
+ my $count = @{$function->parameters};
+ my $name = $function->signature->name;
+ my $result = " const int ${name}_argc = ${count};\n" .
+ " v8::Handle<v8::FunctionTemplate> ${name}_argv[${name}_argc] = { ";
+ my $first = 1;
+ foreach my $parameter (@{$function->parameters}) {
+ if ($first) { $first = 0; }
+ else { $result .= ", "; }
+ if (IsWrapperType($parameter->type)) {
+ my $type = $parameter->type;
+ my $header = GetV8HeaderName($type);
+ $implIncludes{$header} = 1;
+ $result .= "V8${type}::GetRawTemplate()";
+ } else {
+ $result .= "v8::Handle<v8::FunctionTemplate>()";
+ }
+ }
+ $result .= " };\n";
+ $result .= " v8::Handle<v8::Signature> ${name}_signature = v8::Signature::New(desc, ${name}_argc, ${name}_argv);\n";
+ return $result;
+}
+
+
+sub RequiresCustomSignature
+{
+ my $function = shift;
+ # No signature needed for Custom function
+ if ($function->signature->extendedAttributes->{"Custom"} ||
+ $function->signature->extendedAttributes->{"V8Custom"}) {
+ return 0;
+ }
+
+ foreach my $parameter (@{$function->parameters}) {
+ if (IsWrapperType($parameter->type)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+my %non_wrapper_types = (
+ 'float' => 1,
+ 'AtomicString' => 1,
+ 'double' => 1,
+ 'short' => 1,
+ 'unsigned short' => 1,
+ 'long' => 1,
+ 'unsigned long' => 1,
+ 'boolean' => 1,
+ 'DOMString' => 1,
+ 'CompareHow' => 1,
+ 'SVGRect' => 1,
+ 'SVGPoint' => 1,
+ 'SVGMatrix' => 1,
+ 'SVGTransform' => 1,
+ 'SVGLength' => 1,
+ 'SVGNumber' => 1,
+ 'SVGPaintType' => 1,
+ 'DOMTimeStamp' => 1,
+ 'JSObject' => 1,
+ 'EventTarget' => 1,
+ 'NodeFilter' => 1,
+ 'EventListener' => 1
+);
+
+
+sub IsWrapperType
+{
+ my $type = $codeGenerator->StripModule(shift);
+ return !($non_wrapper_types{$type});
+}
+
+sub IsDOMNodeType
+{
+ my $type = shift;
+
+ return 1 if $type eq 'Attr';
+ return 1 if $type eq 'CDATASection';
+ return 1 if $type eq 'Comment';
+ return 1 if $type eq 'Document';
+ return 1 if $type eq 'DocumentFragment';
+ return 1 if $type eq 'DocumentType';
+ return 1 if $type eq 'Element';
+ return 1 if $type eq 'EntityReference';
+ return 1 if $type eq 'HTMLCanvasElement';
+ return 1 if $type eq 'HTMLDocument';
+ return 1 if $type eq 'HTMLElement';
+ return 1 if $type eq 'HTMLFormElement';
+ return 1 if $type eq 'HTMLTableCaptionElement';
+ return 1 if $type eq 'HTMLTableSectionElement';
+ return 1 if $type eq 'Node';
+ return 1 if $type eq 'ProcessingInstruction';
+ return 1 if $type eq 'SVGElement';
+ return 1 if $type eq 'SVGDocument';
+ return 1 if $type eq 'SVGSVGElement';
+ return 1 if $type eq 'SVGUseElement';
+ return 1 if $type eq 'Text';
+
+ return 0;
+}
+
+
+sub ReturnNativeToJSValue
+{
+ my $signature = shift;
+ my $value = shift;
+ my $indent = shift;
+ my $type = GetTypeFromSignature($signature);
+ my $className= "V8$type";
+
+ return "return v8::Date::New(static_cast<double>($value))" if $type eq "DOMTimeStamp";
+ return "return $value ? v8::True() : v8::False()" if $type eq "boolean";
+ return "return v8::Undefined()" if $type eq "void";
+
+ # For all the types where we use 'int' as the representation type,
+ # we use Integer::New which has a fast Smi conversion check.
+ return "return v8::Integer::New($value)" if GetNativeType($type) eq "int";
+
+ return "return v8::Number::New($value)" if $codeGenerator->IsPrimitiveType($type) or $type eq "SVGPaintType";
+
+ if ($codeGenerator->IsStringType($type)) {
+ my $conv = $signature->extendedAttributes->{"ConvertNullStringTo"};
+ if (defined $conv) {
+ return "return v8StringOrNull($value)" if $conv eq "Null";
+ return "return v8StringOrUndefined($value)" if $conv eq "Undefined";
+ return "return v8StringOrFalse($value)" if $conv eq "False";
+
+ die "Unknown value for ConvertNullStringTo extended attribute";
+ }
+ return "return v8String($value)";
+ }
+
+ # V8 specific.
+ my $implClassName = $type;
+ AddIncludesForType($type);
+ # $implIncludes{GetImplementationFileName($type)} = 1 unless AvoidInclusionOfType($type);
+
+ # special case for non-DOM node interfaces
+ if (IsDOMNodeType($type)) {
+ return "return V8DOMWrapper::convertNodeToV8Object($value)";
+ }
+
+ if ($type eq "EventTarget" or $type eq "SVGElementInstance") {
+ return "return V8DOMWrapper::convertEventTargetToV8Object($value)";
+ }
+
+ if ($type eq "Event") {
+ return "return V8DOMWrapper::convertEventToV8Object($value)";
+ }
+
+ if ($type eq "EventListener") {
+ return "return V8DOMWrapper::convertEventListenerToV8Object($value)";
+ }
+
+ if ($type eq "DedicatedWorkerContext" or $type eq "WorkerContext" or $type eq "SharedWorkerContext") {
+ $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
+ return "return WorkerContextExecutionProxy::convertWorkerContextToV8Object($value)";
+ }
+
+ if ($type eq "WorkerLocation" or $type eq "WorkerNavigator") {
+ $implIncludes{"WorkerContextExecutionProxy.h"} = 1;
+ my $classIndex = uc($type);
+
+ return "return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::$classIndex, $value)";
+ }
+
+ else {
+ $implIncludes{"wtf/RefCounted.h"} = 1;
+ $implIncludes{"wtf/RefPtr.h"} = 1;
+ $implIncludes{"wtf/GetPtr.h"} = 1;
+ my $classIndex = uc($type);
+
+ if (IsPodType($type)) {
+ $value = GenerateSVGStaticPodTypeWrapper($type, $value);
+ }
+
+ return "return V8DOMWrapper::convertToV8Object(V8ClassIndex::$classIndex, $value)";
+ }
+}
+
+sub GenerateSVGStaticPodTypeWrapper {
+ my $type = shift;
+ my $value = shift;
+
+ $implIncludes{"V8$type.h"}=1;
+ $implIncludes{"V8SVGPODTypeWrapper.h"} = 1;
+
+ my $nativeType = GetNativeType($type);
+ return "V8SVGStaticPODTypeWrapper<$nativeType>::create($value)";
+}
+
+# Internal helper
+sub WriteData
+{
+ if (defined($IMPL)) {
+ # Write content to file.
+ print $IMPL @implContentHeader;
+
+ print $IMPL @implFixedHeader;
+
+ foreach my $implInclude (sort keys(%implIncludes)) {
+ my $checkType = $implInclude;
+ $checkType =~ s/\.h//;
+
+ print $IMPL "#include \"$implInclude\"\n" unless $codeGenerator->IsSVGAnimatedType($checkType);
+ }
+
+ print $IMPL "\n";
+ print $IMPL @implContentDecls;
+ print $IMPL @implContent;
+ close($IMPL);
+ undef($IMPL);
+
+ %implIncludes = ();
+ @implFixedHeader = ();
+ @implHeaderContent = ();
+ @implContentDecls = ();
+ @implContent = ();
+ }
+
+ if (defined($HEADER)) {
+ # Write content to file.
+ print $HEADER @headerContent;
+ close($HEADER);
+ undef($HEADER);
+
+ @headerContent = ();
+ }
+}
+
+sub IsSVGTypeNeedingContextParameter
+{
+ my $implClassName = shift;
+
+ if ($implClassName =~ /SVG/ and not $implClassName =~ /Element/) {
+ return 1 unless $implClassName =~ /SVGPaint/ or $implClassName =~ /SVGColor/ or $implClassName =~ /SVGDocument/;
+ }
+
+ return 0;
+}
+
+sub GenerateSVGContextAssignment
+{
+ my $srcType = shift;
+ my $value = shift;
+ my $indent = shift;
+
+ $result = GenerateSVGContextRetrieval($srcType, $indent);
+ $result .= $indent . "V8Proxy::setSVGContext($value, context);\n";
+
+ return $result;
+}
+
+sub GenerateSVGContextRetrieval
+{
+ my $srcType = shift;
+ my $indent = shift;
+
+ my $srcIsPodType = IsPodType($srcType);
+
+ my $srcObject = "imp";
+ if ($srcIsPodType) {
+ $srcObject = "imp_wrapper";
+ }
+
+ my $contextDecl;
+
+ if (IsSVGTypeNeedingContextParameter($srcType)) {
+ $contextDecl = "V8Proxy::svgContext($srcObject)";
+ } else {
+ $contextDecl = $srcObject;
+ }
+
+ return $indent . "SVGElement* context = $contextDecl;\n";
+}
+
+sub IsSVGListMutator
+{
+ my $functionName = shift;
+
+ return 1 if $functionName eq "clear";
+ return 1 if $functionName eq "initialize";
+ return 1 if $functionName eq "insertItemBefore";
+ return 1 if $functionName eq "replaceItem";
+ return 1 if $functionName eq "removeItem";
+ return 1 if $functionName eq "appendItem";
+
+ return 0;
+}
+
+sub IsSVGListMethod
+{
+ my $functionName = shift;
+
+ return 1 if $functionName eq "getFirst";
+ return 1 if $functionName eq "getLast";
+ return 1 if $functionName eq "getItem";
+
+ return IsSVGListMutator($functionName);
+}
+
+sub IsSVGListTypeNeedingSpecialHandling
+{
+ my $className = shift;
+
+ return 1 if $className eq "SVGPointList";
+ return 1 if $className eq "SVGTransformList";
+
+ return 0;
+}
+
+sub DebugPrint
+{
+ my $output = shift;
+
+ print $output;
+ print "\n";
+}
diff --git a/WebCore/bindings/scripts/IDLParser.pm b/WebCore/bindings/scripts/IDLParser.pm
index de7cf9c..c4cb041 100644
--- a/WebCore/bindings/scripts/IDLParser.pm
+++ b/WebCore/bindings/scripts/IDLParser.pm
@@ -41,6 +41,7 @@ my $preservedParseMode = MODE_UNDEF;
my $beQuiet; # Should not display anything on STDOUT?
my $document = 0; # Will hold the resulting 'idlDocument'
+my $parentsOnly = 0; # If 1, parse only enough to populate parents list
# Default Constructor
sub new
@@ -62,6 +63,7 @@ sub Parse
my $fileName = shift;
my $defines = shift;
my $preprocessor = shift;
+ $parentsOnly = shift;
if (!$preprocessor) {
$preprocessor = "/usr/bin/gcc -E -P -x c++";
@@ -240,6 +242,8 @@ sub ParseInterface
push(@$arrayRef, $line);
}
+ return if $parentsOnly;
+
$interfaceData =~ s/[\n\r]/ /g;
my @interfaceMethods = split(/;/, $interfaceData);
diff --git a/WebCore/bindings/v8/ChildThreadDOMData.cpp b/WebCore/bindings/v8/ChildThreadDOMData.cpp
new file mode 100644
index 0000000..77ce0f4
--- /dev/null
+++ b/WebCore/bindings/v8/ChildThreadDOMData.cpp
@@ -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.
+ */
+
+#include "config.h"
+#include "ChildThreadDOMData.h"
+
+namespace WebCore {
+
+ChildThreadDOMData::ChildThreadDOMData()
+ : m_defaultStore(this)
+{
+}
+
+DOMDataStore& ChildThreadDOMData::getStore()
+{
+ ASSERT(!WTF::isMainThread());
+ // Currently, child threads have only one world.
+ return m_defaultStore;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ChildThreadDOMData.h b/WebCore/bindings/v8/ChildThreadDOMData.h
new file mode 100644
index 0000000..5097c86
--- /dev/null
+++ b/WebCore/bindings/v8/ChildThreadDOMData.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 ChildThreadDOMData_h
+#define ChildThreadDOMData_h
+
+#include "DOMData.h"
+#include "ScopedDOMDataStore.h"
+
+namespace WebCore {
+
+ class ChildThreadDOMData : public DOMData {
+ public:
+ ChildThreadDOMData();
+ DOMDataStore& getStore();
+
+ private:
+ ScopedDOMDataStore m_defaultStore;
+ };
+
+} // namespace WebCore
+
+#endif // ChildThreadDOMData_h
diff --git a/WebCore/bindings/v8/DOMData.cpp b/WebCore/bindings/v8/DOMData.cpp
new file mode 100644
index 0000000..07254fe
--- /dev/null
+++ b/WebCore/bindings/v8/DOMData.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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 "DOMData.h"
+
+#include "ChildThreadDOMData.h"
+#include "MainThreadDOMData.h"
+
+namespace WebCore {
+
+DOMData::DOMData()
+ : m_delayedProcessingScheduled(false)
+ , m_isMainThread(WTF::isMainThread())
+ , m_owningThread(WTF::currentThread())
+{
+}
+
+DOMData* DOMData::getCurrent()
+{
+ if (WTF::isMainThread())
+ return getCurrentMainThread();
+
+ DEFINE_STATIC_LOCAL(WTF::ThreadSpecific<ChildThreadDOMData>, childThreadDOMData, ());
+ return childThreadDOMData;
+}
+
+DOMData* DOMData::getCurrentMainThread()
+{
+ ASSERT(WTF::isMainThread());
+ DEFINE_STATIC_LOCAL(MainThreadDOMData, mainThreadDOMData, ());
+ return &mainThreadDOMData;
+}
+
+void DOMData::ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject)
+{
+ if (m_owningThread == WTF::currentThread()) {
+ // No need to delay the work. We can deref right now.
+ derefObject(type, domObject);
+ return;
+ }
+
+ // We need to do the deref on the correct thread.
+ m_delayedObjectMap.set(domObject, type);
+
+ // Post a task to the owning thread in order to process the delayed queue.
+ // FIXME: For now, we can only post to main thread due to WTF task posting limitation. We will fix this when we work on nested worker.
+ if (!m_delayedProcessingScheduled) {
+ m_delayedProcessingScheduled = true;
+ if (isMainThread())
+ WTF::callOnMainThread(&derefDelayedObjectsInCurrentThread, 0);
+ }
+}
+
+void DOMData::derefObject(V8ClassIndex::V8WrapperType type, void* domObject)
+{
+ switch (type) {
+ case V8ClassIndex::NODE:
+ static_cast<Node*>(domObject)->deref();
+ break;
+
+#define MakeCase(type, name) \
+ case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
+ DOM_OBJECT_TYPES(MakeCase) // This includes both active and non-active.
+#undef MakeCase
+
+#if ENABLE(SVG)
+#define MakeCase(type, name) \
+ case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
+ SVG_OBJECT_TYPES(MakeCase) // This also includes SVGElementInstance.
+#undef MakeCase
+
+#define MakeCase(type, name) \
+ case V8ClassIndex::type: \
+ static_cast<V8SVGPODTypeWrapper<name>*>(domObject)->deref(); break;
+ SVG_POD_NATIVE_TYPES(MakeCase)
+#undef MakeCase
+#endif
+
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void DOMData::derefDelayedObjects()
+{
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+
+ m_delayedProcessingScheduled = false;
+
+ for (DelayedObjectMap::iterator iter(m_delayedObjectMap.begin()); iter != m_delayedObjectMap.end(); ++iter)
+ derefObject(iter->second, iter->first);
+
+ m_delayedObjectMap.clear();
+}
+
+void DOMData::derefDelayedObjectsInCurrentThread(void*)
+{
+ getCurrent()->derefDelayedObjects();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/DOMData.h b/WebCore/bindings/v8/DOMData.h
new file mode 100644
index 0000000..5effe7c
--- /dev/null
+++ b/WebCore/bindings/v8/DOMData.h
@@ -0,0 +1,136 @@
+/*
+ * 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 DOMData_h
+#define DOMData_h
+
+#include "DOMDataStore.h"
+
+namespace WebCore {
+
+ // DOMData
+ //
+ // DOMData represents the all the DOM wrappers for a given thread. In
+ // particular, DOMData holds wrappers for all the isolated worlds in the
+ // thread. The DOMData for the main thread and the DOMData for child threads
+ // use different subclasses.
+ //
+ class DOMData : public Noncopyable {
+ public:
+ DOMData();
+
+ static DOMData* getCurrent();
+ static DOMData* getCurrentMainThread(); // Caller must be on the main thread.
+ virtual DOMDataStore& getStore() = 0;
+
+ template<typename T>
+ static void handleWeakObject(DOMDataStore::DOMWrapperMapType, v8::Handle<v8::Object>, T* domObject);
+
+ void forgetDelayedObject(void* object) { m_delayedObjectMap.take(object); }
+
+ // This is to ensure that we will deref DOM objects from the owning thread,
+ // not the GC thread. The helper function will be scheduled by the GC
+ // thread to get called from the owning thread.
+ static void derefDelayedObjectsInCurrentThread(void*);
+ void derefDelayedObjects();
+
+ template<typename T>
+ static void removeObjectsFromWrapperMap(DOMWrapperMap<T>& domMap);
+
+ ThreadIdentifier owningThread() const { return m_owningThread; }
+
+ private:
+ typedef WTF::HashMap<void*, V8ClassIndex::V8WrapperType> DelayedObjectMap;
+
+ void ensureDeref(V8ClassIndex::V8WrapperType type, void* domObject);
+ static void derefObject(V8ClassIndex::V8WrapperType type, void* domObject);
+
+ // Stores all the DOM objects that are delayed to be processed when the
+ // owning thread gains control.
+ DelayedObjectMap m_delayedObjectMap;
+
+ // The flag to indicate if the task to do the delayed process has
+ // already been posted.
+ bool m_delayedProcessingScheduled;
+
+ bool m_isMainThread;
+ ThreadIdentifier m_owningThread;
+ };
+
+ // Called when the dead object is not in GC thread's map. Go through all
+ // thread maps to find the one containing it. Then clear the JS reference
+ // and push the DOM object into the delayed queue for it to be deref-ed at
+ // later time from the owning thread.
+ //
+ // * This is called when the GC thread is not the owning thread.
+ // * This can be called on any thread that has GC running.
+ // * Only one V8 instance is running at a time due to V8::Locker. So we don't need to worry about concurrency.
+ //
+ template<typename T>
+ void DOMData::handleWeakObject(DOMDataStore::DOMWrapperMapType mapType, v8::Handle<v8::Object> v8Object, T* domObject)
+ {
+
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+
+ DOMDataStore::InternalDOMWrapperMap<T>* domMap = static_cast<DOMDataStore::InternalDOMWrapperMap<T>*>(store->getDOMWrapperMap(mapType));
+
+ v8::Handle<v8::Object> wrapper = domMap->get(domObject);
+ if (*wrapper == *v8Object) {
+ // Clear the JS reference.
+ domMap->forgetOnly(domObject);
+ store->domData()->ensureDeref(V8DOMWrapper::domWrapperType(v8Object), domObject);
+ }
+ }
+ }
+
+ template<typename T>
+ void DOMData::removeObjectsFromWrapperMap(DOMWrapperMap<T>& domMap)
+ {
+ for (typename WTF::HashMap<T*, v8::Object*>::iterator iter(domMap.impl().begin()); iter != domMap.impl().end(); ++iter) {
+ T* domObject = static_cast<T*>(iter->first);
+ v8::Persistent<v8::Object> v8Object(iter->second);
+
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(v8::Handle<v8::Object>::Cast(v8Object));
+
+ // Deref the DOM object.
+ derefObject(type, domObject);
+
+ // Clear the JS wrapper.
+ v8Object.Dispose();
+ }
+ domMap.impl().clear();
+ }
+
+} // namespace WebCore
+
+#endif // DOMData_h
diff --git a/WebCore/bindings/v8/DOMDataStore.cpp b/WebCore/bindings/v8/DOMDataStore.cpp
new file mode 100644
index 0000000..a76ca53
--- /dev/null
+++ b/WebCore/bindings/v8/DOMDataStore.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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 "DOMDataStore.h"
+
+#include "DOMData.h"
+
+namespace WebCore {
+
+// DOM binding algorithm:
+//
+// There are two kinds of DOM objects:
+// 1. DOM tree nodes, such as Document, HTMLElement, ...
+// there classes implement TreeShared<T> interface;
+// 2. Non-node DOM objects, such as CSSRule, Location, etc.
+// these classes implement a ref-counted scheme.
+//
+// A DOM object may have a JS wrapper object. If a tree node
+// is alive, its JS wrapper must be kept alive even it is not
+// reachable from JS roots.
+// However, JS wrappers of non-node objects can go away if
+// not reachable from other JS objects. It works like a cache.
+//
+// DOM objects are ref-counted, and JS objects are traced from
+// a set of root objects. They can create a cycle. To break
+// cycles, we do following:
+// Handles from DOM objects to JS wrappers are always weak,
+// so JS wrappers of non-node object cannot create a cycle.
+// Before starting a global GC, we create a virtual connection
+// between nodes in the same tree in the JS heap. If the wrapper
+// of one node in a tree is alive, wrappers of all nodes in
+// the same tree are considered alive. This is done by creating
+// object groups in GC prologue callbacks. The mark-compact
+// collector will remove these groups after each GC.
+//
+// DOM objects should be deref-ed from the owning thread, not the GC thread
+// that does not own them. In V8, GC can kick in from any thread. To ensure
+// that DOM objects are always deref-ed from the owning thread when running
+// V8 in multi-threading environment, we do following:
+// 1. Maintain a thread specific DOM wrapper map for each object map.
+// (We're using TLS support from WTF instead of base since V8Bindings
+// does not depend on base. We further assume that all child threads
+// running V8 instances are created by WTF and thus a destructor will
+// be called to clean up all thread specific data.)
+// 2. When GC happens:
+// 2.1. If the dead object is in GC thread's map, remove the JS reference
+// and deref the DOM object.
+// 2.2. Otherwise, go through all thread maps to find the owning thread.
+// Remove the JS reference from the owning thread's map and move the
+// DOM object to a delayed queue. Post a task to the owning thread
+// to have it deref-ed from the owning thread at later time.
+// 3. When a thread is tearing down, invoke a cleanup routine to go through
+// all objects in the delayed queue and the thread map and deref all of
+// them.
+
+
+DOMDataStore::DOMDataStore(DOMData* domData)
+ : m_domNodeMap(0)
+ , m_domObjectMap(0)
+ , m_activeDomObjectMap(0)
+#if ENABLE(SVG)
+ , m_domSvgElementInstanceMap(0)
+ , m_domSvgObjectWithContextMap(0)
+#endif
+ , m_domData(domData)
+{
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataStore::allStores().append(this);
+}
+
+DOMDataStore::~DOMDataStore()
+{
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataStore::allStores().remove(DOMDataStore::allStores().find(this));
+}
+
+DOMDataList& DOMDataStore::allStores()
+{
+ DEFINE_STATIC_LOCAL(DOMDataList, staticDOMDataList, ());
+ return staticDOMDataList;
+}
+
+WTF::Mutex& DOMDataStore::allStoresMutex()
+{
+ DEFINE_STATIC_LOCAL(WTF::Mutex, staticDOMDataListMutex, ());
+ return staticDOMDataListMutex;
+}
+
+void DOMDataStore::forgetDelayedObject(DOMData* domData, void* object)
+{
+ domData->forgetDelayedObject(object);
+}
+
+void* DOMDataStore::getDOMWrapperMap(DOMWrapperMapType type)
+{
+ switch (type) {
+ case DOMNodeMap:
+ return m_domNodeMap;
+ case DOMObjectMap:
+ return m_domObjectMap;
+ case ActiveDOMObjectMap:
+ return m_activeDomObjectMap;
+#if ENABLE(SVG)
+ case DOMSVGElementInstanceMap:
+ return m_domSvgElementInstanceMap;
+ case DOMSVGObjectWithContextMap:
+ return m_domSvgObjectWithContextMap;
+#endif
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+// Called when the object is near death (not reachable from JS roots).
+// It is time to remove the entry from the table and dispose the handle.
+void DOMDataStore::weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+{
+ v8::HandleScope scope;
+ ASSERT(v8Object->IsObject());
+ DOMData::handleWeakObject(DOMDataStore::DOMObjectMap, v8::Handle<v8::Object>::Cast(v8Object), domObject);
+}
+
+void DOMDataStore::weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+{
+ v8::HandleScope scope;
+ ASSERT(v8Object->IsObject());
+ DOMData::handleWeakObject(DOMDataStore::ActiveDOMObjectMap, v8::Handle<v8::Object>::Cast(v8Object), domObject);
+}
+
+void DOMDataStore::weakNodeCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+{
+ ASSERT(WTF::isMainThread());
+
+ Node* node = static_cast<Node*>(domObject);
+
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+ HashMap<Node*, v8::Object*>& domMapImpl = store->domNodeMap().impl();
+ HashMap<Node*, v8::Object*>::iterator it = domMapImpl.find(node);
+ if (it == domMapImpl.end() || it->second != *v8Object)
+ continue;
+ ASSERT(store->domData()->owningThread() == WTF::currentThread());
+ v8Object.Dispose();
+ domMapImpl.remove(it);
+ node->deref(); // Nobody overrides Node::deref so it's safe
+ break; // There might be at most one wrapper for the node in world's maps
+ }
+}
+
+#if ENABLE(SVG)
+
+void DOMDataStore::weakSVGElementInstanceCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+{
+ v8::HandleScope scope;
+ ASSERT(v8Object->IsObject());
+ DOMData::handleWeakObject(DOMDataStore::DOMSVGElementInstanceMap, v8::Handle<v8::Object>::Cast(v8Object), static_cast<SVGElementInstance*>(domObject));
+}
+
+void DOMDataStore::weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+{
+ v8::HandleScope scope;
+ ASSERT(v8Object->IsObject());
+ DOMData::handleWeakObject(DOMDataStore::DOMSVGObjectWithContextMap, v8::Handle<v8::Object>::Cast(v8Object), domObject);
+}
+
+#endif // ENABLE(SVG)
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/DOMDataStore.h b/WebCore/bindings/v8/DOMDataStore.h
new file mode 100644
index 0000000..b127089
--- /dev/null
+++ b/WebCore/bindings/v8/DOMDataStore.h
@@ -0,0 +1,142 @@
+/*
+ * 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 DOMDataStore_h
+#define DOMDataStore_h
+
+#include "DOMObjectsInclude.h"
+
+#include <v8.h>
+#include <wtf/HashMap.h>
+#include <wtf/MainThread.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/Threading.h>
+#include <wtf/ThreadSpecific.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class DOMData;
+
+ typedef WTF::Vector<DOMDataStore*> DOMDataList;
+
+ // DOMDataStore
+ //
+ // DOMDataStore is the backing store that holds the maps between DOM objects
+ // and JavaScript objects. In general, each thread can have multiple backing
+ // stores, one per isolated world.
+ //
+ // This class doesn't manage the lifetime of the store. The data store
+ // lifetime is managed by subclasses.
+ //
+ class DOMDataStore : public Noncopyable {
+ public:
+ enum DOMWrapperMapType {
+ DOMNodeMap,
+ DOMObjectMap,
+ ActiveDOMObjectMap,
+#if ENABLE(SVG)
+ DOMSVGElementInstanceMap,
+ DOMSVGObjectWithContextMap
+#endif
+ };
+
+ template <class KeyType>
+ class InternalDOMWrapperMap : public DOMWrapperMap<KeyType> {
+ public:
+ InternalDOMWrapperMap(DOMData* domData, v8::WeakReferenceCallback callback)
+ : DOMWrapperMap<KeyType>(callback), m_domData(domData) { }
+
+ virtual void forget(KeyType* object)
+ {
+ DOMWrapperMap<KeyType>::forget(object);
+ forgetDelayedObject(m_domData, object);
+ }
+
+ void forgetOnly(KeyType* object) { DOMWrapperMap<KeyType>::forget(object); }
+
+ private:
+ DOMData* m_domData;
+ };
+
+ DOMDataStore(DOMData*);
+ virtual ~DOMDataStore();
+
+ // A list of all DOMDataStore objects. Traversed during GC to find a thread-specific map that
+ // contains the object - so we can schedule the object to be deleted on the thread which created it.
+ static DOMDataList& allStores();
+ // Mutex to protect against concurrent access of DOMDataList.
+ static WTF::Mutex& allStoresMutex();
+
+ // Helper function to avoid circular includes.
+ static void forgetDelayedObject(DOMData*, void* object);
+
+ DOMData* domData() const { return m_domData; }
+
+ void* getDOMWrapperMap(DOMWrapperMapType);
+
+ InternalDOMWrapperMap<Node>& domNodeMap() { return *m_domNodeMap; }
+ InternalDOMWrapperMap<void>& domObjectMap() { return *m_domObjectMap; }
+ InternalDOMWrapperMap<void>& activeDomObjectMap() { return *m_activeDomObjectMap; }
+#if ENABLE(SVG)
+ InternalDOMWrapperMap<SVGElementInstance>& domSvgElementInstanceMap() { return *m_domSvgElementInstanceMap; }
+ InternalDOMWrapperMap<void>& domSvgObjectWithContextMap() { return *m_domSvgObjectWithContextMap; }
+#endif
+
+ // Need by V8GCController.
+ static void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
+
+ protected:
+ static void weakNodeCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
+ static void weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
+#if ENABLE(SVG)
+ static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
+ // SVG non-node elements may have a reference to a context node which should be notified when the element is change.
+ static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
+#endif
+
+ InternalDOMWrapperMap<Node>* m_domNodeMap;
+ InternalDOMWrapperMap<void>* m_domObjectMap;
+ InternalDOMWrapperMap<void>* m_activeDomObjectMap;
+#if ENABLE(SVG)
+ InternalDOMWrapperMap<SVGElementInstance>* m_domSvgElementInstanceMap;
+ InternalDOMWrapperMap<void>* m_domSvgObjectWithContextMap;
+#endif
+
+ private:
+ // A back-pointer to the DOMData to which we belong.
+ DOMData* m_domData;
+ };
+
+} // namespace WebCore
+
+#endif // DOMDataStore_h
diff --git a/WebCore/bindings/v8/DOMObjectsInclude.h b/WebCore/bindings/v8/DOMObjectsInclude.h
new file mode 100644
index 0000000..63464db
--- /dev/null
+++ b/WebCore/bindings/v8/DOMObjectsInclude.h
@@ -0,0 +1,229 @@
+/*
+ * 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 DOMObjectsInclude_h
+#define DOMObjectsInclude_h
+
+#include "AbstractWorker.h"
+#include "BarInfo.h"
+#include "CanvasGradient.h"
+#include "CanvasPattern.h"
+#include "CanvasPixelArray.h"
+#include "CanvasRenderingContext2D.h"
+#include "CanvasStyle.h"
+#include "CharacterData.h"
+#include "ClientRect.h"
+#include "ClientRectList.h"
+#include "Clipboard.h"
+#include "Console.h"
+#include "Counter.h"
+#include "CSSCharsetRule.h"
+#include "CSSFontFaceRule.h"
+#include "CSSImportRule.h"
+#include "CSSMediaRule.h"
+#include "CSSPageRule.h"
+#include "CSSRule.h"
+#include "CSSRuleList.h"
+#include "CSSStyleDeclaration.h"
+#include "CSSStyleRule.h"
+#include "CSSStyleSheet.h"
+#include "CSSValueList.h"
+#include "CSSVariablesDeclaration.h"
+#include "CSSVariablesRule.h"
+#include "Database.h"
+#include "DocumentType.h"
+#include "DocumentFragment.h"
+#include "DOMCoreException.h"
+#include "DOMImplementation.h"
+#include "DOMParser.h"
+#include "DOMSelection.h"
+#include "DOMWindow.h"
+#include "Entity.h"
+#include "ErrorEvent.h"
+#include "EventListener.h"
+#include "EventTarget.h"
+#include "Event.h"
+#include "EventException.h"
+#include "ExceptionCode.h"
+#include "File.h"
+#include "FileList.h"
+#include "Frame.h"
+#include "FrameLoader.h"
+#include "FrameTree.h"
+#include "History.h"
+#include "HTMLNames.h"
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
+#include "HTMLImageElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLSelectElement.h"
+#include "HTMLOptionsCollection.h"
+#include "ImageData.h"
+#include "InspectorBackend.h"
+#include "KeyboardEvent.h"
+#include "Location.h"
+#include "Media.h"
+#include "MediaError.h"
+#include "MediaList.h"
+#include "MediaPlayer.h"
+#include "MessageChannel.h"
+#include "MessageEvent.h"
+#include "MessagePort.h"
+#include "MimeTypeArray.h"
+#include "MouseEvent.h"
+#include "MutationEvent.h"
+#include "Navigator.h" // for MimeTypeArray
+#include "NodeFilter.h"
+#include "Notation.h"
+#include "NodeList.h"
+#include "NodeIterator.h"
+#include "OverflowEvent.h"
+#include "Page.h"
+#include "Plugin.h"
+#include "PluginArray.h"
+#include "ProcessingInstruction.h"
+#include "ProgressEvent.h"
+#include "Range.h"
+#include "RangeException.h"
+#include "Rect.h"
+#include "RGBColor.h"
+#include "Screen.h"
+#include "ScriptExecutionContext.h"
+#include "SecurityOrigin.h"
+#include "Settings.h"
+#include "SharedWorker.h"
+#include "SharedWorkerContext.h"
+#include "SQLTransaction.h"
+#include "SQLResultSet.h"
+#include "SQLResultSetRowList.h"
+#include "StyleSheet.h"
+#include "StyleSheetList.h"
+#include "SVGColor.h"
+#include "SVGPaint.h"
+#include "TextEvent.h"
+#include "TextMetrics.h"
+#include "TimeRanges.h"
+#include "TreeWalker.h"
+#include "XSLTProcessor.h"
+#include "V8AbstractEventListener.h"
+#include "V8CustomEventListener.h"
+#include "V8DOMWindow.h"
+#include "V8HTMLElement.h"
+#include "V8LazyEventListener.h"
+#include "V8NodeFilterCondition.h"
+#include "V8ObjectEventListener.h"
+#include "ValidityState.h"
+#include "WebKitAnimationEvent.h"
+#include "WebKitCSSKeyframeRule.h"
+#include "WebKitCSSKeyframesRule.h"
+#include "WebKitCSSMatrix.h"
+#include "WebKitCSSTransformValue.h"
+#include "WebKitPoint.h"
+#include "WebKitTransitionEvent.h"
+#include "WheelEvent.h"
+#include "XMLHttpRequest.h"
+#include "XMLHttpRequestException.h"
+#include "XMLHttpRequestProgressEvent.h"
+#include "XMLHttpRequestUpload.h"
+#include "XMLSerializer.h"
+#include "XPathException.h"
+#include "XPathExpression.h"
+#include "XPathNSResolver.h"
+#include "XPathResult.h"
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "DOMApplicationCache.h"
+#endif
+
+#if ENABLE(DATAGRID)
+#include "DataGridColumn.h"
+#include "DataGridColumnList.h"
+#endif // DATAGRID
+
+#if ENABLE(DOM_STORAGE)
+#include "Storage.h"
+#include "StorageEvent.h"
+#endif // DOM_STORAGE
+
+#if ENABLE(SVG)
+#include "SVGAngle.h"
+#include "SVGAnimatedPoints.h"
+#include "SVGElement.h"
+#include "SVGElementInstance.h"
+#include "SVGElementInstanceList.h"
+#include "SVGException.h"
+#include "SVGLength.h"
+#include "SVGLengthList.h"
+#include "SVGNumberList.h"
+#include "SVGPathSeg.h"
+#include "SVGPathSegArc.h"
+#include "SVGPathSegClosePath.h"
+#include "SVGPathSegCurvetoCubic.h"
+#include "SVGPathSegCurvetoCubicSmooth.h"
+#include "SVGPathSegCurvetoQuadratic.h"
+#include "SVGPathSegCurvetoQuadraticSmooth.h"
+#include "SVGPathSegLineto.h"
+#include "SVGPathSegLinetoHorizontal.h"
+#include "SVGPathSegLinetoVertical.h"
+#include "SVGPathSegList.h"
+#include "SVGPathSegMoveto.h"
+#include "SVGPointList.h"
+#include "SVGPreserveAspectRatio.h"
+#include "SVGRenderingIntent.h"
+#include "SVGStringList.h"
+#include "SVGTransform.h"
+#include "SVGTransformList.h"
+#include "SVGUnitTypes.h"
+#include "SVGURIReference.h"
+#include "SVGZoomEvent.h"
+#include "V8SVGPODTypeWrapper.h"
+#endif // SVG
+
+#if ENABLE(WORKERS)
+#include "DedicatedWorkerContext.h"
+#include "Worker.h"
+#include "WorkerContext.h"
+#include "WorkerLocation.h"
+#include "WorkerNavigator.h"
+#endif // WORKERS
+
+#if ENABLE(XPATH)
+#include "XPathEvaluator.h"
+#endif // XPATH
+
+namespace WebCore {
+
+ // A helper class for undetectable document.all
+ class HTMLAllCollection : public HTMLCollection {
+ };
+
+} // namespace WebCore
+
+#endif // DOMObjectsInclude_h
diff --git a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp
new file mode 100644
index 0000000..4962a92
--- /dev/null
+++ b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This source file coalesces the HTML elements into a single object file to
+// reduce bloat and allow us to link release builds on 32-bit Windows.
+
+#include "bindings/V8AbstractWorker.cpp"
+#include "bindings/V8Attr.cpp"
+#include "bindings/V8BarInfo.cpp"
+#include "bindings/V8CanvasGradient.cpp"
+#include "bindings/V8CanvasPattern.cpp"
+#include "bindings/V8CanvasPixelArray.cpp"
+#include "bindings/V8CanvasRenderingContext2D.cpp"
+#include "bindings/V8CDATASection.cpp"
+#include "bindings/V8CharacterData.cpp"
+#include "bindings/V8ClientRect.cpp"
+#include "bindings/V8ClientRectList.cpp"
+#include "bindings/V8Clipboard.cpp"
+#include "bindings/V8Comment.cpp"
+#include "bindings/V8Console.cpp"
+#include "bindings/V8Counter.cpp"
+#include "bindings/V8CSSCharsetRule.cpp"
+#include "bindings/V8CSSFontFaceRule.cpp"
+#include "bindings/V8CSSImportRule.cpp"
+#include "bindings/V8CSSMediaRule.cpp"
+#include "bindings/V8CSSPageRule.cpp"
+#include "bindings/V8CSSPrimitiveValue.cpp"
+#include "bindings/V8CSSRule.cpp"
+#include "bindings/V8CSSRuleList.cpp"
+#include "bindings/V8CSSStyleDeclaration.cpp"
+#include "bindings/V8CSSStyleRule.cpp"
+#include "bindings/V8CSSStyleSheet.cpp"
+#include "bindings/V8CSSValue.cpp"
+#include "bindings/V8CSSValueList.cpp"
+#include "bindings/V8CSSVariablesDeclaration.cpp"
+#include "bindings/V8CSSVariablesRule.cpp"
+#include "bindings/V8Database.cpp"
+#include "bindings/V8DataGridColumn.cpp"
+#include "bindings/V8DataGridColumnList.cpp"
+#include "bindings/V8DedicatedWorkerContext.cpp"
+#include "bindings/V8Document.cpp"
+#include "bindings/V8DocumentFragment.cpp"
+#include "bindings/V8DocumentType.cpp"
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "bindings/V8DOMApplicationCache.cpp"
+#endif
+#include "bindings/V8DOMCoreException.cpp"
+#include "bindings/V8DOMImplementation.cpp"
+#include "bindings/V8DOMParser.cpp"
+#include "bindings/V8DOMSelection.cpp"
+#include "bindings/V8DOMWindow.cpp"
+#include "bindings/V8Element.cpp"
+#include "bindings/V8Entity.cpp"
+#include "bindings/V8EntityReference.cpp"
+#include "bindings/V8ErrorEvent.cpp"
+#include "bindings/V8Event.cpp"
+#include "bindings/V8EventException.cpp"
+#include "bindings/V8File.cpp"
+#include "bindings/V8FileList.cpp"
+#include "bindings/V8History.cpp"
+#include "bindings/V8HTMLAllCollection.cpp"
+#include "bindings/V8HTMLAnchorElement.cpp"
+#include "bindings/V8HTMLAppletElement.cpp"
+#include "bindings/V8HTMLAreaElement.cpp"
+#include "bindings/V8HTMLAudioElement.cpp"
+#include "bindings/V8HTMLBaseElement.cpp"
+#include "bindings/V8HTMLBaseFontElement.cpp"
+#include "bindings/V8HTMLBlockquoteElement.cpp"
+#include "bindings/V8HTMLBodyElement.cpp"
+#include "bindings/V8HTMLBRElement.cpp"
+#include "bindings/V8HTMLButtonElement.cpp"
+#include "bindings/V8HTMLCanvasElement.cpp"
+#include "bindings/V8HTMLCollection.cpp"
+#include "bindings/V8HTMLDataGridCellElement.cpp"
+#include "bindings/V8HTMLDataGridColElement.cpp"
+#include "bindings/V8HTMLDataGridElement.cpp"
+#include "bindings/V8HTMLDataGridRowElement.cpp"
+#include "bindings/V8HTMLDirectoryElement.cpp"
+#include "bindings/V8HTMLDivElement.cpp"
+#include "bindings/V8HTMLDListElement.cpp"
+#include "bindings/V8HTMLDocument.cpp"
+#include "bindings/V8HTMLElement.cpp"
+#include "bindings/V8HTMLEmbedElement.cpp"
+#include "bindings/V8HTMLFieldSetElement.cpp"
+#include "bindings/V8HTMLFontElement.cpp"
+#include "bindings/V8HTMLFormElement.cpp"
+#include "bindings/V8HTMLFrameElement.cpp"
+#include "bindings/V8HTMLFrameSetElement.cpp"
+#include "bindings/V8HTMLHeadElement.cpp"
+#include "bindings/V8HTMLHeadingElement.cpp"
+#include "bindings/V8HTMLHRElement.cpp"
+#include "bindings/V8HTMLHtmlElement.cpp"
+#include "bindings/V8HTMLIFrameElement.cpp"
+#include "bindings/V8HTMLImageElement.cpp"
+#include "bindings/V8HTMLInputElement.cpp"
+#include "bindings/V8HTMLIsIndexElement.cpp"
+#include "bindings/V8HTMLLabelElement.cpp"
+#include "bindings/V8HTMLLegendElement.cpp"
+#include "bindings/V8HTMLLIElement.cpp"
+#include "bindings/V8HTMLLinkElement.cpp"
+#include "bindings/V8HTMLMapElement.cpp"
+#include "bindings/V8HTMLMarqueeElement.cpp"
+#include "bindings/V8HTMLMediaElement.cpp"
+#include "bindings/V8HTMLMenuElement.cpp"
+#include "bindings/V8HTMLMetaElement.cpp"
+#include "bindings/V8HTMLModElement.cpp"
+#include "bindings/V8HTMLObjectElement.cpp"
+#include "bindings/V8HTMLOListElement.cpp"
+#include "bindings/V8HTMLOptGroupElement.cpp"
+#include "bindings/V8HTMLOptionElement.cpp"
+#include "bindings/V8HTMLOptionsCollection.cpp"
+#include "bindings/V8HTMLParagraphElement.cpp"
+#include "bindings/V8HTMLParamElement.cpp"
+#include "bindings/V8HTMLPreElement.cpp"
+#include "bindings/V8HTMLQuoteElement.cpp"
+#include "bindings/V8HTMLScriptElement.cpp"
+#include "bindings/V8HTMLSelectElement.cpp"
+#include "bindings/V8HTMLSourceElement.cpp"
+#include "bindings/V8HTMLStyleElement.cpp"
+#include "bindings/V8HTMLTableCaptionElement.cpp"
+#include "bindings/V8HTMLTableCellElement.cpp"
+#include "bindings/V8HTMLTableColElement.cpp"
+#include "bindings/V8HTMLTableElement.cpp"
+#include "bindings/V8HTMLTableRowElement.cpp"
+#include "bindings/V8HTMLTableSectionElement.cpp"
+#include "bindings/V8HTMLTextAreaElement.cpp"
+#include "bindings/V8HTMLTitleElement.cpp"
+#include "bindings/V8HTMLUListElement.cpp"
+#include "bindings/V8HTMLVideoElement.cpp"
+#include "bindings/V8ImageData.cpp"
+#include "bindings/V8InspectorBackend.cpp"
+#include "bindings/V8KeyboardEvent.cpp"
+#include "bindings/V8Location.cpp"
+#include "bindings/V8Media.cpp"
+#include "bindings/V8MediaError.cpp"
+#include "bindings/V8MediaList.cpp"
+#include "bindings/V8MessageChannel.cpp"
+#include "bindings/V8MessageEvent.cpp"
+#include "bindings/V8MessagePort.cpp"
+#include "bindings/V8MimeType.cpp"
+#include "bindings/V8MimeTypeArray.cpp"
+#include "bindings/V8MouseEvent.cpp"
+#include "bindings/V8MutationEvent.cpp"
+#include "bindings/V8NamedNodeMap.cpp"
+#include "bindings/V8Navigator.cpp"
+#include "bindings/V8Node.cpp"
+#include "bindings/V8NodeFilter.cpp"
+#include "bindings/V8NodeIterator.cpp"
+#include "bindings/V8NodeList.cpp"
+#include "bindings/V8Notation.cpp"
+#include "bindings/V8OverflowEvent.cpp"
+#include "bindings/V8Plugin.cpp"
+#include "bindings/V8PluginArray.cpp"
+#include "bindings/V8ProcessingInstruction.cpp"
+#include "bindings/V8ProgressEvent.cpp"
+#include "bindings/V8Range.cpp"
+#include "bindings/V8RangeException.cpp"
+#include "bindings/V8Rect.cpp"
+#include "bindings/V8RGBColor.cpp"
+#include "bindings/V8Screen.cpp"
+#include "bindings/V8SharedWorker.cpp"
+#include "bindings/V8SQLError.cpp"
+#include "bindings/V8SQLResultSet.cpp"
+#include "bindings/V8SQLResultSetRowList.cpp"
+#include "bindings/V8SQLTransaction.cpp"
+#if ENABLE(DOM_STORAGE)
+#include "bindings/V8Storage.cpp"
+#include "bindings/V8StorageEvent.cpp"
+#endif
+#include "bindings/V8StyleSheet.cpp"
+#include "bindings/V8StyleSheetList.cpp"
+#include "bindings/V8SVGAElement.cpp"
+#include "bindings/V8SVGAltGlyphElement.cpp"
+#include "bindings/V8SVGAngle.cpp"
+#include "bindings/V8SVGAnimateColorElement.cpp"
+#include "bindings/V8SVGAnimatedAngle.cpp"
+#include "bindings/V8SVGAnimatedBoolean.cpp"
+#include "bindings/V8SVGAnimatedEnumeration.cpp"
+#include "bindings/V8SVGAnimatedInteger.cpp"
+#include "bindings/V8SVGAnimatedLength.cpp"
+#include "bindings/V8SVGAnimatedLengthList.cpp"
+#include "bindings/V8SVGAnimatedNumber.cpp"
+#include "bindings/V8SVGAnimatedNumberList.cpp"
+#include "bindings/V8SVGAnimatedPoints.cpp"
+#include "bindings/V8SVGAnimatedPreserveAspectRatio.cpp"
+#include "bindings/V8SVGAnimatedRect.cpp"
+#include "bindings/V8SVGAnimatedString.cpp"
+#include "bindings/V8SVGAnimatedTransformList.cpp"
+#include "bindings/V8SVGAnimateElement.cpp"
+#include "bindings/V8SVGAnimateTransformElement.cpp"
+#include "bindings/V8SVGAnimationElement.cpp"
+#include "bindings/V8SVGCircleElement.cpp"
+#include "bindings/V8SVGClipPathElement.cpp"
+#include "bindings/V8SVGColor.cpp"
+#include "bindings/V8SVGCursorElement.cpp"
+#include "bindings/V8SVGDefinitionSrcElement.cpp"
+#include "bindings/V8SVGDefsElement.cpp"
+#include "bindings/V8SVGDescElement.cpp"
+#include "bindings/V8SVGDocument.cpp"
+#include "bindings/V8SVGElement.cpp"
+#include "bindings/V8SVGElementInstance.cpp"
+#include "bindings/V8SVGElementInstanceList.cpp"
+#include "bindings/V8SVGEllipseElement.cpp"
+#include "bindings/V8SVGException.cpp"
+#include "bindings/V8SVGFontElement.cpp"
+#include "bindings/V8SVGFontFaceElement.cpp"
+#include "bindings/V8SVGFontFaceFormatElement.cpp"
+#include "bindings/V8SVGFontFaceNameElement.cpp"
+#include "bindings/V8SVGFontFaceSrcElement.cpp"
+#include "bindings/V8SVGFontFaceUriElement.cpp"
+#include "bindings/V8SVGForeignObjectElement.cpp"
+#include "bindings/V8SVGGElement.cpp"
+#include "bindings/V8SVGGlyphElement.cpp"
+#include "bindings/V8SVGGradientElement.cpp"
+#include "bindings/V8SVGImageElement.cpp"
+#include "bindings/V8SVGLength.cpp"
+#include "bindings/V8SVGLengthList.cpp"
+#include "bindings/V8SVGLinearGradientElement.cpp"
+#include "bindings/V8SVGLineElement.cpp"
+#include "bindings/V8SVGMarkerElement.cpp"
+#include "bindings/V8SVGMaskElement.cpp"
+#include "bindings/V8SVGMatrix.cpp"
+#include "bindings/V8SVGMetadataElement.cpp"
+#include "bindings/V8SVGMissingGlyphElement.cpp"
+#include "bindings/V8SVGNumber.cpp"
+#include "bindings/V8SVGNumberList.cpp"
+#include "bindings/V8SVGPaint.cpp"
+#include "bindings/V8SVGPathElement.cpp"
+#include "bindings/V8SVGPathSeg.cpp"
+#include "bindings/V8SVGPathSegArcAbs.cpp"
+#include "bindings/V8SVGPathSegArcRel.cpp"
+#include "bindings/V8SVGPathSegClosePath.cpp"
+#include "bindings/V8SVGPathSegCurvetoCubicAbs.cpp"
+#include "bindings/V8SVGPathSegCurvetoCubicRel.cpp"
+#include "bindings/V8SVGPathSegCurvetoCubicSmoothAbs.cpp"
+#include "bindings/V8SVGPathSegCurvetoCubicSmoothRel.cpp"
+#include "bindings/V8SVGPathSegCurvetoQuadraticAbs.cpp"
+#include "bindings/V8SVGPathSegCurvetoQuadraticRel.cpp"
+#include "bindings/V8SVGPathSegCurvetoQuadraticSmoothAbs.cpp"
+#include "bindings/V8SVGPathSegCurvetoQuadraticSmoothRel.cpp"
+#include "bindings/V8SVGPathSegLinetoAbs.cpp"
+#include "bindings/V8SVGPathSegLinetoHorizontalAbs.cpp"
+#include "bindings/V8SVGPathSegLinetoHorizontalRel.cpp"
+#include "bindings/V8SVGPathSegLinetoRel.cpp"
+#include "bindings/V8SVGPathSegLinetoVerticalAbs.cpp"
+#include "bindings/V8SVGPathSegLinetoVerticalRel.cpp"
+#include "bindings/V8SVGPathSegList.cpp"
+#include "bindings/V8SVGPathSegMovetoAbs.cpp"
+#include "bindings/V8SVGPathSegMovetoRel.cpp"
+#include "bindings/V8SVGPatternElement.cpp"
+#include "bindings/V8SVGPoint.cpp"
+#include "bindings/V8SVGPointList.cpp"
+#include "bindings/V8SVGPolygonElement.cpp"
+#include "bindings/V8SVGPolylineElement.cpp"
+#include "bindings/V8SVGPreserveAspectRatio.cpp"
+#include "bindings/V8SVGRadialGradientElement.cpp"
+#include "bindings/V8SVGRect.cpp"
+#include "bindings/V8SVGRectElement.cpp"
+#include "bindings/V8SVGRenderingIntent.cpp"
+#include "bindings/V8SVGScriptElement.cpp"
+#include "bindings/V8SVGSetElement.cpp"
+#include "bindings/V8SVGStopElement.cpp"
+#include "bindings/V8SVGStringList.cpp"
+#include "bindings/V8SVGStyleElement.cpp"
+#include "bindings/V8SVGSVGElement.cpp"
+#include "bindings/V8SVGSwitchElement.cpp"
+#include "bindings/V8SVGSymbolElement.cpp"
+#include "bindings/V8SVGTextContentElement.cpp"
+#include "bindings/V8SVGTextElement.cpp"
+#include "bindings/V8SVGTextPathElement.cpp"
+#include "bindings/V8SVGTextPositioningElement.cpp"
+#include "bindings/V8SVGTitleElement.cpp"
+#include "bindings/V8SVGTransform.cpp"
+#include "bindings/V8SVGTransformList.cpp"
+#include "bindings/V8SVGTRefElement.cpp"
+#include "bindings/V8SVGTSpanElement.cpp"
+#include "bindings/V8SVGUnitTypes.cpp"
+#include "bindings/V8SVGURIReference.cpp"
+#include "bindings/V8SVGUseElement.cpp"
+#include "bindings/V8SVGViewElement.cpp"
+#include "bindings/V8SVGZoomEvent.cpp"
+#include "bindings/V8Text.cpp"
+#include "bindings/V8TextEvent.cpp"
+#include "bindings/V8TextMetrics.cpp"
+#include "bindings/V8TimeRanges.cpp"
+#include "bindings/V8TreeWalker.cpp"
+#include "bindings/V8UIEvent.cpp"
+#include "bindings/V8ValidityState.cpp"
+#include "bindings/V8WebKitAnimationEvent.cpp"
+#include "bindings/V8WebKitCSSKeyframeRule.cpp"
+#include "bindings/V8WebKitCSSKeyframesRule.cpp"
+#include "bindings/V8WebKitCSSMatrix.cpp"
+#include "bindings/V8WebKitCSSTransformValue.cpp"
+#include "bindings/V8WebKitPoint.cpp"
+#include "bindings/V8WebKitTransitionEvent.cpp"
+#include "bindings/V8WheelEvent.cpp"
+#include "bindings/V8Worker.cpp"
+#include "bindings/V8WorkerContext.cpp"
+#include "bindings/V8WorkerLocation.cpp"
+#include "bindings/V8WorkerNavigator.cpp"
+#include "bindings/V8XMLHttpRequest.cpp"
+#include "bindings/V8XMLHttpRequestException.cpp"
+#include "bindings/V8XMLHttpRequestProgressEvent.cpp"
+#include "bindings/V8XMLHttpRequestUpload.cpp"
+#include "bindings/V8XMLSerializer.cpp"
+#include "bindings/V8XPathEvaluator.cpp"
+#include "bindings/V8XPathException.cpp"
+#include "bindings/V8XPathExpression.cpp"
+#include "bindings/V8XPathNSResolver.cpp"
+#include "bindings/V8XPathResult.cpp"
+#include "bindings/V8XSLTProcessor.cpp"
diff --git a/WebCore/bindings/v8/MainThreadDOMData.cpp b/WebCore/bindings/v8/MainThreadDOMData.cpp
new file mode 100644
index 0000000..ea34444
--- /dev/null
+++ b/WebCore/bindings/v8/MainThreadDOMData.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 "MainThreadDOMData.h"
+
+#include "V8IsolatedWorld.h"
+
+namespace WebCore {
+
+MainThreadDOMData::MainThreadDOMData()
+ : m_defaultStore(this)
+{
+}
+
+DOMDataStore& MainThreadDOMData::getStore()
+{
+ ASSERT(WTF::isMainThread());
+ V8IsolatedWorld* world = V8IsolatedWorld::getEntered();
+ if (world)
+ return *world->getDOMDataStore();
+ return m_defaultStore;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/MainThreadDOMData.h b/WebCore/bindings/v8/MainThreadDOMData.h
new file mode 100644
index 0000000..5c78cec
--- /dev/null
+++ b/WebCore/bindings/v8/MainThreadDOMData.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 MainThreadDOMData_h
+#define MainThreadDOMData_h
+
+#include "DOMData.h"
+#include "StaticDOMDataStore.h"
+
+namespace WebCore {
+
+ class MainThreadDOMData : public DOMData {
+ public:
+ MainThreadDOMData();
+ DOMDataStore& getStore();
+
+ private:
+ StaticDOMDataStore m_defaultStore;
+ // Note: The DOMDataStores for isolated world are owned by the world object.
+ };
+
+} // namespace WebCore
+
+#endif // MainThreadDOMData_h
diff --git a/WebCore/bindings/v8/NPV8Object.cpp b/WebCore/bindings/v8/NPV8Object.cpp
new file mode 100644
index 0000000..15dc852
--- /dev/null
+++ b/WebCore/bindings/v8/NPV8Object.cpp
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 "NPV8Object.h"
+
+#include "ChromiumBridge.h"
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "OwnArrayPtr.h"
+#include "PlatformString.h"
+#include "ScriptController.h"
+#include "V8CustomBinding.h"
+#include "V8GCController.h"
+#include "V8Helpers.h"
+#include "V8NPUtils.h"
+#include "V8Proxy.h"
+#include "bindings/npruntime.h"
+#include "npruntime_impl.h"
+#include "npruntime_priv.h"
+
+#include <stdio.h>
+#include <v8.h>
+#include <wtf/StringExtras.h>
+
+using WebCore::toV8Context;
+using WebCore::toV8Proxy;
+using WebCore::V8ClassIndex;
+using WebCore::V8Custom;
+using WebCore::V8DOMWrapper;
+using WebCore::V8GCController;
+using WebCore::V8Proxy;
+
+// FIXME: Comments on why use malloc and free.
+static NPObject* allocV8NPObject(NPP, NPClass*)
+{
+ return static_cast<NPObject*>(malloc(sizeof(V8NPObject)));
+}
+
+static void freeV8NPObject(NPObject* npObject)
+{
+ V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject);
+#ifndef NDEBUG
+ V8GCController::unregisterGlobalHandle(v8NpObject, v8NpObject->v8Object);
+#endif
+ v8NpObject->v8Object.Dispose();
+ free(v8NpObject);
+}
+
+static v8::Handle<v8::Value>* createValueListFromVariantArgs(const NPVariant* arguments, uint32_t argumentCount, NPObject* owner)
+{
+ v8::Handle<v8::Value>* argv = new v8::Handle<v8::Value>[argumentCount];
+ for (uint32_t index = 0; index < argumentCount; index++) {
+ const NPVariant* arg = &arguments[index];
+ argv[index] = convertNPVariantToV8Object(arg, owner);
+ }
+ return argv;
+}
+
+// Create an identifier (null terminated utf8 char*) from the NPIdentifier.
+static v8::Local<v8::String> npIdentifierToV8Identifier(NPIdentifier name)
+{
+ PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(name);
+ if (identifier->isString)
+ return v8::String::New(static_cast<const char*>(identifier->value.string));
+
+ char buffer[32];
+ snprintf(buffer, sizeof(buffer), "%d", identifier->value.number);
+ return v8::String::New(buffer);
+}
+
+static NPClass V8NPObjectClass = { NP_CLASS_STRUCT_VERSION,
+ allocV8NPObject,
+ freeV8NPObject,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+// NPAPI's npruntime functions.
+NPClass* npScriptObjectClass = &V8NPObjectClass;
+
+NPObject* npCreateV8ScriptObject(NPP npp, v8::Handle<v8::Object> object, WebCore::DOMWindow* root)
+{
+ // Check to see if this object is already wrapped.
+ if (object->InternalFieldCount() == V8Custom::kNPObjectInternalFieldCount) {
+ v8::Local<v8::Value> typeIndex = object->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ if (typeIndex->IsNumber() && typeIndex->Uint32Value() == V8ClassIndex::NPOBJECT) {
+
+ NPObject* returnValue = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, object);
+ _NPN_RetainObject(returnValue);
+ return returnValue;
+ }
+ }
+
+ V8NPObject* v8npObject = reinterpret_cast<V8NPObject*>(_NPN_CreateObject(npp, &V8NPObjectClass));
+ v8npObject->v8Object = v8::Persistent<v8::Object>::New(object);
+#ifndef NDEBUG
+ V8GCController::registerGlobalHandle(WebCore::NPOBJECT, v8npObject, v8npObject->v8Object);
+#endif
+ v8npObject->rootObject = root;
+ return reinterpret_cast<NPObject*>(v8npObject);
+}
+
+bool _NPN_Invoke(NPP npp, NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class != npScriptObjectClass) {
+ if (npObject->_class->invoke)
+ return npObject->_class->invoke(npObject, methodName, arguments, argumentCount, result);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ }
+
+ V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject);
+
+ PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(methodName);
+ if (!identifier->isString)
+ return false;
+
+ v8::HandleScope handleScope;
+ // FIXME: should use the plugin's owner frame as the security context.
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ if (methodName == _NPN_GetStringIdentifier("eval")) {
+ if (argumentCount != 1)
+ return false;
+ if (arguments[0].type != NPVariantType_String)
+ return false;
+ return _NPN_Evaluate(npp, npObject, const_cast<NPString*>(&arguments[0].value.stringValue), result);
+ }
+
+ v8::Handle<v8::Value> functionObject = v8NpObject->v8Object->Get(v8::String::New(identifier->value.string));
+ if (functionObject.IsEmpty() || functionObject->IsNull()) {
+ NULL_TO_NPVARIANT(*result);
+ return false;
+ }
+ if (functionObject->IsUndefined()) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+
+ V8Proxy* proxy = toV8Proxy(npObject);
+ ASSERT(proxy);
+
+ // Call the function object.
+ v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(functionObject);
+ OwnArrayPtr<v8::Handle<v8::Value> > argv(createValueListFromVariantArgs(arguments, argumentCount, npObject));
+ v8::Local<v8::Value> resultObject = proxy->callFunction(function, v8NpObject->v8Object, argumentCount, argv.get());
+
+ // If we had an error, return false. The spec is a little unclear here, but says "Returns true if the method was
+ // successfully invoked". If we get an error return value, was that successfully invoked?
+ if (resultObject.IsEmpty())
+ return false;
+
+ convertV8ObjectToNPVariant(resultObject, npObject, result);
+ return true;
+}
+
+// FIXME: Fix it same as _NPN_Invoke (HandleScope and such).
+bool _NPN_InvokeDefault(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class != npScriptObjectClass) {
+ if (npObject->_class->invokeDefault)
+ return npObject->_class->invokeDefault(npObject, arguments, argumentCount, result);
+
+ VOID_TO_NPVARIANT(*result);
+ return true;
+ }
+
+ V8NPObject* v8NpObject = reinterpret_cast<V8NPObject*>(npObject);
+
+ VOID_TO_NPVARIANT(*result);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ // Lookup the function object and call it.
+ v8::Handle<v8::Object> functionObject(v8NpObject->v8Object);
+ if (!functionObject->IsFunction())
+ return false;
+
+ v8::Local<v8::Value> resultObject;
+ v8::Handle<v8::Function> function(v8::Function::Cast(*functionObject));
+ if (!function->IsNull()) {
+ V8Proxy* proxy = toV8Proxy(npObject);
+ ASSERT(proxy);
+
+ OwnArrayPtr<v8::Handle<v8::Value> > argv(createValueListFromVariantArgs(arguments, argumentCount, npObject));
+ resultObject = proxy->callFunction(function, functionObject, argumentCount, argv.get());
+ }
+ // If we had an error, return false. The spec is a little unclear here, but says "Returns true if the method was
+ // successfully invoked". If we get an error return value, was that successfully invoked?
+ if (resultObject.IsEmpty())
+ return false;
+
+ convertV8ObjectToNPVariant(resultObject, npObject, result);
+ return true;
+}
+
+bool _NPN_Evaluate(NPP npp, NPObject* npObject, NPString* npScript, NPVariant* result)
+{
+ bool popupsAllowed = WebCore::ChromiumBridge::popupsAllowed(npp);
+ return _NPN_EvaluateHelper(npp, popupsAllowed, npObject, npScript, result);
+}
+
+bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPString* npScript, NPVariant* result)
+{
+ VOID_TO_NPVARIANT(*result);
+ if (!npObject)
+ return false;
+
+ if (npObject->_class != npScriptObjectClass)
+ return false;
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+
+ V8Proxy* proxy = toV8Proxy(npObject);
+ ASSERT(proxy);
+
+ v8::Context::Scope scope(context);
+
+ WebCore::String filename;
+ if (!popupsAllowed)
+ filename = "npscript";
+
+ WebCore::String script = WebCore::String::fromUTF8(npScript->UTF8Characters, npScript->UTF8Length);
+ v8::Local<v8::Value> v8result = proxy->evaluate(WebCore::ScriptSourceCode(script, WebCore::KURL(filename)), 0);
+
+ if (v8result.IsEmpty())
+ return false;
+
+ convertV8ObjectToNPVariant(v8result, npObject, result);
+ return true;
+}
+
+bool _NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NPVariant* result)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class == npScriptObjectClass) {
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ v8::Local<v8::Value> v8result = obj->Get(npIdentifierToV8Identifier(propertyName));
+
+ convertV8ObjectToNPVariant(v8result, npObject, result);
+ return true;
+ }
+
+ if (npObject->_class->hasProperty && npObject->_class->getProperty) {
+ if (npObject->_class->hasProperty(npObject, propertyName))
+ return npObject->_class->getProperty(npObject, propertyName, result);
+ }
+
+ VOID_TO_NPVARIANT(*result);
+ return false;
+}
+
+bool _NPN_SetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, const NPVariant* value)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class == npScriptObjectClass) {
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ obj->Set(npIdentifierToV8Identifier(propertyName),
+ convertNPVariantToV8Object(value, object->rootObject->frame()->script()->windowScriptNPObject()));
+ return true;
+ }
+
+ if (npObject->_class->setProperty)
+ return npObject->_class->setProperty(npObject, propertyName, value);
+
+ return false;
+}
+
+bool _NPN_RemoveProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
+{
+ if (!npObject)
+ return false;
+ if (npObject->_class != npScriptObjectClass)
+ return false;
+
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ // FIXME: Verify that setting to undefined is right.
+ obj->Set(npIdentifierToV8Identifier(propertyName), v8::Undefined());
+ return true;
+}
+
+bool _NPN_HasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class == npScriptObjectClass) {
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ return obj->Has(npIdentifierToV8Identifier(propertyName));
+ }
+
+ if (npObject->_class->hasProperty)
+ return npObject->_class->hasProperty(npObject, propertyName);
+ return false;
+}
+
+bool _NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class == npScriptObjectClass) {
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+ v8::Handle<v8::Value> prop = obj->Get(npIdentifierToV8Identifier(methodName));
+ return prop->IsFunction();
+ }
+
+ if (npObject->_class->hasMethod)
+ return npObject->_class->hasMethod(npObject, methodName);
+ return false;
+}
+
+void _NPN_SetException(NPObject* npObject, const NPUTF8 *message)
+{
+ if (npObject->_class != npScriptObjectClass)
+ return;
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(0, npObject);
+ if (context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(context);
+ V8Proxy::throwError(V8Proxy::GeneralError, message);
+}
+
+bool _NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifier, uint32_t* count)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class == npScriptObjectClass) {
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Object> obj(object->v8Object);
+
+ // FIXME: http://b/issue?id=1210340: Use a v8::Object::Keys() method when it exists, instead of evaluating javascript.
+
+ // FIXME: Figure out how to cache this helper function. Run a helper function that collects the properties
+ // on the object into an array.
+ const char enumeratorCode[] =
+ "(function (obj) {"
+ " var props = [];"
+ " for (var prop in obj) {"
+ " props[props.length] = prop;"
+ " }"
+ " return props;"
+ "});";
+ v8::Handle<v8::String> source = v8::String::New(enumeratorCode);
+ v8::Handle<v8::Script> script = v8::Script::Compile(source, 0);
+ v8::Handle<v8::Value> enumeratorObj = script->Run();
+ v8::Handle<v8::Function> enumerator = v8::Handle<v8::Function>::Cast(enumeratorObj);
+ v8::Handle<v8::Value> argv[] = { obj };
+ v8::Local<v8::Value> propsObj = enumerator->Call(v8::Handle<v8::Object>::Cast(enumeratorObj), ARRAYSIZE_UNSAFE(argv), argv);
+ if (propsObj.IsEmpty())
+ return false;
+
+ // Convert the results into an array of NPIdentifiers.
+ v8::Handle<v8::Array> props = v8::Handle<v8::Array>::Cast(propsObj);
+ *count = props->Length();
+ *identifier = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier*) * *count));
+ for (uint32_t i = 0; i < *count; ++i) {
+ v8::Local<v8::Value> name = props->Get(v8::Integer::New(i));
+ (*identifier)[i] = getStringIdentifier(v8::Local<v8::String>::Cast(name));
+ }
+ return true;
+ }
+
+ if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate)
+ return npObject->_class->enumerate(npObject, identifier, count);
+
+ return false;
+}
+
+bool _NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
+{
+ if (!npObject)
+ return false;
+
+ if (npObject->_class == npScriptObjectClass) {
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+
+ v8::HandleScope handleScope;
+ v8::Handle<v8::Context> context = toV8Context(npp, npObject);
+ if (context.IsEmpty())
+ return false;
+ v8::Context::Scope scope(context);
+
+ // Lookup the constructor function.
+ v8::Handle<v8::Object> ctorObj(object->v8Object);
+ if (!ctorObj->IsFunction())
+ return false;
+
+ // Call the constructor.
+ v8::Local<v8::Value> resultObject;
+ v8::Handle<v8::Function> ctor(v8::Function::Cast(*ctorObj));
+ if (!ctor->IsNull()) {
+ V8Proxy* proxy = toV8Proxy(npObject);
+ ASSERT(proxy);
+
+ OwnArrayPtr<v8::Handle<v8::Value> > argv(createValueListFromVariantArgs(arguments, argumentCount, npObject));
+ resultObject = proxy->newInstance(ctor, argumentCount, argv.get());
+ }
+
+ if (resultObject.IsEmpty())
+ return false;
+
+ convertV8ObjectToNPVariant(resultObject, npObject, result);
+ return true;
+ }
+
+ if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npObject->_class) && npObject->_class->construct)
+ return npObject->_class->construct(npObject, arguments, argumentCount, result);
+
+ return false;
+}
diff --git a/WebCore/bindings/v8/NPV8Object.h b/WebCore/bindings/v8/NPV8Object.h
new file mode 100644
index 0000000..65a7ccf
--- /dev/null
+++ b/WebCore/bindings/v8/NPV8Object.h
@@ -0,0 +1,60 @@
+/*
+ * 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 NPV8Object_h
+#define NPV8Object_h
+
+#include "bindings/npruntime.h"
+#include <v8.h>
+
+namespace WebCore {
+ class DOMWindow;
+}
+
+extern NPClass* npScriptObjectClass;
+
+// A V8NPObject is a NPObject which carries additional V8-specific information. It is allocated and deallocated by
+// AllocV8NPObject() and FreeV8NPObject() methods.
+struct V8NPObject {
+ NPObject object;
+ v8::Persistent<v8::Object> v8Object;
+ WebCore::DOMWindow* rootObject;
+};
+
+struct PrivateIdentifier {
+ union {
+ const NPUTF8* string;
+ int32_t number;
+ } value;
+ bool isString;
+};
+
+NPObject* npCreateV8ScriptObject(NPP, v8::Handle<v8::Object>, WebCore::DOMWindow*);
+
+#endif // NPV8Object_h
diff --git a/WebCore/bindings/v8/OwnHandle.h b/WebCore/bindings/v8/OwnHandle.h
new file mode 100644
index 0000000..6580674
--- /dev/null
+++ b/WebCore/bindings/v8/OwnHandle.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 OwnHandle_h
+#define OwnHandle_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+ template<typename T>
+ class OwnHandle {
+ public:
+ OwnHandle() { }
+ explicit OwnHandle(v8::Handle<T> handle) : m_handle(v8::Persistent<T>::New(handle)) { }
+ ~OwnHandle() { clear(); }
+
+ v8::Handle<T> get() const { return m_handle; }
+ void set(v8::Handle<T> handle) { clear(); m_handle = v8::Persistent<T>::New(handle); }
+
+ // FIXME: What if we release a weak handle? Won't the callback do the wrong thing?
+ v8::Persistent<T> release() { v8::Persistent<T> result = m_handle; m_handle.Clear(); return result; }
+ void adopt(v8::Persistent<T> handle) { clear(); m_handle = handle; }
+
+ // Note: This is clear in the OwnPtr sense, not the v8::Handle sense.
+ void clear()
+ {
+ if (m_handle.IsEmpty())
+ return;
+ m_handle.Dispose();
+ m_handle.Clear();
+ }
+
+ // Make the underlying handle weak. The client doesn't get a callback,
+ // we just make the handle empty.
+ void makeWeak()
+ {
+ if (m_handle.IsEmpty())
+ return;
+ m_handle.MakeWeak(this, &OwnHandle<T>::weakCallback);
+ }
+
+ private:
+ static void weakCallback(v8::Persistent<v8::Value> object, void* ownHandle)
+ {
+ OwnHandle<T>* handle = static_cast<OwnHandle<T>*>(ownHandle);
+ handle->clear();
+ }
+
+ v8::Persistent<T> m_handle;
+ };
+
+} // namespace WebCore
+
+#endif // OwnHandle_h
diff --git a/WebCore/bindings/v8/ScheduledAction.cpp b/WebCore/bindings/v8/ScheduledAction.cpp
index b1db8cf..44e8a37 100644
--- a/WebCore/bindings/v8/ScheduledAction.cpp
+++ b/WebCore/bindings/v8/ScheduledAction.cpp
@@ -50,7 +50,7 @@ ScheduledAction::ScheduledAction(v8::Handle<v8::Function> func, int argc, v8::Ha
m_function = v8::Persistent<v8::Function>::New(func);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_function);
+ V8GCController::registerGlobalHandle(SCHEDULED_ACTION, this, m_function);
#endif
m_argc = argc;
@@ -60,7 +60,7 @@ ScheduledAction::ScheduledAction(v8::Handle<v8::Function> func, int argc, v8::Ha
m_argv[i] = v8::Persistent<v8::Value>::New(argv[i]);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(SCHEDULED_ACTION, this, m_argv[i]);
+ V8GCController::registerGlobalHandle(SCHEDULED_ACTION, this, m_argv[i]);
#endif
}
} else
@@ -73,13 +73,13 @@ ScheduledAction::~ScheduledAction()
return;
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_function);
+ V8GCController::unregisterGlobalHandle(this, m_function);
#endif
m_function.Dispose();
for (int i = 0; i < m_argc; i++) {
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_argv[i]);
+ V8GCController::unregisterGlobalHandle(this, m_argv[i]);
#endif
m_argv[i].Dispose();
}
@@ -107,7 +107,7 @@ void ScheduledAction::execute(V8Proxy* proxy)
LOCK_V8;
v8::HandleScope handleScope;
- v8::Local<v8::Context> v8Context = proxy->GetContext();
+ v8::Local<v8::Context> v8Context = proxy->context();
if (v8Context.IsEmpty())
return; // JS may not be enabled.
@@ -117,7 +117,7 @@ void ScheduledAction::execute(V8Proxy* proxy)
// FIXME: Need to implement timeouts for preempting a long-running script.
if (!m_function.IsEmpty() && m_function->IsFunction()) {
- proxy->CallFunction(v8::Persistent<v8::Function>::Cast(m_function), v8Context->Global(), m_argc, m_argv);
+ proxy->callFunction(v8::Persistent<v8::Function>::Cast(m_function), v8Context->Global(), m_argc, m_argv);
Document::updateStyleForAllDocuments();
} else
proxy->evaluate(m_code, 0);
@@ -136,7 +136,7 @@ void ScheduledAction::execute(WorkerContext* workerContext)
if (!m_function.IsEmpty() && m_function->IsFunction()) {
LOCK_V8;
v8::HandleScope handleScope;
- v8::Local<v8::Context> v8Context = scriptController->proxy()->GetContext();
+ v8::Local<v8::Context> v8Context = scriptController->proxy()->context();
ASSERT(!v8Context.IsEmpty());
v8::Context::Scope scope(v8Context);
m_function->Call(v8Context->Global(), m_argc, m_argv);
diff --git a/WebCore/bindings/v8/ScopedDOMDataStore.cpp b/WebCore/bindings/v8/ScopedDOMDataStore.cpp
new file mode 100644
index 0000000..19cd545
--- /dev/null
+++ b/WebCore/bindings/v8/ScopedDOMDataStore.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "ScopedDOMDataStore.h"
+
+namespace WebCore {
+
+ScopedDOMDataStore::ScopedDOMDataStore(DOMData* domData)
+ : DOMDataStore(domData)
+{
+ m_domNodeMap = new InternalDOMWrapperMap<Node>(domData, &DOMDataStore::weakNodeCallback);
+ m_domObjectMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakDOMObjectCallback);
+ m_activeDomObjectMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakActiveDOMObjectCallback);
+#if ENABLE(SVG)
+ m_domSvgElementInstanceMap = new InternalDOMWrapperMap<SVGElementInstance>(domData, &DOMDataStore::weakSVGElementInstanceCallback);
+ m_domSvgObjectWithContextMap = new InternalDOMWrapperMap<void>(domData, &DOMDataStore::weakSVGObjectWithContextCallback);
+#endif
+}
+
+ScopedDOMDataStore::~ScopedDOMDataStore()
+{
+ delete m_domNodeMap;
+ delete m_domObjectMap;
+ delete m_activeDomObjectMap;
+#if ENABLE(SVG)
+ delete m_domSvgElementInstanceMap;
+ delete m_domSvgObjectWithContextMap;
+#endif
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScopedDOMDataStore.h b/WebCore/bindings/v8/ScopedDOMDataStore.h
new file mode 100644
index 0000000..c63bab0
--- /dev/null
+++ b/WebCore/bindings/v8/ScopedDOMDataStore.h
@@ -0,0 +1,56 @@
+/*
+ * 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 ScopedDOMDataStore_h
+#define ScopedDOMDataStore_h
+
+#include "DOMDataStore.h"
+
+namespace WebCore {
+
+ // ScopedDOMDataStore
+ //
+ // ScopedDOMDataStore is a DOMDataStore that controls limits the lifetime of
+ // the store to the lifetime of the object itself. In other words, when the
+ // ScopedDOMDataStore object is deallocated, the maps that belong to the store
+ // are deallocated as well.
+ //
+ class ScopedDOMDataStore : public DOMDataStore {
+ public:
+ ScopedDOMDataStore(DOMData*);
+
+ // This can be called when WTF thread is tearing down.
+ // We assume that all child threads running V8 instances are created by WTF.
+ virtual ~ScopedDOMDataStore();
+ };
+
+} // namespace WebCore
+
+#endif // ScopedDOMDataStore_h
diff --git a/WebCore/bindings/v8/ScriptArray.cpp b/WebCore/bindings/v8/ScriptArray.cpp
new file mode 100644
index 0000000..748ee19
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptArray.cpp
@@ -0,0 +1,105 @@
+/*
+ * 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 "ScriptArray.h"
+
+#include "ScriptScope.h"
+#include "ScriptState.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <v8.h>
+
+namespace WebCore {
+
+ScriptArray::ScriptArray(ScriptState* scriptState, v8::Handle<v8::Array> v8Array)
+ : ScriptObject(scriptState, v8Array)
+{
+}
+
+bool ScriptArray::set(unsigned index, const ScriptObject& value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::Integer::New(index), value.v8Value());
+ return scope.success();
+}
+
+bool ScriptArray::set(unsigned index, const String& value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::Integer::New(index), v8String(value));
+ return scope.success();
+}
+
+bool ScriptArray::set(unsigned index, double value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::Integer::New(index), v8::Number::New(value));
+ return scope.success();
+}
+
+bool ScriptArray::set(unsigned index, long long value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::Integer::New(index), v8::Number::New(value));
+ return scope.success();
+}
+
+bool ScriptArray::set(unsigned index, int value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::Integer::New(index), v8::Number::New(value));
+ return scope.success();
+}
+
+bool ScriptArray::set(unsigned index, bool value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::Integer::New(index), v8Boolean(value));
+ return scope.success();
+}
+
+unsigned ScriptArray::length()
+{
+ ScriptScope scope(m_scriptState);
+ return v8::Array::Cast(*v8Value())->Length();
+}
+
+ScriptArray ScriptArray::createNew(ScriptState* scriptState)
+{
+ ScriptScope scope(scriptState);
+ return ScriptArray(scriptState, v8::Array::New());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptArray.h b/WebCore/bindings/v8/ScriptArray.h
new file mode 100644
index 0000000..6e8f852
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptArray.h
@@ -0,0 +1,58 @@
+/*
+ * 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 ScriptArray_h
+#define ScriptArray_h
+
+#include "ScriptObject.h"
+
+#include <v8.h>
+
+namespace WebCore {
+ class ScriptState;
+
+ class ScriptArray : public ScriptObject {
+ public:
+ ScriptArray(ScriptState* scriptState, v8::Handle<v8::Array>);
+ virtual ~ScriptArray() {}
+
+ bool set(unsigned index, const ScriptObject&);
+ bool set(unsigned index, const String&);
+ bool set(unsigned index, double);
+ bool set(unsigned index, long long);
+ bool set(unsigned index, int);
+ bool set(unsigned index, bool);
+ unsigned length();
+
+ static ScriptArray createNew(ScriptState*);
+ };
+}
+
+#endif // ScriptArray_h
diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp
index 9188dcf..8eb9478 100644
--- a/WebCore/bindings/v8/ScriptCallStack.cpp
+++ b/WebCore/bindings/v8/ScriptCallStack.cpp
@@ -39,7 +39,8 @@
namespace WebCore {
ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount)
- : m_lastCaller(String(), V8Proxy::GetSourceName(), V8Proxy::GetSourceLineNumber() + 1, arguments, skipArgumentCount)
+ : m_lastCaller(String(), V8Proxy::sourceName(), V8Proxy::sourceLineNumber() + 1, arguments, skipArgumentCount)
+ , m_scriptState(new ScriptState(V8Proxy::retrieveFrameForCurrentContext()))
{
}
diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h
index 2dfd484..9f628c8 100644
--- a/WebCore/bindings/v8/ScriptCallStack.h
+++ b/WebCore/bindings/v8/ScriptCallStack.h
@@ -35,6 +35,7 @@
#include "ScriptState.h"
#include "ScriptValue.h"
#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
namespace v8 {
class Arguments;
@@ -51,10 +52,10 @@ namespace WebCore {
// 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; }
+ ScriptState* state() const { return m_scriptState.get(); }
private:
+ OwnPtr<ScriptState> m_scriptState;
ScriptCallFrame m_lastCaller;
};
diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp
index eecff45..97a3553 100644
--- a/WebCore/bindings/v8/ScriptController.cpp
+++ b/WebCore/bindings/v8/ScriptController.cpp
@@ -47,11 +47,13 @@
#include "Frame.h"
#include "Node.h"
#include "NotImplemented.h"
+#include "npruntime_impl.h"
#include "npruntime_priv.h"
#include "NPV8Object.h"
#include "ScriptSourceCode.h"
#include "ScriptState.h"
#include "Widget.h"
+#include "XSSAuditor.h"
#include "V8Binding.h"
#include "V8NPObject.h"
@@ -76,17 +78,17 @@ Frame* ScriptController::retrieveFrameForCurrentContext()
bool ScriptController::isSafeScript(Frame* target)
{
- return V8Proxy::CanAccessFrame(target, true);
+ return V8Proxy::canAccessFrame(target, true);
}
void ScriptController::gcProtectJSWrapper(void* domObject)
{
- V8Proxy::GCProtect(domObject);
+ V8GCController::gcProtect(domObject);
}
void ScriptController::gcUnprotectJSWrapper(void* domObject)
{
- V8Proxy::GCUnprotect(domObject);
+ V8GCController::gcUnprotect(domObject);
}
ScriptController::ScriptController(Frame* frame)
@@ -99,6 +101,7 @@ ScriptController::ScriptController(Frame* frame)
#if ENABLE(NETSCAPE_PLUGIN_API)
, m_windowScriptNPObject(0)
#endif
+ , m_XSSAuditor(new XSSAuditor(frame))
{
}
@@ -112,7 +115,7 @@ void ScriptController::clearScriptObjects()
PluginObjectMap::iterator it = m_pluginObjects.begin();
for (; it != m_pluginObjects.end(); ++it) {
_NPN_UnregisterObject(it->second);
- NPN_ReleaseObject(it->second);
+ _NPN_ReleaseObject(it->second);
}
m_pluginObjects.clear();
@@ -147,18 +150,18 @@ bool ScriptController::processingUserGesture() const
V8Proxy* activeProxy = activeFrame->script()->proxy();
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(activeFrame);
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame);
// FIXME: find all cases context can be empty:
// 1) JS is disabled;
// 2) page is NULL;
- if (context.IsEmpty())
+ if (v8Context.IsEmpty())
return true;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
- v8::Handle<v8::Object> global = context->Global();
+ v8::Handle<v8::Object> global = v8Context->Global();
v8::Handle<v8::Value> jsEvent = global->Get(v8::String::NewSymbol("event"));
- Event* event = V8Proxy::ToNativeEvent(jsEvent);
+ Event* event = V8DOMWrapper::convertToNativeEvent(jsEvent);
// Based on code from kjs_bindings.cpp.
// Note: This is more liberal than Firefox's implementation.
@@ -183,21 +186,41 @@ bool ScriptController::processingUserGesture() const
return false;
}
-void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sources)
+void ScriptController::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup)
{
- m_proxy->evaluateInNewContext(sources);
+ m_proxy->evaluateInNewWorld(sources, extensionGroup);
+}
+
+void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int extensionGroup)
+{
+ m_proxy->evaluateInNewContext(sources, extensionGroup);
}
// Evaluate a script file in the environment of this proxy.
ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
+#ifdef MANUAL_MERGE_REQUIRED
LOCK_V8;
+#else // MANUAL_MERGE_REQUIRED
+ String sourceURL = sourceCode.url();
+
+ if (sourceURL.isNull() && !m_XSSAuditor->canEvaluateJavaScriptURL(sourceCode.source())) {
+ // This JavaScript URL is not safe to be evaluated.
+ return ScriptValue();
+ }
+
+ if (!sourceURL.isNull() && !m_XSSAuditor->canEvaluate(sourceCode.source())) {
+ // This script is not safe to be evaluated.
+ return ScriptValue();
+ }
+
+#endif // MANUAL_MERGE_REQUIRED
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_proxy->frame());
+ if (v8Context.IsEmpty())
return ScriptValue();
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
RefPtr<Frame> protect(m_frame);
@@ -215,7 +238,7 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
void ScriptController::setEventHandlerLineNumber(int lineNumber)
{
- m_proxy->setEventHandlerLineno(lineNumber);
+ m_proxy->setEventHandlerLineNumber(lineNumber);
}
void ScriptController::finishedWithEvent(Event* event)
@@ -229,16 +252,16 @@ void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObj
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
- v8::Handle<v8::Object> value = CreateV8ObjectForNPObject(object, 0);
+ v8::Handle<v8::Object> value = createV8ObjectForNPObject(object, 0);
// Attach to the global object.
- v8::Handle<v8::Object> global = context->Global();
+ v8::Handle<v8::Object> global = v8Context->Global();
global->Set(v8String(key), value);
}
@@ -246,18 +269,18 @@ void ScriptController::collectGarbage()
{
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_proxy->frame());
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_proxy->frame());
+ if (v8Context.IsEmpty())
return;
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
m_proxy->evaluate(ScriptSourceCode("if (window.gc) void(gc());"), 0);
}
bool ScriptController::haveInterpreter() const
{
- return m_proxy->ContextInitialized();
+ return m_proxy->isContextInitialized();
}
bool ScriptController::isEnabled() const
@@ -309,9 +332,9 @@ PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widge
//
// Inside the javascript engine, the engine can keep a reference to the
// NPObject as part of its wrapper. However, before accessing the object
- // it must consult the NPN_Registry.
+ // it must consult the _NPN_Registry.
- v8::Local<v8::Object> wrapper = CreateV8ObjectForNPObject(npObject, 0);
+ v8::Local<v8::Object> wrapper = createV8ObjectForNPObject(npObject, 0);
// Track the plugin object. We've been given a reference to the object.
m_pluginObjects.set(widget, npObject);
@@ -325,7 +348,7 @@ void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
if (it == m_pluginObjects.end())
return;
_NPN_UnregisterObject(it->second);
- NPN_ReleaseObject(it->second);
+ _NPN_ReleaseObject(it->second);
m_pluginObjects.remove(it);
}
@@ -339,13 +362,13 @@ static NPObject* createScriptObject(Frame* frame)
{
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(frame);
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
+ if (v8Context.IsEmpty())
return createNoScriptObject();
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
DOMWindow* window = frame->domWindow();
- v8::Handle<v8::Value> global = V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, window);
+ v8::Handle<v8::Value> global = V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, window);
ASSERT(global->IsObject());
return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(global), window);
}
@@ -377,13 +400,13 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
+ if (v8Context.IsEmpty())
return createNoScriptObject();
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
DOMWindow* window = m_frame->domWindow();
- v8::Handle<v8::Value> v8plugin = V8Proxy::ToV8Object(V8ClassIndex::HTMLEMBEDELEMENT, plugin);
+ v8::Handle<v8::Value> v8plugin = V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLEMBEDELEMENT, plugin);
if (!v8plugin->IsObject())
return createNoScriptObject();
diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h
index 17703b5..47acf35 100644
--- a/WebCore/bindings/v8/ScriptController.h
+++ b/WebCore/bindings/v8/ScriptController.h
@@ -49,6 +49,7 @@ namespace WebCore {
class ScriptState;
class String;
class Widget;
+ class XSSAuditor;
class ScriptController {
public:
@@ -64,11 +65,17 @@ namespace WebCore {
// as a string.
ScriptValue evaluate(const ScriptSourceCode&);
+ // Executes JavaScript in a new world associated with the web frame. The
+ // script gets its own global scope, its own prototypes for intrinsic
+ // JavaScript objects (String, Array, and so-on), and its own wrappers for
+ // all DOM nodes and DOM constructors.
+ void evaluateInNewWorld(const Vector<ScriptSourceCode>&, int extensionGroup);
+
// Executes JavaScript in a new context associated with the web frame. The
// script gets its own global scope and its own prototypes for intrinsic
// JavaScript objects (String, Array, and so-on). It shares the wrappers for
// all DOM nodes and DOM constructors.
- void evaluateInNewContext(const Vector<ScriptSourceCode>&);
+ void evaluateInNewContext(const Vector<ScriptSourceCode>&, int extensionGroup);
// JSC has a WindowShell object, but for V8, the ScriptController
// is the WindowShell.
@@ -81,6 +88,8 @@ namespace WebCore {
ScriptState* state() const { return m_scriptState.get(); }
+ XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); }
+
void collectGarbage();
// Creates a property of the global object of a frame.
@@ -160,6 +169,8 @@ namespace WebCore {
#if ENABLE(NETSCAPE_PLUGIN_API)
NPObject* m_windowScriptNPObject;
#endif
+ // The XSSAuditor associated with this ScriptController.
+ OwnPtr<XSSAuditor> m_XSSAuditor;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index 42c2529..7a8aa64 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -34,6 +34,7 @@
#include "Attribute.h"
#include "Document.h"
#include "Frame.h"
+#include "XSSAuditor.h"
namespace WebCore {
@@ -46,6 +47,11 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribu
if (!frame)
return 0;
+ if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+ // This script is not safe to execute.
+ return 0;
+ }
+
return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), node->isSVGElement());
}
@@ -54,6 +60,11 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
if (!frame)
return 0;
+ if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+ // This script is not safe to execute.
+ return 0;
+ }
+
return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), frame->document()->isSVGDocument());
}
diff --git a/WebCore/bindings/v8/ScriptFunctionCall.cpp b/WebCore/bindings/v8/ScriptFunctionCall.cpp
index d2f7a52..2fa43d5 100644
--- a/WebCore/bindings/v8/ScriptFunctionCall.cpp
+++ b/WebCore/bindings/v8/ScriptFunctionCall.cpp
@@ -162,7 +162,7 @@ ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExcept
return ScriptObject();
}
- return ScriptObject(result);
+ return ScriptObject(m_scriptState, result);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptInstance.cpp b/WebCore/bindings/v8/ScriptInstance.cpp
index aa4a396..645b1da 100644
--- a/WebCore/bindings/v8/ScriptInstance.cpp
+++ b/WebCore/bindings/v8/ScriptInstance.cpp
@@ -62,7 +62,7 @@ void V8ScriptInstance::clear()
if (m_instance.IsEmpty())
return;
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_instance);
+ V8GCController::unregisterGlobalHandle(this, m_instance);
#endif
m_instance.Dispose();
m_instance.Clear();
@@ -76,7 +76,7 @@ void V8ScriptInstance::set(v8::Handle<v8::Object> instance)
m_instance = v8::Persistent<v8::Object>::New(instance);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(SCRIPTINSTANCE, this, m_instance);
+ V8GCController::registerGlobalHandle(SCRIPTINSTANCE, this, m_instance);
#endif
}
diff --git a/WebCore/bindings/v8/ScriptObject.cpp b/WebCore/bindings/v8/ScriptObject.cpp
index 59316f0..c64cfe4 100644
--- a/WebCore/bindings/v8/ScriptObject.cpp
+++ b/WebCore/bindings/v8/ScriptObject.cpp
@@ -43,8 +43,9 @@
namespace WebCore {
-ScriptObject::ScriptObject(v8::Handle<v8::Object> v8Object)
+ScriptObject::ScriptObject(ScriptState* scriptState, v8::Handle<v8::Object> v8Object)
: ScriptValue(v8Object)
+ , m_scriptState(scriptState)
{
}
@@ -54,51 +55,51 @@ v8::Local<v8::Object> ScriptObject::v8Object() const
return v8::Local<v8::Object>(v8::Object::Cast(*v8Value()));
}
-bool ScriptObject::set(ScriptState* scriptState, const String& name, const String& value)
+bool ScriptObject::set(const String& name, const String& value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8String(name), v8String(value));
return scope.success();
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value)
+bool ScriptObject::set(const char* name, const ScriptObject& value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8::String::New(name), value.v8Value());
return scope.success();
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, const String& value)
+bool ScriptObject::set(const char* name, const String& value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8::String::New(name), v8String(value));
return scope.success();
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, double value)
+bool ScriptObject::set(const char* name, double value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8::String::New(name), v8::Number::New(value));
return scope.success();
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, long long value)
+bool ScriptObject::set(const char* name, long long value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8::String::New(name), v8::Number::New(value));
return scope.success();
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, int value)
+bool ScriptObject::set(const char* name, int value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8::String::New(name), v8::Number::New(value));
return scope.success();
}
-bool ScriptObject::set(ScriptState* scriptState, const char* name, bool value)
+bool ScriptObject::set(const char* name, bool value)
{
- ScriptScope scope(scriptState);
+ ScriptScope scope(m_scriptState);
v8Object()->Set(v8::String::New(name), v8Boolean(value));
return scope.success();
}
@@ -106,7 +107,7 @@ bool ScriptObject::set(ScriptState* scriptState, const char* name, bool value)
ScriptObject ScriptObject::createNew(ScriptState* scriptState)
{
ScriptScope scope(scriptState);
- return ScriptObject(v8::Object::New());
+ return ScriptObject(scriptState, v8::Object::New());
}
bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const ScriptObject& value)
@@ -116,12 +117,16 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const S
return scope.success();
}
-bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorController* value)
+bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorBackend* value)
{
ScriptScope scope(scriptState);
+#ifdef MANUAL_MERGE_REQUIRED
#if !PLATFORM(ANDROID)
scope.global()->Set(v8::String::New(name), V8Proxy::ToV8Object(V8ClassIndex::INSPECTORCONTROLLER, value));
#endif
+#else // MANUAL_MERGE_REQUIRED
+ scope.global()->Set(v8::String::New(name), V8DOMWrapper::convertToV8Object(V8ClassIndex::INSPECTORBACKEND, value));
+#endif // MANUAL_MERGE_REQUIRED
return scope.success();
}
@@ -135,7 +140,7 @@ bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptO
if (!v8Value->IsObject())
return false;
- value = ScriptObject(v8::Handle<v8::Object>(v8::Object::Cast(*v8Value)));
+ value = ScriptObject(scriptState, v8::Handle<v8::Object>(v8::Object::Cast(*v8Value)));
return true;
}
diff --git a/WebCore/bindings/v8/ScriptObject.h b/WebCore/bindings/v8/ScriptObject.h
index e5618ab..dcee3a5 100644
--- a/WebCore/bindings/v8/ScriptObject.h
+++ b/WebCore/bindings/v8/ScriptObject.h
@@ -36,32 +36,34 @@
#include <v8.h>
namespace WebCore {
- class InspectorController;
+ class InspectorBackend;
class ScriptState;
class ScriptObject : public ScriptValue {
public:
- ScriptObject(v8::Handle<v8::Object>);
- ScriptObject() {}
+ ScriptObject(ScriptState*, v8::Handle<v8::Object>);
+ ScriptObject() {};
virtual ~ScriptObject() {}
v8::Local<v8::Object> v8Object() const;
- bool set(ScriptState*, const String& name, const String&);
- bool set(ScriptState*, const char* name, const ScriptObject&);
- bool set(ScriptState*, const char* name, const String&);
- bool set(ScriptState*, const char* name, double);
- bool set(ScriptState*, const char* name, long long);
- bool set(ScriptState*, const char* name, int);
- bool set(ScriptState*, const char* name, bool);
+ bool set(const String& name, const String&);
+ bool set(const char* name, const ScriptObject&);
+ bool set(const char* name, const String&);
+ bool set(const char* name, double);
+ bool set(const char* name, long long);
+ bool set(const char* name, int);
+ bool set(const char* name, bool);
static ScriptObject createNew(ScriptState*);
+ protected:
+ ScriptState* m_scriptState;
};
class ScriptGlobalObject {
public:
static bool set(ScriptState*, const char* name, const ScriptObject&);
- static bool set(ScriptState*, const char* name, InspectorController*);
+ static bool set(ScriptState*, const char* name, InspectorBackend*);
static bool get(ScriptState*, const char* name, ScriptObject&);
static bool remove(ScriptState*, const char* name);
private:
diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp
index 8a7715e..053cf68 100644
--- a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp
+++ b/WebCore/bindings/v8/ScriptObjectQuarantine.cpp
@@ -66,9 +66,18 @@ bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& qu
ASSERT(frame);
ASSERT(storage);
- // FIXME: Implement when DOM Storage V8 bindings are enabled
+#if ENABLE(DOM_STORAGE)
+ v8::HandleScope handleScope;
+ v8::Local<v8::Context> context = V8Proxy::context(frame);
+ // FIXME: What if context.IsEmpty()?
+ v8::Context::Scope scope(context);
+
+ v8::Handle<v8::Value> v8Storage = V8DOMWrapper::convertToV8Object(V8ClassIndex::STORAGE, storage);
+ quarantinedObject = ScriptObject(frame->script()->state(), v8::Local<v8::Object>(v8::Object::Cast(*v8Storage)));
+#else
ASSERT_NOT_REACHED();
quarantinedObject = ScriptObject();
+#endif
return true;
}
@@ -77,11 +86,15 @@ bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject)
ASSERT(node);
v8::HandleScope handleScope;
- v8::Local<v8::Context> context = V8Proxy::GetContext(node->document()->page()->mainFrame());
+ // FIXME: What if document() is null?
+ // FIXME: Why are we grabbing the mainFrame?
+ Frame* frame = node->document()->page()->mainFrame();
+ v8::Local<v8::Context> context = V8Proxy::context(frame);
+ // FIXME: What if context.IsEmpty()?
v8::Context::Scope scope(context);
- v8::Handle<v8::Value> v8Node = V8Proxy::NodeToV8Object(node);
- quarantinedObject = ScriptObject(v8::Local<v8::Object>(v8::Object::Cast(*v8Node)));
+ v8::Handle<v8::Value> v8Node = V8DOMWrapper::convertNodeToV8Object(node);
+ quarantinedObject = ScriptObject(frame->script()->state(), v8::Local<v8::Object>(v8::Object::Cast(*v8Node)));
return true;
}
@@ -91,11 +104,14 @@ bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedO
ASSERT(domWindow);
v8::HandleScope handleScope;
- v8::Local<v8::Context> context = V8Proxy::GetContext(domWindow->frame());
+ Frame* frame = domWindow->frame();
+ // FIXME: What if frame is null?
+ v8::Local<v8::Context> context = V8Proxy::context(frame);
+ // FIXME: What if context.IsEmpty()?
v8::Context::Scope scope(context);
- v8::Handle<v8::Value> v8DomWindow = V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, domWindow);
- quarantinedObject = ScriptObject(v8::Local<v8::Object>(v8::Object::Cast(*v8DomWindow)));
+ v8::Handle<v8::Value> v8DomWindow = V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, domWindow);
+ quarantinedObject = ScriptObject(frame->script()->state(), v8::Local<v8::Object>(v8::Object::Cast(*v8DomWindow)));
return true;
}
diff --git a/WebCore/bindings/v8/ScriptScope.cpp b/WebCore/bindings/v8/ScriptScope.cpp
index 937f664..52cab10 100644
--- a/WebCore/bindings/v8/ScriptScope.cpp
+++ b/WebCore/bindings/v8/ScriptScope.cpp
@@ -43,7 +43,7 @@
namespace WebCore {
ScriptScope::ScriptScope(ScriptState* scriptState, bool reportExceptions)
- : m_context(V8Proxy::GetContext(scriptState->frame()))
+ : m_context(V8Proxy::context(scriptState->frame()))
, m_scope(m_context)
, m_scriptState(scriptState)
, m_reportExceptions(reportExceptions)
diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h
index 04e8819..004851b 100644
--- a/WebCore/bindings/v8/ScriptValue.h
+++ b/WebCore/bindings/v8/ScriptValue.h
@@ -53,7 +53,7 @@ public:
m_value = v8::Persistent<v8::Value>::New(value);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value);
+ V8GCController::registerGlobalHandle(SCRIPTVALUE, this, m_value);
#endif
}
@@ -64,7 +64,7 @@ public:
m_value = v8::Persistent<v8::Value>::New(value.m_value);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value);
+ V8GCController::registerGlobalHandle(SCRIPTVALUE, this, m_value);
#endif
}
@@ -80,7 +80,7 @@ public:
m_value = v8::Persistent<v8::Value>::New(value.m_value);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(SCRIPTVALUE, this, m_value);
+ V8GCController::registerGlobalHandle(SCRIPTVALUE, this, m_value);
#endif
return *this;
@@ -122,7 +122,7 @@ public:
return;
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_value);
+ V8GCController::unregisterGlobalHandle(this, m_value);
#endif
m_value.Dispose();
m_value.Clear();
diff --git a/WebCore/bindings/v8/StaticDOMDataStore.cpp b/WebCore/bindings/v8/StaticDOMDataStore.cpp
new file mode 100644
index 0000000..3a02c0b
--- /dev/null
+++ b/WebCore/bindings/v8/StaticDOMDataStore.cpp
@@ -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.
+ */
+
+#include "config.h"
+#include "StaticDOMDataStore.h"
+
+namespace WebCore {
+
+StaticDOMDataStore::StaticDOMDataStore(DOMData* domData)
+ : DOMDataStore(domData)
+ , m_staticDomNodeMap(domData, &DOMDataStore::weakNodeCallback)
+ , m_staticDomObjectMap(domData, &DOMDataStore::weakDOMObjectCallback)
+ , m_staticActiveDomObjectMap(domData, &DOMDataStore::weakActiveDOMObjectCallback)
+#if ENABLE(SVG)
+ , m_staticDomSvgElementInstanceMap(domData, &DOMDataStore::weakSVGElementInstanceCallback)
+ , m_staticDomSvgObjectWithContextMap(domData, &DOMDataStore::weakSVGObjectWithContextCallback)
+#endif
+{
+ m_domNodeMap = &m_staticDomNodeMap;
+ m_domObjectMap = &m_staticDomObjectMap;
+ m_activeDomObjectMap = &m_staticActiveDomObjectMap;
+#if ENABLE(SVG)
+ m_domSvgElementInstanceMap = &m_staticDomSvgElementInstanceMap;
+ m_domSvgObjectWithContextMap = &m_staticDomSvgObjectWithContextMap;
+#endif
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/StaticDOMDataStore.h b/WebCore/bindings/v8/StaticDOMDataStore.h
new file mode 100644
index 0000000..4cd0515
--- /dev/null
+++ b/WebCore/bindings/v8/StaticDOMDataStore.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 StaticDOMDataStore_h
+#define StaticDOMDataStore_h
+
+#include "DOMDataStore.h"
+
+namespace WebCore {
+
+// StaticDOMDataStore
+//
+// StaticDOMDataStore is a DOMDataStore that manages the lifetime of the store
+// statically. This encapsulates thread-specific DOM data for the main
+// thread. All the maps in it are static. This is because we are unable to
+// rely on WTF::ThreadSpecificThreadExit to do the cleanup since the place that
+// tears down the main thread can not call any WTF functions.
+//
+class StaticDOMDataStore : public DOMDataStore {
+public:
+ StaticDOMDataStore(DOMData*);
+
+private:
+ InternalDOMWrapperMap<Node> m_staticDomNodeMap;
+ InternalDOMWrapperMap<void> m_staticDomObjectMap;
+ InternalDOMWrapperMap<void> m_staticActiveDomObjectMap;
+#if ENABLE(SVG)
+ InternalDOMWrapperMap<SVGElementInstance> m_staticDomSvgElementInstanceMap;
+ InternalDOMWrapperMap<void> m_staticDomSvgObjectWithContextMap;
+#endif
+};
+
+} // namespace WebCore
+
+#endif // StaticDOMDataStore_h
+
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index 07e944d..0c81846 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -48,6 +48,12 @@ V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute)
if (!m_frame)
return;
+ // We might be called directly from the parser.
+ v8::HandleScope handleScope;
+
+ m_context.set(V8Proxy::context(m_frame));
+ m_context.makeWeak();
+
// Get the position in the source if any.
if (m_isAttribute && m_frame->document()->tokenizer()) {
m_lineNumber = m_frame->document()->tokenizer()->lineNumber();
@@ -55,7 +61,7 @@ V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute)
}
}
-void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context, Event* event, v8::Handle<v8::Value> jsEvent, bool isWindowEvent)
+void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Context, Event* event, v8::Handle<v8::Value> jsEvent, bool isWindowEvent)
{
// We push the event being processed into the global object, so that it can be exposed by DOMWindow's bindings.
v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event");
@@ -67,11 +73,11 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context
tryCatch.SetVerbose(true);
// Save the old 'event' property so we can restore it later.
- v8::Local<v8::Value> savedEvent = context->Global()->GetHiddenValue(eventSymbol);
+ v8::Local<v8::Value> savedEvent = v8Context->Global()->GetHiddenValue(eventSymbol);
tryCatch.Reset();
// Make the event available in the global object, so DOMWindow can expose it.
- context->Global()->SetHiddenValue(eventSymbol, jsEvent);
+ v8Context->Global()->SetHiddenValue(eventSymbol, jsEvent);
tryCatch.Reset();
// Call the event handler.
@@ -80,13 +86,13 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> context
// Restore the old event. This must be done for all exit paths through this method.
if (savedEvent.IsEmpty())
- context->Global()->SetHiddenValue(eventSymbol, v8::Undefined());
+ v8Context->Global()->SetHiddenValue(eventSymbol, v8::Undefined());
else
- context->Global()->SetHiddenValue(eventSymbol, savedEvent);
+ v8Context->Global()->SetHiddenValue(eventSymbol, savedEvent);
tryCatch.Reset();
}
- ASSERT(!V8Proxy::HandleOutOfMemory() || returnValue.IsEmpty());
+ ASSERT(!V8Proxy::handleOutOfMemory() || returnValue.IsEmpty());
if (returnValue.IsEmpty())
return;
@@ -113,20 +119,20 @@ void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
- if (context.IsEmpty())
+ v8::Handle<v8::Context> v8Context = m_context.get();
+ if (v8Context.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);
+ v8::Context::Scope scope(v8Context);
// Get the V8 wrapper for the event object.
- v8::Handle<v8::Value> jsEvent = V8Proxy::EventToV8Object(event);
+ v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event);
- invokeEventHandler(context, event, jsEvent, isWindowEvent);
+ invokeEventHandler(v8Context, event, jsEvent, isWindowEvent);
Document::updateStyleForAllDocuments();
}
@@ -135,7 +141,7 @@ void V8AbstractEventListener::disposeListenerObject()
{
if (!m_listener.IsEmpty()) {
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_listener);
+ V8GCController::unregisterGlobalHandle(this, m_listener);
#endif
m_listener.Dispose();
m_listener.Clear();
@@ -151,7 +157,7 @@ v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event, b
return v8::Context::GetCurrent()->Global();
EventTarget* target = event->currentTarget();
- v8::Handle<v8::Value> value = V8Proxy::EventTargetToV8Object(target);
+ v8::Handle<v8::Value> value = V8DOMWrapper::convertEventTargetToV8Object(target);
if (value.IsEmpty())
return v8::Local<v8::Object>();
return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h
index ed643db..1521941 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.h
+++ b/WebCore/bindings/v8/V8AbstractEventListener.h
@@ -32,6 +32,7 @@
#define V8AbstractEventListener_h
#include "EventListener.h"
+#include "OwnHandle.h"
#include <v8.h>
namespace WebCore {
@@ -39,11 +40,14 @@ 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.
+ // 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.
+ // 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() { }
@@ -65,6 +69,8 @@ namespace WebCore {
virtual bool disconnected() const { return !m_frame; }
+ virtual bool isObjectListener() const { return false; }
+
protected:
v8::Persistent<v8::Object> m_listener;
@@ -83,6 +89,7 @@ namespace WebCore {
// deleted. See fast/dom/replaceChild.html
// FIXME: this could hold m_frame live until the event listener is deleted.
Frame* m_frame;
+ OwnHandle<v8::Context> m_context;
// Position in the HTML source for HTML event listeners.
int m_lineNumber;
diff --git a/WebCore/bindings/v8/V8Binding.cpp b/WebCore/bindings/v8/V8Binding.cpp
new file mode 100644
index 0000000..c5d580a
--- /dev/null
+++ b/WebCore/bindings/v8/V8Binding.cpp
@@ -0,0 +1,279 @@
+/*
+ * 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 "V8Binding.h"
+
+#include "AtomicString.h"
+#include "CString.h"
+#include "MathExtras.h"
+#include "PlatformString.h"
+#include "StdLibExtras.h"
+#include "StringBuffer.h"
+#include "StringHash.h"
+#include "Threading.h"
+
+#include <v8.h>
+
+namespace WebCore {
+
+// WebCoreStringResource is a helper class for v8ExternalString. It is used
+// to manage the life-cycle of the underlying buffer of the external string.
+class WebCoreStringResource : public v8::String::ExternalStringResource {
+public:
+ explicit WebCoreStringResource(const String& string)
+ : m_plainString(string)
+ {
+#ifndef NDEBUG
+ m_threadId = WTF::currentThread();
+#endif
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * length());
+ }
+
+ explicit WebCoreStringResource(const AtomicString& string)
+ : m_plainString(string)
+ , m_atomicString(string)
+ {
+#ifndef NDEBUG
+ m_threadId = WTF::currentThread();
+#endif
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * length());
+ }
+
+ virtual ~WebCoreStringResource()
+ {
+#ifndef NDEBUG
+ ASSERT(m_threadId == WTF::currentThread());
+#endif
+ int reducedExternalMemory = -2 * length();
+ if (!m_plainString.impl()->inTable())
+ reducedExternalMemory *= 2;
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory);
+ }
+
+ const uint16_t* data() const
+ {
+ return reinterpret_cast<const uint16_t*>(m_plainString.characters());
+ }
+
+ size_t length() const { return m_plainString.length(); }
+
+ String webcoreString() { return m_plainString; }
+
+ AtomicString atomicString()
+ {
+#ifndef NDEBUG
+ ASSERT(m_threadId == WTF::currentThread());
+#endif
+ if (m_atomicString.isNull()) {
+ m_atomicString = AtomicString(m_plainString);
+ if (!m_plainString.impl()->inTable())
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * length());
+ }
+ return m_atomicString;
+ }
+
+ static WebCoreStringResource* toStringResource(v8::Handle<v8::String> v8String)
+ {
+ return static_cast<WebCoreStringResource*>(v8String->GetExternalStringResource());
+ }
+
+private:
+ // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it.
+ String m_plainString;
+ // If this string is atomic or has been made atomic earlier the
+ // atomic string is held here. In the case where the string starts
+ // off non-atomic and becomes atomic later it is necessary to keep
+ // the original string alive because v8 may keep derived pointers
+ // into that string.
+ AtomicString m_atomicString;
+
+#ifndef NDEBUG
+ WTF::ThreadIdentifier m_threadId;
+#endif
+};
+
+String v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external,
+ StringType type)
+{
+ WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String);
+ if (stringResource)
+ return stringResource->webcoreString();
+
+ int length = v8String->Length();
+ if (!length) {
+ // Avoid trying to morph empty strings, as they do not have enough room to contain the external reference.
+ return StringImpl::empty();
+ }
+
+ UChar* buffer;
+ String result = String::createUninitialized(length, buffer);
+ v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
+
+ if (type == AtomicStringType)
+ result = AtomicString(result);
+
+ if (external == Externalize) {
+ WebCoreStringResource* resource = new WebCoreStringResource(result);
+ if (!v8String->MakeExternal(resource)) {
+ // In case of a failure delete the external resource as it was not used.
+ delete resource;
+ }
+ }
+ return result;
+}
+
+AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8String)
+{
+ WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String);
+ if (!stringResource) {
+ // If this string hasn't been externalized, we force it now.
+ String plain = v8StringToWebCoreString(v8String, Externalize, AtomicStringType);
+ // If the string is empty there's no room to cache an atomic
+ // string so we bail out.
+ if (plain.isEmpty())
+ return plain;
+ stringResource = WebCoreStringResource::toStringResource(v8String);
+ ASSERT(stringResource != NULL);
+ }
+ return stringResource->atomicString();
+}
+
+String v8ValueToWebCoreString(v8::Handle<v8::Value> object)
+{
+ if (object->IsString())
+ return v8StringToWebCoreString(v8::Handle<v8::String>::Cast(object), Externalize, PlainStringType);
+
+ if (object->IsInt32()) {
+ int value = object->Int32Value();
+ // Most numbers used are <= 100. Even if they aren't used there's very little in using the space.
+ const int kLowNumbers = 100;
+ static AtomicString lowNumbers[kLowNumbers + 1];
+ String webCoreString;
+ if (0 <= value && value <= kLowNumbers) {
+ webCoreString = lowNumbers[value];
+ if (!webCoreString) {
+ AtomicString valueString = AtomicString(String::number(value));
+ lowNumbers[value] = valueString;
+ webCoreString = valueString;
+ }
+ } else
+ webCoreString = String::number(value);
+ return webCoreString;
+ }
+
+ v8::TryCatch block;
+ v8::Handle<v8::String> v8String = object->ToString();
+ // Check for empty handles to handle the case where an exception
+ // is thrown as part of invoking toString on the objectect.
+ if (v8String.IsEmpty())
+ return StringImpl::empty();
+ return v8StringToWebCoreString(v8String, DoNotExternalize, PlainStringType);
+}
+
+AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> v8Value)
+{
+ if (v8Value->IsString())
+ return v8StringToAtomicWebCoreString(v8::Handle<v8::String>::Cast(v8Value));
+ String string = v8ValueToWebCoreString(v8Value);
+ return AtomicString(string);
+}
+
+v8::Handle<v8::String> v8String(const String& string)
+{
+ return v8ExternalString(string);
+}
+
+static bool stringImplCacheEnabled = false;
+
+void enableStringImplCache()
+{
+ stringImplCacheEnabled = true;
+}
+
+static v8::Local<v8::String> makeExternalString(const String& string)
+{
+ WebCoreStringResource* stringResource = new WebCoreStringResource(string);
+ v8::Local<v8::String> newString = v8::String::NewExternal(stringResource);
+ if (newString.IsEmpty())
+ delete stringResource;
+
+ return newString;
+}
+
+typedef HashMap<StringImpl*, v8::String*> StringCache;
+
+static StringCache& getStringCache()
+{
+ ASSERT(WTF::isMainThread());
+ DEFINE_STATIC_LOCAL(StringCache, mainThreadStringCache, ());
+ return mainThreadStringCache;
+}
+
+static void cachedStringCallback(v8::Persistent<v8::Value> wrapper, void* parameter)
+{
+ ASSERT(WTF::isMainThread());
+ StringImpl* stringImpl = static_cast<StringImpl*>(parameter);
+ ASSERT(getStringCache().contains(stringImpl));
+ getStringCache().remove(stringImpl);
+ wrapper.Dispose();
+ stringImpl->deref();
+}
+
+v8::Local<v8::String> v8ExternalString(const String& string)
+{
+ if (!string.length())
+ return v8::String::Empty();
+
+ if (!stringImplCacheEnabled)
+ return makeExternalString(string);
+
+ StringImpl* stringImpl = string.impl();
+ StringCache& stringCache = getStringCache();
+ v8::String* cachedV8String = stringCache.get(stringImpl);
+ if (cachedV8String)
+ return v8::Local<v8::String>(cachedV8String);
+
+ v8::Local<v8::String> newString = makeExternalString(string);
+ if (newString.IsEmpty())
+ return newString;
+
+ v8::Persistent<v8::String> wrapper = v8::Persistent<v8::String>::New(newString);
+ if (wrapper.IsEmpty())
+ return newString;
+
+ stringImpl->ref();
+ wrapper.MakeWeak(stringImpl, cachedStringCallback);
+ stringCache.set(stringImpl, *wrapper);
+
+ return newString;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index 9fce3f2..4f36f00 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -31,16 +31,91 @@
#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"
+#include "MathExtras.h"
+#include "PlatformString.h"
+
+#include <v8.h>
namespace WebCore {
- // FIXME: Remove once migration is complete.
+ enum ExternalMode {
+ Externalize,
+ DoNotExternalize
+ };
+
+ enum StringType {
+ PlainStringType,
+ AtomicStringType
+ };
+
+ // Convert v8 types to a WebCore::String. If the V8 string is not already
+ // an external string then it is transformed into an external string at this
+ // point to avoid repeated conversions.
+ String v8StringToWebCoreString(v8::Handle<v8::String>, ExternalMode mode, StringType type);
+ String v8ValueToWebCoreString(v8::Handle<v8::Value>);
+
+ // Convert v8 types to a WebCore::AtomicString.
+ AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String>);
+ AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value>);
+
+ // Convert a string to a V8 string.
+ v8::Handle<v8::String> v8String(const String&);
+
+ inline String toString(const String& string)
+ {
+ return string;
+ }
+
+ // Return a V8 external string that shares the underlying buffer with the given
+ // WebCore string. The reference counting mechanism is used to keep the
+ // underlying buffer alive while the string is still live in the V8 engine.
+ v8::Local<v8::String> v8ExternalString(const String&);
+
+ // Enables caching v8 wrappers created for WebCore::StringImpl. Currently this cache requires
+ // all the calls (both to convert WebCore::String to v8::String and to GC the handle)
+ // to be performed on the main thread.
+ void enableStringImplCache();
+
+ // Convert a value to a 32-bit integer. The conversion fails if the
+ // value cannot be converted to an integer or converts to nan or to an infinity.
+ inline int toInt32(v8::Handle<v8::Value> value, bool& ok)
+ {
+ ok = true;
+
+ // Fast case. The value is already a 32-bit integer.
+ if (value->IsInt32())
+ return value->Int32Value();
+
+ // Can the value be converted to a number?
+ v8::Local<v8::Number> numberObject = value->ToNumber();
+ if (numberObject.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ // Does the value convert to nan or to an infinity?
+ double numberValue = numberObject->Value();
+ if (isnan(numberValue) || isinf(numberValue)) {
+ ok = false;
+ return 0;
+ }
+
+ // Can the value be converted to a 32-bit integer?
+ v8::Local<v8::Int32> intValue = value->ToInt32();
+ if (intValue.IsEmpty()) {
+ ok = false;
+ return 0;
+ }
+
+ // Return the result of the int32 conversion.
+ return intValue->Value();
+ }
+
+ // Convert a value to a 32-bit integer assuming the conversion cannot fail.
inline int toInt32(v8::Handle<v8::Value> value)
{
- return ToInt32(value);
+ bool ok;
+ return toInt32(value, ok);
}
inline float toFloat(v8::Local<v8::Value> value)
@@ -48,22 +123,17 @@ namespace WebCore {
return static_cast<float>(value->NumberValue());
}
- // FIXME: Remove once migration is complete.
- inline String toWebCoreString(v8::Handle<v8::Value> obj)
+ // FIXME: Drop this in favor of the type specific v8ValueToWebCoreString when we rework the code generation.
+ inline String toWebCoreString(v8::Handle<v8::Value> object)
{
- return ToWebCoreString(obj);
+ return v8ValueToWebCoreString(object);
}
- // FIXME: Remove once migration is complete.
+ // The string returned by this function is still owned by the argument
+ // and will be deallocated when the argument is deallocated.
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);
+ return reinterpret_cast<const uint16_t*>(str.characters());
}
inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
@@ -75,7 +145,40 @@ namespace WebCore {
{
return value ? v8::True() : v8::False();
}
+
+ inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
+ {
+ if (value->IsNull())
+ return String();
+ return v8ValueToWebCoreString(value);
+ }
-}
+ inline String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value)
+ {
+ if (value->IsNull() || value->IsUndefined())
+ return String();
+ return toWebCoreString(value);
+ }
+
+ inline v8::Handle<v8::String> v8UndetectableString(const String& str)
+ {
+ return v8::String::NewUndetectable(fromWebCoreString(str), str.length());
+ }
+
+ inline v8::Handle<v8::Value> v8StringOrNull(const String& str)
+ {
+ return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str));
+ }
+
+ inline v8::Handle<v8::Value> v8StringOrUndefined(const String& str)
+ {
+ return str.isNull() ? v8::Handle<v8::Value>(v8::Undefined()) : v8::Handle<v8::Value>(v8String(str));
+ }
+
+ inline v8::Handle<v8::Value> v8StringOrFalse(const String& str)
+ {
+ return str.isNull() ? v8::Handle<v8::Value>(v8::False()) : v8::Handle<v8::Value>(v8String(str));
+ }
+} // namespace WebCore
#endif // V8Binding_h
diff --git a/WebCore/bindings/v8/V8Collection.cpp b/WebCore/bindings/v8/V8Collection.cpp
index 861f68a..c9fc9ac 100644
--- a/WebCore/bindings/v8/V8Collection.cpp
+++ b/WebCore/bindings/v8/V8Collection.cpp
@@ -48,14 +48,14 @@ v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::V
// Check that the value is an HTMLOptionElement. If not, throw a TYPE_MISMATCH_ERR DOMException.
if (!V8HTMLOptionElement::HasInstance(value)) {
- V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
return value;
}
- HTMLOptionElement* element = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(v8::Handle<v8::Object>::Cast(value));
+ HTMLOptionElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLOptionElement>(v8::Handle<v8::Object>::Cast(value));
base->setOption(index, element, ec);
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return value;
}
diff --git a/WebCore/bindings/v8/V8Collection.h b/WebCore/bindings/v8/V8Collection.h
index 1731f9c..cbfe921 100644
--- a/WebCore/bindings/v8/V8Collection.h
+++ b/WebCore/bindings/v8/V8Collection.h
@@ -47,8 +47,8 @@ namespace WebCore {
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);
+ return V8DOMWrapper::convertNodeToV8Object(static_cast<Node*>(implementation));
+ return V8DOMWrapper::convertToV8Object(type, implementation);
}
template<class T> static v8::Handle<v8::Value> getV8Object(PassRefPtr<T> implementation, v8::Local<v8::Value> implementationType)
@@ -61,10 +61,10 @@ namespace WebCore {
v8::Local<v8::Value> implementationType)
{
// FIXME: assert object is a collection type
- ASSERT(V8Proxy::MaybeDOMWrapper(object));
- V8ClassIndex::V8WrapperType wrapperType = V8Proxy::GetDOMWrapperType(object);
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
+ V8ClassIndex::V8WrapperType wrapperType = V8DOMWrapper::domWrapperType(object);
ASSERT(wrapperType != V8ClassIndex::NODE);
- Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, object);
+ Collection* collection = V8DOMWrapper::convertToNativeObject<Collection>(wrapperType, object);
String propertyName = toWebCoreString(name);
return getV8Object<ItemType>(collection->namedItem(propertyName), implementationType);
}
@@ -87,8 +87,8 @@ namespace WebCore {
// 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);
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));
+ ASSERT(V8DOMWrapper::domWrapperType(info.Holder()) == V8ClassIndex::NODE);
v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name);
if (!value.IsEmpty())
@@ -98,7 +98,7 @@ namespace WebCore {
// properties.
if (info.Holder()->HasRealNamedCallbackProperty(name))
return notHandledByInterceptor();
- Collection* collection = V8Proxy::DOMWrapperToNode<Collection>(info.Holder());
+ Collection* collection = V8DOMWrapper::convertDOMWrapperToNode<Collection>(info.Holder());
String propertyName = toWebCoreString(name);
void* implementation = collection->namedItem(propertyName);
return getV8Object(implementation, info.Data());
@@ -109,10 +109,10 @@ namespace WebCore {
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(V8DOMWrapper::maybeDOMWrapper(object));
+ V8ClassIndex::V8WrapperType wrapperType = V8DOMWrapper::domWrapperType(object);
ASSERT(wrapperType != V8ClassIndex::NODE);
- Collection* collection = V8Proxy::ToNativeObject<Collection>(wrapperType, object);
+ Collection* collection = V8DOMWrapper::convertToNativeObject<Collection>(wrapperType, object);
return getV8Object<ItemType>(collection->item(index), implementationType);
}
@@ -125,9 +125,9 @@ namespace WebCore {
// 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());
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));
+ ASSERT(V8DOMWrapper::domWrapperType(info.Holder()) == V8ClassIndex::NODE);
+ Collection* collection = V8DOMWrapper::convertDOMWrapperToNode<Collection>(info.Holder());
void* implementation = collection->item(index);
return getV8Object(implementation, info.Data());
}
@@ -135,9 +135,9 @@ namespace WebCore {
// 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());
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));
+ ASSERT(V8DOMWrapper::domWrapperType(info.Holder()) == V8ClassIndex::NODE);
+ Collection* collection = V8DOMWrapper::convertDOMWrapperToNode<Collection>(info.Holder());
int length = collection->length();
v8::Handle<v8::Array> properties = v8::Array::New(length);
for (int i = 0; i < length; ++i) {
@@ -151,9 +151,9 @@ namespace WebCore {
// 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());
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));
+ V8ClassIndex::V8WrapperType wrapperType = V8DOMWrapper::domWrapperType(info.Holder());
+ Collection* collection = V8DOMWrapper::convertToNativeObject<Collection>(wrapperType, info.Holder());
int length = collection->length();
v8::Handle<v8::Array> properties = v8::Array::New(length);
for (int i = 0; i < length; ++i) {
@@ -169,9 +169,9 @@ namespace WebCore {
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());
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));
+ V8ClassIndex::V8WrapperType wrapperType = V8DOMWrapper::domWrapperType(info.Holder());
+ Collection* collection = V8DOMWrapper::convertToNativeObject<Collection>(wrapperType, info.Holder());
String result = collection->item(index);
return v8StringOrNull(result);
}
diff --git a/WebCore/bindings/v8/V8ConsoleMessage.cpp b/WebCore/bindings/v8/V8ConsoleMessage.cpp
new file mode 100644
index 0000000..d9fe069
--- /dev/null
+++ b/WebCore/bindings/v8/V8ConsoleMessage.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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 "V8ConsoleMessage.h"
+
+#include "Console.h"
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "OwnPtr.h"
+#include "Page.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+Vector<V8ConsoleMessage>* V8ConsoleMessage::m_delayedMessages = 0;
+
+V8ConsoleMessage::V8ConsoleMessage(const String& string, const String& sourceID, unsigned lineNumber)
+ : m_string(string)
+ , m_sourceID(sourceID)
+ , m_lineNumber(lineNumber)
+{
+}
+
+void V8ConsoleMessage::dispatchNow(Page* page)
+{
+ ASSERT(page);
+
+ // Process any delayed messages to make sure that messages
+ // appear in the right order in the console.
+ processDelayed();
+
+ Console* console = page->mainFrame()->domWindow()->console();
+ console->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, m_string, m_lineNumber, m_sourceID);
+}
+
+void V8ConsoleMessage::dispatchLater()
+{
+ if (!m_delayedMessages) {
+ // Allocate a vector for the delayed messages. Will be
+ // deallocated when the delayed messages are processed
+ // in processDelayed().
+ m_delayedMessages = new Vector<V8ConsoleMessage>();
+ }
+
+ m_delayedMessages->append(*this);
+}
+
+void V8ConsoleMessage::processDelayed()
+{
+ if (!m_delayedMessages)
+ return;
+
+ // Take ownership of the delayed vector to avoid re-entrancy issues.
+ OwnPtr<Vector<V8ConsoleMessage> > delayedMessages(m_delayedMessages);
+ m_delayedMessages = 0;
+
+ // If we have a delayed vector it cannot be empty.
+ ASSERT(!delayedMessages->isEmpty());
+
+ // Add the delayed messages to the page of the active
+ // context. If that for some bizarre reason does not
+ // exist, we clear the list of delayed messages to avoid
+ // posting messages. We still deallocate the vector.
+ Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+ if (!frame)
+ return;
+ Page* page = frame->page();
+ if (!page)
+ return;
+
+ // Iterate through all the delayed messages and add them
+ // to the console.
+ const int size = delayedMessages->size();
+ for (int i = 0; i < size; ++i)
+ delayedMessages->at(i).dispatchNow(page);
+}
+
+void V8ConsoleMessage::handler(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data)
+{
+ // Use the frame where JavaScript is called from.
+ Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+ if (!frame)
+ return;
+ Page* page = frame->page();
+ if (!page)
+ return;
+
+ v8::Handle<v8::String> errorMessageString = message->Get();
+ ASSERT(!errorMessageString.IsEmpty());
+ String errorMessage = toWebCoreString(errorMessageString);
+
+ v8::Handle<v8::Value> resourceName = message->GetScriptResourceName();
+ bool useURL = resourceName.IsEmpty() || !resourceName->IsString();
+ String resourceNameString = useURL ? frame->document()->url() : toWebCoreString(resourceName);
+ V8ConsoleMessage consoleMessage(errorMessage, resourceNameString, message->GetLineNumber());
+ consoleMessage.dispatchNow(page);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8ConsoleMessage.h b/WebCore/bindings/v8/V8ConsoleMessage.h
new file mode 100644
index 0000000..a8f75ee
--- /dev/null
+++ b/WebCore/bindings/v8/V8ConsoleMessage.h
@@ -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.
+ */
+
+#ifndef V8ConsoleMessage_h
+#define V8ConsoleMessage_h
+
+#include "PlatformString.h"
+#include <v8.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class Page;
+
+ // V8ConsoleMessage encapsulates everything needed to
+ // log messages originating from JavaScript to the console.
+ class V8ConsoleMessage {
+ public:
+ V8ConsoleMessage(const String& string, const String& sourceID, unsigned lineNumber);
+
+ // Add a message to the console. May end up calling JavaScript code
+ // indirectly through the inspector so only call this function when
+ // it is safe to do allocations.
+ void dispatchNow(Page*);
+
+ // Add a message to the console but delay the reporting until it
+ // is safe to do so: Either when we leave JavaScript execution or
+ // when adding other console messages. The primary purpose of this
+ // method is to avoid calling into V8 to handle console messages
+ // when the VM is in a state that does not support GCs or allocations.
+ // Delayed messages are always reported in the page corresponding
+ // to the active context.
+ void dispatchLater();
+
+ // Process any delayed messages. May end up calling JavaScript code
+ // indirectly through the inspector so only call this function when
+ // it is safe to do allocations.
+ static void processDelayed();
+
+ // Convenience class for ensuring that delayed messages in the
+ // ConsoleMessageManager are processed quickly.
+ class Scope {
+ public:
+ Scope() { V8ConsoleMessage::processDelayed(); }
+ ~Scope() { V8ConsoleMessage::processDelayed(); }
+ };
+
+ // Callback from V8.
+ static void handler(v8::Handle<v8::Message>, v8::Handle<v8::Value> data);
+
+ private:
+ const String m_string;
+ const String m_sourceID;
+ const unsigned m_lineNumber;
+
+ // All delayed messages are stored in this vector. If the vector
+ // is 0, there are no delayed messages.
+ static Vector<V8ConsoleMessage>* m_delayedMessages;
+ };
+
+} // namespace WebCore
+
+#endif // V8ConsoleMessage_h
diff --git a/WebCore/bindings/v8/V8DOMMap.cpp b/WebCore/bindings/v8/V8DOMMap.cpp
index 4645c02..2d6639f 100644
--- a/WebCore/bindings/v8/V8DOMMap.cpp
+++ b/WebCore/bindings/v8/V8DOMMap.cpp
@@ -31,19 +31,14 @@
#include "config.h"
#include "V8DOMMap.h"
+#include "DOMData.h"
+#include "DOMDataStore.h"
#include "DOMObjectsInclude.h"
-
-#include <v8.h>
-#include <wtf/HashMap.h>
-#include <wtf/MainThread.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/StdLibExtras.h>
-#include <wtf/Threading.h>
-#include <wtf/ThreadSpecific.h>
-#include <wtf/Vector.h>
+#include "ScopedDOMDataStore.h"
namespace WebCore {
+#ifdef MANUAL_MERGE_REQUIRED
// DOM binding algorithm:
//
// There are two kinds of DOM objects:
@@ -289,291 +284,174 @@ template<typename T>
static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapType mapType, V8ClassIndex::V8WrapperType objectType, T*);
ThreadSpecificDOMData& getThreadSpecificDOMData()
+#else // MANUAL_MERGE_REQUIRED
+DOMDataStoreHandle::DOMDataStoreHandle()
+ : m_store(new ScopedDOMDataStore(DOMData::getCurrent()))
+#endif // MANUAL_MERGE_REQUIRED
{
- if (WTF::isMainThread()) {
- DEFINE_STATIC_LOCAL(MainThreadSpecificDOMData, mainThreadSpecificDOMData, ());
- return mainThreadSpecificDOMData;
- }
- return *threadSpecificDOMData;
}
-template <class KeyType>
-void ThreadSpecificDOMData::InternalDOMWrapperMap<KeyType>::forget(KeyType* object)
+DOMDataStoreHandle::~DOMDataStoreHandle()
{
- DOMWrapperMap<KeyType>::forget(object);
-
- ThreadSpecificDOMData::DelayedObjectMap& delayedObjectMap = getThreadSpecificDOMData().delayedObjectMap();
- delayedObjectMap.take(object);
}
DOMWrapperMap<Node>& getDOMNodeMap()
{
- return getThreadSpecificDOMData().domNodeMap();
+ // Nodes only exist on the main thread.
+ return DOMData::getCurrentMainThread()->getStore().domNodeMap();
}
DOMWrapperMap<void>& getDOMObjectMap()
{
- return getThreadSpecificDOMData().domObjectMap();
+ return DOMData::getCurrent()->getStore().domObjectMap();
}
DOMWrapperMap<void>& getActiveDOMObjectMap()
{
- return getThreadSpecificDOMData().activeDomObjectMap();
+ return DOMData::getCurrent()->getStore().activeDomObjectMap();
}
#if ENABLE(SVG)
-DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap()
-{
- return getThreadSpecificDOMData().domSvgElementInstanceMap();
-}
-static void weakSVGElementInstanceCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap()
{
- SVGElementInstance* instance = static_cast<SVGElementInstance*>(domObject);
-
- ThreadSpecificDOMData::InternalDOMWrapperMap<SVGElementInstance>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<SVGElementInstance>&>(getDOMSVGElementInstanceMap());
- if (map.contains(instance)) {
- instance->deref();
- map.forgetOnly(instance);
- } else
- handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMSVGElementInstanceMap, V8ClassIndex::SVGELEMENTINSTANCE, instance);
+ return DOMData::getCurrent()->getStore().domSvgElementInstanceMap();
}
// Map of SVG objects with contexts to V8 objects
DOMWrapperMap<void>& getDOMSVGObjectWithContextMap()
{
- return getThreadSpecificDOMData().domSvgObjectWithContextMap();
+ return DOMData::getCurrent()->getStore().domSvgObjectWithContextMap();
}
-static void weakSVGObjectWithContextCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
-{
- v8::HandleScope scope;
- ASSERT(v8Object->IsObject());
-
- V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(v8Object));
-
- ThreadSpecificDOMData::InternalDOMWrapperMap<void>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<void>&>(getDOMSVGObjectWithContextMap());
- if (map.contains(domObject)) {
- // The forget function removes object from the map and disposes the wrapper.
- map.forgetOnly(domObject);
-
- switch (type) {
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- SVG_OBJECT_TYPES(MakeCase)
-#undef MakeCase
-#define MakeCase(type, name) \
- case V8ClassIndex::type: \
- static_cast<V8SVGPODTypeWrapper<name>*>(domObject)->deref(); break;
- SVG_POD_NATIVE_TYPES(MakeCase)
-#undef MakeCase
- default:
- ASSERT_NOT_REACHED();
- break;
- }
- } else
- handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMSVGObjectWithContextMap, type, domObject);
-}
#endif // ENABLE(SVG)
-// Called when the dead object is not in GC thread's map. Go through all thread maps to find the one containing it.
-// Then clear the JS reference and push the DOM object into the delayed queue for it to be deref-ed at later time from the owning thread.
-// * This is called when the GC thread is not the owning thread.
-// * This can be called on any thread that has GC running.
-// * Only one V8 instance is running at a time due to V8::Locker. So we don't need to worry about concurrency.
-template<typename T>
-static void handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMWrapperMapType mapType, V8ClassIndex::V8WrapperType objectType, T* object)
+static void removeAllDOMObjectsInCurrentThreadHelper()
{
- WTF::MutexLocker locker(domDataListMutex());
- DOMDataList& list = domDataList();
- for (size_t i = 0; i < list.size(); ++i) {
- ThreadSpecificDOMData* threadData = list[i];
+ v8::HandleScope scope;
- ThreadSpecificDOMData::InternalDOMWrapperMap<T>* domMap = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<T>*>(threadData->getDOMWrapperMap(mapType));
- if (domMap->contains(object)) {
- // Clear the JS reference.
- domMap->forgetOnly(object);
+ // Deref all objects in the delayed queue.
+ DOMData::getCurrent()->derefDelayedObjects();
- // Push into the delayed queue.
- threadData->delayedObjectMap().set(object, objectType);
+ // The DOM objects with the following types only exist on the main thread.
+ if (WTF::isMainThread()) {
+ // Remove all DOM nodes.
+ DOMData::removeObjectsFromWrapperMap<Node>(getDOMNodeMap());
- // Post a task to the owning thread in order to process the delayed queue.
- // FIXME: For now, we can only post to main thread due to WTF task posting limitation. We will fix this when we work on nested worker.
- if (!threadData->delayedProcessingScheduled()) {
- threadData->setDelayedProcessingScheduled(true);
- if (threadData->isMainThread())
- WTF::callOnMainThread(&derefDelayedObjectsInCurrentThread, 0);
- }
+#if ENABLE(SVG)
+ // Remove all SVG element instances in the wrapper map.
+ DOMData::removeObjectsFromWrapperMap<SVGElementInstance>(getDOMSVGElementInstanceMap());
- break;
- }
+ // Remove all SVG objects with context in the wrapper map.
+ DOMData::removeObjectsFromWrapperMap<void>(getDOMSVGObjectWithContextMap());
+#endif
}
-}
-
-// Called when the object is near death (not reachable from JS roots).
-// It is time to remove the entry from the table and dispose the handle.
-static void weakDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
-{
- v8::HandleScope scope;
- ASSERT(v8Object->IsObject());
-
- V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(v8Object));
- ThreadSpecificDOMData::InternalDOMWrapperMap<void>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<void>&>(getDOMObjectMap());
- if (map.contains(domObject)) {
- // The forget function removes object from the map and disposes the wrapper.
- map.forgetOnly(domObject);
+ // Remove all DOM objects in the wrapper map.
+ DOMData::removeObjectsFromWrapperMap<void>(getDOMObjectMap());
- switch (type) {
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- DOM_OBJECT_TYPES(MakeCase)
-#undef MakeCase
- default:
- ASSERT_NOT_REACHED();
- break;
- }
- } else
- handleWeakObjectInOwningThread(ThreadSpecificDOMData::DOMObjectMap, type, domObject);
+ // Remove all active DOM objects in the wrapper map.
+ DOMData::removeObjectsFromWrapperMap<void>(getActiveDOMObjectMap());
}
-void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+void removeAllDOMObjectsInCurrentThread()
{
- v8::HandleScope scope;
- ASSERT(v8Object->IsObject());
-
- V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(v8Object));
-
- ThreadSpecificDOMData::InternalDOMWrapperMap<void>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<void>&>(getActiveDOMObjectMap());
- if (map.contains(domObject)) {
- // The forget function removes object from the map and disposes the wrapper.
- map.forgetOnly(domObject);
-
- switch (type) {
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- ACTIVE_DOM_OBJECT_TYPES(MakeCase)
-#undef MakeCase
- default:
- ASSERT_NOT_REACHED();
- break;
- }
+ // Use the locker only if it has already been invoked before, as by worker thread.
+ if (v8::Locker::IsActive()) {
+ v8::Locker locker;
+ removeAllDOMObjectsInCurrentThreadHelper();
} else
- handleWeakObjectInOwningThread(ThreadSpecificDOMData::ActiveDOMObjectMap, type, domObject);
+ removeAllDOMObjectsInCurrentThreadHelper();
}
-static void weakNodeCallback(v8::Persistent<v8::Value> v8Object, void* domObject)
+
+void visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor* visitor)
{
- Node* node = static_cast<Node*>(domObject);
+ v8::HandleScope scope;
- ThreadSpecificDOMData::InternalDOMWrapperMap<Node>& map = static_cast<ThreadSpecificDOMData::InternalDOMWrapperMap<Node>&>(getDOMNodeMap());
- if (map.contains(node)) {
- map.forgetOnly(node);
- node->deref();
- } else
- handleWeakObjectInOwningThread<Node>(ThreadSpecificDOMData::DOMNodeMap, V8ClassIndex::NODE, node);
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+ if (!store->domData()->owningThread() == WTF::currentThread())
+ continue;
+
+ HashMap<Node*, v8::Object*>& map = store->domNodeMap().impl();
+ for (HashMap<Node*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
+ }
}
-static void derefObject(V8ClassIndex::V8WrapperType type, void* domObject)
+void visitDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
{
- switch (type) {
- case V8ClassIndex::NODE:
- static_cast<Node*>(domObject)->deref();
- break;
-
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- DOM_OBJECT_TYPES(MakeCase) // This includes both active and non-active.
-#undef MakeCase
+ v8::HandleScope scope;
-#if ENABLE(SVG)
-#define MakeCase(type, name) \
- case V8ClassIndex::type: static_cast<name*>(domObject)->deref(); break;
- SVG_OBJECT_TYPES(MakeCase) // This also includes SVGElementInstance.
-#undef MakeCase
-
-#define MakeCase(type, name) \
- case V8ClassIndex::type: \
- static_cast<V8SVGPODTypeWrapper<name>*>(domObject)->deref(); break;
- SVG_POD_NATIVE_TYPES(MakeCase)
-#undef MakeCase
-#endif
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+ if (!store->domData()->owningThread() == WTF::currentThread())
+ continue;
- default:
- ASSERT_NOT_REACHED();
- break;
+ HashMap<void*, v8::Object*> & map = store->domObjectMap().impl();
+ for (HashMap<void*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
}
}
-static void derefDelayedObjects()
+void visitActiveDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
{
- WTF::MutexLocker locker(domDataListMutex());
+ v8::HandleScope scope;
- getThreadSpecificDOMData().setDelayedProcessingScheduled(false);
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+ if (!store->domData()->owningThread() == WTF::currentThread())
+ continue;
- ThreadSpecificDOMData::DelayedObjectMap& delayedObjectMap = getThreadSpecificDOMData().delayedObjectMap();
- for (ThreadSpecificDOMData::DelayedObjectMap::iterator iter(delayedObjectMap.begin()); iter != delayedObjectMap.end(); ++iter) {
- derefObject(iter->second, iter->first);
+ HashMap<void*, v8::Object*>& map = store->activeDomObjectMap().impl();
+ for (HashMap<void*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
}
- delayedObjectMap.clear();
}
-static void derefDelayedObjectsInCurrentThread(void*)
-{
- derefDelayedObjects();
-}
+#if ENABLE(SVG)
-template<typename T>
-static void removeObjectsFromWrapperMap(DOMWrapperMap<T>& domMap)
+void visitDOMSVGElementInstancesInCurrentThread(DOMWrapperMap<SVGElementInstance>::Visitor* visitor)
{
- for (typename WTF::HashMap<T*, v8::Object*>::iterator iter(domMap.impl().begin()); iter != domMap.impl().end(); ++iter) {
- T* domObject = static_cast<T*>(iter->first);
- v8::Persistent<v8::Object> v8Object(iter->second);
-
- V8ClassIndex::V8WrapperType type = V8Proxy::GetDOMWrapperType(v8::Handle<v8::Object>::Cast(v8Object));
+ v8::HandleScope scope;
- // Deref the DOM object.
- derefObject(type, domObject);
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+ if (!store->domData()->owningThread() == WTF::currentThread())
+ continue;
- // Clear the JS wrapper.
- v8Object.Dispose();
+ HashMap<SVGElementInstance*, v8::Object*> & map = store->domSvgElementInstanceMap().impl();
+ for (HashMap<SVGElementInstance*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
}
- domMap.impl().clear();
}
-static void removeAllDOMObjectsInCurrentThreadHelper()
+void visitSVGObjectsInCurrentThread(DOMWrapperMap<void>::Visitor* visitor)
{
v8::HandleScope scope;
- // Deref all objects in the delayed queue.
- derefDelayedObjects();
-
- // Remove all DOM nodes.
- removeObjectsFromWrapperMap<Node>(getDOMNodeMap());
-
- // Remove all DOM objects in the wrapper map.
- removeObjectsFromWrapperMap<void>(getDOMObjectMap());
-
- // Remove all active DOM objects in the wrapper map.
- removeObjectsFromWrapperMap<void>(getActiveDOMObjectMap());
-
-#if ENABLE(SVG)
- // Remove all SVG element instances in the wrapper map.
- removeObjectsFromWrapperMap<SVGElementInstance>(getDOMSVGElementInstanceMap());
+ WTF::MutexLocker locker(DOMDataStore::allStoresMutex());
+ DOMDataList& list = DOMDataStore::allStores();
+ for (size_t i = 0; i < list.size(); ++i) {
+ DOMDataStore* store = list[i];
+ if (!store->domData()->owningThread() == WTF::currentThread())
+ continue;
- // Remove all SVG objects with context in the wrapper map.
- removeObjectsFromWrapperMap<void>(getDOMSVGObjectWithContextMap());
-#endif
+ HashMap<void*, v8::Object*>& map = store->domSvgObjectWithContextMap().impl();
+ for (HashMap<void*, v8::Object*>::iterator it = map.begin(); it != map.end(); ++it)
+ visitor->visitDOMWrapper(it->first, v8::Persistent<v8::Object>(it->second));
+ }
}
-void removeAllDOMObjectsInCurrentThread()
-{
- // Use the locker only if it has already been invoked before, as by worker thread.
- if (v8::Locker::IsActive()) {
- v8::Locker locker;
- removeAllDOMObjectsInCurrentThreadHelper();
- } else
- removeAllDOMObjectsInCurrentThreadHelper();
-}
+#endif
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMMap.h b/WebCore/bindings/v8/V8DOMMap.h
index 47fa765..eac39d2 100644
--- a/WebCore/bindings/v8/V8DOMMap.h
+++ b/WebCore/bindings/v8/V8DOMMap.h
@@ -32,6 +32,7 @@
#define V8DOMMap_h
#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
#include <v8.h>
namespace WebCore {
@@ -48,10 +49,18 @@ namespace WebCore {
WeakReferenceMap(v8::WeakReferenceCallback callback) : m_weakReferenceCallback(callback) { }
virtual ~WeakReferenceMap()
{
+#ifdef MANUAL_MERGE_REQUIRED
#ifndef NDEBUG
+#else // MANUAL_MERGE_REQUIRED
+ #ifndef NDEBUG
+#endif // MANUAL_MERGE_REQUIRED
if (m_map.size() > 0)
fprintf(stderr, "Leak %d JS wrappers.\n", m_map.size());
+#ifdef MANUAL_MERGE_REQUIRED
#endif
+#else // MANUAL_MERGE_REQUIRED
+ #endif
+#endif // MANUAL_MERGE_REQUIRED
}
// Get the JS wrapper object of an object.
@@ -89,23 +98,42 @@ namespace WebCore {
v8::WeakReferenceCallback m_weakReferenceCallback;
};
-
template <class KeyType> class DOMWrapperMap : public WeakReferenceMap<KeyType, v8::Object> {
public:
DOMWrapperMap(v8::WeakReferenceCallback callback) : WeakReferenceMap<KeyType, v8::Object>(callback) { }
+
+ class Visitor {
+ public:
+ virtual void visitDOMWrapper(KeyType* key, v8::Persistent<v8::Object> object) = 0;
+ };
};
- // Callback when JS wrapper of active DOM object is dead.
- void weakActiveDOMObjectCallback(v8::Persistent<v8::Value> v8Object, void* domObject);
+ // An opaque class that represents a set of DOM wrappers.
+ class DOMDataStore;
+
+ // A utility class to manage the lifetime of set of DOM wrappers.
+ class DOMDataStoreHandle {
+ public:
+ DOMDataStoreHandle();
+ ~DOMDataStoreHandle();
+
+ DOMDataStore* getStore() const { return m_store.get(); }
+
+ private:
+ OwnPtr<DOMDataStore> m_store;
+ };
// A map from DOM node to its JS wrapper.
DOMWrapperMap<Node>& getDOMNodeMap();
+ void visitDOMNodesInCurrentThread(DOMWrapperMap<Node>::Visitor*);
// A map from a DOM object (non-node) to its JS wrapper. This map does not contain the DOM objects which can have pending activity (active dom objects).
DOMWrapperMap<void>& getDOMObjectMap();
+ void visitDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor*);
// A map from a DOM object to its JS wrapper for DOM objects which can have pending activity.
DOMWrapperMap<void>& getActiveDOMObjectMap();
+ void visitActiveDOMObjectsInCurrentThread(DOMWrapperMap<void>::Visitor*);
// This should be called to remove all DOM objects associated with the current thread when it is tearing down.
void removeAllDOMObjectsInCurrentThread();
@@ -113,9 +141,11 @@ namespace WebCore {
#if ENABLE(SVG)
// A map for SVGElementInstances to its JS wrapper.
DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap();
+ void visitSVGElementInstancesInCurrentThread(DOMWrapperMap<SVGElementInstance>::Visitor*);
// Map of SVG objects with contexts to V8 objects.
DOMWrapperMap<void>& getDOMSVGObjectWithContextMap();
+ void visitDOMSVGObjectsInCurrentThread(DOMWrapperMap<void>::Visitor*);
#endif
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
new file mode 100644
index 0000000..33d1147
--- /dev/null
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -0,0 +1,1465 @@
+/*
+ * 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 "V8DOMWrapper.h"
+
+#include "ChromiumBridge.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "DOMObjectsInclude.h"
+#include "DocumentLoader.h"
+#include "FrameLoaderClient.h"
+#include "ScriptController.h"
+#include "V8Binding.h"
+#include "V8Collection.h"
+#include "V8CustomBinding.h"
+#include "V8DOMMap.h"
+#include "V8DOMWindow.h"
+#include "V8Index.h"
+#include "V8IsolatedWorld.h"
+#include "WorkerContextExecutionProxy.h"
+
+#include <algorithm>
+#include <utility>
+#include <v8.h>
+#include <v8-debug.h>
+#include <wtf/Assertions.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+typedef HashMap<Node*, v8::Object*> DOMNodeMap;
+typedef HashMap<void*, v8::Object*> DOMObjectMap;
+
+// Get the string 'toString'.
+static v8::Persistent<v8::String> GetToStringName()
+{
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::String>, value, ());
+ if (value.IsEmpty())
+ value = v8::Persistent<v8::String>::New(v8::String::New("toString"));
+ return value;
+}
+
+static v8::Handle<v8::Value> ConstructorToString(const v8::Arguments& args)
+{
+ // The DOM constructors' toString functions grab the current toString
+ // for Functions by taking the toString function of itself and then
+ // calling it with the constructor as its receiver. This means that
+ // changes to the Function prototype chain or toString function are
+ // reflected when printing DOM constructors. The only wart is that
+ // changes to a DOM constructor's toString's toString will cause the
+ // toString of the DOM constructor itself to change. This is extremely
+ // obscure and unlikely to be a problem.
+ v8::Handle<v8::Value> value = args.Callee()->Get(GetToStringName());
+ if (!value->IsFunction())
+ return v8::String::New("");
+ return v8::Handle<v8::Function>::Cast(value)->Call(args.This(), 0, 0);
+}
+
+#if ENABLE(SVG)
+v8::Handle<v8::Value> V8DOMWrapper::convertSVGElementInstanceToV8Object(SVGElementInstance* instance)
+{
+ if (!instance)
+ return v8::Null();
+
+ v8::Handle<v8::Object> existingInstance = getDOMSVGElementInstanceMap().get(instance);
+ if (!existingInstance.IsEmpty())
+ return existingInstance;
+
+ instance->ref();
+
+ // Instantiate the V8 object and remember it
+ v8::Handle<v8::Object> result = instantiateV8Object(V8ClassIndex::SVGELEMENTINSTANCE, V8ClassIndex::SVGELEMENTINSTANCE, instance);
+ if (!result.IsEmpty()) {
+ // Only update the DOM SVG element map if the result is non-empty.
+ getDOMSVGElementInstanceMap().set(instance, v8::Persistent<v8::Object>::New(result));
+ }
+ return result;
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertSVGObjectWithContextToV8Object(V8ClassIndex::V8WrapperType type, void* object)
+{
+ if (!object)
+ return v8::Null();
+
+ v8::Persistent<v8::Object> result = getDOMSVGObjectWithContextMap().get(object);
+ if (!result.IsEmpty())
+ return result;
+
+ // Special case: SVGPathSegs need to be downcast to their real type
+ if (type == V8ClassIndex::SVGPATHSEG)
+ type = V8Custom::DowncastSVGPathSeg(object);
+
+ v8::Local<v8::Object> v8Object = instantiateV8Object(type, type, object);
+ if (!v8Object.IsEmpty()) {
+ result = v8::Persistent<v8::Object>::New(v8Object);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: static_cast<NAME*>(object)->ref(); break;
+ SVG_OBJECT_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: \
+ static_cast<V8SVGPODTypeWrapper<NAME>*>(object)->ref(); break;
+ SVG_POD_NATIVE_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ getDOMSVGObjectWithContextMap().set(object, result);
+ }
+
+ return result;
+}
+
+#endif
+
+bool V8DOMWrapper::domObjectHasJSWrapper(void* object)
+{
+ return getDOMObjectMap().contains(object) || getActiveDOMObjectMap().contains(object);
+}
+
+// The caller must have increased obj's ref count.
+void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
+#ifndef NDEBUG
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ ASSERT_NOT_REACHED();
+#undef MAKE_CASE
+ default:
+ break;
+ }
+#endif
+ getDOMObjectMap().set(object, wrapper);
+}
+
+// The caller must have increased obj's ref count.
+void V8DOMWrapper::setJSWrapperForActiveDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
+#ifndef NDEBUG
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE: break;
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ default:
+ ASSERT_NOT_REACHED();
+#undef MAKE_CASE
+ }
+#endif
+ getActiveDOMObjectMap().set(object, wrapper);
+}
+
+// The caller must have increased node's ref count.
+void V8DOMWrapper::setJSWrapperForDOMNode(Node* node, v8::Persistent<v8::Object> wrapper)
+{
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(wrapper));
+ getDOMNodeMap().set(node, wrapper);
+}
+
+v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8WrapperType type)
+{
+ v8::Persistent<v8::FunctionTemplate>* cacheCell = V8ClassIndex::GetCache(type);
+ if (!cacheCell->IsEmpty())
+ return *cacheCell;
+
+ // Not in the cache.
+ FunctionTemplateFactory factory = V8ClassIndex::GetFactory(type);
+ v8::Persistent<v8::FunctionTemplate> descriptor = factory();
+ // DOM constructors are functions and should print themselves as such.
+ // However, we will later replace their prototypes with Object
+ // prototypes so we need to explicitly override toString on the
+ // instance itself. If we later make DOM constructors full objects
+ // we can give them class names instead and Object.prototype.toString
+ // will work so we can remove this code.
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, toStringTemplate, ());
+ if (toStringTemplate.IsEmpty())
+ toStringTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(ConstructorToString));
+ descriptor->Set(GetToStringName(), toStringTemplate);
+ switch (type) {
+ case V8ClassIndex::CSSSTYLEDECLARATION:
+ // The named property handler for style declarations has a
+ // setter. Therefore, the interceptor has to be on the object
+ // itself and not on the prototype object.
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler( USE_NAMED_PROPERTY_GETTER(CSSStyleDeclaration), USE_NAMED_PROPERTY_SETTER(CSSStyleDeclaration));
+ setCollectionStringOrNullIndexedGetter<CSSStyleDeclaration>(descriptor);
+ break;
+ case V8ClassIndex::CSSRULELIST:
+ setCollectionIndexedGetter<CSSRuleList, CSSRule>(descriptor, V8ClassIndex::CSSRULE);
+ break;
+ case V8ClassIndex::CSSVALUELIST:
+ setCollectionIndexedGetter<CSSValueList, CSSValue>(descriptor, V8ClassIndex::CSSVALUE);
+ break;
+ case V8ClassIndex::CSSVARIABLESDECLARATION:
+ setCollectionStringOrNullIndexedGetter<CSSVariablesDeclaration>(descriptor);
+ break;
+ case V8ClassIndex::WEBKITCSSTRANSFORMVALUE:
+ setCollectionIndexedGetter<WebKitCSSTransformValue, CSSValue>(descriptor, V8ClassIndex::CSSVALUE);
+ break;
+ case V8ClassIndex::HTMLALLCOLLECTION:
+ descriptor->InstanceTemplate()->MarkAsUndetectable(); // fall through
+ case V8ClassIndex::HTMLCOLLECTION:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLCollection));
+ descriptor->InstanceTemplate()->SetCallAsFunctionHandler(USE_CALLBACK(HTMLCollectionCallAsFunction));
+ setCollectionIndexedGetter<HTMLCollection, Node>(descriptor, V8ClassIndex::NODE);
+ break;
+ case V8ClassIndex::HTMLOPTIONSCOLLECTION:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLCollection));
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(HTMLOptionsCollection), USE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection));
+ descriptor->InstanceTemplate()->SetCallAsFunctionHandler(USE_CALLBACK(HTMLCollectionCallAsFunction));
+ break;
+ case V8ClassIndex::HTMLSELECTELEMENT:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLSelectElementCollection));
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(nodeCollectionIndexedPropertyGetter<HTMLSelectElement>, USE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection),
+ 0, 0, nodeCollectionIndexedPropertyEnumerator<HTMLSelectElement>, v8::Integer::New(V8ClassIndex::NODE));
+ break;
+ case V8ClassIndex::HTMLDOCUMENT: {
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLDocument), 0, 0, USE_NAMED_PROPERTY_DELETER(HTMLDocument));
+
+ // We add an extra internal field to all Document wrappers for
+ // storing a per document DOMImplementation wrapper.
+ //
+ // Additionally, we add two extra internal fields for
+ // HTMLDocuments to implement temporary shadowing of
+ // document.all. One field holds an object that is used as a
+ // marker. The other field holds the marker object if
+ // document.all is not shadowed and some other value if
+ // document.all is shadowed.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kNodeMinimumInternalFieldCount);
+ instanceTemplate->SetInternalFieldCount(V8Custom::kHTMLDocumentInternalFieldCount);
+ break;
+ }
+#if ENABLE(SVG)
+ case V8ClassIndex::SVGDOCUMENT: // fall through
+#endif
+ case V8ClassIndex::DOCUMENT: {
+ // We add an extra internal field to all Document wrappers for
+ // storing a per document DOMImplementation wrapper.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kNodeMinimumInternalFieldCount);
+ instanceTemplate->SetInternalFieldCount( V8Custom::kDocumentMinimumInternalFieldCount);
+ break;
+ }
+ case V8ClassIndex::HTMLAPPLETELEMENT: // fall through
+ case V8ClassIndex::HTMLEMBEDELEMENT: // fall through
+ case V8ClassIndex::HTMLOBJECTELEMENT:
+ // HTMLAppletElement, HTMLEmbedElement and HTMLObjectElement are
+ // inherited from HTMLPlugInElement, and they share the same property
+ // handling code.
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLPlugInElement), USE_NAMED_PROPERTY_SETTER(HTMLPlugInElement));
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(HTMLPlugInElement), USE_INDEXED_PROPERTY_SETTER(HTMLPlugInElement));
+ descriptor->InstanceTemplate()->SetCallAsFunctionHandler(USE_CALLBACK(HTMLPlugInElement));
+ break;
+ case V8ClassIndex::HTMLFRAMESETELEMENT:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLFrameSetElement));
+ break;
+ case V8ClassIndex::HTMLFORMELEMENT:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(HTMLFormElement));
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(HTMLFormElement), 0, 0, 0, nodeCollectionIndexedPropertyEnumerator<HTMLFormElement>, v8::Integer::New(V8ClassIndex::NODE));
+ break;
+ case V8ClassIndex::STYLESHEET: // fall through
+ case V8ClassIndex::CSSSTYLESHEET: {
+ // We add an extra internal field to hold a reference to
+ // the owner node.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kDefaultWrapperInternalFieldCount);
+ instanceTemplate->SetInternalFieldCount(V8Custom::kStyleSheetInternalFieldCount);
+ break;
+ }
+ case V8ClassIndex::MEDIALIST:
+ setCollectionStringOrNullIndexedGetter<MediaList>(descriptor);
+ break;
+ case V8ClassIndex::MIMETYPEARRAY:
+ setCollectionIndexedAndNamedGetters<MimeTypeArray, MimeType>(descriptor, V8ClassIndex::MIMETYPE);
+ break;
+ case V8ClassIndex::NAMEDNODEMAP:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(NamedNodeMap));
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(NamedNodeMap), 0, 0, 0, collectionIndexedPropertyEnumerator<NamedNodeMap>, v8::Integer::New(V8ClassIndex::NODE));
+ break;
+#if ENABLE(DOM_STORAGE)
+ case V8ClassIndex::STORAGE:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(Storage), USE_NAMED_PROPERTY_SETTER(Storage), 0, USE_NAMED_PROPERTY_DELETER(Storage), V8Custom::v8StorageNamedPropertyEnumerator);
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(Storage), USE_INDEXED_PROPERTY_SETTER(Storage), 0, USE_INDEXED_PROPERTY_DELETER(Storage));
+ break;
+#endif
+ case V8ClassIndex::NODELIST:
+ setCollectionIndexedGetter<NodeList, Node>(descriptor, V8ClassIndex::NODE);
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(NodeList));
+ break;
+ case V8ClassIndex::PLUGIN:
+ setCollectionIndexedAndNamedGetters<Plugin, MimeType>(descriptor, V8ClassIndex::MIMETYPE);
+ break;
+ case V8ClassIndex::PLUGINARRAY:
+ setCollectionIndexedAndNamedGetters<PluginArray, Plugin>(descriptor, V8ClassIndex::PLUGIN);
+ break;
+ case V8ClassIndex::STYLESHEETLIST:
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(StyleSheetList));
+ setCollectionIndexedGetter<StyleSheetList, StyleSheet>(descriptor, V8ClassIndex::STYLESHEET);
+ break;
+ case V8ClassIndex::DOMWINDOW: {
+ v8::Local<v8::Signature> defaultSignature = v8::Signature::New(descriptor);
+
+ descriptor->PrototypeTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(DOMWindow));
+ descriptor->PrototypeTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(DOMWindow));
+
+ descriptor->SetHiddenPrototype(true);
+
+ // Reserve spaces for references to location, history and
+ // navigator objects.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kDOMWindowInternalFieldCount);
+
+ // Set access check callbacks, but turned off initially.
+ // When a context is detached from a frame, turn on the access check.
+ // Turning on checks also invalidates inline caches of the object.
+ instanceTemplate->SetAccessCheckCallbacks(V8Custom::v8DOMWindowNamedSecurityCheck, V8Custom::v8DOMWindowIndexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW), false);
+ break;
+ }
+ case V8ClassIndex::LOCATION: {
+ // For security reasons, these functions are on the instance
+ // instead of on the prototype object to insure that they cannot
+ // be overwritten.
+ v8::Local<v8::ObjectTemplate> instance = descriptor->InstanceTemplate();
+ instance->SetAccessor(v8::String::New("reload"), V8Custom::v8LocationReloadAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("replace"), V8Custom::v8LocationReplaceAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ instance->SetAccessor(v8::String::New("assign"), V8Custom::v8LocationAssignAccessorGetter, 0, v8::Handle<v8::Value>(), v8::ALL_CAN_READ, static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly));
+ break;
+ }
+ case V8ClassIndex::HISTORY:
+ break;
+
+ case V8ClassIndex::MESSAGECHANNEL: {
+ // Reserve two more internal fields for referencing the port1
+ // and port2 wrappers. This ensures that the port wrappers are
+ // kept alive when the channel wrapper is.
+ descriptor->SetCallHandler(USE_CALLBACK(MessageChannelConstructor));
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kMessageChannelInternalFieldCount);
+ break;
+ }
+
+ case V8ClassIndex::MESSAGEPORT: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kMessagePortInternalFieldCount);
+ break;
+ }
+
+#if ENABLE(WORKERS)
+ case V8ClassIndex::ABSTRACTWORKER: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kAbstractWorkerInternalFieldCount);
+ break;
+ }
+
+ case V8ClassIndex::DEDICATEDWORKERCONTEXT: {
+ // Reserve internal fields for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kDefaultWrapperInternalFieldCount);
+ instanceTemplate->SetInternalFieldCount(V8Custom::kDedicatedWorkerContextInternalFieldCount);
+ break;
+ }
+
+ case V8ClassIndex::WORKER: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kWorkerInternalFieldCount);
+ descriptor->SetCallHandler(USE_CALLBACK(WorkerConstructor));
+ break;
+ }
+
+ case V8ClassIndex::WORKERCONTEXT: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kDefaultWrapperInternalFieldCount);
+ instanceTemplate->SetInternalFieldCount(V8Custom::kWorkerContextMinimumInternalFieldCount);
+ break;
+ }
+
+#endif // WORKERS
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ case V8ClassIndex::DOMAPPLICATIONCACHE: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kDOMApplicationCacheFieldCount);
+ break;
+ }
+#endif
+
+ // The following objects are created from JavaScript.
+ case V8ClassIndex::DOMPARSER:
+ descriptor->SetCallHandler(USE_CALLBACK(DOMParserConstructor));
+ break;
+#if ENABLE(VIDEO)
+ case V8ClassIndex::HTMLAUDIOELEMENT:
+ descriptor->SetCallHandler(USE_CALLBACK(HTMLAudioElementConstructor));
+ break;
+#endif
+ case V8ClassIndex::HTMLIMAGEELEMENT:
+ descriptor->SetCallHandler(USE_CALLBACK(HTMLImageElementConstructor));
+ break;
+ case V8ClassIndex::HTMLOPTIONELEMENT:
+ descriptor->SetCallHandler(USE_CALLBACK(HTMLOptionElementConstructor));
+ break;
+ case V8ClassIndex::WEBKITCSSMATRIX:
+ descriptor->SetCallHandler(USE_CALLBACK(WebKitCSSMatrixConstructor));
+ break;
+ case V8ClassIndex::WEBKITPOINT:
+ descriptor->SetCallHandler(USE_CALLBACK(WebKitPointConstructor));
+ break;
+ case V8ClassIndex::XMLSERIALIZER:
+ descriptor->SetCallHandler(USE_CALLBACK(XMLSerializerConstructor));
+ break;
+ case V8ClassIndex::XMLHTTPREQUEST: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kXMLHttpRequestInternalFieldCount);
+ descriptor->SetCallHandler(USE_CALLBACK(XMLHttpRequestConstructor));
+ break;
+ }
+ case V8ClassIndex::XMLHTTPREQUESTUPLOAD: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kXMLHttpRequestInternalFieldCount);
+ break;
+ }
+ case V8ClassIndex::XPATHEVALUATOR:
+ descriptor->SetCallHandler(USE_CALLBACK(XPathEvaluatorConstructor));
+ break;
+ case V8ClassIndex::XSLTPROCESSOR:
+ descriptor->SetCallHandler(USE_CALLBACK(XSLTProcessorConstructor));
+ break;
+ case V8ClassIndex::CLIENTRECTLIST:
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(ClientRectList));
+ break;
+#if ENABLE(DATAGRID)
+ case V8ClassIndex::DATAGRIDCOLUMNLIST:
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(DataGridColumnList));
+ descriptor->InstanceTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(DataGridColumnList));
+ break;
+#endif
+ default:
+ break;
+ }
+
+ *cacheCell = descriptor;
+ return descriptor;
+}
+
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> objectPrototype)
+{
+ // A DOM constructor is a function instance created from a DOM constructor
+ // template. There is one instance per context. A DOM constructor is
+ // different from a normal function in two ways:
+ // 1) it cannot be called as constructor (aka, used to create a DOM object)
+ // 2) its __proto__ points to Object.prototype rather than
+ // Function.prototype.
+ // The reason for 2) is that, in Safari, a DOM constructor is a normal JS
+ // object, but not a function. Hotmail relies on the fact that, in Safari,
+ // HTMLElement.__proto__ == Object.prototype.
+ v8::Handle<v8::FunctionTemplate> functionTemplate = 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>();
+ // Hotmail fix, see comments above.
+ if (!objectPrototype.IsEmpty())
+ value->Set(v8::String::New("__proto__"), objectPrototype);
+ return value;
+}
+
+v8::Local<v8::Function> V8DOMWrapper::getConstructorForContext(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Context> context)
+{
+ // Enter the scope for this context to get the correct constructor.
+ v8::Context::Scope scope(context);
+
+ return getConstructor(type, V8Proxy::getHiddenObjectPrototype(context));
+}
+
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, DOMWindow* window)
+{
+ Frame* frame = window->frame();
+ if (!frame)
+ return v8::Local<v8::Function>();
+
+ v8::Handle<v8::Context> context = V8Proxy::context(frame);
+ if (context.IsEmpty())
+ return v8::Local<v8::Function>();
+
+ return getConstructorForContext(type, context);
+}
+
+v8::Local<v8::Function> V8DOMWrapper::getConstructor(V8ClassIndex::V8WrapperType type, WorkerContext*)
+{
+ WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+ if (!proxy)
+ return v8::Local<v8::Function>();
+
+ v8::Handle<v8::Context> context = proxy->context();
+ if (context.IsEmpty())
+ return v8::Local<v8::Function>();
+
+ return getConstructorForContext(type, context);
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperType type, void* impl)
+{
+ ASSERT(type != V8ClassIndex::EVENTLISTENER);
+ ASSERT(type != V8ClassIndex::EVENTTARGET);
+ ASSERT(type != V8ClassIndex::EVENT);
+
+ // These objects can be constructed under WorkerContextExecutionProxy. They need special
+ // handling, since if we proceed below V8Proxy::retrieve() will get called and will crash.
+ if ((type == V8ClassIndex::DOMCOREEXCEPTION
+ || type == V8ClassIndex::RANGEEXCEPTION
+ || type == V8ClassIndex::EVENTEXCEPTION
+ || type == V8ClassIndex::XMLHTTPREQUESTEXCEPTION
+ || type == V8ClassIndex::MESSAGEPORT)
+ && WorkerContextExecutionProxy::retrieve()) {
+ return WorkerContextExecutionProxy::convertToV8Object(type, impl);
+ }
+
+ bool isActiveDomObject = false;
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
+ DOM_NODE_TYPES(MAKE_CASE)
+#if ENABLE(SVG)
+ SVG_NODE_TYPES(MAKE_CASE)
+#endif
+ return convertNodeToV8Object(static_cast<Node*>(impl));
+ case V8ClassIndex::CSSVALUE:
+ return convertCSSValueToV8Object(static_cast<CSSValue*>(impl));
+ case V8ClassIndex::CSSRULE:
+ return convertCSSRuleToV8Object(static_cast<CSSRule*>(impl));
+ case V8ClassIndex::STYLESHEET:
+ return convertStyleSheetToV8Object(static_cast<StyleSheet*>(impl));
+ case V8ClassIndex::DOMWINDOW:
+ return convertWindowToV8Object(static_cast<DOMWindow*>(impl));
+#if ENABLE(SVG)
+ SVG_NONNODE_TYPES(MAKE_CASE)
+ if (type == V8ClassIndex::SVGELEMENTINSTANCE)
+ return convertSVGElementInstanceToV8Object(static_cast<SVGElementInstance*>(impl));
+ return convertSVGObjectWithContextToV8Object(type, impl);
+#endif
+
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ isActiveDomObject = true;
+ break;
+ default:
+ break;
+ }
+
+#undef MAKE_CASE
+
+ if (!impl)
+ return v8::Null();
+
+ // Non DOM node
+ v8::Persistent<v8::Object> result = isActiveDomObject ? getActiveDOMObjectMap().get(impl) : getDOMObjectMap().get(impl);
+ if (result.IsEmpty()) {
+ v8::Local<v8::Object> v8Object = instantiateV8Object(type, type, impl);
+ if (!v8Object.IsEmpty()) {
+ // Go through big switch statement, it has some duplications
+ // that were handled by code above (such as CSSVALUE, CSSRULE, etc).
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: static_cast<NAME*>(impl)->ref(); break;
+ DOM_OBJECT_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ result = v8::Persistent<v8::Object>::New(v8Object);
+ if (isActiveDomObject)
+ setJSWrapperForActiveDOMObject(impl, result);
+ else
+ setJSWrapperForDOMObject(impl, result);
+
+ if (type == V8ClassIndex::CANVASPIXELARRAY) {
+ CanvasPixelArray* pixels = reinterpret_cast<CanvasPixelArray*>(impl);
+ result->SetIndexedPropertiesToPixelData(pixels->data()->data(), pixels->length());
+ }
+
+ // Special case for non-node objects associated with a
+ // DOMWindow. Both Safari and FF let the JS wrappers for these
+ // objects survive GC. To mimic their behavior, V8 creates
+ // hidden references from the DOMWindow to these wrapper
+ // objects. These references get cleared when the DOMWindow is
+ // reused by a new page.
+ switch (type) {
+ case V8ClassIndex::CONSOLE:
+ setHiddenWindowReference(static_cast<Console*>(impl)->frame(), V8Custom::kDOMWindowConsoleIndex, result);
+ break;
+ case V8ClassIndex::HISTORY:
+ setHiddenWindowReference(static_cast<History*>(impl)->frame(), V8Custom::kDOMWindowHistoryIndex, result);
+ break;
+ case V8ClassIndex::NAVIGATOR:
+ setHiddenWindowReference(static_cast<Navigator*>(impl)->frame(), V8Custom::kDOMWindowNavigatorIndex, result);
+ break;
+ case V8ClassIndex::SCREEN:
+ setHiddenWindowReference(static_cast<Screen*>(impl)->frame(), V8Custom::kDOMWindowScreenIndex, result);
+ break;
+ case V8ClassIndex::LOCATION:
+ setHiddenWindowReference(static_cast<Location*>(impl)->frame(), V8Custom::kDOMWindowLocationIndex, result);
+ break;
+ case V8ClassIndex::DOMSELECTION:
+ setHiddenWindowReference(static_cast<DOMSelection*>(impl)->frame(), V8Custom::kDOMWindowDOMSelectionIndex, result);
+ break;
+ case V8ClassIndex::BARINFO: {
+ BarInfo* barInfo = static_cast<BarInfo*>(impl);
+ Frame* frame = barInfo->frame();
+ switch (barInfo->type()) {
+ case BarInfo::Locationbar:
+ setHiddenWindowReference(frame, V8Custom::kDOMWindowLocationbarIndex, result);
+ break;
+ case BarInfo::Menubar:
+ setHiddenWindowReference(frame, V8Custom::kDOMWindowMenubarIndex, result);
+ break;
+ case BarInfo::Personalbar:
+ setHiddenWindowReference(frame, V8Custom::kDOMWindowPersonalbarIndex, result);
+ break;
+ case BarInfo::Scrollbars:
+ setHiddenWindowReference(frame, V8Custom::kDOMWindowScrollbarsIndex, result);
+ break;
+ case BarInfo::Statusbar:
+ setHiddenWindowReference(frame, V8Custom::kDOMWindowStatusbarIndex, result);
+ break;
+ case BarInfo::Toolbar:
+ setHiddenWindowReference(frame, V8Custom::kDOMWindowToolbarIndex, result);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+void V8DOMWrapper::setHiddenWindowReference(Frame* frame, const int internalIndex, v8::Handle<v8::Object> jsObject)
+{
+ // Get DOMWindow
+ if (!frame)
+ return; // Object might be detached from window
+ v8::Handle<v8::Context> context = V8Proxy::context(frame);
+ if (context.IsEmpty())
+ return;
+
+ ASSERT(internalIndex < V8Custom::kDOMWindowInternalFieldCount);
+
+ v8::Handle<v8::Object> global = context->Global();
+ // Look for real DOM wrapper.
+ global = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, global);
+ ASSERT(!global.IsEmpty());
+ ASSERT(global->GetInternalField(internalIndex)->IsUndefined());
+ global->SetInternalField(internalIndex, jsObject);
+}
+
+V8ClassIndex::V8WrapperType V8DOMWrapper::domWrapperType(v8::Handle<v8::Object> object)
+{
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
+ v8::Handle<v8::Value> type = object->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ return V8ClassIndex::FromInt(type->Int32Value());
+}
+
+void* V8DOMWrapper::convertToSVGPODTypeImpl(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object)
+{
+ return isWrapperOfType(object, type) ? convertDOMWrapperToNative<void>(v8::Handle<v8::Object>::Cast(object)) : 0;
+}
+
+PassRefPtr<NodeFilter> V8DOMWrapper::wrapNativeNodeFilter(v8::Handle<v8::Value> filter)
+{
+ // A NodeFilter is used when walking through a DOM tree or iterating tree
+ // nodes.
+ // FIXME: we may want to cache NodeFilterCondition and NodeFilter
+ // object, but it is minor.
+ // NodeFilter is passed to NodeIterator that has a ref counted pointer
+ // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition.
+ // In NodeFilterCondition, filter object is persisted in its constructor,
+ // and disposed in its destructor.
+ if (!filter->IsFunction())
+ return 0;
+
+ NodeFilterCondition* condition = new V8NodeFilterCondition(filter);
+ return NodeFilter::create(condition);
+}
+
+v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassIndex::V8WrapperType descriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl)
+{
+ // Make a special case for document.all
+ if (descriptorType == V8ClassIndex::HTMLCOLLECTION && static_cast<HTMLCollection*>(impl)->type() == DocAll)
+ descriptorType = V8ClassIndex::HTMLALLCOLLECTION;
+
+ if (V8IsolatedWorld::getEntered()) {
+ // This effectively disables the wrapper cache for isolated worlds.
+ proxy = 0;
+ // FIXME: Do we need a wrapper cache for the isolated world? We should
+ // see if the performance gains are worth while.
+ } else if (!proxy)
+ proxy = V8Proxy::retrieve();
+
+ v8::Local<v8::Object> instance;
+ if (proxy)
+ instance = proxy->createWrapperFromCache(descriptorType);
+ else {
+ v8::Local<v8::Function> function = getTemplate(descriptorType)->GetFunction();
+ instance = SafeAllocation::newInstance(function);
+ }
+ if (!instance.IsEmpty()) {
+ // Avoid setting the DOM wrapper for failed allocations.
+ setDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl);
+ }
+ return instance;
+}
+
+void V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object> object, int type, void* cptr)
+{
+ ASSERT(object->InternalFieldCount() >= 2);
+ object->SetPointerInInternalField(V8Custom::kDOMWrapperObjectIndex, cptr);
+ object->SetInternalField(V8Custom::kDOMWrapperTypeIndex, v8::Integer::New(type));
+}
+
+#ifndef NDEBUG
+bool V8DOMWrapper::maybeDOMWrapper(v8::Handle<v8::Value> value)
+{
+ if (value.IsEmpty() || !value->IsObject())
+ return false;
+
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ if (!object->InternalFieldCount())
+ return false;
+
+ ASSERT(object->InternalFieldCount() >= V8Custom::kDefaultWrapperInternalFieldCount);
+
+ v8::Handle<v8::Value> type = object->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ ASSERT(type->IsInt32());
+ ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
+
+ v8::Handle<v8::Value> wrapper = object->GetInternalField(V8Custom::kDOMWrapperObjectIndex);
+ ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
+
+ return true;
+}
+#endif
+
+bool V8DOMWrapper::isDOMEventWrapper(v8::Handle<v8::Value> value)
+{
+ // All kinds of events use EVENT as dom type in JS wrappers.
+ // See EventToV8Object
+ return isWrapperOfType(value, V8ClassIndex::EVENT);
+}
+
+bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, V8ClassIndex::V8WrapperType classType)
+{
+ if (value.IsEmpty() || !value->IsObject())
+ return false;
+
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
+ if (!object->InternalFieldCount())
+ return false;
+
+ ASSERT(object->InternalFieldCount() >= V8Custom::kDefaultWrapperInternalFieldCount);
+
+ v8::Handle<v8::Value> wrapper = object->GetInternalField(V8Custom::kDOMWrapperObjectIndex);
+ ASSERT(wrapper->IsNumber() || wrapper->IsExternal());
+
+ v8::Handle<v8::Value> type = object->GetInternalField(V8Custom::kDOMWrapperTypeIndex);
+ ASSERT(type->IsInt32());
+ ASSERT(V8ClassIndex::INVALID_CLASS_INDEX < type->Int32Value() && type->Int32Value() < V8ClassIndex::CLASSINDEX_END);
+
+ return V8ClassIndex::FromInt(type->Int32Value()) == classType;
+}
+
+#if ENABLE(VIDEO)
+#define FOR_EACH_VIDEO_TAG(macro) \
+ macro(audio, AUDIO) \
+ macro(source, SOURCE) \
+ macro(video, VIDEO)
+#else
+#define FOR_EACH_VIDEO_TAG(macro)
+#endif
+
+#if ENABLE(DATAGRID)
+#define FOR_EACH_DATAGRID_TAG(macro) \
+ macro(datagrid, DATAGRID) \
+ macro(dcell, DATAGRIDCELL) \
+ macro(dcol, DATAGRIDCOL) \
+ macro(drow, DATAGRIDROW)
+#else
+#define FOR_EACH_DATAGRID_TAG(macro)
+#endif
+
+#define FOR_EACH_TAG(macro) \
+ FOR_EACH_DATAGRID_TAG(macro) \
+ macro(a, ANCHOR) \
+ macro(applet, APPLET) \
+ macro(area, AREA) \
+ macro(base, BASE) \
+ macro(basefont, BASEFONT) \
+ macro(blockquote, BLOCKQUOTE) \
+ macro(body, BODY) \
+ macro(br, BR) \
+ macro(button, BUTTON) \
+ macro(caption, TABLECAPTION) \
+ macro(col, TABLECOL) \
+ macro(colgroup, TABLECOL) \
+ macro(del, MOD) \
+ macro(canvas, CANVAS) \
+ macro(dir, DIRECTORY) \
+ macro(div, DIV) \
+ macro(dl, DLIST) \
+ macro(embed, EMBED) \
+ macro(fieldset, FIELDSET) \
+ macro(font, FONT) \
+ macro(form, FORM) \
+ macro(frame, FRAME) \
+ macro(frameset, FRAMESET) \
+ macro(h1, HEADING) \
+ macro(h2, HEADING) \
+ macro(h3, HEADING) \
+ macro(h4, HEADING) \
+ macro(h5, HEADING) \
+ macro(h6, HEADING) \
+ macro(head, HEAD) \
+ macro(hr, HR) \
+ macro(html, HTML) \
+ macro(img, IMAGE) \
+ macro(iframe, IFRAME) \
+ macro(image, IMAGE) \
+ macro(input, INPUT) \
+ macro(ins, MOD) \
+ macro(isindex, ISINDEX) \
+ macro(keygen, SELECT) \
+ macro(label, LABEL) \
+ macro(legend, LEGEND) \
+ macro(li, LI) \
+ macro(link, LINK) \
+ macro(listing, PRE) \
+ macro(map, MAP) \
+ macro(marquee, MARQUEE) \
+ macro(menu, MENU) \
+ macro(meta, META) \
+ macro(object, OBJECT) \
+ macro(ol, OLIST) \
+ macro(optgroup, OPTGROUP) \
+ macro(option, OPTION) \
+ macro(p, PARAGRAPH) \
+ macro(param, PARAM) \
+ macro(pre, PRE) \
+ macro(q, QUOTE) \
+ macro(script, SCRIPT) \
+ macro(select, SELECT) \
+ macro(style, STYLE) \
+ macro(table, TABLE) \
+ macro(thead, TABLESECTION) \
+ macro(tbody, TABLESECTION) \
+ macro(tfoot, TABLESECTION) \
+ macro(td, TABLECELL) \
+ macro(th, TABLECELL) \
+ macro(tr, TABLEROW) \
+ macro(textarea, TEXTAREA) \
+ macro(title, TITLE) \
+ macro(ul, ULIST) \
+ macro(xmp, PRE)
+
+V8ClassIndex::V8WrapperType V8DOMWrapper::htmlElementType(HTMLElement* element)
+{
+ typedef HashMap<String, V8ClassIndex::V8WrapperType> WrapperTypeMap;
+ DEFINE_STATIC_LOCAL(WrapperTypeMap, wrapperTypeMap, ());
+ if (wrapperTypeMap.isEmpty()) {
+#define ADD_TO_HASH_MAP(tag, name) \
+ wrapperTypeMap.set(#tag, V8ClassIndex::HTML##name##ELEMENT);
+ FOR_EACH_TAG(ADD_TO_HASH_MAP)
+#if ENABLE(VIDEO)
+ if (MediaPlayer::isAvailable()) {
+ FOR_EACH_VIDEO_TAG(ADD_TO_HASH_MAP)
+ }
+#endif
+#undef ADD_TO_HASH_MAP
+ }
+
+ V8ClassIndex::V8WrapperType type = wrapperTypeMap.get(element->localName().impl());
+ if (!type)
+ return V8ClassIndex::HTMLELEMENT;
+ return type;
+}
+#undef FOR_EACH_TAG
+
+#if ENABLE(SVG)
+
+#if ENABLE(SVG_ANIMATION)
+#define FOR_EACH_ANIMATION_TAG(macro) \
+ macro(animateColor, ANIMATECOLOR) \
+ macro(animate, ANIMATE) \
+ macro(animateTransform, ANIMATETRANSFORM) \
+ macro(set, SET)
+#else
+#define FOR_EACH_ANIMATION_TAG(macro)
+#endif
+
+#if ENABLE(SVG_FILTERS)
+#define FOR_EACH_FILTERS_TAG(macro) \
+ macro(feBlend, FEBLEND) \
+ macro(feColorMatrix, FECOLORMATRIX) \
+ macro(feComponentTransfer, FECOMPONENTTRANSFER) \
+ macro(feComposite, FECOMPOSITE) \
+ macro(feDiffuseLighting, FEDIFFUSELIGHTING) \
+ macro(feDisplacementMap, FEDISPLACEMENTMAP) \
+ macro(feDistantLight, FEDISTANTLIGHT) \
+ macro(feFlood, FEFLOOD) \
+ macro(feFuncA, FEFUNCA) \
+ macro(feFuncB, FEFUNCB) \
+ macro(feFuncG, FEFUNCG) \
+ macro(feFuncR, FEFUNCR) \
+ macro(feGaussianBlur, FEGAUSSIANBLUR) \
+ macro(feImage, FEIMAGE) \
+ macro(feMerge, FEMERGE) \
+ macro(feMergeNode, FEMERGENODE) \
+ macro(feOffset, FEOFFSET) \
+ macro(fePointLight, FEPOINTLIGHT) \
+ macro(feSpecularLighting, FESPECULARLIGHTING) \
+ macro(feSpotLight, FESPOTLIGHT) \
+ macro(feTile, FETILE) \
+ macro(feTurbulence, FETURBULENCE) \
+ macro(filter, FILTER)
+#else
+#define FOR_EACH_FILTERS_TAG(macro)
+#endif
+
+#if ENABLE(SVG_FONTS)
+#define FOR_EACH_FONTS_TAG(macro) \
+ macro(definition-src, DEFINITIONSRC) \
+ macro(font-face, FONTFACE) \
+ macro(font-face-format, FONTFACEFORMAT) \
+ macro(font-face-name, FONTFACENAME) \
+ macro(font-face-src, FONTFACESRC) \
+ macro(font-face-uri, FONTFACEURI)
+#else
+#define FOR_EACH_FONTS_TAG(marco)
+#endif
+
+#if ENABLE(SVG_FOREIGN_OBJECT)
+#define FOR_EACH_FOREIGN_OBJECT_TAG(macro) \
+ macro(foreignObject, FOREIGNOBJECT)
+#else
+#define FOR_EACH_FOREIGN_OBJECT_TAG(macro)
+#endif
+
+#if ENABLE(SVG_USE)
+#define FOR_EACH_USE_TAG(macro) \
+ macro(use, USE)
+#else
+#define FOR_EACH_USE_TAG(macro)
+#endif
+
+#define FOR_EACH_TAG(macro) \
+ FOR_EACH_ANIMATION_TAG(macro) \
+ FOR_EACH_FILTERS_TAG(macro) \
+ FOR_EACH_FONTS_TAG(macro) \
+ FOR_EACH_FOREIGN_OBJECT_TAG(macro) \
+ FOR_EACH_USE_TAG(macro) \
+ macro(a, A) \
+ macro(altGlyph, ALTGLYPH) \
+ macro(circle, CIRCLE) \
+ macro(clipPath, CLIPPATH) \
+ macro(cursor, CURSOR) \
+ macro(defs, DEFS) \
+ macro(desc, DESC) \
+ macro(ellipse, ELLIPSE) \
+ macro(g, G) \
+ macro(glyph, GLYPH) \
+ macro(image, IMAGE) \
+ macro(linearGradient, LINEARGRADIENT) \
+ macro(line, LINE) \
+ macro(marker, MARKER) \
+ macro(mask, MASK) \
+ macro(metadata, METADATA) \
+ macro(path, PATH) \
+ macro(pattern, PATTERN) \
+ macro(polyline, POLYLINE) \
+ macro(polygon, POLYGON) \
+ macro(radialGradient, RADIALGRADIENT) \
+ macro(rect, RECT) \
+ macro(script, SCRIPT) \
+ macro(stop, STOP) \
+ macro(style, STYLE) \
+ macro(svg, SVG) \
+ macro(switch, SWITCH) \
+ macro(symbol, SYMBOL) \
+ macro(text, TEXT) \
+ macro(textPath, TEXTPATH) \
+ macro(title, TITLE) \
+ macro(tref, TREF) \
+ macro(tspan, TSPAN) \
+ macro(view, VIEW) \
+ // end of macro
+
+V8ClassIndex::V8WrapperType V8DOMWrapper::svgElementType(SVGElement* element)
+{
+ typedef HashMap<String, V8ClassIndex::V8WrapperType> WrapperTypeMap;
+ DEFINE_STATIC_LOCAL(WrapperTypeMap, wrapperTypeMap, ());
+ if (wrapperTypeMap.isEmpty()) {
+#define ADD_TO_HASH_MAP(tag, name) \
+ wrapperTypeMap.set(#tag, V8ClassIndex::SVG##name##ELEMENT);
+ FOR_EACH_TAG(ADD_TO_HASH_MAP)
+#undef ADD_TO_HASH_MAP
+ }
+
+ V8ClassIndex::V8WrapperType type = wrapperTypeMap.get(element->localName().impl());
+ if (!type)
+ return V8ClassIndex::SVGELEMENT;
+ return type;
+}
+#undef FOR_EACH_TAG
+
+#endif // ENABLE(SVG)
+
+v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event)
+{
+ if (!event)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(event);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::EVENT;
+
+ if (event->isUIEvent()) {
+ if (event->isKeyboardEvent())
+ type = V8ClassIndex::KEYBOARDEVENT;
+ else if (event->isTextEvent())
+ type = V8ClassIndex::TEXTEVENT;
+ else if (event->isMouseEvent())
+ type = V8ClassIndex::MOUSEEVENT;
+ else if (event->isWheelEvent())
+ type = V8ClassIndex::WHEELEVENT;
+#if ENABLE(SVG)
+ else if (event->isSVGZoomEvent())
+ type = V8ClassIndex::SVGZOOMEVENT;
+#endif
+ else
+ type = V8ClassIndex::UIEVENT;
+ } else if (event->isMutationEvent())
+ type = V8ClassIndex::MUTATIONEVENT;
+ else if (event->isOverflowEvent())
+ type = V8ClassIndex::OVERFLOWEVENT;
+ else if (event->isMessageEvent())
+ type = V8ClassIndex::MESSAGEEVENT;
+ else if (event->isProgressEvent()) {
+ if (event->isXMLHttpRequestProgressEvent())
+ type = V8ClassIndex::XMLHTTPREQUESTPROGRESSEVENT;
+ else
+ type = V8ClassIndex::PROGRESSEVENT;
+ } else if (event->isWebKitAnimationEvent())
+ type = V8ClassIndex::WEBKITANIMATIONEVENT;
+ else if (event->isWebKitTransitionEvent())
+ type = V8ClassIndex::WEBKITTRANSITIONEVENT;
+#if ENABLE(WORKERS)
+ else if (event->isErrorEvent())
+ type = V8ClassIndex::ERROREVENT;
+#endif
+
+
+ v8::Handle<v8::Object> result = instantiateV8Object(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
+ setJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result));
+
+ return result;
+}
+
+static const V8ClassIndex::V8WrapperType mapping[] = {
+ V8ClassIndex::INVALID_CLASS_INDEX, // NONE
+ V8ClassIndex::INVALID_CLASS_INDEX, // ELEMENT_NODE needs special treatment
+ V8ClassIndex::ATTR, // ATTRIBUTE_NODE
+ V8ClassIndex::TEXT, // TEXT_NODE
+ V8ClassIndex::CDATASECTION, // CDATA_SECTION_NODE
+ V8ClassIndex::ENTITYREFERENCE, // ENTITY_REFERENCE_NODE
+ V8ClassIndex::ENTITY, // ENTITY_NODE
+ V8ClassIndex::PROCESSINGINSTRUCTION, // PROCESSING_INSTRUCTION_NODE
+ V8ClassIndex::COMMENT, // COMMENT_NODE
+ V8ClassIndex::INVALID_CLASS_INDEX, // DOCUMENT_NODE needs special treatment
+ V8ClassIndex::DOCUMENTTYPE, // DOCUMENT_TYPE_NODE
+ V8ClassIndex::DOCUMENTFRAGMENT, // DOCUMENT_FRAGMENT_NODE
+ V8ClassIndex::NOTATION, // NOTATION_NODE
+ V8ClassIndex::NODE, // XPATH_NAMESPACE_NODE
+};
+
+// Caller checks node is not null.
+v8::Handle<v8::Value> V8DOMWrapper::convertNodeToV8Object(Node* node)
+{
+ if (!node)
+ return v8::Null();
+
+ // Find a proxy for this node.
+ //
+ // Note that if proxy is found, we might initialize the context which can
+ // instantiate a document wrapper. Therefore, we get the proxy before
+ // checking if the node already has a wrapper.
+ V8Proxy* proxy = 0;
+ Document* document = node->document();
+ if (document) {
+ Frame* frame = document->frame();
+ proxy = V8Proxy::retrieve(frame);
+ if (proxy)
+ proxy->initContextIfNeeded();
+ }
+
+ DOMWrapperMap<Node>& domNodeMap = getDOMNodeMap();
+ v8::Handle<v8::Object> wrapper = domNodeMap.get(node);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ bool isDocument = false; // document type node has special handling
+ V8ClassIndex::V8WrapperType type;
+
+ Node::NodeType nodeType = node->nodeType();
+ if (nodeType == Node::ELEMENT_NODE) {
+ if (node->isHTMLElement())
+ type = htmlElementType(static_cast<HTMLElement*>(node));
+#if ENABLE(SVG)
+ else if (node->isSVGElement())
+ type = svgElementType(static_cast<SVGElement*>(node));
+#endif
+ else
+ type = V8ClassIndex::ELEMENT;
+ } else if (nodeType == Node::DOCUMENT_NODE) {
+ isDocument = true;
+ Document* document = static_cast<Document*>(node);
+ if (document->isHTMLDocument())
+ type = V8ClassIndex::HTMLDOCUMENT;
+#if ENABLE(SVG)
+ else if (document->isSVGDocument())
+ type = V8ClassIndex::SVGDOCUMENT;
+#endif
+ else
+ type = V8ClassIndex::DOCUMENT;
+ } else {
+ ASSERT(nodeType < sizeof(mapping)/sizeof(mapping[0]));
+ type = mapping[nodeType];
+ ASSERT(type != V8ClassIndex::INVALID_CLASS_INDEX);
+ }
+
+ v8::Handle<v8::Context> context;
+ if (proxy)
+ context = V8Proxy::context(proxy->frame());
+
+ // Enter the node's context and create the wrapper in that context.
+ if (!context.IsEmpty())
+ context->Enter();
+
+ v8::Local<v8::Object> result = instantiateV8Object(proxy, type, V8ClassIndex::NODE, node);
+
+ // Exit the node's context if it was entered.
+ if (!context.IsEmpty())
+ context->Exit();
+
+ if (result.IsEmpty()) {
+ // If instantiation failed it's important not to add the result
+ // to the DOM node map. Instead we return an empty handle, which
+ // should already be handled by callers of this function in case
+ // the node is NULL.
+ return result;
+ }
+
+ node->ref();
+ domNodeMap.set(node, v8::Persistent<v8::Object>::New(result));
+
+ if (isDocument) {
+ if (proxy)
+ proxy->updateDocumentWrapper(result);
+
+ if (type == V8ClassIndex::HTMLDOCUMENT) {
+ // Create marker object and insert it in two internal fields.
+ // This is used to implement temporary shadowing of
+ // document.all.
+ ASSERT(result->InternalFieldCount() == V8Custom::kHTMLDocumentInternalFieldCount);
+ v8::Local<v8::Object> marker = v8::Object::New();
+ result->SetInternalField(V8Custom::kHTMLDocumentMarkerIndex, marker);
+ result->SetInternalField(V8Custom::kHTMLDocumentShadowIndex, marker);
+ }
+ }
+
+ return result;
+}
+
+// A JS object of type EventTarget is limited to a small number of possible classes.
+// Check EventTarget.h for new type conversion methods
+v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* target)
+{
+ if (!target)
+ return v8::Null();
+
+#if ENABLE(SVG)
+ SVGElementInstance* instance = target->toSVGElementInstance();
+ if (instance)
+ return convertToV8Object(V8ClassIndex::SVGELEMENTINSTANCE, instance);
+#endif
+
+#if ENABLE(WORKERS)
+ Worker* worker = target->toWorker();
+ if (worker)
+ return convertToV8Object(V8ClassIndex::WORKER, worker);
+#endif // WORKERS
+
+ Node* node = target->toNode();
+ if (node)
+ return convertNodeToV8Object(node);
+
+ if (DOMWindow* domWindow = target->toDOMWindow())
+ return convertToV8Object(V8ClassIndex::DOMWINDOW, domWindow);
+
+ // XMLHttpRequest is created within its JS counterpart.
+ XMLHttpRequest* xmlHttpRequest = target->toXMLHttpRequest();
+ if (xmlHttpRequest) {
+ v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(xmlHttpRequest);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+ }
+
+ // MessagePort is created within its JS counterpart
+ MessagePort* port = target->toMessagePort();
+ if (port) {
+ v8::Handle<v8::Object> wrapper = getActiveDOMObjectMap().get(port);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+ }
+
+ XMLHttpRequestUpload* upload = target->toXMLHttpRequestUpload();
+ if (upload) {
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(upload);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+ }
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ DOMApplicationCache* domAppCache = target->toDOMApplicationCache();
+ if (domAppCache)
+ return convertToV8Object(V8ClassIndex::DOMAPPLICATIONCACHE, domAppCache);
+#endif
+
+ ASSERT(0);
+ return notHandledByInterceptor();
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(EventListener* listener)
+{
+ if (!listener)
+ return v8::Null();
+
+ // FIXME: can a user take a lazy event listener and set to other places?
+ V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListener*>(listener);
+ return v8listener->getListenerObject();
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertDOMImplementationToV8Object(DOMImplementation* impl)
+{
+ v8::Handle<v8::Object> result = instantiateV8Object(V8ClassIndex::DOMIMPLEMENTATION, V8ClassIndex::DOMIMPLEMENTATION, impl);
+ if (result.IsEmpty()) {
+ // If the instantiation failed, we ignore it and return null instead
+ // of returning an empty handle.
+ return v8::Null();
+ }
+ return result;
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertStyleSheetToV8Object(StyleSheet* sheet)
+{
+ if (!sheet)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(sheet);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type = V8ClassIndex::STYLESHEET;
+ if (sheet->isCSSStyleSheet())
+ type = V8ClassIndex::CSSSTYLESHEET;
+
+ v8::Handle<v8::Object> result = instantiateV8Object(type, V8ClassIndex::STYLESHEET, sheet);
+ if (!result.IsEmpty()) {
+ // Only update the DOM object map if the result is non-empty.
+ sheet->ref();
+ setJSWrapperForDOMObject(sheet, v8::Persistent<v8::Object>::New(result));
+ }
+
+ // Add a hidden reference from stylesheet object to its owner node.
+ Node* ownerNode = sheet->ownerNode();
+ if (ownerNode) {
+ v8::Handle<v8::Object> owner = v8::Handle<v8::Object>::Cast(convertNodeToV8Object(ownerNode));
+ result->SetInternalField(V8Custom::kStyleSheetOwnerNodeIndex, owner);
+ }
+
+ return result;
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertCSSValueToV8Object(CSSValue* value)
+{
+ if (!value)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(value);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type;
+
+ if (value->isWebKitCSSTransformValue())
+ type = V8ClassIndex::WEBKITCSSTRANSFORMVALUE;
+ else if (value->isValueList())
+ type = V8ClassIndex::CSSVALUELIST;
+ else if (value->isPrimitiveValue())
+ type = V8ClassIndex::CSSPRIMITIVEVALUE;
+#if ENABLE(SVG)
+ else if (value->isSVGPaint())
+ type = V8ClassIndex::SVGPAINT;
+ else if (value->isSVGColor())
+ type = V8ClassIndex::SVGCOLOR;
+#endif
+ else
+ type = V8ClassIndex::CSSVALUE;
+
+ v8::Handle<v8::Object> result = instantiateV8Object(type, V8ClassIndex::CSSVALUE, value);
+ if (!result.IsEmpty()) {
+ // Only update the DOM object map if the result is non-empty.
+ value->ref();
+ setJSWrapperForDOMObject(value, v8::Persistent<v8::Object>::New(result));
+ }
+
+ return result;
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertCSSRuleToV8Object(CSSRule* rule)
+{
+ if (!rule)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(rule);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ V8ClassIndex::V8WrapperType type;
+
+ switch (rule->type()) {
+ case CSSRule::STYLE_RULE:
+ type = V8ClassIndex::CSSSTYLERULE;
+ break;
+ case CSSRule::CHARSET_RULE:
+ type = V8ClassIndex::CSSCHARSETRULE;
+ break;
+ case CSSRule::IMPORT_RULE:
+ type = V8ClassIndex::CSSIMPORTRULE;
+ break;
+ case CSSRule::MEDIA_RULE:
+ type = V8ClassIndex::CSSMEDIARULE;
+ break;
+ case CSSRule::FONT_FACE_RULE:
+ type = V8ClassIndex::CSSFONTFACERULE;
+ break;
+ case CSSRule::PAGE_RULE:
+ type = V8ClassIndex::CSSPAGERULE;
+ break;
+ case CSSRule::VARIABLES_RULE:
+ type = V8ClassIndex::CSSVARIABLESRULE;
+ break;
+ case CSSRule::WEBKIT_KEYFRAME_RULE:
+ type = V8ClassIndex::WEBKITCSSKEYFRAMERULE;
+ break;
+ case CSSRule::WEBKIT_KEYFRAMES_RULE:
+ type = V8ClassIndex::WEBKITCSSKEYFRAMESRULE;
+ break;
+ default: // CSSRule::UNKNOWN_RULE
+ type = V8ClassIndex::CSSRULE;
+ break;
+ }
+
+ v8::Handle<v8::Object> result = instantiateV8Object(type, V8ClassIndex::CSSRULE, rule);
+ if (!result.IsEmpty()) {
+ // Only update the DOM object map if the result is non-empty.
+ rule->ref();
+ setJSWrapperForDOMObject(rule, v8::Persistent<v8::Object>::New(result));
+ }
+ return result;
+}
+
+v8::Handle<v8::Value> V8DOMWrapper::convertWindowToV8Object(DOMWindow* window)
+{
+ if (!window)
+ return v8::Null();
+ // Initializes environment of a frame, and return the global object
+ // of the frame.
+ Frame* frame = window->frame();
+ if (!frame)
+ return v8::Handle<v8::Object>();
+
+ // Special case: Because of evaluateInNewContext() one DOMWindow can have
+ // multiple contexts and multiple global objects associated with it. When
+ // code running in one of those contexts accesses the window object, we
+ // want to return the global object associated with that context, not
+ // necessarily the first global object associated with that DOMWindow.
+ v8::Handle<v8::Context> currentContext = v8::Context::GetCurrent();
+ v8::Handle<v8::Object> currentGlobal = currentContext->Global();
+ v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, currentGlobal);
+ if (!windowWrapper.IsEmpty()) {
+ if (convertDOMWrapperToNative<DOMWindow>(windowWrapper) == window)
+ return currentGlobal;
+ }
+
+ // Otherwise, return the global object associated with this frame.
+ v8::Handle<v8::Context> context = V8Proxy::context(frame);
+ if (context.IsEmpty())
+ return v8::Handle<v8::Object>();
+
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ return global;
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
new file mode 100644
index 0000000..57b3a69
--- /dev/null
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -0,0 +1,260 @@
+/*
+ * 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 V8DOMWrapper_h
+#define V8DOMWrapper_h
+
+#include "Event.h"
+#include "Node.h"
+#include "NodeFilter.h"
+#include "PlatformString.h" // for WebCore::String
+#include "V8CustomBinding.h"
+#include "V8Index.h"
+#include "V8Utilities.h"
+#include <v8.h>
+
+namespace WebCore {
+
+ // FIXME: This probably aren't all needed.
+ class CSSRule;
+ class CSSRuleList;
+ class CSSStyleDeclaration;
+ class CSSValue;
+ class CSSValueList;
+ class ClientRectList;
+ class DOMImplementation;
+ class DOMWindow;
+ class Document;
+ class Element;
+ class Event;
+ class EventListener;
+ class EventTarget;
+ class Frame;
+ class HTMLCollection;
+ class HTMLDocument;
+ class HTMLElement;
+ class HTMLOptionsCollection;
+ class MediaList;
+ class MimeType;
+ class MimeTypeArray;
+ class NamedNodeMap;
+ class Navigator;
+ class Node;
+ class NodeFilter;
+ class NodeList;
+ class Plugin;
+ class PluginArray;
+ class SVGElement;
+#if ENABLE(SVG)
+ class SVGElementInstance;
+#endif
+ class Screen;
+ class ScriptExecutionContext;
+#if ENABLE(DOM_STORAGE)
+ class Storage;
+ class StorageEvent;
+#endif
+ class String;
+ class StyleSheet;
+ class StyleSheetList;
+ class V8EventListener;
+ class V8ObjectEventListener;
+ class WorkerContext;
+
+ class V8DOMWrapper {
+ public:
+#ifndef NDEBUG
+ // Checks if a v8 value can be a DOM wrapper
+ static bool maybeDOMWrapper(v8::Handle<v8::Value>);
+#endif
+
+ // Sets contents of a DOM wrapper.
+ static void setDOMWrapper(v8::Handle<v8::Object>, int type, void* ptr);
+
+ static v8::Handle<v8::Object> lookupDOMWrapper(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Object> object)
+ {
+ return object.IsEmpty() ? object : object->FindInstanceInPrototypeChain(getTemplate(type));
+ }
+
+ // A helper function extract native object pointer from a DOM wrapper
+ // and cast to the specified type.
+ template <class C>
+ static C* convertDOMWrapperToNative(v8::Handle<v8::Object> object)
+ {
+ ASSERT(maybeDOMWrapper(object));
+ return reinterpret_cast<C*>(object->GetPointerFromInternalField(V8Custom::kDOMWrapperObjectIndex));
+ }
+
+ template <class C>
+ static C* convertDOMWrapperToNode(v8::Handle<v8::Object> object)
+ {
+ ASSERT(maybeDOMWrapper(object));
+ ASSERT(domWrapperType(object) == V8ClassIndex::NODE);
+ return convertDOMWrapperToNative<C>(object);
+ }
+
+ template<typename T>
+ static v8::Handle<v8::Value> convertToV8Object(V8ClassIndex::V8WrapperType type, PassRefPtr<T> imp)
+ {
+ return convertToV8Object(type, imp.get());
+ }
+
+ static v8::Handle<v8::Value> convertToV8Object(V8ClassIndex::V8WrapperType, void*);
+
+ // Fast-path for Node objects.
+ static v8::Handle<v8::Value> convertNodeToV8Object(PassRefPtr<Node> node)
+ {
+ return convertNodeToV8Object(node.get());
+ }
+
+ static v8::Handle<v8::Value> convertNodeToV8Object(Node*);
+
+ template <class C>
+ static C* convertToNativeObject(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Object> object)
+ {
+ // Native event listener is per frame, it cannot be handled by this generic function.
+ ASSERT(type != V8ClassIndex::EVENTLISTENER);
+ ASSERT(type != V8ClassIndex::EVENTTARGET);
+
+ ASSERT(maybeDOMWrapper(object));
+
+#ifndef NDEBUG
+ const bool typeIsValid =
+#define MAKE_CASE(TYPE, NAME) (type != V8ClassIndex::TYPE) &&
+ DOM_NODE_TYPES(MAKE_CASE)
+#if ENABLE(SVG)
+ SVG_NODE_TYPES(MAKE_CASE)
+#endif
+#undef MAKE_CASE
+ true;
+ ASSERT(typeIsValid);
+#endif
+
+ return convertDOMWrapperToNative<C>(object);
+ }
+
+ static V8ClassIndex::V8WrapperType domWrapperType(v8::Handle<v8::Object>);
+
+ static v8::Handle<v8::Value> convertEventToV8Object(PassRefPtr<Event> event)
+ {
+ return convertEventToV8Object(event.get());
+ }
+
+ static v8::Handle<v8::Value> convertEventToV8Object(Event*);
+
+ static Event* convertToNativeEvent(v8::Handle<v8::Value> jsEvent)
+ {
+ if (!isDOMEventWrapper(jsEvent))
+ return 0;
+ return convertDOMWrapperToNative<Event>(v8::Handle<v8::Object>::Cast(jsEvent));
+ }
+
+ static v8::Handle<v8::Value> convertEventTargetToV8Object(PassRefPtr<EventTarget> eventTarget)
+ {
+ return convertEventTargetToV8Object(eventTarget.get());
+ }
+
+ static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*);
+
+ // Wrap and unwrap JS event listeners.
+ static v8::Handle<v8::Value> convertEventListenerToV8Object(PassRefPtr<Event> eventListener)
+ {
+ return convertEventListenerToV8Object(eventListener.get());
+ }
+
+ static v8::Handle<v8::Value> convertEventListenerToV8Object(EventListener*);
+
+ // DOMImplementation is a singleton and it is handled in a special
+ // way. A wrapper is generated per document and stored in an
+ // internal field of the document.
+ static v8::Handle<v8::Value> convertDOMImplementationToV8Object(DOMImplementation*);
+
+ // Wrap JS node filter in C++.
+ static PassRefPtr<NodeFilter> wrapNativeNodeFilter(v8::Handle<v8::Value>);
+
+ static v8::Persistent<v8::FunctionTemplate> getTemplate(V8ClassIndex::V8WrapperType);
+ static v8::Local<v8::Function> getConstructorForContext(V8ClassIndex::V8WrapperType, v8::Handle<v8::Context>);
+ static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, v8::Handle<v8::Value> objectPrototype);
+ static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, DOMWindow*);
+ static v8::Local<v8::Function> getConstructor(V8ClassIndex::V8WrapperType, WorkerContext*);
+
+ // Checks whether a DOM object has a JS wrapper.
+ static bool domObjectHasJSWrapper(void*);
+ // Set JS wrapper of a DOM object, the caller in charge of increase ref.
+ static void setJSWrapperForDOMObject(void*, v8::Persistent<v8::Object>);
+ static void setJSWrapperForActiveDOMObject(void*, v8::Persistent<v8::Object>);
+ static void setJSWrapperForDOMNode(Node*, v8::Persistent<v8::Object>);
+
+ // Check whether a V8 value is a wrapper of type |classType|.
+ static bool isWrapperOfType(v8::Handle<v8::Value>, V8ClassIndex::V8WrapperType);
+
+ static void* convertToSVGPODTypeImpl(V8ClassIndex::V8WrapperType, v8::Handle<v8::Value>);
+
+ // Check whether a V8 value is a DOM Event wrapper.
+ static bool isDOMEventWrapper(v8::Handle<v8::Value>);
+
+ static v8::Handle<v8::Value> convertStyleSheetToV8Object(StyleSheet*);
+ static v8::Handle<v8::Value> convertCSSValueToV8Object(CSSValue*);
+ static v8::Handle<v8::Value> convertCSSRuleToV8Object(CSSRule*);
+ // Returns the JS wrapper of a window object, initializes the environment
+ // of the window frame if needed.
+ static v8::Handle<v8::Value> convertWindowToV8Object(DOMWindow*);
+
+#if ENABLE(SVG)
+ static v8::Handle<v8::Value> convertSVGElementInstanceToV8Object(SVGElementInstance*);
+ static v8::Handle<v8::Value> convertSVGObjectWithContextToV8Object(V8ClassIndex::V8WrapperType, void*);
+#endif
+
+ private:
+ // Set hidden references in a DOMWindow object of a frame.
+ static void setHiddenWindowReference(Frame*, const int internalIndex, v8::Handle<v8::Object>);
+
+ static V8ClassIndex::V8WrapperType htmlElementType(HTMLElement*);
+#if ENABLE(SVG)
+ static V8ClassIndex::V8WrapperType svgElementType(SVGElement*);
+#endif
+
+ // The first V8WrapperType specifies the function descriptor
+ // used to create JS object. The second V8WrapperType specifies
+ // the actual type of the void* for type casting.
+ // For example, a HTML element has HTMLELEMENT for the first V8WrapperType, but always
+ // use NODE as the second V8WrapperType. JS wrapper stores the second
+ // V8WrapperType and the void* as internal fields.
+ static v8::Local<v8::Object> instantiateV8Object(V8ClassIndex::V8WrapperType descType, V8ClassIndex::V8WrapperType cptrType, void* impl)
+ {
+ return instantiateV8Object(NULL, descType, cptrType, impl);
+ }
+
+ static v8::Local<v8::Object> instantiateV8Object(V8Proxy*, V8ClassIndex::V8WrapperType, V8ClassIndex::V8WrapperType, void*);
+ };
+
+}
+
+#endif // V8DOMWrapper_h
diff --git a/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp b/WebCore/bindings/v8/V8DataGridDataSource.cpp
index 52d4399..6fff1f5 100644
--- a/WebCore/bindings/v8/custom/V8DOMStringListCustom.cpp
+++ b/WebCore/bindings/v8/V8DataGridDataSource.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-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
@@ -29,34 +29,37 @@
*/
#include "config.h"
-#include "DOMStringList.h"
-#include "V8Binding.h"
-#include "V8CustomBinding.h"
-#include "V8Proxy.h"
+#if ENABLE(DATAGRID)
+
+#include "V8DataGridDataSource.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "HTMLDataGridElement.h"
+#include "V8HTMLDataGridElement.h"
+
namespace WebCore {
-INDEXED_PROPERTY_GETTER(DOMStringList)
+V8DataGridDataSource::V8DataGridDataSource(v8::Handle<v8::Value> dataSource, Frame* frame)
+ : m_dataSource(v8::Persistent<v8::Value>::New(dataSource))
+ , m_frame(frame)
{
- INC_STATS("DOM.DOMStringList.IndexedPropertyGetter");
- DOMStringList* imp = V8Proxy::DOMWrapperToNative<DOMStringList>(info.Holder());
- return v8String(imp->item(index));
+#ifndef NDEBUG
+ V8GCController::registerGlobalHandle(DATASOURCE, this, m_dataSource);
+#endif
}
-CALLBACK_FUNC_DECL(DOMStringListItem)
+V8DataGridDataSource::~V8DataGridDataSource()
{
- 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));
+#ifndef NDEBUG
+ V8GCController::unregisterGlobalHandle(this, m_dataSource);
+#endif
+ m_dataSource.Dispose();
+ m_dataSource.Clear();
}
} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/WebCore/bindings/v8/V8DataGridDataSource.h b/WebCore/bindings/v8/V8DataGridDataSource.h
new file mode 100644
index 0000000..7f6d8d8
--- /dev/null
+++ b/WebCore/bindings/v8/V8DataGridDataSource.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 V8DataGridDataSource_h
+#define V8DataGridDataSource_h
+
+#if ENABLE(DATAGRID)
+
+#include "DataGridDataSource.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Frame;
+class HTMLDataGridElement;
+
+class V8DataGridDataSource : public DataGridDataSource {
+public:
+ static PassRefPtr<V8DataGridDataSource> create(v8::Handle<v8::Value> dataSource, Frame* frame)
+ {
+ return adoptRef(new V8DataGridDataSource(dataSource, frame));
+ }
+
+ virtual ~V8DataGridDataSource();
+
+ virtual bool isJSDataGridDataSource() const { return true; }
+ v8::Handle<v8::Value> jsDataSource() const { return m_dataSource; }
+
+private:
+ V8DataGridDataSource(v8::Handle<v8::Value>, Frame*);
+
+ v8::Persistent<v8::Value> m_dataSource;
+ RefPtr<Frame> m_frame;
+};
+
+inline V8DataGridDataSource* asV8DataGridDataSource(DataGridDataSource* dataSource)
+{
+ ASSERT(dataSource->isJSDataGridDataSource());
+ return static_cast<V8DataGridDataSource*>(dataSource);
+}
+
+inline const V8DataGridDataSource* asV8DataGridDataSource(const DataGridDataSource* dataSource)
+{
+ ASSERT(dataSource->isJSDataGridDataSource());
+ return static_cast<const V8DataGridDataSource*>(dataSource);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
+#endif // V8DataGridDataSource_h
diff --git a/WebCore/bindings/v8/V8EventListenerList.cpp b/WebCore/bindings/v8/V8EventListenerList.cpp
index df60028..c9aaa12 100644
--- a/WebCore/bindings/v8/V8EventListenerList.cpp
+++ b/WebCore/bindings/v8/V8EventListenerList.cpp
@@ -182,4 +182,14 @@ V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool is
return 0;
}
+PassRefPtr<V8EventListener> V8EventListenerList::findWrapper(v8::Local<v8::Value> object, bool isAttribute)
+{
+ ASSERT(v8::Context::InContext());
+ if (!object->IsObject())
+ return 0;
+
+ // FIXME: Should this be v8::Local<v8::Object>::Cast instead?
+ return find(object->ToObject(), isAttribute);
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h
index d7799b8..4255050 100644
--- a/WebCore/bindings/v8/V8EventListenerList.h
+++ b/WebCore/bindings/v8/V8EventListenerList.h
@@ -35,7 +35,10 @@
#include <wtf/Vector.h>
#include <wtf/HashMap.h>
+#include "PassRefPtr.h"
+
namespace WebCore {
+ class Frame;
class V8EventListener;
class V8EventListenerListIterator;
@@ -67,6 +70,10 @@ namespace WebCore {
void clear();
size_t size() { return m_table.size(); }
+ PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value>, bool isAttribute);
+ template<typename WrapperType>
+ PassRefPtr<V8EventListener> findOrCreateWrapper(Frame*, v8::Local<v8::Value>, bool isAttribute);
+
private:
ListenerMultiMap m_table;
@@ -93,6 +100,25 @@ namespace WebCore {
size_t m_vectorIndex;
};
+ template<typename WrapperType>
+ PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(Frame* frame, v8::Local<v8::Value> object, bool isAttribute)
+ {
+ ASSERT(v8::Context::InContext());
+ if (!object->IsObject())
+ return 0;
+
+ // FIXME: Should this be v8::Local<v8::Object>::Cast instead?
+ V8EventListener* wrapper = find(object->ToObject(), isAttribute);
+ if (wrapper)
+ return wrapper;
+
+ // Create a new one, and add to cache.
+ RefPtr<WrapperType> newListener = WrapperType::create(frame, v8::Local<v8::Object>::Cast(object), isAttribute);
+ add(newListener.get());
+
+ return newListener;
+ };
+
} // namespace WebCore
#endif // V8EventListenerList_h
diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp
new file mode 100644
index 0000000..1b7c5ad
--- /dev/null
+++ b/WebCore/bindings/v8/V8GCController.cpp
@@ -0,0 +1,442 @@
+/*
+ * 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 "V8GCController.h"
+
+#include "DOMDataStore.h"
+#include "DOMObjectsInclude.h"
+#include "V8DOMMap.h"
+#include "V8Index.h"
+#include "V8Proxy.h"
+
+#include <algorithm>
+#include <utility>
+#include <v8.h>
+#include <v8-debug.h>
+#include <wtf/HashMap.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+#ifndef NDEBUG
+// Keeps track of global handles created (not JS wrappers
+// of DOM objects). Often these global handles are source
+// of leaks.
+//
+// If you want to let a C++ object hold a persistent handle
+// to a JS object, you should register the handle here to
+// keep track of leaks.
+//
+// When creating a persistent handle, call:
+//
+// #ifndef NDEBUG
+// V8GCController::registerGlobalHandle(type, host, handle);
+// #endif
+//
+// When releasing the handle, call:
+//
+// #ifndef NDEBUG
+// V8GCController::unregisterGlobalHandle(type, host, handle);
+// #endif
+//
+typedef HashMap<v8::Value*, GlobalHandleInfo*> GlobalHandleMap;
+
+static GlobalHandleMap& globalHandleMap()
+{
+ DEFINE_STATIC_LOCAL(GlobalHandleMap, staticGlobalHandleMap, ());
+ return staticGlobalHandleMap;
+}
+
+// The function is the place to set the break point to inspect
+// live global handles. Leaks are often come from leaked global handles.
+static void enumerateGlobalHandles()
+{
+ for (GlobalHandleMap::iterator it = globalHandleMap().begin(), end = globalHandleMap().end(); it != end; ++it) {
+ GlobalHandleInfo* info = it->second;
+ UNUSED_PARAM(info);
+ v8::Value* handle = it->first;
+ UNUSED_PARAM(handle);
+ }
+}
+
+void V8GCController::registerGlobalHandle(GlobalHandleType type, void* host, v8::Persistent<v8::Value> handle)
+{
+ ASSERT(!globalHandleMap().contains(*handle));
+ globalHandleMap().set(*handle, new GlobalHandleInfo(host, type));
+}
+
+void V8GCController::unregisterGlobalHandle(void* host, v8::Persistent<v8::Value> handle)
+{
+ ASSERT(globalHandleMap().contains(*handle));
+ GlobalHandleInfo* info = globalHandleMap().take(*handle);
+ ASSERT(info->m_host == host);
+ delete info;
+}
+#endif // ifndef NDEBUG
+
+typedef HashMap<Node*, v8::Object*> DOMNodeMap;
+typedef HashMap<void*, v8::Object*> DOMObjectMap;
+
+#ifndef NDEBUG
+
+static void enumerateDOMObjectMap(DOMObjectMap& wrapperMap)
+{
+ for (DOMObjectMap::iterator it = wrapperMap.begin(), end = wrapperMap.end(); it != end; ++it) {
+ v8::Persistent<v8::Object> wrapper(it->second);
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ void* object = it->first;
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(object);
+ }
+}
+
+class DOMObjectVisitor : public DOMWrapperMap<void>::Visitor {
+public:
+ void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
+ {
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ UNUSED_PARAM(type);
+ UNUSED_PARAM(object);
+ }
+};
+
+class EnsureWeakDOMNodeVisitor : public DOMWrapperMap<Node>::Visitor {
+public:
+ void visitDOMWrapper(Node* object, v8::Persistent<v8::Object> wrapper)
+ {
+ UNUSED_PARAM(object);
+ ASSERT(wrapper.IsWeak());
+ }
+};
+
+#endif // NDEBUG
+
+// A map from a DOM node to its JS wrapper, the wrapper
+// is kept as a strong reference to survive GCs.
+static DOMObjectMap& gcProtectedMap()
+{
+ DEFINE_STATIC_LOCAL(DOMObjectMap, staticGcProtectedMap, ());
+ return staticGcProtectedMap;
+}
+
+void V8GCController::gcProtect(void* domObject)
+{
+ if (!domObject)
+ return;
+ if (gcProtectedMap().contains(domObject))
+ return;
+ if (!getDOMObjectMap().contains(domObject))
+ return;
+
+ // Create a new (strong) persistent handle for the object.
+ v8::Persistent<v8::Object> wrapper = getDOMObjectMap().get(domObject);
+ if (wrapper.IsEmpty())
+ return;
+
+ gcProtectedMap().set(domObject, *v8::Persistent<v8::Object>::New(wrapper));
+}
+
+void V8GCController::gcUnprotect(void* domObject)
+{
+ if (!domObject)
+ return;
+ if (!gcProtectedMap().contains(domObject))
+ return;
+
+ // Dispose the strong reference.
+ v8::Persistent<v8::Object> wrapper(gcProtectedMap().take(domObject));
+ wrapper.Dispose();
+}
+
+class GCPrologueVisitor : public DOMWrapperMap<void>::Visitor {
+public:
+ void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
+ {
+ ASSERT(wrapper.IsWeak());
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: { \
+ NAME* impl = static_cast<NAME*>(object); \
+ if (impl->hasPendingActivity()) \
+ wrapper.ClearWeak(); \
+ break; \
+ }
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ default:
+ ASSERT_NOT_REACHED();
+#undef MAKE_CASE
+ }
+
+ // Additional handling of message port ensuring that entangled ports also
+ // have their wrappers entangled. This should ideally be handled when the
+ // ports are actually entangled in MessagePort::entangle, but to avoid
+ // forking MessagePort.* this is postponed to GC time. Having this postponed
+ // has the drawback that the wrappers are "entangled/unentangled" for each
+ // GC even though their entaglement most likely is still the same.
+ if (type == V8ClassIndex::MESSAGEPORT) {
+ // Get the port and its entangled port.
+ MessagePort* port1 = static_cast<MessagePort*>(object);
+ MessagePort* port2 = port1->locallyEntangledPort();
+
+ // If we are remotely entangled, then mark this object as reachable
+ // (we can't determine reachability directly as the remote object is
+ // out-of-proc).
+ if (port1->isEntangled() && !port2)
+ wrapper.ClearWeak();
+
+ if (port2) {
+ // As ports are always entangled in pairs only perform the entanglement
+ // once for each pair (see ASSERT in MessagePort::unentangle()).
+ if (port1 < port2) {
+ v8::Handle<v8::Value> port1Wrapper = V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, port1);
+ v8::Handle<v8::Value> port2Wrapper = V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, port2);
+ ASSERT(port1Wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(port1Wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, port2Wrapper);
+ ASSERT(port2Wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(port2Wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, port1Wrapper);
+ }
+ } else {
+ // Remove the wrapper entanglement when a port is not entangled.
+ if (V8DOMWrapper::domObjectHasJSWrapper(port1)) {
+ v8::Handle<v8::Value> wrapper = V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, port1);
+ ASSERT(wrapper->IsObject());
+ v8::Handle<v8::Object>::Cast(wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, v8::Undefined());
+ }
+ }
+ }
+}
+};
+
+class GrouperItem {
+public:
+ GrouperItem(uintptr_t groupId, Node* node, v8::Persistent<v8::Object> wrapper)
+ : m_groupId(groupId)
+ , m_node(node)
+ , m_wrapper(wrapper)
+ {
+ }
+
+ uintptr_t groupId() const { return m_groupId; }
+ Node* node() const { return m_node; }
+ v8::Persistent<v8::Object> wrapper() const { return m_wrapper; }
+
+private:
+ uintptr_t m_groupId;
+ Node* m_node;
+ v8::Persistent<v8::Object> m_wrapper;
+};
+
+bool operator<(const GrouperItem& a, const GrouperItem& b)
+{
+ return a.groupId() < b.groupId();
+}
+
+typedef Vector<GrouperItem> GrouperList;
+
+class ObjectGrouperVisitor : public DOMWrapperMap<Node>::Visitor {
+public:
+ ObjectGrouperVisitor()
+ {
+ // FIXME: grouper_.reserveCapacity(node_map.size()); ?
+ }
+
+ void visitDOMWrapper(Node* node, v8::Persistent<v8::Object> wrapper)
+ {
+
+ // If the node is in document, put it in the ownerDocument's object group.
+ //
+ // If an image element was created by JavaScript "new Image",
+ // it is not in a document. However, if the load event has not
+ // been fired (still onloading), it is treated as in the document.
+ //
+ // Otherwise, the node is put in an object group identified by the root
+ // element of the tree to which it belongs.
+ uintptr_t groupId;
+ if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()))
+ groupId = reinterpret_cast<uintptr_t>(node->document());
+ else {
+ Node* root = node;
+ while (root->parent())
+ root = root->parent();
+
+ // If the node is alone in its DOM tree (doesn't have a parent or any
+ // children) then the group will be filtered out later anyway.
+ if (root == node && !node->hasChildNodes())
+ return;
+
+ groupId = reinterpret_cast<uintptr_t>(root);
+ }
+ m_grouper.append(GrouperItem(groupId, node, wrapper));
+ }
+
+ void applyGrouping()
+ {
+ // Group by sorting by the group id.
+ std::sort(m_grouper.begin(), m_grouper.end());
+
+ // FIXME Should probably work in iterators here, but indexes were easier for my simple mind.
+ for (size_t i = 0; i < m_grouper.size(); ) {
+ // Seek to the next key (or the end of the list).
+ size_t nextKeyIndex = m_grouper.size();
+ for (size_t j = i; j < m_grouper.size(); ++j) {
+ if (m_grouper[i].groupId() != m_grouper[j].groupId()) {
+ nextKeyIndex = j;
+ break;
+ }
+ }
+
+ ASSERT(nextKeyIndex > i);
+
+ // We only care about a group if it has more than one object. If it only
+ // has one object, it has nothing else that needs to be kept alive.
+ if (nextKeyIndex - i <= 1) {
+ i = nextKeyIndex;
+ continue;
+ }
+
+ Vector<v8::Persistent<v8::Value> > group;
+ group.reserveCapacity(nextKeyIndex - i);
+ for (; i < nextKeyIndex; ++i) {
+ Node* node = m_grouper[i].node();
+ v8::Persistent<v8::Value> wrapper = m_grouper[i].wrapper();
+ if (!wrapper.IsEmpty())
+ group.append(wrapper);
+ /* FIXME: Re-enabled this code to avoid GCing these wrappers!
+ Currently this depends on looking up the wrapper
+ during a GC, but we don't know which isolated world
+ we're in, so it's unclear which map to look in...
+
+ // If the node is styled and there is a wrapper for the inline
+ // style declaration, we need to keep that style declaration
+ // wrapper alive as well, so we add it to the object group.
+ if (node->isStyledElement()) {
+ StyledElement* element = reinterpret_cast<StyledElement*>(node);
+ CSSStyleDeclaration* style = element->inlineStyleDecl();
+ if (style != NULL) {
+ wrapper = getDOMObjectMap().get(style);
+ if (!wrapper.IsEmpty())
+ group.append(wrapper);
+ }
+ }
+ */
+ }
+
+ if (group.size() > 1)
+ v8::V8::AddObjectGroup(&group[0], group.size());
+
+ ASSERT(i == nextKeyIndex);
+ }
+ }
+
+private:
+ GrouperList m_grouper;
+};
+
+// Create object groups for DOM tree nodes.
+void V8GCController::gcPrologue()
+{
+ v8::HandleScope scope;
+
+#ifndef NDEBUG
+ DOMObjectVisitor domObjectVisitor;
+ visitDOMObjectsInCurrentThread(&domObjectVisitor);
+#endif
+
+ // Run through all objects with possible pending activity making their
+ // wrappers non weak if there is pending activity.
+ GCPrologueVisitor prologueVisitor;
+ visitActiveDOMObjectsInCurrentThread(&prologueVisitor);
+
+ // Create object groups.
+ ObjectGrouperVisitor objectGrouperVisitor;
+ visitDOMNodesInCurrentThread(&objectGrouperVisitor);
+ objectGrouperVisitor.applyGrouping();
+}
+
+class GCEpilogueVisitor : public DOMWrapperMap<void>::Visitor {
+public:
+ void visitDOMWrapper(void* object, v8::Persistent<v8::Object> wrapper)
+ {
+ V8ClassIndex::V8WrapperType type = V8DOMWrapper::domWrapperType(wrapper);
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: { \
+ NAME* impl = static_cast<NAME*>(object); \
+ if (impl->hasPendingActivity()) { \
+ ASSERT(!wrapper.IsWeak()); \
+ wrapper.MakeWeak(impl, &DOMDataStore::weakActiveDOMObjectCallback); \
+ } \
+ break; \
+ }
+ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ default:
+ ASSERT_NOT_REACHED();
+#undef MAKE_CASE
+ }
+
+ if (type == V8ClassIndex::MESSAGEPORT) {
+ MessagePort* port1 = static_cast<MessagePort*>(object);
+ MessagePort* port2 = port1->locallyEntangledPort();
+ if (port1->isEntangled() && !port2) {
+ // We marked this port as reachable in GCPrologueVisitor. Undo this now since the
+ // port could be not reachable in the future if it gets disentangled (and also
+ // GCPrologueVisitor expects to see all handles marked as weak).
+ wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback);
+ }
+ }
+ }
+};
+
+void V8GCController::gcEpilogue()
+{
+ v8::HandleScope scope;
+
+ // Run through all objects with pending activity making their wrappers weak
+ // again.
+ GCEpilogueVisitor epilogueVisitor;
+ visitActiveDOMObjectsInCurrentThread(&epilogueVisitor);
+
+#ifndef NDEBUG
+ // Check all survivals are weak.
+ DOMObjectVisitor domObjectVisitor;
+ visitDOMObjectsInCurrentThread(&domObjectVisitor);
+
+ EnsureWeakDOMNodeVisitor weakDOMNodeVisitor;
+ visitDOMNodesInCurrentThread(&weakDOMNodeVisitor);
+
+ enumerateDOMObjectMap(gcProtectedMap());
+ enumerateGlobalHandles();
+#endif
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8GCController.h b/WebCore/bindings/v8/V8GCController.h
new file mode 100644
index 0000000..7441bf0
--- /dev/null
+++ b/WebCore/bindings/v8/V8GCController.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 V8GCController_h
+#define V8GCController_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+#ifndef NDEBUG
+
+#define GlobalHandleTypeList(V) \
+ V(PROXY) \
+ V(NPOBJECT) \
+ V(SCHEDULED_ACTION) \
+ V(EVENT_LISTENER) \
+ V(NODE_FILTER) \
+ V(SCRIPTINSTANCE) \
+ V(SCRIPTVALUE) \
+ V(DATASOURCE)
+
+
+ // Host information of persistent handles.
+ enum GlobalHandleType {
+#define ENUM(name) name,
+ GlobalHandleTypeList(ENUM)
+#undef ENUM
+ };
+
+ class GlobalHandleInfo {
+ public:
+ GlobalHandleInfo(void* host, GlobalHandleType type) : m_host(host), m_type(type) { }
+ void* m_host;
+ GlobalHandleType m_type;
+ };
+
+#endif // NDEBUG
+
+ class V8GCController {
+ public:
+ // Protect/Unprotect JS wrappers of a DOM object.
+ static void gcProtect(void* domObject);
+ static void gcUnprotect(void* domObject);
+
+#ifndef NDEBUG
+ // For debugging and leak detection purpose.
+ static void registerGlobalHandle(GlobalHandleType, void*, v8::Persistent<v8::Value>);
+ static void unregisterGlobalHandle(void*, v8::Persistent<v8::Value>);
+#endif
+
+ static void gcPrologue();
+ static void gcEpilogue();
+ };
+
+}
+
+#endif // V8GCController_h
diff --git a/WebCore/bindings/v8/V8Helpers.cpp b/WebCore/bindings/v8/V8Helpers.cpp
new file mode 100644
index 0000000..a690017
--- /dev/null
+++ b/WebCore/bindings/v8/V8Helpers.cpp
@@ -0,0 +1,59 @@
+/*
+* 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 "V8Helpers.h"
+
+#include "DOMWindow.h"
+#include "NPV8Object.h"
+#include "V8Index.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+void wrapNPObject(v8::Handle<v8::Object> object, NPObject* npObject)
+{
+ V8DOMWrapper::setDOMWrapper(object, V8ClassIndex::NPOBJECT, npObject);
+}
+
+v8::Local<v8::Context> toV8Context(NPP npp, NPObject* npObject)
+{
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+ return V8Proxy::mainWorldContext(object->rootObject->frame());
+}
+
+V8Proxy* toV8Proxy(NPObject* npObject)
+{
+ V8NPObject* object = reinterpret_cast<V8NPObject*>(npObject);
+ Frame* frame = object->rootObject->frame();
+ return V8Proxy::retrieve(frame);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Helpers.h b/WebCore/bindings/v8/V8Helpers.h
new file mode 100644
index 0000000..469833e
--- /dev/null
+++ b/WebCore/bindings/v8/V8Helpers.h
@@ -0,0 +1,49 @@
+/*
+* 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 V8Helpers_h
+#define V8Helpers_h
+
+#include "npruntime.h"
+#include <v8.h>
+
+namespace WebCore {
+ class V8Proxy;
+
+ // Associates an NPObject with a V8 object.
+ void wrapNPObject(v8::Handle<v8::Object>, NPObject*);
+
+ v8::Local<v8::Context> toV8Context(NPP, NPObject*);
+
+ V8Proxy* toV8Proxy(NPObject*);
+
+} // namespace WebCore
+
+#endif // V8Helpers_h
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.cpp b/WebCore/bindings/v8/V8HiddenPropertyName.cpp
new file mode 100644
index 0000000..16ac232
--- /dev/null
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.cpp
@@ -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.
+ */
+
+#include "config.h"
+#include "V8HiddenPropertyName.h"
+
+namespace WebCore {
+
+v8::Handle<v8::String> V8HiddenPropertyName::objectPrototype()
+{
+ static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::objectPrototype");
+
+ return *string;
+}
+
+v8::Handle<v8::String> V8HiddenPropertyName::isolatedWorld()
+{
+ static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::isolatedWorld");
+
+ return *string;
+}
+
+v8::Persistent<v8::String>* V8HiddenPropertyName::createString(const char* key)
+{
+ return new v8::Persistent<v8::String>(v8::Persistent<v8::String>::New(v8::String::NewSymbol(key)));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.h b/WebCore/bindings/v8/V8HiddenPropertyName.h
new file mode 100644
index 0000000..874b525
--- /dev/null
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.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 V8HiddenPropertyName_h
+#define V8HiddenPropertyName_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class V8HiddenPropertyName {
+ public:
+ static v8::Handle<v8::String> objectPrototype();
+ static v8::Handle<v8::String> isolatedWorld();
+
+ private:
+ static v8::Persistent<v8::String>* createString(const char* key);
+ };
+
+}
+
+#endif // V8HiddenPropertyName_h
diff --git a/WebCore/bindings/v8/V8Index.cpp b/WebCore/bindings/v8/V8Index.cpp
new file mode 100644
index 0000000..8ac3669
--- /dev/null
+++ b/WebCore/bindings/v8/V8Index.cpp
@@ -0,0 +1,425 @@
+/*
+ * 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 "V8Index.h"
+
+#include "V8Attr.h"
+#include "V8BarInfo.h"
+#include "V8CanvasRenderingContext2D.h"
+#include "V8CanvasGradient.h"
+#include "V8CanvasPattern.h"
+#include "V8CanvasPixelArray.h"
+#include "V8CDATASection.h"
+#include "V8CharacterData.h"
+#include "V8ClientRect.h"
+#include "V8ClientRectList.h"
+#include "V8Clipboard.h"
+#include "V8Comment.h"
+#include "V8Console.h"
+#include "V8Counter.h"
+#include "V8CSSStyleDeclaration.h"
+#include "V8CSSRule.h"
+#include "V8CSSStyleRule.h"
+#include "V8CSSCharsetRule.h"
+#include "V8CSSImportRule.h"
+#include "V8CSSMediaRule.h"
+#include "V8CSSFontFaceRule.h"
+#include "V8CSSPageRule.h"
+#include "V8CSSRuleList.h"
+#include "V8CSSPrimitiveValue.h"
+#include "V8CSSValue.h"
+#include "V8CSSValueList.h"
+#include "V8CSSStyleSheet.h"
+#include "V8CSSVariablesDeclaration.h"
+#include "V8CSSVariablesRule.h"
+#include "V8DataGridColumn.h"
+#include "V8DataGridColumnList.h"
+#include "V8Database.h"
+#include "V8Document.h"
+#include "V8DocumentFragment.h"
+#include "V8DocumentType.h"
+#include "V8Element.h"
+#include "V8Entity.h"
+#include "V8EntityReference.h"
+#include "V8File.h"
+#include "V8FileList.h"
+#include "V8History.h"
+#include "V8HTMLAllCollection.h"
+#include "V8HTMLCanvasElement.h"
+#include "V8HTMLCollection.h"
+#include "V8HTMLDocument.h"
+#include "V8HTMLElement.h"
+#include "V8HTMLOptionsCollection.h"
+#include "V8HTMLAnchorElement.h"
+#include "V8HTMLAppletElement.h"
+#include "V8HTMLAreaElement.h"
+#include "V8HTMLBaseElement.h"
+#include "V8HTMLBaseFontElement.h"
+#include "V8HTMLBlockquoteElement.h"
+#include "V8HTMLBodyElement.h"
+#include "V8HTMLBRElement.h"
+#include "V8HTMLButtonElement.h"
+#include "V8HTMLCanvasElement.h"
+#include "V8HTMLModElement.h"
+#include "V8HTMLDataGridCellElement.h"
+#include "V8HTMLDataGridColElement.h"
+#include "V8HTMLDataGridElement.h"
+#include "V8HTMLDataGridRowElement.h"
+#include "V8HTMLDirectoryElement.h"
+#include "V8HTMLDivElement.h"
+#include "V8HTMLDListElement.h"
+#include "V8HTMLEmbedElement.h"
+#include "V8HTMLFieldSetElement.h"
+#include "V8HTMLFormElement.h"
+#include "V8HTMLFontElement.h"
+#include "V8HTMLFrameElement.h"
+#include "V8HTMLFrameSetElement.h"
+#include "V8HTMLHeadingElement.h"
+#include "V8HTMLHeadElement.h"
+#include "V8HTMLHRElement.h"
+#include "V8HTMLHtmlElement.h"
+#include "V8HTMLIFrameElement.h"
+#include "V8HTMLImageElement.h"
+#include "V8HTMLInputElement.h"
+#include "V8HTMLIsIndexElement.h"
+#include "V8HTMLLabelElement.h"
+#include "V8HTMLLegendElement.h"
+#include "V8HTMLLIElement.h"
+#include "V8HTMLLinkElement.h"
+#include "V8HTMLMapElement.h"
+#include "V8HTMLMarqueeElement.h"
+#include "V8HTMLMenuElement.h"
+#include "V8HTMLMetaElement.h"
+#include "V8HTMLObjectElement.h"
+#include "V8HTMLOListElement.h"
+#include "V8HTMLOptGroupElement.h"
+#include "V8HTMLOptionElement.h"
+#include "V8HTMLParagraphElement.h"
+#include "V8HTMLParamElement.h"
+#include "V8HTMLPreElement.h"
+#include "V8HTMLQuoteElement.h"
+#include "V8HTMLScriptElement.h"
+#include "V8HTMLSelectElement.h"
+#include "V8HTMLStyleElement.h"
+#include "V8HTMLTableCaptionElement.h"
+#include "V8HTMLTableColElement.h"
+#include "V8HTMLTableElement.h"
+#include "V8HTMLTableSectionElement.h"
+#include "V8HTMLTableCellElement.h"
+#include "V8HTMLTableRowElement.h"
+#include "V8HTMLTextAreaElement.h"
+#include "V8HTMLTitleElement.h"
+#include "V8HTMLUListElement.h"
+#include "V8ImageData.h"
+#include "V8InspectorBackend.h"
+#include "V8Media.h"
+#include "V8MediaList.h"
+#include "V8MessageChannel.h"
+#include "V8MessageEvent.h"
+#include "V8MessagePort.h"
+#include "V8NamedNodeMap.h"
+#include "V8Node.h"
+#include "V8NodeList.h"
+#include "V8NodeFilter.h"
+#include "V8Notation.h"
+#include "V8ProcessingInstruction.h"
+#include "V8ProgressEvent.h"
+#include "V8StyleSheet.h"
+#include "V8Text.h"
+#include "V8TextEvent.h"
+#include "V8DOMCoreException.h"
+#include "V8DOMParser.h"
+#include "V8DOMWindow.h"
+#include "V8ErrorEvent.h"
+#include "V8Event.h"
+#include "V8EventException.h"
+#include "V8KeyboardEvent.h"
+#include "V8MouseEvent.h"
+#include "V8ValidityState.h"
+#include "V8WebKitAnimationEvent.h"
+#include "V8WebKitCSSKeyframeRule.h"
+#include "V8WebKitCSSKeyframesRule.h"
+#include "V8WebKitCSSMatrix.h"
+#include "V8WebKitCSSTransformValue.h"
+#include "V8WebKitPoint.h"
+#include "V8WebKitTransitionEvent.h"
+#include "V8WheelEvent.h"
+#include "V8UIEvent.h"
+#include "V8MutationEvent.h"
+#include "V8OverflowEvent.h"
+#include "V8Location.h"
+#include "V8Screen.h"
+#include "V8DOMSelection.h"
+#include "V8Navigator.h"
+#include "V8MimeType.h"
+#include "V8MimeTypeArray.h"
+#include "V8Plugin.h"
+#include "V8PluginArray.h"
+#include "V8Range.h"
+#include "V8RangeException.h"
+#include "V8Rect.h"
+#include "V8SQLError.h"
+#include "V8SQLResultSet.h"
+#include "V8SQLResultSetRowList.h"
+#include "V8SQLTransaction.h"
+#include "V8NodeIterator.h"
+#include "V8TextMetrics.h"
+#include "V8TreeWalker.h"
+#include "V8StyleSheetList.h"
+#include "V8DOMImplementation.h"
+#include "V8XPathResult.h"
+#include "V8XPathException.h"
+#include "V8XPathExpression.h"
+#include "V8XPathNSResolver.h"
+#include "V8XMLHttpRequest.h"
+#include "V8XMLHttpRequestException.h"
+#include "V8XMLHttpRequestProgressEvent.h"
+#include "V8XMLHttpRequestUpload.h"
+#include "V8XMLSerializer.h"
+#include "V8XPathEvaluator.h"
+#include "V8XSLTProcessor.h"
+#include "V8RGBColor.h"
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "V8DOMApplicationCache.h"
+#endif
+
+#if ENABLE(DOM_STORAGE)
+#include "V8Storage.h"
+#include "V8StorageEvent.h"
+#endif
+
+#if ENABLE(SVG_ANIMATION)
+#include "V8SVGAnimateColorElement.h"
+#include "V8SVGAnimateElement.h"
+#include "V8SVGAnimateTransformElement.h"
+#include "V8SVGAnimationElement.h"
+#include "V8SVGSetElement.h"
+#endif
+
+#if ENABLE(SVG_FILTERS)
+#include "V8SVGComponentTransferFunctionElement.h"
+#include "V8SVGFEBlendElement.h"
+#include "V8SVGFEColorMatrixElement.h"
+#include "V8SVGFEComponentTransferElement.h"
+#include "V8SVGFECompositeElement.h"
+#include "V8SVGFEDiffuseLightingElement.h"
+#include "V8SVGFEDisplacementMapElement.h"
+#include "V8SVGFEDistantLightElement.h"
+#include "V8SVGFEFloodElement.h"
+#include "V8SVGFEFuncAElement.h"
+#include "V8SVGFEFuncBElement.h"
+#include "V8SVGFEFuncGElement.h"
+#include "V8SVGFEFuncRElement.h"
+#include "V8SVGFEGaussianBlurElement.h"
+#include "V8SVGFEImageElement.h"
+#include "V8SVGFEMergeElement.h"
+#include "V8SVGFEMergeNodeElement.h"
+#include "V8SVGFEOffsetElement.h"
+#include "V8SVGFEPointLightElement.h"
+#include "V8SVGFESpecularLightingElement.h"
+#include "V8SVGFESpotLightElement.h"
+#include "V8SVGFETileElement.h"
+#include "V8SVGFETurbulenceElement.h"
+#include "V8SVGFilterElement.h"
+#endif
+
+#if ENABLE(SVG_FONTS)
+#include "V8SVGDefinitionSrcElement.h"
+#include "V8SVGFontFaceElement.h"
+#include "V8SVGFontFaceFormatElement.h"
+#include "V8SVGFontFaceNameElement.h"
+#include "V8SVGFontFaceSrcElement.h"
+#include "V8SVGFontFaceUriElement.h"
+#endif
+
+#if ENABLE(SVG_FOREIGN_OBJECT)
+#include "V8SVGForeignObjectElement.h"
+#endif
+
+#if ENABLE(SVG_USE)
+#include "V8SVGUseElement.h"
+#endif
+
+#if ENABLE(SVG)
+#include "V8SVGAElement.h"
+#include "V8SVGAltGlyphElement.h"
+#include "V8SVGCircleElement.h"
+#include "V8SVGClipPathElement.h"
+#include "V8SVGCursorElement.h"
+#include "V8SVGDefsElement.h"
+#include "V8SVGDescElement.h"
+#include "V8SVGElement.h"
+#include "V8SVGEllipseElement.h"
+#include "V8SVGException.h"
+#include "V8SVGGElement.h"
+#include "V8SVGGlyphElement.h"
+#include "V8SVGGradientElement.h"
+#include "V8SVGImageElement.h"
+#include "V8SVGLinearGradientElement.h"
+#include "V8SVGLineElement.h"
+#include "V8SVGMarkerElement.h"
+#include "V8SVGMaskElement.h"
+#include "V8SVGMetadataElement.h"
+#include "V8SVGPathElement.h"
+#include "V8SVGPatternElement.h"
+#include "V8SVGPolygonElement.h"
+#include "V8SVGPolylineElement.h"
+#include "V8SVGRadialGradientElement.h"
+#include "V8SVGRectElement.h"
+#include "V8SVGScriptElement.h"
+#include "V8SVGStopElement.h"
+#include "V8SVGStyleElement.h"
+#include "V8SVGSVGElement.h"
+#include "V8SVGSwitchElement.h"
+#include "V8SVGSymbolElement.h"
+#include "V8SVGTextContentElement.h"
+#include "V8SVGTextElement.h"
+#include "V8SVGTextPathElement.h"
+#include "V8SVGTextPositioningElement.h"
+#include "V8SVGTitleElement.h"
+#include "V8SVGTRefElement.h"
+#include "V8SVGTSpanElement.h"
+#include "V8SVGViewElement.h"
+#include "V8SVGAngle.h"
+#include "V8SVGAnimatedAngle.h"
+#include "V8SVGAnimatedBoolean.h"
+#include "V8SVGAnimatedEnumeration.h"
+#include "V8SVGAnimatedInteger.h"
+#include "V8SVGAnimatedLength.h"
+#include "V8SVGAnimatedLengthList.h"
+#include "V8SVGAnimatedNumber.h"
+#include "V8SVGAnimatedNumberList.h"
+#include "V8SVGAnimatedPoints.h"
+#include "V8SVGAnimatedPreserveAspectRatio.h"
+#include "V8SVGAnimatedRect.h"
+#include "V8SVGAnimatedString.h"
+#include "V8SVGAnimatedTransformList.h"
+#include "V8SVGColor.h"
+#include "V8SVGDocument.h"
+#include "V8SVGElementInstance.h"
+#include "V8SVGElementInstanceList.h"
+#include "V8SVGLength.h"
+#include "V8SVGLengthList.h"
+#include "V8SVGMatrix.h"
+#include "V8SVGNumber.h"
+#include "V8SVGNumberList.h"
+#include "V8SVGPaint.h"
+#include "V8SVGPathSeg.h"
+#include "V8SVGPathSegArcAbs.h"
+#include "V8SVGPathSegArcRel.h"
+#include "V8SVGPathSegClosePath.h"
+#include "V8SVGPathSegCurvetoCubicAbs.h"
+#include "V8SVGPathSegCurvetoCubicRel.h"
+#include "V8SVGPathSegCurvetoCubicSmoothAbs.h"
+#include "V8SVGPathSegCurvetoCubicSmoothRel.h"
+#include "V8SVGPathSegCurvetoQuadraticAbs.h"
+#include "V8SVGPathSegCurvetoQuadraticRel.h"
+#include "V8SVGPathSegCurvetoQuadraticSmoothAbs.h"
+#include "V8SVGPathSegCurvetoQuadraticSmoothRel.h"
+#include "V8SVGPathSegLinetoAbs.h"
+#include "V8SVGPathSegLinetoHorizontalAbs.h"
+#include "V8SVGPathSegLinetoHorizontalRel.h"
+#include "V8SVGPathSegLinetoRel.h"
+#include "V8SVGPathSegLinetoVerticalAbs.h"
+#include "V8SVGPathSegLinetoVerticalRel.h"
+#include "V8SVGPathSegList.h"
+#include "V8SVGPathSegMovetoAbs.h"
+#include "V8SVGPathSegMovetoRel.h"
+#include "V8SVGPoint.h"
+#include "V8SVGPointList.h"
+#include "V8SVGPreserveAspectRatio.h"
+#include "V8SVGRect.h"
+#include "V8SVGRenderingIntent.h"
+#include "V8SVGStringList.h"
+#include "V8SVGTransform.h"
+#include "V8SVGTransformList.h"
+#include "V8SVGUnitTypes.h"
+#include "V8SVGURIReference.h"
+#include "V8SVGZoomEvent.h"
+#endif
+
+#if ENABLE(VIDEO)
+#include "V8HTMLAudioElement.h"
+#include "V8HTMLMediaElement.h"
+#include "V8HTMLSourceElement.h"
+#include "V8HTMLVideoElement.h"
+#include "V8MediaError.h"
+#include "V8TimeRanges.h"
+#endif
+
+#if ENABLE(WORKERS)
+#include "V8AbstractWorker.h"
+#include "V8DedicatedWorkerContext.h"
+#include "V8Worker.h"
+#include "V8WorkerContext.h"
+#include "V8WorkerLocation.h"
+#include "V8WorkerNavigator.h"
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+#include "V8SharedWorker.h"
+#endif
+
+namespace WebCore {
+
+FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type)
+{
+ switch (type) {
+#define MAKE_CASE(type, name)\
+ case V8ClassIndex::type: return V8##name::GetTemplate;
+ WRAPPER_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default: return NULL;
+ }
+}
+
+
+#define MAKE_CACHE(type, name)\
+ static v8::Persistent<v8::FunctionTemplate> name##_cache_;
+ ALL_WRAPPER_TYPES(MAKE_CACHE)
+#undef MAKE_CACHE
+
+
+v8::Persistent<v8::FunctionTemplate>* V8ClassIndex::GetCache(V8WrapperType type)
+{
+ switch (type) {
+#define MAKE_CASE(type, name)\
+ case V8ClassIndex::type: return &name##_cache_;
+ ALL_WRAPPER_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT(false);
+ return NULL;
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Index.h b/WebCore/bindings/v8/V8Index.h
index 58af42e..d81537d 100644
--- a/WebCore/bindings/v8/V8Index.h
+++ b/WebCore/bindings/v8/V8Index.h
@@ -31,8 +31,537 @@
#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"
+#include <v8.h>
+#include "PlatformString.h" // for WebCore::String
+
+namespace WebCore {
+
+typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
+
+#if ENABLE(DATAGRID)
+#define DATAGRID_HTMLELEMENT_TYPES(V) \
+ V(HTMLDATAGRIDCELLELEMENT, HTMLDataGridCellElement) \
+ V(HTMLDATAGRIDCOLELEMENT, HTMLDataGridColElement) \
+ V(HTMLDATAGRIDELEMENT, HTMLDataGridElement) \
+ V(HTMLDATAGRIDROWELEMENT, HTMLDataGridRowElement)
+#define DATAGRID_NONNODE_TYPES(V) \
+ V(DATAGRIDCOLUMN, DataGridColumn) \
+ V(DATAGRIDCOLUMNLIST, DataGridColumnList)
+#else
+#define DATAGRID_HTMLELEMENT_TYPES(V)
+#define DATAGRID_NONNODE_TYPES(V)
+#endif
+
+#if ENABLE(VIDEO)
+#define VIDEO_HTMLELEMENT_TYPES(V) \
+ V(HTMLAUDIOELEMENT, HTMLAudioElement) \
+ V(HTMLMEDIAELEMENT, HTMLMediaElement) \
+ V(HTMLSOURCEELEMENT, HTMLSourceElement) \
+ V(HTMLVIDEOELEMENT, HTMLVideoElement)
+#define VIDEO_NONNODE_TYPES(V) \
+ V(MEDIAERROR, MediaError) \
+ V(TIMERANGES, TimeRanges)
+#else
+#define VIDEO_HTMLELEMENT_TYPES(V)
+#define VIDEO_NONNODE_TYPES(V)
+#endif
+
+#if ENABLE(WORKERS)
+#define WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V) \
+ V(WORKER, Worker)
+
+#define WORKER_NONNODE_WRAPPER_TYPES(V) \
+ V(ABSTRACTWORKER, AbstractWorker) \
+ V(DEDICATEDWORKERCONTEXT, DedicatedWorkerContext) \
+ V(WORKERCONTEXT, WorkerContext) \
+ V(WORKERLOCATION, WorkerLocation) \
+ V(WORKERNAVIGATOR, WorkerNavigator)
+#else
+#define WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V)
+#define WORKER_NONNODE_WRAPPER_TYPES(V)
+#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
+ V(DOMAPPLICATIONCACHE, DOMApplicationCache)
+#else
+#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V)
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+#define SHARED_WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V) \
+ V(SHAREDWORKER, SharedWorker)
+#define SHARED_WORKER_NONNODE_WRAPPER_TYPES(V)
+#else
+#define SHARED_WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V)
+#define SHARED_WORKER_NONNODE_WRAPPER_TYPES(V)
+#endif
+
+#define DOM_NODE_TYPES(V) \
+ V(ATTR, Attr) \
+ V(CHARACTERDATA, CharacterData) \
+ V(CDATASECTION, CDATASection) \
+ V(COMMENT, Comment) \
+ V(DOCUMENT, Document) \
+ V(DOCUMENTFRAGMENT, DocumentFragment) \
+ V(DOCUMENTTYPE, DocumentType) \
+ V(ELEMENT, Element) \
+ V(ENTITY, Entity) \
+ V(ENTITYREFERENCE, EntityReference) \
+ V(HTMLDOCUMENT, HTMLDocument) \
+ V(NODE, Node) \
+ V(NOTATION, Notation) \
+ V(PROCESSINGINSTRUCTION, ProcessingInstruction) \
+ V(TEXT, Text) \
+ V(HTMLANCHORELEMENT, HTMLAnchorElement) \
+ V(HTMLAPPLETELEMENT, HTMLAppletElement) \
+ V(HTMLAREAELEMENT, HTMLAreaElement) \
+ V(HTMLBASEELEMENT, HTMLBaseElement) \
+ V(HTMLBASEFONTELEMENT, HTMLBaseFontElement) \
+ V(HTMLBLOCKQUOTEELEMENT, HTMLBlockquoteElement) \
+ V(HTMLBODYELEMENT, HTMLBodyElement) \
+ V(HTMLBRELEMENT, HTMLBRElement) \
+ V(HTMLBUTTONELEMENT, HTMLButtonElement) \
+ V(HTMLCANVASELEMENT, HTMLCanvasElement) \
+ V(HTMLDIRECTORYELEMENT, HTMLDirectoryElement) \
+ V(HTMLDIVELEMENT, HTMLDivElement) \
+ V(HTMLDLISTELEMENT, HTMLDListElement) \
+ V(HTMLEMBEDELEMENT, HTMLEmbedElement) \
+ V(HTMLFIELDSETELEMENT, HTMLFieldSetElement) \
+ V(HTMLFONTELEMENT, HTMLFontElement) \
+ V(HTMLFORMELEMENT, HTMLFormElement) \
+ V(HTMLFRAMEELEMENT, HTMLFrameElement) \
+ V(HTMLFRAMESETELEMENT, HTMLFrameSetElement) \
+ V(HTMLHEADINGELEMENT, HTMLHeadingElement) \
+ V(HTMLHEADELEMENT, HTMLHeadElement) \
+ V(HTMLHRELEMENT, HTMLHRElement) \
+ V(HTMLHTMLELEMENT, HTMLHtmlElement) \
+ V(HTMLIFRAMEELEMENT, HTMLIFrameElement) \
+ V(HTMLIMAGEELEMENT, HTMLImageElement) \
+ V(HTMLINPUTELEMENT, HTMLInputElement) \
+ V(HTMLISINDEXELEMENT, HTMLIsIndexElement) \
+ V(HTMLLABELELEMENT, HTMLLabelElement) \
+ V(HTMLLEGENDELEMENT, HTMLLegendElement) \
+ V(HTMLLIELEMENT, HTMLLIElement) \
+ V(HTMLLINKELEMENT, HTMLLinkElement) \
+ V(HTMLMAPELEMENT, HTMLMapElement) \
+ V(HTMLMARQUEEELEMENT, HTMLMarqueeElement) \
+ V(HTMLMENUELEMENT, HTMLMenuElement) \
+ V(HTMLMETAELEMENT, HTMLMetaElement) \
+ V(HTMLMODELEMENT, HTMLModElement) \
+ V(HTMLOBJECTELEMENT, HTMLObjectElement) \
+ V(HTMLOLISTELEMENT, HTMLOListElement) \
+ V(HTMLOPTGROUPELEMENT, HTMLOptGroupElement) \
+ V(HTMLOPTIONELEMENT, HTMLOptionElement) \
+ V(HTMLPARAGRAPHELEMENT, HTMLParagraphElement) \
+ V(HTMLPARAMELEMENT, HTMLParamElement) \
+ V(HTMLPREELEMENT, HTMLPreElement) \
+ V(HTMLQUOTEELEMENT, HTMLQuoteElement) \
+ V(HTMLSCRIPTELEMENT, HTMLScriptElement) \
+ V(HTMLSELECTELEMENT, HTMLSelectElement) \
+ V(HTMLSTYLEELEMENT, HTMLStyleElement) \
+ V(HTMLTABLECAPTIONELEMENT, HTMLTableCaptionElement) \
+ V(HTMLTABLECOLELEMENT, HTMLTableColElement) \
+ V(HTMLTABLEELEMENT, HTMLTableElement) \
+ V(HTMLTABLESECTIONELEMENT, HTMLTableSectionElement) \
+ V(HTMLTABLECELLELEMENT, HTMLTableCellElement) \
+ V(HTMLTABLEROWELEMENT, HTMLTableRowElement) \
+ V(HTMLTEXTAREAELEMENT, HTMLTextAreaElement) \
+ V(HTMLTITLEELEMENT, HTMLTitleElement) \
+ V(HTMLULISTELEMENT, HTMLUListElement) \
+ V(HTMLELEMENT, HTMLElement) \
+ DATAGRID_HTMLELEMENT_TYPES(V) \
+ VIDEO_HTMLELEMENT_TYPES(V)
+
+#if ENABLE(SVG_ANIMATION)
+#define SVG_ANIMATION_ELEMENT_TYPES(V) \
+ V(SVGANIMATECOLORELEMENT, SVGAnimateColorElement) \
+ V(SVGANIMATEELEMENT, SVGAnimateElement) \
+ V(SVGANIMATETRANSFORMELEMENT, SVGAnimateTransformElement) \
+ V(SVGANIMATIONELEMENT, SVGAnimationElement) \
+ V(SVGSETELEMENT, SVGSetElement)
+#else
+#define SVG_ANIMATION_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_FILTERS)
+#define SVG_FILTERS_ELEMENT_TYPES(V) \
+ V(SVGCOMPONENTTRANSFERFUNCTIONELEMENT, SVGComponentTransferFunctionElement)\
+ V(SVGFEBLENDELEMENT, SVGFEBlendElement) \
+ V(SVGFECOLORMATRIXELEMENT, SVGFEColorMatrixElement) \
+ V(SVGFECOMPONENTTRANSFERELEMENT, SVGFEComponentTransferElement) \
+ V(SVGFECOMPOSITEELEMENT, SVGFECompositeElement) \
+ V(SVGFEDIFFUSELIGHTINGELEMENT, SVGFEDiffuseLightingElement) \
+ V(SVGFEDISPLACEMENTMAPELEMENT, SVGFEDisplacementMapElement) \
+ V(SVGFEDISTANTLIGHTELEMENT, SVGFEDistantLightElement) \
+ V(SVGFEFLOODELEMENT, SVGFEFloodElement) \
+ V(SVGFEFUNCAELEMENT, SVGFEFuncAElement) \
+ V(SVGFEFUNCBELEMENT, SVGFEFuncBElement) \
+ V(SVGFEFUNCGELEMENT, SVGFEFuncGElement) \
+ V(SVGFEFUNCRELEMENT, SVGFEFuncRElement) \
+ V(SVGFEGAUSSIANBLURELEMENT, SVGFEGaussianBlurElement) \
+ V(SVGFEIMAGEELEMENT, SVGFEImageElement) \
+ V(SVGFEMERGEELEMENT, SVGFEMergeElement) \
+ V(SVGFEMERGENODEELEMENT, SVGFEMergeNodeElement) \
+ V(SVGFEOFFSETELEMENT, SVGFEOffsetElement) \
+ V(SVGFEPOINTLIGHTELEMENT, SVGFEPointLightElement) \
+ V(SVGFESPECULARLIGHTINGELEMENT, SVGFESpecularLightingElement) \
+ V(SVGFESPOTLIGHTELEMENT, SVGFESpotLightElement) \
+ V(SVGFETILEELEMENT, SVGFETileElement) \
+ V(SVGFETURBULENCEELEMENT, SVGFETurbulenceElement) \
+ V(SVGFILTERELEMENT, SVGFilterElement)
+#else
+#define SVG_FILTERS_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_FONTS)
+#define SVG_FONTS_ELEMENT_TYPES(V) \
+ V(SVGDEFINITIONSRCELEMENT, SVGDefinitionSrcElement) \
+ V(SVGFONTFACEELEMENT, SVGFontFaceElement) \
+ V(SVGFONTFACEFORMATELEMENT, SVGFontFaceFormatElement) \
+ V(SVGFONTFACENAMEELEMENT, SVGFontFaceNameElement) \
+ V(SVGFONTFACESRCELEMENT, SVGFontFaceSrcElement) \
+ V(SVGFONTFACEURIELEMENT, SVGFontFaceUriElement)
+#else
+#define SVG_FONTS_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_FOREIGN_OBJECT)
+#define SVG_FOREIGN_OBJECT_ELEMENT_TYPES(V) \
+ V(SVGFOREIGNOBJECTELEMENT, SVGForeignObjectElement)
+#else
+#define SVG_FOREIGN_OBJECT_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG_USE)
+#define SVG_USE_ELEMENT_TYPES(V) \
+ V(SVGUSEELEMENT, SVGUseElement)
+#else
+#define SVG_USE_ELEMENT_TYPES(V)
+#endif
+
+#if ENABLE(SVG)
+#define SVG_NODE_TYPES(V) \
+ SVG_ANIMATION_ELEMENT_TYPES(V) \
+ SVG_FILTERS_ELEMENT_TYPES(V) \
+ SVG_FONTS_ELEMENT_TYPES(V) \
+ SVG_FOREIGN_OBJECT_ELEMENT_TYPES(V) \
+ SVG_USE_ELEMENT_TYPES(V) \
+ V(SVGAELEMENT, SVGAElement) \
+ V(SVGALTGLYPHELEMENT, SVGAltGlyphElement) \
+ V(SVGCIRCLEELEMENT, SVGCircleElement) \
+ V(SVGCLIPPATHELEMENT, SVGClipPathElement) \
+ V(SVGCURSORELEMENT, SVGCursorElement) \
+ V(SVGDEFSELEMENT, SVGDefsElement) \
+ V(SVGDESCELEMENT, SVGDescElement) \
+ V(SVGELLIPSEELEMENT, SVGEllipseElement) \
+ V(SVGGELEMENT, SVGGElement) \
+ V(SVGGLYPHELEMENT, SVGGlyphElement) \
+ V(SVGGRADIENTELEMENT, SVGGradientElement) \
+ V(SVGIMAGEELEMENT, SVGImageElement) \
+ V(SVGLINEARGRADIENTELEMENT, SVGLinearGradientElement) \
+ V(SVGLINEELEMENT, SVGLineElement) \
+ V(SVGMARKERELEMENT, SVGMarkerElement) \
+ V(SVGMASKELEMENT, SVGMaskElement) \
+ V(SVGMETADATAELEMENT, SVGMetadataElement) \
+ V(SVGPATHELEMENT, SVGPathElement) \
+ V(SVGPATTERNELEMENT, SVGPatternElement) \
+ V(SVGPOLYGONELEMENT, SVGPolygonElement) \
+ V(SVGPOLYLINEELEMENT, SVGPolylineElement) \
+ V(SVGRADIALGRADIENTELEMENT, SVGRadialGradientElement) \
+ V(SVGRECTELEMENT, SVGRectElement) \
+ V(SVGSCRIPTELEMENT, SVGScriptElement) \
+ V(SVGSTOPELEMENT, SVGStopElement) \
+ V(SVGSTYLEELEMENT, SVGStyleElement) \
+ V(SVGSVGELEMENT, SVGSVGElement) \
+ V(SVGSWITCHELEMENT, SVGSwitchElement) \
+ V(SVGSYMBOLELEMENT, SVGSymbolElement) \
+ V(SVGTEXTCONTENTELEMENT, SVGTextContentElement) \
+ V(SVGTEXTELEMENT, SVGTextElement) \
+ V(SVGTEXTPATHELEMENT, SVGTextPathElement) \
+ V(SVGTEXTPOSITIONINGELEMENT, SVGTextPositioningElement) \
+ V(SVGTITLEELEMENT, SVGTitleElement) \
+ V(SVGTREFELEMENT, SVGTRefElement) \
+ V(SVGTSPANELEMENT, SVGTSpanElement) \
+ V(SVGVIEWELEMENT, SVGViewElement) \
+ V(SVGELEMENT, SVGElement) \
+ V(SVGDOCUMENT, SVGDocument)
+#endif // SVG
+
+
+// ACTIVE_DOM_OBJECT_TYPES are DOM_OBJECT_TYPES that need special treatement
+// during GC.
+#define ACTIVE_DOM_OBJECT_TYPES(V) \
+ V(MESSAGEPORT, MessagePort) \
+ V(XMLHTTPREQUEST, XMLHttpRequest) \
+ WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V) \
+ SHARED_WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V)
+
+// NOTE: DOM_OBJECT_TYPES is split into two halves because
+// Visual Studio's Intellinonsense crashes when macros get
+// too large. 10-29-08
+// DOM_OBJECT_TYPES are non-node DOM types.
+#define DOM_OBJECT_TYPES_1(V) \
+ V(BARINFO, BarInfo) \
+ V(CANVASGRADIENT, CanvasGradient) \
+ V(CANVASPATTERN, CanvasPattern) \
+ V(CANVASRENDERINGCONTEXT2D, CanvasRenderingContext2D) \
+ V(CLIENTRECT, ClientRect) \
+ V(CLIENTRECTLIST, ClientRectList) \
+ V(CLIPBOARD, Clipboard) \
+ V(CONSOLE, Console) \
+ V(COUNTER, Counter) \
+ V(CSSCHARSETRULE, CSSCharsetRule) \
+ V(CSSFONTFACERULE, CSSFontFaceRule) \
+ V(CSSIMPORTRULE, CSSImportRule) \
+ V(CSSMEDIARULE, CSSMediaRule) \
+ V(CSSPAGERULE, CSSPageRule) \
+ V(CSSPRIMITIVEVALUE, CSSPrimitiveValue) \
+ V(CSSRULE, CSSRule) \
+ V(CSSRULELIST, CSSRuleList) \
+ V(CSSSTYLEDECLARATION, CSSStyleDeclaration) \
+ V(CSSSTYLERULE, CSSStyleRule) \
+ V(CSSSTYLESHEET, CSSStyleSheet) \
+ V(CSSVALUE, CSSValue) \
+ V(CSSVALUELIST, CSSValueList) \
+ V(CSSVARIABLESDECLARATION, CSSVariablesDeclaration) \
+ V(CSSVARIABLESRULE, CSSVariablesRule) \
+ V(DOMCOREEXCEPTION, DOMCoreException) \
+ V(DOMIMPLEMENTATION, DOMImplementation) \
+ V(DOMPARSER, DOMParser) \
+ V(DOMSELECTION, DOMSelection) \
+ V(DOMWINDOW, DOMWindow) \
+ V(EVENT, Event) \
+ V(EVENTEXCEPTION, EventException) \
+ V(FILE, File) \
+ V(FILELIST, FileList) \
+ V(HISTORY, History) \
+ V(HTMLALLCOLLECTION, HTMLAllCollection) \
+ V(HTMLCOLLECTION, HTMLCollection) \
+ V(HTMLOPTIONSCOLLECTION, HTMLOptionsCollection) \
+ V(IMAGEDATA, ImageData) \
+ V(CANVASPIXELARRAY, CanvasPixelArray) \
+ V(INSPECTORBACKEND, InspectorBackend) \
+ V(KEYBOARDEVENT, KeyboardEvent) \
+ V(LOCATION, Location) \
+ V(MEDIA, Media) \
+ V(MEDIALIST, MediaList)
+
+#define DOM_OBJECT_TYPES_2(V) \
+ V(MESSAGECHANNEL, MessageChannel) \
+ V(MESSAGEEVENT, MessageEvent) \
+ V(MIMETYPE, MimeType) \
+ V(MIMETYPEARRAY, MimeTypeArray) \
+ V(MOUSEEVENT, MouseEvent) \
+ V(MUTATIONEVENT, MutationEvent) \
+ V(NAMEDNODEMAP, NamedNodeMap) \
+ V(NAVIGATOR, Navigator) \
+ V(NODEFILTER, NodeFilter) \
+ V(NODEITERATOR, NodeIterator) \
+ V(NODELIST, NodeList) \
+ V(OVERFLOWEVENT, OverflowEvent) \
+ V(PLUGIN, Plugin) \
+ V(PLUGINARRAY, PluginArray) \
+ V(PROGRESSEVENT, ProgressEvent) \
+ V(RANGE, Range) \
+ V(RANGEEXCEPTION, RangeException) \
+ V(RECT, Rect) \
+ V(RGBCOLOR, RGBColor) \
+ V(SCREEN, Screen) \
+ V(STYLESHEET, StyleSheet) \
+ V(STYLESHEETLIST, StyleSheetList) \
+ V(TEXTEVENT, TextEvent) \
+ V(TEXTMETRICS, TextMetrics) \
+ V(TREEWALKER, TreeWalker) \
+ V(UIEVENT, UIEvent) \
+ V(VALIDITYSTATE, ValidityState) \
+ V(WEBKITANIMATIONEVENT, WebKitAnimationEvent) \
+ V(WEBKITCSSKEYFRAMERULE, WebKitCSSKeyframeRule) \
+ V(WEBKITCSSKEYFRAMESRULE, WebKitCSSKeyframesRule) \
+ V(WEBKITCSSMATRIX, WebKitCSSMatrix) \
+ V(WEBKITPOINT, WebKitPoint) \
+ V(WEBKITCSSTRANSFORMVALUE, WebKitCSSTransformValue) \
+ V(WEBKITTRANSITIONEVENT, WebKitTransitionEvent) \
+ V(WHEELEVENT, WheelEvent) \
+ V(XMLHTTPREQUESTUPLOAD, XMLHttpRequestUpload) \
+ V(XMLHTTPREQUESTEXCEPTION, XMLHttpRequestException) \
+ V(XMLHTTPREQUESTPROGRESSEVENT, XMLHttpRequestProgressEvent) \
+ V(XMLSERIALIZER, XMLSerializer) \
+ V(XPATHEVALUATOR, XPathEvaluator) \
+ V(XPATHEXCEPTION, XPathException) \
+ V(XPATHEXPRESSION, XPathExpression) \
+ V(XPATHNSRESOLVER, XPathNSResolver) \
+ V(XPATHRESULT, XPathResult) \
+ V(XSLTPROCESSOR, XSLTProcessor) \
+ ACTIVE_DOM_OBJECT_TYPES(V) \
+ APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
+ DATAGRID_NONNODE_TYPES(V) \
+ VIDEO_NONNODE_TYPES(V) \
+ SHARED_WORKER_NONNODE_WRAPPER_TYPES(V) \
+ WORKER_NONNODE_WRAPPER_TYPES(V)
+
+#if ENABLE(DATABASE)
+#define DOM_OBJECT_DATABASE_TYPES(V) \
+ V(DATABASE, Database) \
+ V(SQLERROR, SQLError) \
+ V(SQLRESULTSET, SQLResultSet) \
+ V(SQLRESULTSETROWLIST, SQLResultSetRowList) \
+ V(SQLTRANSACTION, SQLTransaction)
+#else
+#define DOM_OBJECT_DATABASE_TYPES(V)
+#endif
+
+#if ENABLE(DOM_STORAGE)
+#define DOM_OBJECT_STORAGE_TYPES(V) \
+ V(STORAGE, Storage) \
+ V(STORAGEEVENT, StorageEvent)
+#else
+#define DOM_OBJECT_STORAGE_TYPES(V)
+#endif
+
+#if ENABLE(WORKERS)
+#define DOM_OBJECT_WORKERS_TYPES(V) \
+ V(ERROREVENT, ErrorEvent)
+#else
+#define DOM_OBJECT_WORKERS_TYPES(V)
+#endif
+
+#define DOM_OBJECT_TYPES(V) \
+ DOM_OBJECT_TYPES_1(V) \
+ DOM_OBJECT_TYPES_2(V) \
+ DOM_OBJECT_DATABASE_TYPES(V) \
+ DOM_OBJECT_STORAGE_TYPES(V) \
+ DOM_OBJECT_WORKERS_TYPES(V)
+
+#if ENABLE(SVG)
+// SVG_OBJECT_TYPES are svg non-node, non-pod types.
+#define SVG_OBJECT_TYPES(V) \
+ V(SVGANGLE, SVGAngle) \
+ V(SVGANIMATEDANGLE, SVGAnimatedAngle) \
+ V(SVGANIMATEDBOOLEAN, SVGAnimatedBoolean) \
+ V(SVGANIMATEDENUMERATION, SVGAnimatedEnumeration) \
+ V(SVGANIMATEDINTEGER, SVGAnimatedInteger) \
+ V(SVGANIMATEDLENGTH, SVGAnimatedLength) \
+ V(SVGANIMATEDLENGTHLIST, SVGAnimatedLengthList) \
+ V(SVGANIMATEDNUMBER, SVGAnimatedNumber) \
+ V(SVGANIMATEDNUMBERLIST, SVGAnimatedNumberList) \
+ V(SVGANIMATEDPRESERVEASPECTRATIO, SVGAnimatedPreserveAspectRatio) \
+ V(SVGANIMATEDRECT, SVGAnimatedRect) \
+ V(SVGANIMATEDSTRING, SVGAnimatedString) \
+ V(SVGANIMATEDTRANSFORMLIST, SVGAnimatedTransformList) \
+ V(SVGCOLOR, SVGColor) \
+ V(SVGELEMENTINSTANCE, SVGElementInstance) \
+ V(SVGELEMENTINSTANCELIST, SVGElementInstanceList) \
+ V(SVGEXCEPTION, SVGException) \
+ V(SVGLENGTHLIST, SVGLengthList) \
+ V(SVGNUMBERLIST, SVGNumberList) \
+ V(SVGPAINT, SVGPaint) \
+ V(SVGPATHSEG, SVGPathSeg) \
+ V(SVGPATHSEGARCABS, SVGPathSegArcAbs) \
+ V(SVGPATHSEGARCREL, SVGPathSegArcRel) \
+ V(SVGPATHSEGCLOSEPATH, SVGPathSegClosePath) \
+ V(SVGPATHSEGCURVETOCUBICABS, SVGPathSegCurvetoCubicAbs) \
+ V(SVGPATHSEGCURVETOCUBICREL, SVGPathSegCurvetoCubicRel) \
+ V(SVGPATHSEGCURVETOCUBICSMOOTHABS, SVGPathSegCurvetoCubicSmoothAbs) \
+ V(SVGPATHSEGCURVETOCUBICSMOOTHREL, SVGPathSegCurvetoCubicSmoothRel) \
+ V(SVGPATHSEGCURVETOQUADRATICABS, SVGPathSegCurvetoQuadraticAbs) \
+ V(SVGPATHSEGCURVETOQUADRATICREL, SVGPathSegCurvetoQuadraticRel) \
+ V(SVGPATHSEGCURVETOQUADRATICSMOOTHABS, SVGPathSegCurvetoQuadraticSmoothAbs)\
+ V(SVGPATHSEGCURVETOQUADRATICSMOOTHREL, SVGPathSegCurvetoQuadraticSmoothRel)\
+ V(SVGPATHSEGLINETOABS, SVGPathSegLinetoAbs) \
+ V(SVGPATHSEGLINETOHORIZONTALABS, SVGPathSegLinetoHorizontalAbs) \
+ V(SVGPATHSEGLINETOHORIZONTALREL, SVGPathSegLinetoHorizontalRel) \
+ V(SVGPATHSEGLINETOREL, SVGPathSegLinetoRel) \
+ V(SVGPATHSEGLINETOVERTICALABS, SVGPathSegLinetoVerticalAbs) \
+ V(SVGPATHSEGLINETOVERTICALREL, SVGPathSegLinetoVerticalRel) \
+ V(SVGPATHSEGLIST, SVGPathSegList) \
+ V(SVGPATHSEGMOVETOABS, SVGPathSegMovetoAbs) \
+ V(SVGPATHSEGMOVETOREL, SVGPathSegMovetoRel) \
+ V(SVGPOINTLIST, SVGPointList) \
+ V(SVGPRESERVEASPECTRATIO, SVGPreserveAspectRatio) \
+ V(SVGRENDERINGINTENT, SVGRenderingIntent) \
+ V(SVGSTRINGLIST, SVGStringList) \
+ V(SVGTRANSFORMLIST, SVGTransformList) \
+ V(SVGUNITTYPES, SVGUnitTypes) \
+ V(SVGZOOMEVENT, SVGZoomEvent)
+
+// SVG POD types should list all types whose IDL has PODType declaration.
+#define SVG_POD_TYPES(V) \
+ V(SVGLENGTH, SVGLength) \
+ V(SVGTRANSFORM, SVGTransform) \
+ V(SVGMATRIX, SVGMatrix) \
+ V(SVGNUMBER, SVGNumber) \
+ V(SVGPOINT, SVGPoint) \
+ V(SVGRECT, SVGRect)
+
+// POD types can have different implementation names, see CodeGenerateV8.pm.
+#define SVG_POD_NATIVE_TYPES(V) \
+ V(SVGLENGTH, SVGLength) \
+ V(SVGTRANSFORM, SVGTransform) \
+ V(SVGMATRIX, TransformationMatrix) \
+ V(SVGNUMBER, float) \
+ V(SVGPOINT, FloatPoint) \
+ V(SVGRECT, FloatRect)
+
+// Shouldn't generate code for these two types.
+#define SVG_NO_WRAPPER_TYPES(V) \
+ V(SVGURIREFERENCE, SVGURIReference) \
+ V(SVGANIMATEDPOINTS, SVGAnimatedPoints)
+
+// SVG_NONNODE_TYPES are SVG non-node object types, pod typs and
+// numerical types.
+#define SVG_NONNODE_TYPES(V) \
+ SVG_OBJECT_TYPES(V) \
+ SVG_POD_TYPES(V)
+#endif // SVG
+
+// EVENTTARGET, EVENTLISTENER, and NPOBJECT do not have V8 wrappers.
+#define DOM_NO_WRAPPER_TYPES(V) \
+ V(EVENTTARGET, EventTarget) \
+ V(EVENTLISTENER, EventListener) \
+ V(NPOBJECT, NPObject)
+
+#if ENABLE(SVG)
+#define WRAPPER_TYPES(V) DOM_NODE_TYPES(V) DOM_OBJECT_TYPES(V) SVG_NODE_TYPES(V) SVG_NONNODE_TYPES(V)
+#define NO_WRAPPER_TYPES(V) DOM_NO_WRAPPER_TYPES(V) SVG_NO_WRAPPER_TYPES(V)
+#else // SVG
+#define WRAPPER_TYPES(V) DOM_NODE_TYPES(V) DOM_OBJECT_TYPES(V)
+#define NO_WRAPPER_TYPES(V) DOM_NO_WRAPPER_TYPES(V)
+#endif // SVG
+
+#define ALL_WRAPPER_TYPES(V) WRAPPER_TYPES(V) NO_WRAPPER_TYPES(V)
+
+ class V8ClassIndex {
+ public:
+ // Type must start at non-negative numbers. See ToInt, FromInt.
+ enum V8WrapperType {
+ INVALID_CLASS_INDEX = 0,
+
+#define DEFINE_ENUM(name, type) name,
+ ALL_WRAPPER_TYPES(DEFINE_ENUM)
+#undef DEFINE_ENUM
+
+ CLASSINDEX_END,
+ WRAPPER_TYPE_COUNT = CLASSINDEX_END
+ };
+
+ // FIXME: Convert to toInt after all the bindings are in one place.
+ static int ToInt(V8WrapperType type) { return static_cast<int>(type); }
+
+ // FIXME: Convert to fromInt after all the bindings are in one place.
+ static V8WrapperType FromInt(int v) {
+ ASSERT(INVALID_CLASS_INDEX <= v && v < CLASSINDEX_END);
+ return static_cast<V8WrapperType>(v);
+ }
+
+ // FIXME: Convert to getFactory after all the bindings are in one place.
+ static FunctionTemplateFactory GetFactory(V8WrapperType type);
+
+ // Returns a field to be used as cache for the template for the given type
+ // FIXME: Convert to getCache after all the bindings are in one place.
+ static v8::Persistent<v8::FunctionTemplate>* GetCache(V8WrapperType type);
+ };
+
+}
#endif // V8Index_h
diff --git a/WebCore/bindings/v8/V8IsolatedWorld.cpp b/WebCore/bindings/v8/V8IsolatedWorld.cpp
new file mode 100644
index 0000000..1457545
--- /dev/null
+++ b/WebCore/bindings/v8/V8IsolatedWorld.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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 "V8IsolatedWorld.h"
+
+#include <v8.h>
+
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "HashMap.h"
+#include "ScriptController.h"
+#include "V8DOMWindow.h"
+#include "V8HiddenPropertyName.h"
+
+namespace WebCore {
+
+static int isolatedWorldCount = 0;
+
+static void contextWeakReferenceCallback(v8::Persistent<v8::Value> object, void* isolated_world)
+{
+ // Our context is going away. Time to clean up the world.
+ V8IsolatedWorld* world = static_cast<V8IsolatedWorld*>(isolated_world);
+ delete world;
+}
+
+void V8IsolatedWorld::evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy* proxy, int extensionGroup)
+{
+ v8::HandleScope scope;
+ v8::Persistent<v8::Context> context = proxy->createNewContext(v8::Handle<v8::Object>(), extensionGroup);
+
+ // Run code in the new context.
+ v8::Context::Scope context_scope(context);
+
+ // The lifetime of this object is controlled by the V8 GC.
+ // We need to create the world before touching DOM wrappers.
+ V8IsolatedWorld* world = new V8IsolatedWorld(context);
+
+ V8Proxy::installHiddenObjectPrototype(context);
+ proxy->installDOMWindow(context, proxy->frame()->domWindow());
+
+ proxy->frame()->loader()->client()->didCreateIsolatedScriptContext();
+
+ for (size_t i = 0; i < sources.size(); ++i)
+ proxy->evaluate(sources[i], 0);
+
+ // Using the default security token means that the canAccess is always
+ // called, which is slow.
+ // FIXME: Use tokens where possible. This will mean keeping track of all
+ // created contexts so that they can all be updated when the
+ // document domain
+ // changes.
+ // FIXME: Move this statement above proxy->evaluate? It seems like we
+ // should set up the token before running the script.
+ context->UseDefaultSecurityToken();
+
+ context.Dispose();
+ // WARNING! This might well delete |world|.
+}
+
+V8IsolatedWorld::V8IsolatedWorld(v8::Handle<v8::Context> context)
+ : m_context(v8::Persistent<v8::Context>::New(context))
+{
+ ++isolatedWorldCount;
+ m_context.MakeWeak(this, &contextWeakReferenceCallback);
+ m_context->Global()->SetHiddenValue(V8HiddenPropertyName::isolatedWorld(), v8::External::Wrap(this));
+}
+
+V8IsolatedWorld::~V8IsolatedWorld()
+{
+ --isolatedWorldCount;
+ m_context.Dispose();
+ m_context.Clear();
+}
+
+V8IsolatedWorld* V8IsolatedWorld::getEntered()
+{
+ if (isolatedWorldCount == 0) {
+ // This is a temporary performance optimization. Essentially,
+ // GetHiddenValue is too slow for this code path. We need to get the
+ // V8 team to add a real property to v8::Context for isolated worlds.
+ // Until then, we optimize the common case of not having any isolated
+ // worlds at all.
+ return 0;
+ }
+
+ if (!v8::Context::InContext())
+ return 0;
+ v8::HandleScope scope;
+
+ v8::Local<v8::Value> world = v8::Context::GetEntered()->Global()->GetHiddenValue(V8HiddenPropertyName::isolatedWorld());
+ if (world.IsEmpty())
+ return 0;
+
+ return static_cast<V8IsolatedWorld*>(v8::External::Unwrap(world));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8IsolatedWorld.h b/WebCore/bindings/v8/V8IsolatedWorld.h
new file mode 100644
index 0000000..2036e65
--- /dev/null
+++ b/WebCore/bindings/v8/V8IsolatedWorld.h
@@ -0,0 +1,98 @@
+/*
+ * 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 V8IsolatedWorld_h
+#define V8IsolatedWorld_h
+
+#include <v8.h>
+
+#include "V8DOMMap.h"
+#include "V8Index.h"
+#include "V8Utilities.h"
+#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
+
+namespace WebCore {
+
+ class V8Proxy;
+
+ // V8IsolatedWorld
+ //
+ // V8IsolatedWorld represents a isolated execution environment for
+ // JavaScript. Each isolated world executes in parallel with the main
+ // JavaScript world. An isolated world has access to the same DOM data
+ // structures as the main world but none of the JavaScript pointers.
+ //
+ // It is an error to ever share a JavaScript pointer between two isolated
+ // worlds or between an isolated world and the main world. Because
+ // isolated worlds have access to the DOM, they need their own DOM wrappers
+ // to avoid having pointers to the main world's DOM wrappers (which are
+ // JavaScript objects).
+ //
+ class V8IsolatedWorld {
+ public:
+ ~V8IsolatedWorld();
+
+ // Evaluate JavaScript in a new isolated world. The script has access
+ // to the DOM of the document associated with |proxy|.
+ static void evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy* proxy, int extensionGroup);
+
+ // Returns the isolated world associated with
+ // v8::Context::GetEntered(). Because worlds are isolated, the entire
+ // JavaScript call stack should be from the same isolated world.
+ // Returns NULL if the entered context is from the main world.
+ //
+ // FIXME: Consider edge cases with DOM mutation events that might
+ // violate this invariant.
+ //
+ static V8IsolatedWorld* getEntered();
+
+ v8::Handle<v8::Context> context() { return m_context; }
+
+ DOMDataStore* getDOMDataStore() const { return m_domDataStore.getStore(); }
+
+ private:
+ // The lifetime of an isolated world is managed by the V8 garbage
+ // collector. In particular, the object created by this constructor is
+ // freed when |context| is garbage collected.
+ explicit V8IsolatedWorld(v8::Handle<v8::Context> context);
+
+ // The v8::Context for the isolated world. This object is keep on the
+ // heap as long as |m_context| has not been garbage collected.
+ v8::Persistent<v8::Context> m_context;
+
+ // The backing store for the isolated world's DOM wrappers. This class
+ // doesn't have visibility into the wrappers. This handle simply helps
+ // manage their lifetime.
+ DOMDataStoreHandle m_domDataStore;
+ };
+
+} // namespace WebCore
+
+#endif // V8IsolatedWorld_h
diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp
index f0e81de..59fa7be 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.cpp
+++ b/WebCore/bindings/v8/V8LazyEventListener.cpp
@@ -54,7 +54,7 @@ V8LazyEventListener::~V8LazyEventListener()
// Dispose wrapped function
if (!m_wrappedFunction.IsEmpty()) {
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_wrappedFunction);
+ V8GCController::unregisterGlobalHandle(this, m_wrappedFunction);
#endif
m_wrappedFunction.Dispose();
m_wrappedFunction.Clear();
@@ -77,12 +77,12 @@ v8::Local<v8::Function> V8LazyEventListener::getListenerFunction()
v8::HandleScope handleScope;
// Use the outer scope to hold context.
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
// Bail out if we could not get the context.
- if (context.IsEmpty())
+ if (v8Context.IsEmpty())
return v8::Local<v8::Function>();
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
// 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.
@@ -102,19 +102,19 @@ v8::Local<v8::Function> V8LazyEventListener::getListenerFunction()
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);
+ 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);
+ 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()));
+ 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);
+ V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
#endif
}
}
@@ -134,7 +134,7 @@ v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Va
v8::Handle<v8::Value> parameters[1] = { jsEvent };
V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- return proxy->CallFunction(handlerFunction, receiver, 1, parameters);
+ return proxy->callFunction(handlerFunction, receiver, 1, parameters);
}
@@ -158,12 +158,12 @@ v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction()
v8::HandleScope handleScope;
// Use the outer scope to hold context.
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame);
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
// Bail out if we cannot get the context.
- if (context.IsEmpty())
+ if (v8Context.IsEmpty())
return v8::Local<v8::Function>();
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
// FIXME: cache the wrapper function.
@@ -184,11 +184,11 @@ v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction()
// Insert '\n' otherwise //-style comments could break the handler.
code.append( "\n}).call(this, evt);}}}})");
v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
- v8::Handle<v8::Script> script = V8Proxy::CompileScript(codeExternalString, m_frame->document()->url(), m_lineNumber);
+ v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_frame->document()->url(), m_lineNumber);
if (!script.IsEmpty()) {
V8Proxy* proxy = V8Proxy::retrieve(m_frame);
ASSERT(proxy);
- v8::Local<v8::Value> value = proxy->RunScript(script, false);
+ v8::Local<v8::Value> value = proxy->runScript(script, false);
if (!value.IsEmpty()) {
ASSERT(value->IsFunction());
@@ -218,7 +218,7 @@ v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction()
}
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction);
+ V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction);
#endif
m_wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
}
diff --git a/WebCore/bindings/v8/V8NPObject.cpp b/WebCore/bindings/v8/V8NPObject.cpp
new file mode 100644
index 0000000..b6bf0f7
--- /dev/null
+++ b/WebCore/bindings/v8/V8NPObject.cpp
@@ -0,0 +1,351 @@
+/*
+* 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 "V8NPObject.h"
+
+#include "HTMLPlugInElement.h"
+#include "NPV8Object.h"
+#include "V8CustomBinding.h"
+#include "V8DOMMap.h"
+#include "V8HTMLAppletElement.h"
+#include "V8HTMLEmbedElement.h"
+#include "V8HTMLObjectElement.h"
+#include "V8Helpers.h"
+#include "V8NPUtils.h"
+#include "V8Proxy.h"
+#include "npruntime_impl.h"
+#include "npruntime_priv.h"
+#include "wtf/OwnArrayPtr.h"
+
+using namespace WebCore;
+
+enum InvokeFunctionType {
+ InvokeMethod = 1,
+ InvokeConstruct = 2,
+ InvokeDefault = 3
+};
+
+// FIXME: need comments.
+// Params: holder could be HTMLEmbedElement or NPObject
+static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, InvokeFunctionType functionId)
+{
+ NPObject* npObject;
+
+ // These three types are subtypes of HTMLPlugInElement.
+ if (V8HTMLAppletElement::HasInstance(args.Holder()) || V8HTMLEmbedElement::HasInstance(args.Holder())
+ || V8HTMLObjectElement::HasInstance(args.Holder())) {
+ // The holder object is a subtype of HTMLPlugInElement.
+ HTMLPlugInElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLPlugInElement>(args.Holder());
+ ScriptInstance scriptInstance = element->getInstance();
+ if (scriptInstance)
+ npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, scriptInstance->instance());
+ else
+ npObject = 0;
+ } else {
+ // The holder object is not a subtype of HTMLPlugInElement, it must be an NPObject which has three
+ // internal fields.
+ if (args.Holder()->InternalFieldCount() != V8Custom::kNPObjectInternalFieldCount)
+ return throwError("NPMethod called on non-NPObject", V8Proxy::ReferenceError);
+
+ npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, args.Holder());
+ }
+
+ // Verify that our wrapper wasn't using a NPObject which has already been deleted.
+ if (!npObject || !_NPN_IsAlive(npObject))
+ return throwError("NPObject deleted", V8Proxy::ReferenceError);
+
+ // Wrap up parameters.
+ int numArgs = args.Length();
+ OwnArrayPtr<NPVariant> npArgs(new NPVariant[numArgs]);
+
+ for (int i = 0; i < numArgs; i++)
+ convertV8ObjectToNPVariant(args[i], npObject, &npArgs[i]);
+
+ NPVariant result;
+ VOID_TO_NPVARIANT(result);
+
+ switch (functionId) {
+ case InvokeMethod:
+ if (npObject->_class->invoke) {
+ v8::Handle<v8::String> functionName(v8::String::Cast(*args.Data()));
+ NPIdentifier identifier = getStringIdentifier(functionName);
+ npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result);
+ }
+ break;
+ case InvokeConstruct:
+ if (npObject->_class->construct)
+ npObject->_class->construct(npObject, npArgs.get(), numArgs, &result);
+ break;
+ case InvokeDefault:
+ if (npObject->_class->invokeDefault)
+ npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result);
+ break;
+ default:
+ break;
+ }
+
+ for (int i=0; i < numArgs; i++)
+ _NPN_ReleaseVariantValue(&npArgs[i]);
+
+ // Unwrap return values.
+ v8::Handle<v8::Value> returnValue = convertNPVariantToV8Object(&result, npObject);
+ _NPN_ReleaseVariantValue(&result);
+
+ return returnValue;
+}
+
+
+v8::Handle<v8::Value> npObjectMethodHandler(const v8::Arguments& args)
+{
+ return npObjectInvokeImpl(args, InvokeMethod);
+}
+
+
+v8::Handle<v8::Value> npObjectInvokeDefaultHandler(const v8::Arguments& args)
+{
+ if (args.IsConstructCall())
+ return npObjectInvokeImpl(args, InvokeConstruct);
+ else
+ return npObjectInvokeImpl(args, InvokeDefault);
+}
+
+
+static void weakTemplateCallback(v8::Persistent<v8::Value>, void* parameter);
+
+// NPIdentifier is PrivateIdentifier*.
+static WeakReferenceMap<PrivateIdentifier, v8::FunctionTemplate> staticTemplateMap(&weakTemplateCallback);
+
+static void weakTemplateCallback(v8::Persistent<v8::Value> object, void* parameter)
+{
+ PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(parameter);
+ ASSERT(identifier);
+ ASSERT(staticTemplateMap.contains(identifier));
+
+ staticTemplateMap.forget(identifier);
+}
+
+
+static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> key)
+{
+ NPObject* npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, self);
+
+ // Verify that our wrapper wasn't using a NPObject which
+ // has already been deleted.
+ if (!npObject || !_NPN_IsAlive(npObject))
+ return throwError("NPObject deleted", V8Proxy::ReferenceError);
+
+
+ if (npObject->_class->hasProperty && npObject->_class->hasProperty(npObject, identifier)
+ && npObject->_class->getProperty) {
+
+ NPVariant result;
+ VOID_TO_NPVARIANT(result);
+ if (!npObject->_class->getProperty(npObject, identifier, &result))
+ return v8::Handle<v8::Value>();
+
+ v8::Handle<v8::Value> returnValue = convertNPVariantToV8Object(&result, npObject);
+ _NPN_ReleaseVariantValue(&result);
+ return returnValue;
+
+ } else if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) {
+ PrivateIdentifier* id = static_cast<PrivateIdentifier*>(identifier);
+ v8::Persistent<v8::FunctionTemplate> functionTemplate = staticTemplateMap.get(id);
+ // Cache templates using identifier as the key.
+ if (functionTemplate.IsEmpty()) {
+ // Create a new template.
+ v8::Local<v8::FunctionTemplate> temp = v8::FunctionTemplate::New();
+ temp->SetCallHandler(npObjectMethodHandler, key);
+ functionTemplate = v8::Persistent<v8::FunctionTemplate>::New(temp);
+ staticTemplateMap.set(id, functionTemplate);
+ }
+
+ // FunctionTemplate caches function for each context.
+ v8::Local<v8::Function> v8Function = functionTemplate->GetFunction();
+ v8Function->SetName(v8::Handle<v8::String>::Cast(key));
+ return v8Function;
+ }
+
+ return v8::Handle<v8::Value>();
+}
+
+v8::Handle<v8::Value> npObjectNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
+{
+ NPIdentifier identifier = getStringIdentifier(name);
+ return npObjectGetProperty(info.Holder(), identifier, name);
+}
+
+v8::Handle<v8::Value> npObjectIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
+{
+ NPIdentifier identifier = _NPN_GetIntIdentifier(index);
+ return npObjectGetProperty(info.Holder(), identifier, v8::Number::New(index));
+}
+
+v8::Handle<v8::Value> npObjectGetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name)
+{
+ NPIdentifier identifier = getStringIdentifier(name);
+ return npObjectGetProperty(self, identifier, name);
+}
+
+v8::Handle<v8::Value> npObjectGetIndexedProperty(v8::Local<v8::Object> self, uint32_t index)
+{
+ NPIdentifier identifier = _NPN_GetIntIdentifier(index);
+ return npObjectGetProperty(self, identifier, v8::Number::New(index));
+}
+
+static v8::Handle<v8::Value> npObjectSetProperty(v8::Local<v8::Object> self, NPIdentifier identifier, v8::Local<v8::Value> value)
+{
+ NPObject* npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, self);
+
+ // Verify that our wrapper wasn't using a NPObject which has already been deleted.
+ if (!npObject || !_NPN_IsAlive(npObject)) {
+ throwError("NPObject deleted", V8Proxy::ReferenceError);
+ return value; // Intercepted, but an exception was thrown.
+ }
+
+ if (npObject->_class->hasProperty && npObject->_class->hasProperty(npObject, identifier)
+ && npObject->_class->setProperty) {
+
+ NPVariant npValue;
+ VOID_TO_NPVARIANT(npValue);
+ convertV8ObjectToNPVariant(value, npObject, &npValue);
+ bool success = npObject->_class->setProperty(npObject, identifier, &npValue);
+ _NPN_ReleaseVariantValue(&npValue);
+ if (success)
+ return value; // Intercept the call.
+ }
+ return notHandledByInterceptor();
+}
+
+
+v8::Handle<v8::Value> npObjectNamedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ NPIdentifier identifier = getStringIdentifier(name);
+ return npObjectSetProperty(info.Holder(), identifier, value);
+}
+
+
+v8::Handle<v8::Value> npObjectIndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+ NPIdentifier identifier = _NPN_GetIntIdentifier(index);
+ return npObjectSetProperty(info.Holder(), identifier, value);
+}
+
+v8::Handle<v8::Value> npObjectSetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name, v8::Local<v8::Value> value)
+{
+ NPIdentifier identifier = getStringIdentifier(name);
+ return npObjectSetProperty(self, identifier, value);
+}
+
+v8::Handle<v8::Value> npObjectSetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, v8::Local<v8::Value> value)
+{
+ NPIdentifier identifier = _NPN_GetIntIdentifier(index);
+ return npObjectSetProperty(self, identifier, value);
+}
+
+
+static void weakNPObjectCallback(v8::Persistent<v8::Value>, void* parameter);
+
+static DOMWrapperMap<NPObject> staticNPObjectMap(&weakNPObjectCallback);
+
+static void weakNPObjectCallback(v8::Persistent<v8::Value> object, void* parameter)
+{
+ NPObject* npObject = static_cast<NPObject*>(parameter);
+ ASSERT(staticNPObjectMap.contains(npObject));
+ ASSERT(npObject);
+
+ // Must remove from our map before calling _NPN_ReleaseObject(). _NPN_ReleaseObject can call ForgetV8ObjectForNPObject, which
+ // uses the table as well.
+ staticNPObjectMap.forget(npObject);
+
+ if (_NPN_IsAlive(npObject))
+ _NPN_ReleaseObject(npObject);
+}
+
+
+v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root)
+{
+ static v8::Persistent<v8::FunctionTemplate> npObjectDesc;
+
+ ASSERT(v8::Context::InContext());
+
+ // If this is a v8 object, just return it.
+ if (object->_class == npScriptObjectClass) {
+ V8NPObject* v8NPObject = reinterpret_cast<V8NPObject*>(object);
+ return v8::Local<v8::Object>::New(v8NPObject->v8Object);
+ }
+
+ // If we've already wrapped this object, just return it.
+ if (staticNPObjectMap.contains(object))
+ return v8::Local<v8::Object>::New(staticNPObjectMap.get(object));
+
+ // FIXME: we should create a Wrapper type as a subclass of JSObject. It has two internal fields, field 0 is the wrapped
+ // pointer, and field 1 is the type. There should be an api function that returns unused type id. The same Wrapper type
+ // can be used by DOM bindings.
+ if (npObjectDesc.IsEmpty()) {
+ npObjectDesc = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+ npObjectDesc->InstanceTemplate()->SetInternalFieldCount(V8Custom::kNPObjectInternalFieldCount);
+ npObjectDesc->InstanceTemplate()->SetNamedPropertyHandler(npObjectNamedPropertyGetter, npObjectNamedPropertySetter);
+ npObjectDesc->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedPropertyGetter, npObjectIndexedPropertySetter);
+ npObjectDesc->InstanceTemplate()->SetCallAsFunctionHandler(npObjectInvokeDefaultHandler);
+ }
+
+ v8::Handle<v8::Function> v8Function = npObjectDesc->GetFunction();
+ v8::Local<v8::Object> value = SafeAllocation::newInstance(v8Function);
+
+ // If we were unable to allocate the instance, we avoid wrapping and registering the NP object.
+ if (value.IsEmpty())
+ return value;
+
+ wrapNPObject(value, object);
+
+ // KJS retains the object as part of its wrapper (see Bindings::CInstance).
+ _NPN_RetainObject(object);
+
+ _NPN_RegisterObject(object, root);
+
+ // Maintain a weak pointer for v8 so we can cleanup the object.
+ v8::Persistent<v8::Object> weakRef = v8::Persistent<v8::Object>::New(value);
+ staticNPObjectMap.set(object, weakRef);
+
+ return value;
+}
+
+void forgetV8ObjectForNPObject(NPObject* object)
+{
+ if (staticNPObjectMap.contains(object)) {
+ v8::HandleScope scope;
+ v8::Persistent<v8::Object> handle(staticNPObjectMap.get(object));
+ V8DOMWrapper::setDOMWrapper(handle, WebCore::V8ClassIndex::NPOBJECT, 0);
+ staticNPObjectMap.forget(object);
+ _NPN_ReleaseObject(object);
+ }
+}
diff --git a/WebCore/bindings/v8/V8NPObject.h b/WebCore/bindings/v8/V8NPObject.h
new file mode 100644
index 0000000..0a759b5
--- /dev/null
+++ b/WebCore/bindings/v8/V8NPObject.h
@@ -0,0 +1,63 @@
+/*
+ * 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 V8NPObject_h
+#define V8NPObject_h
+
+#include <v8.h>
+#include "third_party/npapi/bindings/npruntime.h"
+
+// These functions can be replaced by normal JS operation.
+// Getters
+v8::Handle<v8::Value> npObjectNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo&);
+v8::Handle<v8::Value> npObjectIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo&);
+v8::Handle<v8::Value> npObjectGetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name);
+v8::Handle<v8::Value> npObjectGetIndexedProperty(v8::Local<v8::Object> self, uint32_t index);
+
+// Setters
+v8::Handle<v8::Value> npObjectNamedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value>, const v8::AccessorInfo&);
+v8::Handle<v8::Value> npObjectIndexedPropertySetter(uint32_t index, const v8::AccessorInfo&);
+v8::Handle<v8::Value> npObjectSetNamedProperty(v8::Local<v8::Object> self, v8::Local<v8::String> name, v8::Local<v8::Value>);
+v8::Handle<v8::Value> npObjectSetIndexedProperty(v8::Local<v8::Object> self, uint32_t index, v8::Local<v8::Value>);
+
+v8::Handle<v8::Value> npObjectInvokeDefaultHandler(const v8::Arguments&);
+
+// Get a wrapper for a NPObject.
+// If the object is already wrapped, the pre-existing wrapper will be returned. If the object is not wrapped, wrap it, and
+// give V8 a weak reference to the wrapper which will cleanup when there are no more JS references to the object.
+v8::Local<v8::Object> createV8ObjectForNPObject(NPObject*, NPObject* root);
+
+// Tell V8 to forcibly remove an object.
+// This is used at plugin teardown so that the caller can aggressively unload the plugin library. After calling this
+// function, the persistent handle to the wrapper will be gone, and the wrapped NPObject will be removed so that it
+// cannot be referred to.
+void forgetV8ObjectForNPObject(NPObject*);
+
+#endif // V8NPObject_h
diff --git a/WebCore/bindings/v8/V8NPUtils.cpp b/WebCore/bindings/v8/V8NPUtils.cpp
new file mode 100644
index 0000000..17855d7
--- /dev/null
+++ b/WebCore/bindings/v8/V8NPUtils.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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 "V8NPUtils.h"
+
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "PlatformString.h"
+#undef LOG
+
+#include "NPV8Object.h"
+#include "V8NPObject.h"
+#include "V8Proxy.h"
+#include "npruntime_impl.h"
+#include "npruntime_priv.h"
+
+void convertV8ObjectToNPVariant(v8::Local<v8::Value> object, NPObject* owner, NPVariant* result)
+{
+ VOID_TO_NPVARIANT(*result);
+
+ // It is really the caller's responsibility to deal with the empty handle case because there could be different actions to
+ // take in different contexts.
+ ASSERT(!object.IsEmpty());
+
+ if (object.IsEmpty())
+ return;
+
+ if (object->IsInt32())
+ INT32_TO_NPVARIANT(object->NumberValue(), *result);
+ else if (object->IsNumber())
+ DOUBLE_TO_NPVARIANT(object->NumberValue(), *result);
+ else if (object->IsBoolean())
+ BOOLEAN_TO_NPVARIANT(object->BooleanValue(), *result);
+ else if (object->IsNull())
+ NULL_TO_NPVARIANT(*result);
+ else if (object->IsUndefined())
+ VOID_TO_NPVARIANT(*result);
+ else if (object->IsString()) {
+ v8::String::Utf8Value utf8(object);
+ char* utf8_chars = strdup(*utf8);
+ STRINGN_TO_NPVARIANT(utf8_chars, utf8.length(), *result);
+ } else if (object->IsObject()) {
+ WebCore::DOMWindow* window = WebCore::V8Proxy::retrieveWindow(WebCore::V8Proxy::currentContext());
+ NPObject* npobject = npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(object), window);
+ if (npobject)
+ _NPN_RegisterObject(npobject, owner);
+ OBJECT_TO_NPVARIANT(npobject, *result);
+ }
+}
+
+
+v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant* variant, NPObject* npobject)
+{
+ NPVariantType type = variant->type;
+
+ switch (type) {
+ case NPVariantType_Int32:
+ return v8::Integer::New(NPVARIANT_TO_INT32(*variant));
+ case NPVariantType_Double:
+ return v8::Number::New(NPVARIANT_TO_DOUBLE(*variant));
+ case NPVariantType_Bool:
+ return NPVARIANT_TO_BOOLEAN(*variant) ? v8::True() : v8::False();
+ case NPVariantType_Null:
+ return v8::Null();
+ case NPVariantType_Void:
+ return v8::Undefined();
+ case NPVariantType_String: {
+ NPString src = NPVARIANT_TO_STRING(*variant);
+ return v8::String::New(src.UTF8Characters, src.UTF8Length);
+ }
+ case NPVariantType_Object: {
+ NPObject* obj = NPVARIANT_TO_OBJECT(*variant);
+ if (obj->_class == npScriptObjectClass)
+ return reinterpret_cast<V8NPObject*>(obj)->v8Object;
+ return createV8ObjectForNPObject(obj, npobject);
+ }
+ default:
+ return v8::Undefined();
+ }
+}
+
+// Helper function to create an NPN String Identifier from a v8 string.
+NPIdentifier getStringIdentifier(v8::Handle<v8::String> str)
+{
+ const int kStackBufferSize = 100;
+
+ int bufferLength = str->Utf8Length() + 1;
+ if (bufferLength <= kStackBufferSize) {
+ // Use local stack buffer to avoid heap allocations for small strings. Here we should only use the stack space for
+ // stackBuffer when it's used, not when we use the heap.
+ //
+ // WriteUtf8 is guaranteed to generate a null-terminated string because bufferLength is constructed to be one greater
+ // than the string length.
+ char stackBuffer[kStackBufferSize];
+ str->WriteUtf8(stackBuffer, bufferLength);
+ return _NPN_GetStringIdentifier(stackBuffer);
+ }
+
+ v8::String::Utf8Value utf8(str);
+ return _NPN_GetStringIdentifier(*utf8);
+}
diff --git a/WebCore/bindings/v8/V8NPUtils.h b/WebCore/bindings/v8/V8NPUtils.h
new file mode 100644
index 0000000..82a74b3
--- /dev/null
+++ b/WebCore/bindings/v8/V8NPUtils.h
@@ -0,0 +1,46 @@
+/* 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 V8NPUtils_h
+#define V8NPUtils_h
+
+#include <v8.h>
+#include "third_party/npapi/bindings/npruntime.h"
+
+// Convert a V8 Value of any type (string, bool, object, etc) to a NPVariant.
+void convertV8ObjectToNPVariant(v8::Local<v8::Value>, NPObject*, NPVariant*);
+
+// Convert a NPVariant (string, bool, object, etc) back to a V8 Value. The owner object is the NPObject which relates to the
+// object, if the object is an Object. The created NPObject will be tied to the lifetime of the owner.
+v8::Handle<v8::Value> convertNPVariantToV8Object(const NPVariant*, NPObject*);
+
+// Helper function to create an NPN String Identifier from a v8 string.
+NPIdentifier getStringIdentifier(v8::Handle<v8::String>);
+
+#endif // V8NPUtils_h
diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
index b5ae30c..9f57a44 100644
--- a/WebCore/bindings/v8/V8NodeFilterCondition.cpp
+++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp
@@ -44,14 +44,14 @@ V8NodeFilterCondition::V8NodeFilterCondition(v8::Handle<v8::Value> filter)
: m_filter(v8::Persistent<v8::Value>::New(filter))
{
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(NODE_FILTER, this, m_filter);
+ V8GCController::registerGlobalHandle(NODE_FILTER, this, m_filter);
#endif
}
V8NodeFilterCondition::~V8NodeFilterCondition()
{
#ifndef NDEBUG
- V8Proxy::UnregisterGlobalHandle(this, m_filter);
+ V8GCController::unregisterGlobalHandle(this, m_filter);
#endif
m_filter.Dispose();
m_filter.Clear();
@@ -69,12 +69,12 @@ short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const
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);
+ args[0] = V8DOMWrapper::convertToV8Object(V8ClassIndex::NODE, node);
V8Proxy* proxy = V8Proxy::retrieve();
ASSERT(proxy);
- v8::Handle<v8::Value> result = proxy->CallFunction(callback, object, 1, args.get());
+ v8::Handle<v8::Value> result = proxy->callFunction(callback, object, 1, args.get());
if (exceptionCatcher.HasCaught()) {
state->setException(exceptionCatcher.Exception());
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.cpp b/WebCore/bindings/v8/V8ObjectEventListener.cpp
index 584962a..f10766c 100644
--- a/WebCore/bindings/v8/V8ObjectEventListener.cpp
+++ b/WebCore/bindings/v8/V8ObjectEventListener.cpp
@@ -45,7 +45,7 @@ static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* par
if (frame) {
V8Proxy* proxy = V8Proxy::retrieve(frame);
if (proxy)
- proxy->RemoveObjectEventListener(listener);
+ proxy->objectListeners()->remove(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.
@@ -54,6 +54,23 @@ static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* par
listener->disposeListenerObject();
}
+// An object event listener wrapper only holds a weak reference to the
+// JS function. A strong reference can create a cycle.
+//
+// The lifetime of these objects is bounded by the life time of the JS
+// wrapper of XHR or Node. So we can create a hidden reference from
+// the JS wrapper to to its JS function.
+//
+// (map)
+// XHR or Node <---------- JS_wrapper
+// | (hidden) : ^
+// V V : (may be reachable by closure)
+// V8_listener --------> JS_function
+// (weak) <-- may create a cycle if it is strong
+//
+// The persistent reference is made weak in the constructor of
+// V8ObjectEventListener.
+
V8ObjectEventListener::V8ObjectEventListener(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
: V8EventListener(frame, listener, isInline)
{
@@ -66,7 +83,7 @@ V8ObjectEventListener::~V8ObjectEventListener()
ASSERT(!m_listener.IsEmpty());
V8Proxy* proxy = V8Proxy::retrieve(m_frame);
if (proxy)
- proxy->RemoveObjectEventListener(this);
+ proxy->objectListeners()->remove(this);
}
disposeListenerObject();
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.h b/WebCore/bindings/v8/V8ObjectEventListener.h
index 501bdac..3c5ae10 100644
--- a/WebCore/bindings/v8/V8ObjectEventListener.h
+++ b/WebCore/bindings/v8/V8ObjectEventListener.h
@@ -47,6 +47,8 @@ namespace WebCore {
return adoptRef(new V8ObjectEventListener(frame, listener, isInline));
}
+ virtual bool isObjectListener() const { return true; }
+
private:
V8ObjectEventListener(Frame*, v8::Local<v8::Object> listener, bool isInline);
virtual ~V8ObjectEventListener();
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
new file mode 100644
index 0000000..02bf086
--- /dev/null
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -0,0 +1,1279 @@
+/*
+ * 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 "V8Proxy.h"
+
+#include "ChromiumBridge.h"
+#include "CSSMutableStyleDeclaration.h"
+#include "DOMObjectsInclude.h"
+#include "DocumentLoader.h"
+#include "FrameLoaderClient.h"
+#include "ScriptController.h"
+#include "V8Binding.h"
+#include "V8Collection.h"
+#include "V8ConsoleMessage.h"
+#include "V8CustomBinding.h"
+#include "V8DOMMap.h"
+#include "V8DOMWindow.h"
+#include "V8HiddenPropertyName.h"
+#include "V8Index.h"
+#include "V8IsolatedWorld.h"
+
+#include <algorithm>
+#include <utility>
+#include <v8.h>
+#include <v8-debug.h>
+#include <wtf/Assertions.h>
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnusedParam.h>
+
+namespace WebCore {
+
+v8::Persistent<v8::Context> V8Proxy::m_utilityContext;
+
+// Static list of registered extensions
+V8ExtensionList V8Proxy::m_extensions;
+
+const char* V8Proxy::kContextDebugDataType = "type";
+const char* V8Proxy::kContextDebugDataValue = "value";
+
+void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute* attributes, size_t attributeCount)
+{
+ for (size_t i = 0; i < attributeCount; ++i) {
+ const BatchedAttribute* attribute = &attributes[i];
+ (attribute->onProto ? proto : instance)->SetAccessor(v8::String::New(attribute->name),
+ attribute->getter,
+ attribute->setter,
+ attribute->data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute->data)),
+ attribute->settings,
+ attribute->attribute);
+ }
+}
+
+void batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor, v8::Handle<v8::ObjectTemplate> proto, const BatchedConstant* constants, size_t constantCount)
+{
+ for (size_t i = 0; i < constantCount; ++i) {
+ const BatchedConstant* constant = &constants[i];
+ functionDescriptor->Set(v8::String::New(constant->name), v8::Integer::New(constant->value), v8::ReadOnly);
+ proto->Set(v8::String::New(constant->name), v8::Integer::New(constant->value), v8::ReadOnly);
+ }
+}
+
+typedef HashMap<Node*, v8::Object*> DOMNodeMap;
+typedef HashMap<void*, v8::Object*> DOMObjectMap;
+
+#if ENABLE(SVG)
+// Map of SVG objects with contexts to their contexts
+static HashMap<void*, SVGElement*>& svgObjectToContextMap()
+{
+ typedef HashMap<void*, SVGElement*> SvgObjectToContextMap;
+ DEFINE_STATIC_LOCAL(SvgObjectToContextMap, staticSvgObjectToContextMap, ());
+ return staticSvgObjectToContextMap;
+}
+
+void V8Proxy::setSVGContext(void* object, SVGElement* context)
+{
+ if (!object)
+ return;
+
+ SVGElement* oldContext = svgObjectToContextMap().get(object);
+
+ if (oldContext == context)
+ return;
+
+ if (oldContext)
+ oldContext->deref();
+
+ if (context)
+ context->ref();
+
+ svgObjectToContextMap().set(object, context);
+}
+
+SVGElement* V8Proxy::svgContext(void* object)
+{
+ return svgObjectToContextMap().get(object);
+}
+
+#endif
+
+typedef HashMap<int, v8::FunctionTemplate*> FunctionTemplateMap;
+
+bool AllowAllocation::m_current = false;
+
+void logInfo(Frame* frame, const String& message, const String& url)
+{
+ Page* page = frame->page();
+ if (!page)
+ return;
+ V8ConsoleMessage consoleMessage(message, url, 0);
+ consoleMessage.dispatchNow(page);
+}
+
+enum DelayReporting {
+ ReportLater,
+ ReportNow
+};
+
+static void reportUnsafeAccessTo(Frame* target, DelayReporting delay)
+{
+ ASSERT(target);
+ Document* targetDocument = target->document();
+ if (!targetDocument)
+ return;
+
+ Frame* source = V8Proxy::retrieveFrameForEnteredContext();
+ if (!source || !source->document())
+ return; // Ignore error if the source document is gone.
+
+ Document* sourceDocument = source->document();
+
+ // FIXME: This error message should contain more specifics of why the same
+ // origin check has failed.
+ String str = String::format("Unsafe JavaScript attempt to access frame "
+ "with URL %s from frame with URL %s. "
+ "Domains, protocols and ports must match.\n",
+ targetDocument->url().string().utf8().data(),
+ sourceDocument->url().string().utf8().data());
+
+ // Build a console message with fake source ID and line number.
+ const String kSourceID = "";
+ const int kLineNumber = 1;
+ V8ConsoleMessage message(str, kSourceID, kLineNumber);
+
+ if (delay == ReportNow) {
+ // NOTE: Safari prints the message in the target page, but it seems like
+ // it should be in the source page. Even for delayed messages, we put it in
+ // the source page; see V8ConsoleMessage::processDelayed().
+ message.dispatchNow(source->page());
+ } else {
+ ASSERT(delay == ReportLater);
+ // We cannot safely report the message eagerly, because this may cause
+ // allocations and GCs internally in V8 and we cannot handle that at this
+ // point. Therefore we delay the reporting.
+ message.dispatchLater();
+ }
+}
+
+static void reportUnsafeJavaScriptAccess(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data)
+{
+ Frame* target = V8Custom::GetTargetFrame(host, data);
+ if (target)
+ reportUnsafeAccessTo(target, ReportLater);
+}
+
+static void handleFatalErrorInV8()
+{
+ // FIXME: We temporarily deal with V8 internal error situations
+ // such as out-of-memory by crashing the renderer.
+ CRASH();
+}
+
+static void reportFatalErrorInV8(const char* location, const char* message)
+{
+ // V8 is shutdown, we cannot use V8 api.
+ // The only thing we can do is to disable JavaScript.
+ // FIXME: clean up V8Proxy and disable JavaScript.
+ printf("V8 error: %s (%s)\n", message, location);
+ handleFatalErrorInV8();
+}
+
+V8Proxy::~V8Proxy()
+{
+ clearForClose();
+ destroyGlobal();
+}
+
+void V8Proxy::destroyGlobal()
+{
+ if (!m_global.IsEmpty()) {
+#ifndef NDEBUG
+ V8GCController::unregisterGlobalHandle(this, m_global);
+#endif
+ m_global.Dispose();
+ m_global.Clear();
+ }
+}
+
+static void disconnectEventListenersInList(V8EventListenerList& list)
+{
+ V8EventListenerList::iterator it = list.begin();
+ while (it != list.end()) {
+ (*it)->disconnectFrame();
+ ++it;
+ }
+ list.clear();
+}
+
+void V8Proxy::disconnectEventListeners()
+{
+ disconnectEventListenersInList(m_eventListeners);
+ disconnectEventListenersInList(m_objectListeners);
+}
+
+v8::Handle<v8::Script> V8Proxy::compileScript(v8::Handle<v8::String> code, const String& fileName, int baseLine)
+{
+ const uint16_t* fileNameString = fromWebCoreString(fileName);
+ v8::Handle<v8::String> name = v8::String::New(fileNameString, fileName.length());
+ v8::Handle<v8::Integer> line = v8::Integer::New(baseLine);
+ v8::ScriptOrigin origin(name, line);
+ v8::Handle<v8::Script> script = v8::Script::Compile(code, &origin);
+ return script;
+}
+
+bool V8Proxy::handleOutOfMemory()
+{
+ v8::Local<v8::Context> context = v8::Context::GetCurrent();
+
+ if (!context->HasOutOfMemoryException())
+ return false;
+
+ // Warning, error, disable JS for this frame?
+ Frame* frame = V8Proxy::retrieveFrame(context);
+
+ V8Proxy* proxy = V8Proxy::retrieve(frame);
+ if (proxy) {
+ // Clean m_context, and event handlers.
+ proxy->clearForClose();
+
+ proxy->destroyGlobal();
+ }
+
+ ChromiumBridge::notifyJSOutOfMemory(frame);
+
+ // Disable JS.
+ Settings* settings = frame->settings();
+ ASSERT(settings);
+ settings->setJavaScriptEnabled(false);
+
+ return true;
+}
+
+void V8Proxy::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup)
+{
+ initContextIfNeeded();
+ V8IsolatedWorld::evaluate(sources, this, extensionGroup);
+}
+
+void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int extensionGroup)
+{
+ initContextIfNeeded();
+
+ v8::HandleScope handleScope;
+
+ // Set up the DOM window as the prototype of the new global object.
+ v8::Handle<v8::Context> windowContext = m_context;
+ v8::Handle<v8::Object> windowGlobal = windowContext->Global();
+ v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, windowGlobal);
+
+ ASSERT(V8DOMWrapper::convertDOMWrapperToNative<DOMWindow>(windowWrapper) == m_frame->domWindow());
+
+ v8::Persistent<v8::Context> context = createNewContext(v8::Handle<v8::Object>(), extensionGroup);
+ v8::Context::Scope contextScope(context);
+
+ // Setup context id for JS debugger.
+ v8::Handle<v8::Object> contextData = v8::Object::New();
+ v8::Handle<v8::Value> windowContextData = windowContext->GetData();
+ if (windowContextData->IsObject()) {
+ v8::Handle<v8::String> propertyName = v8::String::New(kContextDebugDataValue);
+ contextData->Set(propertyName, v8::Object::Cast(*windowContextData)->Get(propertyName));
+ }
+ contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("injected"));
+ context->SetData(contextData);
+
+ v8::Handle<v8::Object> global = context->Global();
+
+ v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
+ global->Set(implicitProtoString, windowWrapper);
+
+ // Give the code running in the new context a way to get access to the
+ // original context.
+ global->Set(v8::String::New("contentWindow"), windowGlobal);
+
+ m_frame->loader()->client()->didCreateIsolatedScriptContext();
+
+ // Run code in the new context.
+ for (size_t i = 0; i < sources.size(); ++i)
+ evaluate(sources[i], 0);
+
+ // Using the default security token means that the canAccess is always
+ // called, which is slow.
+ // FIXME: Use tokens where possible. This will mean keeping track of all
+ // created contexts so that they can all be updated when the document domain
+ // changes.
+ context->UseDefaultSecurityToken();
+ context.Dispose();
+}
+
+v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* node)
+{
+ ASSERT(v8::Context::InContext());
+
+ // Compile the script.
+ v8::Local<v8::String> code = v8ExternalString(source.source());
+ ChromiumBridge::traceEventBegin("v8.compile", node, "");
+
+ // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at
+ // 1, whereas v8 starts at 0.
+ v8::Handle<v8::Script> script = compileScript(code, source.url(), source.startLine() - 1);
+ ChromiumBridge::traceEventEnd("v8.compile", node, "");
+
+ ChromiumBridge::traceEventBegin("v8.run", node, "");
+ v8::Local<v8::Value> result;
+ {
+ // Isolate exceptions that occur when executing the code. These
+ // exceptions should not interfere with javascript code we might
+ // evaluate from C++ when returning from here.
+ v8::TryCatch tryCatch;
+ tryCatch.SetVerbose(true);
+
+ // Set inlineCode to true for <a href="javascript:doSomething()">
+ // and false for <script>doSomething</script>. We make a rough guess at
+ // this based on whether the script source has a URL.
+ result = runScript(script, source.url().string().isNull());
+ }
+ ChromiumBridge::traceEventEnd("v8.run", node, "");
+ return result;
+}
+
+v8::Local<v8::Value> V8Proxy::runScript(v8::Handle<v8::Script> script, bool isInlineCode)
+{
+ if (script.IsEmpty())
+ return notHandledByInterceptor();
+
+ // Compute the source string and prevent against infinite recursion.
+ if (m_recursion >= kMaxRecursionDepth) {
+ v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')");
+ // FIXME: Ideally, we should be able to re-use the origin of the
+ // script passed to us as the argument instead of using an empty string
+ // and 0 baseLine.
+ script = compileScript(code, "", 0);
+ }
+
+ if (handleOutOfMemory())
+ ASSERT(script.IsEmpty());
+
+ if (script.IsEmpty())
+ return notHandledByInterceptor();
+
+ // Save the previous value of the inlineCode flag and update the flag for
+ // the duration of the script invocation.
+ bool previousInlineCode = inlineCode();
+ setInlineCode(isInlineCode);
+
+ // Run the script and keep track of the current recursion depth.
+ v8::Local<v8::Value> result;
+ {
+ V8ConsoleMessage::Scope scope;
+ m_recursion++;
+
+ // See comment in V8Proxy::callFunction.
+ m_frame->keepAlive();
+
+ result = script->Run();
+ m_recursion--;
+ }
+
+ if (handleOutOfMemory())
+ ASSERT(result.IsEmpty());
+
+ // Handle V8 internal error situation (Out-of-memory).
+ if (result.IsEmpty())
+ return notHandledByInterceptor();
+
+ // Restore inlineCode flag.
+ setInlineCode(previousInlineCode);
+
+ if (v8::V8::IsDead())
+ handleFatalErrorInV8();
+
+ return result;
+}
+
+v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[])
+{
+ // For now, we don't put any artificial limitations on the depth
+ // of recursion that stems from calling functions. This is in
+ // contrast to the script evaluations.
+ v8::Local<v8::Value> result;
+ {
+ V8ConsoleMessage::Scope scope;
+
+ // Evaluating the JavaScript could cause the frame to be deallocated,
+ // so we start the keep alive timer here.
+ // Frame::keepAlive method adds the ref count of the frame and sets a
+ // timer to decrease the ref count. It assumes that the current JavaScript
+ // execution finishs before firing the timer.
+ m_frame->keepAlive();
+
+ result = function->Call(receiver, argc, args);
+ }
+
+ if (v8::V8::IsDead())
+ handleFatalErrorInV8();
+
+ return result;
+}
+
+v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor, int argc, v8::Handle<v8::Value> args[])
+{
+ // No artificial limitations on the depth of recursion, see comment in
+ // V8Proxy::callFunction.
+ v8::Local<v8::Value> result;
+ {
+ V8ConsoleMessage::Scope scope;
+
+ // See comment in V8Proxy::callFunction.
+ m_frame->keepAlive();
+
+ result = constructor->NewInstance(argc, args);
+ }
+
+ if (v8::V8::IsDead())
+ handleFatalErrorInV8();
+
+ return result;
+}
+
+v8::Local<v8::Object> V8Proxy::createWrapperFromCache(V8ClassIndex::V8WrapperType type)
+{
+ int classIndex = V8ClassIndex::ToInt(type);
+ v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex));
+ if (!clone.IsEmpty())
+ return clone;
+
+ // Not in cache.
+ initContextIfNeeded();
+ v8::Context::Scope scope(m_context);
+ v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(m_context));
+ v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
+ if (!instance.IsEmpty()) {
+ m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance);
+ return instance->Clone();
+ }
+ return notHandledByInterceptor();
+}
+
+bool V8Proxy::isContextInitialized()
+{
+ // m_context, m_global, and m_wrapperBoilerplates should
+ // all be non-empty if if m_context is non-empty.
+ ASSERT(m_context.IsEmpty() || !m_global.IsEmpty());
+ ASSERT(m_context.IsEmpty() || !m_wrapperBoilerplates.IsEmpty());
+ return !m_context.IsEmpty();
+}
+
+DOMWindow* V8Proxy::retrieveWindow(v8::Handle<v8::Context> context)
+{
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+ global = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, global);
+ ASSERT(!global.IsEmpty());
+ return V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, global);
+}
+
+Frame* V8Proxy::retrieveFrame(v8::Handle<v8::Context> context)
+{
+ return retrieveWindow(context)->frame();
+}
+
+Frame* V8Proxy::retrieveFrameForEnteredContext()
+{
+ v8::Handle<v8::Context> context = v8::Context::GetEntered();
+ if (context.IsEmpty())
+ return 0;
+ return retrieveFrame(context);
+}
+
+Frame* V8Proxy::retrieveFrameForCurrentContext()
+{
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ if (context.IsEmpty())
+ return 0;
+ return retrieveFrame(context);
+}
+
+Frame* V8Proxy::retrieveFrameForCallingContext()
+{
+ v8::Handle<v8::Context> context = v8::Context::GetCalling();
+ if (context.IsEmpty())
+ return 0;
+ return retrieveFrame(context);
+}
+
+V8Proxy* V8Proxy::retrieve()
+{
+ DOMWindow* window = retrieveWindow(currentContext());
+ ASSERT(window);
+ return retrieve(window->frame());
+}
+
+V8Proxy* V8Proxy::retrieve(Frame* frame)
+{
+ if (!frame)
+ return 0;
+ return frame->script()->isEnabled() ? frame->script()->proxy() : 0;
+}
+
+V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
+{
+ if (!context->isDocument())
+ return 0;
+ return retrieve(static_cast<Document*>(context)->frame());
+}
+
+void V8Proxy::disconnectFrame()
+{
+ disconnectEventListeners();
+}
+
+bool V8Proxy::isEnabled()
+{
+ Settings* settings = m_frame->settings();
+ if (!settings)
+ return false;
+
+ // In the common case, JavaScript is enabled and we're done.
+ if (settings->isJavaScriptEnabled())
+ return true;
+
+ // If JavaScript has been disabled, we need to look at the frame to tell
+ // whether this script came from the web or the embedder. Scripts from the
+ // embedder are safe to run, but scripts from the other sources are
+ // disallowed.
+ Document* document = m_frame->document();
+ if (!document)
+ return false;
+
+ SecurityOrigin* origin = document->securityOrigin();
+ if (origin->protocol().isEmpty())
+ return false; // Uninitialized document
+
+ if (origin->protocol() == "http" || origin->protocol() == "https")
+ return false; // Web site
+
+ // FIXME: the following are application decisions, and they should
+ // not be made at this layer. instead, we should bridge out to the
+ // embedder to allow them to override policy here.
+
+ if (origin->protocol() == ChromiumBridge::uiResourceProtocol())
+ return true; // Embedder's scripts are ok to run
+
+ // If the scheme is ftp: or file:, an empty file name indicates a directory
+ // listing, which requires JavaScript to function properly.
+ const char* kDirProtocols[] = { "ftp", "file" };
+ for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
+ if (origin->protocol() == kDirProtocols[i]) {
+ const KURL& url = document->url();
+ return url.pathAfterLastSlash() == url.pathEnd();
+ }
+ }
+
+ return false; // Other protocols fall through to here
+}
+
+void V8Proxy::updateDocumentWrapper(v8::Handle<v8::Value> wrapper)
+{
+ clearDocumentWrapper();
+
+ ASSERT(m_document.IsEmpty());
+ m_document = v8::Persistent<v8::Value>::New(wrapper);
+#ifndef NDEBUG
+ V8GCController::registerGlobalHandle(PROXY, this, m_document);
+#endif
+}
+
+void V8Proxy::clearDocumentWrapper()
+{
+ if (!m_document.IsEmpty()) {
+#ifndef NDEBUG
+ V8GCController::unregisterGlobalHandle(this, m_document);
+#endif
+ m_document.Dispose();
+ m_document.Clear();
+ }
+}
+
+void V8Proxy::updateDocumentWrapperCache()
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(context());
+
+ // If the document has no frame, NodeToV8Object might get the
+ // document wrapper for a document that is about to be deleted.
+ // If the ForceSet below causes a garbage collection, the document
+ // might get deleted and the global handle for the document
+ // wrapper cleared. Using the cleared global handle will lead to
+ // crashes. In this case we clear the cache and let the DOMWindow
+ // accessor handle access to the document.
+ if (!m_frame->document()->frame()) {
+ clearDocumentWrapperCache();
+ return;
+ }
+
+ v8::Handle<v8::Value> documentWrapper = V8DOMWrapper::convertNodeToV8Object(m_frame->document());
+
+ // If instantiation of the document wrapper fails, clear the cache
+ // and let the DOMWindow accessor handle access to the document.
+ if (documentWrapper.IsEmpty()) {
+ clearDocumentWrapperCache();
+ return;
+ }
+ m_context->Global()->ForceSet(v8::String::New("document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+}
+
+void V8Proxy::clearDocumentWrapperCache()
+{
+ ASSERT(!m_context.IsEmpty());
+ m_context->Global()->ForceDelete(v8::String::New("document"));
+}
+
+void V8Proxy::disposeContextHandles()
+{
+ if (!m_context.IsEmpty()) {
+ m_frame->loader()->client()->didDestroyScriptContextForFrame();
+ m_context.Dispose();
+ m_context.Clear();
+ }
+
+ if (!m_wrapperBoilerplates.IsEmpty()) {
+#ifndef NDEBUG
+ V8GCController::unregisterGlobalHandle(this, m_wrapperBoilerplates);
+#endif
+ m_wrapperBoilerplates.Dispose();
+ m_wrapperBoilerplates.Clear();
+ }
+}
+
+void V8Proxy::clearForClose()
+{
+ if (!m_context.IsEmpty()) {
+ v8::HandleScope handleScope;
+
+ clearDocumentWrapper();
+ disposeContextHandles();
+ }
+}
+
+void V8Proxy::clearForNavigation()
+{
+ disconnectEventListeners();
+
+ if (!m_context.IsEmpty()) {
+ v8::HandleScope handle;
+ clearDocumentWrapper();
+
+ v8::Context::Scope contextScope(m_context);
+
+ // Clear the document wrapper cache before turning on access checks on
+ // the old DOMWindow wrapper. This way, access to the document wrapper
+ // will be protected by the security checks on the DOMWindow wrapper.
+ clearDocumentWrapperCache();
+
+ // Turn on access check on the old DOMWindow wrapper.
+ v8::Handle<v8::Object> wrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, m_global);
+ ASSERT(!wrapper.IsEmpty());
+ wrapper->TurnOnAccessCheck();
+
+ // Separate the context from its global object.
+ m_context->DetachGlobal();
+
+ disposeContextHandles();
+ }
+}
+
+void V8Proxy::setSecurityToken()
+{
+ Document* document = m_frame->document();
+ // Setup security origin and security token.
+ if (!document) {
+ m_context->UseDefaultSecurityToken();
+ return;
+ }
+
+ // Ask the document's SecurityOrigin to generate a security token.
+ // If two tokens are equal, then the SecurityOrigins canAccess each other.
+ // If two tokens are not equal, then we have to call canAccess.
+ // Note: we can't use the HTTPOrigin if it was set from the DOM.
+ SecurityOrigin* origin = document->securityOrigin();
+ String token;
+ if (!origin->domainWasSetInDOM())
+ token = document->securityOrigin()->toString();
+
+ // An empty or "null" token means we always have to call
+ // canAccess. The toString method on securityOrigins returns the
+ // string "null" for empty security origins and for security
+ // origins that should only allow access to themselves. In this
+ // case, we use the global object as the security token to avoid
+ // calling canAccess when a script accesses its own objects.
+ if (token.isEmpty() || token == "null") {
+ m_context->UseDefaultSecurityToken();
+ return;
+ }
+
+ CString utf8Token = token.utf8();
+ // NOTE: V8 does identity comparison in fast path, must use a symbol
+ // as the security token.
+ m_context->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.length()));
+}
+
+void V8Proxy::updateDocument()
+{
+ if (!m_frame->document())
+ return;
+
+ if (m_global.IsEmpty())
+ return;
+
+ // There is an existing JavaScript wrapper for the global object
+ // of this frame. JavaScript code in other frames might hold a
+ // reference to this wrapper. We eagerly initialize the JavaScript
+ // context for the new document to make property access on the
+ // global object wrapper succeed.
+ initContextIfNeeded();
+
+ // We have a new document and we need to update the cache.
+ updateDocumentWrapperCache();
+
+ updateSecurityOrigin();
+}
+
+void V8Proxy::updateSecurityOrigin()
+{
+ v8::HandleScope scope;
+ setSecurityToken();
+}
+
+// Same origin policy implementation:
+//
+// Same origin policy prevents JS code from domain A access JS & DOM objects
+// in a different domain B. There are exceptions and several objects are
+// accessible by cross-domain code. For example, the window.frames object is
+// accessible by code from a different domain, but window.document is not.
+//
+// The binding code sets security check callbacks on a function template,
+// and accessing instances of the template calls the callback function.
+// The callback function checks same origin policy.
+//
+// Callback functions are expensive. V8 uses a security token string to do
+// fast access checks for the common case where source and target are in the
+// same domain. A security token is a string object that represents
+// the protocol/url/port of a domain.
+//
+// There are special cases where a security token matching is not enough.
+// For example, JavaScript can set its domain to a super domain by calling
+// document.setDomain(...). In these cases, the binding code can reset
+// a context's security token to its global object so that the fast access
+// check will always fail.
+
+// Check if the current execution context can access a target frame.
+// First it checks same domain policy using the lexical context
+//
+// This is equivalent to KJS::Window::allowsAccessFrom(ExecState*, String&).
+bool V8Proxy::canAccessPrivate(DOMWindow* targetWindow)
+{
+ ASSERT(targetWindow);
+
+ String message;
+
+ DOMWindow* originWindow = retrieveWindow(currentContext());
+ if (originWindow == targetWindow)
+ return true;
+
+ if (!originWindow)
+ return false;
+
+ const SecurityOrigin* activeSecurityOrigin = originWindow->securityOrigin();
+ const SecurityOrigin* targetSecurityOrigin = targetWindow->securityOrigin();
+
+ // We have seen crashes were the security origin of the target has not been
+ // initialized. Defend against that.
+ if (!targetSecurityOrigin)
+ return false;
+
+ if (activeSecurityOrigin->canAccess(targetSecurityOrigin))
+ return true;
+
+ // Allow access to a "about:blank" page if the dynamic context is a
+ // detached context of the same frame as the blank page.
+ if (targetSecurityOrigin->isEmpty() && originWindow->frame() == targetWindow->frame())
+ return true;
+
+ return false;
+}
+
+bool V8Proxy::canAccessFrame(Frame* target, bool reportError)
+{
+ // The subject is detached from a frame, deny accesses.
+ if (!target)
+ return false;
+
+ if (!canAccessPrivate(target->domWindow())) {
+ if (reportError)
+ reportUnsafeAccessTo(target, ReportNow);
+ return false;
+ }
+ return true;
+}
+
+bool V8Proxy::checkNodeSecurity(Node* node)
+{
+ if (!node)
+ return false;
+
+ Frame* target = node->document()->frame();
+
+ if (!target)
+ return false;
+
+ return canAccessFrame(target, true);
+}
+
+v8::Persistent<v8::Context> V8Proxy::createNewContext(v8::Handle<v8::Object> global, int extensionGroup)
+{
+ v8::Persistent<v8::Context> result;
+
+ // The activeDocumentLoader pointer could be NULL during frame shutdown.
+ if (!m_frame->loader()->activeDocumentLoader())
+ return result;
+
+ // Create a new environment using an empty template for the shadow
+ // object. Reuse the global object if one has been created earlier.
+ v8::Persistent<v8::ObjectTemplate> globalTemplate = V8DOMWindow::GetShadowObjectTemplate();
+ if (globalTemplate.IsEmpty())
+ return result;
+
+ // Install a security handler with V8.
+ globalTemplate->SetAccessCheckCallbacks(V8Custom::v8DOMWindowNamedSecurityCheck, V8Custom::v8DOMWindowIndexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW));
+
+ // Dynamically tell v8 about our extensions now.
+ OwnArrayPtr<const char*> extensionNames(new const char*[m_extensions.size()]);
+ int index = 0;
+ for (V8ExtensionList::iterator it = m_extensions.begin(); it != m_extensions.end(); ++it) {
+ if (it->group && it->group != extensionGroup)
+ continue;
+
+ // Note: we check the loader URL here instead of the document URL
+ // because we might be currently loading an URL into a blank page.
+ // See http://code.google.com/p/chromium/issues/detail?id=10924
+ if (it->scheme.length() > 0 && (it->scheme != m_frame->loader()->activeDocumentLoader()->url().protocol() || it->scheme != m_frame->page()->mainFrame()->loader()->activeDocumentLoader()->url().protocol()))
+ continue;
+
+ extensionNames[index++] = it->extension->name();
+ }
+ v8::ExtensionConfiguration extensions(index, extensionNames.get());
+ result = v8::Context::New(&extensions, globalTemplate, global);
+
+ return result;
+}
+
+bool V8Proxy::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window)
+{
+ v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__");
+ if (implicitProtoString.IsEmpty())
+ return false;
+
+ // Create a new JS window object and use it as the prototype for the shadow global object.
+ v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(V8ClassIndex::DOMWINDOW, getHiddenObjectPrototype(context));
+ v8::Local<v8::Object> jsWindow = SafeAllocation::newInstance(windowConstructor);
+ // Bail out if allocation failed.
+ if (jsWindow.IsEmpty())
+ return false;
+
+ // Wrap the window.
+ V8DOMWrapper::setDOMWrapper(jsWindow, V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
+
+ window->ref();
+ V8DOMWrapper::setJSWrapperForDOMObject(window, v8::Persistent<v8::Object>::New(jsWindow));
+
+ // Insert the window instance as the prototype of the shadow object.
+ v8::Handle<v8::Object> v8Global = context->Global();
+ v8Global->Set(implicitProtoString, jsWindow);
+ return true;
+}
+
+// Create a new environment and setup the global object.
+//
+// The global object corresponds to a DOMWindow instance. However, to
+// allow properties of the JS DOMWindow instance to be shadowed, we
+// use a shadow object as the global object and use the JS DOMWindow
+// instance as the prototype for that shadow object. The JS DOMWindow
+// instance is undetectable from javascript code because the __proto__
+// accessors skip that object.
+//
+// The shadow object and the DOMWindow instance are seen as one object
+// from javascript. The javascript object that corresponds to a
+// DOMWindow instance is the shadow object. When mapping a DOMWindow
+// instance to a V8 object, we return the shadow object.
+//
+// To implement split-window, see
+// 1) https://bugs.webkit.org/show_bug.cgi?id=17249
+// 2) https://wiki.mozilla.org/Gecko:SplitWindow
+// 3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639
+// we need to split the shadow object further into two objects:
+// an outer window and an inner window. The inner window is the hidden
+// prototype of the outer window. The inner window is the default
+// global object of the context. A variable declared in the global
+// scope is a property of the inner window.
+//
+// The outer window sticks to a Frame, it is exposed to JavaScript
+// via window.window, window.self, window.parent, etc. The outer window
+// has a security token which is the domain. The outer window cannot
+// have its own properties. window.foo = 'x' is delegated to the
+// inner window.
+//
+// When a frame navigates to a new page, the inner window is cut off
+// the outer window, and the outer window identify is preserved for
+// the frame. However, a new inner window is created for the new page.
+// If there are JS code holds a closure to the old inner window,
+// it won't be able to reach the outer window via its global object.
+void V8Proxy::initContextIfNeeded()
+{
+ // Bail out if the context has already been initialized.
+ if (!m_context.IsEmpty())
+ return;
+
+ // Create a handle scope for all local handles.
+ v8::HandleScope handleScope;
+
+ // Setup the security handlers and message listener. This only has
+ // to be done once.
+ static bool isV8Initialized = false;
+ if (!isV8Initialized) {
+ // Tells V8 not to call the default OOM handler, binding code
+ // will handle it.
+ v8::V8::IgnoreOutOfMemoryException();
+ v8::V8::SetFatalErrorHandler(reportFatalErrorInV8);
+
+ v8::V8::SetGlobalGCPrologueCallback(&V8GCController::gcPrologue);
+ v8::V8::SetGlobalGCEpilogueCallback(&V8GCController::gcEpilogue);
+
+ v8::V8::AddMessageListener(&V8ConsoleMessage::handler);
+
+ v8::V8::SetFailedAccessCheckCallbackFunction(reportUnsafeJavaScriptAccess);
+
+ isV8Initialized = true;
+ }
+
+ m_context = createNewContext(m_global, 0);
+ if (m_context.IsEmpty())
+ return;
+
+ // Starting from now, use local context only.
+ v8::Local<v8::Context> v8Context = context();
+ v8::Context::Scope contextScope(v8Context);
+
+ // Store the first global object created so we can reuse it.
+ if (m_global.IsEmpty()) {
+ m_global = v8::Persistent<v8::Object>::New(v8Context->Global());
+ // Bail out if allocation of the first global objects fails.
+ if (m_global.IsEmpty()) {
+ disposeContextHandles();
+ return;
+ }
+#ifndef NDEBUG
+ V8GCController::registerGlobalHandle(PROXY, this, m_global);
+#endif
+ }
+
+ installHiddenObjectPrototype(m_context);
+ m_wrapperBoilerplates = v8::Persistent<v8::Array>::New(v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT));
+ // Bail out if allocation failed.
+ if (m_wrapperBoilerplates.IsEmpty()) {
+ disposeContextHandles();
+ return;
+ }
+#ifndef NDEBUG
+ V8GCController::registerGlobalHandle(PROXY, this, m_wrapperBoilerplates);
+#endif
+
+ if (!installDOMWindow(v8Context, m_frame->domWindow()))
+ disposeContextHandles();
+
+ updateDocument();
+
+ setSecurityToken();
+
+ m_frame->loader()->client()->didCreateScriptContextForFrame();
+ m_frame->loader()->dispatchWindowObjectAvailable();
+}
+
+void V8Proxy::setDOMException(int exceptionCode)
+{
+ if (exceptionCode <= 0)
+ return;
+
+ ExceptionCodeDescription description;
+ getExceptionCodeDescription(exceptionCode, description);
+
+ v8::Handle<v8::Value> exception;
+ switch (description.type) {
+ case DOMExceptionType:
+ exception = V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMCOREEXCEPTION, DOMCoreException::create(description));
+ break;
+ case RangeExceptionType:
+ exception = V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGEEXCEPTION, RangeException::create(description));
+ break;
+ case EventExceptionType:
+ exception = V8DOMWrapper::convertToV8Object(V8ClassIndex::EVENTEXCEPTION, EventException::create(description));
+ break;
+ case XMLHttpRequestExceptionType:
+ exception = V8DOMWrapper::convertToV8Object(V8ClassIndex::XMLHTTPREQUESTEXCEPTION, XMLHttpRequestException::create(description));
+ break;
+#if ENABLE(SVG)
+ case SVGExceptionType:
+ exception = V8DOMWrapper::convertToV8Object(V8ClassIndex::SVGEXCEPTION, SVGException::create(description));
+ break;
+#endif
+#if ENABLE(XPATH)
+ case XPathExceptionType:
+ exception = V8DOMWrapper::convertToV8Object(V8ClassIndex::XPATHEXCEPTION, XPathException::create(description));
+ break;
+#endif
+ }
+
+ ASSERT(!exception.IsEmpty());
+ v8::ThrowException(exception);
+}
+
+v8::Handle<v8::Value> V8Proxy::throwError(ErrorType type, const char* message)
+{
+ switch (type) {
+ case RangeError:
+ return v8::ThrowException(v8::Exception::RangeError(v8String(message)));
+ case ReferenceError:
+ return v8::ThrowException(v8::Exception::ReferenceError(v8String(message)));
+ case SyntaxError:
+ return v8::ThrowException(v8::Exception::SyntaxError(v8String(message)));
+ case TypeError:
+ return v8::ThrowException(v8::Exception::TypeError(v8String(message)));
+ case GeneralError:
+ return v8::ThrowException(v8::Exception::Error(v8String(message)));
+ default:
+ ASSERT_NOT_REACHED();
+ return notHandledByInterceptor();
+ }
+}
+
+v8::Local<v8::Context> V8Proxy::context(Frame* frame)
+{
+ v8::Local<v8::Context> context = V8Proxy::mainWorldContext(frame);
+ if (context.IsEmpty())
+ return v8::Local<v8::Context>();
+
+ if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered()) {
+ context = v8::Local<v8::Context>::New(world->context());
+ if (frame != V8Proxy::retrieveFrame(context))
+ return v8::Local<v8::Context>();
+ }
+
+ return context;
+}
+
+v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
+{
+ V8Proxy* proxy = retrieve(frame);
+ if (!proxy)
+ return v8::Local<v8::Context>();
+
+ proxy->initContextIfNeeded();
+ return proxy->context();
+}
+
+v8::Local<v8::Context> V8Proxy::currentContext()
+{
+ return v8::Context::GetCurrent();
+}
+
+v8::Handle<v8::Value> V8Proxy::checkNewLegal(const v8::Arguments& args)
+{
+ if (!AllowAllocation::m_current)
+ return throwError(TypeError, "Illegal constructor");
+
+ return args.This();
+}
+
+void V8Proxy::bindJsObjectToWindow(Frame* frame, const char* name, int type, v8::Handle<v8::FunctionTemplate> descriptor, void* impl)
+{
+ // Get environment.
+ v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
+ if (v8Context.IsEmpty())
+ return; // JS not enabled.
+
+ v8::Context::Scope scope(v8Context);
+ v8::Handle<v8::Object> instance = descriptor->GetFunction();
+ V8DOMWrapper::setDOMWrapper(instance, type, impl);
+
+ v8::Handle<v8::Object> global = v8Context->Global();
+ global->Set(v8::String::New(name), instance);
+}
+
+void V8Proxy::processConsoleMessages()
+{
+ V8ConsoleMessage::processDelayed();
+}
+
+// Create the utility context for holding JavaScript functions used internally
+// which are not visible to JavaScript executing on the page.
+void V8Proxy::createUtilityContext()
+{
+ ASSERT(m_utilityContext.IsEmpty());
+
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();
+ m_utilityContext = v8::Context::New(0, globalTemplate);
+ v8::Context::Scope contextScope(m_utilityContext);
+
+ // Compile JavaScript function for retrieving the source line of the top
+ // JavaScript stack frame.
+ DEFINE_STATIC_LOCAL(const char*, frameSourceLineSource,
+ ("function frameSourceLine(exec_state) {"
+ " return exec_state.frame(0).sourceLine();"
+ "}"));
+ v8::Script::Compile(v8::String::New(frameSourceLineSource))->Run();
+
+ // Compile JavaScript function for retrieving the source name of the top
+ // JavaScript stack frame.
+ DEFINE_STATIC_LOCAL(const char*, frameSourceNameSource,
+ ("function frameSourceName(exec_state) {"
+ " var frame = exec_state.frame(0);"
+ " if (frame.func().resolved() && "
+ " frame.func().script() && "
+ " frame.func().script().name()) {"
+ " return frame.func().script().name();"
+ " }"
+ "}"));
+ v8::Script::Compile(v8::String::New(frameSourceNameSource))->Run();
+}
+
+int V8Proxy::sourceLineNumber()
+{
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> v8UtilityContext = V8Proxy::utilityContext();
+ if (v8UtilityContext.IsEmpty())
+ return 0;
+ v8::Context::Scope contextScope(v8UtilityContext);
+ v8::Handle<v8::Function> frameSourceLine;
+ frameSourceLine = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("frameSourceLine")));
+ if (frameSourceLine.IsEmpty())
+ return 0;
+ v8::Handle<v8::Value> result = v8::Debug::Call(frameSourceLine);
+ if (result.IsEmpty())
+ return 0;
+ return result->Int32Value();
+}
+
+String V8Proxy::sourceName()
+{
+ v8::HandleScope scope;
+ v8::Handle<v8::Context> v8UtilityContext = utilityContext();
+ if (v8UtilityContext.IsEmpty())
+ return String();
+ v8::Context::Scope contextScope(v8UtilityContext);
+ v8::Handle<v8::Function> frameSourceName;
+ frameSourceName = v8::Local<v8::Function>::Cast(v8UtilityContext->Global()->Get(v8::String::New("frameSourceName")));
+ if (frameSourceName.IsEmpty())
+ return String();
+ return toWebCoreString(v8::Debug::Call(frameSourceName));
+}
+
+void V8Proxy::registerExtensionWithV8(v8::Extension* extension) {
+ // If the extension exists in our list, it was already registered with V8.
+ for (V8ExtensionList::iterator it = m_extensions.begin(); it != m_extensions.end(); ++it) {
+ if (it->extension == extension)
+ return;
+ }
+
+ v8::RegisterExtension(extension);
+}
+
+void V8Proxy::registerExtension(v8::Extension* extension, const String& schemeRestriction)
+{
+ registerExtensionWithV8(extension);
+ V8ExtensionInfo info = {schemeRestriction, 0, extension};
+ m_extensions.push_back(info);
+}
+
+void V8Proxy::registerExtension(v8::Extension* extension, int extensionGroup)
+{
+ registerExtensionWithV8(extension);
+ V8ExtensionInfo info = {String(), extensionGroup, extension};
+ m_extensions.push_back(info);
+}
+
+bool V8Proxy::setContextDebugId(int debugId)
+{
+ ASSERT(debugId > 0);
+ if (m_context.IsEmpty())
+ return false;
+ v8::HandleScope scope;
+ if (!m_context->GetData()->IsUndefined())
+ return false;
+
+ v8::Context::Scope contextScope(m_context);
+ v8::Handle<v8::Object> contextData = v8::Object::New();
+ contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("page"));
+ contextData->Set(v8::String::New(kContextDebugDataValue), v8::Integer::New(debugId));
+ m_context->SetData(contextData);
+ return true;
+}
+
+int V8Proxy::contextDebugId(v8::Handle<v8::Context> context)
+{
+ v8::HandleScope scope;
+ if (!context->GetData()->IsObject())
+ return -1;
+ v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String::New(kContextDebugDataValue));
+ return data->IsInt32() ? data->Int32Value() : -1;
+}
+
+v8::Handle<v8::Value> V8Proxy::getHiddenObjectPrototype(v8::Handle<v8::Context> context)
+{
+ return context->Global()->GetHiddenValue(V8HiddenPropertyName::objectPrototype());
+}
+
+void V8Proxy::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
+{
+ v8::Handle<v8::String> objectString = v8::String::New("Object");
+ v8::Handle<v8::String> prototypeString = v8::String::New("prototype");
+ v8::Handle<v8::String> hiddenObjectPrototypeString = V8HiddenPropertyName::objectPrototype();
+ // Bail out if allocation failed.
+ if (objectString.IsEmpty() || prototypeString.IsEmpty() || hiddenObjectPrototypeString.IsEmpty())
+ return;
+
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(context->Global()->Get(objectString));
+ v8::Handle<v8::Value> objectPrototype = object->Get(prototypeString);
+
+ context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index c21e0dd..caa991c 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -31,12 +31,437 @@
#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"
+#include "ChromiumBridge.h"
+#include "Node.h"
+#include "NodeFilter.h"
+#include "PlatformString.h" // for WebCore::String
+#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
+#include "SecurityOrigin.h" // for WebCore::SecurityOrigin
+#include "V8CustomBinding.h"
+#include "V8DOMMap.h"
+#include "V8DOMWrapper.h"
+#include "V8EventListenerList.h"
+#include "V8GCController.h"
+#include "V8Index.h"
+#include "V8Utilities.h"
+#include <v8.h>
+#include <wtf/Assertions.h>
+#include <wtf/PassRefPtr.h> // so generated bindings don't have to
+#include <wtf/Vector.h>
+
+#include <iterator>
+#include <list>
+
+#ifdef ENABLE_DOM_STATS_COUNTERS
+#define INC_STATS(name) ChromiumBridge::incrementStatsCounter(name)
+#else
+#define INC_STATS(name)
+#endif
namespace WebCore {
+ class CSSRule;
+ class CSSRuleList;
+ class CSSStyleDeclaration;
+ class CSSValue;
+ class CSSValueList;
+ class ClientRectList;
+ class DOMImplementation;
+ class DOMWindow;
+ class Document;
+ class Element;
+ class Event;
+ class EventListener;
+ class EventTarget;
+ class Frame;
+ class HTMLCollection;
+ class HTMLDocument;
+ class HTMLElement;
+ class HTMLOptionsCollection;
+ class MediaList;
+ class MimeType;
+ class MimeTypeArray;
+ class NamedNodeMap;
+ class Navigator;
+ class Node;
+ class NodeFilter;
+ class NodeList;
+ class Plugin;
+ class PluginArray;
+ class SVGElement;
+#if ENABLE(SVG)
+ class SVGElementInstance;
+#endif
+ class Screen;
+ class ScriptExecutionContext;
+#if ENABLE(DOM_STORAGE)
+ class Storage;
+ class StorageEvent;
+#endif
+ class String;
+ class StyleSheet;
+ class StyleSheetList;
+ class V8EventListener;
+ class V8ObjectEventListener;
+
+ // FIXME: use standard logging facilities in WebCore.
+ void logInfo(Frame*, const String& message, const String& url);
+
+ // The following Batch structs and methods are used for setting multiple
+ // properties on an ObjectTemplate, used from the generated bindings
+ // initialization (ConfigureXXXTemplate). This greatly reduces the binary
+ // size by moving from code driven setup to data table driven setup.
+
+ // BatchedAttribute translates into calls to SetAccessor() on either the
+ // instance or the prototype ObjectTemplate, based on |onProto|.
+ struct BatchedAttribute {
+ const char* const name;
+ v8::AccessorGetter getter;
+ v8::AccessorSetter setter;
+ V8ClassIndex::V8WrapperType data;
+ v8::AccessControl settings;
+ v8::PropertyAttribute attribute;
+ bool onProto;
+ };
+
+ void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount);
+
+ // BatchedConstant translates into calls to Set() for setting up an object's
+ // constants. It sets the constant on both the FunctionTemplate and the
+ // ObjectTemplate. PropertyAttributes is always ReadOnly.
+ struct BatchedConstant {
+ const char* const name;
+ int value;
+ };
+
+ void batchConfigureConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedConstant*, size_t constantCount);
+
+ const int kMaxRecursionDepth = 20;
+
+ // Information about an extension that is registered for use with V8. If
+ // scheme is non-empty, it contains the URL scheme the extension should be
+ // used with. If group is non-zero, the extension will only be loaded into
+ // script contexts that belong to that group. Otherwise, the extension is
+ // used with all schemes and contexts.
+ struct V8ExtensionInfo {
+ String scheme;
+ int group;
+ v8::Extension* extension;
+ };
+ typedef std::list<V8ExtensionInfo> V8ExtensionList;
+
+ class V8Proxy {
+ public:
+ // The types of javascript errors that can be thrown.
+ enum ErrorType {
+ RangeError,
+ ReferenceError,
+ SyntaxError,
+ TypeError,
+ GeneralError
+ };
+
+ explicit V8Proxy(Frame* frame) : m_frame(frame), m_inlineCode(false), m_timerCallback(false), m_recursion(0) { }
+
+ ~V8Proxy();
+
+ Frame* frame() { return m_frame; }
+
+ // Clear page-specific data, but keep the global object identify.
+ void clearForNavigation();
+
+ // Clear page-specific data before shutting down the proxy object.
+ void clearForClose();
+
+ // Update document object of the frame.
+ void updateDocument();
+
+ // Update the security origin of a document
+ // (e.g., after setting docoument.domain).
+ void updateSecurityOrigin();
+
+ // Destroy the global object.
+ void destroyGlobal();
+
+ // FIXME: Need comment. User Gesture related.
+ bool inlineCode() const { return m_inlineCode; }
+ void setInlineCode(bool value) { m_inlineCode = value; }
+
+ bool timerCallback() const { return m_timerCallback; }
+ void setTimerCallback(bool value) { m_timerCallback = value; }
+
+ // Has the context for this proxy been initialized?
+ bool isContextInitialized();
+
+ // Disconnects the proxy from its owner frame,
+ // and clears all timeouts on the DOM window.
+ void disconnectFrame();
+
+ bool isEnabled();
+
+ V8EventListenerList* eventListeners() { return &m_eventListeners; }
+ V8EventListenerList* objectListeners() { return &m_objectListeners; }
+
+#if ENABLE(SVG)
+ static void setSVGContext(void*, SVGElement*);
+ static SVGElement* svgContext(void*);
+#endif
+
+ void setEventHandlerLineNumber(int lineNumber) { m_handlerLineNumber = lineNumber; }
+ void finishedWithEvent(Event*) { }
+
+ // Evaluate JavaScript in a new isolated world. The script gets its own
+ // global scope, its own prototypes for intrinsic JavaScript objects (String,
+ // Array, and so-on), and its own wrappers for all DOM nodes and DOM
+ // constructors.
+ void evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup);
+
+ // Evaluate JavaScript in a new context. The script gets its own global scope
+ // and its own prototypes for intrinsic JavaScript objects (String, Array,
+ // and so-on). It shares the wrappers for all DOM nodes and DOM constructors.
+ void evaluateInNewContext(const Vector<ScriptSourceCode>&, int extensionGroup);
+
+ // Evaluate a script file in the current execution environment.
+ // The caller must hold an execution context.
+ // If cannot evalute the script, it returns an error.
+ v8::Local<v8::Value> evaluate(const ScriptSourceCode&, Node*);
+
+ // Run an already compiled script.
+ v8::Local<v8::Value> runScript(v8::Handle<v8::Script>, bool isInlineCode);
+
+ // Call the function with the given receiver and arguments.
+ v8::Local<v8::Value> callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int argc, v8::Handle<v8::Value> argv[]);
+
+ // Call the function as constructor with the given arguments.
+ v8::Local<v8::Value> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
+
+ // To create JS Wrapper objects, we create a cache of a 'boiler plate'
+ // object, and then simply Clone that object each time we need a new one.
+ // This is faster than going through the full object creation process.
+ v8::Local<v8::Object> createWrapperFromCache(V8ClassIndex::V8WrapperType);
+
+ // Returns the window object associated with a context.
+ static DOMWindow* retrieveWindow(v8::Handle<v8::Context>);
+ // Returns V8Proxy object of the currently executing context.
+ static V8Proxy* retrieve();
+ // Returns V8Proxy object associated with a frame.
+ static V8Proxy* retrieve(Frame*);
+ // Returns V8Proxy object associated with a script execution context.
+ static V8Proxy* retrieve(ScriptExecutionContext*);
+
+ // Returns the frame object of the window object associated with
+ // a context.
+ static Frame* retrieveFrame(v8::Handle<v8::Context>);
+
+
+ // The three functions below retrieve WebFrame instances relating the
+ // currently executing JavaScript. Since JavaScript can make function calls
+ // across frames, though, we need to be more precise.
+ //
+ // For example, imagine that a JS function in frame A calls a function in
+ // frame B, which calls native code, which wants to know what the 'active'
+ // frame is.
+ //
+ // The 'entered context' is the context where execution first entered the
+ // script engine; the context that is at the bottom of the JS function stack.
+ // RetrieveFrameForEnteredContext() would return Frame A in our example.
+ // This frame is often referred to as the "dynamic global object."
+ //
+ // The 'current context' is the context the JS engine is currently inside of;
+ // the context that is at the top of the JS function stack.
+ // RetrieveFrameForCurrentContext() would return Frame B in our example.
+ // This frame is often referred to as the "lexical global object."
+ //
+ // Finally, the 'calling context' is the context one below the current
+ // context on the JS function stack. For example, if function f calls
+ // function g, then the calling context will be the context associated with
+ // f. This context is commonly used by DOM security checks because they want
+ // to know who called them.
+ //
+ // If you are unsure which of these functions to use, ask abarth.
+ //
+ // NOTE: These cannot be declared as inline function, because VS complains at
+ // linking time.
+ static Frame* retrieveFrameForEnteredContext();
+ static Frame* retrieveFrameForCurrentContext();
+ static Frame* retrieveFrameForCallingContext();
+
+ // Returns V8 Context of a frame. If none exists, creates
+ // a new context. It is potentially slow and consumes memory.
+ static v8::Local<v8::Context> context(Frame*);
+ static v8::Local<v8::Context> mainWorldContext(Frame*);
+ static v8::Local<v8::Context> currentContext();
+
+ // If the current context causes out of memory, JavaScript setting
+ // is disabled and it returns true.
+ static bool handleOutOfMemory();
+
+ // Check if the active execution context can access the target frame.
+ static bool canAccessFrame(Frame*, bool reportError);
+
+ // Check if it is safe to access the given node from the
+ // current security context.
+ static bool checkNodeSecurity(Node*);
+
+ static v8::Handle<v8::Value> checkNewLegal(const v8::Arguments&);
+
+ static v8::Handle<v8::Script> compileScript(v8::Handle<v8::String> code, const String& fileName, int baseLine);
+
+ // If the exception code is different from zero, a DOM exception is
+ // schedule to be thrown.
+ static void setDOMException(int exceptionCode);
+
+ // Schedule an error object to be thrown.
+ static v8::Handle<v8::Value> throwError(ErrorType, const char* message);
+
+ // Create an instance of a function descriptor and set to the global object
+ // as a named property. Used by v8_test_shell.
+ static void bindJsObjectToWindow(Frame*, const char* name, int type, v8::Handle<v8::FunctionTemplate>, void*);
+
+ template <int tag, typename T>
+ static v8::Handle<v8::Value> constructDOMObject(const v8::Arguments&);
+
+ // Process any pending JavaScript console messages.
+ static void processConsoleMessages();
+
+ // Function for retrieving the line number and source name for the top
+ // JavaScript stack frame.
+ static int sourceLineNumber();
+ static String sourceName();
+
+ // Returns a local handle of the context.
+ v8::Local<v8::Context> context()
+ {
+ return v8::Local<v8::Context>::New(m_context);
+ }
+
+ bool setContextDebugId(int id);
+ static int contextDebugId(v8::Handle<v8::Context>);
+
+ static v8::Handle<v8::Value> getHiddenObjectPrototype(v8::Handle<v8::Context>);
+ // WARNING: Call |installHiddenObjectPrototype| only on fresh contexts!
+ static void installHiddenObjectPrototype(v8::Handle<v8::Context>);
+
+ // Registers a v8 extension to be available on webpages. The two forms
+ // offer various restrictions on what types of contexts the extension is
+ // loaded into. If a scheme is provided, only pages whose URL has the given
+ // scheme will match. If extensionGroup is provided, the extension will
+ // only be loaded into scripts run via evaluateInNewWorld with the
+ // matching group. Will only affect v8 contexts initialized after this
+ // call. Takes ownership of the v8::Extension object passed.
+ static void registerExtension(v8::Extension*, const String& schemeRestriction);
+ static void registerExtension(v8::Extension*, int extensionGroup);
+
+ // FIXME: Separate these concerns from V8Proxy?
+ v8::Persistent<v8::Context> createNewContext(v8::Handle<v8::Object> global, int extensionGroup);
+ static bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window);
+
+ void initContextIfNeeded();
+ void updateDocumentWrapper(v8::Handle<v8::Value> wrapper);
+
+ private:
+ static const char* kContextDebugDataType;
+ static const char* kContextDebugDataValue;
+
+ void disconnectEventListeners();
+ void setSecurityToken();
+ void clearDocumentWrapper();
+
+ // The JavaScript wrapper for the document object is cached on the global
+ // object for fast access. UpdateDocumentWrapperCache sets the wrapper
+ // for the current document on the global object. ClearDocumentWrapperCache
+ // deletes the document wrapper from the global object.
+ void updateDocumentWrapperCache();
+ void clearDocumentWrapperCache();
+
+ // Dispose global handles of m_contexts and friends.
+ void disposeContextHandles();
+
+ static bool canAccessPrivate(DOMWindow*);
+
+ static const char* rangeExceptionName(int exceptionCode);
+ static const char* eventExceptionName(int exceptionCode);
+ static const char* xmlHttpRequestExceptionName(int exceptionCode);
+ static const char* domExceptionName(int exceptionCode);
+
+#if ENABLE(XPATH)
+ static const char* xpathExceptionName(int exceptionCode);
+#endif
+
+#if ENABLE(SVG)
+ static const char* svgExceptionName(int exceptionCode);
+#endif
+
+ static void createUtilityContext();
+
+ // Returns a local handle of the utility context.
+ static v8::Local<v8::Context> utilityContext()
+ {
+ if (m_utilityContext.IsEmpty())
+ createUtilityContext();
+ return v8::Local<v8::Context>::New(m_utilityContext);
+ }
+
+ static void registerExtensionWithV8(v8::Extension*);
+
+ Frame* m_frame;
+
+ v8::Persistent<v8::Context> m_context;
+ // For each possible type of wrapper, we keep a boilerplate object.
+ // The boilerplate is used to create additional wrappers of the same
+ // type. We keep a single persistent handle to an array of the
+ // activated boilerplates.
+ v8::Persistent<v8::Array> m_wrapperBoilerplates;
+
+ v8::Persistent<v8::Object> m_global;
+ v8::Persistent<v8::Value> m_document;
+
+ // Utility context holding JavaScript functions used internally.
+ static v8::Persistent<v8::Context> m_utilityContext;
+
+ int m_handlerLineNumber;
+
+ // A list of event listeners created for this frame,
+ // the list gets cleared when removing all timeouts.
+ V8EventListenerList m_eventListeners;
+
+ // A list of event listeners create for XMLHttpRequest object for this frame,
+ // the list gets cleared when removing all timeouts.
+ V8EventListenerList m_objectListeners;
+
+ // True for <a href="javascript:foo()"> and false for <script>foo()</script>.
+ // Only valid during execution.
+ bool m_inlineCode;
+
+ // True when executing from within a timer callback. Only valid during
+ // execution.
+ bool m_timerCallback;
+
+ // Track the recursion depth to be able to avoid too deep recursion. The V8
+ // engine allows much more recursion than KJS does so we need to guard against
+ // excessive recursion in the binding layer.
+ int m_recursion;
+
+ // List of extensions registered with the context.
+ static V8ExtensionList m_extensions;
+ };
+
+ template <int tag, typename T>
+ v8::Handle<v8::Value> V8Proxy::constructDOMObject(const v8::Arguments& args)
+ {
+ if (!args.IsConstructCall())
+ return throwError(V8Proxy::TypeError, "DOM object constructor cannot be called as a function.");
+
+ // 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<T> obj = T::create();
+ V8DOMWrapper::setDOMWrapper(args.Holder(), tag, obj.get());
+ obj->ref();
+ V8DOMWrapper::setJSWrapperForDOMObject(obj.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+ return args.Holder();
+ }
+
+
// Used by an interceptor callback that it hasn't found anything to
// intercept.
inline static v8::Local<v8::Object> notHandledByInterceptor()
@@ -48,22 +473,15 @@ namespace WebCore {
{
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)
+ inline v8::Handle<v8::Primitive> throwError(const char* message, V8Proxy::ErrorType type = V8Proxy::TypeError)
{
- V8Proxy::ThrowError(type, message);
+ V8Proxy::throwError(type, message);
return v8::Undefined();
}
inline v8::Handle<v8::Primitive> throwError(ExceptionCode ec)
{
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Undefined();
}
@@ -76,7 +494,7 @@ namespace WebCore {
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));
+ V8DOMWrapper::setJSWrapperForDOMObject(object.get(), v8::Persistent<v8::Object>::New(holder));
return holder;
}
diff --git a/WebCore/bindings/v8/V8SVGPODTypeWrapper.h b/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
new file mode 100644
index 0000000..b6e47af
--- /dev/null
+++ b/WebCore/bindings/v8/V8SVGPODTypeWrapper.h
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Google. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 V8SVGPODTypeWrapper_h
+#define V8SVGPODTypeWrapper_h
+
+#if ENABLE(SVG)
+
+#include <utility>
+
+#include "SVGElement.h"
+#include "SVGList.h"
+#include "V8Proxy.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/HashFunctions.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+template<typename PODType>
+class V8SVGPODTypeWrapper : public RefCounted<V8SVGPODTypeWrapper<PODType> > {
+public:
+ V8SVGPODTypeWrapper() { }
+ virtual ~V8SVGPODTypeWrapper() { }
+ virtual operator PODType() = 0;
+ virtual void commitChange(PODType, SVGElement*) = 0;
+};
+
+template<typename PODType>
+class V8SVGPODTypeWrapperCreatorForList : public V8SVGPODTypeWrapper<PODType> {
+public:
+ typedef SVGPODListItem<PODType> PODListItemPtrType;
+
+ typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const;
+ typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType);
+
+ static PassRefPtr<V8SVGPODTypeWrapperCreatorForList> create(PassRefPtr<PODListItemPtrType> creator, const QualifiedName& attributeName)
+ {
+ return adoptRef(new V8SVGPODTypeWrapperCreatorForList(creator, attributeName));
+ }
+
+ virtual ~V8SVGPODTypeWrapperCreatorForList() { }
+
+ // Getter wrapper
+ virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
+
+ // Setter wrapper
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ if (!m_setter)
+ return;
+
+ (m_creator.get()->*m_setter)(type);
+
+ if (context)
+ context->svgAttributeChanged(m_associatedAttributeName);
+ }
+
+private:
+ V8SVGPODTypeWrapperCreatorForList(PassRefPtr<PODListItemPtrType> creator, const QualifiedName& attributeName)
+ : m_creator(creator)
+ , m_getter(&SVGPODListItem<PODType>::value)
+ , m_setter(&SVGPODListItem<PODType>::setValue)
+ , m_associatedAttributeName(attributeName)
+ {
+ ASSERT(m_creator);
+ ASSERT(m_getter);
+ ASSERT(m_setter);
+ }
+
+ // Update callbacks
+ RefPtr<SVGPODListItem<PODType> > m_creator;
+ GetterMethod m_getter;
+ SetterMethod m_setter;
+ const QualifiedName& m_associatedAttributeName;
+};
+
+template<typename PODType>
+class V8SVGStaticPODTypeWrapper : public V8SVGPODTypeWrapper<PODType> {
+public:
+ static PassRefPtr<V8SVGStaticPODTypeWrapper> create(PODType type)
+ {
+ return adoptRef(new V8SVGStaticPODTypeWrapper(type));
+ }
+
+ virtual ~V8SVGStaticPODTypeWrapper() { }
+
+ // Getter wrapper
+ virtual operator PODType() { return m_podType; }
+
+ // Setter wrapper
+ virtual void commitChange(PODType type, SVGElement*)
+ {
+ m_podType = type;
+ }
+
+protected:
+ V8SVGStaticPODTypeWrapper(PODType type)
+ : m_podType(type)
+ {
+ }
+
+ PODType m_podType;
+};
+
+template<typename PODType, typename ParentTypeArg>
+class V8SVGStaticPODTypeWrapperWithPODTypeParent : public V8SVGStaticPODTypeWrapper<PODType> {
+public:
+ typedef V8SVGPODTypeWrapper<ParentTypeArg> ParentType;
+
+ static PassRefPtr<V8SVGStaticPODTypeWrapperWithPODTypeParent> create(PODType type, PassRefPtr<ParentType> parent)
+ {
+ return adoptRef(new V8SVGStaticPODTypeWrapperWithPODTypeParent(type, parent));
+ }
+
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ V8SVGStaticPODTypeWrapper<PODType>::commitChange(type, context);
+ m_parentType->commitChange(ParentTypeArg(type), context);
+ }
+
+private:
+ V8SVGStaticPODTypeWrapperWithPODTypeParent(PODType type, PassRefPtr<ParentType> parent)
+ : V8SVGStaticPODTypeWrapper<PODType>(type)
+ , m_parentType(parent)
+ {
+ }
+
+ RefPtr<ParentType> m_parentType;
+};
+
+template<typename PODType, typename ParentType>
+class V8SVGStaticPODTypeWrapperWithParent : public V8SVGPODTypeWrapper<PODType> {
+public:
+ typedef PODType (ParentType::*GetterMethod)() const;
+ typedef void (ParentType::*SetterMethod)(const PODType&);
+
+ static PassRefPtr<V8SVGStaticPODTypeWrapperWithParent> create(PassRefPtr<ParentType> parent, GetterMethod getter, SetterMethod setter)
+ {
+ return adoptRef(new V8SVGStaticPODTypeWrapperWithParent(parent, getter, setter));
+ }
+
+ virtual operator PODType()
+ {
+ return (m_parent.get()->*m_getter)();
+ }
+
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ (m_parent.get()->*m_setter)(type);
+ }
+
+private:
+ V8SVGStaticPODTypeWrapperWithParent(PassRefPtr<ParentType> parent, GetterMethod getter, SetterMethod setter)
+ : m_parent(parent)
+ , m_getter(getter)
+ , m_setter(setter)
+ {
+ ASSERT(m_parent);
+ ASSERT(m_getter);
+ ASSERT(m_setter);
+ }
+
+ RefPtr<ParentType> m_parent;
+ GetterMethod m_getter;
+ SetterMethod m_setter;
+};
+
+template<typename PODType, typename PODTypeCreator>
+class V8SVGDynamicPODTypeWrapper : public V8SVGPODTypeWrapper<PODType> {
+public:
+ typedef PODType (PODTypeCreator::*GetterMethod)() const;
+ typedef void (PODTypeCreator::*SetterMethod)(PODType);
+ typedef void (*CacheRemovalCallback)(V8SVGPODTypeWrapper<PODType>*);
+
+ static PassRefPtr<V8SVGDynamicPODTypeWrapper> create(PassRefPtr<PODTypeCreator> creator, GetterMethod getter, SetterMethod setter, CacheRemovalCallback cacheRemovalCallback)
+ {
+ return adoptRef(new V8SVGDynamicPODTypeWrapper(creator, getter, setter, cacheRemovalCallback));
+ }
+
+ virtual ~V8SVGDynamicPODTypeWrapper() {
+ ASSERT(m_cacheRemovalCallback);
+
+ (*m_cacheRemovalCallback)(this);
+ }
+
+ // Getter wrapper
+ virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
+
+ // Setter wrapper
+ virtual void commitChange(PODType type, SVGElement* context)
+ {
+ (m_creator.get()->*m_setter)(type);
+
+ if (context)
+ context->svgAttributeChanged(m_creator->associatedAttributeName());
+ }
+
+private:
+ V8SVGDynamicPODTypeWrapper(PassRefPtr<PODTypeCreator> creator, GetterMethod getter, SetterMethod setter, CacheRemovalCallback cacheRemovalCallback)
+ : m_creator(creator)
+ , m_getter(getter)
+ , m_setter(setter)
+ , m_cacheRemovalCallback(cacheRemovalCallback)
+ {
+ ASSERT(m_creator); // |creator|'s pointer was taken by m_creator.
+ ASSERT(getter);
+ ASSERT(setter);
+ ASSERT(cacheRemovalCallback);
+ }
+
+ // Update callbacks
+ RefPtr<PODTypeCreator> m_creator;
+ GetterMethod m_getter;
+ SetterMethod m_setter;
+ CacheRemovalCallback m_cacheRemovalCallback;
+};
+
+// Caching facilities
+template<typename PODType, typename PODTypeCreator>
+struct PODTypeWrapperCacheInfo {
+ typedef PODType (PODTypeCreator::*GetterMethod)() const;
+ typedef void (PODTypeCreator::*SetterMethod)(PODType);
+
+ // Empty value
+ PODTypeWrapperCacheInfo()
+ : creator(0)
+ , getter(0)
+ , setter(0)
+ , fieldHash(0)
+ { }
+
+ // Deleted value
+ explicit PODTypeWrapperCacheInfo(WTF::HashTableDeletedValueType)
+ : creator(reinterpret_cast<PODTypeCreator*>(-1))
+ , getter(0)
+ , setter(0)
+ , fieldHash(0)
+ {
+ }
+
+ bool isHashTableDeletedValue() const
+ {
+ return creator == reinterpret_cast<PODTypeCreator*>(-1);
+ }
+
+ PODTypeWrapperCacheInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter, unsigned _fieldHash)
+ : creator(_creator)
+ , getter(_getter)
+ , setter(_setter)
+ , fieldHash(_fieldHash)
+ {
+ ASSERT(creator);
+ ASSERT(getter);
+ }
+
+ bool operator==(const PODTypeWrapperCacheInfo& other) const
+ {
+ return creator == other.creator && fieldHash == other.fieldHash && getter == other.getter && setter == other.setter;
+ }
+
+ PODTypeCreator* creator;
+ GetterMethod getter;
+ SetterMethod setter;
+ unsigned fieldHash;
+};
+
+template<typename PODType, typename PODTypeCreator>
+struct PODTypeWrapperCacheInfoHash {
+ static unsigned hash(const PODTypeWrapperCacheInfo<PODType, PODTypeCreator>& info)
+ {
+ // We can't hash member function pointers, but we have enough material
+ // to hash the pointer and field identifier, and on a collision
+ // operator== will still differentiate the member function pointers.
+ return WTF::PairHash<void*, unsigned>::hash(std::pair<void*, unsigned>(info.creator, info.fieldHash));
+ }
+
+ static bool equal(const PODTypeWrapperCacheInfo<PODType, PODTypeCreator>& a, const PODTypeWrapperCacheInfo<PODType, PODTypeCreator>& b)
+ {
+ return a == b;
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+template<typename PODType, typename PODTypeCreator>
+struct PODTypeWrapperCacheInfoTraits : WTF::GenericHashTraits<PODTypeWrapperCacheInfo<PODType, PODTypeCreator> > {
+ typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;
+
+ static const bool emptyValueIsZero = true;
+ static const bool needsDestruction = false;
+
+ static const CacheInfo& emptyValue()
+ {
+ DEFINE_STATIC_LOCAL(CacheInfo, key, ());
+ return key;
+ }
+
+ static void constructDeletedValue(CacheInfo& slot)
+ {
+ new (&slot) CacheInfo(WTF::HashTableDeletedValue);
+ }
+
+ static bool isDeletedValue(const CacheInfo& value)
+ {
+ return value.isHashTableDeletedValue();
+ }
+};
+
+template<typename PODType, typename PODTypeCreator>
+class V8SVGDynamicPODTypeWrapperCache {
+public:
+ typedef PODType (PODTypeCreator::*GetterMethod)() const;
+ typedef void (PODTypeCreator::*SetterMethod)(PODType);
+
+ typedef PODTypeWrapperCacheInfo<PODType, PODTypeCreator> CacheInfo;
+ typedef PODTypeWrapperCacheInfoHash<PODType, PODTypeCreator> CacheInfoHash;
+ typedef PODTypeWrapperCacheInfoTraits<PODType, PODTypeCreator> CacheInfoTraits;
+
+ typedef V8SVGPODTypeWrapper<PODType> WrapperBase;
+ typedef V8SVGDynamicPODTypeWrapper<PODType, PODTypeCreator> DynamicWrapper;
+
+ typedef HashMap<CacheInfo, DynamicWrapper*, CacheInfoHash, CacheInfoTraits> DynamicWrapperHashMap;
+ typedef typename DynamicWrapperHashMap::const_iterator DynamicWrapperHashMapIterator;
+
+ static DynamicWrapperHashMap& dynamicWrapperHashMap()
+ {
+ DEFINE_STATIC_LOCAL(DynamicWrapperHashMap, dynamicWrapperHashMap, ());
+ return dynamicWrapperHashMap;
+ }
+
+ // Used for readwrite attributes only
+ static PassRefPtr<WrapperBase> lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter, unsigned fieldHash)
+ {
+ DynamicWrapperHashMap& map(dynamicWrapperHashMap());
+ CacheInfo info(creator, getter, setter, fieldHash);
+
+ if (map.contains(info))
+ return map.get(info);
+
+ RefPtr<DynamicWrapper> wrapper = V8SVGDynamicPODTypeWrapper<PODType, PODTypeCreator>::create(creator, getter, setter, forgetWrapper);
+ map.set(info, wrapper.get());
+ return wrapper.release();
+ }
+
+ static void forgetWrapper(V8SVGPODTypeWrapper<PODType>* wrapper)
+ {
+ DynamicWrapperHashMap& map(dynamicWrapperHashMap());
+
+ DynamicWrapperHashMapIterator it = map.begin();
+ DynamicWrapperHashMapIterator end = map.end();
+
+ for (; it != end; ++it) {
+ if (it->second != wrapper)
+ continue;
+
+ // It's guaranteed that there's just one object we need to take care of.
+ map.remove(it->first);
+ break;
+ }
+ }
+};
+
+class V8SVGPODTypeUtil {
+public:
+ template <class P>
+ static P toSVGPODType(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object, bool& ok);
+};
+
+template <class P>
+P V8SVGPODTypeUtil::toSVGPODType(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Value> object, bool& ok)
+{
+ void *wrapper = V8DOMWrapper::convertToSVGPODTypeImpl(type, object);
+ if (wrapper == NULL) {
+ ok = false;
+ return P();
+ } else {
+ ok = true;
+ return *static_cast<V8SVGPODTypeWrapper<P>*>(wrapper);
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG)
+#endif // V8SVGPODTypeWrapper_h
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index 395a8df..c1ac6d4 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -58,7 +58,8 @@ void createHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> v
void removeHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
{
v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
- ASSERT(cache->IsArray());
+ if (!cache->IsArray())
+ return;
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));
@@ -67,9 +68,6 @@ void removeHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> v
return;
}
}
-
- // We should only get here if we try to remove an event listener that was never added.
- ASSERT_NOT_REACHED();
}
bool processingUserGesture()
diff --git a/WebCore/bindings/v8/V8Utilities.h b/WebCore/bindings/v8/V8Utilities.h
index fdabc7a..781d2bb 100644
--- a/WebCore/bindings/v8/V8Utilities.h
+++ b/WebCore/bindings/v8/V8Utilities.h
@@ -31,6 +31,7 @@
#ifndef V8Utilities_h
#define V8Utilities_h
+#ifdef MANUAL_MERGE_REQUIRED
// FIXME: Remove once chromium dependencies on v8_utility.h are removed.
#define V8UTILITIES_DEFINED 1
#if ENABLE(V8_LOCKERS)
@@ -39,6 +40,8 @@
#define LOCK_V8 ((void) 0)
#endif
+#else // MANUAL_MERGE_REQUIRED
+#endif // MANUAL_MERGE_REQUIRED
#include <v8.h>
namespace WebCore {
@@ -80,11 +83,6 @@ namespace WebCore {
static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>);
static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::ObjectTemplate>);
static inline v8::Local<v8::Object> newInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
-
- // FIXME: These NewInstance functions are here to ease upstreaming. Remove along with V8UTILITIES_DEFINED once chromium dependencies on v8_utility.h are removed.
- static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::Function>);
- static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::ObjectTemplate>);
- static inline v8::Local<v8::Object> NewInstance(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
};
v8::Local<v8::Object> SafeAllocation::newInstance(v8::Handle<v8::Function> function)
@@ -111,22 +109,6 @@ namespace WebCore {
return function->NewInstance(argc, argv);
}
- // FIXME: These NewInstance functions are here to ease upstreaming. Remove along with V8UTILITIES_DEFINED once chromium dependencies on v8_utility.h are removed.
- v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::Function> function)
- {
- return newInstance(function);
- }
-
- v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::ObjectTemplate> objectTemplate)
- {
- return newInstance(objectTemplate);
- }
-
- v8::Local<v8::Object> SafeAllocation::NewInstance(v8::Handle<v8::Function> function, int argc, v8::Handle<v8::Value> argv[])
- {
- return newInstance(function, argc, argv);
- }
-
} // namespace WebCore
#endif // V8Utilities_h
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index a21d3eb..9ed7e32 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -35,7 +35,11 @@
#include "V8WorkerContextEventListener.h"
#include "Event.h"
+#ifdef MANUAL_MERGE_REQUIRED
#include "V8Utilities.h"
+#else // MANUAL_MERGE_REQUIRED
+#include "V8Binding.h"
+#endif // MANUAL_MERGE_REQUIRED
#include "WorkerContextExecutionProxy.h"
namespace WebCore {
@@ -49,7 +53,7 @@ V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutio
V8WorkerContextEventListener::~V8WorkerContextEventListener()
{
if (m_proxy)
- m_proxy->RemoveEventListener(this);
+ m_proxy->removeEventListener(this);
disposeListenerObject();
}
@@ -66,7 +70,7 @@ void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent)
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = m_proxy->GetContext();
+ v8::Handle<v8::Context> context = m_proxy->context();
if (context.IsEmpty())
return;
@@ -74,11 +78,57 @@ void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent)
v8::Context::Scope scope(context);
// Get the V8 wrapper for the event object.
- v8::Handle<v8::Value> jsEvent = WorkerContextExecutionProxy::EventToV8Object(event);
+ v8::Handle<v8::Value> jsEvent = WorkerContextExecutionProxy::convertEventToV8Object(event);
invokeEventHandler(context, event, jsEvent, isWindowEvent);
}
+bool V8WorkerContextEventListener::reportError(const String& message, const String& url, int lineNumber)
+{
+ // Is the EventListener disconnected?
+ if (disconnected())
+ return false;
+
+ // The callback function can clear the event listener and destroy 'this' object. Keep a local reference to it.
+ RefPtr<V8AbstractEventListener> protect(this);
+
+ v8::HandleScope handleScope;
+
+ v8::Handle<v8::Context> context = m_proxy->context();
+ if (context.IsEmpty())
+ return false;
+
+ // Enter the V8 context in which to perform the event handling.
+ v8::Context::Scope scope(context);
+
+ v8::Local<v8::Value> returnValue;
+ {
+ // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire.
+ v8::TryCatch tryCatch;
+ tryCatch.SetVerbose(true);
+
+ // Call the function.
+ if (!m_listener.IsEmpty() && m_listener->IsFunction()) {
+ v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+ v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
+
+ v8::Handle<v8::Value> parameters[3] = { v8String(message), v8String(url), v8::Integer::New(lineNumber) };
+ returnValue = callFunction->Call(thisValue, 3, parameters);
+ }
+
+ // If an error occurs while handling the script error, it should be bubbled up.
+ if (tryCatch.HasCaught()) {
+ tryCatch.Reset();
+ return false;
+ }
+ }
+
+ // If the function returns false, then the error is handled. Otherwise, the error is not handled.
+ bool errorHandled = returnValue->IsBoolean() && !returnValue->BooleanValue();
+
+ return errorHandled;
+}
+
v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
{
v8::Local<v8::Function> handlerFunction = getListenerFunction();
@@ -103,7 +153,7 @@ v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* eve
return v8::Context::GetCurrent()->Global();
EventTarget* target = event->currentTarget();
- v8::Handle<v8::Value> value = WorkerContextExecutionProxy::EventTargetToV8Object(target);
+ v8::Handle<v8::Value> value = WorkerContextExecutionProxy::convertEventTargetToV8Object(target);
if (value.IsEmpty())
return v8::Local<v8::Object>();
return v8::Local<v8::Object>::New(v8::Handle<v8::Object>::Cast(value));
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index 8e56a73..c901c51 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -52,6 +52,7 @@ namespace WebCore {
virtual ~V8WorkerContextEventListener();
virtual void handleEvent(Event*, bool isWindowEvent);
+ virtual bool reportError(const String& message, const String& url, int lineNumber);
virtual bool disconnected() const { return !m_proxy; }
WorkerContextExecutionProxy* proxy() const { return m_proxy; }
diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp
index bec25f1..ce56563 100644
--- a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp
@@ -43,7 +43,7 @@ static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* par
V8WorkerContextObjectEventListener* listener = static_cast<V8WorkerContextObjectEventListener*>(parameter);
// Remove the wrapper
- listener->proxy()->RemoveEventListener(listener);
+ listener->proxy()->removeEventListener(listener);
listener->disposeListenerObject();
}
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index c87cdea..f80d88f 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -35,9 +35,16 @@
#include "WorkerContextExecutionProxy.h"
+#include "DOMCoreException.h"
+#include "DedicatedWorkerContext.h"
+#include "Event.h"
+#include "EventException.h"
+#include "MessagePort.h"
+#include "RangeException.h"
#include "V8Binding.h"
+#include "V8DOMMap.h"
+#include "V8Index.h"
#include "V8Proxy.h"
-#include "Event.h"
#include "V8WorkerContextEventListener.h"
#include "V8WorkerContextObjectEventListener.h"
#include "Worker.h"
@@ -45,48 +52,17 @@
#include "WorkerLocation.h"
#include "WorkerNavigator.h"
#include "WorkerScriptController.h"
+#include "XMLHttpRequest.h"
+#include "XMLHttpRequestException.h"
namespace WebCore {
-static bool isWorkersEnabled = false;
-
static void reportFatalErrorInV8(const char* location, const char* message)
{
// FIXME: We temporarily deal with V8 internal error situations such as out-of-memory by crashing the worker.
CRASH();
}
-static void handleConsoleMessage(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data)
-{
- WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
- if (!proxy)
- return;
-
- WorkerContext* workerContext = proxy->workerContext();
- if (!workerContext)
- return;
-
- v8::Handle<v8::String> errorMessageString = message->Get();
- ASSERT(!errorMessageString.IsEmpty());
- String errorMessage = ToWebCoreString(errorMessageString);
-
- v8::Handle<v8::Value> resourceName = message->GetScriptResourceName();
- bool useURL = (resourceName.IsEmpty() || !resourceName->IsString());
- String resourceNameString = useURL ? workerContext->url() : ToWebCoreString(resourceName);
-
- workerContext->addMessage(ConsoleDestination, JSMessageSource, ErrorMessageLevel, errorMessage, message->GetLineNumber(), resourceNameString);
-}
-
-bool WorkerContextExecutionProxy::isWebWorkersEnabled()
-{
- return isWorkersEnabled;
-}
-
-void WorkerContextExecutionProxy::setIsWebWorkersEnabled(bool value)
-{
- isWorkersEnabled = value;
-}
-
WorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext)
: m_workerContext(workerContext)
, m_recursion(0)
@@ -102,8 +78,7 @@ WorkerContextExecutionProxy::~WorkerContextExecutionProxy()
void WorkerContextExecutionProxy::dispose()
{
// Disconnect all event listeners.
- if (m_listeners.get())
- {
+ if (m_listeners.get()) {
for (V8EventListenerList::iterator iterator(m_listeners->begin()); iterator != m_listeners->end(); ++iterator)
static_cast<V8WorkerContextEventListener*>(*iterator)->disconnect();
@@ -127,13 +102,16 @@ void WorkerContextExecutionProxy::dispose()
WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve()
{
+ // Happens on frame destruction, check otherwise GetCurrent() will crash.
+ if (!v8::Context::InContext())
+ return 0;
v8::Handle<v8::Context> context = v8::Context::GetCurrent();
v8::Handle<v8::Object> global = context->Global();
- global = V8Proxy::LookupDOMWrapper(V8ClassIndex::WORKERCONTEXT, global);
+ global = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::WORKERCONTEXT, global);
// Return 0 if the current executing context is not the worker context.
if (global.IsEmpty())
return 0;
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, global);
+ WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, global);
return workerContext->script()->proxy();
}
@@ -149,6 +127,7 @@ void WorkerContextExecutionProxy::initV8IfNeeded()
v8::V8::IgnoreOutOfMemoryException();
v8::V8::SetFatalErrorHandler(reportFatalErrorInV8);
+#ifdef MANUAL_MERGE_REQUIRED
// Set up the handler for V8 error message.
v8::V8::AddMessageListener(handleConsoleMessage);
@@ -156,6 +135,8 @@ void WorkerContextExecutionProxy::initV8IfNeeded()
const int workerThreadPreemptionIntervalMs = 5;
v8::Locker::StartPreemption(workerThreadPreemptionIntervalMs);
#endif
+#else // MANUAL_MERGE_REQUIRED
+#endif // MANUAL_MERGE_REQUIRED
v8Initialized = true;
}
@@ -177,7 +158,7 @@ void WorkerContextExecutionProxy::initContextIfNeeded()
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::Handle<v8::Function> workerContextConstructor = V8DOMWrapper::getConstructorForContext(V8ClassIndex::DEDICATEDWORKERCONTEXT, context);
v8::Local<v8::Object> jsWorkerContext = SafeAllocation::newInstance(workerContextConstructor);
// Bail out if allocation failed.
if (jsWorkerContext.IsEmpty()) {
@@ -186,9 +167,9 @@ void WorkerContextExecutionProxy::initContextIfNeeded()
}
// Wrap the object.
- V8Proxy::SetDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::WORKERCONTEXT), m_workerContext);
+ V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::DEDICATEDWORKERCONTEXT), m_workerContext);
- V8Proxy::SetJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
+ V8DOMWrapper::setJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
m_workerContext->ref();
// Insert the object instance as the prototype of the shadow object.
@@ -198,45 +179,47 @@ void WorkerContextExecutionProxy::initContextIfNeeded()
m_listeners.set(new V8EventListenerList());
}
-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)
+v8::Handle<v8::Value> WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::V8WrapperType type, void* impl)
{
if (!impl)
return v8::Null();
- if (type == V8ClassIndex::WORKERCONTEXT)
- return WorkerContextToV8Object(static_cast<WorkerContext*>(impl));
+ if (type == V8ClassIndex::DEDICATEDWORKERCONTEXT)
+ return convertWorkerContextToV8Object(static_cast<WorkerContext*>(impl));
+
+ bool isActiveDomObject = false;
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) case V8ClassIndex::TYPE:
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+ isActiveDomObject = true;
+ break;
+#undef MAKE_CASE
+ default:
+ break;
+ }
- if (type == V8ClassIndex::WORKER) {
+ if (isActiveDomObject) {
v8::Persistent<v8::Object> result = getActiveDOMObjectMap().get(impl);
if (!result.IsEmpty())
return result;
v8::Local<v8::Object> object = toV8(type, type, impl);
- if (!object.IsEmpty())
- static_cast<Worker*>(impl)->ref();
+ switch (type) {
+#define MAKE_CASE(TYPE, NAME) \
+ case V8ClassIndex::TYPE: static_cast<NAME*>(impl)->ref(); break;
+ ACTIVE_DOM_OBJECT_TYPES(MAKE_CASE)
+#undef MAKE_CASE
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
result = v8::Persistent<v8::Object>::New(object);
- V8Proxy::SetJSWrapperForDOMObject(impl, result);
+ V8DOMWrapper::setJSWrapperForActiveDOMObject(impl, result);
return result;
}
// Non DOM node
- v8::Persistent<v8::Object> result = domObjectMap().get(impl);
+ v8::Persistent<v8::Object> result = getDOMObjectMap().get(impl);
if (result.IsEmpty()) {
v8::Local<v8::Object> object = toV8(type, type, impl);
if (!object.IsEmpty()) {
@@ -247,22 +230,34 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::ToV8Object(V8ClassIndex::V8Wr
case V8ClassIndex::WORKERNAVIGATOR:
static_cast<WorkerNavigator*>(impl)->ref();
break;
+ case V8ClassIndex::DOMCOREEXCEPTION:
+ static_cast<DOMCoreException*>(impl)->ref();
+ break;
+ case V8ClassIndex::RANGEEXCEPTION:
+ static_cast<RangeException*>(impl)->ref();
+ break;
+ case V8ClassIndex::EVENTEXCEPTION:
+ static_cast<EventException*>(impl)->ref();
+ break;
+ case V8ClassIndex::XMLHTTPREQUESTEXCEPTION:
+ static_cast<XMLHttpRequestException*>(impl)->ref();
+ break;
default:
ASSERT(false);
}
result = v8::Persistent<v8::Object>::New(object);
- V8Proxy::SetJSWrapperForDOMObject(impl, result);
+ V8DOMWrapper::setJSWrapperForDOMObject(impl, result);
}
}
return result;
}
-v8::Handle<v8::Value> WorkerContextExecutionProxy::EventToV8Object(Event* event)
+v8::Handle<v8::Value> WorkerContextExecutionProxy::convertEventToV8Object(Event* event)
{
if (!event)
return v8::Null();
- v8::Handle<v8::Object> wrapper = domObjectMap().get(event);
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(event);
if (!wrapper.IsEmpty())
return wrapper;
@@ -274,73 +269,79 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::EventToV8Object(Event* event)
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.
+ // 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));
+ V8DOMWrapper::setJSWrapperForDOMObject(event, v8::Persistent<v8::Object>::New(result));
return result;
}
-// A JS object of type EventTarget in the worker context can only be Worker or WorkerContext.
-v8::Handle<v8::Value> WorkerContextExecutionProxy::EventTargetToV8Object(EventTarget* target)
+v8::Handle<v8::Value> WorkerContextExecutionProxy::convertEventTargetToV8Object(EventTarget* target)
{
if (!target)
return v8::Null();
- WorkerContext* workerContext = target->toWorkerContext();
+ DedicatedWorkerContext* workerContext = target->toDedicatedWorkerContext();
if (workerContext)
- return WorkerContextToV8Object(workerContext);
+ return convertWorkerContextToV8Object(workerContext);
Worker* worker = target->toWorker();
if (worker)
- return ToV8Object(V8ClassIndex::WORKER, worker);
+ return convertToV8Object(V8ClassIndex::WORKER, worker);
+
+ XMLHttpRequest* xhr = target->toXMLHttpRequest();
+ if (xhr)
+ return convertToV8Object(V8ClassIndex::XMLHTTPREQUEST, xhr);
+
+ MessagePort* mp = target->toMessagePort();
+ if (mp)
+ return convertToV8Object(V8ClassIndex::MESSAGEPORT, mp);
ASSERT_NOT_REACHED();
return v8::Handle<v8::Value>();
}
-v8::Handle<v8::Value> WorkerContextExecutionProxy::WorkerContextToV8Object(WorkerContext* workerContext)
+v8::Handle<v8::Value> WorkerContextExecutionProxy::convertWorkerContextToV8Object(WorkerContext* workerContext)
{
if (!workerContext)
return v8::Null();
- v8::Handle<v8::Context> context = workerContext->script()->proxy()->GetContext();
+ v8::Handle<v8::Context> context = workerContext->script()->proxy()->context();
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::Object> WorkerContextExecutionProxy::toV8(V8ClassIndex::V8WrapperType descriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl)
{
v8::Local<v8::Function> function;
WorkerContextExecutionProxy* proxy = retrieve();
if (proxy)
- function = proxy->GetConstructor(descType);
+ function = V8DOMWrapper::getConstructor(descriptorType, proxy->workerContext());
else
- function = V8Proxy::GetTemplate(descType)->GetFunction();
+ function = V8DOMWrapper::getTemplate(descriptorType)->GetFunction();
v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
- if (!instance.IsEmpty()) {
+ if (!instance.IsEmpty())
// Avoid setting the DOM wrapper for failed allocations.
- V8Proxy::SetDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl);
- }
+ V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(cptrType), impl);
return instance;
}
bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
{
- if (domObjectMap().contains(event)) {
- domObjectMap().forget(event);
+ if (getDOMObjectMap().contains(event)) {
+ getDOMObjectMap().forget(event);
return true;
- } else
- return false;
+ }
+ return false;
}
-v8::Local<v8::Value> WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine)
+ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine, WorkerContextExecutionState* state)
{
LOCK_V8;
v8::HandleScope hs;
@@ -348,9 +349,27 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::evaluate(const String& script,
initContextIfNeeded();
v8::Context::Scope scope(m_context);
+ v8::TryCatch exceptionCatcher;
+
v8::Local<v8::String> scriptString = v8ExternalString(script);
- v8::Handle<v8::Script> compiledScript = V8Proxy::CompileScript(scriptString, fileName, baseLine);
- return runScript(compiledScript);
+ v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, baseLine);
+ v8::Local<v8::Value> result = runScript(compiledScript);
+
+ if (exceptionCatcher.HasCaught()) {
+ v8::Local<v8::Message> message = exceptionCatcher.Message();
+ state->hadException = true;
+ state->exception = ScriptValue(exceptionCatcher.Exception());
+ state->errorMessage = toWebCoreString(message->Get());
+ state->lineNumber = message->GetLineNumber();
+ state->sourceURL = toWebCoreString(message->GetScriptResourceName());
+ exceptionCatcher.Reset();
+ } else
+ state->hadException = false;
+
+ if (result.IsEmpty() || result->IsUndefined())
+ return ScriptValue();
+
+ return ScriptValue(result);
}
v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Script> script)
@@ -361,10 +380,10 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
// 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);
+ script = V8Proxy::compileScript(code, "", 0);
}
- if (V8Proxy::HandleOutOfMemory())
+ if (V8Proxy::handleOutOfMemory())
ASSERT(script.IsEmpty());
if (script.IsEmpty())
@@ -416,7 +435,7 @@ PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateObjectEvent
return findOrCreateEventListenerHelper(object, isInline, findOnly, true);
}
-void WorkerContextExecutionProxy::RemoveEventListener(V8EventListener* listener)
+void WorkerContextExecutionProxy::removeEventListener(V8EventListener* listener)
{
m_listeners->remove(listener);
}
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
index dad191c..75024df 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
@@ -34,9 +34,10 @@
#if ENABLE(WORKERS)
-#include <v8.h>
+#include "ScriptValue.h"
#include "V8EventListenerList.h"
#include "V8Index.h"
+#include <v8.h>
#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
@@ -48,24 +49,27 @@ namespace WebCore {
class V8WorkerContextEventListener;
class WorkerContext;
+ struct WorkerContextExecutionState {
+ WorkerContextExecutionState() : hadException(false), lineNumber(0) { }
+
+ bool hadException;
+ ScriptValue exception;
+ String errorMessage;
+ int lineNumber;
+ String sourceURL;
+ };
+
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);
- 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);
+ void removeEventListener(V8EventListener*);
// Finds/creates event listener wrappers.
PassRefPtr<V8EventListener> findOrCreateEventListener(v8::Local<v8::Value> listener, bool isInline, bool findOnly);
PassRefPtr<V8EventListener> findOrCreateObjectEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly);
+ PassRefPtr<V8EventListener> findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener);
// 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
@@ -73,7 +77,10 @@ namespace WebCore {
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);
+ ScriptValue evaluate(const String& script, const String& fileName, int baseLine, WorkerContextExecutionState*);
+
+ // Returns a local handle of the context.
+ v8::Local<v8::Context> context() { return v8::Local<v8::Context>::New(m_context); }
// Returns WorkerContext object.
WorkerContext* workerContext() { return m_workerContext; }
@@ -81,20 +88,26 @@ namespace WebCore {
// Returns WorkerContextExecutionProxy object of the currently executing context. 0 will be returned if the current executing context is not the worker context.
static WorkerContextExecutionProxy* retrieve();
- // Enables HTML5 worker support.
- static bool isWebWorkersEnabled();
- static void setIsWebWorkersEnabled(bool);
+ // We have to keep all these conversion functions here before WorkerContextExecutionProxy is refactor-ed.
+ template<typename T>
+ static v8::Handle<v8::Value> convertToV8Object(V8ClassIndex::V8WrapperType type, PassRefPtr<T> impl)
+ {
+ return convertToV8Object(type, impl.get());
+ }
+ static v8::Handle<v8::Value> convertToV8Object(V8ClassIndex::V8WrapperType, void* impl);
+ static v8::Handle<v8::Value> convertEventToV8Object(Event*);
+ static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*);
+ static v8::Handle<v8::Value> convertWorkerContextToV8Object(WorkerContext*);
private:
void initV8IfNeeded();
void initContextIfNeeded();
void dispose();
- PassRefPtr<V8EventListener> findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener);
// 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 v8::Local<v8::Object> toV8(V8ClassIndex::V8WrapperType descriptorType, V8ClassIndex::V8WrapperType cptrType, void* impl);
static bool forgetV8EventObject(Event*);
diff --git a/WebCore/bindings/v8/WorkerScriptController.cpp b/WebCore/bindings/v8/WorkerScriptController.cpp
index b3ede11..f2311bf 100644
--- a/WebCore/bindings/v8/WorkerScriptController.cpp
+++ b/WebCore/bindings/v8/WorkerScriptController.cpp
@@ -40,6 +40,7 @@
#include "ScriptValue.h"
#include "DOMTimer.h"
#include "V8DOMMap.h"
+#include "V8Proxy.h"
#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
#include "WorkerObjectProxy.h"
@@ -61,21 +62,27 @@ WorkerScriptController::~WorkerScriptController()
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
+ return evaluate(sourceCode, 0);
+}
+
+ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception)
+{
{
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();
-}
+ WorkerContextExecutionState state;
+ ScriptValue result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startLine() - 1, &state);
+ if (state.hadException) {
+ if (exception)
+ *exception = state.exception;
+ else
+ m_workerContext->reportException(state.errorMessage, state.lineNumber, state.sourceURL);
+ }
-ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* /* exception */)
-{
- // FIXME: Need to return an exception.
- return evaluate(sourceCode);
+ return result;
}
void WorkerScriptController::forbidExecution()
@@ -85,9 +92,9 @@ void WorkerScriptController::forbidExecution()
m_executionForbidden = true;
}
-void WorkerScriptController::setException(ScriptValue /* exception */)
+void WorkerScriptController::setException(ScriptValue exception)
{
- notImplemented();
+ throwError(*exception.v8Value());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
new file mode 100644
index 0000000..ce759eb
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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 "AbstractWorker.h"
+
+#include "ExceptionCode.h"
+#include "ScriptExecutionContext.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8ObjectEventListener.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+PassRefPtr<EventListener> getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
+{
+ if (worker->scriptExecutionContext()->isWorkerContext()) {
+ WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+ ASSERT(workerContextProxy);
+ return workerContextProxy->findOrCreateObjectEventListener(value, isAttribute, findOnly);
+ }
+
+ V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext());
+ if (proxy) {
+ V8EventListenerList* list = proxy->objectListeners();
+ return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
+ }
+
+ return 0;
+}
+
+ACCESSOR_GETTER(AbstractWorkerOnerror)
+{
+ INC_STATS(L"DOM.AbstractWorker.onerror._get");
+ AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, info.Holder());
+ if (worker->onerror()) {
+ V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onerror());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(AbstractWorkerOnerror)
+{
+ INC_STATS(L"DOM.AbstractWorker.onerror._set");
+ AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, info.Holder());
+ V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onerror());
+ if (value->IsNull()) {
+ if (oldListener) {
+ v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
+ removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kAbstractWorkerRequestCacheIndex);
+ }
+
+ // Clear the listener.
+ worker->setOnerror(0);
+ } else {
+ RefPtr<EventListener> listener = getEventListener(worker, value, true, false);
+ if (listener) {
+ if (oldListener) {
+ v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
+ removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kAbstractWorkerRequestCacheIndex);
+ }
+
+ worker->setOnerror(listener);
+ createHiddenDependency(info.Holder(), value, V8Custom::kAbstractWorkerRequestCacheIndex);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(AbstractWorkerAddEventListener)
+{
+ INC_STATS(L"DOM.AbstractWorker.addEventListener()");
+ AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, args.Holder());
+
+ RefPtr<EventListener> listener = getEventListener(worker, args[1], false, false);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ worker->addEventListener(type, listener, useCapture);
+
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kAbstractWorkerRequestCacheIndex);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(AbstractWorkerRemoveEventListener)
+{
+ INC_STATS(L"DOM.AbstractWorker.removeEventListener()");
+ AbstractWorker* worker = V8DOMWrapper::convertToNativeObject<AbstractWorker>(V8ClassIndex::ABSTRACTWORKER, args.Holder());
+
+ RefPtr<EventListener> listener = getEventListener(worker, args[1], false, true);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ worker->removeEventListener(type, listener.get(), useCapture);
+
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kAbstractWorkerRequestCacheIndex);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8AttrCustom.cpp b/WebCore/bindings/v8/custom/V8AttrCustom.cpp
index f34a441..81f1586 100644
--- a/WebCore/bindings/v8/custom/V8AttrCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8AttrCustom.cpp
@@ -42,7 +42,7 @@ namespace WebCore {
ACCESSOR_SETTER(AttrValue)
{
- Attr* imp = V8Proxy::DOMWrapperToNode<Attr>(info.Holder());
+ Attr* imp = V8DOMWrapper::convertDOMWrapperToNode<Attr>(info.Holder());
String attrValue = toWebCoreStringWithNullCheck(value);
Element* ownerElement = imp->ownerElement();
diff --git a/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
index 1ad0e7a..6bd0035 100644
--- a/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -161,7 +161,7 @@ NAMED_PROPERTY_GETTER(CSSStyleDeclaration)
// Search the style declaration.
CSSStyleDeclaration* imp =
- V8Proxy::ToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder());
+ V8DOMWrapper::convertToNativeObject<CSSStyleDeclaration>(V8ClassIndex::CSSSTYLEDECLARATION, info.Holder());
CSSPropertyInfo* propInfo = cssPropertyInfo(name);
// Do not handle non-property names.
@@ -195,13 +195,13 @@ NAMED_PROPERTY_SETTER(CSSStyleDeclaration)
{
INC_STATS("DOM.CSSStyleDeclaration.NamedPropertySetter");
CSSStyleDeclaration* imp =
- V8Proxy::ToNativeObject<CSSStyleDeclaration>(
+ V8DOMWrapper::convertToNativeObject<CSSStyleDeclaration>(
V8ClassIndex::CSSSTYLEDECLARATION, info.Holder());
CSSPropertyInfo* propInfo = cssPropertyInfo(name);
if (!propInfo)
return notHandledByInterceptor();
- String propertyValue = valueToStringWithNullCheck(value);
+ String propertyValue = toWebCoreStringWithNullCheck(value);
if (propInfo->hadPixelOrPosPrefix)
propertyValue.append("px");
diff --git a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp
index 28f6b59..5fe2710 100644
--- a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp
@@ -41,7 +41,7 @@ namespace WebCore {
INDEXED_PROPERTY_GETTER(CanvasPixelArray)
{
INC_STATS("DOM.CanvasPixelArray.IndexedPropertyGetter");
- CanvasPixelArray* pixelBuffer = V8Proxy::ToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder());
+ CanvasPixelArray* pixelBuffer = V8DOMWrapper::convertToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder());
if ((index < 0) || (index >= pixelBuffer->length()))
return v8::Undefined();
@@ -55,7 +55,7 @@ INDEXED_PROPERTY_GETTER(CanvasPixelArray)
INDEXED_PROPERTY_SETTER(CanvasPixelArray)
{
INC_STATS("DOM.CanvasPixelArray.IndexedPropertySetter");
- CanvasPixelArray* pixelBuffer = V8Proxy::ToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder());
+ CanvasPixelArray* pixelBuffer = V8DOMWrapper::convertToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder());
if ((index >= 0) && (index < pixelBuffer->length()))
pixelBuffer->set(index, value->NumberValue());
diff --git a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
index 26086ab..676610c 100644
--- a/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp
@@ -43,6 +43,7 @@
#include "V8CustomBinding.h"
#include "V8HTMLCanvasElement.h"
#include "V8HTMLImageElement.h"
+#include "V8HTMLVideoElement.h"
#include "V8Proxy.h"
namespace WebCore {
@@ -50,10 +51,10 @@ namespace WebCore {
static v8::Handle<v8::Value> toV8(CanvasStyle* style)
{
if (style->canvasGradient())
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASGRADIENT, style->canvasGradient());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASGRADIENT, style->canvasGradient());
if (style->canvasPattern())
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, style->canvasPattern());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASPATTERN, style->canvasPattern());
return v8String(style->color());
}
@@ -64,35 +65,35 @@ static PassRefPtr<CanvasStyle> toCanvasStyle(v8::Handle<v8::Value> value)
return CanvasStyle::create(toWebCoreString(value));
if (V8CanvasGradient::HasInstance(value))
- return CanvasStyle::create(V8Proxy::DOMWrapperToNative<CanvasGradient>(value));
+ return CanvasStyle::create(V8DOMWrapper::convertDOMWrapperToNative<CanvasGradient>(v8::Handle<v8::Object>::Cast(value)));
if (V8CanvasPattern::HasInstance(value))
- return CanvasStyle::create(V8Proxy::DOMWrapperToNative<CanvasPattern>(value));
+ return CanvasStyle::create(V8DOMWrapper::convertDOMWrapperToNative<CanvasPattern>(v8::Handle<v8::Object>::Cast(value)));
return 0;
}
ACCESSOR_GETTER(CanvasRenderingContext2DStrokeStyle)
{
- CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ CanvasRenderingContext2D* impl = V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
return toV8(impl->strokeStyle());
}
ACCESSOR_SETTER(CanvasRenderingContext2DStrokeStyle)
{
- CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ CanvasRenderingContext2D* impl = V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
impl->setStrokeStyle(toCanvasStyle(value));
}
ACCESSOR_GETTER(CanvasRenderingContext2DFillStyle)
{
- CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ CanvasRenderingContext2D* impl = V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
return toV8(impl->fillStyle());
}
ACCESSOR_SETTER(CanvasRenderingContext2DFillStyle)
{
- CanvasRenderingContext2D* impl = V8Proxy::DOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
+ CanvasRenderingContext2D* impl = V8DOMWrapper::convertDOMWrapperToNative<CanvasRenderingContext2D>(info.Holder());
impl->setFillStyle(toCanvasStyle(value));
}
@@ -101,17 +102,17 @@ ACCESSOR_SETTER(CanvasRenderingContext2DFillStyle)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor)
{
INC_STATS("DOM.CanvasRenderingContext2D.setStrokeColor()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
switch (args.Length()) {
case 1:
if (args[0]->IsString())
- context->setStrokeColor(ToWebCoreString(args[0]));
+ context->setStrokeColor(toWebCoreString(args[0]));
else
context->setStrokeColor(toFloat(args[0]));
break;
case 2:
if (args[0]->IsString())
- context->setStrokeColor(ToWebCoreString(args[0]), toFloat(args[1]));
+ context->setStrokeColor(toWebCoreString(args[0]), toFloat(args[1]));
else
context->setStrokeColor(toFloat(args[0]), toFloat(args[1]));
break;
@@ -122,7 +123,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor)
context->setStrokeColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
break;
default:
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "setStrokeColor: Invalid number of arguments");
+ V8Proxy::throwError(V8Proxy::SyntaxError, "setStrokeColor: Invalid number of arguments");
break;
}
return v8::Undefined();
@@ -131,17 +132,17 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetStrokeColor)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor)
{
INC_STATS("DOM.CanvasRenderingContext2D.setFillColor()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
switch (args.Length()) {
case 1:
if (args[0]->IsString())
- context->setFillColor(ToWebCoreString(args[0]));
+ context->setFillColor(toWebCoreString(args[0]));
else
context->setFillColor(toFloat(args[0]));
break;
case 2:
if (args[0]->IsString())
- context->setFillColor(ToWebCoreString(args[0]), toFloat(args[1]));
+ context->setFillColor(toWebCoreString(args[0]), toFloat(args[1]));
else
context->setFillColor(toFloat(args[0]), toFloat(args[1]));
break;
@@ -152,7 +153,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor)
context->setFillColor(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
break;
default:
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "setFillColor: Invalid number of arguments");
+ V8Proxy::throwError(V8Proxy::SyntaxError, "setFillColor: Invalid number of arguments");
break;
}
return v8::Undefined();
@@ -161,13 +162,13 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetFillColor)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeRect)
{
INC_STATS("DOM.CanvasRenderingContext2D.strokeRect()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
if (args.Length() == 5)
context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
else if (args.Length() == 4)
context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
else {
- V8Proxy::SetDOMException(INDEX_SIZE_ERR);
+ V8Proxy::setDOMException(INDEX_SIZE_ERR);
return notHandledByInterceptor();
}
return v8::Undefined();
@@ -176,7 +177,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeRect)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow)
{
INC_STATS("DOM.CanvasRenderingContext2D.setShadow()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
switch (args.Length()) {
case 3:
@@ -184,13 +185,13 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow)
break;
case 4:
if (args[3]->IsString())
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), ToWebCoreString(args[3]));
+ context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]));
else
context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
break;
case 5:
if (args[3]->IsString())
- context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), ToWebCoreString(args[3]), toFloat(args[4]));
+ context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]), toFloat(args[4]));
else
context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
break;
@@ -201,7 +202,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow)
context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]));
break;
default:
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "setShadow: Invalid number of arguments");
+ V8Proxy::throwError(V8Proxy::SyntaxError, "setShadow: Invalid number of arguments");
break;
}
@@ -211,13 +212,13 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DSetShadow)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage)
{
INC_STATS("DOM.CanvasRenderingContext2D.drawImage()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
v8::Handle<v8::Value> arg = args[0];
if (V8HTMLImageElement::HasInstance(arg)) {
ExceptionCode ec = 0;
- HTMLImageElement* image_element = V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg);
+ HTMLImageElement* image_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLImageElement>(v8::Handle<v8::Object>::Cast(arg));
switch (args.Length()) {
case 3:
context->drawImage(image_element, toFloat(args[1]), toFloat(args[2]));
@@ -225,7 +226,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage)
case 5:
context->drawImage(image_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
break;
@@ -235,13 +236,12 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage)
FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
break;
default:
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "drawImage: Invalid number of arguments");
- return v8::Undefined();
+ return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
}
return v8::Undefined();
}
@@ -249,7 +249,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage)
// HTMLCanvasElement
if (V8HTMLCanvasElement::HasInstance(arg)) {
ExceptionCode ec = 0;
- HTMLCanvasElement* canvas_element = V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(arg);
+ HTMLCanvasElement* canvas_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLCanvasElement>(v8::Handle<v8::Object>::Cast(arg));
switch (args.Length()) {
case 3:
context->drawImage(canvas_element, toFloat(args[1]), toFloat(args[2]));
@@ -257,7 +257,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage)
case 5:
context->drawImage(canvas_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
break;
@@ -267,33 +267,65 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImage)
FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
break;
default:
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "drawImage: Invalid number of arguments");
- return v8::Undefined();
+ return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
}
return v8::Undefined();
}
- V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+#if ENABLE(VIDEO)
+ // HTMLVideoElement
+ if (V8HTMLVideoElement::HasInstance(arg)) {
+ ExceptionCode ec = 0;
+ HTMLVideoElement* video_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLVideoElement>(v8::Handle<v8::Object>::Cast(arg));
+ switch (args.Length()) {
+ case 3:
+ context->drawImage(video_element, toFloat(args[1]), toFloat(args[2]));
+ break;
+ case 5:
+ context->drawImage(video_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), ec);
+ if (ec != 0) {
+ V8Proxy::setDOMException(ec);
+ return notHandledByInterceptor();
+ }
+ break;
+ case 9:
+ context->drawImage(video_element,
+ FloatRect(toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4])),
+ FloatRect(toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8])),
+ ec);
+ if (ec != 0) {
+ V8Proxy::setDOMException(ec);
+ return notHandledByInterceptor();
+ }
+ break;
+ default:
+ return throwError("drawImage: Invalid number of arguments", V8Proxy::SyntaxError);
+ }
+ return v8::Undefined();
+ }
+#endif
+
+ V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
return notHandledByInterceptor();
}
CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImageFromRect)
{
INC_STATS("DOM.CanvasRenderingContext2D.drawImageFromRect()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
v8::Handle<v8::Value> arg = args[0];
if (V8HTMLImageElement::HasInstance(arg)) {
- HTMLImageElement* image_element = V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg);
- context->drawImageFromRect(image_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8]), ToWebCoreString(args[9]));
+ HTMLImageElement* image_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLImageElement>(v8::Handle<v8::Object>::Cast(arg));
+ context->drawImageFromRect(image_element, toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8]), toWebCoreString(args[9]));
} else
- V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "drawImageFromRect: Invalid type of arguments");
+ V8Proxy::throwError(V8Proxy::TypeError, "drawImageFromRect: Invalid type of arguments");
return v8::Undefined();
}
@@ -301,33 +333,33 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DDrawImageFromRect)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DCreatePattern)
{
INC_STATS("DOM.CanvasRenderingContext2D.createPattern()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
v8::Handle<v8::Value> arg = args[0];
if (V8HTMLImageElement::HasInstance(arg)) {
- HTMLImageElement* image_element = V8Proxy::DOMWrapperToNode<HTMLImageElement>(arg);
+ HTMLImageElement* image_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLImageElement>(v8::Handle<v8::Object>::Cast(arg));
ExceptionCode ec = 0;
- RefPtr<CanvasPattern> pattern = context->createPattern(image_element, valueToStringWithNullCheck(args[1]), ec);
+ RefPtr<CanvasPattern> pattern = context->createPattern(image_element, toWebCoreStringWithNullCheck(args[1]), ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, pattern.get());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASPATTERN, pattern.release());
}
if (V8HTMLCanvasElement::HasInstance(arg)) {
- HTMLCanvasElement* canvas_element = V8Proxy::DOMWrapperToNode<HTMLCanvasElement>(arg);
+ HTMLCanvasElement* canvas_element = V8DOMWrapper::convertDOMWrapperToNode<HTMLCanvasElement>(v8::Handle<v8::Object>::Cast(arg));
ExceptionCode ec = 0;
- RefPtr<CanvasPattern> pattern = context->createPattern(canvas_element, valueToStringWithNullCheck(args[1]), ec);
+ RefPtr<CanvasPattern> pattern = context->createPattern(canvas_element, toWebCoreStringWithNullCheck(args[1]), ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASPATTERN, pattern.get());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASPATTERN, pattern.release());
}
- V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
return notHandledByInterceptor();
}
@@ -335,17 +367,17 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DFillText)
{
INC_STATS("DOM.CanvasRenderingContext2D.fillText()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
// Two forms:
// * fillText(text, x, y)
// * fillText(text, x, y, maxWidth)
if (args.Length() < 3 || args.Length() > 4) {
- V8Proxy::SetDOMException(SYNTAX_ERR);
+ V8Proxy::setDOMException(SYNTAX_ERR);
return notHandledByInterceptor();
}
- String text = ToWebCoreString(args[0]);
+ String text = toWebCoreString(args[0]);
float x = toFloat(args[1]);
float y = toFloat(args[2]);
@@ -361,17 +393,17 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DFillText)
CALLBACK_FUNC_DECL(CanvasRenderingContext2DStrokeText)
{
INC_STATS("DOM.CanvasRenderingContext2D.strokeText()");
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
// Two forms:
// * strokeText(text, x, y)
// * strokeText(text, x, y, maxWidth)
if (args.Length() < 3 || args.Length() > 4) {
- V8Proxy::SetDOMException(SYNTAX_ERR);
+ V8Proxy::setDOMException(SYNTAX_ERR);
return notHandledByInterceptor();
}
- String text = ToWebCoreString(args[0]);
+ String text = toWebCoreString(args[0]);
float x = toFloat(args[1]);
float y = toFloat(args[2]);
@@ -392,20 +424,20 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DPutImageData)
// * putImageData(ImageData, x, y)
// * putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
if (args.Length() != 3 && args.Length() != 7) {
- V8Proxy::SetDOMException(SYNTAX_ERR);
+ V8Proxy::setDOMException(SYNTAX_ERR);
return notHandledByInterceptor();
}
- CanvasRenderingContext2D* context = V8Proxy::ToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
+ CanvasRenderingContext2D* context = V8DOMWrapper::convertToNativeObject<CanvasRenderingContext2D>(V8ClassIndex::CANVASRENDERINGCONTEXT2D, args.Holder());
ImageData* imageData = 0;
// Need to check that the argument is of the correct type, since
- // ToNativeObject() expects it to be correct. If the argument was incorrect
+ // convertToNativeObject() expects it to be correct. If the argument was incorrect
// we leave it null, and putImageData() will throw the correct exception
// (TYPE_MISMATCH_ERR).
- if (V8Proxy::IsWrapperOfType(args[0], V8ClassIndex::IMAGEDATA))
- imageData = V8Proxy::ToNativeObject<ImageData>(V8ClassIndex::IMAGEDATA, args[0]);
+ if (V8DOMWrapper::isWrapperOfType(args[0], V8ClassIndex::IMAGEDATA))
+ imageData = V8DOMWrapper::convertToNativeObject<ImageData>(V8ClassIndex::IMAGEDATA, v8::Handle<v8::Object>::Cast(args[0]));
ExceptionCode ec = 0;
@@ -415,7 +447,7 @@ CALLBACK_FUNC_DECL(CanvasRenderingContext2DPutImageData)
context->putImageData(imageData, toFloat(args[1]), toFloat(args[2]), ec);
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return notHandledByInterceptor();
}
diff --git a/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp b/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp
index e3f89b9..3c62e14 100644
--- a/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ClientRectListCustom.cpp
@@ -44,12 +44,12 @@ namespace WebCore {
INDEXED_PROPERTY_GETTER(ClientRectList)
{
INC_STATS("DOM.ClientRectList.IndexedPropertyGetter");
- ClientRectList* imp = V8Proxy::ToNativeObject<ClientRectList>(V8ClassIndex::CLIENTRECTLIST, info.Holder());
+ ClientRectList* imp = V8DOMWrapper::convertToNativeObject<ClientRectList>(V8ClassIndex::CLIENTRECTLIST, info.Holder());
RefPtr<ClientRect> result = imp->item(index);
if (!result)
return notHandledByInterceptor();
- return V8Proxy::ToV8Object(V8ClassIndex::CLIENTRECT, result.get());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CLIENTRECT, result.release());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp b/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp
index eff5511..4526304 100644
--- a/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ClipboardCustom.cpp
@@ -47,7 +47,7 @@ namespace WebCore {
ACCESSOR_GETTER(ClipboardTypes)
{
INC_STATS("DOM.Clipboard.types()");
- Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, info.Holder());
+ Clipboard* clipboard = V8DOMWrapper::convertToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, info.Holder());
HashSet<String> types = clipboard->types();
if (types.isEmpty())
@@ -65,7 +65,7 @@ ACCESSOR_GETTER(ClipboardTypes)
CALLBACK_FUNC_DECL(ClipboardClearData)
{
INC_STATS("DOM.Clipboard.clearData()");
- Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+ Clipboard* clipboard = V8DOMWrapper::convertToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
if (!args.Length()) {
clipboard->clearAllData();
@@ -73,7 +73,7 @@ CALLBACK_FUNC_DECL(ClipboardClearData)
}
if (args.Length() != 1)
- return throwError("clearData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("clearData: Invalid number of arguments", V8Proxy::SyntaxError);
String type = toWebCoreString(args[0]);
clipboard->clearData(type);
@@ -83,10 +83,10 @@ CALLBACK_FUNC_DECL(ClipboardClearData)
CALLBACK_FUNC_DECL(ClipboardGetData)
{
INC_STATS("DOM.Clipboard.getData()");
- Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+ Clipboard* clipboard = V8DOMWrapper::convertToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
if (args.Length() != 1)
- return throwError("getData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("getData: Invalid number of arguments", V8Proxy::SyntaxError);
bool success;
String result = clipboard->getData(toWebCoreString(args[0]), success);
@@ -99,10 +99,10 @@ CALLBACK_FUNC_DECL(ClipboardGetData)
CALLBACK_FUNC_DECL(ClipboardSetData)
{
INC_STATS("DOM.Clipboard.setData()");
- Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+ Clipboard* clipboard = V8DOMWrapper::convertToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
if (args.Length() != 2)
- return throwError("setData: Invalid number of arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("setData: Invalid number of arguments", V8Proxy::SyntaxError);
String type = toWebCoreString(args[0]);
String data = toWebCoreString(args[1]);
@@ -112,20 +112,20 @@ CALLBACK_FUNC_DECL(ClipboardSetData)
CALLBACK_FUNC_DECL(ClipboardSetDragImage)
{
INC_STATS("DOM.Clipboard.setDragImage()");
- Clipboard* clipboard = V8Proxy::ToNativeObject<Clipboard>(V8ClassIndex::CLIPBOARD, args.Holder());
+ Clipboard* clipboard = V8DOMWrapper::convertToNativeObject<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);
+ return throwError("setDragImage: Invalid number of arguments", V8Proxy::SyntaxError);
int x = toInt32(args[1]);
int y = toInt32(args[2]);
Node* node = 0;
if (V8Node::HasInstance(args[0]))
- node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
if (!node || !node->isElementNode())
return throwError("setDragImageFromElement: Invalid first argument");
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.cpp b/WebCore/bindings/v8/custom/V8CustomBinding.cpp
index 7789797..ee45abd 100644
--- a/WebCore/bindings/v8/custom/V8CustomBinding.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomBinding.cpp
@@ -49,9 +49,9 @@ namespace WebCore {
bool allowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase* frame, String value)
{
- if (protocolIs(parseURL(value), "javascript")) {
+ if (protocolIs(deprecatedParseURL(value), "javascript")) {
Node* contentDoc = frame->contentDocument();
- if (contentDoc && !V8Proxy::CheckNodeSecurity(contentDoc))
+ if (contentDoc && !V8Proxy::checkNodeSecurity(contentDoc))
return false;
}
return true;
@@ -64,6 +64,7 @@ bool allowSettingSrcToJavascriptURL(Element* element, String name, String value)
return true;
}
+#ifdef MANUAL_MERGE_REQUIRED
// DOMImplementation is a singleton in WebCore. If we use our normal
// mapping from DOM objects to V8 wrappers, the same wrapper will be
// shared for all frames in the same process. This is a major
@@ -179,4 +180,121 @@ V8ClassIndex::V8WrapperType V8Custom::DowncastSVGPathSeg(void* pathSeg)
#endif // ENABLE(SVG)
+#else // MANUAL_MERGE_REQUIRED
+// DOMImplementation is a singleton in WebCore. If we use our normal
+// mapping from DOM objects to V8 wrappers, the same wrapper will be
+// shared for all frames in the same process. This is a major
+// security problem. Therefore, we generate a DOMImplementation
+// wrapper per document and store it in an internal field of the
+// document. Since the DOMImplementation object is a singleton, we do
+// not have to do anything to keep the DOMImplementation object alive
+// for the lifetime of the wrapper.
+ACCESSOR_GETTER(DocumentImplementation)
+{
+ ASSERT(info.Holder()->InternalFieldCount() >= kDocumentMinimumInternalFieldCount);
+
+ // Check if the internal field already contains a wrapper.
+ v8::Local<v8::Value> implementation = info.Holder()->GetInternalField(kDocumentImplementationIndex);
+ if (!implementation->IsUndefined())
+ return implementation;
+
+ // Generate a wrapper.
+ Document* document = V8DOMWrapper::convertDOMWrapperToNative<Document>(info.Holder());
+ v8::Handle<v8::Value> wrapper = V8DOMWrapper::convertDOMImplementationToV8Object(document->implementation());
+
+ // Store the wrapper in the internal field.
+ info.Holder()->SetInternalField(kDocumentImplementationIndex, wrapper);
+
+ return wrapper;
+}
+
+// --------------- Security Checks -------------------------
+INDEXED_ACCESS_CHECK(History)
+{
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
+ // Only allow same origin access.
+ History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, host);
+ return V8Proxy::canAccessFrame(history->frame(), false);
+}
+
+NAMED_ACCESS_CHECK(History)
+{
+ ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::HISTORY);
+ // Only allow same origin access.
+ History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, host);
+ return V8Proxy::canAccessFrame(history->frame(), false);
+}
+
+#undef INDEXED_ACCESS_CHECK
+#undef NAMED_ACCESS_CHECK
+#undef NAMED_PROPERTY_GETTER
+#undef NAMED_PROPERTY_SETTER
+
+Frame* V8Custom::GetTargetFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data)
+{
+ Frame* target = 0;
+ switch (V8ClassIndex::FromInt(data->Int32Value())) {
+ case V8ClassIndex::DOMWINDOW: {
+ v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
+ if (window.IsEmpty())
+ return target;
+
+ DOMWindow* targetWindow = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+ target = targetWindow->frame();
+ break;
+ }
+ case V8ClassIndex::LOCATION: {
+ History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, host);
+ target = history->frame();
+ break;
+ }
+ case V8ClassIndex::HISTORY: {
+ Location* location = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, host);
+ target = location->frame();
+ break;
+ }
+ default:
+ break;
+ }
+ return target;
+}
+
+#if ENABLE(SVG)
+V8ClassIndex::V8WrapperType V8Custom::DowncastSVGPathSeg(void* pathSeg)
+{
+ WebCore::SVGPathSeg* realPathSeg = reinterpret_cast<WebCore::SVGPathSeg*>(pathSeg);
+
+ switch (realPathSeg->pathSegType()) {
+#define MAKE_CASE(svgValue, v8Value) case WebCore::SVGPathSeg::svgValue: return V8ClassIndex::v8Value
+
+ MAKE_CASE(PATHSEG_CLOSEPATH, SVGPATHSEGCLOSEPATH);
+ MAKE_CASE(PATHSEG_MOVETO_ABS, SVGPATHSEGMOVETOABS);
+ MAKE_CASE(PATHSEG_MOVETO_REL, SVGPATHSEGMOVETOREL);
+ MAKE_CASE(PATHSEG_LINETO_ABS, SVGPATHSEGLINETOABS);
+ MAKE_CASE(PATHSEG_LINETO_REL, SVGPATHSEGLINETOREL);
+ MAKE_CASE(PATHSEG_CURVETO_CUBIC_ABS, SVGPATHSEGCURVETOCUBICABS);
+ MAKE_CASE(PATHSEG_CURVETO_CUBIC_REL, SVGPATHSEGCURVETOCUBICREL);
+ MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_ABS, SVGPATHSEGCURVETOQUADRATICABS);
+ MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_REL, SVGPATHSEGCURVETOQUADRATICREL);
+ MAKE_CASE(PATHSEG_ARC_ABS, SVGPATHSEGARCABS);
+ MAKE_CASE(PATHSEG_ARC_REL, SVGPATHSEGARCREL);
+ MAKE_CASE(PATHSEG_LINETO_HORIZONTAL_ABS, SVGPATHSEGLINETOHORIZONTALABS);
+ MAKE_CASE(PATHSEG_LINETO_HORIZONTAL_REL, SVGPATHSEGLINETOHORIZONTALREL);
+ MAKE_CASE(PATHSEG_LINETO_VERTICAL_ABS, SVGPATHSEGLINETOVERTICALABS);
+ MAKE_CASE(PATHSEG_LINETO_VERTICAL_REL, SVGPATHSEGLINETOVERTICALREL);
+ MAKE_CASE(PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, SVGPATHSEGCURVETOCUBICSMOOTHABS);
+ MAKE_CASE(PATHSEG_CURVETO_CUBIC_SMOOTH_REL, SVGPATHSEGCURVETOCUBICSMOOTHREL);
+ MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, SVGPATHSEGCURVETOQUADRATICSMOOTHABS);
+ MAKE_CASE(PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, SVGPATHSEGCURVETOQUADRATICSMOOTHREL);
+
+#undef MAKE_CASE
+
+ default:
+ return V8ClassIndex::INVALID_CLASS_INDEX;
+ }
+}
+
+#endif // ENABLE(SVG)
+
+#endif // MANUAL_MERGE_REQUIRED
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h
index e039c6f..42aca44 100644
--- a/WebCore/bindings/v8/custom/V8CustomBinding.h
+++ b/WebCore/bindings/v8/custom/V8CustomBinding.h
@@ -91,6 +91,7 @@ namespace WebCore {
bool allowSettingFrameSrcToJavascriptUrl(HTMLFrameElementBase*, String value);
bool allowSettingSrcToJavascriptURL(Element*, String name, String value);
+#ifdef MANUAL_MERGE_REQUIRED
class V8Custom {
public:
// Constants.
@@ -542,6 +543,469 @@ namespace WebCore {
static void WindowSetLocation(DOMWindow*, const String&);
};
+#else // MANUAL_MERGE_REQUIRED
+ class V8Custom {
+ public:
+ // Constants.
+ static const int kDOMWrapperTypeIndex = 0;
+ static const int kDOMWrapperObjectIndex = 1;
+ static const int kDefaultWrapperInternalFieldCount = 2;
+
+ static const int kNPObjectInternalFieldCount = kDefaultWrapperInternalFieldCount + 0;
+
+ static const int kNodeEventListenerCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kNodeMinimumInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kDocumentImplementationIndex = kNodeMinimumInternalFieldCount + 0;
+ static const int kDocumentMinimumInternalFieldCount = kNodeMinimumInternalFieldCount + 1;
+
+ static const int kHTMLDocumentMarkerIndex = kDocumentMinimumInternalFieldCount + 0;
+ static const int kHTMLDocumentShadowIndex = kDocumentMinimumInternalFieldCount + 1;
+ static const int kHTMLDocumentInternalFieldCount = kDocumentMinimumInternalFieldCount + 2;
+
+ static const int kXMLHttpRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kXMLHttpRequestInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kMessageChannelPort1Index = kDefaultWrapperInternalFieldCount + 0;
+ static const int kMessageChannelPort2Index = kDefaultWrapperInternalFieldCount + 1;
+ static const int kMessageChannelInternalFieldCount = kDefaultWrapperInternalFieldCount + 2;
+
+ static const int kMessagePortRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kMessagePortEntangledPortIndex = kDefaultWrapperInternalFieldCount + 1;
+ static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 2;
+
+#if ENABLE(WORKERS)
+ static const int kWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kWorkerContextRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kWorkerContextMinimumInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kDedicatedWorkerContextRequestCacheIndex = kWorkerContextMinimumInternalFieldCount + 0;
+ static const int kDedicatedWorkerContextInternalFieldCount = kWorkerContextMinimumInternalFieldCount + 1;
+
+ static const int kAbstractWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kAbstractWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+#endif
+
+ static const int kDOMWindowConsoleIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kDOMWindowHistoryIndex = kDefaultWrapperInternalFieldCount + 1;
+ static const int kDOMWindowLocationbarIndex = kDefaultWrapperInternalFieldCount + 2;
+ static const int kDOMWindowMenubarIndex = kDefaultWrapperInternalFieldCount + 3;
+ static const int kDOMWindowNavigatorIndex = kDefaultWrapperInternalFieldCount + 4;
+ static const int kDOMWindowPersonalbarIndex = kDefaultWrapperInternalFieldCount + 5;
+ static const int kDOMWindowScreenIndex = kDefaultWrapperInternalFieldCount + 6;
+ static const int kDOMWindowScrollbarsIndex = kDefaultWrapperInternalFieldCount + 7;
+ static const int kDOMWindowSelectionIndex = kDefaultWrapperInternalFieldCount + 8;
+ static const int kDOMWindowStatusbarIndex = kDefaultWrapperInternalFieldCount + 9;
+ static const int kDOMWindowToolbarIndex = kDefaultWrapperInternalFieldCount + 10;
+ static const int kDOMWindowLocationIndex = kDefaultWrapperInternalFieldCount + 11;
+ static const int kDOMWindowDOMSelectionIndex = kDefaultWrapperInternalFieldCount + 12;
+ static const int kDOMWindowInternalFieldCount = kDefaultWrapperInternalFieldCount + 13;
+
+ static const int kStyleSheetOwnerNodeIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kStyleSheetInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ static const int kDOMApplicationCacheCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kDOMApplicationCacheFieldCount = kDefaultWrapperInternalFieldCount + 1;
+#endif
+
+#define DECLARE_PROPERTY_ACCESSOR_GETTER(NAME) \
+ static v8::Handle<v8::Value> v8##NAME##AccessorGetter( \
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define DECLARE_PROPERTY_ACCESSOR_SETTER(NAME) \
+ static void v8##NAME##AccessorSetter(v8::Local<v8::String> name, \
+ v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+
+#define DECLARE_PROPERTY_ACCESSOR(NAME) DECLARE_PROPERTY_ACCESSOR_GETTER(NAME); DECLARE_PROPERTY_ACCESSOR_SETTER(NAME)
+
+#define DECLARE_NAMED_PROPERTY_GETTER(NAME) \
+ static v8::Handle<v8::Value> v8##NAME##NamedPropertyGetter( \
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define DECLARE_NAMED_PROPERTY_SETTER(NAME) \
+ static v8::Handle<v8::Value> v8##NAME##NamedPropertySetter( \
+ v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+
+#define DECLARE_NAMED_PROPERTY_DELETER(NAME) \
+ static v8::Handle<v8::Boolean> v8##NAME##NamedPropertyDeleter( \
+ v8::Local<v8::String> name, const v8::AccessorInfo& info)
+
+#define USE_NAMED_PROPERTY_GETTER(NAME) V8Custom::v8##NAME##NamedPropertyGetter
+
+#define USE_NAMED_PROPERTY_SETTER(NAME) V8Custom::v8##NAME##NamedPropertySetter
+
+#define USE_NAMED_PROPERTY_DELETER(NAME) V8Custom::v8##NAME##NamedPropertyDeleter
+
+#define DECLARE_INDEXED_PROPERTY_GETTER(NAME) \
+ static v8::Handle<v8::Value> v8##NAME##IndexedPropertyGetter( \
+ uint32_t index, const v8::AccessorInfo& info)
+
+#define DECLARE_INDEXED_PROPERTY_SETTER(NAME) \
+ static v8::Handle<v8::Value> v8##NAME##IndexedPropertySetter( \
+ uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+
+#define DECLARE_INDEXED_PROPERTY_DELETER(NAME) \
+ static v8::Handle<v8::Boolean> v8##NAME##IndexedPropertyDeleter( \
+ uint32_t index, const v8::AccessorInfo& info)
+
+#define USE_INDEXED_PROPERTY_GETTER(NAME) V8Custom::v8##NAME##IndexedPropertyGetter
+
+#define USE_INDEXED_PROPERTY_SETTER(NAME) V8Custom::v8##NAME##IndexedPropertySetter
+
+#define USE_INDEXED_PROPERTY_DELETER(NAME) V8Custom::v8##NAME##IndexedPropertyDeleter
+
+#define DECLARE_CALLBACK(NAME) static v8::Handle<v8::Value> v8##NAME##Callback(const v8::Arguments& args)
+
+#define USE_CALLBACK(NAME) V8Custom::v8##NAME##Callback
+
+#define DECLARE_NAMED_ACCESS_CHECK(NAME) \
+ static bool v8##NAME##NamedSecurityCheck(v8::Local<v8::Object> host, \
+ v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value> data)
+
+#define DECLARE_INDEXED_ACCESS_CHECK(NAME) \
+ static bool v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \
+ uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+
+ DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DStrokeStyle);
+ DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DFillStyle);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowEvent);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowCrypto);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(DOMWindowLocation);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(DOMWindowOpener);
+
+ DECLARE_PROPERTY_ACCESSOR(DocumentLocation);
+ DECLARE_PROPERTY_ACCESSOR(DocumentImplementation);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(EventSrcElement);
+ DECLARE_PROPERTY_ACCESSOR(EventReturnValue);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(EventDataTransfer);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(EventClipboardData);
+
+ DECLARE_PROPERTY_ACCESSOR(DOMWindowEventHandler);
+ DECLARE_PROPERTY_ACCESSOR(NodeEventHandler);
+
+ DECLARE_CALLBACK(HTMLCanvasElementGetContext);
+
+ DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLFrameElementSrc);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLFrameElementLocation);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(HTMLIFrameElementSrc);
+
+ DECLARE_PROPERTY_ACCESSOR_SETTER(AttrValue);
+
+ DECLARE_PROPERTY_ACCESSOR(HTMLOptionsCollectionLength);
+
+ DECLARE_CALLBACK(HTMLInputElementSetSelectionRange);
+
+ DECLARE_PROPERTY_ACCESSOR(HTMLInputElementSelectionStart);
+ DECLARE_PROPERTY_ACCESSOR(HTMLInputElementSelectionEnd);
+
+ DECLARE_NAMED_ACCESS_CHECK(Location);
+ DECLARE_INDEXED_ACCESS_CHECK(History);
+
+ DECLARE_NAMED_ACCESS_CHECK(History);
+ DECLARE_INDEXED_ACCESS_CHECK(Location);
+
+ DECLARE_CALLBACK(HTMLCollectionItem);
+ DECLARE_CALLBACK(HTMLCollectionNamedItem);
+ DECLARE_CALLBACK(HTMLCollectionCallAsFunction);
+
+ DECLARE_CALLBACK(HTMLSelectElementRemove);
+
+ DECLARE_CALLBACK(HTMLOptionsCollectionRemove);
+ DECLARE_CALLBACK(HTMLOptionsCollectionAdd);
+
+ DECLARE_CALLBACK(HTMLDocumentWrite);
+ DECLARE_CALLBACK(HTMLDocumentWriteln);
+ DECLARE_CALLBACK(HTMLDocumentOpen);
+ DECLARE_PROPERTY_ACCESSOR(HTMLDocumentAll);
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLDocument);
+ DECLARE_NAMED_PROPERTY_DELETER(HTMLDocument);
+
+ DECLARE_CALLBACK(DocumentEvaluate);
+ DECLARE_CALLBACK(DocumentGetCSSCanvasContext);
+
+ DECLARE_CALLBACK(DOMWindowAddEventListener);
+ DECLARE_CALLBACK(DOMWindowRemoveEventListener);
+ DECLARE_CALLBACK(DOMWindowPostMessage);
+ DECLARE_CALLBACK(DOMWindowSetTimeout);
+ DECLARE_CALLBACK(DOMWindowSetInterval);
+ DECLARE_CALLBACK(DOMWindowAtob);
+ DECLARE_CALLBACK(DOMWindowBtoa);
+ DECLARE_CALLBACK(DOMWindowNOP);
+ DECLARE_CALLBACK(DOMWindowToString);
+ DECLARE_CALLBACK(DOMWindowShowModalDialog);
+ DECLARE_CALLBACK(DOMWindowOpen);
+ DECLARE_CALLBACK(DOMWindowClearTimeout);
+ DECLARE_CALLBACK(DOMWindowClearInterval);
+
+ DECLARE_CALLBACK(DOMParserConstructor);
+ DECLARE_CALLBACK(HTMLAudioElementConstructor);
+ DECLARE_CALLBACK(HTMLImageElementConstructor);
+ DECLARE_CALLBACK(HTMLOptionElementConstructor);
+ DECLARE_CALLBACK(MessageChannelConstructor);
+ DECLARE_CALLBACK(WebKitCSSMatrixConstructor);
+ DECLARE_CALLBACK(WebKitPointConstructor);
+ DECLARE_CALLBACK(XMLHttpRequestConstructor);
+ DECLARE_CALLBACK(XMLSerializerConstructor);
+ DECLARE_CALLBACK(XPathEvaluatorConstructor);
+ DECLARE_CALLBACK(XSLTProcessorConstructor);
+
+ DECLARE_CALLBACK(XSLTProcessorImportStylesheet);
+ DECLARE_CALLBACK(XSLTProcessorTransformToFragment);
+ DECLARE_CALLBACK(XSLTProcessorTransformToDocument);
+ DECLARE_CALLBACK(XSLTProcessorSetParameter);
+ DECLARE_CALLBACK(XSLTProcessorGetParameter);
+ DECLARE_CALLBACK(XSLTProcessorRemoveParameter);
+
+ DECLARE_CALLBACK(CSSPrimitiveValueGetRGBColorValue);
+
+ DECLARE_CALLBACK(CanvasRenderingContext2DSetStrokeColor);
+ DECLARE_CALLBACK(CanvasRenderingContext2DSetFillColor);
+ DECLARE_CALLBACK(CanvasRenderingContext2DStrokeRect);
+ DECLARE_CALLBACK(CanvasRenderingContext2DSetShadow);
+ DECLARE_CALLBACK(CanvasRenderingContext2DDrawImage);
+ DECLARE_CALLBACK(CanvasRenderingContext2DDrawImageFromRect);
+ DECLARE_CALLBACK(CanvasRenderingContext2DCreatePattern);
+ DECLARE_CALLBACK(CanvasRenderingContext2DFillText);
+ DECLARE_CALLBACK(CanvasRenderingContext2DStrokeText);
+ DECLARE_CALLBACK(CanvasRenderingContext2DPutImageData);
+
+ DECLARE_PROPERTY_ACCESSOR_GETTER(ClipboardTypes);
+ DECLARE_CALLBACK(ClipboardClearData);
+ DECLARE_CALLBACK(ClipboardGetData);
+ DECLARE_CALLBACK(ClipboardSetData);
+ DECLARE_CALLBACK(ClipboardSetDragImage);
+
+ DECLARE_CALLBACK(ElementQuerySelector);
+ DECLARE_CALLBACK(ElementQuerySelectorAll);
+ DECLARE_CALLBACK(ElementSetAttribute);
+ DECLARE_CALLBACK(ElementSetAttributeNode);
+ DECLARE_CALLBACK(ElementSetAttributeNS);
+ DECLARE_CALLBACK(ElementSetAttributeNodeNS);
+
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationProtocol);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHost);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHostname);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationPort);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationPathname);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationSearch);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHash);
+ DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHref);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(LocationAssign);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(LocationReplace);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(LocationReload);
+ DECLARE_CALLBACK(LocationAssign);
+ DECLARE_CALLBACK(LocationReplace);
+ DECLARE_CALLBACK(LocationReload);
+ DECLARE_CALLBACK(LocationToString);
+ DECLARE_CALLBACK(LocationValueOf);
+
+ DECLARE_CALLBACK(NodeAddEventListener);
+ DECLARE_CALLBACK(NodeRemoveEventListener);
+ DECLARE_CALLBACK(NodeInsertBefore);
+ DECLARE_CALLBACK(NodeReplaceChild);
+ DECLARE_CALLBACK(NodeRemoveChild);
+ DECLARE_CALLBACK(NodeAppendChild);
+
+ // We actually only need this because WebKit has
+ // navigator.appVersion as custom. Our version just
+ // passes through.
+ DECLARE_PROPERTY_ACCESSOR(NavigatorAppVersion);
+
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnabort);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnerror);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnload);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnloadstart);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnprogress);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestOnreadystatechange);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestResponseText);
+ DECLARE_CALLBACK(XMLHttpRequestAddEventListener);
+ DECLARE_CALLBACK(XMLHttpRequestRemoveEventListener);
+ DECLARE_CALLBACK(XMLHttpRequestOpen);
+ DECLARE_CALLBACK(XMLHttpRequestSend);
+ DECLARE_CALLBACK(XMLHttpRequestSetRequestHeader);
+ DECLARE_CALLBACK(XMLHttpRequestGetResponseHeader);
+ DECLARE_CALLBACK(XMLHttpRequestOverrideMimeType);
+ DECLARE_CALLBACK(XMLHttpRequestDispatchEvent);
+
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnabort);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnerror);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnload);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnloadstart);
+ DECLARE_PROPERTY_ACCESSOR(XMLHttpRequestUploadOnprogress);
+ DECLARE_CALLBACK(XMLHttpRequestUploadAddEventListener);
+ DECLARE_CALLBACK(XMLHttpRequestUploadRemoveEventListener);
+ DECLARE_CALLBACK(XMLHttpRequestUploadDispatchEvent);
+
+ DECLARE_CALLBACK(TreeWalkerParentNode);
+ DECLARE_CALLBACK(TreeWalkerFirstChild);
+ DECLARE_CALLBACK(TreeWalkerLastChild);
+ DECLARE_CALLBACK(TreeWalkerNextNode);
+ DECLARE_CALLBACK(TreeWalkerPreviousNode);
+ DECLARE_CALLBACK(TreeWalkerNextSibling);
+ DECLARE_CALLBACK(TreeWalkerPreviousSibling);
+
+ DECLARE_CALLBACK(InspectorBackendProfiles);
+ DECLARE_CALLBACK(InspectorBackendHighlightDOMNode);
+ DECLARE_CALLBACK(InspectorBackendAddResourceSourceToFrame);
+ DECLARE_CALLBACK(InspectorBackendAddSourceToFrame);
+ DECLARE_CALLBACK(InspectorBackendSearch);
+ DECLARE_CALLBACK(InspectorBackendSetting);
+ DECLARE_CALLBACK(InspectorBackendInspectedWindow);
+ DECLARE_CALLBACK(InspectorBackendSetSetting);
+ DECLARE_CALLBACK(InspectorBackendCurrentCallFrame);
+ DECLARE_CALLBACK(InspectorBackendDebuggerEnabled);
+ DECLARE_CALLBACK(InspectorBackendPauseOnExceptions);
+ DECLARE_CALLBACK(InspectorBackendProfilerEnabled);
+#if ENABLE(DATABASE)
+ DECLARE_CALLBACK(InspectorBackendDatabaseTableNames);
+#endif
+ DECLARE_CALLBACK(InspectorBackendWrapCallback);
+
+ DECLARE_CALLBACK(NodeIteratorNextNode);
+ DECLARE_CALLBACK(NodeIteratorPreviousNode);
+
+ DECLARE_CALLBACK(NodeFilterAcceptNode);
+
+ DECLARE_CALLBACK(HTMLFormElementSubmit);
+
+ DECLARE_NAMED_PROPERTY_GETTER(DOMWindow);
+ DECLARE_INDEXED_PROPERTY_GETTER(DOMWindow);
+ DECLARE_NAMED_ACCESS_CHECK(DOMWindow);
+ DECLARE_INDEXED_ACCESS_CHECK(DOMWindow);
+
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLFrameSetElement);
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLFormElement);
+ DECLARE_NAMED_PROPERTY_GETTER(NodeList);
+ DECLARE_NAMED_PROPERTY_GETTER(NamedNodeMap);
+ DECLARE_NAMED_PROPERTY_GETTER(CSSStyleDeclaration);
+ DECLARE_NAMED_PROPERTY_SETTER(CSSStyleDeclaration);
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLPlugInElement);
+ DECLARE_NAMED_PROPERTY_SETTER(HTMLPlugInElement);
+ DECLARE_INDEXED_PROPERTY_GETTER(HTMLPlugInElement);
+ DECLARE_INDEXED_PROPERTY_SETTER(HTMLPlugInElement);
+
+ DECLARE_CALLBACK(HTMLPlugInElement);
+
+ DECLARE_NAMED_PROPERTY_GETTER(StyleSheetList);
+ DECLARE_INDEXED_PROPERTY_GETTER(NamedNodeMap);
+ DECLARE_INDEXED_PROPERTY_GETTER(HTMLFormElement);
+ DECLARE_INDEXED_PROPERTY_GETTER(HTMLOptionsCollection);
+ DECLARE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection);
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLSelectElementCollection);
+ DECLARE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection);
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection);
+
+ DECLARE_INDEXED_PROPERTY_GETTER(CanvasPixelArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(CanvasPixelArray);
+
+ DECLARE_PROPERTY_ACCESSOR(MessagePortOnmessage);
+ DECLARE_PROPERTY_ACCESSOR(MessagePortOnclose);
+ DECLARE_CALLBACK(MessagePortStartConversation);
+ DECLARE_CALLBACK(MessagePortAddEventListener);
+ DECLARE_CALLBACK(MessagePortRemoveEventListener);
+
+ DECLARE_CALLBACK(DatabaseChangeVersion);
+ DECLARE_CALLBACK(DatabaseTransaction);
+ DECLARE_CALLBACK(SQLTransactionExecuteSql);
+ DECLARE_CALLBACK(SQLResultSetRowListItem);
+
+ DECLARE_INDEXED_PROPERTY_GETTER(ClientRectList);
+
+#if ENABLE(DATAGRID)
+ DECLARE_PROPERTY_ACCESSOR(HTMLDataGridElementDataSource);
+ DECLARE_INDEXED_PROPERTY_GETTER(DataGridColumnList);
+ DECLARE_NAMED_PROPERTY_GETTER(DataGridColumnList);
+#endif
+
+#if ENABLE(DOM_STORAGE)
+ DECLARE_INDEXED_PROPERTY_GETTER(Storage);
+ DECLARE_INDEXED_PROPERTY_SETTER(Storage);
+ DECLARE_INDEXED_PROPERTY_DELETER(Storage);
+ DECLARE_NAMED_PROPERTY_GETTER(Storage);
+ DECLARE_NAMED_PROPERTY_SETTER(Storage);
+ DECLARE_NAMED_PROPERTY_DELETER(Storage);
+ static v8::Handle<v8::Array> v8StorageNamedPropertyEnumerator(const v8::AccessorInfo& info);
+#endif
+
+#if ENABLE(SVG)
+ DECLARE_PROPERTY_ACCESSOR_GETTER(SVGLengthValue);
+ DECLARE_CALLBACK(SVGLengthConvertToSpecifiedUnits);
+ DECLARE_CALLBACK(SVGMatrixInverse);
+ DECLARE_CALLBACK(SVGMatrixRotateFromVector);
+ DECLARE_CALLBACK(SVGElementInstanceAddEventListener);
+ DECLARE_CALLBACK(SVGElementInstanceRemoveEventListener);
+#endif
+
+#if ENABLE(WORKERS)
+ DECLARE_PROPERTY_ACCESSOR(AbstractWorkerOnerror);
+ DECLARE_CALLBACK(AbstractWorkerAddEventListener);
+ DECLARE_CALLBACK(AbstractWorkerRemoveEventListener);
+
+ DECLARE_PROPERTY_ACCESSOR(DedicatedWorkerContextOnmessage);
+
+ DECLARE_PROPERTY_ACCESSOR(WorkerOnmessage);
+ DECLARE_CALLBACK(WorkerConstructor);
+
+ DECLARE_PROPERTY_ACCESSOR_GETTER(WorkerContextSelf);
+ DECLARE_PROPERTY_ACCESSOR(WorkerContextOnerror);
+ DECLARE_CALLBACK(WorkerContextImportScripts);
+ DECLARE_CALLBACK(WorkerContextSetTimeout);
+ DECLARE_CALLBACK(WorkerContextClearTimeout);
+ DECLARE_CALLBACK(WorkerContextSetInterval);
+ DECLARE_CALLBACK(WorkerContextClearInterval);
+ DECLARE_CALLBACK(WorkerContextAddEventListener);
+ DECLARE_CALLBACK(WorkerContextRemoveEventListener);
+#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ DECLARE_PROPERTY_ACCESSOR(DOMApplicationCacheEventHandler);
+ DECLARE_CALLBACK(DOMApplicationCacheAddEventListener);
+ DECLARE_CALLBACK(DOMApplicationCacheRemoveEventListener);
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+ DECLARE_CALLBACK(SharedWorkerConstructor);
+#endif
+
+#undef DECLARE_INDEXED_ACCESS_CHECK
+#undef DECLARE_NAMED_ACCESS_CHECK
+
+#undef DECLARE_PROPERTY_ACCESSOR_SETTER
+#undef DECLARE_PROPERTY_ACCESSOR_GETTER
+#undef DECLARE_PROPERTY_ACCESSOR
+
+#undef DECLARE_NAMED_PROPERTY_GETTER
+#undef DECLARE_NAMED_PROPERTY_SETTER
+#undef DECLARE_NAMED_PROPERTY_DELETER
+
+#undef DECLARE_INDEXED_PROPERTY_GETTER
+#undef DECLARE_INDEXED_PROPERTY_SETTER
+#undef DECLARE_INDEXED_PROPERTY_DELETER
+
+#undef DECLARE_CALLBACK
+
+ // Returns the NPObject corresponding to an HTMLElement object.
+ static NPObject* GetHTMLPlugInElementNPObject(v8::Handle<v8::Object>);
+
+ // Returns the owner frame pointer of a DOM wrapper object. It only works for
+ // these DOM objects requiring cross-domain access check.
+ static Frame* GetTargetFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data);
+
+ // Special case for downcasting SVG path segments.
+#if ENABLE(SVG)
+ static V8ClassIndex::V8WrapperType DowncastSVGPathSeg(void* pathSeg);
+#endif
+
+ private:
+ static v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments&, bool singleShot);
+ static void ClearTimeoutImpl(const v8::Arguments&);
+ static void WindowSetLocation(DOMWindow*, const String&);
+ };
+
+#endif // MANUAL_MERGE_REQUIRED
} // namespace WebCore
#endif // V8CustomBinding_h
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
index bd9e307..305da8d 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
@@ -40,7 +40,7 @@ V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, b
{
m_listener = v8::Persistent<v8::Object>::New(listener);
#ifndef NDEBUG
- V8Proxy::RegisterGlobalHandle(EVENT_LISTENER, this, m_listener);
+ V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
#endif
}
@@ -49,7 +49,7 @@ V8EventListener::~V8EventListener()
if (m_frame) {
V8Proxy* proxy = V8Proxy::retrieve(m_frame);
if (proxy)
- proxy->RemoveV8EventListener(this);
+ proxy->eventListeners()->remove(this);
}
disposeListenerObject();
@@ -83,7 +83,9 @@ v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value>
v8::Handle<v8::Value> parameters[1] = { jsEvent };
V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- return proxy->CallFunction(handlerFunction, receiver, 1, parameters);
+ if (!proxy)
+ return v8::Local<v8::Value>();
+ return proxy->callFunction(handlerFunction, receiver, 1, parameters);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
index daa9b34..2abdb15 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
@@ -55,15 +55,15 @@ void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLR
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ v8::Handle<v8::Context> context = V8Proxy::context(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)
+ V8DOMWrapper::convertToV8Object(V8ClassIndex::SQLTRANSACTION, transaction),
+ V8DOMWrapper::convertToV8Object(V8ClassIndex::SQLRESULTSET, resultSet)
};
// Protect the frame until the callback returns.
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
index 6c7aba2..4b84ebe 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
@@ -55,15 +55,15 @@ bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction,
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ v8::Handle<v8::Context> context = V8Proxy::context(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)
+ V8DOMWrapper::convertToV8Object(V8ClassIndex::SQLTRANSACTION, transaction),
+ V8DOMWrapper::convertToV8Object(V8ClassIndex::SQLERROR, error)
};
// Protect the frame until the callback returns.
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
index c255483..704115e 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
@@ -56,14 +56,14 @@ void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bo
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
if (context.IsEmpty())
return;
v8::Context::Scope scope(context);
v8::Handle<v8::Value> argv[] = {
- V8Proxy::ToV8Object(V8ClassIndex::SQLTRANSACTION, transaction)
+ V8DOMWrapper::convertToV8Object(V8ClassIndex::SQLTRANSACTION, transaction)
};
// Protect the frame until the callback returns.
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
index 8dcb0a8..f30467c 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
@@ -55,14 +55,14 @@ void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
if (context.IsEmpty())
return;
v8::Context::Scope scope(context);
v8::Handle<v8::Value> argv[] = {
- V8Proxy::ToV8Object(V8ClassIndex::SQLERROR, error)
+ V8DOMWrapper::convertToV8Object(V8ClassIndex::SQLERROR, error)
};
// Protect the frame until the callback returns.
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
index b2972e4..925271f 100644
--- a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
@@ -51,7 +51,7 @@ void V8CustomVoidCallback::handleEvent()
LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = V8Proxy::GetContext(m_frame.get());
+ v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
if (context.IsEmpty())
return;
@@ -88,7 +88,7 @@ bool invokeCallback(v8::Persistent<v8::Object> callback, int argc, v8::Handle<v8
V8Proxy* proxy = V8Proxy::retrieve();
ASSERT(proxy);
- v8::Handle<v8::Value> result = proxy->CallFunction(callbackFunction, thisObject, argc, argv);
+ v8::Handle<v8::Value> result = proxy->callFunction(callbackFunction, thisObject, argc, argv);
callbackReturnValue = !result.IsEmpty() && result->IsBoolean() && result->BooleanValue();
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
new file mode 100644
index 0000000..3341924
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
@@ -0,0 +1,93 @@
+// 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 "V8CustomXPathNSResolver.h"
+
+#if ENABLE(XPATH)
+
+#include "PlatformString.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver)
+{
+ return adoptRef(new V8CustomXPathNSResolver(resolver));
+}
+
+V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver)
+ : m_resolver(resolver)
+{
+}
+
+V8CustomXPathNSResolver::~V8CustomXPathNSResolver()
+{
+}
+
+String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
+{
+ v8::Handle<v8::Function> lookupNamespaceURIFunc;
+ v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI");
+
+ // Check if the resolver has a function property named lookupNamespaceURI.
+ if (m_resolver->Has(lookupNamespaceURIName)) {
+ v8::Handle<v8::Value> lookupNamespaceURI = m_resolver->Get(lookupNamespaceURIName);
+ if (lookupNamespaceURI->IsFunction())
+ lookupNamespaceURIFunc = v8::Handle<v8::Function>::Cast(lookupNamespaceURI);
+ }
+
+ if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
+ Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+ logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
+ return String();
+ }
+
+ // Catch exceptions from calling the namespace resolver.
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true); // Print exceptions to console.
+
+ const int argc = 1;
+ v8::Handle<v8::Value> argv[argc] = { v8String(prefix) };
+ v8::Handle<v8::Function> function = lookupNamespaceURIFunc.IsEmpty() ? v8::Handle<v8::Function>::Cast(m_resolver) : lookupNamespaceURIFunc;
+
+ V8Proxy* proxy = V8Proxy::retrieve();
+ v8::Handle<v8::Value> retval = proxy->callFunction(function, m_resolver, argc, argv);
+
+ // Eat exceptions from namespace resolver and return an empty string. This will most likely cause NAMESPACE_ERR.
+ if (try_catch.HasCaught())
+ return String();
+
+ return toWebCoreStringWithNullCheck(retval);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(XPATH)
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
new file mode 100644
index 0000000..f1dc65c
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.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 V8CustomXPathNSResolver_h
+#define V8CustomXPathNSResolver_h
+
+#if ENABLE(XPATH)
+
+#include "XPathNSResolver.h"
+#include <v8.h>
+#include <wtf/Forward.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class String;
+
+class V8CustomXPathNSResolver : public XPathNSResolver {
+public:
+ static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver);
+
+ virtual ~V8CustomXPathNSResolver();
+ virtual String lookupNamespaceURI(const String& prefix);
+
+private:
+ V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver);
+
+ v8::Handle<v8::Object> m_resolver; // Handle to resolver object.
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(XPATH)
+
+#endif // V8CustomXPathNSResolver_h
diff --git a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
index 2ed1638..dd05b45 100644
--- a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 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,9 +33,10 @@
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "ApplicationCacheHost.h"
#include "V8Binding.h"
-#include "V8Document.h"
#include "V8CustomBinding.h"
+#include "V8Document.h"
#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
@@ -48,17 +49,10 @@ static const bool kFindOrCreate = false;
static PassRefPtr<EventListener> argumentToEventListener(DOMApplicationCache* appcache, v8::Local<v8::Value> value, bool findOnly)
{
-#if 0 && ENABLE(WORKERS)
- // FIXME: this is not tested yet
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy)
- return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly);
-#endif
-
V8Proxy* proxy = V8Proxy::retrieve(appcache->scriptExecutionContext());
if (proxy)
- return findOnly ? proxy->FindObjectEventListener(value, false)
- : proxy->FindOrCreateObjectEventListener(value, false);
+ return findOnly ? proxy->objectListeners()->findWrapper(value, false)
+ : proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
return 0;
}
@@ -67,30 +61,28 @@ static v8::Local<v8::Object> eventListenerToV8Object(EventListener* listener)
return (static_cast<V8ObjectEventListener*>(listener))->getListenerObject();
}
-static inline String toEventType(v8::Local<v8::String> value)
+static inline ApplicationCacheHost::EventID toEventID(v8::Local<v8::String> value)
{
String key = toWebCoreString(value);
ASSERT(key.startsWith("on"));
- return key.substring(2);
+ return DOMApplicationCache::toEventID(key.substring(2));
}
// Handles appcache.onfooevent attribute getting
ACCESSOR_GETTER(DOMApplicationCacheEventHandler)
{
INC_STATS("DOMApplicationCache.onevent_getter");
- DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
- if (EventListener* listener = appcache->getAttributeEventListener(toEventType(name))) {
- return eventListenerToV8Object(listener);
- }
- return v8::Null();
+ DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
+ EventListener* listener = appcache->getAttributeEventListener(toEventID(name));
+ return eventListenerToV8Object(listener);
}
// Handles appcache.onfooevent attribute setting
ACCESSOR_SETTER(DOMApplicationCacheEventHandler)
{
INC_STATS("DOMApplicationCache.onevent_setter");
- DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
- String eventType = toEventType(name);
+ DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
+ ApplicationCacheHost::EventID eventType = toEventID(name);
if (EventListener* oldListener = appcache->getAttributeEventListener(eventType)) {
v8::Local<v8::Object> object = eventListenerToV8Object(oldListener);
@@ -111,7 +103,7 @@ ACCESSOR_SETTER(DOMApplicationCacheEventHandler)
CALLBACK_FUNC_DECL(DOMApplicationCacheAddEventListener)
{
INC_STATS("DOMApplicationCache.addEventListener()");
- DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
+ DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOrCreate);
if (listener) {
@@ -127,7 +119,7 @@ CALLBACK_FUNC_DECL(DOMApplicationCacheAddEventListener)
CALLBACK_FUNC_DECL(DOMApplicationCacheRemoveEventListener)
{
INC_STATS("DOMApplicationCache.removeEventListener()");
- DOMApplicationCache* appcache = V8Proxy::ToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
+ DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOnly);
if (listener) {
diff --git a/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp b/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp
index f96b889..4af5c6e 100644
--- a/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMParserConstructor.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(DOMParserConstructor)
{
INC_STATS("DOM.DOMParser.Contructor");
- return V8Proxy::ConstructDOMObject<V8ClassIndex::DOMPARSER, DOMParser>(args);
+ return V8Proxy::constructDOMObject<V8ClassIndex::DOMPARSER, DOMParser>(args);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index c13c3b2..7d0b9e6 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -64,12 +64,12 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args,
if (argumentCount < 1)
return v8::Undefined();
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
if (!imp->frame())
return v8::Undefined();
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
ScriptExecutionContext* scriptContext = static_cast<ScriptExecutionContext*>(imp->frame()->document());
@@ -124,7 +124,7 @@ static bool isAscii(const String& str)
static v8::Handle<v8::Value> convertBase64(const String& str, bool encode)
{
if (!isAscii(str)) {
- V8Proxy::SetDOMException(INVALID_CHARACTER_ERR);
+ V8Proxy::setDOMException(INVALID_CHARACTER_ERR);
return notHandledByInterceptor();
}
@@ -137,7 +137,7 @@ static v8::Handle<v8::Value> convertBase64(const String& str, bool encode)
base64Encode(inputCharacters, outputCharacters);
else {
if (!base64Decode(inputCharacters, outputCharacters))
- return throwError("Cannot decode base64", V8Proxy::GENERAL_ERROR);
+ return throwError("Cannot decode base64", V8Proxy::GeneralError);
}
return v8String(String(outputCharacters.data(), outputCharacters.size()));
@@ -161,20 +161,20 @@ ACCESSOR_GETTER(DOMWindowCrypto)
ACCESSOR_SETTER(DOMWindowLocation)
{
- v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
if (holder.IsEmpty())
return;
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
WindowSetLocation(imp, toWebCoreString(value));
}
ACCESSOR_SETTER(DOMWindowOpener)
{
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return;
// Opener can be shadowed if it is in the same domain.
@@ -197,9 +197,9 @@ ACCESSOR_SETTER(DOMWindowOpener)
CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
{
INC_STATS("DOM.DOMWindow.addEventListener()");
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
if (!imp->frame())
@@ -214,7 +214,7 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false);
+ RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
if (listener) {
String eventType = toWebCoreString(args[0]);
@@ -229,9 +229,9 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener)
{
INC_STATS("DOM.DOMWindow.removeEventListener()");
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
if (!imp->frame())
@@ -245,7 +245,7 @@ CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener)
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false);
+ RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
if (listener) {
String eventType = toWebCoreString(args[0]);
@@ -259,13 +259,12 @@ CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener)
CALLBACK_FUNC_DECL(DOMWindowPostMessage)
{
INC_STATS("DOM.DOMWindow.postMessage()");
- DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
DOMWindow* source = V8Proxy::retrieveFrameForCallingContext()->domWindow();
ASSERT(source->frame());
v8::TryCatch tryCatch;
-
String message = toWebCoreString(args[0]);
MessagePort* port = 0;
String targetOrigin;
@@ -275,11 +274,11 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage)
// or
// postMessage(message, targetOrigin);
if (args.Length() > 2) {
- if (V8Proxy::IsWrapperOfType(args[1], V8ClassIndex::MESSAGEPORT))
- port = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args[1]);
- targetOrigin = valueToStringWithNullOrUndefinedCheck(args[2]);
+ if (V8DOMWrapper::isWrapperOfType(args[1], V8ClassIndex::MESSAGEPORT))
+ port = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, v8::Handle<v8::Object>::Cast(args[1]));
+ targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
} else {
- targetOrigin = valueToStringWithNullOrUndefinedCheck(args[1]);
+ targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
}
if (tryCatch.HasCaught())
@@ -288,7 +287,7 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage)
ExceptionCode ec = 0;
window->postMessage(message, port, targetOrigin, source, ec);
if (ec)
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Undefined();
}
@@ -296,13 +295,13 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage)
CALLBACK_FUNC_DECL(DOMWindowAtob)
{
INC_STATS("DOM.DOMWindow.atob()");
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
if (args[0]->IsNull())
return v8String("");
@@ -314,13 +313,13 @@ CALLBACK_FUNC_DECL(DOMWindowAtob)
CALLBACK_FUNC_DECL(DOMWindowBtoa)
{
INC_STATS("DOM.DOMWindow.btoa()");
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
if (args[0]->IsNull())
return v8String("");
@@ -373,11 +372,11 @@ static String eventNameFromAttributeName(const String& name)
ACCESSOR_SETTER(DOMWindowEventHandler)
{
- v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
if (holder.IsEmpty())
return;
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
if (!imp->frame())
return;
@@ -396,8 +395,7 @@ ACCESSOR_SETTER(DOMWindowEventHandler)
if (!proxy)
return;
- RefPtr<EventListener> listener =
- proxy->FindOrCreateV8EventListener(value, true);
+ RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), value, true);
if (listener)
imp->setAttributeEventListener(eventType, listener);
}
@@ -405,11 +403,11 @@ ACCESSOR_SETTER(DOMWindowEventHandler)
ACCESSOR_GETTER(DOMWindowEventHandler)
{
- v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
if (holder.IsEmpty())
return v8::Undefined();
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
if (!imp->frame())
return v8::Undefined();
@@ -421,7 +419,7 @@ ACCESSOR_GETTER(DOMWindowEventHandler)
String eventType = eventNameFromAttributeName(key);
EventListener* listener = imp->getAttributeEventListener(eventType);
- return V8Proxy::EventListenerToV8Object(listener);
+ return V8DOMWrapper::convertEventListenerToV8Object(listener);
}
static bool canShowModalDialogNow(const Frame* frame)
@@ -518,7 +516,7 @@ static Frame* createWindow(Frame* callingFrame,
// Set dialog arguments on the global object of the new frame.
if (!dialogArgs.IsEmpty()) {
- v8::Local<v8::Context> context = V8Proxy::GetContext(newFrame);
+ v8::Local<v8::Context> context = V8Proxy::context(newFrame);
if (!context.IsEmpty()) {
v8::Context::Scope scope(context);
context->Global()->Set(v8::String::New("dialogArguments"), dialogArgs);
@@ -544,11 +542,11 @@ static Frame* createWindow(Frame* callingFrame,
CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
{
INC_STATS("DOM.DOMWindow.showModalDialog()");
- DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(
V8ClassIndex::DOMWINDOW, args.Holder());
Frame* frame = window->frame();
- if (!frame || !V8Proxy::CanAccessFrame(frame, true))
+ if (!frame || !V8Proxy::canAccessFrame(frame, true))
return v8::Undefined();
Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
@@ -562,9 +560,9 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
if (!canShowModalDialogNow(frame) || !allowPopUp())
return v8::Undefined();
- String url = valueToStringWithNullOrUndefinedCheck(args[0]);
+ String url = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
v8::Local<v8::Value> dialogArgs = args[1];
- String featureArgs = valueToStringWithNullOrUndefinedCheck(args[2]);
+ String featureArgs = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
const HashMap<String, String> features = parseModalDialogFeatures(featureArgs);
@@ -611,7 +609,7 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
// Hold on to the context of the dialog window long enough to retrieve the
// value of the return value property.
- v8::Local<v8::Context> context = V8Proxy::GetContext(dialogFrame);
+ v8::Local<v8::Context> context = V8Proxy::context(dialogFrame);
// Run the dialog.
dialogFrame->page()->chrome()->runModal();
@@ -633,10 +631,10 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
CALLBACK_FUNC_DECL(DOMWindowOpen)
{
INC_STATS("DOM.DOMWindow.open()");
- DOMWindow* parent = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+ DOMWindow* parent = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
Frame* frame = parent->frame();
- if (!frame || !V8Proxy::CanAccessFrame(frame, true))
+ if (!frame || !V8Proxy::canAccessFrame(frame, true))
return v8::Undefined();
Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
@@ -651,7 +649,7 @@ CALLBACK_FUNC_DECL(DOMWindowOpen)
if (!page)
return v8::Undefined();
- String urlString = valueToStringWithNullOrUndefinedCheck(args[0]);
+ String urlString = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
AtomicString frameName = (args[1]->IsUndefined() || args[1]->IsNull()) ? "_blank" : AtomicString(toWebCoreString(args[1]));
// Because FrameTree::find() returns true for empty strings, we must check
@@ -691,7 +689,7 @@ CALLBACK_FUNC_DECL(DOMWindowOpen)
frame->loader()->scheduleLocationChange(completedUrl, referrer, false, userGesture);
}
- return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
}
// In the case of a named frame or a new window, we'll use the
@@ -700,7 +698,7 @@ CALLBACK_FUNC_DECL(DOMWindowOpen)
// Parse the values, and then work with a copy of the parsed values
// so we can restore the values we may not want to overwrite after
// we do the multiple monitor fixes.
- WindowFeatures rawFeatures(valueToStringWithNullOrUndefinedCheck(args[2]));
+ WindowFeatures rawFeatures(toWebCoreStringWithNullOrUndefinedCheck(args[2]));
WindowFeatures windowFeatures(rawFeatures);
FloatRect screenRect = screenAvailableRect(page->mainFrame()->view());
@@ -751,18 +749,18 @@ CALLBACK_FUNC_DECL(DOMWindowOpen)
if (!frame)
return v8::Undefined();
- return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
}
INDEXED_PROPERTY_GETTER(DOMWindow)
{
INC_STATS("DOM.DOMWindow.IndexedPropertyGetter");
- v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
if (holder.IsEmpty())
return notHandledByInterceptor();
- DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
if (!window)
return notHandledByInterceptor();
@@ -772,7 +770,7 @@ INDEXED_PROPERTY_GETTER(DOMWindow)
Frame* child = frame->tree()->child(index);
if (child)
- return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow());
return notHandledByInterceptor();
}
@@ -782,11 +780,11 @@ NAMED_PROPERTY_GETTER(DOMWindow)
{
INC_STATS("DOM.DOMWindow.NamedPropertyGetter");
- v8::Handle<v8::Object> holder = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
if (holder.IsEmpty())
return notHandledByInterceptor();
- DOMWindow* window = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
if (!window)
return notHandledByInterceptor();
@@ -799,7 +797,7 @@ NAMED_PROPERTY_GETTER(DOMWindow)
AtomicString propName = v8StringToAtomicWebCoreString(name);
Frame* child = frame->tree()->child(propName);
if (child)
- return V8Proxy::ToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow());
// Search IDL functions defined in the prototype
v8::Handle<v8::Value> result = holder->GetRealNamedPropertyInPrototypeChain(name);
@@ -812,9 +810,9 @@ NAMED_PROPERTY_GETTER(DOMWindow)
RefPtr<HTMLCollection> items = doc->windowNamedItems(propName);
if (items->length() >= 1) {
if (items->length() == 1)
- return V8Proxy::NodeToV8Object(items->firstItem());
+ return V8DOMWrapper::convertNodeToV8Object(items->firstItem());
else
- return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, items.get());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLCOLLECTION, items.release());
}
}
@@ -855,9 +853,9 @@ CALLBACK_FUNC_DECL(DOMWindowSetInterval)
void V8Custom::ClearTimeoutImpl(const v8::Arguments& args)
{
- v8::Handle<v8::Value> holder = args.Holder();
- DOMWindow* imp = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
- if (!V8Proxy::CanAccessFrame(imp->frame(), true))
+ v8::Handle<v8::Object> holder = args.Holder();
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return;
ScriptExecutionContext* context = static_cast<ScriptExecutionContext*>(imp->frame()->document());
int handle = toInt32(args[0]);
@@ -882,11 +880,11 @@ CALLBACK_FUNC_DECL(DOMWindowClearInterval)
NAMED_ACCESS_CHECK(DOMWindow)
{
ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
- v8::Handle<v8::Value> window = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
+ v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
if (window.IsEmpty())
return false; // the frame is gone.
- DOMWindow* targetWindow = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+ DOMWindow* targetWindow = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
ASSERT(targetWindow);
@@ -902,17 +900,17 @@ NAMED_ACCESS_CHECK(DOMWindow)
return true;
}
- return V8Proxy::CanAccessFrame(target, false);
+ return V8Proxy::canAccessFrame(target, false);
}
INDEXED_ACCESS_CHECK(DOMWindow)
{
ASSERT(V8ClassIndex::FromInt(data->Int32Value()) == V8ClassIndex::DOMWINDOW);
- v8::Handle<v8::Value> window = V8Proxy::LookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
+ v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, host);
if (window.IsEmpty())
return false;
- DOMWindow* targetWindow = V8Proxy::ToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
+ DOMWindow* targetWindow = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, window);
ASSERT(targetWindow);
@@ -924,7 +922,7 @@ INDEXED_ACCESS_CHECK(DOMWindow)
if ((type == v8::ACCESS_GET || type == v8::ACCESS_HAS) && target->tree()->child(index))
return true;
- return V8Proxy::CanAccessFrame(target, false);
+ return V8Proxy::canAccessFrame(target, false);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DataGridColumnListCustom.cpp b/WebCore/bindings/v8/custom/V8DataGridColumnListCustom.cpp
new file mode 100644
index 0000000..1dde996
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DataGridColumnListCustom.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 "DataGridColumnList.h"
+
+#include "Document.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#if ENABLE(DATAGRID)
+
+namespace WebCore {
+
+INDEXED_PROPERTY_GETTER(DataGridColumnList)
+{
+ INC_STATS("DataGridColumnList.IndexedPropertyGetter");
+ DataGridColumnList* imp = V8DOMWrapper::convertToNativeObject<DataGridColumnList>(V8ClassIndex::DATAGRIDCOLUMNLIST, info.Holder());
+ DataGridColumn* result = imp->item(index);
+ if (!result)
+ return notHandledByInterceptor();
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::DATAGRIDCOLUMN, result);
+}
+
+NAMED_PROPERTY_GETTER(DataGridColumnList)
+{
+ INC_STATS("DataGridColumnList.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, look up a column by name.
+ DataGridColumnList* imp = V8DOMWrapper::convertToNativeObject<DataGridColumnList>(V8ClassIndex::DATAGRIDCOLUMNLIST, info.Holder());
+ DataGridColumn* result = imp->itemWithName(toWebCoreString(name));
+ if (!result)
+ return notHandledByInterceptor();
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::DATAGRIDCOLUMN, result);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
index 6996d35..dbaa942 100644
--- a/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
@@ -32,14 +32,23 @@
#if ENABLE(DATABASE)
+#ifdef MANUAL_MERGE_REQUIRED
#include "v8_binding.h"
#include "v8_proxy.h"
+#else // MANUAL_MERGE_REQUIRED
+#endif // MANUAL_MERGE_REQUIRED
#include "Database.h"
+#ifdef MANUAL_MERGE_REQUIRED
#include "V8CustomBinding.h"
+#else // MANUAL_MERGE_REQUIRED
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#endif // MANUAL_MERGE_REQUIRED
#include "V8CustomSQLTransactionCallback.h"
#include "V8CustomSQLTransactionErrorCallback.h"
#include "V8CustomVoidCallback.h"
+#include "V8Proxy.h"
namespace WebCore {
@@ -53,37 +62,33 @@ 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.Length())
+ return throwError("Transaction callback is required.", V8Proxy::SyntaxError);
- if (!args[0]->IsObject()) {
- V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Transaction callback must be of valid type.");
- return v8::Undefined();
- }
+ if (!args[0]->IsObject())
+ return throwError("Transaction callback must be of valid type.");
- Database* database = V8Proxy::ToNativeObject<Database>(V8ClassIndex::DATABASE, args.Holder());
+ Database* database = V8DOMWrapper::convertToNativeObject<Database>(V8ClassIndex::DATABASE, args.Holder());
- Frame* frame = V8Proxy::retrieveFrame();
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return v8::Undefined();
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();
- }
+ if (!args[1]->IsObject())
+ return throwError("Transaction error callback must be of valid type.");
+
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();
- }
+ if (!args[1]->IsObject())
+ return throwError("Transaction success callback must be of valid type.");
+
successCallback = V8CustomVoidCallback::create(args[2], frame);
}
diff --git a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
new file mode 100644
index 0000000..f13e45e
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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 "DedicatedWorkerContext.h"
+#include "V8Proxy.h"
+#include "V8WorkerContextEventListener.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(DedicatedWorkerContextOnmessage)
+{
+ INC_STATS(L"DOM.DedicatedWorkerContext.onmessage._get");
+ DedicatedWorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<DedicatedWorkerContext>(V8ClassIndex::DEDICATEDWORKERCONTEXT, info.Holder());
+ if (workerContext->onmessage()) {
+ V8WorkerContextEventListener* listener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage());
+ v8::Local<v8::Object> v8Listener = listener->getListenerObject();
+ return v8Listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(DedicatedWorkerContextOnmessage)
+{
+ INC_STATS(L"DOM.DedicatedWorkerContext.onmessage._set");
+ DedicatedWorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<DedicatedWorkerContext>(V8ClassIndex::DEDICATEDWORKERCONTEXT, info.Holder());
+ V8WorkerContextEventListener* oldListener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage());
+ if (value->IsNull()) {
+ if (workerContext->onmessage()) {
+ v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
+ removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kDedicatedWorkerContextRequestCacheIndex);
+ }
+
+ // Clear the listener.
+ workerContext->setOnmessage(0);
+ } else {
+ RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), false, false);
+ if (listener) {
+ if (oldListener) {
+ v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
+ removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kDedicatedWorkerContextRequestCacheIndex);
+ }
+
+ workerContext->setOnmessage(listener);
+ createHiddenDependency(info.Holder(), value, V8Custom::kDedicatedWorkerContextRequestCacheIndex);
+ }
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
index 3eadce7..60fc22f 100644
--- a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -32,13 +32,13 @@
#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 "V8CustomXPathNSResolver.h"
#include "V8Node.h"
#include "V8Proxy.h"
@@ -54,52 +54,61 @@ namespace WebCore {
CALLBACK_FUNC_DECL(DocumentEvaluate)
{
INC_STATS("DOM.Document.evaluate()");
+#ifdef MANUAL_MERGE_REQUIRED
#if ENABLE(XPATH)
Document* document = V8Proxy::DOMWrapperToNode<Document>(args.Holder());
+#else // MANUAL_MERGE_REQUIRED
+
+ RefPtr<Document> document = V8DOMWrapper::convertDOMWrapperToNode<Document>(args.Holder());
+#endif // MANUAL_MERGE_REQUIRED
ExceptionCode ec = 0;
String expression = toWebCoreString(args[0]);
- Node* contextNode = 0;
+ RefPtr<Node> contextNode;
if (V8Node::HasInstance(args[1]))
- contextNode = V8Proxy::DOMWrapperToNode<Node>(args[1]);
+ contextNode = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1]));
- XPathNSResolver* resolver = 0;
+ RefPtr<XPathNSResolver> resolver;
if (V8XPathNSResolver::HasInstance(args[2]))
- resolver = V8Proxy::ToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, args[2]);
+ resolver = V8DOMWrapper::convertToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, v8::Handle<v8::Object>::Cast(args[2]));
else if (args[2]->IsObject())
- resolver = new JSXPathNSResolver(args[2]->ToObject());
+ resolver = V8CustomXPathNSResolver::create(args[2]->ToObject());
else if (!args[2]->IsNull() && !args[2]->IsUndefined())
return throwError(TYPE_MISMATCH_ERR);
int type = toInt32(args[3]);
- XPathResult* inResult = 0;
+ RefPtr<XPathResult> inResult;
if (V8XPathResult::HasInstance(args[4]))
- inResult = V8Proxy::ToNativeObject<XPathResult>(V8ClassIndex::XPATHRESULT, args[4]);
+ inResult = V8DOMWrapper::convertToNativeObject<XPathResult>(V8ClassIndex::XPATHRESULT, v8::Handle<v8::Object>::Cast(args[4]));
v8::TryCatch exceptionCatcher;
- RefPtr<XPathResult> result = document->evaluate(expression, contextNode, resolver, type, inResult, ec);
+ RefPtr<XPathResult> result = document->evaluate(expression, contextNode.get(), resolver.get(), type, inResult.get(), ec);
if (exceptionCatcher.HasCaught())
return throwError(exceptionCatcher.Exception());
if (ec)
return throwError(ec);
+#ifdef MANUAL_MERGE_REQUIRED
return V8Proxy::ToV8Object(V8ClassIndex::XPATHRESULT, result.get());
#else
return throwError(NOT_SUPPORTED_ERR);
#endif
+#else // MANUAL_MERGE_REQUIRED
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::XPATHRESULT, result.release());
+#endif // MANUAL_MERGE_REQUIRED
}
CALLBACK_FUNC_DECL(DocumentGetCSSCanvasContext)
{
INC_STATS("DOM.Document.getCSSCanvasContext");
- v8::Handle<v8::Value> holder = args.Holder();
- Document* imp = V8Proxy::DOMWrapperToNode<Document>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Document* imp = V8DOMWrapper::convertDOMWrapperToNode<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);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp
index dfcacef..440bbdc 100644
--- a/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DocumentLocationCustom.cpp
@@ -34,17 +34,17 @@ namespace WebCore {
ACCESSOR_GETTER(DocumentLocation)
{
- Document* document = V8Proxy::DOMWrapperToNative<Document>(info.Holder());
+ Document* document = V8DOMWrapper::convertDOMWrapperToNative<Document>(info.Holder());
if (!document->frame())
return v8::Null();
DOMWindow* window = document->frame()->domWindow();
- return V8Proxy::ToV8Object(V8ClassIndex::LOCATION, window->location());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::LOCATION, window->location());
}
ACCESSOR_SETTER(DocumentLocation)
{
- Document* document = V8Proxy::DOMWrapperToNative<Document>(info.Holder());
+ Document* document = V8DOMWrapper::convertDOMWrapperToNative<Document>(info.Holder());
if (!document->frame())
return;
diff --git a/WebCore/bindings/v8/custom/V8ElementCustom.cpp b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
index 64a9d3d..e17e0a9 100644
--- a/WebCore/bindings/v8/custom/V8ElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8ElementCustom.cpp
@@ -34,7 +34,6 @@
#include "Attr.h"
#include "CSSHelper.h"
#include "Document.h"
-#include "EventListener.h"
#include "ExceptionCode.h"
#include "HTMLFrameElementBase.h"
#include "HTMLNames.h"
@@ -43,7 +42,6 @@
#include "V8Attr.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
-#include "V8CustomEventListener.h"
#include "V8Proxy.h"
#include <wtf/RefPtr.h>
@@ -53,7 +51,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(ElementSetAttribute)
{
INC_STATS("DOM.Element.setAttribute()");
- Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ Element* element = V8DOMWrapper::convertDOMWrapperToNode<Element>(args.Holder());
String name = toWebCoreString(args[0]);
String value = toWebCoreString(args[1]);
@@ -74,8 +72,8 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNode)
if (!V8Attr::HasInstance(args[0]))
return throwError(TYPE_MISMATCH_ERR);
- Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]);
- Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ Attr* newAttr = V8DOMWrapper::convertDOMWrapperToNode<Attr>(v8::Handle<v8::Object>::Cast(args[0]));
+ Element* element = V8DOMWrapper::convertDOMWrapperToNode<Element>(args.Holder());
if (!allowSettingSrcToJavascriptURL(element, newAttr->name(), newAttr->value()))
return v8::Undefined();
@@ -85,13 +83,13 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNode)
if (ec)
throwError(ec);
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
CALLBACK_FUNC_DECL(ElementSetAttributeNS)
{
INC_STATS("DOM.Element.setAttributeNS()");
- Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ Element* element = V8DOMWrapper::convertDOMWrapperToNode<Element>(args.Holder());
String namespaceURI = toWebCoreStringWithNullCheck(args[0]);
String qualifiedName = toWebCoreString(args[1]);
String value = toWebCoreString(args[2]);
@@ -113,8 +111,8 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNodeNS)
if (!V8Attr::HasInstance(args[0]))
return throwError(TYPE_MISMATCH_ERR);
- Attr* newAttr = V8Proxy::DOMWrapperToNode<Attr>(args[0]);
- Element* element = V8Proxy::DOMWrapperToNode<Element>(args.Holder());
+ Attr* newAttr = V8DOMWrapper::convertDOMWrapperToNode<Attr>(v8::Handle<v8::Object>::Cast(args[0]));
+ Element* element = V8DOMWrapper::convertDOMWrapperToNode<Element>(args.Holder());
if (!allowSettingSrcToJavascriptURL(element, newAttr->name(), newAttr->value()))
return v8::Undefined();
@@ -124,45 +122,7 @@ CALLBACK_FUNC_DECL(ElementSetAttributeNodeNS)
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::retrieveFrameForEnteredContext());
- if (!proxy)
- return;
-
- if (RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(value, true))
- node->setAttributeEventListener(eventType, listener);
- } else
- node->clearAttributeEventListener(eventType);
-}
-
-ACCESSOR_GETTER(ElementEventHandler)
-{
- Node* node = V8Proxy::DOMWrapperToNode<Node>(info.Holder());
-
- EventListener* listener = node->getAttributeEventListener(toEventType(name));
- return V8Proxy::EventListenerToV8Object(listener);
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8EventCustom.cpp b/WebCore/bindings/v8/custom/V8EventCustom.cpp
index 1dae845..8bac40f 100644
--- a/WebCore/bindings/v8/custom/V8EventCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8EventCustom.cpp
@@ -43,39 +43,39 @@ namespace WebCore {
ACCESSOR_SETTER(EventReturnValue)
{
- Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ Event* event = V8DOMWrapper::convertDOMWrapperToNative<Event>(info.Holder());
event->setDefaultPrevented(!value->BooleanValue());
}
ACCESSOR_GETTER(EventDataTransfer)
{
- Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ Event* event = V8DOMWrapper::convertDOMWrapperToNative<Event>(info.Holder());
if (event->isDragEvent())
- return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, static_cast<MouseEvent*>(event)->clipboard());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CLIPBOARD, static_cast<MouseEvent*>(event)->clipboard());
return v8::Undefined();
}
ACCESSOR_GETTER(EventClipboardData)
{
- Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ Event* event = V8DOMWrapper::convertDOMWrapperToNative<Event>(info.Holder());
if (event->isClipboardEvent())
- return V8Proxy::ToV8Object(V8ClassIndex::CLIPBOARD, static_cast<ClipboardEvent*>(event)->clipboard());
+ return V8DOMWrapper::convertToV8Object(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());
+ Event* event = V8DOMWrapper::convertDOMWrapperToNative<Event>(info.Holder());
+ return V8DOMWrapper::convertEventTargetToV8Object(event->target());
}
ACCESSOR_GETTER(EventReturnValue)
{
- Event* event = V8Proxy::DOMWrapperToNative<Event>(info.Holder());
+ Event* event = V8DOMWrapper::convertDOMWrapperToNative<Event>(info.Holder());
return event->defaultPrevented() ? v8::False() : v8::True();
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
new file mode 100644
index 0000000..6f9b761
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 "HTMLAudioElement.h"
+
+#include "Document.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+
+#include "V8Binding.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(HTMLAudioElementConstructor)
+{
+ INC_STATS("DOM.HTMLAudioElement.Contructor");
+
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.");
+
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return throwError("Audio constructor associated frame is unavailable", V8Proxy::ReferenceError);
+
+ Document* document = frame->document();
+ if (!document)
+ return throwError("Audio constructor associated document is unavailable", V8Proxy::ReferenceError);
+
+ // Make sure the document is added to the DOM Node map. Otherwise, the HTMLAudioElement instance
+ // may end up being the only node in the map and get garbage-ccollected prematurely.
+ V8DOMWrapper::convertNodeToV8Object(document);
+
+ RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document);
+ if (args.Length() > 0)
+ audio->setSrc(toWebCoreString(args[0]));
+
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), audio.get());
+ audio->ref();
+ V8DOMWrapper::setJSWrapperForDOMNode(audio.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+ return args.Holder();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index cf66e39..6ba9367 100644
--- a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -40,12 +40,12 @@ 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]);
+ INC_STATS("DOM.HTMLCanvasElement.context");
+ v8::Handle<v8::Object> holder = args.Holder();
+ HTMLCanvasElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLCanvasElement>(holder);
+ String contextId = toWebCoreString(args[0]);
CanvasRenderingContext2D* result = imp->getContext(contextId);
- return V8Proxy::ToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
index 1436a48..7c9b40f 100644
--- a/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLCollectionCustom.cpp
@@ -47,10 +47,10 @@ static v8::Handle<v8::Value> getNamedItems(HTMLCollection* collection, AtomicStr
return v8::Handle<v8::Value>();
if (namedItems.size() == 1)
- return V8Proxy::NodeToV8Object(namedItems.at(0).get());
+ return V8DOMWrapper::convertNodeToV8Object(namedItems.at(0).release());
NodeList* list = new V8NamedNodesCollection(namedItems);
- return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, list);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODELIST, list);
}
static v8::Handle<v8::Value> getItem(HTMLCollection* collection, v8::Handle<v8::Value> argument)
@@ -66,7 +66,7 @@ static v8::Handle<v8::Value> getItem(HTMLCollection* collection, v8::Handle<v8::
}
RefPtr<Node> result = collection->item(index->Uint32Value());
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
NAMED_PROPERTY_GETTER(HTMLCollection)
@@ -84,21 +84,21 @@ NAMED_PROPERTY_GETTER(HTMLCollection)
return v8::Handle<v8::Value>();
// Finally, search the DOM structure.
- HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, info.Holder());
+ HTMLCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, info.Holder());
return getNamedItems(imp, v8StringToAtomicWebCoreString(name));
}
CALLBACK_FUNC_DECL(HTMLCollectionItem)
{
INC_STATS("DOM.HTMLCollection.item()");
- HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
+ HTMLCollection* imp = V8DOMWrapper::convertToNativeObject<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());
+ HTMLCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0]));
if (result.IsEmpty())
@@ -113,7 +113,7 @@ CALLBACK_FUNC_DECL(HTMLCollectionCallAsFunction)
if (args.Length() < 1)
return v8::Undefined();
- HTMLCollection* imp = V8Proxy::ToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
+ HTMLCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLCollection>(V8ClassIndex::HTMLCOLLECTION, args.Holder());
if (args.Length() == 1)
return getItem(imp, args[0]);
@@ -128,7 +128,7 @@ CALLBACK_FUNC_DECL(HTMLCollectionCallAsFunction)
Node* node = imp->namedItem(name);
while (node) {
if (!current)
- return V8Proxy::NodeToV8Object(node);
+ return V8DOMWrapper::convertNodeToV8Object(node);
node = imp->nextNamedItem(name);
current--;
diff --git a/WebCore/bindings/v8/custom/V8HTMLDataGridElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDataGridElementCustom.cpp
new file mode 100644
index 0000000..0ef4150
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLDataGridElementCustom.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 "HTMLDataGridElement.h"
+
+#include "Document.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8DataGridDataSource.h"
+#include "V8Proxy.h"
+
+#if ENABLE(DATAGRID)
+
+namespace WebCore {
+
+ACCESSOR_GETTER(HTMLDataGridElementDataSource)
+{
+ INC_STATS("DOM.HTMLDataGridElement.dataSource._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ HTMLDataGridElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLDataGridElement>(holder);
+ DataGridDataSource* dataSource = imp->dataSource();
+ if (dataSource && dataSource->isJSDataGridDataSource())
+ return asV8DataGridDataSource(dataSource)->jsDataSource();
+ return v8::Null();
+}
+
+ACCESSOR_SETTER(HTMLDataGridElementDataSource)
+{
+ INC_STATS("DOM.HTMLDataGridElement.dataSource._set");
+ v8::Handle<v8::Object> holder = info.Holder();
+ HTMLDataGridElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLDataGridElement>(holder);
+ RefPtr<DataGridDataSource> dataSource;
+ if (!value.IsEmpty()) {
+ Frame *frame = imp->document()->frame();
+ dataSource = V8DataGridDataSource::create(value, frame);
+ }
+ imp->setDataSource(dataSource.get());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DATAGRID)
diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
index 34bf89c..a0c3d74 100644
--- a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
@@ -78,7 +78,7 @@ NAMED_PROPERTY_GETTER(HTMLDocument)
return value;
}
- HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(info.Holder());
+ HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(info.Holder());
// Fast case for named elements that are not there.
if (!htmlDocument->hasNamedItem(key.impl()) && !htmlDocument->hasExtraNamedItem(key.impl()))
@@ -92,12 +92,12 @@ NAMED_PROPERTY_GETTER(HTMLDocument)
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 V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
- return V8Proxy::NodeToV8Object(node);
+ return V8DOMWrapper::convertNodeToV8Object(node);
}
- return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, items.get());
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLCOLLECTION, items.release());
}
// HTMLDocument ----------------------------------------------------------------
@@ -117,7 +117,7 @@ static String writeHelperGetString(const v8::Arguments& args)
CALLBACK_FUNC_DECL(HTMLDocumentWrite)
{
INC_STATS("DOM.HTMLDocument.write()");
- HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
+ HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder());
Frame* frame = V8Proxy::retrieveFrameForCallingContext();
ASSERT(frame);
htmlDocument->write(writeHelperGetString(args), frame->document());
@@ -127,7 +127,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWrite)
CALLBACK_FUNC_DECL(HTMLDocumentWriteln)
{
INC_STATS("DOM.HTMLDocument.writeln()");
- HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
+ HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder());
Frame* frame = V8Proxy::retrieveFrameForCallingContext();
ASSERT(frame);
htmlDocument->writeln(writeHelperGetString(args), frame->document());
@@ -137,12 +137,12 @@ CALLBACK_FUNC_DECL(HTMLDocumentWriteln)
CALLBACK_FUNC_DECL(HTMLDocumentOpen)
{
INC_STATS("DOM.HTMLDocument.open()");
- HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(args.Holder());
+ HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder());
if (args.Length() > 2) {
if (Frame* frame = htmlDocument->frame()) {
// Fetch the global object for the frame.
- v8::Local<v8::Context> context = V8Proxy::GetContext(frame);
+ v8::Local<v8::Context> context = V8Proxy::context(frame);
// Bail out if we cannot get the context.
if (context.IsEmpty())
return v8::Undefined();
@@ -162,7 +162,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentOpen)
V8Proxy* proxy = V8Proxy::retrieve(frame);
ASSERT(proxy);
- v8::Local<v8::Value> result = proxy->CallFunction(v8::Local<v8::Function>::Cast(function), global, args.Length(), params);
+ v8::Local<v8::Value> result = proxy->callFunction(v8::Local<v8::Function>::Cast(function), global, args.Length(), params);
delete[] params;
return result;
}
@@ -179,9 +179,8 @@ ACCESSOR_GETTER(HTMLDocumentAll)
INC_STATS("DOM.HTMLDocument.all._get");
v8::HandleScope scope;
v8::Handle<v8::Object> holder = info.Holder();
- HTMLDocument* htmlDocument = V8Proxy::DOMWrapperToNode<HTMLDocument>(holder);
- RefPtr<HTMLCollection> collection = WTF::getPtr(htmlDocument->all());
- return V8Proxy::ToV8Object(V8ClassIndex::HTMLCOLLECTION, WTF::getPtr(collection));
+ HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(holder);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLCOLLECTION, htmlDocument->all());
}
ACCESSOR_SETTER(HTMLDocumentAll)
diff --git a/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp
index 27ab7e3..1ec09f7 100644
--- a/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLFormElementCustom.cpp
@@ -42,19 +42,19 @@ namespace WebCore {
INDEXED_PROPERTY_GETTER(HTMLFormElement)
{
INC_STATS("DOM.HTMLFormElement.IndexedPropertyGetter");
- HTMLFormElement* form = V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder());
-
+ HTMLFormElement* form = V8DOMWrapper::convertDOMWrapperToNode<HTMLFormElement>(info.Holder());
+
RefPtr<Node> formElement = form->elements()->item(index);
if (!formElement)
return notHandledByInterceptor();
- return V8Proxy::NodeToV8Object(formElement.get());
+ return V8DOMWrapper::convertNodeToV8Object(formElement.release());
}
NAMED_PROPERTY_GETTER(HTMLFormElement)
{
INC_STATS("DOM.HTMLFormElement.NamedPropertyGetter");
- HTMLFormElement* imp = V8Proxy::DOMWrapperToNode<HTMLFormElement>(info.Holder());
+ HTMLFormElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLFormElement>(info.Holder());
AtomicString v = v8StringToAtomicWebCoreString(name);
// Call getNamedElements twice, first time check if it has a value
@@ -74,15 +74,15 @@ NAMED_PROPERTY_GETTER(HTMLFormElement)
ASSERT(!elements.isEmpty());
if (elements.size() == 1)
- return V8Proxy::NodeToV8Object(elements.at(0).get());
+ return V8DOMWrapper::convertNodeToV8Object(elements.at(0).release());
NodeList* collection = new V8NamedNodesCollection(elements);
- return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, collection);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODELIST, collection);
}
-
+
CALLBACK_FUNC_DECL(HTMLFormElementSubmit) {
INC_STATS("DOM.HTMLFormElement.submit()");
- HTMLFormElement* form = V8Proxy::DOMWrapperToNative<HTMLFormElement>(args.Holder());
+ HTMLFormElement* form = V8DOMWrapper::convertDOMWrapperToNative<HTMLFormElement>(args.Holder());
form->submit(0, false, false);
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
index bfc4c28..4f865dd 100644
--- a/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
ACCESSOR_SETTER(HTMLFrameElementSrc)
{
- HTMLFrameElement* frame = V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder());
+ HTMLFrameElement* frame = V8DOMWrapper::convertDOMWrapperToNode<HTMLFrameElement>(info.Holder());
String srcValue = toWebCoreStringWithNullCheck(value);
if (!allowSettingFrameSrcToJavascriptUrl(frame, srcValue))
@@ -50,7 +50,7 @@ ACCESSOR_SETTER(HTMLFrameElementSrc)
ACCESSOR_SETTER(HTMLFrameElementLocation)
{
- HTMLFrameElement* frame = V8Proxy::DOMWrapperToNode<HTMLFrameElement>(info.Holder());
+ HTMLFrameElement* frame = V8DOMWrapper::convertDOMWrapperToNode<HTMLFrameElement>(info.Holder());
String locationValue = toWebCoreStringWithNullCheck(value);
if (!allowSettingFrameSrcToJavascriptUrl(frame, locationValue))
diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp
index 220af02..e8e2e72 100644
--- a/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLFrameSetElementCustom.cpp
@@ -47,14 +47,14 @@ namespace WebCore {
NAMED_PROPERTY_GETTER(HTMLFrameSetElement)
{
INC_STATS("DOM.HTMLFrameSetElement.NamedPropertyGetter");
- HTMLFrameSetElement* imp = V8Proxy::DOMWrapperToNode<HTMLFrameSetElement>(info.Holder());
+ HTMLFrameSetElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLFrameSetElement>(info.Holder());
Node* frameNode = imp->children()->namedItem(v8StringToAtomicWebCoreString(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 V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
}
return notHandledByInterceptor();
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
index 3739a4e..ce2c29a 100644
--- a/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
@@ -39,8 +39,8 @@ namespace WebCore {
ACCESSOR_SETTER(HTMLIFrameElementSrc)
{
- HTMLIFrameElement* iframe = V8Proxy::DOMWrapperToNode<HTMLIFrameElement>(info.Holder());
- String v = valueToStringWithNullCheck(value);
+ HTMLIFrameElement* iframe = V8DOMWrapper::convertDOMWrapperToNode<HTMLIFrameElement>(info.Holder());
+ String v = toWebCoreStringWithNullCheck(value);
if (!allowSettingFrameSrcToJavascriptUrl(iframe, v))
return;
diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
index afcc29d..91ebd5f 100644
--- a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
@@ -49,24 +49,28 @@ CALLBACK_FUNC_DECL(HTMLImageElementConstructor)
if (!args.IsConstructCall())
return throwError("DOM object constructor cannot be called as a function.");
- Document* document = V8Proxy::retrieveFrame()->document();
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return throwError("Image constructor associated frame is unavailable", V8Proxy::ReferenceError);
+
+ Document* document = frame->document();
if (!document)
- return throwError("Image constructor associated document is unavailable", V8Proxy::REFERENCE_ERROR);
+ return throwError("Image constructor associated document is unavailable", V8Proxy::ReferenceError);
// Make sure the document is added to the DOM Node map. Otherwise, the HTMLImageElement instance
// may end up being the only node in the map and get garbage-ccollected prematurely.
- V8Proxy::NodeToV8Object(document);
+ V8DOMWrapper::convertNodeToV8Object(document);
- RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, V8Proxy::retrieveFrame()->document());
+ RefPtr<HTMLImageElement> image = new HTMLImageElement(HTMLNames::imgTag, document);
if (args.Length() > 0) {
image->setWidth(toInt32(args[0]));
if (args.Length() > 1)
image->setHeight(toInt32(args[1]));
}
- V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), image.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), image.get());
image->ref();
- V8Proxy::SetJSWrapperForDOMNode(image.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+ V8DOMWrapper::setJSWrapperForDOMNode(image.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp
index 628634d..63fbcec 100644
--- a/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLInputElementCustom.cpp
@@ -41,7 +41,7 @@ ACCESSOR_GETTER(HTMLInputElementSelectionStart)
{
INC_STATS("DOM.HTMLInputElement.selectionStart._get");
v8::Handle<v8::Object> holder = info.Holder();
- HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+ HTMLInputElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLInputElement>(holder);
if (!imp->canHaveSelection())
return throwError("Accessing selectionStart on an input element that cannot have a selection.");
@@ -54,7 +54,7 @@ ACCESSOR_SETTER(HTMLInputElementSelectionStart)
{
INC_STATS("DOM.HTMLInputElement.selectionStart._set");
v8::Handle<v8::Object> holder = info.Holder();
- HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+ HTMLInputElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLInputElement>(holder);
if (!imp->canHaveSelection()) {
throwError("Accessing selectionStart on an input element that cannot have a selection.");
@@ -67,7 +67,7 @@ ACCESSOR_GETTER(HTMLInputElementSelectionEnd)
{
INC_STATS("DOM.HTMLInputElement.selectionEnd._get");
v8::Handle<v8::Object> holder = info.Holder();
- HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+ HTMLInputElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLInputElement>(holder);
if (!imp->canHaveSelection())
return throwError("Accessing selectionEnd on an input element that cannot have a selection.");
@@ -80,7 +80,7 @@ ACCESSOR_SETTER(HTMLInputElementSelectionEnd)
{
INC_STATS("DOM.HTMLInputElement.selectionEnd._set");
v8::Handle<v8::Object> holder = info.Holder();
- HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+ HTMLInputElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLInputElement>(holder);
if (!imp->canHaveSelection()) {
throwError("Accessing selectionEnd on an input element that cannot have a selection.");
@@ -94,7 +94,7 @@ CALLBACK_FUNC_DECL(HTMLInputElementSetSelectionRange)
{
INC_STATS("DOM.HTMLInputElement.setSelectionRange");
v8::Handle<v8::Object> holder = args.Holder();
- HTMLInputElement* imp = V8Proxy::DOMWrapperToNode<HTMLInputElement>(holder);
+ HTMLInputElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLInputElement>(holder);
if (!imp->canHaveSelection())
return throwError("Calling setSelectionRange on an input element that cannot have a selection.");
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
index 93a9b68..c22d127 100644
--- a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
@@ -50,11 +50,15 @@ CALLBACK_FUNC_DECL(HTMLOptionElementConstructor)
if (!args.IsConstructCall())
return throwError("DOM object constructor cannot be called as a function.");
- Document* document = V8Proxy::retrieveFrame()->document();
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return throwError("Option constructor associated frame is unavailable", V8Proxy::ReferenceError);
+
+ Document* document = frame->document();
if (!document)
- return throwError("Option constructor associated document is unavailable", V8Proxy::REFERENCE_ERROR);
+ return throwError("Option constructor associated document is unavailable", V8Proxy::ReferenceError);
- RefPtr<HTMLOptionElement> option = new HTMLOptionElement(HTMLNames::optionTag, V8Proxy::retrieveFrame()->document());
+ RefPtr<HTMLOptionElement> option = new HTMLOptionElement(HTMLNames::optionTag, document);
ExceptionCode ec = 0;
RefPtr<Text> text = document->createTextNode("");
@@ -81,9 +85,9 @@ CALLBACK_FUNC_DECL(HTMLOptionElementConstructor)
}
}
- V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), option.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), option.get());
option->ref();
- V8Proxy::SetJSWrapperForDOMNode(option.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+ V8DOMWrapper::setJSWrapperForDOMNode(option.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
index 9f0d25e..02c3499 100644
--- a/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionsCollectionCustom.cpp
@@ -46,7 +46,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(HTMLOptionsCollectionRemove)
{
INC_STATS("DOM.HTMLOptionsCollection.remove()");
- HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder());
+ HTMLOptionsCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder());
HTMLSelectElement* base = static_cast<HTMLSelectElement*>(imp->base());
return removeElement(base, args);
}
@@ -55,11 +55,11 @@ CALLBACK_FUNC_DECL(HTMLOptionsCollectionAdd)
{
INC_STATS("DOM.HTMLOptionsCollection.add()");
if (!V8HTMLOptionElement::HasInstance(args[0])) {
- V8Proxy::SetDOMException(TYPE_MISMATCH_ERR);
+ V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
return v8::Undefined();
}
- HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder());
- HTMLOptionElement* option = V8Proxy::DOMWrapperToNode<HTMLOptionElement>(args[0]);
+ HTMLOptionsCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, args.Holder());
+ HTMLOptionElement* option = V8DOMWrapper::convertDOMWrapperToNode<HTMLOptionElement>(v8::Handle<v8::Object>(v8::Handle<v8::Object>::Cast(args[0])));
ExceptionCode ec = 0;
if (args.Length() < 2)
@@ -67,7 +67,7 @@ CALLBACK_FUNC_DECL(HTMLOptionsCollectionAdd)
else {
bool ok;
v8::TryCatch try_catch;
- int index = ToInt32(args[1], ok);
+ int index = toInt32(args[1], ok);
if (try_catch.HasCaught())
return v8::Undefined();
@@ -79,7 +79,7 @@ CALLBACK_FUNC_DECL(HTMLOptionsCollectionAdd)
}
if (ec != 0)
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Undefined();
}
@@ -87,7 +87,7 @@ CALLBACK_FUNC_DECL(HTMLOptionsCollectionAdd)
ACCESSOR_GETTER(HTMLOptionsCollectionLength)
{
INC_STATS("DOM.HTMLOptionsCollection.length._get");
- HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ HTMLOptionsCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
int v = imp->length();
return v8::Integer::New(v);
}
@@ -95,7 +95,7 @@ ACCESSOR_GETTER(HTMLOptionsCollectionLength)
ACCESSOR_SETTER(HTMLOptionsCollectionLength)
{
INC_STATS("DOM.HTMLOptionsCollection.length._set");
- HTMLOptionsCollection* imp = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ HTMLOptionsCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
double v = value->NumberValue();
unsigned newLength = 0;
ExceptionCode ec = 0;
@@ -110,25 +110,25 @@ ACCESSOR_SETTER(HTMLOptionsCollectionLength)
if (!ec)
imp->setLength(value->Uint32Value(), ec);
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
}
INDEXED_PROPERTY_GETTER(HTMLOptionsCollection)
{
INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertyGetter");
- HTMLOptionsCollection* collection = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ HTMLOptionsCollection* collection = V8DOMWrapper::convertToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
RefPtr<Node> result = collection->item(index);
if (!result)
return notHandledByInterceptor();
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
INDEXED_PROPERTY_SETTER(HTMLOptionsCollection)
{
INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertySetter");
- HTMLOptionsCollection* collection = V8Proxy::ToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
+ HTMLOptionsCollection* collection = V8DOMWrapper::convertToNativeObject<HTMLOptionsCollection>(V8ClassIndex::HTMLOPTIONSCOLLECTION, info.Holder());
HTMLSelectElement* base = static_cast<HTMLSelectElement*>(collection->base());
return toOptionsCollectionSetter(index, value, base);
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
index a6e41a1..13c82f3 100644
--- a/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLPlugInElementCustom.cpp
@@ -35,17 +35,15 @@
#include "V8Binding.h"
#include "V8CustomBinding.h"
+#include "V8NPObject.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());
+ HTMLPlugInElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLPlugInElement>(info.Holder());
ScriptInstance scriptInstance = imp->getInstance();
if (!scriptInstance)
return notHandledByInterceptor();
@@ -54,13 +52,13 @@ NAMED_PROPERTY_GETTER(HTMLPlugInElement)
if (instance.IsEmpty())
return notHandledByInterceptor();
- return NPObjectGetNamedProperty(instance, name);
+ return npObjectGetNamedProperty(instance, name);
}
NAMED_PROPERTY_SETTER(HTMLPlugInElement)
{
INC_STATS("DOM.HTMLPlugInElement.NamedPropertySetter");
- HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ HTMLPlugInElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLPlugInElement>(info.Holder());
ScriptInstance scriptInstance = imp->getInstance();
if (!scriptInstance)
return notHandledByInterceptor();
@@ -69,19 +67,19 @@ NAMED_PROPERTY_SETTER(HTMLPlugInElement)
if (instance.IsEmpty())
return notHandledByInterceptor();
- return NPObjectSetNamedProperty(instance, name, value);
+ return npObjectSetNamedProperty(instance, name, value);
}
CALLBACK_FUNC_DECL(HTMLPlugInElement)
{
INC_STATS("DOM.HTMLPluginElement()");
- return NPObjectInvokeDefaultHandler(args);
+ return npObjectInvokeDefaultHandler(args);
}
INDEXED_PROPERTY_GETTER(HTMLPlugInElement)
{
INC_STATS("DOM.HTMLPlugInElement.IndexedPropertyGetter");
- HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ HTMLPlugInElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLPlugInElement>(info.Holder());
ScriptInstance scriptInstance = imp->getInstance();
if (!scriptInstance)
return notHandledByInterceptor();
@@ -90,13 +88,13 @@ INDEXED_PROPERTY_GETTER(HTMLPlugInElement)
if (instance.IsEmpty())
return notHandledByInterceptor();
- return NPObjectGetIndexedProperty(instance, index);
+ return npObjectGetIndexedProperty(instance, index);
}
INDEXED_PROPERTY_SETTER(HTMLPlugInElement)
{
INC_STATS("DOM.HTMLPlugInElement.IndexedPropertySetter");
- HTMLPlugInElement* imp = V8Proxy::DOMWrapperToNode<HTMLPlugInElement>(info.Holder());
+ HTMLPlugInElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLPlugInElement>(info.Holder());
ScriptInstance scriptInstance = imp->getInstance();
if (!scriptInstance)
return notHandledByInterceptor();
@@ -105,7 +103,7 @@ INDEXED_PROPERTY_SETTER(HTMLPlugInElement)
if (instance.IsEmpty())
return notHandledByInterceptor();
- return NPObjectSetIndexedProperty(instance, index, value);
+ return npObjectSetIndexedProperty(instance, index, value);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp
index 8b3b72a..0dfa515 100644
--- a/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCollectionCustom.cpp
@@ -43,7 +43,7 @@ namespace WebCore {
NAMED_PROPERTY_GETTER(HTMLSelectElementCollection)
{
INC_STATS("DOM.HTMLSelectElementCollection.NamedPropertySetter");
- HTMLSelectElement* select = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder());
+ HTMLSelectElement* select = V8DOMWrapper::convertDOMWrapperToNode<HTMLSelectElement>(info.Holder());
v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name);
if (!value.IsEmpty())
@@ -62,16 +62,16 @@ NAMED_PROPERTY_GETTER(HTMLSelectElementCollection)
return notHandledByInterceptor();
if (items.size() == 1)
- return V8Proxy::NodeToV8Object(items.at(0).get());
+ return V8DOMWrapper::convertNodeToV8Object(items.at(0).release());
NodeList* list = new V8NamedNodesCollection(items);
- return V8Proxy::ToV8Object(V8ClassIndex::NODELIST, list);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODELIST, list);
}
INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection)
{
INC_STATS("DOM.HTMLSelectElementCollection.IndexedPropertySetter");
- HTMLSelectElement* select = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(info.Holder());
+ HTMLSelectElement* select = V8DOMWrapper::convertDOMWrapperToNode<HTMLSelectElement>(info.Holder());
return toOptionsCollectionSetter(index, value, select);
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp
index 97f7726..661ffa2 100644
--- a/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLSelectElementCustom.cpp
@@ -44,19 +44,19 @@ namespace WebCore {
CALLBACK_FUNC_DECL(HTMLSelectElementRemove)
{
INC_STATS("DOM.HTMLSelectElement.remove");
- HTMLSelectElement* imp = V8Proxy::DOMWrapperToNode<HTMLSelectElement>(args.Holder());
+ HTMLSelectElement* imp = V8DOMWrapper::convertDOMWrapperToNode<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]);
+ HTMLOptionElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLOptionElement>(v8::Handle<v8::Object>::Cast(args[0]));
imp->remove(element->index());
return v8::Undefined();
}
- imp->remove(ToInt32(args[0]));
+ imp->remove(toInt32(args[0]));
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp
index a85c0d6..2571df4 100644
--- a/WebCore/bindings/v8/custom/V8InspectorControllerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp
@@ -29,12 +29,13 @@
*/
#include "config.h"
-#include "InspectorController.h"
+#include "InspectorBackend.h"
#include "DOMWindow.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "ExceptionCode.h"
+#include "InspectorController.h"
#include "InspectorResource.h"
#include "NotImplemented.h"
#include "Node.h"
@@ -49,58 +50,31 @@
namespace WebCore {
-CALLBACK_FUNC_DECL(InspectorControllerHighlightDOMNode)
+CALLBACK_FUNC_DECL(InspectorBackendHighlightDOMNode)
{
- INC_STATS("InspectorController.highlightDOMNode()");
+ INC_STATS("InspectorBackend.highlightDOMNode()");
if (args.Length() < 1)
return v8::Undefined();
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
if (!node)
return v8::Undefined();
- InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder());
- inspectorController->highlight(node);
+ InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
+ inspectorBackend->highlight(node);
return v8::Undefined();
}
-CALLBACK_FUNC_DECL(InspectorControllerGetResourceDocumentNode)
+CALLBACK_FUNC_DECL(InspectorBackendSearch)
{
- INC_STATS("InspectorController.getResourceDocumentNode()");
-
- if (args.Length() < 1)
- return v8::Undefined();
-
- if (!args[1]->IsNumber())
- return v8::Undefined();
-
- unsigned identifier = args[1]->Int32Value();
-
- InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder());
- RefPtr<InspectorResource> resource = inspectorController->resources().get(identifier);
- ASSERT(resource);
- if (!resource)
- return v8::Undefined();
-
- Frame* frame = resource->frame();
- Document* document = frame->document();
-
- if (document->isPluginDocument() || document->isImageDocument() || document->isMediaDocument())
- return v8::Undefined();
-
- return V8Proxy::ToV8Object(V8ClassIndex::DOCUMENT, document);
-}
-
-CALLBACK_FUNC_DECL(InspectorControllerSearch)
-{
- INC_STATS("InspectorController.search()");
+ INC_STATS("InspectorBackend.search()");
if (args.Length() < 2)
return v8::Undefined();
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
if (!node)
return v8::Undefined();
@@ -124,7 +98,7 @@ CALLBACK_FUNC_DECL(InspectorControllerSearch)
if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
break;
- result->Set(v8::Number::New(index++), V8Proxy::ToV8Object<Range>(V8ClassIndex::RANGE, resultRange.get()));
+ result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release()));
setStart(searchRange.get(), newStart);
} while (true);
@@ -133,25 +107,28 @@ CALLBACK_FUNC_DECL(InspectorControllerSearch)
}
#if ENABLE(DATABASE)
-CALLBACK_FUNC_DECL(InspectorControllerDatabaseTableNames)
+CALLBACK_FUNC_DECL(InspectorBackendDatabaseTableNames)
{
- INC_STATS("InspectorController.databaseTableNames()");
+ INC_STATS("InspectorBackend.databaseTableNames()");
v8::Local<v8::Array> result = v8::Array::New(0);
return result;
}
#endif
-CALLBACK_FUNC_DECL(InspectorControllerInspectedWindow)
+CALLBACK_FUNC_DECL(InspectorBackendInspectedWindow)
{
- INC_STATS("InspectorController.inspectedWindow()");
+ INC_STATS("InspectorBackend.inspectedWindow()");
- InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder());
- return V8Proxy::ToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, inspectorController->inspectedPage()->mainFrame()->domWindow());
+ InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
+ InspectorController* ic = inspectorBackend->inspectorController();
+ if (!ic)
+ return v8::Undefined();
+ return V8DOMWrapper::convertToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, ic->inspectedPage()->mainFrame()->domWindow());
}
-CALLBACK_FUNC_DECL(InspectorControllerSetting)
+CALLBACK_FUNC_DECL(InspectorBackendSetting)
{
- INC_STATS("InspectorController.setting()");
+ INC_STATS("InspectorBackend.setting()");
if (args.Length() < 1)
return v8::Undefined();
@@ -160,8 +137,11 @@ CALLBACK_FUNC_DECL(InspectorControllerSetting)
if (key.isEmpty())
return v8::Undefined();
- InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder());
- const InspectorController::Setting& setting = inspectorController ->setting(key);
+ InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
+ InspectorController* ic = inspectorBackend->inspectorController();
+ if (!ic)
+ return v8::Undefined();
+ const InspectorController::Setting& setting = ic->setting(key);
switch (setting.type()) {
default:
@@ -186,9 +166,9 @@ CALLBACK_FUNC_DECL(InspectorControllerSetting)
}
}
-CALLBACK_FUNC_DECL(InspectorControllerSetSetting)
+CALLBACK_FUNC_DECL(InspectorBackendSetSetting)
{
- INC_STATS("InspectorController.setSetting()");
+ INC_STATS("InspectorBackend.setSetting()");
if (args.Length() < 2)
return v8::Undefined();
@@ -221,15 +201,17 @@ CALLBACK_FUNC_DECL(InspectorControllerSetSetting)
} else
return v8::Undefined();
- InspectorController* inspectorController = V8Proxy::ToNativeObject<InspectorController>(V8ClassIndex::INSPECTORCONTROLLER, args.Holder());
- inspectorController->setSetting(key, setting);
+ InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
+ InspectorController* ic = inspectorBackend->inspectorController();
+ if (ic)
+ inspectorBackend->inspectorController()->setSetting(key, setting);
return v8::Undefined();
}
-CALLBACK_FUNC_DECL(InspectorControllerWrapCallback)
+CALLBACK_FUNC_DECL(InspectorBackendWrapCallback)
{
- INC_STATS("InspectorController.wrapCallback()");
+ INC_STATS("InspectorBackend.wrapCallback()");
return args[0];
}
diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
index c5f3b1d..3f3ff6b 100644
--- a/WebCore/bindings/v8/custom/V8LocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
@@ -62,7 +62,7 @@ ACCESSOR_SETTER(LocationHash)
{
INC_STATS("DOM.Location.hash._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String hash = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -70,13 +70,13 @@ ACCESSOR_SETTER(LocationHash)
return;
KURL url = frame->loader()->url();
- String oldRef = url.ref();
+ String oldRef = url.fragmentIdentifier();
if (hash.startsWith("#"))
hash = hash.substring(1);
if (oldRef == hash || (oldRef.isNull() && hash.isEmpty()))
return;
- url.setRef(hash);
+ url.setFragmentIdentifier(hash);
navigateIfAllowed(frame, url, false, false);
}
@@ -85,7 +85,7 @@ ACCESSOR_SETTER(LocationHost)
{
INC_STATS("DOM.Location.host._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String host = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -105,7 +105,7 @@ ACCESSOR_SETTER(LocationHostname)
{
INC_STATS("DOM.Location.hostname._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String hostname = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -122,7 +122,7 @@ ACCESSOR_SETTER(LocationHref)
{
INC_STATS("DOM.Location.href._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
Frame* frame = imp->frame();
if (!frame)
@@ -142,7 +142,7 @@ ACCESSOR_SETTER(LocationPathname)
{
INC_STATS("DOM.Location.pathname._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String pathname = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -159,7 +159,7 @@ ACCESSOR_SETTER(LocationPort)
{
INC_STATS("DOM.Location.port._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String port = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -176,7 +176,7 @@ ACCESSOR_SETTER(LocationProtocol)
{
INC_STATS("DOM.Location.protocol._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String protocol = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -193,7 +193,7 @@ ACCESSOR_SETTER(LocationSearch)
{
INC_STATS("DOM.Location.search._set");
v8::Handle<v8::Object> holder = info.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
String query = toWebCoreString(value);
Frame* frame = imp->frame();
@@ -210,14 +210,14 @@ 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());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::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)) {
+ Location* imp = V8DOMWrapper::convertToNativeObject<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
@@ -228,14 +228,14 @@ 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());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::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)) {
+ Location* imp = V8DOMWrapper::convertToNativeObject<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
@@ -247,14 +247,14 @@ 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());
+ v8::Handle<v8::Object> holder = V8DOMWrapper::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)) {
+ Location* imp = V8DOMWrapper::convertToNativeObject<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
@@ -266,8 +266,8 @@ 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);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
Frame* frame = imp->frame();
if (!frame || !ScriptController::isSafeScript(frame))
@@ -281,8 +281,8 @@ CALLBACK_FUNC_DECL(LocationReload)
CALLBACK_FUNC_DECL(LocationReplace)
{
INC_STATS("DOM.Location.replace");
- v8::Handle<v8::Value> holder = args.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
Frame* frame = imp->frame();
if (!frame)
@@ -302,8 +302,8 @@ CALLBACK_FUNC_DECL(LocationReplace)
CALLBACK_FUNC_DECL(LocationAssign)
{
INC_STATS("DOM.Location.assign");
- v8::Handle<v8::Value> holder = args.Holder();
- Location* imp = V8Proxy::ToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
Frame* frame = imp->frame();
if (!frame)
@@ -333,9 +333,9 @@ CALLBACK_FUNC_DECL(LocationValueOf)
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))
+ v8::Handle<v8::Object> holder = args.Holder();
+ Location* imp = V8DOMWrapper::convertToNativeObject<Location>(V8ClassIndex::LOCATION, holder);
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
String result = imp->href();
return v8String(result);
@@ -345,16 +345,16 @@ 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);
+ Location* imp = V8DOMWrapper::convertToNativeObject<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);
+ Location* imp = V8DOMWrapper::convertToNativeObject<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
index 3a41467..f45aecf 100644
--- a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
@@ -31,12 +31,14 @@
#include "config.h"
#include "MessageChannel.h"
-#include "Document.h"
-#include "Frame.h"
-
#include "V8Binding.h"
#include "V8Proxy.h"
+#include "Document.h"
+#include "Frame.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -44,32 +46,37 @@ namespace WebCore {
CALLBACK_FUNC_DECL(MessageChannelConstructor)
{
INC_STATS("DOM.MessageChannel.Constructor");
- // FIXME: The logic here is almost exact duplicate of V8::ConstructDOMObject.
+ // 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();
+ // Get the ScriptExecutionContext (WorkerContext or Document)
+ ScriptExecutionContext* context = 0;
+ WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+ if (proxy)
+ context = proxy->workerContext();
+ else {
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return v8::Undefined();
+ context = 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);
+ RefPtr<MessageChannel> obj = MessageChannel::create(context);
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()));
+ messageChannel->SetInternalField(kMessageChannelPort1Index, V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, obj->port1()));
+ messageChannel->SetInternalField(kMessageChannelPort2Index, V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, obj->port2()));
// Setup the standard wrapper object internal fields.
- V8Proxy::SetDOMWrapper(messageChannel, V8ClassIndex::MESSAGECHANNEL, obj.get());
+ V8DOMWrapper::setDOMWrapper(messageChannel, V8ClassIndex::MESSAGECHANNEL, obj.get());
return toV8(obj.release(), messageChannel);
}
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
index fce04b6..95d248c 100644
--- a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -37,20 +37,38 @@
#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
+#include "WorkerContextExecutionProxy.h"
namespace WebCore {
+PassRefPtr<EventListener> getEventListener(MessagePort* messagePort, v8::Local<v8::Value> value, bool findOnly, bool createObjectEventListener)
+{
+ V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
+ if (proxy) {
+ V8EventListenerList* list = proxy->objectListeners();
+ return findOnly ? list->findWrapper(value, false) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
+ }
+
+#if ENABLE(WORKERS)
+ WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+ if (workerContextProxy)
+ return workerContextProxy->findOrCreateEventListenerHelper(value, false, findOnly, createObjectEventListener);
+#endif
+
+ return PassRefPtr<EventListener>();
+}
+
ACCESSOR_GETTER(MessagePortOnmessage)
{
INC_STATS("DOM.MessagePort.onmessage._get");
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
- return V8Proxy::EventListenerToV8Object(messagePort->onmessage());
+ MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
+ return V8DOMWrapper::convertEventListenerToV8Object(messagePort->onmessage());
}
ACCESSOR_SETTER(MessagePortOnmessage)
{
INC_STATS("DOM.MessagePort.onmessage._set");
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
+ MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
if (value->IsNull()) {
if (messagePort->onmessage()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onmessage());
@@ -61,11 +79,7 @@ ACCESSOR_SETTER(MessagePortOnmessage)
messagePort->setOnmessage(0);
} else {
- V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ RefPtr<EventListener> listener = getEventListener(messagePort, value, false, false);
if (listener) {
messagePort->setOnmessage(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kMessagePortRequestCacheIndex);
@@ -73,64 +87,11 @@ ACCESSOR_SETTER(MessagePortOnmessage)
}
}
-ACCESSOR_GETTER(MessagePortOnclose)
-{
- INC_STATS("DOM.MessagePort.onclose._get");
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
- return V8Proxy::EventListenerToV8Object(messagePort->onclose());
-}
-
-ACCESSOR_SETTER(MessagePortOnclose)
-{
- INC_STATS("DOM.MessagePort.onclose._set");
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
- if (value->IsNull()) {
- if (messagePort->onclose()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onclose());
- removeHiddenDependency(info.Holder(), listener->getListenerObject(), V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- messagePort->setOnclose(0);
- } else {
- V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
- if (listener) {
- messagePort->setOnclose(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kMessagePortRequestCacheIndex);
- }
- }
-}
-
-CALLBACK_FUNC_DECL(MessagePortStartConversation)
-{
- INC_STATS("DOM.MessagePort.StartConversation()");
- if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
-
- V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
- if (!proxy)
- return v8::Undefined();
-
- RefPtr<MessagePort> port = messagePort->startConversation(messagePort->scriptExecutionContext(), toWebCoreString(args[0]));
- v8::Handle<v8::Value> wrapper = V8Proxy::ToV8Object(V8ClassIndex::MESSAGEPORT, port.get());
- return wrapper;
-}
-
CALLBACK_FUNC_DECL(MessagePortAddEventListener)
{
- INC_STATS("DOM.MessagePort.AddEventListener()");
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
-
- V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
- if (!proxy)
- return v8::Undefined();
-
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(args[1], false);
+ INC_STATS("DOM.MessagePort.addEventListener()");
+ MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
+ RefPtr<EventListener> listener = getEventListener(messagePort, args[1], false, true);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -143,15 +104,9 @@ CALLBACK_FUNC_DECL(MessagePortAddEventListener)
CALLBACK_FUNC_DECL(MessagePortRemoveEventListener)
{
- INC_STATS("DOM.MessagePort.RemoveEventListener()");
- MessagePort* messagePort = V8Proxy::ToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
-
- V8Proxy* proxy = V8Proxy::retrieve(messagePort->scriptExecutionContext());
- if (!proxy)
- return v8::Undefined(); // probably leaked
-
- RefPtr<EventListener> listener = proxy->FindObjectEventListener(args[1], false);
-
+ INC_STATS("DOM.MessagePort.removeEventListener()");
+ MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
+ RefPtr<EventListener> listener = getEventListener(messagePort, args[1], true, true);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
index 8e529cc..afa90b7 100644
--- a/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NamedNodeMapCustom.cpp
@@ -42,12 +42,12 @@ namespace WebCore {
INDEXED_PROPERTY_GETTER(NamedNodeMap)
{
INC_STATS("DOM.NamedNodeMap.IndexedPropertyGetter");
- NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder());
+ NamedNodeMap* imp = V8DOMWrapper::convertToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder());
RefPtr<Node> result = imp->item(index);
if (!result)
return notHandledByInterceptor();
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
NAMED_PROPERTY_GETTER(NamedNodeMap)
@@ -63,12 +63,12 @@ NAMED_PROPERTY_GETTER(NamedNodeMap)
return notHandledByInterceptor();
// Finally, search the DOM.
- NamedNodeMap* imp = V8Proxy::ToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder());
+ NamedNodeMap* imp = V8DOMWrapper::convertToNativeObject<NamedNodeMap>(V8ClassIndex::NAMEDNODEMAP, info.Holder());
RefPtr<Node> result = imp->getNamedItem(toWebCoreString(name));
if (!result)
return notHandledByInterceptor();
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
index 9adfe25..6a7b209 100644
--- a/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
@@ -41,7 +41,7 @@ ACCESSOR_GETTER(NavigatorAppVersion)
{
INC_STATS("DOM.Navigator.appVersion");
v8::Handle<v8::Object> holder = info.Holder();
- Navigator* navigator = V8Proxy::ToNativeObject<Navigator>(V8ClassIndex::NAVIGATOR, holder);
+ Navigator* navigator = V8DOMWrapper::convertToNativeObject<Navigator>(V8ClassIndex::NAVIGATOR, holder);
return v8StringOrUndefined(navigator->appVersion());
}
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index e81e8b5..6b0d740 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -34,30 +34,86 @@
#include "Document.h"
#include "EventListener.h"
+#include "V8AbstractEventListener.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8CustomEventListener.h"
#include "V8Node.h"
+#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include <wtf/RefPtr.h>
namespace WebCore {
-CALLBACK_FUNC_DECL(NodeAddEventListener)
+static inline String toEventType(v8::Local<v8::String> value)
{
- INC_STATS("DOM.Node.addEventListener()");
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder());
+ String key = toWebCoreString(value);
+ ASSERT(key.startsWith("on"));
+ return key.substring(2);
+}
- V8Proxy* proxy = V8Proxy::retrieve(node->document()->frame());
+static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
+{
+ V8Proxy* proxy = V8Proxy::retrieve(node->scriptExecutionContext());
+ // The document might be created using createDocument, which does
+ // not have a frame, use the active frame.
if (!proxy)
- return v8::Undefined();
+ proxy = V8Proxy::retrieve(V8Proxy::retrieveFrameForEnteredContext());
+
+ if (proxy) {
+ V8EventListenerList* list = proxy->objectListeners();
+ return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
+ }
+
+ return 0;
+}
+
+ACCESSOR_SETTER(NodeEventHandler)
+{
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(info.Holder());
+ String eventType = toEventType(name);
+
+ // Remove hidden dependency on the old event handler.
+ if (EventListener* listener = node->getAttributeEventListener(eventType)) {
+ if (static_cast<V8AbstractEventListener*>(listener)->isObjectListener()) {
+ v8::Local<v8::Object> v8Listener = static_cast<V8ObjectEventListener*>(listener)->getListenerObject();
+ removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kNodeEventListenerCacheIndex);
+ }
+ }
+
+ // Set handler if the value is a function.
+ if (value->IsFunction()) {
+ RefPtr<EventListener> listener = getEventListener(node, value, true, false);
+ if (listener) {
+ node->setAttributeEventListener(eventType, listener);
+ createHiddenDependency(info.Holder(), value, V8Custom::kNodeEventListenerCacheIndex);
+ }
+ } else {
+ // Otherwise, clear the handler.
+ node->clearAttributeEventListener(eventType);
+ }
+}
+
+ACCESSOR_GETTER(NodeEventHandler)
+{
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(info.Holder());
+
+ EventListener* listener = node->getAttributeEventListener(toEventType(name));
+ return V8DOMWrapper::convertEventListenerToV8Object(listener);
+}
- RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false);
+CALLBACK_FUNC_DECL(NodeAddEventListener)
+{
+ INC_STATS("DOM.Node.addEventListener()");
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(args.Holder());
+
+ RefPtr<EventListener> listener = getEventListener(node, args[1], false, false);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
node->addEventListener(type, listener, useCapture);
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
}
return v8::Undefined();
}
@@ -65,20 +121,17 @@ CALLBACK_FUNC_DECL(NodeAddEventListener)
CALLBACK_FUNC_DECL(NodeRemoveEventListener)
{
INC_STATS("DOM.Node.removeEventListener()");
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args.Holder());
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<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.
+ // from the frame.
// See issue http://b/878909
- if (!proxy)
- return v8::Undefined();
-
- RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false);
+ RefPtr<EventListener> listener = getEventListener(node, args[1], false, true);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
node->removeEventListener(type, listener.get(), useCapture);
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
}
return v8::Undefined();
@@ -88,14 +141,14 @@ CALLBACK_FUNC_DECL(NodeRemoveEventListener)
CALLBACK_FUNC_DECL(NodeInsertBefore)
{
INC_STATS("DOM.Node.insertBefore");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
- Node* refChild = V8Node::HasInstance(args[1]) ? V8Proxy::DOMWrapperToNode<Node>(args[1]) : 0;
+ Node* newChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ Node* refChild = V8Node::HasInstance(args[1]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1])) : 0;
bool success = imp->insertBefore(newChild, refChild, ec, true);
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
@@ -107,14 +160,14 @@ CALLBACK_FUNC_DECL(NodeInsertBefore)
CALLBACK_FUNC_DECL(NodeReplaceChild)
{
INC_STATS("DOM.Node.replaceChild");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
- Node* oldChild = V8Node::HasInstance(args[1]) ? V8Proxy::DOMWrapperToNode<Node>(args[1]) : 0;
+ Node* newChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ Node* oldChild = V8Node::HasInstance(args[1]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1])) : 0;
bool success = imp->replaceChild(newChild, oldChild, ec, true);
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
@@ -125,13 +178,13 @@ CALLBACK_FUNC_DECL(NodeReplaceChild)
CALLBACK_FUNC_DECL(NodeRemoveChild)
{
INC_STATS("DOM.Node.removeChild");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* oldChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
+ Node* oldChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->removeChild(oldChild, ec);
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
@@ -143,13 +196,13 @@ CALLBACK_FUNC_DECL(NodeRemoveChild)
CALLBACK_FUNC_DECL(NodeAppendChild)
{
INC_STATS("DOM.Node.appendChild");
- v8::Handle<v8::Value> holder = args.Holder();
- Node* imp = V8Proxy::DOMWrapperToNode<Node>(holder);
+ v8::Handle<v8::Object> holder = args.Holder();
+ Node* imp = V8DOMWrapper::convertDOMWrapperToNode<Node>(holder);
ExceptionCode ec = 0;
- Node* newChild = V8Node::HasInstance(args[0]) ? V8Proxy::DOMWrapperToNode<Node>(args[0]) : 0;
+ Node* newChild = V8Node::HasInstance(args[0]) ? V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0])) : 0;
bool success = imp->appendChild(newChild, ec, true );
if (ec) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
if (success)
diff --git a/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp b/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp
index 48e6b8f..47ae8ee 100644
--- a/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeIteratorCustom.cpp
@@ -53,13 +53,13 @@ static inline v8::Handle<v8::Value> toV8(PassRefPtr<Node> object, ExceptionCode
if (!object)
return v8::Null();
- return V8Proxy::NodeToV8Object(object.get());
+ return V8DOMWrapper::convertNodeToV8Object(object);
}
CALLBACK_FUNC_DECL(NodeIteratorNextNode)
{
INC_STATS("DOM.NodeIterator.nextNode()");
- NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder());
+ NodeIterator* nodeIterator = V8DOMWrapper::convertToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder());
ExceptionCode ec = 0;
ScriptState state;
@@ -70,7 +70,7 @@ CALLBACK_FUNC_DECL(NodeIteratorNextNode)
CALLBACK_FUNC_DECL(NodeIteratorPreviousNode)
{
INC_STATS("DOM.NodeIterator.previousNode()");
- NodeIterator* nodeIterator = V8Proxy::ToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder());
+ NodeIterator* nodeIterator = V8DOMWrapper::convertToNativeObject<NodeIterator>(V8ClassIndex::NODEITERATOR, args.Holder());
ExceptionCode ec = 0;
ScriptState state;
diff --git a/WebCore/bindings/v8/custom/V8NodeListCustom.cpp b/WebCore/bindings/v8/custom/V8NodeListCustom.cpp
index 27a47f5..ad10952 100644
--- a/WebCore/bindings/v8/custom/V8NodeListCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeListCustom.cpp
@@ -36,24 +36,26 @@
#include "V8Proxy.h"
#include <wtf/RefPtr.h>
+#include <wtf/StdLibExtras.h>
namespace WebCore {
NAMED_PROPERTY_GETTER(NodeList)
{
INC_STATS("DOM.NodeList.NamedPropertyGetter");
- NodeList* list = V8Proxy::ToNativeObject<NodeList>(V8ClassIndex::NODELIST, info.Holder());
+ NodeList* list = V8DOMWrapper::convertToNativeObject<NodeList>(V8ClassIndex::NODELIST, info.Holder());
String key = toWebCoreString(name);
// Length property cannot be overridden.
- if (key == "length")
- return v8::Number::New(list->length());
+ DEFINE_STATIC_LOCAL(const AtomicString, length, ("length"));
+ if (key == length)
+ return v8::Integer::New(list->length());
RefPtr<Node> result = list->itemWithName(key);
if (!result)
return notHandledByInterceptor();
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp b/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
index eaeb26d..aced4ee 100644
--- a/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SQLResultSetRowListCustom.cpp
@@ -32,11 +32,20 @@
#if ENABLE(DATABASE)
+#ifdef MANUAL_MERGE_REQUIRED
#include "v8_binding.h"
#include "v8_proxy.h"
+#else // MANUAL_MERGE_REQUIRED
+#endif // MANUAL_MERGE_REQUIRED
#include "SQLResultSetRowList.h"
+#ifdef MANUAL_MERGE_REQUIRED
#include "V8CustomBinding.h"
+#else // MANUAL_MERGE_REQUIRED
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+#endif // MANUAL_MERGE_REQUIRED
namespace WebCore {
@@ -45,20 +54,20 @@ CALLBACK_FUNC_DECL(SQLResultSetRowListItem)
INC_STATS("DOM.SQLResultSetRowList.item()");
if (args.Length() == 0) {
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Item index is required.");
+ V8Proxy::throwError(V8Proxy::SyntaxError, "Item index is required.");
return v8::Undefined();
}
if (!args[0]->IsNumber()) {
- V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Item index must be a number.");
+ V8Proxy::throwError(V8Proxy::TypeError, "Item index must be a number.");
return v8::Undefined();
}
- SQLResultSetRowList* rowList = V8Proxy::ToNativeObject<SQLResultSetRowList>(V8ClassIndex::SQLRESULTSETROWLIST, args.Holder());
+ SQLResultSetRowList* rowList = V8DOMWrapper::convertToNativeObject<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.");
+ V8Proxy::throwError(V8Proxy::RangeError, "Item index is out of range.");
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp b/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp
index 15cd379..b9b86fc 100644
--- a/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SQLTransactionCustom.cpp
@@ -32,14 +32,23 @@
#if ENABLE(DATABASE)
+#ifdef MANUAL_MERGE_REQUIRED
#include "v8_binding.h"
#include "v8_proxy.h"
+#else // MANUAL_MERGE_REQUIRED
+#endif // MANUAL_MERGE_REQUIRED
#include "Database.h"
#include "SQLValue.h"
+#ifdef MANUAL_MERGE_REQUIRED
#include "V8CustomBinding.h"
+#else // MANUAL_MERGE_REQUIRED
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#endif // MANUAL_MERGE_REQUIRED
#include "V8CustomSQLStatementCallback.h"
#include "V8CustomSQLStatementErrorCallback.h"
+#include "V8Proxy.h"
#include <wtf/Vector.h>
using namespace WTF;
@@ -51,18 +60,18 @@ CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
INC_STATS("DOM.SQLTransaction.executeSql()");
if (args.Length() == 0) {
- V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "SQL statement is required.");
+ V8Proxy::throwError(V8Proxy::SyntaxError, "SQL statement is required.");
return v8::Undefined();
}
- String statement = ToWebCoreString(args[0]);
+ 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.");
+ V8Proxy::throwError(V8Proxy::TypeError, "Statement arguments must be an v8::Array.");
return v8::Undefined();
}
@@ -76,18 +85,18 @@ CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
else if (value->IsNumber())
sqlValues.append(SQLValue(value->NumberValue()));
else
- sqlValues.append(SQLValue(ToWebCoreString(value)));
+ sqlValues.append(SQLValue(toWebCoreString(value)));
}
}
- SQLTransaction* transaction = V8Proxy::ToNativeObject<SQLTransaction>(V8ClassIndex::SQLTRANSACTION, args.Holder());
+ SQLTransaction* transaction = V8DOMWrapper::convertToNativeObject<SQLTransaction>(V8ClassIndex::SQLTRANSACTION, args.Holder());
- Frame* frame = V8Proxy::retrieveFrame();
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
RefPtr<SQLStatementCallback> callback;
if (args.Length() > 2) {
if (!args[2]->IsObject()) {
- V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement callback must be of valid type.");
+ V8Proxy::throwError(V8Proxy::TypeError, "Statement callback must be of valid type.");
return v8::Undefined();
}
@@ -98,7 +107,7 @@ CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
RefPtr<SQLStatementErrorCallback> errorCallback;
if (args.Length() > 3) {
if (!args[2]->IsObject()) {
- V8Proxy::ThrowError(V8Proxy::TYPE_ERROR, "Statement error callback must be of valid type.");
+ V8Proxy::throwError(V8Proxy::TypeError, "Statement error callback must be of valid type.");
return v8::Undefined();
}
@@ -108,7 +117,7 @@ CALLBACK_FUNC_DECL(SQLTransactionExecuteSql)
ExceptionCode ec = 0;
transaction->executeSQL(statement, sqlValues, callback, errorCallback, ec);
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
index 351b030..ce9c345 100644
--- a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
@@ -47,13 +47,13 @@ namespace WebCore {
CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener)
{
INC_STATS("DOM.SVGElementInstance.AddEventListener()");
- SVGElementInstance* instance = V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder());
+ SVGElementInstance* instance = V8DOMWrapper::convertDOMWrapperToNative<SVGElementInstance>(args.Holder());
V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = proxy->FindOrCreateV8EventListener(args[1], false);
+ RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -66,13 +66,13 @@ CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener)
CALLBACK_FUNC_DECL(SVGElementInstanceRemoveEventListener)
{
INC_STATS("DOM.SVGElementInstance.RemoveEventListener()");
- SVGElementInstance* instance = V8Proxy::DOMWrapperToNative<SVGElementInstance>(args.Holder());
+ SVGElementInstance* instance = V8DOMWrapper::convertDOMWrapperToNative<SVGElementInstance>(args.Holder());
V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = proxy->FindV8EventListener(args[1], false);
+ RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp
index a2a4d49..9f75f5a 100644
--- a/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGLengthCustom.cpp
@@ -44,17 +44,17 @@ namespace WebCore {
ACCESSOR_GETTER(SVGLengthValue)
{
INC_STATS("DOM.SVGLength.value");
- V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, info.Holder());
+ V8SVGPODTypeWrapper<SVGLength>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, info.Holder());
SVGLength imp = *wrapper;
- return v8::Number::New(imp.value(V8Proxy::GetSVGContext(wrapper)));
+ return v8::Number::New(imp.value(V8Proxy::svgContext(wrapper)));
}
CALLBACK_FUNC_DECL(SVGLengthConvertToSpecifiedUnits)
{
INC_STATS("DOM.SVGLength.convertToSpecifiedUnits");
- V8SVGPODTypeWrapper<SVGLength>* wrapper = V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, args.Holder());
+ V8SVGPODTypeWrapper<SVGLength>* wrapper = V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<SVGLength> >(V8ClassIndex::SVGLENGTH, args.Holder());
SVGLength imp = *wrapper;
- SVGElement* context = V8Proxy::GetSVGContext(wrapper);
+ SVGElement* context = V8Proxy::svgContext(wrapper);
imp.convertToSpecifiedUnits(toInt32(args[0]), context);
wrapper->commitChange(imp, context);
return v8::Undefined();
diff --git a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
index b69202b..3766397 100644
--- a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
@@ -46,7 +46,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(SVGMatrixInverse)
{
INC_STATS("DOM.SVGMatrix.inverse()");
- TransformationMatrix matrix = *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
+ TransformationMatrix matrix = *V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
ExceptionCode ec = 0;
TransformationMatrix result = matrix.inverse();
@@ -54,17 +54,17 @@ CALLBACK_FUNC_DECL(SVGMatrixInverse)
ec = SVGException::SVG_MATRIX_NOT_INVERTABLE;
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
- return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, new V8SVGStaticPODTypeWrapper<TransformationMatrix>(result));
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::SVGMATRIX, V8SVGStaticPODTypeWrapper<TransformationMatrix>::create(result));
}
CALLBACK_FUNC_DECL(SVGMatrixRotateFromVector)
{
INC_STATS("DOM.SVGMatrix.rotateFromVector()");
- TransformationMatrix matrix = *V8Proxy::ToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
+ TransformationMatrix matrix = *V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
ExceptionCode ec = 0;
float x = toFloat(args[0]);
float y = toFloat(args[1]);
@@ -74,11 +74,11 @@ CALLBACK_FUNC_DECL(SVGMatrixRotateFromVector)
ec = SVGException::SVG_INVALID_VALUE_ERR;
if (ec != 0) {
- V8Proxy::SetDOMException(ec);
+ V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
}
- return V8Proxy::ToV8Object(V8ClassIndex::SVGMATRIX, new V8SVGStaticPODTypeWrapper<TransformationMatrix>(result));
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::SVGMATRIX, V8SVGStaticPODTypeWrapper<TransformationMatrix>::create(result));
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
new file mode 100644
index 0000000..3ab2f8e
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.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"
+
+#if ENABLE(SHARED_WORKERS)
+
+#include "SharedWorker.h"
+
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8ObjectEventListener.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(SharedWorkerConstructor)
+{
+ INC_STATS(L"DOM.SharedWorker.Constructor");
+
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.");
+
+ if (args.Length() < 2)
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
+
+ v8::TryCatch tryCatch;
+ v8::Handle<v8::String> scriptUrl = args[0]->ToString();
+ v8::Handle<v8::String> name = args[1]->ToString();
+ if (tryCatch.HasCaught())
+ return throwError(tryCatch.Exception());
+
+ if (scriptUrl.IsEmpty())
+ return v8::Undefined();
+
+ // Get the script execution context.
+ ScriptExecutionContext* context = 0;
+ WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+ if (proxy)
+ context = proxy->workerContext();
+ else {
+ Frame* frame = V8Proxy::retrieveFrame();
+ if (!frame)
+ return v8::Undefined();
+ context = frame->document();
+ }
+
+ // Create the worker object.
+ // Note: it's OK to let this RefPtr go out of scope because we also call SetDOMWrapper(), which effectively holds a reference to obj.
+ ExceptionCode ec = 0;
+ RefPtr<SharedWorker> obj = SharedWorker::create(toWebCoreString(scriptUrl), toWebCoreString(name), context, ec);
+
+ // Setup the standard wrapper object internal fields.
+ v8::Handle<v8::Object> wrapperObject = args.Holder();
+ V8Proxy::setDOMWrapper(wrapperObject, V8ClassIndex::SHAREDWORKER, obj.get());
+
+ obj->ref();
+ V8Proxy::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
+
+ return wrapperObject;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SHARED_WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8StorageCustom.cpp b/WebCore/bindings/v8/custom/V8StorageCustom.cpp
index af8b4c8..b54e50e 100755
--- a/WebCore/bindings/v8/custom/V8StorageCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8StorageCustom.cpp
@@ -42,13 +42,12 @@ namespace WebCore {
// Get an array containing the names of indexed properties in a collection.
v8::Handle<v8::Array> V8Custom::v8StorageNamedPropertyEnumerator(const v8::AccessorInfo& info)
{
- Storage* storage = V8Proxy::ToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
+ Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
unsigned int length = storage->length();
v8::Handle<v8::Array> properties = v8::Array::New(length);
for (unsigned int i = 0; i < length; ++i) {
- ExceptionCode ec = 0;
- String key = storage->key(i, ec);
- ASSERT(!ec);
+ String key = storage->key(i);
+ ASSERT(!key.isNull());
String val = storage->getItem(key);
properties->Set(v8::Integer::New(i), v8String(key));
}
@@ -58,7 +57,7 @@ v8::Handle<v8::Array> V8Custom::v8StorageNamedPropertyEnumerator(const v8::Acces
static v8::Handle<v8::Value> storageGetter(v8::Local<v8::String> v8Name, const v8::AccessorInfo& info)
{
- Storage* storage = V8Proxy::ToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
+ Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
String name = toWebCoreString(v8Name);
if (storage->contains(name))
@@ -82,7 +81,7 @@ NAMED_PROPERTY_GETTER(Storage)
static v8::Handle<v8::Value> storageSetter(v8::Local<v8::String> v8Name, v8::Local<v8::Value> v8Value, const v8::AccessorInfo& info)
{
- Storage* storage = V8Proxy::ToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
+ Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
String name = toWebCoreString(v8Name);
String value = toWebCoreString(v8Value);
@@ -117,7 +116,7 @@ NAMED_PROPERTY_SETTER(Storage)
static v8::Handle<v8::Boolean> storageDeleter(v8::Local<v8::String> v8Name, const v8::AccessorInfo& info)
{
- Storage* storage = V8Proxy::ToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
+ Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, info.Holder());
String name = toWebCoreString(v8Name);
if (storage->contains(name)) {
diff --git a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
index a362ce5..ecd0153 100644
--- a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
@@ -45,12 +45,12 @@ NAMED_PROPERTY_GETTER(StyleSheetList)
return notHandledByInterceptor();
// Search style sheet.
- StyleSheetList* imp = V8Proxy::ToNativeObject<StyleSheetList>(V8ClassIndex::STYLESHEETLIST, info.Holder());
+ StyleSheetList* imp = V8DOMWrapper::convertToNativeObject<StyleSheetList>(V8ClassIndex::STYLESHEETLIST, info.Holder());
HTMLStyleElement* item = imp->getNamedItem(toWebCoreString(name));
if (!item)
return notHandledByInterceptor();
- return V8Proxy::ToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp b/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp
index baf49c0..5052b7a 100644
--- a/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8TreeWalkerCustom.cpp
@@ -51,13 +51,13 @@ static inline v8::Handle<v8::Value> toV8(PassRefPtr<Node> object, ScriptState* s
if (!object)
return v8::Null();
- return V8Proxy::NodeToV8Object(object.get());
+ return V8DOMWrapper::convertNodeToV8Object(object);
}
CALLBACK_FUNC_DECL(TreeWalkerParentNode)
{
INC_STATS("DOM.TreeWalker.parentNode()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->parentNode(&state);
@@ -67,7 +67,7 @@ CALLBACK_FUNC_DECL(TreeWalkerParentNode)
CALLBACK_FUNC_DECL(TreeWalkerFirstChild)
{
INC_STATS("DOM.TreeWalker.firstChild()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->firstChild(&state);
@@ -77,7 +77,7 @@ CALLBACK_FUNC_DECL(TreeWalkerFirstChild)
CALLBACK_FUNC_DECL(TreeWalkerLastChild)
{
INC_STATS("DOM.TreeWalker.lastChild()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->lastChild(&state);
@@ -87,7 +87,7 @@ CALLBACK_FUNC_DECL(TreeWalkerLastChild)
CALLBACK_FUNC_DECL(TreeWalkerNextNode)
{
INC_STATS("DOM.TreeWalker.nextNode()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->nextNode(&state);
@@ -97,7 +97,7 @@ CALLBACK_FUNC_DECL(TreeWalkerNextNode)
CALLBACK_FUNC_DECL(TreeWalkerPreviousNode)
{
INC_STATS("DOM.TreeWalker.previousNode()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->previousNode(&state);
@@ -107,7 +107,7 @@ CALLBACK_FUNC_DECL(TreeWalkerPreviousNode)
CALLBACK_FUNC_DECL(TreeWalkerNextSibling)
{
INC_STATS("DOM.TreeWalker.nextSibling()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->nextSibling(&state);
@@ -117,7 +117,7 @@ CALLBACK_FUNC_DECL(TreeWalkerNextSibling)
CALLBACK_FUNC_DECL(TreeWalkerPreviousSibling)
{
INC_STATS("DOM.TreeWalker.previousSibling()");
- TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
+ TreeWalker* treeWalker = V8DOMWrapper::convertToNativeObject<TreeWalker>(V8ClassIndex::TREEWALKER, args.Holder());
ScriptState state;
RefPtr<Node> result = treeWalker->previousSibling(&state);
diff --git a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
index b07d288..4819064 100644
--- a/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitCSSMatrixConstructor.cpp
@@ -47,7 +47,11 @@ namespace WebCore {
CALLBACK_FUNC_DECL(WebKitCSSMatrixConstructor)
{
INC_STATS("DOM.WebKitCSSMatrix.Constructor");
- // FIXME: The logic here is almost exact duplicate of V8::ConstructDOMObject.
+
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.");
+
+ // FIXME: The logic here is almost exact duplicate of V8::constructDOMObject.
// Consider refactoring to reduce duplication.
String cssValue;
if (args.Length() >= 1)
@@ -59,7 +63,7 @@ CALLBACK_FUNC_DECL(WebKitCSSMatrixConstructor)
throwError(ec);
// Transform the holder into a wrapper object for the matrix.
- V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), matrix.get());
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBKITCSSMATRIX), matrix.get());
return toV8(matrix.release(), args.Holder());
}
diff --git a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
index d70ebf1..dd19a88 100755
--- a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
@@ -40,7 +40,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(WebKitPointConstructor)
{
INC_STATS("DOM.WebKitPoint.Constructor");
- return V8Proxy::ConstructDOMObject<V8ClassIndex::WEBKITPOINT, WebKitPoint>(args);
+ return V8Proxy::constructDOMObject<V8ClassIndex::WEBKITPOINT, WebKitPoint>(args);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
index a67cb10..b526040 100755
--- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
@@ -32,11 +32,8 @@
#if ENABLE(WORKERS)
-#include "WorkerContextExecutionProxy.h"
-
-#include "ExceptionCode.h"
#include "DOMTimer.h"
-#include "NotImplemented.h"
+#include "ExceptionCode.h"
#include "ScheduledAction.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
@@ -44,50 +41,51 @@
#include "V8Utilities.h"
#include "V8WorkerContextEventListener.h"
#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
namespace WebCore {
ACCESSOR_GETTER(WorkerContextSelf)
{
INC_STATS(L"DOM.WorkerContext.self._get");
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
- return WorkerContextExecutionProxy::WorkerContextToV8Object(workerContext);
+ WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(info.Holder());
+ return WorkerContextExecutionProxy::convertWorkerContextToV8Object(workerContext);
}
-ACCESSOR_GETTER(WorkerContextOnmessage)
+ACCESSOR_GETTER(WorkerContextOnerror)
{
- INC_STATS(L"DOM.WorkerContext.onmessage._get");
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
- if (workerContext->onmessage()) {
- V8WorkerContextEventListener* listener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage());
+ INC_STATS(L"DOM.WorkerContext.onerror._get");
+ WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
+ if (workerContext->onerror()) {
+ V8WorkerContextEventListener* listener = static_cast<V8WorkerContextEventListener*>(workerContext->onerror());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
return v8Listener;
}
return v8::Undefined();
}
-ACCESSOR_SETTER(WorkerContextOnmessage)
+ACCESSOR_SETTER(WorkerContextOnerror)
{
- INC_STATS(L"DOM.WorkerContext.onmessage._set");
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
- V8WorkerContextEventListener* oldListener = static_cast<V8WorkerContextEventListener*>(workerContext->onmessage());
+ INC_STATS(L"DOM.WorkerContext.onerror._set");
+ WorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, info.Holder());
+ V8WorkerContextEventListener* oldListener = static_cast<V8WorkerContextEventListener*>(workerContext->onerror());
if (value->IsNull()) {
- if (workerContext->onmessage()) {
+ if (workerContext->onerror()) {
v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex);
}
// Clear the listener.
- workerContext->setOnmessage(0);
+ workerContext->setOnerror(0);
} else {
- RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), false, false);
+ RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(value), true, false);
if (listener) {
if (oldListener) {
v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex);
}
- workerContext->setOnmessage(listener);
+ workerContext->setOnerror(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kWorkerContextRequestCacheIndex);
}
}
@@ -95,7 +93,7 @@ ACCESSOR_SETTER(WorkerContextOnmessage)
v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singleShot)
{
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, args.Holder());
+ WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
int argumentCount = args.Length();
if (argumentCount < 1)
@@ -106,7 +104,7 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl
int timerId;
if (function->IsString()) {
- WebCore::String stringFunction = ToWebCoreString(function);
+ WebCore::String stringFunction = toWebCoreString(function);
timerId = DOMTimer::install(workerContext, new ScheduledAction(stringFunction, workerContext->url()), timeout, singleShot);
} else if (function->IsFunction()) {
size_t paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
@@ -129,7 +127,29 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl
CALLBACK_FUNC_DECL(WorkerContextImportScripts)
{
INC_STATS(L"DOM.WorkerContext.importScripts()");
- notImplemented();
+ if (!args.Length())
+ return v8::Undefined();
+
+ String callerURL = V8Proxy::sourceName();
+ int callerLine = V8Proxy::sourceLineNumber() + 1;
+
+ Vector<String> urls;
+ for (int i = 0; i < args.Length(); i++) {
+ v8::TryCatch tryCatch;
+ v8::Handle<v8::String> scriptUrl = args[i]->ToString();
+ if (tryCatch.HasCaught() || scriptUrl.IsEmpty())
+ return v8::Undefined();
+ urls.append(toWebCoreString(scriptUrl));
+ }
+
+ WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
+
+ ExceptionCode ec = 0;
+ workerContext->importScripts(urls, callerURL, callerLine, ec);
+
+ if (ec)
+ return throwError(ec);
+
return v8::Undefined();
}
@@ -139,7 +159,8 @@ CALLBACK_FUNC_DECL(WorkerContextSetTimeout)
return SetTimeoutOrInterval(args, true);
}
-CALLBACK_FUNC_DECL(WorkerContextSetInterval) {
+CALLBACK_FUNC_DECL(WorkerContextSetInterval)
+{
INC_STATS(L"DOM.WorkerContext.setInterval()");
return SetTimeoutOrInterval(args, false);
}
@@ -147,7 +168,7 @@ CALLBACK_FUNC_DECL(WorkerContextSetInterval) {
CALLBACK_FUNC_DECL(WorkerContextAddEventListener)
{
INC_STATS(L"DOM.WorkerContext.addEventListener()");
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, args.Holder());
+ WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, false);
@@ -164,7 +185,7 @@ CALLBACK_FUNC_DECL(WorkerContextAddEventListener)
CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener)
{
INC_STATS(L"DOM.WorkerContext.removeEventListener()");
- WorkerContext* workerContext = V8Proxy::ToNativeObject<WorkerContext>(V8ClassIndex::WORKERCONTEXT, args.Holder());
+ WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
RefPtr<V8EventListener> listener = proxy->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, true);
diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
index 3edaa8e..32450b8 100755
--- a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
@@ -50,23 +50,17 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
{
INC_STATS(L"DOM.Worker.Constructor");
- if (!WorkerContextExecutionProxy::isWebWorkersEnabled()) {
- return throwError("Worker is not enabled.", V8Proxy::SYNTAX_ERROR);
- }
-
- if (!args.IsConstructCall()) {
+ if (!args.IsConstructCall())
return throwError("DOM object constructor cannot be called as a function.");
- }
- if (args.Length() == 0) {
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
- }
+ if (!args.Length())
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
v8::TryCatch tryCatch;
v8::Handle<v8::String> scriptUrl = args[0]->ToString();
- if (tryCatch.HasCaught()) {
+ if (tryCatch.HasCaught())
return throwError(tryCatch.Exception());
- }
+
if (scriptUrl.IsEmpty())
return v8::Undefined();
@@ -76,38 +70,42 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
if (proxy)
context = proxy->workerContext();
else {
- Frame* frame = V8Proxy::retrieveFrame();
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
if (!frame)
return v8::Undefined();
context = frame->document();
}
// Create the worker object.
- // Note: it's OK to let this RefPtr go out of scope because we also call SetDOMWrapper(), which effectively holds a reference to obj.
+ // Note: it's OK to let this RefPtr go out of scope because we also call setDOMWrapper(), which effectively holds a reference to obj.
ExceptionCode ec = 0;
RefPtr<Worker> obj = Worker::create(toWebCoreString(scriptUrl), context, ec);
+ if (ec)
+ return throwError(ec);
// Setup the standard wrapper object internal fields.
v8::Handle<v8::Object> wrapperObject = args.Holder();
- V8Proxy::SetDOMWrapper(wrapperObject, V8ClassIndex::WORKER, obj.get());
+ V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::WORKER, obj.get());
obj->ref();
- V8Proxy::SetJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
+ V8DOMWrapper::setJSWrapperForActiveDOMObject(obj.get(), v8::Persistent<v8::Object>::New(wrapperObject));
return wrapperObject;
}
-PassRefPtr<EventListener> getEventListener(Worker* worker, v8::Local<v8::Value> value, bool findOnly)
+PassRefPtr<EventListener> getEventListener(Worker* worker, v8::Local<v8::Value> value, bool isAttribute, bool findOnly)
{
if (worker->scriptExecutionContext()->isWorkerContext()) {
WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
ASSERT(workerContextProxy);
- return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly);
+ return workerContextProxy->findOrCreateObjectEventListener(value, isAttribute, findOnly);
}
V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext());
- if (proxy)
- return findOnly ? proxy->FindObjectEventListener(value, false) : proxy->FindOrCreateObjectEventListener(value, false);
+ if (proxy) {
+ V8EventListenerList* list = proxy->objectListeners();
+ return findOnly ? list->findWrapper(value, isAttribute) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, isAttribute);
+ }
return 0;
}
@@ -115,7 +113,7 @@ PassRefPtr<EventListener> getEventListener(Worker* worker, v8::Local<v8::Value>
ACCESSOR_GETTER(WorkerOnmessage)
{
INC_STATS(L"DOM.Worker.onmessage._get");
- Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
+ Worker* worker = V8DOMWrapper::convertToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
if (worker->onmessage()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onmessage());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -127,7 +125,7 @@ ACCESSOR_GETTER(WorkerOnmessage)
ACCESSOR_SETTER(WorkerOnmessage)
{
INC_STATS(L"DOM.Worker.onmessage._set");
- Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
+ Worker* worker = V8DOMWrapper::convertToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onmessage());
if (value->IsNull()) {
if (oldListener) {
@@ -138,7 +136,7 @@ ACCESSOR_SETTER(WorkerOnmessage)
// Clear the listener.
worker->setOnmessage(0);
} else {
- RefPtr<EventListener> listener = getEventListener(worker, value, false);
+ RefPtr<EventListener> listener = getEventListener(worker, value, true, false);
if (listener) {
if (oldListener) {
v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
@@ -151,78 +149,6 @@ ACCESSOR_SETTER(WorkerOnmessage)
}
}
-ACCESSOR_GETTER(WorkerOnerror)
-{
- INC_STATS(L"DOM.Worker.onerror._get");
- Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
- if (worker->onerror()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(worker->onerror());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- return v8Listener;
- }
- return v8::Undefined();
-}
-
-ACCESSOR_SETTER(WorkerOnerror)
-{
- INC_STATS(L"DOM.Worker.onerror._set");
- Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
- V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onerror());
- if (value->IsNull()) {
- if (oldListener) {
- v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
- removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex);
- }
-
- // Clear the listener.
- worker->setOnerror(0);
- } else {
- RefPtr<EventListener> listener = getEventListener(worker, value, false);
- if (listener) {
- if (oldListener) {
- v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
- removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex);
- }
-
- worker->setOnerror(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kWorkerRequestCacheIndex);
- }
- }
-}
-
-CALLBACK_FUNC_DECL(WorkerAddEventListener)
-{
- INC_STATS(L"DOM.Worker.addEventListener()");
- Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, args.Holder());
-
- RefPtr<EventListener> listener = getEventListener(worker, args[1], false);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- worker->addEventListener(type, listener, useCapture);
-
- createHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerRequestCacheIndex);
- }
- return v8::Undefined();
-}
-
-CALLBACK_FUNC_DECL(WorkerRemoveEventListener)
-{
- INC_STATS(L"DOM.Worker.removeEventListener()");
- Worker* worker = V8Proxy::ToNativeObject<Worker>(V8ClassIndex::WORKER, args.Holder());
-
- RefPtr<EventListener> listener = getEventListener(worker, args[1], true);
- if (listener) {
- String type = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
- worker->removeEventListener(type, listener.get(), useCapture);
-
- removeHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerRequestCacheIndex);
- }
-
- return v8::Undefined();
-}
-
} // namespace WebCore
#endif // ENABLE(WORKERS)
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
index c913c08..02ce8e2 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
@@ -46,7 +46,7 @@ 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);
+ return throwError("DOM object constructor cannot be called as a function.", V8Proxy::TypeError);
// Expect no parameters.
// Allocate a XMLHttpRequest object as its internal field.
@@ -55,15 +55,21 @@ CALLBACK_FUNC_DECL(XMLHttpRequestConstructor)
WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
if (proxy)
context = proxy->workerContext();
- else
+ else {
+#endif
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return throwError("XMLHttpRequest constructor's associated frame is not available", V8Proxy::ReferenceError);
+ context = frame->document();
+#if ENABLE(WORKERS)
+ }
#endif
- context = V8Proxy::retrieveFrame()->document();
RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
- V8Proxy::SetDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());
+ V8DOMWrapper::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()));
+ V8DOMWrapper::setJSWrapperForActiveDOMObject(xmlHttpRequest.get(), v8::Persistent<v8::Object>::New(args.Holder()));
return args.Holder();
}
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index cb80a4f..7204a61 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -44,7 +44,7 @@
namespace WebCore {
-PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::Local<v8::Value> value, bool findOnly)
+static PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::Local<v8::Value> value, bool findOnly)
{
#if ENABLE(WORKERS)
WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
@@ -53,8 +53,10 @@ PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::L
#endif
V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (proxy)
- return findOnly ? proxy->FindObjectEventListener(value, false) : proxy->FindOrCreateObjectEventListener(value, false);
+ if (proxy) {
+ V8EventListenerList* list = proxy->objectListeners();
+ return findOnly ? list->findWrapper(value, false) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
+ }
return PassRefPtr<EventListener>();
}
@@ -62,7 +64,7 @@ PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::L
ACCESSOR_GETTER(XMLHttpRequestOnabort)
{
INC_STATS("DOM.XMLHttpRequest.onabort._get");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (xmlHttpRequest->onabort()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -74,7 +76,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnabort)
ACCESSOR_SETTER(XMLHttpRequestOnabort)
{
INC_STATS("DOM.XMLHttpRequest.onabort._set");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequest->onabort()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
@@ -96,7 +98,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnabort)
ACCESSOR_GETTER(XMLHttpRequestOnerror)
{
INC_STATS("DOM.XMLHttpRequest.onerror._get");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (xmlHttpRequest->onerror()) {
RefPtr<V8ObjectEventListener> listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -108,7 +110,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnerror)
ACCESSOR_SETTER(XMLHttpRequestOnerror)
{
INC_STATS("DOM.XMLHttpRequest.onerror._set");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequest->onerror()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
@@ -130,7 +132,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnerror)
ACCESSOR_GETTER(XMLHttpRequestOnload)
{
INC_STATS("DOM.XMLHttpRequest.onload._get");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (xmlHttpRequest->onload()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -142,7 +144,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnload)
ACCESSOR_SETTER(XMLHttpRequestOnload)
{
INC_STATS("DOM.XMLHttpRequest.onload._set");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequest->onload()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
@@ -164,7 +166,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnload)
ACCESSOR_GETTER(XMLHttpRequestOnloadstart)
{
INC_STATS("DOM.XMLHttpRequest.onloadstart._get");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (xmlHttpRequest->onloadstart()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -176,7 +178,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnloadstart)
ACCESSOR_SETTER(XMLHttpRequestOnloadstart)
{
INC_STATS("DOM.XMLHttpRequest.onloadstart._set");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequest->onloadstart()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
@@ -198,7 +200,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnloadstart)
ACCESSOR_GETTER(XMLHttpRequestOnprogress)
{
INC_STATS("DOM.XMLHttpRequest.onprogress._get");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (xmlHttpRequest->onprogress()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -210,7 +212,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnprogress)
ACCESSOR_SETTER(XMLHttpRequestOnprogress)
{
INC_STATS("DOM.XMLHttpRequest.onprogress._set");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequest->onprogress()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
@@ -232,7 +234,7 @@ ACCESSOR_SETTER(XMLHttpRequestOnprogress)
ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange)
{
INC_STATS("DOM.XMLHttpRequest.onreadystatechange._get");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (xmlHttpRequest->onreadystatechange()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -244,7 +246,7 @@ ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange)
ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange)
{
INC_STATS("DOM.XMLHttpRequest.onreadystatechange._set");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequest->onreadystatechange()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
@@ -268,14 +270,14 @@ 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());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<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());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], false);
if (listener) {
@@ -291,7 +293,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener)
CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener)
{
INC_STATS("DOM.XMLHttpRequest.removeEventListener()");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], true);
if (listener) {
@@ -315,9 +317,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestOpen)
// open(method, url, async, user, passwd)
if (args.Length() < 2)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
String method = toWebCoreString(args[0]);
String urlstring = toWebCoreString(args[1]);
@@ -345,10 +347,10 @@ CALLBACK_FUNC_DECL(XMLHttpRequestOpen)
ExceptionCode ec = 0;
String user, passwd;
if (args.Length() >= 4 && !args[3]->IsUndefined()) {
- user = valueToStringWithNullCheck(args[3]);
+ user = toWebCoreStringWithNullCheck(args[3]);
if (args.Length() >= 5 && !args[4]->IsUndefined()) {
- passwd = valueToStringWithNullCheck(args[4]);
+ passwd = toWebCoreStringWithNullCheck(args[4]);
xmlHttpRequest->open(method, url, async, user, passwd, ec);
} else
xmlHttpRequest->open(method, url, async, user, ec);
@@ -370,7 +372,7 @@ static bool IsDocumentType(v8::Handle<v8::Value> value)
CALLBACK_FUNC_DECL(XMLHttpRequestSend)
{
INC_STATS("DOM.XMLHttpRequest.send()");
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
ExceptionCode ec = 0;
if (args.Length() < 1)
@@ -380,11 +382,11 @@ CALLBACK_FUNC_DECL(XMLHttpRequestSend)
// 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);
+ Document* document = V8DOMWrapper::convertDOMWrapperToNode<Document>(object);
ASSERT(document);
xmlHttpRequest->send(document, ec);
} else
- xmlHttpRequest->send(valueToStringWithNullCheck(arg), ec);
+ xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec);
}
if (ec)
@@ -396,9 +398,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestSend)
CALLBACK_FUNC_DECL(XMLHttpRequestSetRequestHeader) {
INC_STATS("DOM.XMLHttpRequest.setRequestHeader()");
if (args.Length() < 2)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
ExceptionCode ec = 0;
String header = toWebCoreString(args[0]);
String value = toWebCoreString(args[1]);
@@ -412,9 +414,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestGetResponseHeader)
{
INC_STATS("DOM.XMLHttpRequest.getResponseHeader()");
if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
ExceptionCode ec = 0;
String header = toWebCoreString(args[0]);
String result = xmlHttpRequest->getResponseHeader(header, ec);
@@ -427,9 +429,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestOverrideMimeType)
{
INC_STATS("DOM.XMLHttpRequest.overrideMimeType()");
if (args.Length() < 1)
- return throwError("Not enough arguments", V8Proxy::SYNTAX_ERROR);
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
- XMLHttpRequest* xmlHttpRequest = V8Proxy::ToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
+ XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
String value = toWebCoreString(args[0]);
xmlHttpRequest->overrideMimeType(value);
return v8::Undefined();
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
index 7afa82c..bbc69dd 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
@@ -46,7 +46,7 @@ namespace WebCore {
ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)
{
INC_STATS("DOM.XMLHttpRequestUpload.onabort._get");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (xmlHttpRequestUpload->onabort()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -58,7 +58,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)
ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
{
INC_STATS("DOM.XMLHttpRequestUpload.onabort._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequestUpload->onabort()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
@@ -74,7 +74,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
if (!proxy)
return;
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
if (listener) {
xmlHttpRequestUpload->setOnabort(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
@@ -85,7 +85,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)
{
INC_STATS("DOM.XMLHttpRequestUpload.onerror._get");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (xmlHttpRequestUpload->onerror()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -97,7 +97,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)
ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
{
INC_STATS("DOM.XMLHttpRequestUpload.onerror._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequestUpload->onerror()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
@@ -113,7 +113,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
if (!proxy)
return;
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
if (listener) {
xmlHttpRequestUpload->setOnerror(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
@@ -124,7 +124,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
ACCESSOR_GETTER(XMLHttpRequestUploadOnload)
{
INC_STATS("DOM.XMLHttpRequestUpload.onload._get");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (xmlHttpRequestUpload->onload()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -136,7 +136,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnload)
ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
{
INC_STATS("DOM.XMLHttpRequestUpload.onload._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequestUpload->onload()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
@@ -152,7 +152,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
if (!proxy)
return;
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
if (listener) {
xmlHttpRequestUpload->setOnload(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
@@ -163,7 +163,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)
{
INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._get");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (xmlHttpRequestUpload->onloadstart()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -175,7 +175,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)
ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
{
INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequestUpload->onloadstart()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
@@ -191,7 +191,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
if (!proxy)
return;
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
if (listener) {
xmlHttpRequestUpload->setOnloadstart(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
@@ -202,7 +202,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)
{
INC_STATS("DOM.XMLHttpRequestUpload.onprogress._get");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (xmlHttpRequestUpload->onprogress()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
v8::Local<v8::Object> v8Listener = listener->getListenerObject();
@@ -214,7 +214,7 @@ ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)
ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
{
INC_STATS("DOM.XMLHttpRequestUpload.onprogress._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
if (value->IsNull()) {
if (xmlHttpRequestUpload->onprogress()) {
V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
@@ -230,7 +230,7 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
if (!proxy)
return;
- RefPtr<EventListener> listener = proxy->FindOrCreateObjectEventListener(value, false);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
if (listener) {
xmlHttpRequestUpload->setOnprogress(listener);
createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
@@ -241,14 +241,14 @@ ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)
{
INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<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);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), args[1], false);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -262,14 +262,14 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)
CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener)
{
INC_STATS("DOM.XMLHttpRequestUpload.removeEventListener()");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8Proxy::ToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, args.Holder());
+ XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<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);
+ RefPtr<EventListener> listener = proxy->objectListeners()->findWrapper(args[1], false);
if (listener) {
String type = toWebCoreString(args[0]);
diff --git a/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp
index 7b20293..dd1c3ad 100644
--- a/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLSerializerConstructor.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(XMLSerializerConstructor)
{
INC_STATS("DOM.XMLSerializer.Constructor");
- return V8Proxy::ConstructDOMObject<V8ClassIndex::XMLSERIALIZER, XMLSerializer>(args);
+ return V8Proxy::constructDOMObject<V8ClassIndex::XMLSERIALIZER, XMLSerializer>(args);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp b/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp
index 84d75db..69a8635 100644
--- a/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XPathEvaluatorConstructor.cpp
@@ -39,7 +39,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(XPathEvaluatorConstructor)
{
INC_STATS("DOM.XPathEvaluator.Constructor");
- return V8Proxy::ConstructDOMObject<V8ClassIndex::XPATHEVALUATOR, XPathEvaluator>(args);
+ 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
index d470f84..1ad7d4a 100644
--- a/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XSLTProcessorCustom.cpp
@@ -48,7 +48,7 @@ namespace WebCore {
CALLBACK_FUNC_DECL(XSLTProcessorConstructor)
{
INC_STATS("DOM.XSLTProcessor.Constructor");
- return V8Proxy::ConstructDOMObject<V8ClassIndex::XSLTPROCESSOR, XSLTProcessor>(args);
+ return V8Proxy::constructDOMObject<V8ClassIndex::XSLTPROCESSOR, XSLTProcessor>(args);
}
@@ -58,9 +58,9 @@ CALLBACK_FUNC_DECL(XSLTProcessorImportStylesheet)
if (!V8Node::HasInstance(args[0]))
return v8::Undefined();
- XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+ XSLTProcessor* imp = V8DOMWrapper::convertToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
- Node* node = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
imp->importStylesheet(node);
return v8::Undefined();
}
@@ -72,12 +72,12 @@ CALLBACK_FUNC_DECL(XSLTProcessorTransformToFragment)
if (!V8Node::HasInstance(args[0]) || !V8Document::HasInstance(args[1]))
return v8::Undefined();
- XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+ XSLTProcessor* imp = V8DOMWrapper::convertToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
- Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]);
- Document* owner = V8Proxy::DOMWrapperToNode<Document>(args[1]);
+ Node* source = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
+ Document* owner = V8DOMWrapper::convertDOMWrapperToNode<Document>(v8::Handle<v8::Object>::Cast(args[1]));
RefPtr<DocumentFragment> result = imp->transformToFragment(source, owner);
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
@@ -88,9 +88,9 @@ CALLBACK_FUNC_DECL(XSLTProcessorTransformToDocument)
if (!V8Node::HasInstance(args[0]))
return v8::Undefined();
- XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+ XSLTProcessor* imp = V8DOMWrapper::convertToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
- Node* source = V8Proxy::DOMWrapperToNode<Node>(args[0]);
+ Node* source = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
if (!source)
return v8::Undefined();
@@ -98,7 +98,7 @@ CALLBACK_FUNC_DECL(XSLTProcessorTransformToDocument)
if (!result)
return v8::Undefined();
- return V8Proxy::NodeToV8Object(result.get());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
}
@@ -108,7 +108,7 @@ CALLBACK_FUNC_DECL(XSLTProcessorSetParameter)
if (isUndefinedOrNull(args[1]) || isUndefinedOrNull(args[2]))
return v8::Undefined();
- XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+ XSLTProcessor* imp = V8DOMWrapper::convertToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
String namespaceURI = toWebCoreString(args[0]);
String localName = toWebCoreString(args[1]);
@@ -125,7 +125,7 @@ CALLBACK_FUNC_DECL(XSLTProcessorGetParameter)
if (isUndefinedOrNull(args[1]))
return v8::Undefined();
- XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+ XSLTProcessor* imp = V8DOMWrapper::convertToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
String namespaceURI = toWebCoreString(args[0]);
String localName = toWebCoreString(args[1]);
@@ -142,7 +142,7 @@ CALLBACK_FUNC_DECL(XSLTProcessorRemoveParameter)
if (isUndefinedOrNull(args[1]))
return v8::Undefined();
- XSLTProcessor* imp = V8Proxy::ToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
+ XSLTProcessor* imp = V8DOMWrapper::convertToNativeObject<XSLTProcessor>(V8ClassIndex::XSLTPROCESSOR, args.Holder());
String namespaceURI = toWebCoreString(args[0]);
String localName = toWebCoreString(args[1]);
diff --git a/WebCore/bindings/v8/npruntime.cpp b/WebCore/bindings/v8/npruntime.cpp
new file mode 100644
index 0000000..64a1927
--- /dev/null
+++ b/WebCore/bindings/v8/npruntime.cpp
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
+ * 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this 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 "NPV8Object.h"
+#include "npruntime_impl.h"
+#include "npruntime_priv.h"
+#include "V8NPObject.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/Assertions.h>
+
+// FIXME: Consider removing locks if we're singlethreaded already.
+// The static initializer here should work okay, but we want to avoid
+// static initialization in general.
+
+namespace {
+
+// We use StringKey here as the key-type to avoid a string copy to
+// construct the map key and for faster comparisons than strcmp.
+class StringKey {
+public:
+ explicit StringKey(const char* str) : m_string(str), m_length(strlen(str)) { }
+ StringKey() : m_string(0), m_length(0) { }
+ explicit StringKey(WTF::HashTableDeletedValueType) : m_string(hashTableDeletedValue()), m_length(0) { }
+
+ StringKey& operator=(const StringKey& other)
+ {
+ this->m_string = other.m_string;
+ this->m_length = other.m_length;
+ return *this;
+ }
+
+ bool isHashTableDeletedValue() const
+ {
+ return m_string == hashTableDeletedValue();
+ }
+
+ const char* m_string;
+ size_t m_length;
+
+private:
+ const char* hashTableDeletedValue() const
+ {
+ return reinterpret_cast<const char*>(-1);
+ }
+};
+
+inline bool operator==(const StringKey& x, const StringKey& y)
+{
+ if (x.m_length != y.m_length)
+ return false;
+ if (x.m_string == y.m_string)
+ return true;
+
+ ASSERT(!x.isHashTableDeletedValue() && !y.isHashTableDeletedValue());
+ return !memcmp(x.m_string, y.m_string, y.m_length);
+}
+
+// Implement WTF::DefaultHash<StringKey>::Hash interface.
+struct StringKeyHash {
+ static unsigned hash(const StringKey& key)
+ {
+ // Compute string hash.
+ unsigned hash = 0;
+ size_t len = key.m_length;
+ const char* str = key.m_string;
+ for (size_t i = 0; i < len; i++) {
+ char c = str[i];
+ hash += c;
+ hash += (hash << 10);
+ hash ^= (hash >> 6);
+ }
+ hash += (hash << 3);
+ hash ^= (hash >> 11);
+ hash += (hash << 15);
+ if (hash == 0)
+ hash = 27;
+ return hash;
+ }
+
+ static bool equal(const StringKey& x, const StringKey& y)
+ {
+ return x == y;
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} // namespace
+
+// Implement HashTraits<StringKey>
+struct StringKeyHashTraits : WTF::GenericHashTraits<StringKey> {
+ static void constructDeletedValue(StringKey& slot)
+ {
+ new (&slot) StringKey(WTF::HashTableDeletedValue);
+ }
+
+ static bool isDeletedValue(const StringKey& value)
+ {
+ return value.isHashTableDeletedValue();
+ }
+};
+
+typedef WTF::HashMap<StringKey, PrivateIdentifier*, StringKeyHash, StringKeyHashTraits> StringIdentifierMap;
+
+static StringIdentifierMap* getStringIdentifierMap()
+{
+ static StringIdentifierMap* stringIdentifierMap = 0;
+ if (!stringIdentifierMap)
+ stringIdentifierMap = new StringIdentifierMap();
+ return stringIdentifierMap;
+}
+
+typedef WTF::HashMap<int, PrivateIdentifier*> IntIdentifierMap;
+
+static IntIdentifierMap* getIntIdentifierMap()
+{
+ static IntIdentifierMap* intIdentifierMap = 0;
+ if (!intIdentifierMap)
+ intIdentifierMap = new IntIdentifierMap();
+ return intIdentifierMap;
+}
+
+extern "C" {
+
+NPIdentifier _NPN_GetStringIdentifier(const NPUTF8* name)
+{
+ ASSERT(name);
+
+ if (name) {
+
+ StringKey key(name);
+ StringIdentifierMap* identMap = getStringIdentifierMap();
+ StringIdentifierMap::iterator iter = identMap->find(key);
+ if (iter != identMap->end())
+ return static_cast<NPIdentifier>(iter->second);
+
+ size_t nameLen = key.m_length;
+
+ // We never release identifiers, so this dictionary will grow.
+ PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(malloc(sizeof(PrivateIdentifier) + nameLen + 1));
+ char* nameStorage = reinterpret_cast<char*>(identifier + 1);
+ memcpy(nameStorage, name, nameLen + 1);
+ identifier->isString = true;
+ identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage);
+ key.m_string = nameStorage;
+ identMap->set(key, identifier);
+ return (NPIdentifier)identifier;
+ }
+
+ return 0;
+}
+
+void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers)
+{
+ ASSERT(names);
+ ASSERT(identifiers);
+
+ if (names && identifiers) {
+ for (int i = 0; i < nameCount; i++)
+ identifiers[i] = _NPN_GetStringIdentifier(names[i]);
+ }
+}
+
+NPIdentifier _NPN_GetIntIdentifier(int32_t intId)
+{
+ // Special case for -1 and 0, both cannot be used as key in HashMap.
+ if (!intId || intId == -1) {
+ static PrivateIdentifier* minusOneOrZeroIds[2];
+ PrivateIdentifier* id = minusOneOrZeroIds[intId + 1];
+ if (!id) {
+ id = reinterpret_cast<PrivateIdentifier*>(malloc(sizeof(PrivateIdentifier)));
+ id->isString = false;
+ id->value.number = intId;
+ minusOneOrZeroIds[intId + 1] = id;
+ }
+ return (NPIdentifier) id;
+ }
+
+ IntIdentifierMap* identMap = getIntIdentifierMap();
+ IntIdentifierMap::iterator iter = identMap->find(intId);
+ if (iter != identMap->end())
+ return static_cast<NPIdentifier>(iter->second);
+
+ // We never release identifiers, so this dictionary will grow.
+ PrivateIdentifier* identifier = reinterpret_cast<PrivateIdentifier*>(malloc(sizeof(PrivateIdentifier)));
+ identifier->isString = false;
+ identifier->value.number = intId;
+ identMap->set(intId, identifier);
+ return (NPIdentifier)identifier;
+}
+
+bool _NPN_IdentifierIsString(NPIdentifier identifier)
+{
+ PrivateIdentifier* privateIdentifier = reinterpret_cast<PrivateIdentifier*>(identifier);
+ return privateIdentifier->isString;
+}
+
+NPUTF8 *_NPN_UTF8FromIdentifier(NPIdentifier identifier)
+{
+ PrivateIdentifier* privateIdentifier = reinterpret_cast<PrivateIdentifier*>(identifier);
+ if (!privateIdentifier->isString || !privateIdentifier->value.string)
+ return 0;
+
+ return (NPUTF8*) strdup(privateIdentifier->value.string);
+}
+
+int32_t _NPN_IntFromIdentifier(NPIdentifier identifier)
+{
+ PrivateIdentifier* privateIdentifier = reinterpret_cast<PrivateIdentifier*>(identifier);
+ if (privateIdentifier->isString)
+ return 0;
+ return privateIdentifier->value.number;
+}
+
+void _NPN_ReleaseVariantValue(NPVariant* variant)
+{
+ ASSERT(variant);
+
+ if (variant->type == NPVariantType_Object) {
+ _NPN_ReleaseObject(variant->value.objectValue);
+ variant->value.objectValue = 0;
+ } else if (variant->type == NPVariantType_String) {
+ free((void*)variant->value.stringValue.UTF8Characters);
+ variant->value.stringValue.UTF8Characters = 0;
+ variant->value.stringValue.UTF8Length = 0;
+ }
+
+ variant->type = NPVariantType_Void;
+}
+
+NPObject *_NPN_CreateObject(NPP npp, NPClass* npClass)
+{
+ ASSERT(npClass);
+
+ if (npClass) {
+ NPObject* npObject;
+ if (npClass->allocate != 0)
+ npObject = npClass->allocate(npp, npClass);
+ else
+ npObject = reinterpret_cast<NPObject*>(malloc(sizeof(NPObject)));
+
+ npObject->_class = npClass;
+ npObject->referenceCount = 1;
+ return npObject;
+ }
+
+ return 0;
+}
+
+NPObject* _NPN_RetainObject(NPObject* npObject)
+{
+ ASSERT(npObject);
+ ASSERT(npObject->referenceCount > 0);
+
+ if (npObject)
+ npObject->referenceCount++;
+
+ return npObject;
+}
+
+// _NPN_DeallocateObject actually deletes the object. Technically,
+// callers should use _NPN_ReleaseObject. Webkit exposes this function
+// to kill objects which plugins may not have properly released.
+void _NPN_DeallocateObject(NPObject* npObject)
+{
+ ASSERT(npObject);
+ ASSERT(npObject->referenceCount >= 0);
+
+ if (npObject) {
+ // NPObjects that remain in pure C++ may never have wrappers.
+ // Hence, if it's not already alive, don't unregister it.
+ // If it is alive, unregister it as the *last* thing we do
+ // so that it can do as much cleanup as possible on its own.
+ if (_NPN_IsAlive(npObject))
+ _NPN_UnregisterObject(npObject);
+
+ npObject->referenceCount = -1;
+ if (npObject->_class->deallocate)
+ npObject->_class->deallocate(npObject);
+ else
+ free(npObject);
+ }
+}
+
+void _NPN_ReleaseObject(NPObject* npObject)
+{
+ ASSERT(npObject);
+ ASSERT(npObject->referenceCount >= 1);
+
+ if (npObject && npObject->referenceCount >= 1) {
+ if (!--npObject->referenceCount)
+ _NPN_DeallocateObject(npObject);
+ }
+}
+
+void _NPN_InitializeVariantWithStringCopy(NPVariant* variant, const NPString* value)
+{
+ variant->type = NPVariantType_String;
+ variant->value.stringValue.UTF8Length = value->UTF8Length;
+ variant->value.stringValue.UTF8Characters = reinterpret_cast<NPUTF8*>(malloc(sizeof(NPUTF8) * value->UTF8Length));
+ memcpy((void*)variant->value.stringValue.UTF8Characters, value->UTF8Characters, sizeof(NPUTF8) * value->UTF8Length);
+}
+
+
+// NPN_Registry
+//
+// The registry is designed for quick lookup of NPObjects.
+// JS needs to be able to quickly lookup a given NPObject to determine
+// if it is alive or not.
+// The browser needs to be able to quickly lookup all NPObjects which are
+// "owned" by an object.
+//
+// The liveObjectMap is a hash table of all live objects to their owner
+// objects. Presence in this table is used primarily to determine if
+// objects are live or not.
+//
+// The rootObjectMap is a hash table of root objects to a set of
+// objects that should be deactivated in sync with the root. A
+// root is defined as a top-level owner object. This is used on
+// Frame teardown to deactivate all objects associated
+// with a particular plugin.
+
+typedef WTF::HashSet<NPObject*> NPObjectSet;
+typedef WTF::HashMap<NPObject*, NPObject*> NPObjectMap;
+typedef WTF::HashMap<NPObject*, NPObjectSet*> NPRootObjectMap;
+
+// A map of live NPObjects with pointers to their Roots.
+NPObjectMap liveObjectMap;
+
+// A map of the root objects and the list of NPObjects
+// associated with that object.
+NPRootObjectMap rootObjectMap;
+
+void _NPN_RegisterObject(NPObject* npObject, NPObject* owner)
+{
+ ASSERT(npObject);
+
+ // Check if already registered.
+ if (liveObjectMap.find(npObject) != liveObjectMap.end())
+ return;
+
+ if (!owner) {
+ // Registering a new owner object.
+ ASSERT(rootObjectMap.find(npObject) == rootObjectMap.end());
+ rootObjectMap.set(npObject, new NPObjectSet());
+ } else {
+ // Always associate this object with it's top-most parent.
+ // Since we always flatten, we only have to look up one level.
+ NPObjectMap::iterator ownerEntry = liveObjectMap.find(owner);
+ NPObject* parent = 0;
+ if (liveObjectMap.end() != ownerEntry)
+ parent = ownerEntry->second;
+
+ if (parent)
+ owner = parent;
+ ASSERT(rootObjectMap.find(npObject) == rootObjectMap.end());
+ if (rootObjectMap.find(owner) != rootObjectMap.end())
+ rootObjectMap.get(owner)->add(npObject);
+ }
+
+ ASSERT(liveObjectMap.find(npObject) == liveObjectMap.end());
+ liveObjectMap.set(npObject, owner);
+}
+
+void _NPN_UnregisterObject(NPObject* npObject)
+{
+ ASSERT(npObject);
+ ASSERT(liveObjectMap.find(npObject) != liveObjectMap.end());
+
+ NPObject* owner = 0;
+ if (liveObjectMap.find(npObject) != liveObjectMap.end())
+ owner = liveObjectMap.find(npObject)->second;
+
+ if (!owner) {
+ // Unregistering a owner object; also unregister it's descendants.
+ ASSERT(rootObjectMap.find(npObject) != rootObjectMap.end());
+ NPObjectSet* set = rootObjectMap.get(npObject);
+ while (set->size() > 0) {
+#ifndef NDEBUG
+ int size = set->size();
+#endif
+ NPObject* sub_object = *(set->begin());
+ // The sub-object should not be a owner!
+ ASSERT(rootObjectMap.find(sub_object) == rootObjectMap.end());
+
+ // First, unregister the object.
+ set->remove(sub_object);
+ liveObjectMap.remove(sub_object);
+
+ // Remove the JS references to the object.
+ forgetV8ObjectForNPObject(sub_object);
+
+ ASSERT(set->size() < size);
+ }
+ delete set;
+ rootObjectMap.remove(npObject);
+ } else {
+ NPRootObjectMap::iterator ownerEntry = rootObjectMap.find(owner);
+ if (ownerEntry != rootObjectMap.end()) {
+ NPObjectSet* list = ownerEntry->second;
+ ASSERT(list->find(npObject) != list->end());
+ list->remove(npObject);
+ }
+ }
+
+ liveObjectMap.remove(npObject);
+ forgetV8ObjectForNPObject(npObject);
+}
+
+bool _NPN_IsAlive(NPObject* npObject)
+{
+ return liveObjectMap.find(npObject) != liveObjectMap.end();
+}
+
+} // extern "C"
diff --git a/WebCore/bindings/v8/npruntime_impl.h b/WebCore/bindings/v8/npruntime_impl.h
new file mode 100644
index 0000000..31c0f42
--- /dev/null
+++ b/WebCore/bindings/v8/npruntime_impl.h
@@ -0,0 +1,70 @@
+/*
+ * 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 npruntime_impl_h
+#define npruntime_impl_h
+
+#include "bindings/npruntime.h"
+
+// This file exists to support WebCore, which expects to be able to call upon
+// portions of the NPRuntime implementation.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+NPIdentifier _NPN_GetStringIdentifier(const NPUTF8* name);
+void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier*);
+NPIdentifier _NPN_GetIntIdentifier(int32_t intId);
+bool _NPN_IdentifierIsString(NPIdentifier);
+NPUTF8 *_NPN_UTF8FromIdentifier(NPIdentifier);
+int32_t _NPN_IntFromIdentifier(NPIdentifier);
+void _NPN_ReleaseVariantValue(NPVariant*);
+NPObject *_NPN_CreateObject(NPP, NPClass*);
+NPObject* _NPN_RetainObject(NPObject*);
+void _NPN_ReleaseObject(NPObject*);
+bool _NPN_Invoke(NPP, NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+bool _NPN_InvokeDefault(NPP, NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+bool _NPN_Evaluate(NPP, NPObject*, NPString* npScript, NPVariant* result);
+bool _NPN_EvaluateHelper(NPP, bool popupsAllowed, NPObject*, NPString* npScript, NPVariant* result);
+bool _NPN_GetProperty(NPP, NPObject*, NPIdentifier propertyName, NPVariant* result);
+bool _NPN_SetProperty(NPP, NPObject*, NPIdentifier propertyName, const NPVariant* value);
+bool _NPN_RemoveProperty(NPP, NPObject*, NPIdentifier propertyName);
+bool _NPN_HasProperty(NPP, NPObject*, NPIdentifier propertyName);
+bool _NPN_HasMethod(NPP, NPObject*, NPIdentifier methodName);
+void _NPN_SetException(NPObject*, const NPUTF8 *message);
+bool _NPN_Enumerate(NPP, NPObject*, NPIdentifier**, uint32_t* count);
+bool _NPN_Construct(NPP, NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif
diff --git a/WebCore/bindings/v8/npruntime_internal.h b/WebCore/bindings/v8/npruntime_internal.h
new file mode 100644
index 0000000..75bf2b0
--- /dev/null
+++ b/WebCore/bindings/v8/npruntime_internal.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007 Collabora, Ltd. 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.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This is a internal include header for npapi.h
+ *
+ * Some of the #defines which are in X11 headers conflict with type and enum
+ * names in JavaScriptCore and WebCore
+ * This header #undefs those defines to fix the conflicts
+ * If you need to include npapi.h or npruntime.h when building on X11,
+ * include this file instead of the actual npapi.h or npruntime.h
+ */
+
+#include "npapi.h"
+#include "npruntime.h"
+#include "npfunctions.h"
+
+#ifdef XP_UNIX
+ #include <X11/Xresource.h>
+
+ #undef None
+ #undef Above
+ #undef Below
+ #undef Auto
+ #undef Complex
+ #undef Status
+#endif
diff --git a/WebCore/bindings/v8/npruntime_priv.h b/WebCore/bindings/v8/npruntime_priv.h
new file mode 100644
index 0000000..3887758
--- /dev/null
+++ b/WebCore/bindings/v8/npruntime_priv.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2003, 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 npruntime_priv_h
+#define npruntime_priv_h
+
+#include "third_party/npapi/bindings/npruntime.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ _NPN_InitializeVariantWithStringCopy() will copy string data. The string data
+ will be deallocated by calls to NPReleaseVariantValue().
+*/
+void _NPN_InitializeVariantWithStringCopy(NPVariant*, const NPString*);
+void _NPN_DeallocateObject(NPObject*);
+
+// The following routines allow the browser to aggressively cleanup NPObjects
+// on a per plugin basis. All NPObjects used through the NPRuntime API should
+// be "registered" while they are alive. After an object has been
+// deleted, it is possible for Javascript to have a reference to that object
+// which has not yet been garbage collected. Javascript access to NPObjects
+// will reference this registry to determine if the object is accessible or
+// not.
+
+// Windows introduces an additional complication for objects created by the
+// plugin. Plugins load inside of a DLL. Each DLL has it's own heap. If
+// the browser unloads the plugin DLL, all objects created within the DLL's
+// heap instantly become invalid. Normally, when WebKit drops the reference
+// on the top-level plugin object, it tells the plugin manager that the
+// plugin can be destroyed, which can unload the DLL. So, we must eliminate
+// all pointers to any object ever created by the plugin.
+
+// We generally associate NPObjects with an owner. The owner of an NPObject
+// is an NPObject which, when destroyed, also destroys all objects it owns.
+// For example, if an NPAPI plugin creates 10 sub-NPObjects, all 11 objects
+// (the NPAPI plugin + its 10 sub-objects) should become inaccessible
+// simultaneously.
+
+// The ownership hierarchy is flat, and not a tree. Imagine the following
+// object creation:
+// PluginObject
+// |
+// +-- Creates -----> Object1
+// |
+// +-- Creates -----> Object2
+//
+// PluginObject will be the "owner" for both Object1 and Object2.
+
+// Register an NPObject with the runtime. If the owner is NULL, the
+// object is treated as an owning object. If owner is not NULL,
+// this object will be registered as owned by owner's top-level owner.
+void _NPN_RegisterObject(NPObject*, NPObject* owner);
+
+// Unregister an NPObject with the runtime. If obj is an owning
+// object, this call will also unregister all of the owned objects.
+void _NPN_UnregisterObject(NPObject*);
+
+// Check to see if an object is registered with the runtime.
+// Return true if registered, false otherwise.
+bool _NPN_IsAlive(NPObject*);
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+
+#endif // npruntime_priv_h