Skip to content

Commit

Permalink
Refactor to properly cleanup devtool artifacts (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
hopsoft authored Jan 29, 2023
1 parent 04035dd commit 9aa1784
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 61 deletions.
26 changes: 13 additions & 13 deletions app/assets/builds/@turbo-boost/elements.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions app/assets/builds/@turbo-boost/elements.js.map

Large diffs are not rendered by default.

24 changes: 17 additions & 7 deletions app/javascript/elements/toggle_elements/target_element/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default class ToggleTargetElement extends ToggleElement {
this.innerHTML = ''
try {
this.expanded = false
this.currentTriggerElement.hideDevtool()
this.triggerElement.hideDevtool()
} catch {}
}

Expand All @@ -86,7 +86,7 @@ export default class ToggleTargetElement extends ToggleElement {

get collapseSelector () {
return (
this.currentTriggerElement.collapseSelector ||
this.triggerElement.collapseSelector ||
this.getAttribute('collapse-selector')
)
}
Expand All @@ -99,15 +99,25 @@ export default class ToggleTargetElement extends ToggleElement {
}

get focusSelector () {
if (this.currentTriggerElement && this.currentTriggerElement.focusSelector)
return this.currentTriggerElement.focusSelector
return this.getAttribute('focus-selector')
let value = this.getAttribute('focus-selector')
if (this.triggerElement)
value = this.triggerElement.getAttribute('focus-selector') || value
return value
}

get focusElement () {
return this.querySelector(this.focusSelector)
}

get triggerElement () {
return (
document.getElementById(this.labeledBy) ||
document.querySelector(
`turbo-boost-toggle-trigger[aria-controls="${this.id}"]`
)
)
}

get labeledBy () {
return this.getAttribute('aria-labeledby')
}
Expand All @@ -119,10 +129,10 @@ export default class ToggleTargetElement extends ToggleElement {
}

get expanded () {
return this.currentTriggerElement.expanded
return this.triggerElement.expanded
}

set expanded (value) {
return (this.currentTriggerElement.expanded = value)
return (this.triggerElement.expanded = value)
}
}
104 changes: 68 additions & 36 deletions app/javascript/elements/toggle_elements/trigger_element/devtool.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import {
appendHTML,
addHighlight,
attempt,
coordinates,
removeHighlight
} from '../../../utils/dom'
Expand Down Expand Up @@ -34,43 +35,59 @@ export default class Devtool {
this.targetElement = triggerElement.targetElement // SEE: app/javascript/elements/toggle_target_element.js
this.morphElement = triggerElement.morphElement

document.addEventListener('turbo-boost:devtool-enable', event => {
const { name } = event.detail
if (name === this.name) {
addHighlight(this.triggerElement, {
outline: '3px dashed blueviolet',
outlineOffset: '2px'
})
}
})

document.addEventListener('turbo-boost:devtool-disable', event => {
const { name } = event.detail
if (name === this.name) removeHighlight(this.triggerElement)
})

let hideTimeout
const debouncedHide = () => {
clearTimeout(hideTimeout)
hideTimeout = setTimeout(this.hide({ active: false }), 25)
}

addEventListener('click', event => {
if (event.target.closest('turbo-boost-devtool-tooltip')) return
debouncedHide()
})
this.eventListeners['turbo-boost:devtool-enable'] = event => {
// LeaderLine.positionByWindowResize = false
const { name } = event.detail
if (name !== this.name) return

addHighlight(this.triggerElement, {
outline: '3px dashed blueviolet',
outlineOffset: '2px'
})

addEventListener('resize', () => {
if (this.active) {
this.hide({ active: false })
this.show()
}
}

this.eventListeners['turbo-boost:devtool-disable'] = event => {
const { name } = event.detail
if (name === this.name) removeHighlight(this.triggerElement)
}

this.eventListeners['click'] = event => {
if (event.target.closest('turbo-boost-devtool-tooltip')) return
debouncedHide()
}

this.eventListeners['turbo:load'] = debouncedHide
this.eventListeners['turbo-frame:load'] = debouncedHide
this.eventListeners[TurboBoost.Commands.events.finish] = debouncedHide

this.registerEventListeners()
}

registerEventListeners () {
Object.entries(this.eventListeners).forEach(([type, listener]) => {
addEventListener(type, listener)
})
}

addEventListener('turbo:load', debouncedHide)
addEventListener('turbo-frame:load', debouncedHide)
addEventListener(TurboBoost.Commands.events.success, debouncedHide)
addEventListener(TurboBoost.Commands.events.finish, debouncedHide)
unregisterEventListeners () {
Object.entries(this.eventListeners).forEach(([type, listener]) => {
removeEventListener(type, listener)
})
}

get eventListeners () {
return this._eventListeners || (this._eventListeners = {})
}

get enabled () {
Expand All @@ -88,8 +105,10 @@ export default class Devtool {

show () {
if (!this.enabled) return

if (this.active) return
this.active = true

this.hide({ active: true })

addHighlight(this.targetElement, {
Expand All @@ -102,9 +121,12 @@ export default class Devtool {
outlineOffset: '3px'
})

const morphTooltip = this.createMorphTooltip()
const targetTooltip = this.createTargetTooltip()
this.createTriggerTooltip(targetTooltip, morphTooltip)
this.renderingTooltip = this.createRenderingTooltip()
this.targetTooltip = this.createTargetTooltip()
this.triggerTooltip = this.createTriggerTooltip(
this.targetTooltip,
this.renderingTooltip
)

document
.querySelectorAll('.leader-line')
Expand Down Expand Up @@ -140,10 +162,15 @@ export default class Devtool {
}

hide ({ active: active = false }) {
document.querySelectorAll('.leader-line').forEach(el => el.remove())
document
.querySelectorAll('turbo-boost-devtool-tooltip')
.forEach(el => el.remove())
.forEach(tooltip => {
attempt(() => tooltip.line.remove())
attempt(() => tooltip.drag.remove())
attempt(() => tooltip.lineToRendering.remove())
attempt(() => tooltip.lineToTarget.remove())
attempt(() => tooltip.remove())
})

document.querySelectorAll('[data-turbo-boost-highlight]').forEach(el => {
if (!el.tagName.match(/turbo-boost-toggle-trigger/i)) removeHighlight(el)
Expand All @@ -152,10 +179,15 @@ export default class Devtool {
this.active = active
}

createMorphTooltip () {
createRenderingTooltip () {
if (!this.triggerElement.renders)
return console.debug(
`Unable to create the rendering tooltip! The trigger element must set the 'renders' attribute.`
)

if (!this.triggerElement.morphs)
return console.debug(
`Unable to create the morph tooltip! No element matches the DOM id: '${this.triggerElement.morphs}'`
`Unable to create the rendering tooltip! The trigger element specified the 'morphs' attrbiute but no element matches the DOM id: '${this.triggerElement.morphs}'`
)

const title = `
Expand Down Expand Up @@ -245,7 +277,7 @@ export default class Devtool {
return tooltip
}

createTriggerTooltip (targetTooltip, morphTooltip) {
createTriggerTooltip (targetTooltip, renderingTooltip) {
if (!this.triggerElement) return
const title = `
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline;" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
Expand Down Expand Up @@ -305,16 +337,16 @@ export default class Devtool {
}
}

if (morphTooltip) {
tooltip.lineToRendering = new LeaderLine(tooltip, morphTooltip, {
if (renderingTooltip) {
tooltip.lineToRendering = new LeaderLine(tooltip, renderingTooltip, {
...this.leaderLineOptions,
color: 'blueviolet',
middleLabel: 'renders & morphs',
size: 2.1
})

morphTooltip.drag.onMove = () => {
morphTooltip.line.position()
renderingTooltip.drag.onMove = () => {
renderingTooltip.line.position()
if (tooltip.lineToTarget) tooltip.lineToTarget.position()
tooltip.lineToRendering.position()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default class ToggleTriggerElement extends ToggleElement {
removeEventListener(beforeInvokeEvent, this.beforeInvokeHandler)

this.devtool.hide({ active: false })
this.devtool.unregisterEventListeners()
delete this.devtool
}

Expand All @@ -45,6 +46,8 @@ export default class ToggleTriggerElement extends ToggleElement {

addEventListener('turbo-boost:devtools-stop', () => {
this.removeEventListener('mouseenter', mouseenter)
this.devtool.hide({ active: false })
this.devtool.unregisterEventListeners()
delete this.devtool
})

Expand All @@ -58,7 +61,6 @@ export default class ToggleTriggerElement extends ToggleElement {
}

onCommandStart (event) {
this.targetElement.currentTriggerElement = this
this.targetElement.setAttribute('aria-labeledby', this.id)
this.targetElement.collapseMatches()
this.targetElement.busy = true
Expand Down Expand Up @@ -144,7 +146,10 @@ export default class ToggleTriggerElement extends ToggleElement {
}

get focusSelector () {
return this.getAttribute('focus-selector')
return (
this.getAttribute('focus-selector') ||
this.targetElement.getAttribute('focus-selector')
)
}

// indicates if the toggle state should be remembered across requests
Expand Down
6 changes: 6 additions & 0 deletions app/javascript/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,9 @@ export function coordinates (element) {
const bottom = top + height
return { top, left, right, bottom, width, height }
}

export function attempt (callback) {
try {
callback()
} catch {}
}

0 comments on commit 9aa1784

Please sign in to comment.