| 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 Vector<String> types; |
| 163 if (info.Length() > 1 && info[1]->IsString()) |
| 164 types.append(toCoreString(info[1].As<v8::String>())); |
| 165 if (info.Length() > 1 && info[1]->IsArray()) { |
| 166 v8::Local<v8::Array> typesArray = v8::Local<v8::Array>::Cast(info[1]); |
| 167 for (size_t i = 0; i < typesArray->Length(); ++i) { |
| 168 v8::Local<v8::Value> typeValue; |
| 169 if (!typesArray->Get(info.GetIsolate()->GetCurrentContext(), i).ToLo
cal(&typeValue) || !typeValue->IsString()) |
| 170 continue; |
| 171 types.append(toCoreString(v8::Local<v8::String>::Cast(typeValue))); |
| 172 } |
| 173 } |
| 174 if (info.Length() == 1) |
| 175 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" })); |
| 176 |
| 177 Vector<String> outputTypes; |
| 178 for (size_t i = 0; i < types.size(); ++i) { |
| 179 if (types[i] == "mouse") |
| 180 outputTypes.appendVector(Vector<String>({ "click", "dblclick", "mous
edown", "mouseeenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mous
eup", "mouseleave", "mousewheel" })); |
| 181 else if (types[i] == "key") |
| 182 outputTypes.appendVector(Vector<String>({ "keydown", "keyup", "keypr
ess", "textInput" })); |
| 183 else if (types[i] == "touch") |
| 184 outputTypes.appendVector(Vector<String>({ "touchstart", "touchmove",
"touchend", "touchcancel" })); |
| 185 else if (types[i] == "pointer") |
| 186 outputTypes.appendVector(Vector<String>({ "pointerover", "pointerout
", "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "p
ointercancel", "gotpointercapture", "lostpointercapture" })); |
| 187 else if (types[i] == "control") |
| 188 outputTypes.appendVector(Vector<String>({ "resize", "scroll", "zoom"
, "focus", "blur", "select", "input", "change", "submit", "reset" })); |
| 189 else |
| 190 outputTypes.append(types[i]); |
| 191 } |
| 192 return outputTypes; |
| 193 } |
| 194 |
| 195 void ThreadDebugger::logCallback(const v8::FunctionCallbackInfo<v8::Value>& info
) |
| 196 { |
| 197 if (info.Length() < 1) |
| 198 return; |
| 199 ThreadDebugger* debugger = static_cast<ThreadDebugger*>(v8::Local<v8::Extern
al>::Cast(info.Data())->Value()); |
| 200 DCHECK(debugger); |
| 201 Event* event = V8Event::toImplWithTypeCheck(info.GetIsolate(), info[0]); |
| 202 if (!event) |
| 203 return; |
| 204 |
| 205 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); |
| 206 ScriptState* scriptState = ScriptState::from(context); |
| 207 DCHECK(scriptState->contextIsValid()); |
| 208 Vector<ScriptValue> arguments = Vector<ScriptValue>({ |
| 209 ScriptValue(scriptState, v8String(info.GetIsolate(), event->type())), |
| 210 ScriptValue(scriptState, info[0]) |
| 211 }); |
| 212 |
| 213 ConsoleMessage* consoleMessage = ConsoleMessage::create(ConsoleAPIMessageSou
rce, LogMessageLevel, event->type()); |
| 214 consoleMessage->setType(LogMessageType); |
| 215 consoleMessage->setScriptState(scriptState); |
| 216 consoleMessage->setScriptArguments(ScriptArguments::create(scriptState, argu
ments)); |
| 217 debugger->reportMessageToConsole(context, consoleMessage); |
| 218 } |
| 219 |
| 220 v8::Local<v8::Function> ThreadDebugger::eventLogFunction() |
| 221 { |
| 222 if (m_eventLogFunction.IsEmpty()) |
| 223 m_eventLogFunction.Reset(m_isolate, v8::Function::New(m_isolate, logCall
back, v8::External::New(m_isolate, this))); |
| 224 return m_eventLogFunction.Get(m_isolate); |
| 225 } |
| 226 |
| 227 static EventTarget* firstArgumentAsEventTarget(const v8::FunctionCallbackInfo<v8
::Value>& info) |
| 228 { |
| 229 if (info.Length() < 1) |
| 230 return nullptr; |
| 231 if (EventTarget* target = V8EventTarget::toImplWithTypeCheck(info.GetIsolate
(), info[0])) |
| 232 return target; |
| 233 return toDOMWindow(info.GetIsolate(), info[0]); |
| 234 } |
| 235 |
| 236 void ThreadDebugger::setMonitorEventsCallback(const v8::FunctionCallbackInfo<v8:
:Value>& info, bool enabled) |
| 237 { |
| 238 EventTarget* eventTarget = firstArgumentAsEventTarget(info); |
| 239 if (!eventTarget) |
| 240 return; |
| 241 Vector<String> types = normalizeEventTypes(info); |
| 242 ThreadDebugger* debugger = static_cast<ThreadDebugger*>(v8::Local<v8::Extern
al>::Cast(info.Data())->Value()); |
| 243 DCHECK(debugger); |
| 244 EventListener* eventListener = V8EventListenerList::getEventListener(ScriptS
tate::current(info.GetIsolate()), debugger->eventLogFunction(), false, enabled ?
ListenerFindOrCreate : ListenerFindOnly); |
| 245 if (!eventListener) |
| 246 return; |
| 247 for (size_t i = 0; i < types.size(); ++i) { |
| 248 if (enabled) |
| 249 eventTarget->addEventListener(AtomicString(types[i]), eventListener,
false); |
| 250 else |
| 251 eventTarget->removeEventListener(AtomicString(types[i]), eventListen
er, false); |
| 252 } |
| 253 } |
| 254 |
| 255 // static |
| 256 void ThreadDebugger::monitorEventsCallback(const v8::FunctionCallbackInfo<v8::Va
lue>& info) |
| 257 { |
| 258 setMonitorEventsCallback(info, true); |
| 259 } |
| 260 |
| 261 // static |
| 262 void ThreadDebugger::unmonitorEventsCallback(const v8::FunctionCallbackInfo<v8::
Value>& info) |
| 263 { |
| 264 setMonitorEventsCallback(info, false); |
| 265 } |
| 266 |
| 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) | 267 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 { | 268 { |
| 122 ScriptState* scriptState = ScriptState::from(context); | 269 ScriptState* scriptState = ScriptState::from(context); |
| 123 ScriptArguments* scriptArguments = nullptr; | 270 ScriptArguments* scriptArguments = nullptr; |
| 124 if (arguments && scriptState->contextIsValid()) | 271 if (arguments && scriptState->contextIsValid()) |
| 125 scriptArguments = ScriptArguments::create(scriptState, *arguments, skipA
rgumentCount); | 272 scriptArguments = ScriptArguments::create(scriptState, *arguments, skipA
rgumentCount); |
| 126 String messageText = message; | 273 String messageText = message; |
| 127 if (messageText.isEmpty() && scriptArguments) | 274 if (messageText.isEmpty() && scriptArguments) |
| 128 scriptArguments->getFirstArgumentAsString(messageText); | 275 scriptArguments->getFirstArgumentAsString(messageText); |
| 129 | 276 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 { | 326 { |
| 180 for (size_t index = 0; index < m_timers.size(); ++index) { | 327 for (size_t index = 0; index < m_timers.size(); ++index) { |
| 181 if (m_timers[index] == timer) { | 328 if (m_timers[index] == timer) { |
| 182 m_timerCallbacks[index](m_timerData[index]); | 329 m_timerCallbacks[index](m_timerData[index]); |
| 183 return; | 330 return; |
| 184 } | 331 } |
| 185 } | 332 } |
| 186 } | 333 } |
| 187 | 334 |
| 188 } // namespace blink | 335 } // namespace blink |
| OLD | NEW |