1/*
2* Copyright (C) 2011 Google Inc. All rights reserved.
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7*
8*     * Redistributions of source code must retain the above copyright
9* notice, this list of conditions and the following disclaimer.
10*     * Redistributions in binary form must reproduce the above
11* copyright notice, this list of conditions and the following disclaimer
12* in the documentation and/or other materials provided with the
13* distribution.
14*     * Neither the name of Google Inc. nor the names of its
15* contributors may be used to endorse or promote products derived from
16* this software without specific prior written permission.
17*
18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
30
31#include "config.h"
32#include "InspectorInstrumentation.h"
33
34#if ENABLE(INSPECTOR)
35
36#include "DOMWindow.h"
37#include "Database.h"
38#include "DocumentLoader.h"
39#include "Event.h"
40#include "EventContext.h"
41#include "InspectorAgent.h"
42#include "InspectorApplicationCacheAgent.h"
43#include "InspectorBrowserDebuggerAgent.h"
44#include "InspectorCSSAgent.h"
45#include "InspectorConsoleAgent.h"
46#include "InspectorDatabaseAgent.h"
47#include "InspectorDOMAgent.h"
48#include "InspectorDOMStorageAgent.h"
49#include "InspectorDebuggerAgent.h"
50#include "InspectorPageAgent.h"
51#include "InspectorProfilerAgent.h"
52#include "InspectorResourceAgent.h"
53#include "InspectorTimelineAgent.h"
54#include "InstrumentingAgents.h"
55#include "ScriptArguments.h"
56#include "ScriptCallStack.h"
57#include "XMLHttpRequest.h"
58#include <wtf/text/CString.h>
59
60namespace WebCore {
61
62static const char* const listenerEventCategoryType = "listener";
63static const char* const instrumentationEventCategoryType = "instrumentation";
64
65static const char* const setTimerEventName = "setTimer";
66static const char* const clearTimerEventName = "clearTimer";
67static const char* const timerFiredEventName = "timerFired";
68
69HashMap<Page*, InspectorAgent*>& InspectorInstrumentation::inspectorAgents()
70{
71    static HashMap<Page*, InspectorAgent*>& agents = *new HashMap<Page*, InspectorAgent*>;
72    return agents;
73}
74
75int InspectorInstrumentation::s_frontendCounter = 0;
76
77static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
78{
79    if (window && window->hasEventListeners(eventType))
80        return true;
81
82    if (node->hasEventListeners(eventType))
83        return true;
84
85    for (size_t i = 0; i < ancestors.size(); i++) {
86        Node* ancestor = ancestors[i].node();
87        if (ancestor->hasEventListeners(eventType))
88            return true;
89    }
90
91    return false;
92}
93
94void InspectorInstrumentation::didClearWindowObjectInWorldImpl(InspectorAgent* inspectorAgent, Frame* frame, DOMWrapperWorld* world)
95{
96    if (InspectorPageAgent* pageAgent = inspectorAgent->instrumentingAgents()->inspectorPageAgent())
97        pageAgent->didClearWindowObjectInWorld(frame, world);
98    inspectorAgent->didClearWindowObjectInWorld(frame, world);
99}
100
101void InspectorInstrumentation::inspectedPageDestroyedImpl(InspectorAgent* inspectorAgent)
102{
103    inspectorAgent->inspectedPageDestroyed();
104}
105
106void InspectorInstrumentation::willInsertDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node, Node* parent)
107{
108#if ENABLE(JAVASCRIPT_DEBUGGER)
109    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
110        browserDebuggerAgent->willInsertDOMNode(node, parent);
111#endif
112}
113
114void InspectorInstrumentation::didInsertDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node)
115{
116    if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent())
117        domAgent->didInsertDOMNode(node);
118#if ENABLE(JAVASCRIPT_DEBUGGER)
119    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
120        browserDebuggerAgent->didInsertDOMNode(node);
121#endif
122}
123
124void InspectorInstrumentation::willRemoveDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node)
125{
126#if ENABLE(JAVASCRIPT_DEBUGGER)
127    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
128        browserDebuggerAgent->willRemoveDOMNode(node);
129#endif
130}
131
132void InspectorInstrumentation::didRemoveDOMNodeImpl(InspectorAgent* inspectorAgent, Node* node)
133{
134#if ENABLE(JAVASCRIPT_DEBUGGER)
135    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
136        browserDebuggerAgent->didRemoveDOMNode(node);
137#endif
138    if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent())
139        domAgent->didRemoveDOMNode(node);
140}
141
142void InspectorInstrumentation::willModifyDOMAttrImpl(InspectorAgent* inspectorAgent, Element* element)
143{
144#if ENABLE(JAVASCRIPT_DEBUGGER)
145    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
146        browserDebuggerAgent->willModifyDOMAttr(element);
147#endif
148}
149
150void InspectorInstrumentation::didModifyDOMAttrImpl(InspectorAgent* inspectorAgent, Element* element)
151{
152    if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent())
153        domAgent->didModifyDOMAttr(element);
154}
155
156void InspectorInstrumentation::didInvalidateStyleAttrImpl(InspectorAgent* inspectorAgent, Node* node)
157{
158    if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent())
159        domAgent->didInvalidateStyleAttr(node);
160}
161
162void InspectorInstrumentation::mouseDidMoveOverElementImpl(InspectorAgent* inspectorAgent, const HitTestResult& result, unsigned modifierFlags)
163{
164    if (InspectorDOMAgent* domAgent = inspectorAgent->instrumentingAgents()->inspectorDOMAgent())
165        domAgent->mouseDidMoveOverElement(result, modifierFlags);
166}
167
168bool InspectorInstrumentation::handleMousePressImpl(InspectorAgent* inspectorAgent)
169{
170    if (InspectorDOMAgent* domAgent = inspectorAgent->instrumentingAgents()->inspectorDOMAgent())
171        return domAgent->handleMousePress();
172    return false;
173}
174
175void InspectorInstrumentation::characterDataModifiedImpl(InspectorAgent* inspectorAgent, CharacterData* characterData)
176{
177    if (InspectorDOMAgent* domAgent = inspectorAgent->domAgent())
178        domAgent->characterDataModified(characterData);
179}
180
181void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorAgent* inspectorAgent, const String& url)
182{
183#if ENABLE(JAVASCRIPT_DEBUGGER)
184    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
185        browserDebuggerAgent->willSendXMLHttpRequest(url);
186#endif
187}
188
189void InspectorInstrumentation::didScheduleResourceRequestImpl(InspectorAgent* inspectorAgent, const String& url)
190{
191    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent))
192        timelineAgent->didScheduleResourceRequest(url);
193}
194
195void InspectorInstrumentation::didInstallTimerImpl(InspectorAgent* inspectorAgent, int timerId, int timeout, bool singleShot)
196{
197    pauseOnNativeEventIfNeeded(inspectorAgent, instrumentationEventCategoryType, setTimerEventName, true);
198    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent))
199        timelineAgent->didInstallTimer(timerId, timeout, singleShot);
200}
201
202void InspectorInstrumentation::didRemoveTimerImpl(InspectorAgent* inspectorAgent, int timerId)
203{
204    pauseOnNativeEventIfNeeded(inspectorAgent, instrumentationEventCategoryType, clearTimerEventName, true);
205    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent))
206        timelineAgent->didRemoveTimer(timerId);
207}
208
209InspectorInstrumentationCookie InspectorInstrumentation::willCallFunctionImpl(InspectorAgent* inspectorAgent, const String& scriptName, int scriptLine)
210{
211    int timelineAgentId = 0;
212    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
213    if (timelineAgent) {
214        timelineAgent->willCallFunction(scriptName, scriptLine);
215        timelineAgentId = timelineAgent->id();
216    }
217    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
218}
219
220void InspectorInstrumentation::didCallFunctionImpl(const InspectorInstrumentationCookie& cookie)
221{
222    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
223        timelineAgent->didCallFunction();
224}
225
226InspectorInstrumentationCookie InspectorInstrumentation::willChangeXHRReadyStateImpl(InspectorAgent* inspectorAgent, XMLHttpRequest* request)
227{
228    int timelineAgentId = 0;
229    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
230    if (timelineAgent && request->hasEventListeners(eventNames().readystatechangeEvent)) {
231        timelineAgent->willChangeXHRReadyState(request->url().string(), request->readyState());
232        timelineAgentId = timelineAgent->id();
233    }
234    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
235}
236
237void InspectorInstrumentation::didChangeXHRReadyStateImpl(const InspectorInstrumentationCookie& cookie)
238{
239    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
240        timelineAgent->didChangeXHRReadyState();
241}
242
243InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InspectorAgent* inspectorAgent, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
244{
245    pauseOnNativeEventIfNeeded(inspectorAgent, listenerEventCategoryType, event.type(), false);
246
247    int timelineAgentId = 0;
248    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
249    if (timelineAgent && eventHasListeners(event.type(), window, node, ancestors)) {
250        timelineAgent->willDispatchEvent(event);
251        timelineAgentId = timelineAgent->id();
252    }
253    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
254}
255
256void InspectorInstrumentation::didDispatchEventImpl(const InspectorInstrumentationCookie& cookie)
257{
258    cancelPauseOnNativeEvent(cookie.first);
259
260    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
261        timelineAgent->didDispatchEvent();
262}
263
264InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventOnWindowImpl(InspectorAgent* inspectorAgent, const Event& event, DOMWindow* window)
265{
266    pauseOnNativeEventIfNeeded(inspectorAgent, listenerEventCategoryType, event.type(), false);
267
268    int timelineAgentId = 0;
269    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
270    if (timelineAgent && window->hasEventListeners(event.type())) {
271        timelineAgent->willDispatchEvent(event);
272        timelineAgentId = timelineAgent->id();
273    }
274    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
275}
276
277void InspectorInstrumentation::didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie& cookie)
278{
279    cancelPauseOnNativeEvent(cookie.first);
280
281    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
282        timelineAgent->didDispatchEvent();
283}
284
285InspectorInstrumentationCookie InspectorInstrumentation::willEvaluateScriptImpl(InspectorAgent* inspectorAgent, const String& url, int lineNumber)
286{
287    int timelineAgentId = 0;
288    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
289    if (timelineAgent) {
290        timelineAgent->willEvaluateScript(url, lineNumber);
291        timelineAgentId = timelineAgent->id();
292    }
293    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
294}
295
296void InspectorInstrumentation::didEvaluateScriptImpl(const InspectorInstrumentationCookie& cookie)
297{
298    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
299        timelineAgent->didEvaluateScript();
300}
301
302InspectorInstrumentationCookie InspectorInstrumentation::willFireTimerImpl(InspectorAgent* inspectorAgent, int timerId)
303{
304    pauseOnNativeEventIfNeeded(inspectorAgent, instrumentationEventCategoryType, timerFiredEventName, false);
305
306    int timelineAgentId = 0;
307    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
308    if (timelineAgent) {
309        timelineAgent->willFireTimer(timerId);
310        timelineAgentId = timelineAgent->id();
311    }
312    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
313}
314
315void InspectorInstrumentation::didFireTimerImpl(const InspectorInstrumentationCookie& cookie)
316{
317    cancelPauseOnNativeEvent(cookie.first);
318
319    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
320        timelineAgent->didFireTimer();
321}
322
323InspectorInstrumentationCookie InspectorInstrumentation::willLayoutImpl(InspectorAgent* inspectorAgent)
324{
325    int timelineAgentId = 0;
326    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
327    if (timelineAgent) {
328        timelineAgent->willLayout();
329        timelineAgentId = timelineAgent->id();
330    }
331    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
332}
333
334void InspectorInstrumentation::didLayoutImpl(const InspectorInstrumentationCookie& cookie)
335{
336    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
337        timelineAgent->didLayout();
338}
339
340InspectorInstrumentationCookie InspectorInstrumentation::willLoadXHRImpl(InspectorAgent* inspectorAgent, XMLHttpRequest* request)
341{
342    int timelineAgentId = 0;
343    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
344    if (timelineAgent && request->hasEventListeners(eventNames().loadEvent)) {
345        timelineAgent->willLoadXHR(request->url());
346        timelineAgentId = timelineAgent->id();
347    }
348    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
349}
350
351void InspectorInstrumentation::didLoadXHRImpl(const InspectorInstrumentationCookie& cookie)
352{
353    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
354        timelineAgent->didLoadXHR();
355}
356
357InspectorInstrumentationCookie InspectorInstrumentation::willPaintImpl(InspectorAgent* inspectorAgent, const IntRect& rect)
358{
359    int timelineAgentId = 0;
360    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
361    if (timelineAgent) {
362        timelineAgent->willPaint(rect);
363        timelineAgentId = timelineAgent->id();
364    }
365    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
366}
367
368void InspectorInstrumentation::didPaintImpl(const InspectorInstrumentationCookie& cookie)
369{
370    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
371        timelineAgent->didPaint();
372}
373
374InspectorInstrumentationCookie InspectorInstrumentation::willRecalculateStyleImpl(InspectorAgent* inspectorAgent)
375{
376    int timelineAgentId = 0;
377    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
378    if (timelineAgent) {
379        timelineAgent->willRecalculateStyle();
380        timelineAgentId = timelineAgent->id();
381    }
382    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
383}
384
385void InspectorInstrumentation::didRecalculateStyleImpl(const InspectorInstrumentationCookie& cookie)
386{
387    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
388        timelineAgent->didRecalculateStyle();
389}
390
391void InspectorInstrumentation::applyUserAgentOverrideImpl(InspectorAgent* inspectorAgent, String* userAgent)
392{
393    if (InspectorPageAgent* pageAgent = retrievePageAgent(inspectorAgent))
394        pageAgent->applyUserAgentOverride(userAgent);
395}
396
397void InspectorInstrumentation::willSendRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
398{
399    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent))
400        timelineAgent->willSendResourceRequest(identifier, request);
401    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
402        resourceAgent->willSendRequest(identifier, loader, request, redirectResponse);
403}
404
405void InspectorInstrumentation::markResourceAsCachedImpl(InspectorAgent* inspectorAgent, unsigned long identifier)
406{
407    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
408        resourceAgent->markResourceAsCached(identifier);
409}
410
411void InspectorInstrumentation::didLoadResourceFromMemoryCacheImpl(InspectorAgent* inspectorAgent, DocumentLoader* loader, const CachedResource* cachedResource)
412{
413    if (!inspectorAgent->enabled())
414        return;
415    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
416        resourceAgent->didLoadResourceFromMemoryCache(loader, cachedResource);
417}
418
419InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceDataImpl(InspectorAgent* inspectorAgent, unsigned long identifier)
420{
421    int timelineAgentId = 0;
422    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
423    if (timelineAgent) {
424        timelineAgent->willReceiveResourceData(identifier);
425        timelineAgentId = timelineAgent->id();
426    }
427    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
428}
429
430void InspectorInstrumentation::didReceiveResourceDataImpl(const InspectorInstrumentationCookie& cookie)
431{
432    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
433        timelineAgent->didReceiveResourceData();
434}
435
436InspectorInstrumentationCookie InspectorInstrumentation::willReceiveResourceResponseImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const ResourceResponse& response)
437{
438    int timelineAgentId = 0;
439    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
440    if (timelineAgent) {
441        timelineAgent->willReceiveResourceResponse(identifier, response);
442        timelineAgentId = timelineAgent->id();
443    }
444    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
445}
446
447void InspectorInstrumentation::didReceiveResourceResponseImpl(const InspectorInstrumentationCookie& cookie, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response)
448{
449    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
450        timelineAgent->didReceiveResourceResponse();
451    if (!loader)
452        return;
453    if (InspectorAgent* inspectorAgent = inspectorAgentForFrame(loader->frame())) {
454        if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
455            resourceAgent->didReceiveResponse(identifier, loader, response);
456        inspectorAgent->consoleAgent()->didReceiveResponse(identifier, response); // This should come AFTER resource notification, front-end relies on this.
457    }
458}
459
460void InspectorInstrumentation::didReceiveResourceResponseButCanceledImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
461{
462    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(frame, identifier, r);
463    InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, r);
464}
465
466void InspectorInstrumentation::continueAfterXFrameOptionsDeniedImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
467{
468    didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
469}
470
471void InspectorInstrumentation::continueWithPolicyDownloadImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
472{
473    didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
474}
475
476void InspectorInstrumentation::continueWithPolicyIgnoreImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
477{
478    didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
479}
480
481void InspectorInstrumentation::didReceiveContentLengthImpl(InspectorAgent* inspectorAgent, unsigned long identifier, int dataLength, int encodedDataLength)
482{
483    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
484        resourceAgent->didReceiveContentLength(identifier, dataLength, encodedDataLength);
485}
486
487void InspectorInstrumentation::didFinishLoadingImpl(InspectorAgent* inspectorAgent, unsigned long identifier, double finishTime)
488{
489    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent))
490        timelineAgent->didFinishLoadingResource(identifier, false, finishTime);
491    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
492        resourceAgent->didFinishLoading(identifier, finishTime);
493}
494
495void InspectorInstrumentation::didFailLoadingImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const ResourceError& error)
496{
497    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent))
498        timelineAgent->didFinishLoadingResource(identifier, true, 0);
499    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
500        resourceAgent->didFailLoading(identifier, error);
501    inspectorAgent->consoleAgent()->didFailLoading(identifier, error); // This should come AFTER resource notification, front-end relies on this.
502}
503
504void InspectorInstrumentation::resourceRetrievedByXMLHttpRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const String& sourceString, const String& url, const String& sendURL, unsigned sendLineNumber)
505{
506    inspectorAgent->consoleAgent()->resourceRetrievedByXMLHttpRequest(url, sendURL, sendLineNumber);
507    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
508        resourceAgent->setInitialXHRContent(identifier, sourceString);
509}
510
511void InspectorInstrumentation::scriptImportedImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const String& sourceString)
512{
513    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
514        resourceAgent->setInitialScriptContent(identifier, sourceString);
515}
516
517void InspectorInstrumentation::domContentLoadedEventFiredImpl(InspectorAgent* inspectorAgent, Frame* frame, const KURL& url)
518{
519    DocumentLoader* documentLoader = frame->loader()->documentLoader();
520    ASSERT(documentLoader);
521
522    if (frame->page()->mainFrame() != frame || url != documentLoader->requestURL())
523        return;
524
525    inspectorAgent->domContentLoadedEventFired();
526
527    if (InspectorDOMAgent* domAgent = inspectorAgent->instrumentingAgents()->inspectorDOMAgent())
528        domAgent->mainFrameDOMContentLoaded();
529
530    if (InspectorTimelineAgent* timelineAgent = inspectorAgent->instrumentingAgents()->inspectorTimelineAgent())
531        timelineAgent->didMarkDOMContentEvent();
532
533    if (InspectorResourceAgent* resourceAgent = inspectorAgent->instrumentingAgents()->inspectorResourceAgent())
534        resourceAgent->domContentEventFired();
535
536    if (InspectorPageAgent* pageAgent = inspectorAgent->instrumentingAgents()->inspectorPageAgent())
537        pageAgent->domContentEventFired();
538}
539
540void InspectorInstrumentation::loadEventFiredImpl(InspectorAgent* inspectorAgent, Frame* frame, const KURL& url)
541{
542    DocumentLoader* documentLoader = frame->loader()->documentLoader();
543    ASSERT(documentLoader);
544
545    if (InspectorDOMAgent* domAgent = inspectorAgent->instrumentingAgents()->inspectorDOMAgent())
546        domAgent->loadEventFired(documentLoader->frame()->document());
547
548    if (frame->page()->mainFrame() != frame || url != documentLoader->requestURL())
549        return;
550
551    if (InspectorTimelineAgent* timelineAgent = inspectorAgent->instrumentingAgents()->inspectorTimelineAgent())
552        timelineAgent->didMarkLoadEvent();
553
554    if (InspectorResourceAgent* resourceAgent = inspectorAgent->instrumentingAgents()->inspectorResourceAgent())
555        resourceAgent->loadEventFired();
556
557    if (InspectorPageAgent* pageAgent = inspectorAgent->instrumentingAgents()->inspectorPageAgent())
558        pageAgent->loadEventFired();
559}
560
561void InspectorInstrumentation::frameDetachedFromParentImpl(InspectorAgent* inspectorAgent, Frame* frame)
562{
563    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
564        resourceAgent->frameDetachedFromParent(frame);
565}
566
567void InspectorInstrumentation::didCommitLoadImpl(Page* page, InspectorAgent* inspectorAgent, DocumentLoader* loader)
568{
569    if (!inspectorAgent->enabled())
570        return;
571
572    InstrumentingAgents* instrumentingAgents = inspectorAgent->instrumentingAgents();
573    if (InspectorResourceAgent* resourceAgent = instrumentingAgents->inspectorResourceAgent())
574        resourceAgent->didCommitLoad(loader);
575
576    Frame* mainFrame = page->mainFrame();
577    if (loader->frame() != mainFrame)
578        return;
579
580    if (InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent())
581        consoleAgent->reset();
582#if ENABLE(JAVASCRIPT_DEBUGGER)
583    if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent()) {
584        KURL url = inspectorAgent->inspectedURLWithoutFragment();
585        debuggerAgent->inspectedURLChanged(url);
586    }
587#endif
588#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
589    if (InspectorProfilerAgent* profilerAgent = instrumentingAgents->inspectorProfilerAgent()) {
590        profilerAgent->stopUserInitiatedProfiling(true);
591        profilerAgent->resetState();
592    }
593#endif
594    if (InspectorCSSAgent* cssAgent = instrumentingAgents->inspectorCSSAgent())
595        cssAgent->reset();
596#if ENABLE(DATABASE)
597    if (InspectorDatabaseAgent* databaseAgent = instrumentingAgents->inspectorDatabaseAgent())
598        databaseAgent->clearResources();
599#endif
600#if ENABLE(DOM_STORAGE)
601    if (InspectorDOMStorageAgent* domStorageAgent = instrumentingAgents->inspectorDOMStorageAgent())
602        domStorageAgent->clearResources();
603#endif
604    if (InspectorDOMAgent* domAgent = instrumentingAgents->inspectorDOMAgent())
605        domAgent->setDocument(mainFrame->document());
606
607    if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent())
608        pageAgent->inspectedURLChanged(loader->url().string());
609
610    inspectorAgent->didCommitLoad();
611}
612
613InspectorInstrumentationCookie InspectorInstrumentation::willWriteHTMLImpl(InspectorAgent* inspectorAgent, unsigned int length, unsigned int startLine)
614{
615    int timelineAgentId = 0;
616    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent);
617    if (timelineAgent) {
618        timelineAgent->willWriteHTML(length, startLine);
619        timelineAgentId = timelineAgent->id();
620    }
621    return InspectorInstrumentationCookie(inspectorAgent, timelineAgentId);
622}
623
624void InspectorInstrumentation::didWriteHTMLImpl(const InspectorInstrumentationCookie& cookie, unsigned int endLine)
625{
626    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie))
627        timelineAgent->didWriteHTML(endLine);
628}
629
630void InspectorInstrumentation::addMessageToConsoleImpl(InspectorAgent* inspectorAgent, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> callStack)
631{
632    inspectorAgent->consoleAgent()->addMessageToConsole(source, type, level, message, arguments, callStack);
633}
634
635void InspectorInstrumentation::addMessageToConsoleImpl(InspectorAgent* inspectorAgent, MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceID)
636{
637    inspectorAgent->consoleAgent()->addMessageToConsole(source, type, level, message, lineNumber, sourceID);
638}
639
640void InspectorInstrumentation::consoleCountImpl(InspectorAgent* inspectorAgent, PassRefPtr<ScriptArguments> arguments, PassRefPtr<ScriptCallStack> stack)
641{
642    inspectorAgent->consoleAgent()->count(arguments, stack);
643}
644
645void InspectorInstrumentation::startConsoleTimingImpl(InspectorAgent* inspectorAgent, const String& title)
646{
647    inspectorAgent->consoleAgent()->startTiming(title);
648}
649
650void InspectorInstrumentation::stopConsoleTimingImpl(InspectorAgent* inspectorAgent, const String& title, PassRefPtr<ScriptCallStack> stack)
651{
652    inspectorAgent->consoleAgent()->stopTiming(title, stack);
653}
654
655void InspectorInstrumentation::consoleMarkTimelineImpl(InspectorAgent* inspectorAgent, PassRefPtr<ScriptArguments> arguments)
656{
657    if (InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(inspectorAgent)) {
658        String message;
659        arguments->getFirstArgumentAsString(message);
660        timelineAgent->didMarkTimeline(message);
661     }
662}
663
664#if ENABLE(JAVASCRIPT_DEBUGGER)
665void InspectorInstrumentation::addStartProfilingMessageToConsoleImpl(InspectorAgent* inspectorAgent, const String& title, unsigned lineNumber, const String& sourceURL)
666{
667    if (InspectorProfilerAgent* profilerAgent = inspectorAgent->profilerAgent())
668        profilerAgent->addStartProfilingMessageToConsole(title, lineNumber, sourceURL);
669}
670
671void InspectorInstrumentation::addProfileImpl(InspectorAgent* inspectorAgent, RefPtr<ScriptProfile> profile, PassRefPtr<ScriptCallStack> callStack)
672{
673    if (InspectorProfilerAgent* profilerAgent = inspectorAgent->profilerAgent()) {
674        const ScriptCallFrame& lastCaller = callStack->at(0);
675        profilerAgent->addProfile(profile, lastCaller.lineNumber(), lastCaller.sourceURL());
676    }
677}
678
679String InspectorInstrumentation::getCurrentUserInitiatedProfileNameImpl(InspectorAgent* inspectorAgent, bool incrementProfileNumber)
680{
681    if (InspectorProfilerAgent* profilerAgent = inspectorAgent->profilerAgent())
682        return profilerAgent->getCurrentUserInitiatedProfileName(incrementProfileNumber);
683    return "";
684}
685
686bool InspectorInstrumentation::profilerEnabledImpl(InspectorAgent* inspectorAgent)
687{
688    return inspectorAgent->instrumentingAgents()->inspectorProfilerAgent()->enabled();
689}
690#endif
691
692#if ENABLE(DATABASE)
693void InspectorInstrumentation::didOpenDatabaseImpl(InspectorAgent* inspectorAgent, PassRefPtr<Database> database, const String& domain, const String& name, const String& version)
694{
695    if (!inspectorAgent->enabled())
696        return;
697    if (InspectorDatabaseAgent* dbAgent = inspectorAgent->instrumentingAgents()->inspectorDatabaseAgent())
698        dbAgent->didOpenDatabase(database, domain, name, version);
699}
700#endif
701
702#if ENABLE(DOM_STORAGE)
703void InspectorInstrumentation::didUseDOMStorageImpl(InspectorAgent* inspectorAgent, StorageArea* storageArea, bool isLocalStorage, Frame* frame)
704{
705    if (!inspectorAgent->enabled())
706        return;
707    if (InspectorDOMStorageAgent* domStorageAgent = inspectorAgent->instrumentingAgents()->inspectorDOMStorageAgent())
708        domStorageAgent->didUseDOMStorage(storageArea, isLocalStorage, frame);
709}
710#endif
711
712#if ENABLE(WORKERS)
713void InspectorInstrumentation::didCreateWorkerImpl(InspectorAgent* inspectorAgent, intptr_t id, const String& url, bool isSharedWorker)
714{
715    inspectorAgent->didCreateWorker(id, url, isSharedWorker);
716}
717
718void InspectorInstrumentation::didDestroyWorkerImpl(InspectorAgent* inspectorAgent, intptr_t id)
719{
720    inspectorAgent->didDestroyWorker(id);
721}
722#endif
723
724#if ENABLE(WEB_SOCKETS)
725void InspectorInstrumentation::didCreateWebSocketImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const KURL& requestURL, const KURL&)
726{
727    if (!inspectorAgent->enabled())
728        return;
729    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
730        resourceAgent->didCreateWebSocket(identifier, requestURL);
731}
732
733void InspectorInstrumentation::willSendWebSocketHandshakeRequestImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const WebSocketHandshakeRequest& request)
734{
735    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
736        resourceAgent->willSendWebSocketHandshakeRequest(identifier, request);
737}
738
739void InspectorInstrumentation::didReceiveWebSocketHandshakeResponseImpl(InspectorAgent* inspectorAgent, unsigned long identifier, const WebSocketHandshakeResponse& response)
740{
741    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
742        resourceAgent->didReceiveWebSocketHandshakeResponse(identifier, response);
743}
744
745void InspectorInstrumentation::didCloseWebSocketImpl(InspectorAgent* inspectorAgent, unsigned long identifier)
746{
747    if (InspectorResourceAgent* resourceAgent = retrieveResourceAgent(inspectorAgent))
748        resourceAgent->didCloseWebSocket(identifier);
749}
750#endif
751
752#if ENABLE(OFFLINE_WEB_APPLICATIONS)
753void InspectorInstrumentation::networkStateChangedImpl(InspectorAgent* inspectorAgent)
754{
755    if (InspectorApplicationCacheAgent* applicationCacheAgent = inspectorAgent->instrumentingAgents()->inspectorApplicationCacheAgent())
756        applicationCacheAgent->networkStateChanged();
757}
758
759void InspectorInstrumentation::updateApplicationCacheStatusImpl(InspectorAgent* inspectorAgent, Frame* frame)
760{
761    if (InspectorApplicationCacheAgent* applicationCacheAgent = inspectorAgent->instrumentingAgents()->inspectorApplicationCacheAgent())
762        applicationCacheAgent->updateApplicationCacheStatus(frame);
763}
764#endif
765
766bool InspectorInstrumentation::hasFrontend(InspectorAgent* inspectorAgent)
767{
768    return inspectorAgent->hasFrontend();
769}
770
771void InspectorInstrumentation::pauseOnNativeEventIfNeeded(InspectorAgent* inspectorAgent, const String& categoryType, const String& eventName, bool synchronous)
772{
773#if ENABLE(JAVASCRIPT_DEBUGGER)
774    if (InspectorBrowserDebuggerAgent* browserDebuggerAgent = inspectorAgent->instrumentingAgents()->inspectorBrowserDebuggerAgent())
775        browserDebuggerAgent->pauseOnNativeEventIfNeeded(categoryType, eventName, synchronous);
776#endif
777}
778
779void InspectorInstrumentation::cancelPauseOnNativeEvent(InspectorAgent* inspectorAgent)
780{
781#if ENABLE(JAVASCRIPT_DEBUGGER)
782    if (InspectorDebuggerAgent* debuggerAgent = inspectorAgent->debuggerAgent())
783        debuggerAgent->cancelPauseOnNextStatement();
784#endif
785}
786
787InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(InspectorAgent* inspectorAgent)
788{
789    return inspectorAgent->instrumentingAgents()->inspectorTimelineAgent();
790}
791
792InspectorTimelineAgent* InspectorInstrumentation::retrieveTimelineAgent(const InspectorInstrumentationCookie& cookie)
793{
794    if (!cookie.first)
795        return 0;
796    InspectorTimelineAgent* timelineAgent = retrieveTimelineAgent(cookie.first);
797    if (timelineAgent && timelineAgent->id() == cookie.second)
798        return timelineAgent;
799    return 0;
800}
801
802InspectorResourceAgent* InspectorInstrumentation::retrieveResourceAgent(InspectorAgent* inspectorAgent)
803{
804    return inspectorAgent->instrumentingAgents()->inspectorResourceAgent();
805}
806
807InspectorPageAgent* InspectorInstrumentation::retrievePageAgent(InspectorAgent* inspectorAgent)
808{
809    return inspectorAgent->instrumentingAgents()->inspectorPageAgent();
810}
811
812} // namespace WebCore
813
814#endif // !ENABLE(INSPECTOR)
815