diff options
author | Steve Block <steveblock@google.com> | 2010-08-27 11:02:25 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-09-02 17:17:20 +0100 |
commit | e8b154fd68f9b33be40a3590e58347f353835f5c (patch) | |
tree | 0733ce26384183245aaa5656af26c653636fe6c1 /WebCore/bindings | |
parent | da56157816334089526a7a115a85fd85a6e9a1dc (diff) | |
download | external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.zip external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.tar.gz external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.tar.bz2 |
Merge WebKit at r66079 : Initial merge by git
Change-Id: Ie2e1440fb9d487d24e52c247342c076fecaecac7
Diffstat (limited to 'WebCore/bindings')
24 files changed, 297 insertions, 55 deletions
diff --git a/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp b/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp index 4c57946..da420ae 100644 --- a/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp +++ b/WebCore/bindings/gobject/WebKitHTMLElementWrapperFactory.cpp @@ -96,7 +96,6 @@ #include "webkit/WebKitDOMHTMLAnchorElementPrivate.h" #include "webkit/WebKitDOMHTMLAppletElementPrivate.h" #include "webkit/WebKitDOMHTMLAreaElementPrivate.h" -#include "webkit/WebKitDOMHTMLAudioElementPrivate.h" #include "webkit/WebKitDOMHTMLBRElementPrivate.h" #include "webkit/WebKitDOMHTMLBaseElementPrivate.h" #include "webkit/WebKitDOMHTMLBaseFontElementPrivate.h" @@ -153,6 +152,10 @@ #include "webkit/WebKitDOMHTMLUListElementPrivate.h" #include "webkit/webkitdom.h" +#if ENABLE(VIDEO) +#include "webkit/WebKitDOMHTMLAudioElementPrivate.h" +#endif + #include <wtf/text/CString.h> namespace WebKit { @@ -177,10 +180,12 @@ static gpointer createAreaWrapper(PassRefPtr<HTMLElement> element) return wrapHTMLAreaElement(static_cast<HTMLAreaElement*>(element.get())); } +#if ENABLE(VIDEO) static gpointer createAudioWrapper(PassRefPtr<HTMLElement> element) { return wrapHTMLAudioElement(static_cast<HTMLAudioElement*>(element.get())); } +#endif static gpointer createBaseWrapper(PassRefPtr<HTMLElement> element) { @@ -453,7 +458,9 @@ gpointer createHTMLElementWrapper(PassRefPtr<WebCore::HTMLElement> element) if (map.isEmpty()) { map.set(aTag.localName().impl(), createAnchorWrapper); map.set(appletTag.localName().impl(), createAppletWrapper); +#if ENABLE(VIDEO) map.set(audioTag.localName().impl(), createAudioWrapper); +#endif map.set(areaTag.localName().impl(), createAreaWrapper); map.set(baseTag.localName().impl(), createBaseWrapper); map.set(basefontTag.localName().impl(), createBaseFontWrapper); diff --git a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp index 06360fb..ac5225e 100644 --- a/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp +++ b/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp @@ -103,6 +103,12 @@ ScriptObject InjectedScriptHost::createInjectedScript(const String& source, Scri return ScriptObject(); } +void InjectedScriptHost::discardInjectedScript(ScriptState* scriptState) +{ + JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject()); + globalObject->setInjectedScript(0); +} + #if ENABLE(JAVASCRIPT_DEBUGGER) JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec) { diff --git a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp index b724f50..1df1af0 100644 --- a/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp +++ b/WebCore/bindings/js/JSInspectorFrontendHostCustom.cpp @@ -40,6 +40,7 @@ #include "InspectorFrontendHost.h" #include "JSEvent.h" #include "MouseEvent.h" +#include "PlatformString.h" #include <runtime/JSArray.h> #include <runtime/JSLock.h> #include <runtime/JSObject.h> @@ -90,14 +91,26 @@ JSValue JSInspectorFrontendHost::showContextMenu(ExecState* exec) for (size_t i = 0; i < array->length(); ++i) { JSObject* item = asObject(array->getIndex(i)); JSValue label = item->get(exec, Identifier(exec, "label")); + JSValue type = item->get(exec, Identifier(exec, "type")); JSValue id = item->get(exec, Identifier(exec, "id")); - if (label.isUndefined() || id.isUndefined()) + JSValue enabled = item->get(exec, Identifier(exec, "enabled")); + JSValue checked = item->get(exec, Identifier(exec, "checked")); + if (!type.isString()) + continue; + + String typeString = ustringToString(type.toString(exec)); + if (typeString == "separator") { items.append(new ContextMenuItem(SeparatorType, ContextMenuItemCustomTagNoAction, String())); - else { + } else { ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(exec)); - items.append(new ContextMenuItem(ActionType, typedId, ustringToString(label.toString(exec)))); + ContextMenuItem* menuItem = new ContextMenuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, ustringToString(label.toString(exec))); + if (!enabled.isUndefined()) + menuItem->setEnabled(enabled.toBoolean(exec)); + if (!checked.isUndefined()) + menuItem->setChecked(checked.toBoolean(exec)); + items.append(menuItem); } } diff --git a/WebCore/bindings/js/JSNodeFilterCondition.cpp b/WebCore/bindings/js/JSNodeFilterCondition.cpp index b723286..b269e5f 100644 --- a/WebCore/bindings/js/JSNodeFilterCondition.cpp +++ b/WebCore/bindings/js/JSNodeFilterCondition.cpp @@ -23,6 +23,7 @@ #include "JSNode.h" #include "JSNodeFilter.h" #include "NodeFilter.h" +#include <runtime/Error.h> #include <runtime/JSLock.h> namespace WebCore { @@ -45,9 +46,7 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) { JSLock lock(SilenceAssertionsOnly); - CallData callData; - CallType callType = getCallData(m_filter, callData); - if (callType == CallTypeNone) + if (!m_filter.isObject()) return NodeFilter::FILTER_ACCEPT; // The exec argument here should only be null if this was called from a @@ -59,6 +58,18 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) if (!exec) return NodeFilter::FILTER_REJECT; + JSValue function = m_filter; + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) { + function = m_filter.get(exec, Identifier(exec, "acceptNode")); + callType = getCallData(function, callData); + if (callType == CallTypeNone) { + throwError(exec, createTypeError(exec, "NodeFilter object does not have an acceptNode function")); + return NodeFilter::FILTER_REJECT; + } + } + MarkedArgumentBuffer args; // FIXME: The node should have the prototype chain that came from its document, not // whatever prototype chain might be on the window this filter came from. Bug 27662 @@ -66,7 +77,7 @@ short JSNodeFilterCondition::acceptNode(JSC::ExecState* exec, Node* filterNode) if (exec->hadException()) return NodeFilter::FILTER_REJECT; - JSValue result = JSC::call(exec, m_filter, callType, callData, m_filter, args); + JSValue result = JSC::call(exec, function, callType, callData, m_filter, args); if (exec->hadException()) return NodeFilter::FILTER_REJECT; diff --git a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp index 0342ab6..4b31659 100644 --- a/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp +++ b/WebCore/bindings/js/JSWebGLRenderingContextCustom.cpp @@ -167,6 +167,8 @@ JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec) return throwSyntaxError(exec); ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info)) + return throwTypeError(exec); WebGLProgram* program = toWebGLProgram(exec->argument(0)); if (exec->hadException()) return jsUndefined(); @@ -238,6 +240,8 @@ JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* exec) ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info)) + return throwTypeError(exec); WebGLProgram* program = toWebGLProgram(exec->argument(0)); unsigned pname = exec->argument(1).toInt32(exec); if (exec->hadException()) @@ -262,6 +266,8 @@ JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec) ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLShader::s_info)) + return throwTypeError(exec); WebGLShader* shader = toWebGLShader(exec->argument(0)); unsigned pname = exec->argument(1).toInt32(exec); if (exec->hadException()) @@ -286,7 +292,11 @@ JSValue JSWebGLRenderingContext::getUniform(ExecState* exec) ExceptionCode ec = 0; WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl()); + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info)) + return throwTypeError(exec); WebGLProgram* program = toWebGLProgram(exec->argument(0)); + if (exec->argumentCount() > 1 && !exec->argument(1).isUndefinedOrNull() && !exec->argument(1).inherits(&JSWebGLUniformLocation::s_info)) + return throwTypeError(exec); WebGLUniformLocation* loc = toWebGLUniformLocation(exec->argument(1)); if (exec->hadException()) return jsUndefined(); @@ -354,9 +364,11 @@ static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, We WebGLUniformLocation* location = 0; long index = -1; - if (functionForUniform(f)) + if (functionForUniform(f)) { + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info)) + return throwTypeError(exec); location = toWebGLUniformLocation(exec->argument(0)); - else + } else index = exec->argument(0).toInt32(exec); if (exec->hadException()) @@ -439,6 +451,8 @@ static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, We if (exec->argumentCount() != 2) return throwSyntaxError(exec); + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info)) + return throwTypeError(exec); WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0)); if (exec->hadException()) @@ -502,6 +516,8 @@ static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecStat if (exec->argumentCount() != 3) return throwSyntaxError(exec); + if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info)) + return throwTypeError(exec); WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0)); if (exec->hadException()) diff --git a/WebCore/bindings/js/ScriptDebugServer.cpp b/WebCore/bindings/js/ScriptDebugServer.cpp index cd80de4..ecb7fa6 100644 --- a/WebCore/bindings/js/ScriptDebugServer.cpp +++ b/WebCore/bindings/js/ScriptDebugServer.cpp @@ -205,6 +205,11 @@ void ScriptDebugServer::pause() m_pauseOnNextStatement = true; } +void ScriptDebugServer::breakProgram() +{ + // FIXME(WK43332): implement this. +} + void ScriptDebugServer::continueProgram() { if (!m_paused) diff --git a/WebCore/bindings/js/ScriptDebugServer.h b/WebCore/bindings/js/ScriptDebugServer.h index fd8976b..432fe9a 100644 --- a/WebCore/bindings/js/ScriptDebugServer.h +++ b/WebCore/bindings/js/ScriptDebugServer.h @@ -79,6 +79,7 @@ public: void setPauseOnExceptionsState(PauseOnExceptionsState); void pause(); + void breakProgram(); void continueProgram(); void stepIntoStatement(); void stepOverStatement(); diff --git a/WebCore/bindings/js/ScriptProfiler.cpp b/WebCore/bindings/js/ScriptProfiler.cpp index f372c3c..62ae9ba 100644 --- a/WebCore/bindings/js/ScriptProfiler.cpp +++ b/WebCore/bindings/js/ScriptProfiler.cpp @@ -46,6 +46,11 @@ PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String& return ScriptProfile::create(profile); } +bool ScriptProfiler::isProfilerAlwaysEnabled() +{ + return false; +} + } // namespace WebCore #endif // ENABLE(JAVASCRIPT_DEBUGGER) diff --git a/WebCore/bindings/js/ScriptProfiler.h b/WebCore/bindings/js/ScriptProfiler.h index 4fa331c..180c49f 100644 --- a/WebCore/bindings/js/ScriptProfiler.h +++ b/WebCore/bindings/js/ScriptProfiler.h @@ -41,6 +41,7 @@ public: static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title); static void takeHeapSnapshot() { } static long getProfilerLogLines(long, String*) { return 0; } + static bool isProfilerAlwaysEnabled(); }; } // namespace WebCore diff --git a/WebCore/bindings/objc/DOM.mm b/WebCore/bindings/objc/DOM.mm index 008acec..c526123 100644 --- a/WebCore/bindings/objc/DOM.mm +++ b/WebCore/bindings/objc/DOM.mm @@ -377,7 +377,7 @@ id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget) WebCore::Frame* frame = node->document()->frame(); if (!frame) return nil; - return frame->nodeImage(node); + return frame->nodeImage(node).get(); } - (NSArray *)textRects diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm index 0b18d95..84e3919 100644 --- a/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -1963,6 +1963,20 @@ sub GenerateImplementation push(@implContent, " RefPtr<" . $parameter->type . "> $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n"); } } else { + # For functions with "StrictTypeChecking", if an input parameter's type does not match the signature, + # a TypeError is thrown instead of casting to null. + if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) { + my $argValue = "exec->argument($argsIndex)"; + my $argType = $codeGenerator->StripModule($parameter->type); + if (!IsNativeType($argType)) { + push(@implContent, " if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.inherits(&JS${argType}::s_info))\n"); + push(@implContent, " return throwVMTypeError(exec);\n"); + } elsif ($codeGenerator->IsStringType($argType)) { + push(@implContent, " if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.isString() && !${argValue}.isObject())\n"); + push(@implContent, " return throwVMTypeError(exec);\n"); + } + } + push(@implContent, " " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "exec->argument($argsIndex)") . ";\n"); # If a parameter is "an index" and it's negative it should throw an INDEX_SIZE_ERR exception. diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm index ebbcf8b..56838ca 100644 --- a/WebCore/bindings/scripts/CodeGeneratorV8.pm +++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm @@ -1245,6 +1245,23 @@ END } } else { $implIncludes{"V8BindingMacros.h"} = 1; + # For functions with "StrictTypeChecking", if an input parameter's type does not match the signature, + # a TypeError is thrown instead of casting to null. + if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) { + my $argValue = "args[$paramIndex]"; + my $argType = GetTypeFromSignature($parameter); + if (IsWrapperType($argType)) { + push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue)) {\n"); + push(@implContentDecls, " V8Proxy::throwTypeError();\n"); + push(@implContentDecls, " return notHandledByInterceptor();\n"); + push(@implContentDecls, " }\n"); + } elsif ($codeGenerator->IsStringType($argType)) { + push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !${argValue}->IsString() && !${argValue}->IsObject()) {\n"); + push(@implContentDecls, " V8Proxy::throwTypeError();\n"); + push(@implContentDecls, " return notHandledByInterceptor();\n"); + push(@implContentDecls, " }\n"); + } + } push(@implContentDecls, " EXCEPTION_BLOCK($nativeType, $parameterName, " . JSValueToNative($parameter, "args[$paramIndex]", BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ");\n"); } @@ -2988,7 +3005,10 @@ sub RequiresCustomSignature if (@{$function->{overloads}} > 1) { return 0; } - + # Type checking is performed in the generated code + if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) { + return 0; + } foreach my $parameter (@{$function->parameters}) { if ($parameter->extendedAttributes->{"Optional"} || $parameter->extendedAttributes->{"Callback"}) { return 0; diff --git a/WebCore/bindings/v8/ScriptDebugServer.cpp b/WebCore/bindings/v8/ScriptDebugServer.cpp index 0c24678..3f1a0c5 100644 --- a/WebCore/bindings/v8/ScriptDebugServer.cpp +++ b/WebCore/bindings/v8/ScriptDebugServer.cpp @@ -84,6 +84,7 @@ ScriptDebugServer::ScriptDebugServer() : m_pauseOnExceptionsState(DontPauseOnExceptions) , m_pausedPage(0) , m_enabled(true) + , m_breakpointsActivated(true) { } @@ -186,7 +187,7 @@ void ScriptDebugServer::clearBreakpoints() v8::Debug::Call(clearBreakpoints); } -void ScriptDebugServer::setBreakpointsActivated(bool enabled) +void ScriptDebugServer::setBreakpointsActivated(bool activated) { ensureDebuggerScriptCompiled(); v8::HandleScope scope; @@ -194,9 +195,11 @@ void ScriptDebugServer::setBreakpointsActivated(bool enabled) v8::Context::Scope contextScope(debuggerContext); v8::Local<v8::Object> args = v8::Object::New(); - args->Set(v8::String::New("enabled"), v8::Boolean::New(enabled)); + args->Set(v8::String::New("enabled"), v8::Boolean::New(activated)); v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpointsActivated"))); v8::Debug::Call(setBreakpointsActivated, args); + + m_breakpointsActivated = activated; } ScriptDebugServer::PauseOnExceptionsState ScriptDebugServer::pauseOnExceptionsState() @@ -228,6 +231,31 @@ void ScriptDebugServer::pause() v8::Debug::DebugBreak(); } +void ScriptDebugServer::breakProgram() +{ + DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, callbackTemplate, ()); + + if (!m_breakpointsActivated) + return; + + if (!v8::Context::InContext()) + return; + + if (callbackTemplate.IsEmpty()) { + callbackTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New()); + callbackTemplate->SetCallHandler(&ScriptDebugServer::breakProgramCallback); + } + + v8::Handle<v8::Context> context = v8::Context::GetCurrent(); + if (context.IsEmpty()) + return; + + m_pausedPageContext = *context; + v8::Handle<v8::Function> breakProgramFunction = callbackTemplate->GetFunction(); + v8::Debug::Call(breakProgramFunction); + m_pausedPageContext.Clear(); +} + void ScriptDebugServer::continueProgram() { if (m_pausedPage) @@ -323,6 +351,41 @@ void ScriptDebugServer::runPendingTasks() v8::Debug::ProcessDebugMessages(); } +v8::Handle<v8::Value> ScriptDebugServer::breakProgramCallback(const v8::Arguments& args) +{ + ASSERT(2 == args.Length()); + ScriptDebugServer::shared().breakProgram(v8::Handle<v8::Object>::Cast(args[0])); + return v8::Undefined(); +} + +void ScriptDebugServer::breakProgram(v8::Handle<v8::Object> executionState) +{ + // Don't allow nested breaks. + if (m_pausedPage) + return; + + Frame* frame = retrieveFrame(m_pausedPageContext); + if (!frame) + return; + + ScriptDebugListener* listener = m_listenersMap.get(frame->page()); + if (!listener) + return; + + m_executionState.set(executionState); + m_pausedPage = frame->page(); + ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedPageContext); + listener->didPause(currentCallFrameState); + + // Wait for continue or step command. + m_clientMessageLoop->run(m_pausedPage); + ASSERT(!m_pausedPage); + + // The listener may have been removed in the nested loop. + if (ScriptDebugListener* listener = m_listenersMap.get(frame->page())) + listener->didContinue(); +} + void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails) { ScriptDebugServer::shared().handleV8DebugEvent(eventDetails); @@ -365,21 +428,9 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD return; } - // Don't allow nested breaks. - if (m_pausedPage) - return; - m_executionState.set(eventDetails.GetExecutionState()); - m_pausedPage = frame->page(); - ScriptState* currentCallFrameState = mainWorldScriptState(frame); - listener->didPause(currentCallFrameState); - - // Wait for continue or step command. - m_clientMessageLoop->run(m_pausedPage); - ASSERT(!m_pausedPage); - - // The listener may have been removed in the nested loop. - if (ScriptDebugListener* listener = m_listenersMap.get(frame->page())) - listener->didContinue(); + m_pausedPageContext = *eventContext; + breakProgram(eventDetails.GetExecutionState()); + m_pausedPageContext.Clear(); } } } diff --git a/WebCore/bindings/v8/ScriptDebugServer.h b/WebCore/bindings/v8/ScriptDebugServer.h index a1e0a47..d1fd71f 100644 --- a/WebCore/bindings/v8/ScriptDebugServer.h +++ b/WebCore/bindings/v8/ScriptDebugServer.h @@ -71,6 +71,7 @@ public: void setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState); void pause(); + void breakProgram(); void continueProgram(); void stepIntoStatement(); void stepOverStatement(); @@ -111,6 +112,9 @@ private: ScriptDebugServer(); ~ScriptDebugServer() { } + static v8::Handle<v8::Value> breakProgramCallback(const v8::Arguments& args); + void breakProgram(v8::Handle<v8::Object> executionState); + static void v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails); void handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails); @@ -128,7 +132,10 @@ private: OwnHandle<v8::Object> m_executionState; OwnPtr<ClientMessageLoop> m_clientMessageLoop; Page* m_pausedPage; + v8::Local<v8::Context> m_pausedPageContext; bool m_enabled; + + bool m_breakpointsActivated; }; } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptProfiler.cpp b/WebCore/bindings/v8/ScriptProfiler.cpp index 9213774..0de4a24 100644 --- a/WebCore/bindings/v8/ScriptProfiler.cpp +++ b/WebCore/bindings/v8/ScriptProfiler.cpp @@ -69,4 +69,9 @@ long ScriptProfiler::getProfilerLogLines(long position, String* data) return position; } +bool ScriptProfiler::isProfilerAlwaysEnabled() +{ + return true; +} + } // namespace WebCore diff --git a/WebCore/bindings/v8/ScriptProfiler.h b/WebCore/bindings/v8/ScriptProfiler.h index 5c1054b..b1ab3b1 100644 --- a/WebCore/bindings/v8/ScriptProfiler.h +++ b/WebCore/bindings/v8/ScriptProfiler.h @@ -45,6 +45,7 @@ public: static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title); static void takeHeapSnapshot(); static long getProfilerLogLines(long position, String* data); + static bool isProfilerAlwaysEnabled(); }; } // namespace WebCore diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp index 8a72a3a..921f957 100644 --- a/WebCore/bindings/v8/V8DOMWrapper.cpp +++ b/WebCore/bindings/v8/V8DOMWrapper.cpp @@ -51,6 +51,7 @@ #include "V8HTMLCollection.h" #include "V8HTMLDocument.h" #include "V8IDBRequest.h" +#include "V8IDBTransaction.h" #include "V8IsolatedContext.h" #include "V8Location.h" #include "V8MessageChannel.h" @@ -221,9 +222,6 @@ PassRefPtr<NodeFilter> V8DOMWrapper::wrapNativeNodeFilter(v8::Handle<v8::Value> // to NodeFilter. NodeFilter has a ref counted pointer to NodeFilterCondition. // In NodeFilterCondition, filter object is persisted in its constructor, // and disposed in its destructor. - if (!filter->IsFunction()) - return 0; - return NodeFilter::create(V8NodeFilterCondition::create(filter)); } @@ -382,6 +380,8 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta #if ENABLE(INDEXED_DATABASE) if (IDBRequest* idbRequest = target->toIDBRequest()) return toV8(idbRequest); + if (IDBTransaction* idbTransaction = target->toIDBTransaction()) + return toV8(idbTransaction); #endif #if ENABLE(WEB_SOCKETS) diff --git a/WebCore/bindings/v8/V8HiddenPropertyName.h b/WebCore/bindings/v8/V8HiddenPropertyName.h index 2d0e8d6..7867b36 100644 --- a/WebCore/bindings/v8/V8HiddenPropertyName.h +++ b/WebCore/bindings/v8/V8HiddenPropertyName.h @@ -40,10 +40,12 @@ namespace WebCore { V(listener) \ V(attributeListener) \ V(scriptState) \ + V(devtoolsInjectedScript) \ V(sleepFunction) \ V(toStringString) \ V(event) + class V8HiddenPropertyName { public: #define V8_DECLARE_PROPERTY(name) static v8::Handle<v8::String> name(); diff --git a/WebCore/bindings/v8/V8NodeFilterCondition.cpp b/WebCore/bindings/v8/V8NodeFilterCondition.cpp index 2170698..4e0240d 100644 --- a/WebCore/bindings/v8/V8NodeFilterCondition.cpp +++ b/WebCore/bindings/v8/V8NodeFilterCondition.cpp @@ -62,13 +62,24 @@ short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const { ASSERT(v8::Context::InContext()); - if (!m_filter->IsFunction()) + if (!m_filter->IsObject()) return NodeFilter::FILTER_ACCEPT; v8::TryCatch exceptionCatcher; + v8::Handle<v8::Function> callback; + if (m_filter->IsFunction()) + callback = v8::Handle<v8::Function>::Cast(m_filter); + else { + v8::Local<v8::Value> value = m_filter->ToObject()->Get(v8::String::New("acceptNode")); + if (!value->IsFunction()) { + V8Proxy::throwError(V8Proxy::TypeError, "NodeFilter object does not have an acceptNode function"); + return NodeFilter::FILTER_REJECT; + } + callback = v8::Handle<v8::Function>::Cast(value); + } + v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global(); - v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(m_filter); OwnArrayPtr<v8::Handle<v8::Value> > args(new v8::Handle<v8::Value>[1]); args[0] = toV8(node); diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp index 50e9fdc..5d3eeb8 100644 --- a/WebCore/bindings/v8/V8Proxy.cpp +++ b/WebCore/bindings/v8/V8Proxy.cpp @@ -37,6 +37,8 @@ #include "DocumentLoader.h" #include "Frame.h" #include "FrameLoaderClient.h" +#include "IDBFactoryBackendInterface.h" +#include "IDBPendingTransactionMonitor.h" #include "InspectorTimelineAgent.h" #include "Page.h" #include "PageGroup.h" @@ -487,7 +489,7 @@ v8::Local<v8::Value> V8Proxy::runScriptInternal(v8::Handle<v8::Script> script, b } // Release the storage mutex if applicable. - releaseStorageMutex(); + didLeaveScriptContext(); if (handleOutOfMemory()) ASSERT(result.IsEmpty()); @@ -563,7 +565,7 @@ v8::Local<v8::Value> V8Proxy::callFunction(v8::Handle<v8::Function> function, v8 } // Release the storage mutex if applicable. - releaseStorageMutex(); + didLeaveScriptContext(); if (v8::V8::IsDead()) handleFatalErrorInV8(); @@ -675,16 +677,24 @@ void V8Proxy::disconnectFrame() { } -void V8Proxy::releaseStorageMutex() +void V8Proxy::didLeaveScriptContext() { + Page* page = m_frame->page(); + if (!page) + return; + // If we've just left a script context and indexed database has been + // instantiated, we must let its transaction coordinator know so it can terminate + // any not-yet-started transactions. + if (IDBPendingTransactionMonitor::hasPendingTransactions()) { + ASSERT(page->group().hasIDBFactory()); + page->group().idbFactory()->abortPendingTransactions(IDBPendingTransactionMonitor::pendingTransactions()); + IDBPendingTransactionMonitor::clearPendingTransactions(); + } // 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(); } diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h index 94ff17c..ca3920b 100644 --- a/WebCore/bindings/v8/V8Proxy.h +++ b/WebCore/bindings/v8/V8Proxy.h @@ -346,9 +346,7 @@ namespace WebCore { static void reportUnsafeAccessTo(Frame* target, DelayReporting delay); private: - // If m_recursionCount is 0, let LocalStorage know so we can release - // the storage mutex. - void releaseStorageMutex(); + void didLeaveScriptContext(); void resetIsolatedWorlds(); diff --git a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp index 1b069cf..b3007a4 100644 --- a/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp +++ b/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp @@ -46,6 +46,7 @@ #include "V8BindingState.h" #include "V8DOMWindow.h" #include "V8Database.h" +#include "V8HiddenPropertyName.h" #include "V8JavaScriptCallFrame.h" #include "V8Node.h" #include "V8Proxy.h" @@ -120,6 +121,21 @@ ScriptObject InjectedScriptHost::createInjectedScript(const String& scriptSource return ScriptObject(inspectedScriptState, injectedScript); } +void InjectedScriptHost::discardInjectedScript(ScriptState* inspectedScriptState) +{ + v8::HandleScope handleScope; + v8::Local<v8::Context> context = inspectedScriptState->context(); + v8::Context::Scope contextScope(context); + + v8::Local<v8::Object> global = context->Global(); + // Skip proxy object. The proxy object will survive page navigation while we need + // an object whose lifetime consides with that of the inspected context. + global = v8::Local<v8::Object>::Cast(global->GetPrototype()); + + v8::Handle<v8::String> key = V8HiddenPropertyName::devtoolsInjectedScript(); + global->DeleteHiddenValue(key); +} + v8::Handle<v8::Value> V8InjectedScriptHost::nodeForIdCallback(const v8::Arguments& args) { INC_STATS("InjectedScriptHost.nodeForId()"); @@ -206,7 +222,7 @@ InjectedScript InjectedScriptHost::injectedScriptFor(ScriptState* inspectedScrip // an object whose lifetime consides with that of the inspected context. global = v8::Local<v8::Object>::Cast(global->GetPrototype()); - v8::Local<v8::String> key = v8::String::New("Devtools_InjectedScript"); + 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))); diff --git a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp index 7733a70..25b9010 100644 --- a/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp +++ b/WebCore/bindings/v8/custom/V8InspectorFrontendHostCustom.cpp @@ -33,6 +33,7 @@ #include "InspectorController.h" #include "InspectorFrontendHost.h" +#include "PlatformString.h" #include "V8Binding.h" #include "V8MouseEvent.h" @@ -76,18 +77,26 @@ v8::Handle<v8::Value> V8InspectorFrontendHost::showContextMenuCallback(const v8: for (size_t i = 0; i < array->Length(); ++i) { v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i))); - v8::Local<v8::Value> label = item->Get(v8::String::New("label")); + v8::Local<v8::Value> type = item->Get(v8::String::New("type")); v8::Local<v8::Value> id = item->Get(v8::String::New("id")); - if (label->IsUndefined() || id->IsUndefined()) { - items.append(new ContextMenuItem(SeparatorType, - ContextMenuItemCustomTagNoAction, - String())); + v8::Local<v8::Value> label = item->Get(v8::String::New("label")); + v8::Local<v8::Value> enabled = item->Get(v8::String::New("enabled")); + v8::Local<v8::Value> checked = item->Get(v8::String::New("checked")); + if (!type->IsString()) + continue; + String typeString = toWebCoreStringWithNullCheck(type); + if (typeString == "separator") { + items.append(new ContextMenuItem(SeparatorType, + ContextMenuItemCustomTagNoAction, + String())); } else { - ContextMenuAction typedId = static_cast<ContextMenuAction>( - ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); - items.append(new ContextMenuItem(ActionType, - typedId, - toWebCoreStringWithNullCheck(label))); + ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); + ContextMenuItem* menuItem = new ContextMenuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, toWebCoreStringWithNullCheck(label)); + if (checked->IsBoolean()) + menuItem->setChecked(checked->ToBoolean()->Value()); + if (enabled->IsBoolean()) + menuItem->setEnabled(enabled->ToBoolean()->Value()); + items.append(menuItem); } } diff --git a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp index fd6e120..9346a05 100644 --- a/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp +++ b/WebCore/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp @@ -227,6 +227,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const ExceptionCode ec = 0; WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0; Vector<WebGLShader*> shaders; bool succeed = context->getAttachedShaders(program, shaders, ec); @@ -319,6 +323,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getProgramParameterCallback(const ExceptionCode ec = 0; WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0; bool ok; unsigned pname = toInt32(args[1], ok); @@ -351,6 +359,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getShaderParameterCallback(const ExceptionCode ec = 0; WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLShader::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0; bool ok; unsigned pname = toInt32(args[1], ok); @@ -383,8 +395,16 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Argu ExceptionCode ec = 0; WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0; + if (args.Length() > 1 && !isUndefinedOrNull(args[1]) && !V8WebGLUniformLocation::HasInstance(args[1])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } bool ok = false; WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok); @@ -452,8 +472,13 @@ static v8::Handle<v8::Value> vertexAttribAndUniformHelperf(const v8::Arguments& if (isFunctionToCallForAttribute(functionToCall)) index = toInt32(args[0], ok); - else + else { + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } location = toWebGLUniformLocation(args[0], ok); + } WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); @@ -526,6 +551,10 @@ static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args, } WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } bool ok = false; WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok); @@ -639,6 +668,10 @@ static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args, WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder()); + if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) { + V8Proxy::throwTypeError(); + return notHandledByInterceptor(); + } bool ok = false; WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok); |