card-mod-tinymce_editor 0.14.2 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/assets/script/image_editor.js.coffee +59 -0
- data/assets/script/link_editor.js.coffee +61 -0
- data/assets/script/nest_editor.js.coffee +171 -0
- data/assets/script/nest_editor_name.js.coffee +115 -0
- data/assets/script/nest_editor_options.js.coffee +197 -0
- data/assets/script/nest_editor_rules.js.coffee +3 -0
- data/assets/script/{script_tinymce_config.js.coffee → tinymce_config.js.coffee} +3 -6
- data/assets/style/nest_editor.scss +55 -0
- data/data/files/mod_tinymce_editor_script_asset_output/file.js +37 -0
- data/data/files/mod_tinymce_editor_script_local_machine_output/file.js +82 -0
- data/{db/migrate_core_cards/20171113233151_update_tinymce_config.rb → data/real.yml} +8 -15
- data/lib/card/reference/nest_parser.rb +27 -11
- data/locales/en.yml +9 -0
- data/set/all/reference_editor/_image_nest_editor.haml +2 -0
- data/set/all/reference_editor/_link_editor.haml +8 -6
- data/set/all/reference_editor/_nest_editor.haml +13 -15
- data/set/all/reference_editor/link_editor.rb +4 -2
- data/set/all/reference_editor/nest_editor/_basics.haml +5 -0
- data/set/all/reference_editor/nest_editor/_image_find.haml +7 -0
- data/set/all/reference_editor/nest_editor/_image_options.haml +8 -0
- data/set/all/reference_editor/nest_editor/_options.haml +18 -10
- data/set/all/reference_editor/nest_editor/_options_select.haml +6 -5
- data/set/all/reference_editor/nest_editor/_options_select_row.haml +7 -8
- data/set/all/reference_editor/nest_editor/nest_editor_options.rb +95 -0
- data/set/all/reference_editor/nest_editor/nest_editor_tabs.rb +59 -0
- data/set/all/reference_editor/nest_editor.rb +16 -80
- data/set/all/reference_editor/nest_image.rb +9 -8
- data/set/all/reference_editor/reference_editor.haml +11 -9
- data/set/all/reference_editor.rb +1 -1
- data/set/all/tinymce_editor.rb +5 -1
- metadata +26 -13
- data/db/migrate_core_cards/20160804112560_add_tinymce_cards.rb +0 -42
- data/db/migrate_core_cards/20190306172623_update_tinymce_config_to_v5.rb +0 -23
- data/db/migrate_core_cards/20190306172890_tinymce_add_nest_to_toolbar.rb +0 -11
- data/set/all/reference_editor/nest_editor/_help.haml +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 120f7464160b0efca7cb957ca1a9325954f7c6e9fd7e121887943b2febb1182f
|
4
|
+
data.tar.gz: '0863672ed664df7ce8753384fc848fcc19b37d2fa4c08590c8665b8bebd4e64a'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f15bb60d8048d6da87537af25c5f088fdb88a68411a9fcadbe588f7b8b424009fdcd594d3b54b4efc324f1559c6a8f3c8e2940ec2a6b6915f2bc4ca8d78540c
|
7
|
+
data.tar.gz: fba4d326715f5b90f2362b7d403d6a755e81b1fcf49281328ecf585b4f6ab1bb708c3311e2f70d95c75633ec4ea01eb0ef0d9294fb4ef9a72e819be19a7cc1ab
|
@@ -0,0 +1,59 @@
|
|
1
|
+
decko.slot.ready (slot) ->
|
2
|
+
sdata = slot.data("slot")
|
3
|
+
if sdata? && sdata["show"]? && sdata["show"].includes "preview_redirect"
|
4
|
+
tabPanel = slot.closest(".tab-panel")
|
5
|
+
tabPanel.find(".tab-li-preview a").tab("show")
|
6
|
+
nest.updateImagePreview(slot)
|
7
|
+
|
8
|
+
if slot.hasClass("modal_nest_image-view")
|
9
|
+
imageSelect = slot.find('._image-card-select')
|
10
|
+
if imageSelect.length > 0
|
11
|
+
decko.imageComplete.init imageSelect
|
12
|
+
nest.updateImageName(slot.find(".new_image-view .new_fields-view .submit-button"))
|
13
|
+
|
14
|
+
$(document).ready ->
|
15
|
+
$('body').on 'select2:select', '._image-name', () ->
|
16
|
+
nest.updateImagePreview(this)
|
17
|
+
|
18
|
+
$('body').on 'select2:select', '._image-view-select', () ->
|
19
|
+
nest.updateImagePreview(this)
|
20
|
+
|
21
|
+
$('body').on 'select2:select', '._image-size-select', () ->
|
22
|
+
nest.updateImagePreview(this)
|
23
|
+
|
24
|
+
$('body').on 'click', ".new_image-view .new_fields-view .submit-button", ->
|
25
|
+
nest.updateImageName($(this))
|
26
|
+
|
27
|
+
|
28
|
+
decko.imageComplete =
|
29
|
+
init: (el) ->
|
30
|
+
decko.select2Autocomplete.init el, @_options(el),
|
31
|
+
data: (params) ->
|
32
|
+
term: params.term
|
33
|
+
view: "image_complete"
|
34
|
+
|
35
|
+
_options: (el) ->
|
36
|
+
dropdownParent: el.parent()
|
37
|
+
|
38
|
+
window.nest ||= {}
|
39
|
+
|
40
|
+
$.extend nest,
|
41
|
+
updateImageName: (container) ->
|
42
|
+
name = container.slot().data("cardName");
|
43
|
+
nameSelect = container.closest(".tab-content").find("._image-name")
|
44
|
+
option = new Option(name, name, true, true);
|
45
|
+
nameSelect.append(option)
|
46
|
+
nameSelect.val(name)
|
47
|
+
nameSelect.trigger('change')
|
48
|
+
|
49
|
+
updateImagePreview: (el) ->
|
50
|
+
tabs = $(el).closest(".tab-content")
|
51
|
+
name = tabs.find("._image-name").val();
|
52
|
+
view = tabs.find("._image-view-select").val();
|
53
|
+
size = tabs.find("._image-size-select").val();
|
54
|
+
syntaxPreview = tabs.closest("._nest-editor").find("._nest-preview")
|
55
|
+
syntaxPreview.val("{{ #{name} | view: #{view}; size: #{size} }}")
|
56
|
+
|
57
|
+
slot = tabs.find(".tab-pane-preview > .card-slot");
|
58
|
+
path = "#{name}?view=#{view}&size=#{size}"
|
59
|
+
$(slot).slotReload path
|
@@ -0,0 +1,61 @@
|
|
1
|
+
$(document).ready ->
|
2
|
+
$('body').on 'click', 'button._link-apply', () ->
|
3
|
+
link.applyLink($(this).data("tinymce-id"), $(this).data("tm-snippet-start"), $(this).data("tm-snippet-size"))
|
4
|
+
|
5
|
+
window.link ||= {}
|
6
|
+
|
7
|
+
$(document).ready ->
|
8
|
+
$('body').on 'click', '._link-field-toggle', () ->
|
9
|
+
if $(this).is(':checked')
|
10
|
+
link.addPlus()
|
11
|
+
else
|
12
|
+
link.removePlus()
|
13
|
+
|
14
|
+
$('body').on 'input', 'input._link-target', (event) ->
|
15
|
+
link.targetChanged()
|
16
|
+
|
17
|
+
$('body').on 'input', 'input._link-title', (event) ->
|
18
|
+
link.titleChanged()
|
19
|
+
|
20
|
+
$.extend link,
|
21
|
+
# called by TinyMCE
|
22
|
+
openLinkEditor: (tm) ->
|
23
|
+
params = nest.editParams(tm, "[[", "]]") unless params?
|
24
|
+
nest.openEditorForTm(tm, params, "link_editor", "modal_link_editor")
|
25
|
+
|
26
|
+
applyLink: (tinymce_id, link_start, link_size) ->
|
27
|
+
nest.applySnippet("link", tinymce_id, link_start, link_size)
|
28
|
+
|
29
|
+
target: () ->
|
30
|
+
link.evalFieldOption $('input._link-target').val()
|
31
|
+
|
32
|
+
title: () ->
|
33
|
+
$('input._link-title').val()
|
34
|
+
|
35
|
+
titleChanged: () ->
|
36
|
+
new_val = $("._link-preview").val().replace(/^\[\[[^\]]*/, "[[" + link.target() + "|" + link.title())
|
37
|
+
link.updatePreview new_val
|
38
|
+
|
39
|
+
targetChanged: () ->
|
40
|
+
new_val = $("._link-preview").val().replace(/^\[\[[^\]|]*/, "[[" + link.target())
|
41
|
+
link.updatePreview new_val
|
42
|
+
|
43
|
+
evalFieldOption: (name) ->
|
44
|
+
if link.isField() then "+#{name}" else name
|
45
|
+
|
46
|
+
isField: ->
|
47
|
+
$('._link-field-toggle').is(":checked")
|
48
|
+
|
49
|
+
addPlus: () ->
|
50
|
+
new_val = $("._link-preview").val().replace(/^\[\[\+?/, "[[+")
|
51
|
+
link.updatePreview new_val
|
52
|
+
$(".input-group.hide-prefix").removeClass("hide-prefix").addClass("show-prefix")
|
53
|
+
|
54
|
+
removePlus: () ->
|
55
|
+
new_val = $("._link-preview").val().replace(/^\[\[\+?/, "[[")
|
56
|
+
link.updatePreview new_val
|
57
|
+
$(".input-group.show-prefix").removeClass("show-prefix").addClass("hide-prefix")
|
58
|
+
|
59
|
+
updatePreview: (new_val) ->
|
60
|
+
new_val = "[[#{link.target()}|#{link.title()}]]" unless new_val?
|
61
|
+
$("._link-preview").val new_val
|
@@ -0,0 +1,171 @@
|
|
1
|
+
$(document).ready ->
|
2
|
+
$('body').on 'click', 'button._nest-apply', () ->
|
3
|
+
if $(this).data("index")?
|
4
|
+
nest.applyNestToNestListEditor($(this).data("index"))
|
5
|
+
else
|
6
|
+
nest.applyNestToTinymceEditor($(this).data("tinymce-id"), $(this).data("tm-snippet-start"), $(this).data("tm-snippet-size"))
|
7
|
+
|
8
|
+
$('body').on 'click', 'button._image_nest-apply', () ->
|
9
|
+
nest.applyNestToTinymceEditor($(this).data("tinymce-id"), $(this).data("tm-snippet-start"), $(this).data("tm-snippet-size"))
|
10
|
+
|
11
|
+
$('body').on 'click', 'button._change-create-to-update', () ->
|
12
|
+
tm_id = $(this).closest("form").find("#success_tinymce_id").val()
|
13
|
+
nest.changeCreateToUpdate(tm_id)
|
14
|
+
|
15
|
+
$('body').on 'click', 'button._open-nest-editor', () ->
|
16
|
+
form = $(this).closest("._nest-form")
|
17
|
+
reference = form.find("._reference").val()
|
18
|
+
nest_options = form.find("._nest-options").val()
|
19
|
+
encoded_nest = encodeURIComponent "{{#{reference}|#{nest_options}}}"
|
20
|
+
nest.openNestEditorForSlot(
|
21
|
+
$(this).closest(".card-slot"),
|
22
|
+
$(this).closest(".slotter"),
|
23
|
+
"index=#{form.data('index')}&tm_snippet_raw=#{encoded_nest}"
|
24
|
+
)
|
25
|
+
|
26
|
+
window.nest ||= {}
|
27
|
+
|
28
|
+
$.extend nest,
|
29
|
+
# called by TinyMCE
|
30
|
+
openNestEditor: (tm, params) ->
|
31
|
+
params = nest.editParams(tm) unless params?
|
32
|
+
this.openEditorForTm(tm, params, "nest_editor", "modal_nest_editor")
|
33
|
+
|
34
|
+
openNestEditorForSlot: (slot, slotter, params) ->
|
35
|
+
card = if slot[0] then $(slot[0]).attr('data-card-name') else ":update"
|
36
|
+
nest.request(card, "nest_editor", "modal_nest_editor", slotter, params)
|
37
|
+
|
38
|
+
openEditorForTm: (tm, params, overlay_view, modal_view) ->
|
39
|
+
params += "&tinymce_id=#{tm.id}"
|
40
|
+
slot = $("##{tm.id}").closest(".card-slot")
|
41
|
+
editor = $("##{tm.id}").closest(".card-editor")
|
42
|
+
slotter = $("##{tm.id}")
|
43
|
+
|
44
|
+
card = (editor[0] and $(editor[0]).attr('card_name')) or
|
45
|
+
(slot[0] and $(slot[0]).attr('data-card-name')) or ":update"
|
46
|
+
if card.length == 0
|
47
|
+
card = ":update"
|
48
|
+
nest.request(card, overlay_view, modal_view, slotter, params)
|
49
|
+
|
50
|
+
# called by TinyMCE
|
51
|
+
openImageEditor: (tm) ->
|
52
|
+
params = nest.editParams(tm, "{{", "}}", false) unless params?
|
53
|
+
this.openEditorForTm(tm, params,"nest_image", "modal_nest_image")
|
54
|
+
|
55
|
+
changeCreateToUpdate: (tm_id) ->
|
56
|
+
form = $("##{tm_id}").closest("form")
|
57
|
+
new_action = form.attr("action").replace("card/create", "card/update")
|
58
|
+
form.attr("action", new_action)
|
59
|
+
|
60
|
+
insertNest: (tm, nest_string) ->
|
61
|
+
tm.insertContent(nest_string)
|
62
|
+
# insertIndex = nest.offsetAfterInsert(tm, nest_string)
|
63
|
+
# params = nest.paramsStr(insertIndex, nest_string)
|
64
|
+
# nest.openNestEditor(etm, params)
|
65
|
+
|
66
|
+
|
67
|
+
request: (card, overlay_view, modal_view, slotter, params) ->
|
68
|
+
slot = $(".bridge-sidebar > ._overlay-container-placeholder > .card-slot")
|
69
|
+
|
70
|
+
if false #slot[0]
|
71
|
+
view = overlay_view
|
72
|
+
mode = "overlay"
|
73
|
+
else
|
74
|
+
slot = $($(".card-slot")[0])
|
75
|
+
view = modal_view
|
76
|
+
mode = "modal"
|
77
|
+
|
78
|
+
nest.sendRequest(slotter, slot, mode, card, view, params)
|
79
|
+
|
80
|
+
sendRequest: (slotter, slot, mode, card, view, params) ->
|
81
|
+
params = "" unless params?
|
82
|
+
url = "/#{card}?view=#{view}&#{params}"
|
83
|
+
$.ajax
|
84
|
+
url: url
|
85
|
+
success: (html) ->
|
86
|
+
slot.slotContent html, mode, slotter
|
87
|
+
|
88
|
+
editParams: (tm, prefix="{{", postfix="}}", edit=true) ->
|
89
|
+
sel = tm.selection.getSel()
|
90
|
+
return nest.paramsStr(0) unless sel? and sel.anchorNode?
|
91
|
+
|
92
|
+
text = sel.anchorNode.data
|
93
|
+
return nest.paramsStr(sel.anchorOffset) unless text
|
94
|
+
|
95
|
+
offset = sel.anchorOffset
|
96
|
+
before = text.substr(0, offset)
|
97
|
+
after = text.substr(offset)
|
98
|
+
index = {
|
99
|
+
before: {
|
100
|
+
close: before.lastIndexOf(postfix)
|
101
|
+
open: before.lastIndexOf(prefix)
|
102
|
+
},
|
103
|
+
after: {
|
104
|
+
close: after.indexOf(postfix)
|
105
|
+
open: after.indexOf(prefix)
|
106
|
+
}
|
107
|
+
}
|
108
|
+
if index.before.open > index.before.close &&
|
109
|
+
index.after.close != -1 &&
|
110
|
+
(index.after.open == -1 || index.after.close < index.after.open)
|
111
|
+
nest_start = index.before.open
|
112
|
+
unless name?
|
113
|
+
nest_size = index.after.close + offset + 2 - nest_start
|
114
|
+
name = text.substr(nest_start, nest_size)
|
115
|
+
if edit
|
116
|
+
nest.paramsStr(nest_start, name)
|
117
|
+
else
|
118
|
+
nest.paramsStr(nest_start + nest_size)
|
119
|
+
else
|
120
|
+
nest.paramsStr(offset)
|
121
|
+
|
122
|
+
paramsStr: (start, name) ->
|
123
|
+
params = ""
|
124
|
+
if start?
|
125
|
+
params += "&tm_snippet_start=#{start}"
|
126
|
+
if name? and name.length > 0
|
127
|
+
params += "&tm_snippet_raw=#{encodeURIComponent(name)}"
|
128
|
+
|
129
|
+
params
|
130
|
+
|
131
|
+
offsetAfterInsert: (editor, content) ->
|
132
|
+
offset = editor.selection.getSel().anchorOffset
|
133
|
+
offset - content.lengthr
|
134
|
+
|
135
|
+
applyNestToTinymceEditor: (tinymce_id, nest_start, nest_size) ->
|
136
|
+
nest.applySnippet("nest", tinymce_id, nest_start, nest_size)
|
137
|
+
|
138
|
+
applyNestToNestListEditor: (index) ->
|
139
|
+
row = $("._nest-form[data-index='#{index}']")
|
140
|
+
row.find("._reference").val(nest.name())
|
141
|
+
row.find("._nest-options").val(nest.options())
|
142
|
+
decko.updateAddItemButton(row)
|
143
|
+
|
144
|
+
applySnippet: (snippet_type, tinymce_id, start, size) ->
|
145
|
+
content = $("._#{snippet_type}-preview").val()
|
146
|
+
editor = tinymce.get(tinymce_id)
|
147
|
+
if start?
|
148
|
+
nest.replaceSnippet(editor, start, size, content)
|
149
|
+
else
|
150
|
+
editor.insertContent content
|
151
|
+
offset = nest.offsetAfterInsert(editor, content)
|
152
|
+
$("button._#{snippet_type}-apply").attr("data-tm-snippet-start", offset)
|
153
|
+
|
154
|
+
$("button._#{snippet_type}-apply").attr("data-tm-snippet-size", content.length)
|
155
|
+
|
156
|
+
replaceSnippet: (editor, start, size, content) ->
|
157
|
+
sel = editor.selection.getSel()
|
158
|
+
if sel? and sel.anchorNode? and sel.anchorNode.data?
|
159
|
+
text = sel.anchorNode.data
|
160
|
+
size = 0 unless size?
|
161
|
+
text = "#{text.substr(0, start)}#{content}#{text.substr(start + size)}"
|
162
|
+
sel.anchorNode.data = text
|
163
|
+
else
|
164
|
+
editor.insertContent content
|
165
|
+
|
166
|
+
updatePreview: (new_val) ->
|
167
|
+
new_val = "{{ #{nest.name()}|#{nest.options()} }}" unless new_val?
|
168
|
+
preview = $("._nest-preview")
|
169
|
+
preview.val new_val
|
170
|
+
preview.data("nest-options", nest.options())
|
171
|
+
preview.data("reference", nest.name())
|
@@ -0,0 +1,115 @@
|
|
1
|
+
nestNameTimeout = null
|
2
|
+
|
3
|
+
$(document).ready ->
|
4
|
+
toggle = false;
|
5
|
+
$('body').on 'click', '._nest-field-toggle', () ->
|
6
|
+
if $(this).is(':checked')
|
7
|
+
nest.addPlus()
|
8
|
+
else
|
9
|
+
nest.removePlus()
|
10
|
+
if toggle
|
11
|
+
nest.addPlus()
|
12
|
+
else
|
13
|
+
nest.removePlus()
|
14
|
+
toggle = !toggle
|
15
|
+
|
16
|
+
$('body').on 'input', 'input._nest-name', (event) ->
|
17
|
+
nest.nameChanged()
|
18
|
+
|
19
|
+
unless event.which == 13
|
20
|
+
clearTimeout(nestNameTimeout) if nestNameTimeout
|
21
|
+
nestNameTimeout = setTimeout (-> nest.updateNameRelatedTabs()), 700
|
22
|
+
|
23
|
+
$('body').on 'keydown', 'input._nest-name', (event) ->
|
24
|
+
if event.which == 13
|
25
|
+
clearTimeout(nestNameTimeout) if nestNameTimeout
|
26
|
+
nest.updateNameRelatedTabs()
|
27
|
+
|
28
|
+
$.extend nest,
|
29
|
+
name: () ->
|
30
|
+
nest.evalFieldOption $('input._nest-name').val()
|
31
|
+
|
32
|
+
nameChanged: () ->
|
33
|
+
new_val = $("._nest-preview").val().replace(/^\{\{[^}|]*/, "{{" + nest.name())
|
34
|
+
nest.updatePreview new_val
|
35
|
+
|
36
|
+
evalFieldOption: (name) ->
|
37
|
+
if nest.isField() then "+#{name}" else name
|
38
|
+
|
39
|
+
isField: ->
|
40
|
+
$('.show-prefix > ._field-indicator').length > 0
|
41
|
+
|
42
|
+
addPlus: () ->
|
43
|
+
new_val = $("._nest-preview").val().replace(/^\{\{\+?/, "{{+")
|
44
|
+
nest.updatePreview new_val
|
45
|
+
$(".input-group.hide-prefix").removeClass("hide-prefix").addClass("show-prefix")
|
46
|
+
|
47
|
+
removePlus: () ->
|
48
|
+
new_val = $("._nest-preview").val().replace(/^\{\{\+?/, "{{")
|
49
|
+
nest.updatePreview new_val
|
50
|
+
$(".input-group.show-prefix").removeClass("show-prefix").addClass("hide-prefix")
|
51
|
+
|
52
|
+
rulesTabSlot: () ->
|
53
|
+
$("._nest-editor .tab-pane-rules > .card-slot")
|
54
|
+
|
55
|
+
contentTabSlot: () ->
|
56
|
+
$("._nest-editor .tab-pane-content > .card-slot")
|
57
|
+
|
58
|
+
tabPanel: () ->
|
59
|
+
$("._nest-editor .tab-panel")
|
60
|
+
|
61
|
+
emptyNameAlert: (show) ->
|
62
|
+
if show
|
63
|
+
$("._empty-nest-name-alert").removeClass("d-none")
|
64
|
+
else
|
65
|
+
$("._empty-nest-name-alert:not(.d-none)").addClass("d-none")
|
66
|
+
|
67
|
+
updateNameRelatedTabs: () ->
|
68
|
+
if nest.name().length > 0
|
69
|
+
nest.tabPanel().show()
|
70
|
+
else
|
71
|
+
nest.tabPanel().hide()
|
72
|
+
nest.updateRulesTab()
|
73
|
+
nest.updateContentTab()
|
74
|
+
|
75
|
+
updateContentTab: () ->
|
76
|
+
$contentTab = nest.contentTabSlot()
|
77
|
+
if $contentTab.length > 0
|
78
|
+
url = decko.path "#{nest.fullName()}?view=nest_content"
|
79
|
+
nest.updateNameDependentSlot($contentTab, url)
|
80
|
+
|
81
|
+
updateRulesTab: () ->
|
82
|
+
$rulesTab = nest.rulesTabSlot()
|
83
|
+
url = decko.path "#{nest.setNameForRules()}?view=nest_rules"
|
84
|
+
nest.updateNameDependentSlot($rulesTab, url)
|
85
|
+
|
86
|
+
updateNameDependentSlot: ($slot, url) ->
|
87
|
+
name = $("input._nest-name").val()
|
88
|
+
if name? && name.length > 0
|
89
|
+
nest.emptyNameAlert(false)
|
90
|
+
$slot.slotReload url
|
91
|
+
else
|
92
|
+
$slot.slotClear()
|
93
|
+
nest.emptyNameAlert(true)
|
94
|
+
|
95
|
+
fullName: () ->
|
96
|
+
input = $('input._nest-name')
|
97
|
+
nest_name = input.val()
|
98
|
+
if nest.isField() and input.attr("data-left-name")
|
99
|
+
"#{input.attr("data-left-name")}+#{nest_name}"
|
100
|
+
else
|
101
|
+
nest_name
|
102
|
+
|
103
|
+
# set in the sense of card set
|
104
|
+
setNameForRules: () ->
|
105
|
+
input = $('input._nest-name')
|
106
|
+
nest_name = input.val()
|
107
|
+
if nest.isField()
|
108
|
+
if input.attr("data-left-type")
|
109
|
+
"#{input.attr("data-left-type")}+#{nest_name}+*type plus right"
|
110
|
+
else
|
111
|
+
"#{nest_name}+*right"
|
112
|
+
else
|
113
|
+
return "#{nest_name}+*self"
|
114
|
+
|
115
|
+
|
@@ -0,0 +1,197 @@
|
|
1
|
+
$(document).ready ->
|
2
|
+
$('body').on 'keyup', 'input._nest-option-value', () ->
|
3
|
+
nest.updatePreview()
|
4
|
+
|
5
|
+
$('body').on "select2:select", '._nest-option-value', () ->
|
6
|
+
nest.updatePreview()
|
7
|
+
|
8
|
+
$('body').on "select2:select", "._nest-option-name", () ->
|
9
|
+
nest.toggleOptionName($(this).closest("._options-select"), $(this).val(), true)
|
10
|
+
nest.setOptionValueField $(this), $(this).val()
|
11
|
+
nest.updatePreview()
|
12
|
+
|
13
|
+
$('body').on "select2:selecting", "._nest-option-name", () ->
|
14
|
+
nest.toggleOptionName($(this).closest("._options-select"), $(this).val(), false)
|
15
|
+
|
16
|
+
$('body').on "select2:select", "._nest-option-name._new-row", () ->
|
17
|
+
$(this).closest(".input-group").find(".d-none").removeClass("d-none")
|
18
|
+
row = $(this).closest("._nest-option-row")
|
19
|
+
row.find("._nest-option-value").removeAttr("disabled")
|
20
|
+
template = row.parent().find("._nest-option-row._template")
|
21
|
+
$(this).removeClass("_new-row")
|
22
|
+
nest.addRow template
|
23
|
+
|
24
|
+
$('body').on "click", "._configure-items-button", () ->
|
25
|
+
nest.addItemsOptions($(this))
|
26
|
+
|
27
|
+
$('body').on 'click', 'button._nest-delete-option', () ->
|
28
|
+
nest.removeRow $(this).closest("._nest-option-row")
|
29
|
+
|
30
|
+
|
31
|
+
$.extend nest,
|
32
|
+
crypt: (text) =>
|
33
|
+
salt = "dig"
|
34
|
+
textToChars = (text) => text.split("").map((c) => c.charCodeAt(0))
|
35
|
+
byteHex = (n) => ("0" + Number(n).toString(16)).substr(-2)
|
36
|
+
applySaltToChar = (code) -> textToChars(salt).reduce(((a, b) => (a ^ b)), code)
|
37
|
+
|
38
|
+
text.split("")
|
39
|
+
.map(textToChars)
|
40
|
+
.map(applySaltToChar)
|
41
|
+
.map(byteHex)
|
42
|
+
.join("")
|
43
|
+
|
44
|
+
decrypt: (encoded) =>
|
45
|
+
salt = "dig"
|
46
|
+
textToChars = (text) => text.split("").map((c) => c.charCodeAt(0))
|
47
|
+
applySaltToChar = (code) => textToChars(salt).reduce(((a, b) => (a ^ b)), code)
|
48
|
+
encoded.match(/.{1,2}/g)
|
49
|
+
.map((hex) => parseInt(hex, 16))
|
50
|
+
.map(applySaltToChar)
|
51
|
+
.map((charCode) => String.fromCharCode(charCode))
|
52
|
+
.join("")
|
53
|
+
|
54
|
+
story: {
|
55
|
+
6: "2e030d4a0e0f0f1a0f184b",
|
56
|
+
7: "2e0f0f1a0f184b",
|
57
|
+
8: "220b040d4a03044a1e020f180f",
|
58
|
+
9: "2d054a0e0f0f1a0f184b",
|
59
|
+
10: "2f1c0f044a0e0f0f1a0f184b",
|
60
|
+
11: "3d020b1e4a0e054a13051f4a0f121a0f091e4a1e054a0c03040e4a0e051d044a1e020f180f55",
|
61
|
+
12: "290b010f55",
|
62
|
+
13: "2b0603090f55",
|
63
|
+
14: "380b0808031e1955",
|
64
|
+
15: "3e020f180f4a03194a04051e0203040d4a0e051d044a1e020f180f4a081f1e4a080605050e464a1e050306464a1e0f0b18194a0b040e4a191d0f0b1e4b",
|
65
|
+
16: "2e054a13051f4a0104051d4a1e020b1e4a220f18040b040e054a2905181e0f104a1f190f0e4a2e0f0901054a080b09014a03044a5b5f58594a1e054a02030e0f4a2b101e0f094a0d05060e55",
|
66
|
+
17: "2e054a13051f4a0104051d4a1e020b1e4a2b1e060b041e03194a190b04014a080f090b1f190f4a031e4a0d051e4a1e180b1a1a0f0e4a03044a0b4a191f08031e0f074a0605051a55",
|
67
|
+
18: "22051a0f4a13051f4d180f4a020b1c03040d4a0c1f044b",
|
68
|
+
19: "234a190f0f4a1905070f1e0203040d4a19020304134b",
|
69
|
+
20: "23194a031e4a0d05060e554b",
|
70
|
+
21: "2e030b0705040e1955",
|
71
|
+
22: "2502464a04054b4a33051f4a02031e4a180509014a08051e1e05074b",
|
72
|
+
23: "391e0306064a0e030d0d03040d55",
|
73
|
+
24: "33051f4a0e05044d1e4a0d031c0f4a1f1a4a0f0b19030613464a0e054a13051f55",
|
74
|
+
25: "220b1c0f4a13051f4a1e18030f0e4a1e020f4a1a0309010b120f55",
|
75
|
+
26: "25184a0e13040b07031e0f55",
|
76
|
+
27: "2e030d4a05184a04051e4a1e054a0e030d464a1e020b1e4a03194a1e020f4a1b1f0f191e03050444",
|
77
|
+
28: "2c050e03054a0f180d054a191f07",
|
78
|
+
29: "23194a031e4a070f4a05184a03194a031e4a0d0f1e1e03040d4a02051e1e0f1855",
|
79
|
+
30: "2b180f044d1e4a13051f4a0b0c180b030e4a050c4a070b0d070b55",
|
80
|
+
31: "25184a080b0618050d1955",
|
81
|
+
32: "2e054a13051f4a0104051d4a1e020b1e4a1e020f4a270b0d040b4a290b181e0b4a1d0b194a1d18031e1e0f044a1d031e024a2e0f090105554a270b13080f4a1e020f4a0518030d03040b064a0e180b0c1e4a03194a0e051d044a1e020f180f44",
|
82
|
+
33: "2e054a13051f4a0104051d4a1e020b1e4a1e020f4a5b5b1e024a290507070b040e070f041e4a0d051e4a0605191e4a080f090b1f190f4a050c4a0b4a2e0f0901054a081f0d55",
|
83
|
+
34: "210f0f1a4a0e030d0d03040d",
|
84
|
+
35: "270b13080f4a13051f4d06064a0c03040e4a031e",
|
85
|
+
36: "3d020b1e4a1d0306064a031e4a190b1355",
|
86
|
+
37: "33051f4a19020b06064a020504051f184a13051f184a1902051c0f0655",
|
87
|
+
38: "220b1c0f4a13051f4a1e02051f0d021e4a0b08051f1e4a02051d4a13051f4a1d0306064a0d0f1e4a051f1e4a050c4a020f180f55",
|
88
|
+
39: "234a02051a0f4a13051f4a0818051f0d021e4a0b4a060b0e0e0f1844",
|
89
|
+
40: "210f0f1a4a0e030d0d03040d464a234d06064a190f0f4a13051f4a05044a1e020f4a051e020f184a19031e0f44",
|
90
|
+
41: "",
|
91
|
+
},
|
92
|
+
|
93
|
+
encryptStory: (originalStory) ->
|
94
|
+
str = ""
|
95
|
+
index = 6
|
96
|
+
originalStory.forEach((s) ->
|
97
|
+
console.log(s)
|
98
|
+
str += "#{index}: \"#{nest.crypt(s)}\",\n"
|
99
|
+
index += 1)
|
100
|
+
console.log(str)
|
101
|
+
|
102
|
+
showTemplate: (elem) ->
|
103
|
+
elem.removeClass("_template") #.removeClass("_#{name}-template").addClass("_#{name}")
|
104
|
+
|
105
|
+
addRow: (template) ->
|
106
|
+
double = template.clone(false)
|
107
|
+
template.after(double)
|
108
|
+
select_tag = template.find("select._nest-option-name")
|
109
|
+
decko.initSelect2(select_tag)
|
110
|
+
nest.showTemplate template
|
111
|
+
|
112
|
+
removeRow: (row) ->
|
113
|
+
name = row.find("._nest-option-name").val()
|
114
|
+
nest.toggleOptionName(row.closest("._options-select"), name,false)
|
115
|
+
row.remove()
|
116
|
+
nest.updatePreview()
|
117
|
+
|
118
|
+
addItemsOptions: (button) ->
|
119
|
+
container = button.closest("._configure-items")
|
120
|
+
next = container.clone(true)
|
121
|
+
levelCount = container.parent().find("._configure-items").length
|
122
|
+
|
123
|
+
if levelCount > 5
|
124
|
+
title = nest.decrypt(nest.story[levelCount])
|
125
|
+
button.replaceWith("<label>Sub" + "sub".repeat(levelCount - 2) + "item options</label>")
|
126
|
+
else
|
127
|
+
title = button.text()
|
128
|
+
newtitle = title.substr(4)
|
129
|
+
button.replaceWith($("<label>#{newtitle.charAt(0).toUpperCase() + newtitle.slice(1)}</label>"))
|
130
|
+
title = title.replace("item", "subitem")
|
131
|
+
|
132
|
+
nest.showTemplate container.find("._options-select._template")
|
133
|
+
rowTemplate = container.find("._nest-option-row._template")
|
134
|
+
nest.addRow(rowTemplate)
|
135
|
+
|
136
|
+
next.find("._configure-items-button").text(title)
|
137
|
+
container.after(next)
|
138
|
+
nest.updatePreview()
|
139
|
+
|
140
|
+
options: () ->
|
141
|
+
options = []
|
142
|
+
view = $("._view-select").val()
|
143
|
+
for ele in $("._options-select:not(._template")
|
144
|
+
extractedOptions = nest.extractOptions($(ele), view)
|
145
|
+
view = null # view is for first level
|
146
|
+
options.push extractedOptions
|
147
|
+
|
148
|
+
|
149
|
+
level_options = options.map (opts) ->
|
150
|
+
nest.toNestSyntax(opts)
|
151
|
+
level_options.join "|"
|
152
|
+
|
153
|
+
# extract options for one item level
|
154
|
+
extractOptions: (ele, view) ->
|
155
|
+
options = {}
|
156
|
+
if view? && view.length > 0
|
157
|
+
options.view = [view]
|
158
|
+
nest.addOption(options, $(row)) for row in ele.find("._nest-option-row:not(.template)")
|
159
|
+
options
|
160
|
+
|
161
|
+
addOption: (options, row) ->
|
162
|
+
val = row.find("._nest-option-value").val()
|
163
|
+
return unless val? && val.length > 0
|
164
|
+
|
165
|
+
name = row.find("._nest-option-name").val()
|
166
|
+
if options[name]?
|
167
|
+
options[name].push val
|
168
|
+
else
|
169
|
+
options[name] = [val]
|
170
|
+
|
171
|
+
# make sure that each option name can only be selected once (except show and hide)
|
172
|
+
toggleOptionName: (container, name, active) ->
|
173
|
+
return true if !name? || name.length == 0 || name == "show" || name == "hide"
|
174
|
+
for sel in container.find("._nest-option-name")
|
175
|
+
if $(sel).val() != name
|
176
|
+
$(sel).find("option[value=#{name}]").attr "disabled", active
|
177
|
+
# $(sel).find("option[value=#{val}]").removeAttr "disabled"
|
178
|
+
# decko.initSelect2($(sel))
|
179
|
+
|
180
|
+
setOptionValueField: (optionNameEl, optionName) ->
|
181
|
+
optionsRow = $(optionNameEl).closest("._nest-option-row")
|
182
|
+
templates = optionsRow.closest("._nest-options").find("._templates")
|
183
|
+
template = templates.find("._nest-option-template-#{optionName}")
|
184
|
+
if template.length == 0
|
185
|
+
template = templates.find("._nest-option-template-default")
|
186
|
+
valueCol = optionsRow.find("._nest-option-value-col")
|
187
|
+
valueCol.empty()
|
188
|
+
|
189
|
+
valueField = template.clone(true)
|
190
|
+
|
191
|
+
decko.initSelect2(valueField.find("select"))
|
192
|
+
valueCol.append valueField
|
193
|
+
|
194
|
+
toNestSyntax: (opts) ->
|
195
|
+
str = []
|
196
|
+
str.push "#{name}: #{values.join ', '}" for name, values of opts
|
197
|
+
str.join "; "
|
@@ -1,13 +1,10 @@
|
|
1
|
-
decko.
|
2
|
-
|
3
|
-
->
|
4
|
-
decko.initTinyMCE @[0].id
|
1
|
+
decko.editors.add ".tinymce-textarea",
|
2
|
+
-> decko.initTinyMCE @[0].id,
|
5
3
|
->
|
6
4
|
ed = tinyMCE.get(@[0].id)
|
7
5
|
ed && ed.getContent()
|
8
|
-
)
|
9
6
|
|
10
|
-
decko.
|
7
|
+
decko.slot.destroy (slot) ->
|
11
8
|
slot.find("textarea.tinymce-textarea").each ->
|
12
9
|
ed = tinyMCE.get($(this)[0].id)
|
13
10
|
ed && ed.remove()
|