Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 1 | // 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 Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 5 | import * as Common from '../common/common.js'; |
Changhao Han | 03c4838 | 2020-09-14 21:17:50 | [diff] [blame] | 6 | import * as Host from '../host/host.js'; |
Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 7 | import * as SDK from '../sdk/sdk.js'; |
| 8 | import * as UI from '../ui/ui.js'; |
| 9 | |
Alex Rudenko | 21a9ca3 | 2020-08-18 06:11:37 | [diff] [blame] | 10 | import {ElementsPanel} from './ElementsPanel.js'; |
Jack Franklin | fb0426e | 2020-08-18 11:09:52 | [diff] [blame] | 11 | import {createLayoutPane, LayoutElement} from './LayoutPane_bridge.js'; // eslint-disable-line no-unused-vars |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 12 | |
| 13 | /** |
| 14 | * @param {!Array<!SDK.DOMModel.DOMNode>} nodes |
Jack Franklin | fb0426e | 2020-08-18 11:09:52 | [diff] [blame] | 15 | * @return {!Array<!LayoutElement>} |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 16 | */ |
| 17 | const gridNodesToElements = nodes => { |
Patrick Brosset | bf746e6 | 2020-08-14 08:43:14 | [diff] [blame] | 18 | return nodes.map(node => { |
| 19 | const className = node.getAttribute('class'); |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 20 | const nodeId = node.id; |
Patrick Brosset | bf746e6 | 2020-08-14 08:43:14 | [diff] [blame] | 21 | return { |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 22 | id: nodeId, |
| 23 | color: node.domModel().overlayModel().colorOfGridInPersistentOverlay(nodeId) || '#000', |
Patrick Brosset | bf746e6 | 2020-08-14 08:43:14 | [diff] [blame] | 24 | name: node.localName(), |
| 25 | domId: node.getAttribute('id'), |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 26 | domClasses: className ? className.split(/\s+/).filter(s => !!s) : undefined, |
| 27 | enabled: node.domModel().overlayModel().isHighlightedGridInPersistentOverlay(nodeId), |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 28 | reveal: () => { |
| 29 | ElementsPanel.instance().revealAndSelectNode(node, true, true); |
Patrick Brosset | 50e1d66 | 2020-09-14 12:41:44 | [diff] [blame] | 30 | node.scrollIntoView(); |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 31 | }, |
Alex Rudenko | 994d019 | 2020-09-17 14:19:18 | [diff] [blame] | 32 | highlight: () => { |
| 33 | node.highlight(); |
| 34 | }, |
| 35 | hideHighlight: () => { |
| 36 | SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight(); |
| 37 | }, |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 38 | toggle: value => { |
| 39 | if (value) { |
Changhao Han | 03c4838 | 2020-09-14 21:17:50 | [diff] [blame] | 40 | node.domModel().overlayModel().highlightGridInPersistentOverlay( |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 41 | nodeId, Host.UserMetrics.GridOverlayOpener.LayoutPane); |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 42 | } else { |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 43 | node.domModel().overlayModel().hideGridInPersistentOverlay(nodeId); |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 44 | } |
Alex Rudenko | bc83da9 | 2020-09-15 08:46:53 | [diff] [blame] | 45 | }, |
| 46 | setColor(value) { |
| 47 | this.color = value; |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 48 | node.domModel().overlayModel().setColorOfGridInPersistentOverlay(nodeId, value); |
Alex Rudenko | bc83da9 | 2020-09-15 08:46:53 | [diff] [blame] | 49 | }, |
Patrick Brosset | bf746e6 | 2020-08-14 08:43:14 | [diff] [blame] | 50 | }; |
| 51 | }); |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 52 | }; |
Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 53 | |
| 54 | /** |
| 55 | * @unrestricted |
| 56 | */ |
| 57 | export class LayoutSidebarPane extends UI.ThrottledWidget.ThrottledWidget { |
| 58 | constructor() { |
| 59 | super(true /* isWebComponent */); |
| 60 | this._layoutPane = createLayoutPane(); |
| 61 | this.contentElement.appendChild(this._layoutPane); |
Alex Rudenko | b779980 | 2020-08-26 10:18:54 | [diff] [blame] | 62 | this._settings = ['showGridLineLabels', 'showGridTrackSizes', 'showGridAreas', 'extendGridLines']; |
Patrick Brosset | f398c10 | 2020-10-14 07:35:08 | [diff] [blame] | 63 | this._uaShadowDOMSetting = Common.Settings.Settings.instance().moduleSetting('showUAShadowDOM'); |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 64 | this._boundOnSettingChanged = this.onSettingChanged.bind(this); |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 65 | /** |
| 66 | * @type {!Array<!SDK.DOMModel.DOMModel>} |
| 67 | */ |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 68 | this._domModels = []; |
Alex Rudenko | 0e97afa | 2020-08-14 09:51:11 | [diff] [blame] | 69 | } |
| 70 | |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 71 | /** |
| 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 Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | async _fetchGridNodes() { |
Patrick Brosset | f398c10 | 2020-10-14 07:35:08 | [diff] [blame] | 92 | const showUAShadowDOM = this._uaShadowDOMSetting.get(); |
| 93 | |
Alex Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 94 | 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 Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 98 | 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 Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 104 | } |
Patrick Brosset | f398c10 | 2020-10-14 07:35:08 | [diff] [blame] | 105 | |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 106 | return nodes; |
| 107 | } |
| 108 | |
| 109 | _mapSettings() { |
Alex Rudenko | 6ddda3e | 2020-10-26 10:15:06 | [diff] [blame] | 110 | 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 Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | /** |
| 134 | * @override |
| 135 | * @protected |
| 136 | * @return {!Promise<void>} |
| 137 | */ |
| 138 | async doUpdate() { |
| 139 | this._layoutPane.data = { |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 140 | gridElements: gridNodesToElements(await this._fetchGridNodes()), |
| 141 | settings: this._mapSettings(), |
Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 142 | }; |
| 143 | } |
| 144 | |
| 145 | /** |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 146 | * @param {*} event |
| 147 | */ |
| 148 | onSettingChanged(event) { |
| 149 | Common.Settings.Settings.instance().moduleSetting(event.data.setting).set(event.data.value); |
| 150 | } |
| 151 | |
| 152 | /** |
Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 153 | * @override |
| 154 | */ |
| 155 | wasShown() { |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 156 | 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 Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 160 | 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 Lippe | d1a00aa | 2020-08-19 16:03:56 | [diff] [blame] | 165 | UI.Context.Context.instance().addFlavorChangeListener(SDK.DOMModel.DOMNode, this.update, this); |
Patrick Brosset | f398c10 | 2020-10-14 07:35:08 | [diff] [blame] | 166 | this._uaShadowDOMSetting.addChangeListener(this.update, this); |
Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 167 | this.update(); |
| 168 | } |
| 169 | |
| 170 | /** |
| 171 | * @override |
| 172 | */ |
| 173 | willHide() { |
Alex Rudenko | 034db88 | 2020-08-13 12:21:09 | [diff] [blame] | 174 | 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 Rudenko | 7529de9 | 2020-08-20 09:47:05 | [diff] [blame] | 178 | SDK.SDKModel.TargetManager.instance().unobserveModels(SDK.DOMModel.DOMModel, this); |
Tim van der Lippe | d1a00aa | 2020-08-19 16:03:56 | [diff] [blame] | 179 | UI.Context.Context.instance().removeFlavorChangeListener(SDK.DOMModel.DOMNode, this.update, this); |
Patrick Brosset | f398c10 | 2020-10-14 07:35:08 | [diff] [blame] | 180 | this._uaShadowDOMSetting.removeChangeListener(this.update, this); |
Alex Rudenko | a39d214 | 2020-08-11 05:09:40 | [diff] [blame] | 181 | } |
| 182 | } |