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.
- checksums.yaml +4 -4
- data/assets/script/decko/autosave.js.coffee +30 -0
- data/assets/script/decko/bridge.js.coffee +31 -0
- data/assets/script/decko/card_menu.js.coffee +26 -0
- data/assets/script/decko/components.js.coffee +46 -0
- data/assets/script/decko/decko.js.coffee +97 -0
- data/assets/script/decko/doubleclick.js.coffee +30 -0
- data/assets/script/decko/editor.js.coffee +55 -0
- data/assets/script/decko/filter.js.coffee +176 -0
- data/assets/script/decko/filter_items.js.coffee +128 -0
- data/assets/script/decko/filter_links.js.coffee +81 -0
- data/assets/script/decko/follow.js.coffee +22 -0
- data/assets/script/decko/layout.js.coffee +76 -0
- data/assets/script/decko/link_editor.js.coffee +61 -0
- data/assets/script/decko/mod.js.coffee +85 -0
- data/assets/script/decko/modal.js.coffee +113 -0
- data/assets/script/decko/name_editor.js.coffee +40 -0
- data/assets/script/decko/navbox.js.coffee +74 -0
- data/assets/script/decko/nest_editor.js.coffee +166 -0
- data/assets/script/decko/nest_editor_name.js.coffee +102 -0
- data/assets/script/decko/nest_editor_options.js.coffee +93 -0
- data/assets/script/decko/nest_editor_rules.js.coffee +3 -0
- data/assets/script/decko/overlay.js.coffee +54 -0
- data/assets/script/decko/recaptcha.js.coffee +19 -0
- data/assets/script/decko/selectable_filtered_content.js.coffee +12 -0
- data/assets/script/decko/slot.js.coffee +182 -0
- data/assets/script/decko/slot_ready.js.coffee +11 -0
- data/assets/script/decko/slotter.js.coffee +276 -0
- data/assets/script/decko/upload.js.coffee +57 -0
- data/assets/script/jquery-ui.min.js +13 -0
- data/assets/script/jquery.autosize.js +274 -0
- data/assets/script/manifest.yml +44 -0
- data/assets/script/script_pointer_config.js.coffee +80 -0
- data/assets/script/script_pointer_list_editor.js.coffee +67 -0
- data/file/mod_script_script_decko_machine_output/file.js +5 -30
- data/file/mod_script_script_jquery_machine_output/file.js +11 -9
- data/init/early/init_execjs.rb +3 -0
- data/set/all/head_javascript.rb +8 -3
- data/set/self/script_mods.rb +1 -1
- 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()
|