Skip to content

Commit

Permalink
feat: support shadow dom
Browse files Browse the repository at this point in the history
surunzi committed Sep 26, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 3a14def commit f0908c1
Showing 4 changed files with 69 additions and 7 deletions.
13 changes: 13 additions & 0 deletions devtools/target.html
Original file line number Diff line number Diff line change
@@ -49,6 +49,19 @@
console.log('touch')
})
</script>
<div id="shadow1">
<template shadowrootmode="open">
<span>I'm in the shadow DOM</span>
</template>
</div>
<div id="shadow2"></div>
<script>
setTimeout(() => {
const shadow2 = document.getElementById('shadow2')
const shadow2Root = shadow2.attachShadow({ mode: 'closed' })
shadow2Root.innerHTML = "<span>I'm in the shadow DOM</span>"
}, 2000)
</script>
<div class="scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus.
Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies
34 changes: 33 additions & 1 deletion src/domains/DOM.ts
Original file line number Diff line number Diff line change
@@ -56,11 +56,43 @@ export function copyTo(params: DOM.CopyToRequest): DOM.CopyToResponse {
}
}

let isEnable = false

export function enable() {
mutationObserver.observe()
isEnable = true

mutationObserver.disconnect()
mutationObserver.observe(document.documentElement)
nodeManager.clear()
}

function hookAttachShadow() {
const origAttachShadow = Element.prototype.attachShadow
if (origAttachShadow) {
Element.prototype.attachShadow = function (init) {
const shadowRoot = origAttachShadow.apply(this, [init])
if (!nodeManager.isValidNode(this)) {
return shadowRoot
}

;(this as any).__shadowRoot__ = shadowRoot
if (isEnable) {
mutationObserver.observe(shadowRoot)
const hostId = getNodeId(this)
if (hostId) {
connector.trigger('DOM.shadowRootPushed', {
hostId,
root: nodeManager.wrap(shadowRoot, { depth: 1 }),
})
}
}
return shadowRoot
}
}
}

hookAttachShadow()

export function getDocument() {
return {
root: nodeManager.wrap(document, {
10 changes: 5 additions & 5 deletions src/lib/mutationObserver.ts
Original file line number Diff line number Diff line change
@@ -9,17 +9,17 @@ class Observer extends Emitter {
each(mutations, mutation => this.handleMutation(mutation))
})
}
observe() {
const { observer } = this

observer.disconnect()
observer.observe(document.documentElement, {
observe(node: Node) {
this.observer.observe(node, {
attributes: true,
childList: true,
characterData: true,
subtree: true,
})
}
disconnect() {
this.observer.disconnect()
}
private handleMutation(mutation: MutationRecord) {
if (mutation.type === 'attributes') {
this.emit('attributes', mutation.target, mutation.attributeName)
19 changes: 18 additions & 1 deletion src/lib/nodeManager.ts
Original file line number Diff line number Diff line change
@@ -59,6 +59,15 @@ export function wrap(node: any, { depth = 1 } = {}) {
ret.attributes = attributes
}

if (node.shadowRoot) {
ret.shadowRoots = [wrap(node.shadowRoot, { depth: 1 })]
} else if (node.__shadowRoot__) {
ret.shadowRoots = [wrap(node.__shadowRoot__, { depth: 1 })]
}
if (isShadowRoot(node)) {
ret.shadowRootType = node.mode || 'user-agent'
}

const childNodes = filterNodes(node.childNodes)
ret.childNodeCount = childNodes.length
const hasOneTextNode =
@@ -114,9 +123,17 @@ export function isValidNode(node: Node): boolean {
export function getNode(nodeId: number) {
const node = nodes.get(nodeId)

if (!node || node.nodeType === 10) {
if (!node || node.nodeType === 10 || node.nodeType === 11) {
throw createErr(-32000, 'Could not find node with given id')
}

return node
}

function isShadowRoot(node: any) {
if (window.ShadowRoot) {
return node instanceof ShadowRoot
}

return false
}

0 comments on commit f0908c1

Please sign in to comment.