weaver 0.8.13 → 0.9.0

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/data/weaver/css/plugins/codemirror/codemirror.css +97 -96
  3. data/data/weaver/css/style-dark.css +8628 -0
  4. data/data/weaver/css/style.css +37 -0
  5. data/data/weaver/js/plugins/codemirror/codemirror.js +8817 -6763
  6. data/data/weaver/js/plugins/skeuocard/Gruntfile.coffee +74 -0
  7. data/data/weaver/js/plugins/skeuocard/LICENSE +21 -0
  8. data/data/weaver/js/plugins/skeuocard/README.md +393 -0
  9. data/data/weaver/js/plugins/skeuocard/bower.json +40 -0
  10. data/data/weaver/js/plugins/skeuocard/fonts/ocra-webfont.eot +0 -0
  11. data/data/weaver/js/plugins/skeuocard/fonts/ocra-webfont.svg +138 -0
  12. data/data/weaver/js/plugins/skeuocard/fonts/ocra-webfont.ttf +0 -0
  13. data/data/weaver/js/plugins/skeuocard/fonts/ocra-webfont.woff +0 -0
  14. data/data/weaver/js/plugins/skeuocard/images/card-flip-arrow.png +0 -0
  15. data/data/weaver/js/plugins/skeuocard/images/card-front-background.png +0 -0
  16. data/data/weaver/js/plugins/skeuocard/images/card-invalid-indicator.png +0 -0
  17. data/data/weaver/js/plugins/skeuocard/images/card-valid-anim.gif +0 -0
  18. data/data/weaver/js/plugins/skeuocard/images/card-valid-indicator.png +0 -0
  19. data/data/weaver/js/plugins/skeuocard/images/error-pointer.png +0 -0
  20. data/data/weaver/js/plugins/skeuocard/images/issuers/visa-chase-sapphire.png +0 -0
  21. data/data/weaver/js/plugins/skeuocard/images/issuers/visa-simple-front.png +0 -0
  22. data/data/weaver/js/plugins/skeuocard/images/products/amex-front.png +0 -0
  23. data/data/weaver/js/plugins/skeuocard/images/products/dinersclubintl-front.png +0 -0
  24. data/data/weaver/js/plugins/skeuocard/images/products/discover-front.png +0 -0
  25. data/data/weaver/js/plugins/skeuocard/images/products/generic-back.png +0 -0
  26. data/data/weaver/js/plugins/skeuocard/images/products/generic-front.png +0 -0
  27. data/data/weaver/js/plugins/skeuocard/images/products/jcb-front.png +0 -0
  28. data/data/weaver/js/plugins/skeuocard/images/products/maestro-front.png +0 -0
  29. data/data/weaver/js/plugins/skeuocard/images/products/mastercard-front.png +0 -0
  30. data/data/weaver/js/plugins/skeuocard/images/products/unionpay-front.png +0 -0
  31. data/data/weaver/js/plugins/skeuocard/images/products/visa-back.png +0 -0
  32. data/data/weaver/js/plugins/skeuocard/images/products/visa-front.png +0 -0
  33. data/data/weaver/js/plugins/skeuocard/images/src/card-front-background.fw.png +0 -0
  34. data/data/weaver/js/plugins/skeuocard/images/src/error-pointer.png +0 -0
  35. data/data/weaver/js/plugins/skeuocard/images/src/product-amex-front.fw.png +0 -0
  36. data/data/weaver/js/plugins/skeuocard/images/src/product-dinersclub-front.fw.png +0 -0
  37. data/data/weaver/js/plugins/skeuocard/images/src/product-discover-front.fw.png +0 -0
  38. data/data/weaver/js/plugins/skeuocard/images/src/product-generic-front.fw.png +0 -0
  39. data/data/weaver/js/plugins/skeuocard/images/src/product-jcb-front.fw.png +0 -0
  40. data/data/weaver/js/plugins/skeuocard/images/src/product-maestro-front.fw.png +0 -0
  41. data/data/weaver/js/plugins/skeuocard/images/src/product-mastercard-front.fw.png +0 -0
  42. data/data/weaver/js/plugins/skeuocard/images/src/product-unionpay-front.fw.png +0 -0
  43. data/data/weaver/js/plugins/skeuocard/images/src/product-visa-front.fw.png +0 -0
  44. data/data/weaver/js/plugins/skeuocard/index.html +124 -0
  45. data/data/weaver/js/plugins/skeuocard/javascripts/skeuocard.js +1748 -0
  46. data/data/weaver/js/plugins/skeuocard/javascripts/skeuocard.min.js +2 -0
  47. data/data/weaver/js/plugins/skeuocard/javascripts/src/CardProduct.coffee +284 -0
  48. data/data/weaver/js/plugins/skeuocard/javascripts/src/ExpirationInputView.coffee +206 -0
  49. data/data/weaver/js/plugins/skeuocard/javascripts/src/FlipTabView.coffee +67 -0
  50. data/data/weaver/js/plugins/skeuocard/javascripts/src/SegmentedCardNumberInputView.coffee +284 -0
  51. data/data/weaver/js/plugins/skeuocard/javascripts/src/Skeuocard.coffee +439 -0
  52. data/data/weaver/js/plugins/skeuocard/javascripts/src/TextInputView.coffee +42 -0
  53. data/data/weaver/js/plugins/skeuocard/javascripts/vendor/cssua.min.js +7 -0
  54. data/data/weaver/js/plugins/skeuocard/javascripts/vendor/demo.fix.js +17 -0
  55. data/data/weaver/js/plugins/skeuocard/javascripts/vendor/jquery-2.0.3.min.js +5 -0
  56. data/data/weaver/js/plugins/skeuocard/package-lock.json +760 -0
  57. data/data/weaver/js/plugins/skeuocard/package.json +19 -0
  58. data/data/weaver/js/plugins/skeuocard/screenshot.png +0 -0
  59. data/data/weaver/js/plugins/skeuocard/styles/demo.css +2 -0
  60. data/data/weaver/js/plugins/skeuocard/styles/skeuocard.css +2 -0
  61. data/data/weaver/js/plugins/skeuocard/styles/skeuocard.reset.css +2 -0
  62. data/data/weaver/js/plugins/skeuocard/styles/src/_browser_hacks.scss +52 -0
  63. data/data/weaver/js/plugins/skeuocard/styles/src/_cards.scss +516 -0
  64. data/data/weaver/js/plugins/skeuocard/styles/src/_util.scss +15 -0
  65. data/data/weaver/js/plugins/skeuocard/styles/src/demo.scss +265 -0
  66. data/data/weaver/js/plugins/skeuocard/styles/src/skeuocard.reset.scss +60 -0
  67. data/data/weaver/js/plugins/skeuocard/styles/src/skeuocard.scss +190 -0
  68. data/lib/weaver/element_types/accordion.rb +2 -0
  69. data/lib/weaver/page_types/page.rb +5 -0
  70. data/lib/weaver/page_types/structured_page.rb +1 -1
  71. data/lib/weaver/version.rb +1 -1
  72. metadata +69 -6
