Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 6597826

Browse files
committed
[FIX] Devtools: can use inspect dom into iframe
1 parent bad60f9 commit 6597826

File tree

1 file changed

+43
-13
lines changed

1 file changed

+43
-13
lines changed

packages/plugin-devtools/src/components/InspectorComponent.ts

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Layout } from '../../../plugin-layout/src/Layout';
77
import { DomLayoutEngine } from '../../../plugin-dom-layout/src/DomLayoutEngine';
88
import { caretPositionFromPoint } from '../../../utils/src/polyfill';
99
import { CharNode } from '../../../plugin-char/src/CharNode';
10+
import { nodeName } from '../../../utils/src/utils';
1011

1112
const hoverStyle = 'box-shadow: inset 0 0 0 100vh rgba(95, 146, 204, 0.5); cursor: pointer;';
1213

@@ -31,9 +32,11 @@ export class InspectorComponent extends OwlComponent<InspectorComponentProps> {
3132
selectedID: this.domEngine.components.get('editable')[0]?.id || this.domEngine.root.id,
3233
};
3334
selectedNode = this.getNode(this.state.selectedID);
35+
private _inspecting = new Set<Document | ShadowRoot>();
3436

3537
constructor(parent?: OwlComponent<{}>, props?: InspectorComponentProps) {
3638
super(parent, props);
39+
this._onInspectorMouseEnter = this._onInspectorMouseEnter.bind(this);
3740
this._onInspectorMouseMove = this._onInspectorMouseMove.bind(this);
3841
this._onInspectorMouseLeave = this._onInspectorMouseLeave.bind(this);
3942
this._onInspectorMouseDown = this._onInspectorMouseDown.bind(this);
@@ -126,17 +129,32 @@ export class InspectorComponent extends OwlComponent<InspectorComponentProps> {
126129
*
127130
* @param ev
128131
*/
129-
inspectDom(): void {
130-
window.addEventListener('mousemove', this._onInspectorMouseMove, true);
131-
window.addEventListener('mouseleave', this._onInspectorMouseLeave, true);
132-
window.addEventListener('mousedown', this._onInspectorMouseDown, true);
133-
window.addEventListener('click', this._onInspectorClick, true);
132+
inspectDom(doc: Document | ShadowRoot = document): void {
133+
if (!this._inspecting.has(doc)) {
134+
this._inspecting.add(doc);
135+
doc.addEventListener('mouseenter', this._onInspectorMouseEnter, true);
136+
doc.addEventListener('mousemove', this._onInspectorMouseMove, true);
137+
doc.addEventListener('mouseleave', this._onInspectorMouseLeave, true);
138+
doc.addEventListener('mousedown', this._onInspectorMouseDown, true);
139+
doc.addEventListener('click', this._onInspectorClick, true);
140+
}
134141
}
135142

136143
//--------------------------------------------------------------------------
137144
// Private
138145
//--------------------------------------------------------------------------
139146

147+
private async _onInspectorMouseEnter(ev: MouseEvent): Promise<void> {
148+
const el = ev.target as Element;
149+
if (nodeName(el) === 'IFRAME') {
150+
const doc = (ev.target as HTMLIFrameElement).contentWindow?.document;
151+
if (doc) {
152+
this.inspectDom(doc);
153+
}
154+
} else if (el.shadowRoot) {
155+
this.inspectDom(el.shadowRoot);
156+
}
157+
}
140158
/**
141159
* Add a class to highlight the targeted node (like to VNode).
142160
*
@@ -151,7 +169,11 @@ export class InspectorComponent extends OwlComponent<InspectorComponentProps> {
151169
this._hoveredTargets = [];
152170

153171
const elements: HTMLElement[] = [];
154-
for (const node of this._getNodeFromPosition(ev.clientX, ev.clientY)) {
172+
for (const node of this._getNodeFromPosition(
173+
ev.clientX,
174+
ev.clientY,
175+
(ev.target as Node).ownerDocument,
176+
)) {
155177
for (const domNode of this.domEngine.getDomNodes(node)) {
156178
const element = domNode instanceof HTMLElement ? domNode : domNode.parentElement;
157179
if (!elements.includes(element)) {
@@ -192,8 +214,8 @@ export class InspectorComponent extends OwlComponent<InspectorComponentProps> {
192214
ev.stopImmediatePropagation();
193215
ev.preventDefault();
194216
}
195-
private _getNodeFromPosition(clientX: number, clientY: number): VNode[] {
196-
const caretPosition = caretPositionFromPoint(clientX, clientY);
217+
private _getNodeFromPosition(clientX: number, clientY: number, doc: Document): VNode[] {
218+
const caretPosition = caretPositionFromPoint(clientX, clientY, doc);
197219
let node = caretPosition?.offsetNode;
198220
let nodes = [];
199221
while (!nodes.length && node) {
@@ -211,18 +233,26 @@ export class InspectorComponent extends OwlComponent<InspectorComponentProps> {
211233
* @param ev
212234
*/
213235
private async _onInspectorClick(ev: MouseEvent): Promise<void> {
214-
window.removeEventListener('mousemove', this._onInspectorMouseMove, true);
215-
window.removeEventListener('mouseleave', this._onInspectorMouseLeave, true);
216-
window.removeEventListener('mousedown', this._onInspectorMouseDown, true);
217-
window.removeEventListener('click', this._onInspectorClick, true);
236+
for (const doc of this._inspecting) {
237+
doc.removeEventListener('mouseenter', this._onInspectorMouseEnter, true);
238+
doc.removeEventListener('mousemove', this._onInspectorMouseMove, true);
239+
doc.removeEventListener('mouseleave', this._onInspectorMouseLeave, true);
240+
doc.removeEventListener('mousedown', this._onInspectorMouseDown, true);
241+
doc.removeEventListener('click', this._onInspectorClick, true);
242+
}
243+
this._inspecting.clear();
218244
ev.stopImmediatePropagation();
219245
ev.preventDefault();
220246
for (const inspected of this._hoveredTargets) {
221247
inspected.element.setAttribute('style', inspected.oldStyle);
222248
}
223249
this._hoveredTargets = [];
224250

225-
const nodes = this._getNodeFromPosition(ev.clientX, ev.clientY);
251+
const nodes = this._getNodeFromPosition(
252+
ev.clientX,
253+
ev.clientY,
254+
(ev.target as Node).ownerDocument,
255+
);
226256
if (nodes.length) {
227257
this.state.selectedID = nodes[0].id;
228258
this.selectedNode = this.getNode(this.state.selectedID);

0 commit comments

Comments
 (0)