chrome-devtools-frontend 1.0.982087 → 1.0.995227

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (489) hide show
  1. package/AUTHORS +2 -0
  2. package/config/gni/devtools_grd_files.gni +8 -7
  3. package/config/gni/devtools_image_files.gni +1 -0
  4. package/front_end/.eslintrc.js +10 -0
  5. package/front_end/Images/src/ic_rendering.svg +3 -0
  6. package/front_end/core/common/ParsedURL.ts +39 -28
  7. package/front_end/core/common/ResourceType.ts +1 -1
  8. package/front_end/core/common/SettingRegistration.ts +1 -0
  9. package/front_end/core/host/InspectorFrontendHost.ts +4 -4
  10. package/front_end/core/host/InspectorFrontendHostAPI.ts +7 -6
  11. package/front_end/core/host/Platform.ts +11 -2
  12. package/front_end/core/host/UserMetrics.ts +27 -2
  13. package/front_end/core/i18n/DevToolsLocale.ts +4 -0
  14. package/front_end/core/i18n/locales/af.json +76 -16
  15. package/front_end/core/i18n/locales/am.json +76 -16
  16. package/front_end/core/i18n/locales/ar.json +77 -17
  17. package/front_end/core/i18n/locales/as.json +76 -16
  18. package/front_end/core/i18n/locales/az.json +76 -16
  19. package/front_end/core/i18n/locales/be.json +75 -15
  20. package/front_end/core/i18n/locales/bg.json +76 -16
  21. package/front_end/core/i18n/locales/bn.json +76 -16
  22. package/front_end/core/i18n/locales/bs.json +88 -28
  23. package/front_end/core/i18n/locales/ca.json +76 -16
  24. package/front_end/core/i18n/locales/cs.json +76 -16
  25. package/front_end/core/i18n/locales/cy.json +76 -16
  26. package/front_end/core/i18n/locales/da.json +77 -17
  27. package/front_end/core/i18n/locales/de.json +178 -118
  28. package/front_end/core/i18n/locales/el.json +76 -16
  29. package/front_end/core/i18n/locales/en-GB.json +76 -16
  30. package/front_end/core/i18n/locales/en-US.json +193 -52
  31. package/front_end/core/i18n/locales/en-XL.json +193 -52
  32. package/front_end/core/i18n/locales/es-419.json +76 -16
  33. package/front_end/core/i18n/locales/es.json +76 -16
  34. package/front_end/core/i18n/locales/et.json +76 -16
  35. package/front_end/core/i18n/locales/eu.json +76 -16
  36. package/front_end/core/i18n/locales/fa.json +83 -23
  37. package/front_end/core/i18n/locales/fi.json +76 -16
  38. package/front_end/core/i18n/locales/fil.json +76 -16
  39. package/front_end/core/i18n/locales/fr-CA.json +76 -16
  40. package/front_end/core/i18n/locales/fr.json +76 -16
  41. package/front_end/core/i18n/locales/gl.json +76 -16
  42. package/front_end/core/i18n/locales/gu.json +76 -16
  43. package/front_end/core/i18n/locales/he.json +76 -16
  44. package/front_end/core/i18n/locales/hi.json +76 -16
  45. package/front_end/core/i18n/locales/hr.json +76 -16
  46. package/front_end/core/i18n/locales/hu.json +76 -16
  47. package/front_end/core/i18n/locales/hy.json +76 -16
  48. package/front_end/core/i18n/locales/id.json +79 -19
  49. package/front_end/core/i18n/locales/is.json +75 -15
  50. package/front_end/core/i18n/locales/it.json +124 -64
  51. package/front_end/core/i18n/locales/ja.json +76 -16
  52. package/front_end/core/i18n/locales/ka.json +76 -16
  53. package/front_end/core/i18n/locales/kk.json +76 -16
  54. package/front_end/core/i18n/locales/km.json +76 -16
  55. package/front_end/core/i18n/locales/kn.json +76 -16
  56. package/front_end/core/i18n/locales/ko.json +76 -16
  57. package/front_end/core/i18n/locales/ky.json +76 -16
  58. package/front_end/core/i18n/locales/lo.json +76 -16
  59. package/front_end/core/i18n/locales/lt.json +76 -16
  60. package/front_end/core/i18n/locales/lv.json +76 -16
  61. package/front_end/core/i18n/locales/mk.json +76 -16
  62. package/front_end/core/i18n/locales/ml.json +76 -16
  63. package/front_end/core/i18n/locales/mn.json +76 -16
  64. package/front_end/core/i18n/locales/mr.json +76 -16
  65. package/front_end/core/i18n/locales/ms.json +76 -16
  66. package/front_end/core/i18n/locales/my.json +78 -18
  67. package/front_end/core/i18n/locales/ne.json +76 -16
  68. package/front_end/core/i18n/locales/nl.json +77 -17
  69. package/front_end/core/i18n/locales/no.json +76 -16
  70. package/front_end/core/i18n/locales/or.json +76 -16
  71. package/front_end/core/i18n/locales/pa.json +76 -16
  72. package/front_end/core/i18n/locales/pl.json +78 -18
  73. package/front_end/core/i18n/locales/pt-PT.json +123 -63
  74. package/front_end/core/i18n/locales/pt.json +78 -18
  75. package/front_end/core/i18n/locales/ro.json +76 -16
  76. package/front_end/core/i18n/locales/ru.json +77 -17
  77. package/front_end/core/i18n/locales/si.json +76 -16
  78. package/front_end/core/i18n/locales/sk.json +76 -16
  79. package/front_end/core/i18n/locales/sl.json +76 -16
  80. package/front_end/core/i18n/locales/sq.json +76 -16
  81. package/front_end/core/i18n/locales/sr-Latn.json +76 -16
  82. package/front_end/core/i18n/locales/sr.json +76 -16
  83. package/front_end/core/i18n/locales/sv.json +76 -16
  84. package/front_end/core/i18n/locales/sw.json +76 -16
  85. package/front_end/core/i18n/locales/ta.json +77 -17
  86. package/front_end/core/i18n/locales/te.json +76 -16
  87. package/front_end/core/i18n/locales/th.json +76 -16
  88. package/front_end/core/i18n/locales/tr.json +76 -16
  89. package/front_end/core/i18n/locales/uk.json +76 -16
  90. package/front_end/core/i18n/locales/ur.json +76 -16
  91. package/front_end/core/i18n/locales/uz.json +77 -17
  92. package/front_end/core/i18n/locales/vi.json +76 -16
  93. package/front_end/core/i18n/locales/zh-HK.json +76 -16
  94. package/front_end/core/i18n/locales/zh-TW.json +76 -16
  95. package/front_end/core/i18n/locales/zh.json +76 -16
  96. package/front_end/core/i18n/locales/zu.json +76 -16
  97. package/front_end/core/platform/dom-utilities.ts +16 -0
  98. package/front_end/core/platform/platform.ts +2 -0
  99. package/front_end/core/protocol_client/InspectorBackend.ts +2 -1
  100. package/front_end/core/protocol_client/NodeURL.ts +1 -1
  101. package/front_end/core/root/Runtime.ts +6 -0
  102. package/front_end/core/sdk/AccessibilityModel.ts +7 -6
  103. package/front_end/core/sdk/CSSMatchedStyles.ts +71 -17
  104. package/front_end/core/sdk/CSSMetadata.ts +15 -0
  105. package/front_end/core/sdk/CSSModel.ts +9 -7
  106. package/front_end/core/sdk/CSSProperty.ts +97 -11
  107. package/front_end/core/sdk/CSSStyleSheetHeader.ts +9 -5
  108. package/front_end/core/sdk/CSSSupports.ts +4 -1
  109. package/front_end/core/sdk/ChildTargetManager.ts +3 -1
  110. package/front_end/core/sdk/Connections.ts +3 -2
  111. package/front_end/core/sdk/ConsoleModel.ts +6 -5
  112. package/front_end/core/sdk/Cookie.ts +4 -2
  113. package/front_end/core/sdk/DOMDebuggerModel.ts +10 -6
  114. package/front_end/core/sdk/DOMModel.ts +2 -2
  115. package/front_end/core/sdk/DebuggerModel.ts +27 -5
  116. package/front_end/core/sdk/HeapProfilerModel.ts +2 -1
  117. package/front_end/core/sdk/NetworkManager.ts +13 -12
  118. package/front_end/core/sdk/NetworkRequest.ts +1 -1
  119. package/front_end/core/sdk/PageLoad.ts +3 -1
  120. package/front_end/core/sdk/PageResourceLoader.ts +9 -7
  121. package/front_end/core/sdk/ProfileTreeModel.ts +3 -2
  122. package/front_end/core/sdk/RemoteObject.ts +18 -6
  123. package/front_end/core/sdk/ResourceTreeModel.ts +17 -11
  124. package/front_end/core/sdk/ScreenCaptureModel.ts +3 -0
  125. package/front_end/core/sdk/Script.ts +4 -3
  126. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +2 -1
  127. package/front_end/core/sdk/SourceMap.ts +10 -6
  128. package/front_end/core/sdk/SourceMapManager.ts +47 -5
  129. package/front_end/core/sdk/TracingModel.ts +0 -9
  130. package/front_end/devtools_compatibility.js +1 -0
  131. package/front_end/entrypoints/formatter_worker/CSSRuleParser.ts +1 -1
  132. package/front_end/entrypoints/lighthouse_worker/LighthouseWorkerService.ts +10 -3
  133. package/front_end/entrypoints/main/MainImpl.ts +22 -2
  134. package/front_end/generated/InspectorBackendCommands.js +79 -14
  135. package/front_end/generated/SupportedCSSProperties.js +21 -8
  136. package/front_end/generated/protocol-mapping.d.ts +4 -0
  137. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  138. package/front_end/generated/protocol.ts +158 -28
  139. package/front_end/legacy/legacy-defs.d.ts +0 -4
  140. package/front_end/legacy_test_runner/heap_profiler_test_runner/heap_profiler_test_runner.js +1 -1
  141. package/front_end/legacy_test_runner/test_runner/TestRunner.js +1 -0
  142. package/front_end/models/bindings/BreakpointManager.ts +68 -11
  143. package/front_end/models/bindings/CSSWorkspaceBinding.ts +9 -2
  144. package/front_end/models/bindings/CompilerScriptMapping.ts +3 -2
  145. package/front_end/models/bindings/ContentProviderBasedProject.ts +12 -9
  146. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +10 -8
  147. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -1
  148. package/front_end/models/bindings/DefaultScriptMapping.ts +8 -2
  149. package/front_end/models/bindings/IgnoreListManager.ts +5 -5
  150. package/front_end/models/bindings/ResourceUtils.ts +5 -4
  151. package/front_end/models/emulation/EmulatedDevices.ts +17 -0
  152. package/front_end/models/extensions/ExtensionAPI.ts +5 -2
  153. package/front_end/models/extensions/ExtensionPanel.ts +2 -1
  154. package/front_end/models/extensions/ExtensionServer.ts +13 -8
  155. package/front_end/models/issues_manager/AttributionReportingIssue.ts +0 -63
  156. package/front_end/models/issues_manager/CookieIssue.ts +7 -0
  157. package/front_end/models/issues_manager/DeprecationIssue.ts +326 -8
  158. package/front_end/models/issues_manager/IssuesManager.ts +4 -0
  159. package/front_end/models/issues_manager/descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
  160. package/front_end/models/issues_manager/descriptions/deprecation.md +1 -1
  161. package/front_end/models/logs/LogManager.ts +2 -1
  162. package/front_end/models/logs/NetworkLog.ts +14 -12
  163. package/front_end/models/persistence/Automapping.ts +17 -16
  164. package/front_end/models/persistence/EditFileSystemView.ts +5 -4
  165. package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +24 -24
  166. package/front_end/models/persistence/IsolatedFileSystem.ts +2 -2
  167. package/front_end/models/persistence/IsolatedFileSystemManager.ts +7 -6
  168. package/front_end/models/persistence/NetworkPersistenceManager.ts +92 -54
  169. package/front_end/models/persistence/PersistenceImpl.ts +7 -7
  170. package/front_end/models/persistence/PlatformFileSystem.ts +7 -8
  171. package/front_end/models/persistence/WorkspaceSettingsTab.ts +3 -2
  172. package/front_end/models/text_utils/CodeMirrorUtils.ts +53 -0
  173. package/front_end/models/text_utils/text_utils.ts +2 -0
  174. package/front_end/models/timeline_model/TimelineModel.ts +31 -30
  175. package/front_end/models/timeline_model/TimelineProfileTree.ts +3 -2
  176. package/front_end/models/workspace/UISourceCode.ts +16 -14
  177. package/front_end/models/workspace/WorkspaceImpl.ts +40 -16
  178. package/front_end/panels/accessibility/AccessibilitySubPane.ts +2 -1
  179. package/front_end/panels/application/AppManifestView.ts +1 -1
  180. package/front_end/panels/application/ApplicationPanelCacheSection.ts +5 -4
  181. package/front_end/panels/application/ApplicationPanelSidebar.ts +34 -30
  182. package/front_end/panels/application/ApplicationPanelTreeElement.ts +5 -4
  183. package/front_end/panels/application/DatabaseQueryView.ts +2 -1
  184. package/front_end/panels/application/InterestGroupTreeElement.ts +3 -2
  185. package/front_end/panels/application/ReportingApiTreeElement.ts +3 -2
  186. package/front_end/panels/application/ResourcesPanel.ts +4 -3
  187. package/front_end/panels/application/ServiceWorkerCacheViews.ts +6 -1
  188. package/front_end/panels/application/TrustTokensTreeElement.ts +3 -2
  189. package/front_end/panels/application/components/BackForwardCacheStrings.ts +10 -1
  190. package/front_end/panels/application/components/BackForwardCacheView.ts +163 -13
  191. package/front_end/panels/application/components/backForwardCacheView.css +15 -4
  192. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +19 -19
  193. package/front_end/panels/changes/ChangesView.ts +38 -0
  194. package/front_end/panels/console/ConsolePinPane.ts +7 -0
  195. package/front_end/panels/console/ConsolePrompt.ts +11 -1
  196. package/front_end/panels/console/ConsoleSidebar.ts +2 -1
  197. package/front_end/panels/console/ConsoleView.ts +57 -31
  198. package/front_end/panels/console/ConsoleViewMessage.ts +12 -9
  199. package/front_end/panels/console/ConsoleViewport.ts +2 -1
  200. package/front_end/panels/console/ErrorStackParser.ts +8 -4
  201. package/front_end/panels/console/consoleView.css +0 -1
  202. package/front_end/panels/coverage/CoverageListView.ts +1 -1
  203. package/front_end/panels/coverage/CoverageModel.ts +6 -6
  204. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -1
  205. package/front_end/panels/css_overview/components/CSSOverviewStartView.ts +7 -6
  206. package/front_end/panels/css_overview/components/cssOverviewStartView.css +0 -48
  207. package/front_end/panels/css_overview/cssOverviewCompletedView.css +5 -0
  208. package/front_end/panels/css_overview/cssOverviewSidebarPanel.css +2 -0
  209. package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +2 -1
  210. package/front_end/panels/elements/ComputedStyleWidget.ts +2 -1
  211. package/front_end/panels/elements/ElementStatePaneWidget.ts +4 -6
  212. package/front_end/panels/elements/ElementsPanel.ts +16 -5
  213. package/front_end/panels/elements/ImagePreviewPopover.ts +6 -4
  214. package/front_end/panels/elements/PropertiesWidget.ts +4 -24
  215. package/front_end/panels/elements/StyleEditorWidget.ts +2 -1
  216. package/front_end/panels/elements/StylePropertiesSection.ts +1614 -0
  217. package/front_end/panels/elements/StylePropertyHighlighter.ts +2 -1
  218. package/front_end/panels/elements/StylePropertyTreeElement.ts +20 -1
  219. package/front_end/panels/elements/StylesSidebarPane.ts +97 -1675
  220. package/front_end/panels/elements/elements-legacy.ts +3 -3
  221. package/front_end/panels/elements/elements.ts +3 -0
  222. package/front_end/panels/elements/stylesSidebarPane.css +3 -1
  223. package/front_end/panels/input/InputTimeline.ts +1 -1
  224. package/front_end/panels/issues/AttributionReportingIssueDetailsView.ts +0 -50
  225. package/front_end/panels/issues/ComboBoxOfCheckBoxes.ts +14 -2
  226. package/front_end/panels/issues/IssueAggregator.ts +8 -0
  227. package/front_end/panels/issues/issues.ts +2 -0
  228. package/front_end/panels/lighthouse/LighthouseController.ts +5 -1
  229. package/front_end/panels/lighthouse/LighthousePanel.ts +3 -1
  230. package/front_end/panels/lighthouse/LighthouseTimespanView.ts +3 -3
  231. package/front_end/panels/network/BlockedURLsPane.ts +3 -2
  232. package/front_end/panels/network/NetworkConfigView.ts +6 -0
  233. package/front_end/panels/network/NetworkDataGridNode.ts +4 -0
  234. package/front_end/panels/network/NetworkLogView.ts +1 -1
  235. package/front_end/panels/network/RequestHTMLView.ts +1 -0
  236. package/front_end/panels/network/RequestHeadersView.ts +71 -10
  237. package/front_end/panels/network/networkLogView.css +9 -17
  238. package/front_end/panels/network/requestHeadersTree.css +16 -0
  239. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -0
  240. package/front_end/panels/profiler/LiveHeapProfileView.ts +3 -1
  241. package/front_end/panels/profiler/ProfilesPanel.ts +2 -1
  242. package/front_end/panels/profiler/heapProfiler.css +15 -3
  243. package/front_end/panels/screencast/ScreencastView.ts +1 -1
  244. package/front_end/panels/search/SearchConfig.ts +2 -1
  245. package/front_end/panels/settings/KeybindsSettingsTab.ts +3 -2
  246. package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +1 -2
  247. package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +4 -4
  248. package/front_end/panels/sources/BreakpointEditDialog.ts +0 -1
  249. package/front_end/panels/sources/CSSPlugin.ts +6 -6
  250. package/front_end/panels/sources/CoveragePlugin.ts +2 -1
  251. package/front_end/panels/sources/DebuggerPlugin.ts +4 -4
  252. package/front_end/panels/sources/EditingLocationHistoryManager.ts +4 -1
  253. package/front_end/panels/sources/NavigatorView.ts +28 -20
  254. package/front_end/panels/sources/SearchSourcesView.ts +2 -2
  255. package/front_end/panels/sources/SourcesNavigator.ts +4 -2
  256. package/front_end/panels/sources/SourcesPanel.ts +4 -4
  257. package/front_end/panels/sources/SourcesSearchScope.ts +12 -8
  258. package/front_end/panels/sources/SourcesView.ts +3 -1
  259. package/front_end/panels/sources/TabbedEditorContainer.ts +1 -1
  260. package/front_end/panels/sources/components/HeadersView.ts +1 -1
  261. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +9 -9
  262. package/front_end/panels/timeline/TimelinePanel.ts +1 -1
  263. package/front_end/panels/timeline/timelinePanel.css +1 -2
  264. package/front_end/panels/utils/utils.ts +97 -0
  265. package/front_end/third_party/codemirror.next/bundle.ts +27 -25
  266. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  267. package/front_end/third_party/codemirror.next/chunk/cpp.js +2 -2
  268. package/front_end/third_party/codemirror.next/chunk/java.js +2 -1
  269. package/front_end/third_party/codemirror.next/chunk/json.js +2 -2
  270. package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
  271. package/front_end/third_party/codemirror.next/chunk/markdown.js +2 -2
  272. package/front_end/third_party/codemirror.next/chunk/php.js +2 -1
  273. package/front_end/third_party/codemirror.next/chunk/python.js +2 -2
  274. package/front_end/third_party/codemirror.next/chunk/wast.js +2 -1
  275. package/front_end/third_party/codemirror.next/chunk/xml.js +2 -1
  276. package/front_end/third_party/codemirror.next/codemirror.next.d.ts +1884 -2281
  277. package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
  278. package/front_end/third_party/codemirror.next/package.json +21 -32
  279. package/front_end/third_party/lit-html/README.chromium +3 -3
  280. package/front_end/third_party/lit-html/package/README.md +1 -1
  281. package/front_end/third_party/lit-html/package/async-directive.d.ts +1 -1
  282. package/front_end/third_party/lit-html/package/async-directive.js.map +1 -1
  283. package/front_end/third_party/lit-html/package/development/async-directive.d.ts +1 -1
  284. package/front_end/third_party/lit-html/package/development/async-directive.js.map +1 -1
  285. package/front_end/third_party/lit-html/package/development/directives/choose.d.ts +32 -0
  286. package/front_end/third_party/lit-html/package/development/directives/choose.d.ts.map +1 -0
  287. package/front_end/third_party/lit-html/package/development/directives/choose.js +41 -0
  288. package/front_end/third_party/lit-html/package/development/directives/choose.js.map +1 -0
  289. package/front_end/third_party/lit-html/package/development/directives/join.d.ts +21 -0
  290. package/front_end/third_party/lit-html/package/development/directives/join.d.ts.map +1 -0
  291. package/front_end/third_party/lit-html/package/development/directives/join.js +19 -0
  292. package/front_end/third_party/lit-html/package/development/directives/join.js.map +1 -0
  293. package/front_end/third_party/lit-html/package/development/directives/keyed.d.ts +23 -0
  294. package/front_end/third_party/lit-html/package/development/directives/keyed.d.ts.map +1 -0
  295. package/front_end/third_party/lit-html/package/development/directives/keyed.js +39 -0
  296. package/front_end/third_party/lit-html/package/development/directives/keyed.js.map +1 -0
  297. package/front_end/third_party/lit-html/package/development/directives/map.d.ts +23 -0
  298. package/front_end/third_party/lit-html/package/development/directives/map.d.ts.map +1 -0
  299. package/front_end/third_party/lit-html/package/development/directives/map.js +30 -0
  300. package/front_end/third_party/lit-html/package/development/directives/map.js.map +1 -0
  301. package/front_end/third_party/lit-html/package/development/directives/range.d.ts +24 -0
  302. package/front_end/third_party/lit-html/package/development/directives/range.d.ts.map +1 -0
  303. package/front_end/third_party/lit-html/package/development/directives/range.js +13 -0
  304. package/front_end/third_party/lit-html/package/development/directives/range.js.map +1 -0
  305. package/front_end/third_party/lit-html/package/development/directives/template-content.d.ts +1 -1
  306. package/front_end/third_party/lit-html/package/development/directives/when.d.ts +26 -0
  307. package/front_end/third_party/lit-html/package/development/directives/when.d.ts.map +1 -0
  308. package/front_end/third_party/lit-html/package/development/directives/when.js +9 -0
  309. package/front_end/third_party/lit-html/package/development/directives/when.js.map +1 -0
  310. package/front_end/third_party/lit-html/package/development/lit-html.d.ts +182 -1
  311. package/front_end/third_party/lit-html/package/development/lit-html.d.ts.map +1 -1
  312. package/front_end/third_party/lit-html/package/development/lit-html.js +187 -4
  313. package/front_end/third_party/lit-html/package/development/lit-html.js.map +1 -1
  314. package/front_end/third_party/lit-html/package/development/static.d.ts.map +1 -1
  315. package/front_end/third_party/lit-html/package/development/static.js +7 -0
  316. package/front_end/third_party/lit-html/package/development/static.js.map +1 -1
  317. package/front_end/third_party/lit-html/package/directives/choose.d.ts +32 -0
  318. package/front_end/third_party/lit-html/package/directives/choose.d.ts.map +1 -0
  319. package/front_end/third_party/lit-html/package/directives/choose.js +7 -0
  320. package/front_end/third_party/lit-html/package/directives/choose.js.map +1 -0
  321. package/front_end/third_party/lit-html/package/directives/class-map.js +1 -1
  322. package/front_end/third_party/lit-html/package/directives/guard.js +1 -1
  323. package/front_end/third_party/lit-html/package/directives/join.d.ts +21 -0
  324. package/front_end/third_party/lit-html/package/directives/join.d.ts.map +1 -0
  325. package/front_end/third_party/lit-html/package/directives/join.js +7 -0
  326. package/front_end/third_party/lit-html/package/directives/join.js.map +1 -0
  327. package/front_end/third_party/lit-html/package/directives/keyed.d.ts +23 -0
  328. package/front_end/third_party/lit-html/package/directives/keyed.d.ts.map +1 -0
  329. package/front_end/third_party/lit-html/package/directives/keyed.js +7 -0
  330. package/front_end/third_party/lit-html/package/directives/keyed.js.map +1 -0
  331. package/front_end/third_party/lit-html/package/directives/map.d.ts +23 -0
  332. package/front_end/third_party/lit-html/package/directives/map.d.ts.map +1 -0
  333. package/front_end/third_party/lit-html/package/directives/map.js +7 -0
  334. package/front_end/third_party/lit-html/package/directives/map.js.map +1 -0
  335. package/front_end/third_party/lit-html/package/directives/range.d.ts +24 -0
  336. package/front_end/third_party/lit-html/package/directives/range.d.ts.map +1 -0
  337. package/front_end/third_party/lit-html/package/directives/range.js +7 -0
  338. package/front_end/third_party/lit-html/package/directives/range.js.map +1 -0
  339. package/front_end/third_party/lit-html/package/directives/ref.js +1 -1
  340. package/front_end/third_party/lit-html/package/directives/repeat.js +1 -1
  341. package/front_end/third_party/lit-html/package/directives/style-map.js +1 -1
  342. package/front_end/third_party/lit-html/package/directives/template-content.d.ts +1 -1
  343. package/front_end/third_party/lit-html/package/directives/template-content.js +1 -1
  344. package/front_end/third_party/lit-html/package/directives/unsafe-html.js +1 -1
  345. package/front_end/third_party/lit-html/package/directives/until.js +1 -1
  346. package/front_end/third_party/lit-html/package/directives/when.d.ts +26 -0
  347. package/front_end/third_party/lit-html/package/directives/when.d.ts.map +1 -0
  348. package/front_end/third_party/lit-html/package/directives/when.js +7 -0
  349. package/front_end/third_party/lit-html/package/directives/when.js.map +1 -0
  350. package/front_end/third_party/lit-html/package/lit-html.d.ts +182 -1
  351. package/front_end/third_party/lit-html/package/lit-html.d.ts.map +1 -1
  352. package/front_end/third_party/lit-html/package/lit-html.js +1 -1
  353. package/front_end/third_party/lit-html/package/lit-html.js.map +1 -1
  354. package/front_end/third_party/lit-html/package/package.json +25 -1
  355. package/front_end/third_party/lit-html/package/private-ssr-support.js +1 -1
  356. package/front_end/third_party/lit-html/package/static.d.ts.map +1 -1
  357. package/front_end/third_party/lit-html/package/static.js +1 -1
  358. package/front_end/third_party/lit-html/package/static.js.map +1 -1
  359. package/front_end/third_party/puppeteer/README.chromium +1 -1
  360. package/front_end/third_party/puppeteer/package/README.md +12 -13
  361. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api-docs-entry.js +5 -1
  362. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api-docs-entry.js.map +1 -1
  363. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/BrowserConnector.js +5 -1
  364. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/BrowserConnector.js.map +1 -1
  365. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/FrameManager.d.ts +2 -2
  366. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/FrameManager.js +2 -2
  367. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/HTTPRequest.d.ts +2 -2
  368. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/HTTPRequest.d.ts.map +1 -1
  369. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/HTTPRequest.js +13 -6
  370. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/HTTPRequest.js.map +1 -1
  371. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/JSHandle.js +5 -1
  372. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/JSHandle.js.map +1 -1
  373. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkEventManager.d.ts +1 -0
  374. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkEventManager.d.ts.map +1 -1
  375. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkEventManager.js +4 -1
  376. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkEventManager.js.map +1 -1
  377. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkManager.d.ts +1 -0
  378. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkManager.d.ts.map +1 -1
  379. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkManager.js +10 -0
  380. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/NetworkManager.js.map +1 -1
  381. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/PDFOptions.d.ts +4 -2
  382. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/PDFOptions.d.ts.map +1 -1
  383. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/PDFOptions.js.map +1 -1
  384. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/Page.d.ts.map +1 -1
  385. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/Page.js +12 -1
  386. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/Page.js.map +1 -1
  387. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/fetch.js +5 -1
  388. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/fetch.js.map +1 -1
  389. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/helper.d.ts.map +1 -1
  390. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/helper.js +7 -6
  391. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/helper.js.map +1 -1
  392. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserFetcher.js +8 -1
  393. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserFetcher.js.map +1 -1
  394. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserRunner.js +6 -2
  395. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserRunner.js.map +1 -1
  396. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/Launcher.js +6 -2
  397. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/Launcher.js.map +1 -1
  398. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +1 -1
  399. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/FrameManager.d.ts +2 -2
  400. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/FrameManager.js +2 -2
  401. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/HTTPRequest.d.ts +2 -2
  402. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/HTTPRequest.d.ts.map +1 -1
  403. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/HTTPRequest.js +13 -6
  404. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/HTTPRequest.js.map +1 -1
  405. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkEventManager.d.ts +1 -0
  406. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkEventManager.d.ts.map +1 -1
  407. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkEventManager.js +4 -1
  408. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkEventManager.js.map +1 -1
  409. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkManager.d.ts +1 -0
  410. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkManager.d.ts.map +1 -1
  411. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkManager.js +10 -0
  412. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/NetworkManager.js.map +1 -1
  413. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/PDFOptions.d.ts +4 -2
  414. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/PDFOptions.d.ts.map +1 -1
  415. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/PDFOptions.js.map +1 -1
  416. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/Page.d.ts.map +1 -1
  417. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/Page.js +12 -1
  418. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/Page.js.map +1 -1
  419. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/helper.d.ts.map +1 -1
  420. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/helper.js +2 -5
  421. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/helper.js.map +1 -1
  422. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserFetcher.js +3 -0
  423. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserFetcher.js.map +1 -1
  424. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserRunner.js +1 -1
  425. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserRunner.js.map +1 -1
  426. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/Launcher.js +1 -1
  427. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/Launcher.js.map +1 -1
  428. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +1 -1
  429. package/front_end/third_party/puppeteer/package/lib/types.d.ts +10 -6
  430. package/front_end/third_party/puppeteer/package/package.json +17 -17
  431. package/front_end/ui/components/code_highlighter/CodeHighlighter.ts +1 -1
  432. package/front_end/ui/components/data_grid/DataGrid.ts +8 -9
  433. package/front_end/ui/components/data_grid/DataGridController.ts +3 -1
  434. package/front_end/ui/components/docs/panel_introduction_steps/basic.html +25 -0
  435. package/front_end/ui/components/docs/panel_introduction_steps/basic.ts +25 -0
  436. package/front_end/ui/components/input/input.ts +2 -2
  437. package/front_end/ui/components/linkifier/LinkifierUtils.ts +3 -1
  438. package/front_end/ui/components/panel_introduction_steps/PanelIntroductionSteps.ts +44 -0
  439. package/front_end/ui/components/panel_introduction_steps/panelIntroductionSteps.css +56 -0
  440. package/front_end/ui/components/panel_introduction_steps/panel_introduction_steps.ts +5 -0
  441. package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +3 -4
  442. package/front_end/ui/components/text_editor/TextEditor.ts +1 -1
  443. package/front_end/ui/components/text_editor/config.ts +1 -35
  444. package/front_end/ui/components/text_editor/javascript.ts +8 -8
  445. package/front_end/ui/components/tree_outline/TreeOutline.ts +10 -9
  446. package/front_end/ui/components/tree_outline/treeOutline.css +1 -1
  447. package/front_end/ui/legacy/ARIAUtils.ts +4 -2
  448. package/front_end/ui/legacy/ContextMenu.ts +14 -0
  449. package/front_end/ui/legacy/DockController.ts +2 -1
  450. package/front_end/ui/legacy/SettingsUI.ts +3 -3
  451. package/front_end/ui/legacy/SoftContextMenu.ts +43 -14
  452. package/front_end/ui/legacy/Toolbar.ts +16 -0
  453. package/front_end/ui/legacy/Treeoutline.ts +17 -7
  454. package/front_end/ui/legacy/UIUtils.ts +2 -2
  455. package/front_end/ui/legacy/View.ts +14 -8
  456. package/front_end/ui/legacy/ViewManager.ts +2 -1
  457. package/front_end/ui/legacy/ViewRegistration.ts +6 -0
  458. package/front_end/ui/legacy/Widget.ts +2 -1
  459. package/front_end/ui/legacy/components/color_picker/Spectrum.ts +43 -11
  460. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +98 -48
  461. package/front_end/ui/legacy/components/data_grid/ViewportDataGrid.ts +4 -3
  462. package/front_end/ui/legacy/components/data_grid/dataGrid.css +24 -28
  463. package/front_end/ui/legacy/components/inline_editor/CSSAngle.ts +5 -11
  464. package/front_end/ui/legacy/components/inline_editor/CSSLength.ts +8 -1
  465. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +10 -7
  466. package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +11 -10
  467. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +7 -1
  468. package/front_end/ui/legacy/components/utils/ImagePreview.ts +12 -7
  469. package/front_end/ui/legacy/components/utils/Linkifier.ts +7 -5
  470. package/front_end/ui/legacy/reportView.css +1 -0
  471. package/front_end/ui/legacy/splitWidget.css +1 -1
  472. package/front_end/ui/legacy/tabbedPane.css +1 -0
  473. package/front_end/ui/legacy/themeColors.css +1 -1
  474. package/front_end/ui/legacy/toolbar.css +17 -1
  475. package/front_end/ui/legacy/utils/focus-changed.ts +3 -1
  476. package/inspector_overlay/.eslintrc.js +9 -0
  477. package/package.json +17 -17
  478. package/scripts/eslint_rules/lib/check_component_naming.js +4 -0
  479. package/scripts/eslint_rules/lib/es_modules_import.js +6 -0
  480. package/scripts/eslint_rules/lib/inject_checkbox_styles.js +121 -0
  481. package/scripts/eslint_rules/tests/es_modules_import_test.js +12 -0
  482. package/scripts/eslint_rules/tests/inject_checkbox_styles_test.js +127 -0
  483. package/front_end/models/issues_manager/descriptions/arAttributionEventSourceTriggerDataTooLarge.md +0 -4
  484. package/front_end/models/issues_manager/descriptions/arAttributionTriggerDataTooLarge.md +0 -4
  485. package/front_end/models/issues_manager/descriptions/arInvalidAttributionData.md +0 -8
  486. package/front_end/models/issues_manager/descriptions/arInvalidEventSourceTriggerData.md +0 -9
  487. package/front_end/models/issues_manager/descriptions/arInvalidTriggerDedupKey.md +0 -5
  488. package/front_end/models/issues_manager/descriptions/arInvalidTriggerPriority.md +0 -5
  489. package/front_end/models/issues_manager/descriptions/arMissingAttributionData.md +0 -7
