mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:12:43 +00:00 
			
		
		
		
	LibWebView: Move the Inspector JS and CSS to independent files
These are much easier to work with in their own files with syntax highlighting and other IDE-friendliness.
This commit is contained in:
		
							parent
							
								
									353642168a
								
							
						
					
					
						commit
						030b90b79d
					
				
					 3 changed files with 314 additions and 301 deletions
				
			
		
							
								
								
									
										169
									
								
								Base/res/html/inspector/inspector.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								Base/res/html/inspector/inspector.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,169 @@ | |||
| body { | ||||
|     font-family: system-ui, sans-serif; | ||||
|     font-size: 10pt; | ||||
| 
 | ||||
|     margin: 0; | ||||
| } | ||||
| 
 | ||||
| .split-view { | ||||
|     width: 100vw; | ||||
|     height: 100vh; | ||||
| } | ||||
| 
 | ||||
| .split-view-container { | ||||
|     overflow: scroll; | ||||
| } | ||||
| 
 | ||||
| .tab-controls-container { | ||||
|     position: absolute; | ||||
|     width: 100%; | ||||
| 
 | ||||
|     padding: 4px; | ||||
| 
 | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
| 
 | ||||
|     z-index: 100; | ||||
| } | ||||
| 
 | ||||
| .tab-controls { | ||||
|     overflow: hidden; | ||||
|     flex-shrink: 0; | ||||
| } | ||||
| 
 | ||||
| .tab-controls button { | ||||
|     font-size: 12px; | ||||
|     font-weight: 600; | ||||
| 
 | ||||
|     float: left; | ||||
|     border: none; | ||||
|     outline: none; | ||||
|     cursor: pointer; | ||||
| 
 | ||||
|     padding: 4px 8px; | ||||
| } | ||||
| 
 | ||||
| .tab-controls :first-child { | ||||
|     border-radius: 0.5rem 0 0 0.5rem; | ||||
| } | ||||
| 
 | ||||
| .tab-controls :last-child { | ||||
|     border-radius: 0 0.5rem 0.5rem 0; | ||||
| } | ||||
| 
 | ||||
