Interactive Functions
Functions that require user interaction or wait for events.
selectElement
Interactive element picker - user clicks to select.
window.__devtool.selectElement()
Parameters: None
Returns: Promise that resolves when user clicks:
{
selector: "#user-avatar",
element: {
tag: "img",
id: "user-avatar",
classes: ["avatar", "rounded"],
attributes: {src: "/images/user.png", alt: "User"}
},
position: {x: 150, y: 200},
path: "html > body > header > div.user-info > img#user-avatar"
}
When cancelled (Escape key):
{
cancelled: true,
message: "Selection cancelled by user"
}
User Experience:
- Cursor changes to crosshair
- Hovered elements are highlighted
- Click to select
- Press Escape to cancel
Example via MCP:
proxy {action: "exec", id: "app", code: "window.__devtool.selectElement()"}
The exec waits for the Promise to resolve.
measureBetween
Measure the distance between two elements.
window.__devtool.measureBetween(selector1, selector2)
Parameters:
selector1(string): CSS selector for first elementselector2(string): CSS selector for second element
Returns:
{
distance: {
x: 0,
y: 150,
diagonal: 150
},
direction: "below",
gap: {
horizontal: 0,
vertical: 100 // Empty space between elements
},
element1: {
center: {x: 400, y: 100},
bounds: {top: 50, left: 300, width: 200, height: 100}
},
element2: {
center: {x: 400, y: 350},
bounds: {top: 250, left: 300, width: 200, height: 200}
}
}
Direction values:
"above","below","left","right""above-left","above-right","below-left","below-right""overlapping"(centers are at same position)
Example:
window.__devtool.measureBetween('#header', '#footer')
→ {distance: {y: 850}, gap: {vertical: 800}, direction: "below"}
waitForElement
Wait for an element to appear in the DOM.
window.__devtool.waitForElement(selector, timeout)
Parameters:
selector(string): CSS selector to wait fortimeout(number, optional): Maximum wait time in ms (default: 5000)
Returns: Promise that resolves when element appears:
{
found: true,
element: {
tag: "div",
classes: ["loading-complete"],
id: ""
},
waited: 1234 // milliseconds
}
When timeout:
{
found: false,
timeout: true,
waited: 5000,
message: "Element not found within 5000ms"
}
Example:
// Wait for loading to complete
await window.__devtool.waitForElement('.data-loaded', 10000)
// Then inspect the content
window.__devtool.inspect('.data-content')
How it works:
- Uses MutationObserver for efficiency
- Checks immediately first
- No polling - responds as soon as element appears
ask
Show a modal dialog to ask the user a question.
window.__devtool.ask(question, options, config)
Parameters:
question(string): The question to displayoptions(string[]): Array of answer optionsconfig(object, optional): Configuration
Config Options:
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 30000 | Auto-dismiss timeout in ms |
allowCancel | boolean | true | Show cancel button |
defaultOption | number | null | Pre-selected option index |
Returns: Promise that resolves with user selection:
{
answer: "Option A",
index: 0,
cancelled: false
}
When cancelled:
{
answer: null,
index: null,
cancelled: true
}
When timeout:
{
answer: null,
index: null,
timeout: true
}
Examples:
Simple yes/no:
window.__devtool.ask('Is this the correct element?', ['Yes', 'No'])
Multiple options:
window.__devtool.ask('Which layout looks better?', [
'Grid layout',
'Flex layout',
'Table layout',
'None of these'
])
With timeout:
window.__devtool.ask('Continue with changes?', ['Yes', 'No'], {
timeout: 10000
})
User Experience:
- Modal appears centered on screen
- Click option button to select
- Click cancel or press Escape to dismiss
- Auto-dismisses after timeout
Common Patterns
Interactive Element Selection Workflow
// Let user select element
const selected = await window.__devtool.selectElement()
if (selected.cancelled) {
console.log('User cancelled selection')
return
}
// Inspect the selected element
const info = window.__devtool.inspect(selected.selector)
// Ask what to do
const action = await window.__devtool.ask('What would you like to do?', [
'Show layout',
'Check accessibility',
'Measure from here'
])
if (action.answer === 'Show layout') {
window.__devtool.showLayout()
} else if (action.answer === 'Check accessibility') {
const a11y = window.__devtool.getA11yInfo(selected.selector)
console.log(a11y)
} else if (action.answer === 'Measure from here') {
const second = await window.__devtool.selectElement()
const measure = window.__devtool.measureBetween(selected.selector, second.selector)
console.log(measure)
}
Wait for Dynamic Content
// Click a button that loads content
document.querySelector('#load-data').click()
// Wait for content to appear
const result = await window.__devtool.waitForElement('.data-container', 10000)
if (result.found) {
// Now safe to inspect
const data = window.__devtool.inspect('.data-container')
console.log(`Loaded in ${result.waited}ms`)
}
Spacing Verification
// Measure spacing between elements
const headerToNav = window.__devtool.measureBetween('#header', '#nav')
const navToContent = window.__devtool.measureBetween('#nav', '#content')
console.log('Header to nav gap:', headerToNav.gap.vertical, 'px')
console.log('Nav to content gap:', navToContent.gap.vertical, 'px')
// Check consistency
if (headerToNav.gap.vertical !== navToContent.gap.vertical) {
console.warn('Inconsistent spacing!')
}
User Confirmation Before Changes
// Show what will change
window.__devtool.highlight('.affected-elements', {color: 'yellow', duration: 0})
// Ask for confirmation
const confirm = await window.__devtool.ask(
'These elements will be modified. Proceed?',
['Yes, proceed', 'No, cancel'],
{timeout: 60000}
)
window.__devtool.clearAllOverlays()
if (confirm.answer === 'Yes, proceed') {
// Make changes
} else {
console.log('User cancelled')
}
Multi-Step Selection
async function measureMultiple() {
const points = []
while (true) {
const action = await window.__devtool.ask(
`${points.length} points selected. What next?`,
['Add point', 'Finish', 'Cancel']
)
if (action.answer === 'Cancel' || action.cancelled) {
return null
}
if (action.answer === 'Finish') {
break
}
const point = await window.__devtool.selectElement()
if (!point.cancelled) {
points.push(point)
window.__devtool.highlight(point.selector, {
label: `Point ${points.length}`,
duration: 0
})
}
}
return points
}
See Also
- Visual Overlays - Highlight selected elements
- Element Inspection - Inspect after selection