card-mod-script 0.13.1 → 0.14.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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/assets/script/decko/autosave.js.coffee +30 -0
  3. data/assets/script/decko/bridge.js.coffee +31 -0
  4. data/assets/script/decko/card_menu.js.coffee +26 -0
  5. data/assets/script/decko/components.js.coffee +49 -0
  6. data/assets/script/decko/decko.js.coffee +82 -0
  7. data/assets/script/decko/doubleclick.js.coffee +30 -0
  8. data/assets/script/decko/editor.js.coffee +57 -0
  9. data/assets/script/decko/filter.js.coffee +183 -0
  10. data/assets/script/decko/filter_items.js.coffee +128 -0
  11. data/assets/script/decko/filter_links.js.coffee +81 -0
  12. data/assets/script/decko/follow.js.coffee +22 -0
  13. data/assets/script/decko/layout.js.coffee +76 -0
  14. data/assets/script/decko/link_editor.js.coffee +61 -0
  15. data/assets/script/decko/mod.js.coffee +79 -0
  16. data/assets/script/decko/modal.js.coffee +113 -0
  17. data/assets/script/decko/name_editor.js.coffee +40 -0
  18. data/assets/script/decko/navbox.js.coffee +74 -0
  19. data/assets/script/decko/nest_editor.js.coffee +166 -0
  20. data/assets/script/decko/nest_editor_name.js.coffee +102 -0
  21. data/assets/script/decko/nest_editor_options.js.coffee +93 -0
  22. data/assets/script/decko/nest_editor_rules.js.coffee +3 -0
  23. data/assets/script/decko/overlay.js.coffee +54 -0
  24. data/assets/script/decko/pointer_config.js.coffee +79 -0
  25. data/assets/script/decko/pointer_list_editor.js.coffee +67 -0
  26. data/assets/script/decko/recaptcha.js.coffee +19 -0
  27. data/assets/script/decko/selectable_filtered_content.js.coffee +12 -0
  28. data/assets/script/decko/slot.js.coffee +182 -0
  29. data/assets/script/decko/slot_ready.js.coffee +12 -0
  30. data/assets/script/decko/slotter.js.coffee +268 -0
  31. data/assets/script/decko/type_editor.js.coffee +21 -0
  32. data/assets/script/decko/upload.js.coffee +64 -0
  33. data/assets/script/jquery-ui.min.js +13 -0
  34. data/assets/script/jquery.autosize.js +274 -0
  35. data/assets/script/manifest.yml +57 -0
  36. data/init/early/init_execjs.rb +3 -0
  37. data/set/abstract/00_script.rb +30 -31
  38. data/set/abstract/01_asset_script.rb +0 -16
  39. data/set/abstract/{script_asset_list.rb → script_group.rb} +12 -13
  40. data/set/all/head_javascript.rb +12 -8
  41. data/set/right/script.rb +1 -14
  42. data/set/type/local_script_folder_group.rb +2 -2
  43. data/set/type/local_script_manifest_group.rb +1 -1
  44. data/set/type_plus_right/mod/script.rb +56 -0
  45. data/set/type_plus_right/set/script.rb +7 -0
  46. data/vendor/jquery_file_upload/LICENSE.txt +11 -12
  47. data/vendor/jquery_file_upload/README.md +189 -72
  48. data/vendor/jquery_file_upload/SECURITY.md +227 -0
  49. data/vendor/jquery_file_upload/VULNERABILITIES.md +118 -0
  50. data/vendor/jquery_file_upload/cors/postmessage.html +68 -58
  51. data/vendor/jquery_file_upload/cors/result.html +12 -10
  52. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +24 -13
  53. data/vendor/jquery_file_upload/css/jquery.fileupload.css +3 -4
  54. data/vendor/jquery_file_upload/docker-compose.yml +55 -0
  55. data/vendor/jquery_file_upload/index.html +332 -230
  56. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +109 -109
  57. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +81 -73
  58. data/vendor/jquery_file_upload/js/demo.js +75 -0
  59. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +82 -94
  60. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +321 -300
  61. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +138 -146
  62. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +737 -692
  63. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +91 -97
  64. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +82 -94
  65. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1569 -1451
  66. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +208 -205
  67. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +397 -340
  68. data/vendor/jquery_file_upload/package-lock.json +6853 -0
  69. data/vendor/jquery_file_upload/package.json +71 -10
  70. data/vendor/jquery_file_upload/server/gae-python/app.yaml +11 -10
  71. data/vendor/jquery_file_upload/server/php/Dockerfile +23 -17
  72. data/vendor/jquery_file_upload/server/php/UploadHandler.php +206 -137
  73. data/vendor/jquery_file_upload/server/php/php.ini +5 -0
  74. data/vendor/jquery_file_upload/test/index.html +36 -159
  75. data/vendor/jquery_file_upload/test/unit.js +989 -0
  76. data/vendor/jquery_file_upload/test/vendor/chai.js +10854 -0
  77. data/vendor/jquery_file_upload/test/vendor/mocha.css +325 -0
  78. data/vendor/jquery_file_upload/test/vendor/mocha.js +18178 -0
  79. data/vendor/jquery_file_upload/wdio/LICENSE.txt +20 -0
  80. data/vendor/jquery_file_upload/wdio/assets/black+white-3x2.jpg +0 -0
  81. data/vendor/jquery_file_upload/wdio/assets/black+white-60x40.gif +0 -0
  82. data/vendor/jquery_file_upload/wdio/conf/chrome.js +40 -0
  83. data/vendor/jquery_file_upload/wdio/conf/firefox.js +25 -0
  84. data/vendor/jquery_file_upload/wdio/hooks/index.js +36 -0
  85. data/vendor/jquery_file_upload/wdio/test/pages/file-upload.js +79 -0
  86. data/vendor/jquery_file_upload/wdio/test/specs/01-file-upload.js +25 -0
  87. data/vendor/jquery_file_upload/wdio/wdio.conf.js +4 -0
  88. metadata +66 -50
  89. data/file/mod_script_script_decko_machine_output/file.js +0 -2710
  90. data/file/mod_script_script_jquery_machine_output/file.js +0 -12924
  91. data/lib/javascript/script_html5shiv_printshiv.js +0 -1
  92. data/set/self/script_html5shiv_printshiv.rb +0 -11
  93. data/set/self/script_mods.rb +0 -1
  94. data/set/type/mod_script_assets.rb +0 -21
  95. data/vendor/jquery_file_upload/CONTRIBUTING.md +0 -15
  96. data/vendor/jquery_file_upload/angularjs.html +0 -211
  97. data/vendor/jquery_file_upload/basic-plus.html +0 -226
  98. data/vendor/jquery_file_upload/basic.html +0 -136
  99. data/vendor/jquery_file_upload/bower-version-update.js +0 -16
  100. data/vendor/jquery_file_upload/bower.json +0 -64
  101. data/vendor/jquery_file_upload/css/jquery-ui-demo-ie8.css +0 -21
  102. data/vendor/jquery_file_upload/css/jquery-ui-demo.css +0 -67
  103. data/vendor/jquery_file_upload/css/style.css +0 -15
  104. data/vendor/jquery_file_upload/jquery-ui.html +0 -252
  105. data/vendor/jquery_file_upload/js/app.js +0 -101
  106. data/vendor/jquery_file_upload/js/jquery.fileupload-angular.js +0 -437
  107. data/vendor/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +0 -161
  108. data/vendor/jquery_file_upload/js/main.js +0 -75
  109. data/vendor/jquery_file_upload/server/gae-go/app/main.go +0 -361
  110. data/vendor/jquery_file_upload/server/gae-go/app.yaml +0 -12
  111. data/vendor/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
  112. data/vendor/jquery_file_upload/server/gae-go/static/robots.txt +0 -2
  113. data/vendor/jquery_file_upload/server/php/docker-compose.yml +0 -9
  114. data/vendor/jquery_file_upload/test/test.js +0 -1292