| .tab-content { | ||||
|     height: 100%; | ||||
| 
 | ||||
|     display: none; | ||||
|     border-radius: 0.5rem; | ||||
| 
 | ||||
|     margin-top: 30px; | ||||
|     padding: 8px; | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: dark) { | ||||
|     html { | ||||
|         background-color: rgb(23, 23, 23); | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls-container { | ||||
|         background-color: rgb(57, 57, 57); | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls button { | ||||
|         color: white; | ||||
|         background-color: rgb(43, 42, 50); | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls button.active { | ||||
|         background-color: rgb(22 100 219); | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls button + button { | ||||
|         border-left: 1px solid rgb(96, 96, 96); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: light) { | ||||
|     .tab-controls-container { | ||||
|         background-color: rgb(229, 229, 229); | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls button { | ||||
|         color: black; | ||||
|         background-color: white; | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls button.active { | ||||
|         color: white; | ||||
|         background-color: rgb(28, 138, 255); | ||||
|     } | ||||
| 
 | ||||
|     .tab-controls button + button { | ||||
|         border-left: 1px solid rgb(242, 242, 242); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| details > :not(:first-child) { | ||||
|     display: list-item; | ||||
|     list-style: none inside; | ||||
|     margin-left: 1em; | ||||
| } | ||||
| 
 | ||||
| .hoverable { | ||||
|     display: block; | ||||
|     padding: 1px; | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: dark) { | ||||
|     .hoverable:hover { | ||||
|         background-color: #31383e; | ||||
|     } | ||||
| 
 | ||||
|     .selected { | ||||
|         border: 1px dashed cyan; | ||||
|         padding: 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: light) { | ||||
|     .hoverable:hover { | ||||
|         background-color: rgb(236, 236, 236); | ||||
|     } | ||||
| 
 | ||||
|     .selected { | ||||
|         border: 1px dashed blue; | ||||
|         padding: 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| .property-table { | ||||
|     width: 100%; | ||||
| 
 | ||||
|     table-layout: fixed; | ||||
|     border-collapse: collapse; | ||||
| } | ||||
| 
 | ||||
| .property-table th { | ||||
|     position: sticky; | ||||
|     top: 0px; | ||||
| } | ||||
| 
 | ||||
| .property-table th, | ||||
| .property-table td { | ||||
|     padding: 4px; | ||||
|     text-align: left; | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: dark) { | ||||
|     .property-table th { | ||||
|         background-color: rgb(57, 57, 57); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @media (prefers-color-scheme: light) { | ||||
|     .property-table th { | ||||
|         background-color: rgb(229, 229, 229); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										136
									
								
								Base/res/html/inspector/inspector.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								Base/res/html/inspector/inspector.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,136 @@ | |||
| let selectedTopTab = null; | ||||
| let selectedTopTabButton = null; | ||||
| 
 | ||||
| let selectedBottomTab = null; | ||||
| let selectedBottomTabButton = null; | ||||
| 
 | ||||
| let selectedDOMNode = null; | ||||
| 
 | ||||
| const selectTab = (tabButton, tabID, selectedTab, selectedTabButton) => { | ||||
|     let tab = document.getElementById(tabID); | ||||
| 
 | ||||
|     if (selectedTab === tab) { | ||||
|         return selectedTab; | ||||
|     } | ||||
|     if (selectedTab !== null) { | ||||
|         selectedTab.style.display = "none"; | ||||
|         selectedTabButton.classList.remove("active"); | ||||
|     } | ||||
| 
 | ||||
|     tab.style.display = "block"; | ||||
|     tabButton.classList.add("active"); | ||||
| 
 | ||||
|     return tab; | ||||
| }; | ||||
| 
 | ||||
| const selectTopTab = (tabButton, tabID) => { | ||||
|     selectedTopTab = selectTab(tabButton, tabID, selectedTopTab, selectedTopTabButton); | ||||
|     selectedTopTabButton = tabButton; | ||||
| }; | ||||
| 
 | ||||
| const selectBottomTab = (tabButton, tabID) => { | ||||
|     selectedBottomTab = selectTab(tabButton, tabID, selectedBottomTab, selectedBottomTabButton); | ||||
|     selectedBottomTabButton = tabButton; | ||||
| }; | ||||
| 
 | ||||
| let initialTopTabButton = document.getElementById("dom-tree-button"); | ||||
| selectTopTab(initialTopTabButton, "dom-tree"); | ||||
| 
 | ||||
| let initialBottomTabButton = document.getElementById("computed-style-button"); | ||||
| selectBottomTab(initialBottomTabButton, "computed-style"); | ||||
| 
 | ||||
| const scrollToElement = element => { | ||||
|     // Include an offset to prevent the element being placed behind the fixed `tab-controls` header.
 | ||||
|     const offset = 45; | ||||
| 
 | ||||
|     let position = element.getBoundingClientRect().top; | ||||
|     position += window.pageYOffset - offset; | ||||
| 
 | ||||
|     window.scrollTo(0, position); | ||||
| }; | ||||
| 
 | ||||
| inspector.loadDOMTree = tree => { | ||||
|     let domTree = document.getElementById("dom-tree"); | ||||
|     domTree.innerHTML = atob(tree); | ||||
| 
 | ||||
|     let domNodes = domTree.getElementsByClassName("hoverable"); | ||||
| 
 | ||||
|     for (let domNode of domNodes) { | ||||
|         domNode.addEventListener("click", event => { | ||||
|             inspectDOMNode(domNode); | ||||
|             event.preventDefault(); | ||||
|         }); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| inspector.loadAccessibilityTree = tree => { | ||||
|     let accessibilityTree = document.getElementById("accessibility-tree"); | ||||
|     accessibilityTree.innerHTML = atob(tree); | ||||
| }; | ||||
| 
 | ||||
| inspector.inspectDOMNodeID = nodeID => { | ||||
|     let domNodes = document.querySelectorAll(`[data-id="${nodeID}"]`); | ||||
|     if (domNodes.length !== 1) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     for (let domNode = domNodes[0]; domNode; domNode = domNode.parentNode) { | ||||
|         if (domNode.tagName === "DETAILS") { | ||||
|             domNode.setAttribute("open", ""); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     inspectDOMNode(domNodes[0]); | ||||
|     scrollToElement(selectedDOMNode); | ||||
| }; | ||||
| 
 | ||||
| inspector.clearInspectedDOMNode = () => { | ||||
|     if (selectedDOMNode !== null) { | ||||
|         selectedDOMNode.classList.remove("selected"); | ||||
|         selectedDOMNode = null; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| inspector.createPropertyTables = (computedStyle, resolvedStyle, customProperties) => { | ||||
|     const createPropertyTable = (tableID, properties) => { | ||||
|         let oldTable = document.getElementById(tableID); | ||||
| 
 | ||||
|         let newTable = document.createElement("tbody"); | ||||
|         newTable.setAttribute("id", tableID); | ||||
| 
 | ||||
|         Object.keys(properties) | ||||
|             .sort() | ||||
|             .forEach(name => { | ||||
|                 let row = newTable.insertRow(); | ||||
| 
 | ||||
|                 let nameColumn = row.insertCell(); | ||||
|                 nameColumn.innerText = name; | ||||
| 
 | ||||
|                 let valueColumn = row.insertCell(); | ||||
|                 valueColumn.innerText = properties[name]; | ||||
|             }); | ||||
| 
 | ||||
|         oldTable.parentNode.replaceChild(newTable, oldTable); | ||||
|     }; | ||||
| 
 | ||||
|     createPropertyTable("computed-style-table", JSON.parse(computedStyle)); | ||||
|     createPropertyTable("resolved-style-table", JSON.parse(resolvedStyle)); | ||||
|     createPropertyTable("custom-properties-table", JSON.parse(customProperties)); | ||||
| }; | ||||
| 
 | ||||
| const inspectDOMNode = domNode => { | ||||
|     if (selectedDOMNode === domNode) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     inspector.clearInspectedDOMNode(); | ||||
| 
 | ||||
|     domNode.classList.add("selected"); | ||||
|     selectedDOMNode = domNode; | ||||
| 
 | ||||
|     inspector.inspectDOMNode(domNode.dataset.id, domNode.dataset.pseudoElement); | ||||
| }; | ||||
| 
 | ||||
| document.addEventListener("DOMContentLoaded", () => { | ||||
|     inspector.inspectorLoaded(); | ||||
| }); | ||||
|  | @ -8,6 +8,7 @@ | |||
| #include <AK/JsonArray.h> | ||||
| #include <AK/JsonObject.h> | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <LibCore/Resource.h> | ||||
| #include <LibWeb/Infra/Strings.h> | ||||
| #include <LibWebView/InspectorClient.h> | ||||
| #include <LibWebView/SourceHighlighter.h> | ||||
|  | @ -155,6 +156,10 @@ void InspectorClient::load_inspector() | |||
| { | ||||
|     StringBuilder builder; | ||||
| 
 | ||||
|     // FIXME: Teach LibWeb how to load resource:// URIs instead of needing to read these files here.
 | ||||
|     auto inspector_css = MUST(Core::Resource::load_from_uri("resource://html/inspector/inspector.css"sv)); | ||||
|     auto inspector_js = MUST(Core::Resource::load_from_uri("resource://html/inspector/inspector.js"sv)); | ||||
| 
 | ||||
|     builder.append(R"~~~( | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | @ -164,177 +169,9 @@ void InspectorClient::load_inspector() | |||
| )~~~"sv); | ||||
| 
 | ||||
|     builder.append(HTML_HIGHLIGHTER_STYLE); | ||||
|     builder.append(inspector_css->data()); | ||||
| 
 | ||||
|     builder.append(R"~~~( | ||||
|         body { | ||||
|             font-family: system-ui, sans-serif; | ||||
|             font-size: 10pt; | ||||
| 
 | ||||
|             margin: 0; | ||||
|         } | ||||
| 
 | ||||
|         .split-view { | ||||
|             width: 100vw; | ||||
|             height: 100vh; | ||||
|         } | ||||
| 
 | ||||
|         .split-view-container { | ||||
|             overflow: scroll; | ||||
|         } | ||||
| 
 | ||||
|         .tab-controls-container { | ||||
|             position: absolute; | ||||
|             width: 100%; | ||||
| 
 | ||||
|             padding: 4px; | ||||
| 
 | ||||
|             display: flex; | ||||
|             align-items: center; | ||||
|             justify-content: center; | ||||
| 
 | ||||
|             z-index: 100; | ||||
|         } | ||||
| 
 | ||||
|         .tab-controls { | ||||
|             overflow: hidden; | ||||
|             flex-shrink: 0; | ||||
|         } | ||||
| 
 | ||||
|         .tab-controls button { | ||||
|             font-size: 12px; | ||||
|             font-weight: 600; | ||||
| 
 | ||||
|             float: left; | ||||
|             border: none; | ||||
|             outline: none; | ||||
|             cursor: pointer; | ||||
| 
 | ||||
|             padding: 4px 8px; | ||||
|         } | ||||
| 
 | ||||
|         .tab-controls :first-child { | ||||
|             border-radius: 0.5rem 0 0 0.5rem; | ||||
|         } | ||||
| 
 | ||||
|         .tab-controls :last-child { | ||||
|             border-radius: 0 0.5rem 0.5rem 0; | ||||
|         } | ||||
| 
 | ||||
|         .tab-content { | ||||
|             height: 100%; | ||||
| 
 | ||||
|             display: none; | ||||
|             border-radius: 0.5rem; | ||||
| 
 | ||||
|             margin-top: 30px; | ||||
|             padding: 8px; | ||||
|         } | ||||
| 
 | ||||
|         @media (prefers-color-scheme: dark) { | ||||
|             html { | ||||
|                 background-color: rgb(23, 23, 23); | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls-container { | ||||
|                 background-color: rgb(57, 57, 57); | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls button { | ||||
|                 color: white; | ||||
|                 background-color: rgb(43, 42, 50); | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls button.active { | ||||
|                 background-color: rgb(22 100 219); | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls button + button { | ||||
|                 border-left: 1px solid rgb(96, 96, 96); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         @media (prefers-color-scheme: light) { | ||||
|             .tab-controls-container { | ||||
|                 background-color: rgb(229, 229, 229); | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls button { | ||||
|                 color: black; | ||||
|                 background-color: white; | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls button.active { | ||||
|                 color: white; | ||||
|                 background-color: rgb(28, 138, 255); | ||||
|             } | ||||
| 
 | ||||
|             .tab-controls button + button { | ||||
|                 border-left: 1px solid rgb(242, 242, 242); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         details > :not(:first-child) { | ||||
|             display: list-item; | ||||
|             list-style: none inside; | ||||
|             margin-left: 1em; | ||||
|         } | ||||
| 
 | ||||
|         .hoverable { | ||||
|             display: block; | ||||
|             padding: 1px; | ||||
|         } | ||||
| 
 | ||||
|         @media (prefers-color-scheme: dark) { | ||||
|             .hoverable:hover { | ||||
|                 background-color: #31383e; | ||||
|             } | ||||
| 
 | ||||
|             .selected { | ||||
|                 border: 1px dashed cyan; | ||||
|                 padding: 0; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         @media (prefers-color-scheme: light) { | ||||
|             .hoverable:hover { | ||||
|                 background-color: rgb(236, 236, 236); | ||||
|             } | ||||
| 
 | ||||
|             .selected { | ||||
|                 border: 1px dashed blue; | ||||
|                 padding: 0; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         .property-table { | ||||
|             width: 100%; | ||||
| 
 | ||||
|             table-layout: fixed; | ||||
|             border-collapse: collapse; | ||||
|         } | ||||
| 
 | ||||
|         .property-table th { | ||||
|             position: sticky; | ||||
|             top: 0px; | ||||
|         } | ||||
| 
 | ||||
|         .property-table th, | ||||
|         .property-table td { | ||||
|             padding: 4px; | ||||
|             text-align: left; | ||||
|         } | ||||
| 
 | ||||
|         @media (prefers-color-scheme: dark) { | ||||
|             .property-table th { | ||||
|                 background-color: rgb(57, 57, 57); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         @media (prefers-color-scheme: light) { | ||||
|             .property-table th { | ||||
|                 background-color: rgb(229, 229, 229); | ||||
|             } | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
|  | @ -386,140 +223,11 @@ void InspectorClient::load_inspector() | |||
|     </div> | ||||
| 
 | ||||
|     <script type="text/javascript"> | ||||
|         let selectedTopTab = null; | ||||
|         let selectedTopTabButton = null; | ||||
| )~~~"sv); | ||||
| 
 | ||||
|         let selectedBottomTab = null; | ||||
|         let selectedBottomTabButton = null; | ||||
|     builder.append(inspector_js->data()); | ||||
| 
 | ||||
|         let selectedDOMNode = null; | ||||
| 
 | ||||
|         const selectTab = (tabButton, tabID, selectedTab, selectedTabButton) => { | ||||
|             let tab = document.getElementById(tabID); | ||||
| 
 | ||||
|             if (selectedTab === tab) { | ||||
|                 return selectedTab; | ||||
|             } | ||||
|             if (selectedTab !== null) { | ||||
|                 selectedTab.style.display = "none"; | ||||
|                 selectedTabButton.classList.remove("active"); | ||||
|             } | ||||
| 
 | ||||
|             tab.style.display = "block"; | ||||
|             tabButton.classList.add("active"); | ||||
| 
 | ||||
|             return tab; | ||||
|         }; | ||||
| 
 | ||||
|         const selectTopTab = (tabButton, tabID) => { | ||||
|             selectedTopTab = selectTab(tabButton, tabID, selectedTopTab, selectedTopTabButton); | ||||
|             selectedTopTabButton = tabButton; | ||||
|         }; | ||||
| 
 | ||||
|         const selectBottomTab = (tabButton, tabID) => { | ||||
|             selectedBottomTab = selectTab(tabButton, tabID, selectedBottomTab, selectedBottomTabButton); | ||||
|             selectedBottomTabButton = tabButton; | ||||
|         }; | ||||
| 
 | ||||
|         let initialTopTabButton = document.getElementById("dom-tree-button"); | ||||
|         selectTopTab(initialTopTabButton, "dom-tree"); | ||||
| 
 | ||||
|         let initialBottomTabButton = document.getElementById("computed-style-button"); | ||||
|         selectBottomTab(initialBottomTabButton, "computed-style"); | ||||
| 
 | ||||
|         const scrollToElement = (element) => { | ||||
|             // Include an offset to prevent the element being placed behind the fixed `tab-controls` header.
 | ||||
|             const offset = 45; | ||||
| 
 | ||||
|             let position = element.getBoundingClientRect().top; | ||||
|             position += window.pageYOffset - offset; | ||||
| 
 | ||||
|             window.scrollTo(0, position); | ||||
|         } | ||||
| 
 | ||||
|         inspector.loadDOMTree = tree => { | ||||
|             let domTree = document.getElementById("dom-tree"); | ||||
|             domTree.innerHTML = atob(tree); | ||||
| 
 | ||||
|             let domNodes = domTree.getElementsByClassName("hoverable"); | ||||
| 
 | ||||
|             for (let domNode of domNodes) { | ||||
|                 domNode.addEventListener("click", event => { | ||||
|                     inspectDOMNode(domNode); | ||||
|                     event.preventDefault(); | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         inspector.loadAccessibilityTree = tree => { | ||||
|             let accessibilityTree = document.getElementById("accessibility-tree"); | ||||
|             accessibilityTree.innerHTML = atob(tree); | ||||
|         }; | ||||
| 
 | ||||
|         inspector.inspectDOMNodeID = nodeID => { | ||||
|             let domNodes = document.querySelectorAll(`[data-id="${nodeID}"]`); | ||||
|             if (domNodes.length !== 1) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             for (let domNode = domNodes[0]; domNode; domNode = domNode.parentNode) { | ||||
|                 if (domNode.tagName === "DETAILS") { | ||||
|                     domNode.setAttribute("open", ""); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             inspectDOMNode(domNodes[0]); | ||||
|             scrollToElement(selectedDOMNode); | ||||
|         }; | ||||
| 
 | ||||
|         inspector.clearInspectedDOMNode = () => { | ||||
|             if (selectedDOMNode !== null) { | ||||
|                 selectedDOMNode.classList.remove("selected"); | ||||
|                 selectedDOMNode = null; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         inspector.createPropertyTables = (computedStyle, resolvedStyle, customProperties) => { | ||||
|             const createPropertyTable = (tableID, properties) => { | ||||
|                 let oldTable = document.getElementById(tableID); | ||||
| 
 | ||||
|                 let newTable = document.createElement("tbody"); | ||||
|                 newTable.setAttribute("id", tableID); | ||||
| 
 | ||||
|                 Object.keys(properties).sort().forEach(name => { | ||||
|                     let row = newTable.insertRow(); | ||||
| 
 | ||||
|                     let nameColumn = row.insertCell(); | ||||
|                     nameColumn.innerText = name; | ||||
| 
 | ||||
|                     let valueColumn = row.insertCell(); | ||||
|                     valueColumn.innerText = properties[name]; | ||||
|                 }); | ||||
| 
 | ||||
|                 oldTable.parentNode.replaceChild(newTable, oldTable) | ||||
|             }; | ||||
| 
 | ||||
|             createPropertyTable("computed-style-table", JSON.parse(computedStyle)); | ||||
|             createPropertyTable("resolved-style-table", JSON.parse(resolvedStyle)); | ||||
|             createPropertyTable("custom-properties-table", JSON.parse(customProperties)); | ||||
|         }; | ||||
| 
 | ||||
|         const inspectDOMNode = domNode => { | ||||
|             if (selectedDOMNode === domNode) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             inspector.clearInspectedDOMNode(); | ||||
| 
 | ||||
|             domNode.classList.add("selected"); | ||||
|             selectedDOMNode = domNode; | ||||
| 
 | ||||
|             inspector.inspectDOMNode(domNode.dataset.id, domNode.dataset.pseudoElement); | ||||
|         }; | ||||
| 
 | ||||
|         document.addEventListener("DOMContentLoaded", () => { | ||||
|             inspector.inspectorLoaded(); | ||||
|         }); | ||||
|     builder.append(R"~~~( | ||||
|     </script> | ||||
| </body> | ||||
| </html> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Flynn
						Timothy Flynn