Home | History | Annotate | Download | only in inspector
      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