@@ -0,0 +1,182 @@
1
+ $.extend decko,
2
+ snakeCase: (str)->
3
+ str.replace /([a-z])([A-Z])/g, (match) -> match[0] + '_' +
4
+ match[1].toLowerCase()
5
+
6
+ # returns full path with slot parameters
7
+ slotPath: (path, slot)->
8
+ params = decko.slotData(slot)
9
+ decko.path(path) + ( (if path.match /\?/ then '&' else '?') + $.param(params) )
10
+
11
+ slotData: (slot) ->
12
+ xtra = {}
13
+ main = $('#main').children('.card-slot').data 'cardName'
14
+ xtra['main'] = main if main?
15
+
16
+ if slot
17
+ xtra['is_main'] = true if slot.isMain()
18
+ slotdata = slot.data 'slot'
19
+ if slotdata?
20
+ decko.slotParams slotdata, xtra, 'slot'
21
+ xtra['type'] = slotdata['type'] if slotdata['type']
22
+ xtra
23
+
24
+ slotEditView: (slot) ->
25
+ data = decko.slotData(slot)
26
+ switch data["slot[edit]"]
27
+ when "inline" then "edit_inline"
28
+ when "full" then "bridge"
29
+ else "edit"
30
+
31
+ slotEditLink: (slot) ->
32
+ edit_links =
33
+ slot.find(".edit-link").filter (i, el) ->
34
+ $(el).slot().data('slotId') == slot.data('slotId')
35
+
36
+ if edit_links[0] then $(edit_links[0]) else false
37
+
38
+ slotParams: (raw, processed, prefix)->
39
+ $.each raw, (key, value)->
40
+ cgiKey = prefix + '[' + decko.snakeCase(key) + ']'
41
+ if key == 'items'
42
+ decko.slotParams value, processed, cgiKey
43
+ else
44
+ processed[cgiKey] = value
45
+
46
+ contentLoaded: (el, slotter)->
47
+ decko.initializeEditors(el)
48
+ notice = slotter.attr('notify-success')
49
+ if notice?
50
+ el.notify notice, "success"
51
+ el.triggerSlotReady(slotter)
52
+
53
+ slotReady: (func)->
54
+ $('document').ready ->
55
+ $('body').on 'slotReady', '.card-slot', (e, slotter) ->
56
+ e.stopPropagation()
57
+ if slotter?
58
+ func.call this, $(this), $(slotter)
59
+ else
60
+ func.call this, $(this)
61
+
62
+ slotDestroy: (func)->
63
+ $('document').ready ->
64
+ $('body').on 'slotDestroy', '.card-slot, ._modal-slot', (e) ->
65
+ e.stopPropagation()
66
+ func.call this, $(this)
67
+
68
+ jQuery.fn.extend
69
+ slot: (status="success", mode="replace") ->
70
+ if mode == "modal"
71
+ @modalSlot()
72
+ else
73
+ @selectSlot("slot-#{status}-selector") ||
74
+ @selectSlot("slot-selector") ||
75
+ @closest(".card-slot")
76
+
77
+ selectSlot: (selectorName) ->
78
+ if selector = @data(selectorName)
79
+ slot = @findSlot selector
80
+ slot && slot[0] && slot
81
+
82
+ isSlot: ->
83
+ $(this).hasClass "card-slot"
84
+
85
+ isMain: ->
86
+ @slot().parent('#main')[0]
87
+
88
+ isMainOrMainModal: ->
89
+ el = $(this)
90
+ el = el.findOriginSlot("modal") if el.closest(".modal")[0]
91
+ el && el.isMain()
92
+
93
+ findSlot: (selector) ->
94
+ if selector == "modal-origin"
95
+ @findOriginSlot("modal")
96
+ else if selector == "overlay-origin"
97
+ @findOriginSlot("overlay")
98
+ else
99
+ target_slot = @closest(selector)
100
+ parent_slot = @closest '.card-slot'
101
+
102
+ # if slot-selector doesn't apply to a child, search in all parent slots and finally in the body
103
+ while target_slot.length == 0 and parent_slot.length > 0
104
+ target_slot = $(parent_slot).find(selector)
105
+ parent_slot = $(parent_slot).parent().closest '.card-slot'
106
+ if target_slot.length == 0
107
+ $(selector)
108
+ else
109
+ target_slot
110
+
111
+ # type can be "modal" or "overlay"
112
+ findOriginSlot: (type) ->
113
+ overlaySlot = @closest("[data-#{type}-origin-slot-id]")
114
+ origin_slot_id = overlaySlot.data("#{type}-origin-slot-id")
115
+ origin_slot = $("[data-slot-id=#{origin_slot_id}]")
116
+ if origin_slot[0]?
117
+ origin_slot
118
+ else
119
+ console.log "couldn't find origin with slot id #{origin_slot_id}"
120
+
121
+ reloadSlot: (url) ->
122
+ $slot = $(this)
123
+ if $slot.length > 1
124
+ $slot.each ->
125
+ $(this).reloadSlot url
126
+ return
127
+
128
+ $slot = $slot.slot() unless $slot.isSlot
129
+ return unless $slot[0]
130
+
131
+ unless url?
132
+ url = $slot.slotUrl()
133
+ $slot.addClass 'slotter'
134
+ $slot.attr 'href', url
135
+ $slot.data "url", url
136
+ this[0].href = url # that's where handleRemote gets the url from
137
+ # .attr(href, url) only works for anchors
138
+ $slot.data "remote", true
139
+ $.rails.handleRemote($slot)
140
+
141
+ clearSlot: () ->
142
+ @triggerSlotDestroy()
143
+ @empty()
144
+
145
+ slotUrl: ->
146
+ decko.slotPath "#{this.slotMark()}?view=#{@data("slot")["view"]}"
147
+
148
+ slotMark: ->
149
+ if @data('cardId') then "~#{@data('cardId')}" else @data("cardName")
150
+
151
+ setSlotContent: (newContent, mode, $slotter) ->
152
+ v = $(newContent)[0] && $(newContent) || newContent
153
+
154
+ if typeof(v) == "string"
155
+ # Needed to support "TEXT: result" pattern in success (eg deleting nested cards)
156
+ @slot("success", mode).replaceWith v
157
+ else
158
+ if v.hasClass("_overlay")
159
+ mode = "overlay"
160
+ else if v.hasClass("_modal")
161
+ mode = "modal"
162
+ @slot("success", mode).setSlotContentFromElement v, mode, $slotter
163
+ v
164
+
165
+ setSlotContentFromElement: (el, mode, $slotter) ->
166
+ if mode == "overlay"
167
+ @addOverlay(el, $slotter)
168
+ else if el.hasClass("_modal-slot") or mode == "modal"
169
+ el.showAsModal($slotter)
170
+ else
171
+ slot_id = @data("slot-id")
172
+ el.attr("data-slot-id", slot_id) if slot_id
173
+ @triggerSlotDestroy()
174
+ @replaceWith el
175
+ decko.contentLoaded(el, $slotter)
176
+
177
+ triggerSlotReady: (slotter) ->
178
+ @trigger "slotReady", slotter if @isSlot()
179
+ @find(".card-slot").trigger "slotReady", slotter
180
+
181
+ triggerSlotDestroy: () ->
182
+ @trigger "slotDestroy"
@@ -0,0 +1,12 @@
1
+ decko.slotReady (slot) ->
2
+ slot.find('._disappear').delay(5000).animate(
3
+ height: 0, 1000, -> $(this).hide())
4
+
5
+ if slot.hasClass("_refresh-timer")
6
+ setTimeout(
7
+ -> slot.reloadSlot(slot.data("refresh-url")),
8
+ 2000
9
+ )
10
+
11
+
12
+
@@ -0,0 +1,268 @@
1
+ # There are three places that can control what happens after an ajax request
2
+ # 1. the element that triggered the request (eg. a link or a button)
3
+ # 2. the closest ".slotter" element
4
+ # (if the trigger itself isn't a slotter,
5
+ # a common example is that a form is a slotter but the form buttons aren't)
6
+ # 3. the slot returned by the request
7
+ #
8
+ # A slot is an element marked with "card-slot" class, a slotter has a "slotter" class.
9
+ # By the default, the closest slot of the slotter is replaced with the new slot that the
10
+ # request returned. The behavior can be changed with css classes and data attributes.
11
+ #
12
+ # To 1. The trigger element has only a few options to override the slotter.
13
+ # classes:
14
+ # "_close-modal-on-success"
15
+ # "_close-overlay-on-success"
16
+ # "_update-origin"
17
+ #
18
+ # To 2. The slotter is the standard way to define what happens with request result
19
+ # data:
20
+ # slot-selector
21
+ # a css selector that defines which slot will be replaced.
22
+ # You can also use "modal-origin" and "overlay-origin" to refer to the origin slots.
23
+ # slot-success-selector/slot-error-selector
24
+ # the same as slot-selector but only used
25
+ # for success case or error case, respectively
26
+ # update-foreign-slot
27
+ # a css selector to specify an additional slot that will be
28
+ # updated after the request.
29
+ # update-foreign-slot-url
30
+ # a url to fetch the new content for the additional slot
31
+ # if not given the slot is updated with the same card and view that was used before
32
+ # update-origin
33
+ # if present then the slot from where the current modal or overlay slot was opened
34
+ # will be updated
35
+ # slotter-mode
36
+ # possible values are
37
+ # replace (default)
38
+ # replace the closest slot with new slot
39
+ # modal
40
+ # show new slot in modal; if there is already a modal then put it on top
41
+ # modal-replace
42
+ # replace existing modal
43
+ # overlay
44
+ # show new slot in overlay
45
+ # update-origin
46
+ # update closest slot of the slotter that opened the modal or overlay
47
+ # (assumes that the request was triggered from a modal or overlay)
48
+ # If you need the update-origin mode together with another mode then use
49
+ # data-update-origin="true".
50
+ # silent-success
51
+ # do nothing
52
+ #
53
+ # classes:
54
+ # _close-overlay
55
+ # _close-modal
56
+ #
57
+ # To 3. Similar as 1, the slot has only overlay and modal options.
58
+ # classes:
59
+ # _modal
60
+ # show slot in modal
61
+ # _overlay
62
+ # show slot in overlay
63
+ #
64
+ #
65
+ $(window).ready ->
66
+ $('body').on 'ajax:success', '.slotter', (event, data) ->
67
+ $(this).slotterSuccess event, data
68
+
69
+ $('body').on 'ajax:error', '.slotter', (event, xhr) ->
70
+ $(this).showErrorResponse xhr.status, xhr.responseText
71
+
72
+ $('body').on 'click', 'button.slotter', (event)->
73
+ return false if !$.rails.allowAction $(this)
74
+ $.rails.handleRemote $(this)
75
+
76
+ $('body').on 'click', '._clickable.slotter', (event)->
77
+ $(this)[0].href = $(this).attr("href") # that's where rails.handleRemote
78
+ # expects the url
79
+ $.rails.handleRemote $(this)
80
+
81
+ $('body').on 'click', '[data-dismiss="overlay"]', (event) ->
82
+ $(this).findSlot(".card-slot._overlay").removeOverlay()
83
+
84
+ $('body').on 'click', '._close-overlay-on-success', (event) ->
85
+ $(this).closeOnSuccess("overlay")
86
+
87
+ $('body').on 'click', '._close-modal-on-success', (event) ->
88
+ $(this).closeOnSuccess("modal")
89
+
90
+ $('body').on 'click', '._close-on-success', (event) ->
91
+ $(this).closeOnSuccess()
92
+
93
+ $('body').on 'click', '._update-origin', (event) ->
94
+ $(this).closest('.slotter').data("slotter-mode", "update-origin")
95
+
96
+ $('body').on 'submit', 'form.slotter', (event)->
97
+ form = $(this)
98
+ if form.data("main-success") and form.isMainOrMainModal()
99
+ form.mainSuccess()
100
+ if form.data('recaptcha') == 'on'
101
+ return form.handleRecaptchaBeforeSubmit(event)
102
+
103
+ $('body').on 'ajax:beforeSend', '.slotter', (event, xhr, opt)->
104
+ $(this).slotterBeforeSend opt
105
+
106
+ jQuery.fn.extend
107
+ mainSuccess: ()->
108
+ form = $(this)
109
+ $.each form.data("main-success"), (key, value)->
110
+ inputSelector = "[name=success\\[" + key + "\\]]"
111
+ input = form.find inputSelector
112
+ unless input[0]
113
+ input = $('<input type="hidden" name="success[' + key + ']"/>')
114
+ form.append input
115
+ input.val value
116
+
117
+ slotterSuccess: (event, responseData) ->
118
+ debugger
119
+ unless @hasClass("slotter")
120
+ console.log "warning: slotterSuccess called on non-slotter element #{this}"
121
+ return
122
+
123
+ return if event.slotSuccessful
124
+
125
+ @showSuccessResponse responseData, @data("slotter-mode")
126
+
127
+ if @hasClass "_close-overlay"
128
+ @removeOverlay()
129
+ if @hasClass "_close-modal"
130
+ @closest('.modal').modal('hide')
131
+
132
+ # should scroll to top after clicking on new page
133
+ if @hasClass "card-paging-link"
134
+ slot_top_pos = @slot().offset().top
135
+ $("body").scrollTop slot_top_pos
136
+ if @data("update-foreign-slot")
137
+ $slot = @findSlot @data("update-foreign-slot")
138
+ reload_url = @data("update-foreign-slot-url")
139
+ $slot.reloadSlot reload_url
140
+
141
+ if @data('original-slotter-mode')
142
+ @attr 'data-slotter-mode', @data('original-slotter-mode')
143
+ if @data('original-slot-selector')
144
+ @attr 'data-slot-selector', @data('original-slot-selector')
145
+
146
+ event.slotSuccessful = true
147
+
148
+ showSuccessResponse: (responseData, mode) ->
149
+ if responseData.redirect
150
+ window.location = responseData.redirect
151
+ else if responseData.reload
152
+ window.location.reload(true)
153
+ else
154
+ switch mode
155
+ when "silent-success" then return
156
+ when "update-modal-origin" then @updateModalOrigin()
157
+ when "update-origin" then @updateOrigin()
158
+ else @updateSlot responseData, mode
159
+
160
+ showErrorResponse: (status, result) ->
161
+ if status == 403 #permission denied
162
+ $(result).showAsModal $(this)
163
+ else if status == 900
164
+ $(result).showAsModal $(this)
165
+ else
166
+ @notify result, "error"
167
+
168
+ if status == 409 #edit conflict
169
+ @slot().find('.current_revision_id').val(
170
+ @slot().find('.new-current-revision-id').text()
171
+ )
172
+
173
+ updateModalOrigin: () ->
174
+ if @overlaySlot()
175
+ overlayOrigin = @findOriginSlot("overlay")
176
+ overlayOrigin.updateOrigin()
177
+ else if @closest("#modal-container")[0]
178
+ @updateOrigin()
179
+
180
+ updateOrigin: () ->
181
+ type = if @overlaySlot()
182
+ "overlay"
183
+ else if @closest("#modal-container")[0]
184
+ "modal"
185
+
186
+ return unless type?
187
+
188
+ origin = @findOriginSlot(type)
189
+ if origin && origin[0]?
190
+ origin.reloadSlot()
191
+
192
+ registerAsOrigin: (type, slot) ->
193
+ if slot.hasClass("_modal-slot")
194
+ slot = slot.find(".modal-body") # put the origin slot id on the modal-body instead
195
+ # of on the slot, so that it survives slot reloads
196
+ slot.attr("data-#{type}-origin-slot-id", @closest(".card-slot").data("slot-id"))
197
+
198
+ updateSlot: (newContent, mode) ->
199
+ mode ||= "replace"
200
+ @setSlotContent newContent, mode, $(this)
201
+
202
+ # close modal or overlay
203
+ closeOnSuccess: (type) ->
204
+ slotter = @closest('.slotter')
205
+ if !type?
206
+ type = if @isInOverlay() then "overlay" else "modal"
207
+ slotter.addClass "_close-#{type}"
208
+
209
+ slotterBeforeSend: (opt) ->
210
+ return if opt.skip_before_send
211
+
212
+ # avoiding duplication. could be better test?
213
+ unless (opt.url.match(/home_view/) or @data("slotter-mode") == "modal")
214
+ opt.url = decko.slotPath opt.url, @slot()
215
+
216
+ if @is('form')
217
+ if data = @data 'file-data'
218
+ # NOTE - this entire solution is temporary.
219
+ @uploadWithBlueimp(data, opt)
220
+ false
221
+
222
+ uploadWithBlueimp: (data, opt) ->
223
+ input = @find '.file-upload'
224
+ if input[1]
225
+ @notify(
226
+ "Decko does not yet support multiple files in a single form.",
227
+ "error"
228
+ )
229
+ return false
230
+
231
+ widget = input.data 'wblueimpFileupload' #jQuery UI widget
232
+
233
+ # browsers that can't do ajax uploads use iframe
234
+ unless widget._isXHRUpload(widget.options)
235
+ # can't do normal redirects.
236
+ @find('[name=success]').val('_self')
237
+ # iframe response not passed back;
238
+ # all responses treated as success. boo
239
+ opt.url += '&simulate_xhr=true'
240
+ # iframe is not xhr request,
241
+ # so would otherwise get full response with layout
242
+ iframeUploadFilter = (data)-> data.find('body').html()
243
+ opt.dataFilter = iframeUploadFilter
244
+ # gets rid of default html and body tags
245
+
246
+ args = $.extend opt, (widget._getAJAXSettings data), url: opt.url
247
+ # combines settings from decko's slotter and jQuery UI's upload widget
248
+ args.skip_before_send = true #avoid looping through this method again
249
+
250
+ $.ajax( args )
251
+
252
+ handleRecaptchaBeforeSubmit: (event) ->
253
+ recaptcha = @find("input._recaptcha-token")
254
+
255
+ if !recaptcha[0]?
256
+ # monkey error (bad form)
257
+ recaptcha.val "recaptcha-token-field-missing"
258
+ else if recaptcha.hasClass "_token-updated"
259
+ # recaptcha token is fine - continue submitting
260
+ recaptcha.removeClass "_token-updated"
261
+ else if !grecaptcha?
262
+ # shark error (probably recaptcha keys of pre v3 version)
263
+ recaptcha.val "grecaptcha-undefined"
264
+ else
265
+ @updateRecaptchaToken(event)
266
+ # this stops the submit here
267
+ # and submits again when the token is ready
268
+
@@ -0,0 +1,21 @@
1
+ $(window).ready ->
2
+ $('body').on "change", '._live-type-field', ->
3
+ $this = $(this)
4
+
5
+ setSlotMode($this)
6
+ debugger
7
+ $this.data 'params', $this.closest('form').serialize()
8
+ $this.data 'url', $this.attr 'href'
9
+
10
+ $('body').on 'change', '.edit-type-field', ->
11
+ $(this).closest('form').submit()
12
+
13
+ setSlotMode = ($el, mode=null) ->
14
+ $slotter = $el.closest(".slotter")
15
+ if $slotter.length
16
+ if $slotter.attr('data-slotter-mode')
17
+ $slotter.attr 'data-original-slotter-mode', $slotter.attr('data-slotter-mode')
18
+ $slotter.attr 'data-slotter-mode', mode
19
+ if $slotter.attr('data-slot-selector')
20
+ $slotter.attr 'data-original-slot-selector', $slotter.attr('data-slot-selector')
21
+ $slotter.removeAttr 'data-slot-selector'
@@ -0,0 +1,64 @@
1
+ $.extend decko,
2
+ upload_file: (fileupload) ->
3
+ # for file as a subcard in a form,
4
+ # excess parameters are included in the request which cause errors.
5
+ # only the file, type_id and attachment_card_name are needed
6
+ # attachment_card_name is the original card name,
7
+ # ex: card[subcards][+logo][image], card[file]
8
+ $(fileupload).on 'fileuploadsubmit', (e,data) ->
9
+ $_this = $(this)
10
+ card_name = $_this.siblings(".attachment_card_name:first").attr("name")
11
+ type_id = $_this.siblings("#attachment_type_id").val()
12
+ data.formData = {
13
+ "card[type_id]": type_id,
14
+ "attachment_upload": card_name
15
+ }
16
+ $_fileupload = $(fileupload)
17
+ if $_fileupload.closest("form").attr("action").indexOf("update") > -1
18
+ url = "card/update/"+$(fileupload).siblings("#file_card_name").val()
19
+ else
20
+ url = "card/create"
21
+ $(fileupload).fileupload(
22
+ url: decko.path(url),
23
+ dataType: 'html',
24
+ done: decko.doneFile,
25
+ add: decko.chooseFile,
26
+ progressall: decko.progressallFile
27
+ )#, forceIframeTransport: true )
28
+
29
+ chooseFile: (e, data) ->
30
+ data.form.find('button[type=submit]').attr('disabled',true)
31
+ editor = $(this).closest '.card-editor'
32
+ $('#progress').show()
33
+ editor.append '<input type="hidden" class="extra_upload_param" ' +
34
+ 'value="true" name="attachment_upload">'
35
+ editor.append '<input type="hidden" class="extra_upload_param" ' +
36
+ 'value="preview_editor" name="view">'
37
+ data.submit()
38
+ editor.find('.choose-file').hide()
39
+ # editor.find(".file-upload").prop "disabled", true
40
+ editor.find('.extra_upload_param').remove()
41
+
42
+ progressallFile: (e, data) ->
43
+ progress = parseInt(data.loaded / data.total * 100, 10)
44
+ $('#progress .progress-bar').css('width', progress + '%')
45
+
46
+ doneFile: (e, data) ->
47
+ editor = $(this).closest '.card-editor'
48
+ editor.find('.chosen-file').replaceWith data.result
49
+ data.form.find('button[type=submit]').attr('disabled',false)
50
+
51
+ $(window).ready ->
52
+ $('body').on 'click', '.cancel-upload', ->
53
+ editor = $(this).closest '.card-editor'
54
+ editor.find('.choose-file').show()
55
+ # editor.find(".file-upload").prop "disabled", false
56
+ editor.find('.chosen-file').empty()
57
+ editor.find('.progress').show()
58
+ editor.find('#progress .progress-bar').css('width', '0%')
59
+ editor.find('#progress').hide()
60
+
61
+ $('body').on "submit", "form", ->
62
+ uploader = $(this).find ".file-upload[type=file]"
63
+ if uploader[0]
64
+ uploader.prop "disabled", true