fleetio_spark 0.2.17 → 0.2.18
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/javascripts/spark/_cookie.js +11 -11
- data/app/assets/javascripts/spark/_icons.js +1 -1
- data/app/assets/javascripts/spark/_modal.js +118 -118
- data/app/assets/javascripts/spark/_search.js +24 -24
- data/app/assets/javascripts/spark/_stack.js +92 -92
- data/app/assets/javascripts/spark/code.js +21 -0
- data/app/assets/javascripts/spark/components/nav/_tree.js +22 -22
- data/app/assets/javascripts/spark/components/sidebar/_toggle.js +11 -11
- data/app/assets/javascripts/spark/components/ui/_sticky_panel.js +6 -6
- data/app/assets/javascripts/spark/form/_input-status.js +16 -17
- data/app/assets/javascripts/spark/form/_set-input.js +16 -16
- data/app/assets/javascripts/spark/form/_sync-select.js +6 -5
- data/app/assets/javascripts/spark/shims/_scroll-detect.js +6 -5
- data/app/assets/javascripts/spark/spark.js +20 -19
- data/app/assets/stylesheets/spark/components_old/_dropdown.scss +3 -3
- data/lib/fleetio_spark/version.rb +1 -1
- data/public/code-0.2.18.js +2 -0
- data/public/code-0.2.18.js.gz +0 -0
- data/public/code-0.2.18.js.map +1 -0
- data/public/{spark-0.2.17.css → spark-0.2.18.css} +1 -1
- data/public/{spark-0.2.17.css.gz → spark-0.2.18.css.gz} +0 -0
- data/public/spark-0.2.18.js +2 -0
- data/public/spark-0.2.18.js.gz +0 -0
- data/public/spark-0.2.18.js.map +1 -0
- metadata +11 -8
- data/app/assets/javascripts/spark/shims/_dataset.js +0 -241
- data/public/spark-0.2.17.js +0 -2
- data/public/spark-0.2.17.js.gz +0 -0
- data/public/spark-0.2.17.js.map +0 -1
@@ -1,12 +1,12 @@
|
|
1
|
-
var toolbox = require(
|
2
|
-
Event =
|
3
|
-
modal = require(
|
4
|
-
stack = require(
|
1
|
+
var toolbox = require('@spark-engine/toolbox'),
|
2
|
+
Event = require('@spark-engine/event'),
|
3
|
+
modal = require('./_modal'),
|
4
|
+
stack = require('./_stack')
|
5
5
|
|
6
6
|
// Focus on search when `/` key is pressed
|
7
|
-
Event.keyOn(
|
7
|
+
Event.keyOn('/', function(event){
|
8
8
|
var q = document.querySelector('[name=q]')
|
9
|
-
if (
|
9
|
+
if (q && !event.target.closest('[contenteditable=true]')) {
|
10
10
|
event.preventDefault()
|
11
11
|
q.focus()
|
12
12
|
}
|
@@ -15,62 +15,62 @@ Event.keyOn( '/', function(event){
|
|
15
15
|
function setup() {
|
16
16
|
var q = document.querySelector('[name=q]'),
|
17
17
|
filter = document.querySelector('#search_model')
|
18
|
-
searchPanel = document.querySelector(
|
19
|
-
searchStack = stack.get(
|
20
|
-
searchModal = modal.get(
|
18
|
+
searchPanel = document.querySelector('.search-panel'),
|
19
|
+
searchStack = stack.get('#search-stack'),
|
20
|
+
searchModal = modal.get('#search-results')
|
21
21
|
|
22
|
-
if (
|
22
|
+
if (!searchModal || !q) return
|
23
23
|
|
24
24
|
// 1. Focus on query input when characters are typed
|
25
25
|
// 2. Clear input when escape is pressed
|
26
|
-
function keyWatcher (
|
26
|
+
function keyWatcher (event) {
|
27
27
|
var focusEl = document.activeElement
|
28
28
|
|
29
29
|
// If a letter, number, or backspace is pressed, focus on search input
|
30
|
-
if (
|
30
|
+
if ((event.key.length === 1 || Event.key.isPressed("backspace")) && focusEl != q && !focusEl.tagName.match(/select|button/i)) {
|
31
31
|
q.focus()
|
32
32
|
|
33
33
|
// Restore default search input behavior
|
34
34
|
// When foucsed, esc clears input
|
35
|
-
} else if (
|
35
|
+
} else if (focusEl == q && Event.key.isPressed("esc")) {
|
36
36
|
q.value = ''
|
37
|
-
Event.fire(
|
37
|
+
Event.fire(q, 'input')
|
38
38
|
}
|
39
39
|
}
|
40
40
|
|
41
41
|
// Scroll all navs back to top
|
42
42
|
function resetScroll () {
|
43
|
-
toolbox.each(
|
43
|
+
toolbox.each(searchStack.root.querySelectorAll('nav'), function (nav) {
|
44
44
|
nav.scrollTop = 0
|
45
45
|
})
|
46
46
|
}
|
47
47
|
|
48
48
|
// Show first panel stack when query is cleared
|
49
|
-
Event.on(
|
50
|
-
if (
|
51
|
-
searchStack.show(
|
49
|
+
Event.on(q, 'input', function (event) {
|
50
|
+
if (q.value == '') {
|
51
|
+
searchStack.show(0)
|
52
52
|
searchPanel.classList.remove('search-in-progress')
|
53
53
|
resetScroll()
|
54
54
|
}
|
55
55
|
})
|
56
56
|
|
57
|
-
searchModal.on(
|
58
|
-
Event.on(
|
57
|
+
searchModal.on('open', function() {
|
58
|
+
Event.on(document, 'keydown', keyWatcher)
|
59
59
|
})
|
60
60
|
|
61
61
|
// Reset stack when modal is closed and query is clear
|
62
|
-
searchModal.on(
|
62
|
+
searchModal.on('close', function() {
|
63
63
|
// Restore state of search panel
|
64
|
-
if (
|
64
|
+
if (q.value == '') {
|
65
65
|
searchStack.reset()
|
66
66
|
resetScroll()
|
67
67
|
}
|
68
68
|
|
69
69
|
searchPanel.classList.remove('search-in-progress')
|
70
70
|
|
71
|
-
Event.off(
|
71
|
+
Event.off(document, 'keydown', keyWatcher)
|
72
72
|
})
|
73
73
|
}
|
74
74
|
|
75
75
|
// Reset search results panel when query is cleared
|
76
|
-
Event.ready(
|
76
|
+
Event.ready(setup)
|
@@ -1,14 +1,14 @@
|
|
1
|
-
var toolbox = require(
|
2
|
-
Event =
|
1
|
+
var toolbox = require('@spark-engine/toolbox'),
|
2
|
+
Event = require('@spark-engine/event'),
|
3
3
|
Stacks = []
|
4
4
|
|
5
5
|
var Stack = {
|
6
|
-
new: function(
|
6
|
+
new: function(root) {
|
7
7
|
|
8
|
-
if (
|
8
|
+
if (!isElement(root)) root = document.querySelector(root)
|
9
9
|
|
10
10
|
// Don't add a new stack if no element found or if stack already exists
|
11
|
-
if (
|
11
|
+
if (!isElement(root) || root.dataset.stackId) return
|
12
12
|
|
13
13
|
// Set up stack by searching DOM node under it.
|
14
14
|
// The first child found will be set up as a default
|
@@ -20,46 +20,46 @@ var Stack = {
|
|
20
20
|
focus: [],
|
21
21
|
current: null,
|
22
22
|
|
23
|
-
add: function (
|
23
|
+
add: function (panelEl, name) {
|
24
24
|
panelEl.dataset.stackIndex = stack.panels.length
|
25
25
|
|
26
|
-
hideEl(
|
26
|
+
hideEl(panelEl)
|
27
27
|
|
28
|
-
stack.panels.push(
|
28
|
+
stack.panels.push(panelEl)
|
29
29
|
},
|
30
30
|
|
31
31
|
// Reset stack to first panel
|
32
32
|
reset: function () {
|
33
33
|
// Already reset? We're done.
|
34
|
-
if (
|
34
|
+
if (stack.current == 0) return
|
35
35
|
|
36
36
|
// If hidden or first is empty, hide all
|
37
|
-
if (
|
37
|
+
if (stack.root.offsetParent == null) {
|
38
38
|
stack.focus = [] // Clear focus stack
|
39
39
|
|
40
40
|
// Hide and reset scroll on all panels
|
41
41
|
stack.hidePanels()
|
42
42
|
|
43
43
|
// Show first panel
|
44
|
-
if (
|
44
|
+
if (isEmpty(stack.panels[0])) {
|
45
45
|
stack.current = null
|
46
46
|
} else {
|
47
47
|
stack.current = 0
|
48
48
|
}
|
49
|
-
showEl(
|
49
|
+
showEl(stack.panels[0])
|
50
50
|
stack.updateWatchers()
|
51
51
|
}
|
52
52
|
|
53
53
|
// If not hidden, dismiss current panel and reset to first panel
|
54
|
-
else stack.show(
|
54
|
+
else stack.show(0)
|
55
55
|
},
|
56
56
|
|
57
57
|
// Show a specific panel, hiding all others
|
58
|
-
show: function (
|
59
|
-
var panel = stack.findPanel(
|
60
|
-
if (
|
58
|
+
show: function (name) {
|
59
|
+
var panel = stack.findPanel(name)
|
60
|
+
if (!panel) return // This panel doesn't exist
|
61
61
|
|
62
|
-
if (
|
62
|
+
if (isEmpty(panel)) {
|
63
63
|
stack.current = null
|
64
64
|
stack.hidePanels()
|
65
65
|
stack.updateWatchers()
|
@@ -67,81 +67,81 @@ var Stack = {
|
|
67
67
|
}
|
68
68
|
|
69
69
|
var current = stack.currentPanel()
|
70
|
-
if (
|
70
|
+
if (!current) return stack.enter(panel) // the stack isn't currently active
|
71
71
|
|
72
72
|
// If a panel isn't the current panel
|
73
|
-
if (
|
73
|
+
if (panel != current) {
|
74
74
|
|
75
75
|
// Dismiss it with the callback load in the next panel
|
76
|
-
return stack.dismiss(
|
77
|
-
stack.enter(
|
76
|
+
return stack.dismiss(stack.direction(panel), function() {
|
77
|
+
stack.enter(panel)
|
78
78
|
})
|
79
79
|
|
80
80
|
}
|
81
81
|
},
|
82
82
|
|
83
|
-
enter: function (
|
84
|
-
var direction = stack.direction(
|
83
|
+
enter: function (el) {
|
84
|
+
var direction = stack.direction(el)
|
85
85
|
el.dataset.direction = direction
|
86
|
-
stack.current = Number(
|
86
|
+
stack.current = Number(el.dataset.stackIndex)
|
87
87
|
|
88
|
-
Event.afterAnimation(
|
88
|
+
Event.afterAnimation(el, function() {
|
89
89
|
el.dataset.direction = ''
|
90
|
-
el.classList.remove(
|
91
|
-
}, 50
|
90
|
+
el.classList.remove('enter')
|
91
|
+
}, 50)
|
92
92
|
|
93
|
-
el.classList.add(
|
94
|
-
showEl(
|
93
|
+
el.classList.add('enter')
|
94
|
+
showEl(el)
|
95
95
|
|
96
96
|
stack.updateWatchers()
|
97
97
|
|
98
|
-
if (
|
98
|
+
if (direction == 'forward') {
|
99
99
|
// If the previous focused element was in the stack
|
100
|
-
//if (
|
100
|
+
//if (toolbox.childOf(stack.lastFocus(), stack.root)) {
|
101
101
|
|
102
102
|
// focus on the first input
|
103
|
-
//var firstItem = el.querySelector(
|
104
|
-
//if (
|
103
|
+
//var firstItem = el.querySelector('input:not([hidden]), textarea, select, a[tabindex]')
|
104
|
+
//if (firstItem) firstItem.focus()
|
105
105
|
|
106
106
|
//}
|
107
107
|
|
108
108
|
}
|
109
109
|
|
110
110
|
// When reversing, focus on the previously focused element
|
111
|
-
if (
|
111
|
+
if (direction == 'reverse' && stack.focus.length > 0) {
|
112
112
|
stack.focus.pop().focus()
|
113
113
|
}
|
114
114
|
},
|
115
115
|
|
116
|
-
dismiss: function (
|
116
|
+
dismiss: function (direction, callback) {
|
117
117
|
|
118
118
|
var el = stack.currentPanel()
|
119
119
|
|
120
|
-
if (
|
121
|
-
stack.focus.push(
|
120
|
+
if (direction == 'forward')
|
121
|
+
stack.focus.push(document.activeElement)
|
122
122
|
|
123
|
-
el.classList.remove(
|
124
|
-
el.classList.add(
|
123
|
+
el.classList.remove('enter')
|
124
|
+
el.classList.add('exit')
|
125
125
|
el.dataset.direction = direction
|
126
126
|
|
127
|
-
Event.afterAnimation(
|
127
|
+
Event.afterAnimation(el, function() {
|
128
128
|
// Ensure panel is scrolled to top
|
129
|
-
if (
|
129
|
+
if (direction == 'reverse') el.scrollTop = 0
|
130
130
|
|
131
|
-
hideEl(
|
132
|
-
el.classList.remove(
|
131
|
+
hideEl(el)
|
132
|
+
el.classList.remove('exit')
|
133
133
|
el.dataset.direction = ''
|
134
134
|
|
135
|
-
if (
|
135
|
+
if (typeof callback === 'function') callback()
|
136
136
|
|
137
|
-
}, 50
|
137
|
+
}, 50)
|
138
138
|
|
139
139
|
},
|
140
140
|
|
141
141
|
hidePanels: function() {
|
142
|
-
stack.panels.forEach(
|
142
|
+
stack.panels.forEach(function(el) {
|
143
143
|
el.scrollTop = 0
|
144
|
-
hideEl(
|
144
|
+
hideEl(el)
|
145
145
|
})
|
146
146
|
},
|
147
147
|
|
@@ -150,130 +150,130 @@ var Stack = {
|
|
150
150
|
},
|
151
151
|
|
152
152
|
// Find a panel by name or index
|
153
|
-
findPanel: function (
|
154
|
-
if (
|
153
|
+
findPanel: function (name) {
|
154
|
+
if (isElement(name))
|
155
155
|
return name
|
156
156
|
else
|
157
|
-
return root.querySelector(
|
157
|
+
return root.querySelector('[data-stack="'+name+'"], [data-stack-index="'+name+'"]')
|
158
158
|
},
|
159
159
|
|
160
160
|
// Walk backwards in the stack, showing the panel previous to the current panel
|
161
161
|
back: function () {
|
162
|
-
stack.show(
|
162
|
+
stack.show(stack.panels[ stack.current - 1 ])
|
163
163
|
},
|
164
164
|
|
165
165
|
// add aria-hidden=false to the first hidden element
|
166
166
|
next: function () {
|
167
|
-
stack.show(
|
167
|
+
stack.show(stack.panels[ stack.current + 1 ])
|
168
168
|
},
|
169
169
|
|
170
|
-
direction: function(
|
171
|
-
var index = stack.panelIndex(
|
170
|
+
direction: function(panel) {
|
171
|
+
var index = stack.panelIndex(panel)
|
172
172
|
|
173
|
-
if (
|
174
|
-
else return (
|
173
|
+
if (index == stack.current || stack.current == null) return 'none'
|
174
|
+
else return (stack.current < index) ? 'forward' : 'reverse'
|
175
175
|
|
176
176
|
},
|
177
177
|
|
178
|
-
currentPanel: function (
|
179
|
-
if (
|
178
|
+
currentPanel: function (name) {
|
179
|
+
if (typeof stack.current == 'undefined') return
|
180
180
|
|
181
|
-
if (
|
182
|
-
return stack.panels[ stack.current ] == stack.findPanel(
|
181
|
+
if (name) {
|
182
|
+
return stack.panels[ stack.current ] == stack.findPanel(name)
|
183
183
|
}
|
184
184
|
return stack.panels[ stack.current ]
|
185
185
|
},
|
186
186
|
|
187
|
-
panelIndex: function (
|
188
|
-
return Number(
|
187
|
+
panelIndex: function (panel) {
|
188
|
+
return Number(panel.dataset.stackIndex)
|
189
189
|
},
|
190
190
|
|
191
191
|
updateWatchers: function () {
|
192
|
-
toolbox.each(
|
193
|
-
if (
|
194
|
-
el.removeAttribute(
|
192
|
+
toolbox.each(stack.watchers, function(el) {
|
193
|
+
if (stack.current == null)
|
194
|
+
el.removeAttribute('data-active-stack')
|
195
195
|
else
|
196
196
|
el.dataset.activeStack = stack.currentPanel().dataset.stack || stack.currentPanel().dataset.stackIndex
|
197
197
|
})
|
198
198
|
}
|
199
199
|
}
|
200
200
|
|
201
|
-
toolbox.each(
|
201
|
+
toolbox.each(root.children, stack.add)
|
202
202
|
|
203
|
-
if (
|
203
|
+
if (root.id) stack.watchers = document.querySelectorAll('[data-watch-stack="#'+root.id+'"]')
|
204
204
|
|
205
205
|
// Only show the first panel if it has content.
|
206
206
|
// If it doesn't, assume async and manual panel showing.
|
207
|
-
if (
|
207
|
+
if (!isEmpty(stack.panels[0])) stack.show(0)
|
208
208
|
|
209
209
|
// Add a queryable stack id
|
210
210
|
root.dataset.stackId = Stacks.length
|
211
211
|
|
212
|
-
Stacks.push(
|
212
|
+
Stacks.push(stack)
|
213
213
|
|
214
214
|
return stack
|
215
215
|
}
|
216
216
|
}
|
217
217
|
|
218
|
-
function showEl (
|
219
|
-
el.setAttribute(
|
218
|
+
function showEl (el) {
|
219
|
+
el.setAttribute('aria-hidden', false)
|
220
220
|
}
|
221
221
|
|
222
|
-
function isEmpty (
|
222
|
+
function isEmpty (el) {
|
223
223
|
return el.childElementCount == 0
|
224
224
|
}
|
225
225
|
|
226
|
-
function hideEl (
|
227
|
-
el.setAttribute(
|
226
|
+
function hideEl (el) {
|
227
|
+
el.setAttribute('aria-hidden', true)
|
228
228
|
}
|
229
229
|
|
230
|
-
function isElement (
|
230
|
+
function isElement (item) {
|
231
231
|
return item.constructor.toString().search(/HTML.+Element/) > -1
|
232
232
|
}
|
233
233
|
|
234
|
-
function navClick (
|
234
|
+
function navClick (event) {
|
235
235
|
var el = event.currentTarget
|
236
236
|
var panel = el.dataset.stackNav
|
237
|
-
var stack = getStack(
|
238
|
-
if (
|
237
|
+
var stack = getStack(el.closest('[data-stack="root"]'))
|
238
|
+
if (!stack) return
|
239
239
|
|
240
|
-
if (
|
241
|
-
else if (
|
242
|
-
else if (
|
240
|
+
if (panel == 'next') stack.next()
|
241
|
+
else if (panel == 'back') stack.back()
|
242
|
+
else if (stack.findPanel(panel)) stack.show(panel)
|
243
243
|
else return
|
244
244
|
|
245
245
|
//event.preventDefault()
|
246
246
|
}
|
247
247
|
|
248
|
-
function prevPanel (
|
249
|
-
var stack = getStack(
|
248
|
+
function prevPanel (event) {
|
249
|
+
var stack = getStack(event.target.closest('[data-stack="root"]'))
|
250
250
|
stack.back()
|
251
251
|
event.preventDefault()
|
252
252
|
}
|
253
253
|
|
254
254
|
function setup () {
|
255
|
-
Event.change(
|
256
|
-
toolbox.each(
|
255
|
+
Event.change(function() {
|
256
|
+
toolbox.each(document.querySelectorAll('[data-stack="root"]'), Stack.new)
|
257
257
|
})
|
258
258
|
|
259
259
|
// Localise clicks to a stack root
|
260
260
|
// Future: consider expanding this to allow controls to live anywhere and point to a stack
|
261
|
-
Event.on(
|
261
|
+
Event.on(document, 'click', '[data-stack="root"] [data-stack-nav]', navClick)
|
262
262
|
}
|
263
263
|
|
264
|
-
function getStack (
|
264
|
+
function getStack (search) {
|
265
265
|
|
266
|
-
if (
|
267
|
-
if (
|
266
|
+
if (isElement(search)) {
|
267
|
+
if (search.dataset.stackId) return Stacks[ search.dataset.stackId ]
|
268
268
|
}
|
269
269
|
|
270
|
-
if (
|
270
|
+
if (typeof search === 'string') {
|
271
271
|
|
272
272
|
// Well, let's hope it's a DOM selector
|
273
|
-
var stack = document.querySelector(
|
273
|
+
var stack = document.querySelector(search)
|
274
274
|
|
275
275
|
// If it is woo hoo
|
276
|
-
if (
|
276
|
+
if (stack && stack.dataset.stackId) {
|
277
277
|
return Stacks[ stack.dataset.stackId ]
|
278
278
|
}
|
279
279
|
}
|