card-mod-script 0.13.0 → 0.13.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.
Files changed (40) 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 +46 -0
  6. data/assets/script/decko/decko.js.coffee +97 -0
  7. data/assets/script/decko/doubleclick.js.coffee +30 -0
  8. data/assets/script/decko/editor.js.coffee +55 -0
  9. data/assets/script/decko/filter.js.coffee +176 -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 +85 -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/recaptcha.js.coffee +19 -0
  25. data/assets/script/decko/selectable_filtered_content.js.coffee +12 -0
  26. data/assets/script/decko/slot.js.coffee +182 -0
  27. data/assets/script/decko/slot_ready.js.coffee +11 -0
  28. data/assets/script/decko/slotter.js.coffee +276 -0
  29. data/assets/script/decko/upload.js.coffee +57 -0
  30. data/assets/script/jquery-ui.min.js +13 -0
  31. data/assets/script/jquery.autosize.js +274 -0
  32. data/assets/script/manifest.yml +44 -0
  33. data/assets/script/script_pointer_config.js.coffee +80 -0
  34. data/assets/script/script_pointer_list_editor.js.coffee +67 -0
  35. data/file/mod_script_script_decko_machine_output/file.js +5 -30
  36. data/file/mod_script_script_jquery_machine_output/file.js +11 -9
  37. data/init/early/init_execjs.rb +3 -0
  38. data/set/all/head_javascript.rb +8 -3
  39. data/set/self/script_mods.rb +1 -1
  40. metadata +44 -10