@@ -0,0 +1,284 @@
1
+ ###
2
+ # Skeuocard::SegmentedCardNumberInputView
3
+ # Provides a reconfigurable segmented input view for credit card numbers.
4
+ ###
5
+ class Skeuocard::SegmentedCardNumberInputView
6
+
7
+ _digits: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
8
+
9
+ _keys:
10
+ backspace: 8
11
+ tab: 9
12
+ enter: 13
13
+ del: 46
14
+ arrowLeft: 37
15
+ arrowUp: 38
16
+ arrowRight: 39
17
+ arrowDown: 40
18
+ arrows: [37..40]
19
+ command: 16
20
+ alt: 17
21
+
22
+ _specialKeys: [8, 9, 13, 46, 37, 38, 39, 40, 16, 17]
23
+
24
+ constructor: (opts = {})->
25
+ @optDefaults =
26
+ value: ""
27
+ groupings: [19]
28
+ placeholderChar: "X"
29
+ @options = $.extend({}, @optDefaults, opts)
30
+ @_state =
31
+ selectingAll: false # indicates whether the field is in "select all"
32
+ @_buildDOM()
33
+ @setGroupings(@options.groupings)
34
+
35
+ _buildDOM: ->
36
+ @el = $('<fieldset>')
37
+ @el.addClass('cc-field')
38
+ @el.delegate "input", "keypress", @_handleGroupKeyPress.bind(@)
39
+ @el.delegate "input", "keydown", @_handleGroupKeyDown.bind(@)
40
+ @el.delegate "input", "keyup", @_handleGroupKeyUp.bind(@)
41
+ @el.delegate "input", "paste", @_handleGroupPaste.bind(@)
42
+ @el.delegate "input", "change", @_handleGroupChange.bind(@)
43
+ @el.delegate "input", "focus", (e)=>
44
+ @el.addClass('focus')
45
+ @el.delegate "input", "blur", (e)=>
46
+ @el.removeClass('focus')
47
+
48
+ _handleGroupKeyDown: (e)->
49
+ # If this is called with the control or meta key, defer to another handler
50
+ return @_handleModifiedKeyDown(e) if e.ctrlKey or e.metaKey
51
+
52
+ inputGroupEl = $(e.currentTarget)
53
+ currentTarget = e.currentTarget # get rid of that e.
54
+ cursorStart = currentTarget.selectionStart
55
+ cursorEnd = currentTarget.selectionEnd
56
+ inputMaxLength = currentTarget.maxLength
57
+
58
+ prevInputEl = inputGroupEl.prevAll('input')
59
+ nextInputEl = inputGroupEl.nextAll('input')
60
+
61
+ switch e.which
62
+ # handle backspace
63
+ when @_keys.backspace
64
+ if prevInputEl.length > 0 and cursorEnd is 0
65
+ @_focusField(prevInputEl.first(), 'end')
66
+ # handle up arrow
67
+ when @_keys.arrowUp
68
+ if cursorEnd is inputMaxLength
69
+ @_focusField(inputGroupEl, 'start')
70
+ else
71
+ @_focusField(inputGroupEl.prev(), 'end')
72
+ e.preventDefault()
73
+ # handle down arrow
74
+ when @_keys.arrowDown
75
+ if cursorEnd is inputMaxLength
76
+ @_focusField(inputGroupEl.next(), 'start')
77
+ else
78
+ @_focusField(inputGroupEl, 'end')
79
+ e.preventDefault()
80
+ # handle left arrow
81
+ when @_keys.arrowLeft
82
+ if cursorEnd is 0
83
+ @_focusField(inputGroupEl.prev(), 'end')
84
+ e.preventDefault()
85
+ # handle right arrow
86
+ when @_keys.arrowRight
87
+ if cursorEnd is inputMaxLength
88
+ @_focusField(inputGroupEl.next(), 'start')
89
+ e.preventDefault()
90
+ else
91
+ if not (e.which in @_specialKeys) and
92
+ (cursorStart is inputMaxLength and cursorEnd is inputMaxLength) and
93
+ nextInputEl.length isnt 0
94
+ @_focusField(nextInputEl.first(), 'start')
95
+
96
+ # Allow the event to propagate, and otherwise be happy
97
+ return true
98
+
99
+ _handleGroupKeyPress: (e)->
100
+ inputGroupEl = $(e.currentTarget)
101
+ isDigit = (String.fromCharCode(e.which) in @_digits)
102
+
103
+ return true if e.ctrlKey or e.metaKey
104
+ return true if e.which is 0
105
+
106
+ if (not e.shiftKey and (e.which in @_specialKeys)) or isDigit
107
+ return true
108
+
109
+ e.preventDefault()
110
+ return false
111
+
112
+ _handleGroupKeyUp: (e)->
113
+ inputGroupEl = $(e.currentTarget)
114
+ currentTarget = e.currentTarget # get rid of that e.
115
+ inputMaxLength = currentTarget.maxLength
116
+
117
+ cursorStart = currentTarget.selectionStart
118
+ cursorEnd = currentTarget.selectionEnd
119
+
120
+ nextInputEl = inputGroupEl.nextAll('input')
121
+
122
+ return true if e.ctrlKey or e.metaKey # ignore control keys
123
+
124
+
125
+ if @_state.selectingAll and
126
+ (e.which in @_specialKeys) and
127
+ e.which isnt @_keys.command and
128
+ e.which isnt @_keys.alt
129
+ @_endSelectAll()
130
+
131
+ if not (e.which in @_specialKeys) and
132
+ not (e.shiftKey and e.which is @_keys.tab) and
133
+ (cursorStart is inputMaxLength and cursorEnd is inputMaxLength) and
134
+ nextInputEl.length isnt 0
135
+ @_focusField(nextInputEl.first(), 'start')
136
+
137
+ unless e.shiftKey and (e.which in @_specialKeys)
138
+ @trigger('change', [@])
139
+
140
+ return true
141
+
142
+ _handleModifiedKeyDown: (e)->
143
+ char = String.fromCharCode(e.which)
144
+ switch char
145
+ when 'a', 'A'
146
+ @_beginSelectAll()
147
+ e.preventDefault()
148
+
149
+ _handleGroupPaste: (e)->
150
+ # clean and re-split the value
151
+ setTimeout =>
152
+ newValue = @getValue().replace(/[^0-9]+/g, '')
153
+ @_endSelectAll() if @_state.selectingAll
154
+ @setValue(newValue)
155
+ @trigger('change', [@])
156
+ , 50
157
+
158
+ _handleGroupChange: (e)->
159
+ e.stopPropagation()
160
+
161
+ _getFocusedField: ->
162
+ @el.find("input:focus")
163
+
164
+ _beginSelectAll: ->
165
+ unless @el.hasClass('selecting-all')
166
+ @_state.lastGrouping = @options.groupings
167
+ @_state.lastLength = @getValue().length
168
+ @setGroupings(@optDefaults.groupings)
169
+ @el.addClass('selecting-all')
170
+ fieldEl = @el.find("input")
171
+ fieldEl[0].setSelectionRange(0, fieldEl.val().length)
172
+ @_state.selectingAll = true
173
+ else
174
+ fieldEl = @el.find("input")
175
+ fieldEl[0].setSelectionRange(0, fieldEl.val().length)
176
+
177
+ _endSelectAll: ->
178
+ if @el.hasClass('selecting-all')
179
+ # if the value hasn't been changed while selecting all, restore grouping
180
+ @_state.selectingAll = false
181
+ # restore groupings if length is the same
182
+ if @_state.lastLength is @getValue().length
183
+ @setGroupings(@_state.lastGrouping)
184
+ @el.removeClass('selecting-all')
185
+
186
+ # figure out what position in the overall value we're at given a selection
187
+ _indexInValueAtFieldSelection: (field)->
188
+ groupingIndex = @el.find('input').index(field)
189
+ offset = 0
190
+ offset += len for len, i in @options.groupings when i < groupingIndex
191
+ return offset + field[0].selectionEnd
192
+
193
+ setGroupings: (groupings, dontFocus)->
194
+ # store the value and current caret position so we can reapply it
195
+ _currentField = @_getFocusedField()
196
+ _value = @getValue()
197
+ _caretPosition = 0
198
+ if _currentField.length > 0
199
+ _caretPosition = @_indexInValueAtFieldSelection(_currentField)
200
+ # remove any existing input elements
201
+ @el.empty() # remove all existing inputs
202
+ for groupLength in groupings
203
+ groupEl = $("<input>").attr
204
+ type: 'text'
205
+ pattern: '[0-9]*'
206
+ size: groupLength
207
+ maxlength: groupLength
208
+ class: "group#{groupLength}"
209
+ placeholder: new Array(groupLength+1).join(@options.placeholderChar)
210
+ @el.append(groupEl)
211
+ @options.groupings = groupings
212
+ @setValue(_value)
213
+ _currentField = @_focusFieldForValue([_caretPosition, _caretPosition], dontFocus)
214
+ if _currentField? and _currentField[0].selectionEnd is _currentField[0].maxLength
215
+ @_focusField(_currentField.next(), 'start')
216
+
217
+ _focusFieldForValue: (place, dontFocus)->
218
+ value = @getValue()
219
+ if place is 'start'
220
+ field = @el.find('input').first()
221
+ @_focusField(field, place) unless dontFocus
222
+ else if place is 'end'
223
+ field = @el.find('input').last()
224
+ @_focusField(field, place) unless dontFocus
225
+ else
226
+ field = null
227
+ fieldOffset = null
228
+ _lastStartPos = 0
229
+ for groupLength, groupIndex in @options.groupings
230
+ if place[1] > _lastStartPos and place[1] <= _lastStartPos + groupLength
231
+ field = $(@el.find('input')[groupIndex])
232
+ fieldPosition = place[1] - _lastStartPos
233
+ _lastStartPos += groupLength
234
+ if field? and fieldPosition?
235
+ @_focusField(field, [fieldPosition, fieldPosition]) unless dontFocus
236
+ else
237
+ @_focusField(@el.find('input'), 'end') unless dontFocus
238
+ return field
239
+
240
+ _focusField: (field, place)->
241
+ if field.length isnt 0
242
+ field[0].focus()
243
+ if $(field[0]).is(':visible') and field[0] is document.activeElement
244
+ if place is 'start'
245
+ field[0].setSelectionRange(0, 0)
246
+ else if place is 'end'
247
+ fieldLen = field[0].maxLength
248
+ field[0].setSelectionRange(fieldLen, fieldLen)
249
+ else # array of start, end
250
+ field[0].setSelectionRange(place[0], place[1])
251
+
252
+ setValue: (newValue)->
253
+ _lastStartPos = 0
254
+ for groupLength, groupIndex in @options.groupings
255
+ el = $(@el.find('input').get(groupIndex))
256
+ groupVal = newValue.substr(_lastStartPos, groupLength)
257
+ el.val(groupVal)
258
+ _lastStartPos += groupLength
259
+
260
+ getValue: ->
261
+ buffer = ""
262
+ buffer += $(el).val() for el in @el.find('input')
263
+ return buffer
264
+
265
+ maxLength: ->
266
+ @options.groupings.reduce((a,b)->(a+b))
267
+
268
+ bind: (args...)->
269
+ @el.bind(args...)
270
+
271
+ trigger: (args...)->
272
+ @el.trigger(args...)
273
+
274
+ show: ->
275
+ @el.show()
276
+
277
+ hide: ->
278
+ @el.hide()
279
+
280
+ addClass: (args...)->
281
+ @el.addClass(args...)
282
+
283
+ removeClass: (args...)->
284
+ @el.removeClass(args...)