switch_access-rails 1.1.4
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.
- data/LICENSE +10 -0
- data/README.md +121 -0
- data/Rakefile +16 -0
- data/lib/switch_access-rails.rb +1 -0
- data/lib/switch_access/rails.rb +3 -0
- data/lib/switch_access/rails/engine.rb +6 -0
- data/lib/switch_access/rails/railtie.rb +14 -0
- data/lib/switch_access/rails/version.rb +5 -0
- data/lib/switch_access/rails/view_helpers.rb +109 -0
- data/vendor/assets/javascripts/switch_access.js +3 -0
- data/vendor/assets/javascripts/switch_access/execute_method.coffee +107 -0
- data/vendor/assets/javascripts/switch_access/jquery.csswatch.coffee +264 -0
- data/vendor/assets/javascripts/switch_access/log4javascript.js +5877 -0
- data/vendor/assets/javascripts/switch_access/switch_access.coffee +1007 -0
- data/vendor/assets/stylesheets/switch_access/example.css +2 -0
- data/vendor/assets/stylesheets/switch_access/example_highlighter.css +14 -0
- data/vendor/assets/stylesheets/switch_access/example_switch_element.css +14 -0
- metadata +125 -0
@@ -0,0 +1,1007 @@
|
|
1
|
+
###
|
2
|
+
Switch Access for webpages
|
3
|
+
(c) 2012 Leif Ringstad
|
4
|
+
Dual-licensed under GPL or commercial license (LICENSE and LICENSE.GPL)
|
5
|
+
Source: http://github.com/leifcr/switch_access
|
6
|
+
v 1.1.4
|
7
|
+
###
|
8
|
+
|
9
|
+
SwitchAccessCommon =
|
10
|
+
generateRandomUUID: ->
|
11
|
+
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace /[xy]/g, (c) ->
|
12
|
+
r = Math.random() * 16 | 0
|
13
|
+
v = (if c is "x" then r else (r & 0x3 | 0x8))
|
14
|
+
v.toString 16
|
15
|
+
options:
|
16
|
+
###
|
17
|
+
Element highlighting using the built in Highlighter object feature
|
18
|
+
###
|
19
|
+
highlighter:
|
20
|
+
###
|
21
|
+
Use highlighter div element for each element. A div is positioned absolute
|
22
|
+
around the element and shown/hidden accordingly
|
23
|
+
Default: true
|
24
|
+
###
|
25
|
+
use: true
|
26
|
+
|
27
|
+
###
|
28
|
+
Additional content for the highlighter
|
29
|
+
Note: The content is placed within every highlighter and multiple
|
30
|
+
highlighters can be visible at the same time. It is best to not
|
31
|
+
use IDs on elements placed inside the highlighter, to avoid duplicate
|
32
|
+
IDs on a page
|
33
|
+
Default: ""
|
34
|
+
###
|
35
|
+
content: ""
|
36
|
+
|
37
|
+
###
|
38
|
+
Class for the highlighter
|
39
|
+
Default: "highlighter"
|
40
|
+
###
|
41
|
+
class: "highlighter"
|
42
|
+
|
43
|
+
###
|
44
|
+
The class when a highlighter is active/currently selected
|
45
|
+
Default: "current"
|
46
|
+
###
|
47
|
+
current_class: "current"
|
48
|
+
|
49
|
+
###
|
50
|
+
The class when set on a highlighter when activated action is triggered
|
51
|
+
Note: only usable if options.visual.delay_before_activating_element is > 0
|
52
|
+
Default: "activate"
|
53
|
+
###
|
54
|
+
activate_class: "activate"
|
55
|
+
|
56
|
+
###
|
57
|
+
Margin between the highlighter and the element
|
58
|
+
Default: 5
|
59
|
+
###
|
60
|
+
margin_to_element: 5
|
61
|
+
|
62
|
+
###
|
63
|
+
Selector to set size on. (Change in case you have content inside the highlighter you wish to highlight)
|
64
|
+
###
|
65
|
+
selector_for_set_to_size: ".highlighter"
|
66
|
+
|
67
|
+
###
|
68
|
+
Use CSS watch to watch the element for changes in position and dimensions
|
69
|
+
This is only needed if you have javascript or other DOM elements
|
70
|
+
that might change the position or size of a switch-enabled element
|
71
|
+
Default: false
|
72
|
+
###
|
73
|
+
watch_for_resize: false
|
74
|
+
# use_size_position_check: true
|
75
|
+
|
76
|
+
###
|
77
|
+
The ID for the holder for all highlighters. Unlikely to need changing
|
78
|
+
Default: "sw-highlighter-holder"
|
79
|
+
###
|
80
|
+
holder_id: "sw-highlighter-holder"
|
81
|
+
|
82
|
+
###
|
83
|
+
Options specific to highlighting
|
84
|
+
###
|
85
|
+
highlight:
|
86
|
+
###
|
87
|
+
Options specifict to highlighting a switch-element
|
88
|
+
###
|
89
|
+
element:
|
90
|
+
###
|
91
|
+
The class when a element is active/currently selected
|
92
|
+
Default: "current"
|
93
|
+
###
|
94
|
+
current_class: "current"
|
95
|
+
|
96
|
+
###
|
97
|
+
The class when set on a switch-element when activated
|
98
|
+
action is triggered
|
99
|
+
Note: options.visual.delay_before_activating_element must
|
100
|
+
be greater than 0
|
101
|
+
Default: "activate"
|
102
|
+
###
|
103
|
+
activate_class: "activate"
|
104
|
+
|
105
|
+
debug: false
|
106
|
+
|
107
|
+
###
|
108
|
+
Internal options, but can be changed if needed
|
109
|
+
###
|
110
|
+
internal:
|
111
|
+
###
|
112
|
+
The data attribute for the unique ID on each element and switch highlighter
|
113
|
+
Default: "sw-elem"
|
114
|
+
###
|
115
|
+
unique_element_data_attribute: "sw-elem"
|
116
|
+
|
117
|
+
###
|
118
|
+
Set a unique class on each element
|
119
|
+
Default: false
|
120
|
+
###
|
121
|
+
set_unique_element_class: false
|
122
|
+
|
123
|
+
###
|
124
|
+
Actions (Enumish)
|
125
|
+
These should not be overridden, as they are used internally
|
126
|
+
###
|
127
|
+
actions:
|
128
|
+
none: 0
|
129
|
+
moved_to_next_element: 1
|
130
|
+
moved_to_next_level: 2
|
131
|
+
moved_to_previous_level: 3
|
132
|
+
triggered_action: 10
|
133
|
+
triggered_delayed_action: 11
|
134
|
+
stayed_at_element: 20
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
class SwitchAccess
|
139
|
+
constructor: (options) ->
|
140
|
+
# return existing instance if already initialized, as there should only be one instance of Switch Access on a page
|
141
|
+
if typeof (window['__switch_access_sci']) != "undefined" && window['__switch_access_sci'] != null
|
142
|
+
window.__switch_access_sci.setoptions(options)
|
143
|
+
return window.__switch_access_sci
|
144
|
+
|
145
|
+
window.__switch_access_sci = this
|
146
|
+
###
|
147
|
+
Options
|
148
|
+
###
|
149
|
+
@options =
|
150
|
+
###
|
151
|
+
Switch/Key settings
|
152
|
+
###
|
153
|
+
switches:
|
154
|
+
|
155
|
+
###
|
156
|
+
The number of switches 0 = disable, 1 = single switch, 2 = two switches
|
157
|
+
Default: 2
|
158
|
+
###
|
159
|
+
number_of_switches: 0
|
160
|
+
|
161
|
+
###
|
162
|
+
Array for the keycodes to use as single switch (Multiple keycodes possible)
|
163
|
+
Default: [32, 13] (32 = 'Space', 13 = 'Enter')
|
164
|
+
###
|
165
|
+
keys_1: [32, 13] # Space / Enter
|
166
|
+
|
167
|
+
###
|
168
|
+
Array of two arrays for the keys to use as two switches
|
169
|
+
Default: [[32, 9], [13]] (9 = 'Tab, 32 = 'Space', 13 = 'Enter')
|
170
|
+
###
|
171
|
+
keys_2: [[9, 32], [13]] # Tab + Space / Enter
|
172
|
+
|
173
|
+
#keys_3: # forward/backward and select
|
174
|
+
|
175
|
+
###
|
176
|
+
Time for single switch scanning to move from element to element
|
177
|
+
Default: 1500 milliseconds
|
178
|
+
###
|
179
|
+
single_switch_move_time: 1500
|
180
|
+
|
181
|
+
###
|
182
|
+
If the single switch movement should restart/go to index 0 when restarted
|
183
|
+
Default: true
|
184
|
+
###
|
185
|
+
single_switch_restart_on_activate: true
|
186
|
+
|
187
|
+
###
|
188
|
+
Time after "triggering" a element to it's activated
|
189
|
+
Default: 0
|
190
|
+
###
|
191
|
+
delay_before_activating_element: 0
|
192
|
+
|
193
|
+
###
|
194
|
+
Delay before an keypress is "allowed" after last keypress.
|
195
|
+
Default: 250 ms
|
196
|
+
###
|
197
|
+
delay_for_allowed_keypress: 250
|
198
|
+
|
199
|
+
###
|
200
|
+
Groups enabled/disabled (If elements should be grouped or run as single elements)
|
201
|
+
Default: true
|
202
|
+
###
|
203
|
+
groups: true
|
204
|
+
|
205
|
+
###
|
206
|
+
DOM options
|
207
|
+
###
|
208
|
+
dom:
|
209
|
+
###
|
210
|
+
The class which all elements must have to be a switch controlled element
|
211
|
+
The class should be appended with numbers 1,2,3 etc to set order of elements.
|
212
|
+
order is unpredicaable if several elements have the same number within a group.
|
213
|
+
Use classnames switch-element-1 switch-element-2 or change this value
|
214
|
+
Default: "switch-element-"
|
215
|
+
###
|
216
|
+
element_class: "switch-element-"
|
217
|
+
###
|
218
|
+
The jQuery selector from where the first switch element should be searched for.
|
219
|
+
Usually this should be body or the first container on the webpage
|
220
|
+
Note: Use a selector which selects a single object. Else behaviour is unpredictable
|
221
|
+
###
|
222
|
+
start_element_selector: "body"
|
223
|
+
|
224
|
+
###
|
225
|
+
Other settings
|
226
|
+
###
|
227
|
+
# Use .search where you have class="search" or #search for id="search" (jQuery selectors)
|
228
|
+
key_filter_skip: [".search"]
|
229
|
+
|
230
|
+
###
|
231
|
+
If set to true, the first link within the element is "clicked".
|
232
|
+
Else the actual element is clicked.
|
233
|
+
FUTURE feature: (on the todo list)
|
234
|
+
A data attribute can be set on the element in order to override this on a per-element basis
|
235
|
+
###
|
236
|
+
activate_first_link: true # activate element or first link within
|
237
|
+
###
|
238
|
+
Enable/Disable debug
|
239
|
+
Note: log4javascript must be available if used
|
240
|
+
Default: false
|
241
|
+
###
|
242
|
+
debug: false
|
243
|
+
|
244
|
+
###
|
245
|
+
Visual settings
|
246
|
+
###
|
247
|
+
visual:
|
248
|
+
###
|
249
|
+
Scroll to ensure the entire element in focus is visible (if possible)
|
250
|
+
Default: true
|
251
|
+
###
|
252
|
+
ensure_visible_element: true # ensure element is visible on the page
|
253
|
+
|
254
|
+
###
|
255
|
+
The number of pixels for margin to the viewport/window when
|
256
|
+
the element is positioned in the viewport/window
|
257
|
+
Default: 15
|
258
|
+
###
|
259
|
+
scroll_offset: 15
|
260
|
+
|
261
|
+
###
|
262
|
+
Time in milliseconds the scroll will animate
|
263
|
+
(set to 0 if instant scroll is preferred)
|
264
|
+
Default: 200
|
265
|
+
###
|
266
|
+
animate_scroll_time: 200
|
267
|
+
###
|
268
|
+
The easing to use for animation
|
269
|
+
Default: "linear"
|
270
|
+
###
|
271
|
+
easing: "linear" # easing to use for scrolling
|
272
|
+
|
273
|
+
# hide_show_delay: 500
|
274
|
+
# move_fade_delay: 200
|
275
|
+
# pulsate: false
|
276
|
+
# play_sound: false
|
277
|
+
# highlight_sound: "./switch_move.mp3"
|
278
|
+
# activate_sound: "./switch_activate.mp3"
|
279
|
+
|
280
|
+
###
|
281
|
+
Runtime properties
|
282
|
+
###
|
283
|
+
@runtime =
|
284
|
+
active: false # switchaccess is active or not
|
285
|
+
element_list: null # an array with root elements
|
286
|
+
current_list: null # the current list
|
287
|
+
# (Root or an elements list of children)
|
288
|
+
|
289
|
+
parent_list: null # the list the parent is in after going into
|
290
|
+
# the group and highlighting the first child
|
291
|
+
|
292
|
+
element:
|
293
|
+
current: null # the current element within the active group
|
294
|
+
idx: 0 # the current element idx within the active group
|
295
|
+
level: 0 # the current level within a group or nested group
|
296
|
+
next_level: 0 # next level when moving to elements.
|
297
|
+
next_idx: 0 # next elements idx
|
298
|
+
parent_idx: 0 # the last idx on the parent before moving into the group
|
299
|
+
action_triggered: false # set to true if an action is triggered
|
300
|
+
keypress_allowed: true # keypress allowed or not
|
301
|
+
timers:
|
302
|
+
single_switch_id: null # The id of the single switch timer
|
303
|
+
|
304
|
+
highlighter_holder: null # The highlighter holder as a jquery object
|
305
|
+
|
306
|
+
@setoptions(options)
|
307
|
+
@init()
|
308
|
+
|
309
|
+
init: ->
|
310
|
+
if (@options.debug)
|
311
|
+
appender = null
|
312
|
+
@logger = log4javascript.getLogger()
|
313
|
+
if $('iframe[id*=log4javascript]').length <= 0
|
314
|
+
if $('#logger').length > 0
|
315
|
+
appender = new log4javascript.InPageAppender("logger")
|
316
|
+
appender.setWidth("100%")
|
317
|
+
appender.setHeight("100%")
|
318
|
+
else
|
319
|
+
appender = new log4javascript.InPageAppender()
|
320
|
+
appender.setHeight("500px")
|
321
|
+
|
322
|
+
appender.setThreshold(log4javascript.Level.ALL)
|
323
|
+
@logger.setLevel(log4javascript.Level.ALL)
|
324
|
+
@logger.addAppender(appender)
|
325
|
+
|
326
|
+
@log("init") if (@options.debug)
|
327
|
+
@createHighlighterHolder() if SwitchAccessCommon.options.highlighter.use
|
328
|
+
@registerCallbacks()
|
329
|
+
@start()
|
330
|
+
|
331
|
+
setoptions: (options) ->
|
332
|
+
@log "setoptions" if (@options.debug)
|
333
|
+
# @log options, "trace", true
|
334
|
+
@stop() if @runtime.active == true
|
335
|
+
jQuery.extend SwitchAccessCommon.options, {
|
336
|
+
highlighter: options.highlighter,
|
337
|
+
highlight: options.highlight,
|
338
|
+
internal: options.internal,
|
339
|
+
debug: options.debug
|
340
|
+
}
|
341
|
+
delete options.highlighter
|
342
|
+
delete options.highlight
|
343
|
+
delete options.internal
|
344
|
+
jQuery.extend true, @options, options
|
345
|
+
return
|
346
|
+
|
347
|
+
log: (msg, type = "debug", raw = false) ->
|
348
|
+
#console.log msg if @options.nested_debug
|
349
|
+
if (@options.debug)
|
350
|
+
if (raw)
|
351
|
+
@logger[type] msg
|
352
|
+
else
|
353
|
+
@logger[type] "SwitchAccess: " + msg
|
354
|
+
|
355
|
+
checkForNonNumberedElements: ->
|
356
|
+
if $(".#{@options.dom.element_class}").length > 0
|
357
|
+
msg = "Warning! #{$(".#{@options.dom.element_class}").length} element(s) without numbers found. Class selector is: #{@options.element_class}."
|
358
|
+
@log msg, "warning" if (@options.debug)
|
359
|
+
console.log "SwitchAccess: " + msg # Alert about no-numbered elements
|
360
|
+
return
|
361
|
+
|
362
|
+
buildListFromjqElement: (jq_element, parent, depth = 0) ->
|
363
|
+
not_str = "[class*=#{@options.dom.element_class}] [class*=#{@options.dom.element_class}]"
|
364
|
+
i = 0
|
365
|
+
while i < depth
|
366
|
+
not_str += " [class*=#{@options.dom.element_class}]"
|
367
|
+
i++
|
368
|
+
|
369
|
+
temp_list = jq_element.find("[class*=#{@options.dom.element_class}]").not(not_str)
|
370
|
+
@log "buildListFromjqElement - element count #{temp_list.length} depth: #{depth} element-classes:#{jq_element.attr("class")}", "trace" if (@options.debug)
|
371
|
+
return [] if temp_list.length <= 0
|
372
|
+
# warn if there are any elements that don't have any numbers
|
373
|
+
@hashAlizeAndRecurseList(@sortList(temp_list, @options.dom.element_class), parent, depth)
|
374
|
+
|
375
|
+
hashAlizeAndRecurseList: (list, parent, depth) ->
|
376
|
+
ret = []
|
377
|
+
i = 0
|
378
|
+
while i < list.length
|
379
|
+
new_element = new SwitchAccessElement($(list[i]), @runtime.highlighter_holder, @, parent)
|
380
|
+
new_element.children(@buildListFromjqElement($(list[i]), new_element, depth + 1 ))
|
381
|
+
ret.push( new_element )
|
382
|
+
i++
|
383
|
+
ret
|
384
|
+
|
385
|
+
sortList: (list, list_class) ->
|
386
|
+
@log "sortList Sorting list for #{list_class} Elements: #{list.length}" if (@options.debug)
|
387
|
+
search_regexp_class = ///#{list_class}\d+///
|
388
|
+
search_regexp_num = ///\d+///
|
389
|
+
list.sort (a,b) =>
|
390
|
+
item_class_name_a = search_regexp_class.exec($(a).attr("class"))
|
391
|
+
item_class_name_b = search_regexp_class.exec($(b).attr("class"))
|
392
|
+
num_a = 0
|
393
|
+
num_b = 0
|
394
|
+
if (item_class_name_a != null && item_class_name_b != null)
|
395
|
+
num_a = search_regexp_num.exec(item_class_name_a)
|
396
|
+
num_b = search_regexp_num.exec(item_class_name_b)
|
397
|
+
num_a - num_b
|
398
|
+
list
|
399
|
+
|
400
|
+
elementWithoutChildren: (element) ->
|
401
|
+
@log "elementWithoutChildren #{element.uniqueDataAttr()}" if (@options.debug)
|
402
|
+
ret = []
|
403
|
+
if element.children().length == 0
|
404
|
+
ret.push(element)
|
405
|
+
else
|
406
|
+
ret = ret.concat(@elementWithoutChildren(child)) for child in element.children()
|
407
|
+
element.children([]) # remove children from the element
|
408
|
+
element.destroy() # destroy the element, as the children have been returned
|
409
|
+
ret
|
410
|
+
|
411
|
+
|
412
|
+
flattenElementList: ->
|
413
|
+
@log "flattenElementList" if (@options.debug)
|
414
|
+
new_list = []
|
415
|
+
new_list = new_list.concat(@elementWithoutChildren(element)) for element in @runtime.element_list
|
416
|
+
new_list
|
417
|
+
|
418
|
+
buildElementList: ->
|
419
|
+
@runtime.element_list = @buildListFromjqElement($(@options.dom.start_element_selector), null, 0)
|
420
|
+
|
421
|
+
# if groups are disabled, flatten the list by moving children upwards
|
422
|
+
if @options.switches.groups == false
|
423
|
+
@runtime.element_list = @flattenElementList()
|
424
|
+
|
425
|
+
@log "buildElementList: count:#{@runtime.element_list.length}, class-name: #{@options.dom.element_class}" if (@options.debug)
|
426
|
+
return
|
427
|
+
|
428
|
+
deinit: ->
|
429
|
+
@log "deinit" if (@options.debug)
|
430
|
+
@stop()
|
431
|
+
@removeHighlightdiv()
|
432
|
+
|
433
|
+
start: ->
|
434
|
+
return if (@options.switches.number_of_switches == 0) || (@runtime.active == true)
|
435
|
+
@log "start" if (@options.debug)
|
436
|
+
@buildElementList()
|
437
|
+
# return
|
438
|
+
@runtime.active = true
|
439
|
+
@moveToFirstRootElement()
|
440
|
+
@startSingleSwitchTimer()
|
441
|
+
@runtime.action_triggered = false
|
442
|
+
|
443
|
+
stop: ->
|
444
|
+
return if (@runtime.active == false)
|
445
|
+
@log "stop" if (@options.debug)
|
446
|
+
@runtime.active = false
|
447
|
+
@removeHighlight()
|
448
|
+
@removeActivateClass()
|
449
|
+
@stopSingleSwitchTimer()
|
450
|
+
|
451
|
+
destroy: ->
|
452
|
+
@log "destroy" if (@options.debug)
|
453
|
+
@stop()
|
454
|
+
@removeCallbacks()
|
455
|
+
@destroy_elements(@runtime.element_list)
|
456
|
+
@removeHighlighterHolder()
|
457
|
+
@runtime.element_list = null
|
458
|
+
@runtime.current_list = null
|
459
|
+
@runtime.parent_list = null
|
460
|
+
@runtime.element.current = null
|
461
|
+
@runtime.highlighter_holder = null
|
462
|
+
window.__switch_access_sci = null
|
463
|
+
|
464
|
+
###
|
465
|
+
Destroy elements in a list
|
466
|
+
Children of the element will be destroyed by the element itself
|
467
|
+
###
|
468
|
+
destroy_elements: (list) ->
|
469
|
+
@log "destroy_elements", "trace" if (@options.debug)
|
470
|
+
element.destroy() for element in list
|
471
|
+
return
|
472
|
+
|
473
|
+
moveToFirstRootElement: ->
|
474
|
+
@runtime.element.idx = -1
|
475
|
+
@moveToNextElementAtLevel()
|
476
|
+
|
477
|
+
moveToNextElementAtLevel: ->
|
478
|
+
@log "moveToNextElementAtLevel", "trace" if (@options.debug)
|
479
|
+
@runtime.element.next_idx = @runtime.element.idx + 1
|
480
|
+
# verify that next idx is possible for "root"
|
481
|
+
if @runtime.element.next_level == @runtime.element.level and @runtime.element.level == 0
|
482
|
+
if (@runtime.element.next_idx >= @runtime.element_list.length)
|
483
|
+
@runtime.element.next_idx = 0
|
484
|
+
|
485
|
+
# see if we should move "out" of the current group
|
486
|
+
if @runtime.element.next_level isnt 0
|
487
|
+
if @runtime.element.next_idx >= @runtime.current_list.length
|
488
|
+
return @moveToPreviousLevel()
|
489
|
+
|
490
|
+
if @moveToNext()
|
491
|
+
@runtime.element.current.jq_element().triggerHandler("switch-access-move", [@runtime.element.idx, @runtime.element.level, @runtime.element.current])
|
492
|
+
return SwitchAccessCommon.actions.moved_to_next_element
|
493
|
+
else
|
494
|
+
return SwitchAccessCommon.actions.stayed_at_element
|
495
|
+
|
496
|
+
moveToNextLevel: ->
|
497
|
+
@log "moveToNextLevel", "trace" if (@options.debug)
|
498
|
+
# "catch" if the current element doesn't have children
|
499
|
+
if @runtime.element.current.children().length > 1
|
500
|
+
@runtime.element.next_level = @runtime.element.level + 1
|
501
|
+
@runtime.element.next_idx = 0
|
502
|
+
# return SwitchAccessCommon.actions.stayed_at_element
|
503
|
+
|
504
|
+
if @moveToNext()
|
505
|
+
@runtime.element.current.parent().jq_element().triggerHandler("switch-access-enter-group", [@runtime.element.idx, @runtime.element.level, @runtime.element.current])
|
506
|
+
return SwitchAccessCommon.actions.moved_to_next_level
|
507
|
+
else
|
508
|
+
return SwitchAccessCommon.actions.stayed_at_element
|
509
|
+
|
510
|
+
moveToPreviousLevel: ->
|
511
|
+
@log "moveToPreviousLevel", "trace" if (@options.debug)
|
512
|
+
@runtime.element.next_level = @runtime.element.level - 1
|
513
|
+
@runtime.element.next_idx = @runtime.element.parent_idx
|
514
|
+
# safety catch impossible levelss
|
515
|
+
if @runtime.element.next_level < 0
|
516
|
+
@runtime.element.next_level = 0
|
517
|
+
@runtime.element.next_idx = 0
|
518
|
+
|
519
|
+
if @moveToNext()
|
520
|
+
@runtime.element.current.jq_element().triggerHandler("switch-access-leave-group", [@runtime.element.idx, @runtime.element.level, @runtime.element.current])
|
521
|
+
return SwitchAccessCommon.actions.moved_to_previous_level
|
522
|
+
else
|
523
|
+
return SwitchAccessCommon.actions.stayed_at_element
|
524
|
+
|
525
|
+
moveToNext: ->
|
526
|
+
@log "moveToNext Current: I: #{@runtime.element.next_idx} L: #{@runtime.element.level} Next: I: #{@runtime.element.next_idx} L: #{@runtime.element.next_level}" if (@options.debug)
|
527
|
+
@runtime.action_triggered = true
|
528
|
+
|
529
|
+
# return if current level and idxs are equal
|
530
|
+
return false if (@runtime.element.next_level == @runtime.element.level) and (@runtime.element.idx == @runtime.element.next_idx)
|
531
|
+
|
532
|
+
@removeHighlight()
|
533
|
+
|
534
|
+
# find list to work on element
|
535
|
+
if @runtime.element.next_level > @runtime.element.level
|
536
|
+
list_n = @runtime.element.current.children()
|
537
|
+
@runtime.element.parent_idx = @runtime.element.idx
|
538
|
+
@runtime.parent_list = @runtime.current_list
|
539
|
+
@runtime.element.next_idx = 0
|
540
|
+
else if @runtime.element.next_level < @runtime.element.level
|
541
|
+
@runtime.element.next_idx = @runtime.element.parent_idx
|
542
|
+
if @runtime.element.current.parent() isnt null
|
543
|
+
list_n = @runtime.parent_list
|
544
|
+
else
|
545
|
+
list_n = @runtime.element_list
|
546
|
+
else if @runtime.element.next_level == 0
|
547
|
+
list_n = @runtime.element_list
|
548
|
+
else
|
549
|
+
list_n = @runtime.current_list
|
550
|
+
|
551
|
+
list_n[@runtime.element.next_idx].highlight()
|
552
|
+
|
553
|
+
@runtime.element.idx = @runtime.element.next_idx
|
554
|
+
@runtime.element.level = @runtime.element.next_level
|
555
|
+
@runtime.current_list = list_n
|
556
|
+
@runtime.element.current = list_n[@runtime.element.idx]
|
557
|
+
|
558
|
+
@makeElementVisible()
|
559
|
+
return true
|
560
|
+
|
561
|
+
removeHighlight: ->
|
562
|
+
@log "removeHighlight" if (@options.debug)
|
563
|
+
return if @runtime.element.current is null
|
564
|
+
@runtime.element.current.removeHighlight()
|
565
|
+
return
|
566
|
+
|
567
|
+
removeActivateClass: ->
|
568
|
+
@log "removeHighlight" if (@options.debug)
|
569
|
+
return if @runtime.current_list is null
|
570
|
+
if @runtime.element.current.children().length == 0
|
571
|
+
@runtime.element.current.removeActivateClass()
|
572
|
+
else
|
573
|
+
# else it's most likely that the children should be highlighted
|
574
|
+
child.removeActivateClass() for child in @runtime.element.current.children()
|
575
|
+
return
|
576
|
+
|
577
|
+
###
|
578
|
+
Make the element(s) visible. If the current selected element is a group, they are all moved inside the visible area of the screen
|
579
|
+
###
|
580
|
+
makeElementVisible: ->
|
581
|
+
return unless @options.visual.ensure_visible_element == true
|
582
|
+
@log "makeElementVisible", "trace" if (@options.debug)
|
583
|
+
scrollval = null
|
584
|
+
scroll_top = $(document).scrollTop()
|
585
|
+
element = @runtime.element.current.jq_element()
|
586
|
+
# positive scroll:
|
587
|
+
if ($(window).height() + scroll_top) < (element.offset().top + element.outerHeight() + @options.visual.scroll_offset)
|
588
|
+
diff_to_make_visible = (element.offset().top + element.outerHeight() + @options.visual.scroll_offset) - ($(document).scrollTop() + $(window).height())
|
589
|
+
if (diff_to_make_visible > 0)
|
590
|
+
scrollval = diff_to_make_visible + scroll_top
|
591
|
+
# negative scroll:
|
592
|
+
else if (scroll_top > (element.offset().top - @options.visual.scroll_offset))
|
593
|
+
if (element.offset().top - @options.visual.scroll_offset < 0)
|
594
|
+
scrollval = 0
|
595
|
+
else
|
596
|
+
scrollval = element.offset().top - @options.visual.scroll_offset
|
597
|
+
|
598
|
+
if (scroll_top != scrollval) && scrollval != null
|
599
|
+
if (@options.visual.animate_scroll_time == 0)
|
600
|
+
# for FF
|
601
|
+
$("html").scrollTop(scrollval)
|
602
|
+
# for Chrome
|
603
|
+
$("html body").scrollTop(scrollval)
|
604
|
+
else
|
605
|
+
# for FF
|
606
|
+
$("html").animate({scrollTop: scrollval}, @options.visual.animate_scroll_time, @options.visual.easing);
|
607
|
+
# for Chrome
|
608
|
+
$("html body").animate({scrollTop: scrollval}, @options.visual.animate_scroll_time, @options.visual.easing);
|
609
|
+
|
610
|
+
|
611
|
+
activateElement: ->
|
612
|
+
@log "activateElement" if (@options.debug)
|
613
|
+
@runtime.action_triggered = true
|
614
|
+
@stopSingleSwitchTimer()
|
615
|
+
|
616
|
+
@log "Activate Element: idx: #{@runtime.element.idx} level: IDX: #{@runtime.element.level} uuid: #{@runtime.element.current.uniqueDataAttr()}" if (@options.debug)
|
617
|
+
if (@options.switches.delay_before_activating_element == 0)
|
618
|
+
return @activateElementCallBack()
|
619
|
+
else
|
620
|
+
@runtime.element.current.jq_element().addClass(@options.element_activate_class)
|
621
|
+
if @runtime.element.current.children().length > 0
|
622
|
+
child.addActivateClass() for child in @runtime.element.current.children()
|
623
|
+
else
|
624
|
+
@runtime.element.current.addActivateClass()
|
625
|
+
|
626
|
+
window.setTimeout(( => @removeActivateClass(); @activateElementCallBack(); return), @options.switches.delay_before_activating_element)
|
627
|
+
return SwitchAccessCommon.actions.triggered_delayed_action
|
628
|
+
|
629
|
+
activateElementCallBack: ->
|
630
|
+
@log "activateElementCallBack" if (@options.debug)
|
631
|
+
|
632
|
+
# see if the element has children, if so go into level
|
633
|
+
if @runtime.element.current.children().length > 0
|
634
|
+
@startSingleSwitchTimer()
|
635
|
+
return @moveToNextLevel()
|
636
|
+
# else the element should "activate"
|
637
|
+
|
638
|
+
if ((@runtime.element.current.jq_element().is("a")) || (@activate_first_link == false))
|
639
|
+
element_to_click = @runtime.element.current.jq_element()
|
640
|
+
else
|
641
|
+
# if element isn't a link, find first link within element and go to the url/trigger it
|
642
|
+
element_to_click = @runtime.element.current.jq_element().find("a")
|
643
|
+
|
644
|
+
# safety catch
|
645
|
+
if (element_to_click.length <= 0)
|
646
|
+
element_to_click = @runtime.element.current.jq_element()
|
647
|
+
|
648
|
+
@log "Triggering Element: IDX: #{@runtime.element.current_idx} Element Tag: #{$(element_to_click).get(0).tagName.toLowerCase()} Text: #{$(element_to_click).text()}" if (@options.debug)
|
649
|
+
|
650
|
+
@runtime.element.current.jq_element().triggerHandler("switch-access-activate", [@runtime.element.idx, @runtime.element.level, element_to_click, @runtime.element.current])
|
651
|
+
if element_to_click.length > 0
|
652
|
+
element_to_click[0].click() #trigger("click")
|
653
|
+
# if (ret == true) && element_to_click.is("a")
|
654
|
+
# document.location = element_to_click.attr("href")
|
655
|
+
if (@options.switches.number_of_switches == 1)
|
656
|
+
@runtime.next_element_idx = -1 if (@options.single_switch_restart_on_activate)
|
657
|
+
@runtime.next_level = 0
|
658
|
+
@startSingleSwitchTimer()
|
659
|
+
else
|
660
|
+
msg = "Nothing to do. Verify options passed to SwitchAccess"
|
661
|
+
@log msg, "warn" if (@options.debug)
|
662
|
+
console.log "SwitchAccess: Warning: " + msg
|
663
|
+
return SwitchAccessCommon.actions.none
|
664
|
+
|
665
|
+
return SwitchAccessCommon.actions.triggered_action
|
666
|
+
|
667
|
+
|
668
|
+
singleSwitchTimerCallback: ->
|
669
|
+
@log "singleSwitchTimerCallback", "trace" if (@options.debug)
|
670
|
+
@moveToNextElementAtLevel()
|
671
|
+
|
672
|
+
allowKeyPressCallback: ->
|
673
|
+
@log "allowKeyPressCallback", "trace" if (@options.debug)
|
674
|
+
@runtime.keypress_allowed = true
|
675
|
+
|
676
|
+
createHighlighterHolder: ->
|
677
|
+
if $("div##{SwitchAccessCommon.options.holder_id}").length == 0
|
678
|
+
@runtime.highlighter_holder = $("<div id=\"#{SwitchAccessCommon.options.highlighter.holder_id}\"></div>")
|
679
|
+
$('body').append(@runtime.highlighter_holder)
|
680
|
+
return
|
681
|
+
|
682
|
+
removeHighlighterHolder: ->
|
683
|
+
$("div##{SwitchAccessCommon.options.highlighter.holder_id}").remove()
|
684
|
+
|
685
|
+
callbackForKeyPress: (event) ->
|
686
|
+
@log "callbackForKeyPress keycode: #{event.which} Allowed: #{@runtime.keypress_allowed}" if (@options.debug)
|
687
|
+
return if (@options.switches.number_of_switches == 0)
|
688
|
+
action = 0
|
689
|
+
|
690
|
+
if @options.switches.number_of_switches == 1
|
691
|
+
if event.which in @options.switches.keys_1
|
692
|
+
if !@runtime.keypress_allowed
|
693
|
+
event.stopPropagation()
|
694
|
+
return false
|
695
|
+
action = @activateElement()
|
696
|
+
|
697
|
+
else if @options.switches.number_of_switches == 2
|
698
|
+
if (event.which in @options.switches.keys_2[0]) || (event.which in @options.switches.keys_2[1])
|
699
|
+
if !@runtime.keypress_allowed
|
700
|
+
event.stopPropagation()
|
701
|
+
return false
|
702
|
+
action = @moveToNextElementAtLevel() if event.which in @options.switches.keys_2[0]
|
703
|
+
action = @activateElement() if event.which in @options.switches.keys_2[1]
|
704
|
+
|
705
|
+
if (@runtime.action_triggered)
|
706
|
+
@runtime.action_triggered = false
|
707
|
+
@runtime.keypress_allowed = false
|
708
|
+
timeout = @options.switches.delay_for_allowed_keypress
|
709
|
+
if (action == SwitchAccessCommon.actions.triggered_action) || (action == SwitchAccessCommon.actions.triggered_delayed_action)
|
710
|
+
if (@options.switches.number_of_switches == 1)
|
711
|
+
if (@options.switches.single_switch_move_time > @options.switches.delay_before_activating_element)
|
712
|
+
timeout = @options.switches.single_switch_move_time
|
713
|
+
else
|
714
|
+
timeout = @options.switches.delay_before_activating_element
|
715
|
+
else
|
716
|
+
if (@options.switches.delay_before_activating_element > timeout)
|
717
|
+
timeout = @options.switches.delay_before_activating_element
|
718
|
+
|
719
|
+
if timeout == 0
|
720
|
+
@allowKeyPressCallback()
|
721
|
+
else
|
722
|
+
window.setTimeout((=>@allowKeyPressCallback();return), timeout)
|
723
|
+
|
724
|
+
event.stopPropagation()
|
725
|
+
return false
|
726
|
+
else
|
727
|
+
return true
|
728
|
+
|
729
|
+
startSingleSwitchTimer: ->
|
730
|
+
return unless @options.switches.number_of_switches == 1
|
731
|
+
@log "startSingleSwitchTimer", "trace" if (@options.debug)
|
732
|
+
@runtime.single_switch_timer_id = window.setInterval(( => @singleSwitchTimerCallback();return), @options.switches.single_switch_move_time)
|
733
|
+
|
734
|
+
stopSingleSwitchTimer: ->
|
735
|
+
return unless @options.switches.number_of_switches == 1
|
736
|
+
@log "stopSingleSwitchTimer", "trace" if (@options.debug)
|
737
|
+
window.clearInterval(@runtime.single_switch_timer_id)
|
738
|
+
|
739
|
+
removeCallbacks: ->
|
740
|
+
@log "removeCallbacks", "trace" if (@options.debug)
|
741
|
+
$(document).off("keydown.switch_access")
|
742
|
+
|
743
|
+
registerCallbacks: ->
|
744
|
+
@log "registerCallbacks", "trace" if (@options.debug)
|
745
|
+
$(document).on("keydown.switch_access", (event) =>
|
746
|
+
@callbackForKeyPress(event)
|
747
|
+
)
|
748
|
+
return
|
749
|
+
|
750
|
+
window.SwitchAccess = SwitchAccess
|
751
|
+
|
752
|
+
class SwitchAccessElement
|
753
|
+
constructor: (jq_element, highlight_holder = null, logger = null, parent = null, children = []) ->
|
754
|
+
@options =
|
755
|
+
debug: false
|
756
|
+
|
757
|
+
@runtime =
|
758
|
+
jq_highlighter: null # jquery object of the highlighter belonging to this element
|
759
|
+
jq_element: jq_element # jquery object of this element
|
760
|
+
uuid: null # The UUID for this element
|
761
|
+
watching: false # if csswatch is enabled for this element
|
762
|
+
csswatch_init: false # if csswatch has been initialized on/for this element
|
763
|
+
parent: parent # the parent switch-element of this element
|
764
|
+
children: children # the child switch-elements of this element
|
765
|
+
highlight_holder: null # the highlight holder from SwitchAccess
|
766
|
+
|
767
|
+
@options.debug = SwitchAccessCommon.options.debug
|
768
|
+
@logger = logger if (@options.debug)
|
769
|
+
|
770
|
+
@runtime.highlight_holder = if highlight_holder == null then $('body') else highlight_holder
|
771
|
+
|
772
|
+
@init(@runtime.highlight_holder)
|
773
|
+
|
774
|
+
init: (highlight_holder)->
|
775
|
+
@uniqueDataAttr(true)
|
776
|
+
@createHighlighter(highlight_holder)
|
777
|
+
@log "init", "trace" if (@options.debug)
|
778
|
+
|
779
|
+
destroy: ->
|
780
|
+
@log "destroy", "trace" if (@options.debug)
|
781
|
+
@destroyHighlighter()
|
782
|
+
# destroy any children
|
783
|
+
child.destroy() for child in @children()
|
784
|
+
|
785
|
+
parent = null
|
786
|
+
children = null
|
787
|
+
jq_element = null
|
788
|
+
|
789
|
+
parent: (parent = null) ->
|
790
|
+
if parent == null
|
791
|
+
@runtime.parent
|
792
|
+
else
|
793
|
+
@runtime.parent = parent
|
794
|
+
|
795
|
+
children: (children = null) ->
|
796
|
+
if children == null
|
797
|
+
@runtime.children
|
798
|
+
else
|
799
|
+
@runtime.children = children
|
800
|
+
|
801
|
+
jq_element: (jq_element = null) ->
|
802
|
+
if (jq_element == null)
|
803
|
+
@runtime.jq_element
|
804
|
+
else
|
805
|
+
@runtime.jq_element = jq_element
|
806
|
+
|
807
|
+
log: (msg, type = "debug", raw = false) ->
|
808
|
+
if @options.debug && @logger != null
|
809
|
+
if (raw)
|
810
|
+
@logger.log "Element: #{@runtime.uuid} :", type
|
811
|
+
@logger.log msg, type, true
|
812
|
+
else
|
813
|
+
@logger.log "Element: #{@runtime.uuid} : #{msg}", type
|
814
|
+
|
815
|
+
###
|
816
|
+
Trigger the active element, link or event depending on options
|
817
|
+
###
|
818
|
+
trigger: ->
|
819
|
+
@log "trigger" if (@options.debug)
|
820
|
+
|
821
|
+
###
|
822
|
+
Show the highlighter and add highlight class to current object
|
823
|
+
###
|
824
|
+
highlight: (check_children = true) ->
|
825
|
+
@log "highlight" if (@options.debug)
|
826
|
+
# if the element has children, it's most likely that the children should be highlighted
|
827
|
+
if @children().length > 0 and check_children == true
|
828
|
+
child.highlight(false) for child in @children()
|
829
|
+
return
|
830
|
+
|
831
|
+
# if the next element doesn't have any children, highlight it
|
832
|
+
@runtime.jq_element.addClass(SwitchAccessCommon.options.highlight.element.current_class)
|
833
|
+
return unless SwitchAccessCommon.options.highlighter.use
|
834
|
+
@runtime.jq_highlighter.addClass(SwitchAccessCommon.options.highlighter.current_class)
|
835
|
+
@runtime.jq_highlighter.show()
|
836
|
+
# Must show the element before moving, else the offset will not be correct
|
837
|
+
@setHighlighterSizeAndPosition()
|
838
|
+
if SwitchAccessCommon.options.highlighter.watch_for_resize
|
839
|
+
if @runtime.watching == false
|
840
|
+
@enableCSSWatch()
|
841
|
+
|
842
|
+
###
|
843
|
+
Hide highlighter and remove highlight class on the current object(s)
|
844
|
+
###
|
845
|
+
removeHighlight: (check_children = true) ->
|
846
|
+
@log "removeHighlight" if (@options.debug)
|
847
|
+
|
848
|
+
# if set to check for children:
|
849
|
+
if @children().length > 0 and check_children == true
|
850
|
+
child.removeHighlight(false) for child in @children()
|
851
|
+
return
|
852
|
+
|
853
|
+
@runtime.jq_element.removeClass(SwitchAccessCommon.options.highlight.element.current_class)
|
854
|
+
@runtime.jq_element.removeClass(SwitchAccessCommon.options.highlight.element.activate_class)
|
855
|
+
return unless SwitchAccessCommon.options.highlighter.use
|
856
|
+
@runtime.jq_highlighter.removeClass(SwitchAccessCommon.options.highlighter.current_class)
|
857
|
+
@runtime.jq_highlighter.removeClass(SwitchAccessCommon.options.highlighter.activate_class)
|
858
|
+
@runtime.jq_highlighter.hide()
|
859
|
+
if SwitchAccessCommon.options.highlighter.watch_for_resize
|
860
|
+
@disableCSSWatch()
|
861
|
+
|
862
|
+
addActivateClass: ->
|
863
|
+
@runtime.jq_element.addClass(SwitchAccessCommon.options.highlight.element.activate_class)
|
864
|
+
return unless SwitchAccessCommon.options.highlighter.use
|
865
|
+
@runtime.jq_highlighter.addClass(SwitchAccessCommon.options.highlighter.activate_class)
|
866
|
+
|
867
|
+
removeActivateClass: ->
|
868
|
+
@log "removeActivateClass" if (@options.debug)
|
869
|
+
@runtime.jq_element.removeClass(SwitchAccessCommon.options.highlight.element.activate_class)
|
870
|
+
return unless SwitchAccessCommon.options.highlighter.use
|
871
|
+
@runtime.jq_highlighter.removeClass(SwitchAccessCommon.options.highlighter.activate_class)
|
872
|
+
|
873
|
+
###
|
874
|
+
Set Highlighter size and position
|
875
|
+
###
|
876
|
+
setHighlighterSizeAndPosition: ->
|
877
|
+
@setHighlighterSize(@runtime.jq_element, @runtime.jq_highlighter)
|
878
|
+
@setHighlighterPosition(@runtime.jq_element, @runtime.jq_highlighter)
|
879
|
+
|
880
|
+
###
|
881
|
+
Set highlighter position
|
882
|
+
###
|
883
|
+
setHighlighterPosition: (element, highlighter) ->
|
884
|
+
# posshift = SwitchAccessCommon.options.highlighter.margin_to_element #+ ((highlighter.outerWidth() - highlighter.innerWidth())/2)
|
885
|
+
@log "m_to_el: #{SwitchAccessCommon.options.highlighter.margin_to_element}, outerW-innerW: #{highlighter.outerWidth() - highlighter.width()} outerH-innerH: #{highlighter.outerHeight() - highlighter.innerHeight()}", "trace" if (@options.debug)
|
886
|
+
position = {
|
887
|
+
top: element.offset().top - SwitchAccessCommon.options.highlighter.margin_to_element - (highlighter.outerHeight() - highlighter.innerHeight())/2
|
888
|
+
left: element.offset().left - SwitchAccessCommon.options.highlighter.margin_to_element - (highlighter.outerWidth() - highlighter.innerWidth())/2
|
889
|
+
}
|
890
|
+
return if (highlighter.offset().top == position.top) and (highlighter.offset().left == position.left)
|
891
|
+
highlighter.offset(position)
|
892
|
+
@log "setHighlighterPosition left: #{position.left} top: #{position.top}", "trace" if (@options.debug)
|
893
|
+
return
|
894
|
+
|
895
|
+
###
|
896
|
+
Set size on the Highlighter object to the match the given element
|
897
|
+
###
|
898
|
+
setHighlighterSize: (element, highlighter) ->
|
899
|
+
w = element.outerWidth(false) + (SwitchAccessCommon.options.highlighter.margin_to_element * 2)
|
900
|
+
h = element.outerHeight(false) + (SwitchAccessCommon.options.highlighter.margin_to_element * 2)
|
901
|
+
|
902
|
+
highlighter.width(w)
|
903
|
+
highlighter.height(h)
|
904
|
+
@log "setHighlighterSize w: #{w}, h: #{h}", "trace" if (@options.debug)
|
905
|
+
return
|
906
|
+
|
907
|
+
###
|
908
|
+
Create the highlighter DOM object
|
909
|
+
###
|
910
|
+
createHighlighter: (jq_holder)->
|
911
|
+
return if (SwitchAccessCommon.options.highlighter.use is false) or
|
912
|
+
(@runtime.jq_highlighter isnt null)
|
913
|
+
@log "createHighlight" if (@options.debug)
|
914
|
+
|
915
|
+
@runtime.jq_highlighter = $("<div id=\"sw-el-#{@runtime.uuid}\" class=\"#{SwitchAccessCommon.options.highlighter.class}\"></div>")
|
916
|
+
jq_holder.append(@runtime.jq_highlighter)
|
917
|
+
@runtime.jq_highlighter.css('position','absolute')
|
918
|
+
@runtime.jq_highlighter.hide()
|
919
|
+
@runtime.jq_highlighter.append(SwitchAccessCommon.options.highlighter.content)
|
920
|
+
|
921
|
+
if SwitchAccessCommon.options.watch_for_resize
|
922
|
+
# check if content contains selector to use for resizeing
|
923
|
+
if @runtime.jq_highlighter.find(SwitchAccessCommon.options.highlighter.selector_for_set_to_size).length == 0
|
924
|
+
@runtime.jq_highlighter.addClass(SwitchAccessCommon.options.highlighter.selector_for_set_to_size)
|
925
|
+
|
926
|
+
###
|
927
|
+
Destroy the highlighter DOM object
|
928
|
+
###
|
929
|
+
destroyHighlighter: ->
|
930
|
+
return if @runtime.jq_highlighter == null
|
931
|
+
@log "destroyHighlight", "trace" if (@options.debug)
|
932
|
+
@disableCSSWatch()
|
933
|
+
|
934
|
+
@runtime.jq_highlighter.remove()
|
935
|
+
@runtime.jq_highlighter = null
|
936
|
+
|
937
|
+
###
|
938
|
+
Enable wathcing CSS changes on the element belonging to this object
|
939
|
+
###
|
940
|
+
enableCSSWatch: ->
|
941
|
+
return unless SwitchAccessCommon.options.highlighter.use == true and
|
942
|
+
SwitchAccessCommon.options.highlighter.watch_for_resize == true
|
943
|
+
@log "enableCSSWatch", "trace" if (@options.debug)
|
944
|
+
@runtime.watching = true
|
945
|
+
if @runtime.csswatch_init
|
946
|
+
@runtime.jq_element.csswatch('start')
|
947
|
+
else
|
948
|
+
@runtime.csswatch_init = true
|
949
|
+
@runtime.jq_element.csswatch({
|
950
|
+
props: "top,left,bottom,right,width,height"
|
951
|
+
props_functions: {
|
952
|
+
top: "offset().top"
|
953
|
+
left: "offset().left"
|
954
|
+
bottom: "offset().bottom"
|
955
|
+
right: "offset().right"
|
956
|
+
outerwidth: "outerWidth(false)"
|
957
|
+
outerheight: "outerHeight(false)"
|
958
|
+
}
|
959
|
+
callback: (->@callbackForResize????)
|
960
|
+
})
|
961
|
+
|
962
|
+
###
|
963
|
+
Disable watching CSS changes on the element belonging to this object
|
964
|
+
###
|
965
|
+
disableCSSWatch: ->
|
966
|
+
return unless SwitchAccessCommon.options.highlighter.use == true and
|
967
|
+
SwitchAccessCommon.options.highlighter.watch_for_resize == true
|
968
|
+
@log "disableCSSWatch", "trace" if (@options.debug)
|
969
|
+
@runtime.watching = false
|
970
|
+
@runtime.jq_element.csswatch('stop')
|
971
|
+
|
972
|
+
###
|
973
|
+
Add a data attribute to the element that has a unique ID.
|
974
|
+
Will also add the same attribute as a class if option
|
975
|
+
set_unique_element_class is enabled.
|
976
|
+
###
|
977
|
+
uniqueDataAttr: (create = false) ->
|
978
|
+
@log "uniqueDataAttr: Create: #{create}", "trace" if (@options.debug)
|
979
|
+
if create
|
980
|
+
@runtime.uuid = SwitchAccessCommon.generateRandomUUID()
|
981
|
+
@runtime.jq_element.data(SwitchAccessCommon.options.internal.unique_element_data_attribute, @runtime.uuid)
|
982
|
+
if SwitchAccessCommon.options.set_unique_element_class == true
|
983
|
+
@runtime.jq_element.addClass("#{SwitchAccessCommon.options.internal.unique_element_data_attribute}+uuid")
|
984
|
+
@runtime.uuid
|
985
|
+
else
|
986
|
+
@runtime.uuid
|
987
|
+
|
988
|
+
###
|
989
|
+
Callback for resize event on this particular element
|
990
|
+
###
|
991
|
+
callbackForResize: (event, changes) ->
|
992
|
+
@log "callbackForResize", "trace" if (@options.debug)
|
993
|
+
return unless SwitchAccessCommon.options.highlighter.use
|
994
|
+
@setHighlighterSize(@runtime.jq_element, @runtime.jq_highlighter)
|
995
|
+
@setHighlighterPosition(@runtime.jq_element, @runtime.jq_highlighter)
|
996
|
+
# if (changes.keys)
|
997
|
+
|
998
|
+
###
|
999
|
+
Play the sound for the current element upon highlight
|
1000
|
+
###
|
1001
|
+
# playHighlightSound: ->
|
1002
|
+
|
1003
|
+
|
1004
|
+
###
|
1005
|
+
Play the sound for the current element upon activation
|
1006
|
+
###
|
1007
|
+
# playActivateSound: ->
|