@@ -0,0 +1,1614 @@
1
+ // Copyright 2022 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
+
5
+ /*
6
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
7
+ * Copyright (C) 2009 Joseph Pecoraro
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions
11
+ * are met:
12
+ *
13
+ * 1. Redistributions of source code must retain the above copyright
14
+ * notice, this list of conditions and the following disclaimer.
15
+ * 2. Redistributions in binary form must reproduce the above copyright
16
+ * notice, this list of conditions and the following disclaimer in the
17
+ * documentation and/or other materials provided with the distribution.
18
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
19
+ * its contributors may be used to endorse or promote products derived
20
+ * from this software without specific prior written permission.
21
+ *
22
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
23
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
26
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+
34
+ import * as Common from '../../core/common/common.js';
35
+ import * as Host from '../../core/host/host.js';
36
+ import * as i18n from '../../core/i18n/i18n.js';
37
+ import * as Root from '../../core/root/root.js';
38
+ import * as SDK from '../../core/sdk/sdk.js';
39
+ import type * as Protocol from '../../generated/protocol.js';
40
+ import * as Bindings from '../../models/bindings/bindings.js';
41
+ import * as TextUtils from '../../models/text_utils/text_utils.js';
42
+ import type * as Components from '../../ui/legacy/components/utils/utils.js';
43
+ import * as UI from '../../ui/legacy/legacy.js';
44
+
45
+ import {FontEditorSectionManager} from './ColorSwatchPopoverIcon.js';
46
+ import * as ElementsComponents from './components/components.js';
47
+ import {linkifyDeferredNodeReference} from './DOMLinkifier.js';
48
+ import {ElementsPanel} from './ElementsPanel.js';
49
+ import stylesSectionTreeStyles from './stylesSectionTree.css.js';
50
+
51
+ import type {Context} from './StylePropertyTreeElement.js';
52
+ import {StylePropertyTreeElement} from './StylePropertyTreeElement.js';
53
+ import {StylesSidebarPane} from './StylesSidebarPane.js';
54
+
55
+ const UIStrings = {
56
+ /**
57
+ *@description Tooltip text that appears when hovering over the largeicon add button in the Styles Sidebar Pane of the Elements panel
58
+ */
59
+ insertStyleRuleBelow: 'Insert Style Rule Below',
60
+ /**
61
+ *@description Text in Styles Sidebar Pane of the Elements panel
62
+ */
63
+ constructedStylesheet: 'constructed stylesheet',
64
+ /**
65
+ *@description Text in Styles Sidebar Pane of the Elements panel
66
+ */
67
+ userAgentStylesheet: 'user agent stylesheet',
68
+ /**
69
+ *@description Text in Styles Sidebar Pane of the Elements panel
70
+ */
71
+ injectedStylesheet: 'injected stylesheet',
72
+ /**
73
+ *@description Text in Styles Sidebar Pane of the Elements panel
74
+ */
75
+ viaInspector: 'via inspector',
76
+ /**
77
+ *@description Text in Styles Sidebar Pane of the Elements panel
78
+ */
79
+ styleAttribute: '`style` attribute',
80
+ /**
81
+ *@description Text in Styles Sidebar Pane of the Elements panel
82
+ *@example {html} PH1
83
+ */
84
+ sattributesStyle: '{PH1}[Attributes Style]',
85
+ /**
86
+ *@description Show all button text content in Styles Sidebar Pane of the Elements panel
87
+ *@example {3} PH1
88
+ */
89
+ showAllPropertiesSMore: 'Show All Properties ({PH1} more)',
90
+ /**
91
+ *@description Text in Elements Tree Element of the Elements panel, copy should be used as a verb
92
+ */
93
+ copySelector: 'Copy `selector`',
94
+ /**
95
+ *@description A context menu item in Styles panel to copy CSS rule
96
+ */
97
+ copyRule: 'Copy rule',
98
+ /**
99
+ *@description A context menu item in Styles panel to copy all CSS declarations
100
+ */
101
+ copyAllDeclarations: 'Copy all declarations',
102
+ /**
103
+ *@description A context menu item in Styles panel to copy all the CSS changes
104
+ */
105
+ copyAllCSSChanges: 'Copy all CSS changes',
106
+ /**
107
+ *@description Text that is announced by the screen reader when the user focuses on an input field for editing the name of a CSS selector in the Styles panel
108
+ */
109
+ cssSelector: '`CSS` selector',
110
+ };
111
+
112
+ const str_ = i18n.i18n.registerUIStrings('panels/elements/StylePropertiesSection.ts', UIStrings);
113
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
114
+
115
+ // TODO(crbug.com/1172300) This workaround is needed to keep the linter happy.
116
+ // Otherwise it complains about: Unknown word CssSyntaxError
117
+ const STYLE_TAG = '<' +
118
+ 'style>';
119
+
120
+ export class StylePropertiesSection {
121
+ protected parentPane: StylesSidebarPane;
122
+ styleInternal: SDK.CSSStyleDeclaration.CSSStyleDeclaration;
123
+ readonly matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles;
124
+ editable: boolean;
125
+ private hoverTimer: number|null;
126
+ private willCauseCancelEditing: boolean;
127
+ private forceShowAll: boolean;
128
+ private readonly originalPropertiesCount: number;
129
+ element: HTMLDivElement;
130
+ private readonly innerElement: HTMLElement;
131
+ private readonly titleElement: HTMLElement;
132
+ propertiesTreeOutline: UI.TreeOutline.TreeOutlineInShadow;
133
+ private showAllButton: HTMLButtonElement;
134
+ protected selectorElement: HTMLSpanElement;
135
+ private readonly newStyleRuleToolbar: UI.Toolbar.Toolbar|undefined;
136
+ private readonly fontEditorToolbar: UI.Toolbar.Toolbar|undefined;
137
+ private readonly fontEditorSectionManager: FontEditorSectionManager|undefined;
138
+ private readonly fontEditorButton: UI.Toolbar.ToolbarButton|undefined;
139
+ private selectedSinceMouseDown: boolean;
140
+ private readonly elementToSelectorIndex: WeakMap<Element, number>;
141
+ navigable: boolean|null|undefined;
142
+ protected readonly selectorRefElement: HTMLElement;
143
+ private readonly selectorContainer: HTMLDivElement;
144
+ private hoverableSelectorsMode: boolean;
145
+ private isHiddenInternal: boolean;
146
+
147
+ private queryListElement: HTMLElement;
148
+
149
+ // Used to identify buttons that trigger a flexbox or grid editor.
150
+ nextEditorTriggerButtonIdx = 1;
151
+ private sectionIdx = 0;
152
+
153
+ constructor(
154
+ parentPane: StylesSidebarPane, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
155
+ style: SDK.CSSStyleDeclaration.CSSStyleDeclaration, sectionIdx: number) {
156
+ this.parentPane = parentPane;
157
+ this.sectionIdx = sectionIdx;
158
+ this.styleInternal = style;
159
+ this.matchedStyles = matchedStyles;
160
+ this.editable = Boolean(style.styleSheetId && style.range);
161
+ this.hoverTimer = null;
162
+ this.willCauseCancelEditing = false;
163
+ this.forceShowAll = false;
164
+ this.originalPropertiesCount = style.leadingProperties().length;
165
+
166
+ const rule = style.parentRule;
167
+ this.element = document.createElement('div');
168
+ this.element.classList.add('styles-section');
169
+ this.element.classList.add('matched-styles');
170
+ this.element.classList.add('monospace');
171
+ UI.ARIAUtils.setAccessibleName(this.element, `${this.headerText()}, css selector`);
172
+ this.element.tabIndex = -1;
173
+ UI.ARIAUtils.markAsListitem(this.element);
174
+ this.element.addEventListener('keydown', this.onKeyDown.bind(this), false);
175
+ parentPane.sectionByElement.set(this.element, this);
176
+ this.innerElement = this.element.createChild('div');
177
+
178
+ this.titleElement = this.innerElement.createChild('div', 'styles-section-title ' + (rule ? 'styles-selector' : ''));
179
+
180
+ this.propertiesTreeOutline = new UI.TreeOutline.TreeOutlineInShadow();
181
+ this.propertiesTreeOutline.setFocusable(false);
182
+ this.propertiesTreeOutline.registerCSSFiles([stylesSectionTreeStyles]);
183
+ this.propertiesTreeOutline.element.classList.add('style-properties', 'matched-styles', 'monospace');
184
+ // @ts-ignore TODO: fix ad hoc section property in a separate CL to be safe
185
+ this.propertiesTreeOutline.section = this;
186
+ this.innerElement.appendChild(this.propertiesTreeOutline.element);
187
+
188
+ this.showAllButton = UI.UIUtils.createTextButton('', this.showAllItems.bind(this), 'styles-show-all');
189
+ this.innerElement.appendChild(this.showAllButton);
190
+
191
+ const selectorContainer = document.createElement('div');
192
+ this.selectorElement = document.createElement('span');
193
+ UI.ARIAUtils.setAccessibleName(this.selectorElement, i18nString(UIStrings.cssSelector));
194
+ this.selectorElement.classList.add('selector');
195
+ this.selectorElement.textContent = this.headerText();
196
+ selectorContainer.appendChild(this.selectorElement);
197
+ this.selectorElement.addEventListener('mouseenter', this.onMouseEnterSelector.bind(this), false);
198
+ this.selectorElement.addEventListener('mousemove', event => event.consume(), false);
199
+ this.selectorElement.addEventListener('mouseleave', this.onMouseOutSelector.bind(this), false);
200
+
201
+ const openBrace = selectorContainer.createChild('span', 'sidebar-pane-open-brace');
202
+ openBrace.textContent = ' {';
203
+ selectorContainer.addEventListener('mousedown', this.handleEmptySpaceMouseDown.bind(this), false);
204
+ selectorContainer.addEventListener('click', this.handleSelectorContainerClick.bind(this), false);
205
+
206
+ const closeBrace = this.innerElement.createChild('div', 'sidebar-pane-closing-brace');
207
+ closeBrace.textContent = '}';
208
+
209
+ if (this.styleInternal.parentRule) {
210
+ const newRuleButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.insertStyleRuleBelow), 'largeicon-add');
211
+ newRuleButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this.onNewRuleClick, this);
212
+ newRuleButton.element.tabIndex = -1;
213
+ if (!this.newStyleRuleToolbar) {
214
+ this.newStyleRuleToolbar =
215
+ new UI.Toolbar.Toolbar('sidebar-pane-section-toolbar new-rule-toolbar', this.innerElement);
216
+ }
217
+ this.newStyleRuleToolbar.appendToolbarItem(newRuleButton);
218
+ UI.ARIAUtils.markAsHidden(this.newStyleRuleToolbar.element);
219
+ }
220
+
221
+ if (Root.Runtime.experiments.isEnabled('fontEditor') && this.editable) {
222
+ this.fontEditorToolbar = new UI.Toolbar.Toolbar('sidebar-pane-section-toolbar', this.innerElement);
223
+ this.fontEditorSectionManager = new FontEditorSectionManager(this.parentPane.swatchPopoverHelper(), this);
224
+ this.fontEditorButton = new UI.Toolbar.ToolbarButton('Font Editor', 'largeicon-font-editor');
225
+ this.fontEditorButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => {
226
+ this.onFontEditorButtonClicked();
227
+ }, this);
228
+ this.fontEditorButton.element.addEventListener('keydown', event => {
229
+ if (isEnterOrSpaceKey(event)) {
230
+ event.consume(true);
231
+ this.onFontEditorButtonClicked();
232
+ }
233
+ }, false);
234
+ this.fontEditorToolbar.appendToolbarItem(this.fontEditorButton);
235
+
236
+ if (this.styleInternal.type === SDK.CSSStyleDeclaration.Type.Inline) {
237
+ if (this.newStyleRuleToolbar) {
238
+ this.newStyleRuleToolbar.element.classList.add('shifted-toolbar');
239
+ }
240
+ } else {
241
+ this.fontEditorToolbar.element.classList.add('font-toolbar-hidden');
242
+ }
243
+ }
244
+
245
+ this.selectorElement.addEventListener('click', this.handleSelectorClick.bind(this), false);
246
+ this.element.addEventListener('contextmenu', this.handleContextMenuEvent.bind(this), false);
247
+ this.element.addEventListener('mousedown', this.handleEmptySpaceMouseDown.bind(this), false);
248
+ this.element.addEventListener('click', this.handleEmptySpaceClick.bind(this), false);
249
+ this.element.addEventListener('mousemove', this.onMouseMove.bind(this), false);
250
+ this.element.addEventListener('mouseleave', this.onMouseLeave.bind(this), false);
251
+ this.selectedSinceMouseDown = false;
252
+
253
+ this.elementToSelectorIndex = new WeakMap();
254
+
255
+ if (rule) {
256
+ // Prevent editing the user agent and user rules.
257
+ if (rule.isUserAgent() || rule.isInjected()) {
258
+ this.editable = false;
259
+ } else {
260
+ // Check this is a real CSSRule, not a bogus object coming from BlankStylePropertiesSection.
261
+ if (rule.styleSheetId) {
262
+ const header = rule.cssModel().styleSheetHeaderForId(rule.styleSheetId);
263
+ this.navigable = header && !header.isAnonymousInlineStyleSheet();
264
+ }
265
+ }
266
+ }
267
+
268
+ this.queryListElement = this.titleElement.createChild('div', 'query-list query-matches');
269
+ this.selectorRefElement = this.titleElement.createChild('div', 'styles-section-subtitle');
270
+ this.updateQueryList();
271
+ this.updateRuleOrigin();
272
+ this.titleElement.appendChild(selectorContainer);
273
+ this.selectorContainer = selectorContainer;
274
+
275
+ if (this.navigable) {
276
+ this.element.classList.add('navigable');
277
+ }
278
+
279
+ if (!this.editable) {
280
+ this.element.classList.add('read-only');
281
+ this.propertiesTreeOutline.element.classList.add('read-only');
282
+ }
283
+ this.hoverableSelectorsMode = false;
284
+ this.isHiddenInternal = false;
285
+ this.markSelectorMatches();
286
+ this.onpopulate();
287
+ }
288
+
289
+ setSectionIdx(sectionIdx: number): void {
290
+ this.sectionIdx = sectionIdx;
291
+ this.onpopulate();
292
+ }
293
+
294
+ getSectionIdx(): number {
295
+ return this.sectionIdx;
296
+ }
297
+
298
+ registerFontProperty(treeElement: StylePropertyTreeElement): void {
299
+ if (this.fontEditorSectionManager) {
300
+ this.fontEditorSectionManager.registerFontProperty(treeElement);
301
+ }
302
+ if (this.fontEditorToolbar) {
303
+ this.fontEditorToolbar.element.classList.remove('font-toolbar-hidden');
304
+ if (this.newStyleRuleToolbar) {
305
+ this.newStyleRuleToolbar.element.classList.add('shifted-toolbar');
306
+ }
307
+ }
308
+ }
309
+
310
+ resetToolbars(): void {
311
+ if (this.parentPane.swatchPopoverHelper().isShowing() ||
312
+ this.styleInternal.type === SDK.CSSStyleDeclaration.Type.Inline) {
313
+ return;
314
+ }
315
+ if (this.fontEditorToolbar) {
316
+ this.fontEditorToolbar.element.classList.add('font-toolbar-hidden');
317
+ }
318
+ if (this.newStyleRuleToolbar) {
319
+ this.newStyleRuleToolbar.element.classList.remove('shifted-toolbar');
320
+ }
321
+ }
322
+
323
+ static createRuleOriginNode(
324
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, linkifier: Components.Linkifier.Linkifier,
325
+ rule: SDK.CSSRule.CSSRule|null): Node {
326
+ if (!rule) {
327
+ return document.createTextNode('');
328
+ }
329
+
330
+ const ruleLocation = this.getRuleLocationFromCSSRule(rule);
331
+
332
+ const header = rule.styleSheetId ? matchedStyles.cssModel().styleSheetHeaderForId(rule.styleSheetId) : null;
333
+
334
+ function linkifyRuleLocation(): Node|null {
335
+ if (!rule) {
336
+ return null;
337
+ }
338
+ if (ruleLocation && rule.styleSheetId && header && !header.isAnonymousInlineStyleSheet()) {
339
+ return StylePropertiesSection.linkifyRuleLocation(
340
+ matchedStyles.cssModel(), linkifier, rule.styleSheetId, ruleLocation);
341
+ }
342
+ return null;
343
+ }
344
+
345
+ function linkifyNode(label: string): Node|null {
346
+ if (header?.ownerNode) {
347
+ const link = linkifyDeferredNodeReference(header.ownerNode, {
348
+ preventKeyboardFocus: false,
349
+ tooltip: undefined,
350
+ });
351
+ link.textContent = label;
352
+ return link;
353
+ }
354
+ return null;
355
+ }
356
+
357
+ if (header?.isMutable && !header.isViaInspector()) {
358
+ const location = header.isConstructedByNew() ? null : linkifyRuleLocation();
359
+ if (location) {
360
+ return location;
361
+ }
362
+ const label = header.isConstructedByNew() ? i18nString(UIStrings.constructedStylesheet) : STYLE_TAG;
363
+ const node = linkifyNode(label);
364
+ if (node) {
365
+ return node;
366
+ }
367
+ return document.createTextNode(label);
368
+ }
369
+
370
+ const location = linkifyRuleLocation();
371
+ if (location) {
372
+ return location;
373
+ }
374
+
375
+ if (rule.isUserAgent()) {
376
+ return document.createTextNode(i18nString(UIStrings.userAgentStylesheet));
377
+ }
378
+ if (rule.isInjected()) {
379
+ return document.createTextNode(i18nString(UIStrings.injectedStylesheet));
380
+ }
381
+ if (rule.isViaInspector()) {
382
+ return document.createTextNode(i18nString(UIStrings.viaInspector));
383
+ }
384
+
385
+ const node = linkifyNode(STYLE_TAG);
386
+ if (node) {
387
+ return node;
388
+ }
389
+
390
+ return document.createTextNode('');
391
+ }
392
+
393
+ private static getRuleLocationFromCSSRule(rule: SDK.CSSRule.CSSRule): TextUtils.TextRange.TextRange|null|undefined {
394
+ let ruleLocation;
395
+ if (rule instanceof SDK.CSSRule.CSSStyleRule) {
396
+ ruleLocation = rule.style.range;
397
+ } else if (rule instanceof SDK.CSSRule.CSSKeyframeRule) {
398
+ ruleLocation = rule.key().range;
399
+ }
400
+ return ruleLocation;
401
+ }
402
+
403
+ static tryNavigateToRuleLocation(
404
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, rule: SDK.CSSRule.CSSRule|null): void {
405
+ if (!rule) {
406
+ return;
407
+ }
408
+
409
+ const ruleLocation = this.getRuleLocationFromCSSRule(rule);
410
+ const header = rule.styleSheetId ? matchedStyles.cssModel().styleSheetHeaderForId(rule.styleSheetId) : null;
411
+
412
+ if (ruleLocation && rule.styleSheetId && header && !header.isAnonymousInlineStyleSheet()) {
413
+ const matchingSelectorLocation =
414
+ this.getCSSSelectorLocation(matchedStyles.cssModel(), rule.styleSheetId, ruleLocation);
415
+ this.revealSelectorSource(matchingSelectorLocation, true);
416
+ }
417
+ }
418
+
419
+ protected static linkifyRuleLocation(
420
+ cssModel: SDK.CSSModel.CSSModel, linkifier: Components.Linkifier.Linkifier,
421
+ styleSheetId: Protocol.CSS.StyleSheetId, ruleLocation: TextUtils.TextRange.TextRange): Node {
422
+ const matchingSelectorLocation = this.getCSSSelectorLocation(cssModel, styleSheetId, ruleLocation);
423
+ return linkifier.linkifyCSSLocation(matchingSelectorLocation);
424
+ }
425
+
426
+ private static getCSSSelectorLocation(
427
+ cssModel: SDK.CSSModel.CSSModel, styleSheetId: Protocol.CSS.StyleSheetId,
428
+ ruleLocation: TextUtils.TextRange.TextRange): SDK.CSSModel.CSSLocation {
429
+ const styleSheetHeader =
430
+ (cssModel.styleSheetHeaderForId(styleSheetId) as SDK.CSSStyleSheetHeader.CSSStyleSheetHeader);
431
+ const lineNumber = styleSheetHeader.lineNumberInSource(ruleLocation.startLine);
432
+ const columnNumber = styleSheetHeader.columnNumberInSource(ruleLocation.startLine, ruleLocation.startColumn);
433
+ return new SDK.CSSModel.CSSLocation(styleSheetHeader, lineNumber, columnNumber);
434
+ }
435
+
436
+ private getFocused(): HTMLElement|null {
437
+ return (this.propertiesTreeOutline.shadowRoot.activeElement as HTMLElement) || null;
438
+ }
439
+
440
+ private focusNext(element: HTMLElement): void {
441
+ // Clear remembered focused item (if any).
442
+ const focused = this.getFocused();
443
+ if (focused) {
444
+ focused.tabIndex = -1;
445
+ }
446
+
447
+ // Focus the next item and remember it (if in our subtree).
448
+ element.focus();
449
+ if (this.propertiesTreeOutline.shadowRoot.contains(element)) {
450
+ element.tabIndex = 0;
451
+ }
452
+ }
453
+
454
+ private ruleNavigation(keyboardEvent: KeyboardEvent): void {
455
+ if (keyboardEvent.altKey || keyboardEvent.ctrlKey || keyboardEvent.metaKey || keyboardEvent.shiftKey) {
456
+ return;
457
+ }
458
+
459
+ const focused = this.getFocused();
460
+
461
+ let focusNext: HTMLElement|null = null;
462
+ const focusable =
463
+ Array.from((this.propertiesTreeOutline.shadowRoot.querySelectorAll('[tabindex]') as NodeListOf<HTMLElement>));
464
+
465
+ if (focusable.length === 0) {
466
+ return;
467
+ }
468
+
469
+ const focusedIndex = focused ? focusable.indexOf(focused) : -1;
470
+
471
+ if (keyboardEvent.key === 'ArrowLeft') {
472
+ focusNext = focusable[focusedIndex - 1] || this.element;
473
+ } else if (keyboardEvent.key === 'ArrowRight') {
474
+ focusNext = focusable[focusedIndex + 1] || this.element;
475
+ } else if (keyboardEvent.key === 'ArrowUp' || keyboardEvent.key === 'ArrowDown') {
476
+ this.focusNext(this.element);
477
+ return;
478
+ }
479
+
480
+ if (focusNext) {
481
+ this.focusNext(focusNext);
482
+ keyboardEvent.consume(true);
483
+ }
484
+ }
485
+
486
+ private onKeyDown(event: Event): void {
487
+ const keyboardEvent = (event as KeyboardEvent);
488
+ if (UI.UIUtils.isEditing() || !this.editable || keyboardEvent.altKey || keyboardEvent.ctrlKey ||
489
+ keyboardEvent.metaKey) {
490
+ return;
491
+ }
492
+ switch (keyboardEvent.key) {
493
+ case 'Enter':
494
+ case ' ':
495
+ this.startEditingAtFirstPosition();
496
+ keyboardEvent.consume(true);
497
+ break;
498
+ case 'ArrowLeft':
499
+ case 'ArrowRight':
500
+ case 'ArrowUp':
501
+ case 'ArrowDown':
502
+ this.ruleNavigation(keyboardEvent);
503
+ break;
504
+ default:
505
+ // Filter out non-printable key strokes.
506
+ if (keyboardEvent.key.length === 1) {
507
+ this.addNewBlankProperty(0).startEditing();
508
+ }
509
+ break;
510
+ }
511
+ }
512
+
513
+ private setSectionHovered(isHovered: boolean): void {
514
+ this.element.classList.toggle('styles-panel-hovered', isHovered);
515
+ this.propertiesTreeOutline.element.classList.toggle('styles-panel-hovered', isHovered);
516
+ if (this.hoverableSelectorsMode !== isHovered) {
517
+ this.hoverableSelectorsMode = isHovered;
518
+ this.markSelectorMatches();
519
+ }
520
+ }
521
+
522
+ private onMouseLeave(_event: Event): void {
523
+ this.setSectionHovered(false);
524
+ this.parentPane.setActiveProperty(null);
525
+ }
526
+
527
+ private onMouseMove(event: MouseEvent): void {
528
+ const hasCtrlOrMeta = UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event);
529
+ this.setSectionHovered(hasCtrlOrMeta);
530
+
531
+ const treeElement = this.propertiesTreeOutline.treeElementFromEvent(event);
532
+ if (treeElement instanceof StylePropertyTreeElement) {
533
+ this.parentPane.setActiveProperty((treeElement as StylePropertyTreeElement));
534
+ } else {
535
+ this.parentPane.setActiveProperty(null);
536
+ }
537
+ const selection = this.element.getComponentSelection();
538
+ if (!this.selectedSinceMouseDown && selection && selection.toString()) {
539
+ this.selectedSinceMouseDown = true;
540
+ }
541
+ }
542
+
543
+ private onFontEditorButtonClicked(): void {
544
+ if (this.fontEditorSectionManager && this.fontEditorButton) {
545
+ void this.fontEditorSectionManager.showPopover(this.fontEditorButton.element, this.parentPane);
546
+ }
547
+ }
548
+
549
+ style(): SDK.CSSStyleDeclaration.CSSStyleDeclaration {
550
+ return this.styleInternal;
551
+ }
552
+
553
+ headerText(): string {
554
+ const node = this.matchedStyles.nodeForStyle(this.styleInternal);
555
+ if (this.styleInternal.type === SDK.CSSStyleDeclaration.Type.Inline) {
556
+ return this.matchedStyles.isInherited(this.styleInternal) ? i18nString(UIStrings.styleAttribute) :
557
+ 'element.style';
558
+ }
559
+ if (node && this.styleInternal.type === SDK.CSSStyleDeclaration.Type.Attributes) {
560
+ return i18nString(UIStrings.sattributesStyle, {PH1: node.nodeNameInCorrectCase()});
561
+ }
562
+ if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
563
+ return this.styleInternal.parentRule.selectorText();
564
+ }
565
+ return '';
566
+ }
567
+
568
+ private onMouseOutSelector(): void {
569
+ if (this.hoverTimer) {
570
+ clearTimeout(this.hoverTimer);
571
+ }
572
+ SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
573
+ }
574
+
575
+ private onMouseEnterSelector(): void {
576
+ if (this.hoverTimer) {
577
+ clearTimeout(this.hoverTimer);
578
+ }
579
+ this.hoverTimer = window.setTimeout(this.highlight.bind(this), 300);
580
+ }
581
+
582
+ highlight(mode: string|undefined = 'all'): void {
583
+ SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
584
+ const node = this.parentPane.node();
585
+ if (!node) {
586
+ return;
587
+ }
588
+ const selectorList =
589
+ this.styleInternal.parentRule && this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule ?
590
+ this.styleInternal.parentRule.selectorText() :
591
+ undefined;
592
+ node.domModel().overlayModel().highlightInOverlay({node, selectorList}, mode);
593
+ }
594
+
595
+ firstSibling(): StylePropertiesSection|null {
596
+ const parent = this.element.parentElement;
597
+ if (!parent) {
598
+ return null;
599
+ }
600
+
601
+ let childElement: (ChildNode|null) = parent.firstChild;
602
+ while (childElement) {
603
+ const childSection = this.parentPane.sectionByElement.get(childElement);
604
+ if (childSection) {
605
+ return childSection;
606
+ }
607
+ childElement = childElement.nextSibling;
608
+ }
609
+
610
+ return null;
611
+ }
612
+
613
+ findCurrentOrNextVisible(willIterateForward: boolean, originalSection?: StylePropertiesSection):
614
+ StylePropertiesSection|null {
615
+ if (!this.isHidden()) {
616
+ return this;
617
+ }
618
+ if (this === originalSection) {
619
+ return null;
620
+ }
621
+ if (!originalSection) {
622
+ originalSection = this;
623
+ }
624
+ let visibleSibling: (StylePropertiesSection|null)|null = null;
625
+ const nextSibling = willIterateForward ? this.nextSibling() : this.previousSibling();
626
+ if (nextSibling) {
627
+ visibleSibling = nextSibling.findCurrentOrNextVisible(willIterateForward, originalSection);
628
+ } else {
629
+ const loopSibling = willIterateForward ? this.firstSibling() : this.lastSibling();
630
+ if (loopSibling) {
631
+ visibleSibling = loopSibling.findCurrentOrNextVisible(willIterateForward, originalSection);
632
+ }
633
+ }
634
+
635
+ return visibleSibling;
636
+ }
637
+
638
+ lastSibling(): StylePropertiesSection|null {
639
+ const parent = this.element.parentElement;
640
+ if (!parent) {
641
+ return null;
642
+ }
643
+
644
+ let childElement: (ChildNode|null) = parent.lastChild;
645
+ while (childElement) {
646
+ const childSection = this.parentPane.sectionByElement.get(childElement);
647
+ if (childSection) {
648
+ return childSection;
649
+ }
650
+ childElement = childElement.previousSibling;
651
+ }
652
+
653
+ return null;
654
+ }
655
+
656
+ nextSibling(): StylePropertiesSection|undefined {
657
+ let curElement: (ChildNode|null)|HTMLDivElement = this.element;
658
+ do {
659
+ curElement = curElement.nextSibling;
660
+ } while (curElement && !this.parentPane.sectionByElement.has(curElement));
661
+
662
+ if (curElement) {
663
+ return this.parentPane.sectionByElement.get(curElement);
664
+ }
665
+ return;
666
+ }
667
+
668
+ previousSibling(): StylePropertiesSection|undefined {
669
+ let curElement: (ChildNode|null)|HTMLDivElement = this.element;
670
+ do {
671
+ curElement = curElement.previousSibling;
672
+ } while (curElement && !this.parentPane.sectionByElement.has(curElement));
673
+
674
+ if (curElement) {
675
+ return this.parentPane.sectionByElement.get(curElement);
676
+ }
677
+ return;
678
+ }
679
+
680
+ private onNewRuleClick(event: Common.EventTarget.EventTargetEvent<Event>): void {
681
+ event.data.consume();
682
+ const rule = this.styleInternal.parentRule;
683
+ if (!rule || !rule.style.range || rule.styleSheetId === undefined) {
684
+ return;
685
+ }
686
+ const range =
687
+ TextUtils.TextRange.TextRange.createFromLocation(rule.style.range.endLine, rule.style.range.endColumn + 1);
688
+ this.parentPane.addBlankSection(this, rule.styleSheetId, range);
689
+ }
690
+
691
+ styleSheetEdited(edit: SDK.CSSModel.Edit): void {
692
+ const rule = this.styleInternal.parentRule;
693
+ if (rule) {
694
+ rule.rebase(edit);
695
+ } else {
696
+ this.styleInternal.rebase(edit);
697
+ }
698
+
699
+ this.updateQueryList();
700
+ this.updateRuleOrigin();
701
+ }
702
+
703
+ protected createAtRuleLists(rule: SDK.CSSRule.CSSStyleRule): void {
704
+ this.createMediaList(rule.media);
705
+ this.createContainerQueryList(rule.containerQueries);
706
+ this.createSupportsList(rule.supports);
707
+ }
708
+
709
+ protected createMediaList(mediaRules: SDK.CSSMedia.CSSMedia[]): void {
710
+ for (let i = mediaRules.length - 1; i >= 0; --i) {
711
+ const media = mediaRules[i];
712
+ // Don't display trivial non-print media types.
713
+ const isMedia = !media.text || !media.text.includes('(') && media.text !== 'print';
714
+ if (isMedia) {
715
+ continue;
716
+ }
717
+
718
+ let queryPrefix = '';
719
+ let queryText = '';
720
+ let onQueryTextClick;
721
+ switch (media.source) {
722
+ case SDK.CSSMedia.Source.LINKED_SHEET:
723
+ case SDK.CSSMedia.Source.INLINE_SHEET: {
724
+ queryText = `media="${media.text}"`;
725
+ break;
726
+ }
727
+ case SDK.CSSMedia.Source.MEDIA_RULE: {
728
+ queryPrefix = '@media';
729
+ queryText = media.text;
730
+ if (media.styleSheetId) {
731
+ onQueryTextClick = this.handleQueryRuleClick.bind(this, media);
732
+ }
733
+ break;
734
+ }
735
+ case SDK.CSSMedia.Source.IMPORT_RULE: {
736
+ queryText = `@import ${media.text}`;
737
+ break;
738
+ }
739
+ }
740
+
741
+ const mediaQueryElement = new ElementsComponents.CSSQuery.CSSQuery();
742
+ mediaQueryElement.data = {
743
+ queryPrefix,
744
+ queryText,
745
+ onQueryTextClick,
746
+ };
747
+ this.queryListElement.append(mediaQueryElement);
748
+ }
749
+ }
750
+
751
+ protected createContainerQueryList(containerQueries: SDK.CSSContainerQuery.CSSContainerQuery[]): void {
752
+ for (let i = containerQueries.length - 1; i >= 0; --i) {
753
+ const containerQuery = containerQueries[i];
754
+ if (!containerQuery.text) {
755
+ continue;
756
+ }
757
+
758
+ let onQueryTextClick;
759
+ if (containerQuery.styleSheetId) {
760
+ onQueryTextClick = this.handleQueryRuleClick.bind(this, containerQuery);
761
+ }
762
+
763
+ const containerQueryElement = new ElementsComponents.CSSQuery.CSSQuery();
764
+ containerQueryElement.data = {
765
+ queryPrefix: '@container',
766
+ queryName: containerQuery.name,
767
+ queryText: containerQuery.text,
768
+ onQueryTextClick,
769
+ };
770
+ this.queryListElement.append(containerQueryElement);
771
+
772
+ void this.addContainerForContainerQuery(containerQuery);
773
+ }
774
+ }
775
+
776
+ protected createSupportsList(supportsList: SDK.CSSSupports.CSSSupports[]): void {
777
+ for (let i = supportsList.length - 1; i >= 0; --i) {
778
+ const supports = supportsList[i];
779
+ if (!supports.text) {
780
+ continue;
781
+ }
782
+
783
+ let onQueryTextClick;
784
+ if (supports.styleSheetId) {
785
+ onQueryTextClick = this.handleQueryRuleClick.bind(this, supports);
786
+ }
787
+
788
+ const supportsElement = new ElementsComponents.CSSQuery.CSSQuery();
789
+ supportsElement.data = {
790
+ queryPrefix: '@supports',
791
+ queryText: supports.text,
792
+ onQueryTextClick,
793
+ };
794
+ this.queryListElement.append(supportsElement);
795
+ }
796
+ }
797
+
798
+ private async addContainerForContainerQuery(containerQuery: SDK.CSSContainerQuery.CSSContainerQuery): Promise<void> {
799
+ const container = await containerQuery.getContainerForNode(this.matchedStyles.node().id);
800
+ if (!container) {
801
+ return;
802
+ }
803
+
804
+ const containerElement = new ElementsComponents.QueryContainer.QueryContainer();
805
+ containerElement.data = {
806
+ container: ElementsComponents.Helper.legacyNodeToElementsComponentsNode(container.containerNode),
807
+ queryName: containerQuery.name,
808
+ onContainerLinkClick: (event): void => {
809
+ event.preventDefault();
810
+ void ElementsPanel.instance().revealAndSelectNode(container.containerNode, true, true);
811
+ void container.containerNode.scrollIntoView();
812
+ },
813
+ };
814
+
815
+ containerElement.addEventListener('queriedsizerequested', async () => {
816
+ const details = await container.getContainerSizeDetails();
817
+ if (details) {
818
+ containerElement.updateContainerQueriedSizeDetails(details);
819
+ }
820
+ });
821
+
822
+ this.queryListElement.prepend(containerElement);
823
+ }
824
+
825
+ private updateQueryList(): void {
826
+ this.queryListElement.removeChildren();
827
+ if (this.styleInternal.parentRule && this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
828
+ this.createAtRuleLists(this.styleInternal.parentRule);
829
+ }
830
+ }
831
+
832
+ isPropertyInherited(propertyName: string): boolean {
833
+ if (this.matchedStyles.isInherited(this.styleInternal)) {
834
+ // While rendering inherited stylesheet, reverse meaning of this property.
835
+ // Render truly inherited properties with black, i.e. return them as non-inherited.
836
+ return !SDK.CSSMetadata.cssMetadata().isPropertyInherited(propertyName);
837
+ }
838
+ return false;
839
+ }
840
+
841
+ nextEditableSibling(): StylePropertiesSection|null {
842
+ let curSection: (StylePropertiesSection|undefined)|(StylePropertiesSection | null)|this = this;
843
+ do {
844
+ curSection = curSection.nextSibling();
845
+ } while (curSection && !curSection.editable);
846
+
847
+ if (!curSection) {
848
+ curSection = this.firstSibling();
849
+ while (curSection && !curSection.editable) {
850
+ curSection = curSection.nextSibling();
851
+ }
852
+ }
853
+
854
+ return (curSection && curSection.editable) ? curSection : null;
855
+ }
856
+
857
+ previousEditableSibling(): StylePropertiesSection|null {
858
+ let curSection: (StylePropertiesSection|undefined)|(StylePropertiesSection | null)|this = this;
859
+ do {
860
+ curSection = curSection.previousSibling();
861
+ } while (curSection && !curSection.editable);
862
+
863
+ if (!curSection) {
864
+ curSection = this.lastSibling();
865
+ while (curSection && !curSection.editable) {
866
+ curSection = curSection.previousSibling();
867
+ }
868
+ }
869
+
870
+ return (curSection && curSection.editable) ? curSection : null;
871
+ }
872
+
873
+ refreshUpdate(editedTreeElement: StylePropertyTreeElement): void {
874
+ this.parentPane.refreshUpdate(this, editedTreeElement);
875
+ }
876
+
877
+ updateVarFunctions(editedTreeElement: StylePropertyTreeElement): void {
878
+ let child = this.propertiesTreeOutline.firstChild();
879
+ while (child) {
880
+ if (child !== editedTreeElement && child instanceof StylePropertyTreeElement) {
881
+ child.updateTitleIfComputedValueChanged();
882
+ }
883
+ child = child.traverseNextTreeElement(false /* skipUnrevealed */, null /* stayWithin */, true /* dontPopulate */);
884
+ }
885
+ }
886
+
887
+ update(full: boolean): void {
888
+ this.selectorElement.textContent = this.headerText();
889
+ this.markSelectorMatches();
890
+ if (full) {
891
+ this.onpopulate();
892
+ } else {
893
+ let child = this.propertiesTreeOutline.firstChild();
894
+ while (child && child instanceof StylePropertyTreeElement) {
895
+ child.setOverloaded(this.isPropertyOverloaded(child.property));
896
+ child =
897
+ child.traverseNextTreeElement(false /* skipUnrevealed */, null /* stayWithin */, true /* dontPopulate */);
898
+ }
899
+ }
900
+ }
901
+
902
+ showAllItems(event?: Event): void {
903
+ if (event) {
904
+ event.consume();
905
+ }
906
+ if (this.forceShowAll) {
907
+ return;
908
+ }
909
+ this.forceShowAll = true;
910
+ this.onpopulate();
911
+ }
912
+
913
+ onpopulate(): void {
914
+ this.parentPane.setActiveProperty(null);
915
+ this.nextEditorTriggerButtonIdx = 1;
916
+ this.propertiesTreeOutline.removeChildren();
917
+ const style = this.styleInternal;
918
+ let count = 0;
919
+ const properties = style.leadingProperties();
920
+ const maxProperties = StylePropertiesSection.MaxProperties + properties.length - this.originalPropertiesCount;
921
+
922
+ for (const property of properties) {
923
+ if (!this.forceShowAll && count >= maxProperties) {
924
+ break;
925
+ }
926
+ count++;
927
+ const isShorthand = Boolean(style.longhandProperties(property.name).length);
928
+ const inherited = this.isPropertyInherited(property.name);
929
+ const overloaded = this.isPropertyOverloaded(property);
930
+ if (style.parentRule && style.parentRule.isUserAgent() && inherited) {
931
+ continue;
932
+ }
933
+ const item = new StylePropertyTreeElement(
934
+ this.parentPane, this.matchedStyles, property, isShorthand, inherited, overloaded, false);
935
+ this.propertiesTreeOutline.appendChild(item);
936
+ }
937
+
938
+ if (count < properties.length) {
939
+ this.showAllButton.classList.remove('hidden');
940
+ this.showAllButton.textContent = i18nString(UIStrings.showAllPropertiesSMore, {PH1: properties.length - count});
941
+ } else {
942
+ this.showAllButton.classList.add('hidden');
943
+ }
944
+ }
945
+
946
+ isPropertyOverloaded(property: SDK.CSSProperty.CSSProperty): boolean {
947
+ return this.matchedStyles.propertyState(property) === SDK.CSSMatchedStyles.PropertyState.Overloaded;
948
+ }
949
+
950
+ updateFilter(): boolean {
951
+ let hasMatchingChild = false;
952
+ this.showAllItems();
953
+ for (const child of this.propertiesTreeOutline.rootElement().children()) {
954
+ if (child instanceof StylePropertyTreeElement) {
955
+ const childHasMatches = child.updateFilter();
956
+ hasMatchingChild = hasMatchingChild || childHasMatches;
957
+ }
958
+ }
959
+
960
+ const regex = this.parentPane.filterRegex();
961
+ const hideRule = !hasMatchingChild && regex !== null && !regex.test(this.element.deepTextContent());
962
+ this.isHiddenInternal = hideRule;
963
+ this.element.classList.toggle('hidden', hideRule);
964
+ if (!hideRule && this.styleInternal.parentRule) {
965
+ this.markSelectorHighlights();
966
+ }
967
+ return !hideRule;
968
+ }
969
+
970
+ isHidden(): boolean {
971
+ return this.isHiddenInternal;
972
+ }
973
+
974
+ markSelectorMatches(): void {
975
+ const rule = this.styleInternal.parentRule;
976
+ if (!rule || !(rule instanceof SDK.CSSRule.CSSStyleRule)) {
977
+ return;
978
+ }
979
+
980
+ this.queryListElement.classList.toggle('query-matches', this.matchedStyles.queryMatches(this.styleInternal));
981
+
982
+ const selectorTexts = rule.selectors.map(selector => selector.text);
983
+ const matchingSelectorIndexes = this.matchedStyles.getMatchingSelectors(rule);
984
+ const matchingSelectors = (new Array(selectorTexts.length).fill(false) as boolean[]);
985
+ for (const matchingIndex of matchingSelectorIndexes) {
986
+ matchingSelectors[matchingIndex] = true;
987
+ }
988
+
989
+ if (this.parentPane.isEditingStyle) {
990
+ return;
991
+ }
992
+
993
+ const fragment = this.hoverableSelectorsMode ? this.renderHoverableSelectors(selectorTexts, matchingSelectors) :
994
+ this.renderSimplifiedSelectors(selectorTexts, matchingSelectors);
995
+ this.selectorElement.removeChildren();
996
+ this.selectorElement.appendChild(fragment);
997
+ this.markSelectorHighlights();
998
+ }
999
+
1000
+ private renderHoverableSelectors(selectors: string[], matchingSelectors: boolean[]): DocumentFragment {
1001
+ const fragment = document.createDocumentFragment();
1002
+ for (let i = 0; i < selectors.length; ++i) {
1003
+ if (i) {
1004
+ UI.UIUtils.createTextChild(fragment, ', ');
1005
+ }
1006
+ fragment.appendChild(this.createSelectorElement(selectors[i], matchingSelectors[i], i));
1007
+ }
1008
+ return fragment;
1009
+ }
1010
+
1011
+ private createSelectorElement(text: string, isMatching: boolean, navigationIndex?: number): Element {
1012
+ const element = document.createElement('span');
1013
+ element.classList.add('simple-selector');
1014
+ element.classList.toggle('selector-matches', isMatching);
1015
+ if (typeof navigationIndex === 'number') {
1016
+ this.elementToSelectorIndex.set(element, navigationIndex);
1017
+ }
1018
+ element.textContent = text;
1019
+ return element;
1020
+ }
1021
+
1022
+ private renderSimplifiedSelectors(selectors: string[], matchingSelectors: boolean[]): DocumentFragment {
1023
+ const fragment = document.createDocumentFragment();
1024
+ let currentMatching = false;
1025
+ let text = '';
1026
+ for (let i = 0; i < selectors.length; ++i) {
1027
+ if (currentMatching !== matchingSelectors[i] && text) {
1028
+ fragment.appendChild(this.createSelectorElement(text, currentMatching));
1029
+ text = '';
1030
+ }
1031
+ currentMatching = matchingSelectors[i];
1032
+ text += selectors[i] + (i === selectors.length - 1 ? '' : ', ');
1033
+ }
1034
+ if (text) {
1035
+ fragment.appendChild(this.createSelectorElement(text, currentMatching));
1036
+ }
1037
+ return fragment;
1038
+ }
1039
+
1040
+ markSelectorHighlights(): void {
1041
+ const selectors = this.selectorElement.getElementsByClassName('simple-selector');
1042
+ const regex = this.parentPane.filterRegex();
1043
+ for (let i = 0; i < selectors.length; ++i) {
1044
+ const selectorMatchesFilter = regex !== null && regex.test(selectors[i].textContent || '');
1045
+ selectors[i].classList.toggle('filter-match', selectorMatchesFilter);
1046
+ }
1047
+ }
1048
+
1049
+ private checkWillCancelEditing(): boolean {
1050
+ const willCauseCancelEditing = this.willCauseCancelEditing;
1051
+ this.willCauseCancelEditing = false;
1052
+ return willCauseCancelEditing;
1053
+ }
1054
+
1055
+ private handleSelectorContainerClick(event: Event): void {
1056
+ if (this.checkWillCancelEditing() || !this.editable) {
1057
+ return;
1058
+ }
1059
+ if (event.target === this.selectorContainer) {
1060
+ this.addNewBlankProperty(0).startEditing();
1061
+ event.consume(true);
1062
+ }
1063
+ }
1064
+
1065
+ addNewBlankProperty(index: number|undefined = this.propertiesTreeOutline.rootElement().childCount()):
1066
+ StylePropertyTreeElement {
1067
+ const property = this.styleInternal.newBlankProperty(index);
1068
+ const item = new StylePropertyTreeElement(this.parentPane, this.matchedStyles, property, false, false, false, true);
1069
+ this.propertiesTreeOutline.insertChild(item, property.index);
1070
+ return item;
1071
+ }
1072
+
1073
+ private handleEmptySpaceMouseDown(): void {
1074
+ this.willCauseCancelEditing = this.parentPane.isEditingStyle;
1075
+ this.selectedSinceMouseDown = false;
1076
+ }
1077
+
1078
+ private handleEmptySpaceClick(event: Event): void {
1079
+ if (!this.editable || this.element.hasSelection() || this.checkWillCancelEditing() || this.selectedSinceMouseDown) {
1080
+ return;
1081
+ }
1082
+
1083
+ const target = (event.target as Element);
1084
+
1085
+ if (target.classList.contains('header') || this.element.classList.contains('read-only') ||
1086
+ target.enclosingNodeOrSelfWithClass('query')) {
1087
+ event.consume();
1088
+ return;
1089
+ }
1090
+ const deepTarget = UI.UIUtils.deepElementFromEvent(event);
1091
+ const treeElement = deepTarget && UI.TreeOutline.TreeElement.getTreeElementBylistItemNode(deepTarget);
1092
+ if (treeElement && treeElement instanceof StylePropertyTreeElement) {
1093
+ this.addNewBlankProperty(treeElement.property.index + 1).startEditing();
1094
+ } else {
1095
+ this.addNewBlankProperty().startEditing();
1096
+ }
1097
+ event.consume(true);
1098
+ }
1099
+
1100
+ private handleQueryRuleClick(query: SDK.CSSQuery.CSSQuery, event: Event): void {
1101
+ const element = event.currentTarget as Element;
1102
+ if (UI.UIUtils.isBeingEdited(element)) {
1103
+ return;
1104
+ }
1105
+
1106
+ if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event as MouseEvent) && this.navigable) {
1107
+ const location = query.rawLocation();
1108
+ if (!location) {
1109
+ event.consume(true);
1110
+ return;
1111
+ }
1112
+ const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().rawLocationToUILocation(location);
1113
+ if (uiLocation) {
1114
+ void Common.Revealer.reveal(uiLocation);
1115
+ }
1116
+ event.consume(true);
1117
+ return;
1118
+ }
1119
+
1120
+ if (!this.editable) {
1121
+ return;
1122
+ }
1123
+
1124
+ const config = new UI.InplaceEditor.Config(
1125
+ this.editingMediaCommitted.bind(this, query), this.editingMediaCancelled.bind(this, element), undefined,
1126
+ this.editingMediaBlurHandler.bind(this));
1127
+ UI.InplaceEditor.InplaceEditor.startEditing(element, config);
1128
+
1129
+ const selection = element.getComponentSelection();
1130
+ if (selection) {
1131
+ selection.selectAllChildren(element);
1132
+ }
1133
+ this.parentPane.setEditingStyle(true);
1134
+ const parentMediaElement = element.enclosingNodeOrSelfWithClass('query');
1135
+ parentMediaElement.classList.add('editing-query');
1136
+
1137
+ event.consume(true);
1138
+ }
1139
+
1140
+ private editingMediaFinished(element: Element): void {
1141
+ this.parentPane.setEditingStyle(false);
1142
+ const parentMediaElement = element.enclosingNodeOrSelfWithClass('query');
1143
+ parentMediaElement.classList.remove('editing-query');
1144
+ }
1145
+
1146
+ private editingMediaCancelled(element: Element): void {
1147
+ this.editingMediaFinished(element);
1148
+ // Mark the selectors in group if necessary.
1149
+ // This is overridden by BlankStylePropertiesSection.
1150
+ this.markSelectorMatches();
1151
+ const selection = element.getComponentSelection();
1152
+ if (selection) {
1153
+ selection.collapse(element, 0);
1154
+ }
1155
+ }
1156
+
1157
+ private editingMediaBlurHandler(): boolean {
1158
+ return true;
1159
+ }
1160
+
1161
+ private async editingMediaCommitted(
1162
+ query: SDK.CSSQuery.CSSQuery, element: Element, newContent: string, _oldContent: string,
1163
+ _context: Context|undefined, _moveDirection: string): Promise<void> {
1164
+ this.parentPane.setEditingStyle(false);
1165
+ this.editingMediaFinished(element);
1166
+
1167
+ if (newContent) {
1168
+ newContent = newContent.trim();
1169
+ }
1170
+
1171
+ // This gets deleted in finishOperation(), which is called both on success and failure.
1172
+ this.parentPane.setUserOperation(true);
1173
+ const cssModel = this.parentPane.cssModel();
1174
+ if (cssModel && query.styleSheetId) {
1175
+ const range = query.range as TextUtils.TextRange.TextRange;
1176
+ let success = false;
1177
+ if (query instanceof SDK.CSSContainerQuery.CSSContainerQuery) {
1178
+ success = await cssModel.setContainerQueryText(query.styleSheetId, range, newContent);
1179
+ } else if (query instanceof SDK.CSSSupports.CSSSupports) {
1180
+ success = await cssModel.setSupportsText(query.styleSheetId, range, newContent);
1181
+ } else {
1182
+ success = await cssModel.setMediaText(query.styleSheetId, range, newContent);
1183
+ }
1184
+
1185
+ if (success) {
1186
+ this.matchedStyles.resetActiveProperties();
1187
+ this.parentPane.refreshUpdate(this);
1188
+ }
1189
+ this.parentPane.setUserOperation(false);
1190
+ this.editingMediaTextCommittedForTest();
1191
+ }
1192
+ }
1193
+
1194
+ private editingMediaTextCommittedForTest(): void {
1195
+ }
1196
+
1197
+ private handleSelectorClick(event: Event): void {
1198
+ const target = (event.target as Element | null);
1199
+ if (!target) {
1200
+ return;
1201
+ }
1202
+ if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey((event as MouseEvent)) && this.navigable &&
1203
+ target.classList.contains('simple-selector')) {
1204
+ const selectorIndex = this.elementToSelectorIndex.get(target);
1205
+ if (selectorIndex) {
1206
+ this.navigateToSelectorSource(selectorIndex, true);
1207
+ }
1208
+ event.consume(true);
1209
+ return;
1210
+ }
1211
+ if (this.element.hasSelection()) {
1212
+ return;
1213
+ }
1214
+ this.startEditingAtFirstPosition();
1215
+ event.consume(true);
1216
+ }
1217
+
1218
+ private handleContextMenuEvent(event: Event): void {
1219
+ const target = (event.target as Element | null);
1220
+ if (!target) {
1221
+ return;
1222
+ }
1223
+
1224
+ const contextMenu = new UI.ContextMenu.ContextMenu(event);
1225
+ contextMenu.clipboardSection().appendItem(i18nString(UIStrings.copySelector), () => {
1226
+ const selectorText = this.headerText();
1227
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(selectorText);
1228
+ Host.userMetrics.styleTextCopied(Host.UserMetrics.StyleTextCopied.SelectorViaContextMenu);
1229
+ });
1230
+
1231
+ contextMenu.clipboardSection().appendItem(i18nString(UIStrings.copyRule), () => {
1232
+ const ruleText = StylesSidebarPane.formatLeadingProperties(this).ruleText;
1233
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(ruleText);
1234
+ Host.userMetrics.styleTextCopied(Host.UserMetrics.StyleTextCopied.RuleViaContextMenu);
1235
+ });
1236
+
1237
+ contextMenu.clipboardSection().appendItem(i18nString(UIStrings.copyAllDeclarations), () => {
1238
+ const allDeclarationText = StylesSidebarPane.formatLeadingProperties(this).allDeclarationText;
1239
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(allDeclarationText);
1240
+ Host.userMetrics.styleTextCopied(Host.UserMetrics.StyleTextCopied.AllDeclarationsViaContextMenu);
1241
+ });
1242
+
1243
+ // TODO(changhaohan): conditionally add this item only when there are changes to copy
1244
+ contextMenu.clipboardSection().appendItem(i18nString(UIStrings.copyAllCSSChanges), async () => {
1245
+ const allChanges = await this.parentPane.getFormattedChanges();
1246
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(allChanges);
1247
+ Host.userMetrics.styleTextCopied(Host.UserMetrics.StyleTextCopied.AllChangesViaStylesPane);
1248
+ });
1249
+ void contextMenu.show();
1250
+ }
1251
+
1252
+ private navigateToSelectorSource(index: number, focus: boolean): void {
1253
+ const cssModel = this.parentPane.cssModel();
1254
+ if (!cssModel) {
1255
+ return;
1256
+ }
1257
+ const rule = (this.styleInternal.parentRule as SDK.CSSRule.CSSStyleRule | null);
1258
+ if (!rule || rule.styleSheetId === undefined) {
1259
+ return;
1260
+ }
1261
+ const header = cssModel.styleSheetHeaderForId(rule.styleSheetId);
1262
+ if (!header) {
1263
+ return;
1264
+ }
1265
+ const rawLocation =
1266
+ new SDK.CSSModel.CSSLocation(header, rule.lineNumberInSource(index), rule.columnNumberInSource(index));
1267
+ StylePropertiesSection.revealSelectorSource(rawLocation, focus);
1268
+ }
1269
+
1270
+ private static revealSelectorSource(rawLocation: SDK.CSSModel.CSSLocation, focus: boolean): void {
1271
+ const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().rawLocationToUILocation(rawLocation);
1272
+ if (uiLocation) {
1273
+ void Common.Revealer.reveal(uiLocation, !focus);
1274
+ }
1275
+ }
1276
+
1277
+ private startEditingAtFirstPosition(): void {
1278
+ if (!this.editable) {
1279
+ return;
1280
+ }
1281
+
1282
+ if (!this.styleInternal.parentRule) {
1283
+ this.moveEditorFromSelector('forward');
1284
+ return;
1285
+ }
1286
+
1287
+ this.startEditingSelector();
1288
+ }
1289
+
1290
+ startEditingSelector(): void {
1291
+ const element = this.selectorElement;
1292
+ if (UI.UIUtils.isBeingEdited(element)) {
1293
+ return;
1294
+ }
1295
+
1296
+ element.scrollIntoViewIfNeeded(false);
1297
+ // Reset selector marks in group, and normalize whitespace.
1298
+ const textContent = element.textContent;
1299
+ if (textContent !== null) {
1300
+ element.textContent = textContent.replace(/\s+/g, ' ').trim();
1301
+ }
1302
+
1303
+ const config =
1304
+ new UI.InplaceEditor.Config(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this));
1305
+ UI.InplaceEditor.InplaceEditor.startEditing(this.selectorElement, config);
1306
+
1307
+ const selection = element.getComponentSelection();
1308
+ if (selection) {
1309
+ selection.selectAllChildren(element);
1310
+ }
1311
+ this.parentPane.setEditingStyle(true);
1312
+ if (element.classList.contains('simple-selector')) {
1313
+ this.navigateToSelectorSource(0, false);
1314
+ }
1315
+ }
1316
+
1317
+ moveEditorFromSelector(moveDirection: string): void {
1318
+ this.markSelectorMatches();
1319
+
1320
+ if (!moveDirection) {
1321
+ return;
1322
+ }
1323
+
1324
+ if (moveDirection === 'forward') {
1325
+ const firstChild = (this.propertiesTreeOutline.firstChild() as StylePropertyTreeElement);
1326
+ let currentChild: (StylePropertyTreeElement|null)|StylePropertyTreeElement = firstChild;
1327
+ while (currentChild && currentChild.inherited()) {
1328
+ const sibling: UI.TreeOutline.TreeElement|null = currentChild.nextSibling;
1329
+ currentChild = sibling instanceof StylePropertyTreeElement ? sibling : null;
1330
+ }
1331
+ if (!currentChild) {
1332
+ this.addNewBlankProperty().startEditing();
1333
+ } else {
1334
+ currentChild.startEditing(currentChild.nameElement);
1335
+ }
1336
+ } else {
1337
+ const previousSection = this.previousEditableSibling();
1338
+ if (!previousSection) {
1339
+ return;
1340
+ }
1341
+
1342
+ previousSection.addNewBlankProperty().startEditing();
1343
+ }
1344
+ }
1345
+
1346
+ editingSelectorCommitted(
1347
+ element: Element, newContent: string, oldContent: string, context: Context|undefined,
1348
+ moveDirection: string): void {
1349
+ this.editingSelectorEnded();
1350
+ if (newContent) {
1351
+ newContent = newContent.trim();
1352
+ }
1353
+ if (newContent === oldContent) {
1354
+ // Revert to a trimmed version of the selector if need be.
1355
+ this.selectorElement.textContent = newContent;
1356
+ this.moveEditorFromSelector(moveDirection);
1357
+ return;
1358
+ }
1359
+ const rule = this.styleInternal.parentRule;
1360
+ if (!rule) {
1361
+ return;
1362
+ }
1363
+
1364
+ function headerTextCommitted(this: StylePropertiesSection): void {
1365
+ this.parentPane.setUserOperation(false);
1366
+ this.moveEditorFromSelector(moveDirection);
1367
+ this.editingSelectorCommittedForTest();
1368
+ }
1369
+
1370
+ // This gets deleted in finishOperationAndMoveEditor(), which is called both on success and failure.
1371
+ this.parentPane.setUserOperation(true);
1372
+ void this.setHeaderText(rule, newContent).then(headerTextCommitted.bind(this));
1373
+ }
1374
+
1375
+ setHeaderText(rule: SDK.CSSRule.CSSRule, newContent: string): Promise<void> {
1376
+ function onSelectorsUpdated(
1377
+ this: StylePropertiesSection, rule: SDK.CSSRule.CSSStyleRule, success: boolean): Promise<void> {
1378
+ if (!success) {
1379
+ return Promise.resolve();
1380
+ }
1381
+ return this.matchedStyles.recomputeMatchingSelectors(rule).then(updateSourceRanges.bind(this, rule));
1382
+ }
1383
+
1384
+ function updateSourceRanges(this: StylePropertiesSection, rule: SDK.CSSRule.CSSStyleRule): void {
1385
+ const doesAffectSelectedNode = this.matchedStyles.getMatchingSelectors(rule).length > 0;
1386
+ this.propertiesTreeOutline.element.classList.toggle('no-affect', !doesAffectSelectedNode);
1387
+ this.matchedStyles.resetActiveProperties();
1388
+ this.parentPane.refreshUpdate(this);
1389
+ }
1390
+
1391
+ if (!(rule instanceof SDK.CSSRule.CSSStyleRule)) {
1392
+ return Promise.resolve();
1393
+ }
1394
+ const oldSelectorRange = rule.selectorRange();
1395
+ if (!oldSelectorRange) {
1396
+ return Promise.resolve();
1397
+ }
1398
+ return rule.setSelectorText(newContent).then(onSelectorsUpdated.bind(this, rule, Boolean(oldSelectorRange)));
1399
+ }
1400
+
1401
+ protected editingSelectorCommittedForTest(): void {
1402
+ }
1403
+
1404
+ protected updateRuleOrigin(): void {
1405
+ this.selectorRefElement.removeChildren();
1406
+ this.selectorRefElement.appendChild(StylePropertiesSection.createRuleOriginNode(
1407
+ this.matchedStyles, this.parentPane.linkifier, this.styleInternal.parentRule));
1408
+ }
1409
+
1410
+ protected editingSelectorEnded(): void {
1411
+ this.parentPane.setEditingStyle(false);
1412
+ }
1413
+
1414
+ editingSelectorCancelled(): void {
1415
+ this.editingSelectorEnded();
1416
+
1417
+ // Mark the selectors in group if necessary.
1418
+ // This is overridden by BlankStylePropertiesSection.
1419
+ this.markSelectorMatches();
1420
+ }
1421
+
1422
+ /**
1423
+ * A property at or near an index and suitable for subsequent editing.
1424
+ * Either the last property, if index out-of-upper-bound,
1425
+ * or property at index, if such a property exists,
1426
+ * or otherwise, null.
1427
+ */
1428
+ closestPropertyForEditing(propertyIndex: number): UI.TreeOutline.TreeElement|null {
1429
+ const rootElement = this.propertiesTreeOutline.rootElement();
1430
+ if (propertyIndex >= rootElement.childCount()) {
1431
+ return rootElement.lastChild();
1432
+ }
1433
+ return rootElement.childAt(propertyIndex);
1434
+ }
1435
+
1436
+ // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
1437
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1438
+ static MaxProperties = 50;
1439
+ }
1440
+
1441
+ export class BlankStylePropertiesSection extends StylePropertiesSection {
1442
+ private normal: boolean;
1443
+ private readonly ruleLocation: TextUtils.TextRange.TextRange;
1444
+ private readonly styleSheetId: Protocol.CSS.StyleSheetId;
1445
+
1446
+ constructor(
1447
+ stylesPane: StylesSidebarPane, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, defaultSelectorText: string,
1448
+ styleSheetId: Protocol.CSS.StyleSheetId, ruleLocation: TextUtils.TextRange.TextRange,
1449
+ insertAfterStyle: SDK.CSSStyleDeclaration.CSSStyleDeclaration, sectionIdx: number) {
1450
+ const cssModel = (stylesPane.cssModel() as SDK.CSSModel.CSSModel);
1451
+ const rule = SDK.CSSRule.CSSStyleRule.createDummyRule(cssModel, defaultSelectorText);
1452
+ super(stylesPane, matchedStyles, rule.style, sectionIdx);
1453
+ this.normal = false;
1454
+ this.ruleLocation = ruleLocation;
1455
+ this.styleSheetId = styleSheetId;
1456
+ this.selectorRefElement.removeChildren();
1457
+ this.selectorRefElement.appendChild(StylePropertiesSection.linkifyRuleLocation(
1458
+ cssModel, this.parentPane.linkifier, styleSheetId, this.actualRuleLocation()));
1459
+ if (insertAfterStyle && insertAfterStyle.parentRule &&
1460
+ insertAfterStyle.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
1461
+ this.createAtRuleLists(insertAfterStyle.parentRule);
1462
+ }
1463
+ this.element.classList.add('blank-section');
1464
+ }
1465
+
1466
+ private actualRuleLocation(): TextUtils.TextRange.TextRange {
1467
+ const prefix = this.rulePrefix();
1468
+ const lines = prefix.split('\n');
1469
+ const lastLine = lines[lines.length - 1];
1470
+ const editRange = new TextUtils.TextRange.TextRange(0, 0, lines.length - 1, lastLine ? lastLine.length : 0);
1471
+ return this.ruleLocation.rebaseAfterTextEdit(TextUtils.TextRange.TextRange.createFromLocation(0, 0), editRange);
1472
+ }
1473
+
1474
+ private rulePrefix(): string {
1475
+ return this.ruleLocation.startLine === 0 && this.ruleLocation.startColumn === 0 ? '' : '\n\n';
1476
+ }
1477
+
1478
+ get isBlank(): boolean {
1479
+ return !this.normal;
1480
+ }
1481
+
1482
+ editingSelectorCommitted(
1483
+ element: Element, newContent: string, oldContent: string, context: Context|undefined,
1484
+ moveDirection: string): void {
1485
+ if (!this.isBlank) {
1486
+ super.editingSelectorCommitted(element, newContent, oldContent, context, moveDirection);
1487
+ return;
1488
+ }
1489
+
1490
+ function onRuleAdded(this: BlankStylePropertiesSection, newRule: SDK.CSSRule.CSSStyleRule|null): Promise<void> {
1491
+ if (!newRule) {
1492
+ this.editingSelectorCancelled();
1493
+ this.editingSelectorCommittedForTest();
1494
+ return Promise.resolve();
1495
+ }
1496
+ return this.matchedStyles.addNewRule(newRule, this.matchedStyles.node())
1497
+ .then(onAddedToCascade.bind(this, newRule));
1498
+ }
1499
+
1500
+ function onAddedToCascade(this: BlankStylePropertiesSection, newRule: SDK.CSSRule.CSSStyleRule): void {
1501
+ const doesSelectorAffectSelectedNode = this.matchedStyles.getMatchingSelectors(newRule).length > 0;
1502
+ this.makeNormal(newRule);
1503
+
1504
+ if (!doesSelectorAffectSelectedNode) {
1505
+ this.propertiesTreeOutline.element.classList.add('no-affect');
1506
+ }
1507
+
1508
+ this.updateRuleOrigin();
1509
+
1510
+ this.parentPane.setUserOperation(false);
1511
+ this.editingSelectorEnded();
1512
+ if (this.element.parentElement) // Might have been detached already.
1513
+ {
1514
+ this.moveEditorFromSelector(moveDirection);
1515
+ }
1516
+ this.markSelectorMatches();
1517
+
1518
+ this.editingSelectorCommittedForTest();
1519
+ }
1520
+
1521
+ if (newContent) {
1522
+ newContent = newContent.trim();
1523
+ }
1524
+ this.parentPane.setUserOperation(true);
1525
+
1526
+ const cssModel = this.parentPane.cssModel();
1527
+ const ruleText = this.rulePrefix() + newContent + ' {}';
1528
+ if (cssModel) {
1529
+ void cssModel.addRule(this.styleSheetId, ruleText, this.ruleLocation).then(onRuleAdded.bind(this));
1530
+ }
1531
+ }
1532
+
1533
+ editingSelectorCancelled(): void {
1534
+ this.parentPane.setUserOperation(false);
1535
+ if (!this.isBlank) {
1536
+ super.editingSelectorCancelled();
1537
+ return;
1538
+ }
1539
+
1540
+ this.editingSelectorEnded();
1541
+ this.parentPane.removeSection(this);
1542
+ }
1543
+
1544
+ private makeNormal(newRule: SDK.CSSRule.CSSRule): void {
1545
+ this.element.classList.remove('blank-section');
1546
+ this.styleInternal = newRule.style;
1547
+ // FIXME: replace this instance by a normal StylePropertiesSection.
1548
+ this.normal = true;
1549
+ }
1550
+ }
1551
+
1552
+ export class KeyframePropertiesSection extends StylePropertiesSection {
1553
+ constructor(
1554
+ stylesPane: StylesSidebarPane, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
1555
+ style: SDK.CSSStyleDeclaration.CSSStyleDeclaration, sectionIdx: number) {
1556
+ super(stylesPane, matchedStyles, style, sectionIdx);
1557
+ this.selectorElement.className = 'keyframe-key';
1558
+ }
1559
+
1560
+ headerText(): string {
1561
+ if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSKeyframeRule) {
1562
+ return this.styleInternal.parentRule.key().text;
1563
+ }
1564
+ return '';
1565
+ }
1566
+
1567
+ setHeaderText(rule: SDK.CSSRule.CSSRule, newContent: string): Promise<void> {
1568
+ function updateSourceRanges(this: KeyframePropertiesSection, success: boolean): void {
1569
+ if (!success) {
1570
+ return;
1571
+ }
1572
+ this.parentPane.refreshUpdate(this);
1573
+ }
1574
+
1575
+ if (!(rule instanceof SDK.CSSRule.CSSKeyframeRule)) {
1576
+ return Promise.resolve();
1577
+ }
1578
+ const oldRange = rule.key().range;
1579
+ if (!oldRange) {
1580
+ return Promise.resolve();
1581
+ }
1582
+ return rule.setKeyText(newContent).then(updateSourceRanges.bind(this));
1583
+ }
1584
+
1585
+ isPropertyInherited(_propertyName: string): boolean {
1586
+ return false;
1587
+ }
1588
+
1589
+ isPropertyOverloaded(_property: SDK.CSSProperty.CSSProperty): boolean {
1590
+ return false;
1591
+ }
1592
+
1593
+ markSelectorHighlights(): void {
1594
+ }
1595
+
1596
+ markSelectorMatches(): void {
1597
+ if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSKeyframeRule) {
1598
+ this.selectorElement.textContent = this.styleInternal.parentRule.key().text;
1599
+ }
1600
+ }
1601
+
1602
+ highlight(): void {
1603
+ }
1604
+ }
1605
+
1606
+ export class HighlightPseudoStylePropertiesSection extends StylePropertiesSection {
1607
+ isPropertyInherited(_propertyName: string): boolean {
1608
+ // For highlight pseudos, all valid properties are treated as inherited.
1609
+ // Note that the meaning is reversed in this context; the result of
1610
+ // returning false here is that properties of inherited pseudos will never
1611
+ // be shown in the darker style of non-inherited properties.
1612
+ return false;
1613
+ }
1614
+ }