Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / sdk / ResourceTreeModel.js
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 /**
32  * @constructor
33  * @extends {WebInspector.SDKModel}
34  * @param {!WebInspector.Target} target
35  */
36 WebInspector.ResourceTreeModel = function(target)
37 {
38     WebInspector.SDKModel.call(this, WebInspector.ResourceTreeModel, target);
39
40     target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
41     target.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);
42
43     target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
44     target.consoleModel.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
45
46     this._agent = target.pageAgent();
47     this._agent.enable();
48
49     this._fetchResourceTree();
50
51     target.registerPageDispatcher(new WebInspector.PageDispatcher(this));
52
53     this._pendingConsoleMessages = {};
54     this._securityOriginFrameCount = {};
55     this._inspectedPageURL = "";
56 }
57
58 WebInspector.ResourceTreeModel.EventTypes = {
59     FrameAdded: "FrameAdded",
60     FrameNavigated: "FrameNavigated",
61     FrameDetached: "FrameDetached",
62     FrameResized: "FrameResized",
63     MainFrameNavigated: "MainFrameNavigated",
64     ResourceAdded: "ResourceAdded",
65     WillLoadCachedResources: "WillLoadCachedResources",
66     CachedResourcesLoaded: "CachedResourcesLoaded",
67     DOMContentLoaded: "DOMContentLoaded",
68     Load: "Load",
69     WillReloadPage: "WillReloadPage",
70     InspectedURLChanged: "InspectedURLChanged",
71     SecurityOriginAdded: "SecurityOriginAdded",
72     SecurityOriginRemoved: "SecurityOriginRemoved",
73     ScreencastFrame: "ScreencastFrame",
74     ScreencastVisibilityChanged: "ScreencastVisibilityChanged",
75     ViewportChanged: "ViewportChanged",
76     ColorPicked: "ColorPicked"
77 }
78
79 WebInspector.ResourceTreeModel.prototype = {
80     _fetchResourceTree: function()
81     {
82         /** @type {!Object.<string, !WebInspector.ResourceTreeFrame>} */
83         this._frames = {};
84         delete this._cachedResourcesProcessed;
85         this._agent.getResourceTree(this._processCachedResources.bind(this));
86     },
87
88     _processCachedResources: function(error, mainFramePayload)
89     {
90         if (error) {
91             //FIXME: remove resourceTreeModel from worker
92             if (!this.target().isWorkerTarget())
93                 console.error(JSON.stringify(error));
94             return;
95         }
96
97         this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
98         this._inspectedPageURL = mainFramePayload.frame.url;
99         this._addFramesRecursively(null, mainFramePayload);
100         this._dispatchInspectedURLChanged();
101         this._cachedResourcesProcessed = true;
102         this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
103     },
104
105     /**
106      * @return {string}
107      */
108     inspectedPageURL: function()
109     {
110         return this._inspectedPageURL;
111     },
112
113     /**
114      * @return {string}
115      */
116     inspectedPageDomain: function()
117     {
118         var parsedURL = this._inspectedPageURL ? this._inspectedPageURL.asParsedURL() : null;
119         return parsedURL ? parsedURL.host : "";
120     },
121
122     /**
123      * @return {boolean}
124      */
125     cachedResourcesLoaded: function()
126     {
127         return this._cachedResourcesProcessed;
128     },
129
130     _dispatchInspectedURLChanged: function()
131     {
132         InspectorFrontendHost.inspectedURLChanged(this._inspectedPageURL);
133         this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedPageURL);
134     },
135
136     /**
137      * @param {!WebInspector.ResourceTreeFrame} frame
138      * @param {boolean=} aboutToNavigate
139      */
140     _addFrame: function(frame, aboutToNavigate)
141     {
142         this._frames[frame.id] = frame;
143         if (frame.isMainFrame())
144             this.mainFrame = frame;
145         this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
146         if (!aboutToNavigate)
147             this._addSecurityOrigin(frame.securityOrigin);
148     },
149
150     /**
151      * @param {string} securityOrigin
152      */
153     _addSecurityOrigin: function(securityOrigin)
154     {
155         if (!this._securityOriginFrameCount[securityOrigin]) {
156             this._securityOriginFrameCount[securityOrigin] = 1;
157             this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginAdded, securityOrigin);
158             return;
159         }
160         this._securityOriginFrameCount[securityOrigin] += 1;
161     },
162
163     /**
164      * @param {string|undefined} securityOrigin
165      */
166     _removeSecurityOrigin: function(securityOrigin)
167     {
168         if (typeof securityOrigin === "undefined")
169             return;
170         if (this._securityOriginFrameCount[securityOrigin] === 1) {
171             delete this._securityOriginFrameCount[securityOrigin];
172             this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.SecurityOriginRemoved, securityOrigin);
173             return;
174         }
175         this._securityOriginFrameCount[securityOrigin] -= 1;
176     },
177
178     /**
179      * @return {!Array.<string>}
180      */
181     securityOrigins: function()
182     {
183         return Object.keys(this._securityOriginFrameCount);
184     },
185
186     /**
187      * @param {!WebInspector.ResourceTreeFrame} mainFrame
188      */
189     _handleMainFrameDetached: function(mainFrame)
190     {
191         /**
192          * @param {!WebInspector.ResourceTreeFrame} frame
193          * @this {WebInspector.ResourceTreeModel}
194          */
195         function removeOriginForFrame(frame)
196         {
197             for (var i = 0; i < frame.childFrames.length; ++i)
198                 removeOriginForFrame.call(this, frame.childFrames[i]);
199             if (!frame.isMainFrame())
200                 this._removeSecurityOrigin(frame.securityOrigin);
201         }
202         removeOriginForFrame.call(this, mainFrame);
203     },
204
205     /**
206      * @param {!PageAgent.FrameId} frameId
207      * @param {?PageAgent.FrameId} parentFrameId
208      * @return {?WebInspector.ResourceTreeFrame}
209      */
210     _frameAttached: function(frameId, parentFrameId)
211     {
212         // Do nothing unless cached resource tree is processed - it will overwrite everything.
213         if (!this._cachedResourcesProcessed)
214             return null;
215         if (this._frames[frameId])
216             return null;
217
218         var parentFrame = parentFrameId ? this._frames[parentFrameId] : null;
219         var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, frameId);
220         if (frame.isMainFrame() && this.mainFrame) {
221             this._handleMainFrameDetached(this.mainFrame);
222             // Navigation to the new backend process.
223             this._frameDetached(this.mainFrame.id);
224         }
225         this._addFrame(frame, true);
226         return frame;
227     },
228
229     /**
230      * @param {!PageAgent.Frame} framePayload
231      */
232     _frameNavigated: function(framePayload)
233     {
234         // Do nothing unless cached resource tree is processed - it will overwrite everything.
235         if (!this._cachedResourcesProcessed)
236             return;
237         var frame = this._frames[framePayload.id];
238         if (!frame) {
239             // Simulate missed "frameAttached" for a main frame navigation to the new backend process.
240             console.assert(!framePayload.parentId, "Main frame shouldn't have parent frame id.");
241             frame = this._frameAttached(framePayload.id, framePayload.parentId || "");
242             console.assert(frame);
243         }
244         this._removeSecurityOrigin(frame.securityOrigin);
245         frame._navigate(framePayload);
246         var addedOrigin = frame.securityOrigin;
247
248         if (frame.isMainFrame())
249             this._inspectedPageURL = frame.url;
250
251         this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
252         if (frame.isMainFrame())
253             this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);
254         if (addedOrigin)
255             this._addSecurityOrigin(addedOrigin);
256
257         // Fill frame with retained resources (the ones loaded using new loader).
258         var resources = frame.resources();
259         for (var i = 0; i < resources.length; ++i)
260             this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]);
261
262         if (frame.isMainFrame())
263             this._dispatchInspectedURLChanged();
264     },
265
266     /**
267      * @param {!PageAgent.FrameId} frameId
268      */
269     _frameDetached: function(frameId)
270     {
271         // Do nothing unless cached resource tree is processed - it will overwrite everything.
272         if (!this._cachedResourcesProcessed)
273             return;
274
275         var frame = this._frames[frameId];
276         if (!frame)
277             return;
278
279         this._removeSecurityOrigin(frame.securityOrigin);
280         if (frame.parentFrame)
281             frame.parentFrame._removeChildFrame(frame);
282         else
283             frame._remove();
284     },
285
286     /**
287      * @param {!WebInspector.Event} event
288      */
289     _onRequestFinished: function(event)
290     {
291         if (!this._cachedResourcesProcessed)
292             return;
293
294         var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
295         if (request.failed || request.resourceType() === WebInspector.resourceTypes.XHR)
296             return;
297
298         var frame = this._frames[request.frameId];
299         if (frame) {
300             var resource = frame._addRequest(request);
301             this._addPendingConsoleMessagesToResource(resource);
302         }
303     },
304
305     /**
306      * @param {!WebInspector.Event} event
307      */
308     _onRequestUpdateDropped: function(event)
309     {
310         if (!this._cachedResourcesProcessed)
311             return;
312
313         var frameId = event.data.frameId;
314         var frame = this._frames[frameId];
315         if (!frame)
316             return;
317
318         var url = event.data.url;
319         if (frame._resourcesMap[url])
320             return;
321
322         var resource = new WebInspector.Resource(this.target(), null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType);
323         frame.addResource(resource);
324     },
325
326     /**
327      * @param {!PageAgent.FrameId} frameId
328      * @return {!WebInspector.ResourceTreeFrame}
329      */
330     frameForId: function(frameId)
331     {
332         return this._frames[frameId];
333     },
334
335     /**
336      * @param {function(!WebInspector.Resource)} callback
337      * @return {boolean}
338      */
339     forAllResources: function(callback)
340     {
341         if (this.mainFrame)
342             return this.mainFrame._callForFrameResources(callback);
343         return false;
344     },
345
346     /**
347      * @return {!Array.<!WebInspector.ResourceTreeFrame>}
348      */
349     frames: function()
350     {
351         return Object.values(this._frames);
352     },
353
354     /**
355      * @param {!WebInspector.Event} event
356      */
357     _consoleMessageAdded: function(event)
358     {
359         var msg = /** @type {!WebInspector.ConsoleMessage} */ (event.data);
360         var resource = msg.url ? this.resourceForURL(msg.url) : null;
361         if (resource)
362             this._addConsoleMessageToResource(msg, resource);
363         else
364             this._addPendingConsoleMessage(msg);
365     },
366
367     /**
368      * @param {!WebInspector.ConsoleMessage} msg
369      */
370     _addPendingConsoleMessage: function(msg)
371     {
372         if (!msg.url)
373             return;
374         if (!this._pendingConsoleMessages[msg.url])
375             this._pendingConsoleMessages[msg.url] = [];
376         this._pendingConsoleMessages[msg.url].push(msg);
377     },
378
379     /**
380      * @param {!WebInspector.Resource} resource
381      */
382     _addPendingConsoleMessagesToResource: function(resource)
383     {
384         var messages = this._pendingConsoleMessages[resource.url];
385         if (messages) {
386             for (var i = 0; i < messages.length; i++)
387                 this._addConsoleMessageToResource(messages[i], resource);
388             delete this._pendingConsoleMessages[resource.url];
389         }
390     },
391
392     /**
393      * @param {!WebInspector.ConsoleMessage} msg
394      * @param {!WebInspector.Resource} resource
395      */
396     _addConsoleMessageToResource: function(msg, resource)
397     {
398         switch (msg.level) {
399         case WebInspector.ConsoleMessage.MessageLevel.Warning:
400             resource.warnings++;
401             break;
402         case WebInspector.ConsoleMessage.MessageLevel.Error:
403             resource.errors++;
404             break;
405         }
406         resource.addMessage(msg);
407     },
408
409     _consoleCleared: function()
410     {
411         function callback(resource)
412         {
413             resource.clearErrorsAndWarnings();
414         }
415
416         this._pendingConsoleMessages = {};
417         this.forAllResources(callback);
418     },
419
420     /**
421      * @param {string} url
422      * @return {?WebInspector.Resource}
423      */
424     resourceForURL: function(url)
425     {
426         // Workers call into this with no frames available.
427         return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
428     },
429
430     /**
431      * @param {?WebInspector.ResourceTreeFrame} parentFrame
432      * @param {!PageAgent.FrameResourceTree} frameTreePayload
433      */
434     _addFramesRecursively: function(parentFrame, frameTreePayload)
435     {
436         var framePayload = frameTreePayload.frame;
437         var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload.id, framePayload);
438         this._addFrame(frame);
439
440         var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
441         if (frame.isMainFrame())
442             this._inspectedPageURL = frameResource.url;
443         // FIXME(413891): This check could be removed once we stop to send frame tree for service/shared workers.
444         // This makes sure that the shadow page document resource does not hide the worker script resource (they have the same url).
445         if (!WebInspector.isWorkerFrontend())
446             frame.addResource(frameResource);
447
448         for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
449             this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
450
451         for (var i = 0; i < frameTreePayload.resources.length; ++i) {
452             var subresource = frameTreePayload.resources[i];
453             var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
454             frame.addResource(resource);
455         }
456     },
457
458     /**
459      * @param {!PageAgent.Frame} frame
460      * @param {string} url
461      * @param {!WebInspector.ResourceType} type
462      * @param {string} mimeType
463      * @return {!WebInspector.Resource}
464      */
465     _createResourceFromFramePayload: function(frame, url, type, mimeType)
466     {
467         return new WebInspector.Resource(this.target(), null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
468     },
469
470     /**
471      * @param {boolean=} ignoreCache
472      * @param {string=} scriptToEvaluateOnLoad
473      * @param {string=} scriptPreprocessor
474      */
475     reloadPage: function(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor)
476     {
477         this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage);
478         this._agent.reload(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor);
479     },
480
481     __proto__: WebInspector.SDKModel.prototype
482 }
483
484 /**
485  * @constructor
486  * @param {!WebInspector.ResourceTreeModel} model
487  * @param {?WebInspector.ResourceTreeFrame} parentFrame
488  * @param {!PageAgent.FrameId} frameId
489  * @param {!PageAgent.Frame=} payload
490  */
491 WebInspector.ResourceTreeFrame = function(model, parentFrame, frameId, payload)
492 {
493     this._model = model;
494     this._parentFrame = parentFrame;
495     this._id = frameId;
496     this._url = "";
497
498     if (payload) {
499         this._loaderId = payload.loaderId;
500         this._name = payload.name;
501         this._url = payload.url;
502         this._securityOrigin = payload.securityOrigin;
503         this._mimeType = payload.mimeType;
504     }
505
506     /**
507      * @type {!Array.<!WebInspector.ResourceTreeFrame>}
508      */
509     this._childFrames = [];
510
511     /**
512      * @type {!Object.<string, !WebInspector.Resource>}
513      */
514     this._resourcesMap = {};
515
516     if (this._parentFrame)
517         this._parentFrame._childFrames.push(this);
518 }
519
520 WebInspector.ResourceTreeFrame.prototype = {
521     /**
522      * @return {!WebInspector.Target}
523      */
524     target: function()
525     {
526         return this._model.target();
527     },
528
529     /**
530      * @return {string}
531      */
532     get id()
533     {
534         return this._id;
535     },
536
537     /**
538      * @return {string}
539      */
540     get name()
541     {
542         return this._name || "";
543     },
544
545     /**
546      * @return {string}
547      */
548     get url()
549     {
550         return this._url;
551     },
552
553     /**
554      * @return {string}
555      */
556     get securityOrigin()
557     {
558         return this._securityOrigin;
559     },
560
561     /**
562      * @return {string}
563      */
564     get loaderId()
565     {
566         return this._loaderId;
567     },
568
569     /**
570      * @return {?WebInspector.ResourceTreeFrame}
571      */
572     get parentFrame()
573     {
574         return this._parentFrame;
575     },
576
577     /**
578      * @return {!Array.<!WebInspector.ResourceTreeFrame>}
579      */
580     get childFrames()
581     {
582         return this._childFrames;
583     },
584
585     /**
586      * @return {boolean}
587      */
588     isMainFrame: function()
589     {
590         return !this._parentFrame;
591     },
592
593     /**
594      * @param {!PageAgent.Frame} framePayload
595      */
596     _navigate: function(framePayload)
597     {
598         this._loaderId = framePayload.loaderId;
599         this._name = framePayload.name;
600         this._url = framePayload.url;
601         this._securityOrigin = framePayload.securityOrigin;
602         this._mimeType = framePayload.mimeType;
603
604         var mainResource = this._resourcesMap[this._url];
605         this._resourcesMap = {};
606         this._removeChildFrames();
607         if (mainResource && mainResource.loaderId === this._loaderId)
608             this.addResource(mainResource);
609     },
610
611     /**
612      * @return {!WebInspector.Resource}
613      */
614     get mainResource()
615     {
616         return this._resourcesMap[this._url];
617     },
618
619     /**
620      * @param {!WebInspector.ResourceTreeFrame} frame
621      */
622     _removeChildFrame: function(frame)
623     {
624         this._childFrames.remove(frame);
625         frame._remove();
626     },
627
628     _removeChildFrames: function()
629     {
630         var frames = this._childFrames;
631         this._childFrames = [];
632         for (var i = 0; i < frames.length; ++i)
633             frames[i]._remove();
634     },
635
636     _remove: function()
637     {
638         this._removeChildFrames();
639         delete this._model._frames[this.id];
640         this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
641     },
642
643     /**
644      * @param {!WebInspector.Resource} resource
645      */
646     addResource: function(resource)
647     {
648         if (this._resourcesMap[resource.url] === resource) {
649             // Already in the tree, we just got an extra update.
650             return;
651         }
652         this._resourcesMap[resource.url] = resource;
653         this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
654     },
655
656     /**
657      * @param {!WebInspector.NetworkRequest} request
658      * @return {!WebInspector.Resource}
659      */
660     _addRequest: function(request)
661     {
662         var resource = this._resourcesMap[request.url];
663         if (resource && resource.request === request) {
664             // Already in the tree, we just got an extra update.
665             return resource;
666         }
667         resource = new WebInspector.Resource(this.target(), request, request.url, request.documentURL, request.frameId, request.loaderId, request.resourceType(), request.mimeType);
668         this._resourcesMap[resource.url] = resource;
669         this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
670         return resource;
671     },
672
673     /**
674      * @return {!Array.<!WebInspector.Resource>}
675      */
676     resources: function()
677     {
678         var result = [];
679         for (var url in this._resourcesMap)
680             result.push(this._resourcesMap[url]);
681         return result;
682     },
683
684     /**
685      * @param {string} url
686      * @return {?WebInspector.Resource}
687      */
688     resourceForURL: function(url)
689     {
690         var result;
691         function filter(resource)
692         {
693             if (resource.url === url) {
694                 result = resource;
695                 return true;
696             }
697         }
698         this._callForFrameResources(filter);
699         return result || null;
700     },
701
702     /**
703      * @param {function(!WebInspector.Resource)} callback
704      * @return {boolean}
705      */
706     _callForFrameResources: function(callback)
707     {
708         for (var url in this._resourcesMap) {
709             if (callback(this._resourcesMap[url]))
710                 return true;
711         }
712
713         for (var i = 0; i < this._childFrames.length; ++i) {
714             if (this._childFrames[i]._callForFrameResources(callback))
715                 return true;
716         }
717         return false;
718     },
719
720     /**
721      * @return {string}
722      */
723     displayName: function()
724     {
725         if (!this._parentFrame)
726             return WebInspector.UIString("<top frame>");
727         var subtitle = new WebInspector.ParsedURL(this._url).displayName;
728         if (subtitle) {
729             if (!this._name)
730                 return subtitle;
731             return this._name + "( " + subtitle + " )";
732         }
733         return WebInspector.UIString("<iframe>");
734     }
735 }
736
737 /**
738  * @constructor
739  * @implements {PageAgent.Dispatcher}
740  */
741 WebInspector.PageDispatcher = function(resourceTreeModel)
742 {
743     this._resourceTreeModel = resourceTreeModel;
744 }
745
746 WebInspector.PageDispatcher.prototype = {
747     /**
748      * @override
749      * @param {number} time
750      */
751     domContentEventFired: function(time)
752     {
753         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
754     },
755
756     /**
757      * @override
758      * @param {number} time
759      */
760     loadEventFired: function(time)
761     {
762         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.Load, time);
763     },
764
765     frameAttached: function(frameId, parentFrameId)
766     {
767         this._resourceTreeModel._frameAttached(frameId, parentFrameId);
768     },
769
770     frameNavigated: function(frame)
771     {
772         this._resourceTreeModel._frameNavigated(frame);
773     },
774
775     frameDetached: function(frameId)
776     {
777         this._resourceTreeModel._frameDetached(frameId);
778     },
779
780     frameStartedLoading: function(frameId)
781     {
782     },
783
784     frameStoppedLoading: function(frameId)
785     {
786     },
787
788     frameScheduledNavigation: function(frameId, delay)
789     {
790     },
791
792     frameClearedScheduledNavigation: function(frameId)
793     {
794     },
795
796     frameResized: function()
797     {
798         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameResized, null);
799     },
800
801     javascriptDialogOpening: function(message)
802     {
803     },
804
805     javascriptDialogClosed: function()
806     {
807     },
808
809     scriptsEnabled: function(isEnabled)
810     {
811         WebInspector.settings.javaScriptDisabled.set(!isEnabled);
812     },
813
814     /**
815      * @param {string} data
816      * @param {!PageAgent.ScreencastFrameMetadata=} metadata
817      */
818     screencastFrame: function(data, metadata)
819     {
820         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, {data:data, metadata:metadata});
821     },
822
823     /**
824      * @param {boolean} visible
825      */
826     screencastVisibilityChanged: function(visible)
827     {
828         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged, {visible:visible});
829     },
830
831     /**
832      * @param {!PageAgent.Viewport=} viewport
833      */
834     viewportChanged: function(viewport)
835     {
836         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ViewportChanged, viewport);
837     },
838
839     /**
840      * @param {!DOMAgent.RGBA} color
841      */
842     colorPicked: function(color)
843     {
844         this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ColorPicked, color);
845     },
846
847     interstitialShown: function()
848     {
849         // Frontend is not interested in interstitials.
850     },
851
852     interstitialHidden: function()
853     {
854         // Frontend is not interested in interstitials.
855     }
856 }
857
858 /**
859  * @type {!WebInspector.ResourceTreeModel}
860  */
861 WebInspector.resourceTreeModel;