turbo_boost-elements 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/builds/@turbo-boost/commands.metafile.json +1 -0
- data/app/assets/builds/@turbo-boost/elements.js +34 -39
- data/app/assets/builds/@turbo-boost/elements.js.map +4 -4
- data/app/assets/builds/@turbo-boost/elements.metafile.json +1 -0
- data/app/javascript/elements/toggle_elements/target_element/index.js +20 -24
- data/app/javascript/elements/toggle_elements/toggle_element/index.js +10 -10
- data/app/javascript/elements/toggle_elements/trigger_element/focus.js +6 -22
- data/app/javascript/elements/toggle_elements/trigger_element/index.js +102 -66
- data/app/javascript/elements/turbo_boost_element/index.js +7 -10
- data/app/javascript/index.js +1 -1
- data/lib/turbo_boost/elements/version.rb +1 -1
- metadata +5 -11
- data/app/javascript/devtools/dependencies.js +0 -53
- data/app/javascript/devtools/elements/devtool_element.js +0 -75
- data/app/javascript/devtools/elements/supervisor_element.js +0 -136
- data/app/javascript/devtools/elements/tooltip_element.js +0 -121
- data/app/javascript/devtools/index.js +0 -5
- data/app/javascript/devtools/supervisor.js +0 -116
- data/app/javascript/elements/toggle_elements/trigger_element/devtool.js +0 -374
- data/app/javascript/utils/dom.js +0 -70
@@ -0,0 +1 @@
|
|
1
|
+
{"inputs":{"node_modules/@turbo-boost/commands/app/assets/builds/@turbo-boost/commands.js":{"bytes":11151,"imports":[],"format":"esm"},"node_modules/@turbo-boost/devtools/dist/@turbo-boost/devtools.js":{"bytes":19326,"imports":[],"format":"esm"},"app/javascript/elements/turbo_boost_element/index.js":{"bytes":844,"imports":[],"format":"esm"},"app/javascript/elements/toggle_elements/toggle_element/index.js":{"bytes":2193,"imports":[{"path":"app/javascript/elements/turbo_boost_element/index.js","kind":"import-statement","original":"../../turbo_boost_element"}],"format":"esm"},"app/javascript/elements/toggle_elements/target_element/index.js":{"bytes":3370,"imports":[{"path":"app/javascript/elements/toggle_elements/toggle_element/index.js","kind":"import-statement","original":"../toggle_element"}],"format":"esm"},"app/javascript/elements/toggle_elements/trigger_element/focus.js":{"bytes":1585,"imports":[],"format":"esm"},"app/javascript/elements/toggle_elements/trigger_element/index.js":{"bytes":7168,"imports":[{"path":"node_modules/@turbo-boost/devtools/dist/@turbo-boost/devtools.js","kind":"import-statement","original":"@turbo-boost/devtools"},{"path":"app/javascript/elements/toggle_elements/toggle_element/index.js","kind":"import-statement","original":"../toggle_element"},{"path":"app/javascript/elements/toggle_elements/trigger_element/focus.js","kind":"import-statement","original":"./focus"}],"format":"esm"},"app/javascript/elements/index.js":{"bytes":481,"imports":[{"path":"app/javascript/elements/turbo_boost_element/index.js","kind":"import-statement","original":"./turbo_boost_element"},{"path":"app/javascript/elements/toggle_elements/target_element/index.js","kind":"import-statement","original":"./toggle_elements/target_element"},{"path":"app/javascript/elements/toggle_elements/trigger_element/index.js","kind":"import-statement","original":"./toggle_elements/trigger_element"}],"format":"esm"},"app/javascript/index.js":{"bytes":244,"imports":[{"path":"node_modules/@turbo-boost/commands/app/assets/builds/@turbo-boost/commands.js","kind":"import-statement","original":"@turbo-boost/commands"},{"path":"node_modules/@turbo-boost/devtools/dist/@turbo-boost/devtools.js","kind":"import-statement","original":"@turbo-boost/devtools"},{"path":"app/javascript/elements/index.js","kind":"import-statement","original":"./elements"}],"format":"esm"}},"outputs":{"app/assets/builds/@turbo-boost/elements.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":92571},"app/assets/builds/@turbo-boost/elements.js":{"imports":[],"exports":["default"],"entryPoint":"app/javascript/index.js","inputs":{"node_modules/@turbo-boost/commands/app/assets/builds/@turbo-boost/commands.js":{"bytesInOutput":11085},"node_modules/@turbo-boost/devtools/dist/@turbo-boost/devtools.js":{"bytesInOutput":19262},"app/javascript/elements/turbo_boost_element/index.js":{"bytesInOutput":541},"app/javascript/elements/toggle_elements/toggle_element/index.js":{"bytesInOutput":1284},"app/javascript/elements/toggle_elements/target_element/index.js":{"bytesInOutput":2040},"app/javascript/elements/toggle_elements/trigger_element/focus.js":{"bytesInOutput":768},"app/javascript/elements/toggle_elements/trigger_element/index.js":{"bytesInOutput":4299},"app/javascript/elements/index.js":{"bytesInOutput":146},"app/javascript/index.js":{"bytesInOutput":124}},"bytes":39609}}}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import ToggleElement from '../toggle_element'
|
2
2
|
|
3
3
|
export default class ToggleTargetElement extends ToggleElement {
|
4
|
-
connectedCallback
|
4
|
+
connectedCallback() {
|
5
5
|
super.connectedCallback()
|
6
6
|
|
7
7
|
this.mouseenterHandler = this.onMouseenter.bind(this)
|
@@ -23,7 +23,7 @@ export default class ToggleTargetElement extends ToggleElement {
|
|
23
23
|
})
|
24
24
|
}
|
25
25
|
|
26
|
-
disconnectedCallback
|
26
|
+
disconnectedCallback() {
|
27
27
|
this.removeEventListener('mouseenter', this.mouseenterHandler)
|
28
28
|
|
29
29
|
this.collapseOn.forEach(entry => {
|
@@ -43,27 +43,26 @@ export default class ToggleTargetElement extends ToggleElement {
|
|
43
43
|
// perhaps use a mechanic other than morph
|
44
44
|
|
45
45
|
// TODO: implement cache (similar to Turbo Drive restoration visit)
|
46
|
-
cacheHTML
|
46
|
+
cacheHTML() {
|
47
47
|
// this.cachedHTML = this.innerHTML
|
48
48
|
}
|
49
49
|
|
50
50
|
// TODO: implement cache (similar to Turbo Drive restoration visit)
|
51
|
-
renderCachedHTML
|
51
|
+
renderCachedHTML() {
|
52
52
|
// if (!this.cachedHTML) return
|
53
53
|
// this.innerHTML = this.cachedHTML
|
54
54
|
}
|
55
55
|
|
56
|
-
onMouseenter
|
56
|
+
onMouseenter() {
|
57
57
|
clearTimeout(this.collapseTimeout)
|
58
58
|
}
|
59
59
|
|
60
|
-
collapse
|
60
|
+
collapse(delay = 250) {
|
61
61
|
clearTimeout(this.collapseTimeout)
|
62
62
|
if (this.busy) return
|
63
63
|
if (typeof delay !== 'number') delay = 250
|
64
64
|
|
65
|
-
if (delay > 0)
|
66
|
-
return (this.collapseTimeout = setTimeout(() => this.collapse(0), delay))
|
65
|
+
if (delay > 0) return (this.collapseTimeout = setTimeout(() => this.collapse(0), delay))
|
67
66
|
|
68
67
|
this.innerHTML = ''
|
69
68
|
try {
|
@@ -72,63 +71,60 @@ export default class ToggleTargetElement extends ToggleElement {
|
|
72
71
|
} catch {}
|
73
72
|
}
|
74
73
|
|
75
|
-
collapseNow
|
74
|
+
collapseNow(event) {
|
76
75
|
if (event.target.closest('turbo-boost-devtool-tooltip')) return
|
77
76
|
this.collapse(0)
|
78
77
|
}
|
79
78
|
|
80
|
-
collapseMatches
|
79
|
+
collapseMatches() {
|
81
80
|
document.querySelectorAll(this.collapseSelector).forEach(el => {
|
82
81
|
if (el.id === this.id) return
|
83
82
|
if (el.collapse) el.collapse(0)
|
84
83
|
})
|
85
84
|
}
|
86
85
|
|
87
|
-
get collapseSelector
|
88
|
-
return (
|
89
|
-
this.triggerElement.collapseSelector ||
|
90
|
-
this.getAttribute('collapse-selector')
|
91
|
-
)
|
86
|
+
get collapseSelector() {
|
87
|
+
return this.triggerElement.collapseSelector || this.getAttribute('collapse-selector')
|
92
88
|
}
|
93
89
|
|
94
|
-
get focusSelector
|
90
|
+
get focusSelector() {
|
95
91
|
return this.getAttribute('focus-selector')
|
96
92
|
}
|
97
93
|
|
98
94
|
// the active trigger
|
99
|
-
get triggerElement
|
95
|
+
get triggerElement() {
|
100
96
|
return document.getElementById(this.labeledBy)
|
101
97
|
}
|
102
98
|
|
103
99
|
// all triggers
|
104
|
-
get triggerElements
|
100
|
+
get triggerElements() {
|
105
101
|
return document.querySelectorAll(`[aria-controls="${this.id}"]`)
|
106
102
|
}
|
107
103
|
|
108
104
|
// the dom id of the active trigger
|
109
|
-
get labeledBy
|
105
|
+
get labeledBy() {
|
110
106
|
return this.getAttribute('aria-labeledby')
|
111
107
|
}
|
112
108
|
|
113
|
-
set labeledBy
|
109
|
+
set labeledBy(value) {
|
114
110
|
return this.setAttribute('aria-labeledby', value)
|
115
111
|
}
|
116
112
|
|
117
|
-
get collapseOn
|
113
|
+
get collapseOn() {
|
118
114
|
const value = this.getAttribute('collapse-on')
|
119
115
|
if (!value) return []
|
120
116
|
return JSON.parse(value)
|
121
117
|
}
|
122
118
|
|
123
|
-
get expanded
|
119
|
+
get expanded() {
|
124
120
|
return this.triggerElement ? this.triggerElement.expanded : false
|
125
121
|
}
|
126
122
|
|
127
|
-
set expanded
|
123
|
+
set expanded(value) {
|
128
124
|
this.triggerElements.forEach(el => (el.expanded = value))
|
129
125
|
}
|
130
126
|
|
131
|
-
get busy
|
127
|
+
get busy() {
|
132
128
|
return this.triggerElement && this.triggerElement.busy
|
133
129
|
}
|
134
130
|
}
|
@@ -11,13 +11,13 @@ export const busyDelay = 100 // milliseconds - time to wait before showing busy
|
|
11
11
|
export const busyDuration = 400 // milliseconds - minimum time that busy element is shown
|
12
12
|
|
13
13
|
export default class ToggleElement extends TurboBoostElement {
|
14
|
-
constructor
|
14
|
+
constructor() {
|
15
15
|
super(html)
|
16
16
|
}
|
17
17
|
|
18
18
|
// TODO: Should we timeout after a theoretical max wait time?
|
19
19
|
// The idea being that a server error occurred and the toggle failed.
|
20
|
-
showBusyElement
|
20
|
+
showBusyElement() {
|
21
21
|
clearTimeout(this.showBusyElementTimeout)
|
22
22
|
clearTimeout(this.hideBusyElementTimeout)
|
23
23
|
|
@@ -30,7 +30,7 @@ export default class ToggleElement extends TurboBoostElement {
|
|
30
30
|
}, busyDelay)
|
31
31
|
}
|
32
32
|
|
33
|
-
hideBusyElement
|
33
|
+
hideBusyElement() {
|
34
34
|
clearTimeout(this.showBusyElementTimeout)
|
35
35
|
clearTimeout(this.hideBusyElementTimeout)
|
36
36
|
|
@@ -46,25 +46,25 @@ export default class ToggleElement extends TurboBoostElement {
|
|
46
46
|
}, delay)
|
47
47
|
}
|
48
48
|
|
49
|
-
get busyElement
|
49
|
+
get busyElement() {
|
50
50
|
return this.querySelector(':scope > [slot="busy"]')
|
51
51
|
}
|
52
52
|
|
53
|
-
get busySlotElement
|
53
|
+
get busySlotElement() {
|
54
54
|
return this.shadowRoot.querySelector('slot[name="busy"]')
|
55
55
|
}
|
56
56
|
|
57
|
-
get defaultSlotElement
|
57
|
+
get defaultSlotElement() {
|
58
58
|
return this.shadowRoot.querySelector('slot:not([name])')
|
59
59
|
}
|
60
60
|
|
61
61
|
// indicates if an rpc call is active/busy
|
62
|
-
get busy
|
62
|
+
get busy() {
|
63
63
|
return this.getAttribute('busy') === 'true'
|
64
64
|
}
|
65
65
|
|
66
66
|
// indicates if an rpc call is active/busy
|
67
|
-
set busy
|
67
|
+
set busy(value) {
|
68
68
|
value = !!value
|
69
69
|
if (this.busy === value) return
|
70
70
|
this.setAttribute('busy', value)
|
@@ -72,12 +72,12 @@ export default class ToggleElement extends TurboBoostElement {
|
|
72
72
|
else this.hideBusyElement()
|
73
73
|
}
|
74
74
|
|
75
|
-
get busyStartedAt
|
75
|
+
get busyStartedAt() {
|
76
76
|
if (!this.dataset.busyStartedAt) return 0
|
77
77
|
return Number(this.dataset.busyStartedAt)
|
78
78
|
}
|
79
79
|
|
80
|
-
set busyStartedAt
|
80
|
+
set busyStartedAt(value) {
|
81
81
|
this.dataset.busyStartedAt = value
|
82
82
|
}
|
83
83
|
}
|
@@ -1,31 +1,18 @@
|
|
1
1
|
let focusTimeout
|
2
2
|
|
3
|
-
function deactivateTrixAttributes
|
4
|
-
const attributes = [
|
5
|
-
'bold',
|
6
|
-
'bullet',
|
7
|
-
'code',
|
8
|
-
'heading1',
|
9
|
-
'href',
|
10
|
-
'italic',
|
11
|
-
'number',
|
12
|
-
'quote',
|
13
|
-
'strike'
|
14
|
-
]
|
3
|
+
function deactivateTrixAttributes(editor) {
|
4
|
+
const attributes = ['bold', 'bullet', 'code', 'heading1', 'href', 'italic', 'number', 'quote', 'strike']
|
15
5
|
attributes.forEach(name => editor.deactivateAttribute(name))
|
16
6
|
}
|
17
7
|
|
18
|
-
function focusTrixEditorElement
|
8
|
+
function focusTrixEditorElement(element) {
|
19
9
|
if (element.value.length === 0) return
|
20
10
|
|
21
11
|
const editor = element.editor
|
22
12
|
|
23
13
|
// move cursor to the end
|
24
14
|
let lastRange = []
|
25
|
-
while (
|
26
|
-
lastRange[0] !== editor.getSelectedRange()[0] &&
|
27
|
-
lastRange[1] !== editor.getSelectedRange()[1]
|
28
|
-
) {
|
15
|
+
while (lastRange[0] !== editor.getSelectedRange()[0] && lastRange[1] !== editor.getSelectedRange()[1]) {
|
29
16
|
lastRange = editor.getSelectedRange()
|
30
17
|
editor.moveCursorInDirection('forward')
|
31
18
|
}
|
@@ -39,13 +26,10 @@ function focusTrixEditorElement (element) {
|
|
39
26
|
deactivateTrixAttributes(editor)
|
40
27
|
|
41
28
|
// move cursor to end and collapse the selection
|
42
|
-
editor.setSelectedRange([
|
43
|
-
editor.getSelectedRange()[1],
|
44
|
-
editor.getSelectedRange()[1]
|
45
|
-
])
|
29
|
+
editor.setSelectedRange([editor.getSelectedRange()[1], editor.getSelectedRange()[1]])
|
46
30
|
}
|
47
31
|
|
48
|
-
function debouncedFocus
|
32
|
+
function debouncedFocus(element) {
|
49
33
|
clearTimeout(focusTimeout)
|
50
34
|
|
51
35
|
focusTimeout = setTimeout(() => {
|
@@ -1,11 +1,20 @@
|
|
1
|
+
import { Devtool, decorateElementWithDevtool } from '@turbo-boost/devtools'
|
2
|
+
|
1
3
|
import ToggleElement, { busyDuration } from '../toggle_element'
|
2
|
-
import Devtool from './devtool'
|
3
4
|
import focus from './focus'
|
4
5
|
|
6
|
+
document.addEventListener('turbo-boost:devtools-start', () => Devtool.register('toggle', 'toggles'))
|
7
|
+
|
5
8
|
let currentFocusSelector
|
6
9
|
|
7
10
|
export default class ToggleTriggerElement extends ToggleElement {
|
8
|
-
|
11
|
+
constructor() {
|
12
|
+
super()
|
13
|
+
|
14
|
+
decorateElementWithDevtool(this, 'toggle', 'toggles')
|
15
|
+
}
|
16
|
+
|
17
|
+
connectedCallback() {
|
9
18
|
super.connectedCallback()
|
10
19
|
|
11
20
|
const { start: commandStartEvent } = TurboBoost.Commands.events
|
@@ -24,7 +33,7 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
24
33
|
this.initializeDevtool()
|
25
34
|
}
|
26
35
|
|
27
|
-
disconnectedCallback
|
36
|
+
disconnectedCallback() {
|
28
37
|
// delay cleanup because the trigger may have been morphed out of the DOM,
|
29
38
|
// but it's needed to apply behavior like focus etc...
|
30
39
|
setTimeout(() => {
|
@@ -34,37 +43,11 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
34
43
|
const { before: beforeInvokeEvent } = TurboBoost.Streams.invokeEvents
|
35
44
|
removeEventListener(beforeInvokeEvent, this.beforeInvokeHandler)
|
36
45
|
|
37
|
-
this.
|
38
|
-
this.devtool.unregisterEventListeners()
|
39
|
-
delete this.devtool
|
46
|
+
this.removeDevtool()
|
40
47
|
}, 1000)
|
41
48
|
}
|
42
49
|
|
43
|
-
|
44
|
-
const mouseenter = () => this.devtool.show()
|
45
|
-
|
46
|
-
addEventListener('turbo-boost:devtools-start', () => {
|
47
|
-
this.devtool = new Devtool(this)
|
48
|
-
this.addEventListener('mouseenter', mouseenter)
|
49
|
-
})
|
50
|
-
|
51
|
-
addEventListener('turbo-boost:devtools-stop', () => {
|
52
|
-
this.removeEventListener('mouseenter', mouseenter)
|
53
|
-
this.devtool.hide({ active: false })
|
54
|
-
this.devtool.unregisterEventListeners()
|
55
|
-
delete this.devtool
|
56
|
-
})
|
57
|
-
|
58
|
-
this.dispatchEvent(
|
59
|
-
new CustomEvent('turbo-boost:devtools-connect', { bubbles: true })
|
60
|
-
)
|
61
|
-
}
|
62
|
-
|
63
|
-
hideDevtool () {
|
64
|
-
if (this.devtool) this.devtool.hide({ active: false })
|
65
|
-
}
|
66
|
-
|
67
|
-
onCommandStart (event) {
|
50
|
+
onCommandStart(event) {
|
68
51
|
currentFocusSelector = this.focusSelector
|
69
52
|
this.targetElement.labeledBy = this.id
|
70
53
|
this.targetElement.collapseMatches()
|
@@ -73,7 +56,7 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
73
56
|
}
|
74
57
|
|
75
58
|
// runs before an invoke turbo stream is executed
|
76
|
-
onBeforeInvoke
|
59
|
+
onBeforeInvoke(event) {
|
77
60
|
// return early if we're not the element responsible for this invoke
|
78
61
|
if (event.detail.method !== 'morph') return
|
79
62
|
if (event.target.id !== this.morphs) return
|
@@ -95,14 +78,11 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
95
78
|
}, delay - 10)
|
96
79
|
|
97
80
|
// runs after the morph is executed
|
98
|
-
setTimeout(
|
99
|
-
() => focus(this.targetElement.querySelector(currentFocusSelector)),
|
100
|
-
delay + 100
|
101
|
-
)
|
81
|
+
setTimeout(() => focus(this.targetElement.querySelector(currentFocusSelector)), delay + 100)
|
102
82
|
}
|
103
83
|
|
104
84
|
// a list of views shared between the trigger and target
|
105
|
-
get sharedViews
|
85
|
+
get sharedViews() {
|
106
86
|
if (!this.targetElement) return []
|
107
87
|
if (!this.targetElement.viewStack) return []
|
108
88
|
const reducer = (memo, view) => {
|
@@ -113,69 +93,125 @@ export default class ToggleTriggerElement extends ToggleElement {
|
|
113
93
|
}
|
114
94
|
|
115
95
|
// the partial to render
|
116
|
-
get renders
|
96
|
+
get renders() {
|
117
97
|
return this.getAttribute('renders')
|
118
98
|
}
|
119
99
|
|
120
100
|
// the renderered partial's top wrapping dom_id
|
121
|
-
get morphs
|
101
|
+
get morphs() {
|
122
102
|
return this.getAttribute('morphs')
|
123
103
|
}
|
124
104
|
|
125
|
-
// the morph element
|
126
|
-
get morphElement () {
|
127
|
-
if (!this.morphs) return null
|
128
|
-
return document.getElementById(this.morphs)
|
129
|
-
}
|
130
|
-
|
131
105
|
// all toggle elements contained by the `morphElement`
|
132
|
-
get morphToggleTriggerElements
|
133
|
-
return Array.from(
|
134
|
-
this.morphElement.querySelectorAll('turbo-boost-toggle-trigger')
|
135
|
-
)
|
106
|
+
get morphToggleTriggerElements() {
|
107
|
+
return Array.from(this.morphElement.querySelectorAll('turbo-boost-toggle-trigger'))
|
136
108
|
}
|
137
109
|
|
138
110
|
// the target's dom_id
|
139
|
-
get controls
|
111
|
+
get controls() {
|
140
112
|
return this.getAttribute('aria-controls')
|
141
113
|
}
|
142
114
|
|
143
|
-
|
144
|
-
get targetElement () {
|
145
|
-
if (!this.controls) return null
|
146
|
-
return document.getElementById(this.controls)
|
147
|
-
}
|
148
|
-
|
149
|
-
get collapseSelector () {
|
115
|
+
get collapseSelector() {
|
150
116
|
return this.getAttribute('collapse-selector')
|
151
117
|
}
|
152
118
|
|
153
|
-
get focusSelector
|
154
|
-
return (
|
155
|
-
this.getAttribute('focus-selector') || this.targetElement.focusSelector
|
156
|
-
)
|
119
|
+
get focusSelector() {
|
120
|
+
return this.getAttribute('focus-selector') || this.targetElement.focusSelector
|
157
121
|
}
|
158
122
|
|
159
123
|
// indicates if the toggle state should be remembered across requests
|
160
|
-
get remember
|
124
|
+
get remember() {
|
161
125
|
return this.getAttribute('remember') === 'true'
|
162
126
|
}
|
163
127
|
|
164
|
-
set remember
|
128
|
+
set remember(value) {
|
165
129
|
return this.setAttribute('remember', !!value)
|
166
130
|
}
|
167
131
|
|
168
132
|
// indicates if the target is expanded
|
169
|
-
get expanded
|
133
|
+
get expanded() {
|
170
134
|
return this.getAttribute('aria-expanded') === 'true'
|
171
135
|
}
|
172
136
|
|
173
|
-
set expanded
|
137
|
+
set expanded(value) {
|
174
138
|
this.setAttribute('aria-expanded', !!value)
|
175
139
|
}
|
176
140
|
|
177
141
|
// indicates if the target is expanded
|
178
|
-
get collapsed
|
142
|
+
get collapsed() {
|
179
143
|
return !this.expanded
|
180
144
|
}
|
145
|
+
|
146
|
+
// ------ DevToolDelegate ------
|
147
|
+
get command() {
|
148
|
+
return this.dataset.turboCommand
|
149
|
+
}
|
150
|
+
|
151
|
+
get renderingLineLabel() {
|
152
|
+
return 'renders & morphs'
|
153
|
+
}
|
154
|
+
|
155
|
+
// the morph element
|
156
|
+
get morphElement() {
|
157
|
+
if (!this.morphs) return null
|
158
|
+
return document.getElementById(this.morphs)
|
159
|
+
}
|
160
|
+
|
161
|
+
// the target element
|
162
|
+
get targetElement() {
|
163
|
+
if (!this.controls) return null
|
164
|
+
return document.getElementById(this.controls)
|
165
|
+
}
|
166
|
+
|
167
|
+
get triggerTooltipData() {
|
168
|
+
let content = this.triggerElement.viewStack
|
169
|
+
.reverse()
|
170
|
+
.map((view, index) => {
|
171
|
+
return this.triggerElement.sharedViews.includes(view)
|
172
|
+
? `<div slot="content">${index + 1}. ${view}</div>`
|
173
|
+
: `<div slot="content-bottom">${index + 1}. ${view}</div>`
|
174
|
+
}, this)
|
175
|
+
.join('')
|
176
|
+
|
177
|
+
return {
|
178
|
+
subtitle: `
|
179
|
+
<b>id</b>: ${this.triggerElement.id}<br>
|
180
|
+
<b>aria-controls</b>: ${this.triggerElement.controls}<br>
|
181
|
+
<b>aria-expanded</b>: ${this.triggerElement.expanded}<br>
|
182
|
+
<b>remember</b>: ${this.triggerElement.remember}<br>
|
183
|
+
`,
|
184
|
+
content: `
|
185
|
+
<div slot="content-top">
|
186
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline-block;" 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="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
|
187
|
+
<b>View Stack</b>
|
188
|
+
</div>
|
189
|
+
${content}
|
190
|
+
`
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
get targetTooltipData() {
|
195
|
+
let content = this.targetElement.viewStack
|
196
|
+
.reverse()
|
197
|
+
.map((view, index) => {
|
198
|
+
return this.triggerElement.sharedViews.includes(view)
|
199
|
+
? `<div slot="content">${index + 1}. ${view}</div>`
|
200
|
+
: `<div slot="content-bottom">${index + 1}. ${view}</div>`
|
201
|
+
}, this)
|
202
|
+
.join('')
|
203
|
+
|
204
|
+
return {
|
205
|
+
subtitle: `<b>id</b>: ${this.targetElement.id}<br>
|
206
|
+
<b>aria-labeled-by</b>: ${this.targetElement.labeledBy}<br>
|
207
|
+
`,
|
208
|
+
content: `
|
209
|
+
<div slot="content-top">
|
210
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display:inline-block;" 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="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
|
211
|
+
<b>View Stack</b>
|
212
|
+
</div>
|
213
|
+
${content}
|
214
|
+
`
|
215
|
+
}
|
216
|
+
}
|
181
217
|
}
|
@@ -1,37 +1,34 @@
|
|
1
1
|
export default class TurboBoostElement extends HTMLElement {
|
2
|
-
constructor
|
2
|
+
constructor(html) {
|
3
3
|
super()
|
4
4
|
this.devtool = 'unknown'
|
5
5
|
this.attachShadow({ mode: 'open' })
|
6
6
|
this.shadowRoot.innerHTML = html || '<slot></slot>'
|
7
7
|
}
|
8
8
|
|
9
|
-
connectedCallback
|
9
|
+
connectedCallback() {
|
10
10
|
this.ensureId()
|
11
11
|
}
|
12
12
|
|
13
|
-
ensureId
|
13
|
+
ensureId() {
|
14
14
|
if (this.id.trim().length) return
|
15
15
|
this.id = `${this.tagName}-${this.uuidv4()}`.toLowerCase()
|
16
16
|
}
|
17
17
|
|
18
18
|
// SEE: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
|
19
|
-
uuidv4
|
19
|
+
uuidv4() {
|
20
20
|
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
|
21
|
-
(
|
22
|
-
c ^
|
23
|
-
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
|
24
|
-
).toString(16)
|
21
|
+
(c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
|
25
22
|
)
|
26
23
|
}
|
27
24
|
|
28
|
-
get viewStack
|
25
|
+
get viewStack() {
|
29
26
|
const value = this.getAttribute('view-stack')
|
30
27
|
if (!value) return []
|
31
28
|
return JSON.parse(value)
|
32
29
|
}
|
33
30
|
|
34
|
-
get partial
|
31
|
+
get partial() {
|
35
32
|
return this.viewStack[0]
|
36
33
|
}
|
37
34
|
}
|
data/app/javascript/index.js
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo_boost-elements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Hopkins (hopsoft)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -132,26 +132,20 @@ extra_rdoc_files: []
|
|
132
132
|
files:
|
133
133
|
- MIT-LICENSE
|
134
134
|
- README.md
|
135
|
+
- app/assets/builds/@turbo-boost/commands.metafile.json
|
135
136
|
- app/assets/builds/@turbo-boost/elements.js
|
136
137
|
- app/assets/builds/@turbo-boost/elements.js.map
|
138
|
+
- app/assets/builds/@turbo-boost/elements.metafile.json
|
137
139
|
- app/commands/turbo_boost/elements/application_command.rb
|
138
140
|
- app/commands/turbo_boost/elements/toggle_command.rb
|
139
141
|
- app/helpers/turbo_boost/elements/application_helper.rb
|
140
|
-
- app/javascript/devtools/dependencies.js
|
141
|
-
- app/javascript/devtools/elements/devtool_element.js
|
142
|
-
- app/javascript/devtools/elements/supervisor_element.js
|
143
|
-
- app/javascript/devtools/elements/tooltip_element.js
|
144
|
-
- app/javascript/devtools/index.js
|
145
|
-
- app/javascript/devtools/supervisor.js
|
146
142
|
- app/javascript/elements/index.js
|
147
143
|
- app/javascript/elements/toggle_elements/target_element/index.js
|
148
144
|
- app/javascript/elements/toggle_elements/toggle_element/index.js
|
149
|
-
- app/javascript/elements/toggle_elements/trigger_element/devtool.js
|
150
145
|
- app/javascript/elements/toggle_elements/trigger_element/focus.js
|
151
146
|
- app/javascript/elements/toggle_elements/trigger_element/index.js
|
152
147
|
- app/javascript/elements/turbo_boost_element/index.js
|
153
148
|
- app/javascript/index.js
|
154
|
-
- app/javascript/utils/dom.js
|
155
149
|
- lib/turbo_boost/elements.rb
|
156
150
|
- lib/turbo_boost/elements/engine.rb
|
157
151
|
- lib/turbo_boost/elements/tag_builders.rb
|
@@ -180,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
180
174
|
- !ruby/object:Gem::Version
|
181
175
|
version: '0'
|
182
176
|
requirements: []
|
183
|
-
rubygems_version: 3.
|
177
|
+
rubygems_version: 3.4.10
|
184
178
|
signing_key:
|
185
179
|
specification_version: 4
|
186
180
|
summary: Pre-built easy to use reactive TurboBoost elements for Rails/Hotwire apps.
|
@@ -1,53 +0,0 @@
|
|
1
|
-
const added = []
|
2
|
-
|
3
|
-
const dependencies = {
|
4
|
-
LeaderLine: {
|
5
|
-
src:
|
6
|
-
'https://cdnjs.cloudflare.com/ajax/libs/leader-line/1.0.7/leader-line.min.js',
|
7
|
-
integrity:
|
8
|
-
'sha512-0dNdzMjpT6pJdFGF1DwybFCfm3K/lzHhxaMXC/92J9/DZujHlqYFqmhTOAoD0o+LkeEsVK2ar/ESs7/Q2B6wJg==',
|
9
|
-
global: 'LeaderLine'
|
10
|
-
},
|
11
|
-
|
12
|
-
PlainDraggable: {
|
13
|
-
src:
|
14
|
-
'https://cdn.jsdelivr.net/npm/plain-draggable@2.5.14/plain-draggable.min.js',
|
15
|
-
global: 'PlainDraggable'
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
|
-
function exists (dependency) {
|
20
|
-
if (dependency.global && self[dependency.global]) return true
|
21
|
-
if (document.querySelector(`[src='${dependency.src}']`)) return true
|
22
|
-
return added.includes(dependency)
|
23
|
-
}
|
24
|
-
|
25
|
-
function add (dependency) {
|
26
|
-
if (exists(dependency)) return
|
27
|
-
added.push(dependency)
|
28
|
-
|
29
|
-
const { src, integrity } = dependency
|
30
|
-
const script = document.createElement('script')
|
31
|
-
script.setAttribute('src', src)
|
32
|
-
script.setAttribute('crossorigin', 'anonymous')
|
33
|
-
script.setAttribute('referrerpolicy', 'no-referrer')
|
34
|
-
if (integrity) script.setAttribute('integrity', integrity)
|
35
|
-
document.head.appendChild(script)
|
36
|
-
}
|
37
|
-
|
38
|
-
function remove (dependency) {
|
39
|
-
if (!added.includes(dependency)) return
|
40
|
-
added.splice(added.indexOf(dependency), 1)
|
41
|
-
|
42
|
-
const { src } = dependency
|
43
|
-
const el = document.querySelector(`script[src='${src}']`)
|
44
|
-
if (el) el.remove()
|
45
|
-
if (dependency.global && self[dependency.global])
|
46
|
-
self[dependency.global] = null
|
47
|
-
}
|
48
|
-
|
49
|
-
function removeAll () {
|
50
|
-
;[...added].forEach(dependency => remove(dependency))
|
51
|
-
}
|
52
|
-
|
53
|
-
export default { ...dependencies, add, remove, removeAll }
|