@@ -0,0 +1,276 @@
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, c, d) ->
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, data) ->
118
+ unless @hasClass("slotter")
119
+ console.log "warning: slotterSuccess called on non-slotter element #{this}"
120
+ return
121
+
122
+ return if event.slotSuccessful
123
+
124
+ if @data("reload")
125
+ window.location.reload(true)
126
+
127
+ if @data("update-modal-origin")
128
+ @updateModalOrigin()
129
+
130
+ if @data("update-origin")
131
+ @updateOrigin()
132
+
133
+ if @data('original-slotter-mode')
134
+ @attr 'data-slotter-mode', @data('original-slotter-mode')
135
+
136
+ mode = @data("slotter-mode")
137
+ @showSuccessResponse data, mode
138
+
139
+ if @hasClass "_close-overlay"
140
+ @removeOverlay()
141
+ if @hasClass "_close-modal"
142
+ @closest('.modal').modal('hide')
143
+
144
+ # should scroll to top after clicking on new page
145
+ if @hasClass "card-paging-link"
146
+ slot_top_pos = @slot().offset().top
147
+ $("body").scrollTop slot_top_pos
148
+ if @data("update-foreign-slot")
149
+ $slot = @findSlot @data("update-foreign-slot")
150
+ reload_url = @data("update-foreign-slot-url")
151
+ $slot.reloadSlot reload_url
152
+
153
+ event.slotSuccessful = true
154
+
155
+ showSuccessResponse: (data, mode) ->
156
+ if mode == "silent-success"
157
+ return
158
+ else if mode == "update-modal-origin"
159
+ @updateModalOrigin()
160
+ else if mode == "update-origin"
161
+ @updateOrigin()
162
+ else if data.redirect
163
+ window.location = data.redirect
164
+ else if data.reload
165
+ window.location.reload(true)
166
+ else
167
+ @updateSlot data, mode
168
+
169
+ showErrorResponse: (status, result) ->
170
+ if status == 403 #permission denied
171
+ $(result).showAsModal $(this)
172
+ else if status == 900
173
+ $(result).showAsModal $(this)
174
+ else
175
+ @notify result, "error"
176
+
177
+ if status == 409 #edit conflict
178
+ @slot().find('.current_revision_id').val(
179
+ @slot().find('.new-current-revision-id').text()
180
+ )
181
+
182
+ updateModalOrigin: () ->
183
+ if @overlaySlot()
184
+ overlayOrigin = @findOriginSlot("overlay")
185
+ overlayOrigin.updateOrigin()
186
+ else if @closest("#modal-container")[0]
187
+ @updateOrigin()
188
+
189
+ updateOrigin: () ->
190
+ type = if @overlaySlot()
191
+ "overlay"
192
+ else if @closest("#modal-container")[0]
193
+ "modal"
194
+
195
+ return unless type?
196
+
197
+ origin = @findOriginSlot(type)
198
+ if origin && origin[0]?
199
+ origin.reloadSlot()
200
+
201
+ registerAsOrigin: (type, slot) ->
202
+ if slot.hasClass("_modal-slot")
203
+ slot = slot.find(".modal-body .card-slot")
204
+ slot.attr("data-#{type}-origin-slot-id", @closest(".card-slot").data("slot-id"))
205
+
206
+ updateSlot: (data, mode) ->
207
+ mode ||= "replace"
208
+ @setSlotContent data, mode, $(this)
209
+
210
+ # close modal or overlay
211
+ closeOnSuccess: (type) ->
212
+ slotter = @closest('.slotter')
213
+ if !type?
214
+ type = if @isInOverlay() then "overlay" else "modal"
215
+ slotter.addClass "_close-#{type}"
216
+
217
+ slotterBeforeSend: (opt) ->
218
+ return if opt.skip_before_send
219
+
220
+ # avoiding duplication. could be better test?
221
+ unless (opt.url.match(/home_view/) or @data("slotter-mode") == "modal")
222
+ opt.url = decko.slotPath opt.url, @slot()
223
+
224
+ if @is('form')
225
+ if data = @data 'file-data'
226
+ # NOTE - this entire solution is temporary.
227
+ @uploadWithBlueimp(data, opt)
228
+ false
229
+
230
+ uploadWithBlueimp: (data, opt) ->
231
+ input = @find '.file-upload'
232
+ if input[1]
233
+ @notify(
234
+ "Decko does not yet support multiple files in a single form.",
235
+ "error"
236
+ )
237
+ return false
238
+
239
+ widget = input.data 'blueimpFileupload' #jQuery UI widget
240
+
241
+ # browsers that can't do ajax uploads use iframe
242
+ unless widget._isXHRUpload(widget.options)
243
+ # can't do normal redirects.
244
+ @find('[name=success]').val('_self')
245
+ # iframe response not passed back;
246
+ # all responses treated as success. boo
247
+ opt.url += '&simulate_xhr=true'
248
+ # iframe is not xhr request,
249
+ # so would otherwise get full response with layout
250
+ iframeUploadFilter = (data)-> data.find('body').html()
251
+ opt.dataFilter = iframeUploadFilter
252
+ # gets rid of default html and body tags
253
+
254
+ args = $.extend opt, (widget._getAJAXSettings data), url: opt.url
255
+ # combines settings from decko's slotter and jQuery UI's upload widget
256
+ args.skip_before_send = true #avoid looping through this method again
257
+
258
+ $.ajax( args )
259
+
260
+ handleRecaptchaBeforeSubmit: (event) ->
261
+ recaptcha = @find("input._recaptcha-token")
262
+
263
+ if !recaptcha[0]?
264
+ # monkey error (bad form)
265
+ recaptcha.val "recaptcha-token-field-missing"
266
+ else if recaptcha.hasClass "_token-updated"
267
+ # recaptcha token is fine - continue submitting
268
+ recaptcha.removeClass "_token-updated"
269
+ else if !grecaptcha?
270
+ # shark error (probably recaptcha keys of pre v3 version)
271
+ recaptcha.val "grecaptcha-undefined"
272
+ else
273
+ @updateRecaptchaToken(event)
274
+ # this stops the submit here
275
+ # and submits again when the token is ready
276
+
@@ -0,0 +1,57 @@
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('.extra_upload_param').remove()
40
+
41
+ progressallFile: (e, data) ->
42
+ progress = parseInt(data.loaded / data.total * 100, 10)
43
+ $('#progress .progress-bar').css('width', progress + '%')
44
+
45
+ doneFile: (e, data) ->
46
+ editor = $(this).closest '.card-editor'
47
+ editor.find('.chosen-file').replaceWith data.result
48
+ data.form.find('button[type=submit]').attr('disabled',false)
49
+
50
+ $(window).ready ->
51
+ $('body').on 'click', '.cancel-upload', ->
52
+ editor = $(this).closest '.card-editor'
53
+ editor.find('.choose-file').show()
54
+ editor.find('.chosen-file').empty()
55
+ editor.find('.progress').show()
56
+ editor.find('#progress .progress-bar').css('width', '0%')
57
+ editor.find('#progress').hide()