ElementsPanel.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. export default class ElementsPanel extends UI.Panel{constructor(){super('elements');this.registerRequiredCSS('elements/elementsPanel.css');this._splitWidget=new UI.SplitWidget(true,true,'elementsPanelSplitViewState',325,325);this._splitWidget.addEventListener(UI.SplitWidget.Events.SidebarSizeChanged,this._updateTreeOutlineVisibleWidth.bind(this));this._splitWidget.show(this.element);this._searchableView=new UI.SearchableView(this);this._searchableView.setMinimumSize(25,28);this._searchableView.setPlaceholder(Common.UIString('Find by string, selector, or XPath'));const stackElement=this._searchableView.element;this._contentElement=createElement('div');const crumbsContainer=createElement('div');stackElement.appendChild(this._contentElement);stackElement.appendChild(crumbsContainer);this._splitWidget.setMainWidget(this._searchableView);this._splitMode=null;this._contentElement.id='elements-content';if(Common.moduleSetting('domWordWrap').get()){this._contentElement.classList.add('elements-wrap');}
  2. Common.moduleSetting('domWordWrap').addChangeListener(this._domWordWrapSettingChanged.bind(this));crumbsContainer.id='elements-crumbs';this._breadcrumbs=new Elements.ElementsBreadcrumbs();this._breadcrumbs.show(crumbsContainer);this._breadcrumbs.addEventListener(Elements.ElementsBreadcrumbs.Events.NodeSelected,this._crumbNodeSelected,this);this._stylesWidget=new Elements.StylesSidebarPane();this._computedStyleWidget=new Elements.ComputedStyleWidget();this._metricsWidget=new Elements.MetricsSidebarPane();Common.moduleSetting('sidebarPosition').addChangeListener(this._updateSidebarPosition.bind(this));this._updateSidebarPosition();this._treeOutlines=[];this._treeOutlineHeaders=new Map();SDK.targetManager.observeModels(SDK.DOMModel,this);SDK.targetManager.addEventListener(SDK.TargetManager.Events.NameChanged,event=>this._targetNameChanged((event.data)));Common.moduleSetting('showUAShadowDOM').addChangeListener(this._showUAShadowDOMChanged.bind(this));SDK.targetManager.addModelListener(SDK.DOMModel,SDK.DOMModel.Events.DocumentUpdated,this._documentUpdatedEvent,this);Extensions.extensionServer.addEventListener(Extensions.ExtensionServer.Events.SidebarPaneAdded,this._extensionSidebarPaneAdded,this);this._searchResults;}
  3. static instance(){return(self.runtime.sharedInstance(ElementsPanel));}
  4. _revealProperty(cssProperty){return this.sidebarPaneView.showView(this._stylesViewToReveal).then(()=>{this._stylesWidget.revealProperty((cssProperty));});}
  5. resolveLocation(locationName){return this.sidebarPaneView;}
  6. showToolbarPane(widget,toggle){this._stylesWidget.showToolbarPane(widget,toggle);}
  7. modelAdded(domModel){const parentModel=domModel.parentModel();let treeOutline=parentModel?Elements.ElementsTreeOutline.forDOMModel(parentModel):null;if(!treeOutline){treeOutline=new Elements.ElementsTreeOutline(true,true);treeOutline.setWordWrap(Common.moduleSetting('domWordWrap').get());treeOutline.addEventListener(Elements.ElementsTreeOutline.Events.SelectedNodeChanged,this._selectedNodeChanged,this);treeOutline.addEventListener(Elements.ElementsTreeOutline.Events.ElementsTreeUpdated,this._updateBreadcrumbIfNeeded,this);new Elements.ElementsTreeElementHighlighter(treeOutline);this._treeOutlines.push(treeOutline);if(domModel.target().parentTarget()){this._treeOutlineHeaders.set(treeOutline,createElementWithClass('div','elements-tree-header'));this._targetNameChanged(domModel.target());}}
  8. treeOutline.wireToDOMModel(domModel);if(this.isShowing()){this.wasShown();}}
  9. modelRemoved(domModel){const treeOutline=Elements.ElementsTreeOutline.forDOMModel(domModel);treeOutline.unwireFromDOMModel(domModel);if(domModel.parentModel()){return;}
  10. this._treeOutlines.remove(treeOutline);const header=this._treeOutlineHeaders.get(treeOutline);if(header){header.remove();}
  11. this._treeOutlineHeaders.delete(treeOutline);treeOutline.element.remove();}
  12. _targetNameChanged(target){const domModel=target.model(SDK.DOMModel);if(!domModel){return;}
  13. const treeOutline=Elements.ElementsTreeOutline.forDOMModel(domModel);if(!treeOutline){return;}
  14. const header=this._treeOutlineHeaders.get(treeOutline);if(!header){return;}
  15. header.removeChildren();header.createChild('div','elements-tree-header-frame').textContent=Common.UIString('Frame');header.appendChild(Components.Linkifier.linkifyURL(target.inspectedURL(),{text:target.name()}));}
  16. _updateTreeOutlineVisibleWidth(){if(!this._treeOutlines.length){return;}
  17. let width=this._splitWidget.element.offsetWidth;if(this._splitWidget.isVertical()){width-=this._splitWidget.sidebarSize();}
  18. for(let i=0;i<this._treeOutlines.length;++i){this._treeOutlines[i].setVisibleWidth(width);}
  19. this._breadcrumbs.updateSizes();}
  20. focus(){if(this._treeOutlines.length){this._treeOutlines[0].focus();}}
  21. searchableView(){return this._searchableView;}
  22. wasShown(){UI.context.setFlavor(ElementsPanel,this);for(let i=0;i<this._treeOutlines.length;++i){const treeOutline=this._treeOutlines[i];if(treeOutline.element.parentElement!==this._contentElement){const header=this._treeOutlineHeaders.get(treeOutline);if(header){this._contentElement.appendChild(header);}
  23. this._contentElement.appendChild(treeOutline.element);}}
  24. super.wasShown();this._breadcrumbs.update();const domModels=SDK.targetManager.models(SDK.DOMModel);for(const domModel of domModels){if(domModel.parentModel()){continue;}
  25. const treeOutline=Elements.ElementsTreeOutline.forDOMModel(domModel);treeOutline.setVisible(true);if(!treeOutline.rootDOMNode){if(domModel.existingDocument()){treeOutline.rootDOMNode=domModel.existingDocument();this._documentUpdated(domModel);}else{domModel.requestDocument();}}}}
  26. willHide(){SDK.OverlayModel.hideDOMNodeHighlight();for(let i=0;i<this._treeOutlines.length;++i){const treeOutline=this._treeOutlines[i];treeOutline.setVisible(false);this._contentElement.removeChild(treeOutline.element);const header=this._treeOutlineHeaders.get(treeOutline);if(header){this._contentElement.removeChild(header);}}
  27. if(this._popoverHelper){this._popoverHelper.hidePopover();}
  28. super.willHide();UI.context.setFlavor(ElementsPanel,null);}
  29. onResize(){this.element.window().requestAnimationFrame(this._updateSidebarPosition.bind(this));this._updateTreeOutlineVisibleWidth();}
  30. _selectedNodeChanged(event){const selectedNode=(event.data.node);const focus=(event.data.focus);for(const treeOutline of this._treeOutlines){if(!selectedNode||Elements.ElementsTreeOutline.forDOMModel(selectedNode.domModel())!==treeOutline){treeOutline.selectDOMNode(null);}}
  31. this._breadcrumbs.setSelectedNode(selectedNode);UI.context.setFlavor(SDK.DOMNode,selectedNode);if(!selectedNode){return;}
  32. selectedNode.setAsInspectedNode();if(focus){this._selectedNodeOnReset=selectedNode;this._hasNonDefaultSelectedNode=true;}
  33. const executionContexts=selectedNode.domModel().runtimeModel().executionContexts();const nodeFrameId=selectedNode.frameId();for(const context of executionContexts){if(context.frameId===nodeFrameId){UI.context.setFlavor(SDK.ExecutionContext,context);break;}}}
  34. _documentUpdatedEvent(event){const domModel=(event.data);this._documentUpdated(domModel);}
  35. _documentUpdated(domModel){this._searchableView.resetSearch();if(!domModel.existingDocument()){if(this.isShowing()){domModel.requestDocument();}
  36. return;}
  37. this._hasNonDefaultSelectedNode=false;if(this._omitDefaultSelection){return;}
  38. const savedSelectedNodeOnReset=this._selectedNodeOnReset;restoreNode.call(this,domModel,this._selectedNodeOnReset);async function restoreNode(domModel,staleNode){const nodePath=staleNode?staleNode.path():null;const restoredNodeId=nodePath?await domModel.pushNodeByPathToFrontend(nodePath):null;if(savedSelectedNodeOnReset!==this._selectedNodeOnReset){return;}
  39. let node=restoredNodeId?domModel.nodeForId(restoredNodeId):null;if(!node){const inspectedDocument=domModel.existingDocument();node=inspectedDocument?inspectedDocument.body||inspectedDocument.documentElement:null;}
  40. this._setDefaultSelectedNode(node);this._lastSelectedNodeSelectedForTest();}}
  41. _lastSelectedNodeSelectedForTest(){}
  42. _setDefaultSelectedNode(node){if(!node||this._hasNonDefaultSelectedNode||this._pendingNodeReveal){return;}
  43. const treeOutline=Elements.ElementsTreeOutline.forDOMModel(node.domModel());if(!treeOutline){return;}
  44. this.selectDOMNode(node);if(treeOutline.selectedTreeElement){treeOutline.selectedTreeElement.expand();}}
  45. searchCanceled(){delete this._searchConfig;this._hideSearchHighlights();this._searchableView.updateSearchMatchesCount(0);delete this._currentSearchResultIndex;delete this._searchResults;SDK.DOMModel.cancelSearch();}
  46. performSearch(searchConfig,shouldJump,jumpBackwards){const query=searchConfig.query;const whitespaceTrimmedQuery=query.trim();if(!whitespaceTrimmedQuery.length){return;}
  47. if(!this._searchConfig||this._searchConfig.query!==query){this.searchCanceled();}else{this._hideSearchHighlights();}
  48. this._searchConfig=searchConfig;const showUAShadowDOM=Common.moduleSetting('showUAShadowDOM').get();const domModels=SDK.targetManager.models(SDK.DOMModel);const promises=domModels.map(domModel=>domModel.performSearch(whitespaceTrimmedQuery,showUAShadowDOM));Promise.all(promises).then(resultCountCallback.bind(this));function resultCountCallback(resultCounts){this._searchResults=[];for(let i=0;i<resultCounts.length;++i){const resultCount=resultCounts[i];for(let j=0;j<resultCount;++j){this._searchResults.push({domModel:domModels[i],index:j,node:undefined});}}
  49. this._searchableView.updateSearchMatchesCount(this._searchResults.length);if(!this._searchResults.length){return;}
  50. if(this._currentSearchResultIndex>=this._searchResults.length){this._currentSearchResultIndex=undefined;}
  51. let index=this._currentSearchResultIndex;if(shouldJump){if(this._currentSearchResultIndex===undefined){index=jumpBackwards?-1:0;}else{index=jumpBackwards?index-1:index+1;}
  52. this._jumpToSearchResult(index);}}}
  53. _domWordWrapSettingChanged(event){this._contentElement.classList.toggle('elements-wrap',event.data);for(let i=0;i<this._treeOutlines.length;++i){this._treeOutlines[i].setWordWrap((event.data));}}
  54. switchToAndFocus(node){this._searchableView.cancelSearch();UI.viewManager.showView('elements').then(()=>this.selectDOMNode(node,true));}
  55. _getPopoverRequest(event){let link=event.target;while(link&&!link[Elements.ElementsTreeElement.HrefSymbol]){link=link.parentElementOrShadowHost();}
  56. if(!link){return null;}
  57. return{box:link.boxInWindow(),show:async popover=>{const node=this.selectedDOMNode();if(!node){return false;}
  58. const preview=await Components.ImagePreview.build(node.domModel().target(),link[Elements.ElementsTreeElement.HrefSymbol],true);if(preview){popover.contentElement.appendChild(preview);}
  59. return!!preview;}};}
  60. _jumpToSearchResult(index){if(!this._searchResults){return;}
  61. this._currentSearchResultIndex=(index+this._searchResults.length)%this._searchResults.length;this._highlightCurrentSearchResult();}
  62. jumpToNextSearchResult(){if(!this._searchResults){return;}
  63. this.performSearch(this._searchConfig,true);}
  64. jumpToPreviousSearchResult(){if(!this._searchResults){return;}
  65. this.performSearch(this._searchConfig,true,true);}
  66. supportsCaseSensitiveSearch(){return false;}
  67. supportsRegexSearch(){return false;}
  68. _highlightCurrentSearchResult(){const index=this._currentSearchResultIndex;const searchResults=this._searchResults;if(!searchResults){return;}
  69. const searchResult=searchResults[index];this._searchableView.updateCurrentMatchIndex(index);if(searchResult.node===null){return;}
  70. if(typeof searchResult.node==='undefined'){searchResult.domModel.searchResult(searchResult.index).then(node=>{searchResult.node=node;this._highlightCurrentSearchResult();});return;}
  71. const treeElement=this._treeElementForNode(searchResult.node);searchResult.node.scrollIntoView();if(treeElement){treeElement.highlightSearchResults(this._searchConfig.query);treeElement.reveal();const matches=treeElement.listItemElement.getElementsByClassName(UI.highlightedSearchResultClassName);if(matches.length){matches[0].scrollIntoViewIfNeeded(false);}}}
  72. _hideSearchHighlights(){if(!this._searchResults||!this._searchResults.length||this._currentSearchResultIndex===undefined){return;}
  73. const searchResult=this._searchResults[this._currentSearchResultIndex];if(!searchResult.node){return;}
  74. const treeOutline=Elements.ElementsTreeOutline.forDOMModel(searchResult.node.domModel());const treeElement=treeOutline.findTreeElement(searchResult.node);if(treeElement){treeElement.hideSearchHighlights();}}
  75. selectedDOMNode(){for(let i=0;i<this._treeOutlines.length;++i){const treeOutline=this._treeOutlines[i];if(treeOutline.selectedDOMNode()){return treeOutline.selectedDOMNode();}}
  76. return null;}
  77. selectDOMNode(node,focus){for(const treeOutline of this._treeOutlines){const outline=Elements.ElementsTreeOutline.forDOMModel(node.domModel());if(outline===treeOutline){treeOutline.selectDOMNode(node,focus);}else{treeOutline.selectDOMNode(null);}}}
  78. _updateBreadcrumbIfNeeded(event){const nodes=(event.data);this._breadcrumbs.updateNodes(nodes);}
  79. _crumbNodeSelected(event){const node=(event.data);this.selectDOMNode(node,true);}
  80. _treeOutlineForNode(node){if(!node){return null;}
  81. return Elements.ElementsTreeOutline.forDOMModel(node.domModel());}
  82. _treeElementForNode(node){const treeOutline=this._treeOutlineForNode(node);return(treeOutline.findTreeElement(node));}
  83. _leaveUserAgentShadowDOM(node){let userAgentShadowRoot;while((userAgentShadowRoot=node.ancestorUserAgentShadowRoot())&&userAgentShadowRoot.parentNode){node=userAgentShadowRoot.parentNode;}
  84. return node;}
  85. revealAndSelectNode(node,focus,omitHighlight){this._omitDefaultSelection=true;node=Common.moduleSetting('showUAShadowDOM').get()?node:this._leaveUserAgentShadowDOM(node);if(!omitHighlight){node.highlightForTwoSeconds();}
  86. return UI.viewManager.showView('elements',false,!focus).then(()=>{this.selectDOMNode(node,focus);delete this._omitDefaultSelection;if(!this._notFirstInspectElement){Elements.ElementsPanel._firstInspectElementNodeNameForTest=node.nodeName();Elements.ElementsPanel._firstInspectElementCompletedForTest();Host.InspectorFrontendHost.inspectElementCompleted();}
  87. this._notFirstInspectElement=true;});}
  88. _showUAShadowDOMChanged(){for(let i=0;i<this._treeOutlines.length;++i){this._treeOutlines[i].update();}}
  89. _setupTextSelectionHack(stylePaneWrapperElement){const uninstallHackBound=uninstallHack.bind(this);const uninstallHackOnMousemove=event=>{if(event.buttons===0){uninstallHack.call(this);}};stylePaneWrapperElement.addEventListener('mousedown',event=>{if(event.which!==1){return;}
  90. this._splitWidget.element.classList.add('disable-resizer-for-elements-hack');stylePaneWrapperElement.style.setProperty('height',`${stylePaneWrapperElement.offsetHeight}px`);const largeLength=1000000;stylePaneWrapperElement.style.setProperty('left',`${- 1 * largeLength}px`);stylePaneWrapperElement.style.setProperty('padding-left',`${largeLength}px`);stylePaneWrapperElement.style.setProperty('width',`calc(100% + ${largeLength}px)`);stylePaneWrapperElement.style.setProperty('position',`fixed`);stylePaneWrapperElement.window().addEventListener('blur',uninstallHackBound);stylePaneWrapperElement.window().addEventListener('contextmenu',uninstallHackBound,true);stylePaneWrapperElement.window().addEventListener('dragstart',uninstallHackBound,true);stylePaneWrapperElement.window().addEventListener('mousemove',uninstallHackOnMousemove,true);stylePaneWrapperElement.window().addEventListener('mouseup',uninstallHackBound,true);stylePaneWrapperElement.window().addEventListener('visibilitychange',uninstallHackBound);},true);function uninstallHack(){this._splitWidget.element.classList.remove('disable-resizer-for-elements-hack');stylePaneWrapperElement.style.removeProperty('left');stylePaneWrapperElement.style.removeProperty('padding-left');stylePaneWrapperElement.style.removeProperty('width');stylePaneWrapperElement.style.removeProperty('position');stylePaneWrapperElement.window().removeEventListener('blur',uninstallHackBound);stylePaneWrapperElement.window().removeEventListener('contextmenu',uninstallHackBound,true);stylePaneWrapperElement.window().removeEventListener('dragstart',uninstallHackBound,true);stylePaneWrapperElement.window().removeEventListener('mousemove',uninstallHackOnMousemove,true);stylePaneWrapperElement.window().removeEventListener('mouseup',uninstallHackBound,true);stylePaneWrapperElement.window().removeEventListener('visibilitychange',uninstallHackBound);}}
  91. _updateSidebarPosition(){if(this.sidebarPaneView&&this.sidebarPaneView.tabbedPane().shouldHideOnDetach()){return;}
  92. let splitMode;const position=Common.moduleSetting('sidebarPosition').get();if(position==='right'||(position==='auto'&&UI.inspectorView.element.offsetWidth>680)){splitMode=_splitMode.Vertical;}else if(UI.inspectorView.element.offsetWidth>415){splitMode=_splitMode.Horizontal;}else{splitMode=_splitMode.Slim;}
  93. if(this.sidebarPaneView&&splitMode===this._splitMode){return;}
  94. this._splitMode=splitMode;const extensionSidebarPanes=Extensions.extensionServer.sidebarPanes();let lastSelectedTabId=null;if(this.sidebarPaneView){lastSelectedTabId=this.sidebarPaneView.tabbedPane().selectedTabId;this.sidebarPaneView.tabbedPane().detach();this._splitWidget.uninstallResizer(this.sidebarPaneView.tabbedPane().headerElement());}
  95. this._splitWidget.setVertical(this._splitMode===_splitMode.Vertical);this.showToolbarPane(null,null);const matchedStylePanesWrapper=new UI.VBox();matchedStylePanesWrapper.element.classList.add('style-panes-wrapper');this._stylesWidget.show(matchedStylePanesWrapper.element);this._setupTextSelectionHack(matchedStylePanesWrapper.element);const computedStylePanesWrapper=new UI.VBox();computedStylePanesWrapper.element.classList.add('style-panes-wrapper');this._computedStyleWidget.show(computedStylePanesWrapper.element);function showMetrics(inComputedStyle){if(inComputedStyle){this._metricsWidget.show(computedStylePanesWrapper.element,this._computedStyleWidget.element);}else{this._metricsWidget.show(matchedStylePanesWrapper.element);}}
  96. function tabSelected(event){const tabId=(event.data.tabId);if(tabId===Common.UIString('Computed')){showMetrics.call(this,true);}else if(tabId===Common.UIString('Styles')){showMetrics.call(this,false);}}
  97. this.sidebarPaneView=UI.viewManager.createTabbedLocation(()=>UI.viewManager.showView('elements'));const tabbedPane=this.sidebarPaneView.tabbedPane();if(this._popoverHelper){this._popoverHelper.hidePopover();}
  98. this._popoverHelper=new UI.PopoverHelper(tabbedPane.element,this._getPopoverRequest.bind(this));this._popoverHelper.setHasPadding(true);this._popoverHelper.setTimeout(0);if(this._splitMode!==_splitMode.Vertical){this._splitWidget.installResizer(tabbedPane.headerElement());}
  99. const stylesView=new UI.SimpleView(Common.UIString('Styles'));this.sidebarPaneView.appendView(stylesView);if(splitMode===_splitMode.Horizontal){stylesView.element.classList.add('flex-auto');const splitWidget=new UI.SplitWidget(true,true,'stylesPaneSplitViewState',215);splitWidget.show(stylesView.element);splitWidget.setMainWidget(matchedStylePanesWrapper);splitWidget.setSidebarWidget(computedStylePanesWrapper);}else{stylesView.element.classList.add('flex-auto');matchedStylePanesWrapper.show(stylesView.element);const computedView=new UI.SimpleView(Common.UIString('Computed'));computedView.element.classList.add('composite','fill');computedStylePanesWrapper.show(computedView.element);tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected,tabSelected,this);this.sidebarPaneView.appendView(computedView);}
  100. this._stylesViewToReveal=stylesView;showMetrics.call(this,this._splitMode===_splitMode.Horizontal);this.sidebarPaneView.appendApplicableItems('elements-sidebar');for(let i=0;i<extensionSidebarPanes.length;++i){this._addExtensionSidebarPane(extensionSidebarPanes[i]);}
  101. if(lastSelectedTabId){this.sidebarPaneView.tabbedPane().selectTab(lastSelectedTabId);}
  102. this._splitWidget.setSidebarWidget(this.sidebarPaneView.tabbedPane());}
  103. _extensionSidebarPaneAdded(event){const pane=(event.data);this._addExtensionSidebarPane(pane);}
  104. _addExtensionSidebarPane(pane){if(pane.panelName()===this.name){this.sidebarPaneView.appendView(pane);}}}
  105. export const _splitMode={Vertical:Symbol('Vertical'),Horizontal:Symbol('Horizontal'),Slim:Symbol('Slim'),};export class ContextMenuProvider{appendApplicableItems(event,contextMenu,object){if(!(object instanceof SDK.RemoteObject&&((object)).isNode())&&!(object instanceof SDK.DOMNode)&&!(object instanceof SDK.DeferredDOMNode)){return;}
  106. if(ElementsPanel.instance().element.isAncestor((event.target))){return;}
  107. const commandCallback=Common.Revealer.reveal.bind(Common.Revealer,object);contextMenu.revealSection().appendItem(Common.UIString('Reveal in Elements panel'),commandCallback);}}
  108. export class DOMNodeRevealer{reveal(node,omitFocus){const panel=ElementsPanel.instance();panel._pendingNodeReveal=true;return new Promise(revealPromise);function revealPromise(resolve,reject){if(node instanceof SDK.DOMNode){onNodeResolved((node));}else if(node instanceof SDK.DeferredDOMNode){((node)).resolve(onNodeResolved);}else if(node instanceof SDK.RemoteObject){const domModel=(node).runtimeModel().target().model(SDK.DOMModel);if(domModel){domModel.pushObjectAsNodeToFrontend(node).then(onNodeResolved);}else{reject(new Error('Could not resolve a node to reveal.'));}}else{reject(new Error('Can\'t reveal a non-node.'));panel._pendingNodeReveal=false;}
  109. function onNodeResolved(resolvedNode){panel._pendingNodeReveal=false;let currentNode=resolvedNode;while(currentNode.parentNode){currentNode=currentNode.parentNode;}
  110. const isDetached=!(currentNode instanceof SDK.DOMDocument);const isDocument=node instanceof SDK.DOMDocument;if(!isDocument&&isDetached){const msg=ls`Node cannot be found in the current page.`;Common.console.warn(msg);reject(new Error(msg));return;}
  111. if(resolvedNode){panel.revealAndSelectNode(resolvedNode,!omitFocus).then(resolve);return;}
  112. reject(new Error('Could not resolve node to reveal.'));}}}}
  113. export class CSSPropertyRevealer{reveal(property){const panel=ElementsPanel.instance();return panel._revealProperty((property));}}
  114. export class ElementsActionDelegate{handleAction(context,actionId){const node=UI.context.flavor(SDK.DOMNode);if(!node){return true;}
  115. const treeOutline=Elements.ElementsTreeOutline.forDOMModel(node.domModel());if(!treeOutline){return true;}
  116. switch(actionId){case'elements.hide-element':treeOutline.toggleHideElement(node);return true;case'elements.edit-as-html':treeOutline.toggleEditAsHTML(node);return true;case'elements.undo':SDK.domModelUndoStack.undo();ElementsPanel.instance()._stylesWidget.forceUpdate();return true;case'elements.redo':SDK.domModelUndoStack.redo();ElementsPanel.instance()._stylesWidget.forceUpdate();return true;}
  117. return false;}}
  118. export class PseudoStateMarkerDecorator{decorate(node){return{color:'orange',title:Common.UIString('Element state: %s',':'+node.domModel().cssModel().pseudoState(node).join(', :'))};}}
  119. self.Elements=self.Elements||{};Elements=Elements||{};Elements.ElementsPanel=ElementsPanel;Elements.ElementsPanel._firstInspectElementCompletedForTest=function(){};Elements.ElementsPanel._splitMode=_splitMode;Elements.ElementsPanel.ContextMenuProvider=ContextMenuProvider;Elements.ElementsPanel.DOMNodeRevealer=DOMNodeRevealer;Elements.ElementsPanel.CSSPropertyRevealer=CSSPropertyRevealer;Elements.ElementsActionDelegate=ElementsActionDelegate;Elements.ElementsPanel.PseudoStateMarkerDecorator=PseudoStateMarkerDecorator;