blob: e2ca71a5876fb782b779cec2d83d8b042b412890 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @implements {Protocol.OverlayDispatcher}
*/
SDK.OverlayModel = class extends SDK.SDKModel {
/**
* @param {!SDK.Target} target
*/
constructor(target) {
super(target);
this._domModel = /** @type {!SDK.DOMModel} */ (target.model(SDK.DOMModel));
target.registerOverlayDispatcher(this);
this._overlayAgent = target.overlayAgent();
this._overlayAgent.enable();
this._overlayAgent.setShowViewportSizeOnResize(true);
this._debuggerModel = target.model(SDK.DebuggerModel);
if (this._debuggerModel) {
Common.moduleSetting('disablePausedStateOverlay').addChangeListener(this._updatePausedInDebuggerMessage, this);
this._debuggerModel.addEventListener(
SDK.DebuggerModel.Events.DebuggerPaused, this._updatePausedInDebuggerMessage, this);
this._debuggerModel.addEventListener(
SDK.DebuggerModel.Events.DebuggerResumed, this._updatePausedInDebuggerMessage, this);
// TODO(dgozman): we should get DebuggerResumed on navigations instead of listening to GlobalObjectCleared.
this._debuggerModel.addEventListener(
SDK.DebuggerModel.Events.GlobalObjectCleared, this._updatePausedInDebuggerMessage, this);
}
this._inspectModeEnabled = false;
this._hideHighlightTimeout = null;
this._defaultHighlighter = new SDK.OverlayModel.DefaultHighlighter(this);
this._highlighter = this._defaultHighlighter;
this._showPaintRectsSetting = Common.moduleSetting('showPaintRects');
this._showPaintRectsSetting.addChangeListener(
() => this._overlayAgent.setShowPaintRects(this._showPaintRectsSetting.get()));
if (this._showPaintRectsSetting.get())
this._overlayAgent.setShowPaintRects(true);
this._showDebugBordersSetting = Common.moduleSetting('showDebugBorders');
this._showDebugBordersSetting.addChangeListener(
() => this._overlayAgent.setShowDebugBorders(this._showDebugBordersSetting.get()));
if (this._showDebugBordersSetting.get())
this._overlayAgent.setShowDebugBorders(true);
this._showFPSCounterSetting = Common.moduleSetting('showFPSCounter');
this._showFPSCounterSetting.addChangeListener(
() => this._overlayAgent.setShowFPSCounter(this._showFPSCounterSetting.get()));
if (this._showFPSCounterSetting.get())
this._overlayAgent.setShowFPSCounter(true);
this._showScrollBottleneckRectsSetting = Common.moduleSetting('showScrollBottleneckRects');
this._showScrollBottleneckRectsSetting.addChangeListener(
() => this._overlayAgent.setShowScrollBottleneckRects(this._showScrollBottleneckRectsSetting.get()));
if (this._showScrollBottleneckRectsSetting.get())
this._overlayAgent.setShowScrollBottleneckRects(true);
if (target.suspended())
this._overlayAgent.setSuspended(true);
}
/**
* @param {!SDK.RemoteObject} object
*/
static highlightObjectAsDOMNode(object) {
const domModel = object.runtimeModel().target().model(SDK.DOMModel);
if (domModel)
domModel.overlayModel().highlightDOMNode(undefined, undefined, undefined, object.objectId);
}
static hideDOMNodeHighlight() {
for (const overlayModel of SDK.targetManager.models(SDK.OverlayModel))
overlayModel.highlightDOMNode(0);
}
static muteHighlight() {
SDK.OverlayModel.hideDOMNodeHighlight();
SDK.OverlayModel._highlightDisabled = true;
}
static unmuteHighlight() {
SDK.OverlayModel._highlightDisabled = false;
}
/**
* @override
* @return {!Promise}
*/
suspendModel() {
return this._overlayAgent.setSuspended(true);
}
/**
* @override
* @return {!Promise}
*/
resumeModel() {
return this._overlayAgent.setSuspended(false);
}
setShowViewportSizeOnResize(show) {
this._overlayAgent.setShowViewportSizeOnResize(show);
}
_updatePausedInDebuggerMessage() {
const message = this._debuggerModel.isPaused() && !Common.moduleSetting('disablePausedStateOverlay').get() ?
Common.UIString('Paused in debugger') :
undefined;
this._overlayAgent.setPausedInDebuggerMessage(message);
}
/**
* @param {?SDK.OverlayModel.Highlighter} highlighter
*/
setHighlighter(highlighter) {
this._highlighter = highlighter || this._defaultHighlighter;
}
/**
* @param {!Protocol.Overlay.InspectMode} mode
* @return {!Promise}
*/
async setInspectMode(mode) {
await this._domModel.requestDocument();
this._inspectModeEnabled = mode !== Protocol.Overlay.InspectMode.None;
this.dispatchEventToListeners(SDK.OverlayModel.Events.InspectModeWillBeToggled, this);
this._highlighter.setInspectMode(mode, this._buildHighlightConfig());
}
/**
* @return {boolean}
*/
inspectModeEnabled() {
return this._inspectModeEnabled;
}
/**
* @param {!Protocol.DOM.NodeId=} nodeId
* @param {string=} mode
* @param {!Protocol.DOM.BackendNodeId=} backendNodeId
* @param {!Protocol.Runtime.RemoteObjectId=} objectId
*/
highlightDOMNode(nodeId, mode, backendNodeId, objectId) {
this.highlightDOMNodeWithConfig(nodeId, {mode: mode}, backendNodeId, objectId);
}
/**
* @param {!Protocol.DOM.NodeId=} nodeId
* @param {!{mode: (string|undefined), showInfo: (boolean|undefined), selectors: (string|undefined)}=} config
* @param {!Protocol.DOM.BackendNodeId=} backendNodeId
* @param {!Protocol.Runtime.RemoteObjectId=} objectId
*/
highlightDOMNodeWithConfig(nodeId, config, backendNodeId, objectId) {
if (SDK.OverlayModel._highlightDisabled)
return;
config = config || {mode: 'all', showInfo: undefined, selectors: undefined};
if (this._hideHighlightTimeout) {
clearTimeout(this._hideHighlightTimeout);
this._hideHighlightTimeout = null;
}
const highlightConfig = this._buildHighlightConfig(config.mode);
if (typeof config.showInfo !== 'undefined')
highlightConfig.showInfo = config.showInfo;
if (typeof config.selectors !== 'undefined')
highlightConfig.selectorList = config.selectors;
this._highlighter.highlightDOMNode(this._domModel.nodeForId(nodeId || 0), highlightConfig, backendNodeId, objectId);
}
/**
* @param {!Protocol.DOM.NodeId} nodeId
*/
highlightDOMNodeForTwoSeconds(nodeId) {
this.highlightDOMNode(nodeId);
this._hideHighlightTimeout = setTimeout(() => this.highlightDOMNode(0), 2000);
}
/**
* @param {!Protocol.Page.FrameId} frameId
*/
highlightFrame(frameId) {
if (SDK.OverlayModel._highlightDisabled)
return;
this._highlighter.highlightFrame(frameId);
}
/**
* @param {string=} mode
* @return {!Protocol.Overlay.HighlightConfig}
*/
_buildHighlightConfig(mode) {
mode = mode || 'all';
const showRulers = Common.moduleSetting('showMetricsRulers').get();
const highlightConfig = {showInfo: mode === 'all', showRulers: showRulers, showExtensionLines: showRulers};
if (mode === 'all' || mode === 'content')
highlightConfig.contentColor = Common.Color.PageHighlight.Content.toProtocolRGBA();
if (mode === 'all' || mode === 'padding')
highlightConfig.paddingColor = Common.Color.PageHighlight.Padding.toProtocolRGBA();
if (mode === 'all' || mode === 'border')
highlightConfig.borderColor = Common.Color.PageHighlight.Border.toProtocolRGBA();
if (mode === 'all' || mode === 'margin')
highlightConfig.marginColor = Common.Color.PageHighlight.Margin.toProtocolRGBA();
if (mode === 'all') {
highlightConfig.eventTargetColor = Common.Color.PageHighlight.EventTarget.toProtocolRGBA();
highlightConfig.shapeColor = Common.Color.PageHighlight.Shape.toProtocolRGBA();
highlightConfig.shapeMarginColor = Common.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
highlightConfig.displayAsMaterial = true;
}
if (mode === 'all')
highlightConfig.cssGridColor = Common.Color.PageHighlight.CssGrid.toProtocolRGBA();
return highlightConfig;
}
/**
* @override
* @param {!Protocol.DOM.NodeId} nodeId
*/
nodeHighlightRequested(nodeId) {
const node = this._domModel.nodeForId(nodeId);
if (node)
this.dispatchEventToListeners(SDK.OverlayModel.Events.HighlightNodeRequested, node);
}
/**
* @override
* @param {!Protocol.DOM.BackendNodeId} backendNodeId
*/
inspectNodeRequested(backendNodeId) {
const deferredNode = new SDK.DeferredDOMNode(this.target(), backendNodeId);
this.dispatchEventToListeners(SDK.OverlayModel.Events.InspectNodeRequested, deferredNode);
}
/**
* @override
* @param {!Protocol.Page.Viewport} viewport
*/
screenshotRequested(viewport) {
this.dispatchEventToListeners(SDK.OverlayModel.Events.ScreenshotRequested, viewport);
}
};
SDK.SDKModel.register(SDK.OverlayModel, SDK.Target.Capability.DOM, true);
/** @enum {symbol} */
SDK.OverlayModel.Events = {
InspectModeWillBeToggled: Symbol('InspectModeWillBeToggled'),
HighlightNodeRequested: Symbol('HighlightNodeRequested'),
InspectNodeRequested: Symbol('InspectNodeRequested'),
ScreenshotRequested: Symbol('ScreenshotRequested'),
};
/**
* @interface
*/
SDK.OverlayModel.Highlighter = function() {};
SDK.OverlayModel.Highlighter.prototype = {
/**
* @param {?SDK.DOMNode} node
* @param {!Protocol.Overlay.HighlightConfig} config
* @param {!Protocol.DOM.BackendNodeId=} backendNodeId
* @param {!Protocol.Runtime.RemoteObjectId=} objectId
*/
highlightDOMNode(node, config, backendNodeId, objectId) {},
/**
* @param {!Protocol.Overlay.InspectMode} mode
* @param {!Protocol.Overlay.HighlightConfig} config
* @return {!Promise}
*/
setInspectMode(mode, config) {},
/**
* @param {!Protocol.Page.FrameId} frameId
*/
highlightFrame(frameId) {}
};
/**
* @implements {SDK.OverlayModel.Highlighter}
*/
SDK.OverlayModel.DefaultHighlighter = class {
/**
* @param {!SDK.OverlayModel} model
*/
constructor(model) {
this._model = model;
}
/**
* @override
* @param {?SDK.DOMNode} node
* @param {!Protocol.Overlay.HighlightConfig} config
* @param {!Protocol.DOM.BackendNodeId=} backendNodeId
* @param {!Protocol.Runtime.RemoteObjectId=} objectId
*/
highlightDOMNode(node, config, backendNodeId, objectId) {
if (objectId || node || backendNodeId) {
this._model._overlayAgent.highlightNode(
config, (objectId || backendNodeId) ? undefined : node.id, backendNodeId, objectId);
} else {
this._model._overlayAgent.hideHighlight();
}
}
/**
* @override
* @param {!Protocol.Overlay.InspectMode} mode
* @param {!Protocol.Overlay.HighlightConfig} config
* @return {!Promise}
*/
setInspectMode(mode, config) {
return this._model._overlayAgent.setInspectMode(mode, config);
}
/**
* @override
* @param {!Protocol.Page.FrameId} frameId
*/
highlightFrame(frameId) {
this._model._overlayAgent.highlightFrame(
frameId, Common.Color.PageHighlight.Content.toProtocolRGBA(),
Common.Color.PageHighlight.ContentOutline.toProtocolRGBA());
}
};