• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
36WebInspector.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
58WebInspector.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
79WebInspector.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.type === 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        frame.addResource(frameResource);
444
445        for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
446            this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
447
448        for (var i = 0; i < frameTreePayload.resources.length; ++i) {
449            var subresource = frameTreePayload.resources[i];
450            var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
451            frame.addResource(resource);
452        }
453    },
454
455    /**
456     * @param {!PageAgent.Frame} frame
457     * @param {string} url
458     * @param {!WebInspector.ResourceType} type
459     * @param {string} mimeType
460     * @return {!WebInspector.Resource}
461     */
462    _createResourceFromFramePayload: function(frame, url, type, mimeType)
463    {
464        return new WebInspector.Resource(this.target(), null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
465    },
466
467    /**
468     * @param {boolean=} ignoreCache
469     * @param {string=} scriptToEvaluateOnLoad
470     * @param {string=} scriptPreprocessor
471     */
472    reloadPage: function(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor)
473    {
474        this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillReloadPage);
475        this._agent.reload(ignoreCache, scriptToEvaluateOnLoad, scriptPreprocessor);
476    },
477
478    __proto__: WebInspector.SDKModel.prototype
479}
480
481/**
482 * @constructor
483 * @param {!WebInspector.ResourceTreeModel} model
484 * @param {?WebInspector.ResourceTreeFrame} parentFrame
485 * @param {!PageAgent.FrameId} frameId
486 * @param {!PageAgent.Frame=} payload
487 */
488WebInspector.ResourceTreeFrame = function(model, parentFrame, frameId, payload)
489{
490    this._model = model;
491    this._parentFrame = parentFrame;
492    this._id = frameId;
493    this._url = "";
494
495    if (payload) {
496        this._loaderId = payload.loaderId;
497        this._name = payload.name;
498        this._url = payload.url;
499        this._securityOrigin = payload.securityOrigin;
500        this._mimeType = payload.mimeType;
501    }
502
503    /**
504     * @type {!Array.<!WebInspector.ResourceTreeFrame>}
505     */
506    this._childFrames = [];
507
508    /**
509     * @type {!Object.<string, !WebInspector.Resource>}
510     */
511    this._resourcesMap = {};
512
513    if (this._parentFrame)
514        this._parentFrame._childFrames.push(this);
515}
516
517WebInspector.ResourceTreeFrame.prototype = {
518    /**
519     * @return {!WebInspector.Target}
520     */
521    target: function()
522    {
523        return this._model.target();
524    },
525
526    /**
527     * @return {string}
528     */
529    get id()
530    {
531        return this._id;
532    },
533
534    /**
535     * @return {string}
536     */
537    get name()
538    {
539        return this._name || "";
540    },
541
542    /**
543     * @return {string}
544     */
545    get url()
546    {
547        return this._url;
548    },
549
550    /**
551     * @return {string}
552     */
553    get securityOrigin()
554    {
555        return this._securityOrigin;
556    },
557
558    /**
559     * @return {string}
560     */
561    get loaderId()
562    {
563        return this._loaderId;
564    },
565
566    /**
567     * @return {?WebInspector.ResourceTreeFrame}
568     */
569    get parentFrame()
570    {
571        return this._parentFrame;
572    },
573
574    /**
575     * @return {!Array.<!WebInspector.ResourceTreeFrame>}
576     */
577    get childFrames()
578    {
579        return this._childFrames;
580    },
581
582    /**
583     * @return {boolean}
584     */
585    isMainFrame: function()
586    {
587        return !this._parentFrame;
588    },
589
590    /**
591     * @param {!PageAgent.Frame} framePayload
592     */
593    _navigate: function(framePayload)
594    {
595        this._loaderId = framePayload.loaderId;
596        this._name = framePayload.name;
597        this._url = framePayload.url;
598        this._securityOrigin = framePayload.securityOrigin;
599        this._mimeType = framePayload.mimeType;
600
601        var mainResource = this._resourcesMap[this._url];
602        this._resourcesMap = {};
603        this._removeChildFrames();
604        if (mainResource && mainResource.loaderId === this._loaderId)
605            this.addResource(mainResource);
606    },
607
608    /**
609     * @return {!WebInspector.Resource}
610     */
611    get mainResource()
612    {
613        return this._resourcesMap[this._url];
614    },
615
616    /**
617     * @param {!WebInspector.ResourceTreeFrame} frame
618     */
619    _removeChildFrame: function(frame)
620    {
621        this._childFrames.remove(frame);
622        frame._remove();
623    },
624
625    _removeChildFrames: function()
626    {
627        var frames = this._childFrames;
628        this._childFrames = [];
629        for (var i = 0; i < frames.length; ++i)
630            frames[i]._remove();
631    },
632
633    _remove: function()
634    {
635        this._removeChildFrames();
636        delete this._model._frames[this.id];
637        this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
638    },
639
640    /**
641     * @param {!WebInspector.Resource} resource
642     */
643    addResource: function(resource)
644    {
645        if (this._resourcesMap[resource.url] === resource) {
646            // Already in the tree, we just got an extra update.
647            return;
648        }
649        this._resourcesMap[resource.url] = resource;
650        this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
651    },
652
653    /**
654     * @param {!WebInspector.NetworkRequest} request
655     * @return {!WebInspector.Resource}
656     */
657    _addRequest: function(request)
658    {
659        var resource = this._resourcesMap[request.url];
660        if (resource && resource.request === request) {
661            // Already in the tree, we just got an extra update.
662            return resource;
663        }
664        resource = new WebInspector.Resource(this.target(), request, request.url, request.documentURL, request.frameId, request.loaderId, request.type, request.mimeType);
665        this._resourcesMap[resource.url] = resource;
666        this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
667        return resource;
668    },
669
670    /**
671     * @return {!Array.<!WebInspector.Resource>}
672     */
673    resources: function()
674    {
675        var result = [];
676        for (var url in this._resourcesMap)
677            result.push(this._resourcesMap[url]);
678        return result;
679    },
680
681    /**
682     * @param {string} url
683     * @return {?WebInspector.Resource}
684     */
685    resourceForURL: function(url)
686    {
687        var result;
688        function filter(resource)
689        {
690            if (resource.url === url) {
691                result = resource;
692                return true;
693            }
694        }
695        this._callForFrameResources(filter);
696        return result || null;
697    },
698
699    /**
700     * @param {function(!WebInspector.Resource)} callback
701     * @return {boolean}
702     */
703    _callForFrameResources: function(callback)
704    {
705        for (var url in this._resourcesMap) {
706            if (callback(this._resourcesMap[url]))
707                return true;
708        }
709
710        for (var i = 0; i < this._childFrames.length; ++i) {
711            if (this._childFrames[i]._callForFrameResources(callback))
712                return true;
713        }
714        return false;
715    },
716
717    /**
718     * @return {string}
719     */
720    displayName: function()
721    {
722        if (!this._parentFrame)
723            return WebInspector.UIString("<top frame>");
724        var subtitle = new WebInspector.ParsedURL(this._url).displayName;
725        if (subtitle) {
726            if (!this._name)
727                return subtitle;
728            return this._name + "( " + subtitle + " )";
729        }
730        return WebInspector.UIString("<iframe>");
731    }
732}
733
734/**
735 * @constructor
736 * @implements {PageAgent.Dispatcher}
737 */
738WebInspector.PageDispatcher = function(resourceTreeModel)
739{
740    this._resourceTreeModel = resourceTreeModel;
741}
742
743WebInspector.PageDispatcher.prototype = {
744    /**
745     * @override
746     * @param {number} time
747     */
748    domContentEventFired: function(time)
749    {
750        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
751    },
752
753    /**
754     * @override
755     * @param {number} time
756     */
757    loadEventFired: function(time)
758    {
759        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.Load, time);
760    },
761
762    frameAttached: function(frameId, parentFrameId)
763    {
764        this._resourceTreeModel._frameAttached(frameId, parentFrameId);
765    },
766
767    frameNavigated: function(frame)
768    {
769        this._resourceTreeModel._frameNavigated(frame);
770    },
771
772    frameDetached: function(frameId)
773    {
774        this._resourceTreeModel._frameDetached(frameId);
775    },
776
777    frameStartedLoading: function(frameId)
778    {
779    },
780
781    frameStoppedLoading: function(frameId)
782    {
783    },
784
785    frameScheduledNavigation: function(frameId, delay)
786    {
787    },
788
789    frameClearedScheduledNavigation: function(frameId)
790    {
791    },
792
793    frameResized: function()
794    {
795        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameResized, null);
796    },
797
798    javascriptDialogOpening: function(message)
799    {
800    },
801
802    javascriptDialogClosed: function()
803    {
804    },
805
806    scriptsEnabled: function(isEnabled)
807    {
808        WebInspector.settings.javaScriptDisabled.set(!isEnabled);
809    },
810
811    /**
812     * @param {string} data
813     * @param {!PageAgent.ScreencastFrameMetadata=} metadata
814     */
815    screencastFrame: function(data, metadata)
816    {
817        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastFrame, {data:data, metadata:metadata});
818    },
819
820    /**
821     * @param {boolean} visible
822     */
823    screencastVisibilityChanged: function(visible)
824    {
825        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ScreencastVisibilityChanged, {visible:visible});
826    },
827
828    /**
829     * @param {!PageAgent.Viewport=} viewport
830     */
831    viewportChanged: function(viewport)
832    {
833        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ViewportChanged, viewport);
834    },
835
836    /**
837     * @param {!DOMAgent.RGBA} color
838     */
839    colorPicked: function(color)
840    {
841        this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ColorPicked, color);
842    },
843
844    interstitialShown: function()
845    {
846        // Frontend is not interested in interstitials.
847    },
848
849    interstitialHidden: function()
850    {
851        // Frontend is not interested in interstitials.
852    }
853}
854
855/**
856 * @type {!WebInspector.ResourceTreeModel}
857 */
858WebInspector.resourceTreeModel;
859