card-mod-script 0.11.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 (126) hide show
  1. checksums.yaml +7 -0
  2. data/lib/javascript/decko/autosave.js.coffee +30 -0
  3. data/lib/javascript/decko/bridge.js.coffee +31 -0
  4. data/lib/javascript/decko/card_menu.js.coffee +26 -0
  5. data/lib/javascript/decko/components.js.coffee +51 -0
  6. data/lib/javascript/decko/decko.js.coffee +100 -0
  7. data/lib/javascript/decko/doubleclick.js.coffee +30 -0
  8. data/lib/javascript/decko/editor.js.coffee +55 -0
  9. data/lib/javascript/decko/filter.js.coffee +176 -0
  10. data/lib/javascript/decko/filter_items.js.coffee +128 -0
  11. data/lib/javascript/decko/filter_links.js.coffee +81 -0
  12. data/lib/javascript/decko/follow.js.coffee +22 -0
  13. data/lib/javascript/decko/layout.js.coffee +76 -0
  14. data/lib/javascript/decko/link_editor.js.coffee +61 -0
  15. data/lib/javascript/decko/mod.js.coffee +85 -0
  16. data/lib/javascript/decko/modal.js.coffee +110 -0
  17. data/lib/javascript/decko/name_editor.js.coffee +51 -0
  18. data/lib/javascript/decko/navbox.js.coffee +74 -0
  19. data/lib/javascript/decko/nest_editor.js.coffee +166 -0
  20. data/lib/javascript/decko/nest_editor_name.js.coffee +102 -0
  21. data/lib/javascript/decko/nest_editor_options.js.coffee +93 -0
  22. data/lib/javascript/decko/nest_editor_rules.js.coffee +3 -0
  23. data/lib/javascript/decko/overlay.js.coffee +57 -0
  24. data/lib/javascript/decko/recaptcha.js.coffee +19 -0
  25. data/lib/javascript/decko/selectable_filtered_content.js.coffee +12 -0
  26. data/lib/javascript/decko/slot.js.coffee +172 -0
  27. data/lib/javascript/decko/slot_ready.js.coffee +11 -0
  28. data/lib/javascript/decko/slotter.js.coffee +269 -0
  29. data/lib/javascript/decko/upload.js.coffee +57 -0
  30. data/lib/javascript/jquery-ui.js +10 -0
  31. data/lib/javascript/jquery.autosize.js +274 -0
  32. data/lib/javascript/jquery.iframe-transport.js +185 -0
  33. data/lib/javascript/script_html5shiv_printshiv.js +1 -0
  34. data/lib/javascript/script_pointer_config.js.coffee +80 -0
  35. data/lib/javascript/script_pointer_list_editor.js.coffee +67 -0
  36. data/lib/javascript/theme-textmate.js +130 -0
  37. data/set/abstract/script.rb +85 -0
  38. data/set/right/script.rb +19 -0
  39. data/set/self/01_script_libraries.rb +1 -0
  40. data/set/self/script.rb +1 -0
  41. data/set/self/script_decko.rb +12 -0
  42. data/set/self/script_editors.rb +1 -0
  43. data/set/self/script_html5shiv_printshiv.rb +11 -0
  44. data/set/self/script_jquery.rb +10 -0
  45. data/set/self/script_jquery_helper.rb +14 -0
  46. data/set/self/script_mods.rb +1 -0
  47. data/set/self/script_pointer_config.rb +9 -0
  48. data/set/type/coffee_script.rb +25 -0
  49. data/set/type/java_script.rb +9 -0
  50. data/vendor/jquery_file_upload/CONTRIBUTING.md +15 -0
  51. data/vendor/jquery_file_upload/LICENSE.txt +21 -0
  52. data/vendor/jquery_file_upload/README.md +107 -0
  53. data/vendor/jquery_file_upload/angularjs.html +211 -0
  54. data/vendor/jquery_file_upload/basic-plus.html +226 -0
  55. data/vendor/jquery_file_upload/basic.html +136 -0
  56. data/vendor/jquery_file_upload/bower-version-update.js +16 -0
  57. data/vendor/jquery_file_upload/bower.json +64 -0
  58. data/vendor/jquery_file_upload/cors/postmessage.html +75 -0
  59. data/vendor/jquery_file_upload/cors/result.html +24 -0
  60. data/vendor/jquery_file_upload/css/jquery-ui-demo-ie8.css +21 -0
  61. data/vendor/jquery_file_upload/css/jquery-ui-demo.css +67 -0
  62. data/vendor/jquery_file_upload/css/jquery.fileupload-noscript.css +22 -0
  63. data/vendor/jquery_file_upload/css/jquery.fileupload-ui-noscript.css +17 -0
  64. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +57 -0
  65. data/vendor/jquery_file_upload/css/jquery.fileupload.css +37 -0
  66. data/vendor/jquery_file_upload/css/style.css +15 -0
  67. data/vendor/jquery_file_upload/img/loading.gif +0 -0
  68. data/vendor/jquery_file_upload/img/progressbar.gif +0 -0
  69. data/vendor/jquery_file_upload/index.html +255 -0
  70. data/vendor/jquery_file_upload/jquery-ui.html +252 -0
  71. data/vendor/jquery_file_upload/js/app.js +101 -0
  72. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +126 -0
  73. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +89 -0
  74. data/vendor/jquery_file_upload/js/jquery.fileupload-angular.js +437 -0
  75. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +113 -0
  76. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +326 -0
  77. data/vendor/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +161 -0
  78. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +178 -0
  79. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +714 -0
  80. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +125 -0
  81. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +113 -0
  82. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1486 -0
  83. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +224 -0
  84. data/vendor/jquery_file_upload/js/main.js +75 -0
  85. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +748 -0
  86. data/vendor/jquery_file_upload/package.json +55 -0
  87. data/vendor/jquery_file_upload/server/gae-go/app.yaml +12 -0
  88. data/vendor/jquery_file_upload/server/gae-go/app/main.go +361 -0
  89. data/vendor/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
  90. data/vendor/jquery_file_upload/server/gae-go/static/robots.txt +2 -0
  91. data/vendor/jquery_file_upload/server/gae-python/app.yaml +17 -0
  92. data/vendor/jquery_file_upload/server/gae-python/main.py +204 -0
  93. data/vendor/jquery_file_upload/server/gae-python/static/favicon.ico +0 -0
  94. data/vendor/jquery_file_upload/server/gae-python/static/robots.txt +2 -0
  95. data/vendor/jquery_file_upload/server/php/Dockerfile +38 -0
  96. data/vendor/jquery_file_upload/server/php/UploadHandler.php +1411 -0
  97. data/vendor/jquery_file_upload/server/php/docker-compose.yml +9 -0
  98. data/vendor/jquery_file_upload/server/php/index.php +15 -0
  99. data/vendor/jquery_file_upload/test/index.html +172 -0
  100. data/vendor/jquery_file_upload/test/test.js +1292 -0
  101. data/vendor/jquery_rails/CHANGELOG.md +359 -0
  102. data/vendor/jquery_rails/CONTRIBUTING.md +132 -0
  103. data/vendor/jquery_rails/Gemfile +22 -0
  104. data/vendor/jquery_rails/MIT-LICENSE +21 -0
  105. data/vendor/jquery_rails/README.md +75 -0
  106. data/vendor/jquery_rails/Rakefile +59 -0
  107. data/vendor/jquery_rails/VERSIONS.md +62 -0
  108. data/vendor/jquery_rails/jquery-rails.gemspec +26 -0
  109. data/vendor/jquery_rails/lib/jquery-rails.rb +1 -0
  110. data/vendor/jquery_rails/lib/jquery/assert_select.rb +149 -0
  111. data/vendor/jquery_rails/lib/jquery/rails.rb +8 -0
  112. data/vendor/jquery_rails/lib/jquery/rails/engine.rb +6 -0
  113. data/vendor/jquery_rails/lib/jquery/rails/version.rb +9 -0
  114. data/vendor/jquery_rails/test/assert_select_jquery_test.rb +85 -0
  115. data/vendor/jquery_rails/test/test_helper.rb +6 -0
  116. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.js +11008 -0
  117. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.js +5 -0
  118. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.map +1 -0
  119. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.js +9814 -0
  120. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.js +4 -0
  121. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.map +1 -0
  122. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.js +10364 -0
  123. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.js +2 -0
  124. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.map +1 -0
  125. data/vendor/jquery_rails/vendor/assets/javascripts/jquery_ujs.js +555 -0
  126. metadata +212 -0
