DOM Detection
DOM detection looks for elements a technology inserts into the page, matched by CSS selector, plus optional checks on an element's attributes or text. Chat widgets, page builders, embeds and frameworks all leave signature nodes.
Why it matters
Some technologies are invisible to every other vector but unmistakable in the DOM: a specific id, a custom element, a widget container, or a builder wrapper. Selector-based detection catches them. Matching a live DOM structure is also harder to spoof than a single string, which makes a clean DOM match strong evidence.
A page builder like Webflow or Elementor leaves its fingerprint in the DOM structure, not in a script URL or meta tag. A chat widget might inject a div with a specific id. A third-party comment system embeds a custom element. These are the traces DOM detection is built to catch.
How it works
DOM detection runs CSS selectors against the page's DOM to find signature elements. Each fingerprint in the open database can specify:
- A CSS selector (e.g.
#intercom-frame,.elementor-editor,div.drift-frame-controller) - Optional attribute checks (does the element have a
data-versionattribute, and if so, does it match a pattern?) - Optional text checks (does the element's text content contain a specific substring?)
When Scalpel Stack runs a DOM selector, it wraps the query in a try/catch so a malformed selector never crashes. If the selector finds a match and any optional conditions pass, the detection fires with the selector and (if applicable) the matched attribute or text as evidence.
For performance and safety, Scalpel Stack runs these queries against a re-parsed copy of the captured HTML, not the live DOM. This avoids browser stalls from complex selectors and isolates the search from hostile page content.
What does not matter
A DOM match does not tell you which script runs on the page or what version it is, unless the element's text or attributes encode that. It tells you the structure or wrapper is there; it does not guarantee the script itself is loaded or active.
The element matching also does not inspect the properties or computed styles of an element (e.g. element.offsetHeight). Scalpel Stack intentionally stays out of that space because computed properties can be expensive, browser-dependent, and a footprint for the extension itself.
Code example
Here are real examples of DOM-matched technologies:
<!-- Intercom chat widget -->
<div id="intercom-frame"></div>
<!-- Matched by: #intercom-frame -->
<!-- Elementor page builder -->
<div class="elementor-editor-active">
<section class="elementor-section">...</section>
</div>
<!-- Matched by: .elementor-editor, or .elementor-section if .elementor-editor-active is present -->
<!-- Drift chat widget -->
<div class="drift-frame-controller"></div>
<!-- Matched by: .drift-frame-controller -->
<!-- Custom element (e.g. from a framework) -->
<custom-element data-version="2.1.0"></custom-element>
<!-- Matched by: custom-element (by tag name, which is a valid CSS selector) -->
When a selector like #intercom-frame matches, the evidence line records the vector (dom), the selector key, and confirmation that the match succeeded. No text content is scraped; the match itself is the signal.
How Scalpel Stack shows it
DOM evidence uses the dom vector badge with the CSS selector as the key (e.g. dom: #my-widget-id). The evidence line confirms that the selector matched. If there are optional attribute or text checks, they are noted in the matched text field.
Matching runs on a DOMParser re-parse of the captured HTML, so the element is found in the same snapshot of the page that the other vectors are scanning. This keeps the results consistent and the extension lightweight.