blob: 48ea2934369e19cf734b65c64d27b32ce1aad8e5 [file] [log] [blame]
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @unrestricted
*/
SDK.ResourceTreeModel = class extends SDK.SDKModel {
/**
* @param {!SDK.Target} target
* @param {?SDK.NetworkManager} networkManager
* @param {!SDK.SecurityOriginManager} securityOriginManager
*/
constructor(target, networkManager, securityOriginManager) {
super(SDK.ResourceTreeModel, target);
if (networkManager) {
networkManager.addEventListener(
SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this);
networkManager.addEventListener(
SDK.NetworkManager.Events.RequestUpdateDropped, this._onRequestUpdateDropped, this);
}
this._agent = target.pageAgent();
this._agent.enable();
this._securityOriginManager = securityOriginManager;
this._fetchResourceTree();
target.registerPageDispatcher(new SDK.PageDispatcher(this));
this._pendingReloadOptions = null;
this._reloadSuspensionCount = 0;
}
/**
* @param {!SDK.Target} target
* @return {?SDK.ResourceTreeModel}
*/
static fromTarget(target) {
return /** @type {?SDK.ResourceTreeModel} */ (target.model(SDK.ResourceTreeModel));
}
/**
* @return {!Array.<!SDK.ResourceTreeFrame>}
*/
static frames() {
var result = [];
for (var target of SDK.targetManager.targets(SDK.Target.Capability.DOM))
result = result.concat(SDK.ResourceTreeModel.fromTarget(target)._frames.valuesArray());
return result;
}
/**
* @param {string} url
* @return {?SDK.Resource}
*/
static resourceForURL(url) {
for (var target of SDK.targetManager.targets(SDK.Target.Capability.DOM)) {
var mainFrame = SDK.ResourceTreeModel.fromTarget(target).mainFrame;
var result = mainFrame ? mainFrame.resourceForURL(url) : null;
if (result)
return result;
}
return null;
}
_fetchResourceTree() {
/** @type {!Map<string, !SDK.ResourceTreeFrame>} */
this._frames = new Map();
this._cachedResourcesProcessed = false;
this._agent.getResourceTree(this._processCachedResources.bind(this));
}
_processCachedResources(error, mainFramePayload) {
if (!error) {
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.WillLoadCachedResources);
this._addFramesRecursively(null, mainFramePayload);
this.target().setInspectedURL(mainFramePayload.frame.url);
}
this._cachedResourcesProcessed = true;
this.target().runtimeModel.setExecutionContextComparator(this._executionContextComparator.bind(this));
this.target().runtimeModel.fireExecutionContextOrderChanged();
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.CachedResourcesLoaded);
}
/**
* @return {boolean}
*/
cachedResourcesLoaded() {
return this._cachedResourcesProcessed;
}
/**
* @param {!SDK.ResourceTreeFrame} frame
* @param {boolean=} aboutToNavigate
*/
_addFrame(frame, aboutToNavigate) {
this._frames.set(frame.id, frame);
if (frame.isMainFrame()) {
this.mainFrame = frame;
this._securityOriginManager.setMainSecurityOrigin(frame.url);
}
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameAdded, frame);
if (!aboutToNavigate)
this._securityOriginManager.addSecurityOrigin(frame.securityOrigin);
}
/**
* @param {!SDK.ResourceTreeFrame} mainFrame
*/
_handleMainFrameDetached(mainFrame) {
/**
* @param {!SDK.ResourceTreeFrame} frame
* @this {SDK.ResourceTreeModel}
*/
function removeOriginForFrame(frame) {
for (var i = 0; i < frame.childFrames.length; ++i)
removeOriginForFrame.call(this, frame.childFrames[i]);
if (!frame.isMainFrame())
this._securityOriginManager.removeSecurityOrigin(frame.securityOrigin);
}
removeOriginForFrame.call(this, mainFrame);
}
/**
* @param {!Protocol.Page.FrameId} frameId
* @param {?Protocol.Page.FrameId} parentFrameId
* @return {?SDK.ResourceTreeFrame}
*/
_frameAttached(frameId, parentFrameId) {
// Do nothing unless cached resource tree is processed - it will overwrite everything.
if (!this._cachedResourcesProcessed && parentFrameId)
return null;
if (this._frames.has(frameId))
return null;
var parentFrame = parentFrameId ? (this._frames.get(parentFrameId) || null) : null;
var frame = new SDK.ResourceTreeFrame(this, parentFrame, frameId);
if (frame.isMainFrame() && this.mainFrame) {
this._handleMainFrameDetached(this.mainFrame);
// Navigation to the new backend process.
this._frameDetached(this.mainFrame.id);
}
this._addFrame(frame, true);
return frame;
}
/**
* @param {!Protocol.Page.Frame} framePayload
*/
_frameNavigated(framePayload) {
// Do nothing unless cached resource tree is processed - it will overwrite everything.
if (!this._cachedResourcesProcessed && framePayload.parentId)
return;
var frame = this._frames.get(framePayload.id);
if (!frame) {
// Simulate missed "frameAttached" for a main frame navigation to the new backend process.
console.assert(!framePayload.parentId, 'Main frame shouldn\'t have parent frame id.');
frame = this._frameAttached(framePayload.id, framePayload.parentId || '');
console.assert(frame);
}
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameWillNavigate, frame);
this._securityOriginManager.removeSecurityOrigin(frame.securityOrigin);
frame._navigate(framePayload);
var addedOrigin = frame.securityOrigin;
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameNavigated, frame);
if (frame.isMainFrame()) {
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.MainFrameNavigated, frame);
if (Common.moduleSetting('preserveConsoleLog').get())
Common.console.log(Common.UIString('Navigated to %s', frame.url));
else
this.target().consoleModel.clear();
}
if (addedOrigin)
this._securityOriginManager.addSecurityOrigin(addedOrigin);
// Fill frame with retained resources (the ones loaded using new loader).
var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ResourceAdded, resources[i]);
if (frame.isMainFrame())
this.target().setInspectedURL(frame.url);
}
/**
* @param {!Protocol.Page.FrameId} frameId
*/
_frameDetached(frameId) {
// Do nothing unless cached resource tree is processed - it will overwrite everything.
if (!this._cachedResourcesProcessed)
return;
var frame = this._frames.get(frameId);
if (!frame)
return;
this._securityOriginManager.removeSecurityOrigin(frame.securityOrigin);
if (frame.parentFrame)
frame.parentFrame._removeChildFrame(frame);
else
frame._remove();
}
/**
* @param {!Common.Event} event
*/
_onRequestFinished(event) {
if (!this._cachedResourcesProcessed)
return;
var request = /** @type {!SDK.NetworkRequest} */ (event.data);
if (request.failed || request.resourceType() === Common.resourceTypes.XHR)
return;
var frame = this._frames.get(request.frameId);
if (frame)
frame._addRequest(request);
}
/**
* @param {!Common.Event} event
*/
_onRequestUpdateDropped(event) {
if (!this._cachedResourcesProcessed)
return;
var frameId = event.data.frameId;
var frame = this._frames.get(frameId);
if (!frame)
return;
var url = event.data.url;
if (frame._resourcesMap[url])
return;
var resource = new SDK.Resource(
this.target(), null, url, frame.url, frameId, event.data.loaderId,
Common.resourceTypes[event.data.resourceType], event.data.mimeType, event.data.lastModified, null);
frame.addResource(resource);
}
/**
* @param {!Protocol.Page.FrameId} frameId
* @return {!SDK.ResourceTreeFrame}
*/
frameForId(frameId) {
return this._frames.get(frameId);
}
/**
* @param {function(!SDK.Resource)} callback
* @return {boolean}
*/
forAllResources(callback) {
if (this.mainFrame)
return this.mainFrame._callForFrameResources(callback);
return false;
}
/**
* @return {!Array<!SDK.ResourceTreeFrame>}
*/
frames() {
return this._frames.valuesArray();
}
/**
* @param {string} url
* @return {?SDK.Resource}
*/
resourceForURL(url) {
// Workers call into this with no frames available.
return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
}
/**
* @param {?SDK.ResourceTreeFrame} parentFrame
* @param {!Protocol.Page.FrameResourceTree} frameTreePayload
*/
_addFramesRecursively(parentFrame, frameTreePayload) {
var framePayload = frameTreePayload.frame;
var frame = new SDK.ResourceTreeFrame(this, parentFrame, framePayload.id, framePayload);
this._addFrame(frame);
var frameResource = this._createResourceFromFramePayload(
framePayload, framePayload.url, Common.resourceTypes.Document, framePayload.mimeType, null, null);
frame.addResource(frameResource);
for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
for (var i = 0; i < frameTreePayload.resources.length; ++i) {
var subresource = frameTreePayload.resources[i];
var resource = this._createResourceFromFramePayload(
framePayload, subresource.url, Common.resourceTypes[subresource.type], subresource.mimeType,
subresource.lastModified || null, subresource.contentSize || null);
frame.addResource(resource);
}
}
/**
* @param {!Protocol.Page.Frame} frame
* @param {string} url
* @param {!Common.ResourceType} type
* @param {string} mimeType
* @param {?number} lastModifiedTime
* @param {?number} contentSize
* @return {!SDK.Resource}
*/
_createResourceFromFramePayload(frame, url, type, mimeType, lastModifiedTime, contentSize) {
var lastModified = typeof lastModifiedTime === 'number' ? new Date(lastModifiedTime * 1000) : null;
return new SDK.Resource(
this.target(), null, url, frame.url, frame.id, frame.loaderId, type, mimeType, lastModified, contentSize);
}
suspendReload() {
this._reloadSuspensionCount++;
}
resumeReload() {
this._reloadSuspensionCount--;
console.assert(this._reloadSuspensionCount >= 0, 'Unbalanced call to ResourceTreeModel.resumeReload()');
if (!this._reloadSuspensionCount && this._pendingReloadOptions)
this.reloadPage.apply(this, this._pendingReloadOptions);
}
/**
* @param {boolean=} bypassCache
* @param {string=} scriptToEvaluateOnLoad
*/
reloadPage(bypassCache, scriptToEvaluateOnLoad) {
// Only dispatch PageReloadRequested upon first reload request to simplify client logic.
if (!this._pendingReloadOptions)
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.PageReloadRequested);
if (this._reloadSuspensionCount) {
this._pendingReloadOptions = [bypassCache, scriptToEvaluateOnLoad];
return;
}
this._pendingReloadOptions = null;
this.dispatchEventToListeners(SDK.ResourceTreeModel.Events.WillReloadPage);
this._agent.reload(bypassCache, scriptToEvaluateOnLoad);
}
/**
* @param {function(string, ?string,!Array<!Protocol.Page.AppManifestError>)} callback
*/
fetchAppManifest(callback) {
this._agent.getAppManifest(myCallback);
/**
* @param {?Protocol.Error} protocolError
* @param {string} url
* @param {!Array<!Protocol.Page.AppManifestError>} errors
* @param {string=} data
*/
function myCallback(protocolError, url, errors, data) {
if (protocolError) {
callback(url, null, []);
return;
}
callback(url, data || null, errors);
}
}
/**
* @param {!SDK.ExecutionContext} a
* @param {!SDK.ExecutionContext} b
* @return {number}
*/
_executionContextComparator(a, b) {
/**
* @param {!SDK.ResourceTreeFrame} frame
*/
function framePath(frame) {
var currentFrame = frame;
var parents = [];
while (currentFrame) {
parents.push(currentFrame);
currentFrame = currentFrame.parentFrame;
}
return parents.reverse();
}
var framesA = a.frameId ? framePath(this.frameForId(a.frameId)) : [];
var framesB = b.frameId ? framePath(this.frameForId(b.frameId)) : [];
var frameA;
var frameB;
for (var i = 0;; i++) {
if (!framesA[i] || !framesB[i] || (framesA[i] !== framesB[i])) {
frameA = framesA[i];
frameB = framesB[i];
break;
}
}
if (!frameA && frameB)
return -1;
if (!frameB && frameA)
return 1;
if (frameA && frameB) {
return frameA.id.localeCompare(frameB.id);
}
return SDK.ExecutionContext.comparator(a, b);
}
};
/** @enum {symbol} */
SDK.ResourceTreeModel.Events = {
FrameAdded: Symbol('FrameAdded'),
FrameNavigated: Symbol('FrameNavigated'),
FrameDetached: Symbol('FrameDetached'),
FrameResized: Symbol('FrameResized'),
FrameWillNavigate: Symbol('FrameWillNavigate'),
MainFrameNavigated: Symbol('MainFrameNavigated'),
ResourceAdded: Symbol('ResourceAdded'),
WillLoadCachedResources: Symbol('WillLoadCachedResources'),
CachedResourcesLoaded: Symbol('CachedResourcesLoaded'),
DOMContentLoaded: Symbol('DOMContentLoaded'),
Load: Symbol('Load'),
PageReloadRequested: Symbol('PageReloadRequested'),
WillReloadPage: Symbol('WillReloadPage'),
ScreencastFrame: Symbol('ScreencastFrame'),
ScreencastVisibilityChanged: Symbol('ScreencastVisibilityChanged'),
ColorPicked: Symbol('ColorPicked'),
InterstitialShown: Symbol('InterstitialShown'),
InterstitialHidden: Symbol('InterstitialHidden')
};
/**
* @unrestricted
*/
SDK.ResourceTreeFrame = class {
/**
* @param {!SDK.ResourceTreeModel} model
* @param {?SDK.ResourceTreeFrame} parentFrame
* @param {!Protocol.Page.FrameId} frameId
* @param {!Protocol.Page.Frame=} payload
*/
constructor(model, parentFrame, frameId, payload) {
this._model = model;
this._parentFrame = parentFrame;
this._id = frameId;
this._url = '';
if (payload) {
this._loaderId = payload.loaderId;
this._name = payload.name;
this._url = payload.url;
this._securityOrigin = payload.securityOrigin;
this._mimeType = payload.mimeType;
}
/**
* @type {!Array.<!SDK.ResourceTreeFrame>}
*/
this._childFrames = [];
/**
* @type {!Object.<string, !SDK.Resource>}
*/
this._resourcesMap = {};
if (this._parentFrame)
this._parentFrame._childFrames.push(this);
}
/**
* @param {!SDK.ExecutionContext|!SDK.CSSStyleSheetHeader|!SDK.Resource} object
* @return {?SDK.ResourceTreeFrame}
*/
static _fromObject(object) {
var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(object.target());
var frameId = object.frameId;
if (!resourceTreeModel || !frameId)
return null;
return resourceTreeModel.frameForId(frameId);
}
/**
* @param {!SDK.Script} script
* @return {?SDK.ResourceTreeFrame}
*/
static fromScript(script) {
var executionContext = script.executionContext();
if (!executionContext)
return null;
return SDK.ResourceTreeFrame._fromObject(executionContext);
}
/**
* @param {!SDK.CSSStyleSheetHeader} header
* @return {?SDK.ResourceTreeFrame}
*/
static fromStyleSheet(header) {
return SDK.ResourceTreeFrame._fromObject(header);
}
/**
* @param {!SDK.Resource} resource
* @return {?SDK.ResourceTreeFrame}
*/
static fromResource(resource) {
return SDK.ResourceTreeFrame._fromObject(resource);
}
/**
* @return {!SDK.Target}
*/
target() {
return this._model.target();
}
/**
* @return {string}
*/
get id() {
return this._id;
}
/**
* @return {string}
*/
get name() {
return this._name || '';
}
/**
* @return {string}
*/
get url() {
return this._url;
}
/**
* @return {string}
*/
get securityOrigin() {
return this._securityOrigin;
}
/**
* @return {string}
*/
get loaderId() {
return this._loaderId;
}
/**
* @return {?SDK.ResourceTreeFrame}
*/
get parentFrame() {
return this._parentFrame;
}
/**
* @return {!Array.<!SDK.ResourceTreeFrame>}
*/
get childFrames() {
return this._childFrames;
}
/**
* @return {boolean}
*/
isMainFrame() {
return !this._parentFrame;
}
/**
* @param {!Protocol.Page.Frame} framePayload
*/
_navigate(framePayload) {
this._loaderId = framePayload.loaderId;
this._name = framePayload.name;
this._url = framePayload.url;
this._securityOrigin = framePayload.securityOrigin;
this._mimeType = framePayload.mimeType;
var mainResource = this._resourcesMap[this._url];
this._resourcesMap = {};
this._removeChildFrames();
if (mainResource && mainResource.loaderId === this._loaderId)
this.addResource(mainResource);
}
/**
* @return {!SDK.Resource}
*/
get mainResource() {
return this._resourcesMap[this._url];
}
/**
* @param {!SDK.ResourceTreeFrame} frame
*/
_removeChildFrame(frame) {
this._childFrames.remove(frame);
frame._remove();
}
_removeChildFrames() {
var frames = this._childFrames;
this._childFrames = [];
for (var i = 0; i < frames.length; ++i)
frames[i]._remove();
}
_remove() {
this._removeChildFrames();
this._model._frames.delete(this.id);
this._model.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameDetached, this);
}
/**
* @param {!SDK.Resource} resource
*/
addResource(resource) {
if (this._resourcesMap[resource.url] === resource) {
// Already in the tree, we just got an extra update.
return;
}
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ResourceAdded, resource);
}
/**
* @param {!SDK.NetworkRequest} request
*/
_addRequest(request) {
var resource = this._resourcesMap[request.url];
if (resource && resource.request === request) {
// Already in the tree, we just got an extra update.
return;
}
resource = new SDK.Resource(
this.target(), request, request.url, request.documentURL, request.frameId, request.loaderId,
request.resourceType(), request.mimeType, null, null);
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ResourceAdded, resource);
}
/**
* @return {!Array.<!SDK.Resource>}
*/
resources() {
var result = [];
for (var url in this._resourcesMap)
result.push(this._resourcesMap[url]);
return result;
}
/**
* @param {string} url
* @return {?SDK.Resource}
*/
resourceForURL(url) {
var resource = this._resourcesMap[url] || null;
if (resource)
return resource;
for (var i = 0; !resource && i < this._childFrames.length; ++i)
resource = this._childFrames[i].resourceForURL(url);
return resource;
}
/**
* @param {function(!SDK.Resource)} callback
* @return {boolean}
*/
_callForFrameResources(callback) {
for (var url in this._resourcesMap) {
if (callback(this._resourcesMap[url]))
return true;
}
for (var i = 0; i < this._childFrames.length; ++i) {
if (this._childFrames[i]._callForFrameResources(callback))
return true;
}
return false;
}
/**
* @return {string}
*/
displayName() {
if (!this._parentFrame)
return Common.UIString('top');
var subtitle = new Common.ParsedURL(this._url).displayName;
if (subtitle) {
if (!this._name)
return subtitle;
return this._name + ' (' + subtitle + ')';
}
return Common.UIString('<iframe>');
}
};
/**
* @implements {Protocol.PageDispatcher}
* @unrestricted
*/
SDK.PageDispatcher = class {
constructor(resourceTreeModel) {
this._resourceTreeModel = resourceTreeModel;
}
/**
* @override
* @param {number} time
*/
domContentEventFired(time) {
this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.DOMContentLoaded, time);
}
/**
* @override
* @param {number} time
*/
loadEventFired(time) {
this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.Load, time);
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
* @param {!Protocol.Page.FrameId} parentFrameId
*/
frameAttached(frameId, parentFrameId) {
this._resourceTreeModel._frameAttached(frameId, parentFrameId);
}
/**
* @override
* @param {!Protocol.Page.Frame} frame
*/
frameNavigated(frame) {
this._resourceTreeModel._frameNavigated(frame);
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
*/
frameDetached(frameId) {
this._resourceTreeModel._frameDetached(frameId);
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
*/
frameStartedLoading(frameId) {
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
*/
frameStoppedLoading(frameId) {
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
* @param {number} delay
*/
frameScheduledNavigation(frameId, delay) {
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
*/
frameClearedScheduledNavigation(frameId) {
}
/**
* @override
*/
frameResized() {
this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.FrameResized, null);
}
/**
* @override
* @param {string} message
* @param {string} dialogType
*/
javascriptDialogOpening(message, dialogType) {
}
/**
* @override
* @param {boolean} result
*/
javascriptDialogClosed(result) {
}
/**
* @override
* @param {string} data
* @param {!Protocol.Page.ScreencastFrameMetadata=} metadata
* @param {number=} sessionId
*/
screencastFrame(data, metadata, sessionId) {
this._resourceTreeModel._agent.screencastFrameAck(sessionId);
this._resourceTreeModel.dispatchEventToListeners(
SDK.ResourceTreeModel.Events.ScreencastFrame, {data: data, metadata: metadata});
}
/**
* @override
* @param {boolean} visible
*/
screencastVisibilityChanged(visible) {
this._resourceTreeModel.dispatchEventToListeners(
SDK.ResourceTreeModel.Events.ScreencastVisibilityChanged, {visible: visible});
}
/**
* @override
* @param {!Protocol.DOM.RGBA} color
*/
colorPicked(color) {
this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.ColorPicked, color);
}
/**
* @override
*/
interstitialShown() {
this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.InterstitialShown);
}
/**
* @override
*/
interstitialHidden() {
this._resourceTreeModel.dispatchEventToListeners(SDK.ResourceTreeModel.Events.InterstitialHidden);
}
/**
* @override
*/
navigationRequested() {
// Frontend is not interested in when navigations are requested.
}
};