summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/bindings/v8
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/WebCore/bindings/v8
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/WebCore/bindings/v8')
-rw-r--r--Source/WebCore/bindings/v8/DebuggerScript.js30
-rw-r--r--Source/WebCore/bindings/v8/ScriptDebugServer.cpp12
-rw-r--r--Source/WebCore/bindings/v8/ScriptDebugServer.h2
-rw-r--r--Source/WebCore/bindings/v8/ScriptState.cpp19
-rw-r--r--Source/WebCore/bindings/v8/ScriptState.h7
-rw-r--r--Source/WebCore/bindings/v8/ScriptValue.cpp9
-rw-r--r--Source/WebCore/bindings/v8/V8AbstractEventListener.cpp10
-rw-r--r--Source/WebCore/bindings/v8/V8DOMWrapper.cpp3
-rw-r--r--Source/WebCore/bindings/v8/V8GCController.cpp18
-rw-r--r--Source/WebCore/bindings/v8/V8Utilities.cpp5
-rw-r--r--Source/WebCore/bindings/v8/V8Utilities.h30
-rw-r--r--Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp7
-rw-r--r--Source/WebCore/bindings/v8/WorkerScriptController.cpp25
-rw-r--r--Source/WebCore/bindings/v8/WorkerScriptController.h18
-rwxr-xr-xSource/WebCore/bindings/v8/WorkerScriptDebugServer.cpp101
-rwxr-xr-xSource/WebCore/bindings/v8/WorkerScriptDebugServer.h10
-rw-r--r--Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp29
-rw-r--r--Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp20
-rw-r--r--Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp3
-rw-r--r--Source/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp18
-rw-r--r--Source/WebCore/bindings/v8/custom/V8DirectoryEntrySyncCustom.cpp14
-rw-r--r--Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp28
-rw-r--r--Source/WebCore/bindings/v8/custom/V8EventCustom.cpp3
-rw-r--r--Source/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp51
-rw-r--r--Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp6
-rw-r--r--Source/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp65
26 files changed, 394 insertions, 149 deletions
diff --git a/Source/WebCore/bindings/v8/DebuggerScript.js b/Source/WebCore/bindings/v8/DebuggerScript.js
index fe6e8ab..c6540d7 100644
--- a/Source/WebCore/bindings/v8/DebuggerScript.js
+++ b/Source/WebCore/bindings/v8/DebuggerScript.js
@@ -38,11 +38,6 @@ DebuggerScript.PauseOnExceptionsState = {
PauseOnUncaughtExceptions: 2
};
-DebuggerScript.ScriptWorldType = {
- MainWorld : 0,
- ExtensionsWorld : 1
-};
-
DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.DontPauseOnExceptions;
Debug.clearBreakOnException();
Debug.clearBreakOnUncaughtException();
@@ -52,6 +47,21 @@ DebuggerScript.getAfterCompileScript = function(eventData)
return DebuggerScript._formatScript(eventData.script_.script_);
}
+DebuggerScript.getWorkerScripts = function()
+{
+ var result = [];
+ var scripts = Debug.scripts();
+ for (var i = 0; i < scripts.length; ++i) {
+ var script = scripts[i];
+ // Workers don't share same V8 heap now so there is no need to complicate stuff with
+ // the context id like we do to discriminate between scripts from different pages.
+ // However we need to filter out v8 native scripts.
+ if (script.context_data && script.context_data === "worker")
+ result.push(DebuggerScript._formatScript(script));
+ }
+ return result;
+}
+
DebuggerScript.getScripts = function(contextData)
{
var result = [];
@@ -76,24 +86,19 @@ DebuggerScript.getScripts = function(contextData)
DebuggerScript._formatScript = function(script)
{
- var scriptWorldType = DebuggerScript.ScriptWorldType.MainWorld;
- if (script.context_data && script.context_data.indexOf("injected") == 0)
- scriptWorldType = DebuggerScript.ScriptWorldType.ExtensionsWorld;
return {
id: script.id,
name: script.nameOrSourceURL(),
source: script.source,
lineOffset: script.line_offset,
columnOffset: script.column_offset,
- scriptWorldType: scriptWorldType
+ isContentScript: !!script.context_data && script.context_data.indexOf("injected") == 0
};
}
DebuggerScript.setBreakpoint = function(execState, args)
{
- var breakId = Debug.setScriptBreakPointById(args.scriptId, args.lineNumber, args.columnNumber, args.condition);
- if (!args.enabled)
- Debug.disableScriptBreakPoint(breakId);
+ var breakId = Debug.setScriptBreakPointById(args.sourceID, args.lineNumber, args.columnNumber, args.condition);
var locations = Debug.findBreakPointActualLocations(breakId);
if (!locations.length)
@@ -252,7 +257,6 @@ DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
"line": location.line,
"column": location.column,
"functionName": functionName,
- "type": "function",
"thisObject": thisObject,
"scopeChain": scopeChain,
"scopeType": scopeType,
diff --git a/Source/WebCore/bindings/v8/ScriptDebugServer.cpp b/Source/WebCore/bindings/v8/ScriptDebugServer.cpp
index 5758639..a0e14f3 100644
--- a/Source/WebCore/bindings/v8/ScriptDebugServer.cpp
+++ b/Source/WebCore/bindings/v8/ScriptDebugServer.cpp
@@ -67,11 +67,10 @@ String ScriptDebugServer::setBreakpoint(const String& sourceID, const ScriptBrea
v8::Context::Scope contextScope(debuggerContext);
v8::Local<v8::Object> args = v8::Object::New();
- args->Set(v8::String::New("scriptId"), v8String(sourceID));
+ args->Set(v8::String::New("sourceID"), v8String(sourceID));
args->Set(v8::String::New("lineNumber"), v8::Integer::New(scriptBreakpoint.lineNumber));
args->Set(v8::String::New("columnNumber"), v8::Integer::New(scriptBreakpoint.columnNumber));
args->Set(v8::String::New("condition"), v8String(scriptBreakpoint.condition));
- args->Set(v8::String::New("enabled"), v8::Boolean::New(scriptBreakpoint.enabled));
v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpoint")));
v8::Handle<v8::Value> breakpointId = v8::Debug::Call(setBreakpointFunction, args);
@@ -212,7 +211,7 @@ void ScriptDebugServer::stepOutOfFunction()
continueProgram();
}
-bool ScriptDebugServer::editScriptSource(const String& sourceID, const String& newContent, String& newSourceOrErrorMessage)
+bool ScriptDebugServer::editScriptSource(const String& sourceID, const String& newContent, String* error)
{
ensureDebuggerScriptCompiled();
v8::HandleScope scope;
@@ -230,11 +229,12 @@ bool ScriptDebugServer::editScriptSource(const String& sourceID, const String& n
if (tryCatch.HasCaught()) {
v8::Local<v8::Message> message = tryCatch.Message();
if (!message.IsEmpty())
- newSourceOrErrorMessage = toWebCoreStringWithNullOrUndefinedCheck(message->Get());
+ *error = toWebCoreStringWithNullOrUndefinedCheck(message->Get());
+ else
+ *error = "Unknown error.";
return false;
}
ASSERT(!result.IsEmpty());
- newSourceOrErrorMessage = toWebCoreStringWithNullOrUndefinedCheck(result);
// Call stack may have changed after if the edited function was on the stack.
if (m_currentCallFrame)
@@ -351,7 +351,7 @@ void ScriptDebugServer::dispatchDidParseSource(ScriptDebugListener* listener, v8
toWebCoreStringWithNullOrUndefinedCheck(object->Get(v8::String::New("source"))),
object->Get(v8::String::New("lineOffset"))->ToInteger()->Value(),
object->Get(v8::String::New("columnOffset"))->ToInteger()->Value(),
- static_cast<ScriptWorldType>(object->Get(v8::String::New("scriptWorldType"))->Int32Value()));
+ object->Get(v8::String::New("isContentScript"))->ToBoolean()->Value());
}
void ScriptDebugServer::ensureDebuggerScriptCompiled()
diff --git a/Source/WebCore/bindings/v8/ScriptDebugServer.h b/Source/WebCore/bindings/v8/ScriptDebugServer.h
index 15004ea..93d897c 100644
--- a/Source/WebCore/bindings/v8/ScriptDebugServer.h
+++ b/Source/WebCore/bindings/v8/ScriptDebugServer.h
@@ -72,7 +72,7 @@ public:
void stepOverStatement();
void stepOutOfFunction();
- bool editScriptSource(const String& sourceID, const String& newContent, String& newSourceOrErrorMessage);
+ bool editScriptSource(const String& sourceID, const String& newContent, String* error);
void recompileAllJSFunctionsSoon() { }
void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) { }
diff --git a/Source/WebCore/bindings/v8/ScriptState.cpp b/Source/WebCore/bindings/v8/ScriptState.cpp
index fac1d26..600a92a 100644
--- a/Source/WebCore/bindings/v8/ScriptState.cpp
+++ b/Source/WebCore/bindings/v8/ScriptState.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -37,6 +37,10 @@
#include "ScriptController.h"
#include "V8HiddenPropertyName.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+#include "WorkerScriptController.h"
+
#include <v8.h>
#include <wtf/Assertions.h>
@@ -111,4 +115,17 @@ ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page* page)
return mainWorldScriptState(page->mainFrame());
}
+#if ENABLE(WORKERS)
+ScriptState* scriptStateFromWorkerContext(WorkerContext* workerContext)
+{
+ WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
+ if (!proxy)
+ return 0;
+
+ v8::HandleScope handleScope;
+ v8::Local<v8::Context> context = proxy->context();
+ return ScriptState::forContext(context);
+}
+#endif
+
}
diff --git a/Source/WebCore/bindings/v8/ScriptState.h b/Source/WebCore/bindings/v8/ScriptState.h
index 0fecee8..c7dbbb2 100644
--- a/Source/WebCore/bindings/v8/ScriptState.h
+++ b/Source/WebCore/bindings/v8/ScriptState.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -41,6 +41,7 @@ class DOMWrapperWorld;
class Frame;
class Node;
class Page;
+class WorkerContext;
class ScriptState {
WTF_MAKE_NONCOPYABLE(ScriptState);
@@ -108,6 +109,10 @@ ScriptState* mainWorldScriptState(Frame*);
ScriptState* scriptStateFromNode(DOMWrapperWorld*, Node*);
ScriptState* scriptStateFromPage(DOMWrapperWorld*, Page*);
+#if ENABLE(WORKERS)
+ScriptState* scriptStateFromWorkerContext(WorkerContext*);
+#endif
+
inline DOMWrapperWorld* debuggerWorld() { return mainThreadNormalWorld(); }
inline DOMWrapperWorld* pluginWorld() { return mainThreadNormalWorld(); }
diff --git a/Source/WebCore/bindings/v8/ScriptValue.cpp b/Source/WebCore/bindings/v8/ScriptValue.cpp
index ebe9ccc..3487d39 100644
--- a/Source/WebCore/bindings/v8/ScriptValue.cpp
+++ b/Source/WebCore/bindings/v8/ScriptValue.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -64,7 +64,12 @@ bool ScriptValue::getString(String& result) const
String ScriptValue::toString(ScriptState*) const
{
- return toWebCoreString(m_value);
+ v8::TryCatch block;
+ v8::Handle<v8::String> s = m_value->ToString();
+ // Handle the case where an exception is thrown as part of invoking toString on the object.
+ if (block.HasCaught())
+ return String();
+ return v8StringToWebCoreString<String>(s, DoNotExternalize);
}
#if ENABLE(INSPECTOR)
diff --git a/Source/WebCore/bindings/v8/V8AbstractEventListener.cpp b/Source/WebCore/bindings/v8/V8AbstractEventListener.cpp
index 6dc49fa..f1102c2 100644
--- a/Source/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/Source/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -72,6 +72,10 @@ V8AbstractEventListener::~V8AbstractEventListener()
void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
{
+ // Don't reenter V8 if execution was terminated in this instance of V8.
+ if (context->isJSExecutionForbidden())
+ return;
+
ASSERT(event);
// The callback function on XMLHttpRequest can clear the event listener and destroys 'this' object. Keep a local reference to it.
@@ -150,8 +154,12 @@ void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context
returnValue = callListenerFunction(context, jsEvent, event);
if (tryCatch.HasCaught())
event->target()->uncaughtExceptionInEventHandler();
- if (!tryCatch.CanContinue())
+
+ if (!tryCatch.CanContinue()) { // Result of TerminateExecution().
+ if (context->isWorkerContext())
+ static_cast<WorkerContext*>(context)->script()->forbidExecution();
return;
+ }
tryCatch.Reset();
// Restore the old event. This must be done for all exit paths through this method.
diff --git a/Source/WebCore/bindings/v8/V8DOMWrapper.cpp b/Source/WebCore/bindings/v8/V8DOMWrapper.cpp
index b439274..bef28a2 100644
--- a/Source/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/Source/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -84,6 +84,7 @@
#endif
#if ENABLE(WEB_AUDIO)
+#include "V8AudioContext.h"
#include "V8JavaScriptAudioNode.h"
#endif
@@ -444,6 +445,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
#if ENABLE(WEB_AUDIO)
if (JavaScriptAudioNode* jsAudioNode = target->toJavaScriptAudioNode())
return toV8(jsAudioNode);
+ if (AudioContext* audioContext = target->toAudioContext())
+ return toV8(audioContext);
#endif
ASSERT(0);
diff --git a/Source/WebCore/bindings/v8/V8GCController.cpp b/Source/WebCore/bindings/v8/V8GCController.cpp
index 82c9ca4..c9e9dfd 100644
--- a/Source/WebCore/bindings/v8/V8GCController.cpp
+++ b/Source/WebCore/bindings/v8/V8GCController.cpp
@@ -359,6 +359,24 @@ public:
GroupId groupId = calculateGroupId(cssStyleDeclaration);
m_grouper.append(GrouperItem(groupId, wrapper));
+ // Keep alive "dirty" primitive values (i.e. the ones that
+ // have user-added properties) by creating implicit
+ // references between the style declaration and the values
+ // in it.
+ if (cssStyleDeclaration->isMutableStyleDeclaration()) {
+ CSSMutableStyleDeclaration* cssMutableStyleDeclaration = static_cast<CSSMutableStyleDeclaration*>(cssStyleDeclaration);
+ Vector<v8::Persistent<v8::Value> > values;
+ values.reserveCapacity(cssMutableStyleDeclaration->length());
+ CSSMutableStyleDeclaration::const_iterator end = cssMutableStyleDeclaration->end();
+ for (CSSMutableStyleDeclaration::const_iterator it = cssMutableStyleDeclaration->begin(); it != end; ++it) {
+ v8::Persistent<v8::Object> value = store->domObjectMap().get(it->value());
+ if (!value.IsEmpty() && value->IsDirty())
+ values.append(value);
+ }
+ if (!values.isEmpty())
+ v8::V8::AddImplicitReferences(wrapper, values.data(), values.size());
+ }
+
} else if (typeInfo->isSubclass(&V8CSSRuleList::info)) {
CSSRuleList* cssRuleList = static_cast<CSSRuleList*>(object);
GroupId groupId(cssRuleList);
diff --git a/Source/WebCore/bindings/v8/V8Utilities.cpp b/Source/WebCore/bindings/v8/V8Utilities.cpp
index eebe6b5..b631359 100644
--- a/Source/WebCore/bindings/v8/V8Utilities.cpp
+++ b/Source/WebCore/bindings/v8/V8Utilities.cpp
@@ -127,4 +127,9 @@ ScriptExecutionContext* getScriptExecutionContext()
return 0;
}
+void throwTypeMismatchException()
+{
+ V8Proxy::throwError(V8Proxy::GeneralError, "TYPE_MISMATCH_ERR: DOM Exception 17");
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/V8Utilities.h b/Source/WebCore/bindings/v8/V8Utilities.h
index 1892bb7..4a44f3c 100644
--- a/Source/WebCore/bindings/v8/V8Utilities.h
+++ b/Source/WebCore/bindings/v8/V8Utilities.h
@@ -55,6 +55,36 @@ namespace WebCore {
ScriptExecutionContext* getScriptExecutionContext();
+ void throwTypeMismatchException();
+
+ enum CallbackAllowedValueFlag {
+ CallbackAllowUndefined = 1,
+ CallbackAllowNull = 1 << 1
+ };
+
+ typedef unsigned CallbackAllowedValueFlags;
+
+ // 'FunctionOnly' is assumed for the created callback.
+ template <typename V8CallbackType>
+ PassRefPtr<V8CallbackType> createFunctionOnlyCallback(v8::Local<v8::Value> value, bool& succeeded, CallbackAllowedValueFlags acceptedValues = 0)
+ {
+ succeeded = true;
+
+ if (value->IsUndefined() && (acceptedValues & CallbackAllowUndefined))
+ return 0;
+
+ if (value->IsNull() && (acceptedValues & CallbackAllowNull))
+ return 0;
+
+ if (!value->IsFunction()) {
+ succeeded = false;
+ throwTypeMismatchException();
+ return 0;
+ }
+
+ return V8CallbackType::create(value, getScriptExecutionContext());
+ }
+
class AllowAllocation {
public:
inline AllowAllocation()
diff --git a/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index eb7252b..42259d5 100644
--- a/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -150,6 +150,9 @@ bool WorkerContextExecutionProxy::initContextIfNeeded()
v8::Context::Scope scope(context);
+ // Set DebugId for the new context.
+ context->SetData(v8::String::New("worker"));
+
// Create a new JS object and use it as the prototype for the shadow global object.
WrapperTypeInfo* contextType = &V8DedicatedWorkerContext::info;
#if ENABLE(SHARED_WORKERS)
@@ -200,8 +203,10 @@ ScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const St
v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, scriptStartPosition);
v8::Local<v8::Value> result = runScript(compiledScript);
- if (!exceptionCatcher.CanContinue())
+ if (!exceptionCatcher.CanContinue()) {
+ m_workerContext->script()->forbidExecution();
return ScriptValue();
+ }
if (exceptionCatcher.HasCaught()) {
v8::Local<v8::Message> message = exceptionCatcher.Message();
diff --git a/Source/WebCore/bindings/v8/WorkerScriptController.cpp b/Source/WebCore/bindings/v8/WorkerScriptController.cpp
index 42e02e6..214da4e 100644
--- a/Source/WebCore/bindings/v8/WorkerScriptController.cpp
+++ b/Source/WebCore/bindings/v8/WorkerScriptController.cpp
@@ -68,11 +68,8 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception)
{
- {
- MutexLocker lock(m_sharedDataMutex);
- if (m_executionForbidden)
- return ScriptValue();
- }
+ if (isExecutionForbidden())
+ return ScriptValue();
WorkerContextExecutionState state;
ScriptValue result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), WTF::toZeroBasedTextPosition(sourceCode.startPosition()), &state);
@@ -86,13 +83,21 @@ ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode,
return result;
}
-void WorkerScriptController::forbidExecution(ForbidExecutionOption option)
+void WorkerScriptController::scheduleExecutionTermination()
+{
+ v8::V8::TerminateExecution();
+}
+
+void WorkerScriptController::forbidExecution()
{
- // This function may be called from another thread.
- MutexLocker lock(m_sharedDataMutex);
+ ASSERT(m_workerContext->isContextThread());
m_executionForbidden = true;
- if (option == TerminateRunningScript)
- v8::V8::TerminateExecution();
+}
+
+bool WorkerScriptController::isExecutionForbidden() const
+{
+ ASSERT(m_workerContext->isContextThread());
+ return m_executionForbidden;
}
void WorkerScriptController::setException(ScriptValue exception)
diff --git a/Source/WebCore/bindings/v8/WorkerScriptController.h b/Source/WebCore/bindings/v8/WorkerScriptController.h
index 5e3159f..cc4b7c4 100644
--- a/Source/WebCore/bindings/v8/WorkerScriptController.h
+++ b/Source/WebCore/bindings/v8/WorkerScriptController.h
@@ -48,7 +48,7 @@ namespace WebCore {
WorkerScriptController(WorkerContext*);
~WorkerScriptController();
- WorkerContextExecutionProxy* proxy() { return m_executionForbidden ? 0 : m_proxy.get(); }
+ WorkerContextExecutionProxy* proxy() { return m_proxy.get(); }
WorkerContext* workerContext() { return m_workerContext; }
ScriptValue evaluate(const ScriptSourceCode&);
@@ -56,9 +56,17 @@ namespace WebCore {
void setException(ScriptValue);
- enum ForbidExecutionOption { TerminateRunningScript, LetRunningScriptFinish };
- void forbidExecution(ForbidExecutionOption);
- bool isExecutionForbidden() const { return m_executionForbidden; }
+ // Async request to terminate a future JS execution. Eventually causes termination
+ // exception raised during JS execution, if the worker thread happens to run JS.
+ // After JS execution was terminated in this way, the Worker thread has to use
+ // forbidExecution()/isExecutionForbidden() to guard against reentry into JS.
+ // Can be called from any thread.
+ void scheduleExecutionTermination();
+
+ // Called on Worker thread when JS exits with termination exception caused by forbidExecution() request,
+ // or by Worker thread termination code to prevent future entry into JS.
+ void forbidExecution();
+ bool isExecutionForbidden() const;
// Returns WorkerScriptController for the currently executing context. 0 will be returned if the current executing context is not the worker context.
static WorkerScriptController* controllerForContext();
@@ -66,8 +74,6 @@ namespace WebCore {
private:
WorkerContext* m_workerContext;
OwnPtr<WorkerContextExecutionProxy> m_proxy;
-
- Mutex m_sharedDataMutex;
bool m_executionForbidden;
};
diff --git a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
index 5e2acd2..1887cea 100755
--- a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
+++ b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
@@ -33,21 +33,118 @@
#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(WORKERS)
+#include "ScriptDebugListener.h"
+#include "V8DOMWrapper.h"
+#include "V8DedicatedWorkerContext.h"
+#include "V8SharedWorkerContext.h"
#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+#include "WorkerThread.h"
+#include <v8.h>
+#include <wtf/MessageQueue.h>
namespace WebCore {
+static WorkerContext* retrieveWorkerContext(v8::Handle<v8::Context> context)
+{
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+
+ v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(global->GetPrototype());
+ ASSERT(!prototype.IsEmpty());
+
+ prototype = v8::Handle<v8::Object>::Cast(prototype->GetPrototype());
+ ASSERT(!prototype.IsEmpty());
+
+ WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(prototype);
+ if (&V8DedicatedWorkerContext::info == typeInfo)
+ return V8DedicatedWorkerContext::toNative(prototype);
+ if (&V8SharedWorkerContext::info == typeInfo)
+ return V8SharedWorkerContext::toNative(prototype);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
WorkerScriptDebugServer::WorkerScriptDebugServer()
: ScriptDebugServer()
+ , m_pausedWorkerContext(0)
+{
+}
+
+void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener, WorkerContext* workerContext)
+{
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ if (!m_listenersMap.size()) {
+ // FIXME: synchronize access to this code.
+ ensureDebuggerScriptCompiled();
+ ASSERT(!m_debuggerScript.get()->IsUndefined());
+ v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(this));
+ }
+ m_listenersMap.set(workerContext, listener);
+
+ WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
+ if (!proxy)
+ return;
+ v8::Handle<v8::Context> context = proxy->context();
+
+ v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getWorkerScripts")));
+ v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value>() };
+ v8::Handle<v8::Value> value = getScriptsFunction->Call(m_debuggerScript.get(), 0, argv);
+ if (value.IsEmpty())
+ return;
+ ASSERT(!value->IsUndefined() && value->IsArray());
+ v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value);
+ for (unsigned i = 0; i < scriptsArray->Length(); ++i)
+ dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i))));
+}
+
+void WorkerScriptDebugServer::removeListener(ScriptDebugListener* listener, WorkerContext* workerContext)
{
+ if (!m_listenersMap.contains(workerContext))
+ return;
+
+ if (m_pausedWorkerContext == workerContext)
+ continueProgram();
+
+ m_listenersMap.remove(workerContext);
+
+ if (m_listenersMap.isEmpty())
+ v8::Debug::SetDebugEventListener2(0);
}
-void WorkerScriptDebugServer::addListener(ScriptDebugListener*, WorkerContext*)
+ScriptDebugListener* WorkerScriptDebugServer::getDebugListenerForContext(v8::Handle<v8::Context> context)
{
+ WorkerContext* workerContext = retrieveWorkerContext(context);
+ if (!workerContext)
+ return 0;
+ return m_listenersMap.get(workerContext);
+}
+
+void WorkerScriptDebugServer::runMessageLoopOnPause(v8::Handle<v8::Context> context)
+{
+ WorkerContext* workerContext = retrieveWorkerContext(context);
+ WorkerThread* workerThread = workerContext->thread();
+
+ m_pausedWorkerContext = workerContext;
+
+ MessageQueueWaitResult result;
+ do {
+ result = workerThread->runLoop().runInMode(workerContext, "debugger");
+ // Keep waiting until execution is resumed.
+ } while (result == MessageQueueMessageReceived && isPaused());
+ m_pausedWorkerContext = 0;
+
+ // The listener may have been removed in the nested loop.
+ if (ScriptDebugListener* listener = m_listenersMap.get(workerContext))
+ listener->didContinue();
}
-void WorkerScriptDebugServer::removeListener(ScriptDebugListener*, WorkerContext*)
+void WorkerScriptDebugServer::quitMessageLoopOnPause()
{
+ // FIXME: do exit nested loop when listener is removed on pause.
}
} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.h b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.h
index fdc47ac..6264c68 100755
--- a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.h
+++ b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.h
@@ -49,9 +49,13 @@ public:
void removeListener(ScriptDebugListener*, WorkerContext*);
private:
- virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>) { return 0; }
- virtual void runMessageLoopOnPause(v8::Handle<v8::Context>) { }
- virtual void quitMessageLoopOnPause() { }
+ virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>);
+ virtual void runMessageLoopOnPause(v8::Handle<v8::Context>);
+ virtual void quitMessageLoopOnPause();
+
+ typedef HashMap<WorkerContext*, ScriptDebugListener*> ListenersMap;
+ ListenersMap m_listenersMap;
+ WorkerContext* m_pausedWorkerContext;
};
} // namespace WebCore
diff --git a/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp b/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp
index 419cd60..f2f8dc0 100644
--- a/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8AudioContextCustom.cpp
@@ -51,7 +51,34 @@ v8::Handle<v8::Value> V8AudioContext::constructorCallback(const v8::Arguments& a
if (!document)
return throwError("AudioContext constructor associated document is unavailable", V8Proxy::ReferenceError);
- RefPtr<AudioContext> audioContext = AudioContext::create(document);
+ RefPtr<AudioContext> audioContext;
+
+ if (!args.Length()) {
+ // Constructor for default AudioContext which talks to audio hardware.
+ audioContext = AudioContext::create(document);
+ } else {
+ // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer.
+ // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate);
+ if (args.Length() < 3)
+ return throwError("Not enough arguments", V8Proxy::SyntaxError);
+
+ bool ok = false;
+
+ unsigned numberOfChannels = toInt32(args[0], ok);
+ if (!ok)
+ return throwError("Invalid number of channels", V8Proxy::SyntaxError);
+
+ unsigned numberOfFrames = toInt32(args[1], ok);
+ if (!ok)
+ return throwError("Invalid number of frames", V8Proxy::SyntaxError);
+
+ float sampleRate = toFloat(args[2]);
+
+ audioContext = AudioContext::createOfflineContext(document, numberOfChannels, numberOfFrames, sampleRate);
+ }
+
+ if (!audioContext.get())
+ return throwError("Error creating AudioContext", V8Proxy::SyntaxError);
// Transform the holder into a wrapper object for the audio context.
V8DOMWrapper::setDOMWrapper(args.Holder(), &info, audioContext.get());
diff --git a/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp b/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
index 850ae14..097924b 100644
--- a/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp
@@ -40,6 +40,8 @@
#include "V8Binding.h"
#include "V8Proxy.h"
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenate.h>
#include <wtf/ASCIICType.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
@@ -107,8 +109,8 @@ static CSSPropertyInfo* cssPropertyInfo(v8::Handle<v8::String>v8PropertyName)
if (!length)
return 0;
- Vector<UChar> name;
- name.reserveCapacity(length);
+ StringBuilder builder;
+ builder.reserveCapacity(length);
unsigned i = 0;
@@ -123,23 +125,21 @@ static CSSPropertyInfo* cssPropertyInfo(v8::Handle<v8::String>v8PropertyName)
} else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
|| hasCSSPropertyNamePrefix(propertyName, "khtml")
|| hasCSSPropertyNamePrefix(propertyName, "apple"))
- name.append('-');
+ builder.append('-');
else if (WTF::isASCIIUpper(propertyName[0]))
return 0;
- name.append(WTF::toASCIILower(propertyName[i++]));
+ builder.append(WTF::toASCIILower(propertyName[i++]));
for (; i < length; ++i) {
UChar c = propertyName[i];
if (!WTF::isASCIIUpper(c))
- name.append(c);
- else {
- name.append('-');
- name.append(WTF::toASCIILower(c));
- }
+ builder.append(c);
+ else
+ builder.append(makeString('-', toASCIILower(c)));
}
- String propName = String::adopt(name);
+ String propName = builder.toString();
int propertyID = cssPropertyID(propName);
if (propertyID) {
propInfo = new CSSPropertyInfo();
diff --git a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index 85ae322..43d5a15 100644
--- a/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -32,6 +32,7 @@
#include "V8DOMWindow.h"
#include "Chrome.h"
+#include "ContentSecurityPolicy.h"
#include "DOMTimer.h"
#include "DOMWindow.h"
#include "ExceptionCode.h"
@@ -131,6 +132,8 @@ v8::Handle<v8::Value> WindowSetTimeoutImpl(const v8::Arguments& args, bool singl
id = DOMTimer::install(scriptContext, action, timeout, singleShot);
} else {
+ if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval())
+ return v8::Integer::New(0);
id = DOMTimer::install(scriptContext, new ScheduledAction(V8Proxy::context(imp->frame()), functionString), timeout, singleShot);
}
diff --git a/Source/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp
index a44131a..0889451 100644
--- a/Source/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8DirectoryEntryCustom.cpp
@@ -39,7 +39,7 @@
#include "V8BindingMacros.h"
#include "V8EntryCallback.h"
#include "V8ErrorCallback.h"
-#include "V8Flags.h"
+#include "V8WebKitFlags.h"
#include "V8Proxy.h"
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -55,10 +55,10 @@ v8::Handle<v8::Value> V8DirectoryEntry::getDirectoryCallback(const v8::Arguments
imp->getDirectory(path);
return v8::Handle<v8::Value>();
}
- RefPtr<Flags> flags;
- if (!isUndefinedOrNull(args[1]) && args[1]->IsObject() && !V8Flags::HasInstance(args[1])) {
+ RefPtr<WebKitFlags> flags;
+ if (!isUndefinedOrNull(args[1]) && args[1]->IsObject() && !V8WebKitFlags::HasInstance(args[1])) {
EXCEPTION_BLOCK(v8::Handle<v8::Object>, object, v8::Handle<v8::Object>::Cast(args[1]));
- flags = Flags::create();
+ flags = WebKitFlags::create();
v8::Local<v8::Value> v8Create = object->Get(v8::String::New("create"));
if (!v8Create.IsEmpty() && !isUndefinedOrNull(v8Create)) {
EXCEPTION_BLOCK(bool, isCreate, v8Create->BooleanValue());
@@ -70,7 +70,7 @@ v8::Handle<v8::Value> V8DirectoryEntry::getDirectoryCallback(const v8::Arguments
flags->setExclusive(isExclusive);
}
} else {
- EXCEPTION_BLOCK(Flags*, tmp_flags, V8Flags::HasInstance(args[1]) ? V8Flags::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0);
+ EXCEPTION_BLOCK(WebKitFlags*, tmp_flags, V8WebKitFlags::HasInstance(args[1]) ? V8WebKitFlags::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0);
flags = tmp_flags;
}
RefPtr<EntryCallback> successCallback;
@@ -98,10 +98,10 @@ v8::Handle<v8::Value> V8DirectoryEntry::getFileCallback(const v8::Arguments& arg
imp->getFile(path);
return v8::Handle<v8::Value>();
}
- RefPtr<Flags> flags;
- if (!isUndefinedOrNull(args[1]) && args[1]->IsObject() && !V8Flags::HasInstance(args[1])) {
+ RefPtr<WebKitFlags> flags;
+ if (!isUndefinedOrNull(args[1]) && args[1]->IsObject() && !V8WebKitFlags::HasInstance(args[1])) {
EXCEPTION_BLOCK(v8::Handle<v8::Object>, object, v8::Handle<v8::Object>::Cast(args[1]));
- flags = Flags::create();
+ flags = WebKitFlags::create();
v8::Local<v8::Value> v8Create = object->Get(v8::String::New("create"));
if (!v8Create.IsEmpty() && !isUndefinedOrNull(v8Create)) {
EXCEPTION_BLOCK(bool, isCreate, v8Create->BooleanValue());
@@ -113,7 +113,7 @@ v8::Handle<v8::Value> V8DirectoryEntry::getFileCallback(const v8::Arguments& arg
flags->setExclusive(isExclusive);
}
} else {
- EXCEPTION_BLOCK(Flags*, tmp_flags, V8Flags::HasInstance(args[1]) ? V8Flags::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0);
+ EXCEPTION_BLOCK(WebKitFlags*, tmp_flags, V8WebKitFlags::HasInstance(args[1]) ? V8WebKitFlags::toNative(v8::Handle<v8::Object>::Cast(args[1])) : 0);
flags = tmp_flags;
}
RefPtr<EntryCallback> successCallback;
diff --git a/Source/WebCore/bindings/v8/custom/V8DirectoryEntrySyncCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DirectoryEntrySyncCustom.cpp
index 90b3d13..cd38ca4 100644
--- a/Source/WebCore/bindings/v8/custom/V8DirectoryEntrySyncCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8DirectoryEntrySyncCustom.cpp
@@ -40,7 +40,7 @@
#include "V8EntryCallback.h"
#include "V8ErrorCallback.h"
#include "V8FileEntrySync.h"
-#include "V8Flags.h"
+#include "V8WebKitFlags.h"
#include "V8Proxy.h"
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
@@ -62,13 +62,13 @@ static bool extractBooleanValue(const v8::Handle<v8::Object>& object, const char
return false;
}
-static PassRefPtr<Flags> getFlags(const v8::Local<v8::Value>& arg, ExceptionCode& ec)
+static PassRefPtr<WebKitFlags> getFlags(const v8::Local<v8::Value>& arg, ExceptionCode& ec)
{
ec = 0;
if (isUndefinedOrNull(arg) || !arg->IsObject())
return 0;
- if (V8Flags::HasInstance(arg))
- return V8Flags::toNative(v8::Handle<v8::Object>::Cast(arg));
+ if (V8WebKitFlags::HasInstance(arg))
+ return V8WebKitFlags::toNative(v8::Handle<v8::Object>::Cast(arg));
v8::Handle<v8::Object> object;
{
@@ -87,7 +87,7 @@ static PassRefPtr<Flags> getFlags(const v8::Local<v8::Value>& arg, ExceptionCode
if (ec)
return 0;
- RefPtr<Flags> flags = Flags::create();
+ RefPtr<WebKitFlags> flags = WebKitFlags::create();
flags->setCreate(isCreate);
flags->setExclusive(isExclusive);
@@ -100,7 +100,7 @@ v8::Handle<v8::Value> V8DirectoryEntrySync::getDirectoryCallback(const v8::Argum
DirectoryEntrySync* imp = V8DirectoryEntrySync::toNative(args.Holder());
ExceptionCode ec = 0;
STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, path, args[0]);
- RefPtr<Flags> flags = getFlags(args[1], ec);
+ RefPtr<WebKitFlags> flags = getFlags(args[1], ec);
if (UNLIKELY(ec)) {
V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
@@ -119,7 +119,7 @@ v8::Handle<v8::Value> V8DirectoryEntrySync::getFileCallback(const v8::Arguments&
DirectoryEntrySync* imp = V8DirectoryEntrySync::toNative(args.Holder());
ExceptionCode ec = 0;
STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, path, args[0]);
- RefPtr<Flags> flags = getFlags(args[1], ec);
+ RefPtr<WebKitFlags> flags = getFlags(args[1], ec);
if (UNLIKELY(ec)) {
V8Proxy::setDOMException(ec);
return v8::Handle<v8::Value>();
diff --git a/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
index c435863..7cad58e 100644
--- a/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -118,34 +118,6 @@ v8::Handle<v8::Value> V8Document::getCSSCanvasContextCallback(const v8::Argument
return v8::Undefined();
}
-
-// DOMImplementation is a singleton in WebCore. If we use our normal
-// mapping from DOM objects to V8 wrappers, the same wrapper will be
-// shared for all frames in the same process. This is a major
-// security problem. Therefore, we generate a DOMImplementation
-// wrapper per document and store it in an internal field of the
-// document. Since the DOMImplementation object is a singleton, we do
-// not have to do anything to keep the DOMImplementation object alive
-// for the lifetime of the wrapper.
-v8::Handle<v8::Value> V8Document::implementationAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
-{
- ASSERT(info.Holder()->InternalFieldCount() >= internalFieldCount);
-
- // Check if the internal field already contains a wrapper.
- v8::Local<v8::Value> implementation = info.Holder()->GetInternalField(V8Document::implementationIndex);
- if (!implementation->IsUndefined())
- return implementation;
-
- // Generate a wrapper.
- Document* document = V8Document::toNative(info.Holder());
- v8::Handle<v8::Value> wrapper = toV8(document->implementation());
-
- // Store the wrapper in the internal field.
- info.Holder()->SetInternalField(implementationIndex, wrapper);
-
- return wrapper;
-}
-
v8::Handle<v8::Value> toV8(Document* impl, bool forceNewObject)
{
if (!impl)
diff --git a/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp b/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp
index abb7d4c..7e12034 100644
--- a/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8EventCustom.cpp
@@ -70,6 +70,7 @@
#if ENABLE(WEB_AUDIO)
#include "V8AudioProcessingEvent.h"
+#include "V8OfflineAudioCompletionEvent.h"
#endif
namespace WebCore {
@@ -169,6 +170,8 @@ v8::Handle<v8::Value> toV8(Event* impl)
#if ENABLE(WEB_AUDIO)
if (impl->isAudioProcessingEvent())
return toV8(static_cast<AudioProcessingEvent*>(impl));
+ if (impl->isOfflineAudioCompletionEvent())
+ return toV8(static_cast<OfflineAudioCompletionEvent*>(impl));
#endif
#if ENABLE(INPUT_SPEECH)
if (impl->isSpeechInputEvent())
diff --git a/Source/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp b/Source/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp
index 54bd11c..91389d8 100644
--- a/Source/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8GeolocationCustom.cpp
@@ -33,52 +33,13 @@
#include "V8Binding.h"
#include "V8CustomPositionCallback.h"
#include "V8CustomPositionErrorCallback.h"
-#include "V8Proxy.h"
+#include "V8Utilities.h"
using namespace std;
using namespace WTF;
namespace WebCore {
-static const char typeMismatchError[] = "TYPE_MISMATCH_ERR: DOM Exception 17";
-
-static void throwTypeMismatchException()
-{
- V8Proxy::throwError(V8Proxy::GeneralError, typeMismatchError);
-}
-
-static PassRefPtr<PositionCallback> createPositionCallback(v8::Local<v8::Value> value, bool& succeeded)
-{
- succeeded = true;
-
- // The spec specifies 'FunctionOnly' for this object.
- if (!value->IsFunction()) {
- succeeded = false;
- throwTypeMismatchException();
- return 0;
- }
-
- return V8CustomPositionCallback::create(value, getScriptExecutionContext());
-}
-
-static PassRefPtr<PositionErrorCallback> createPositionErrorCallback(v8::Local<v8::Value> value, bool& succeeded)
-{
- succeeded = true;
-
- // Argument is optional (hence undefined is allowed), and null is allowed.
- if (isUndefinedOrNull(value))
- return 0;
-
- // The spec specifies 'FunctionOnly' for this object.
- if (!value->IsFunction()) {
- succeeded = false;
- throwTypeMismatchException();
- return 0;
- }
-
- return V8CustomPositionErrorCallback::create(value, getScriptExecutionContext());
-}
-
static PassRefPtr<PositionOptions> createPositionOptions(v8::Local<v8::Value> value, bool& succeeded)
{
succeeded = true;
@@ -172,12 +133,13 @@ v8::Handle<v8::Value> V8Geolocation::getCurrentPositionCallback(const v8::Argume
bool succeeded = false;
- RefPtr<PositionCallback> positionCallback = createPositionCallback(args[0], succeeded);
+ RefPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8CustomPositionCallback>(args[0], succeeded);
if (!succeeded)
return v8::Undefined();
ASSERT(positionCallback);
- RefPtr<PositionErrorCallback> positionErrorCallback = createPositionErrorCallback(args[1], succeeded);
+ // Argument is optional (hence undefined is allowed), and null is allowed.
+ RefPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8CustomPositionErrorCallback>(args[1], succeeded, CallbackAllowUndefined | CallbackAllowNull);
if (!succeeded)
return v8::Undefined();
@@ -197,12 +159,13 @@ v8::Handle<v8::Value> V8Geolocation::watchPositionCallback(const v8::Arguments&
bool succeeded = false;
- RefPtr<PositionCallback> positionCallback = createPositionCallback(args[0], succeeded);
+ RefPtr<PositionCallback> positionCallback = createFunctionOnlyCallback<V8CustomPositionCallback>(args[0], succeeded);
if (!succeeded)
return v8::Undefined();
ASSERT(positionCallback);
- RefPtr<PositionErrorCallback> positionErrorCallback = createPositionErrorCallback(args[1], succeeded);
+ // Argument is optional (hence undefined is allowed), and null is allowed.
+ RefPtr<PositionErrorCallback> positionErrorCallback = createFunctionOnlyCallback<V8CustomPositionErrorCallback>(args[1], succeeded, CallbackAllowUndefined | CallbackAllowNull);
if (!succeeded)
return v8::Undefined();
diff --git a/Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp b/Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp
index f4006b8..8bb4281 100644
--- a/Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8InjectedScriptManager.cpp
@@ -139,13 +139,13 @@ InjectedScript InjectedScriptManager::injectedScriptFor(ScriptState* inspectedSc
v8::Handle<v8::String> key = V8HiddenPropertyName::devtoolsInjectedScript();
v8::Local<v8::Value> val = global->GetHiddenValue(key);
if (!val.IsEmpty() && val->IsObject())
- return InjectedScript(ScriptObject(inspectedScriptState, v8::Local<v8::Object>::Cast(val)));
+ return InjectedScript(ScriptObject(inspectedScriptState, v8::Local<v8::Object>::Cast(val)), m_inspectedStateAccessCheck);
- if (!canAccessInspectedWindow(inspectedScriptState))
+ if (!m_inspectedStateAccessCheck(inspectedScriptState))
return InjectedScript();
pair<long, ScriptObject> injectedScript = injectScript(injectedScriptSource(), inspectedScriptState);
- InjectedScript result(injectedScript.second);
+ InjectedScript result(injectedScript.second, m_inspectedStateAccessCheck);
m_idToInjectedScript.set(injectedScript.first, result);
global->SetHiddenValue(key, injectedScript.second.v8Object());
return result;
diff --git a/Source/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp b/Source/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
index e5a6909..16e8cfe 100644
--- a/Source/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8NavigatorCustom.cpp
@@ -1,4 +1,5 @@
/*
+<<<<<<< HEAD
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,11 +27,35 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+=======
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+>>>>>>> WebKit.org at r84325
*/
#include "config.h"
#include "V8Navigator.h"
+<<<<<<< HEAD
#if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
#include "ExceptionCode.h"
@@ -77,9 +102,49 @@ v8::Handle<v8::Value> V8Navigator::isApplicationInstalledCallback(const v8::Argu
if (!navigator->isApplicationInstalled(toWebCoreString(args[0]), callback.release()))
return throwError(INVALID_STATE_ERR);
+=======
+#if ENABLE(MEDIA_STREAM)
+
+#include "Navigator.h"
+#include "V8Binding.h"
+#include "V8NavigatorUserMediaErrorCallback.h"
+#include "V8NavigatorUserMediaSuccessCallback.h"
+#include "V8Utilities.h"
+
+using namespace WTF;
+
+namespace WebCore {
+
+v8::Handle<v8::Value> V8Navigator::webkitGetUserMediaCallback(const v8::Arguments& args)
+{
+ INC_STATS("DOM.Navigator.webkitGetUserMedia()");
+
+ v8::TryCatch exceptionCatcher;
+ String options = toWebCoreString(args[0]);
+ if (exceptionCatcher.HasCaught())
+ return throwError(exceptionCatcher.Exception());
+
+ bool succeeded = false;
+
+ RefPtr<NavigatorUserMediaSuccessCallback> successCallback = createFunctionOnlyCallback<V8NavigatorUserMediaSuccessCallback>(args[1], succeeded);
+ if (!succeeded)
+ return v8::Undefined();
+
+ // Argument is optional, hence undefined is allowed.
+ RefPtr<NavigatorUserMediaErrorCallback> errorCallback = createFunctionOnlyCallback<V8NavigatorUserMediaErrorCallback>(args[2], succeeded, CallbackAllowUndefined);
+ if (!succeeded)
+ return v8::Undefined();
+
+ Navigator* navigator = V8Navigator::toNative(args.Holder());
+ navigator->webkitGetUserMedia(options, successCallback.release(), errorCallback.release());
+>>>>>>> WebKit.org at r84325
return v8::Undefined();
}
} // namespace WebCore
+<<<<<<< HEAD
#endif // PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
+=======
+#endif // ENABLE(MEDIA_STREAM)
+>>>>>>> WebKit.org at r84325