Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/inspector/ThreadDebugger.h" | 5 #include "core/inspector/ThreadDebugger.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptCallStack.h" | 7 #include "bindings/core/v8/ScriptCallStack.h" |
| 8 #include "bindings/core/v8/ScriptValue.h" | 8 #include "bindings/core/v8/ScriptValue.h" |
| 9 #include "bindings/core/v8/V8Binding.h" | 9 #include "bindings/core/v8/V8Binding.h" |
| 10 #include "bindings/core/v8/V8DOMException.h" | 10 #include "bindings/core/v8/V8DOMException.h" |
| 11 #include "bindings/core/v8/V8DOMTokenList.h" | 11 #include "bindings/core/v8/V8DOMTokenList.h" |
| 12 #include "bindings/core/v8/V8Event.h" | |
| 13 #include "bindings/core/v8/V8EventListener.h" | |
| 14 #include "bindings/core/v8/V8EventListenerList.h" | |
| 12 #include "bindings/core/v8/V8HTMLAllCollection.h" | 15 #include "bindings/core/v8/V8HTMLAllCollection.h" |
| 13 #include "bindings/core/v8/V8HTMLCollection.h" | 16 #include "bindings/core/v8/V8HTMLCollection.h" |
| 14 #include "bindings/core/v8/V8Node.h" | 17 #include "bindings/core/v8/V8Node.h" |
| 15 #include "bindings/core/v8/V8NodeList.h" | 18 #include "bindings/core/v8/V8NodeList.h" |
| 16 #include "core/inspector/ConsoleMessage.h" | 19 #include "core/inspector/ConsoleMessage.h" |
| 17 #include "core/inspector/InspectorDOMDebuggerAgent.h" | 20 #include "core/inspector/InspectorDOMDebuggerAgent.h" |
| 18 #include "core/inspector/InspectorTraceEvents.h" | 21 #include "core/inspector/InspectorTraceEvents.h" |
| 19 #include "core/inspector/ScriptArguments.h" | 22 #include "core/inspector/ScriptArguments.h" |
| 20 #include "platform/ScriptForbiddenScope.h" | 23 #include "platform/ScriptForbiddenScope.h" |
| 21 #include "wtf/CurrentTime.h" | 24 #include "wtf/CurrentTime.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 110 if (object->InternalFieldCount() < v8DefaultWrapperInternalFieldCount) | 113 if (object->InternalFieldCount() < v8DefaultWrapperInternalFieldCount) |
| 111 return true; | 114 return true; |
| 112 v8::Local<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIn dex); | 115 v8::Local<v8::Value> wrapper = object->GetInternalField(v8DOMWrapperObjectIn dex); |
| 113 // Skip wrapper boilerplates which are like regular wrappers but don't have | 116 // Skip wrapper boilerplates which are like regular wrappers but don't have |
| 114 // native object. | 117 // native object. |
| 115 if (!wrapper.IsEmpty() && wrapper->IsUndefined()) | 118 if (!wrapper.IsEmpty() && wrapper->IsUndefined()) |
| 116 return false; | 119 return false; |
| 117 return true; | 120 return true; |
| 118 } | 121 } |
| 119 | 122 |
| 123 static void returnDataCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | |
| 124 { | |
| 125 info.GetReturnValue().Set(info.Data()); | |
| 126 } | |
| 127 | |
| 128 void ThreadDebugger::createFunctionProperty(v8::Local<v8::Context> context, v8:: Local<v8::Object> object, const char* name, v8::FunctionCallback callback, const char* description) | |
| 129 { | |
| 130 v8::Local<v8::String> funcName = v8String(context->GetIsolate(), name); | |
| 131 v8::Local<v8::Function> func; | |
| 132 if (!v8::Function::New(context, callback, v8::External::New(context->GetIsol ate(), this)).ToLocal(&func)) | |
| 133 return; | |
| 134 func->SetName(funcName); | |
| 135 v8::Local<v8::String> returnValue = v8String(context->GetIsolate(), descript ion); | |
| 136 v8::Local<v8::Function> toStringFunction; | |
| 137 if (v8::Function::New(context, returnDataCallback, returnValue).ToLocal(&toS tringFunction)) | |
| 138 func->Set(v8String(context->GetIsolate(), "toString"), toStringFunction) ; | |
| 139 if (!object->Set(context, funcName, func).FromMaybe(false)) | |
| 140 return; | |
| 141 } | |
| 142 | |
| 143 bool ThreadDebugger::isCommandLineAPIMethod(const String& name) | |
| 144 { | |
| 145 DEFINE_STATIC_LOCAL(HashSet<String>, methods, ()); | |
| 146 if (methods.size() == 0) { | |
| 147 const char* members[] = { "monitorEvents", "unmonitorEvents" }; | |
| 148 for (size_t i = 0; i < WTF_ARRAY_LENGTH(members); ++i) | |
| 149 methods.add(members[i]); | |
| 150 } | |
| 151 return methods.find(name) != methods.end() || V8Debugger::isCommandLineAPIMe thod(name); | |
| 152 } | |
| 153 | |
| 154 void ThreadDebugger::installAdditionalCommandLineAPI(v8::Local<v8::Context> cont ext, v8::Local<v8::Object> object) | |
| 155 { | |
| 156 createFunctionProperty(context, object, "monitorEvents", ThreadDebugger::mon itorEventsCallback, "function monitorEvents(object, [types]) { [Command Line API ] }"); | |
| 157 createFunctionProperty(context, object, "unmonitorEvents", ThreadDebugger::u nmonitorEventsCallback, "function unmonitorEvents(object, [types]) { [Command Li ne API] }"); | |
| 158 } | |
| 159 | |
| 160 static Vector<String> normalizeEventTypes(const v8::FunctionCallbackInfo<v8::Val ue>& info) | |
| 161 { | |
| 162 v8::Isolate* isolate = info.GetIsolate(); | |
|
dgozman
2016/05/20 22:12:04
nit: inline this.
kozy
2016/05/20 22:42:17
Done.
| |
| 163 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | |
| 164 | |
| 165 Vector<String> types; | |
| 166 if (info.Length() > 1 && info[1]->IsString()) | |
| 167 types.append(toCoreString(info[1].As<v8::String>())); | |
| 168 if (info.Length() > 1 && info[1]->IsArray()) { | |
| 169 v8::Local<v8::Array> typesArray = v8::Local<v8::Array>::Cast(info[1]); | |
| 170 for (size_t i = 0; i < typesArray->Length(); ++i) { | |
| 171 v8::Local<v8::Value> typeValue; | |
| 172 if (!typesArray->Get(context, i).ToLocal(&typeValue) || !typeValue-> IsString()) | |
| 173 continue; | |
| 174 types.append(toCoreString(v8::Local<v8::String>::Cast(typeValue))); | |
| 175 } | |
| 176 } | |
| 177 if (info.Length() == 1) | |
| 178 types.appendVector(Vector<String>({ "mouse", "key", "touch", "pointer", "control", "load", "unload", "abort", "error", "select", "input", "change", "sub mit", "reset", "focus", "blur", "resize", "scroll", "search", "devicemotion", "d eviceorientation" })); | |
| 179 | |
| 180 Vector<String> outputTypes; | |
| 181 for (size_t i = 0; i < types.size(); ++i) { | |
| 182 if (types[i] == "mouse") | |
| 183 outputTypes.appendVector(Vector<String>({ "click", "dblclick", "mous edown", "mouseeenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mous eup", "mouseleave", "mousewheel" })); | |
| 184 else if (types[i] == "key") | |
| 185 outputTypes.appendVector(Vector<String>({ "keydown", "keyup", "keypr ess", "textInput" })); | |
| 186 else if (types[i] == "touch") | |
| 187 outputTypes.appendVector(Vector<String>({ "touchstart", "touchmove", "touchend", "touchcancel" })); | |
| 188 else if (types[i] == "pointer") | |
| 189 outputTypes.appendVector(Vector<String>({ "pointerover", "pointerout ", "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "p ointercancel", "gotpointercapture", "lostpointercapture" })); | |
| 190 else if (types[i] == "control") | |
| 191 outputTypes.appendVector(Vector<String>({ "resize", "scroll", "zoom" , "focus", "blur", "select", "input", "change", "submit", "reset" })); | |
| 192 else | |
| 193 outputTypes.append(types[i]); | |
| 194 } | |
| 195 return outputTypes; | |
| 196 } | |
| 197 | |
| 198 void ThreadDebugger::logCallback(const v8::FunctionCallbackInfo<v8::Value>& info ) | |
| 199 { | |
| 200 if (info.Length() < 1) | |
| 201 return; | |
| 202 ThreadDebugger* debugger = static_cast<ThreadDebugger*>(v8::Local<v8::Extern al>::Cast(info.Data())->Value()); | |
| 203 if (!debugger) | |
|
dgozman
2016/05/20 22:12:04
DCHECK(debugger)
kozy
2016/05/20 22:42:17
Done.
| |
| 204 return; | |
| 205 Event* event = V8Event::toImplWithTypeCheck(info.GetIsolate(), info[0]); | |
| 206 if (!event) | |
| 207 return; | |
| 208 | |
| 209 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); | |
| 210 ScriptState* scriptState = ScriptState::from(context); | |
| 211 DCHECK(scriptState->contextIsValid()); | |
| 212 Vector<ScriptValue> arguments = Vector<ScriptValue>({ | |
|
dgozman
2016/05/20 22:12:04
Is this the right formatting? Looks strange, but I
kozy
2016/05/20 22:42:17
Acknowledged.
| |
| 213 ScriptValue(scriptState, v8String(info.GetIsolate(), event->type())), | |
| 214 ScriptValue(scriptState, info[0]) | |
| 215 }); | |
| 216 | |
| 217 ConsoleMessage* consoleMessage = ConsoleMessage::create(ConsoleAPIMessageSou rce, LogMessageLevel, event->type()); | |
| 218 consoleMessage->setType(LogMessageType); | |
| 219 consoleMessage->setScriptState(scriptState); | |
| 220 consoleMessage->setScriptArguments(ScriptArguments::create(scriptState, argu ments)); | |
| 221 debugger->reportMessageToConsole(context, consoleMessage); | |
| 222 } | |
| 223 | |
| 224 v8::Local<v8::Function> ThreadDebugger::eventLogFunction() | |
| 225 { | |
| 226 if (m_eventLogFunction.IsEmpty()) | |
| 227 m_eventLogFunction.Reset(m_isolate, v8::Function::New(m_isolate, logCall back, v8::External::New(m_isolate, this))); | |
| 228 return m_eventLogFunction.Get(m_isolate); | |
| 229 } | |
| 230 | |
| 231 static EventTarget* firstArgumentAsEventTarget(const v8::FunctionCallbackInfo<v8 ::Value>& info) | |
| 232 { | |
| 233 if (info.Length() < 1) | |
| 234 return nullptr; | |
| 235 if (EventTarget* target = V8EventTarget::toImplWithTypeCheck(info.GetIsolat e(), info[0])) | |
|
dgozman
2016/05/20 22:12:04
style: two spaces after =
kozy
2016/05/20 22:42:17
Done.
| |
| 236 return target; | |
| 237 return toDOMWindow(info.GetIsolate(), info[0]); | |
| 238 } | |
| 239 | |
| 240 void ThreadDebugger::setMonitorEventsCallback(const v8::FunctionCallbackInfo<v8: :Value>& info, bool enabled) | |
| 241 { | |
| 242 EventTarget* eventTarget = firstArgumentAsEventTarget(info); | |
| 243 if (!eventTarget) | |
| 244 return; | |
| 245 Vector<String> types = normalizeEventTypes(info); | |
| 246 ThreadDebugger* debugger = static_cast<ThreadDebugger*>(v8::Local<v8::Extern al>::Cast(info.Data())->Value()); | |
| 247 DCHECK(debugger); | |
| 248 EventListener* eventListener = V8EventListenerList::getEventListener(ScriptS tate::current(info.GetIsolate()), debugger->eventLogFunction(), false, enabled ? ListenerFindOrCreate : ListenerFindOnly); | |
| 249 if (!eventListener) | |
| 250 return; | |
| 251 for (size_t i = 0; i < types.size(); ++i) { | |
| 252 if (enabled) | |
| 253 eventTarget->addEventListener(AtomicString(types[i]), eventListener, false); | |
| 254 else | |
| 255 eventTarget->removeEventListener(AtomicString(types[i]), eventListen er, false); | |
| 256 } | |
| 257 } | |
| 258 | |
| 120 void ThreadDebugger::reportMessageToConsole(v8::Local<v8::Context> context, Mess ageType type, MessageLevel level, const String16& message, const v8::FunctionCal lbackInfo<v8::Value>* arguments, unsigned skipArgumentCount) | 259 void ThreadDebugger::reportMessageToConsole(v8::Local<v8::Context> context, Mess ageType type, MessageLevel level, const String16& message, const v8::FunctionCal lbackInfo<v8::Value>* arguments, unsigned skipArgumentCount) |
| 121 { | 260 { |
| 122 ScriptState* scriptState = ScriptState::from(context); | 261 ScriptState* scriptState = ScriptState::from(context); |
| 123 ScriptArguments* scriptArguments = nullptr; | 262 ScriptArguments* scriptArguments = nullptr; |
| 124 if (arguments && scriptState->contextIsValid()) | 263 if (arguments && scriptState->contextIsValid()) |
| 125 scriptArguments = ScriptArguments::create(scriptState, *arguments, skipA rgumentCount); | 264 scriptArguments = ScriptArguments::create(scriptState, *arguments, skipA rgumentCount); |
| 126 String messageText = message; | 265 String messageText = message; |
| 127 if (messageText.isEmpty() && scriptArguments) | 266 if (messageText.isEmpty() && scriptArguments) |
| 128 scriptArguments->getFirstArgumentAsString(messageText); | 267 scriptArguments->getFirstArgumentAsString(messageText); |
| 129 | 268 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 { | 318 { |
| 180 for (size_t index = 0; index < m_timers.size(); ++index) { | 319 for (size_t index = 0; index < m_timers.size(); ++index) { |
| 181 if (m_timers[index] == timer) { | 320 if (m_timers[index] == timer) { |
| 182 m_timerCallbacks[index](m_timerData[index]); | 321 m_timerCallbacks[index](m_timerData[index]); |
| 183 return; | 322 return; |
| 184 } | 323 } |
| 185 } | 324 } |
| 186 } | 325 } |
| 187 | 326 |
| 188 } // namespace blink | 327 } // namespace blink |
| OLD | NEW |