@@ -0,0 +1,93 @@
1
+ $(document).ready ->
2
+ $('body').on 'keyup', 'input._nest-option-value', () ->
3
+ nest.updatePreview()
4
+
5
+ $('body').on "select2:select", "._nest-option-name", () ->
6
+ nest.toggleOptionName($(this).closest("._options-select"), $(this).val(), true)
7
+ nest.updatePreview()
8
+
9
+ $('body').on "select2:selecting", "._nest-option-name", () ->
10
+ nest.toggleOptionName($(this).closest("._options-select"), $(this).val(), false)
11
+
12
+ $('body').on "select2:select", "._nest-option-name._new-row", () ->
13
+ $(this).closest(".input-group").find(".input-group-prepend").removeClass("d-none")
14
+ row = $(this).closest("._nest-option-row")
15
+ row.find("._nest-option-value").removeAttr("disabled")
16
+ template = row.parent().find("._nest-option-row._template")
17
+ $(this).removeClass("_new-row")
18
+ nest.addRow(template)
19
+
20
+ $('body').on "click", "._configure-items-button", () ->
21
+ nest.addItemsOptions($(this))
22
+
23
+ $('body').on 'click', 'button._nest-delete-option', () ->
24
+ nest.removeRow $(this).closest("._nest-option-row")
25
+
26
+ $.extend nest,
27
+ showTemplate: (elem) ->
28
+ elem.removeClass("_template") #.removeClass("_#{name}-template").addClass("_#{name}")
29
+
30
+ addRow: (template) ->
31
+ select_tag = template.find("select")
32
+ select_tag.select2("destroy")
33
+ select_tag.removeAttr("data-select2-id")
34
+ double = template.clone()
35
+ #double = template.cloneSelect2(true, true)
36
+ decko.initSelect2(select_tag)
37
+ nest.showTemplate template
38
+ template.after(double)
39
+ decko.initSelect2(double.find("select"))
40
+
41
+ removeRow: (row) ->
42
+ name = row.find("._nest-option-name").val()
43
+ nest.toggleOptionName(row.closest("._options-select"), name,false)
44
+ row.remove()
45
+ nest.updatePreview()
46
+
47
+ addItemsOptions: (button) ->
48
+ container = button.closest("._configure-items")
49
+ next = container.cloneSelect2(true)
50
+ title = button.text()
51
+ button.replaceWith($("<h6>#{title.substr(9)}<h6>"))
52
+ nest.showTemplate container.find("._options-select._template")
53
+ next.find("._configure-items-button").text(title.replace("items", "subitems"))
54
+ container.after(next)
55
+ nest.updatePreview()
56
+
57
+ options: () ->
58
+ options = []
59
+ for ele in $("._options-select:not(._template")
60
+ options.push nest.extractOptions($(ele))
61
+
62
+ level_options = options.map (opts) ->
63
+ nest.toNestSyntax(opts)
64
+ level_options.join "|"
65
+
66
+ # extract options for one item level
67
+ extractOptions: (ele) ->
68
+ options = {}
69
+ nest.addOption(options, $(row)) for row in ele.find("._nest-option-row:not(.template)")
70
+ options
71
+
72
+ addOption: (options, row) ->
73
+ val = row.find("._nest-option-value").val()
74
+ return unless val? && val.length > 0
75
+
76
+ name = row.find("._nest-option-name").val()
77
+ if options[name]?
78
+ options[name].push val
79
+ else
80
+ options[name] = [val]
81
+
82
+ toggleOptionName: (container, name, active) ->
83
+ return true if name == "show" || name == "hide"
84
+ for sel in container.find("._nest-option-name")
85
+ if $(sel).val() != name
86
+ $(sel).find("option[value=#{name}]").attr "disabled", active
87
+ # $(sel).find("option[value=#{val}]").removeAttr "disabled"
88
+ decko.initSelect2($(sel))
89
+
90
+ toNestSyntax: (opts) ->
91
+ str = []
92
+ str.push "#{name}: #{values.join ', '}" for name, values of opts
93
+ str.join "; "
@@ -0,0 +1,57 @@
1
+ jQuery.fn.extend
2
+ overlaySlot: ->
3
+ oslot = @closest(".card-slot._overlay")
4
+ return oslot if oslot[0]?
5
+ oslot = @closest(".overlay-container").find("._overlay")
6
+ oslot[0]? && $(oslot[0])
7
+
8
+ addOverlay: (overlay, $slotter) ->
9
+ if @parent().hasClass("overlay-container")
10
+ if $(overlay).hasClass("_stack-overlay")
11
+ @before overlay
12
+ else
13
+ $("._overlay-origin").removeClass("_overlay-origin")
14
+ @replaceOverlay(overlay)
15
+ else
16
+ #@find(".tinymce-textarea").each ->
17
+ # tinymce.remove("##{$(this).attr("id")}")
18
+ # #tinyMCE.execCommand('mceRemoveControl', false, $(this).attr("id"))
19
+ if @parent().hasClass("_overlay-container-placeholder")
20
+ @parent().addClass("overlay-container")
21
+ else
22
+ @wrapAll('<div class="overlay-container">')
23
+ @addClass("_bottomlay-slot")
24
+ @before overlay
25
+
26
+ $slotter.registerAsOrigin("overlay", overlay)
27
+ decko.contentLoaded(overlay, $slotter)
28
+
29
+ replaceOverlay: (overlay) ->
30
+ @overlaySlot().trigger "slotDestroy"
31
+ @overlaySlot().replaceWith overlay
32
+ $(".bridge-sidebar .tab-pane:not(.active) .bridge-pills > .nav-item > .nav-link.active").removeClass("active")
33
+
34
+ isInOverlay: ->
35
+ return @closest(".card-slot._overlay").length
36
+
37
+ removeOverlay: () ->
38
+ slot = @overlaySlot()
39
+ if slot
40
+ slot.removeOverlaySlot()
41
+
42
+ removeOverlaySlot: () ->
43
+ @trigger "slotDestroy"
44
+ if @siblings().length == 1
45
+ bottomlay = $(@siblings()[0])
46
+ if bottomlay.hasClass("_bottomlay-slot")
47
+ if bottomlay.parent().hasClass("_overlay-container-placeholder")
48
+ bottomlay.parent().removeClass("overlay-container")
49
+ else
50
+ bottomlay.unwrap()
51
+ bottomlay.removeClass("_bottomlay-slot").updateBridge(true, bottomlay)
52
+
53
+ #bottomlay.find(".tinymce-textarea").each ->
54
+ # tinymce.EditorManager.execCommand('mceAddControl',true, editor_id);
55
+ # decko.initTinyMCE($(this).attr("id"))
56
+
57
+ @remove()
@@ -0,0 +1,19 @@
1
+ jQuery.fn.extend {
2
+ updateRecaptchaToken: (event) ->
3
+ recaptcha = @find("input._recaptcha-token")
4
+
5
+ if !recaptcha[0]?
6
+ recaptcha.val "recaptcha-token-field-missing"
7
+ else if !grecaptcha?
8
+ recaptcha.val("grecaptcha-undefined")
9
+ else
10
+ $slotter = $(this)
11
+ event.stopPropagation() if event
12
+ grecaptcha.execute(recaptcha.data("site-key"), action: recaptcha.data("action"))
13
+ .then (token) ->
14
+ recaptcha.val(token)
15
+ recaptcha.addClass("_token-updated")
16
+ if event
17
+ $slotter.submit()
18
+ false
19
+ }
@@ -0,0 +1,12 @@
1
+ $(window).ready ->
2
+
3
+ # TODO: generalize so this works with item views other than bar
4
+ $("body").on "click", "._selectable-filtered-content .bar-body", (e) ->
5
+ item = $(this)
6
+ name = item.slot().data("card-name")
7
+ container = item.closest("._selectable-filtered-content")
8
+ input = $(container.data("input-selector"))
9
+ input.val name
10
+ item.closest('.modal').modal('hide')
11
+ e.preventDefault()
12
+ e.stopPropagation()
@@ -0,0 +1,172 @@
1
+ $.extend decko,
2
+ # returns full path with slot parameters
3
+ slotPath: (path, slot)->
4
+ params = decko.slotData(slot)
5
+ decko.path(path) + ( (if path.match /\?/ then '&' else '?') + $.param(params) )
6
+
7
+ slotData: (slot) ->
8
+ xtra = {}
9
+ main = $('#main').children('.card-slot').data 'cardName'
10
+ xtra['main'] = main if main?
11
+
12
+ if slot
13
+ xtra['is_main'] = true if slot.isMain()
14
+ slotdata = slot.data 'slot'
15
+ if slotdata?
16
+ decko.slotParams slotdata, xtra, 'slot'
17
+ xtra['type'] = slotdata['type'] if slotdata['type']
18
+ xtra
19
+
20
+ slotEditView: (slot) ->
21
+ data = decko.slotData(slot)
22
+ switch data["slot[edit]"]
23
+ when "inline" then "edit_inline"
24
+ when "full" then "bridge"
25
+ else "edit"
26
+
27
+ slotEditLink: (slot) ->
28
+ edit_links =
29
+ slot.find(".edit-link").filter (i, el) ->
30
+ $(el).slot().data('slotId') == slot.data('slotId')
31
+
32
+ if edit_links[0] then $(edit_links[0]) else false
33
+
34
+ slotParams: (raw, processed, prefix)->
35
+ $.each raw, (key, value)->
36
+ cgiKey = prefix + '[' + snakeCase(key) + ']'
37
+ if key == 'items'
38
+ decko.slotParams value, processed, cgiKey
39
+ else
40
+ processed[cgiKey] = value
41
+
42
+ contentLoaded: (el, slotter)->
43
+ decko.initializeEditors(el)
44
+ notice = slotter.attr('notify-success')
45
+ if notice?
46
+ el.notify notice, "success"
47
+ el.triggerSlotReady(slotter)
48
+
49
+ slotReady: (func)->
50
+ $('document').ready ->
51
+ $('body').on 'slotReady', '.card-slot', (e, slotter) ->
52
+ e.stopPropagation()
53
+ if slotter?
54
+ func.call this, $(this), $(slotter)
55
+ else
56
+ func.call this, $(this)
57
+
58
+ slotDestroy: (func)->
59
+ $('document').ready ->
60
+ $('body').on 'slotDestroy', '.card-slot, ._modal-slot', (e) ->
61
+ e.stopPropagation()
62
+ func.call this, $(this)
63
+
64
+ jQuery.fn.extend
65
+ slot: (status="success", mode="replace") ->
66
+ if mode == "modal"
67
+ @modalSlot()
68
+ else
69
+ @selectSlot("slot-#{status}-selector") ||
70
+ @selectSlot("slot-selector") ||
71
+ @closest(".card-slot")
72
+
73
+ selectSlot: (selectorName) ->
74
+ if selector = @data(selectorName)
75
+ slot = @findSlot selector
76
+ slot && slot[0] && slot
77
+
78
+ isSlot: ->
79
+ $(this).hasClass "card-slot"
80
+
81
+ isMain: -> @slot().parent('#main')[0]
82
+
83
+ findSlot: (selector) ->
84
+ if selector == "modal-origin"
85
+ @findOriginSlot("modal")
86
+ else if selector == "overlay-origin"
87
+ @findOriginSlot("overlay")
88
+ else
89
+ target_slot = @closest(selector)
90
+ parent_slot = @closest '.card-slot'
91
+
92
+ # if slot-selector doesn't apply to a child, search in all parent slots and finally in the body
93
+ while target_slot.length == 0 and parent_slot.length > 0
94
+ target_slot = $(parent_slot).find(selector)
95
+ parent_slot = $(parent_slot).parent().closest '.card-slot'
96
+ if target_slot.length == 0
97
+ $(selector)
98
+ else
99
+ target_slot
100
+
101
+ # type can be "modal" or "overlay"
102
+ findOriginSlot: (type) ->
103
+ overlaySlot = @closest("[data-#{type}-origin-slot-id]")
104
+ origin_slot_id = overlaySlot.data("#{type}-origin-slot-id")
105
+ origin_slot = $("[data-slot-id=#{origin_slot_id}]")
106
+ if origin_slot[0]?
107
+ origin_slot
108
+ else
109
+ console.log "couldn't find origin with slot id #{origin_slot_id}"
110
+
111
+ reloadSlot: (url) ->
112
+ $slot = $(this)
113
+ if $slot.length > 1
114
+ $slot.each ->
115
+ $(this).reloadSlot url
116
+ return
117
+
118
+ $slot = $slot.slot() unless $slot.isSlot
119
+ return unless $slot[0]
120
+
121
+ unless url?
122
+ url = $slot.slotUrl()
123
+ $slot.addClass 'slotter'
124
+ $slot.attr 'href', url
125
+ $slot.data "url", url
126
+ this[0].href = url # that's where handleRemote gets the url from
127
+ # .attr(href, url) only works for anchors
128
+ $slot.data "remote", true
129
+ $.rails.handleRemote($slot)
130
+
131
+ clearSlot: () ->
132
+ @triggerSlotDestroy()
133
+ @empty()
134
+
135
+ slotUrl: ->
136
+ decko.slotPath "#{this.slotMark()}?view=#{@data("slot")["view"]}"
137
+
138
+ slotMark: ->
139
+ if @data('cardId') then "~#{@data('cardId')}" else @data("cardName")
140
+
141
+ setSlotContent: (val, mode, $slotter) ->
142
+ v = $(val)[0] && $(val) || val
143
+
144
+ if typeof(v) == "string"
145
+ # Needed to support "TEXT: result" pattern in success (eg deleting nested cards)
146
+ @slot("success", mode).replaceWith v
147
+ else
148
+ if v.hasClass("_overlay")
149
+ mode = "overlay"
150
+ else if v.hasClass("_modal")
151
+ mode = "modal"
152
+ @slot("success", mode).setSlotContentFromElement v, mode, $slotter
153
+ v
154
+
155
+ setSlotContentFromElement: (el, mode, $slotter) ->
156
+ if mode == "overlay"
157
+ @addOverlay(el, $slotter)
158
+ else if el.hasClass("_modal-slot") or mode == "modal"
159
+ el.showAsModal($slotter)
160
+ else
161
+ slot_id = @data("slot-id")
162
+ el.attr("data-slot-id", slot_id) if slot_id
163
+ @triggerSlotDestroy()
164
+ @replaceWith el
165
+ decko.contentLoaded(el, $slotter)
166
+
167
+ triggerSlotReady: (slotter) ->
168
+ @trigger "slotReady", slotter if @isSlot()
169
+ @find(".card-slot").trigger "slotReady", slotter
170
+
171
+ triggerSlotDestroy: () ->
172
+ @trigger "slotDestroy"
@@ -0,0 +1,11 @@
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
+
@@ -0,0 +1,269 @@
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
+ if (target = $(this).attr 'main-success') and $(this).isMain()
98
+ input = $(this).find '[name=success]'
99
+ if input and input.val() and !(input.val().match /^REDIRECT/)
100
+ input.val(
101
+ (if target == 'REDIRECT' then target + ': ' + input.val() else target)
102
+ )
103
+ if $(this).data('recaptcha') == 'on'
104
+ return $(this).handleRecaptchaBeforeSubmit(event)
105
+
106
+ $('body').on 'ajax:beforeSend', '.slotter', (event, xhr, opt)->
107
+ $(this).slotterBeforeSend(opt)
108
+
109
+ jQuery.fn.extend
110
+ slotterSuccess: (event, data) ->
111
+ unless @hasClass("slotter")
112
+ console.log "warning: slotterSuccess called on non-slotter element #{this}"
113
+ return
114
+
115
+ return if event.slotSuccessful
116
+
117
+ if @data("reload")
118
+ window.location.reload(true)
119
+
120
+ if @data("update-modal-origin")
121
+ @updateModalOrigin()
122
+
123
+ if @data("update-origin")
124
+ @updateOrigin()
125
+
126
+ if @data('original-slotter-mode')
127
+ @attr 'data-slotter-mode', @data('original-slotter-mode')
128
+
129
+ mode = @data("slotter-mode")
130
+ @showSuccessResponse data, mode
131
+
132
+ if @hasClass "_close-overlay"
133
+ @removeOverlay()
134
+ if @hasClass "_close-modal"
135
+ @closest('.modal').modal('hide')
136
+
137
+ # should scroll to top after clicking on new page
138
+ if @hasClass "card-paging-link"
139
+ slot_top_pos = @slot().offset().top
140
+ $("body").scrollTop slot_top_pos
141
+ if @data("update-foreign-slot")
142
+ $slot = @findSlot @data("update-foreign-slot")
143
+ reload_url = @data("update-foreign-slot-url")
144
+ $slot.reloadSlot reload_url
145
+
146
+ event.slotSuccessful = true
147
+
148
+ showSuccessResponse: (data, mode) ->
149
+ if mode == "silent-success"
150
+ return
151
+ else if mode == "update-modal-origin"
152
+ @updateModalOrigin()
153
+ else if mode == "update-origin"
154
+ @updateOrigin()
155
+ else if data.redirect
156
+ window.location = data.redirect
157
+ else if data.reload
158
+ window.location.reload(true)
159
+ else
160
+ @updateSlot data, mode
161
+
162
+ showErrorResponse: (status, result) ->
163
+ if status == 403 #permission denied
164
+ $(result).showAsModal $(this)
165
+ else if status == 900
166
+ $(result).showAsModal $(this)
167
+ else
168
+ @notify result, "error"
169
+
170
+ if status == 409 #edit conflict
171
+ @slot().find('.current_revision_id').val(
172
+ @slot().find('.new-current-revision-id').text()
173
+ )
174
+
175
+ updateModalOrigin: () ->
176
+ if @overlaySlot()
177
+ overlayOrigin = @findOriginSlot("overlay")
178
+ overlayOrigin.updateOrigin()
179
+ else if @closest("#modal-container")[0]
180
+ @updateOrigin()
181
+
182
+ updateOrigin: () ->
183
+ type = if @overlaySlot()
184
+ "overlay"
185
+ else if @closest("#modal-container")[0]
186
+ "modal"
187
+
188
+ return unless type?
189
+
190
+ origin = @findOriginSlot(type)
191
+ if origin && origin[0]?
192
+ origin.reloadSlot()
193
+
194
+ registerAsOrigin: (type, slot) ->
195
+ if slot.hasClass("_modal-slot")
196
+ slot = slot.find(".modal-body .card-slot")
197
+ slot.attr("data-#{type}-origin-slot-id", @closest(".card-slot").data("slot-id"))
198
+
199
+ updateSlot: (data, mode) ->
200
+ mode ||= "replace"
201
+ @setSlotContent data, mode, $(this)
202
+
203
+ # close modal or overlay
204
+ closeOnSuccess: (type) ->
205
+ slotter = @closest('.slotter')
206
+ if !type?
207
+ type = if @isInOverlay() then "overlay" else "modal"
208
+ slotter.addClass "_close-#{type}"
209
+
210
+ slotterBeforeSend: (opt) ->
211
+ return if opt.skip_before_send
212
+
213
+ # avoiding duplication. could be better test?
214
+ unless (opt.url.match(/home_view/) or @data("slotter-mode") == "modal")
215
+ opt.url = decko.slotPath opt.url, @slot()
216
+
217
+ if @is('form')
218
+ if data = @data 'file-data'
219
+ # NOTE - this entire solution is temporary.
220
+ @uploadWithBlueimp(data, opt)
221
+ false
222
+
223
+ uploadWithBlueimp: (data, opt) ->
224
+ input = @find '.file-upload'
225
+ if input[1]
226
+ @notify(
227
+ "Decko does not yet support multiple files in a single form.",
228
+ "error"
229
+ )
230
+ return false
231
+
232
+ widget = input.data 'blueimpFileupload' #jQuery UI widget
233
+
234
+ # browsers that can't do ajax uploads use iframe
235
+ unless widget._isXHRUpload(widget.options)
236
+ # can't do normal redirects.
237
+ @find('[name=success]').val('_self')
238
+ # iframe response not passed back;
239
+ # all responses treated as success. boo
240
+ opt.url += '&simulate_xhr=true'
241
+ # iframe is not xhr request,
242
+ # so would otherwise get full response with layout
243
+ iframeUploadFilter = (data)-> data.find('body').html()
244
+ opt.dataFilter = iframeUploadFilter
245
+ # gets rid of default html and body tags
246
+
247
+ args = $.extend opt, (widget._getAJAXSettings data), url: opt.url
248
+ # combines settings from decko's slotter and jQuery UI's upload widget
249
+ args.skip_before_send = true #avoid looping through this method again
250
+
251
+ $.ajax( args )
252
+
253
+ handleRecaptchaBeforeSubmit: (event) ->
254
+ recaptcha = @find("input._recaptcha-token")
255
+
256
+ if !recaptcha[0]?
257
+ # monkey error (bad form)
258
+ recaptcha.val "recaptcha-token-field-missing"
259
+ else if recaptcha.hasClass "_token-updated"
260
+ # recaptcha token is fine - continue submitting
261
+ recaptcha.removeClass "_token-updated"
262
+ else if !grecaptcha?
263
+ # shark error (probably recaptcha keys of pre v3 version)
264
+ recaptcha.val "grecaptcha-undefined"
265
+ else
266
+ @updateRecaptchaToken(event)
267
+ # this stops the submit here
268
+ # and submits again when the token is ready
269
+