1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "config.h" 31 #include "InspectorFrontend.h" 32 33 #if ENABLE(INSPECTOR) 34 35 #include "ConsoleMessage.h" 36 #include "Frame.h" 37 #include "InjectedScript.h" 38 #include "InjectedScriptHost.h" 39 #include "InspectorController.h" 40 #include "Node.h" 41 #include "ScriptFunctionCall.h" 42 #include "ScriptObject.h" 43 #include "ScriptState.h" 44 #include "ScriptString.h" 45 #include "ScriptValue.h" 46 #include "SerializedScriptValue.h" 47 #include <wtf/OwnPtr.h> 48 49 #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) 50 #include <parser/SourceCode.h> 51 #include <runtime/JSValue.h> 52 #include <runtime/UString.h> 53 #endif 54 55 namespace WebCore { 56 57 InspectorFrontend::InspectorFrontend(InspectorController* inspectorController, ScriptObject webInspector) 58 : m_inspectorController(inspectorController) 59 , m_webInspector(webInspector) 60 { 61 } 62 63 InspectorFrontend::~InspectorFrontend() 64 { 65 m_webInspector = ScriptObject(); 66 } 67 68 ScriptArray InspectorFrontend::newScriptArray() 69 { 70 return ScriptArray::createNew(scriptState()); 71 } 72 73 ScriptObject InspectorFrontend::newScriptObject() 74 { 75 return ScriptObject::createNew(scriptState()); 76 } 77 78 void InspectorFrontend::didCommitLoad() 79 { 80 callSimpleFunction("didCommitLoad"); 81 } 82 83 void InspectorFrontend::populateFrontendSettings(const String& settings) 84 { 85 ScriptFunctionCall function(m_webInspector, "dispatch"); 86 function.appendArgument("populateFrontendSettings"); 87 function.appendArgument(settings); 88 function.call(); 89 } 90 91 void InspectorFrontend::updateConsoleMessageExpiredCount(unsigned count) 92 { 93 ScriptFunctionCall function(m_webInspector, "dispatch"); 94 function.appendArgument("updateConsoleMessageExpiredCount"); 95 function.appendArgument(count); 96 function.call(); 97 } 98 99 void InspectorFrontend::addConsoleMessage(const ScriptObject& messageObj, const Vector<ScriptString>& frames, ScriptState* scriptState, const Vector<ScriptValue> arguments, const String& message) 100 { 101 ScriptFunctionCall function(m_webInspector, "dispatch"); 102 function.appendArgument("addConsoleMessage"); 103 function.appendArgument(messageObj); 104 if (!frames.isEmpty()) { 105 for (unsigned i = 0; i < frames.size(); ++i) 106 function.appendArgument(frames[i]); 107 } else if (!arguments.isEmpty()) { 108 InjectedScript injectedScript = m_inspectorController->injectedScriptHost()->injectedScriptFor(scriptState); 109 for (unsigned i = 0; i < arguments.size(); ++i) { 110 RefPtr<SerializedScriptValue> serializedValue = injectedScript.wrapForConsole(arguments[i]); 111 ScriptValue scriptValue = ScriptValue::deserialize(this->scriptState(), serializedValue.get()); 112 if (scriptValue.hasNoValue()) { 113 ASSERT_NOT_REACHED(); 114 return; 115 } 116 function.appendArgument(scriptValue); 117 } 118 } else { 119 function.appendArgument(message); 120 } 121 function.call(); 122 } 123 124 void InspectorFrontend::updateConsoleMessageRepeatCount(unsigned count) 125 { 126 ScriptFunctionCall function(m_webInspector, "dispatch"); 127 function.appendArgument("updateConsoleMessageRepeatCount"); 128 function.appendArgument(count); 129 function.call(); 130 } 131 132 void InspectorFrontend::clearConsoleMessages() 133 { 134 callSimpleFunction("clearConsoleMessages"); 135 } 136 137 bool InspectorFrontend::updateResource(unsigned long identifier, const ScriptObject& resourceObj) 138 { 139 ScriptFunctionCall function(m_webInspector, "dispatch"); 140 function.appendArgument("updateResource"); 141 function.appendArgument(identifier); 142 function.appendArgument(resourceObj); 143 bool hadException = false; 144 function.call(hadException); 145 return !hadException; 146 } 147 148 void InspectorFrontend::removeResource(unsigned long identifier) 149 { 150 ScriptFunctionCall function(m_webInspector, "dispatch"); 151 function.appendArgument("removeResource"); 152 function.appendArgument(identifier); 153 function.call(); 154 } 155 156 void InspectorFrontend::didGetResourceContent(int callId, const String& content) 157 { 158 ScriptFunctionCall function(m_webInspector, "dispatch"); 159 function.appendArgument("didGetResourceContent"); 160 function.appendArgument(callId); 161 function.appendArgument(content); 162 function.call(); 163 } 164 165 void InspectorFrontend::updateFocusedNode(long nodeId) 166 { 167 ScriptFunctionCall function(m_webInspector, "dispatch"); 168 function.appendArgument("updateFocusedNode"); 169 function.appendArgument(nodeId); 170 function.call(); 171 } 172 173 void InspectorFrontend::setAttachedWindow(bool attached) 174 { 175 ScriptFunctionCall function(m_webInspector, "dispatch"); 176 function.appendArgument("setAttachedWindow"); 177 function.appendArgument(attached); 178 function.call(); 179 } 180 181 void InspectorFrontend::showPanel(int panel) 182 { 183 const char* showFunctionName; 184 switch (panel) { 185 case InspectorController::ConsolePanel: 186 showFunctionName = "showConsolePanel"; 187 break; 188 case InspectorController::ElementsPanel: 189 showFunctionName = "showElementsPanel"; 190 break; 191 case InspectorController::ResourcesPanel: 192 showFunctionName = "showResourcesPanel"; 193 break; 194 case InspectorController::ScriptsPanel: 195 showFunctionName = "showScriptsPanel"; 196 break; 197 case InspectorController::TimelinePanel: 198 showFunctionName = "showTimelinePanel"; 199 break; 200 case InspectorController::ProfilesPanel: 201 showFunctionName = "showProfilesPanel"; 202 break; 203 case InspectorController::StoragePanel: 204 showFunctionName = "showStoragePanel"; 205 break; 206 default: 207 ASSERT_NOT_REACHED(); 208 showFunctionName = 0; 209 } 210 211 if (showFunctionName) 212 callSimpleFunction(showFunctionName); 213 } 214 215 void InspectorFrontend::populateInterface() 216 { 217 callSimpleFunction("populateInterface"); 218 } 219 220 void InspectorFrontend::reset() 221 { 222 callSimpleFunction("reset"); 223 } 224 225 void InspectorFrontend::resourceTrackingWasEnabled() 226 { 227 callSimpleFunction("resourceTrackingWasEnabled"); 228 } 229 230 void InspectorFrontend::resourceTrackingWasDisabled() 231 { 232 callSimpleFunction("resourceTrackingWasDisabled"); 233 } 234 235 void InspectorFrontend::timelineProfilerWasStarted() 236 { 237 callSimpleFunction("timelineProfilerWasStarted"); 238 } 239 240 void InspectorFrontend::timelineProfilerWasStopped() 241 { 242 callSimpleFunction("timelineProfilerWasStopped"); 243 } 244 245 void InspectorFrontend::addRecordToTimeline(const ScriptObject& record) 246 { 247 ScriptFunctionCall function(m_webInspector, "dispatch"); 248 function.appendArgument("addRecordToTimeline"); 249 function.appendArgument(record); 250 function.call(); 251 } 252 253 #if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC) 254 void InspectorFrontend::attachDebuggerWhenShown() 255 { 256 callSimpleFunction("attachDebuggerWhenShown"); 257 } 258 259 void InspectorFrontend::debuggerWasEnabled() 260 { 261 callSimpleFunction("debuggerWasEnabled"); 262 } 263 264 void InspectorFrontend::debuggerWasDisabled() 265 { 266 callSimpleFunction("debuggerWasDisabled"); 267 } 268 269 void InspectorFrontend::parsedScriptSource(const JSC::SourceCode& source) 270 { 271 ScriptFunctionCall function(m_webInspector, "dispatch"); 272 function.appendArgument("parsedScriptSource"); 273 function.appendArgument(JSC::UString(JSC::UString::from(source.provider()->asID()))); 274 function.appendArgument(source.provider()->url()); 275 function.appendArgument(JSC::UString(source.data(), source.length())); 276 function.appendArgument(source.firstLine()); 277 function.call(); 278 } 279 280 void InspectorFrontend::failedToParseScriptSource(const JSC::SourceCode& source, int errorLine, const JSC::UString& errorMessage) 281 { 282 ScriptFunctionCall function(m_webInspector, "dispatch"); 283 function.appendArgument("failedToParseScriptSource"); 284 function.appendArgument(source.provider()->url()); 285 function.appendArgument(JSC::UString(source.data(), source.length())); 286 function.appendArgument(source.firstLine()); 287 function.appendArgument(errorLine); 288 function.appendArgument(errorMessage); 289 function.call(); 290 } 291 292 void InspectorFrontend::pausedScript(SerializedScriptValue* callFrames) 293 { 294 ScriptValue callFramesValue = ScriptValue::deserialize(scriptState(), callFrames); 295 ScriptFunctionCall function(m_webInspector, "dispatch"); 296 function.appendArgument("pausedScript"); 297 function.appendArgument(callFramesValue); 298 function.call(); 299 } 300 301 void InspectorFrontend::resumedScript() 302 { 303 callSimpleFunction("resumedScript"); 304 } 305 #endif 306 307 #if ENABLE(JAVASCRIPT_DEBUGGER) 308 void InspectorFrontend::profilerWasEnabled() 309 { 310 callSimpleFunction("profilerWasEnabled"); 311 } 312 313 void InspectorFrontend::profilerWasDisabled() 314 { 315 callSimpleFunction("profilerWasDisabled"); 316 } 317 318 void InspectorFrontend::addProfileHeader(const ScriptValue& profile) 319 { 320 ScriptFunctionCall function(m_webInspector, "dispatch"); 321 function.appendArgument("addProfileHeader"); 322 function.appendArgument(profile); 323 function.call(); 324 } 325 326 void InspectorFrontend::setRecordingProfile(bool isProfiling) 327 { 328 ScriptFunctionCall function(m_webInspector, "dispatch"); 329 function.appendArgument("setRecordingProfile"); 330 function.appendArgument(isProfiling); 331 function.call(); 332 } 333 334 void InspectorFrontend::didGetProfileHeaders(int callId, const ScriptArray& headers) 335 { 336 ScriptFunctionCall function(m_webInspector, "dispatch"); 337 function.appendArgument("didGetProfileHeaders"); 338 function.appendArgument(callId); 339 function.appendArgument(headers); 340 function.call(); 341 } 342 343 void InspectorFrontend::didGetProfile(int callId, const ScriptValue& profile) 344 { 345 ScriptFunctionCall function(m_webInspector, "dispatch"); 346 function.appendArgument("didGetProfile"); 347 function.appendArgument(callId); 348 function.appendArgument(profile); 349 function.call(); 350 } 351 #endif 352 353 void InspectorFrontend::setDocument(const ScriptObject& root) 354 { 355 ScriptFunctionCall function(m_webInspector, "dispatch"); 356 function.appendArgument("setDocument"); 357 function.appendArgument(root); 358 function.call(); 359 } 360 361 void InspectorFrontend::setDetachedRoot(const ScriptObject& root) 362 { 363 ScriptFunctionCall function(m_webInspector, "dispatch"); 364 function.appendArgument("setDetachedRoot"); 365 function.appendArgument(root); 366 function.call(); 367 } 368 369 void InspectorFrontend::setChildNodes(int parentId, const ScriptArray& nodes) 370 { 371 ScriptFunctionCall function(m_webInspector, "dispatch"); 372 function.appendArgument("setChildNodes"); 373 function.appendArgument(parentId); 374 function.appendArgument(nodes); 375 function.call(); 376 } 377 378 void InspectorFrontend::childNodeCountUpdated(int id, int newValue) 379 { 380 ScriptFunctionCall function(m_webInspector, "dispatch"); 381 function.appendArgument("childNodeCountUpdated"); 382 function.appendArgument(id); 383 function.appendArgument(newValue); 384 function.call(); 385 } 386 387 void InspectorFrontend::childNodeInserted(int parentId, int prevId, const ScriptObject& node) 388 { 389 ScriptFunctionCall function(m_webInspector, "dispatch"); 390 function.appendArgument("childNodeInserted"); 391 function.appendArgument(parentId); 392 function.appendArgument(prevId); 393 function.appendArgument(node); 394 function.call(); 395 } 396 397 void InspectorFrontend::childNodeRemoved(int parentId, int id) 398 { 399 ScriptFunctionCall function(m_webInspector, "dispatch"); 400 function.appendArgument("childNodeRemoved"); 401 function.appendArgument(parentId); 402 function.appendArgument(id); 403 function.call(); 404 } 405 406 void InspectorFrontend::attributesUpdated(int id, const ScriptArray& attributes) 407 { 408 ScriptFunctionCall function(m_webInspector, "dispatch"); 409 function.appendArgument("attributesUpdated"); 410 function.appendArgument(id); 411 function.appendArgument(attributes); 412 function.call(); 413 } 414 415 void InspectorFrontend::didRemoveNode(int callId, int nodeId) 416 { 417 ScriptFunctionCall function(m_webInspector, "dispatch"); 418 function.appendArgument("didRemoveNode"); 419 function.appendArgument(callId); 420 function.appendArgument(nodeId); 421 function.call(); 422 } 423 424 void InspectorFrontend::didGetChildNodes(int callId) 425 { 426 ScriptFunctionCall function(m_webInspector, "dispatch"); 427 function.appendArgument("didGetChildNodes"); 428 function.appendArgument(callId); 429 function.call(); 430 } 431 432 void InspectorFrontend::didApplyDomChange(int callId, bool success) 433 { 434 ScriptFunctionCall function(m_webInspector, "dispatch"); 435 function.appendArgument("didApplyDomChange"); 436 function.appendArgument(callId); 437 function.appendArgument(success); 438 function.call(); 439 } 440 441 void InspectorFrontend::didGetEventListenersForNode(int callId, int nodeId, ScriptArray& listenersArray) 442 { 443 ScriptFunctionCall function(m_webInspector, "dispatch"); 444 function.appendArgument("didGetEventListenersForNode"); 445 function.appendArgument(callId); 446 function.appendArgument(nodeId); 447 function.appendArgument(listenersArray); 448 function.call(); 449 } 450 451 void InspectorFrontend::didGetCookies(int callId, const ScriptArray& cookies, const String& cookiesString) 452 { 453 ScriptFunctionCall function(m_webInspector, "dispatch"); 454 function.appendArgument("didGetCookies"); 455 function.appendArgument(callId); 456 function.appendArgument(cookies); 457 function.appendArgument(cookiesString); 458 function.call(); 459 } 460 461 void InspectorFrontend::didDispatchOnInjectedScript(int callId, SerializedScriptValue* result, bool isException) 462 { 463 ScriptFunctionCall function(m_webInspector, "dispatch"); 464 function.appendArgument("didDispatchOnInjectedScript"); 465 function.appendArgument(callId); 466 if (isException) 467 function.appendArgument(""); 468 else { 469 ScriptValue resultValue = ScriptValue::deserialize(scriptState(), result); 470 function.appendArgument(resultValue); 471 } 472 function.appendArgument(isException); 473 function.call(); 474 } 475 476 #if ENABLE(DATABASE) 477 bool InspectorFrontend::addDatabase(const ScriptObject& dbObject) 478 { 479 ScriptFunctionCall function(m_webInspector, "dispatch"); 480 function.appendArgument("addDatabase"); 481 function.appendArgument(dbObject); 482 bool hadException = false; 483 function.call(hadException); 484 return !hadException; 485 } 486 487 void InspectorFrontend::selectDatabase(int databaseId) 488 { 489 ScriptFunctionCall function(m_webInspector, "dispatch"); 490 function.appendArgument("selectDatabase"); 491 function.appendArgument(databaseId); 492 function.call(); 493 } 494 void InspectorFrontend::didGetDatabaseTableNames(int callId, const ScriptArray& tableNames) 495 { 496 ScriptFunctionCall function(m_webInspector, "dispatch"); 497 function.appendArgument("didGetDatabaseTableNames"); 498 function.appendArgument(callId); 499 function.appendArgument(tableNames); 500 function.call(); 501 } 502 #endif 503 504 #if ENABLE(DOM_STORAGE) 505 bool InspectorFrontend::addDOMStorage(const ScriptObject& domStorageObj) 506 { 507 ScriptFunctionCall function(m_webInspector, "dispatch"); 508 function.appendArgument("addDOMStorage"); 509 function.appendArgument(domStorageObj); 510 bool hadException = false; 511 function.call(hadException); 512 return !hadException; 513 } 514 515 void InspectorFrontend::selectDOMStorage(int storageId) 516 { 517 ScriptFunctionCall function(m_webInspector, "dispatch"); 518 function.appendArgument("selectDOMStorage"); 519 function.appendArgument(storageId); 520 function.call(); 521 } 522 523 void InspectorFrontend::didGetDOMStorageEntries(int callId, const ScriptArray& entries) 524 { 525 ScriptFunctionCall function(m_webInspector, "dispatch"); 526 function.appendArgument("didGetDOMStorageEntries"); 527 function.appendArgument(callId); 528 function.appendArgument(entries); 529 function.call(); 530 } 531 532 void InspectorFrontend::didSetDOMStorageItem(int callId, bool success) 533 { 534 ScriptFunctionCall function(m_webInspector, "dispatch"); 535 function.appendArgument("didSetDOMStorageItem"); 536 function.appendArgument(callId); 537 function.appendArgument(success); 538 function.call(); 539 } 540 541 void InspectorFrontend::didRemoveDOMStorageItem(int callId, bool success) 542 { 543 ScriptFunctionCall function(m_webInspector, "dispatch"); 544 function.appendArgument("didRemoveDOMStorageItem"); 545 function.appendArgument(callId); 546 function.appendArgument(success); 547 function.call(); 548 } 549 550 void InspectorFrontend::updateDOMStorage(int storageId) 551 { 552 ScriptFunctionCall function(m_webInspector, "dispatch"); 553 function.appendArgument("updateDOMStorage"); 554 function.appendArgument(storageId); 555 function.call(); 556 } 557 #endif 558 559 void InspectorFrontend::addNodesToSearchResult(const String& nodeIds) 560 { 561 ScriptFunctionCall function(m_webInspector, "dispatch"); 562 function.appendArgument("addNodesToSearchResult"); 563 function.appendArgument(nodeIds); 564 function.call(); 565 } 566 567 void InspectorFrontend::contextMenuItemSelected(int itemId) 568 { 569 ScriptFunctionCall function(m_webInspector, "dispatch"); 570 function.appendArgument("contextMenuItemSelected"); 571 function.appendArgument(itemId); 572 function.call(); 573 } 574 575 void InspectorFrontend::contextMenuCleared() 576 { 577 callSimpleFunction("contextMenuCleared"); 578 } 579 580 void InspectorFrontend::evaluateForTestInFrontend(int callId, const String& script) 581 { 582 ScriptFunctionCall function(m_webInspector, "dispatch"); 583 function.appendArgument("evaluateForTestInFrontend"); 584 function.appendArgument(callId); 585 function.appendArgument(script); 586 function.call(); 587 } 588 589 void InspectorFrontend::callSimpleFunction(const String& functionName) 590 { 591 ScriptFunctionCall function(m_webInspector, "dispatch"); 592 function.appendArgument(functionName); 593 function.call(); 594 } 595 596 } // namespace WebCore 597 598 #endif // ENABLE(INSPECTOR) 599