summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/v8
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/v8')
-rw-r--r--WebCore/bindings/v8/ChildThreadDOMData.h1
-rw-r--r--WebCore/bindings/v8/DOMData.cpp14
-rw-r--r--WebCore/bindings/v8/DOMData.h18
-rw-r--r--WebCore/bindings/v8/DOMObjectsInclude.h81
-rw-r--r--WebCore/bindings/v8/DateExtension.cpp123
-rw-r--r--WebCore/bindings/v8/DateExtension.h55
-rw-r--r--WebCore/bindings/v8/DerivedSourcesAllInOne.cpp109
-rw-r--r--WebCore/bindings/v8/MainThreadDOMData.cpp20
-rw-r--r--WebCore/bindings/v8/MainThreadDOMData.h10
-rw-r--r--WebCore/bindings/v8/NPV8Object.cpp8
-rw-r--r--WebCore/bindings/v8/OwnHandle.h6
-rw-r--r--WebCore/bindings/v8/RuntimeEnabledFeatures.cpp42
-rw-r--r--WebCore/bindings/v8/RuntimeEnabledFeatures.h67
-rw-r--r--WebCore/bindings/v8/ScheduledAction.cpp11
-rw-r--r--WebCore/bindings/v8/ScheduledAction.h10
-rw-r--r--WebCore/bindings/v8/ScriptCallFrame.cpp2
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.cpp17
-rw-r--r--WebCore/bindings/v8/ScriptCallStack.h6
-rw-r--r--WebCore/bindings/v8/ScriptController.cpp63
-rw-r--r--WebCore/bindings/v8/ScriptController.h55
-rw-r--r--WebCore/bindings/v8/ScriptEventListener.cpp62
-rw-r--r--WebCore/bindings/v8/ScriptEventListener.h3
-rw-r--r--WebCore/bindings/v8/ScriptFunctionCall.cpp28
-rw-r--r--WebCore/bindings/v8/ScriptFunctionCall.h3
-rw-r--r--WebCore/bindings/v8/ScriptObject.cpp39
-rw-r--r--WebCore/bindings/v8/ScriptObject.h7
-rw-r--r--WebCore/bindings/v8/ScriptObjectQuarantine.cpp120
-rw-r--r--WebCore/bindings/v8/ScriptScope.cpp3
-rw-r--r--WebCore/bindings/v8/ScriptSourceCode.h2
-rw-r--r--WebCore/bindings/v8/ScriptState.cpp28
-rw-r--r--WebCore/bindings/v8/ScriptState.h25
-rw-r--r--WebCore/bindings/v8/ScriptString.h25
-rw-r--r--WebCore/bindings/v8/ScriptStringImpl.cpp74
-rw-r--r--WebCore/bindings/v8/ScriptStringImpl.h77
-rw-r--r--WebCore/bindings/v8/ScriptValue.h15
-rw-r--r--WebCore/bindings/v8/SerializedScriptValue.h77
-rw-r--r--WebCore/bindings/v8/SharedPersistent.h (renamed from WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp)70
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.cpp154
-rw-r--r--WebCore/bindings/v8/V8AbstractEventListener.h83
-rw-r--r--WebCore/bindings/v8/V8Binding.cpp316
-rw-r--r--WebCore/bindings/v8/V8Binding.h246
-rw-r--r--WebCore/bindings/v8/V8Collection.h21
-rw-r--r--WebCore/bindings/v8/V8DOMMap.cpp29
-rw-r--r--WebCore/bindings/v8/V8DOMMap.h2
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.cpp402
-rw-r--r--WebCore/bindings/v8/V8DOMWrapper.h87
-rw-r--r--WebCore/bindings/v8/V8EventListenerList.cpp159
-rw-r--r--WebCore/bindings/v8/V8EventListenerList.h111
-rw-r--r--WebCore/bindings/v8/V8GCController.cpp111
-rw-r--r--WebCore/bindings/v8/V8GCController.h6
-rw-r--r--WebCore/bindings/v8/V8HiddenPropertyName.cpp21
-rw-r--r--WebCore/bindings/v8/V8HiddenPropertyName.h12
-rw-r--r--WebCore/bindings/v8/V8Index.cpp94
-rw-r--r--WebCore/bindings/v8/V8Index.h134
-rw-r--r--WebCore/bindings/v8/V8IsolatedWorld.cpp66
-rw-r--r--WebCore/bindings/v8/V8IsolatedWorld.h44
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.cpp259
-rw-r--r--WebCore/bindings/v8/V8LazyEventListener.h32
-rw-r--r--WebCore/bindings/v8/V8NPObject.cpp65
-rw-r--r--WebCore/bindings/v8/V8ObjectEventListener.cpp92
-rw-r--r--WebCore/bindings/v8/V8Proxy.cpp475
-rw-r--r--WebCore/bindings/v8/V8Proxy.h171
-rw-r--r--WebCore/bindings/v8/V8Utilities.cpp79
-rw-r--r--WebCore/bindings/v8/V8Utilities.h26
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.cpp71
-rw-r--r--WebCore/bindings/v8/V8WorkerContextEventListener.h21
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.cpp94
-rw-r--r--WebCore/bindings/v8/WorkerContextExecutionProxy.h7
-rw-r--r--WebCore/bindings/v8/WorldContextHandle.cpp (renamed from WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp)30
-rw-r--r--WebCore/bindings/v8/WorldContextHandle.h (renamed from WebCore/bindings/v8/V8WorkerContextObjectEventListener.h)34
-rw-r--r--WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp61
-rw-r--r--WebCore/bindings/v8/custom/V8ConsoleCustom.cpp (renamed from WebCore/bindings/v8/V8ObjectEventListener.h)43
-rw-r--r--WebCore/bindings/v8/custom/V8CoordinatesCustom.cpp111
-rw-r--r--WebCore/bindings/v8/custom/V8CustomBinding.h230
-rw-r--r--WebCore/bindings/v8/custom/V8CustomEventListener.cpp47
-rw-r--r--WebCore/bindings/v8/custom/V8CustomEventListener.h18
-rw-r--r--WebCore/bindings/v8/custom/V8CustomPositionCallback.cpp40
-rw-r--r--WebCore/bindings/v8/custom/V8CustomPositionCallback.h39
-rw-r--r--WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.cpp40
-rw-r--r--WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.h39
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp1
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp20
-rw-r--r--WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h9
-rw-r--r--WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp62
-rw-r--r--WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp407
-rw-r--r--WebCore/bindings/v8/custom/V8DatabaseCustom.cpp61
-rw-r--r--WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp48
-rw-r--r--WebCore/bindings/v8/custom/V8DocumentCustom.cpp23
-rw-r--r--WebCore/bindings/v8/custom/V8FileListCustom.cpp54
-rw-r--r--WebCore/bindings/v8/custom/V8GeolocationCustom.cpp54
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp140
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp26
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h47
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp15
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp9
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp5
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp5
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp21
-rwxr-xr-x[-rw-r--r--]WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h (renamed from WebCore/bindings/v8/ScriptObjectQuarantine.h)31
-rw-r--r--WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp21
-rwxr-xr-xWebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h47
-rw-r--r--WebCore/bindings/v8/custom/V8HistoryCustom.cpp83
-rw-r--r--WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp163
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp218
-rw-r--r--WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp92
-rw-r--r--WebCore/bindings/v8/custom/V8LocationCustom.cpp20
-rw-r--r--WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp14
-rw-r--r--WebCore/bindings/v8/custom/V8MessageEventCustom.cpp81
-rw-r--r--WebCore/bindings/v8/custom/V8MessagePortCustom.cpp114
-rw-r--r--WebCore/bindings/v8/custom/V8MessagePortCustom.h48
-rw-r--r--WebCore/bindings/v8/custom/V8NodeCustom.cpp64
-rw-r--r--WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp141
-rw-r--r--WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp14
-rw-r--r--WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp16
-rw-r--r--WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp33
-rw-r--r--WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp3
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp84
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLArrayCustom.h220
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp96
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp93
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp96
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp928
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp96
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp96
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp96
-rw-r--r--WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp96
-rwxr-xr-xWebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp23
-rw-r--r--WebCore/bindings/v8/custom/V8WebSocketCustom.cpp160
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerContextCustom.cpp69
-rwxr-xr-xWebCore/bindings/v8/custom/V8WorkerCustom.cpp79
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp19
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp258
-rw-r--r--WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp207
-rw-r--r--WebCore/bindings/v8/npruntime.cpp16
138 files changed, 7235 insertions, 3309 deletions
diff --git a/WebCore/bindings/v8/ChildThreadDOMData.h b/WebCore/bindings/v8/ChildThreadDOMData.h
index ab90e5b..dfb85e8 100644
--- a/WebCore/bindings/v8/ChildThreadDOMData.h
+++ b/WebCore/bindings/v8/ChildThreadDOMData.h
@@ -39,7 +39,6 @@ namespace WebCore {
class ChildThreadDOMData : public DOMData {
public:
ChildThreadDOMData();
- virtual ~ChildThreadDOMData() { }
DOMDataStore& getStore();
diff --git a/WebCore/bindings/v8/DOMData.cpp b/WebCore/bindings/v8/DOMData.cpp
index 07254fe..ec9a938 100644
--- a/WebCore/bindings/v8/DOMData.cpp
+++ b/WebCore/bindings/v8/DOMData.cpp
@@ -33,6 +33,7 @@
#include "ChildThreadDOMData.h"
#include "MainThreadDOMData.h"
+#include "WebGLUniformLocation.h"
namespace WebCore {
@@ -43,22 +44,19 @@ DOMData::DOMData()
{
}
+DOMData::~DOMData()
+{
+}
+
DOMData* DOMData::getCurrent()
{
if (WTF::isMainThread())
- return getCurrentMainThread();
+ return MainThreadDOMData::getCurrent();
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()) {
diff --git a/WebCore/bindings/v8/DOMData.h b/WebCore/bindings/v8/DOMData.h
index 07e14e5..4947e82 100644
--- a/WebCore/bindings/v8/DOMData.h
+++ b/WebCore/bindings/v8/DOMData.h
@@ -45,10 +45,9 @@ namespace WebCore {
class DOMData : public Noncopyable {
public:
DOMData();
- virtual ~DOMData() { }
+ virtual ~DOMData();
static DOMData* getCurrent();
- static DOMData* getCurrentMainThread(); // Caller must be on the main thread.
virtual DOMDataStore& getStore() = 0;
template<typename T>
@@ -85,20 +84,10 @@ namespace WebCore {
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());
+ ASSERT(WTF::isMainThread());
DOMDataList& list = DOMDataStore::allStores();
for (size_t i = 0; i < list.size(); ++i) {
DOMDataStore* store = list[i];
@@ -109,7 +98,8 @@ namespace WebCore {
if (*wrapper == *v8Object) {
// Clear the JS reference.
domMap->forgetOnly(domObject);
- store->domData()->ensureDeref(V8DOMWrapper::domWrapperType(v8Object), domObject);
+ ASSERT(store->domData()->owningThread() == WTF::currentThread());
+ store->domData()->derefObject(V8DOMWrapper::domWrapperType(v8Object), domObject);
}
}
}
diff --git a/WebCore/bindings/v8/DOMObjectsInclude.h b/WebCore/bindings/v8/DOMObjectsInclude.h
index 6f36f3b..6ed14be 100644
--- a/WebCore/bindings/v8/DOMObjectsInclude.h
+++ b/WebCore/bindings/v8/DOMObjectsInclude.h
@@ -31,17 +31,38 @@
#ifndef DOMObjectsInclude_h
#define DOMObjectsInclude_h
-#include "AbstractWorker.h"
+#include "Attr.h"
#include "BarInfo.h"
+#include "BeforeLoadEvent.h"
+#include "WebGLActiveInfo.h"
+#include "WebGLArray.h"
+#include "WebGLArrayBuffer.h"
+#include "WebGLBuffer.h"
+#include "WebGLByteArray.h"
+#include "WebGLFloatArray.h"
+#include "WebGLFramebuffer.h"
#include "CanvasGradient.h"
+#include "WebGLIntArray.h"
+#include "CanvasObject.h"
#include "CanvasPattern.h"
#include "CanvasPixelArray.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
+#include "CanvasRenderingContext.h"
#include "CanvasRenderingContext2D.h"
+#include "WebGLRenderingContext.h"
+#include "WebGLShader.h"
+#include "WebGLShortArray.h"
+#include "WebGLUnsignedByteArray.h"
+#include "WebGLUnsignedIntArray.h"
+#include "WebGLUnsignedShortArray.h"
#include "CanvasStyle.h"
+#include "WebGLTexture.h"
#include "CharacterData.h"
#include "ClientRect.h"
#include "ClientRectList.h"
#include "Clipboard.h"
+#include "CompositionEvent.h"
#include "Console.h"
#include "Counter.h"
#include "CSSCharsetRule.h"
@@ -57,7 +78,6 @@
#include "CSSValueList.h"
#include "CSSVariablesDeclaration.h"
#include "CSSVariablesRule.h"
-#include "Database.h"
#include "DocumentType.h"
#include "DocumentFragment.h"
#include "DOMCoreException.h"
@@ -86,7 +106,6 @@
#include "HTMLSelectElement.h"
#include "HTMLOptionsCollection.h"
#include "ImageData.h"
-#include "InspectorBackend.h"
#include "KeyboardEvent.h"
#include "Location.h"
#include "Media.h"
@@ -106,6 +125,7 @@
#include "NodeIterator.h"
#include "OverflowEvent.h"
#include "Page.h"
+#include "PageTransitionEvent.h"
#include "Plugin.h"
#include "PluginArray.h"
#include "ProcessingInstruction.h"
@@ -118,11 +138,6 @@
#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 "TextEvent.h"
@@ -135,9 +150,7 @@
#include "V8HTMLElement.h"
#include "V8LazyEventListener.h"
#include "V8NodeFilterCondition.h"
-#include "V8ObjectEventListener.h"
#include "ValidityState.h"
-#include "VoidCallback.h"
#include "WebKitAnimationEvent.h"
#include "WebKitCSSKeyframeRule.h"
#include "WebKitCSSKeyframesRule.h"
@@ -151,16 +164,18 @@
#include "XMLHttpRequestProgressEvent.h"
#include "XMLHttpRequestUpload.h"
#include "XMLSerializer.h"
-#include "XPathException.h"
-#include "XPathExpression.h"
-#include "XPathNSResolver.h"
-#include "XPathResult.h"
-#include "XSLTProcessor.h"
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include "DOMApplicationCache.h"
#endif
+#if ENABLE(DATABASE)
+#include "Database.h"
+#include "SQLTransaction.h"
+#include "SQLResultSet.h"
+#include "SQLResultSetRowList.h"
+#endif // DATABASE
+
#if ENABLE(DATAGRID)
#include "DataGridColumn.h"
#include "DataGridColumnList.h"
@@ -171,13 +186,11 @@
#include "StorageEvent.h"
#endif // DOM_STORAGE
-#if ENABLE(GEOLOCATION)
+// GEOLOCATION
#include "Coordinates.h"
#include "Geolocation.h"
#include "Geoposition.h"
#include "PositionError.h"
-#include "PositionErrorCallback.h"
-#endif
#if ENABLE(SVG)
#include "SVGAngle.h"
@@ -215,13 +228,21 @@
#include "V8SVGPODTypeWrapper.h"
#endif // SVG
+#if PLATFORM(ANDROID)
+// TODO: Upstream TOUCH_EVENTS guard.
#if ENABLE(TOUCH_EVENTS)
#include "Touch.h"
#include "TouchList.h"
#include "TouchEvent.h"
#endif
+#endif
+
+#if ENABLE(WEB_SOCKETS)
+#include "WebSocket.h"
+#endif
#if ENABLE(WORKERS)
+#include "AbstractWorker.h"
#include "DedicatedWorkerContext.h"
#include "Worker.h"
#include "WorkerContext.h"
@@ -229,10 +250,34 @@
#include "WorkerNavigator.h"
#endif // WORKERS
+#if ENABLE(SHARED_WORKERS)
+#include "SharedWorker.h"
+#include "SharedWorkerContext.h"
+#endif // SHARED_WORKERS
+
+#if ENABLE(NOTIFICATIONS)
+#include "Notification.h"
+#include "NotificationCenter.h"
+#endif // NOTIFICATIONS
+
#if ENABLE(XPATH)
#include "XPathEvaluator.h"
+#include "XPathException.h"
+#include "XPathExpression.h"
+#include "XPathNSResolver.h"
+#include "XPathResult.h"
#endif // XPATH
+#if ENABLE(XSLT)
+#include "XSLTProcessor.h"
+#endif // XSLT
+
+#if ENABLE(INSPECTOR)
+#include "InjectedScriptHost.h"
+#include "InspectorBackend.h"
+#include "InspectorFrontendHost.h"
+#endif // INSPECTOR
+
namespace WebCore {
// A helper class for undetectable document.all
diff --git a/WebCore/bindings/v8/DateExtension.cpp b/WebCore/bindings/v8/DateExtension.cpp
new file mode 100644
index 0000000..7d8b9be
--- /dev/null
+++ b/WebCore/bindings/v8/DateExtension.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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 "DateExtension.h"
+
+#include "V8Proxy.h"
+#include "V8HiddenPropertyName.h"
+
+namespace WebCore {
+
+DateExtension* DateExtension::extension;
+
+static const char* dateExtensionName = "v8/DateExtension";
+static const char* dateExtensionScript =
+ "(function () {"
+ " var counter;"
+ " var orig_getTime;"
+ " function getTimeOverride() {"
+ " if (++counter > 1000)"
+ " OnSleepDetected();"
+ " return orig_getTime.call(this);"
+ " };"
+ " function enableSleepDetection(enable) {"
+ " if (enable) {"
+ " counter = 0;"
+ " orig_getTime = Date.prototype.getTime;"
+ " Date.prototype.getTime = getTimeOverride;"
+ " } else {"
+ " Date.prototype.getTime = orig_getTime;"
+ " }"
+ " };"
+ " native function Setup();"
+ " native function OnSleepDetected();"
+ " Setup(Date, enableSleepDetection);"
+ "})()";
+
+DateExtension::DateExtension() : v8::Extension(dateExtensionName, dateExtensionScript)
+{
+}
+
+DateExtension* DateExtension::get()
+{
+ if (!extension)
+ extension = new DateExtension();
+ return extension;
+}
+
+void DateExtension::setAllowSleep(bool allow)
+{
+ v8::Local<v8::Value> result = V8Proxy::currentContext()->Global()->Get(v8::String::New("Date"));
+ if (result.IsEmpty())
+ return;
+
+ v8::Handle<v8::Object> dateObject = v8::Handle<v8::Object>::Cast(result);
+ if (dateObject.IsEmpty())
+ return;
+
+ v8::Local<v8::Value> sleepFunctionHandle = dateObject->GetHiddenValue(V8HiddenPropertyName::sleepFunction());
+ if (sleepFunctionHandle.IsEmpty() || !sleepFunctionHandle->IsFunction())
+ return;
+
+ v8::Handle<v8::Value> argv[1];
+ argv[0] = v8::String::New(allow ? "false" : "true");
+ v8::Handle<v8::Function>::Cast(sleepFunctionHandle)->Call(v8::Object::New(), 1, argv);
+}
+
+v8::Handle<v8::FunctionTemplate> DateExtension::GetNativeFunction(v8::Handle<v8::String> name)
+{
+ if (name->Equals(v8::String::New("Setup")))
+ return v8::FunctionTemplate::New(Setup);
+ if (name->Equals(v8::String::New("OnSleepDetected")))
+ return v8::FunctionTemplate::New(OnSleepDetected);
+
+ return v8::Handle<v8::FunctionTemplate>();
+}
+
+v8::Handle<v8::Value> DateExtension::Setup(const v8::Arguments& args)
+{
+ if (args.Length() != 2 || !args[0]->IsObject() || !args[1]->IsFunction())
+ return v8::Undefined();
+
+ v8::Handle<v8::Object> dateObject = v8::Handle<v8::Object>::Cast(args[0]);
+ v8::Handle<v8::Function> enableSleepDetectionFunction = v8::Handle<v8::Function>::Cast(args[1]);
+
+ dateObject->SetHiddenValue(V8HiddenPropertyName::sleepFunction(), enableSleepDetectionFunction);
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> DateExtension::OnSleepDetected(const v8::Arguments&)
+{
+ v8::V8::TerminateExecution();
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/DateExtension.h b/WebCore/bindings/v8/DateExtension.h
new file mode 100644
index 0000000..2bccac4
--- /dev/null
+++ b/WebCore/bindings/v8/DateExtension.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DateExtension_h
+#define DateExtension_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+// Prevent "sleep" calls in unload handlers.
+class DateExtension : public v8::Extension {
+public:
+ static DateExtension* get();
+ void setAllowSleep(bool allow);
+
+private:
+ DateExtension();
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(v8::Handle<v8::String>);
+ static v8::Handle<v8::Value> Setup(const v8::Arguments&);
+ static v8::Handle<v8::Value> OnSleepDetected(const v8::Arguments&);
+
+ static DateExtension* extension;
+};
+
+} // namespace WebCore
+
+#endif // DateExtension_h
diff --git a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp
index e52a505..bd2bb7b 100644
--- a/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp
+++ b/WebCore/bindings/v8/DerivedSourcesAllInOne.cpp
@@ -31,19 +31,45 @@
// This source file coalesces the V8 derived sources into a single object file to
// reduce bloat and allow us to link release builds on 32-bit Windows.
+// Require explicit conversion to AtomicString. This helps catch cases where
+// the generated bindings cause an expensive implicit conversion.
+#define NO_IMPLICIT_ATOMICSTRING
+
#include "bindings/V8Attr.cpp"
#include "bindings/V8BarInfo.cpp"
+#include "bindings/V8BeforeLoadEvent.cpp"
+#include "bindings/V8WebGLActiveInfo.cpp"
+#include "bindings/V8WebGLArray.cpp"
+#include "bindings/V8WebGLArrayBuffer.cpp"
+#include "bindings/V8WebGLBuffer.cpp"
+#include "bindings/V8WebGLByteArray.cpp"
+#include "bindings/V8WebGLFloatArray.cpp"
+#include "bindings/V8WebGLFramebuffer.cpp"
#include "bindings/V8CanvasGradient.cpp"
+#include "bindings/V8WebGLIntArray.cpp"
#include "bindings/V8CanvasPattern.cpp"
#include "bindings/V8CanvasPixelArray.cpp"
+#include "bindings/V8WebGLProgram.cpp"
+#include "bindings/V8WebGLRenderbuffer.cpp"
+#include "bindings/V8CanvasRenderingContext.cpp"
#include "bindings/V8CanvasRenderingContext2D.cpp"
+#include "bindings/V8WebGLRenderingContext.cpp"
+#include "bindings/V8WebGLShader.cpp"
+#include "bindings/V8WebGLShortArray.cpp"
+#include "bindings/V8WebGLTexture.cpp"
+#include "bindings/V8WebGLUniformLocation.cpp"
+#include "bindings/V8WebGLUnsignedByteArray.cpp"
+#include "bindings/V8WebGLUnsignedIntArray.cpp"
+#include "bindings/V8WebGLUnsignedShortArray.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/V8CompositionEvent.cpp"
#include "bindings/V8Console.cpp"
+#include "bindings/V8Coordinates.cpp"
#include "bindings/V8Counter.cpp"
#include "bindings/V8CSSCharsetRule.cpp"
#include "bindings/V8CSSFontFaceRule.cpp"
@@ -78,8 +104,9 @@
#include "bindings/V8EventException.cpp"
#include "bindings/V8File.cpp"
#include "bindings/V8FileList.cpp"
-#include "bindings/V8History.cpp"
#include "bindings/V8Geolocation.cpp"
+#include "bindings/V8Geoposition.cpp"
+#include "bindings/V8History.cpp"
#include "bindings/V8HTMLAllCollection.cpp"
#include "bindings/V8HTMLAnchorElement.cpp"
#include "bindings/V8HTMLAppletElement.cpp"
@@ -150,11 +177,6 @@
#include "bindings/V8HTMLUListElement.cpp"
#include "bindings/V8HTMLVideoElement.cpp"
#include "bindings/V8ImageData.cpp"
-#if PLATFORM(ANDROID)
-// No inspector for now
-#else
-#include "bindings/V8InspectorBackend.cpp"
-#endif
#include "bindings/V8KeyboardEvent.cpp"
#include "bindings/V8Location.cpp"
#include "bindings/V8Media.cpp"
@@ -174,9 +196,13 @@
#include "bindings/V8NodeIterator.cpp"
#include "bindings/V8NodeList.cpp"
#include "bindings/V8Notation.cpp"
+#include "bindings/V8Notification.cpp"
+#include "bindings/V8NotificationCenter.cpp"
#include "bindings/V8OverflowEvent.cpp"
+#include "bindings/V8PageTransitionEvent.cpp"
#include "bindings/V8Plugin.cpp"
#include "bindings/V8PluginArray.cpp"
+#include "bindings/V8PositionError.cpp"
#include "bindings/V8ProcessingInstruction.cpp"
#include "bindings/V8ProgressEvent.cpp"
#include "bindings/V8Range.cpp"
@@ -207,6 +233,18 @@
#include "bindings/V8XMLHttpRequestUpload.cpp"
#include "bindings/V8XMLSerializer.cpp"
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+#include "bindings/V8DOMApplicationCache.cpp"
+#endif
+
+#if ENABLE(DOM_STORAGE)
+#include "bindings/V8Storage.cpp"
+#include "bindings/V8StorageEvent.cpp"
+#endif
+
+#if ENABLE(WEB_SOCKETS)
+#include "bindings/V8WebSocket.cpp"
+#endif
#if ENABLE(DATABASE)
#include "bindings/V8Database.cpp"
@@ -216,14 +254,18 @@
#include "bindings/V8SQLTransaction.cpp"
#endif
-
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#include "bindings/V8DOMApplicationCache.cpp"
+#if ENABLE(WORKERS)
+#include "bindings/V8AbstractWorker.cpp"
+#include "bindings/V8DedicatedWorkerContext.cpp"
+#include "bindings/V8Worker.cpp"
+#include "bindings/V8WorkerContext.cpp"
+#include "bindings/V8WorkerLocation.cpp"
+#include "bindings/V8WorkerNavigator.cpp"
#endif
-#if ENABLE(DOM_STORAGE)
-#include "bindings/V8Storage.cpp"
-#include "bindings/V8StorageEvent.cpp"
+#if ENABLE(SHARED_WORKERS)
+#include "bindings/V8SharedWorker.cpp"
+#include "bindings/V8SharedWorkerContext.cpp"
#endif
#if ENABLE(SVG)
@@ -250,8 +292,8 @@
#include "bindings/V8SVGCircleElement.cpp"
#include "bindings/V8SVGClipPathElement.cpp"
#include "bindings/V8SVGColor.cpp"
+#include "bindings/V8SVGComponentTransferFunctionElement.cpp"
#include "bindings/V8SVGCursorElement.cpp"
-#include "bindings/V8SVGDefinitionSrcElement.cpp"
#include "bindings/V8SVGDefsElement.cpp"
#include "bindings/V8SVGDescElement.cpp"
#include "bindings/V8SVGDocument.cpp"
@@ -260,6 +302,30 @@
#include "bindings/V8SVGElementInstanceList.cpp"
#include "bindings/V8SVGEllipseElement.cpp"
#include "bindings/V8SVGException.cpp"
+#include "bindings/V8SVGFEBlendElement.cpp"
+#include "bindings/V8SVGFEColorMatrixElement.cpp"
+#include "bindings/V8SVGFEComponentTransferElement.cpp"
+#include "bindings/V8SVGFECompositeElement.cpp"
+#include "bindings/V8SVGFEDiffuseLightingElement.cpp"
+#include "bindings/V8SVGFEDisplacementMapElement.cpp"
+#include "bindings/V8SVGFEDistantLightElement.cpp"
+#include "bindings/V8SVGFEFloodElement.cpp"
+#include "bindings/V8SVGFEFuncAElement.cpp"
+#include "bindings/V8SVGFEFuncBElement.cpp"
+#include "bindings/V8SVGFEFuncGElement.cpp"
+#include "bindings/V8SVGFEFuncRElement.cpp"
+#include "bindings/V8SVGFEGaussianBlurElement.cpp"
+#include "bindings/V8SVGFEImageElement.cpp"
+#include "bindings/V8SVGFEMergeElement.cpp"
+#include "bindings/V8SVGFEMergeNodeElement.cpp"
+#include "bindings/V8SVGFEMorphologyElement.cpp"
+#include "bindings/V8SVGFEOffsetElement.cpp"
+#include "bindings/V8SVGFEPointLightElement.cpp"
+#include "bindings/V8SVGFESpecularLightingElement.cpp"
+#include "bindings/V8SVGFESpotLightElement.cpp"
+#include "bindings/V8SVGFETileElement.cpp"
+#include "bindings/V8SVGFETurbulenceElement.cpp"
+#include "bindings/V8SVGFilterElement.cpp"
#include "bindings/V8SVGFontElement.cpp"
#include "bindings/V8SVGFontFaceElement.cpp"
#include "bindings/V8SVGFontFaceFormatElement.cpp"
@@ -333,22 +399,11 @@
#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"
#endif
-#if ENABLE(WORKERS)
-#include "bindings/V8AbstractWorker.cpp"
-#include "bindings/V8DedicatedWorkerContext.cpp"
-#include "bindings/V8SharedWorker.cpp"
-#include "bindings/V8Worker.cpp"
-#include "bindings/V8WorkerContext.cpp"
-#include "bindings/V8WorkerLocation.cpp"
-#include "bindings/V8WorkerNavigator.cpp"
-#endif
-
#if ENABLE(XPATH)
#include "bindings/V8XPathEvaluator.cpp"
#include "bindings/V8XPathException.cpp"
@@ -360,3 +415,9 @@
#if ENABLE(XSLT)
#include "bindings/V8XSLTProcessor.cpp"
#endif
+
+#if ENABLE(INSPECTOR)
+#include "bindings/V8InjectedScriptHost.cpp"
+#include "bindings/V8InspectorBackend.cpp"
+#include "bindings/V8InspectorFrontendHost.cpp"
+#endif
diff --git a/WebCore/bindings/v8/MainThreadDOMData.cpp b/WebCore/bindings/v8/MainThreadDOMData.cpp
index ea34444..b1b63bf 100644
--- a/WebCore/bindings/v8/MainThreadDOMData.cpp
+++ b/WebCore/bindings/v8/MainThreadDOMData.cpp
@@ -39,14 +39,30 @@ MainThreadDOMData::MainThreadDOMData()
: m_defaultStore(this)
{
}
+
+MainThreadDOMData* MainThreadDOMData::getCurrent()
+{
+ ASSERT(WTF::isMainThread());
+ DEFINE_STATIC_LOCAL(MainThreadDOMData, mainThreadDOMData, ());
+ return &mainThreadDOMData;
+}
-DOMDataStore& MainThreadDOMData::getStore()
+DOMDataStore& MainThreadDOMData::getMainThreadStore()
{
+ // This is broken out as a separate non-virtual method from getStore()
+ // so that it can be inlined by getCurrentMainThreadStore, which is
+ // a hot spot in Dromaeo DOM tests.
ASSERT(WTF::isMainThread());
V8IsolatedWorld* world = V8IsolatedWorld::getEntered();
- if (world)
+ if (UNLIKELY(world != 0))
return *world->getDOMDataStore();
return m_defaultStore;
}
+DOMDataStore& MainThreadDOMData::getCurrentMainThreadStore()
+{
+ return getCurrent()->getMainThreadStore();
+}
+
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/MainThreadDOMData.h b/WebCore/bindings/v8/MainThreadDOMData.h
index 5c78cec..e8f99c9 100644
--- a/WebCore/bindings/v8/MainThreadDOMData.h
+++ b/WebCore/bindings/v8/MainThreadDOMData.h
@@ -38,10 +38,16 @@ namespace WebCore {
class MainThreadDOMData : public DOMData {
public:
- MainThreadDOMData();
- DOMDataStore& getStore();
+ static MainThreadDOMData* getCurrent(); // Caller must be on the main thread.
+ static DOMDataStore& getCurrentMainThreadStore();
+
+ virtual DOMDataStore& getStore() { return getMainThreadStore(); }
+
private:
+ MainThreadDOMData();
+ DOMDataStore& getMainThreadStore();
+
StaticDOMDataStore m_defaultStore;
// Note: The DOMDataStores for isolated world are owned by the world object.
};
diff --git a/WebCore/bindings/v8/NPV8Object.cpp b/WebCore/bindings/v8/NPV8Object.cpp
index cb2a6c1..69cd303 100644
--- a/WebCore/bindings/v8/NPV8Object.cpp
+++ b/WebCore/bindings/v8/NPV8Object.cpp
@@ -276,7 +276,7 @@ bool _NPN_EvaluateHelper(NPP npp, bool popupsAllowed, NPObject* npObject, NPStri
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);
+ v8::Local<v8::Value> v8result = proxy->evaluate(WebCore::ScriptSourceCode(script, WebCore::KURL(WebCore::ParsedURLString, filename)), 0);
if (v8result.IsEmpty())
return false;
@@ -413,8 +413,12 @@ bool _NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName)
void _NPN_SetException(NPObject* npObject, const NPUTF8 *message)
{
- if (npObject->_class != npScriptObjectClass)
+ if (!npObject || npObject->_class != npScriptObjectClass) {
+ // We won't be able to find a proper scope for this exception, so just throw it.
+ // This is consistent with JSC, which throws a global exception all the time.
+ V8Proxy::throwError(V8Proxy::GeneralError, message);
return;
+ }
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = toV8Context(0, npObject);
if (context.IsEmpty())
diff --git a/WebCore/bindings/v8/OwnHandle.h b/WebCore/bindings/v8/OwnHandle.h
index 6580674..17c551c 100644
--- a/WebCore/bindings/v8/OwnHandle.h
+++ b/WebCore/bindings/v8/OwnHandle.h
@@ -45,15 +45,13 @@ namespace WebCore {
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;
+ if (m_handle.IsWeak())
+ m_handle.ClearWeak();
m_handle.Dispose();
m_handle.Clear();
}
diff --git a/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp b/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp
new file mode 100644
index 0000000..cf97b5b
--- /dev/null
+++ b/WebCore/bindings/v8/RuntimeEnabledFeatures.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 "RuntimeEnabledFeatures.h"
+
+namespace WebCore {
+
+bool RuntimeEnabledFeatures::isDatabaseEnabled = false;
+bool RuntimeEnabledFeatures::isLocalStorageEnabled = true;
+bool RuntimeEnabledFeatures::isSessionStorageEnabled = true;
+bool RuntimeEnabledFeatures::isNotificationsEnabled = false;
+bool RuntimeEnabledFeatures::isApplicationCacheEnabled = false;
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/RuntimeEnabledFeatures.h b/WebCore/bindings/v8/RuntimeEnabledFeatures.h
new file mode 100644
index 0000000..d8078c5
--- /dev/null
+++ b/WebCore/bindings/v8/RuntimeEnabledFeatures.h
@@ -0,0 +1,67 @@
+/*
+ * 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 RuntimeEnabledFeatures_h
+#define RuntimeEnabledFeatures_h
+
+namespace WebCore {
+
+// A class that stores static enablers for all experimental features
+class RuntimeEnabledFeatures {
+public:
+ static void setDatabaseEnabled(bool isEnabled) { isDatabaseEnabled = isEnabled; }
+ static bool databaseEnabled() { return isDatabaseEnabled; }
+
+ static void setLocalStorageEnabled(bool isEnabled) { isLocalStorageEnabled = isEnabled; }
+ static bool localStorageEnabled() { return isLocalStorageEnabled; }
+
+ static void setSessionStorageEnabled(bool isEnabled) { isSessionStorageEnabled = isEnabled; }
+ static bool sessionStorageEnabled() { return isSessionStorageEnabled; }
+
+ static void setNotificationsEnabled(bool isEnabled) { isNotificationsEnabled = isEnabled; }
+ static bool notificationsEnabled() { return isNotificationsEnabled; }
+
+ static void setApplicationCacheEnabled(bool isEnabled) { isApplicationCacheEnabled = isEnabled; }
+ static bool applicationCacheEnabled() { return isApplicationCacheEnabled; }
+
+private:
+ // Never instantiate.
+ RuntimeEnabledFeatures() { }
+
+ static bool isDatabaseEnabled;
+ static bool isLocalStorageEnabled;
+ static bool isSessionStorageEnabled;
+ static bool isNotificationsEnabled;
+ static bool isApplicationCacheEnabled;
+};
+
+} // namespace WebCore
+
+#endif // RuntimeEnabledFeatures_h
diff --git a/WebCore/bindings/v8/ScheduledAction.cpp b/WebCore/bindings/v8/ScheduledAction.cpp
index 44e8a37..4f321cb 100644
--- a/WebCore/bindings/v8/ScheduledAction.cpp
+++ b/WebCore/bindings/v8/ScheduledAction.cpp
@@ -44,8 +44,9 @@
namespace WebCore {
-ScheduledAction::ScheduledAction(v8::Handle<v8::Function> func, int argc, v8::Handle<v8::Value> argv[])
- : m_code(String(), KURL(), 0)
+ScheduledAction::ScheduledAction(v8::Handle<v8::Context> context, v8::Handle<v8::Function> func, int argc, v8::Handle<v8::Value> argv[])
+ : m_context(context)
+ , m_code(String(), KURL(), 0)
{
m_function = v8::Persistent<v8::Function>::New(func);
@@ -105,9 +106,8 @@ void ScheduledAction::execute(V8Proxy* proxy)
{
ASSERT(proxy);
- LOCK_V8;
v8::HandleScope handleScope;
- v8::Local<v8::Context> v8Context = proxy->context();
+ v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context.get());
if (v8Context.IsEmpty())
return; // JS may not be enabled.
@@ -134,9 +134,8 @@ void ScheduledAction::execute(WorkerContext* workerContext)
WorkerScriptController* scriptController = workerContext->script();
if (!m_function.IsEmpty() && m_function->IsFunction()) {
- LOCK_V8;
v8::HandleScope handleScope;
- v8::Local<v8::Context> v8Context = scriptController->proxy()->context();
+ v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context.get());
ASSERT(!v8Context.IsEmpty());
v8::Context::Scope scope(v8Context);
m_function->Call(v8Context->Global(), m_argc, m_argv);
diff --git a/WebCore/bindings/v8/ScheduledAction.h b/WebCore/bindings/v8/ScheduledAction.h
index 53694c7..003885f 100644
--- a/WebCore/bindings/v8/ScheduledAction.h
+++ b/WebCore/bindings/v8/ScheduledAction.h
@@ -31,7 +31,9 @@
#ifndef ScheduledAction_h
#define ScheduledAction_h
+#include "OwnHandle.h"
#include "ScriptSourceCode.h"
+#include "V8GCController.h"
#include <v8.h>
@@ -44,9 +46,10 @@ namespace WebCore {
class ScheduledAction {
public:
- ScheduledAction(v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
- explicit ScheduledAction(const WebCore::String& code, const KURL& url = KURL())
- : m_argc(0)
+ ScheduledAction(v8::Handle<v8::Context>, v8::Handle<v8::Function>, int argc, v8::Handle<v8::Value> argv[]);
+ explicit ScheduledAction(v8::Handle<v8::Context> context, const WebCore::String& code, const KURL& url = KURL())
+ : m_context(context)
+ , m_argc(0)
, m_argv(0)
, m_code(code, url)
{
@@ -61,6 +64,7 @@ namespace WebCore {
void execute(WorkerContext*);
#endif
+ OwnHandle<v8::Context> m_context;
v8::Persistent<v8::Function> m_function;
int m_argc;
v8::Persistent<v8::Value>* m_argv;
diff --git a/WebCore/bindings/v8/ScriptCallFrame.cpp b/WebCore/bindings/v8/ScriptCallFrame.cpp
index ab30862..4c29814 100644
--- a/WebCore/bindings/v8/ScriptCallFrame.cpp
+++ b/WebCore/bindings/v8/ScriptCallFrame.cpp
@@ -42,7 +42,7 @@ namespace WebCore {
ScriptCallFrame::ScriptCallFrame(const String& functionName, const String& urlString, int lineNumber, const v8::Arguments& arguments, unsigned skipArgumentCount)
: m_functionName(functionName)
- , m_sourceURL(urlString)
+ , m_sourceURL(ParsedURLString, urlString)
, m_lineNumber(lineNumber)
{
for (int i = 0; i < arguments.Length(); ++i)
diff --git a/WebCore/bindings/v8/ScriptCallStack.cpp b/WebCore/bindings/v8/ScriptCallStack.cpp
index 8eb9478..d9b2fcf 100644
--- a/WebCore/bindings/v8/ScriptCallStack.cpp
+++ b/WebCore/bindings/v8/ScriptCallStack.cpp
@@ -38,8 +38,21 @@
namespace WebCore {
-ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount)
- : m_lastCaller(String(), V8Proxy::sourceName(), V8Proxy::sourceLineNumber() + 1, arguments, skipArgumentCount)
+ScriptCallStack* ScriptCallStack::create(const v8::Arguments& arguments, unsigned skipArgumentCount) {
+ String sourceName;
+ int sourceLineNumber;
+ if (!V8Proxy::sourceName(sourceName)) {
+ return 0;
+ }
+ if (!V8Proxy::sourceLineNumber(sourceLineNumber)) {
+ return 0;
+ }
+ sourceLineNumber += 1;
+ return new ScriptCallStack(arguments, skipArgumentCount, sourceName, sourceLineNumber);
+}
+
+ScriptCallStack::ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber)
+ : m_lastCaller(String(), sourceName, sourceLineNumber, arguments, skipArgumentCount)
, m_scriptState(new ScriptState(V8Proxy::retrieveFrameForCurrentContext()))
{
}
diff --git a/WebCore/bindings/v8/ScriptCallStack.h b/WebCore/bindings/v8/ScriptCallStack.h
index 9f628c8..f6a7e39 100644
--- a/WebCore/bindings/v8/ScriptCallStack.h
+++ b/WebCore/bindings/v8/ScriptCallStack.h
@@ -45,7 +45,7 @@ namespace WebCore {
class ScriptCallStack : public Noncopyable {
public:
- ScriptCallStack(const v8::Arguments&, unsigned skipArgumentCount = 0);
+ static ScriptCallStack* create(const v8::Arguments&, unsigned skipArgumentCount = 0);
~ScriptCallStack();
const ScriptCallFrame& at(unsigned) const;
@@ -55,8 +55,10 @@ namespace WebCore {
ScriptState* state() const { return m_scriptState.get(); }
private:
- OwnPtr<ScriptState> m_scriptState;
+ ScriptCallStack(const v8::Arguments& arguments, unsigned skipArgumentCount, String sourceName, int sourceLineNumber);
+
ScriptCallFrame m_lastCaller;
+ OwnPtr<ScriptState> m_scriptState;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp
index 48c5115..5b4dbc2 100644
--- a/WebCore/bindings/v8/ScriptController.cpp
+++ b/WebCore/bindings/v8/ScriptController.cpp
@@ -45,6 +45,7 @@
#include "EventListener.h"
#include "EventNames.h"
#include "Frame.h"
+#include "FrameLoaderClient.h"
#include "Node.h"
#include "NotImplemented.h"
#include "npruntime_impl.h"
@@ -52,15 +53,25 @@
#include "NPV8Object.h"
#include "ScriptSourceCode.h"
#include "ScriptState.h"
-#include "Widget.h"
-#include "XSSAuditor.h"
-
+#include "Settings.h"
#include "V8Binding.h"
#include "V8NPObject.h"
#include "V8Proxy.h"
+#include "Widget.h"
+#include "XSSAuditor.h"
+#include <wtf/StdLibExtras.h>
namespace WebCore {
+void ScriptController::initializeThreading()
+{
+ static bool initializedThreading = false;
+ if (!initializedThreading) {
+ WTF::initializeThreading();
+ initializedThreading = true;
+ }
+}
+
void ScriptController::setFlags(const char* string, int length)
{
v8::V8::SetFlagsFromString(string, length);
@@ -94,9 +105,9 @@ void ScriptController::gcUnprotectJSWrapper(void* domObject)
ScriptController::ScriptController(Frame* frame)
: m_frame(frame)
, m_sourceURL(0)
+ , m_inExecuteScript(false)
, m_processingTimerCallback(false)
, m_paused(false)
- , m_scriptState(new ScriptState(frame))
, m_proxy(new V8Proxy(frame))
#if ENABLE(NETSCAPE_PLUGIN_API)
, m_windowScriptNPObject(0)
@@ -148,7 +159,7 @@ bool ScriptController::processingUserGesture() const
return true;
V8Proxy* activeProxy = activeFrame->script()->proxy();
- LOCK_V8;
+
v8::HandleScope handleScope;
v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(activeFrame);
// FIXME: find all cases context can be empty:
@@ -166,6 +177,9 @@ bool ScriptController::processingUserGesture() const
// Based on code from kjs_bindings.cpp.
// Note: This is more liberal than Firefox's implementation.
if (event) {
+ if (event->createdByDOM())
+ return false;
+
const AtomicString& type = event->type();
bool eventOk =
// mouse events
@@ -186,9 +200,14 @@ bool ScriptController::processingUserGesture() const
return false;
}
-void ScriptController::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup)
+void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>& sources)
+{
+ m_proxy->evaluateInIsolatedWorld(worldID, sources, 0);
+}
+
+void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup)
{
- m_proxy->evaluateInNewWorld(sources, extensionGroup);
+ m_proxy->evaluateInIsolatedWorld(worldID, sources, extensionGroup);
}
void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int extensionGroup)
@@ -199,15 +218,9 @@ void ScriptController::evaluateInNewContext(const Vector<ScriptSourceCode>& sour
// Evaluate a script file in the environment of this proxy.
ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
{
- LOCK_V8;
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())) {
+ if (!m_XSSAuditor->canEvaluate(sourceCode.source())) {
// This script is not safe to be evaluated.
return ScriptValue();
}
@@ -246,7 +259,6 @@ void ScriptController::finishedWithEvent(Event* event)
// Create a V8 object with an interceptor of NPObjectPropertyGetter.
void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObject* object)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
@@ -264,13 +276,13 @@ void ScriptController::bindToWindowObject(Frame* frame, const String& key, NPObj
void ScriptController::collectGarbage()
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_proxy->frame());
if (v8Context.IsEmpty())
return;
v8::Context::Scope scope(v8Context);
+
m_proxy->evaluate(ScriptSourceCode("if (window.gc) void(gc());"), 0);
}
@@ -286,7 +298,8 @@ bool ScriptController::haveInterpreter() const
bool ScriptController::isEnabled() const
{
- return m_proxy->isEnabled();
+ Settings* settings = m_proxy->frame()->settings();
+ return m_proxy->frame()->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled() && !m_frame->loader()->isSandboxed(SandboxScripts));
}
PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
@@ -343,7 +356,7 @@ PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widge
return V8ScriptInstance::create(wrapper);
}
-void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
+void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle)
{
PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
if (it == m_pluginObjects.end())
@@ -353,6 +366,18 @@ void ScriptController::cleanupScriptObjectsForPlugin(void* nativeHandle)
m_pluginObjects.remove(it);
}
+void ScriptController::getAllWorlds(Vector<DOMWrapperWorld*>& worlds)
+{
+ worlds.append(mainThreadNormalWorld());
+}
+
+ScriptState* ScriptController::mainWorldScriptState()
+{
+ if (!m_mainWorldScriptState)
+ m_mainWorldScriptState.set(new ScriptState(m_frame, V8Proxy::mainWorldContext(m_frame)));
+ return m_mainWorldScriptState.get();
+}
+
static NPObject* createNoScriptObject()
{
notImplemented();
@@ -361,7 +386,6 @@ static NPObject* createNoScriptObject()
static NPObject* createScriptObject(Frame* frame)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame);
if (v8Context.IsEmpty())
@@ -399,7 +423,6 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement
if (!isEnabled())
return createNoScriptObject();
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
if (v8Context.IsEmpty())
diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h
index d614619..fb7bbee 100644
--- a/WebCore/bindings/v8/ScriptController.h
+++ b/WebCore/bindings/v8/ScriptController.h
@@ -39,9 +39,11 @@
#include <v8.h>
#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
+ class DOMWrapperWorld;
class Event;
class Frame;
class HTMLPlugInElement;
@@ -60,16 +62,33 @@ namespace WebCore {
// or this accessor should be made JSProxy*
V8Proxy* proxy() { return m_proxy.get(); }
+ ScriptValue executeScript(const ScriptSourceCode&);
+ ScriptValue executeScript(const String& script, bool forceUserGesture = false);
+
+ // Returns true if argument is a JavaScript URL.
+ bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true);
+
+ // This function must be called from the main thread. It is safe to call it repeatedly.
+ static void initializeThreading();
+
// Evaluate a script file in the environment of this proxy.
// If succeeded, 'succ' is set to true and result is returned
// 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);
+ void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&);
+
+ // Executes JavaScript in an 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.
+ //
+ // If an isolated world with the specified ID already exists, it is reused.
+ // Otherwise, a new world is created.
+ //
+ // If the worldID is 0, a new world is always created.
+ //
+ // FIXME: Get rid of extensionGroup here.
+ void evaluateInIsolatedWorld(unsigned worldID, 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
@@ -77,16 +96,11 @@ namespace WebCore {
// all DOM nodes and DOM constructors.
void evaluateInNewContext(const Vector<ScriptSourceCode>&, int extensionGroup);
- // JSC has a WindowShell object, but for V8, the ScriptController
- // is the WindowShell.
- bool haveWindowShell() const { return true; }
-
// Masquerade 'this' as the windowShell.
// This is a bit of a hack, but provides reasonable compatibility
// with what JSC does as well.
- ScriptController* windowShell() { return this; }
-
- ScriptState* state() const { return m_scriptState.get(); }
+ ScriptController* windowShell(DOMWrapperWorld*) { return this; }
+ ScriptController* existingWindowShell(DOMWrapperWorld*) { return this; }
XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); }
@@ -146,23 +160,31 @@ namespace WebCore {
void updateSecurityOrigin();
void clearScriptObjects();
void updatePlatformScriptObjects();
- void cleanupScriptObjectsForPlugin(void*);
+ void cleanupScriptObjectsForPlugin(Widget*);
#if ENABLE(NETSCAPE_PLUGIN_API)
NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*);
NPObject* windowScriptNPObject();
#endif
+ // Dummy method to avoid a bunch of ifdef's in WebCore.
+ void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*) { }
+ static void getAllWorlds(Vector<DOMWrapperWorld*>& worlds);
+
+ // Script state for the main world context.
+ ScriptState* mainWorldScriptState();
+
private:
Frame* m_frame;
const String* m_sourceURL;
+ bool m_inExecuteScript;
+
bool m_processingTimerCallback;
bool m_paused;
- OwnPtr<ScriptState> m_scriptState;
OwnPtr<V8Proxy> m_proxy;
- typedef HashMap<void*, NPObject*> PluginObjectMap;
+ typedef HashMap<Widget*, NPObject*> PluginObjectMap;
// A mapping between Widgets and their corresponding script object.
// This list is used so that when the plugin dies, we can immediately
@@ -174,6 +196,9 @@ namespace WebCore {
#endif
// The XSSAuditor associated with this ScriptController.
OwnPtr<XSSAuditor> m_XSSAuditor;
+
+ // Script state for the main world context.
+ OwnPtr<ScriptState> m_mainWorldScriptState;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index 7a8aa64..51d53ab 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -33,7 +33,12 @@
#include "Attribute.h"
#include "Document.h"
+#include "EventListener.h"
#include "Frame.h"
+#include "ScriptScope.h"
+#include "Tokenizer.h"
+#include "V8AbstractEventListener.h"
+#include "V8Binding.h"
#include "XSSAuditor.h"
namespace WebCore {
@@ -41,18 +46,29 @@ namespace WebCore {
PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribute* attr)
{
ASSERT(node);
+ int lineNumber = 1;
+ int columnNumber = 0;
+ String sourceURL;
- Frame* frame = node->document()->frame();
+ if (Frame* frame = node->document()->frame()) {
+ ScriptController* scriptController = frame->script();
+ if (!scriptController->isEnabled())
+ return 0;
- if (!frame)
- return 0;
+ if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+ // This script is not safe to execute.
+ return 0;
+ }
- if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
- // This script is not safe to execute.
- return 0;
+ if (frame->document()->tokenizer()) {
+ // FIXME: Change to use script->eventHandlerLineNumber() when implemented.
+ lineNumber = frame->document()->tokenizer()->lineNumber();
+ columnNumber = frame->document()->tokenizer()->columnNumber();
+ }
+ sourceURL = node->document()->url().string();
}
- return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), node->isSVGElement());
+ return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld));
}
PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr)
@@ -60,12 +76,40 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
if (!frame)
return 0;
- if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+ int lineNumber = 1;
+ int columnNumber = 0;
+ String sourceURL;
+
+ 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;
}
- return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), frame->document()->isSVGDocument());
+ if (frame->document()->tokenizer()) {
+ // FIXME: Change to use script->eventHandlerLineNumber() when implemented.
+ lineNumber = frame->document()->tokenizer()->lineNumber();
+ columnNumber = frame->document()->tokenizer()->columnNumber();
+ }
+ sourceURL = frame->document()->url().string();
+ return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber, WorldContextHandle(UseMainWorld));
+}
+
+String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState* scriptState, EventListener* listener)
+{
+ if (listener->type() != EventListener::JSEventListenerType)
+ return "";
+
+ ScriptScope scope(scriptState);
+ V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener);
+ v8::Handle<v8::Object> function = v8Listener->getListenerObject(context);
+ if (function.IsEmpty())
+ return "";
+
+ return toWebCoreStringWithNullCheck(function);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptEventListener.h b/WebCore/bindings/v8/ScriptEventListener.h
index 0171120..ce12a53 100644
--- a/WebCore/bindings/v8/ScriptEventListener.h
+++ b/WebCore/bindings/v8/ScriptEventListener.h
@@ -38,11 +38,14 @@
namespace WebCore {
class Attribute;
+ class EventListener;
class Frame;
class Node;
+ class ScriptState;
PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node*, Attribute*);
PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame*, Attribute*);
+ String getEventListenerHandlerBody(ScriptExecutionContext*, ScriptState*, EventListener*);
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptFunctionCall.cpp b/WebCore/bindings/v8/ScriptFunctionCall.cpp
index 2fa43d5..a232acd 100644
--- a/WebCore/bindings/v8/ScriptFunctionCall.cpp
+++ b/WebCore/bindings/v8/ScriptFunctionCall.cpp
@@ -31,8 +31,6 @@
#include "config.h"
#include "ScriptFunctionCall.h"
-#include "Document.h"
-#include "Frame.h"
#include "ScriptScope.h"
#include "ScriptState.h"
#include "ScriptString.h"
@@ -40,19 +38,13 @@
#include "V8Binding.h"
#include "V8Proxy.h"
+#include "V8Utilities.h"
#include <v8.h>
#include <wtf/OwnArrayPtr.h>
namespace WebCore {
-static void reportException(ScriptState* scriptState, v8::TryCatch &exceptionCatcher)
-{
- v8::Local<v8::Message> message = exceptionCatcher.Message();
- scriptState->frame()->document()->reportException(toWebCoreString(message->Get()), message->GetLineNumber(), toWebCoreString(message->GetScriptResourceName()));
- exceptionCatcher.Reset();
-}
-
ScriptFunctionCall::ScriptFunctionCall(ScriptState* scriptState, const ScriptObject& thisObject, const String& name)
: m_scriptState(scriptState)
, m_thisObject(thisObject)
@@ -82,6 +74,18 @@ void ScriptFunctionCall::appendArgument(const String& argument)
m_arguments.append(v8String(argument));
}
+void ScriptFunctionCall::appendArgument(const char* argument)
+{
+ ScriptScope scope(m_scriptState);
+ m_arguments.append(v8String(argument));
+}
+
+void ScriptFunctionCall::appendArgument(long argument)
+{
+ ScriptScope scope(m_scriptState);
+ m_arguments.append(v8::Number::New(argument));
+}
+
void ScriptFunctionCall::appendArgument(long long argument)
{
ScriptScope scope(m_scriptState);
@@ -94,6 +98,12 @@ void ScriptFunctionCall::appendArgument(unsigned int argument)
m_arguments.append(v8::Number::New(argument));
}
+void ScriptFunctionCall::appendArgument(unsigned long argument)
+{
+ ScriptScope scope(m_scriptState);
+ m_arguments.append(v8::Number::New(argument));
+}
+
void ScriptFunctionCall::appendArgument(int argument)
{
ScriptScope scope(m_scriptState);
diff --git a/WebCore/bindings/v8/ScriptFunctionCall.h b/WebCore/bindings/v8/ScriptFunctionCall.h
index 8365a4e..6203402 100644
--- a/WebCore/bindings/v8/ScriptFunctionCall.h
+++ b/WebCore/bindings/v8/ScriptFunctionCall.h
@@ -50,8 +50,11 @@ namespace WebCore {
void appendArgument(const ScriptString&);
void appendArgument(const ScriptValue&);
void appendArgument(const String&);
+ void appendArgument(const char*);
+ void appendArgument(long);
void appendArgument(long long);
void appendArgument(unsigned int);
+ void appendArgument(unsigned long);
void appendArgument(int);
void appendArgument(bool);
ScriptValue call(bool& hadException, bool reportExceptions = true);
diff --git a/WebCore/bindings/v8/ScriptObject.cpp b/WebCore/bindings/v8/ScriptObject.cpp
index b6943bd..5f5609c 100644
--- a/WebCore/bindings/v8/ScriptObject.cpp
+++ b/WebCore/bindings/v8/ScriptObject.cpp
@@ -36,6 +36,8 @@
#include "Document.h"
#include "Frame.h"
+#include "InspectorBackend.h"
+#include "InspectorFrontendHost.h"
#include "V8Binding.h"
#include "V8Proxy.h"
@@ -83,6 +85,13 @@ bool ScriptObject::set(const char* name, double value)
return scope.success();
}
+bool ScriptObject::set(const char* name, long value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::String::New(name), v8::Number::New(value));
+ return scope.success();
+}
+
bool ScriptObject::set(const char* name, long long value)
{
ScriptScope scope(m_scriptState);
@@ -97,6 +106,20 @@ bool ScriptObject::set(const char* name, int value)
return scope.success();
}
+bool ScriptObject::set(const char* name, unsigned value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::String::New(name), v8::Number::New(value));
+ return scope.success();
+}
+
+bool ScriptObject::set(const char* name, unsigned long value)
+{
+ ScriptScope scope(m_scriptState);
+ v8Object()->Set(v8::String::New(name), v8::Number::New(value));
+ return scope.success();
+}
+
bool ScriptObject::set(const char* name, bool value)
{
ScriptScope scope(m_scriptState);
@@ -117,6 +140,7 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, const S
return scope.success();
}
+#if ENABLE(INSPECTOR)
bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorBackend* value)
{
ScriptScope scope(scriptState);
@@ -126,6 +150,21 @@ bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, Inspect
return scope.success();
}
+bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InspectorFrontendHost* value)
+{
+ ScriptScope scope(scriptState);
+ scope.global()->Set(v8::String::New(name), V8DOMWrapper::convertToV8Object(V8ClassIndex::INSPECTORFRONTENDHOST, value));
+ return scope.success();
+}
+
+bool ScriptGlobalObject::set(ScriptState* scriptState, const char* name, InjectedScriptHost* value)
+{
+ ScriptScope scope(scriptState);
+ scope.global()->Set(v8::String::New(name), V8DOMWrapper::convertToV8Object(V8ClassIndex::INJECTEDSCRIPTHOST, value));
+ return scope.success();
+}
+#endif
+
bool ScriptGlobalObject::get(ScriptState* scriptState, const char* name, ScriptObject& value)
{
ScriptScope scope(scriptState);
diff --git a/WebCore/bindings/v8/ScriptObject.h b/WebCore/bindings/v8/ScriptObject.h
index dcee3a5..630d3b9 100644
--- a/WebCore/bindings/v8/ScriptObject.h
+++ b/WebCore/bindings/v8/ScriptObject.h
@@ -36,7 +36,9 @@
#include <v8.h>
namespace WebCore {
+ class InjectedScriptHost;
class InspectorBackend;
+ class InspectorFrontendHost;
class ScriptState;
class ScriptObject : public ScriptValue {
@@ -51,8 +53,11 @@ namespace WebCore {
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);
bool set(const char* name, long long);
bool set(const char* name, int);
+ bool set(const char* name, unsigned);
+ bool set(const char* name, unsigned long);
bool set(const char* name, bool);
static ScriptObject createNew(ScriptState*);
@@ -64,6 +69,8 @@ namespace WebCore {
public:
static bool set(ScriptState*, const char* name, const ScriptObject&);
static bool set(ScriptState*, const char* name, InspectorBackend*);
+ static bool set(ScriptState*, const char* name, InspectorFrontendHost*);
+ static bool set(ScriptState*, const char* name, InjectedScriptHost*);
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
deleted file mode 100644
index 053cf68..0000000
--- a/WebCore/bindings/v8/ScriptObjectQuarantine.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ScriptObjectQuarantine.h"
-
-#include "Database.h"
-#include "Document.h"
-#include "DOMWindow.h"
-#include "Frame.h"
-#include "Page.h"
-#include "ScriptObject.h"
-#include "ScriptValue.h"
-
-#include "V8Binding.h"
-#include "V8Proxy.h"
-
-#include <v8.h>
-
-namespace WebCore {
-
-ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value)
-{
- return value;
-}
-
-bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject)
-{
- ASSERT(database);
-
- // FIXME: Implement when Database V8 bindings are enabled
- ASSERT_NOT_REACHED();
- quarantinedObject = ScriptObject();
- return false;
-}
-
-bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject)
-{
- ASSERT(frame);
- ASSERT(storage);
-
-#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;
-}
-
-bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject)
-{
- ASSERT(node);
-
- v8::HandleScope handleScope;
- // 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 = V8DOMWrapper::convertNodeToV8Object(node);
- quarantinedObject = ScriptObject(frame->script()->state(), v8::Local<v8::Object>(v8::Object::Cast(*v8Node)));
-
- return true;
-}
-
-bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject)
-{
- ASSERT(domWindow);
-
- v8::HandleScope handleScope;
- 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 = V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, domWindow);
- quarantinedObject = ScriptObject(frame->script()->state(), v8::Local<v8::Object>(v8::Object::Cast(*v8DomWindow)));
-
- return true;
-}
-
-
-} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptScope.cpp b/WebCore/bindings/v8/ScriptScope.cpp
index 52cab10..727ab25 100644
--- a/WebCore/bindings/v8/ScriptScope.cpp
+++ b/WebCore/bindings/v8/ScriptScope.cpp
@@ -36,14 +36,13 @@
#include "Document.h"
#include "Frame.h"
#include "V8Binding.h"
-#include "V8Proxy.h"
#include <v8.h>
namespace WebCore {
ScriptScope::ScriptScope(ScriptState* scriptState, bool reportExceptions)
- : m_context(V8Proxy::context(scriptState->frame()))
+ : m_context(scriptState->context())
, m_scope(m_context)
, m_scriptState(scriptState)
, m_reportExceptions(reportExceptions)
diff --git a/WebCore/bindings/v8/ScriptSourceCode.h b/WebCore/bindings/v8/ScriptSourceCode.h
index fea387a..5c16168 100644
--- a/WebCore/bindings/v8/ScriptSourceCode.h
+++ b/WebCore/bindings/v8/ScriptSourceCode.h
@@ -50,7 +50,7 @@ public:
// Not sure if that matters.
ScriptSourceCode(CachedScript* cs)
: m_source(cs->script())
- , m_url(cs->url())
+ , m_url(ParsedURLString, cs->url())
, m_startLine(1)
{
}
diff --git a/WebCore/bindings/v8/ScriptState.cpp b/WebCore/bindings/v8/ScriptState.cpp
index b9e240c..68593e7 100644
--- a/WebCore/bindings/v8/ScriptState.cpp
+++ b/WebCore/bindings/v8/ScriptState.cpp
@@ -37,15 +37,29 @@
#include "ScriptController.h"
#include <wtf/Assertions.h>
+#include <wtf/StdLibExtras.h>
namespace WebCore {
ScriptState::ScriptState(Frame* frame)
: m_frame(frame)
+ , m_context(v8::Persistent<v8::Context>::New(V8Proxy::mainWorldContext(frame)))
{
}
-ScriptState* scriptStateFromNode(Node* node)
+ScriptState::ScriptState(Frame* frame, v8::Handle<v8::Context> context)
+ : m_frame(frame)
+ , m_context(v8::Persistent<v8::Context>::New(context))
+{
+}
+
+ScriptState::~ScriptState()
+{
+ m_context.Dispose();
+ m_context.Clear();
+}
+
+ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node* node)
{
// This should be never reached with V8 bindings (WebKit only uses it
// for non-JS bindings)
@@ -53,9 +67,17 @@ ScriptState* scriptStateFromNode(Node* node)
return 0;
}
-ScriptState* scriptStateFromPage(Page* page)
+ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page* page)
+{
+ // This should be only reached with V8 bindings from single process layout tests.
+ return page->mainFrame()->script()->mainWorldScriptState();
+}
+
+// FIXME: Stub method so we compile. Currently called from FrameLoader.cpp.
+DOMWrapperWorld* mainThreadNormalWorld()
{
- return page->mainFrame()->script()->state();
+ DEFINE_STATIC_LOCAL(DOMWrapperWorld, oneWorld, ());
+ return &oneWorld;
}
}
diff --git a/WebCore/bindings/v8/ScriptState.h b/WebCore/bindings/v8/ScriptState.h
index 8fbcfa3..12a1388 100644
--- a/WebCore/bindings/v8/ScriptState.h
+++ b/WebCore/bindings/v8/ScriptState.h
@@ -32,16 +32,21 @@
#define ScriptState_h
#include <v8.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
+ class DOMWrapperWorld;
class Node;
class Page;
class Frame;
- class ScriptState {
+ class ScriptState : public Noncopyable {
public:
ScriptState() { }
ScriptState(Frame* frame);
+ ScriptState(Frame* frame, v8::Handle<v8::Context> context);
+ ~ScriptState();
bool hadException() { return !m_exception.IsEmpty(); }
void setException(v8::Local<v8::Value> exception)
@@ -51,14 +56,28 @@ namespace WebCore {
v8::Local<v8::Value> exception() { return m_exception; }
Frame* frame() const { return m_frame; }
+ v8::Local<v8::Context> context() const
+ {
+ return v8::Local<v8::Context>::New(m_context);
+ }
private:
v8::Local<v8::Value> m_exception;
Frame* m_frame;
+ v8::Persistent<v8::Context> m_context;
+ };
+
+ ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
+ ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
+
+ DOMWrapperWorld* mainThreadNormalWorld();
+ inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
+ inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
+
+ // Dummy class to avoid a bunch of ifdef's in WebCore.
+ class DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
};
- ScriptState* scriptStateFromNode(Node*);
- ScriptState* scriptStateFromPage(Page*);
}
#endif // ScriptState_h
diff --git a/WebCore/bindings/v8/ScriptString.h b/WebCore/bindings/v8/ScriptString.h
index fe254a5..414818a 100644
--- a/WebCore/bindings/v8/ScriptString.h
+++ b/WebCore/bindings/v8/ScriptString.h
@@ -32,34 +32,41 @@
#define ScriptString_h
#include "PlatformString.h"
+#include "ScriptStringImpl.h"
+#include "V8Binding.h"
namespace WebCore {
class ScriptString {
public:
- ScriptString() {}
- ScriptString(const String& s) : m_str(s) {}
- ScriptString(const char* s) : m_str(s) {}
+ ScriptString() : m_impl(0) {}
+ ScriptString(const String& s) : m_impl(ScriptStringImpl::create(s)) {}
+ ScriptString(const char* s) : m_impl(ScriptStringImpl::create(s)) {}
- operator String() const { return m_str; }
+ operator String() const { return m_impl->toString(); }
- bool isNull() const { return m_str.isNull(); }
- size_t size() const { return m_str.length(); }
+ bool isNull() const { return !m_impl.get() || m_impl->isNull(); }
+ size_t size() const { return m_impl->size(); }
ScriptString& operator=(const char* s)
{
- m_str = s;
+ m_impl = ScriptStringImpl::create(s);
return *this;
}
ScriptString& operator+=(const String& s)
{
- m_str += s;
+ m_impl->append(s);
return *this;
}
+ v8::Handle<v8::Value> v8StringOrNull() const
+ {
+ return isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(m_impl->v8StringHandle());
+ }
+
private:
- String m_str;
+ RefPtr<ScriptStringImpl> m_impl;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptStringImpl.cpp b/WebCore/bindings/v8/ScriptStringImpl.cpp
new file mode 100644
index 0000000..afe74b1
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptStringImpl.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 "ScriptStringImpl.h"
+
+#include "V8Binding.h"
+
+namespace WebCore {
+
+ScriptStringImpl::ScriptStringImpl(const String& s)
+{
+ v8::HandleScope scope;
+ m_handle.set(v8String(s));
+}
+
+ScriptStringImpl::ScriptStringImpl(const char* s)
+{
+ v8::HandleScope scope;
+ m_handle.set(v8::String::New(s));
+}
+
+String ScriptStringImpl::toString() const
+{
+ return v8StringToWebCoreString(m_handle.get());
+}
+
+bool ScriptStringImpl::isNull() const
+{
+ return m_handle.get().IsEmpty();
+}
+
+size_t ScriptStringImpl::size() const
+{
+ return m_handle.get()->Length();
+}
+
+void ScriptStringImpl::append(const String& s)
+{
+ v8::HandleScope scope;
+ if (m_handle.get().IsEmpty())
+ m_handle.set(v8String(s));
+ else
+ m_handle.set(v8::String::Concat(m_handle.get(), v8String(s)));
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptStringImpl.h b/WebCore/bindings/v8/ScriptStringImpl.h
new file mode 100644
index 0000000..8a47b4f
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptStringImpl.h
@@ -0,0 +1,77 @@
+/*
+ * 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 ScriptStringImpl_h
+#define ScriptStringImpl_h
+
+#include "OwnHandle.h"
+#include "PlatformString.h"
+
+#include <v8.h>
+
+namespace WebCore {
+
+// This class is used for strings that tend to be shared with JavaScript frequently. The JSC implementation uses wtf::UString - see bindings/js/ScriptString.h
+// Currently XMLHttpRequest uses a ScriptString to build up the responseText attribute. As data arrives from the network, it is appended to the ScriptString
+// via operator+= and a JavaScript readystatechange event is fired. JavaScript can access the responseText attribute of the XMLHttpRequest object. JavaScript
+// may also query the responseXML attribute of the XMLHttpRequest object which results in the responseText attribute being coerced into a WebCore::String and
+// then parsed as an XML document.
+// This implementation optimizes for the common case where the responseText is built up with many calls to operator+= before the actual text is queried.
+class ScriptStringImpl : public RefCounted<ScriptStringImpl> {
+public:
+ static PassRefPtr<ScriptStringImpl> create(const String& s)
+ {
+ return adoptRef(new ScriptStringImpl(s));
+ }
+
+ static PassRefPtr<ScriptStringImpl> create(const char* s)
+ {
+ return adoptRef(new ScriptStringImpl(s));
+ }
+
+ String toString() const;
+
+ bool isNull() const;
+ size_t size() const;
+
+ void append(const String& s);
+
+ v8::Handle<v8::String> v8StringHandle() { return m_handle.get(); }
+
+private:
+ ScriptStringImpl(const String& s);
+ ScriptStringImpl(const char* s);
+
+ OwnHandle<v8::String> m_handle;
+};
+
+} // namespace WebCore
+
+#endif // ScriptStringImpl_h
diff --git a/WebCore/bindings/v8/ScriptValue.h b/WebCore/bindings/v8/ScriptValue.h
index 004851b..c0ba8d5 100644
--- a/WebCore/bindings/v8/ScriptValue.h
+++ b/WebCore/bindings/v8/ScriptValue.h
@@ -44,6 +44,11 @@ namespace WebCore {
class ScriptValue {
public:
+ static ScriptValue quarantineValue(ScriptState* scriptState, const ScriptValue& value)
+ {
+ return value;
+ }
+
ScriptValue() {}
ScriptValue(v8::Handle<v8::Value> value)
@@ -110,7 +115,12 @@ public:
{
return m_value->IsUndefined();
}
-
+
+ bool isObject() const
+ {
+ return m_value->IsObject();
+ }
+
bool hasNoValue() const
{
return m_value.IsEmpty();
@@ -128,12 +138,13 @@ public:
m_value.Clear();
}
- ~ScriptValue()
+ virtual ~ScriptValue()
{
clear();
}
v8::Handle<v8::Value> v8Value() const { return m_value; }
+ bool getString(ScriptState*, String& result) const { return getString(result); }
bool getString(String& result) const;
String toString(ScriptState*) const;
diff --git a/WebCore/bindings/v8/SerializedScriptValue.h b/WebCore/bindings/v8/SerializedScriptValue.h
new file mode 100644
index 0000000..26a4199
--- /dev/null
+++ b/WebCore/bindings/v8/SerializedScriptValue.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SerializedScriptValue_h
+#define SerializedScriptValue_h
+
+#include "ScriptValue.h"
+#include "V8Binding.h"
+#include <v8.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class SerializedScriptValue : public RefCounted<SerializedScriptValue> {
+public:
+ static PassRefPtr<SerializedScriptValue> create(String string)
+ {
+ return adoptRef(new SerializedScriptValue(string));
+ }
+
+ static PassRefPtr<SerializedScriptValue> create()
+ {
+ return adoptRef(new SerializedScriptValue());
+ }
+
+ PassRefPtr<SerializedScriptValue> release()
+ {
+ RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data));
+ m_data = String();
+ return result.release();
+ }
+
+ String toString()
+ {
+ return m_data;
+ }
+
+private:
+ SerializedScriptValue(String string)
+ : m_data(string)
+ {
+ }
+
+ SerializedScriptValue() { }
+ String m_data;
+};
+
+} // namespace WebCore
+
+#endif // SerializedScriptValue_h
diff --git a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp b/WebCore/bindings/v8/SharedPersistent.h
index 5fe2710..8825bd5 100644
--- a/WebCore/bindings/v8/custom/V8CanvasPixelArrayCustom.cpp
+++ b/WebCore/bindings/v8/SharedPersistent.h
@@ -28,38 +28,50 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "CanvasPixelArray.h"
+#ifndef SharedPersistent_h
+#define SharedPersistent_h
-#include "V8Binding.h"
-#include "V8CustomBinding.h"
-#include "V8Proxy.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
-// Get the specified value from the pixel buffer and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined".
-INDEXED_PROPERTY_GETTER(CanvasPixelArray)
-{
- INC_STATS("DOM.CanvasPixelArray.IndexedPropertyGetter");
- CanvasPixelArray* pixelBuffer = V8DOMWrapper::convertToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder());
-
- if ((index < 0) || (index >= pixelBuffer->length()))
- return v8::Undefined();
- unsigned char result;
- if (!pixelBuffer->get(index, result))
- return v8::Undefined();
- return v8::Number::New(result);
-}
-
-// Set the specified value in the pixel buffer. Accesses outside the valid pixel buffer range are silently ignored.
-INDEXED_PROPERTY_SETTER(CanvasPixelArray)
-{
- INC_STATS("DOM.CanvasPixelArray.IndexedPropertySetter");
- CanvasPixelArray* pixelBuffer = V8DOMWrapper::convertToNativeObject<CanvasPixelArray>(V8ClassIndex::CANVASPIXELARRAY, info.Holder());
-
- if ((index >= 0) && (index < pixelBuffer->length()))
- pixelBuffer->set(index, value->NumberValue());
- return value;
-}
+ // A shareable reference to a v8 persistent handle. Using a shared
+ // persistent any number of objects can share a reference to a v8
+ // object and when it should no longer be accessible the object's
+ // owner can clear it.
+ template <typename T>
+ class SharedPersistent : public RefCounted<SharedPersistent<T> > {
+ public:
+ void set(v8::Persistent<T> value)
+ {
+ m_value = value;
+ }
+ v8::Persistent<T> get()
+ {
+ return m_value;
+ }
+ void disposeHandle()
+ {
+ if (!m_value.IsEmpty()) {
+ m_value.Dispose();
+ m_value.Clear();
+ }
+ }
+ static PassRefPtr<SharedPersistent<T> > create(v8::Persistent<T> value)
+ {
+ return adoptRef(new SharedPersistent<T>(value));
+ }
+ static PassRefPtr<SharedPersistent<T> > create()
+ {
+ return create(v8::Persistent<T>());
+ }
+ private:
+ explicit SharedPersistent(v8::Persistent<T> value) : m_value(value) { }
+ v8::Persistent<T> m_value;
+ };
} // namespace WebCore
+
+#endif // SharedPersistent_h
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index 0c81846..0f5b5c8 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -31,42 +31,103 @@
#include "config.h"
#include "V8AbstractEventListener.h"
+#include "DateExtension.h"
#include "Document.h"
#include "Event.h"
#include "Frame.h"
-#include "Tokenizer.h"
#include "V8Binding.h"
+#include "V8EventListenerList.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
namespace WebCore {
-V8AbstractEventListener::V8AbstractEventListener(Frame* frame, bool isAttribute)
- : m_isAttribute(isAttribute)
- , m_frame(frame)
- , m_lineNumber(0)
- , m_columnNumber(0)
+static void weakEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
{
- if (!m_frame)
- return;
+ V8AbstractEventListener* listener = static_cast<V8AbstractEventListener*>(parameter);
+ listener->disposeListenerObject();
+}
+
+V8AbstractEventListener::V8AbstractEventListener(bool isAttribute, const WorldContextHandle& worldContext)
+ : EventListener(JSEventListenerType)
+ , m_isWeak(true)
+ , m_isAttribute(isAttribute)
+ , m_worldContext(worldContext)
+{
+}
+
+V8AbstractEventListener::~V8AbstractEventListener()
+{
+ if (!m_listener.IsEmpty()) {
+ v8::HandleScope scope;
+ v8::Local<v8::Object> listener = v8::Local<v8::Object>::New(m_listener);
+ V8EventListenerList::clearWrapper(listener, m_isAttribute);
+ }
+ disposeListenerObject();
+}
+
+void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
+{
+ // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
+ // See issue 889829.
+ RefPtr<V8AbstractEventListener> protect(this);
- // We might be called directly from the parser.
v8::HandleScope handleScope;
- m_context.set(V8Proxy::context(m_frame));
- m_context.makeWeak();
+ v8::Local<v8::Context> v8Context = toV8Context(context, worldContext());
+ if (v8Context.IsEmpty())
+ return;
+
+ // Enter the V8 context in which to perform the event handling.
+ v8::Context::Scope scope(v8Context);
+
+ // Get the V8 wrapper for the event object.
+ v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event);
+
+ invokeEventHandler(context, event, jsEvent);
+
+ Document::updateStyleForAllDocuments();
+}
- // Get the position in the source if any.
- if (m_isAttribute && m_frame->document()->tokenizer()) {
- m_lineNumber = m_frame->document()->tokenizer()->lineNumber();
- m_columnNumber = m_frame->document()->tokenizer()->columnNumber();
+void V8AbstractEventListener::disposeListenerObject()
+{
+ if (!m_listener.IsEmpty()) {
+#ifndef NDEBUG
+ V8GCController::unregisterGlobalHandle(this, m_listener);
+#endif
+ m_listener.Dispose();
+ m_listener.Clear();
}
}
-void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Context, Event* event, v8::Handle<v8::Value> jsEvent, bool isWindowEvent)
+void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener)
+{
+ disposeListenerObject();
+ m_listener = v8::Persistent<v8::Object>::New(listener);
+#ifndef NDEBUG
+ V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
+#endif
+ if (m_isWeak)
+ m_listener.MakeWeak(this, &weakEventListenerCallback);
+}
+
+void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context, Event* event, v8::Handle<v8::Value> jsEvent)
{
+
+ v8::Local<v8::Context> v8Context = toV8Context(context, worldContext());
+ if (v8Context.IsEmpty())
+ return;
+
// 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");
v8::Local<v8::Value> returnValue;
+ // In beforeunload/unload handlers, we want to avoid sleeps which do tight loops of calling Date.getTime().
+ if (event->type() == "beforeunload" || event->type() == "unload")
+ DateExtension::get()->setAllowSleep(false);
+
{
// Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire.
v8::TryCatch tryCatch;
@@ -81,8 +142,15 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte
tryCatch.Reset();
// Call the event handler.
- returnValue = callListenerFunction(jsEvent, event, isWindowEvent);
- tryCatch.Reset();
+ returnValue = callListenerFunction(context, jsEvent, event);
+ if (!tryCatch.CanContinue())
+ return;
+
+ // If an error occurs while handling the event, it should be reported.
+ if (tryCatch.HasCaught()) {
+ reportException(0, tryCatch);
+ tryCatch.Reset();
+ }
// Restore the old event. This must be done for all exit paths through this method.
if (savedEvent.IsEmpty())
@@ -92,6 +160,9 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte
tryCatch.Reset();
}
+ if (event->type() == "beforeunload" || event->type() == "unload")
+ DateExtension::get()->setAllowSleep(true);
+
ASSERT(!V8Proxy::handleOutOfMemory() || returnValue.IsEmpty());
if (returnValue.IsEmpty())
@@ -106,56 +177,11 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte
event->preventDefault();
}
-void V8AbstractEventListener::handleEvent(Event* event, bool isWindowEvent)
-{
- // EventListener could be disconnected from the frame.
- if (disconnected())
- return;
-
- // The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
- // See issue 889829.
- RefPtr<V8AbstractEventListener> protect(this);
-
- LOCK_V8;
- v8::HandleScope handleScope;
-
- 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(v8Context);
-
- // Get the V8 wrapper for the event object.
- v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event);
-
- invokeEventHandler(v8Context, event, jsEvent, isWindowEvent);
-
- Document::updateStyleForAllDocuments();
-}
-
-void V8AbstractEventListener::disposeListenerObject()
-{
- if (!m_listener.IsEmpty()) {
-#ifndef NDEBUG
- V8GCController::unregisterGlobalHandle(this, m_listener);
-#endif
- m_listener.Dispose();
- m_listener.Clear();
- }
-}
-
-v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event, bool isWindowEvent)
+v8::Local<v8::Object> V8AbstractEventListener::getReceiverObject(Event* event)
{
if (!m_listener.IsEmpty() && !m_listener->IsFunction())
return v8::Local<v8::Object>::New(m_listener);
- if (isWindowEvent)
- return v8::Context::GetCurrent()->Global();
-
EventTarget* target = event->currentTarget();
v8::Handle<v8::Value> value = V8DOMWrapper::convertEventTargetToV8Object(target);
if (value.IsEmpty())
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h
index 1521941..0afbed5 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.h
+++ b/WebCore/bindings/v8/V8AbstractEventListener.h
@@ -32,13 +32,17 @@
#define V8AbstractEventListener_h
#include "EventListener.h"
-#include "OwnHandle.h"
+#include "WorldContextHandle.h"
+
#include <v8.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
class Event;
class Frame;
+ class V8Proxy;
// There are two kinds of event listeners: HTML or non-HMTL. onload,
// onfocus, etc (attributes) are always HTML event handler type; Event
@@ -50,54 +54,77 @@ namespace WebCore {
// but ALLOWs duplicated non-HTML event handlers.
class V8AbstractEventListener : public EventListener {
public:
- virtual ~V8AbstractEventListener() { }
+ virtual ~V8AbstractEventListener();
+
+ static const V8AbstractEventListener* cast(const EventListener* listener)
+ {
+ return listener->type() == JSEventListenerType
+ ? static_cast<const V8AbstractEventListener*>(listener)
+ : 0;
+ }
+
+ static V8AbstractEventListener* cast(EventListener* listener)
+ {
+ return const_cast<V8AbstractEventListener*>(cast(const_cast<const EventListener*>(listener)));
+ }
- // Returns the owner frame of the listener.
- Frame* frame() { return m_frame; }
+ // Implementation of EventListener interface.
- virtual void handleEvent(Event*, bool isWindowEvent);
- void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent, bool isWindowEvent);
+ virtual bool operator==(const EventListener& other) { return this == &other; }
+
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+ virtual bool isLazy() const { return false; }
// Returns the listener object, either a function or an object.
- virtual v8::Local<v8::Object> getListenerObject()
+ v8::Local<v8::Object> getListenerObject(ScriptExecutionContext* context)
{
+ prepareListenerObject(context);
return v8::Local<v8::Object>::New(m_listener);
}
+ v8::Local<v8::Object> getExistingListenerObject()
+ {
+ return v8::Local<v8::Object>::New(m_listener);
+ }
+
+ bool hasExistingListenerObject()
+ {
+ return !m_listener.IsEmpty();
+ }
+
// Dispose listener object and clear the handle.
void disposeListenerObject();
- virtual bool disconnected() const { return !m_frame; }
+ protected:
+ V8AbstractEventListener(bool isAttribute, const WorldContextHandle& worldContext);
- virtual bool isObjectListener() const { return false; }
+ virtual void prepareListenerObject(ScriptExecutionContext*) { }
- protected:
- v8::Persistent<v8::Object> m_listener;
+ void setListenerObject(v8::Handle<v8::Object> listener);
- // Indicates if this is an HTML type listener.
- bool m_isAttribute;
+ void invokeEventHandler(ScriptExecutionContext*, Event*, v8::Handle<v8::Value> jsEvent);
+
+ // Get the receiver object to use for event listener call.
+ v8::Local<v8::Object> getReceiverObject(Event*);
+
+ const WorldContextHandle& worldContext() const { return m_worldContext; }
private:
- V8AbstractEventListener(Frame*, bool isInline);
+ // Implementation of EventListener function.
+ virtual bool virtualisAttribute() const { return m_isAttribute; }
- virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*, bool isWindowEvent) = 0;
+ virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsevent, Event*) = 0;
- // Get the receiver object to use for event listener call.
- v8::Local<v8::Object> getReceiverObject(Event*, bool isWindowEvent);
+ v8::Persistent<v8::Object> m_listener;
- // Frame to which the event listener is attached to. An event listener must be destroyed before its owner frame is
- // deleted. See fast/dom/replaceChild.html
- // FIXME: this could hold m_frame live until the event listener is deleted.
- Frame* m_frame;
- OwnHandle<v8::Context> m_context;
+ // Indicates if the above handle is weak.
+ bool m_isWeak;
- // Position in the HTML source for HTML event listeners.
- int m_lineNumber;
- int m_columnNumber;
+ // Indicates if this is an HTML type listener.
+ bool m_isAttribute;
- friend class V8EventListener;
- friend class V8ObjectEventListener;
- friend class V8LazyEventListener;
+ WorldContextHandle m_worldContext;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Binding.cpp b/WebCore/bindings/v8/V8Binding.cpp
index 0da910b..00286e5 100644
--- a/WebCore/bindings/v8/V8Binding.cpp
+++ b/WebCore/bindings/v8/V8Binding.cpp
@@ -33,8 +33,10 @@
#include "AtomicString.h"
#include "CString.h"
+#include "Element.h"
#include "MathExtras.h"
#include "PlatformString.h"
+#include "QualifiedName.h"
#include "StdLibExtras.h"
#include "StringBuffer.h"
#include "StringHash.h"
@@ -55,7 +57,8 @@ public:
#ifndef NDEBUG
m_threadId = WTF::currentThread();
#endif
- v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * length());
+ ASSERT(!string.isNull());
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * string.length());
}
explicit WebCoreStringResource(const AtomicString& string)
@@ -65,7 +68,8 @@ public:
#ifndef NDEBUG
m_threadId = WTF::currentThread();
#endif
- v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * length());
+ ASSERT(!string.isNull());
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * string.length());
}
virtual ~WebCoreStringResource()
@@ -73,18 +77,18 @@ public:
#ifndef NDEBUG
ASSERT(m_threadId == WTF::currentThread());
#endif
- int reducedExternalMemory = -2 * length();
- if (!m_plainString.impl()->inTable())
+ int reducedExternalMemory = -2 * m_plainString.length();
+ if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull())
reducedExternalMemory *= 2;
v8::V8::AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory);
}
- const uint16_t* data() const
+ virtual const uint16_t* data() const
{
- return reinterpret_cast<const uint16_t*>(m_plainString.characters());
+ return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters());
}
- size_t length() const { return m_plainString.length(); }
+ virtual size_t length() const { return m_plainString.impl()->length(); }
String webcoreString() { return m_plainString; }
@@ -95,8 +99,9 @@ public:
#endif
if (m_atomicString.isNull()) {
m_atomicString = AtomicString(m_plainString);
- if (!m_plainString.impl()->inTable())
- v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * length());
+ ASSERT(!m_atomicString.isNull());
+ if (m_plainString.impl() != m_atomicString.impl())
+ v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * m_atomicString.length());
}
return m_atomicString;
}
@@ -121,12 +126,177 @@ private:
#endif
};
-String v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external,
- StringType type)
+
+void* v8DOMWrapperToNative(v8::Handle<v8::Object> object) {
+ return object->GetPointerFromInternalField(V8Custom::kDOMWrapperObjectIndex);
+}
+
+void* v8DOMWrapperToNative(const v8::AccessorInfo& info) {
+ return info.Holder()->GetPointerFromInternalField(V8Custom::kDOMWrapperObjectIndex);
+}
+
+
+String v8ValueToWebCoreString(v8::Handle<v8::Value> value)
+{
+ if (value->IsString())
+ return v8StringToWebCoreString(v8::Handle<v8::String>::Cast(value));
+ return v8NonStringValueToWebCoreString(value);
+}
+
+AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value)
+{
+ if (value->IsString())
+ return v8StringToAtomicWebCoreString(v8::Handle<v8::String>::Cast(value));
+ return v8NonStringValueToAtomicWebCoreString(value);
+}
+
+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();
+}
+
+String toWebCoreString(const v8::Arguments& args, int index) {
+ return v8ValueToWebCoreString(args[index]);
+}
+
+
+String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
+{
+ if (value->IsNull())
+ return String();
+ return v8ValueToWebCoreString(value);
+}
+
+AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
+{
+ if (value->IsNull())
+ return AtomicString();
+ return v8ValueToAtomicWebCoreString(value);
+}
+
+String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value)
+{
+ if (value->IsNull() || value->IsUndefined())
+ return String();
+ return toWebCoreString(value);
+}
+
+bool isUndefinedOrNull(v8::Handle<v8::Value> value)
+{
+ return value->IsNull() || value->IsUndefined();
+}
+
+v8::Handle<v8::Boolean> v8Boolean(bool value)
+{
+ return value ? v8::True() : v8::False();
+}
+
+v8::Handle<v8::String> v8UndetectableString(const String& str)
+{
+ return v8::String::NewUndetectable(fromWebCoreString(str), str.length());
+}
+
+v8::Handle<v8::Value> v8StringOrNull(const String& str)
+{
+ return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str));
+}
+
+v8::Handle<v8::Value> v8StringOrUndefined(const String& str)
+{
+ return str.isNull() ? v8::Handle<v8::Value>(v8::Undefined()) : v8::Handle<v8::Value>(v8String(str));
+}
+
+v8::Handle<v8::Value> v8StringOrFalse(const String& str)
+{
+ return str.isNull() ? v8::Handle<v8::Value>(v8::False()) : v8::Handle<v8::Value>(v8String(str));
+}
+
+
+template <class S> struct StringTraits
+{
+ static S fromStringResource(WebCoreStringResource* resource);
+
+ static S fromV8String(v8::Handle<v8::String> v8String, int length);
+};
+
+template<>
+struct StringTraits<String>
+{
+ static String fromStringResource(WebCoreStringResource* resource)
+ {
+ return resource->webcoreString();
+ }
+
+ static String fromV8String(v8::Handle<v8::String> v8String, int length)
+ {
+ ASSERT(v8String->Length() == length);
+ // NOTE: as of now, String(const UChar*, int) performs String::createUninitialized
+ // anyway, so no need to optimize like we do for AtomicString below.
+ UChar* buffer;
+ String result = String::createUninitialized(length, buffer);
+ v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
+ return result;
+ }
+};
+
+template<>
+struct StringTraits<AtomicString>
+{
+ static AtomicString fromStringResource(WebCoreStringResource* resource)
+ {
+ return resource->atomicString();
+ }
+
+ static AtomicString fromV8String(v8::Handle<v8::String> v8String, int length)
+ {
+ ASSERT(v8String->Length() == length);
+ static const int inlineBufferSize = 16;
+ if (length <= inlineBufferSize) {
+ UChar inlineBuffer[inlineBufferSize];
+ v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length);
+ return AtomicString(inlineBuffer, length);
+ }
+ UChar* buffer;
+ String tmp = String::createUninitialized(length, buffer);
+ v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
+ return AtomicString(tmp);
+ }
+};
+
+template <typename StringType>
+StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external)
{
WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String);
if (stringResource)
- return stringResource->webcoreString();
+ return StringTraits<StringType>::fromStringResource(stringResource);
int length = v8String->Length();
if (!length) {
@@ -134,44 +304,27 @@ String v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode ext
return StringImpl::empty();
}
- UChar* buffer;
- String result = String::createUninitialized(length, buffer);
- v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
+ StringType result(StringTraits<StringType>::fromV8String(v8String, length));
- if (type == AtomicStringType)
- result = AtomicString(result);
-
- if (external == Externalize) {
- WebCoreStringResource* resource = new WebCoreStringResource(result);
- if (!v8String->MakeExternal(resource)) {
+ if (external == Externalize && v8String->CanMakeExternal()) {
+ stringResource = new WebCoreStringResource(result);
+ if (!v8String->MakeExternal(stringResource)) {
// In case of a failure delete the external resource as it was not used.
- delete resource;
+ delete stringResource;
}
}
return result;
}
+
+// Explicitly instantiate the above template with the expected parameterizations,
+// to ensure the compiler generates the code; otherwise link errors can result in GCC 4.4.
+template String v8StringToWebCoreString<String>(v8::Handle<v8::String>, ExternalMode);
+template AtomicString v8StringToWebCoreString<AtomicString>(v8::Handle<v8::String>, ExternalMode);
-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)
+String v8NonStringValueToWebCoreString(v8::Handle<v8::Value> object)
{
- if (object->IsString())
- return v8StringToWebCoreString(v8::Handle<v8::String>::Cast(object), Externalize, PlainStringType);
-
+ ASSERT(!object->IsString());
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.
@@ -197,20 +350,13 @@ String v8ValueToWebCoreString(v8::Handle<v8::Value> object)
throwError(block.Exception());
return StringImpl::empty();
}
- return v8StringToWebCoreString(v8String, DoNotExternalize, PlainStringType);
+ return v8StringToWebCoreString<String>(v8String, DoNotExternalize);
}
-AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> v8Value)
+AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value> object)
{
- 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);
+ ASSERT(!object->IsString());
+ return AtomicString(v8NonStringValueToWebCoreString(object));
}
static bool stringImplCacheEnabled = false;
@@ -251,17 +397,17 @@ static void cachedStringCallback(v8::Persistent<v8::Value> wrapper, void* parame
v8::Local<v8::String> v8ExternalString(const String& string)
{
- if (!string.length())
+ StringImpl* stringImpl = string.impl();
+ if (!stringImpl || !stringImpl->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);
+ return v8::Local<v8::String>::New(v8::Handle<v8::String>(cachedV8String));
v8::Local<v8::String> newString = makeExternalString(string);
if (newString.IsEmpty())
@@ -277,5 +423,65 @@ v8::Local<v8::String> v8ExternalString(const String& string)
return newString;
}
+
+v8::Persistent<v8::FunctionTemplate> createRawTemplate()
+{
+ v8::HandleScope scope;
+ v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(V8Proxy::checkNewLegal);
+ return v8::Persistent<v8::FunctionTemplate>::New(result);
+}
+
+v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>desc,
+ const char *interfaceName,
+ V8ClassIndex::V8WrapperType parentClassIndex,
+ int fieldCount,
+ const BatchedAttribute* attributes,
+ size_t attributeCount,
+ const BatchedCallback* callbacks,
+ size_t callbackCount)
+{
+ desc->SetClassName(v8::String::New(interfaceName));
+ v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
+ instance->SetInternalFieldCount(fieldCount);
+ if (parentClassIndex)
+ desc->Inherit(V8DOMWrapper::getTemplate(parentClassIndex));
+ if (attributeCount)
+ batchConfigureAttributes(instance, desc->PrototypeTemplate(),
+ attributes, attributeCount);
+ v8::Local<v8::Signature> defaultSignature = v8::Signature::New(desc);
+ if (callbackCount)
+ batchConfigureCallbacks(desc->PrototypeTemplate(),
+ defaultSignature,
+ static_cast<v8::PropertyAttribute>(v8::DontDelete),
+ callbacks, callbackCount);
+ return defaultSignature;
+}
+
+void createCallback(v8::Local<v8::ObjectTemplate> proto,
+ const char *name,
+ v8::InvocationCallback callback,
+ v8::Handle<v8::Signature> signature,
+ v8::PropertyAttribute attribute)
+{
+ proto->Set(v8::String::New(name),
+ v8::FunctionTemplate::New(callback, v8::Handle<v8::Value>(), signature),
+ attribute);
+}
+
+v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo& info,
+ const QualifiedName& name)
+{
+ Element *imp = v8DOMWrapperToNode<Element>(info);
+ return v8ExternalString(imp->getAttribute(name));
+}
+
+void setElementStringAttr(const v8::AccessorInfo& info,
+ const QualifiedName& name,
+ v8::Local<v8::Value> value)
+{
+ Element* imp = v8DOMWrapperToNode<Element>(info);
+ AtomicString v = toAtomicWebCoreStringWithNullCheck(value);
+ imp->setAttribute(name, v);
+}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Binding.h b/WebCore/bindings/v8/V8Binding.h
index 4f36f00..de5bb4c 100644
--- a/WebCore/bindings/v8/V8Binding.h
+++ b/WebCore/bindings/v8/V8Binding.h
@@ -31,46 +31,122 @@
#ifndef V8Binding_h
#define V8Binding_h
+#include "AtomicString.h"
#include "MathExtras.h"
#include "PlatformString.h"
+#include "V8DOMWrapper.h"
+#include "V8Index.h"
#include <v8.h>
namespace WebCore {
+
+ class EventListener;
+ class EventTarget;
+
+ // A helper function extract native object pointer from a DOM wrapper
+ // and cast to the specified type.
+ void* v8DOMWrapperToNative(v8::Handle<v8::Object>);
+
+ template <class C>
+ C* v8DOMWrapperTo(v8::Handle<v8::Object> object)
+ {
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
+ return reinterpret_cast<C*>(v8DOMWrapperToNative(object));
+ }
+ template <class C>
+ C* v8DOMWrapperToNode(v8::Handle<v8::Object> object)
+ {
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(object));
+ ASSERT(V8DOMWrapper::domWrapperType(object) == V8ClassIndex::NODE);
+ return reinterpret_cast<C*>(v8DOMWrapperToNative(object));
+ }
+
+ void* v8DOMWrapperToNative(const v8::AccessorInfo&);
+
+ template <class C>
+ C* v8DOMWrapperTo(const v8::AccessorInfo& info) {
+ ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder()));
+ return reinterpret_cast<C*>(v8DOMWrapperToNative(info));
+ }
+ template <class C>
+ C* v8DOMWrapperToNode(const v8::AccessorInfo& info) {
+ ASSERT(V8DOMWrapper::domWrapperType(info.Holder()) == V8ClassIndex::NODE);
+ return reinterpret_cast<C*>(v8DOMWrapperToNative(info));
+ }
+
+ template <class C>
+ C* v8DOMWrapperTo(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(V8DOMWrapper::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 v8DOMWrapperTo<C>(object);
+ }
+
+ template <class C>
+ C* v8DOMWrapperTo(V8ClassIndex::V8WrapperType type, const v8::AccessorInfo& info)
+ {
+#ifndef NDEBUG
+ return v8DOMWrapperTo<C>(type, info.Holder());
+#else
+ return reinterpret_cast<C*>(v8DOMWrapperToNative(info));
+#endif
+ }
+
enum ExternalMode {
Externalize,
DoNotExternalize
};
-
- enum StringType {
- PlainStringType,
- AtomicStringType
- };
+
+ template <typename StringType>
+ StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external);
// 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>);
+ inline String v8StringToWebCoreString(v8::Handle<v8::String> v8String)
+ {
+ return v8StringToWebCoreString<String>(v8String, Externalize);
+ }
+ String v8NonStringValueToWebCoreString(v8::Handle<v8::Value>);
+ String v8ValueToWebCoreString(v8::Handle<v8::Value> 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;
+ inline AtomicString v8StringToAtomicWebCoreString(v8::Handle<v8::String> v8String)
+ {
+ return v8StringToWebCoreString<AtomicString>(v8String, Externalize);
}
+ AtomicString v8NonStringValueToAtomicWebCoreString(v8::Handle<v8::Value>);
+ AtomicString v8ValueToAtomicWebCoreString(v8::Handle<v8::Value> value);
// 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&);
+ // Convert a string to a V8 string.
+ inline v8::Handle<v8::String> v8String(const String& string)
+ {
+ return v8ExternalString(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.
@@ -78,38 +154,7 @@ namespace WebCore {
// 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();
- }
+ int toInt32(v8::Handle<v8::Value> value, bool& ok);
// Convert a value to a 32-bit integer assuming the conversion cannot fail.
inline int toInt32(v8::Handle<v8::Value> value)
@@ -128,6 +173,8 @@ namespace WebCore {
{
return v8ValueToWebCoreString(object);
}
+
+ String toWebCoreString(const v8::Arguments&, int index);
// The string returned by this function is still owned by the argument
// and will be deallocated when the argument is deallocated.
@@ -136,49 +183,78 @@ namespace WebCore {
return reinterpret_cast<const uint16_t*>(str.characters());
}
- inline bool isUndefinedOrNull(v8::Handle<v8::Value> value)
- {
- return value->IsNull() || value->IsUndefined();
- }
+ bool isUndefinedOrNull(v8::Handle<v8::Value> value);
- inline v8::Handle<v8::Boolean> v8Boolean(bool value)
- {
- return value ? v8::True() : v8::False();
- }
-
- inline String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value)
- {
- if (value->IsNull())
- return String();
- return v8ValueToWebCoreString(value);
- }
+ v8::Handle<v8::Boolean> v8Boolean(bool value);
- inline String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value)
- {
- if (value->IsNull() || value->IsUndefined())
- return String();
- return toWebCoreString(value);
- }
+ String toWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
+
+ AtomicString toAtomicWebCoreStringWithNullCheck(v8::Handle<v8::Value> value);
+
+ String toWebCoreStringWithNullOrUndefinedCheck(v8::Handle<v8::Value> value);
- inline v8::Handle<v8::String> v8UndetectableString(const String& str)
- {
- return v8::String::NewUndetectable(fromWebCoreString(str), str.length());
- }
+ v8::Handle<v8::String> v8UndetectableString(const String& str);
- inline v8::Handle<v8::Value> v8StringOrNull(const String& str)
- {
- return str.isNull() ? v8::Handle<v8::Value>(v8::Null()) : v8::Handle<v8::Value>(v8String(str));
- }
+ v8::Handle<v8::Value> v8StringOrNull(const String& 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));
- }
+ v8::Handle<v8::Value> v8StringOrUndefined(const String& str);
+
+ v8::Handle<v8::Value> v8StringOrFalse(const String& str);
+
+ v8::Persistent<v8::FunctionTemplate> createRawTemplate();
+
+ struct BatchedAttribute;
+ struct BatchedCallback;
+
+ v8::Local<v8::Signature> configureTemplate(v8::Persistent<v8::FunctionTemplate>,
+ const char *interfaceName,
+ V8ClassIndex::V8WrapperType parentClassIndex,
+ int fieldCount,
+ const BatchedAttribute*,
+ size_t attributeCount,
+ const BatchedCallback*,
+ size_t callbackCount);
+
+ void createCallback(v8::Local<v8::ObjectTemplate> proto,
+ const char *name,
+ v8::InvocationCallback,
+ v8::Handle<v8::Signature>,
+ v8::PropertyAttribute attributes = v8::DontDelete);
+
+ v8::Handle<v8::Value> getElementStringAttr(const v8::AccessorInfo&,
+ const QualifiedName&);
+ void setElementStringAttr(const v8::AccessorInfo&,
+ const QualifiedName&,
+ v8::Local<v8::Value>);
+
+ v8::Handle<v8::Value> getElementEventHandlerAttr(const v8::AccessorInfo&,
+ const AtomicString&);
+
+ // V8Parameter is an adapter class that converts V8 values to Strings
+ // or AtomicStrings as appropriate, using multiple typecast operators.
+ enum V8ParameterMode {
+ DefaultMode,
+ WithNullCheck,
+ WithUndefinedOrNullCheck
+ };
+ template <V8ParameterMode MODE = DefaultMode>
+ class V8Parameter {
+ public:
+ V8Parameter (v8::Local<v8::Value> object) :m_v8Object(object) { }
+ operator String();
+ operator AtomicString();
+ private:
+ v8::Local<v8::Value> m_v8Object;
+ };
+
+ template<> inline V8Parameter<DefaultMode>::operator String() { return toWebCoreString(m_v8Object); }
+ template<> inline V8Parameter<WithNullCheck>::operator String() { return toWebCoreStringWithNullCheck(m_v8Object); }
+ template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator String() { return toWebCoreStringWithNullOrUndefinedCheck(m_v8Object); }
+
+ template<> inline V8Parameter<DefaultMode>::operator AtomicString() { return v8ValueToAtomicWebCoreString(m_v8Object); }
+ template<> inline V8Parameter<WithNullCheck>::operator AtomicString() { return toAtomicWebCoreStringWithNullCheck(m_v8Object); }
+ template<> inline V8Parameter<WithUndefinedOrNullCheck>::operator AtomicString() { return toAtomicWebCoreStringWithNullCheck(m_v8Object); }
- 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.h b/WebCore/bindings/v8/V8Collection.h
index cbfe921..0a4134e 100644
--- a/WebCore/bindings/v8/V8Collection.h
+++ b/WebCore/bindings/v8/V8Collection.h
@@ -41,7 +41,7 @@ namespace WebCore {
// FIXME: These functions should be named using to* since they return the item (get* is used for method that take a ref param).
// See https://bugs.webkit.org/show_bug.cgi?id=24664.
- static v8::Handle<v8::Value> getV8Object(void* implementation, v8::Local<v8::Value> implementationType)
+ inline v8::Handle<v8::Value> getV8Object(void* implementation, v8::Local<v8::Value> implementationType)
{
if (!implementation)
return v8::Handle<v8::Value>();
@@ -177,6 +177,18 @@ namespace WebCore {
}
+ // A template for indexed getters on collections of strings.
+ template<class Collection> static v8::Handle<v8::Value> collectionStringIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
+ {
+ // FIXME: assert that object must be a collection type
+ 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 v8String(result);
+ }
+
+
// Add indexed getter to the function template for a collection.
template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc, V8ClassIndex::V8WrapperType type)
{
@@ -208,6 +220,13 @@ namespace WebCore {
desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>);
}
+
+ // Add indexed getter returning a string to a function template for a collection.
+ template<class Collection> static void setCollectionStringIndexedGetter(v8::Handle<v8::FunctionTemplate> desc)
+ {
+ desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>);
+ }
+
v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value>, HTMLSelectElement*);
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMMap.cpp b/WebCore/bindings/v8/V8DOMMap.cpp
index 1bd68f7..acd88ec 100644
--- a/WebCore/bindings/v8/V8DOMMap.cpp
+++ b/WebCore/bindings/v8/V8DOMMap.cpp
@@ -34,6 +34,7 @@
#include "DOMData.h"
#include "DOMDataStore.h"
#include "DOMObjectsInclude.h"
+#include "MainThreadDOMData.h"
#include "ScopedDOMDataStore.h"
namespace WebCore {
@@ -47,33 +48,49 @@ DOMDataStoreHandle::~DOMDataStoreHandle()
{
}
+static bool fasterDOMStoreAccess = false;
+
+static inline DOMDataStore& getDOMDataStore()
+{
+ if (LIKELY(fasterDOMStoreAccess)) {
+ ASSERT(WTF::isMainThread());
+ return MainThreadDOMData::getCurrentMainThreadStore();
+ }
+
+ return DOMData::getCurrent()->getStore();
+}
+
+void enableFasterDOMStoreAccess()
+{
+ fasterDOMStoreAccess = true;
+}
+
DOMWrapperMap<Node>& getDOMNodeMap()
{
- // Nodes only exist on the main thread.
- return DOMData::getCurrentMainThread()->getStore().domNodeMap();
+ return getDOMDataStore().domNodeMap();
}
DOMWrapperMap<void>& getDOMObjectMap()
{
- return DOMData::getCurrent()->getStore().domObjectMap();
+ return getDOMDataStore().domObjectMap();
}
DOMWrapperMap<void>& getActiveDOMObjectMap()
{
- return DOMData::getCurrent()->getStore().activeDomObjectMap();
+ return getDOMDataStore().activeDomObjectMap();
}
#if ENABLE(SVG)
DOMWrapperMap<SVGElementInstance>& getDOMSVGElementInstanceMap()
{
- return DOMData::getCurrent()->getStore().domSvgElementInstanceMap();
+ return getDOMDataStore().domSvgElementInstanceMap();
}
// Map of SVG objects with contexts to V8 objects
DOMWrapperMap<void>& getDOMSVGObjectWithContextMap()
{
- return DOMData::getCurrent()->getStore().domSvgObjectWithContextMap();
+ return getDOMDataStore().domSvgObjectWithContextMap();
}
#endif // ENABLE(SVG)
diff --git a/WebCore/bindings/v8/V8DOMMap.h b/WebCore/bindings/v8/V8DOMMap.h
index 754ac3a..b6861d4 100644
--- a/WebCore/bindings/v8/V8DOMMap.h
+++ b/WebCore/bindings/v8/V8DOMMap.h
@@ -140,6 +140,8 @@ namespace WebCore {
DOMWrapperMap<void>& getDOMSVGObjectWithContextMap();
void visitDOMSVGObjectsInCurrentThread(DOMWrapperMap<void>::Visitor*);
#endif
+
+ void enableFasterDOMStoreAccess();
} // namespace WebCore
#endif // V8DOMMap_h
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index 8a9741a..6a691a9 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -31,21 +31,33 @@
#include "config.h"
#include "V8DOMWrapper.h"
+#include "CSSMutableStyleDeclaration.h"
+// ANDROID: Upstream CHROMIUM guard.
#if PLATFORM(CHROMIUM)
#include "ChromiumBridge.h"
#endif
-#include "CSSMutableStyleDeclaration.h"
#include "DOMObjectsInclude.h"
#include "DocumentLoader.h"
#include "FrameLoaderClient.h"
+#include "Notification.h"
+// ANDROID: Upstream SVG guard.
+#if ENABLE(SVG)
+#include "SVGElementInstance.h"
+#endif
#include "ScriptController.h"
+#include "V8AbstractEventListener.h"
#include "V8Binding.h"
#include "V8Collection.h"
#include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
#include "V8DOMMap.h"
#include "V8DOMWindow.h"
+#include "V8EventListenerList.h"
#include "V8Index.h"
#include "V8IsolatedWorld.h"
+#include "V8Proxy.h"
+#include "WebGLArray.h"
+#include "WebGLUniformLocation.h"
#include "WorkerContextExecutionProxy.h"
#include <algorithm>
@@ -145,11 +157,64 @@ v8::Handle<v8::Value> V8DOMWrapper::convertSVGObjectWithContextToV8Object(V8Clas
#endif
+#if ENABLE(3D_CANVAS)
+void V8DOMWrapper::setIndexedPropertiesToExternalArray(v8::Handle<v8::Object> wrapper,
+ int index,
+ void* address,
+ int length)
+{
+ v8::ExternalArrayType array_type = v8::kExternalByteArray;
+ V8ClassIndex::V8WrapperType classIndex = V8ClassIndex::FromInt(index);
+ switch (classIndex) {
+ case V8ClassIndex::WEBGLBYTEARRAY:
+ array_type = v8::kExternalByteArray;
+ break;
+ case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY:
+ array_type = v8::kExternalUnsignedByteArray;
+ break;
+ case V8ClassIndex::WEBGLSHORTARRAY:
+ array_type = v8::kExternalShortArray;
+ break;
+ case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY:
+ array_type = v8::kExternalUnsignedShortArray;
+ break;
+ case V8ClassIndex::WEBGLINTARRAY:
+ array_type = v8::kExternalIntArray;
+ break;
+ case V8ClassIndex::WEBGLUNSIGNEDINTARRAY:
+ array_type = v8::kExternalUnsignedIntArray;
+ break;
+ case V8ClassIndex::WEBGLFLOATARRAY:
+ array_type = v8::kExternalFloatArray;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ wrapper->SetIndexedPropertiesToExternalArrayData(address,
+ array_type,
+ length);
+}
+#endif
+
bool V8DOMWrapper::domObjectHasJSWrapper(void* object)
{
return getDOMObjectMap().contains(object) || getActiveDOMObjectMap().contains(object);
}
+v8::Persistent<v8::Object> V8DOMWrapper::jsWrapperForDOMObject(void* object)
+{
+ v8::Persistent<v8::Object> wrapper = getDOMObjectMap().get(object);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+}
+
+v8::Persistent<v8::Object> V8DOMWrapper::jsWrapperForActiveDOMObject(void* object)
+{
+ v8::Persistent<v8::Object> wrapper = getActiveDOMObjectMap().get(object);
+ ASSERT(!wrapper.IsEmpty());
+ return wrapper;
+}
+
// The caller must have increased obj's ref count.
void V8DOMWrapper::setJSWrapperForDOMObject(void* object, v8::Persistent<v8::Object> wrapper)
{
@@ -217,7 +282,7 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
// 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);
+ setCollectionStringIndexedGetter<CSSStyleDeclaration>(descriptor);
break;
case V8ClassIndex::CSSRULELIST:
setCollectionIndexedGetter<CSSRuleList, CSSRule>(descriptor, V8ClassIndex::CSSRULE);
@@ -226,7 +291,7 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
setCollectionIndexedGetter<CSSValueList, CSSValue>(descriptor, V8ClassIndex::CSSVALUE);
break;
case V8ClassIndex::CSSVARIABLESDECLARATION:
- setCollectionStringOrNullIndexedGetter<CSSVariablesDeclaration>(descriptor);
+ setCollectionStringIndexedGetter<CSSVariablesDeclaration>(descriptor);
break;
case V8ClassIndex::WEBKITCSSTRANSFORMVALUE:
setCollectionIndexedGetter<WebKitCSSTransformValue, CSSValue>(descriptor, V8ClassIndex::CSSVALUE);
@@ -308,10 +373,15 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
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));
+ case V8ClassIndex::NAMEDNODEMAP: {
+ // 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::kNamedNodeMapInternalFieldCount);
+ instanceTemplate->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(NamedNodeMap));
+ 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);
@@ -337,6 +407,7 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
descriptor->PrototypeTemplate()->SetNamedPropertyHandler(USE_NAMED_PROPERTY_GETTER(DOMWindow));
descriptor->PrototypeTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(DOMWindow));
+ descriptor->PrototypeTemplate()->SetInternalFieldCount(V8Custom::kDOMWindowInternalFieldCount);
descriptor->SetHiddenPrototype(true);
@@ -381,6 +452,24 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
break;
}
+#if ENABLE(NOTIFICATIONS)
+ case V8ClassIndex::NOTIFICATION: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kNotificationInternalFieldCount);
+ break;
+ }
+#endif // NOTIFICATIONS
+
+#if ENABLE(SVG)
+ case V8ClassIndex::SVGELEMENTINSTANCE: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kSVGElementInstanceInternalFieldCount);
+ break;
+ }
+#endif
+
#if ENABLE(WORKERS)
case V8ClassIndex::ABSTRACTWORKER: {
// Reserve one more internal field for keeping event listeners.
@@ -415,6 +504,24 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
#endif // WORKERS
+#if ENABLE(SHARED_WORKERS)
+ case V8ClassIndex::SHAREDWORKER: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kSharedWorkerInternalFieldCount);
+ descriptor->SetCallHandler(USE_CALLBACK(SharedWorkerConstructor));
+ break;
+ }
+
+ case V8ClassIndex::SHAREDWORKERCONTEXT: {
+ // Reserve internal fields for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ ASSERT(instanceTemplate->InternalFieldCount() == V8Custom::kDefaultWrapperInternalFieldCount);
+ instanceTemplate->SetInternalFieldCount(V8Custom::kSharedWorkerContextInternalFieldCount);
+ break;
+ }
+#endif // SHARED_WORKERS
+
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
case V8ClassIndex::DOMAPPLICATIONCACHE: {
// Reserve one more internal field for keeping event listeners.
@@ -424,20 +531,35 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
}
#endif
+#if ENABLE(3D_CANVAS)
// The following objects are created from JavaScript.
- case V8ClassIndex::DOMPARSER:
- descriptor->SetCallHandler(USE_CALLBACK(DOMParserConstructor));
+ case V8ClassIndex::WEBGLARRAYBUFFER:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLArrayBufferConstructor));
break;
-#if ENABLE(VIDEO)
- case V8ClassIndex::HTMLAUDIOELEMENT:
- descriptor->SetCallHandler(USE_CALLBACK(HTMLAudioElementConstructor));
+ case V8ClassIndex::WEBGLBYTEARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLByteArrayConstructor));
break;
-#endif
- case V8ClassIndex::HTMLIMAGEELEMENT:
- descriptor->SetCallHandler(USE_CALLBACK(HTMLImageElementConstructor));
+ case V8ClassIndex::WEBGLFLOATARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLFloatArrayConstructor));
+ break;
+ case V8ClassIndex::WEBGLINTARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLIntArrayConstructor));
break;
- case V8ClassIndex::HTMLOPTIONELEMENT:
- descriptor->SetCallHandler(USE_CALLBACK(HTMLOptionElementConstructor));
+ case V8ClassIndex::WEBGLSHORTARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLShortArrayConstructor));
+ break;
+ case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLUnsignedByteArrayConstructor));
+ break;
+ case V8ClassIndex::WEBGLUNSIGNEDINTARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLUnsignedIntArrayConstructor));
+ break;
+ case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY:
+ descriptor->SetCallHandler(USE_CALLBACK(WebGLUnsignedShortArrayConstructor));
+ break;
+#endif
+ case V8ClassIndex::DOMPARSER:
+ descriptor->SetCallHandler(USE_CALLBACK(DOMParserConstructor));
break;
case V8ClassIndex::WEBKITCSSMATRIX:
descriptor->SetCallHandler(USE_CALLBACK(WebKitCSSMatrixConstructor));
@@ -445,6 +567,15 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
case V8ClassIndex::WEBKITPOINT:
descriptor->SetCallHandler(USE_CALLBACK(WebKitPointConstructor));
break;
+#if ENABLE(WEB_SOCKETS)
+ case V8ClassIndex::WEBSOCKET: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
+ instanceTemplate->SetInternalFieldCount(V8Custom::kWebSocketInternalFieldCount);
+ descriptor->SetCallHandler(USE_CALLBACK(WebSocketConstructor));
+ break;
+ }
+#endif
case V8ClassIndex::XMLSERIALIZER:
descriptor->SetCallHandler(USE_CALLBACK(XMLSerializerConstructor));
break;
@@ -461,18 +592,20 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
instanceTemplate->SetInternalFieldCount(V8Custom::kXMLHttpRequestInternalFieldCount);
break;
}
+// ANDROID: Upstream XPATH guard.
#if ENABLE(XPATH)
case V8ClassIndex::XPATHEVALUATOR:
descriptor->SetCallHandler(USE_CALLBACK(XPathEvaluatorConstructor));
break;
#endif
+// ANDROID: Upstream XSLT guard.
#if ENABLE(XSLT)
case V8ClassIndex::XSLTPROCESSOR:
descriptor->SetCallHandler(USE_CALLBACK(XSLTProcessorConstructor));
break;
#endif
+// ANDROID: Upstream TOUCH_EVENTS.
#if ENABLE(TOUCH_EVENTS)
- // TODO(andreip): upstream touch related changes to Chromium
case V8ClassIndex::TOUCHLIST: {
v8::Local<v8::ObjectTemplate> instanceTemplate = descriptor->InstanceTemplate();
instanceTemplate->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(TouchList));
@@ -482,6 +615,9 @@ v8::Persistent<v8::FunctionTemplate> V8DOMWrapper::getTemplate(V8ClassIndex::V8W
case V8ClassIndex::CLIENTRECTLIST:
descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(ClientRectList));
break;
+ case V8ClassIndex::FILELIST:
+ descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(FileList));
+ break;
#if ENABLE(DATAGRID)
case V8ClassIndex::DATAGRIDCOLUMNLIST:
descriptor->InstanceTemplate()->SetIndexedPropertyHandler(USE_INDEXED_PROPERTY_GETTER(DataGridColumnList));
@@ -562,6 +698,7 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp
// These objects can be constructed under WorkerContextExecutionProxy. They need special
// handling, since if we proceed below V8Proxy::retrieve() will get called and will crash.
+ // TODO(ukai): websocket?
if ((type == V8ClassIndex::DOMCOREEXCEPTION
|| type == V8ClassIndex::RANGEEXCEPTION
|| type == V8ClassIndex::EVENTEXCEPTION
@@ -587,6 +724,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp
return convertStyleSheetToV8Object(static_cast<StyleSheet*>(impl));
case V8ClassIndex::DOMWINDOW:
return convertWindowToV8Object(static_cast<DOMWindow*>(impl));
+ case V8ClassIndex::NAMEDNODEMAP:
+ return convertNamedNodeMapToV8Object(static_cast<NamedNodeMap*>(impl));
#if ENABLE(SVG)
SVG_NONNODE_TYPES(MAKE_CASE)
if (type == V8ClassIndex::SVGELEMENTINSTANCE)
@@ -609,6 +748,27 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp
// Non DOM node
v8::Persistent<v8::Object> result = isActiveDomObject ? getActiveDOMObjectMap().get(impl) : getDOMObjectMap().get(impl);
if (result.IsEmpty()) {
+#if ENABLE(3D_CANVAS)
+ if (type == V8ClassIndex::WEBGLARRAY && impl) {
+ // Determine which subclass we are wrapping.
+ WebGLArray* array = reinterpret_cast<WebGLArray*>(impl);
+ if (array->isByteArray())
+ type = V8ClassIndex::WEBGLBYTEARRAY;
+ else if (array->isFloatArray())
+ type = V8ClassIndex::WEBGLFLOATARRAY;
+ else if (array->isIntArray())
+ type = V8ClassIndex::WEBGLINTARRAY;
+ else if (array->isShortArray())
+ type = V8ClassIndex::WEBGLSHORTARRAY;
+ else if (array->isUnsignedByteArray())
+ type = V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY;
+ else if (array->isUnsignedIntArray())
+ type = V8ClassIndex::WEBGLUNSIGNEDINTARRAY;
+ else if (array->isUnsignedShortArray())
+ type = V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY;
+ }
+#endif
+
v8::Local<v8::Object> v8Object = instantiateV8Object(type, type, impl);
if (!v8Object.IsEmpty()) {
// Go through big switch statement, it has some duplications
@@ -632,6 +792,28 @@ v8::Handle<v8::Value> V8DOMWrapper::convertToV8Object(V8ClassIndex::V8WrapperTyp
result->SetIndexedPropertiesToPixelData(pixels->data()->data(), pixels->length());
}
+#if ENABLE(3D_CANVAS)
+ // Set up WebGLArray subclasses' accesses similarly.
+ switch (type) {
+ case V8ClassIndex::WEBGLBYTEARRAY:
+ case V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY:
+ case V8ClassIndex::WEBGLSHORTARRAY:
+ case V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY:
+ case V8ClassIndex::WEBGLINTARRAY:
+ case V8ClassIndex::WEBGLUNSIGNEDINTARRAY:
+ case V8ClassIndex::WEBGLFLOATARRAY: {
+ WebGLArray* array = reinterpret_cast<WebGLArray*>(impl);
+ setIndexedPropertiesToExternalArray(result,
+ V8ClassIndex::ToInt(type),
+ array->baseAddress(),
+ array->length());
+ break;
+ }
+ default:
+ break;
+ }
+#endif
+
// 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
@@ -766,13 +948,6 @@ v8::Local<v8::Object> V8DOMWrapper::instantiateV8Object(V8Proxy* proxy, V8ClassI
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)
{
@@ -951,7 +1126,7 @@ V8ClassIndex::V8WrapperType V8DOMWrapper::htmlElementType(HTMLElement* element)
#define FOR_EACH_ANIMATION_TAG(macro)
#endif
-#if ENABLE(SVG_FILTERS)
+#if ENABLE(SVG) && ENABLE(FILTERS)
#define FOR_EACH_FILTERS_TAG(macro) \
macro(feBlend, FEBLEND) \
macro(feColorMatrix, FECOLORMATRIX) \
@@ -982,7 +1157,6 @@ V8ClassIndex::V8WrapperType V8DOMWrapper::htmlElementType(HTMLElement* element)
#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) \
@@ -1088,8 +1262,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event)
type = V8ClassIndex::MOUSEEVENT;
else if (event->isWheelEvent())
type = V8ClassIndex::WHEELEVENT;
+// ANDROID: Upstream TOUCH_EVENTS.
#if ENABLE(TOUCH_EVENTS)
- // TODO(andreip): upstream touch related changes to WebKit
else if (event->isTouchEvent())
type = V8ClassIndex::TOUCHEVENT;
#endif
@@ -1097,6 +1271,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event)
else if (event->isSVGZoomEvent())
type = V8ClassIndex::SVGZOOMEVENT;
#endif
+ else if (event->isCompositionEvent())
+ type = V8ClassIndex::COMPOSITIONEVENT;
else
type = V8ClassIndex::UIEVENT;
} else if (event->isMutationEvent())
@@ -1105,6 +1281,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event)
type = V8ClassIndex::OVERFLOWEVENT;
else if (event->isMessageEvent())
type = V8ClassIndex::MESSAGEEVENT;
+ else if (event->isPageTransitionEvent())
+ type = V8ClassIndex::PAGETRANSITIONEVENT;
else if (event->isProgressEvent()) {
if (event->isXMLHttpRequestProgressEvent())
type = V8ClassIndex::XMLHTTPREQUESTPROGRESSEVENT;
@@ -1122,6 +1300,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventToV8Object(Event* event)
else if (event->isStorageEvent())
type = V8ClassIndex::STORAGEEVENT;
#endif
+ else if (event->isBeforeLoadEvent())
+ type = V8ClassIndex::BEFORELOADEVENT;
v8::Handle<v8::Object> result = instantiateV8Object(type, V8ClassIndex::EVENT, event);
@@ -1155,30 +1335,47 @@ static const V8ClassIndex::V8WrapperType mapping[] = {
V8ClassIndex::NODE, // XPATH_NAMESPACE_NODE
};
-// Caller checks node is not null.
-v8::Handle<v8::Value> V8DOMWrapper::convertNodeToV8Object(Node* node)
+v8::Handle<v8::Value> V8DOMWrapper::convertDocumentToV8Object(Document* document)
{
- 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();
- }
+ V8Proxy* proxy = V8Proxy::retrieve(document->frame());
+ if (proxy)
+ proxy->initContextIfNeeded();
+
+ DOMWrapperMap<Node>& domNodeMap = getDOMNodeMap();
+ v8::Handle<v8::Object> wrapper = domNodeMap.get(document);
+ if (wrapper.IsEmpty())
+ return convertNewNodeToV8Object(document, proxy, domNodeMap);
+
+ return wrapper;
+}
+v8::Handle<v8::Value> V8DOMWrapper::convertNodeToV8Object(Node* node)
+{
+ if (!node)
+ return v8::Null();
+
+ Document* document = node->document();
+ if (node == document)
+ return convertDocumentToV8Object(document);
+
DOMWrapperMap<Node>& domNodeMap = getDOMNodeMap();
v8::Handle<v8::Object> wrapper = domNodeMap.get(node);
- if (!wrapper.IsEmpty())
- return wrapper;
+ if (wrapper.IsEmpty())
+ return convertNewNodeToV8Object(node, 0, domNodeMap);
+
+ return wrapper;
+}
+
+// Caller checks node is not null.
+v8::Handle<v8::Value> V8DOMWrapper::convertNewNodeToV8Object(Node* node, V8Proxy* proxy, DOMWrapperMap<Node>& domNodeMap)
+{
+ if (!proxy && node->document())
+ proxy = V8Proxy::retrieve(node->document()->frame());
bool isDocument = false; // document type node has special handling
V8ClassIndex::V8WrapperType type;
@@ -1205,14 +1402,14 @@ v8::Handle<v8::Value> V8DOMWrapper::convertNodeToV8Object(Node* node)
else
type = V8ClassIndex::DOCUMENT;
} else {
- ASSERT(nodeType < sizeof(mapping)/sizeof(mapping[0]));
+ ASSERT(nodeType < static_cast<int>(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());
+ context = proxy->context();
// Enter the node's context and create the wrapper in that context.
if (!context.IsEmpty())
@@ -1272,6 +1469,24 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
return convertToV8Object(V8ClassIndex::WORKER, worker);
#endif // WORKERS
+#if ENABLE(SHARED_WORKERS)
+ SharedWorker* sharedWorker = target->toSharedWorker();
+ if (sharedWorker)
+ return convertToV8Object(V8ClassIndex::SHAREDWORKER, sharedWorker);
+#endif // SHARED_WORKERS
+
+#if ENABLE(NOTIFICATIONS)
+ Notification* notification = target->toNotification();
+ if (notification)
+ return convertToV8Object(V8ClassIndex::NOTIFICATION, notification);
+#endif
+
+#if ENABLE(WEB_SOCKETS)
+ WebSocket* webSocket = target->toWebSocket();
+ if (webSocket)
+ return convertToV8Object(V8ClassIndex::WEBSOCKET, webSocket);
+#endif
+
Node* node = target->toNode();
if (node)
return convertNodeToV8Object(node);
@@ -1312,14 +1527,83 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
return notHandledByInterceptor();
}
-v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(EventListener* listener)
+v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(ScriptExecutionContext* context, 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();
+ return v8listener->getListenerObject(context);
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
+}
+
+#if ENABLE(SVG)
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ return getEventListener(element->correspondingElement(), value, isAttribute, lookup);
+}
+#endif
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ if (worker->scriptExecutionContext()->isWorkerContext()) {
+ WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+ ASSERT(workerContextProxy);
+ return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+ }
+
+ return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
+}
+
+#if ENABLE(NOTIFICATIONS)
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Notification* notification, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ if (notification->scriptExecutionContext()->isWorkerContext()) {
+ WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+ ASSERT(workerContextProxy);
+ return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+ }
+
+ return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
+}
+#endif
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(WorkerContext* workerContext, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ WorkerContextExecutionProxy* workerContextProxy = workerContext->script()->proxy();
+ if (workerContextProxy)
+ return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+
+ return 0;
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(XMLHttpRequestUpload* upload, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ return getEventListener(upload->associatedXMLHttpRequest(), value, isAttribute, lookup);
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ if (V8Proxy::retrieve(eventTarget->scriptExecutionContext()))
+ return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
+
+#if ENABLE(WORKERS)
+ WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
+ if (workerContextProxy)
+ return workerContextProxy->findOrCreateEventListener(value, isAttribute, lookup == ListenerFindOnly);
+#endif
+
+ return 0;
+}
+
+PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
+{
+ return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(value, isAttribute);
}
v8::Handle<v8::Value> V8DOMWrapper::convertDOMImplementationToV8Object(DOMImplementation* impl)
@@ -1485,4 +1769,30 @@ v8::Handle<v8::Value> V8DOMWrapper::convertWindowToV8Object(DOMWindow* window)
return global;
}
+v8::Handle<v8::Value> V8DOMWrapper::convertNamedNodeMapToV8Object(NamedNodeMap* map)
+{
+ if (!map)
+ return v8::Null();
+
+ v8::Handle<v8::Object> wrapper = getDOMObjectMap().get(map);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+
+ v8::Handle<v8::Object> result = instantiateV8Object(V8ClassIndex::NAMEDNODEMAP, V8ClassIndex::NAMEDNODEMAP, map);
+ if (result.IsEmpty())
+ return result;
+
+ // Only update the DOM object map if the result is non-empty.
+ map->ref();
+ setJSWrapperForDOMObject(map, v8::Persistent<v8::Object>::New(result));
+
+ // Add a hidden reference from named node map to its owner node.
+ if (Element* element = map->element()) {
+ v8::Handle<v8::Object> owner = v8::Handle<v8::Object>::Cast(convertNodeToV8Object(element));
+ result->SetInternalField(V8Custom::kNamedNodeMapOwnerNodeIndex, owner);
+ }
+
+ return result;
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index 57b3a69..660b827 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -31,13 +31,18 @@
#ifndef V8DOMWrapper_h
#define V8DOMWrapper_h
+#include "Document.h"
#include "Event.h"
#include "Node.h"
#include "NodeFilter.h"
#include "PlatformString.h" // for WebCore::String
#include "V8CustomBinding.h"
+#include "V8CustomXPathNSResolver.h"
+#include "V8DOMMap.h"
#include "V8Index.h"
#include "V8Utilities.h"
+#include "V8XPathNSResolver.h"
+#include "XPathNSResolver.h"
#include <v8.h>
namespace WebCore {
@@ -86,8 +91,16 @@ namespace WebCore {
class StyleSheetList;
class V8EventListener;
class V8ObjectEventListener;
+#if ENABLE(WEB_SOCKETS)
+ class WebSocket;
+#endif
class WorkerContext;
+ enum ListenerLookupType {
+ ListenerFindOnly,
+ ListenerFindOrCreate,
+ };
+
class V8DOMWrapper {
public:
#ifndef NDEBUG
@@ -96,7 +109,12 @@ namespace WebCore {
#endif
// Sets contents of a DOM wrapper.
- static void setDOMWrapper(v8::Handle<v8::Object>, int type, void* ptr);
+ static void 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));
+ }
static v8::Handle<v8::Object> lookupDOMWrapper(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Object> object)
{
@@ -136,6 +154,20 @@ namespace WebCore {
static v8::Handle<v8::Value> convertNodeToV8Object(Node*);
+ static v8::Handle<v8::Value> convertDocumentToV8Object(Document*);
+
+ static v8::Handle<v8::Value> convertNewNodeToV8Object(PassRefPtr<Node> node)
+ {
+ return convertNewNodeToV8Object(node.get());
+ }
+
+ static v8::Handle<v8::Value> convertNewNodeToV8Object(Node* node)
+ {
+ return convertNewNodeToV8Object(node, 0, getDOMNodeMap());
+ }
+
+ static v8::Handle<v8::Value> convertNewNodeToV8Object(Node*, V8Proxy*, DOMWrapperMap<Node>&);
+
template <class C>
static C* convertToNativeObject(V8ClassIndex::V8WrapperType type, v8::Handle<v8::Object> object)
{
@@ -184,12 +216,47 @@ namespace WebCore {
static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*);
// Wrap and unwrap JS event listeners.
- static v8::Handle<v8::Value> convertEventListenerToV8Object(PassRefPtr<Event> eventListener)
+ static v8::Handle<v8::Value> convertEventListenerToV8Object(ScriptExecutionContext* context, PassRefPtr<EventListener> eventListener)
{
- return convertEventListenerToV8Object(eventListener.get());
+ return convertEventListenerToV8Object(context, eventListener.get());
}
- static v8::Handle<v8::Value> convertEventListenerToV8Object(EventListener*);
+ static v8::Handle<v8::Value> convertEventListenerToV8Object(ScriptExecutionContext*, EventListener*);
+
+ static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+ static PassRefPtr<EventListener> getEventListener(SVGElementInstance* element, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+ static PassRefPtr<EventListener> getEventListener(AbstractWorker* worker, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+#if ENABLE(NOTIFICATIONS)
+ static PassRefPtr<EventListener> getEventListener(Notification* notification, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+#endif
+
+ static PassRefPtr<EventListener> getEventListener(WorkerContext* workerContext, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+ static PassRefPtr<EventListener> getEventListener(XMLHttpRequestUpload* upload, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+ static PassRefPtr<EventListener> getEventListener(EventTarget* eventTarget, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+ static PassRefPtr<EventListener> getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
+
+
+#if PLATFORM(ANDROID)
+// TODO: upstream XPATH guard.
+#if ENABLE(XPATH)
+ // XPath-related utilities
+ static RefPtr<XPathNSResolver> getXPathNSResolver(v8::Handle<v8::Value> value, V8Proxy* proxy = 0)
+ {
+ RefPtr<XPathNSResolver> resolver;
+ if (V8XPathNSResolver::HasInstance(value))
+ resolver = convertToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, v8::Handle<v8::Object>::Cast(value));
+ else if (value->IsObject())
+ resolver = V8CustomXPathNSResolver::create(proxy, value->ToObject());
+ return resolver;
+ }
+#endif
+#endif
// DOMImplementation is a singleton and it is handled in a special
// way. A wrapper is generated per document and stored in an
@@ -207,6 +274,10 @@ namespace WebCore {
// Checks whether a DOM object has a JS wrapper.
static bool domObjectHasJSWrapper(void*);
+ // Get JS wrapper of an existing DOM object, assuming that the wrapper
+ // exists.
+ static v8::Persistent<v8::Object> jsWrapperForDOMObject(void*);
+ static v8::Persistent<v8::Object> jsWrapperForActiveDOMObject(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>);
@@ -226,12 +297,20 @@ namespace WebCore {
// Returns the JS wrapper of a window object, initializes the environment
// of the window frame if needed.
static v8::Handle<v8::Value> convertWindowToV8Object(DOMWindow*);
+ static v8::Handle<v8::Value> convertNamedNodeMapToV8Object(NamedNodeMap*);
#if ENABLE(SVG)
static v8::Handle<v8::Value> convertSVGElementInstanceToV8Object(SVGElementInstance*);
static v8::Handle<v8::Value> convertSVGObjectWithContextToV8Object(V8ClassIndex::V8WrapperType, void*);
#endif
+#if ENABLE(3D_CANVAS)
+ static void setIndexedPropertiesToExternalArray(v8::Handle<v8::Object>,
+ int,
+ void*,
+ int);
+#endif
+
private:
// Set hidden references in a DOMWindow object of a frame.
static void setHiddenWindowReference(Frame*, const int internalIndex, v8::Handle<v8::Object>);
diff --git a/WebCore/bindings/v8/V8EventListenerList.cpp b/WebCore/bindings/v8/V8EventListenerList.cpp
index c9aaa12..e37d630 100644
--- a/WebCore/bindings/v8/V8EventListenerList.cpp
+++ b/WebCore/bindings/v8/V8EventListenerList.cpp
@@ -31,165 +31,6 @@
#include "config.h"
#include "V8EventListenerList.h"
-#include "V8CustomEventListener.h"
-
namespace WebCore {
-V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list)
- : m_list(list)
- , m_vectorIndex(0)
- , m_iter(list->m_table.begin())
-{
-}
-
-V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list, bool shouldSeekToEnd)
- : m_list(list)
- , m_vectorIndex(0)
- , m_iter(list->m_table.begin())
-{
- if (shouldSeekToEnd)
- seekToEnd();
-}
-
-V8EventListenerListIterator::~V8EventListenerListIterator() { }
-
-void V8EventListenerListIterator::operator++()
-{
- if (m_iter != m_list->m_table.end()) {
- Vector<V8EventListener*>* vector = m_iter->second;
- if (m_vectorIndex + 1 < vector->size()) {
- m_vectorIndex++;
- return;
- }
- m_vectorIndex = 0;
- ++m_iter;
- }
-}
-
-bool V8EventListenerListIterator::operator==(const V8EventListenerListIterator& other)
-{
- return other.m_iter == m_iter && other.m_vectorIndex == m_vectorIndex && other.m_list == m_list;
-}
-
-bool V8EventListenerListIterator::operator!=(const V8EventListenerListIterator& other)
-{
- return !operator==(other);
-}
-
-V8EventListener* V8EventListenerListIterator::operator*()
-{
- if (m_iter != m_list->m_table.end()) {
- Vector<V8EventListener*>* vector = m_iter->second;
- if (m_vectorIndex < vector->size())
- return vector->at(m_vectorIndex);
- }
- return 0;
-}
-
-void V8EventListenerListIterator::seekToEnd()
-{
- m_iter = m_list->m_table.end();
- m_vectorIndex = 0;
-}
-
-
-V8EventListenerList::V8EventListenerList()
-{
-}
-
-V8EventListenerList::~V8EventListenerList()
-{
-}
-
-V8EventListenerListIterator V8EventListenerList::begin()
-{
- return iterator(this);
-}
-
-V8EventListenerListIterator V8EventListenerList::end()
-{
- return iterator(this, true);
-}
-
-
-static int getKey(v8::Local<v8::Object> object)
-{
- // 0 is a sentinel value for the HashMap key, so we map it to 1.
- int hash = object->GetIdentityHash();
- if (!hash)
- return 1;
- return hash;
-}
-
-void V8EventListenerList::add(V8EventListener* listener)
-{
- ASSERT(v8::Context::InContext());
- v8::HandleScope handleScope;
-
- v8::Local<v8::Object> object = listener->getListenerObject();
- int key = getKey(object);
- Vector<V8EventListener*>* vector = m_table.get(key);
- if (!vector) {
- vector = new Vector<V8EventListener*>();
- m_table.set(key, vector);
- }
- vector->append(listener);
- m_reverseTable.set(listener, key);
-}
-
-void V8EventListenerList::remove(V8EventListener* listener)
-{
- if (m_reverseTable.contains(listener)) {
- int key = m_reverseTable.get(listener);
- Vector<V8EventListener*>* vector = m_table.get(key);
- if (!vector)
- return;
- for (size_t j = 0; j < vector->size(); j++) {
- if (vector->at(j) == listener) {
- vector->remove(j);
- if (!vector->size()) {
- m_table.remove(key);
- delete vector;
- vector = 0;
- }
- m_reverseTable.remove(listener);
- return;
- }
- }
- }
-}
-
-void V8EventListenerList::clear()
-{
- m_table.clear();
- m_reverseTable.clear();
-}
-
-V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isAttribute)
-{
- ASSERT(v8::Context::InContext());
- int key = getKey(object);
-
- Vector<V8EventListener*>* vector = m_table.get(key);
- if (!vector)
- return 0;
-
- for (size_t i = 0; i < vector->size(); i++) {
- V8EventListener* element = vector->at(i);
- if (isAttribute == element->isAttribute() && object == element->getListenerObject())
- return element;
- }
- 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 4255050..fdf211d 100644
--- a/WebCore/bindings/v8/V8EventListenerList.h
+++ b/WebCore/bindings/v8/V8EventListenerList.h
@@ -31,93 +31,74 @@
#ifndef V8EventListenerList_h
#define V8EventListenerList_h
-#include <v8.h>
-#include <wtf/Vector.h>
-#include <wtf/HashMap.h>
+#include "V8CustomEventListener.h"
+#include "V8HiddenPropertyName.h"
-#include "PassRefPtr.h"
+#include <v8.h>
+#include <wtf/PassRefPtr.h>
namespace WebCore {
class Frame;
- class V8EventListener;
- class V8EventListenerListIterator;
- // This is a container for V8EventListener objects that uses the identity hash of the v8::Object to
- // speed up lookups
+ // This is a container for V8EventListener objects that uses hidden properties of v8::Object to speed up lookups.
class V8EventListenerList {
public:
- // Because v8::Object identity hashes are not guaranteed to be unique, we unfortunately can't just map
- // an int to V8EventListener. Instead we define a HashMap of int to Vector of V8EventListener
- // called a ListenerMultiMap.
- typedef Vector<V8EventListener*>* Values;
- struct ValuesTraits : HashTraits<Values> {
- static const bool needsDestruction = true;
- };
- typedef HashMap<int, Values, DefaultHash<int>::Hash, HashTraits<int>, ValuesTraits> ListenerMultiMap;
-
- V8EventListenerList();
- ~V8EventListenerList();
-
- friend class V8EventListenerListIterator;
- typedef V8EventListenerListIterator iterator;
-
- iterator begin();
- iterator end();
-
- void add(V8EventListener*);
- void remove(V8EventListener*);
- V8EventListener* find(v8::Local<v8::Object>, bool isAttribute);
- 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);
+ static PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value> value, bool isAttribute)
+ {
+ ASSERT(v8::Context::InContext());
+ if (!value->IsObject())
+ return 0;
- private:
- ListenerMultiMap m_table;
+ v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute);
+ return doFindWrapper(v8::Local<v8::Object>::Cast(value), wrapperProperty);
+ }
- // we also keep a reverse mapping of V8EventListener to v8::Object identity hash,
- // in order to speed up removal by V8EventListener
- HashMap<V8EventListener*, int> m_reverseTable;
- };
+ template<typename WrapperType>
+ static PassRefPtr<V8EventListener> findOrCreateWrapper(v8::Local<v8::Value>, bool isAttribute);
+
+ static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute)
+ {
+ v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute);
+ listenerObject->DeleteHiddenValue(wrapperProperty);
+ }
- class V8EventListenerListIterator {
- public:
- ~V8EventListenerListIterator();
- void operator++();
- bool operator==(const V8EventListenerListIterator&);
- bool operator!=(const V8EventListenerListIterator&);
- V8EventListener* operator*();
private:
- friend class V8EventListenerList;
- explicit V8EventListenerListIterator(V8EventListenerList*);
- V8EventListenerListIterator(V8EventListenerList*, bool shouldSeekToEnd);
- void seekToEnd();
-
- V8EventListenerList* m_list;
- V8EventListenerList::ListenerMultiMap::iterator m_iter;
- size_t m_vectorIndex;
+ static V8EventListener* doFindWrapper(v8::Local<v8::Object> object, v8::Handle<v8::String> wrapperProperty)
+ {
+ ASSERT(v8::Context::InContext());
+ v8::HandleScope scope;
+ v8::Local<v8::Value> listener = object->GetHiddenValue(wrapperProperty);
+ if (listener.IsEmpty())
+ return 0;
+ return static_cast<V8EventListener*>(v8::External::Unwrap(listener));
+ }
+
+ static inline v8::Handle<v8::String> getHiddenProperty(bool isAttribute)
+ {
+ return isAttribute ? V8HiddenPropertyName::attributeListener() : V8HiddenPropertyName::listener();
+ }
};
template<typename WrapperType>
- PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(Frame* frame, v8::Local<v8::Value> object, bool isAttribute)
+ PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(v8::Local<v8::Value> value, bool isAttribute)
{
ASSERT(v8::Context::InContext());
- if (!object->IsObject())
+ if (!value->IsObject())
return 0;
- // FIXME: Should this be v8::Local<v8::Object>::Cast instead?
- V8EventListener* wrapper = find(object->ToObject(), isAttribute);
+ v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
+ v8::Handle<v8::String> wrapperProperty = getHiddenProperty(isAttribute);
+
+ V8EventListener* wrapper = doFindWrapper(object, wrapperProperty);
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());
+ PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(object, isAttribute, WorldContextHandle(UseCurrentWorld));
+ if (wrapperPtr)
+ object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get()));
- return newListener;
- };
+ return wrapperPtr;
+ }
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8GCController.cpp b/WebCore/bindings/v8/V8GCController.cpp
index f3b1376..b478636 100644
--- a/WebCore/bindings/v8/V8GCController.cpp
+++ b/WebCore/bindings/v8/V8GCController.cpp
@@ -204,35 +204,11 @@ public:
// 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.
+ // Mark each port as in-use if it's entangled. For simplicity's sake, we assume all ports are remotely entangled,
+ // since the Chromium port implementation can't tell the difference.
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)
+ if (port1->isEntangled())
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());
- }
- }
}
}
};
@@ -263,16 +239,6 @@ bool operator<(const GrouperItem& a, const GrouperItem& b)
typedef Vector<GrouperItem> GrouperList;
-#if PLATFORM(ANDROID)
-// Sort GrouperList by the group id. Node* is only involved to sort within
-// a group id, so it will be fine.
-// TODO(andreip): used by std::stable_sort function. We can implement
-// the std::sort function and remove this one.
-static bool compareGrouperItem(const GrouperItem& a, const GrouperItem& b) {
- return a.groupId() < b.groupId();
-}
-#endif
-
class ObjectGrouperVisitor : public DOMWrapperMap<Node>::Visitor {
public:
ObjectGrouperVisitor()
@@ -296,14 +262,21 @@ public:
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;
-
+ if (node->isAttributeNode()) {
+ root = static_cast<Attr*>(node)->ownerElement();
+ // If the attribute has no element, no need to put it in the group,
+ // because it'll always be a group of 1.
+ if (!root)
+ return;
+ } else {
+ 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() && !node->hasAttributes())
+ return;
+ }
groupId = reinterpret_cast<uintptr_t>(root);
}
m_grouper.append(GrouperItem(groupId, node, wrapper));
@@ -311,13 +284,8 @@ public:
void applyGrouping()
{
-#if PLATFORM(ANDROID)
- // TODO(andreip): implement std::sort() and get rid of this.
- std::stable_sort<GrouperItem>(m_grouper.begin(), m_grouper.end(), compareGrouperItem);
-#else
// Group by sorting by the group id.
std::sort(m_grouper.begin(), m_grouper.end());
-#endif
// FIXME Should probably work in iterators here, but indexes were easier for my simple mind.
for (size_t i = 0; i < m_grouper.size(); ) {
@@ -342,7 +310,6 @@ public:
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);
@@ -421,17 +388,30 @@ ACTIVE_DOM_OBJECT_TYPES(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).
+ // 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).
+ if (!wrapper.IsWeak() && !wrapper.IsNearDeath())
wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback);
- }
}
}
};
+int V8GCController::workingSetEstimateMB = 0;
+
+namespace {
+
+int getMemoryUsageInMB()
+{
+#if PLATFORM(CHROMIUM)
+ return ChromiumBridge::memoryUsageMB();
+#else
+ return 0;
+#endif
+}
+
+} // anonymous namespace
+
void V8GCController::gcEpilogue()
{
v8::HandleScope scope;
@@ -441,6 +421,8 @@ void V8GCController::gcEpilogue()
GCEpilogueVisitor epilogueVisitor;
visitActiveDOMObjectsInCurrentThread(&epilogueVisitor);
+ workingSetEstimateMB = getMemoryUsageInMB();
+
#ifndef NDEBUG
// Check all survivals are weak.
DOMObjectVisitor domObjectVisitor;
@@ -454,4 +436,19 @@ void V8GCController::gcEpilogue()
#endif
}
+void V8GCController::checkMemoryUsage()
+{
+#if PLATFORM(CHROMIUM)
+ // These values are appropriate for Chromium only.
+ const int lowUsageMB = 256; // If memory usage is below this threshold, do not bother forcing GC.
+ const int highUsageMB = 1024; // If memory usage is above this threshold, force GC more aggresively.
+ const int highUsageDeltaMB = 128; // Delta of memory usage growth (vs. last workingSetEstimateMB) to force GC when memory usage is high.
+
+ int memoryUsageMB = getMemoryUsageInMB();
+ if ((memoryUsageMB > lowUsageMB && memoryUsageMB > 2 * workingSetEstimateMB) || (memoryUsageMB > highUsageMB && memoryUsageMB > workingSetEstimateMB + highUsageDeltaMB))
+ v8::V8::LowMemoryNotification();
+#endif
+}
+
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8GCController.h b/WebCore/bindings/v8/V8GCController.h
index 7441bf0..484be24 100644
--- a/WebCore/bindings/v8/V8GCController.h
+++ b/WebCore/bindings/v8/V8GCController.h
@@ -78,6 +78,12 @@ namespace WebCore {
static void gcPrologue();
static void gcEpilogue();
+
+ static void checkMemoryUsage();
+
+ private:
+ // Estimate of current working set.
+ static int workingSetEstimateMB;
};
}
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.cpp b/WebCore/bindings/v8/V8HiddenPropertyName.cpp
index 16ac232..d83573f 100644
--- a/WebCore/bindings/v8/V8HiddenPropertyName.cpp
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.cpp
@@ -33,22 +33,21 @@
namespace WebCore {
-v8::Handle<v8::String> V8HiddenPropertyName::objectPrototype()
-{
- static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::objectPrototype");
-
- return *string;
+#define V8_AS_STRING(x) V8_AS_STRING_IMPL(x)
+#define V8_AS_STRING_IMPL(x) #x
+
+#define V8_DEFINE_PROPERTY(name) \
+v8::Handle<v8::String> V8HiddenPropertyName::name() \
+{ \
+ static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::" V8_AS_STRING(name)); \
+ return *string; \
}
-v8::Handle<v8::String> V8HiddenPropertyName::isolatedWorld()
-{
- static v8::Persistent<v8::String>* string = createString("WebCore::V8HiddenPropertyName::isolatedWorld");
-
- return *string;
-}
+V8_HIDDEN_PROPERTIES(V8_DEFINE_PROPERTY);
v8::Persistent<v8::String>* V8HiddenPropertyName::createString(const char* key)
{
+ v8::HandleScope scope;
return new v8::Persistent<v8::String>(v8::Persistent<v8::String>::New(v8::String::NewSymbol(key)));
}
diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.h b/WebCore/bindings/v8/V8HiddenPropertyName.h
index 874b525..bb1ca4c 100644
--- a/WebCore/bindings/v8/V8HiddenPropertyName.h
+++ b/WebCore/bindings/v8/V8HiddenPropertyName.h
@@ -35,10 +35,18 @@
namespace WebCore {
+#define V8_HIDDEN_PROPERTIES(V) \
+ V(objectPrototype) \
+ V(listener) \
+ V(attributeListener) \
+ V(sleepFunction) \
+ V(toStringString)
+
class V8HiddenPropertyName {
public:
- static v8::Handle<v8::String> objectPrototype();
- static v8::Handle<v8::String> isolatedWorld();
+#define V8_DECLARE_PROPERTY(name) static v8::Handle<v8::String> name();
+ V8_HIDDEN_PROPERTIES(V8_DECLARE_PROPERTY);
+#undef V8_DECLARE_PROPERTY
private:
static v8::Persistent<v8::String>* createString(const char* key);
diff --git a/WebCore/bindings/v8/V8Index.cpp b/WebCore/bindings/v8/V8Index.cpp
index 9efbc3d..9686dc6 100644
--- a/WebCore/bindings/v8/V8Index.cpp
+++ b/WebCore/bindings/v8/V8Index.cpp
@@ -33,6 +33,9 @@
#include "V8Attr.h"
#include "V8BarInfo.h"
+#include "V8BeforeLoadEvent.h"
+#include "V8WebGLActiveInfo.h"
+#include "V8CanvasRenderingContext.h"
#include "V8CanvasRenderingContext2D.h"
#include "V8CanvasGradient.h"
#include "V8CanvasPattern.h"
@@ -43,6 +46,7 @@
#include "V8ClientRectList.h"
#include "V8Clipboard.h"
#include "V8Comment.h"
+#include "V8CompositionEvent.h"
#include "V8Console.h"
#include "V8Counter.h"
#include "V8CSSStyleDeclaration.h"
@@ -107,6 +111,7 @@
#include "V8HTMLHtmlElement.h"
#include "V8HTMLIFrameElement.h"
#include "V8HTMLImageElement.h"
+#include "V8HTMLImageElementConstructor.h"
#include "V8HTMLInputElement.h"
#include "V8HTMLIsIndexElement.h"
#include "V8HTMLLabelElement.h"
@@ -121,6 +126,7 @@
#include "V8HTMLOListElement.h"
#include "V8HTMLOptGroupElement.h"
#include "V8HTMLOptionElement.h"
+#include "V8HTMLOptionElementConstructor.h"
#include "V8HTMLParagraphElement.h"
#include "V8HTMLParamElement.h"
#include "V8HTMLPreElement.h"
@@ -179,6 +185,7 @@
#include "V8Navigator.h"
#include "V8MimeType.h"
#include "V8MimeTypeArray.h"
+#include "V8PageTransitionEvent.h"
#include "V8Plugin.h"
#include "V8PluginArray.h"
#include "V8Range.h"
@@ -195,24 +202,11 @@
#include "V8XMLHttpRequestUpload.h"
#include "V8XMLSerializer.h"
#include "V8RGBColor.h"
-#include "V8VoidCallback.h"
-
-#if !PLATFORM(ANDROID)
-#include "V8InspectorBackend.h"
-#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
#include "V8DOMApplicationCache.h"
#endif
-#if ENABLE(DATABASE)
-#include "V8Database.h"
-#include "V8SQLError.h"
-#include "V8SQLResultSet.h"
-#include "V8SQLResultSetRowList.h"
-#include "V8SQLTransaction.h"
-#endif
-
#if ENABLE(DOM_STORAGE)
#include "V8Storage.h"
#include "V8StorageEvent.h"
@@ -226,7 +220,7 @@
#include "V8SVGSetElement.h"
#endif
-#if ENABLE(SVG_FILTERS)
+#if ENABLE(SVG) && ENABLE(FILTERS)
#include "V8SVGComponentTransferFunctionElement.h"
#include "V8SVGFEBlendElement.h"
#include "V8SVGFEColorMatrixElement.h"
@@ -244,6 +238,7 @@
#include "V8SVGFEImageElement.h"
#include "V8SVGFEMergeElement.h"
#include "V8SVGFEMergeNodeElement.h"
+#include "V8SVGFEMorphologyElement.h"
#include "V8SVGFEOffsetElement.h"
#include "V8SVGFEPointLightElement.h"
#include "V8SVGFESpecularLightingElement.h"
@@ -254,7 +249,6 @@
#endif
#if ENABLE(SVG_FONTS)
-#include "V8SVGDefinitionSrcElement.h"
#include "V8SVGFontFaceElement.h"
#include "V8SVGFontFaceFormatElement.h"
#include "V8SVGFontFaceNameElement.h"
@@ -364,12 +358,12 @@
#include "V8SVGTransform.h"
#include "V8SVGTransformList.h"
#include "V8SVGUnitTypes.h"
-#include "V8SVGURIReference.h"
#include "V8SVGZoomEvent.h"
#endif
#if ENABLE(VIDEO)
#include "V8HTMLAudioElement.h"
+#include "V8HTMLAudioElementConstructor.h"
#include "V8HTMLMediaElement.h"
#include "V8HTMLSourceElement.h"
#include "V8HTMLVideoElement.h"
@@ -377,6 +371,10 @@
#include "V8TimeRanges.h"
#endif
+#if ENABLE(WEB_SOCKETS)
+#include "V8WebSocket.h"
+#endif
+
#if ENABLE(WORKERS)
#include "V8AbstractWorker.h"
#include "V8DedicatedWorkerContext.h"
@@ -386,35 +384,79 @@
#include "V8WorkerNavigator.h"
#endif
+#if ENABLE(NOTIFICATIONS)
+#include "V8Notification.h"
+#include "V8NotificationCenter.h"
+#endif
+
#if ENABLE(SHARED_WORKERS)
#include "V8SharedWorker.h"
+#include "V8SharedWorkerContext.h"
#endif
-#if ENABLE(GEOLOCATION)
-#include "V8Coordinates.h"
-#include "V8Geolocation.h"
-#include "V8Geoposition.h"
-#include "V8PositionError.h"
+#if ENABLE(3D_CANVAS)
+#include "V8WebGLRenderingContext.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArray.h"
+#include "V8WebGLByteArray.h"
+#include "V8WebGLBuffer.h"
+#include "V8WebGLFloatArray.h"
+#include "V8WebGLFramebuffer.h"
+#include "V8WebGLIntArray.h"
+#include "V8WebGLProgram.h"
+#include "V8WebGLRenderbuffer.h"
+#include "V8WebGLShader.h"
+#include "V8WebGLShortArray.h"
+#include "V8WebGLTexture.h"
+#include "V8WebGLUniformLocation.h"
+#include "V8WebGLUnsignedByteArray.h"
+#include "V8WebGLUnsignedIntArray.h"
+#include "V8WebGLUnsignedShortArray.h"
#endif
-#if ENABLE(TOUCH_EVENTS)
-#include "V8Touch.h"
-#include "V8TouchList.h"
-#include "V8TouchEvent.h"
+#if ENABLE(DATABASE)
+#include "V8Database.h"
+#include "V8SQLError.h"
+#include "V8SQLResultSet.h"
+#include "V8SQLResultSetRowList.h"
+#include "V8SQLTransaction.h"
#endif
#if ENABLE(XPATH)
#include "V8XPathResult.h"
#include "V8XPathException.h"
#include "V8XPathExpression.h"
-#include "V8XPathEvaluator.h"
#include "V8XPathNSResolver.h"
+#include "V8XPathEvaluator.h"
#endif
#if ENABLE(XSLT)
#include "V8XSLTProcessor.h"
#endif
+#if ENABLE(INSPECTOR)
+#include "V8InjectedScriptHost.h"
+#include "V8InspectorBackend.h"
+#include "V8InspectorFrontendHost.h"
+#endif
+
+// Geolocation
+#include "V8Coordinates.h"
+#include "V8Geolocation.h"
+#include "V8Geoposition.h"
+#include "V8PositionError.h"
+
+#if PLATFORM(ANDROID)
+// TODO: Upstream these guards to webkit.org
+#if ENABLE(TOUCH_EVENTS)
+#include "V8Touch.h"
+#include "V8TouchList.h"
+#include "V8TouchEvent.h"
+#endif
+
+#include "V8VoidCallback.h"
+#endif // PLATFORM(ANDROID)
+
namespace WebCore {
FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type)
diff --git a/WebCore/bindings/v8/V8Index.h b/WebCore/bindings/v8/V8Index.h
index d6db4c6..d786aab 100644
--- a/WebCore/bindings/v8/V8Index.h
+++ b/WebCore/bindings/v8/V8Index.h
@@ -54,6 +54,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#if ENABLE(VIDEO)
#define VIDEO_HTMLELEMENT_TYPES(V) \
+ V(AUDIO, HTMLAudioElementConstructor) \
V(HTMLAUDIOELEMENT, HTMLAudioElement) \
V(HTMLMEDIAELEMENT, HTMLMediaElement) \
V(HTMLSOURCEELEMENT, HTMLSourceElement) \
@@ -82,16 +83,26 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
+#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
V(DOMAPPLICATIONCACHE, DOMApplicationCache)
#else
#define APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V)
#endif
+#if ENABLE(NOTIFICATIONS)
+#define NOTIFICATIONS_NONNODE_WRAPPER_TYPES(V) \
+ V(NOTIFICATION, Notification) \
+ V(NOTIFICATIONCENTER, NotificationCenter)
+#else
+#define NOTIFICATIONS_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)
+
+#define SHARED_WORKER_NONNODE_WRAPPER_TYPES(V) \
+ V(SHAREDWORKERCONTEXT, SharedWorkerContext)
#else
#define SHARED_WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V)
#define SHARED_WORKER_NONNODE_WRAPPER_TYPES(V)
@@ -109,7 +120,9 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(ENTITY, Entity) \
V(ENTITYREFERENCE, EntityReference) \
V(HTMLDOCUMENT, HTMLDocument) \
+ V(IMAGE, HTMLImageElementConstructor) \
V(NODE, Node) \
+ V(OPTION, HTMLOptionElementConstructor) \
V(NOTATION, Notation) \
V(PROCESSINGINSTRUCTION, ProcessingInstruction) \
V(TEXT, Text) \
@@ -184,7 +197,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#define SVG_ANIMATION_ELEMENT_TYPES(V)
#endif
-#if ENABLE(SVG_FILTERS)
+#if ENABLE(SVG) && ENABLE(FILTERS)
#define SVG_FILTERS_ELEMENT_TYPES(V) \
V(SVGCOMPONENTTRANSFERFUNCTIONELEMENT, SVGComponentTransferFunctionElement)\
V(SVGFEBLENDELEMENT, SVGFEBlendElement) \
@@ -203,6 +216,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(SVGFEIMAGEELEMENT, SVGFEImageElement) \
V(SVGFEMERGEELEMENT, SVGFEMergeElement) \
V(SVGFEMERGENODEELEMENT, SVGFEMergeNodeElement) \
+ V(SVGFEMORPHOLOGYELEMENT, SVGFEMorphologyElement) \
V(SVGFEOFFSETELEMENT, SVGFEOffsetElement) \
V(SVGFEPOINTLIGHTELEMENT, SVGFEPointLightElement) \
V(SVGFESPECULARLIGHTINGELEMENT, SVGFESpecularLightingElement) \
@@ -216,7 +230,6 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#if ENABLE(SVG_FONTS)
#define SVG_FONTS_ELEMENT_TYPES(V) \
- V(SVGDEFINITIONSRCELEMENT, SVGDefinitionSrcElement) \
V(SVGFONTFACEELEMENT, SVGFontFaceElement) \
V(SVGFONTFACEFORMATELEMENT, SVGFontFaceFormatElement) \
V(SVGFONTFACENAMEELEMENT, SVGFontFaceNameElement) \
@@ -289,13 +302,21 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#endif // SVG
+#if ENABLE(WEB_SOCKETS)
+#define WEBSOCKET_ACTIVE_OBJECT_WRAPPER_TYPES(V) \
+ V(WEBSOCKET, WebSocket)
+#else
+#define WEBSOCKET_ACTIVE_OBJECT_WRAPPER_TYPES(V)
+#endif
+
// 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)
+ SHARED_WORKER_ACTIVE_OBJECT_WRAPPER_TYPES(V) \
+ WEBSOCKET_ACTIVE_OBJECT_WRAPPER_TYPES(V)
// NOTE: DOM_OBJECT_TYPES is split into two halves because
// Visual Studio's Intellinonsense crashes when macros get
@@ -303,13 +324,16 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
// DOM_OBJECT_TYPES are non-node DOM types.
#define DOM_OBJECT_TYPES_1(V) \
V(BARINFO, BarInfo) \
+ V(BEFORELOADEVENT, BeforeLoadEvent) \
V(CANVASGRADIENT, CanvasGradient) \
V(CANVASPATTERN, CanvasPattern) \
+ V(CANVASRENDERINGCONTEXT, CanvasRenderingContext) \
V(CANVASRENDERINGCONTEXT2D, CanvasRenderingContext2D) \
V(CLIENTRECT, ClientRect) \
V(CLIENTRECTLIST, ClientRectList) \
V(CLIPBOARD, Clipboard) \
V(CONSOLE, Console) \
+ V(COMPOSITIONEVENT, CompositionEvent) \
V(COUNTER, Counter) \
V(CSSCHARSETRULE, CSSCharsetRule) \
V(CSSFONTFACERULE, CSSFontFaceRule) \
@@ -359,6 +383,7 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(NODEITERATOR, NodeIterator) \
V(NODELIST, NodeList) \
V(OVERFLOWEVENT, OverflowEvent) \
+ V(PAGETRANSITIONEVENT, PageTransitionEvent) \
V(PLUGIN, Plugin) \
V(PLUGINARRAY, PluginArray) \
V(PROGRESSEVENT, ProgressEvent) \
@@ -374,7 +399,6 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(TREEWALKER, TreeWalker) \
V(UIEVENT, UIEvent) \
V(VALIDITYSTATE, ValidityState) \
- V(VOIDCALLBACK, VoidCallback) \
V(WEBKITANIMATIONEVENT, WebKitAnimationEvent) \
V(WEBKITCSSKEYFRAMERULE, WebKitCSSKeyframeRule) \
V(WEBKITCSSKEYFRAMESRULE, WebKitCSSKeyframesRule) \
@@ -391,27 +415,10 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
APPLICATIONCACHE_NONNODE_WRAPPER_TYPES(V) \
DATAGRID_NONNODE_TYPES(V) \
VIDEO_NONNODE_TYPES(V) \
+ NOTIFICATIONS_NONNODE_WRAPPER_TYPES(V) \
SHARED_WORKER_NONNODE_WRAPPER_TYPES(V) \
WORKER_NONNODE_WRAPPER_TYPES(V)
-#if ENABLE(XPATH)
-#define DOM_OBJECT_XPATH_TYPES(V) \
- V(XPATHEVALUATOR, XPathEvaluator) \
- V(XPATHEXCEPTION, XPathException) \
- V(XPATHEXPRESSION, XPathExpression) \
- V(XPATHNSRESOLVER, XPathNSResolver) \
- V(XPATHRESULT, XPathResult)
-#else
-#define DOM_OBJECT_XPATH_TYPES(V)
-#endif
-
-#if ENABLE(XSLT)
-#define DOM_OBJECT_XSLT_TYPES(V) \
- V(XSLTPROCESSOR, XSLTProcessor)
-#else
-#define DOM_OBJECT_XSLT_TYPES(V)
-#endif
-
#if ENABLE(DATABASE)
#define DOM_OBJECT_DATABASE_TYPES(V) \
V(DATABASE, Database) \
@@ -438,16 +445,65 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#define DOM_OBJECT_WORKERS_TYPES(V)
#endif
-#if ENABLE(GEOLOCATION)
+#if ENABLE(3D_CANVAS)
+#define DOM_OBJECT_3D_CANVAS_TYPES(V) \
+ V(WEBGLACTIVEINFO, WebGLActiveInfo) \
+ V(WEBGLARRAY, WebGLArray) \
+ V(WEBGLARRAYBUFFER, WebGLArrayBuffer) \
+ V(WEBGLBUFFER, WebGLBuffer) \
+ V(WEBGLBYTEARRAY, WebGLByteArray) \
+ V(WEBGLFLOATARRAY, WebGLFloatArray) \
+ V(WEBGLFRAMEBUFFER, WebGLFramebuffer) \
+ V(WEBGLINTARRAY, WebGLIntArray) \
+ V(WEBGLPROGRAM, WebGLProgram) \
+ V(WEBGLRENDERBUFFER, WebGLRenderbuffer) \
+ V(WEBGLRENDERINGCONTEXT, WebGLRenderingContext) \
+ V(WEBGLSHADER, WebGLShader) \
+ V(WEBGLSHORTARRAY, WebGLShortArray) \
+ V(WEBGLTEXTURE, WebGLTexture) \
+ V(WEBGLUNIFORMLOCATION, WebGLUniformLocation) \
+ V(WEBGLUNSIGNEDBYTEARRAY, WebGLUnsignedByteArray) \
+ V(WEBGLUNSIGNEDINTARRAY, WebGLUnsignedIntArray) \
+ V(WEBGLUNSIGNEDSHORTARRAY, WebGLUnsignedShortArray)
+#else
+#define DOM_OBJECT_3D_CANVAS_TYPES(V)
+#endif
+
+#if ENABLE(XPATH)
+#define DOM_OBJECT_XPATH_TYPES(V) \
+ V(XPATHEVALUATOR, XPathEvaluator) \
+ V(XPATHEXCEPTION, XPathException) \
+ V(XPATHEXPRESSION, XPathExpression) \
+ V(XPATHNSRESOLVER, XPathNSResolver) \
+ V(XPATHRESULT, XPathResult)
+#else
+#define DOM_OBJECT_XPATH_TYPES(V)
+#endif
+
+#if ENABLE(XSLT)
+#define DOM_OBJECT_XSLT_TYPES(V) \
+ V(XSLTPROCESSOR, XSLTProcessor)
+#else
+#define DOM_OBJECT_XSLT_TYPES(V)
+#endif
+
+#if ENABLE(INSPECTOR)
+#define DOM_OBJECT_INSPECTOR_TYPES(V) \
+ V(INSPECTORBACKEND, InspectorBackend) \
+ V(INSPECTORFRONTENDHOST, InspectorFrontendHost) \
+ V(INJECTEDSCRIPTHOST, InjectedScriptHost)
+#else
+#define DOM_OBJECT_INSPECTOR_TYPES(V)
+#endif
+
#define DOM_OBJECT_GEOLOCATION_TYPES(V) \
V(COORDINATES, Coordinates) \
V(GEOLOCATION, Geolocation) \
V(GEOPOSITION, Geoposition) \
V(POSITIONERROR, PositionError)
-#else
-#define DOM_OBJECT_GEOLOCATION_TYPES(V)
-#endif
+#if PLATFORM(ANDROID)
+// TODO: Upstream this guard.
#if ENABLE(TOUCH_EVENTS)
#define DOM_OBJECT_TOUCH_EVENT_TYPES(V) \
V(TOUCHLIST, TouchList) \
@@ -456,26 +512,30 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#else
#define DOM_OBJECT_TOUCH_EVENT_TYPES(V)
#endif
+#endif
-#if PLATFORM(CHROMIUM)
+#if PLATFORM(ANDROID)
+#define DOM_OBJECT_VOIDCALLBACK_TYPES(V) \
+ V(VOIDCALLBACK, VoidCallback)
+#else
+#define DOM_OBJECT_VOIDCALLBACK_TYPES(V)
+#endif
+
+#if PLATFORM(ANDROID)
+// This block is modified, but is not Android-specific.
#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) \
+ DOM_OBJECT_3D_CANVAS_TYPES(V) \
DOM_OBJECT_XPATH_TYPES(V) \
DOM_OBJECT_XSLT_TYPES(V) \
- V(INSPECTORBACKEND, InspectorBackend)
-#elif PLATFORM(ANDROID)
-#define DOM_OBJECT_TYPES(V) \
- DOM_OBJECT_TYPES_1(V) \
- DOM_OBJECT_TYPES_2(V) \
- DOM_OBJECT_DATABASE_TYPES(V) \
+ DOM_OBJECT_INSPECTOR_TYPES(V) \
DOM_OBJECT_GEOLOCATION_TYPES(V) \
- DOM_OBJECT_STORAGE_TYPES(V) \
DOM_OBJECT_TOUCH_EVENT_TYPES(V) \
- DOM_OBJECT_WORKERS_TYPES(V)
+ DOM_OBJECT_VOIDCALLBACK_TYPES(V)
#endif
#if ENABLE(SVG)
diff --git a/WebCore/bindings/v8/V8IsolatedWorld.cpp b/WebCore/bindings/v8/V8IsolatedWorld.cpp
index 1457545..cb65097 100644
--- a/WebCore/bindings/v8/V8IsolatedWorld.cpp
+++ b/WebCore/bindings/v8/V8IsolatedWorld.cpp
@@ -43,34 +43,31 @@
namespace WebCore {
-static int isolatedWorldCount = 0;
+int V8IsolatedWorld::isolatedWorldCount = 0;
-static void contextWeakReferenceCallback(v8::Persistent<v8::Value> object, void* isolated_world)
+void V8IsolatedWorld::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)
+V8IsolatedWorld::V8IsolatedWorld(V8Proxy* proxy, int extensionGroup)
{
+ ++isolatedWorldCount;
+
v8::HandleScope scope;
- v8::Persistent<v8::Context> context = proxy->createNewContext(v8::Handle<v8::Object>(), extensionGroup);
+ m_context = SharedPersistent<v8::Context>::create(proxy->createNewContext(v8::Handle<v8::Object>(), extensionGroup));
+ if (m_context->get().IsEmpty())
+ return;
// Run code in the new context.
- v8::Context::Scope context_scope(context);
+ v8::Context::Scope context_scope(m_context->get());
- // 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);
+ getGlobalObject(m_context->get())->SetPointerInInternalField(V8Custom::kDOMWindowEnteredIsolatedWorldIndex, this);
- 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);
+ V8Proxy::installHiddenObjectPrototype(m_context->get());
+ proxy->installDOMWindow(m_context->get(), proxy->frame()->domWindow());
// Using the default security token means that the canAccess is always
// called, which is slow.
@@ -78,49 +75,20 @@ void V8IsolatedWorld::evaluate(const Vector<ScriptSourceCode>& sources, V8Proxy*
// 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();
+ m_context->get()->UseDefaultSecurityToken();
- context.Dispose();
- // WARNING! This might well delete |world|.
+ proxy->frame()->loader()->client()->didCreateIsolatedScriptContext();
}
-V8IsolatedWorld::V8IsolatedWorld(v8::Handle<v8::Context> context)
- : m_context(v8::Persistent<v8::Context>::New(context))
+void V8IsolatedWorld::destroy()
{
- ++isolatedWorldCount;
- m_context.MakeWeak(this, &contextWeakReferenceCallback);
- m_context->Global()->SetHiddenValue(V8HiddenPropertyName::isolatedWorld(), v8::External::Wrap(this));
+ m_context->get().MakeWeak(this, &contextWeakReferenceCallback);
}
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));
+ m_context->disposeHandle();
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8IsolatedWorld.h b/WebCore/bindings/v8/V8IsolatedWorld.h
index 2036e65..6313da8 100644
--- a/WebCore/bindings/v8/V8IsolatedWorld.h
+++ b/WebCore/bindings/v8/V8IsolatedWorld.h
@@ -35,6 +35,7 @@
#include "V8DOMMap.h"
#include "V8Index.h"
+#include "V8Proxy.h"
#include "V8Utilities.h"
#include "ScriptSourceCode.h" // for WebCore::ScriptSourceCode
@@ -57,11 +58,15 @@ namespace WebCore {
//
class V8IsolatedWorld {
public:
+ // Creates an isolated world. To destroy it, call destroy().
+ // This will delete the isolated world when the context it owns is GC'd.
+ V8IsolatedWorld(V8Proxy* proxy, int extensionGroup);
~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);
+ // Call this to destroy the isolated world. It will be deleted sometime
+ // after this call, once all script references to the world's context
+ // have been dropped.
+ void destroy();
// Returns the isolated world associated with
// v8::Context::GetEntered(). Because worlds are isolated, the entire
@@ -71,26 +76,45 @@ namespace WebCore {
// FIXME: Consider edge cases with DOM mutation events that might
// violate this invariant.
//
- static V8IsolatedWorld* getEntered();
+ static V8IsolatedWorld* getEntered()
+ {
+ // 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.
+ if (!isolatedWorldCount)
+ return 0;
+ if (!v8::Context::InContext())
+ return 0;
+ return reinterpret_cast<V8IsolatedWorld*>(getGlobalObject(v8::Context::GetEntered())->GetPointerFromInternalField(V8Custom::kDOMWindowEnteredIsolatedWorldIndex));
+ }
- v8::Handle<v8::Context> context() { return m_context; }
+ v8::Handle<v8::Context> context() { return m_context->get(); }
+ PassRefPtr<SharedPersistent<v8::Context> > sharedContext() { 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);
+ static v8::Handle<v8::Object> getGlobalObject(v8::Handle<v8::Context> context)
+ {
+ return v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype());
+ }
+
+ // Called by the garbage collector when our JavaScript context is about
+ // to be destroyed.
+ static void contextWeakReferenceCallback(v8::Persistent<v8::Value> object, void* isolated_world);
// 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;
+ RefPtr<SharedPersistent<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;
+
+ static int isolatedWorldCount;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp
index 59fa7be..16b21d6 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.cpp
+++ b/WebCore/bindings/v8/V8LazyEventListener.cpp
@@ -33,199 +33,122 @@
#include "Frame.h"
#include "V8Binding.h"
+#include "V8HiddenPropertyName.h"
#include "V8Proxy.h"
+#include "WorldContextHandle.h"
+
+#include <wtf/StdLibExtras.h>
namespace WebCore {
-V8LazyEventListener::V8LazyEventListener(Frame *frame, const String& code, const String& functionName, bool isSVGEvent)
- : V8AbstractEventListener(frame, true)
- , m_code(code)
+V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext)
+ : V8AbstractEventListener(true, worldContext)
, m_functionName(functionName)
, m_isSVGEvent(isSVGEvent)
- , m_compiled(false)
- , m_wrappedFunctionCompiled(false)
-{
-}
-
-V8LazyEventListener::~V8LazyEventListener()
-{
- disposeListenerObject();
-
- // Dispose wrapped function
- if (!m_wrappedFunction.IsEmpty()) {
-#ifndef NDEBUG
- V8GCController::unregisterGlobalHandle(this, m_wrappedFunction);
-#endif
- m_wrappedFunction.Dispose();
- m_wrappedFunction.Clear();
- }
-}
-
-v8::Local<v8::Function> V8LazyEventListener::getListenerFunction()
+ , m_code(code)
+ , m_sourceURL(sourceURL)
+ , m_lineNumber(lineNumber)
+ , m_columnNumber(columnNumber)
{
- if (m_compiled) {
- ASSERT(m_listener.IsEmpty() || m_listener->IsFunction());
- return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
- }
-
- m_compiled = true;
-
- ASSERT(m_frame);
-
- {
- // Switch to the context of m_frame.
- v8::HandleScope handleScope;
-
- // Use the outer scope to hold context.
- v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
- // Bail out if we could not get the context.
- if (v8Context.IsEmpty())
- return v8::Local<v8::Function>();
-
- 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.
-
- // Make it an anonymous function to avoid name conflict for cases like
- // <body onload='onload()'>
- // <script> function onload() { alert('hi'); } </script>.
- // Set function name to function object instead.
- // See issue 944690.
- //
- // The ECMAScript spec says (very obliquely) that the parameter to an event handler is named "evt".
- //
- // Don't use new lines so that lines in the modified handler
- // have the same numbers as in the original code.
- String code = "(function (evt) {";
- code.append(m_code);
- code.append("\n})");
-
- v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
- v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_frame->document()->url(), m_lineNumber - 1);
- if (!script.IsEmpty()) {
- V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- ASSERT(proxy);
- v8::Local<v8::Value> value = proxy->runScript(script, false);
- if (!value.IsEmpty()) {
- ASSERT(value->IsFunction());
- v8::Local<v8::Function> listenerFunction = v8::Local<v8::Function>::Cast(value);
- listenerFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
-
- m_listener = v8::Persistent<v8::Function>::New(listenerFunction);
-#ifndef NDEBUG
- V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
-#endif
- }
- }
- }
-
- ASSERT(m_listener.IsEmpty() || m_listener->IsFunction());
- return m_listener.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
}
-v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
+v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
- v8::Local<v8::Function> handlerFunction = getWrappedListenerFunction();
- v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent);
+ v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(getListenerObject(context));
+ v8::Local<v8::Object> receiver = getReceiverObject(event);
if (handlerFunction.IsEmpty() || receiver.IsEmpty())
return v8::Local<v8::Value>();
v8::Handle<v8::Value> parameters[1] = { jsEvent };
- V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- return proxy->callFunction(handlerFunction, receiver, 1, parameters);
-}
+ if (V8Proxy* proxy = V8Proxy::retrieve(context))
+ return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+ return v8::Local<v8::Value>();
+}
static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& args)
{
- return args.Callee()->GetHiddenValue(v8::String::New("toStringString"));
+ return args.Holder()->GetHiddenValue(V8HiddenPropertyName::toStringString());
}
-
-v8::Local<v8::Function> V8LazyEventListener::getWrappedListenerFunction()
+void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context)
{
- if (m_wrappedFunctionCompiled) {
- ASSERT(m_wrappedFunction.IsEmpty() || m_wrappedFunction->IsFunction());
- return m_wrappedFunction.IsEmpty() ? v8::Local<v8::Function>() : v8::Local<v8::Function>::New(m_wrappedFunction);
- }
-
- m_wrappedFunctionCompiled = true;
-
- {
- // Switch to the context of m_frame.
- v8::HandleScope handleScope;
-
- // Use the outer scope to hold context.
- v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(m_frame);
- // Bail out if we cannot get the context.
- if (v8Context.IsEmpty())
- return v8::Local<v8::Function>();
-
- v8::Context::Scope scope(v8Context);
-
- // FIXME: cache the wrapper function.
-
- // Nodes other than the document object, when executing inline event handlers push document, form, and the target node on the scope chain.
- // We do this by using 'with' statement.
- // See chrome/fast/forms/form-action.html
- // chrome/fast/forms/selected-index-value.html
- // base/fast/overflow/onscroll-layer-self-destruct.html
- //
- // Don't use new lines so that lines in the modified handler
- // have the same numbers as in the original code.
- String code = "(function (evt) {" \
- "with (this.ownerDocument ? this.ownerDocument : {}) {" \
- "with (this.form ? this.form : {}) {" \
- "with (this) {" \
- "return (function(evt){";
- code.append(m_code);
- // 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);
- if (!script.IsEmpty()) {
- V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- ASSERT(proxy);
- v8::Local<v8::Value> value = proxy->runScript(script, false);
- if (!value.IsEmpty()) {
- ASSERT(value->IsFunction());
-
- m_wrappedFunction = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(value));
-
- // Change the toString function on the wrapper function to avoid it returning the source for the actual wrapper function. Instead
- // it returns source for a clean wrapper function with the event argument wrapping the event source code. The reason for this
- // is that some web sites uses toString on event functions and the evals the source returned (some times a RegExp is applied as
- // well) for some other use. That fails miserably if the actual wrapper source is returned.
- v8::Local<v8::FunctionTemplate> toStringTemplate = v8::FunctionTemplate::New(V8LazyEventListenerToString);
- v8::Local<v8::Function> toStringFunction;
- if (!toStringTemplate.IsEmpty())
- toStringFunction = toStringTemplate->GetFunction();
- if (!toStringFunction.IsEmpty()) {
- String toStringResult = "function ";
- toStringResult.append(m_functionName);
- toStringResult.append("(");
- if (m_isSVGEvent)
- toStringResult.append("evt");
- else
- toStringResult.append("event");
- toStringResult.append(") {\n ");
- toStringResult.append(m_code);
- toStringResult.append("\n}");
- toStringFunction->SetHiddenValue(v8::String::New("toStringString"), v8ExternalString(toStringResult));
- m_wrappedFunction->Set(v8::String::New("toString"), toStringFunction);
- }
-
-#ifndef NDEBUG
- V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_wrappedFunction);
-#endif
- m_wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
+ if (hasExistingListenerObject())
+ return;
+
+ v8::HandleScope handleScope;
+
+ V8Proxy* proxy = V8Proxy::retrieve(context);
+ if (!proxy)
+ return;
+
+ // Use the outer scope to hold context.
+ v8::Local<v8::Context> v8Context = worldContext().adjustedContext(proxy);
+ // Bail out if we cannot get the context.
+ if (v8Context.IsEmpty())
+ return;
+
+ v8::Context::Scope scope(v8Context);
+
+ // FIXME: cache the wrapper function.
+
+ // Nodes other than the document object, when executing inline event handlers push document, form, and the target node on the scope chain.
+ // We do this by using 'with' statement.
+ // See chrome/fast/forms/form-action.html
+ // chrome/fast/forms/selected-index-value.html
+ // base/fast/overflow/onscroll-layer-self-destruct.html
+ //
+ // Don't use new lines so that lines in the modified handler
+ // have the same numbers as in the original code.
+ String code = "(function (evt) {" \
+ "with (this.ownerDocument ? this.ownerDocument : {}) {" \
+ "with (this.form ? this.form : {}) {" \
+ "with (this) {" \
+ "return (function(evt){";
+ code.append(m_code);
+ // 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_sourceURL, m_lineNumber);
+ if (!script.IsEmpty()) {
+ v8::Local<v8::Value> value = proxy->runScript(script, false);
+ if (!value.IsEmpty()) {
+ ASSERT(value->IsFunction());
+
+ v8::Local<v8::Function> wrappedFunction = v8::Local<v8::Function>::Cast(value);
+
+ // Change the toString function on the wrapper function to avoid it
+ // returning the source for the actual wrapper function. Instead it
+ // returns source for a clean wrapper function with the event
+ // argument wrapping the event source code. The reason for this is
+ // that some web sites use toString on event functions and eval the
+ // source returned (sometimes a RegExp is applied as well) for some
+ // other use. That fails miserably if the actual wrapper source is
+ // returned.
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, toStringTemplate, ());
+ if (toStringTemplate.IsEmpty())
+ toStringTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New(V8LazyEventListenerToString));
+ v8::Local<v8::Function> toStringFunction;
+ if (!toStringTemplate.IsEmpty())
+ toStringFunction = toStringTemplate->GetFunction();
+ if (!toStringFunction.IsEmpty()) {
+ String toStringResult = "function ";
+ toStringResult.append(m_functionName);
+ toStringResult.append("(");
+ toStringResult.append(m_isSVGEvent ? "evt" : "event");
+ toStringResult.append(") {\n ");
+ toStringResult.append(m_code);
+ toStringResult.append("\n}");
+ wrappedFunction->SetHiddenValue(V8HiddenPropertyName::toStringString(), v8ExternalString(toStringResult));
+ wrappedFunction->Set(v8::String::New("toString"), toStringFunction);
}
+
+ wrappedFunction->SetName(v8::String::New(fromWebCoreString(m_functionName), m_functionName.length()));
+
+ setListenerObject(wrappedFunction);
}
}
-
- return v8::Local<v8::Function>::New(m_wrappedFunction);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
index 62d9342..078dcf1 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.h
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -45,35 +45,27 @@ namespace WebCore {
// A V8LazyEventListener is always a HTML event handler.
class V8LazyEventListener : public V8AbstractEventListener {
public:
- static PassRefPtr<V8LazyEventListener> create(Frame* frame, const String& code, const String& functionName, bool isSVGEvent)
+ static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext)
{
- return adoptRef(new V8LazyEventListener(frame, code, functionName, isSVGEvent));
+ return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber, worldContext));
}
- // For lazy event listener, the listener object is the same as its listener
- // function without additional scope chains.
- virtual v8::Local<v8::Object> getListenerObject() { return getWrappedListenerFunction(); }
+ virtual bool isLazy() const { return true; }
+
+ protected:
+ virtual void prepareListenerObject(ScriptExecutionContext*);
private:
- V8LazyEventListener(Frame*, const String& code, const String& functionName, bool isSVGEvent);
- virtual ~V8LazyEventListener();
+ V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber, const WorldContextHandle& worldContext);
- virtual bool virtualisAttribute() const { return true; }
+ virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
- String m_code;
String m_functionName;
bool m_isSVGEvent;
- bool m_compiled;
-
- // If the event listener is on a non-document dom node, we compile the function with some implicit scope chains before it.
- bool m_wrappedFunctionCompiled;
- v8::Persistent<v8::Function> m_wrappedFunction;
-
- v8::Local<v8::Function> getWrappedListenerFunction();
-
- virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent);
-
- v8::Local<v8::Function> getListenerFunction();
+ String m_code;
+ String m_sourceURL;
+ int m_lineNumber;
+ int m_columnNumber;
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8NPObject.cpp b/WebCore/bindings/v8/V8NPObject.cpp
index b6bf0f7..bab3688 100644
--- a/WebCore/bindings/v8/V8NPObject.cpp
+++ b/WebCore/bindings/v8/V8NPObject.cpp
@@ -33,6 +33,7 @@
#include "V8NPObject.h"
#include "HTMLPlugInElement.h"
+#include "IdentifierRep.h"
#include "NPV8Object.h"
#include "V8CustomBinding.h"
#include "V8DOMMap.h"
@@ -44,7 +45,7 @@
#include "V8Proxy.h"
#include "npruntime_impl.h"
#include "npruntime_priv.h"
-#include "wtf/OwnArrayPtr.h"
+#include <wtf/OwnArrayPtr.h>
using namespace WebCore;
@@ -93,27 +94,31 @@ static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, Invok
NPVariant result;
VOID_TO_NPVARIANT(result);
+ bool retval = true;
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);
+ retval = npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result);
}
break;
case InvokeConstruct:
if (npObject->_class->construct)
- npObject->_class->construct(npObject, npArgs.get(), numArgs, &result);
+ retval = npObject->_class->construct(npObject, npArgs.get(), numArgs, &result);
break;
case InvokeDefault:
if (npObject->_class->invokeDefault)
- npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result);
+ retval = npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result);
break;
default:
break;
}
- for (int i=0; i < numArgs; i++)
+ if (!retval)
+ throwError("Error calling method on NPObject!", V8Proxy::GeneralError);
+
+ for (int i = 0; i < numArgs; i++)
_NPN_ReleaseVariantValue(&npArgs[i]);
// Unwrap return values.
@@ -134,8 +139,8 @@ v8::Handle<v8::Value> npObjectInvokeDefaultHandler(const v8::Arguments& args)
{
if (args.IsConstructCall())
return npObjectInvokeImpl(args, InvokeConstruct);
- else
- return npObjectInvokeImpl(args, InvokeDefault);
+
+ return npObjectInvokeImpl(args, InvokeDefault);
}
@@ -176,7 +181,9 @@ static v8::Handle<v8::Value> npObjectGetProperty(v8::Local<v8::Object> self, NPI
_NPN_ReleaseVariantValue(&result);
return returnValue;
- } else if (key->IsString() && npObject->_class->hasMethod && npObject->_class->hasMethod(npObject, identifier)) {
+ }
+
+ 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.
@@ -271,6 +278,44 @@ v8::Handle<v8::Value> npObjectSetIndexedProperty(v8::Local<v8::Object> self, uin
return npObjectSetProperty(self, identifier, value);
}
+v8::Handle<v8::Array> npObjectPropertyEnumerator(const v8::AccessorInfo& info, bool namedProperty)
+{
+ NPObject* npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, info.Holder());
+
+ // Verify that our wrapper wasn't using a NPObject which
+ // has already been deleted.
+ if (!npObject || !_NPN_IsAlive(npObject))
+ throwError("NPObject deleted", V8Proxy::ReferenceError);
+
+ if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) {
+ uint32_t count;
+ NPIdentifier* identifiers;
+ if (npObject->_class->enumerate(npObject, &identifiers, &count)) {
+ v8::Handle<v8::Array> properties = v8::Array::New(count);
+ for (uint32_t i = 0; i < count; ++i) {
+ IdentifierRep* identifier = static_cast<IdentifierRep*>(identifiers[i]);
+ if (namedProperty)
+ properties->Set(v8::Integer::New(i), v8::String::New(identifier->string()));
+ else
+ properties->Set(v8::Integer::New(i), v8::Integer::New(identifier->number()));
+ }
+
+ return properties;
+ }
+ }
+
+ return v8::Handle<v8::Array>();
+}
+
+v8::Handle<v8::Array> npObjectNamedPropertyEnumerator(const v8::AccessorInfo& info)
+{
+ return npObjectPropertyEnumerator(info, true);
+}
+
+v8::Handle<v8::Array> npObjectIndexedPropertyEnumerator(const v8::AccessorInfo& info)
+{
+ return npObjectPropertyEnumerator(info, false);
+}
static void weakNPObjectCallback(v8::Persistent<v8::Value>, void* parameter);
@@ -313,8 +358,8 @@ v8::Local<v8::Object> createV8ObjectForNPObject(NPObject* object, NPObject* root
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()->SetNamedPropertyHandler(npObjectNamedPropertyGetter, npObjectNamedPropertySetter, 0, 0, npObjectNamedPropertyEnumerator);
+ npObjectDesc->InstanceTemplate()->SetIndexedPropertyHandler(npObjectIndexedPropertyGetter, npObjectIndexedPropertySetter, 0, 0, npObjectIndexedPropertyEnumerator);
npObjectDesc->InstanceTemplate()->SetCallAsFunctionHandler(npObjectInvokeDefaultHandler);
}
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.cpp b/WebCore/bindings/v8/V8ObjectEventListener.cpp
deleted file mode 100644
index f10766c..0000000
--- a/WebCore/bindings/v8/V8ObjectEventListener.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "V8ObjectEventListener.h"
-
-#include "Frame.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
-{
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(parameter);
-
- // Remove the wrapper
- Frame* frame = listener->frame();
- if (frame) {
- V8Proxy* proxy = V8Proxy::retrieve(frame);
- if (proxy)
- proxy->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.
- listener->disconnectFrame();
- }
- 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)
-{
- m_listener.MakeWeak(this, weakObjectEventListenerCallback);
-}
-
-V8ObjectEventListener::~V8ObjectEventListener()
-{
- if (m_frame) {
- ASSERT(!m_listener.IsEmpty());
- V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- if (proxy)
- proxy->objectListeners()->remove(this);
- }
-
- disposeListenerObject();
-}
-
-} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 1cfafb8..5da73d5 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -32,11 +32,15 @@
#include "V8Proxy.h"
#include "CSSMutableStyleDeclaration.h"
-#include "CString.h"
+#include "DateExtension.h"
#include "DOMObjectsInclude.h"
#include "DocumentLoader.h"
#include "FrameLoaderClient.h"
+#include "InspectorTimelineAgent.h"
+#include "Page.h"
+#include "PageGroup.h"
#include "ScriptController.h"
+#include "StorageNamespace.h"
#include "V8Binding.h"
#include "V8Collection.h"
#include "V8ConsoleMessage.h"
@@ -46,12 +50,17 @@
#include "V8HiddenPropertyName.h"
#include "V8Index.h"
#include "V8IsolatedWorld.h"
+#include "WorkerContextExecutionProxy.h"
+#include <algorithm>
+#include <stdio.h>
+#include <utility>
#include <v8.h>
#include <v8-debug.h>
#include <wtf/Assertions.h>
#include <wtf/OwnArrayPtr.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/StringExtras.h>
#include <wtf/UnusedParam.h>
#if PLATFORM(CHROMIUM)
@@ -62,30 +71,45 @@
#include "TimeCounter.h"
#endif
+#if PLATFORM(ANDROID)
+#include "CString.h"
+#endif
+
namespace WebCore {
v8::Persistent<v8::Context> V8Proxy::m_utilityContext;
// Static list of registered extensions
-V8ExtensionList V8Proxy::m_extensions;
+V8Extensions 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)
+ configureAttribute(instance, proto, attributes[i]);
+}
-void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute* attributes, size_t attributeCount)
+void batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate> proto,
+ v8::Handle<v8::Signature> signature,
+ v8::PropertyAttribute attributes,
+ const BatchedCallback* callbacks,
+ size_t callbackCount)
{
- 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);
+ for (size_t i = 0; i < callbackCount; ++i) {
+ proto->Set(v8::String::New(callbacks[i].name),
+ v8::FunctionTemplate::New(callbacks[i].callback,
+ v8::Handle<v8::Value>(),
+ signature),
+ attributes);
}
}
-void batchConfigureConstants(v8::Handle<v8::FunctionTemplate> functionDescriptor, v8::Handle<v8::ObjectTemplate> proto, const BatchedConstant* constants, size_t constantCount)
+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];
@@ -213,6 +237,14 @@ static void reportFatalErrorInV8(const char* location, const char* message)
handleFatalErrorInV8();
}
+V8Proxy::V8Proxy(Frame* frame)
+ : m_frame(frame)
+ , m_inlineCode(false)
+ , m_timerCallback(false)
+ , m_recursion(0)
+{
+}
+
V8Proxy::~V8Proxy()
{
clearForClose();
@@ -230,22 +262,6 @@ void V8Proxy::destroyGlobal()
}
}
-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)
#ifdef ANDROID_INSTRUMENT
{
@@ -288,6 +304,7 @@ bool V8Proxy::handleOutOfMemory()
// TODO (andreip): ChromeBridge -> BrowserBridge?
ChromiumBridge::notifyJSOutOfMemory(frame);
#endif
+
// Disable JS.
Settings* settings = frame->settings();
ASSERT(settings);
@@ -296,10 +313,48 @@ bool V8Proxy::handleOutOfMemory()
return true;
}
-void V8Proxy::evaluateInNewWorld(const Vector<ScriptSourceCode>& sources, int extensionGroup)
+void V8Proxy::evaluateInIsolatedWorld(int worldID, const Vector<ScriptSourceCode>& sources, int extensionGroup)
{
initContextIfNeeded();
- V8IsolatedWorld::evaluate(sources, this, extensionGroup);
+
+ v8::HandleScope handleScope;
+ V8IsolatedWorld* world = 0;
+
+ if (worldID > 0) {
+ IsolatedWorldMap::iterator iter = m_isolatedWorlds.find(worldID);
+ if (iter != m_isolatedWorlds.end()) {
+ world = iter->second;
+ } else {
+ world = new V8IsolatedWorld(this, extensionGroup);
+ if (world->context().IsEmpty()) {
+ delete world;
+ return;
+ }
+
+ m_isolatedWorlds.set(worldID, world);
+
+ // Setup context id for JS debugger.
+ if (!setInjectedScriptContextDebugId(world->context())) {
+ m_isolatedWorlds.take(worldID);
+ delete world;
+ return;
+ }
+ }
+ } else {
+ world = new V8IsolatedWorld(this, extensionGroup);
+ if (world->context().IsEmpty()) {
+ delete world;
+ return;
+ }
+ }
+
+ v8::Local<v8::Context> context = v8::Local<v8::Context>::New(world->context());
+ v8::Context::Scope context_scope(context);
+ for (size_t i = 0; i < sources.size(); ++i)
+ evaluate(sources[i], 0);
+
+ if (worldID == 0)
+ world->destroy();
}
void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int extensionGroup)
@@ -316,17 +371,16 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int
ASSERT(V8DOMWrapper::convertDOMWrapperToNative<DOMWindow>(windowWrapper) == m_frame->domWindow());
v8::Persistent<v8::Context> context = createNewContext(v8::Handle<v8::Object>(), extensionGroup);
+ if (context.IsEmpty())
+ return;
+
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));
+ if (!setInjectedScriptContextDebugId(context)) {
+ context.Dispose();
+ return;
}
- contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("injected"));
- context->SetData(contextData);
v8::Handle<v8::Object> global = context->Global();
@@ -352,41 +406,73 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int
context.Dispose();
}
+bool V8Proxy::setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext)
+{
+ // Setup context id for JS debugger.
+ v8::Context::Scope contextScope(targetContext);
+ if (m_context.IsEmpty())
+ return false;
+ int debugId = contextDebugId(m_context);
+
+ char buffer[32];
+ if (debugId == -1)
+ snprintf(buffer, sizeof(buffer), "injected");
+ else
+ snprintf(buffer, sizeof(buffer), "injected,%d", debugId);
+ targetContext->SetData(v8::String::New(buffer));
+
+ return true;
+}
+
v8::Local<v8::Value> V8Proxy::evaluate(const ScriptSourceCode& source, Node* node)
{
ASSERT(v8::Context::InContext());
- LOCK_V8;
- // Compile the script.
- v8::Local<v8::String> code = v8ExternalString(source.source());
-#if PLATFORM(CHROMIUM)
- // TODO(andreip): ChromeBridge->BrowserBridge?
- ChromiumBridge::traceEventBegin("v8.compile", node, "");
-#endif
+ V8GCController::checkMemoryUsage();
- // 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);
-#if PLATFORM(CHROMIUM)
- // TODO(andreip): ChromeBridge->BrowserBridge?
- ChromiumBridge::traceEventEnd("v8.compile", node, "");
- ChromiumBridge::traceEventBegin("v8.run", node, "");
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0)
+ timelineAgent->willEvaluateScript(source.url().isNull() ? String() : source.url().string(), source.startLine());
#endif
+
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.
+ // Isolate exceptions that occur when compiling and 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);
+ // Compile the script.
+ v8::Local<v8::String> code = v8ExternalString(source.source());
+#if PLATFORM(CHROMIUM)
+ // TODO(andreip): ChromeBridge->BrowserBridge?
+ ChromiumBridge::traceEventBegin("v8.compile", node, "");
+#endif
+
+ // 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);
+#if PLATFORM(CHROMIUM)
+ // TODO(andreip): ChromeBridge->BrowserBridge?
+ ChromiumBridge::traceEventEnd("v8.compile", node, "");
+
+ ChromiumBridge::traceEventBegin("v8.run", node, "");
+#endif
// 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());
}
+
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0)
+ timelineAgent->didEvaluateScript();
+#endif
+
#if PLATFORM(CHROMIUM)
- // TODO(andreip): ChromeBridge->BrowserBridge?
+ // TODO(andreip): upstream CHROMIUM guards to webkit.org
ChromiumBridge::traceEventEnd("v8.run", node, "");
#endif
return result;
@@ -407,6 +493,7 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b
if (script.IsEmpty())
return notHandledByInterceptor();
+ V8GCController::checkMemoryUsage();
// Compute the source string and prevent against infinite recursion.
if (m_recursion >= kMaxRecursionDepth) {
v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')");
@@ -431,15 +518,18 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b
v8::Local<v8::Value> result;
{
V8ConsoleMessage::Scope scope;
- m_recursion++;
// See comment in V8Proxy::callFunction.
m_frame->keepAlive();
+ m_recursion++;
result = script->Run();
m_recursion--;
}
+ // Release the storage mutex if applicable.
+ releaseStorageMutex();
+
if (handleOutOfMemory())
ASSERT(result.IsEmpty());
@@ -461,14 +551,22 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::JavaScriptExecuteTimeCounter);
#endif
-
- // 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.
+ V8GCController::checkMemoryUsage();
v8::Local<v8::Value> result;
{
V8ConsoleMessage::Scope scope;
+ if (m_recursion >= kMaxRecursionDepth) {
+ v8::Local<v8::String> code = v8::String::New("throw new RangeError('Maximum call stack size exceeded.')");
+ if (code.IsEmpty())
+ return result;
+ v8::Local<v8::Script> script = v8::Script::Compile(code);
+ if (script.IsEmpty())
+ return result;
+ script->Run();
+ return result;
+ }
+
// 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
@@ -476,9 +574,14 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8
// execution finishs before firing the timer.
m_frame->keepAlive();
+ m_recursion++;
result = function->Call(receiver, argc, args);
+ m_recursion--;
}
+ // Release the storage mutex if applicable.
+ releaseStorageMutex();
+
if (v8::V8::IsDead())
handleFatalErrorInV8();
@@ -508,14 +611,10 @@ v8::Local<v8::Value> V8Proxy::newInstance(v8::Handle<v8::Function> constructor,
return result;
}
-v8::Local<v8::Object> V8Proxy::createWrapperFromCache(V8ClassIndex::V8WrapperType type)
+v8::Local<v8::Object> V8Proxy::createWrapperFromCacheSlowCase(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.
+ int classIndex = V8ClassIndex::ToInt(type);
initContextIfNeeded();
v8::Context::Scope scope(m_context);
v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(m_context));
@@ -547,7 +646,14 @@ DOMWindow* V8Proxy::retrieveWindow(v8::Handle<v8::Context> context)
Frame* V8Proxy::retrieveFrame(v8::Handle<v8::Context> context)
{
- return retrieveWindow(context)->frame();
+ DOMWindow* window = retrieveWindow(context);
+ Frame* frame = window->frame();
+ if (frame && frame->domWindow() == window)
+ return frame;
+ // We return 0 here because |context| is detached from the Frame. If we
+ // did return |frame| we could get in trouble because the frame could be
+ // navigated to another security origin.
+ return 0;
}
Frame* V8Proxy::retrieveFrameForEnteredContext()
@@ -597,60 +703,6 @@ V8Proxy* V8Proxy::retrieve(ScriptExecutionContext* context)
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 PLATFORM(CHROMIUM)
- // TODO(andreip): ChromeBridge->BrowserBridge?
- if (origin->protocol() == ChromiumBridge::uiResourceProtocol())
- return true; // Embedder's scripts are ok to run
-#endif
-
- // 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" };
-#if PLATFORM(ANDROID)
- // TODO(andreip): Port arraysize function to Android. There's one in Gears.
- for (size_t i = 0; i < 2; ++i) {
-#else
- for (size_t i = 0; i < arraysize(kDirProtocols); ++i) {
-#endif
- 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)
@@ -677,9 +729,8 @@ void V8Proxy::clearDocumentWrapper()
void V8Proxy::updateDocumentWrapperCache()
{
- LOCK_V8;
v8::HandleScope handleScope;
- v8::Context::Scope contextScope(context());
+ v8::Context::Scope contextScope(m_context);
// If the document has no frame, NodeToV8Object might get the
// document wrapper for a document that is about to be deleted.
@@ -727,10 +778,34 @@ void V8Proxy::disposeContextHandles()
}
}
+void V8Proxy::releaseStorageMutex()
+{
+ // If we've just left a top level script context and local storage has been
+ // instantiated, we must ensure that any storage locks have been freed.
+ // Per http://dev.w3.org/html5/spec/Overview.html#storage-mutex
+ if (m_recursion != 0)
+ return;
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+ if (page->group().hasLocalStorage())
+ page->group().localStorage()->unlock();
+}
+
+void V8Proxy::resetIsolatedWorlds()
+{
+ for (IsolatedWorldMap::iterator iter = m_isolatedWorlds.begin();
+ iter != m_isolatedWorlds.end(); ++iter) {
+ iter->second->destroy();
+ }
+ m_isolatedWorlds.clear();
+}
+
void V8Proxy::clearForClose()
{
+ resetIsolatedWorlds();
+
if (!m_context.IsEmpty()) {
- LOCK_V8;
v8::HandleScope handleScope;
clearDocumentWrapper();
@@ -740,10 +815,9 @@ void V8Proxy::clearForClose()
void V8Proxy::clearForNavigation()
{
- disconnectEventListeners();
+ resetIsolatedWorlds();
if (!m_context.IsEmpty()) {
- LOCK_V8;
v8::HandleScope handle;
clearDocumentWrapper();
@@ -816,6 +890,10 @@ void V8Proxy::updateDocument()
// global object wrapper succeed.
initContextIfNeeded();
+ // Bail out if context initialization failed.
+ if (m_context.IsEmpty())
+ return;
+
// We have a new document and we need to update the cache.
updateDocumentWrapperCache();
@@ -824,7 +902,6 @@ void V8Proxy::updateDocument()
void V8Proxy::updateSecurityOrigin()
{
- LOCK_V8;
v8::HandleScope scope;
setSecurityToken();
}
@@ -861,14 +938,20 @@ bool V8Proxy::canAccessPrivate(DOMWindow* targetWindow)
String message;
- DOMWindow* originWindow = retrieveWindow(currentContext());
- if (originWindow == targetWindow)
+ v8::Local<v8::Context> activeContext = v8::Context::GetCalling();
+ if (activeContext.IsEmpty()) {
+ // There is a single activation record on the stack, so that must
+ // be the activeContext.
+ activeContext = v8::Context::GetCurrent();
+ }
+ DOMWindow* activeWindow = retrieveWindow(activeContext);
+ if (activeWindow == targetWindow)
return true;
- if (!originWindow)
+ if (!activeWindow)
return false;
- const SecurityOrigin* activeSecurityOrigin = originWindow->securityOrigin();
+ const SecurityOrigin* activeSecurityOrigin = activeWindow->securityOrigin();
const SecurityOrigin* targetSecurityOrigin = targetWindow->securityOrigin();
// We have seen crashes were the security origin of the target has not been
@@ -881,7 +964,7 @@ bool V8Proxy::canAccessPrivate(DOMWindow* targetWindow)
// 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())
+ if (targetSecurityOrigin->isEmpty() && activeWindow->frame() == targetWindow->frame())
return true;
return false;
@@ -930,21 +1013,26 @@ v8::Persistent<v8::Context> V8Proxy::createNewContext(v8::Handle<v8::Object> glo
// Install a security handler with V8.
globalTemplate->SetAccessCheckCallbacks(V8Custom::v8DOMWindowNamedSecurityCheck, V8Custom::v8DOMWindowIndexedSecurityCheck, v8::Integer::New(V8ClassIndex::DOMWINDOW));
+ globalTemplate->SetInternalFieldCount(V8Custom::kDOMWindowInternalFieldCount);
+
+ // Used to avoid sleep calls in unload handlers.
+ if (!registeredExtensionWithV8(DateExtension::get()))
+ registerExtension(DateExtension::get(), String());
// 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)
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ if (m_extensions[i].group && m_extensions[i].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()))
+ if (m_extensions[i].scheme.length() > 0 && (m_extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol() || m_extensions[i].scheme != m_frame->page()->mainFrame()->loader()->activeDocumentLoader()->url().protocol()))
continue;
- extensionNames[index++] = it->extension->name();
+ extensionNames[index++] = m_extensions[i].extension->name();
}
v8::ExtensionConfiguration extensions(index, extensionNames.get());
result = v8::Context::New(&extensions, globalTemplate, global);
@@ -967,12 +1055,14 @@ bool V8Proxy::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* windo
// Wrap the window.
V8DOMWrapper::setDOMWrapper(jsWindow, V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
+ V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), 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();
+ V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(v8Global->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window);
v8Global->Set(implicitProtoString, jsWindow);
return true;
}
@@ -1021,7 +1111,6 @@ void V8Proxy::initContextIfNeeded()
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::start(android::TimeCounter::JavaScriptInitTimeCounter);
#endif
- LOCK_V8;
// Create a handle scope for all local handles.
v8::HandleScope handleScope;
@@ -1044,12 +1133,12 @@ void V8Proxy::initContextIfNeeded()
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::Local<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context);
v8::Context::Scope contextScope(v8Context);
// Store the first global object created so we can reuse it.
@@ -1065,7 +1154,7 @@ void V8Proxy::initContextIfNeeded()
#endif
}
- installHiddenObjectPrototype(m_context);
+ installHiddenObjectPrototype(v8Context);
m_wrapperBoilerplates = v8::Persistent<v8::Array>::New(v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT));
// Bail out if allocation failed.
if (m_wrapperBoilerplates.IsEmpty()) {
@@ -1084,7 +1173,11 @@ void V8Proxy::initContextIfNeeded()
setSecurityToken();
m_frame->loader()->client()->didCreateScriptContextForFrame();
- m_frame->loader()->dispatchWindowObjectAvailable();
+
+ // FIXME: This is wrong. We should actually do this for the proper world once
+ // we do isolated worlds the WebCore way.
+ m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
+
#ifdef ANDROID_INSTRUMENT
android::TimeCounter::record(android::TimeCounter::JavaScriptInitTimeCounter, __FUNCTION__);
#endif
@@ -1162,14 +1255,30 @@ v8::Local<v8::Context> V8Proxy::context(Frame* frame)
return context;
}
+v8::Local<v8::Context> V8Proxy::context()
+{
+ if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered()) {
+ RefPtr<SharedPersistent<v8::Context> > context = world->sharedContext();
+ if (m_frame != V8Proxy::retrieveFrame(context->get()))
+ return v8::Local<v8::Context>();
+ return v8::Local<v8::Context>::New(context->get());
+ }
+ return mainWorldContext();
+}
+
+v8::Local<v8::Context> V8Proxy::mainWorldContext()
+{
+ initContextIfNeeded();
+ return v8::Local<v8::Context>::New(m_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();
+ return proxy->mainWorldContext();
}
v8::Local<v8::Context> V8Proxy::currentContext()
@@ -1238,7 +1347,7 @@ void V8Proxy::createUtilityContext()
v8::Script::Compile(v8::String::New(frameSourceNameSource))->Run();
}
-int V8Proxy::sourceLineNumber()
+bool V8Proxy::sourceLineNumber(int& result)
{
#if PLATFORM(ANDROID)
// TODO(andreip): consider V8's DEBUG flag here, rather than PLATFORM(ANDROID)
@@ -1248,45 +1357,57 @@ int V8Proxy::sourceLineNumber()
v8::HandleScope scope;
v8::Handle<v8::Context> v8UtilityContext = V8Proxy::utilityContext();
if (v8UtilityContext.IsEmpty())
- return 0;
+ return false;
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();
+ return false;
+ v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceLine);
+ if (value.IsEmpty())
+ return false;
+ result = value->Int32Value();
+ return true;
#endif
}
-String V8Proxy::sourceName()
+bool V8Proxy::sourceName(String& result)
{
#if PLATFORM(ANDROID)
- return String();
+ return false;
#else
v8::HandleScope scope;
v8::Handle<v8::Context> v8UtilityContext = utilityContext();
if (v8UtilityContext.IsEmpty())
- return String();
+ return false;
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));
+ return false;
+ v8::Handle<v8::Value> value = v8::Debug::Call(frameSourceName);
+ if (value.IsEmpty())
+ return false;
+ result = toWebCoreString(value);
+ return true;
#endif
}
-void V8Proxy::registerExtensionWithV8(v8::Extension* extension) {
+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;
+ if (!registeredExtensionWithV8(extension))
+ v8::RegisterExtension(extension);
+}
+
+bool V8Proxy::registeredExtensionWithV8(v8::Extension* extension)
+{
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ if (m_extensions[i].extension == extension)
+ return true;
}
- v8::RegisterExtension(extension);
+ return false;
}
void V8Proxy::registerExtension(v8::Extension* extension, const String& schemeRestriction)
@@ -1313,20 +1434,24 @@ bool V8Proxy::setContextDebugId(int debugId)
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);
+
+ char buffer[32];
+ snprintf(buffer, sizeof(buffer), "page,%d", debugId);
+ m_context->SetData(v8::String::New(buffer));
+
return true;
}
int V8Proxy::contextDebugId(v8::Handle<v8::Context> context)
{
v8::HandleScope scope;
- if (!context->GetData()->IsObject())
+ if (!context->GetData()->IsString())
+ return -1;
+ v8::String::AsciiValue ascii(context->GetData());
+ char* comma = strnstr(*ascii, ",", ascii.length());
+ if (!comma)
return -1;
- v8::Handle<v8::Value> data = context->GetData()->ToObject()->Get( v8::String::New(kContextDebugDataValue));
- return data->IsInt32() ? data->Int32Value() : -1;
+ return atoi(comma + 1);
}
v8::Handle<v8::Value> V8Proxy::getHiddenObjectPrototype(v8::Handle<v8::Context> context)
@@ -1349,4 +1474,16 @@ void V8Proxy::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype);
}
+v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context, const WorldContextHandle& worldContext)
+{
+ if (context->isDocument()) {
+ if (V8Proxy* proxy = V8Proxy::retrieve(context))
+ return worldContext.adjustedContext(proxy);
+ } else if (context->isWorkerContext()) {
+ if (WorkerContextExecutionProxy* proxy = static_cast<WorkerContext*>(context)->script()->proxy())
+ return proxy->context();
+ }
+ return v8::Local<v8::Context>();
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index d8f546c..900ee18 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -31,20 +31,14 @@
#ifndef V8Proxy_h
#define V8Proxy_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 "SharedPersistent.h"
+#include "V8AbstractEventListener.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>
@@ -57,49 +51,15 @@
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;
+ class V8IsolatedWorld;
+ class WorldContextHandle;
// FIXME: use standard logging facilities in WebCore.
void logInfo(Frame*, const String& message, const String& url);
@@ -123,6 +83,16 @@ namespace WebCore {
void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount);
+ inline void configureAttribute(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute& attribute)
+ {
+ (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);
+ }
+
// 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.
@@ -133,6 +103,17 @@ namespace WebCore {
void batchConfigureConstants(v8::Handle<v8::FunctionTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedConstant*, size_t constantCount);
+ struct BatchedCallback {
+ const char* const name;
+ v8::InvocationCallback callback;
+ };
+
+ void batchConfigureCallbacks(v8::Handle<v8::ObjectTemplate>,
+ v8::Handle<v8::Signature>,
+ v8::PropertyAttribute,
+ const BatchedCallback*,
+ size_t callbackCount);
+
const int kMaxRecursionDepth = 20;
// Information about an extension that is registered for use with V8. If
@@ -145,7 +126,7 @@ namespace WebCore {
int group;
v8::Extension* extension;
};
- typedef WTF::Vector<V8ExtensionInfo> V8ExtensionList;
+ typedef WTF::Vector<V8ExtensionInfo> V8Extensions;
class V8Proxy {
public:
@@ -158,7 +139,7 @@ namespace WebCore {
GeneralError
};
- explicit V8Proxy(Frame* frame) : m_frame(frame), m_inlineCode(false), m_timerCallback(false), m_recursion(0) { }
+ explicit V8Proxy(Frame*);
~V8Proxy();
@@ -194,14 +175,36 @@ namespace WebCore {
// 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*);
+
+ // These helper functions are required in case we are given a PassRefPtr
+ // to a (possibly) newly created object and must prevent its reference
+ // count from dropping to zero as would happen in code like
+ //
+ // V8Proxy::setSVGContext(imp->getNewlyCreatedObject().get(), context);
+ // foo(imp->getNewlyCreatedObject().get());
+ //
+ // In the above two lines each time getNewlyCreatedObject() is called it
+ // creates a new object because we don't ref() it. (So our attemts to
+ // associate a context with it fail.) Such code should be rewritten to
+ //
+ // foo(V8Proxy::withSVGContext(imp->getNewlyCreatedObject(), context).get());
+ //
+ // where PassRefPtr::~PassRefPtr() is invoked only after foo() is
+ // called.
+ template <typename T>
+ static PassRefPtr<T> withSVGContext(PassRefPtr<T> object, SVGElement* context)
+ {
+ setSVGContext(object.get(), context);
+ return object;
+ }
+ static void* withSVGContext(void* object, SVGElement* context)
+ {
+ setSVGContext(object, context);
+ return object;
+ }
#endif
void setEventHandlerLineNumber(int lineNumber) { m_handlerLineNumber = lineNumber; }
@@ -211,7 +214,7 @@ namespace WebCore {
// 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);
+ void evaluateInIsolatedWorld(int worldId, 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,
@@ -239,7 +242,12 @@ namespace WebCore {
// 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);
+ v8::Local<v8::Object> createWrapperFromCache(V8ClassIndex::V8WrapperType type)
+ {
+ int classIndex = V8ClassIndex::ToInt(type);
+ v8::Local<v8::Object> clone(m_wrapperBoilerplates->CloneElementAt(classIndex));
+ return clone.IsEmpty() ? createWrapperFromCacheSlowCase(type) : clone;
+ }
// Returns the window object associated with a context.
static DOMWindow* retrieveWindow(v8::Handle<v8::Context>);
@@ -331,14 +339,16 @@ namespace WebCore {
// Function for retrieving the line number and source name for the top
// JavaScript stack frame.
- static int sourceLineNumber();
- static String sourceName();
+ //
+ // It will return true if the line number was successfully retrieved and written
+ // into the |result| parameter, otherwise the function will return false. It may
+ // fail due to a stck overflow in the underlying JavaScript implentation, handling
+ // of such exception is up to the caller.
+ static bool sourceLineNumber(int& result);
+ static bool sourceName(String& result);
- // Returns a local handle of the context.
- v8::Local<v8::Context> context()
- {
- return v8::Local<v8::Context>::New(m_context);
- }
+ v8::Local<v8::Context> context();
+ v8::Local<v8::Context> mainWorldContext();
bool setContextDebugId(int id);
static int contextDebugId(v8::Handle<v8::Context>);
@@ -365,10 +375,6 @@ namespace WebCore {
void updateDocumentWrapper(v8::Handle<v8::Value> wrapper);
private:
- static const char* kContextDebugDataType;
- static const char* kContextDebugDataValue;
-
- void disconnectEventListeners();
void setSecurityToken();
void clearDocumentWrapper();
@@ -382,6 +388,15 @@ namespace WebCore {
// Dispose global handles of m_contexts and friends.
void disposeContextHandles();
+ // If m_recursionCount is 0, let LocalStorage know so we can release
+ // the storage mutex.
+ void releaseStorageMutex();
+
+ void resetIsolatedWorlds();
+
+ // Returns false when we're out of memory in V8.
+ bool setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetContext);
+
static bool canAccessPrivate(DOMWindow*);
static const char* rangeExceptionName(int exceptionCode);
@@ -407,11 +422,15 @@ namespace WebCore {
return v8::Local<v8::Context>::New(m_utilityContext);
}
+ v8::Local<v8::Object> createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType);
+
static void registerExtensionWithV8(v8::Extension*);
+ static bool registeredExtensionWithV8(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
@@ -426,14 +445,6 @@ namespace WebCore {
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;
@@ -447,8 +458,18 @@ namespace WebCore {
// excessive recursion in the binding layer.
int m_recursion;
- // List of extensions registered with the context.
- static V8ExtensionList m_extensions;
+ // All of the extensions registered with the context.
+ static V8Extensions m_extensions;
+
+ // The isolated worlds we are tracking for this frame. We hold them alive
+ // here so that they can be used again by future calls to
+ // evaluateInIsolatedWorld().
+ //
+ // Note: although the pointer is raw, the instance is kept alive by a strong
+ // reference to the v8 context it contains, which is not made weak until we
+ // call world->destroy().
+ typedef HashMap<int, V8IsolatedWorld*> IsolatedWorldMap;
+ IsolatedWorldMap m_isolatedWorlds;
};
template <int tag, typename T>
@@ -467,6 +488,8 @@ namespace WebCore {
}
+ v8::Local<v8::Context> toV8Context(ScriptExecutionContext*, const WorldContextHandle& worldContext);
+
// Used by an interceptor callback that it hasn't found anything to
// intercept.
inline static v8::Local<v8::Object> notHandledByInterceptor()
diff --git a/WebCore/bindings/v8/V8Utilities.cpp b/WebCore/bindings/v8/V8Utilities.cpp
index c1ac6d4..c547cc7 100644
--- a/WebCore/bindings/v8/V8Utilities.cpp
+++ b/WebCore/bindings/v8/V8Utilities.cpp
@@ -33,8 +33,15 @@
#include <v8.h>
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptExecutionContext.h"
+#include "ScriptState.h"
#include "V8CustomBinding.h"
+#include "V8Binding.h"
#include "V8Proxy.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
#include <wtf/Assertions.h>
#include "Frame.h"
@@ -43,7 +50,7 @@ namespace WebCore {
// Use an array to hold dependents. It works like a ref-counted scheme.
// A value can be added more than once to the DOM object.
-void createHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
+void createHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
{
v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
if (cache->IsNull() || cache->IsUndefined()) {
@@ -55,7 +62,7 @@ void createHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> v
cacheArray->Set(v8::Integer::New(cacheArray->Length()), value);
}
-void removeHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
+void removeHiddenDependency(v8::Handle<v8::Object> object, v8::Local<v8::Value> value, int cacheIndex)
{
v8::Local<v8::Value> cache = object->GetInternalField(cacheIndex);
if (!cache->IsArray())
@@ -69,6 +76,24 @@ void removeHiddenDependency(v8::Local<v8::Object> object, v8::Local<v8::Value> v
}
}
}
+
+void transferHiddenDependency(v8::Handle<v8::Object> object,
+ EventListener* oldValue,
+ v8::Local<v8::Value> newValue,
+ int cacheIndex)
+{
+ if (oldValue) {
+ V8AbstractEventListener* oldListener = V8AbstractEventListener::cast(oldValue);
+ if (oldListener) {
+ v8::Local<v8::Object> oldListenerObject = oldListener->getExistingListenerObject();
+ if (!oldListenerObject.IsEmpty())
+ removeHiddenDependency(object, oldListenerObject, cacheIndex);
+ }
+ }
+ if (!newValue->IsNull() && !newValue->IsUndefined())
+ createHiddenDependency(object, newValue, cacheIndex);
+}
+
bool processingUserGesture()
{
@@ -98,7 +123,55 @@ void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool loc
return;
if (!protocolIsJavaScript(url) || ScriptController::isSafeScript(frame))
- frame->loader()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
+ frame->redirectScheduler()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
+}
+
+ScriptExecutionContext* getScriptExecutionContext(ScriptState* scriptState)
+{
+#if ENABLE(WORKERS)
+ WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+ if (proxy)
+ return proxy->workerContext()->scriptExecutionContext();
+#endif
+
+ if (scriptState)
+ return scriptState->frame()->document()->scriptExecutionContext();
+ else {
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (frame)
+ return frame->document()->scriptExecutionContext();
+ }
+
+ return 0;
+}
+
+void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher)
+{
+ String errorMessage;
+ int lineNumber = 0;
+ String sourceURL;
+
+ // There can be a situation that an exception is thrown without setting a message.
+ v8::Local<v8::Message> message = exceptionCatcher.Message();
+ if (message.IsEmpty()) {
+ v8::Local<v8::String> exceptionString = exceptionCatcher.Exception()->ToString();
+ // Conversion of the exception object to string can fail if an
+ // exception is thrown during conversion.
+ if (!exceptionString.IsEmpty())
+ errorMessage = toWebCoreString(exceptionString);
+ } else {
+ errorMessage = toWebCoreString(message->Get());
+ lineNumber = message->GetLineNumber();
+ sourceURL = toWebCoreString(message->GetScriptResourceName());
+ }
+
+ // Do not report the exception if the current execution context is Document because we do not want to lead to duplicate error messages in the console.
+ // FIXME (31171): need better design to solve the duplicate error message reporting problem.
+ ScriptExecutionContext* context = getScriptExecutionContext(scriptState);
+ // During the frame teardown, there may not be a valid context.
+ if (context && !context->isDocument())
+ context->reportException(errorMessage, lineNumber, sourceURL);
+ exceptionCatcher.Reset();
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Utilities.h b/WebCore/bindings/v8/V8Utilities.h
index 3e59d34..944823a 100644
--- a/WebCore/bindings/v8/V8Utilities.h
+++ b/WebCore/bindings/v8/V8Utilities.h
@@ -31,30 +31,36 @@
#ifndef V8Utilities_h
#define V8Utilities_h
-#if ENABLE(V8_LOCKERS)
-// TODO(benm): Need to re-add in locking for V8. We lost some of the lock points during the merge. Define it to void here so we don't lock some of the time.
-#define LOCK_V8 ((void) 0)
-#else
-#define LOCK_V8 ((void) 0)
-#endif
-
#include <v8.h>
namespace WebCore {
+ class EventListener;
class Frame;
class KURL;
+ class ScriptExecutionContext;
+ class ScriptState;
class String;
// Use an array to hold dependents. It works like a ref-counted scheme. A value can be added more than once to the DOM object.
- void createHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex);
- void removeHiddenDependency(v8::Local<v8::Object>, v8::Local<v8::Value>, int cacheIndex);
-
+ void createHiddenDependency(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex);
+ void removeHiddenDependency(v8::Handle<v8::Object>, v8::Local<v8::Value>, int cacheIndex);
+
+ // Combo create/remove, for generated event-handler-setter bindings:
+ void transferHiddenDependency(v8::Handle<v8::Object>, EventListener* oldValue, v8::Local<v8::Value> newValue, int cacheIndex);
+
bool processingUserGesture();
bool shouldAllowNavigation(Frame*);
KURL completeURL(const String& relativeURL);
void navigateIfAllowed(Frame*, const KURL&, bool lockHistory, bool lockBackForwardList);
+ ScriptExecutionContext* getScriptExecutionContext(ScriptState*);
+ inline ScriptExecutionContext* getScriptExecutionContext() {
+ return getScriptExecutionContext(0);
+ }
+
+ void reportException(ScriptState*, v8::TryCatch&);
+
class AllowAllocation {
public:
inline AllowAllocation()
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index 862cd2d..e5356de 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -36,54 +36,54 @@
#include "Event.h"
#include "V8Binding.h"
-#include "V8Utilities.h"
+#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
namespace WebCore {
-V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
- : V8EventListener(0, listener, isInline)
- , m_proxy(proxy)
+static WorkerContextExecutionProxy* workerProxy(ScriptExecutionContext* context)
{
+ ASSERT(context->isWorkerContext());
+ WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+ return workerContext->script()->proxy();
}
-V8WorkerContextEventListener::~V8WorkerContextEventListener()
+V8WorkerContextEventListener::V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
+ : V8EventListener(listener, isInline, worldContext)
{
- if (m_proxy)
- m_proxy->removeEventListener(this);
- disposeListenerObject();
}
-void V8WorkerContextEventListener::handleEvent(Event* event, bool isWindowEvent)
+void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
{
- // Is the EventListener disconnected?
- if (disconnected())
+ if (!context)
return;
// The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
// See issue 889829.
RefPtr<V8AbstractEventListener> protect(this);
- LOCK_V8;
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = m_proxy->context();
- if (context.IsEmpty())
+ WorkerContextExecutionProxy* proxy = workerProxy(context);
+ if (!proxy)
+ return;
+
+ v8::Handle<v8::Context> v8Context = proxy->context();
+ if (v8Context.IsEmpty())
return;
// 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 = WorkerContextExecutionProxy::convertEventToV8Object(event);
- invokeEventHandler(context, event, jsEvent, isWindowEvent);
+ invokeEventHandler(context, event, jsEvent);
}
-bool V8WorkerContextEventListener::reportError(const String& message, const String& url, int lineNumber)
+bool V8WorkerContextEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber)
{
- // Is the EventListener disconnected?
- if (disconnected())
+ if (!context)
return false;
// The callback function can clear the event listener and destroy 'this' object. Keep a local reference to it.
@@ -91,13 +91,18 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri
v8::HandleScope handleScope;
- v8::Handle<v8::Context> context = m_proxy->context();
- if (context.IsEmpty())
+ WorkerContextExecutionProxy* proxy = workerProxy(context);
+ if (!proxy)
+ return false;
+
+ v8::Handle<v8::Context> v8Context = proxy->context();
+ if (v8Context.IsEmpty())
return false;
// Enter the V8 context in which to perform the event handling.
- v8::Context::Scope scope(context);
+ v8::Context::Scope scope(v8Context);
+ v8::Local<v8::Object> listener = getListenerObject(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.
@@ -105,8 +110,8 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri
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));
+ if (!listener.IsEmpty() && listener->IsFunction()) {
+ v8::Local<v8::Function> callFunction = v8::Local<v8::Function>::Cast(listener);
v8::Local<v8::Object> thisValue = v8::Context::GetCurrent()->Global();
v8::Handle<v8::Value> parameters[3] = { v8String(message), v8String(url), v8::Integer::New(lineNumber) };
@@ -126,28 +131,28 @@ bool V8WorkerContextEventListener::reportError(const String& message, const Stri
return errorHandled;
}
-v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
+v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
- v8::Local<v8::Function> handlerFunction = getListenerFunction();
- v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent);
+ v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
+ v8::Local<v8::Object> receiver = getReceiverObject(context, event);
if (handlerFunction.IsEmpty() || receiver.IsEmpty())
return v8::Local<v8::Value>();
v8::Handle<v8::Value> parameters[1] = { jsEvent };
v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters);
- m_proxy->trackEvent(event);
+ if (WorkerContextExecutionProxy* proxy = workerProxy(context))
+ proxy->trackEvent(event);
return result;
}
-v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* event, bool isWindowEvent)
+v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(ScriptExecutionContext* context, Event* event)
{
- if (!m_listener.IsEmpty() && !m_listener->IsFunction())
- return v8::Local<v8::Object>::New(m_listener);
+ v8::Local<v8::Object> listener = getListenerObject(context);
- if (isWindowEvent)
- return v8::Context::GetCurrent()->Global();
+ if (!listener.IsEmpty() && !listener->IsFunction())
+ return listener;
EventTarget* target = event->currentTarget();
v8::Handle<v8::Value> value = WorkerContextExecutionProxy::convertEventTargetToV8Object(target);
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index c901c51..4487497 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -44,24 +44,19 @@ namespace WebCore {
class V8WorkerContextEventListener : public V8EventListener {
public:
- static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
+ static PassRefPtr<V8WorkerContextEventListener> create(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext)
{
- return adoptRef(new V8WorkerContextEventListener(proxy, listener, isInline));
+ return adoptRef(new V8WorkerContextEventListener(listener, isInline, worldContext));
}
- V8WorkerContextEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline);
- 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; }
- void disconnect() { m_proxy = 0; }
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+ virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
private:
- virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent);
- v8::Local<v8::Object> getReceiverObject(Event*, bool isWindowEvent);
- WorkerContextExecutionProxy* m_proxy;
+ V8WorkerContextEventListener(v8::Local<v8::Object> listener, bool isInline, const WorldContextHandle& worldContext);
+
+ virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+ v8::Local<v8::Object> getReceiverObject(ScriptExecutionContext*, Event*);
};
} // namespace WebCore
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index ba858cf..8c66d7b 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -38,15 +38,21 @@
#include "DOMCoreException.h"
#include "DedicatedWorkerContext.h"
#include "Event.h"
+#include "Notification.h"
+#include "NotificationCenter.h"
#include "EventException.h"
#include "MessagePort.h"
#include "RangeException.h"
+#include "SharedWorker.h"
+#include "SharedWorkerContext.h"
#include "V8Binding.h"
#include "V8DOMMap.h"
#include "V8Index.h"
#include "V8Proxy.h"
#include "V8WorkerContextEventListener.h"
-#include "V8WorkerContextObjectEventListener.h"
+#if ENABLE(WEB_SOCKETS)
+#include "WebSocket.h"
+#endif
#include "Worker.h"
#include "WorkerContext.h"
#include "WorkerLocation.h"
@@ -77,14 +83,6 @@ WorkerContextExecutionProxy::~WorkerContextExecutionProxy()
void WorkerContextExecutionProxy::dispose()
{
- // Disconnect all event listeners.
- if (m_listeners.get()) {
- for (V8EventListenerList::iterator iterator(m_listeners->begin()); iterator != m_listeners->end(); ++iterator)
- static_cast<V8WorkerContextEventListener*>(*iterator)->disconnect();
-
- m_listeners->clear();
- }
-
// Detach all events from their JS wrappers.
for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) {
Event* event = m_events[eventIndex];
@@ -119,7 +117,6 @@ void WorkerContextExecutionProxy::initV8IfNeeded()
{
static bool v8Initialized = false;
- LOCK_V8;
if (v8Initialized)
return;
@@ -131,6 +128,12 @@ void WorkerContextExecutionProxy::initV8IfNeeded()
const int workerThreadPreemptionIntervalMs = 5;
v8::Locker::StartPreemption(workerThreadPreemptionIntervalMs);
#endif
+
+ v8::ResourceConstraints resource_constraints;
+ uint32_t here;
+ resource_constraints.set_stack_limit(&here - kWorkerMaxStackSize / sizeof(uint32_t*));
+ v8::SetResourceConstraints(&resource_constraints);
+
v8Initialized = true;
}
@@ -152,7 +155,12 @@ 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 = V8DOMWrapper::getConstructorForContext(V8ClassIndex::DEDICATEDWORKERCONTEXT, context);
+ V8ClassIndex::V8WrapperType contextType = V8ClassIndex::DEDICATEDWORKERCONTEXT;
+#if ENABLE(SHARED_WORKERS)
+ if (!m_workerContext->isDedicatedWorkerContext())
+ contextType = V8ClassIndex::SHAREDWORKERCONTEXT;
+#endif
+ v8::Handle<v8::Function> workerContextConstructor = V8DOMWrapper::getConstructorForContext(contextType, context);
v8::Local<v8::Object> jsWorkerContext = SafeAllocation::newInstance(workerContextConstructor);
// Bail out if allocation failed.
if (jsWorkerContext.IsEmpty()) {
@@ -161,7 +169,7 @@ void WorkerContextExecutionProxy::initContextIfNeeded()
}
// Wrap the object.
- V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(V8ClassIndex::DEDICATEDWORKERCONTEXT), m_workerContext);
+ V8DOMWrapper::setDOMWrapper(jsWorkerContext, V8ClassIndex::ToInt(contextType), m_workerContext);
V8DOMWrapper::setJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
m_workerContext->ref();
@@ -169,8 +177,6 @@ void WorkerContextExecutionProxy::initContextIfNeeded()
// Insert the object instance as the prototype of the shadow object.
v8::Handle<v8::Object> globalObject = m_context->Global();
globalObject->Set(implicitProtoString, jsWorkerContext);
-
- m_listeners.set(new V8EventListenerList());
}
v8::Handle<v8::Value> WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::V8WrapperType type, void* impl)
@@ -178,7 +184,11 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::convertToV8Object(V8ClassInde
if (!impl)
return v8::Null();
- if (type == V8ClassIndex::DEDICATEDWORKERCONTEXT)
+ if (type == V8ClassIndex::DEDICATEDWORKERCONTEXT
+#if ENABLE(SHARED_WORKERS)
+ || type == V8ClassIndex::SHAREDWORKERCONTEXT
+#endif
+ )
return convertWorkerContextToV8Object(static_cast<WorkerContext*>(impl));
bool isActiveDomObject = false;
@@ -224,6 +234,14 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::convertToV8Object(V8ClassInde
case V8ClassIndex::WORKERNAVIGATOR:
static_cast<WorkerNavigator*>(impl)->ref();
break;
+#if ENABLE(NOTIFICATIONS)
+ case V8ClassIndex::NOTIFICATIONCENTER:
+ static_cast<NotificationCenter*>(impl)->ref();
+ break;
+ case V8ClassIndex::NOTIFICATION:
+ static_cast<Notification*>(impl)->ref();
+ break;
+#endif
case V8ClassIndex::DOMCOREEXCEPTION:
static_cast<DOMCoreException*>(impl)->ref();
break;
@@ -282,10 +300,22 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::convertEventTargetToV8Object(
if (workerContext)
return convertWorkerContextToV8Object(workerContext);
+#if ENABLE(SHARED_WORKERS)
+ SharedWorkerContext* sharedWorkerContext = target->toSharedWorkerContext();
+ if (sharedWorkerContext)
+ return convertWorkerContextToV8Object(sharedWorkerContext);
+#endif
+
Worker* worker = target->toWorker();
if (worker)
return convertToV8Object(V8ClassIndex::WORKER, worker);
+#if ENABLE(SHARED_WORKERS)
+ SharedWorker* sharedWorker = target->toSharedWorker();
+ if (sharedWorker)
+ return convertToV8Object(V8ClassIndex::SHAREDWORKER, sharedWorker);
+#endif
+
XMLHttpRequest* xhr = target->toXMLHttpRequest();
if (xhr)
return convertToV8Object(V8ClassIndex::XMLHTTPREQUEST, xhr);
@@ -337,7 +367,6 @@ bool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, int baseLine, WorkerContextExecutionState* state)
{
- LOCK_V8;
v8::HandleScope hs;
initContextIfNeeded();
@@ -398,40 +427,9 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
return result;
}
-PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListenerHelper(v8::Local<v8::Value> object, bool isInline, bool findOnly, bool createObjectEventListener)
-{
- if (!object->IsObject())
- return 0;
-
- V8EventListener* listener = m_listeners->find(object->ToObject(), isInline);
- if (findOnly)
- return listener;
-
- // Create a new one, and add to cache.
- RefPtr<V8EventListener> newListener;
- if (createObjectEventListener)
- newListener = V8WorkerContextObjectEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline);
- else
- newListener = V8WorkerContextEventListener::create(this, v8::Local<v8::Object>::Cast(object), isInline);
-
- m_listeners->add(newListener.get());
-
- return newListener.release();
-}
-
PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
{
- return findOrCreateEventListenerHelper(object, isInline, findOnly, false);
-}
-
-PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateObjectEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
-{
- return findOrCreateEventListenerHelper(object, isInline, findOnly, true);
-}
-
-void WorkerContextExecutionProxy::removeEventListener(V8EventListener* listener)
-{
- m_listeners->remove(listener);
+ return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(object, isInline);
}
void WorkerContextExecutionProxy::trackEvent(Event* event)
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.h b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
index 75024df..3b8ab9e 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.h
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.h
@@ -64,12 +64,8 @@ namespace WebCore {
WorkerContextExecutionProxy(WorkerContext*);
~WorkerContextExecutionProxy();
- 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
@@ -111,11 +107,12 @@ namespace WebCore {
static bool forgetV8EventObject(Event*);
+ static const int kWorkerMaxStackSize = 500 * 1024;
+
WorkerContext* m_workerContext;
v8::Persistent<v8::Context> m_context;
int m_recursion;
- OwnPtr<V8EventListenerList> m_listeners;
Vector<Event*> m_events;
};
diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp b/WebCore/bindings/v8/WorldContextHandle.cpp
index ce56563..eb83586 100644
--- a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.cpp
+++ b/WebCore/bindings/v8/WorldContextHandle.cpp
@@ -29,31 +29,29 @@
*/
#include "config.h"
+#include "WorldContextHandle.h"
-#if ENABLE(WORKERS)
-
-#include "V8WorkerContextObjectEventListener.h"
-
-#include "WorkerContextExecutionProxy.h"
+#include "V8IsolatedWorld.h"
namespace WebCore {
-static void weakObjectEventListenerCallback(v8::Persistent<v8::Value>, void* parameter)
+WorldContextHandle::WorldContextHandle(WorldToUse worldToUse)
+ : m_worldToUse(worldToUse)
{
- V8WorkerContextObjectEventListener* listener = static_cast<V8WorkerContextObjectEventListener*>(parameter);
+ if (worldToUse == UseMainWorld)
+ return;
- // Remove the wrapper
- listener->proxy()->removeEventListener(listener);
-
- listener->disposeListenerObject();
+ if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered())
+ m_context = world->sharedContext();
}
-V8WorkerContextObjectEventListener::V8WorkerContextObjectEventListener(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
- : V8WorkerContextEventListener(proxy, listener, isInline)
+v8::Local<v8::Context> WorldContextHandle::adjustedContext(V8Proxy* proxy) const
{
- m_listener.MakeWeak(this, weakObjectEventListenerCallback);
+ if (m_worldToUse == UseMainWorld)
+ return proxy->mainWorldContext();
+ if (!m_context || m_context->get().IsEmpty())
+ return proxy->context();
+ return v8::Local<v8::Context>::New(m_context->get());
}
} // namespace WebCore
-
-#endif // WORKERS
diff --git a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h b/WebCore/bindings/v8/WorldContextHandle.h
index 6471637..ad0983e 100644
--- a/WebCore/bindings/v8/V8WorkerContextObjectEventListener.h
+++ b/WebCore/bindings/v8/WorldContextHandle.h
@@ -28,32 +28,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef V8WorkerContextObjectEventListener_h
-#define V8WorkerContextObjectEventListener_h
+#ifndef WorldContextHandle_h
+#define WorldContextHandle_h
-#if ENABLE(WORKERS)
+#include "SharedPersistent.h"
-#include "V8WorkerContextEventListener.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
- class WorkerContextExecutionProxy;
+class V8Proxy;
- class V8WorkerContextObjectEventListener : public V8WorkerContextEventListener {
- public:
- static PassRefPtr<V8WorkerContextObjectEventListener> create(WorkerContextExecutionProxy* proxy, v8::Local<v8::Object> listener, bool isInline)
- {
- return adoptRef(new V8WorkerContextObjectEventListener(proxy, listener, isInline));
- }
+enum WorldToUse { UseMainWorld, UseCurrentWorld };
- private:
- V8WorkerContextObjectEventListener(WorkerContextExecutionProxy*, v8::Local<v8::Object> listener, bool isInline);
- };
+class WorldContextHandle {
+public:
+ WorldContextHandle(WorldToUse);
+ v8::Local<v8::Context> adjustedContext(V8Proxy*) const;
-} // namespace WebCore
+private:
+ WorldToUse m_worldToUse;
+ RefPtr<SharedPersistent<v8::Context> > m_context;
+};
-#endif // WORKERS
+} // namespace WebCore
-#endif // V8WorkerContextObjectEventListener_h
+#endif // WorldContextHandle_h
diff --git a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
index ce759eb..0240895 100644
--- a/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8AbstractWorkerCustom.cpp
@@ -38,75 +38,18 @@
#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);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -122,7 +65,7 @@ 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);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(worker, args[1], false, ListenerFindOnly);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/V8ObjectEventListener.h b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
index 3c5ae10..b44e074 100644
--- a/WebCore/bindings/v8/V8ObjectEventListener.h
+++ b/WebCore/bindings/v8/custom/V8ConsoleCustom.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 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
@@ -28,32 +28,29 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef V8ObjectEventListener_h
-#define V8ObjectEventListener_h
+#include "config.h"
-#include "V8CustomEventListener.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
#include <v8.h>
-#include <wtf/PassRefPtr.h>
namespace WebCore {
- class Frame;
-
- // V8ObjectEventListener is a special listener wrapper for objects not in the DOM. It keeps the JS listener as a weak pointer.
- class V8ObjectEventListener : public V8EventListener {
- public:
- static PassRefPtr<V8ObjectEventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isInline)
- {
- return adoptRef(new V8ObjectEventListener(frame, listener, isInline));
- }
-
- virtual bool isObjectListener() const { return true; }
-
- private:
- V8ObjectEventListener(Frame*, v8::Local<v8::Object> listener, bool isInline);
- virtual ~V8ObjectEventListener();
- };
+CALLBACK_FUNC_DECL(ConsoleProfile)
+{
+ INC_STATS("console.profile()");
+ v8::HandleScope scope;
+ v8::Context::Scope context_scope(v8::Context::GetCurrent());
+ v8::V8::ResumeProfiler();
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(ConsoleProfileEnd)
+{
+ INC_STATS("console.profileEnd()");
+ v8::V8::PauseProfiler();
+ return v8::Undefined();
+}
} // namespace WebCore
-
-#endif // V8ObjectEventListener_h
diff --git a/WebCore/bindings/v8/custom/V8CoordinatesCustom.cpp b/WebCore/bindings/v8/custom/V8CoordinatesCustom.cpp
index 09522ba..1c07f29 100644
--- a/WebCore/bindings/v8/custom/V8CoordinatesCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8CoordinatesCustom.cpp
@@ -1,78 +1,75 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
+#include "Coordinates.h"
-#include "V8Coordinates.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8Proxy.h"
-#include "Coordinates.h"
-
namespace WebCore {
- ACCESSOR_GETTER(CoordinatesAltitude) {
- INC_STATS("DOM.Coordinates.altitude._get");
- v8::Handle<v8::Object> holder = info.Holder();
- Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
- if (!imp->canProvideAltitude())
- return v8::Null();
- return v8::Number::New(imp->altitude());
- }
+ACCESSOR_GETTER(CoordinatesAltitude)
+{
+ INC_STATS("DOM.Coordinates.altitude._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
+ if (!imp->canProvideAltitude())
+ return v8::Null();
+ return v8::Number::New(imp->altitude());
+}
- ACCESSOR_GETTER(CoordinatesAltitudeAccuracy) {
- INC_STATS("DOM.Coordinates.altitudeAccuracy._get");
- v8::Handle<v8::Object> holder = info.Holder();
- Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
- if (!imp->canProvideAltitudeAccuracy())
- return v8::Null();
- return v8::Number::New(imp->altitudeAccuracy());
- }
+ACCESSOR_GETTER(CoordinatesAltitudeAccuracy)
+{
+ INC_STATS("DOM.Coordinates.altitudeAccuracy._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
+ if (!imp->canProvideAltitudeAccuracy())
+ return v8::Null();
+ return v8::Number::New(imp->altitudeAccuracy());
+}
- ACCESSOR_GETTER(CoordinatesHeading) {
- INC_STATS("DOM.Coordinates.heading._get");
- v8::Handle<v8::Object> holder = info.Holder();
- Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
- if (!imp->canProvideHeading())
- return v8::Null();
- return v8::Number::New(imp->heading());
- }
+ACCESSOR_GETTER(CoordinatesHeading)
+{
+ INC_STATS("DOM.Coordinates.heading._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
+ if (!imp->canProvideHeading())
+ return v8::Null();
+ return v8::Number::New(imp->heading());
+}
- ACCESSOR_GETTER(CoordinatesSpeed) {
- INC_STATS("DOM.Coordinates.speed._get");
- v8::Handle<v8::Object> holder = info.Holder();
- Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
- if (!imp->canProvideSpeed())
- return v8::Null();
- return v8::Number::New(imp->speed());
- }
+ACCESSOR_GETTER(CoordinatesSpeed)
+{
+ INC_STATS("DOM.Coordinates.speed._get");
+ v8::Handle<v8::Object> holder = info.Holder();
+ Coordinates* imp = V8DOMWrapper::convertToNativeObject<Coordinates>(V8ClassIndex::COORDINATES, holder);
+ if (!imp->canProvideSpeed())
+ return v8::Null();
+ return v8::Number::New(imp->speed());
+}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomBinding.h b/WebCore/bindings/v8/custom/V8CustomBinding.h
index 22b4a94..e7670b7 100644
--- a/WebCore/bindings/v8/custom/V8CustomBinding.h
+++ b/WebCore/bindings/v8/custom/V8CustomBinding.h
@@ -78,6 +78,8 @@ struct NPObject;
bool V8Custom::v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \
uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+#define ACCESSOR_RUNTIME_ENABLER(NAME) bool V8Custom::v8##NAME##Enabled()
+
namespace WebCore {
class DOMWindow;
@@ -118,21 +120,38 @@ namespace WebCore {
static const int kMessageChannelInternalFieldCount = kDefaultWrapperInternalFieldCount + 2;
static const int kMessagePortRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
- static const int kMessagePortEntangledPortIndex = kDefaultWrapperInternalFieldCount + 1;
- static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 2;
+ static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
#if ENABLE(WORKERS)
- static const int kWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
- static const int kWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+ static const int kAbstractWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kAbstractWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+
+ static const int kWorkerRequestCacheIndex = kAbstractWorkerInternalFieldCount + 0;
+ static const int kWorkerInternalFieldCount = kAbstractWorkerInternalFieldCount + 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;
+#endif
- static const int kAbstractWorkerRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
- static const int kAbstractWorkerInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+#if ENABLE(SHARED_WORKERS)
+ static const int kSharedWorkerRequestCacheIndex = kAbstractWorkerInternalFieldCount + 0;
+ static const int kSharedWorkerInternalFieldCount = kAbstractWorkerInternalFieldCount + 1;
+
+ static const int kSharedWorkerContextRequestCacheIndex = kWorkerContextMinimumInternalFieldCount + 0;
+ static const int kSharedWorkerContextInternalFieldCount = kWorkerContextMinimumInternalFieldCount + 1;
+#endif
+
+#if ENABLE(NOTIFICATIONS)
+ static const int kNotificationRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kNotificationInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+#endif
+
+#if ENABLE(SVG)
+ static const int kSVGElementInstanceEventListenerCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kSVGElementInstanceInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
#endif
static const int kDOMWindowConsoleIndex = kDefaultWrapperInternalFieldCount + 0;
@@ -148,16 +167,25 @@ namespace WebCore {
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 kDOMWindowEventListenerCacheIndex = kDefaultWrapperInternalFieldCount + 13;
+ static const int kDOMWindowEnteredIsolatedWorldIndex = kDefaultWrapperInternalFieldCount + 14;
+ static const int kDOMWindowInternalFieldCount = kDefaultWrapperInternalFieldCount + 15;
static const int kStyleSheetOwnerNodeIndex = kDefaultWrapperInternalFieldCount + 0;
static const int kStyleSheetInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
+ static const int kNamedNodeMapOwnerNodeIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kNamedNodeMapInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
static const int kDOMApplicationCacheCacheIndex = kDefaultWrapperInternalFieldCount + 0;
static const int kDOMApplicationCacheFieldCount = kDefaultWrapperInternalFieldCount + 1;
#endif
+#if ENABLE(WEB_SOCKETS)
+ static const int kWebSocketCacheIndex = kDefaultWrapperInternalFieldCount + 0;
+ static const int kWebSocketInternalFieldCount = 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)
@@ -216,13 +244,27 @@ namespace WebCore {
static bool v8##NAME##IndexedSecurityCheck(v8::Local<v8::Object> host, \
uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
+#define DECLARE_ACCESSOR_RUNTIME_ENABLER(NAME) static bool v8##NAME##Enabled()
+
DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DStrokeStyle);
DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DFillStyle);
- DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowEvent);
+ DECLARE_PROPERTY_ACCESSOR(DOMWindowEvent);
DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowCrypto);
DECLARE_PROPERTY_ACCESSOR_SETTER(DOMWindowLocation);
DECLARE_PROPERTY_ACCESSOR_SETTER(DOMWindowOpener);
+#if ENABLE(VIDEO)
+ DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowAudio);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLMediaElement);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLAudioElement);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLVideoElement);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowMediaError);
+#endif
+
+ DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowImage);
+ DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowOption);
+
DECLARE_PROPERTY_ACCESSOR(DocumentLocation);
DECLARE_PROPERTY_ACCESSOR(DocumentImplementation);
DECLARE_PROPERTY_ACCESSOR_GETTER(EventSrcElement);
@@ -231,7 +273,6 @@ namespace WebCore {
DECLARE_PROPERTY_ACCESSOR_GETTER(EventClipboardData);
DECLARE_PROPERTY_ACCESSOR(DOMWindowEventHandler);
- DECLARE_PROPERTY_ACCESSOR(NodeEventHandler);
DECLARE_CALLBACK(HTMLCanvasElementGetContext);
@@ -258,6 +299,10 @@ namespace WebCore {
DECLARE_CALLBACK(HTMLCollectionNamedItem);
DECLARE_CALLBACK(HTMLCollectionCallAsFunction);
+ DECLARE_CALLBACK(HTMLAllCollectionItem);
+ DECLARE_CALLBACK(HTMLAllCollectionNamedItem);
+ DECLARE_CALLBACK(HTMLAllCollectionCallAsFunction);
+
DECLARE_CALLBACK(HTMLSelectElementRemove);
DECLARE_CALLBACK(HTMLOptionsCollectionRemove);
@@ -319,6 +364,46 @@ namespace WebCore {
DECLARE_CALLBACK(CanvasRenderingContext2DStrokeText);
DECLARE_CALLBACK(CanvasRenderingContext2DPutImageData);
+#if ENABLE(3D_CANVAS)
+ DECLARE_CALLBACK(WebGLRenderingContextBufferData);
+ DECLARE_CALLBACK(WebGLRenderingContextBufferSubData);
+ DECLARE_CALLBACK(WebGLRenderingContextGetBufferParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetFramebufferAttachmentParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetProgramParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetRenderbufferParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetShaderParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetTexParameter);
+ DECLARE_CALLBACK(WebGLRenderingContextGetUniform);
+ DECLARE_CALLBACK(WebGLRenderingContextGetVertexAttrib);
+ DECLARE_CALLBACK(WebGLRenderingContextTexImage2D);
+ DECLARE_CALLBACK(WebGLRenderingContextTexSubImage2D);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform1fv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform1iv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform2fv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform2iv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform3fv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform3iv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform4fv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniform4iv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniformMatrix2fv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniformMatrix3fv);
+ DECLARE_CALLBACK(WebGLRenderingContextUniformMatrix4fv);
+ DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib1fv);
+ DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib2fv);
+ DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib3fv);
+ DECLARE_CALLBACK(WebGLRenderingContextVertexAttrib4fv);
+
+ DECLARE_CALLBACK(WebGLArrayBufferConstructor);
+ DECLARE_CALLBACK(WebGLByteArrayConstructor);
+ DECLARE_CALLBACK(WebGLFloatArrayConstructor);
+ DECLARE_CALLBACK(WebGLIntArrayConstructor);
+ DECLARE_CALLBACK(WebGLShortArrayConstructor);
+ DECLARE_CALLBACK(WebGLUnsignedByteArrayConstructor);
+ DECLARE_CALLBACK(WebGLUnsignedIntArrayConstructor);
+ DECLARE_CALLBACK(WebGLUnsignedShortArrayConstructor);
+#endif
+
DECLARE_PROPERTY_ACCESSOR_GETTER(ClipboardTypes);
DECLARE_CALLBACK(ClipboardClearData);
DECLARE_CALLBACK(ClipboardGetData);
@@ -332,6 +417,9 @@ namespace WebCore {
DECLARE_CALLBACK(ElementSetAttributeNS);
DECLARE_CALLBACK(ElementSetAttributeNodeNS);
+ DECLARE_CALLBACK(HistoryPushState);
+ DECLARE_CALLBACK(HistoryReplaceState);
+
DECLARE_PROPERTY_ACCESSOR_SETTER(LocationProtocol);
DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHost);
DECLARE_PROPERTY_ACCESSOR_SETTER(LocationHostname);
@@ -348,7 +436,6 @@ namespace WebCore {
DECLARE_CALLBACK(LocationReload);
DECLARE_CALLBACK(LocationToString);
DECLARE_CALLBACK(LocationValueOf);
-
DECLARE_CALLBACK(NodeAddEventListener);
DECLARE_CALLBACK(NodeRemoveEventListener);
DECLARE_CALLBACK(NodeInsertBefore);
@@ -394,22 +481,25 @@ namespace WebCore {
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);
+ DECLARE_CALLBACK(InjectedScriptHostInspectedWindow);
+ DECLARE_CALLBACK(InjectedScriptHostNodeForId);
+ DECLARE_CALLBACK(InjectedScriptHostWrapObject);
+ DECLARE_CALLBACK(InjectedScriptHostUnwrapObject);
+ DECLARE_CALLBACK(InjectedScriptHostPushNodePathToFrontend);
+ DECLARE_CALLBACK(InjectedScriptHostWrapCallback);
#if ENABLE(DATABASE)
- DECLARE_CALLBACK(InspectorBackendDatabaseTableNames);
+ DECLARE_CALLBACK(InjectedScriptHostSelectDatabase);
+ DECLARE_CALLBACK(InjectedScriptHostDatabaseForId);
+#endif
+#if ENABLE(DOM_STORAGE)
+ DECLARE_CALLBACK(InjectedScriptHostSelectDOMStorage);
#endif
- DECLARE_CALLBACK(InspectorBackendWrapCallback);
+
+ DECLARE_CALLBACK(InspectorFrontendHostSearch);
+ DECLARE_CALLBACK(InspectorFrontendHostShowContextMenu);
+
+ DECLARE_CALLBACK(ConsoleProfile);
+ DECLARE_CALLBACK(ConsoleProfileEnd);
DECLARE_CALLBACK(NodeIteratorNextNode);
DECLARE_CALLBACK(NodeIteratorPreviousNode);
@@ -443,31 +533,78 @@ namespace WebCore {
DECLARE_INDEXED_PROPERTY_SETTER(HTMLOptionsCollection);
DECLARE_NAMED_PROPERTY_GETTER(HTMLSelectElementCollection);
DECLARE_INDEXED_PROPERTY_SETTER(HTMLSelectElementCollection);
+ DECLARE_NAMED_PROPERTY_GETTER(HTMLAllCollection);
DECLARE_NAMED_PROPERTY_GETTER(HTMLCollection);
- DECLARE_INDEXED_PROPERTY_GETTER(CanvasPixelArray);
- DECLARE_INDEXED_PROPERTY_SETTER(CanvasPixelArray);
+#if ENABLE(3D_CANVAS)
+ DECLARE_CALLBACK(WebGLByteArrayGet);
+ DECLARE_CALLBACK(WebGLByteArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLByteArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLByteArray);
+
+ DECLARE_CALLBACK(WebGLFloatArrayGet);
+ DECLARE_CALLBACK(WebGLFloatArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLFloatArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLFloatArray);
+
+ DECLARE_CALLBACK(WebGLIntArrayGet);
+ DECLARE_CALLBACK(WebGLIntArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLIntArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLIntArray);
+
+ DECLARE_CALLBACK(WebGLShortArrayGet);
+ DECLARE_CALLBACK(WebGLShortArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLShortArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLShortArray);
+
+ DECLARE_CALLBACK(WebGLUnsignedByteArrayGet);
+ DECLARE_CALLBACK(WebGLUnsignedByteArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLUnsignedByteArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLUnsignedByteArray);
+
+ DECLARE_CALLBACK(WebGLUnsignedIntArrayGet);
+ DECLARE_CALLBACK(WebGLUnsignedIntArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLUnsignedIntArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLUnsignedIntArray);
+
+ DECLARE_CALLBACK(WebGLUnsignedShortArrayGet);
+ DECLARE_CALLBACK(WebGLUnsignedShortArraySet);
+ DECLARE_INDEXED_PROPERTY_GETTER(WebGLUnsignedShortArray);
+ DECLARE_INDEXED_PROPERTY_SETTER(WebGLUnsignedShortArray);
+#endif
+
+ DECLARE_PROPERTY_ACCESSOR_GETTER(MessageEventPorts);
+ DECLARE_CALLBACK(MessageEventInitMessageEvent);
DECLARE_PROPERTY_ACCESSOR(MessagePortOnmessage);
DECLARE_PROPERTY_ACCESSOR(MessagePortOnclose);
- DECLARE_CALLBACK(MessagePortStartConversation);
DECLARE_CALLBACK(MessagePortAddEventListener);
+ DECLARE_CALLBACK(MessagePortPostMessage);
DECLARE_CALLBACK(MessagePortRemoveEventListener);
+ DECLARE_CALLBACK(MessagePortStartConversation);
DECLARE_CALLBACK(DatabaseChangeVersion);
DECLARE_CALLBACK(DatabaseTransaction);
+ DECLARE_CALLBACK(DatabaseReadTransaction);
DECLARE_CALLBACK(SQLTransactionExecuteSql);
DECLARE_CALLBACK(SQLResultSetRowListItem);
DECLARE_INDEXED_PROPERTY_GETTER(ClientRectList);
-
+ DECLARE_INDEXED_PROPERTY_GETTER(FileList);
+
#if ENABLE(DATAGRID)
DECLARE_PROPERTY_ACCESSOR(HTMLDataGridElementDataSource);
DECLARE_INDEXED_PROPERTY_GETTER(DataGridColumnList);
DECLARE_NAMED_PROPERTY_GETTER(DataGridColumnList);
-#endif
+#endif
+
+#if ENABLE(DATABASE)
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowOpenDatabase);
+#endif
#if ENABLE(DOM_STORAGE)
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowLocalStorage);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowSessionStorage);
DECLARE_INDEXED_PROPERTY_GETTER(Storage);
DECLARE_INDEXED_PROPERTY_SETTER(Storage);
DECLARE_INDEXED_PROPERTY_DELETER(Storage);
@@ -480,6 +617,7 @@ namespace WebCore {
#if ENABLE(SVG)
DECLARE_PROPERTY_ACCESSOR_GETTER(SVGLengthValue);
DECLARE_CALLBACK(SVGLengthConvertToSpecifiedUnits);
+ DECLARE_CALLBACK(SVGMatrixMultiply);
DECLARE_CALLBACK(SVGMatrixInverse);
DECLARE_CALLBACK(SVGMatrixRotateFromVector);
DECLARE_CALLBACK(SVGElementInstanceAddEventListener);
@@ -496,8 +634,10 @@ namespace WebCore {
DECLARE_CALLBACK(AbstractWorkerRemoveEventListener);
DECLARE_PROPERTY_ACCESSOR(DedicatedWorkerContextOnmessage);
+ DECLARE_CALLBACK(DedicatedWorkerContextPostMessage);
DECLARE_PROPERTY_ACCESSOR(WorkerOnmessage);
+ DECLARE_CALLBACK(WorkerPostMessage);
DECLARE_CALLBACK(WorkerConstructor);
DECLARE_PROPERTY_ACCESSOR_GETTER(WorkerContextSelf);
@@ -509,9 +649,24 @@ namespace WebCore {
DECLARE_CALLBACK(WorkerContextClearInterval);
DECLARE_CALLBACK(WorkerContextAddEventListener);
DECLARE_CALLBACK(WorkerContextRemoveEventListener);
+
+#if ENABLE(NOTIFICATIONS)
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(WorkerContextWebkitNotifications);
#endif
+#endif // ENABLE(WORKERS)
+
+#if ENABLE(NOTIFICATIONS)
+ DECLARE_CALLBACK(NotificationCenterRequestPermission);
+ DECLARE_CALLBACK(NotificationCenterCreateNotification);
+ DECLARE_CALLBACK(NotificationCenterCreateHTMLNotification);
+
+ DECLARE_CALLBACK(NotificationAddEventListener);
+ DECLARE_CALLBACK(NotificationRemoveEventListener);
+ DECLARE_PROPERTY_ACCESSOR(NotificationEventHandler);
+#endif // ENABLE(NOTIFICATIONS)
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowApplicationCache);
DECLARE_PROPERTY_ACCESSOR(DOMApplicationCacheEventHandler);
DECLARE_CALLBACK(DOMApplicationCacheAddEventListener);
DECLARE_CALLBACK(DOMApplicationCacheRemoveEventListener);
@@ -519,6 +674,23 @@ namespace WebCore {
#if ENABLE(SHARED_WORKERS)
DECLARE_CALLBACK(SharedWorkerConstructor);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowSharedWorker);
+#endif
+
+#if ENABLE(NOTIFICATIONS)
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowWebkitNotifications);
+#endif
+
+#if ENABLE(WEB_SOCKETS)
+ DECLARE_PROPERTY_ACCESSOR(WebSocketOnopen);
+ DECLARE_PROPERTY_ACCESSOR(WebSocketOnmessage);
+ DECLARE_PROPERTY_ACCESSOR(WebSocketOnclose);
+ DECLARE_CALLBACK(WebSocketConstructor);
+ DECLARE_CALLBACK(WebSocketAddEventListener);
+ DECLARE_CALLBACK(WebSocketRemoveEventListener);
+ DECLARE_CALLBACK(WebSocketSend);
+ DECLARE_CALLBACK(WebSocketClose);
+ DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowWebSocket);
#endif
DECLARE_CALLBACK(GeolocationGetCurrentPosition);
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
index 305da8d..24d752f 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
@@ -35,37 +35,25 @@
namespace WebCore {
-V8EventListener::V8EventListener(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute)
- : V8AbstractEventListener(frame, isAttribute)
+V8EventListener::V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext)
+ : V8AbstractEventListener(isAttribute, worldContext)
{
- m_listener = v8::Persistent<v8::Object>::New(listener);
-#ifndef NDEBUG
- V8GCController::registerGlobalHandle(EVENT_LISTENER, this, m_listener);
-#endif
+ setListenerObject(listener);
}
-V8EventListener::~V8EventListener()
+v8::Local<v8::Function> V8EventListener::getListenerFunction(ScriptExecutionContext* context)
{
- if (m_frame) {
- V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- if (proxy)
- proxy->eventListeners()->remove(this);
- }
-
- disposeListenerObject();
-}
+ v8::Local<v8::Object> listener = getListenerObject(context);
-v8::Local<v8::Function> V8EventListener::getListenerFunction()
-{
// Has the listener been disposed?
- if (m_listener.IsEmpty())
+ if (listener.IsEmpty())
return v8::Local<v8::Function>();
- if (m_listener->IsFunction())
- return v8::Local<v8::Function>::New(v8::Persistent<v8::Function>::Cast(m_listener));
+ if (listener->IsFunction())
+ return v8::Local<v8::Function>::Cast(listener);
- if (m_listener->IsObject()) {
- v8::Local<v8::Value> property = m_listener->Get(v8::String::NewSymbol("handleEvent"));
+ if (listener->IsObject()) {
+ v8::Local<v8::Value> property = listener->Get(v8::String::NewSymbol("handleEvent"));
if (property->IsFunction())
return v8::Local<v8::Function>::Cast(property);
}
@@ -73,19 +61,20 @@ v8::Local<v8::Function> V8EventListener::getListenerFunction()
return v8::Local<v8::Function>();
}
-v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event, bool isWindowEvent)
+v8::Local<v8::Value> V8EventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
{
- v8::Local<v8::Function> handlerFunction = getListenerFunction();
- v8::Local<v8::Object> receiver = getReceiverObject(event, isWindowEvent);
+
+ v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
+ v8::Local<v8::Object> receiver = getReceiverObject(event);
if (handlerFunction.IsEmpty() || receiver.IsEmpty())
return v8::Local<v8::Value>();
v8::Handle<v8::Value> parameters[1] = { jsEvent };
- V8Proxy* proxy = V8Proxy::retrieve(m_frame);
- if (!proxy)
- return v8::Local<v8::Value>();
- return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+ if (V8Proxy* proxy = V8Proxy::retrieve(context))
+ return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+
+ return v8::Local<v8::Value>();
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h
index 20adf99..f9d5385 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.h
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h
@@ -44,23 +44,19 @@ namespace WebCore {
// that can handle the event.
class V8EventListener : public V8AbstractEventListener {
public:
- static PassRefPtr<V8EventListener> create(Frame* frame, v8::Local<v8::Object> listener, bool isAttribute)
+ static PassRefPtr<V8EventListener> create(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext)
{
- return adoptRef(new V8EventListener(frame, listener, isAttribute));
+ return adoptRef(new V8EventListener(listener, isAttribute, worldContext));
}
- // Detach the listener from its owner frame.
- void disconnectFrame() { m_frame = 0; }
-
protected:
- V8EventListener(Frame*, v8::Local<v8::Object> listener, bool isAttribute);
- virtual ~V8EventListener();
- v8::Local<v8::Function> getListenerFunction();
+ V8EventListener(v8::Local<v8::Object> listener, bool isAttribute, const WorldContextHandle& worldContext);
+
+ v8::Local<v8::Function> getListenerFunction(ScriptExecutionContext*);
private:
- virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*, bool isWindowEvent);
- virtual bool virtualisAttribute() const { return m_isAttribute; }
- };
+ virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+ };
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomPositionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomPositionCallback.cpp
index 4f2fe0e..5e9a8f2 100644
--- a/WebCore/bindings/v8/custom/V8CustomPositionCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomPositionCallback.cpp
@@ -1,29 +1,24 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -49,7 +44,6 @@ V8CustomPositionCallback::~V8CustomPositionCallback()
void V8CustomPositionCallback::handleEvent(Geoposition* position)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomPositionCallback.h b/WebCore/bindings/v8/custom/V8CustomPositionCallback.h
index 06be83b..d2290ee 100644
--- a/WebCore/bindings/v8/custom/V8CustomPositionCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomPositionCallback.h
@@ -1,29 +1,24 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
diff --git a/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.cpp
index e446d85..117f374 100644
--- a/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.cpp
@@ -1,29 +1,24 @@
/*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -49,7 +44,6 @@ V8CustomPositionErrorCallback::~V8CustomPositionErrorCallback()
void V8CustomPositionErrorCallback::handleEvent(PositionError* error)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.h b/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.h
index 703b7b2..aaf56a7 100644
--- a/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.h
+++ b/WebCore/bindings/v8/custom/V8CustomPositionErrorCallback.h
@@ -1,29 +1,24 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
index 2abdb15..64abdc4 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementCallback.cpp
@@ -52,7 +52,6 @@ V8CustomSQLStatementCallback::~V8CustomSQLStatementCallback()
void V8CustomSQLStatementCallback::handleEvent(SQLTransaction* transaction, SQLResultSet* resultSet, bool& raisedException)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
index efab455..1af3562 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp
@@ -52,7 +52,6 @@ V8CustomSQLStatementErrorCallback::~V8CustomSQLStatementErrorCallback()
bool V8CustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
index 704115e..2cef6b3 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionCallback.cpp
@@ -53,7 +53,6 @@ V8CustomSQLTransactionCallback::~V8CustomSQLTransactionCallback()
void V8CustomSQLTransactionCallback::handleEvent(SQLTransaction* transaction, bool& raisedException)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
index f30467c..1a0939d 100644
--- a/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomSQLTransactionErrorCallback.cpp
@@ -52,7 +52,6 @@ V8CustomSQLTransactionErrorCallback::~V8CustomSQLTransactionErrorCallback()
void V8CustomSQLTransactionErrorCallback::handleEvent(SQLError* error)
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
index b538b33..94cb104 100644
--- a/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomVoidCallback.cpp
@@ -49,7 +49,6 @@ V8CustomVoidCallback::~V8CustomVoidCallback()
void V8CustomVoidCallback::handleEvent()
{
- LOCK_V8;
v8::HandleScope handleScope;
v8::Handle<v8::Context> context = V8Proxy::context(m_frame.get());
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
index 3341924..e45cba0 100644
--- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.cpp
@@ -38,13 +38,14 @@
namespace WebCore {
-PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(v8::Handle<v8::Object> resolver)
+PassRefPtr<V8CustomXPathNSResolver> V8CustomXPathNSResolver::create(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
{
- return adoptRef(new V8CustomXPathNSResolver(resolver));
+ return adoptRef(new V8CustomXPathNSResolver(proxy, resolver));
}
-V8CustomXPathNSResolver::V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver)
- : m_resolver(resolver)
+V8CustomXPathNSResolver::V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver)
+ : m_proxy(proxy)
+ , m_resolver(resolver)
{
}
@@ -54,6 +55,14 @@ V8CustomXPathNSResolver::~V8CustomXPathNSResolver()
String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
{
+ V8Proxy* proxy = m_proxy;
+
+ if (!proxy) {
+ proxy = V8Proxy::retrieve();
+ if (!proxy)
+ return String();
+ }
+
v8::Handle<v8::Function> lookupNamespaceURIFunc;
v8::Handle<v8::String> lookupNamespaceURIName = v8::String::New("lookupNamespaceURI");
@@ -65,7 +74,7 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
}
if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
- Frame* frame = V8Proxy::retrieveFrameForEnteredContext();
+ Frame* frame = proxy->frame();
logInfo(frame, "XPathNSResolver does not have a lookupNamespaceURI method.", String());
return String();
}
@@ -78,7 +87,6 @@ String V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
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.
diff --git a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
index f1dc65c..15ac27d 100644
--- a/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
+++ b/WebCore/bindings/v8/custom/V8CustomXPathNSResolver.h
@@ -42,17 +42,22 @@
namespace WebCore {
class String;
+class V8Proxy;
+// V8CustomXPathNSResolver does not create a persistent handle to the
+// given resolver object. So the lifetime of V8CustomXPathNSResolver
+// must not exceed the lifetime of the passed handle.
class V8CustomXPathNSResolver : public XPathNSResolver {
public:
- static PassRefPtr<V8CustomXPathNSResolver> create(v8::Handle<v8::Object> resolver);
+ static PassRefPtr<V8CustomXPathNSResolver> create(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
virtual ~V8CustomXPathNSResolver();
virtual String lookupNamespaceURI(const String& prefix);
private:
- V8CustomXPathNSResolver(v8::Handle<v8::Object> resolver);
+ V8CustomXPathNSResolver(V8Proxy* proxy, v8::Handle<v8::Object> resolver);
+ V8Proxy* m_proxy;
v8::Handle<v8::Object> m_resolver; // Handle to resolver object.
};
diff --git a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
index 7a3bfe6..134de95 100644
--- a/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMApplicationCacheCustom.cpp
@@ -37,77 +37,19 @@
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8Document.h"
-#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "WorkerContextExecutionProxy.h"
namespace WebCore {
-static const bool kFindOnly = true;
-static const bool kFindOrCreate = false;
-
-static PassRefPtr<EventListener> argumentToEventListener(DOMApplicationCache* appcache, v8::Local<v8::Value> value, bool findOnly)
-{
- V8Proxy* proxy = V8Proxy::retrieve(appcache->scriptExecutionContext());
- if (proxy)
- return findOnly ? proxy->objectListeners()->findWrapper(value, false)
- : proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- return 0;
-}
-
-static v8::Local<v8::Object> eventListenerToV8Object(EventListener* listener)
-{
- return (static_cast<V8ObjectEventListener*>(listener))->getListenerObject();
-}
-
-static inline ApplicationCacheHost::EventID toEventID(v8::Local<v8::String> value)
-{
- String key = toWebCoreString(value);
- ASSERT(key.startsWith("on"));
- return DOMApplicationCache::toEventID(key.substring(2));
-}
-
-// Handles appcache.onfooevent attribute getting
-ACCESSOR_GETTER(DOMApplicationCacheEventHandler)
-{
- INC_STATS("DOMApplicationCache.onevent_getter");
- DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, info.Holder());
- EventListener* listener = appcache->getAttributeEventListener(toEventID(name));
- if (!listener)
- return v8::Null();
- return eventListenerToV8Object(listener);
-}
-
-// Handles appcache.onfooevent attribute setting
-ACCESSOR_SETTER(DOMApplicationCacheEventHandler)
-{
- INC_STATS("DOMApplicationCache.onevent_setter");
- 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);
- removeHiddenDependency(info.Holder(), object, V8Custom::kDOMApplicationCacheCacheIndex);
- appcache->clearAttributeEventListener(eventType);
- }
-
- if (value->IsFunction()) {
- RefPtr<EventListener> newListener = argumentToEventListener(appcache, value, kFindOrCreate);
- if (newListener) {
- createHiddenDependency(info.Holder(), value, V8Custom::kDOMApplicationCacheCacheIndex);
- appcache->setAttributeEventListener(eventType, newListener);
- }
- }
-}
-
// Handles appcache.addEventListner(name, func, capture) method calls
CALLBACK_FUNC_DECL(DOMApplicationCacheAddEventListener)
{
INC_STATS("DOMApplicationCache.addEventListener()");
DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
- RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOrCreate);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOrCreate);
if (listener) {
createHiddenDependency(args.Holder(), args[1], V8Custom::kDOMApplicationCacheCacheIndex);
String eventType = toWebCoreString(args[0]);
@@ -123,7 +65,7 @@ CALLBACK_FUNC_DECL(DOMApplicationCacheRemoveEventListener)
INC_STATS("DOMApplicationCache.removeEventListener()");
DOMApplicationCache* appcache = V8DOMWrapper::convertToNativeObject<DOMApplicationCache>(V8ClassIndex::DOMAPPLICATIONCACHE, args.Holder());
- RefPtr<EventListener> listener = argumentToEventListener(appcache, args[1], kFindOnly);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(appcache, args[1], false, ListenerFindOnly);
if (listener) {
removeHiddenDependency(args.Holder(), args[1], V8Custom::kDOMApplicationCacheCacheIndex);
String eventType = toWebCoreString(args[0]);
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index 7d0b9e6..46c33b9 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -34,6 +34,7 @@
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8CustomEventListener.h"
+#include "V8MessagePortCustom.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
@@ -44,11 +45,19 @@
#include "FrameLoadRequest.h"
#include "FrameView.h"
#include "HTMLCollection.h"
+#include "MediaPlayer.h"
#include "Page.h"
#include "PlatformScreen.h"
+#include "RuntimeEnabledFeatures.h"
#include "ScheduledAction.h"
#include "ScriptSourceCode.h"
+#include "SerializedScriptValue.h"
#include "Settings.h"
+#include "SharedWorkerRepository.h"
+#include "Storage.h"
+#if ENABLE(WEB_SOCKETS)
+#include "WebSocket.h"
+#endif
#include "WindowFeatures.h"
// Horizontal and vertical offset, from the parent content area, around newly
@@ -64,32 +73,44 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args,
if (argumentCount < 1)
return v8::Undefined();
- DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
-
- if (!imp->frame())
- return v8::Undefined();
-
- if (!V8Proxy::canAccessFrame(imp->frame(), true))
- return v8::Undefined();
+ v8::Handle<v8::Value> function = args[0];
- ScriptExecutionContext* scriptContext = static_cast<ScriptExecutionContext*>(imp->frame()->document());
+ WebCore::String functionString;
+ if (!function->IsFunction()) {
+ if (function->IsString())
+ functionString = toWebCoreString(function);
+ else {
+ v8::Handle<v8::Value> v8String = function->ToString();
- v8::Handle<v8::Value> function = args[0];
+ // Bail out if string conversion failed.
+ if (v8String.IsEmpty())
+ return v8::Undefined();
- int32_t timeout = 0;
- if (argumentCount >= 2)
- timeout = args[1]->Int32Value();
+ functionString = toWebCoreString(v8String);
+ }
- int id;
- if (function->IsString()) {
// Don't allow setting timeouts to run empty functions!
// (Bug 1009597)
- WebCore::String functionString = toWebCoreString(function);
if (functionString.length() == 0)
return v8::Undefined();
+ }
- id = DOMTimer::install(scriptContext, new ScheduledAction(functionString), timeout, singleShot);
- } else if (function->IsFunction()) {
+ int32_t timeout = 0;
+ if (argumentCount >= 2)
+ timeout = args[1]->Int32Value();
+
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
+
+ if (!V8Proxy::canAccessFrame(imp->frame(), true))
+ return v8::Undefined();
+
+ ScriptExecutionContext* scriptContext = static_cast<ScriptExecutionContext*>(imp->document());
+
+ if (!scriptContext)
+ return v8::Undefined();
+
+ int id;
+ if (function->IsFunction()) {
int paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
v8::Local<v8::Value>* params = 0;
if (paramCount > 0) {
@@ -100,14 +121,14 @@ v8::Handle<v8::Value> V8Custom::WindowSetTimeoutImpl(const v8::Arguments& args,
}
// params is passed to action, and released in action's destructor
- ScheduledAction* action = new ScheduledAction(v8::Handle<v8::Function>::Cast(function), paramCount, params);
+ ScheduledAction* action = new ScheduledAction(V8Proxy::context(imp->frame()), v8::Handle<v8::Function>::Cast(function), paramCount, params);
delete[] params;
id = DOMTimer::install(scriptContext, action, timeout, singleShot);
- } else
- // FIXME(fqian): what's the right return value if failed.
- return v8::Undefined();
+ } else {
+ id = DOMTimer::install(scriptContext, new ScheduledAction(V8Proxy::context(imp->frame()), functionString), timeout, singleShot);
+ }
return v8::Integer::New(id);
}
@@ -145,14 +166,43 @@ static v8::Handle<v8::Value> convertBase64(const String& str, bool encode)
ACCESSOR_GETTER(DOMWindowEvent)
{
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ if (holder.IsEmpty())
+ return v8::Undefined();
+
+ Frame* frame = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder)->frame();
+ if (!V8Proxy::canAccessFrame(frame, true))
+ return v8::Undefined();
+
+ v8::Local<v8::Context> context = V8Proxy::context(frame);
+ if (context.IsEmpty())
+ return v8::Undefined();
+
v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event");
- v8::Local<v8::Context> context = v8::Context::GetCurrent();
v8::Handle<v8::Value> jsEvent = context->Global()->GetHiddenValue(eventSymbol);
if (jsEvent.IsEmpty())
return v8::Undefined();
return jsEvent;
}
+ACCESSOR_SETTER(DOMWindowEvent)
+{
+ v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
+ if (holder.IsEmpty())
+ return;
+
+ Frame* frame = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder)->frame();
+ if (!V8Proxy::canAccessFrame(frame, true))
+ return;
+
+ v8::Local<v8::Context> context = V8Proxy::context(frame);
+ if (context.IsEmpty())
+ return;
+
+ v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event");
+ context->Global()->SetHiddenValue(eventSymbol, value);
+}
+
ACCESSOR_GETTER(DOMWindowCrypto)
{
// FIXME: Implement me.
@@ -161,11 +211,7 @@ ACCESSOR_GETTER(DOMWindowCrypto)
ACCESSOR_SETTER(DOMWindowLocation)
{
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
- if (holder.IsEmpty())
- return;
-
- DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
WindowSetLocation(imp, toWebCoreString(value));
}
@@ -194,18 +240,114 @@ ACCESSOR_SETTER(DOMWindowOpener)
info.This()->Set(name, value);
}
+#if ENABLE(VIDEO)
+
+ACCESSOR_GETTER(DOMWindowAudio)
+{
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
+ return V8DOMWrapper::getConstructor(V8ClassIndex::AUDIO, window);
+}
+
+ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio)
+{
+ return MediaPlayer::isAvailable();
+}
+
+ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLMediaElement)
+{
+ return MediaPlayer::isAvailable();
+}
+
+ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLAudioElement)
+{
+ return MediaPlayer::isAvailable();
+}
+
+ACCESSOR_RUNTIME_ENABLER(DOMWindowHTMLVideoElement)
+{
+ return MediaPlayer::isAvailable();
+}
+
+ACCESSOR_RUNTIME_ENABLER(DOMWindowMediaError)
+{
+ return MediaPlayer::isAvailable();
+}
+
+#endif
+
+#if ENABLE(SHARED_WORKERS)
+ACCESSOR_RUNTIME_ENABLER(DOMWindowSharedWorker)
+{
+ return SharedWorkerRepository::isAvailable();
+}
+#endif
+
+#if ENABLE(WEB_SOCKETS)
+ACCESSOR_RUNTIME_ENABLER(DOMWindowWebSocket)
+{
+ return WebSocket::isAvailable();
+}
+#endif
+
+#if ENABLE(DATABASE)
+ACCESSOR_RUNTIME_ENABLER(DOMWindowOpenDatabase)
+{
+ return WebCore::RuntimeEnabledFeatures::databaseEnabled();
+}
+#endif
+
+#if ENABLE(DOM_STORAGE)
+ACCESSOR_RUNTIME_ENABLER(DOMWindowLocalStorage)
+{
+ return RuntimeEnabledFeatures::localStorageEnabled();
+}
+
+ACCESSOR_RUNTIME_ENABLER(DOMWindowSessionStorage)
+{
+ return RuntimeEnabledFeatures::sessionStorageEnabled();
+}
+#endif
+
+#if ENABLE(NOTIFICATIONS)
+ACCESSOR_RUNTIME_ENABLER(DOMWindowWebkitNotifications)
+{
+ return RuntimeEnabledFeatures::notificationsEnabled();
+}
+#endif
+
+#if ENABLE(OFFLINE_WEB_APPLICATIONS)
+ACCESSOR_RUNTIME_ENABLER(DOMWindowApplicationCache)
+{
+ return RuntimeEnabledFeatures::applicationCacheEnabled();
+}
+#endif
+
+ACCESSOR_GETTER(DOMWindowImage)
+{
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
+ return V8DOMWrapper::getConstructor(V8ClassIndex::IMAGE, window);
+}
+
+ACCESSOR_GETTER(DOMWindowOption)
+{
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
+ return V8DOMWrapper::getConstructor(V8ClassIndex::OPTION, window);
+}
+
CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
{
INC_STATS("DOM.DOMWindow.addEventListener()");
+
+ String eventType = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+
DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
- if (!imp->frame())
- return v8::Undefined(); // DOMWindow could be disconnected from the frame
-
- Document* doc = imp->frame()->document();
+ Document* doc = imp->document();
+
if (!doc)
return v8::Undefined();
@@ -214,12 +356,11 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOrCreate);
if (listener) {
- String eventType = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
imp->addEventListener(eventType, listener, useCapture);
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kDOMWindowEventListenerCacheIndex);
}
return v8::Undefined();
@@ -229,15 +370,17 @@ CALLBACK_FUNC_DECL(DOMWindowAddEventListener)
CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener)
{
INC_STATS("DOM.DOMWindow.removeEventListener()");
+
+ String eventType = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+
DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
if (!V8Proxy::canAccessFrame(imp->frame(), true))
return v8::Undefined();
- if (!imp->frame())
- return v8::Undefined();
+ Document* doc = imp->document();
- Document* doc = imp->frame()->document();
if (!doc)
return v8::Undefined();
@@ -245,12 +388,11 @@ CALLBACK_FUNC_DECL(DOMWindowRemoveEventListener)
if (!proxy)
return v8::Undefined();
- RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(proxy, args[1], false, ListenerFindOnly);
if (listener) {
- String eventType = toWebCoreString(args[0]);
- bool useCapture = args[2]->BooleanValue();
imp->removeEventListener(eventType, listener.get(), useCapture);
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kDOMWindowEventListenerCacheIndex);
}
return v8::Undefined();
@@ -265,8 +407,8 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage)
ASSERT(source->frame());
v8::TryCatch tryCatch;
- String message = toWebCoreString(args[0]);
- MessagePort* port = 0;
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(toWebCoreString(args[0]));
+ MessagePortArray portArray;
String targetOrigin;
// This function has variable arguments and can either be:
@@ -274,8 +416,8 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage)
// or
// postMessage(message, targetOrigin);
if (args.Length() > 2) {
- if (V8DOMWrapper::isWrapperOfType(args[1], V8ClassIndex::MESSAGEPORT))
- port = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, v8::Handle<v8::Object>::Cast(args[1]));
+ if (!getMessagePortArray(args[1], portArray))
+ return v8::Undefined();
targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
} else {
targetOrigin = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
@@ -285,16 +427,18 @@ CALLBACK_FUNC_DECL(DOMWindowPostMessage)
return v8::Undefined();
ExceptionCode ec = 0;
- window->postMessage(message, port, targetOrigin, source, ec);
- if (ec)
- V8Proxy::setDOMException(ec);
-
- return v8::Undefined();
+ window->postMessage(message.release(), &portArray, targetOrigin, source, ec);
+ return throwError(ec);
}
CALLBACK_FUNC_DECL(DOMWindowAtob)
{
INC_STATS("DOM.DOMWindow.atob()");
+
+ if (args[0]->IsNull())
+ return v8String("");
+ String str = toWebCoreString(args[0]);
+
DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
if (!V8Proxy::canAccessFrame(imp->frame(), true))
@@ -303,16 +447,17 @@ CALLBACK_FUNC_DECL(DOMWindowAtob)
if (args.Length() < 1)
return throwError("Not enough arguments", V8Proxy::SyntaxError);
- if (args[0]->IsNull())
- return v8String("");
-
- String str = toWebCoreString(args[0]);
return convertBase64(str, false);
}
CALLBACK_FUNC_DECL(DOMWindowBtoa)
{
INC_STATS("DOM.DOMWindow.btoa()");
+
+ if (args[0]->IsNull())
+ return v8String("");
+ String str = toWebCoreString(args[0]);
+
DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
if (!V8Proxy::canAccessFrame(imp->frame(), true))
@@ -321,10 +466,6 @@ CALLBACK_FUNC_DECL(DOMWindowBtoa)
if (args.Length() < 1)
return throwError("Not enough arguments", V8Proxy::SyntaxError);
- if (args[0]->IsNull())
- return v8String("");
-
- String str = toWebCoreString(args[0]);
return convertBase64(str, true);
}
@@ -335,7 +476,10 @@ CALLBACK_FUNC_DECL(DOMWindowBtoa)
CALLBACK_FUNC_DECL(DOMWindowToString)
{
INC_STATS("DOM.DOMWindow.toString()");
- return args.This()->ObjectProtoToString();
+ v8::Handle<v8::Object> domWrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, args.This());
+ if (domWrapper.IsEmpty())
+ return args.This()->ObjectProtoToString();
+ return domWrapper->ObjectProtoToString();
}
CALLBACK_FUNC_DECL(DOMWindowNOP)
@@ -344,84 +488,6 @@ CALLBACK_FUNC_DECL(DOMWindowNOP)
return v8::Undefined();
}
-static String eventNameFromAttributeName(const String& name)
-{
- ASSERT(name.startsWith("on"));
- String eventType = name.substring(2);
-
- if (eventType.startsWith("w")) {
- switch(eventType[eventType.length() - 1]) {
- case 't':
- eventType = "webkitAnimationStart";
- break;
- case 'n':
- eventType = "webkitAnimationIteration";
- break;
- case 'd':
- ASSERT(eventType.length() > 7);
- if (eventType[7] == 'a')
- eventType = "webkitAnimationEnd";
- else
- eventType = "webkitTransitionEnd";
- break;
- }
- }
-
- return eventType;
-}
-
-ACCESSOR_SETTER(DOMWindowEventHandler)
-{
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
- if (holder.IsEmpty())
- return;
-
- DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
- if (!imp->frame())
- return;
-
- Document* doc = imp->frame()->document();
- if (!doc)
- return;
-
- String key = toWebCoreString(name);
- String eventType = eventNameFromAttributeName(key);
-
- if (value->IsNull()) {
- // Clear the event listener
- imp->clearAttributeEventListener(eventType);
- } else {
- V8Proxy* proxy = V8Proxy::retrieve(imp->frame());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), value, true);
- if (listener)
- imp->setAttributeEventListener(eventType, listener);
- }
-}
-
-ACCESSOR_GETTER(DOMWindowEventHandler)
-{
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
- if (holder.IsEmpty())
- return v8::Undefined();
-
- DOMWindow* imp = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
- if (!imp->frame())
- return v8::Undefined();
-
- Document* doc = imp->frame()->document();
- if (!doc)
- return v8::Undefined();
-
- String key = toWebCoreString(name);
- String eventType = eventNameFromAttributeName(key);
-
- EventListener* listener = imp->getAttributeEventListener(eventType);
- return V8DOMWrapper::convertEventListenerToV8Object(listener);
-}
-
static bool canShowModalDialogNow(const Frame* frame)
{
// A frame can out live its page. See bug 1219613.
@@ -484,6 +550,10 @@ static Frame* createWindow(Frame* callingFrame,
ASSERT(callingFrame);
ASSERT(enteredFrame);
+ // Sandboxed iframes cannot open new auxiliary browsing contexts.
+ if (callingFrame && callingFrame->loader()->isSandboxed(SandboxNavigation))
+ return 0;
+
ResourceRequest request;
// For whatever reason, Firefox uses the entered frame to determine
@@ -512,7 +582,7 @@ static Frame* createWindow(Frame* callingFrame,
return 0;
newFrame->loader()->setOpener(openerFrame);
- newFrame->loader()->setOpenedByDOM();
+ newFrame->page()->setOpenedByDOM();
// Set dialog arguments on the global object of the new frame.
if (!dialogArgs.IsEmpty()) {
@@ -525,13 +595,13 @@ static Frame* createWindow(Frame* callingFrame,
if (protocolIsJavaScript(url) || ScriptController::isSafeScript(newFrame)) {
KURL completedUrl =
- url.isEmpty() ? KURL("") : completeURL(url);
+ url.isEmpty() ? KURL(ParsedURLString, "") : completeURL(url);
bool userGesture = processingUserGesture();
if (created)
newFrame->loader()->changeLocation(completedUrl, referrer, false, false, userGesture);
else if (!url.isEmpty())
- newFrame->loader()->scheduleLocationChange(completedUrl.string(), referrer, false, userGesture);
+ newFrame->redirectScheduler()->scheduleLocationChange(completedUrl.string(), referrer, false, userGesture);
}
return newFrame;
@@ -542,11 +612,16 @@ static Frame* createWindow(Frame* callingFrame,
CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
{
INC_STATS("DOM.DOMWindow.showModalDialog()");
+
+ String url = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
+ v8::Local<v8::Value> dialogArgs = args[1];
+ String featureArgs = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
+
DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(
V8ClassIndex::DOMWINDOW, args.Holder());
Frame* frame = window->frame();
- if (!frame || !V8Proxy::canAccessFrame(frame, true))
+ if (!V8Proxy::canAccessFrame(frame, true))
return v8::Undefined();
Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
@@ -560,10 +635,6 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
if (!canShowModalDialogNow(frame) || !allowPopUp())
return v8::Undefined();
- String url = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
- v8::Local<v8::Value> dialogArgs = args[1];
- String featureArgs = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
-
const HashMap<String, String> features = parseModalDialogFeatures(featureArgs);
const bool trusted = false;
@@ -631,27 +702,29 @@ CALLBACK_FUNC_DECL(DOMWindowShowModalDialog)
CALLBACK_FUNC_DECL(DOMWindowOpen)
{
INC_STATS("DOM.DOMWindow.open()");
+
+ String urlString = toWebCoreStringWithNullOrUndefinedCheck(args[0]);
+ AtomicString frameName = (args[1]->IsUndefined() || args[1]->IsNull()) ? "_blank" : AtomicString(toWebCoreString(args[1]));
+
DOMWindow* parent = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, args.Holder());
Frame* frame = parent->frame();
- if (!frame || !V8Proxy::canAccessFrame(frame, true))
- return v8::Undefined();
-
- Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
- if (!callingFrame)
+ if (!V8Proxy::canAccessFrame(frame, true))
return v8::Undefined();
Frame* enteredFrame = V8Proxy::retrieveFrameForEnteredContext();
if (!enteredFrame)
return v8::Undefined();
+ Frame* callingFrame = V8Proxy::retrieveFrameForCallingContext();
+ // We may not have a calling context if we are invoked by a plugin via NPAPI.
+ if (!callingFrame)
+ callingFrame = enteredFrame;
+
Page* page = frame->page();
if (!page)
return v8::Undefined();
- 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
// for empty framenames. Otherwise, illegitimate window.open() calls with
// no name will pass right through the popup blocker.
@@ -687,7 +760,7 @@ CALLBACK_FUNC_DECL(DOMWindowOpen)
// the outgoingReferrer. We replicate that behavior here.
String referrer = enteredFrame->loader()->outgoingReferrer();
- frame->loader()->scheduleLocationChange(completedUrl, referrer, false, userGesture);
+ frame->redirectScheduler()->scheduleLocationChange(completedUrl, referrer, false, userGesture);
}
return V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, frame->domWindow());
}
@@ -756,11 +829,8 @@ CALLBACK_FUNC_DECL(DOMWindowOpen)
INDEXED_PROPERTY_GETTER(DOMWindow)
{
INC_STATS("DOM.DOMWindow.IndexedPropertyGetter");
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
- if (holder.IsEmpty())
- return notHandledByInterceptor();
- DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
if (!window)
return notHandledByInterceptor();
@@ -780,11 +850,8 @@ NAMED_PROPERTY_GETTER(DOMWindow)
{
INC_STATS("DOM.DOMWindow.NamedPropertyGetter");
- v8::Handle<v8::Object> holder = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, info.This());
- if (holder.IsEmpty())
- return notHandledByInterceptor();
-
- DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, holder);
+ // TODO(antonm): investigate what convertToNativeObject does for the case of DOMWINDOW.
+ DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
if (!window)
return notHandledByInterceptor();
@@ -800,12 +867,13 @@ NAMED_PROPERTY_GETTER(DOMWindow)
return V8DOMWrapper::convertToV8Object(V8ClassIndex::DOMWINDOW, child->domWindow());
// Search IDL functions defined in the prototype
- v8::Handle<v8::Value> result = holder->GetRealNamedPropertyInPrototypeChain(name);
+ v8::Handle<v8::Value> result = info.Holder()->GetRealNamedProperty(name);
if (!result.IsEmpty())
return result;
// Search named items in the document.
Document* doc = frame->document();
+
if (doc) {
RefPtr<HTMLCollection> items = doc->windowNamedItems(propName);
if (items->length() >= 1) {
@@ -826,13 +894,13 @@ void V8Custom::WindowSetLocation(DOMWindow* window, const String& relativeURL)
if (!frame)
return;
- if (!shouldAllowNavigation(frame))
- return;
-
KURL url = completeURL(relativeURL);
if (url.isNull())
return;
+ if (!shouldAllowNavigation(frame))
+ return;
+
navigateIfAllowed(frame, url, false, false);
}
@@ -853,12 +921,15 @@ CALLBACK_FUNC_DECL(DOMWindowSetInterval)
void V8Custom::ClearTimeoutImpl(const v8::Arguments& args)
{
+ int handle = toInt32(args[0]);
+
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]);
+ ScriptExecutionContext* context = static_cast<ScriptExecutionContext*>(imp->document());
+ if (!context)
+ return;
DOMTimer::removeById(context, handle);
}
diff --git a/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
index 300e829..9ddd620 100644
--- a/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DatabaseCustom.cpp
@@ -45,13 +45,50 @@ namespace WebCore {
CALLBACK_FUNC_DECL(DatabaseChangeVersion)
{
INC_STATS("DOM.Database.changeVersion()");
+
+ if (args.Length() < 2)
+ return throwError("The old and new version strings are required.", V8Proxy::SyntaxError);
+
+ if (!(args[0]->IsString() && args[1]->IsString()))
+ return throwError("The old and new versions must be strings.");
+
+ Database* database = V8DOMWrapper::convertToNativeObject<Database>(V8ClassIndex::DATABASE, args.Holder());
+
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return v8::Undefined();
+
+ RefPtr<V8CustomSQLTransactionCallback> callback;
+ if (args.Length() > 2) {
+ if (!args[2]->IsObject())
+ return throwError("changeVersion transaction callback must be of valid type.");
+
+ callback = V8CustomSQLTransactionCallback::create(args[2], frame);
+ }
+
+ RefPtr<V8CustomSQLTransactionErrorCallback> errorCallback;
+ if (args.Length() > 3) {
+ if (!args[3]->IsObject())
+ return throwError("changeVersion error callback must be of valid type.");
+
+ errorCallback = V8CustomSQLTransactionErrorCallback::create(args[3], frame);
+ }
+
+ RefPtr<V8CustomVoidCallback> successCallback;
+ if (args.Length() > 4) {
+ if (!args[4]->IsObject())
+ return throwError("changeVersion success callback must be of valid type.");
+
+ successCallback = V8CustomVoidCallback::create(args[4], frame);
+ }
+
+ database->changeVersion(toWebCoreString(args[0]), toWebCoreString(args[1]), callback.release(), errorCallback.release(), successCallback.release());
+
return v8::Undefined();
}
-CALLBACK_FUNC_DECL(DatabaseTransaction)
+static v8::Handle<v8::Value> createTransaction(const v8::Arguments& args, bool readOnly)
{
- INC_STATS("DOM.Database.transaction()");
-
if (!args.Length())
return throwError("Transaction callback is required.", V8Proxy::SyntaxError);
@@ -76,18 +113,28 @@ CALLBACK_FUNC_DECL(DatabaseTransaction)
RefPtr<V8CustomVoidCallback> successCallback;
if (args.Length() > 2) {
- if (!args[1]->IsObject())
+ if (!args[2]->IsObject())
return throwError("Transaction success callback must be of valid type.");
successCallback = V8CustomVoidCallback::create(args[2], frame);
}
- database->transaction(callback.release(), errorCallback.release(), successCallback.release());
-
+ database->transaction(callback.release(), errorCallback.release(), successCallback.release(), readOnly);
return v8::Undefined();
}
+CALLBACK_FUNC_DECL(DatabaseTransaction)
+{
+ INC_STATS("DOM.Database.transaction()");
+ return createTransaction(args, false);
+}
+
+CALLBACK_FUNC_DECL(DatabaseReadTransaction)
+{
+ INC_STATS("DOM.Database.readTransaction()");
+ return createTransaction(args, true);
+}
+
} // namespace WebCore
#endif
-
diff --git a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
index f13e45e..263c005 100644
--- a/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DedicatedWorkerContextCustom.cpp
@@ -35,48 +35,26 @@
#include "WorkerContextExecutionProxy.h"
#include "DedicatedWorkerContext.h"
+#include "V8Binding.h"
+#include "V8MessagePortCustom.h"
#include "V8Proxy.h"
#include "V8WorkerContextEventListener.h"
namespace WebCore {
-ACCESSOR_GETTER(DedicatedWorkerContextOnmessage)
+CALLBACK_FUNC_DECL(DedicatedWorkerContextPostMessage)
{
- 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);
- }
+ INC_STATS(L"DOM.DedicatedWorkerContext.postMessage");
+ DedicatedWorkerContext* workerContext = V8DOMWrapper::convertToNativeObject<DedicatedWorkerContext>(V8ClassIndex::DEDICATEDWORKERCONTEXT, args.Holder());
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(v8ValueToWebCoreString(args[0]));
+ MessagePortArray portArray;
+ if (args.Length() > 1) {
+ if (!getMessagePortArray(args[1], portArray))
+ return v8::Undefined();
}
+ ExceptionCode ec = 0;
+ workerContext->postMessage(message.release(), &portArray, ec);
+ return throwError(ec);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
index 80d204b..ee68293 100644
--- a/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -31,10 +31,12 @@
#include "config.h"
#include "Document.h"
+#include "CanvasRenderingContext.h"
#include "ExceptionCode.h"
#include "Node.h"
#include "XPathNSResolver.h"
#include "XPathResult.h"
+#include "CanvasRenderingContext.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
@@ -62,12 +64,8 @@ CALLBACK_FUNC_DECL(DocumentEvaluate)
if (V8Node::HasInstance(args[1]))
contextNode = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[1]));
- RefPtr<XPathNSResolver> resolver;
- if (V8XPathNSResolver::HasInstance(args[2]))
- resolver = V8DOMWrapper::convertToNativeObject<XPathNSResolver>(V8ClassIndex::XPATHNSRESOLVER, v8::Handle<v8::Object>::Cast(args[2]));
- else if (args[2]->IsObject())
- resolver = V8CustomXPathNSResolver::create(args[2]->ToObject());
- else if (!args[2]->IsNull() && !args[2]->IsUndefined())
+ RefPtr<XPathNSResolver> resolver = V8DOMWrapper::getXPathNSResolver(args[2], V8Proxy::retrieve(V8Proxy::retrieveFrameForCallingContext()));
+ if (!resolver && !args[2]->IsNull() && !args[2]->IsUndefined())
return throwError(TYPE_MISMATCH_ERR);
int type = toInt32(args[3]);
@@ -99,8 +97,17 @@ CALLBACK_FUNC_DECL(DocumentGetCSSCanvasContext)
String name = toWebCoreString(args[1]);
int width = toInt32(args[2]);
int height = toInt32(args[3]);
- CanvasRenderingContext2D* result = imp->getCSSCanvasContext(contextId, name, width, height);
- return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+ CanvasRenderingContext* result = imp->getCSSCanvasContext(contextId, name, width, height);
+ if (!result)
+ return v8::Undefined();
+ if (result->is2d())
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+#if ENABLE(3D_CANVAS)
+ else if (result->is3d())
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLRENDERINGCONTEXT, result);
+#endif // ENABLE(3D_CANVAS)
+ ASSERT_NOT_REACHED();
+ return v8::Undefined();
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8FileListCustom.cpp b/WebCore/bindings/v8/custom/V8FileListCustom.cpp
new file mode 100644
index 0000000..bc533cf
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8FileListCustom.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 "FileList.h"
+
+#include "File.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+INDEXED_PROPERTY_GETTER(FileList)
+{
+ INC_STATS("DOM.FileList.IndexedPropertyGetter");
+ FileList* fileList = V8DOMWrapper::convertToNativeObject<FileList>(V8ClassIndex::FILELIST, info.Holder());
+ RefPtr<File> file = fileList->item(index);
+ if (!file)
+ return notHandledByInterceptor();
+
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::FILE, file.release());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp b/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp
index 7bc687c..011beff 100644
--- a/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp
@@ -1,49 +1,43 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-
#include "Geolocation.h"
+
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8CustomPositionCallback.h"
#include "V8CustomPositionErrorCallback.h"
#include "V8Proxy.h"
-
using namespace std;
using namespace WTF;
namespace WebCore {
-static const char* typeMismatchError = "TYPE_MISMATCH_ERR: DOM Exception 17";
+static const char typeMismatchError[] = "TYPE_MISMATCH_ERR: DOM Exception 17";
static void throwTypeMismatchException()
{
@@ -130,13 +124,7 @@ static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> va
return 0;
}
double timeoutDouble = timeoutNumber->Value();
- // V8 does not export a public symbol for infinity, so we must use a
- // platform type. On Android, it seems that V8 uses 0xf70f000000000000,
- // which is the standard way to represent infinity in a double. However,
- // numeric_limits<double>::infinity uses the system HUGE_VAL, which is
- // different. Therefore we test using isinf() and check that the value
- // is positive, which seems to handle things correctly.
- // If the value is infinity, there's nothing to do.
+ // If the value is positive infinity, there's nothing to do.
if (!(isinf(timeoutDouble) && timeoutDouble > 0)) {
v8::Local<v8::Int32> timeoutInt32 = timeoutValue->ToInt32();
if (timeoutInt32.IsEmpty()) {
@@ -161,7 +149,7 @@ static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> va
}
double maximumAgeDouble = maximumAgeNumber->Value();
if (isinf(maximumAgeDouble) && maximumAgeDouble > 0) {
- // If the value is infinity, clear maximumAge.
+ // If the value is positive infinity, clear maximumAge.
options->clearMaximumAge();
} else {
v8::Local<v8::Int32> maximumAgeInt32 = maximumAgeValue->ToInt32();
diff --git a/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp
new file mode 100644
index 0000000..419f374
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLAllCollectionCustom.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLAllCollection.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8NamedNodesCollection.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+static v8::Handle<v8::Value> getNamedItems(HTMLAllCollection* collection, AtomicString name)
+{
+ Vector<RefPtr<Node> > namedItems;
+ collection->namedItems(name, namedItems);
+
+ if (!namedItems.size())
+ return v8::Handle<v8::Value>();
+
+ if (namedItems.size() == 1)
+ return V8DOMWrapper::convertNodeToV8Object(namedItems.at(0).release());
+
+ NodeList* list = new V8NamedNodesCollection(namedItems);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODELIST, list);
+}
+
+static v8::Handle<v8::Value> getItem(HTMLAllCollection* collection, v8::Handle<v8::Value> argument)
+{
+ v8::Local<v8::Uint32> index = argument->ToArrayIndex();
+ if (index.IsEmpty()) {
+ v8::Handle<v8::Value> result = getNamedItems(collection, toWebCoreString(argument->ToString()));
+
+ if (result.IsEmpty())
+ return v8::Undefined();
+
+ return result;
+ }
+
+ RefPtr<Node> result = collection->item(index->Uint32Value());
+ return V8DOMWrapper::convertNodeToV8Object(result.release());
+}
+
+NAMED_PROPERTY_GETTER(HTMLAllCollection)
+{
+ INC_STATS("DOM.HTMLAllCollection.NamedPropertyGetter");
+ // Search the prototype chain first.
+ v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name);
+
+ if (!value.IsEmpty())
+ return value;
+
+ // Search local callback properties next to find IDL defined
+ // properties.
+ if (info.Holder()->HasRealNamedCallbackProperty(name))
+ return v8::Handle<v8::Value>();
+
+ // Finally, search the DOM structure.
+ HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, info.Holder());
+ return getNamedItems(imp, v8StringToAtomicWebCoreString(name));
+}
+
+CALLBACK_FUNC_DECL(HTMLAllCollectionItem)
+{
+ INC_STATS("DOM.HTMLAllCollection.item()");
+ HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, args.Holder());
+ return getItem(imp, args[0]);
+}
+
+CALLBACK_FUNC_DECL(HTMLAllCollectionNamedItem)
+{
+ INC_STATS("DOM.HTMLAllCollection.namedItem()");
+ HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, args.Holder());
+ v8::Handle<v8::Value> result = getNamedItems(imp, toWebCoreString(args[0]));
+
+ if (result.IsEmpty())
+ return v8::Undefined();
+
+ return result;
+}
+
+CALLBACK_FUNC_DECL(HTMLAllCollectionCallAsFunction)
+{
+ INC_STATS("DOM.HTMLAllCollection.callAsFunction()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ HTMLAllCollection* imp = V8DOMWrapper::convertToNativeObject<HTMLAllCollection>(V8ClassIndex::HTMLALLCOLLECTION, args.Holder());
+
+ if (args.Length() == 1)
+ return getItem(imp, args[0]);
+
+ // If there is a second argument it is the index of the item we want.
+ String name = toWebCoreString(args[0]);
+ v8::Local<v8::Uint32> index = args[1]->ToArrayIndex();
+ if (index.IsEmpty())
+ return v8::Undefined();
+
+ unsigned current = index->Uint32Value();
+ Node* node = imp->namedItem(name);
+ while (node) {
+ if (!current)
+ return V8DOMWrapper::convertNodeToV8Object(node);
+
+ node = imp->nextNamedItem(name);
+ current--;
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
index 6f9b761..c82d88a 100644
--- a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.cpp
@@ -29,8 +29,9 @@
*/
#include "config.h"
-#include "HTMLAudioElement.h"
+#include "V8HTMLAudioElementConstructor.h"
+#include "HTMLAudioElement.h"
#include "Document.h"
#include "Frame.h"
#include "HTMLNames.h"
@@ -42,6 +43,24 @@
namespace WebCore {
+v8::Persistent<v8::FunctionTemplate> V8HTMLAudioElementConstructor::GetTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> cachedTemplate;
+ if (!cachedTemplate.IsEmpty())
+ return cachedTemplate;
+
+ v8::HandleScope scope;
+ v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(USE_CALLBACK(HTMLAudioElementConstructor));
+
+ v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate();
+ instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
+ result->SetClassName(v8::String::New("HTMLAudioElement"));
+ result->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::HTMLAUDIOELEMENT));
+
+ cachedTemplate = v8::Persistent<v8::FunctionTemplate>::New(result);
+ return cachedTemplate;
+}
+
CALLBACK_FUNC_DECL(HTMLAudioElementConstructor)
{
INC_STATS("DOM.HTMLAudioElement.Contructor");
@@ -62,8 +81,11 @@ CALLBACK_FUNC_DECL(HTMLAudioElementConstructor)
V8DOMWrapper::convertNodeToV8Object(document);
RefPtr<HTMLAudioElement> audio = new HTMLAudioElement(HTMLNames::audioTag, document);
- if (args.Length() > 0)
+ audio->setAutobuffer(true);
+ if (args.Length() > 0) {
audio->setSrc(toWebCoreString(args[0]));
+ audio->scheduleLoad();
+ }
V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::NODE), audio.get());
audio->ref();
diff --git a/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
new file mode 100755
index 0000000..ac4b46d
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLAudioElementConstructor.h
@@ -0,0 +1,47 @@
+/*
+ * 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 V8HTMLAudioElementConstructor_h
+#define V8HTMLAudioElementConstructor_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+class V8HTMLAudioElementConstructor {
+private:
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+
+ friend class V8ClassIndex;
+};
+
+}
+
+#endif // V8HTMLAudioElementConstructor_h
diff --git a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
index 6ba9367..e51437e 100644
--- a/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLCanvasElementCustom.cpp
@@ -30,7 +30,9 @@
#include "config.h"
#include "HTMLCanvasElement.h"
+#include "CanvasRenderingContext.h"
+#include "CanvasRenderingContext.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
#include "V8Node.h"
@@ -44,8 +46,17 @@ CALLBACK_FUNC_DECL(HTMLCanvasElementGetContext)
v8::Handle<v8::Object> holder = args.Holder();
HTMLCanvasElement* imp = V8DOMWrapper::convertDOMWrapperToNode<HTMLCanvasElement>(holder);
String contextId = toWebCoreString(args[0]);
- CanvasRenderingContext2D* result = imp->getContext(contextId);
- return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+ CanvasRenderingContext* result = imp->getContext(contextId);
+ if (!result)
+ return v8::Undefined();
+ if (result->is2d())
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::CANVASRENDERINGCONTEXT2D, result);
+#if ENABLE(3D_CANVAS)
+ else if (result->is3d())
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLRENDERINGCONTEXT, result);
+#endif
+ ASSERT_NOT_REACHED();
+ return v8::Undefined();
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
index a0c3d74..9cf2f3d 100644
--- a/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLDocumentCustom.cpp
@@ -32,6 +32,7 @@
#include "HTMLDocument.h"
#include "Frame.h"
+#include "HTMLAllCollection.h"
#include "HTMLCollection.h"
#include "HTMLIFrameElement.h"
#include "HTMLNames.h"
@@ -119,8 +120,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWrite)
INC_STATS("DOM.HTMLDocument.write()");
HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder());
Frame* frame = V8Proxy::retrieveFrameForCallingContext();
- ASSERT(frame);
- htmlDocument->write(writeHelperGetString(args), frame->document());
+ htmlDocument->write(writeHelperGetString(args), frame ? frame->document() : NULL);
return v8::Undefined();
}
@@ -129,8 +129,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentWriteln)
INC_STATS("DOM.HTMLDocument.writeln()");
HTMLDocument* htmlDocument = V8DOMWrapper::convertDOMWrapperToNode<HTMLDocument>(args.Holder());
Frame* frame = V8Proxy::retrieveFrameForCallingContext();
- ASSERT(frame);
- htmlDocument->writeln(writeHelperGetString(args), frame->document());
+ htmlDocument->writeln(writeHelperGetString(args), frame ? frame->document() : NULL);
return v8::Undefined();
}
@@ -169,7 +168,7 @@ CALLBACK_FUNC_DECL(HTMLDocumentOpen)
}
Frame* frame = V8Proxy::retrieveFrameForCallingContext();
- htmlDocument->open(frame->document());
+ htmlDocument->open(frame ? frame->document() : NULL);
// Return the document.
return args.Holder();
}
diff --git a/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
index 4f865dd..2f55758 100644
--- a/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLFrameElementCustom.cpp
@@ -30,6 +30,7 @@
#include "config.h"
#include "HTMLFrameElement.h"
+#include "HTMLNames.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
@@ -37,6 +38,8 @@
namespace WebCore {
+using namespace HTMLNames;
+
ACCESSOR_SETTER(HTMLFrameElementSrc)
{
HTMLFrameElement* frame = V8DOMWrapper::convertDOMWrapperToNode<HTMLFrameElement>(info.Holder());
@@ -45,7 +48,7 @@ ACCESSOR_SETTER(HTMLFrameElementSrc)
if (!allowSettingFrameSrcToJavascriptUrl(frame, srcValue))
return;
- frame->setSrc(srcValue);
+ frame->setAttribute(srcAttr, srcValue);
}
ACCESSOR_SETTER(HTMLFrameElementLocation)
diff --git a/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
index ce2c29a..a4863e8 100644
--- a/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLIFrameElementCustom.cpp
@@ -30,6 +30,7 @@
#include "config.h"
#include "HTMLIFrameElement.h"
+#include "HTMLNames.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
@@ -37,6 +38,8 @@
namespace WebCore {
+using namespace HTMLNames;
+
ACCESSOR_SETTER(HTMLIFrameElementSrc)
{
HTMLIFrameElement* iframe = V8DOMWrapper::convertDOMWrapperToNode<HTMLIFrameElement>(info.Holder());
@@ -45,7 +48,7 @@ ACCESSOR_SETTER(HTMLIFrameElementSrc)
if (!allowSettingFrameSrcToJavascriptUrl(iframe, v))
return;
- iframe->setSrc(v);
+ iframe->setAttribute(srcAttr, v);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
index 91ebd5f..71c99cf 100644
--- a/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.cpp
@@ -29,8 +29,9 @@
*/
#include "config.h"
-#include "HTMLImageElement.h"
+#include "V8HTMLImageElementConstructor.h"
+#include "HTMLImageElement.h"
#include "Document.h"
#include "Frame.h"
#include "HTMLNames.h"
@@ -42,6 +43,24 @@
namespace WebCore {
+v8::Persistent<v8::FunctionTemplate> V8HTMLImageElementConstructor::GetTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> cachedTemplate;
+ if (!cachedTemplate.IsEmpty())
+ return cachedTemplate;
+
+ v8::HandleScope scope;
+ v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(USE_CALLBACK(HTMLImageElementConstructor));
+
+ v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate();
+ instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
+ result->SetClassName(v8::String::New("HTMLImageElement"));
+ result->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::HTMLIMAGEELEMENT));
+
+ cachedTemplate = v8::Persistent<v8::FunctionTemplate>::New(result);
+ return cachedTemplate;
+}
+
CALLBACK_FUNC_DECL(HTMLImageElementConstructor)
{
INC_STATS("DOM.HTMLImageElement.Contructor");
diff --git a/WebCore/bindings/v8/ScriptObjectQuarantine.h b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
index 3b7ccff..cdce0e0 100644..100755
--- a/WebCore/bindings/v8/ScriptObjectQuarantine.h
+++ b/WebCore/bindings/v8/custom/V8HTMLImageElementConstructor.h
@@ -28,33 +28,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// ScriptObjectQuarantine is used in JSC for wrapping DOM objects of the page
-// before they are passed to Inspector's front-end. The wrapping prevents
-// malicious scripts from gaining privileges. For V8, we are currently just
-// passing the object itself, without any wrapping.
+#ifndef V8HTMLImageElementConstructor_h
+#define V8HTMLImageElementConstructor_h
-#ifndef ScriptObjectQuarantine_h
-#define ScriptObjectQuarantine_h
-
-#include "ScriptState.h"
+#include <v8.h>
namespace WebCore {
- class Database;
- class DOMWindow;
- class Frame;
- class Node;
- class ScriptObject;
- class ScriptValue;
- class Storage;
-
- ScriptValue quarantineValue(ScriptState*, const ScriptValue&);
+ class V8HTMLImageElementConstructor {
+ private:
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
- bool getQuarantinedScriptObject(Database* database, ScriptObject& quarantinedObject);
- bool getQuarantinedScriptObject(Frame* frame, Storage* storage, ScriptObject& quarantinedObject);
- bool getQuarantinedScriptObject(Node* node, ScriptObject& quarantinedObject);
- bool getQuarantinedScriptObject(DOMWindow* domWindow, ScriptObject& quarantinedObject);
+ friend class V8ClassIndex;
+ };
}
-#endif // ScriptObjectQuarantine_h
+#endif // V8HTMLImageElementConstructor_h
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
index c22d127..f9c9cb4 100644
--- a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.cpp
@@ -29,8 +29,9 @@
*/
#include "config.h"
-#include "HTMLOptionElement.h"
+#include "V8HTMLOptionElementConstructor.h"
+#include "HTMLOptionElement.h"
#include "Document.h"
#include "Frame.h"
#include "HTMLNames.h"
@@ -43,6 +44,24 @@
namespace WebCore {
+v8::Persistent<v8::FunctionTemplate> V8HTMLOptionElementConstructor::GetTemplate()
+{
+ static v8::Persistent<v8::FunctionTemplate> cachedTemplate;
+ if (!cachedTemplate.IsEmpty())
+ return cachedTemplate;
+
+ v8::HandleScope scope;
+ v8::Local<v8::FunctionTemplate> result = v8::FunctionTemplate::New(USE_CALLBACK(HTMLOptionElementConstructor));
+
+ v8::Local<v8::ObjectTemplate> instance = result->InstanceTemplate();
+ instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
+ result->SetClassName(v8::String::New("HTMLOptionElement"));
+ result->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::HTMLOPTIONELEMENT));
+
+ cachedTemplate = v8::Persistent<v8::FunctionTemplate>::New(result);
+ return cachedTemplate;
+}
+
CALLBACK_FUNC_DECL(HTMLOptionElementConstructor)
{
INC_STATS("DOM.HTMLOptionElement.Contructor");
diff --git a/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
new file mode 100755
index 0000000..70076a5
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HTMLOptionElementConstructor.h
@@ -0,0 +1,47 @@
+/*
+ * 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 V8HTMLOptionElementConstructor_h
+#define V8HTMLOptionElementConstructor_h
+
+#include <v8.h>
+
+namespace WebCore {
+
+ class V8HTMLOptionElementConstructor {
+ private:
+ static v8::Persistent<v8::FunctionTemplate> GetTemplate();
+
+ friend class V8ClassIndex;
+ };
+
+}
+
+#endif // V8HTMLOptionElementConstructor_h
diff --git a/WebCore/bindings/v8/custom/V8HistoryCustom.cpp b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
new file mode 100644
index 0000000..c884d15
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8HistoryCustom.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 "History.h"
+
+#include "ExceptionCode.h"
+#include "SerializedScriptValue.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+CALLBACK_FUNC_DECL(HistoryPushState)
+{
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(toWebCoreString(args[0]));
+
+ v8::TryCatch tryCatch;
+ String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
+ if (tryCatch.HasCaught())
+ return v8::Undefined();
+ String url;
+ if (args.Length() > 2) {
+ url = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
+ if (tryCatch.HasCaught())
+ return v8::Undefined();
+ }
+
+ ExceptionCode ec = 0;
+ History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, args.Holder());
+ history->stateObjectAdded(historyState.release(), title, url, History::StateObjectPush, ec);
+ return throwError(ec);
+}
+
+CALLBACK_FUNC_DECL(HistoryReplaceState)
+{
+ RefPtr<SerializedScriptValue> historyState = SerializedScriptValue::create(toWebCoreString(args[0]));
+
+ v8::TryCatch tryCatch;
+ String title = toWebCoreStringWithNullOrUndefinedCheck(args[1]);
+ if (tryCatch.HasCaught())
+ return v8::Undefined();
+ String url;
+ if (args.Length() > 2) {
+ url = toWebCoreStringWithNullOrUndefinedCheck(args[2]);
+ if (tryCatch.HasCaught())
+ return v8::Undefined();
+ }
+
+ ExceptionCode ec = 0;
+ History* history = V8DOMWrapper::convertToNativeObject<History>(V8ClassIndex::HISTORY, args.Holder());
+ history->stateObjectAdded(historyState.release(), title, url, History::StateObjectReplace, ec);
+ return throwError(ec);
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
new file mode 100644
index 0000000..fac6733
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InjectedScriptHost.h"
+
+#include "Database.h"
+#include "DOMWindow.h"
+#include "Frame.h"
+#include "InspectorController.h"
+#include "Node.h"
+#include "Page.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(InjectedScriptHostInspectedWindow)
+{
+ INC_STATS("InjectedScriptHost.inspectedWindow()");
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ InspectorController* ic = host->inspectorController();
+ if (!ic)
+ return v8::Undefined();
+ return V8DOMWrapper::convertToV8Object<DOMWindow>(V8ClassIndex::DOMWINDOW, ic->inspectedPage()->mainFrame()->domWindow());
+}
+
+CALLBACK_FUNC_DECL(InjectedScriptHostWrapCallback)
+{
+ INC_STATS("InjectedScriptHost.wrapCallback()");
+ return args[0];
+}
+
+CALLBACK_FUNC_DECL(InjectedScriptHostNodeForId)
+{
+ INC_STATS("InjectedScriptHost.nodeForId()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+
+ Node* node = host->nodeForId(args[0]->ToInt32()->Value());
+ if (!node)
+ return v8::Undefined();
+
+ InspectorController* ic = host->inspectorController();
+ if (!ic)
+ return v8::Undefined();
+
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NODE, node);
+}
+
+CALLBACK_FUNC_DECL(InjectedScriptHostWrapObject)
+{
+ INC_STATS("InjectedScriptHost.wrapObject()");
+ if (args.Length() < 2)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ return host->wrapObject(ScriptValue(args[0]), toWebCoreStringWithNullCheck(args[1])).v8Value();
+}
+
+CALLBACK_FUNC_DECL(InjectedScriptHostUnwrapObject)
+{
+ INC_STATS("InjectedScriptHost.unwrapObject()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ return host->unwrapObject(toWebCoreStringWithNullCheck(args[0])).v8Value();
+}
+
+CALLBACK_FUNC_DECL(InjectedScriptHostPushNodePathToFrontend)
+{
+ INC_STATS("InjectedScriptHost.pushNodePathToFrontend()");
+ if (args.Length() < 2)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
+ bool selectInUI = args[1]->ToBoolean()->Value();
+ if (node)
+ return v8::Number::New(host->pushNodePathToFrontend(node, selectInUI));
+
+ return v8::Undefined();
+}
+
+#if ENABLE(DATABASE)
+CALLBACK_FUNC_DECL(InjectedScriptHostDatabaseForId)
+{
+ INC_STATS("InjectedScriptHost.databaseForId()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ Database* database = host->databaseForId(args[0]->ToInt32()->Value());
+ if (!database)
+ return v8::Undefined();
+ return V8DOMWrapper::convertToV8Object<Database>(V8ClassIndex::DATABASE, database);
+}
+
+CALLBACK_FUNC_DECL(InjectedScriptHostSelectDatabase)
+{
+ INC_STATS("InjectedScriptHost.selectDatabase()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ Database* database = V8DOMWrapper::convertToNativeObject<Database>(V8ClassIndex::DATABASE, v8::Handle<v8::Object>::Cast(args[0]));
+ if (database)
+ host->selectDatabase(database);
+
+ return v8::Undefined();
+}
+#endif
+
+#if ENABLE(DOM_STORAGE)
+CALLBACK_FUNC_DECL(InjectedScriptHostSelectDOMStorage)
+{
+ INC_STATS("InjectedScriptHost.selectDOMStorage()");
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ InjectedScriptHost* host = V8DOMWrapper::convertToNativeObject<InjectedScriptHost>(V8ClassIndex::INJECTEDSCRIPTHOST, args.Holder());
+ Storage* storage = V8DOMWrapper::convertToNativeObject<Storage>(V8ClassIndex::STORAGE, v8::Handle<v8::Object>::Cast(args[0]));
+ if (storage)
+ host->selectDOMStorage(storage);
+
+ return v8::Undefined();
+}
+#endif
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp
deleted file mode 100644
index 2571df4..0000000
--- a/WebCore/bindings/v8/custom/V8InspectorBackendCustom.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "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"
-#include "Range.h"
-#include "Page.h"
-#include "TextIterator.h"
-#include "VisiblePosition.h"
-
-#include "V8Binding.h"
-#include "V8CustomBinding.h"
-#include "V8Proxy.h"
-
-namespace WebCore {
-
-CALLBACK_FUNC_DECL(InspectorBackendHighlightDOMNode)
-{
- INC_STATS("InspectorBackend.highlightDOMNode()");
-
- if (args.Length() < 1)
- return v8::Undefined();
-
- Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
- if (!node)
- return v8::Undefined();
-
- InspectorBackend* inspectorBackend = V8DOMWrapper::convertToNativeObject<InspectorBackend>(V8ClassIndex::INSPECTORBACKEND, args.Holder());
- inspectorBackend->highlight(node);
-
- return v8::Undefined();
-}
-
-CALLBACK_FUNC_DECL(InspectorBackendSearch)
-{
- INC_STATS("InspectorBackend.search()");
-
- if (args.Length() < 2)
- return v8::Undefined();
-
- Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
- if (!node)
- return v8::Undefined();
-
- String target = toWebCoreStringWithNullCheck(args[1]);
- if (target.isEmpty())
- return v8::Undefined();
-
- v8::Local<v8::Array> result = v8::Array::New();
- RefPtr<Range> searchRange(rangeOfContents(node));
-
- ExceptionCode ec = 0;
- int index = 0;
- do {
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
- if (resultRange->collapsed(ec))
- break;
-
- // A non-collapsed result range can in some funky whitespace cases still not
- // advance the range's start position (4509328). Break to avoid infinite loop.
- VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
- if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
- break;
-
- result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release()));
-
- setStart(searchRange.get(), newStart);
- } while (true);
-
- return result;
-}
-
-#if ENABLE(DATABASE)
-CALLBACK_FUNC_DECL(InspectorBackendDatabaseTableNames)
-{
- INC_STATS("InspectorBackend.databaseTableNames()");
- v8::Local<v8::Array> result = v8::Array::New(0);
- return result;
-}
-#endif
-
-CALLBACK_FUNC_DECL(InspectorBackendInspectedWindow)
-{
- INC_STATS("InspectorBackend.inspectedWindow()");
-
- 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(InspectorBackendSetting)
-{
- INC_STATS("InspectorBackend.setting()");
-
- if (args.Length() < 1)
- return v8::Undefined();
-
- String key = toWebCoreStringWithNullCheck(args[0]);
- if (key.isEmpty())
- return v8::Undefined();
-
- 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:
- case InspectorController::Setting::NoType:
- return v8::Undefined();
- case InspectorController::Setting::StringType:
- return v8String(setting.string());
- case InspectorController::Setting::DoubleType:
- return v8::Number::New(setting.doubleValue());
- case InspectorController::Setting::IntegerType:
- return v8::Number::New(setting.integerValue());
- case InspectorController::Setting::BooleanType:
- return v8Boolean(setting.booleanValue());
- case InspectorController::Setting::StringVectorType: {
- const Vector<String>& strings = setting.stringVector();
- v8::Local<v8::Array> stringsArray = v8::Array::New(strings.size());
- const unsigned length = strings.size();
- for (unsigned i = 0; i < length; ++i)
- stringsArray->Set(v8::Number::New(i), v8String(strings[i]));
- return stringsArray;
- }
- }
-}
-
-CALLBACK_FUNC_DECL(InspectorBackendSetSetting)
-{
- INC_STATS("InspectorBackend.setSetting()");
- if (args.Length() < 2)
- return v8::Undefined();
-
- String key = toWebCoreStringWithNullCheck(args[0]);
- if (key.isEmpty())
- return v8::Undefined();
-
- InspectorController::Setting setting;
-
- v8::Local<v8::Value> value = args[1];
- if (value->IsUndefined() || value->IsNull()) {
- // Do nothing. The setting is already NoType.
- ASSERT(setting.type() == InspectorController::Setting::NoType);
- } else if (value->IsString())
- setting.set(toWebCoreStringWithNullCheck(value));
- else if (value->IsNumber())
- setting.set(value->NumberValue());
- else if (value->IsBoolean())
- setting.set(value->BooleanValue());
- else if (value->IsArray()) {
- v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(value);
- Vector<String> strings;
- for (unsigned i = 0; i < v8Array->Length(); ++i) {
- String item = toWebCoreString(v8Array->Get(v8::Integer::New(i)));
- if (item.isEmpty())
- return v8::Undefined();
- strings.append(item);
- }
- setting.set(strings);
- } else
- return v8::Undefined();
-
- 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(InspectorBackendWrapCallback)
-{
- INC_STATS("InspectorBackend.wrapCallback()");
- return args[0];
-}
-
-} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
new file mode 100644
index 0000000..15b45e9
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorFrontendHost.h"
+
+#include "ExceptionCode.h"
+#include "InspectorController.h"
+#include "Node.h"
+#include "Range.h"
+#include "Page.h"
+#include "TextIterator.h"
+#include "VisiblePosition.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(InspectorFrontendHostSearch)
+{
+ INC_STATS("InspectorFrontendHost.search()");
+
+ if (args.Length() < 2)
+ return v8::Undefined();
+
+ Node* node = V8DOMWrapper::convertDOMWrapperToNode<Node>(v8::Handle<v8::Object>::Cast(args[0]));
+ if (!node)
+ return v8::Undefined();
+
+ String target = toWebCoreStringWithNullCheck(args[1]);
+ if (target.isEmpty())
+ return v8::Undefined();
+
+ v8::Local<v8::Array> result = v8::Array::New();
+ RefPtr<Range> searchRange(rangeOfContents(node));
+
+ ExceptionCode ec = 0;
+ int index = 0;
+ do {
+ RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, false));
+ if (resultRange->collapsed(ec))
+ break;
+
+ // A non-collapsed result range can in some funky whitespace cases still not
+ // advance the range's start position (4509328). Break to avoid infinite loop.
+ VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
+ if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
+ break;
+
+ result->Set(v8::Number::New(index++), V8DOMWrapper::convertToV8Object(V8ClassIndex::RANGE, resultRange.release()));
+
+ setStart(searchRange.get(), newStart);
+ } while (true);
+
+ return result;
+}
+
+CALLBACK_FUNC_DECL(InspectorFrontendHostShowContextMenu)
+{
+ return v8::Undefined();
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8LocationCustom.cpp b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
index 3f3ff6b..1ed4c51 100644
--- a/WebCore/bindings/v8/custom/V8LocationCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8LocationCustom.cpp
@@ -128,13 +128,13 @@ ACCESSOR_SETTER(LocationHref)
if (!frame)
return;
- if (!shouldAllowNavigation(frame))
- return;
-
KURL url = completeURL(toWebCoreString(value));
if (url.isNull())
return;
+ if (!shouldAllowNavigation(frame))
+ return;
+
navigateIfAllowed(frame, url, false, false);
}
@@ -274,7 +274,7 @@ CALLBACK_FUNC_DECL(LocationReload)
return v8::Undefined();
if (!protocolIsJavaScript(frame->loader()->url()))
- frame->loader()->scheduleRefresh(processingUserGesture());
+ frame->redirectScheduler()->scheduleRefresh(processingUserGesture());
return v8::Undefined();
}
@@ -288,13 +288,13 @@ CALLBACK_FUNC_DECL(LocationReplace)
if (!frame)
return v8::Undefined();
- if (!shouldAllowNavigation(frame))
- return v8::Undefined();
-
KURL url = completeURL(toWebCoreString(args[0]));
if (url.isNull())
return v8::Undefined();
+ if (!shouldAllowNavigation(frame))
+ return v8::Undefined();
+
navigateIfAllowed(frame, url, true, true);
return v8::Undefined();
}
@@ -309,13 +309,13 @@ CALLBACK_FUNC_DECL(LocationAssign)
if (!frame)
return v8::Undefined();
- if (!shouldAllowNavigation(frame))
- return v8::Undefined();
-
KURL url = completeURL(toWebCoreString(args[0]));
if (url.isNull())
return v8::Undefined();
+ if (!shouldAllowNavigation(frame))
+ return v8::Undefined();
+
navigateIfAllowed(frame, url, false, false);
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
index f45aecf..ca02b16 100644
--- a/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
@@ -36,6 +36,7 @@
#include "Document.h"
#include "Frame.h"
+#include "V8Utilities.h"
#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
@@ -52,16 +53,9 @@ CALLBACK_FUNC_DECL(MessageChannelConstructor)
return throwError("DOM object constructor cannot be called as a function.");
// 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();
- }
+ ScriptExecutionContext* context = getScriptExecutionContext();
+ if (!context)
+ return v8::Undefined();
// Note: it's OK to let this RefPtr go out of scope because we also call
// SetDOMWrapper(), which effectively holds a reference to obj.
diff --git a/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
new file mode 100644
index 0000000..c5af635
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8MessageEventCustom.cpp
@@ -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.
+ */
+
+#include "config.h"
+#include "MessageEvent.h"
+#include "SerializedScriptValue.h"
+
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8DOMWindow.h"
+#include "V8MessagePortCustom.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+ACCESSOR_GETTER(MessageEventPorts)
+{
+ INC_STATS("DOM.MessageEvent.ports");
+ MessageEvent* event = V8DOMWrapper::convertToNativeObject<MessageEvent>(V8ClassIndex::MESSAGEEVENT, info.Holder());
+
+ MessagePortArray* ports = event->ports();
+ if (!ports || ports->isEmpty())
+ return v8::Null();
+
+ v8::Local<v8::Array> portArray = v8::Array::New(ports->size());
+ for (size_t i = 0; i < ports->size(); ++i)
+ portArray->Set(v8::Integer::New(i), V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, (*ports)[i].get()));
+
+ return portArray;
+}
+
+CALLBACK_FUNC_DECL(MessageEventInitMessageEvent)
+{
+ INC_STATS("DOM.MessageEvent.initMessageEvent");
+ MessageEvent* event = V8DOMWrapper::convertToNativeObject<MessageEvent>(V8ClassIndex::MESSAGEEVENT, args.Holder());
+ String typeArg = v8ValueToWebCoreString(args[0]);
+ bool canBubbleArg = args[1]->BooleanValue();
+ bool cancelableArg = args[2]->BooleanValue();
+ RefPtr<SerializedScriptValue> dataArg = SerializedScriptValue::create(v8ValueToWebCoreString(args[3]));
+ String originArg = v8ValueToWebCoreString(args[4]);
+ String lastEventIdArg = v8ValueToWebCoreString(args[5]);
+ DOMWindow* sourceArg = V8DOMWindow::HasInstance(args[6]) ? V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, v8::Handle<v8::Object>::Cast(args[6])) : 0;
+ OwnPtr<MessagePortArray> portArray;
+
+ if (!isUndefinedOrNull(args[7])) {
+ portArray = new MessagePortArray();
+ if (!getMessagePortArray(args[7], *portArray))
+ return v8::Undefined();
+ }
+ event->initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg.release(), originArg, lastEventIdArg, sourceArg, portArray.release());
+ return v8::Undefined();
+ }
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
index 95d248c..0d8631f 100644
--- a/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.cpp
@@ -32,66 +32,22 @@
#include "ExceptionCode.h"
#include "MessagePort.h"
+#include "SerializedScriptValue.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
+#include "V8MessagePortCustom.h"
+#include "V8MessagePort.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 = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
- return V8DOMWrapper::convertEventListenerToV8Object(messagePort->onmessage());
-}
-
-ACCESSOR_SETTER(MessagePortOnmessage)
-{
- INC_STATS("DOM.MessagePort.onmessage._set");
- MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, info.Holder());
- if (value->IsNull()) {
- if (messagePort->onmessage()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(messagePort->onmessage());
- removeHiddenDependency(info.Holder(), listener->getListenerObject(), V8Custom::kMessagePortRequestCacheIndex);
- }
-
- // Clear the listener.
- messagePort->setOnmessage(0);
-
- } else {
- RefPtr<EventListener> listener = getEventListener(messagePort, value, false, false);
- if (listener) {
- messagePort->setOnmessage(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kMessagePortRequestCacheIndex);
- }
- }
-}
-
CALLBACK_FUNC_DECL(MessagePortAddEventListener)
{
INC_STATS("DOM.MessagePort.addEventListener()");
MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
- RefPtr<EventListener> listener = getEventListener(messagePort, args[1], false, true);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -106,7 +62,7 @@ CALLBACK_FUNC_DECL(MessagePortRemoveEventListener)
{
INC_STATS("DOM.MessagePort.removeEventListener()");
MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
- RefPtr<EventListener> listener = getEventListener(messagePort, args[1], true, true);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(messagePort, args[1], false, ListenerFindOnly);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -118,4 +74,64 @@ CALLBACK_FUNC_DECL(MessagePortRemoveEventListener)
return v8::Undefined();
}
+CALLBACK_FUNC_DECL(MessagePortPostMessage)
+{
+ INC_STATS("DOM.MessagePort.postMessage");
+ MessagePort* messagePort = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, args.Holder());
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(toWebCoreString(args[0]));
+ MessagePortArray portArray;
+ if (args.Length() > 1) {
+ if (!getMessagePortArray(args[1], portArray))
+ return v8::Undefined();
+ }
+ ExceptionCode ec = 0;
+ messagePort->postMessage(message.release(), &portArray, ec);
+ return throwError(ec);
+}
+
+bool getMessagePortArray(v8::Local<v8::Value> value, MessagePortArray& portArray)
+{
+ if (isUndefinedOrNull(value)) {
+ portArray.resize(0);
+ return true;
+ }
+
+ if (!value->IsObject()) {
+ throwError("MessagePortArray argument must be an object");
+ return false;
+ }
+ uint32_t length = 0;
+ v8::Local<v8::Object> ports = v8::Local<v8::Object>::Cast(value);
+
+ if (value->IsArray()) {
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(value);
+ length = array->Length();
+ } else {
+ // Sequence-type object - get the length attribute
+ v8::Local<v8::Value> sequenceLength = ports->Get(v8::String::New("length"));
+ if (!sequenceLength->IsNumber()) {
+ throwError("MessagePortArray argument has no length attribute");
+ return false;
+ }
+ length = sequenceLength->Uint32Value();
+ }
+ portArray.resize(length);
+
+ for (unsigned int i = 0; i < length; ++i) {
+ v8::Local<v8::Value> port = ports->Get(v8::Integer::New(i));
+ // Validation of non-null objects, per HTML5 spec 8.3.3.
+ if (isUndefinedOrNull(port)) {
+ throwError(INVALID_STATE_ERR);
+ return false;
+ }
+ // Validation of Objects implementing an interface, per WebIDL spec 4.1.15.
+ if (!V8MessagePort::HasInstance(port)) {
+ throwError("MessagePortArray argument must contain only MessagePorts");
+ return false;
+ }
+ portArray[i] = V8DOMWrapper::convertToNativeObject<MessagePort>(V8ClassIndex::MESSAGEPORT, v8::Handle<v8::Object>::Cast(port));
+ }
+ return true;
+}
+
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8MessagePortCustom.h b/WebCore/bindings/v8/custom/V8MessagePortCustom.h
new file mode 100644
index 0000000..7ab502b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8MessagePortCustom.h
@@ -0,0 +1,48 @@
+/*
+ * 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 V8MessagePortCustom_h
+#define V8MessagePortCustom_h
+
+#include <v8.h>
+
+#include "MessagePort.h"
+
+namespace WebCore {
+
+ // Helper function which pulls the values out of a JS sequence and into a MessagePortArray.
+ // Also validates the elements per sections 4.1.13 and 4.1.15 of the WebIDL spec and section 8.3.3 of the HTML5 spec and generates exceptions as appropriate.
+ // Returns true if the array was filled, or false if the passed value was not of an appropriate type.
+ bool getMessagePortArray(v8::Local<v8::Value>, MessagePortArray&);
+
+} // namespace WebCore
+
+#endif // V8MessagePortCustom_h
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index 6b0d740..9b4b9aa 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -39,76 +39,18 @@
#include "V8CustomBinding.h"
#include "V8CustomEventListener.h"
#include "V8Node.h"
-#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include <wtf/RefPtr.h>
namespace WebCore {
-static inline String toEventType(v8::Local<v8::String> value)
-{
- String key = toWebCoreString(value);
- ASSERT(key.startsWith("on"));
- return key.substring(2);
-}
-
-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)
- 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);
-}
-
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);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -126,9 +68,9 @@ CALLBACK_FUNC_DECL(NodeRemoveEventListener)
// It is possbile that the owner document of the node is detached
// from the frame.
// See issue http://b/878909
- RefPtr<EventListener> listener = getEventListener(node, args[1], false, true);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(node, args[1], false, ListenerFindOnly);
if (listener) {
- String type = toWebCoreString(args[0]);
+ AtomicString type = v8ValueToAtomicWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
node->removeEventListener(type, listener.get(), useCapture);
removeHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
diff --git a/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
new file mode 100644
index 0000000..a1f20cc
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8NotificationCenterCustom.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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(NOTIFICATIONS)
+
+#include "NotImplemented.h"
+#include "Notification.h"
+#include "NotificationCenter.h"
+#include "V8Binding.h"
+#include "V8CustomBinding.h"
+#include "V8CustomEventListener.h"
+#include "V8CustomVoidCallback.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(NotificationAddEventListener)
+{
+ INC_STATS("DOM.Notification.addEventListener()");
+ Notification* notification = V8DOMWrapper::convertToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, args.Holder());
+
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOrCreate);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ notification->addEventListener(type, listener, useCapture);
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kNotificationRequestCacheIndex);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(NotificationRemoveEventListener)
+{
+ INC_STATS("DOM.Notification.removeEventListener()");
+ Notification* notification = V8DOMWrapper::convertToNativeObject<Notification>(V8ClassIndex::NOTIFICATION, args.Holder());
+
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(notification, args[1], false, ListenerFindOnly);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ notification->removeEventListener(type, listener.get(), useCapture);
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kNotificationRequestCacheIndex);
+ }
+
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(NotificationCenterCreateHTMLNotification)
+{
+ INC_STATS(L"DOM.NotificationCenter.CreateHTMLNotification()");
+ NotificationCenter* notificationCenter = V8DOMWrapper::convertToNativeObject<NotificationCenter>(V8ClassIndex::NOTIFICATIONCENTER, args.Holder());
+
+ ExceptionCode ec = 0;
+ String url = toWebCoreString(args[0]);
+ RefPtr<Notification> notification = notificationCenter->createHTMLNotification(url, ec);
+
+ if (ec)
+ return throwError(ec);
+
+ if (notificationCenter->context()->isWorkerContext())
+ return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get());
+
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get());
+}
+
+CALLBACK_FUNC_DECL(NotificationCenterCreateNotification)
+{
+ INC_STATS(L"DOM.NotificationCenter.CreateNotification()");
+ NotificationCenter* notificationCenter = V8DOMWrapper::convertToNativeObject<NotificationCenter>(V8ClassIndex::NOTIFICATIONCENTER, args.Holder());
+
+ ExceptionCode ec = 0;
+ RefPtr<Notification> notification = notificationCenter->createNotification(toWebCoreString(args[0]), toWebCoreString(args[1]), toWebCoreString(args[2]), ec);
+
+ if (ec)
+ return throwError(ec);
+
+ if (notificationCenter->context()->isWorkerContext())
+ return WorkerContextExecutionProxy::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get());
+
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::NOTIFICATION, notification.get());
+}
+
+CALLBACK_FUNC_DECL(NotificationCenterRequestPermission)
+{
+ INC_STATS(L"DOM.NotificationCenter.RequestPermission()");
+ NotificationCenter* notificationCenter = V8DOMWrapper::convertToNativeObject<NotificationCenter>(V8ClassIndex::NOTIFICATIONCENTER, args.Holder());
+ ScriptExecutionContext* context = notificationCenter->context();
+
+ // Requesting permission is only valid from a page context.
+ if (context->isWorkerContext())
+ return throwError(NOT_SUPPORTED_ERR);
+
+ RefPtr<V8CustomVoidCallback> callback;
+ if (args.Length() > 0) {
+ if (!args[0]->IsObject())
+ return throwError("Callback must be of valid type.", V8Proxy::TypeError);
+
+ callback = V8CustomVoidCallback::create(args[0], V8Proxy::retrieveFrameForCurrentContext());
+ }
+
+ notificationCenter->requestPermission(callback.release());
+ return v8::Undefined();
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(NOTIFICATIONS)
diff --git a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
index ce9c345..dff4ff4 100644
--- a/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGElementInstanceCustom.cpp
@@ -49,15 +49,12 @@ CALLBACK_FUNC_DECL(SVGElementInstanceAddEventListener)
INC_STATS("DOM.SVGElementInstance.AddEventListener()");
SVGElementInstance* instance = V8DOMWrapper::convertDOMWrapperToNative<SVGElementInstance>(args.Holder());
- V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
- if (!proxy)
- return v8::Undefined();
-
- RefPtr<EventListener> listener = proxy->eventListeners()->findOrCreateWrapper<V8EventListener>(proxy->frame(), args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
instance->addEventListener(type, listener, useCapture);
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
}
return v8::Undefined();
@@ -68,15 +65,12 @@ CALLBACK_FUNC_DECL(SVGElementInstanceRemoveEventListener)
INC_STATS("DOM.SVGElementInstance.RemoveEventListener()");
SVGElementInstance* instance = V8DOMWrapper::convertDOMWrapperToNative<SVGElementInstance>(args.Holder());
- V8Proxy* proxy = V8Proxy::retrieve(instance->scriptExecutionContext());
- if (!proxy)
- return v8::Undefined();
-
- RefPtr<EventListener> listener = proxy->eventListeners()->findWrapper(args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(instance, args[1], false, ListenerFindOnly);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
instance->removeEventListener(type, listener.get(), useCapture);
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kNodeEventListenerCacheIndex);
}
return v8::Undefined();
diff --git a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
index 3766397..690eac1 100644
--- a/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SVGMatrixCustom.cpp
@@ -38,11 +38,27 @@
#include "V8Binding.h"
#include "V8CustomBinding.h"
+#include "V8SVGMatrix.h"
#include "V8SVGPODTypeWrapper.h"
#include "V8Proxy.h"
namespace WebCore {
+CALLBACK_FUNC_DECL(SVGMatrixMultiply)
+{
+ INC_STATS("DOM.SVGMatrix.multiply()");
+ if (args.Length() < 1)
+ return throwError("Not enough arguments");
+
+ if (!V8SVGMatrix::HasInstance(args[0]))
+ return throwError("secondMatrix argument was not a SVGMatrix");
+
+ TransformationMatrix m1 = *V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, args.Holder());
+ TransformationMatrix m2 = *V8DOMWrapper::convertToNativeObject<V8SVGPODTypeWrapper<TransformationMatrix> >(V8ClassIndex::SVGMATRIX, v8::Handle<v8::Object>::Cast(args[0]));
+
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::SVGMATRIX, V8SVGStaticPODTypeWrapper<TransformationMatrix>::create(m1.multLeft(m2)));
+}
+
CALLBACK_FUNC_DECL(SVGMatrixInverse)
{
INC_STATS("DOM.SVGMatrix.inverse()");
diff --git a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
index 3ab2f8e..de53ac7 100644
--- a/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
@@ -38,7 +38,6 @@
#include "Frame.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "WorkerContext.h"
@@ -53,12 +52,15 @@ CALLBACK_FUNC_DECL(SharedWorkerConstructor)
if (!args.IsConstructCall())
return throwError("DOM object constructor cannot be called as a function.");
- if (args.Length() < 2)
+ if (!args.Length())
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();
+ String name;
+ if (args.Length() > 1)
+ name = toWebCoreString(args[1]->ToString());
+
if (tryCatch.HasCaught())
return throwError(tryCatch.Exception());
@@ -66,28 +68,23 @@ CALLBACK_FUNC_DECL(SharedWorkerConstructor)
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.
+ ScriptExecutionContext* context = getScriptExecutionContext();
+ if (!context)
+ return v8::Undefined();
+
+ // Create the SharedWorker 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);
+ RefPtr<SharedWorker> obj = SharedWorker::create(toWebCoreString(scriptUrl), name, 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::SHAREDWORKER, obj.get());
+ V8DOMWrapper::setDOMWrapper(wrapperObject, V8ClassIndex::SHAREDWORKER, 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;
}
diff --git a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
index ecd0153..32a48eb 100644
--- a/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8StyleSheetListCustom.cpp
@@ -29,6 +29,7 @@
*/
#include "config.h"
+#include "HTMLStyleElement.h"
#include "StyleSheetList.h"
#include "V8Binding.h"
@@ -50,7 +51,7 @@ NAMED_PROPERTY_GETTER(StyleSheetList)
if (!item)
return notHandledByInterceptor();
- return V8DOMWrapper::convertToV8Object(V8ClassIndex::HTMLSTYLEELEMENT, item);
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::STYLESHEET, item->sheet());
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
new file mode 100644
index 0000000..16a1f51
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLArrayBufferConstructor)
+{
+ INC_STATS("DOM.WebGLArrayBuffer.Constructor");
+
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.");
+
+ // If we return a previously constructed WebGLArrayBuffer,
+ // e.g. from the call to WebGLArray.buffer, this code is called
+ // with a zero-length argument list. The V8DOMWrapper will then
+ // set the internal pointer in the newly-created object.
+ // Unfortunately it doesn't look like it's possible to distinguish
+ // between this case and that where the user calls "new
+ // WebGLArrayBuffer()" from JavaScript. To guard against problems,
+ // we always create at least a zero-length WebGLArrayBuffer, even
+ // if it is immediately overwritten by the V8DOMWrapper.
+
+ // Supported constructors:
+ // WebGLArrayBuffer(n) where n is an integer:
+ // -- create an empty buffer of n bytes
+
+ int argLen = args.Length();
+ if (argLen > 1)
+ return throwError("Wrong number of arguments specified to constructor (requires 1)");
+
+ int len = 0;
+ if (argLen > 0) {
+ if (!args[0]->IsInt32())
+ return throwError("Argument to WebGLArrayBuffer constructor was not an integer");
+ len = toInt32(args[0]);
+ }
+
+ RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len);
+ // Transform the holder into a wrapper object for the array.
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBGLARRAYBUFFER), buffer.get());
+ return toV8(buffer.release(), args.Holder());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
new file mode 100644
index 0000000..1a4b6a4
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
@@ -0,0 +1,220 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+// Template function used by the WebGLArray*Constructor callbacks.
+template<class ArrayClass>
+v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
+ int classIndex)
+{
+ if (!args.IsConstructCall())
+ return throwError("DOM object constructor cannot be called as a function.");
+
+ int argLen = args.Length();
+ if (argLen == 0) {
+ // This happens when we return a previously constructed
+ // WebGLArray, e.g. from the call to WebGL<T>Array.slice().
+ // The V8DOMWrapper will set the internal pointer in the
+ // created object. Unfortunately it doesn't look like it's
+ // possible to distinguish between this case and that where
+ // the user calls "new WebGL<T>Array()" from JavaScript.
+ return args.Holder();
+ }
+
+ // Supported constructors:
+ // WebGL<T>Array(n) where n is an integer:
+ // -- create an empty array of n elements
+ // WebGL<T>Array(arr) where arr is an array:
+ // -- create a WebGL<T>Array containing the contents of "arr"
+ // WebGL<T>Array(buf, offset, length)
+ // -- create a WebGL<T>Array pointing to the WebGLArrayBuffer
+ // "buf", starting at the specified offset, for the given
+ // length
+
+ // See whether the first argument is a WebGLArrayBuffer.
+ if (V8WebGLArrayBuffer::HasInstance(args[0])) {
+ if (argLen > 3)
+ return throwError("Wrong number of arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
+
+ WebGLArrayBuffer* buf =
+ V8DOMWrapper::convertToNativeObject<WebGLArrayBuffer>(V8ClassIndex::WEBGLARRAYBUFFER,
+ args[0]->ToObject());
+ if (buf == NULL)
+ return throwError("Could not convert argument 0 to a WebGLArrayBuffer");
+ bool ok;
+ int offset = 0;
+ if (argLen > 1) {
+ offset = toInt32(args[1], ok);
+ if (!ok)
+ return throwError("Could not convert argument 1 to an integer");
+ }
+ int length = buf->byteLength() - offset;
+ if (argLen > 2) {
+ length = toInt32(args[2], ok);
+ if (!ok)
+ return throwError("Could not convert argument 2 to an integer");
+ }
+ if (length < 0)
+ return throwError("Length / offset out of range");
+
+ RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length);
+ if (array == NULL)
+ return throwError("Invalid arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
+ // Transform the holder into a wrapper object for the array.
+ V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
+ V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
+ classIndex,
+ array.get()->baseAddress(),
+ array.get()->length());
+ return toV8(array.release(), args.Holder());
+ }
+
+ int len = 0;
+ v8::Handle<v8::Object> srcArray;
+ if (argLen != 1)
+ return throwError("Wrong number of arguments to new WebGL<T>Array(int / array)");
+
+ if (args[0]->IsInt32()) {
+ len = toInt32(args[0]);
+ } else if (args[0]->IsObject()) {
+ srcArray = args[0]->ToObject();
+ if (srcArray.IsEmpty())
+ return throwError("Could not convert argument 0 to an object");
+ len = toInt32(srcArray->Get(v8::String::New("length")));
+ } else
+ return throwError("Could not convert argument 0 to either an int32 or an object");
+
+ RefPtr<ArrayClass> array = ArrayClass::create(len);
+ if (!srcArray.IsEmpty()) {
+ // Need to copy the incoming array into the newly created WebGLArray.
+ for (int i = 0; i < len; i++) {
+ v8::Local<v8::Value> val = srcArray->Get(v8::Integer::New(i));
+ array->set(i, val->NumberValue());
+ }
+ }
+
+ // Transform the holder into a wrapper object for the array.
+ V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
+ V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
+ classIndex,
+ array.get()->baseAddress(),
+ array.get()->length());
+ return toV8(array.release(), args.Holder());
+}
+
+template <class T, typename ElementType>
+v8::Handle<v8::Value> getWebGLArrayElement(const v8::Arguments& args,
+ V8ClassIndex::V8WrapperType wrapperType)
+{
+ if (args.Length() != 1) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ bool ok;
+ uint32_t index = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ T* array = V8DOMWrapper::convertToNativeObject<T>(wrapperType, args.Holder());
+ if (index >= array->length())
+ return v8::Undefined();
+ ElementType result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+template <class T>
+v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments& args)
+{
+ if (args[0]->IsObject()) {
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ v8::Local<v8::Object> array = args[0]->ToObject();
+ uint32_t offset = 0;
+ if (args.Length() == 2)
+ offset = toInt32(args[1]);
+ uint32_t length = toInt32(array->Get(v8::String::New("length")));
+ for (uint32_t i = 0; i < length; i++) {
+ webGLArray->set(offset + i, array->Get(v8::Integer::New(i))->NumberValue());
+ }
+ }
+
+ return v8::Undefined();
+}
+
+template <class CPlusPlusArrayType, class JavaScriptWrapperArrayType>
+v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
+ V8ClassIndex::V8WrapperType wrapperType)
+{
+ if (args.Length() < 1 || args.Length() > 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ CPlusPlusArrayType* array = V8DOMWrapper::convertToNativeObject<CPlusPlusArrayType>(wrapperType, args.Holder());
+
+ if (args.Length() == 2 && args[0]->IsInt32()) {
+ // void set(in unsigned long index, in long value);
+ uint32_t index = toInt32(args[0]);
+ array->set(index, args[1]->NumberValue());
+ return v8::Undefined();
+ }
+
+ if (JavaScriptWrapperArrayType::HasInstance(args[0])) {
+ // void set(in WebGL<T>Array array, [Optional] in unsigned long offset);
+ CPlusPlusArrayType* src = V8DOMWrapper::convertToNativeObject<CPlusPlusArrayType>(wrapperType, args[0]->ToObject());
+ uint32_t offset = 0;
+ if (args.Length() == 2)
+ offset = toInt32(args[1]);
+ ExceptionCode ec = 0;
+ array->set(src, offset, ec);
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+
+ return setWebGLArrayFromArray(array, args);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
new file mode 100644
index 0000000..5719c8a
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLByteArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLByteArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLByteArrayConstructor)
+{
+ INC_STATS("DOM.WebGLByteArray.Contructor");
+
+ return constructWebGLArray<WebGLByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLBYTEARRAY));
+}
+
+// Get the specified value from the byte buffer and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid byte buffer range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLByteArray)
+{
+ INC_STATS("DOM.WebGLByteArray.IndexedPropertyGetter");
+ WebGLByteArray* byteBuffer = V8DOMWrapper::convertToNativeObject<WebGLByteArray>(V8ClassIndex::WEBGLBYTEARRAY, info.Holder());
+
+ if ((index < 0) || (index >= byteBuffer->length()))
+ return v8::Undefined();
+ signed char result;
+ if (!byteBuffer->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the byte buffer. Accesses outside the valid byte buffer range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLByteArray)
+{
+ INC_STATS("DOM.WebGLByteArray.IndexedPropertySetter");
+ WebGLByteArray* array = V8DOMWrapper::convertToNativeObject<WebGLByteArray>(V8ClassIndex::WEBGLBYTEARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length())) {
+ if (!value->IsNumber())
+ return throwError("Could not convert value argument to a number");
+ array->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLByteArrayGet)
+{
+ INC_STATS("DOM.WebGLByteArray.get()");
+ return getWebGLArrayElement<WebGLByteArray, signed char>(args, V8ClassIndex::WEBGLBYTEARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLByteArraySet)
+{
+ INC_STATS("DOM.WebGLByteArray.set()");
+ return setWebGLArray<WebGLByteArray, V8WebGLByteArray>(args, V8ClassIndex::WEBGLBYTEARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
new file mode 100644
index 0000000..6e56760
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLFloatArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLFloatArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLFloatArrayConstructor)
+{
+ INC_STATS("DOM.WebGLFloatArray.Contructor");
+
+ return constructWebGLArray<WebGLFloatArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLFLOATARRAY));
+}
+
+// Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLFloatArray)
+{
+ INC_STATS("DOM.WebGLFloatArray.IndexedPropertyGetter");
+ WebGLFloatArray* array = V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, info.Holder());
+
+ if ((index < 0) || (index >= array->length()))
+ return v8::Undefined();
+ float result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the array. Accesses outside the valid array range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLFloatArray)
+{
+ INC_STATS("DOM.WebGLFloatArray.IndexedPropertySetter");
+ WebGLFloatArray* array = V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length()))
+ array->set(index, value->NumberValue());
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLFloatArrayGet)
+{
+ INC_STATS("DOM.WebGLFloatArray.get()");
+ return getWebGLArrayElement<WebGLFloatArray, float>(args, V8ClassIndex::WEBGLFLOATARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLFloatArraySet)
+{
+ INC_STATS("DOM.WebGLFloatArray.set()");
+ return setWebGLArray<WebGLFloatArray, V8WebGLFloatArray>(args, V8ClassIndex::WEBGLFLOATARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
new file mode 100644
index 0000000..1bd30b2
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLIntArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLIntArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLIntArrayConstructor)
+{
+ INC_STATS("DOM.WebGLIntArray.Contructor");
+
+ return constructWebGLArray<WebGLIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLINTARRAY));
+}
+
+// Get the specified value from the integer array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLIntArray)
+{
+ INC_STATS("DOM.WebGLIntArray.IndexedPropertyGetter");
+ WebGLIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLIntArray>(V8ClassIndex::WEBGLINTARRAY, info.Holder());
+
+ if ((index < 0) || (index >= array->length()))
+ return v8::Undefined();
+ int result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the integer array. Accesses outside the valid integer array range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLIntArray)
+{
+ INC_STATS("DOM.WebGLIntArray.IndexedPropertySetter");
+ WebGLIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLIntArray>(V8ClassIndex::WEBGLINTARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length())) {
+ if (!value->IsNumber())
+ return throwError("Could not convert value argument to a number");
+ array->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLIntArrayGet)
+{
+ INC_STATS("DOM.WebGLIntArray.get()");
+ return getWebGLArrayElement<WebGLIntArray, int>(args, V8ClassIndex::WEBGLINTARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLIntArraySet)
+{
+ INC_STATS("DOM.WebGLIntArray.set()");
+ return setWebGLArray<WebGLIntArray, V8WebGLIntArray>(args, V8ClassIndex::WEBGLINTARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
new file mode 100644
index 0000000..fd73a5b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp
@@ -0,0 +1,928 @@
+/*
+ * 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 areV8ClassIndex::WEBGL
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS)
+
+#include "WebGLRenderingContext.h"
+
+#include "ExceptionCode.h"
+
+#include "NotImplemented.h"
+
+#include <wtf/FastMalloc.h>
+
+#include "V8Binding.h"
+#include "V8WebGLArray.h"
+#include "V8WebGLByteArray.h"
+#include "V8WebGLFloatArray.h"
+#include "V8WebGLIntArray.h"
+#include "V8WebGLProgram.h"
+#include "V8WebGLShader.h"
+#include "V8WebGLShortArray.h"
+#include "V8WebGLUniformLocation.h"
+#include "V8WebGLUnsignedByteArray.h"
+#include "V8WebGLUnsignedIntArray.h"
+#include "V8WebGLUnsignedShortArray.h"
+#include "V8HTMLCanvasElement.h"
+#include "V8HTMLImageElement.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+// Allocates new storage via tryFastMalloc.
+// Returns NULL if array failed to convert for any reason.
+static float* jsArrayToFloatArray(v8::Handle<v8::Array> array, uint32_t len)
+{
+ // Convert the data element-by-element.
+ float* data;
+ if (!tryFastMalloc(len * sizeof(float)).getValue(data))
+ return 0;
+ for (uint32_t i = 0; i < len; i++) {
+ v8::Local<v8::Value> val = array->Get(v8::Integer::New(i));
+ if (!val->IsNumber()) {
+ fastFree(data);
+ return 0;
+ }
+ data[i] = toFloat(val);
+ }
+ return data;
+}
+
+// Allocates new storage via tryFastMalloc.
+// Returns NULL if array failed to convert for any reason.
+static int* jsArrayToIntArray(v8::Handle<v8::Array> array, uint32_t len)
+{
+ // Convert the data element-by-element.
+ int* data;
+ if (!tryFastMalloc(len * sizeof(int)).getValue(data))
+ return 0;
+ for (uint32_t i = 0; i < len; i++) {
+ v8::Local<v8::Value> val = array->Get(v8::Integer::New(i));
+ bool ok;
+ int ival = toInt32(val, ok);
+ if (!ok) {
+ fastFree(data);
+ return 0;
+ }
+ data[i] = ival;
+ }
+ return data;
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextBufferData)
+{
+ INC_STATS("DOM.WebGLRenderingContext.bufferData()");
+
+ // Forms:
+ // * bufferData(GLenum target, WebGLArray data, GLenum usage);
+ // - Sets the buffer's data from the given WebGLArray
+ // * bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+ // - Sets the size of the buffer to the given size in bytes
+ if (args.Length() != 3) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok;
+ int target = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int usage = toInt32(args[2], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ if (args[1]->IsInt32()) {
+ int size = toInt32(args[1]);
+ ExceptionCode exceptionCode;
+ context->bufferData(target, size, usage, exceptionCode);
+ } else if (V8WebGLArray::HasInstance(args[1])) {
+ WebGLArray* array = V8DOMWrapper::convertToNativeObject<WebGLArray>(V8ClassIndex::WEBGLARRAY, args[1]->ToObject());
+ ExceptionCode exceptionCode;
+ context->bufferData(target, array, usage, exceptionCode);
+ } else {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextBufferSubData)
+{
+ INC_STATS("DOM.WebGLRenderingContext.bufferSubData()");
+
+ // Forms:
+ // * bufferSubData(GLenum target, GLintptr offset, WebGLArray data);
+ if (args.Length() != 3) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok;
+ int target = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int offset = toInt32(args[1], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ if (!V8WebGLArray::HasInstance(args[2])) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLArray* array = V8DOMWrapper::convertToNativeObject<WebGLArray>(V8ClassIndex::WEBGLARRAY, args[2]->ToObject());
+ ExceptionCode exceptionCode;
+ context->bufferSubData(target, offset, array, exceptionCode);
+ return v8::Undefined();
+}
+
+static v8::Handle<v8::Value> toV8(const WebGLGetInfo& info)
+{
+ switch (info.getType()) {
+ case WebGLGetInfo::kTypeBool:
+ return v8::Boolean::New(info.getBool());
+ case WebGLGetInfo::kTypeFloat:
+ return v8::Number::New(info.getFloat());
+ case WebGLGetInfo::kTypeLong:
+ return v8::Integer::New(info.getLong());
+ case WebGLGetInfo::kTypeNull:
+ return v8::Null();
+ case WebGLGetInfo::kTypeString:
+ return v8::String::New(fromWebCoreString(info.getString()), info.getString().length());
+ case WebGLGetInfo::kTypeUnsignedLong:
+ return v8::Integer::NewFromUnsigned(info.getUnsignedLong());
+ case WebGLGetInfo::kTypeWebGLBuffer:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLBUFFER, info.getWebGLBuffer());
+ case WebGLGetInfo::kTypeWebGLFloatArray:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLFLOATARRAY, info.getWebGLFloatArray());
+ case WebGLGetInfo::kTypeWebGLFramebuffer:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLFRAMEBUFFER, info.getWebGLFramebuffer());
+ case WebGLGetInfo::kTypeWebGLIntArray:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLINTARRAY, info.getWebGLIntArray());
+ // FIXME: implement WebGLObjectArray
+ // case WebGLGetInfo::kTypeWebGLObjectArray:
+ case WebGLGetInfo::kTypeWebGLProgram:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLPROGRAM, info.getWebGLProgram());
+ case WebGLGetInfo::kTypeWebGLRenderbuffer:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLRENDERBUFFER, info.getWebGLRenderbuffer());
+ case WebGLGetInfo::kTypeWebGLTexture:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLTEXTURE, info.getWebGLTexture());
+ case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
+ return V8DOMWrapper::convertToV8Object(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY, info.getWebGLUnsignedByteArray());
+ default:
+ notImplemented();
+ return v8::Undefined();
+ }
+}
+
+enum ObjectType {
+ kBuffer, kRenderbuffer, kTexture, kVertexAttrib
+};
+
+static v8::Handle<v8::Value> getObjectParameter(const v8::Arguments& args, ObjectType objectType)
+{
+ if (args.Length() != 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok;
+ unsigned target = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ unsigned pname = toInt32(args[1], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLGetInfo info;
+ switch (objectType) {
+ case kBuffer:
+ info = context->getBufferParameter(target, pname, ec);
+ break;
+ case kRenderbuffer:
+ info = context->getRenderbufferParameter(target, pname, ec);
+ break;
+ case kTexture:
+ info = context->getTexParameter(target, pname, ec);
+ break;
+ case kVertexAttrib:
+ // target => index
+ info = context->getVertexAttrib(target, pname, ec);
+ break;
+ default:
+ notImplemented();
+ break;
+ }
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+ return toV8(info);
+}
+
+static WebGLUniformLocation* toWebGLUniformLocation(v8::Handle<v8::Value> value, bool& ok)
+{
+ ok = false;
+ WebGLUniformLocation* location = 0;
+ if (V8WebGLUniformLocation::HasInstance(value)) {
+ location = V8DOMWrapper::convertToNativeObject<WebGLUniformLocation>(
+ V8ClassIndex::WEBGLUNIFORMLOCATION, value->ToObject());
+ ok = true;
+ }
+ return location;
+}
+
+enum WhichProgramCall {
+ kProgramParameter, kUniform
+};
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetBufferParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getBufferParameter()");
+ return getObjectParameter(args, kBuffer);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetFramebufferAttachmentParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getFramebufferAttachmentParameter()");
+
+ if (args.Length() != 3) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok;
+ unsigned target = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ unsigned attachment = toInt32(args[1], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ unsigned pname = toInt32(args[2], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec);
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+ return toV8(info);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getParameter()");
+
+ if (args.Length() != 1) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok;
+ unsigned pname = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLGetInfo info = context->getParameter(pname, ec);
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+ return toV8(info);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetProgramParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getProgramParameter()");
+
+ if (args.Length() != 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? v8DOMWrapperTo<WebGLProgram>(V8ClassIndex::WEBGLPROGRAM, v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ bool ok;
+ unsigned pname = toInt32(args[1], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLGetInfo info = context->getProgramParameter(program, pname, ec);
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+ return toV8(info);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetRenderbufferParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getRenderbufferParameter()");
+ return getObjectParameter(args, kRenderbuffer);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetShaderParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getShaderParameter()");
+
+ if (args.Length() != 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? v8DOMWrapperTo<WebGLShader>(V8ClassIndex::WEBGLSHADER, v8::Handle<v8::Object>::Cast(args[0])) : 0;
+ bool ok;
+ unsigned pname = toInt32(args[1], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+ return toV8(info);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetTexParameter)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getTexParameter()");
+ return getObjectParameter(args, kTexture);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetUniform)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getUniform()");
+
+ if (args.Length() != 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? v8DOMWrapperTo<WebGLProgram>(V8ClassIndex::WEBGLPROGRAM, v8::Handle<v8::Object>::Cast(args[0])) : 0;
+
+ bool ok = false;
+ WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok);
+
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ WebGLGetInfo info = context->getUniform(program, location, ec);
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+ return toV8(info);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextGetVertexAttrib)
+{
+ INC_STATS("DOM.WebGLRenderingContext.getVertexAttrib()");
+ return getObjectParameter(args, kVertexAttrib);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextTexImage2D)
+{
+ INC_STATS("DOM.WebGLRenderingContext.texImage2D()");
+
+ // Currently supported forms:
+ // * void texImage2D(in GLenum target, in GLint level,
+ // in GLint internalformat,
+ // in GLsizei width, in GLsizei height, in GLint border,
+ // in GLenum format, in GLenum type, in WebGLArray pixels);
+ // * void texImage2D(in GLenum target, in GLint level, in HTMLImageElement image,
+ // [Optional] in GLboolean flipY, [Optional] in GLboolean premultiplyAlpha);
+ // * void texImage2D(in GLenum target, in GLint level, in HTMLCanvasElement image,
+ // [Optional] in GLboolean flipY, [Optional] in GLboolean premultiplyAlpha);
+ if (args.Length() != 3 &&
+ args.Length() != 4 &&
+ args.Length() != 5 &&
+ args.Length() != 9) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok;
+ int target = toInt32(args[0], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int level = toInt32(args[1], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ ExceptionCode ec = 0;
+ if (args.Length() == 3 ||
+ args.Length() == 4 ||
+ args.Length() == 5) {
+ v8::Handle<v8::Value> arg = args[2];
+ bool flipY = false;
+ bool premultiplyAlpha = false;
+ if (args.Length() >= 4)
+ flipY = args[3]->BooleanValue();
+ if (args.Length() >= 5)
+ premultiplyAlpha = args[4]->BooleanValue();
+ if (V8HTMLImageElement::HasInstance(arg)) {
+ HTMLImageElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLImageElement>(v8::Handle<v8::Object>::Cast(arg));
+ context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec);
+ } else if (V8HTMLCanvasElement::HasInstance(arg)) {
+ HTMLCanvasElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLCanvasElement>(v8::Handle<v8::Object>::Cast(arg));
+ context->texImage2D(target, level, element, flipY, premultiplyAlpha, ec);
+ } else {
+ // FIXME: support HTMLVideoElement and ImageData.
+ // FIXME: consider different / better exception type.
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ // Fall through
+ } else if (args.Length() == 9) {
+ int internalformat = toInt32(args[2], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int width = toInt32(args[3], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int height = toInt32(args[4], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int border = toInt32(args[5], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int format = toInt32(args[6], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ int type = toInt32(args[7], ok);
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ v8::Handle<v8::Value> arg = args[8];
+ if (V8WebGLArray::HasInstance(arg)) {
+ WebGLArray* array = V8DOMWrapper::convertToNativeObject<WebGLArray>(V8ClassIndex::WEBGLARRAY, arg->ToObject());
+ // FIXME: must do validation similar to JOGL's to ensure that
+ // the incoming array is of the appropriate length and type
+ context->texImage2D(target,
+ level,
+ internalformat,
+ width,
+ height,
+ border,
+ format,
+ type,
+ array,
+ ec);
+ // Fall through
+ } else {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ } else {
+ ASSERT_NOT_REACHED();
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ if (ec) {
+ V8Proxy::setDOMException(ec);
+ return v8::Handle<v8::Value>();
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextTexSubImage2D)
+{
+ INC_STATS("DOM.WebGLRenderingContext.texSubImage2D()");
+
+ // FIXME: implement
+ notImplemented();
+
+ return v8::Undefined();
+}
+
+enum FunctionToCall {
+ kUniform1v, kUniform2v, kUniform3v, kUniform4v,
+ kVertexAttrib1v, kVertexAttrib2v, kVertexAttrib3v, kVertexAttrib4v
+};
+
+bool isFunctionToCallForAttribute(FunctionToCall functionToCall)
+{
+ switch (functionToCall) {
+ case kVertexAttrib1v:
+ case kVertexAttrib2v:
+ case kVertexAttrib3v:
+ case kVertexAttrib4v:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments& args,
+ FunctionToCall functionToCall) {
+ // Forms:
+ // * glUniform1fv(WebGLUniformLocation location, Array data);
+ // * glUniform1fv(WebGLUniformLocation location, WebGLFloatArray data);
+ // * glUniform2fv(WebGLUniformLocation location, Array data);
+ // * glUniform2fv(WebGLUniformLocation location, WebGLFloatArray data);
+ // * glUniform3fv(WebGLUniformLocation location, Array data);
+ // * glUniform3fv(WebGLUniformLocation location, WebGLFloatArray data);
+ // * glUniform4fv(WebGLUniformLocation location, Array data);
+ // * glUniform4fv(WebGLUniformLocation location, WebGLFloatArray data);
+ // * glVertexAttrib1fv(GLint index, Array data);
+ // * glVertexAttrib1fv(GLint index, WebGLFloatArray data);
+ // * glVertexAttrib2fv(GLint index, Array data);
+ // * glVertexAttrib2fv(GLint index, WebGLFloatArray data);
+ // * glVertexAttrib3fv(GLint index, Array data);
+ // * glVertexAttrib3fv(GLint index, WebGLFloatArray data);
+ // * glVertexAttrib4fv(GLint index, Array data);
+ // * glVertexAttrib4fv(GLint index, WebGLFloatArray data);
+
+ if (args.Length() != 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ bool ok = false;
+ int index = -1;
+ WebGLUniformLocation* location = 0;
+
+ if (isFunctionToCallForAttribute(functionToCall))
+ index = toInt32(args[0], ok);
+ else
+ location = toWebGLUniformLocation(args[0], ok);
+
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ if (V8WebGLFloatArray::HasInstance(args[1])) {
+ WebGLFloatArray* array =
+ V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, args[1]->ToObject());
+ ASSERT(array != NULL);
+ ExceptionCode ec = 0;
+ switch (functionToCall) {
+ case kUniform1v: context->uniform1fv(location, array, ec); break;
+ case kUniform2v: context->uniform2fv(location, array, ec); break;
+ case kUniform3v: context->uniform3fv(location, array, ec); break;
+ case kUniform4v: context->uniform4fv(location, array, ec); break;
+ case kVertexAttrib1v: context->vertexAttrib1fv(index, array); break;
+ case kVertexAttrib2v: context->vertexAttrib2fv(index, array); break;
+ case kVertexAttrib3v: context->vertexAttrib3fv(index, array); break;
+ case kVertexAttrib4v: context->vertexAttrib4fv(index, array); break;
+ default: ASSERT_NOT_REACHED(); break;
+ }
+ if (ec)
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+
+ v8::Handle<v8::Array> array =
+ v8::Local<v8::Array>::Cast(args[1]);
+ if (array.IsEmpty()) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ uint32_t len = array->Length();
+ float* data = jsArrayToFloatArray(array, len);
+ if (!data) {
+ // FIXME: consider different / better exception type.
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ ExceptionCode ec = 0;
+ switch (functionToCall) {
+ case kUniform1v: context->uniform1fv(location, data, len, ec); break;
+ case kUniform2v: context->uniform2fv(location, data, len, ec); break;
+ case kUniform3v: context->uniform3fv(location, data, len, ec); break;
+ case kUniform4v: context->uniform4fv(location, data, len, ec); break;
+ case kVertexAttrib1v: context->vertexAttrib1fv(index, data, len); break;
+ case kVertexAttrib2v: context->vertexAttrib2fv(index, data, len); break;
+ case kVertexAttrib3v: context->vertexAttrib3fv(index, data, len); break;
+ case kVertexAttrib4v: context->vertexAttrib4fv(index, data, len); break;
+ default: ASSERT_NOT_REACHED(); break;
+ }
+ fastFree(data);
+ if (ec)
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+}
+
+static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
+ FunctionToCall functionToCall) {
+ // Forms:
+ // * glUniform1iv(GLUniformLocation location, Array data);
+ // * glUniform1iv(GLUniformLocation location, WebGLIntArray data);
+ // * glUniform2iv(GLUniformLocation location, Array data);
+ // * glUniform2iv(GLUniformLocation location, WebGLIntArray data);
+ // * glUniform3iv(GLUniformLocation location, Array data);
+ // * glUniform3iv(GLUniformLocation location, WebGLIntArray data);
+ // * glUniform4iv(GLUniformLocation location, Array data);
+ // * glUniform4iv(GLUniformLocation location, WebGLIntArray data);
+
+ if (args.Length() != 2) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+ bool ok = false;
+ WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
+
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ if (V8WebGLIntArray::HasInstance(args[1])) {
+ WebGLIntArray* array =
+ V8DOMWrapper::convertToNativeObject<WebGLIntArray>(V8ClassIndex::WEBGLINTARRAY, args[1]->ToObject());
+ ASSERT(array != NULL);
+ ExceptionCode ec = 0;
+ switch (functionToCall) {
+ case kUniform1v: context->uniform1iv(location, array, ec); break;
+ case kUniform2v: context->uniform2iv(location, array, ec); break;
+ case kUniform3v: context->uniform3iv(location, array, ec); break;
+ case kUniform4v: context->uniform4iv(location, array, ec); break;
+ default: ASSERT_NOT_REACHED(); break;
+ }
+ if (ec)
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+
+ v8::Handle<v8::Array> array =
+ v8::Local<v8::Array>::Cast(args[1]);
+ if (array.IsEmpty()) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ uint32_t len = array->Length();
+ int* data = jsArrayToIntArray(array, len);
+ if (!data) {
+ // FIXME: consider different / better exception type.
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ ExceptionCode ec = 0;
+ switch (functionToCall) {
+ case kUniform1v: context->uniform1iv(location, data, len, ec); break;
+ case kUniform2v: context->uniform2iv(location, data, len, ec); break;
+ case kUniform3v: context->uniform3iv(location, data, len, ec); break;
+ case kUniform4v: context->uniform4iv(location, data, len, ec); break;
+ default: ASSERT_NOT_REACHED(); break;
+ }
+ fastFree(data);
+ if (ec)
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform1fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform1fv()");
+ return vertexAttribAndUniformHelperf(args, kUniform1v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform1iv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform1iv()");
+ return uniformHelperi(args, kUniform1v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform2fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform2fv()");
+ return vertexAttribAndUniformHelperf(args, kUniform2v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform2iv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform2iv()");
+ return uniformHelperi(args, kUniform2v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform3fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform3fv()");
+ return vertexAttribAndUniformHelperf(args, kUniform3v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform3iv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform3iv()");
+ return uniformHelperi(args, kUniform3v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform4fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform4fv()");
+ return vertexAttribAndUniformHelperf(args, kUniform4v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniform4iv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniform4iv()");
+ return uniformHelperi(args, kUniform4v);
+}
+
+static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
+ int matrixSize)
+{
+ // Forms:
+ // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
+ // * glUniformMatrix2fv(GLint location, GLboolean transpose, WebGLFloatArray data);
+ // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
+ // * glUniformMatrix3fv(GLint location, GLboolean transpose, WebGLFloatArray data);
+ // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
+ // * glUniformMatrix4fv(GLint location, GLboolean transpose, WebGLFloatArray data);
+ //
+ // FIXME: need to change to accept WebGLFloatArray as well.
+ if (args.Length() != 3) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+
+ WebGLRenderingContext* context =
+ V8DOMWrapper::convertDOMWrapperToNative<WebGLRenderingContext>(args.Holder());
+
+ bool ok = false;
+ WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
+
+ if (!ok) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ bool transpose = args[1]->BooleanValue();
+ if (V8WebGLFloatArray::HasInstance(args[2])) {
+ WebGLFloatArray* array =
+ V8DOMWrapper::convertToNativeObject<WebGLFloatArray>(V8ClassIndex::WEBGLFLOATARRAY, args[2]->ToObject());
+ ASSERT(array != NULL);
+ ExceptionCode ec = 0;
+ switch (matrixSize) {
+ case 2: context->uniformMatrix2fv(location, transpose, array, ec); break;
+ case 3: context->uniformMatrix3fv(location, transpose, array, ec); break;
+ case 4: context->uniformMatrix4fv(location, transpose, array, ec); break;
+ default: ASSERT_NOT_REACHED(); break;
+ }
+ if (ec)
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+ }
+
+ v8::Handle<v8::Array> array =
+ v8::Local<v8::Array>::Cast(args[2]);
+ if (array.IsEmpty()) {
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ uint32_t len = array->Length();
+ float* data = jsArrayToFloatArray(array, len);
+ if (!data) {
+ // FIXME: consider different / better exception type.
+ V8Proxy::setDOMException(SYNTAX_ERR);
+ return notHandledByInterceptor();
+ }
+ ExceptionCode ec = 0;
+ switch (matrixSize) {
+ case 2: context->uniformMatrix2fv(location, transpose, data, len, ec); break;
+ case 3: context->uniformMatrix3fv(location, transpose, data, len, ec); break;
+ case 4: context->uniformMatrix4fv(location, transpose, data, len, ec); break;
+ default: ASSERT_NOT_REACHED(); break;
+ }
+ fastFree(data);
+ if (ec)
+ V8Proxy::setDOMException(ec);
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniformMatrix2fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniformMatrix2fv()");
+ return uniformMatrixHelper(args, 2);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniformMatrix3fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniformMatrix3fv()");
+ return uniformMatrixHelper(args, 3);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextUniformMatrix4fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.uniformMatrix4fv()");
+ return uniformMatrixHelper(args, 4);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib1fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.vertexAttrib1fv()");
+ return vertexAttribAndUniformHelperf(args, kVertexAttrib1v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib2fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.vertexAttrib2fv()");
+ return vertexAttribAndUniformHelperf(args, kVertexAttrib2v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib3fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.vertexAttrib3fv()");
+ return vertexAttribAndUniformHelperf(args, kVertexAttrib3v);
+}
+
+CALLBACK_FUNC_DECL(WebGLRenderingContextVertexAttrib4fv)
+{
+ INC_STATS("DOM.WebGLRenderingContext.vertexAttrib4fv()");
+ return vertexAttribAndUniformHelperf(args, kVertexAttrib4v);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
new file mode 100644
index 0000000..f8a26c3
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLShortArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLShortArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLShortArrayConstructor)
+{
+ INC_STATS("DOM.WebGLShortArray.Contructor");
+
+ return constructWebGLArray<WebGLShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLSHORTARRAY));
+}
+
+// Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLShortArray)
+{
+ INC_STATS("DOM.WebGLShortArray.IndexedPropertyGetter");
+ WebGLShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLShortArray>(V8ClassIndex::WEBGLSHORTARRAY, info.Holder());
+
+ if ((index < 0) || (index >= array->length()))
+ return v8::Undefined();
+ short result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the array. Accesses outside the valid array range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLShortArray)
+{
+ INC_STATS("DOM.WebGLShortArray.IndexedPropertySetter");
+ WebGLShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLShortArray>(V8ClassIndex::WEBGLSHORTARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length())) {
+ if (!value->IsNumber())
+ return throwError("Could not convert value argument to a number");
+ array->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLShortArrayGet)
+{
+ INC_STATS("DOM.WebGLShortArray.get()");
+ return getWebGLArrayElement<WebGLShortArray, short>(args, V8ClassIndex::WEBGLSHORTARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLShortArraySet)
+{
+ INC_STATS("DOM.WebGLShortArray.set()");
+ return setWebGLArray<WebGLShortArray, V8WebGLShortArray>(args, V8ClassIndex::WEBGLSHORTARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
new file mode 100644
index 0000000..391f213
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLUnsignedByteArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLUnsignedByteArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLUnsignedByteArrayConstructor)
+{
+ INC_STATS("DOM.WebGLUnsignedByteArray.Contructor");
+
+ return constructWebGLArray<WebGLUnsignedByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY));
+}
+
+// Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLUnsignedByteArray)
+{
+ INC_STATS("DOM.WebGLUnsignedByteArray.IndexedPropertyGetter");
+ WebGLUnsignedByteArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedByteArray>(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY, info.Holder());
+
+ if ((index < 0) || (index >= array->length()))
+ return v8::Undefined();
+ unsigned char result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the array. Accesses outside the valid array range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLUnsignedByteArray)
+{
+ INC_STATS("DOM.WebGLUnsignedByteArray.IndexedPropertySetter");
+ WebGLUnsignedByteArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedByteArray>(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length())) {
+ if (!value->IsNumber())
+ return throwError("Could not convert value argument to a number");
+ array->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLUnsignedByteArrayGet)
+{
+ INC_STATS("DOM.WebGLUnsignedByteArray.get()");
+ return getWebGLArrayElement<WebGLUnsignedByteArray, unsigned char>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLUnsignedByteArraySet)
+{
+ INC_STATS("DOM.WebGLUnsignedByteArray.set()");
+ return setWebGLArray<WebGLUnsignedByteArray, V8WebGLUnsignedByteArray>(args, V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
new file mode 100644
index 0000000..92b9fe0
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLUnsignedIntArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLUnsignedIntArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLUnsignedIntArrayConstructor)
+{
+ INC_STATS("DOM.WebGLUnsignedIntArray.Contructor");
+
+ return constructWebGLArray<WebGLUnsignedIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDINTARRAY));
+}
+
+// Get the specified value from the integer array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid pixel buffer range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLUnsignedIntArray)
+{
+ INC_STATS("DOM.WebGLUnsignedIntArray.IndexedPropertyGetter");
+ WebGLUnsignedIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedIntArray>(V8ClassIndex::WEBGLUNSIGNEDINTARRAY, info.Holder());
+
+ if ((index < 0) || (index >= array->length()))
+ return v8::Undefined();
+ unsigned int result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the integer array. Accesses outside the valid integer array range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLUnsignedIntArray)
+{
+ INC_STATS("DOM.WebGLUnsignedIntArray.IndexedPropertySetter");
+ WebGLUnsignedIntArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedIntArray>(V8ClassIndex::WEBGLUNSIGNEDINTARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length())) {
+ if (!value->IsNumber())
+ return throwError("Could not convert value argument to a number");
+ array->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLUnsignedIntArrayGet)
+{
+ INC_STATS("DOM.WebGLUnsignedIntArray.get()");
+ return getWebGLArrayElement<WebGLUnsignedIntArray, unsigned int>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLUnsignedIntArraySet)
+{
+ INC_STATS("DOM.WebGLUnsignedIntArray.set()");
+ return setWebGLArray<WebGLUnsignedIntArray, V8WebGLUnsignedIntArray>(args, V8ClassIndex::WEBGLUNSIGNEDINTARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
new file mode 100644
index 0000000..ce261e9
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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(3D_CANVAS)
+
+#include "WebGLArrayBuffer.h"
+#include "WebGLUnsignedShortArray.h"
+
+#include "V8Binding.h"
+#include "V8WebGLArrayBuffer.h"
+#include "V8WebGLArrayCustom.h"
+#include "V8WebGLUnsignedShortArray.h"
+#include "V8CustomBinding.h"
+#include "V8Proxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebGLUnsignedShortArrayConstructor)
+{
+ INC_STATS("DOM.WebGLUnsignedShortArray.Contructor");
+
+ return constructWebGLArray<WebGLUnsignedShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY));
+}
+
+// Get the specified value from the array and return it wrapped as a JavaScript Number object to V8. Accesses outside the valid array range return "undefined".
+INDEXED_PROPERTY_GETTER(WebGLUnsignedShortArray)
+{
+ INC_STATS("DOM.WebGLUnsignedShortArray.IndexedPropertyGetter");
+ WebGLUnsignedShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedShortArray>(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY, info.Holder());
+
+ if ((index < 0) || (index >= array->length()))
+ return v8::Undefined();
+ unsigned short result;
+ if (!array->get(index, result))
+ return v8::Undefined();
+ return v8::Number::New(result);
+}
+
+// Set the specified value in the array. Accesses outside the valid array range are silently ignored.
+INDEXED_PROPERTY_SETTER(WebGLUnsignedShortArray)
+{
+ INC_STATS("DOM.WebGLUnsignedShortArray.IndexedPropertySetter");
+ WebGLUnsignedShortArray* array = V8DOMWrapper::convertToNativeObject<WebGLUnsignedShortArray>(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY, info.Holder());
+
+ if ((index >= 0) && (index < array->length())) {
+ if (!value->IsNumber())
+ return throwError("Could not convert value argument to a number");
+ array->set(index, value->NumberValue());
+ }
+ return value;
+}
+
+CALLBACK_FUNC_DECL(WebGLUnsignedShortArrayGet)
+{
+ INC_STATS("DOM.WebGLUnsignedShortArray.get()");
+ return getWebGLArrayElement<WebGLUnsignedShortArray, unsigned short>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY);
+}
+
+CALLBACK_FUNC_DECL(WebGLUnsignedShortArraySet)
+{
+ INC_STATS("DOM.WebGLUnsignedShortArray.set()");
+ return setWebGLArray<WebGLUnsignedShortArray, V8WebGLUnsignedShortArray>(args, V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
index dd19a88..b2a807d 100755
--- a/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8WebKitPointConstructor.cpp
@@ -30,17 +30,38 @@
#include "config.h"
+#include "V8Binding.h"
#include "V8CustomBinding.h"
+#include "V8DOMWrapper.h"
#include "V8Index.h"
#include "V8Proxy.h"
#include "WebKitPoint.h"
+#include <wtf/MathExtras.h>
+
namespace WebCore {
CALLBACK_FUNC_DECL(WebKitPointConstructor)
{
INC_STATS("DOM.WebKitPoint.Constructor");
- return V8Proxy::constructDOMObject<V8ClassIndex::WEBKITPOINT, WebKitPoint>(args);
+ float x = 0;
+ float y = 0;
+ if (args.Length() > 1) {
+ if (!args[0]->IsUndefined()) {
+ x = toFloat(args[0]);
+ if (isnan(x))
+ x = 0;
+ }
+ if (!args[1]->IsUndefined()) {
+ y = toFloat(args[1]);
+ if (isnan(y))
+ y = 0;
+ }
+ }
+ PassRefPtr<WebKitPoint> point = WebKitPoint::create(x, y);
+ point->ref();
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::WEBKITPOINT, point.get());
+ return args.Holder();
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
new file mode 100644
index 0000000..b20635b
--- /dev/null
+++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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 "WebSocket.h"
+
+#include "Frame.h"
+#include "Settings.h"
+#include "V8Binding.h"
+#include "V8Proxy.h"
+#include "V8Utilities.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WebSocketAddEventListener)
+{
+ INC_STATS("DOM.WebSocket.addEventListener()");
+ WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder());
+
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOrCreate);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ webSocket->addEventListener(type, listener, useCapture);
+
+ createHiddenDependency(args.Holder(), args[1], V8Custom::kWebSocketCacheIndex);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WebSocketRemoveEventListener)
+{
+ INC_STATS("DOM.WebSocket.removeEventListener()");
+ WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder());
+
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(webSocket, args[1], false, ListenerFindOnly);
+ if (listener) {
+ String type = toWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ webSocket->removeEventListener(type, listener.get(), useCapture);
+ removeHiddenDependency(args.Holder(), args[1], V8Custom::kWebSocketCacheIndex);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WebSocketConstructor)
+{
+ INC_STATS("DOM.WebSocket.Constructor");
+
+ if (!args.IsConstructCall())
+ return throwError("DOM object custructor cannot be called as a function.");
+ if (args.Length() == 0)
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
+
+ v8::TryCatch tryCatch;
+ v8::Handle<v8::String> urlstring = args[0]->ToString();
+ if (tryCatch.HasCaught())
+ return throwError(tryCatch.Exception());
+ if (urlstring.IsEmpty())
+ return throwError("Empty URL", V8Proxy::SyntaxError);
+
+ // Get the script execution context.
+ ScriptExecutionContext* context = 0;
+ // TODO: Workers
+ if (!context) {
+ Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+ if (!frame)
+ return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError);
+ context = frame->document();
+ }
+
+ const KURL& url = context->completeURL(toWebCoreString(urlstring));
+
+ RefPtr<WebSocket> webSocket = WebSocket::create(context);
+ ExceptionCode ec = 0;
+
+ if (args.Length() < 2)
+ webSocket->connect(url, ec);
+ else {
+ v8::TryCatch tryCatchProtocol;
+ v8::Handle<v8::String> protocol = args[1]->ToString();
+ if (tryCatchProtocol.HasCaught())
+ return throwError(tryCatchProtocol.Exception());
+ webSocket->connect(url, toWebCoreString(protocol), ec);
+ }
+ if (ec)
+ return throwError(ec);
+
+ // Setup the standard wrapper object internal fields.
+ V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBSOCKET), webSocket.get());
+
+ // Add object to the wrapper map.
+ webSocket->ref();
+ V8DOMWrapper::setJSWrapperForActiveDOMObject(webSocket.get(), v8::Persistent<v8::Object>::New(args.Holder()));
+
+ return args.Holder();
+}
+
+CALLBACK_FUNC_DECL(WebSocketSend)
+{
+ INC_STATS("DOM.WebSocket.send()");
+ WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder());
+
+ ExceptionCode ec = 0;
+ bool ret = false;
+ if (args.Length() < 1)
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
+ else {
+ String msg = toWebCoreString(args[0]);
+ ret = webSocket->send(msg, ec);
+ }
+ if (ec)
+ return throwError(ec);
+ return v8Boolean(ret);
+}
+
+CALLBACK_FUNC_DECL(WebSocketClose)
+{
+ INC_STATS("DOM.WebSocket.close()");
+ WebSocket* webSocket = V8DOMWrapper::convertToNativeObject<WebSocket>(V8ClassIndex::WEBSOCKET, args.Holder());
+
+ webSocket->close();
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
index b526040..9b68ac0 100755
--- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
@@ -34,6 +34,7 @@
#include "DOMTimer.h"
#include "ExceptionCode.h"
+#include "RuntimeEnabledFeatures.h"
#include "ScheduledAction.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
@@ -45,6 +46,13 @@
namespace WebCore {
+#if ENABLE(NOTIFICATIONS)
+ACCESSOR_RUNTIME_ENABLER(WorkerContextWebkitNotifications)
+{
+ return RuntimeEnabledFeatures::notificationsEnabled();
+}
+#endif
+
ACCESSOR_GETTER(WorkerContextSelf)
{
INC_STATS(L"DOM.WorkerContext.self._get");
@@ -52,45 +60,6 @@ ACCESSOR_GETTER(WorkerContextSelf)
return WorkerContextExecutionProxy::convertWorkerContextToV8Object(workerContext);
}
-ACCESSOR_GETTER(WorkerContextOnerror)
-{
- 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(WorkerContextOnerror)
-{
- 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->onerror()) {
- v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
- removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerContextRequestCacheIndex);
- }
-
- // Clear the listener.
- workerContext->setOnerror(0);
- } else {
- 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->setOnerror(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kWorkerContextRequestCacheIndex);
- }
- }
-}
-
v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singleShot)
{
WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
@@ -103,9 +72,10 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl
int32_t timeout = argumentCount >= 2 ? args[1]->Int32Value() : 0;
int timerId;
+ v8::Handle<v8::Context> v8Context = workerContext->script()->proxy()->context();
if (function->IsString()) {
WebCore::String stringFunction = toWebCoreString(function);
- timerId = DOMTimer::install(workerContext, new ScheduledAction(stringFunction, workerContext->url()), timeout, singleShot);
+ timerId = DOMTimer::install(workerContext, new ScheduledAction(v8Context, stringFunction, workerContext->url()), timeout, singleShot);
} else if (function->IsFunction()) {
size_t paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
v8::Local<v8::Value>* params = 0;
@@ -115,7 +85,7 @@ v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singl
params[i] = args[i+2];
}
// ScheduledAction takes ownership of actual params and releases them in its destructor.
- ScheduledAction* action = new ScheduledAction(v8::Handle<v8::Function>::Cast(function), paramCount, params);
+ ScheduledAction* action = new ScheduledAction(v8Context, v8::Handle<v8::Function>::Cast(function), paramCount, params);
delete [] params;
timerId = DOMTimer::install(workerContext, action, timeout, singleShot);
} else
@@ -130,8 +100,13 @@ CALLBACK_FUNC_DECL(WorkerContextImportScripts)
if (!args.Length())
return v8::Undefined();
- String callerURL = V8Proxy::sourceName();
- int callerLine = V8Proxy::sourceLineNumber() + 1;
+ String callerURL;
+ if (!V8Proxy::sourceName(callerURL))
+ return v8::Undefined();
+ int callerLine;
+ if (!V8Proxy::sourceLineNumber(callerLine))
+ return v8::Undefined();
+ callerLine += 1;
Vector<String> urls;
for (int i = 0; i < args.Length(); i++) {
@@ -170,8 +145,7 @@ CALLBACK_FUNC_DECL(WorkerContextAddEventListener)
INC_STATS(L"DOM.WorkerContext.addEventListener()");
WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());
- RefPtr<V8EventListener> listener = workerContext->script()->proxy()->findOrCreateEventListener(v8::Local<v8::Object>::Cast(args[1]), false, false);
-
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -186,10 +160,8 @@ CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener)
{
INC_STATS(L"DOM.WorkerContext.removeEventListener()");
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);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOnly);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -197,7 +169,6 @@ CALLBACK_FUNC_DECL(WorkerContextRemoveEventListener)
removeHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerContextRequestCacheIndex);
}
-
return v8::Undefined();
}
diff --git a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
index 32450b8..454e41f 100755
--- a/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerCustom.cpp
@@ -36,9 +36,10 @@
#include "ExceptionCode.h"
#include "Frame.h"
+#include "SerializedScriptValue.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
+#include "V8MessagePortCustom.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "WorkerContext.h"
@@ -65,16 +66,9 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
return v8::Undefined();
// Get the script execution context.
- 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();
- }
+ ScriptExecutionContext* context = getScriptExecutionContext();
+ if (!context)
+ return v8::Undefined();
// 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.
@@ -93,60 +87,19 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
return wrapperObject;
}
-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, 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(WorkerOnmessage)
-{
- INC_STATS(L"DOM.Worker.onmessage._get");
- 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();
- return v8Listener;
- }
- return v8::Undefined();
-}
-
-ACCESSOR_SETTER(WorkerOnmessage)
+CALLBACK_FUNC_DECL(WorkerPostMessage)
{
- INC_STATS(L"DOM.Worker.onmessage._set");
- Worker* worker = V8DOMWrapper::convertToNativeObject<Worker>(V8ClassIndex::WORKER, info.Holder());
- V8ObjectEventListener* oldListener = static_cast<V8ObjectEventListener*>(worker->onmessage());
- if (value->IsNull()) {
- if (oldListener) {
- v8::Local<v8::Object> oldV8Listener = oldListener->getListenerObject();
- removeHiddenDependency(info.Holder(), oldV8Listener, V8Custom::kWorkerRequestCacheIndex);
- }
-
- // Clear the listener.
- worker->setOnmessage(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::kWorkerRequestCacheIndex);
- }
-
- worker->setOnmessage(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kWorkerRequestCacheIndex);
- }
+ INC_STATS("DOM.Worker.postMessage");
+ Worker* worker = V8DOMWrapper::convertToNativeObject<Worker>(V8ClassIndex::WORKER, args.Holder());
+ RefPtr<SerializedScriptValue> message = SerializedScriptValue::create(toWebCoreString(args[0]));
+ MessagePortArray portArray;
+ if (args.Length() > 1) {
+ if (!getMessagePortArray(args[1], portArray))
+ return v8::Undefined();
}
+ ExceptionCode ec = 0;
+ worker->postMessage(message.release(), &portArray, ec);
+ return throwError(ec);
}
} // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
index 02ce8e2..af647cd 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
@@ -33,8 +33,8 @@
#include "Frame.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
+#include "V8Utilities.h"
#include "XMLHttpRequest.h"
#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
@@ -50,20 +50,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestConstructor)
// Expect no parameters.
// Allocate a XMLHttpRequest object as its internal field.
- ScriptExecutionContext* context = 0;
-#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
- if (proxy)
- context = proxy->workerContext();
- 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
+ ScriptExecutionContext* context = getScriptExecutionContext();
+ if (!context)
+ return throwError("XMLHttpRequest constructor's associated context is not available", V8Proxy::ReferenceError);
RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
index 7204a61..c3e4645 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp
@@ -33,10 +33,10 @@
#include "Frame.h"
#include "V8Binding.h"
-#include "V8Document.h"
#include "V8CustomBinding.h"
+#include "V8Document.h"
+#include "V8File.h"
#include "V8HTMLDocument.h"
-#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "WorkerContext.h"
@@ -44,234 +44,11 @@
namespace WebCore {
-static PassRefPtr<EventListener> getEventListener(XMLHttpRequest* xmlHttpRequest, v8::Local<v8::Value> value, bool findOnly)
-{
-#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy)
- return workerContextProxy->findOrCreateObjectEventListener(value, false, findOnly);
-#endif
-
- V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (proxy) {
- V8EventListenerList* list = proxy->objectListeners();
- return findOnly ? list->findWrapper(value, false) : list->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- }
-
- return PassRefPtr<EventListener>();
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnabort)
-{
- INC_STATS("DOM.XMLHttpRequest.onabort._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnabort)
-{
- INC_STATS("DOM.XMLHttpRequest.onabort._set");
- XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequest->onabort()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onabort());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequest->setOnabort(0);
- } else {
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false);
- if (listener) {
- xmlHttpRequest->setOnabort(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnerror)
-{
- INC_STATS("DOM.XMLHttpRequest.onerror._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnerror)
-{
- INC_STATS("DOM.XMLHttpRequest.onerror._set");
- XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequest->onerror()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onerror());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequest->setOnerror(0);
- } else {
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false);
- if (listener) {
- xmlHttpRequest->setOnerror(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnload)
-{
- INC_STATS("DOM.XMLHttpRequest.onload._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnload)
-{
- INC_STATS("DOM.XMLHttpRequest.onload._set");
- XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequest->onload()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onload());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- xmlHttpRequest->setOnload(0);
-
- } else {
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false);
- if (listener) {
- xmlHttpRequest->setOnload(listener.get());
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnloadstart)
-{
- INC_STATS("DOM.XMLHttpRequest.onloadstart._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnloadstart)
-{
- INC_STATS("DOM.XMLHttpRequest.onloadstart._set");
- XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequest->onloadstart()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onloadstart());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequest->setOnloadstart(0);
- } else {
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false);
- if (listener) {
- xmlHttpRequest->setOnloadstart(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnprogress)
-{
- INC_STATS("DOM.XMLHttpRequest.onprogress._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnprogress)
-{
- INC_STATS("DOM.XMLHttpRequest.onprogress._set");
- XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequest->onprogress()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onprogress());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequest->setOnprogress(0);
- } else {
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false);
- if (listener) {
- xmlHttpRequest->setOnprogress(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestOnreadystatechange)
-{
- INC_STATS("DOM.XMLHttpRequest.onreadystatechange._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestOnreadystatechange)
-{
- INC_STATS("DOM.XMLHttpRequest.onreadystatechange._set");
- XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequest->onreadystatechange()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequest->onreadystatechange());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequest->setOnreadystatechange(0);
- } else {
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, value, false);
- if (listener) {
- xmlHttpRequest->setOnreadystatechange(listener.get());
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
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 = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, info.Holder());
- return v8StringOrNull(xmlHttpRequest->responseText());
+ return xmlHttpRequest->responseText().v8StringOrNull();
}
CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener)
@@ -279,7 +56,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestAddEventListener)
INC_STATS("DOM.XMLHttpRequest.addEventListener()");
XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -295,7 +72,7 @@ CALLBACK_FUNC_DECL(XMLHttpRequestRemoveEventListener)
INC_STATS("DOM.XMLHttpRequest.removeEventListener()");
XMLHttpRequest* xmlHttpRequest = V8DOMWrapper::convertToNativeObject<XMLHttpRequest>(V8ClassIndex::XMLHTTPREQUEST, args.Holder());
- RefPtr<EventListener> listener = getEventListener(xmlHttpRequest, args[1], true);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -323,22 +100,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestOpen)
String method = toWebCoreString(args[0]);
String urlstring = toWebCoreString(args[1]);
- ScriptExecutionContext* context = 0;
-#if ENABLE(WORKERS)
- WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
- if (workerContextProxy) {
- context = workerContextProxy->workerContext();
- ASSERT(context);
- }
-#endif
-
- if (!context) {
- V8Proxy* proxy = V8Proxy::retrieve();
- if (!proxy)
- return v8::Undefined();
- context = proxy->frame()->document();
- ASSERT(context);
- }
+ ScriptExecutionContext* context = getScriptExecutionContext();
+ if (!context)
+ return v8::Undefined();
KURL url = context->completeURL(urlstring);
@@ -379,12 +143,16 @@ CALLBACK_FUNC_DECL(XMLHttpRequestSend)
xmlHttpRequest->send(ec);
else {
v8::Handle<v8::Value> arg = args[0];
- // FIXME: upstream handles "File" objects too.
if (IsDocumentType(arg)) {
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
Document* document = V8DOMWrapper::convertDOMWrapperToNode<Document>(object);
ASSERT(document);
xmlHttpRequest->send(document, ec);
+ } else if (V8File::HasInstance(arg)) {
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(arg);
+ File* file = V8DOMWrapper::convertDOMWrapperToNative<File>(object);
+ ASSERT(file);
+ xmlHttpRequest->send(file, ec);
} else
xmlHttpRequest->send(toWebCoreStringWithNullCheck(arg), ec);
}
diff --git a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
index bbc69dd..9323f71 100644
--- a/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8XMLHttpRequestUploadCustom.cpp
@@ -34,7 +34,6 @@
#include "ExceptionCode.h"
#include "V8Binding.h"
#include "V8CustomBinding.h"
-#include "V8ObjectEventListener.h"
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "XMLHttpRequest.h"
@@ -43,212 +42,14 @@
namespace WebCore {
-ACCESSOR_GETTER(XMLHttpRequestUploadOnabort)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onabort._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnabort)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onabort._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequestUpload->onabort()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onabort());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequestUpload->setOnabort(0);
- } else {
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
- V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- if (listener) {
- xmlHttpRequestUpload->setOnabort(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnerror)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onerror._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnerror)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onerror._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequestUpload->onerror()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onerror());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequestUpload->setOnerror(0);
- } else {
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
- V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- if (listener) {
- xmlHttpRequestUpload->setOnerror(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnload)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onload._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnload)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onload._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequestUpload->onload()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onload());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequestUpload->setOnload(0);
- } else {
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
- V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- if (listener) {
- xmlHttpRequestUpload->setOnload(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnloadstart)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnloadstart)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onloadstart._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequestUpload->onloadstart()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onloadstart());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequestUpload->setOnloadstart(0);
- } else {
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
- V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- if (listener) {
- xmlHttpRequestUpload->setOnloadstart(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
-ACCESSOR_GETTER(XMLHttpRequestUploadOnprogress)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onprogress._get");
- 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();
- return v8Listener;
- }
- return v8::Null();
-}
-
-ACCESSOR_SETTER(XMLHttpRequestUploadOnprogress)
-{
- INC_STATS("DOM.XMLHttpRequestUpload.onprogress._set");
- XMLHttpRequestUpload* xmlHttpRequestUpload = V8DOMWrapper::convertToNativeObject<XMLHttpRequestUpload>(V8ClassIndex::XMLHTTPREQUESTUPLOAD, info.Holder());
- if (value->IsNull()) {
- if (xmlHttpRequestUpload->onprogress()) {
- V8ObjectEventListener* listener = static_cast<V8ObjectEventListener*>(xmlHttpRequestUpload->onprogress());
- v8::Local<v8::Object> v8Listener = listener->getListenerObject();
- removeHiddenDependency(info.Holder(), v8Listener, V8Custom::kXMLHttpRequestCacheIndex);
- }
-
- // Clear the listener.
- xmlHttpRequestUpload->setOnprogress(0);
- } else {
- XMLHttpRequest* xmlHttpRequest = xmlHttpRequestUpload->associatedXMLHttpRequest();
- V8Proxy* proxy = V8Proxy::retrieve(xmlHttpRequest->scriptExecutionContext());
- if (!proxy)
- return;
-
- RefPtr<EventListener> listener = proxy->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), value, false);
- if (listener) {
- xmlHttpRequestUpload->setOnprogress(listener);
- createHiddenDependency(info.Holder(), value, V8Custom::kXMLHttpRequestCacheIndex);
- }
- }
-}
-
CALLBACK_FUNC_DECL(XMLHttpRequestUploadAddEventListener)
{
INC_STATS("DOM.XMLHttpRequestUpload.addEventListener()");
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->objectListeners()->findOrCreateWrapper<V8ObjectEventListener>(proxy->frame(), args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOrCreate);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
@@ -265,12 +66,8 @@ CALLBACK_FUNC_DECL(XMLHttpRequestUploadRemoveEventListener)
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->objectListeners()->findWrapper(args[1], false);
+ RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(xmlHttpRequest, args[1], false, ListenerFindOnly);
if (listener) {
String type = toWebCoreString(args[0]);
bool useCapture = args[2]->BooleanValue();
diff --git a/WebCore/bindings/v8/npruntime.cpp b/WebCore/bindings/v8/npruntime.cpp
index 64a1927..35015b0 100644
--- a/WebCore/bindings/v8/npruntime.cpp
+++ b/WebCore/bindings/v8/npruntime.cpp
@@ -39,7 +39,7 @@
// The static initializer here should work okay, but we want to avoid
// static initialization in general.
-namespace {
+namespace npruntime {
// We use StringKey here as the key-type to avoid a string copy to
// construct the map key and for faster comparisons than strcmp.
@@ -112,7 +112,10 @@ struct StringKeyHash {
static const bool safeToCompareToEmptyOrDeleted = true;
};
-} // namespace
+} // namespace npruntime
+
+using npruntime::StringKey;
+using npruntime::StringKeyHash;
// Implement HashTraits<StringKey>
struct StringKeyHashTraits : WTF::GenericHashTraits<StringKey> {
@@ -309,6 +312,15 @@ void _NPN_DeallocateObject(NPObject* npObject)
}
}
+#if PLATFORM(ANDROID)
+// Android uses NPN_ReleaseObject (the 'public' version of _NPN_ReleaseObject)
+// in WebCoreFrameBridge.cpp. See http://trac.webkit.org/changeset/47021.
+// TODO: Upstream this to webkit.org.
+void NPN_ReleaseObject(NPObject *obj)
+{
+ _NPN_ReleaseObject(obj);
+}
+#endif
void _NPN_ReleaseObject(NPObject* npObject)
{
ASSERT(npObject);