blob: ad350d1ed4beea06da02918310ae6eadcaf311d6 [file] [log] [blame]
Alex Rudenkoa39d2142020-08-11 05:09:401// Copyright (c) 2020 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Rudenkoa39d2142020-08-11 05:09:405import * as Common from '../common/common.js';
Changhao Han03c48382020-09-14 21:17:506import * as Host from '../host/host.js';
Alex Rudenkoa39d2142020-08-11 05:09:407import * as SDK from '../sdk/sdk.js';
8import * as UI from '../ui/ui.js';
9
Alex Rudenko21a9ca32020-08-18 06:11:3710import {ElementsPanel} from './ElementsPanel.js';
Jack Franklinfb0426e2020-08-18 11:09:5211import {createLayoutPane, LayoutElement} from './LayoutPane_bridge.js'; // eslint-disable-line no-unused-vars
Alex Rudenko034db882020-08-13 12:21:0912
13/**
14 * @param {!Array<!SDK.DOMModel.DOMNode>} nodes
Jack Franklinfb0426e2020-08-18 11:09:5215 * @return {!Array<!LayoutElement>}
Alex Rudenko034db882020-08-13 12:21:0916 */
17const gridNodesToElements = nodes => {
Patrick Brossetbf746e62020-08-14 08:43:1418 return nodes.map(node => {
19 const className = node.getAttribute('class');
Alex Rudenko6ddda3e2020-10-26 10:15:0620 const nodeId = node.id;
Patrick Brossetbf746e62020-08-14 08:43:1421 return {
Alex Rudenko6ddda3e2020-10-26 10:15:0622 id: nodeId,
23 color: node.domModel().overlayModel().colorOfGridInPersistentOverlay(nodeId) || '#000',
Patrick Brossetbf746e62020-08-14 08:43:1424 name: node.localName(),
25 domId: node.getAttribute('id'),
Alex Rudenko6ddda3e2020-10-26 10:15:0626 domClasses: className ? className.split(/\s+/).filter(s => !!s) : undefined,
27 enabled: node.domModel().overlayModel().isHighlightedGridInPersistentOverlay(nodeId),
Alex Rudenko7529de92020-08-20 09:47:0528 reveal: () => {
29 ElementsPanel.instance().revealAndSelectNode(node, true, true);
Patrick Brosset50e1d662020-09-14 12:41:4430 node.scrollIntoView();
Alex Rudenko7529de92020-08-20 09:47:0531 },
Alex Rudenko994d0192020-09-17 14:19:1832 highlight: () => {
33 node.highlight();
34 },
35 hideHighlight: () => {
36 SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
37 },
Alex Rudenko7529de92020-08-20 09:47:0538 toggle: value => {
39 if (value) {
Changhao Han03c48382020-09-14 21:17:5040 node.domModel().overlayModel().highlightGridInPersistentOverlay(
Alex Rudenko6ddda3e2020-10-26 10:15:0641 nodeId, Host.UserMetrics.GridOverlayOpener.LayoutPane);
Alex Rudenko7529de92020-08-20 09:47:0542 } else {
Alex Rudenko6ddda3e2020-10-26 10:15:0643 node.domModel().overlayModel().hideGridInPersistentOverlay(nodeId);
Alex Rudenko7529de92020-08-20 09:47:0544 }
Alex Rudenkobc83da92020-09-15 08:46:5345 },
46 setColor(value) {
47 this.color = value;
Alex Rudenko6ddda3e2020-10-26 10:15:0648 node.domModel().overlayModel().setColorOfGridInPersistentOverlay(nodeId, value);
Alex Rudenkobc83da92020-09-15 08:46:5349 },
Patrick Brossetbf746e62020-08-14 08:43:1450 };
51 });
Alex Rudenko034db882020-08-13 12:21:0952};
Alex Rudenkoa39d2142020-08-11 05:09:4053
54/**
55 * @unrestricted
56 */
57export class LayoutSidebarPane extends UI.ThrottledWidget.ThrottledWidget {
58 constructor() {
59 super(true /* isWebComponent */);
60 this._layoutPane = createLayoutPane();
61 this.contentElement.appendChild(this._layoutPane);
Alex Rudenkob7799802020-08-26 10:18:5462 this._settings = ['showGridLineLabels', 'showGridTrackSizes', 'showGridAreas', 'extendGridLines'];
Patrick Brossetf398c102020-10-14 07:35:0863 this._uaShadowDOMSetting = Common.Settings.Settings.instance().moduleSetting('showUAShadowDOM');
Alex Rudenko034db882020-08-13 12:21:0964 this._boundOnSettingChanged = this.onSettingChanged.bind(this);
Alex Rudenko6ddda3e2020-10-26 10:15:0665 /**
66 * @type {!Array<!SDK.DOMModel.DOMModel>}
67 */
Alex Rudenko7529de92020-08-20 09:47:0568 this._domModels = [];
Alex Rudenko0e97afa2020-08-14 09:51:1169 }
70
Alex Rudenko7529de92020-08-20 09:47:0571 /**
72 * @param {!SDK.DOMModel.DOMModel} domModel
73 */
74 modelAdded(domModel) {
75 const overlayModel = domModel.overlayModel();
76 overlayModel.addEventListener(SDK.OverlayModel.Events.PersistentGridOverlayCleared, this.update, this);
77 overlayModel.addEventListener(SDK.OverlayModel.Events.PersistentGridOverlayStateChanged, this.update, this);
78 this._domModels.push(domModel);
79 }
80
81 /**
82 * @param {!SDK.DOMModel.DOMModel} domModel
83 */
84 modelRemoved(domModel) {
85 const overlayModel = domModel.overlayModel();
86 overlayModel.removeEventListener(SDK.OverlayModel.Events.PersistentGridOverlayCleared, this.update, this);
87 overlayModel.removeEventListener(SDK.OverlayModel.Events.PersistentGridOverlayStateChanged, this.update, this);
88 this._domModels = this._domModels.filter(model => model !== domModel);
Alex Rudenko034db882020-08-13 12:21:0989 }
90
91 async _fetchGridNodes() {
Patrick Brossetf398c102020-10-14 07:35:0892 const showUAShadowDOM = this._uaShadowDOMSetting.get();
93
Alex Rudenko7529de92020-08-20 09:47:0594 const nodes = [];
95 for (const domModel of this._domModels) {
96 const nodeIds = await domModel.getNodesByStyle(
97 [{name: 'display', value: 'grid'}, {name: 'display', value: 'inline-grid'}], true /* pierce */);
Alex Rudenko6ddda3e2020-10-26 10:15:0698 for (const nodeId of nodeIds) {
99 const node = domModel.nodeForId(nodeId);
100 if (node !== null && (showUAShadowDOM || !node.ancestorUserAgentShadowRoot())) {
101 nodes.push(node);
102 }
103 }
Alex Rudenko7529de92020-08-20 09:47:05104 }
Patrick Brossetf398c102020-10-14 07:35:08105
Alex Rudenko034db882020-08-13 12:21:09106 return nodes;
107 }
108
109 _mapSettings() {
Alex Rudenko6ddda3e2020-10-26 10:15:06110 const settings = [];
111 for (const settingName of this._settings) {
112 const setting = Common.Settings.Settings.instance().moduleSetting(settingName);
113 const ext = setting.extension();
114 if (!ext) {
115 continue;
116 }
117 const descriptor = ext.descriptor();
118 settings.push({
119 type: /** @type {string} */ (descriptor.settingType),
120 name: descriptor.settingName,
121 title: descriptor.title ? ls(descriptor.title) : '',
122 value: setting.get(),
123 options: descriptor.options ? descriptor.options.map(opt => ({
124 title: ls(opt.title),
125 value: /** @type {string} */ (opt.value),
126 })) :
127 []
128 });
129 }
130 return settings;
Alex Rudenkoa39d2142020-08-11 05:09:40131 }
132
133 /**
134 * @override
135 * @protected
136 * @return {!Promise<void>}
137 */
138 async doUpdate() {
139 this._layoutPane.data = {
Alex Rudenko034db882020-08-13 12:21:09140 gridElements: gridNodesToElements(await this._fetchGridNodes()),
141 settings: this._mapSettings(),
Alex Rudenkoa39d2142020-08-11 05:09:40142 };
143 }
144
145 /**
Alex Rudenko034db882020-08-13 12:21:09146 * @param {*} event
147 */
148 onSettingChanged(event) {
149 Common.Settings.Settings.instance().moduleSetting(event.data.setting).set(event.data.value);
150 }
151
152 /**
Alex Rudenkoa39d2142020-08-11 05:09:40153 * @override
154 */
155 wasShown() {
Alex Rudenko034db882020-08-13 12:21:09156 for (const setting of this._settings) {
157 Common.Settings.Settings.instance().moduleSetting(setting).addChangeListener(this.update, this);
158 }
159 this._layoutPane.addEventListener('setting-changed', this._boundOnSettingChanged);
Alex Rudenko7529de92020-08-20 09:47:05160 for (const domModel of this._domModels) {
161 this.modelRemoved(domModel);
162 }
163 this._domModels = [];
164 SDK.SDKModel.TargetManager.instance().observeModels(SDK.DOMModel.DOMModel, this);
Tim van der Lipped1a00aa2020-08-19 16:03:56165 UI.Context.Context.instance().addFlavorChangeListener(SDK.DOMModel.DOMNode, this.update, this);
Patrick Brossetf398c102020-10-14 07:35:08166 this._uaShadowDOMSetting.addChangeListener(this.update, this);
Alex Rudenkoa39d2142020-08-11 05:09:40167 this.update();
168 }
169
170 /**
171 * @override
172 */
173 willHide() {
Alex Rudenko034db882020-08-13 12:21:09174 for (const setting of this._settings) {
175 Common.Settings.Settings.instance().moduleSetting(setting).removeChangeListener(this.update, this);
176 }
177 this._layoutPane.removeEventListener('setting-changed', this._boundOnSettingChanged);
Alex Rudenko7529de92020-08-20 09:47:05178 SDK.SDKModel.TargetManager.instance().unobserveModels(SDK.DOMModel.DOMModel, this);
Tim van der Lipped1a00aa2020-08-19 16:03:56179 UI.Context.Context.instance().removeFlavorChangeListener(SDK.DOMModel.DOMNode, this.update, this);
Patrick Brossetf398c102020-10-14 07:35:08180 this._uaShadowDOMSetting.removeChangeListener(this.update, this);
Alex Rudenkoa39d2142020-08-11 05:09:40181 }
182}