scrivito_editors 1.4.3 → 1.5.0.rc1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d326d1095e36a2c595beb4e547843320c02307a5
4
- data.tar.gz: 9164ff05f79fb885ad8d9815ccdb2df4656e61e5
3
+ metadata.gz: 835e8e50694e5e2d3e60299ffb7c980d99e54198
4
+ data.tar.gz: 6041191e9f760302ae1ee61de1769b3f7ba27a56
5
5
  SHA512:
6
- metadata.gz: e533ddd257bc7db4d8c74bafa529352e5e4719a32b22773846e72a1077d056ebe69e41e1131aa32dd85c4e404849b0e2186ca0bebe2b80a30b0e5d5594068cc0
7
- data.tar.gz: 0f89280703e65e116a947cc5b246863c36a8186aad6bdab20e622a04ab26e7c52a413b31081f8ae4da0311fc0ae840253dcddbc1f9040bbd04e833b3bf8f9f5d
6
+ metadata.gz: bdd533434af6e2f89f01fd11d2ad56ac145568c0cb14cf10a753e6d734f1f6e7822ab3b175078a5a3110ae72e8df6a8a5ea1168e526f8f1511fc961f2d7818ad
7
+ data.tar.gz: 86c98a67a239237dad35c5119627e710881f7a779e5f3f61d7644afe4775a48dab0907f024fa88cb2ef74f6cf66b09e3714445d29254c595b3e948b271ce9b2f
@@ -13,8 +13,11 @@
13
13
  //= require jquery.caret
14
14
  //= require jquery.tag-editor
15
15
  //= require medium-editor
16
- //= require_tree ./scrivito_editors/dependencies
16
+ //= require jquery-ui/sortable
17
+ //= require jquery-ui/datepicker
18
+ //= require jquery-ui/slider
17
19
  //= require jquery-ui-timepicker-addon.min
20
+ //= require jquery-ui/autocomplete
18
21
  //= require redactor
19
22
  //= require redactor_plugins/table
20
23
  //= require canvas-to-blob
@@ -27,13 +27,16 @@
27
27
  activate = function(cmsField) {
28
28
  var link;
29
29
  link = cmsField.scrivito('content') || {};
30
- cmsField.html(template(link));
30
+ cmsField.addClass('scrivito_editors_ui').html(template(link));
31
31
  if (link.obj_id) {
32
32
  fetchDescription(cmsField, link.obj_id);
33
33
  }
34
- cmsField.on('blur', 'li input', function() {
34
+ scrivito.editors._linkTargetEditing.activate(cmsField, cmsField.find('li'), link);
35
+ cmsField.on('scrivito_editors_private:target_changed', function() {
35
36
  return save(cmsField);
36
- }).on('click', 'a.scrivito_open_content_browser', function() {
37
+ }).on('blur', 'input', function() {
38
+ return save(cmsField);
39
+ }).on('click', '[data-scrivito-editors-browse]', function() {
37
40
  return openContentBrowser(cmsField);
38
41
  });
39
42
  return cmsField.find('[name=url]').on('focus', function() {
@@ -48,9 +51,10 @@
48
51
  };
49
52
 
50
53
  template = function(link) {
51
- var obj_url;
54
+ var obj_url, url;
52
55
  obj_url = link.obj_id && scrivito.path_for_id(link.obj_id);
53
- return $("<ul>\n <li data-id=\"" + link.obj_id + "\" data-title=\"" + link.title + "\" data-url=\"" + link.url + "\">\n <input type=\"text\" name=\"title\" value=\"" + (link.title || '') + "\" placeholder=\"Title\" />\n <input type=\"text\" name=\"url\" value=\"" + (link.url || obj_url || '') + "\"\n data-value=\"" + (link.url || obj_url || '') + "\" placeholder=\"Url\" class=\"editing-url\" />\n <div class=\"actions\">\n <a href=\"#\" class=\"scrivito_open_content_browser editing-button editing-green\">\n <i class=\"editing-icon editing-icon-search\" />\n </a>\n </div>\n </li>\n</ul>");
56
+ url = link.url || obj_url || '';
57
+ return $("<ul>\n <li data-id=\"" + (link.obj_id || '') + "\" data-target=\"\">\n <input type=\"text\" name=\"title\" value=\"" + (link.title || '') + "\" placeholder=\"Title\" />\n <input type=\"text\" name=\"url\" value=\"" + url + "\" data-value=\"" + url + "\" placeholder=\"URL\"\n class=\"editing-url\" />\n <div class=\"actions\">\n <div class=\"input_group_btn\">\n <a href=\"#\" class=\"editing-button editing-grey editing-clear\"\n data-scrivito-editors-toggle-target>\n <span class=\"scrivito_editors_current_target\"></span>\n <i class=\"scrivito_icon scrivito_icon_link_target\"></i>\n </a>\n <ul class=\"dropdown_menu\"></ul>\n </div>\n <a href=\"#\" class=\"editing-button content-browser-open editing-green\"\n data-scrivito-editors-browse>\n <i class=\"scrivito_icon scrivito_icon_content_browser\"></i>\n </a>\n </div>\n </li>\n</ul>");
54
58
  };
55
59
 
56
60
  openContentBrowser = function(cmsField) {
@@ -64,7 +68,8 @@
64
68
  filter_context: cmsField.data('scrivitoEditorsFilterContext')
65
69
  }).done(function(selection) {
66
70
  var url, val;
67
- if (id = selection[0]) {
71
+ id = selection[0];
72
+ if (id != null) {
68
73
  url = scrivito.path_for_id(id);
69
74
  val = "Content browser selection (" + url + ")";
70
75
  linkItem.attr('data-id', id).find('[name=url]').attr('data-value', url).val(val);
@@ -76,12 +81,14 @@
76
81
  };
77
82
 
78
83
  save = function(cmsField) {
79
- var li, title, url, urlInput, value;
84
+ var li, target, title, url, urlInput, value;
80
85
  li = cmsField.find('li');
86
+ target = li.attr('data-target');
81
87
  title = li.find('[name=title]').val();
82
88
  urlInput = li.find('[name=url]');
83
89
  url = urlInput.attr('data-value') || urlInput.val();
84
90
  value = url ? {
91
+ target: target,
85
92
  title: title,
86
93
  url: url
87
94
  } : null;
@@ -0,0 +1,49 @@
1
+ (function() {
2
+ var DEFAULT_TARGETS, setTarget, targets, toggleTargetSelection;
3
+
4
+ DEFAULT_TARGETS = {
5
+ _blank: "new window",
6
+ _top: "top-level window",
7
+ "": "same container"
8
+ };
9
+
10
+ scrivito.editors._linkTargetEditing = {
11
+ activate: function(cmsField, listElement, link) {
12
+ var label, ref, target;
13
+ listElement.on('click', '[data-scrivito-editors-toggle-target]', function() {
14
+ return toggleTargetSelection(listElement);
15
+ }).on('click', '[data-target-option]', function() {
16
+ setTarget(cmsField, listElement, $(this).attr("data-target-option"));
17
+ toggleTargetSelection(listElement);
18
+ return cmsField.trigger('scrivito_editors_private:target_changed');
19
+ });
20
+ ref = targets(cmsField);
21
+ for (target in ref) {
22
+ label = ref[target];
23
+ $("<li data-scrivito-editors-set-target>" + label + "</li>").appendTo(listElement.find(".dropdown_menu")).attr("data-target-option", target);
24
+ }
25
+ return setTarget(cmsField, listElement, link.target);
26
+ }
27
+ };
28
+
29
+ setTarget = function(cmsField, listElement, target) {
30
+ var text;
31
+ listElement.attr("data-target", target);
32
+ text = targets(cmsField)[target] || target;
33
+ if (target === "") {
34
+ text = "";
35
+ }
36
+ listElement.find(".scrivito_editors_current_target").text(text);
37
+ return false;
38
+ };
39
+
40
+ toggleTargetSelection = function(listElement) {
41
+ listElement.find('.dropdown_menu').slideToggle();
42
+ return false;
43
+ };
44
+
45
+ targets = function(cmsField) {
46
+ return cmsField.data('scrivito_editors_link_targets') || DEFAULT_TARGETS;
47
+ };
48
+
49
+ }).call(this);
@@ -19,7 +19,7 @@
19
19
  linklist = cmsField.scrivito('content');
20
20
  render(cmsField, linklist);
21
21
  fetchDescriptions(cmsField, objIdsFor(linklist));
22
- attachHandlers(cmsField);
22
+ attachHandlers(cmsField, linklist);
23
23
  return storeLastSaved(cmsField, linklist);
24
24
  };
25
25
 
@@ -30,8 +30,7 @@
30
30
  link = linklist[j];
31
31
  ul.append(linkTemplate(link));
32
32
  }
33
- cmsField.html(ul);
34
- return cmsField.append('<button class="editing-button editing-green add-link">\n <i class="editing-icon editing-icon-plus"></i>\n</button>');
33
+ return cmsField.addClass('scrivito_editors_ui').html(ul).append('<button class="editing-button editing-green add-link">\n <i class="editing-icon editing-icon-plus"></i>\n</button>');
35
34
  };
36
35
 
37
36
  fetchDescriptions = function(cmsField, objIds) {
@@ -65,31 +64,35 @@
65
64
  return results;
66
65
  };
67
66
 
68
- attachHandlers = function(cmsField) {
69
- var j, len, li, ref, results, ul;
67
+ attachHandlers = function(cmsField, linklist) {
68
+ var index, j, len, li, ref, results, ul;
70
69
  ul = cmsField.find('ul');
71
70
  scrivito.editors.Sortable.create(ul.get(0), {
72
71
  ghostClass: 'scrivito-sortable-placeholder',
72
+ handle: '.scrivito-editors-handle',
73
73
  onUpdate: function() {
74
74
  return save(cmsField);
75
75
  }
76
76
  });
77
- cmsField.on('blur', 'li input', function() {
77
+ cmsField.on('scrivito_editors_private:target_changed', function() {
78
+ return save(cmsField);
79
+ }).on('blur', 'li input', function() {
78
80
  return save(cmsField);
79
81
  }).on('click', 'button.add-link', function() {
80
82
  return addLink(cmsField);
81
83
  });
82
84
  ref = ul.find('li');
83
85
  results = [];
84
- for (j = 0, len = ref.length; j < len; j++) {
85
- li = ref[j];
86
- results.push(attachLinkHandlers(cmsField, $(li)));
86
+ for (index = j = 0, len = ref.length; j < len; index = ++j) {
87
+ li = ref[index];
88
+ results.push(attachLinkHandlers(cmsField, $(li), linklist[index]));
87
89
  }
88
90
  return results;
89
91
  };
90
92
 
91
- attachLinkHandlers = function(cmsField, li) {
92
- return li.on('click', 'a.scrivito_open_content_browser', function() {
93
+ attachLinkHandlers = function(cmsField, li, link) {
94
+ scrivito.editors._linkTargetEditing.activate(cmsField, li, link);
95
+ return li.on('click', '[data-scrivito-editors-browse]', function() {
93
96
  return openContentBrowser(cmsField, li);
94
97
  }).on('click', 'a.delete', function() {
95
98
  return removeLink(cmsField, li);
@@ -105,13 +108,14 @@
105
108
  };
106
109
 
107
110
  linkTemplate = function(link) {
108
- var obj_url;
111
+ var obj_url, url;
109
112
  obj_url = link.obj_id && scrivito.path_for_id(link.obj_id);
110
- return $("<li " + (link.obj_id ? "data-id='" + link.obj_id + "'" : void 0) + " data-title=\"" + link.title + "\" data-url=\"" + link.url + "\">\n <input type=\"text\" name=\"title\" value=\"" + (link.title || '') + "\" placeholder=\"Title\" />\n <input type=\"text\" name=\"url\" value=\"" + (link.url || obj_url || '') + "\"\n data-value=\"" + (link.url || obj_url || '') + "\" placeholder=\"Url\" class=\"editing-url\" />\n <div class=\"actions\">\n <a href=\"#\" class=\"scrivito_open_content_browser editing-button editing-green\">\n <i class=\"editing-icon editing-icon-search\" />\n </a>\n <a href=\"#\" class=\"editing-button editing-red delete\">\n <i class=\"editing-icon editing-icon-trash\" />\n </a>\n </div>\n</li>");
113
+ url = link.url || obj_url || '';
114
+ return $("<li data-id=\"" + (link.obj_id || '') + "\" data-title=\"" + (link.title || '') + "\" data-url=\"" + url + "\"\n data-target=\"\">\n <span class=\"scrivito-editors-handle\"></span>\n <input type=\"text\" name=\"title\" value=\"" + (link.title || '') + "\" placeholder=\"Title\" />\n <input type=\"text\" name=\"url\" value=\"" + url + "\" data-value=\"" + url + "\" placeholder=\"URL\"\n class=\"editing-url\" />\n <div class=\"actions\">\n <div class=\"input_group_btn\">\n <a href=\"#\" class=\"editing-button editing-grey editing-clear\"\n data-scrivito-editors-toggle-target>\n <span class=\"scrivito_editors_current_target\"></span>\n <i class=\"scrivito_icon scrivito_icon_link_target\"></i>\n </a>\n <ul class=\"dropdown_menu\"></ul>\n </div>\n <a href=\"#\" class=\"editing-button content-browser-open editing-green\"\n data-scrivito-editors-browse>\n <i class=\"scrivito_icon scrivito_icon_content_browser\"></i>\n </a>\n <a href=\"#\" class=\"editing-button editing-red delete\">\n <i class=\"scrivito_icon scrivito_icon_trash\"></i>\n </a>\n </div>\n</li>");
111
115
  };
112
116
 
113
117
  save = function(cmsField) {
114
- var input, lastSaved, li, title, url, value;
118
+ var input, lastSaved, li, target, title, url, value;
115
119
  value = (function() {
116
120
  var j, len, ref, results;
117
121
  ref = $(cmsField).find('li');
@@ -119,11 +123,13 @@
119
123
  for (j = 0, len = ref.length; j < len; j++) {
120
124
  li = ref[j];
121
125
  li = $(li);
126
+ target = li.attr('data-target');
122
127
  title = li.find('[name=title]').val();
123
128
  input = li.find('[name=url]');
124
129
  url = input.attr('data-value') || input.val();
125
130
  if (url) {
126
131
  results.push({
132
+ target: target,
127
133
  title: title,
128
134
  url: url
129
135
  });
@@ -147,9 +153,8 @@
147
153
 
148
154
  addLink = function(cmsField) {
149
155
  var li;
150
- li = linkTemplate({});
151
- li.appendTo(cmsField.find('ul'));
152
- attachLinkHandlers(cmsField, li);
156
+ li = linkTemplate({}).appendTo(cmsField.children('ul'));
157
+ attachLinkHandlers(cmsField, li, {});
153
158
  return false;
154
159
  };
155
160
 
@@ -129,6 +129,25 @@ a.editing-button:active {
129
129
  cursor: not-allowed;
130
130
  }
131
131
 
132
+
133
+ .editing-button.editing-grey {
134
+ background: #f3f3f3;
135
+ color: #666;
136
+ }
137
+
138
+ .editing-button.editing-grey:hover {
139
+ background: #f6f6f6;
140
+ color: #666;
141
+ }
142
+
143
+ .editing-button.editing-grey:active {
144
+ background: #fafafa;
145
+ color: #666;
146
+ }
147
+
148
+ .editing-button span { font-size: 12px; padding: 0 2px 0 0;}
149
+
150
+
132
151
  .editing-button .editing-icon {
133
152
  color: #333;
134
153
  font-size: 9px;
@@ -146,6 +165,24 @@ a.editing-button:active {
146
165
  color: #fff;
147
166
  }
148
167
 
168
+
169
+ .editing-button .scrivito_icon { color: #555; font-size: 18px; line-height: 14px; }
170
+ .editing-button.editing-blue .scrivito_icon,
171
+ .editing-button.editing-green .scrivito_icon,
172
+ .editing-button.editing-red .scrivito_icon,
173
+ .editing-button.editing-yellow .scrivito_icon {
174
+ color: #fff;
175
+ }
176
+
177
+
178
+ .editing-button.editing-clear {
179
+ color: #888;
180
+ -webkit-box-shadow: none;
181
+ -moz-box-shadow: none;
182
+ box-shadow: none;
183
+ }
184
+ .editing-button.editing-clear .editing-icon {color: #888;}
185
+
149
186
  /*
150
187
  Styling for buttons in the details view dialog.
151
188
  */
@@ -159,3 +196,39 @@ a.editing-button:active {
159
196
  .details-view [data-scrivito-field-type="date"] .editing-button {
160
197
  margin: 10px 10px 0 0;
161
198
  }
199
+
200
+
201
+ .input_group_btn { display: inline-block; position: relative; float: left;}
202
+
203
+ .dropdown_menu { background-color: #fff!important;
204
+ border: 1px solid rgba(0, 0, 0, 0.15);
205
+ border-radius: 4px;
206
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
207
+ display: none;
208
+ float: left;
209
+ font-size: 12px!important;
210
+ right: 0;
211
+ list-style: outside none none;
212
+ margin: 2px 0 0;
213
+ min-width: 140px;
214
+ padding: 5px 0;
215
+ position: absolute;
216
+ text-align: left;
217
+ top: 100%;
218
+ z-index: 1000;
219
+ }
220
+
221
+ .dropdown_menu li {
222
+ background: #fff!important;
223
+ padding: 5px 10px!important;
224
+ margin: 0!important;
225
+ border: 0!important;
226
+ border-radius: 0!important;
227
+ color: #666;
228
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
229
+ font-size: 12px!important;
230
+ border-bottom: 1px solid rgba(0, 0, 0, 0.15)!important;
231
+ }
232
+ .dropdown_menu li:hover { background: #f3f3f3!important; cursor: pointer!important; }
233
+
234
+ .dropdown_menu li:before { display: none;}
@@ -25,6 +25,7 @@
25
25
  }
26
26
 
27
27
  /* kept for backwards compatibility reasons */
28
+ .editing-icon-code:after { content: "\F018"; }
28
29
  .editing-icon-edit:after { content: "\F026"; }
29
30
  .editing-icon-search:after { content: "\F043"; }
30
31
  .editing-icon-trash:after { content: "\F038"; }
@@ -2,44 +2,44 @@
2
2
  An editor to handle CMS link attributes.
3
3
  */
4
4
 
5
- [data-scrivito-field-type="link"] ul {
5
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul {
6
6
  list-style: none;
7
7
  margin: 0;
8
8
  padding: 0;
9
9
  }
10
10
 
11
- [data-scrivito-field-type="link"] ul li{
11
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li{
12
12
  background-color: #f1f1f1;
13
13
  border-radius: 5px;
14
14
  -webkit-border-radius: 5px;
15
15
  -moz-border-radius: 5px;
16
16
  margin: 0;
17
- overflow: hidden;
18
17
  padding: 5px 10px;
19
18
  position: relative;
20
19
  border: 1px solid #ddd;
21
20
  }
22
21
 
23
- [data-scrivito-field-type="link"] ul li .list-content a {
22
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li .list-content a {
24
23
  display:block;
25
24
  }
26
25
 
27
- [data-scrivito-field-type="link"] ul li .actions {
26
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li .actions {
28
27
  position: absolute;
29
28
  bottom: 0;
30
29
  right: 0;
31
30
  }
32
31
 
33
- [data-scrivito-field-type="link"] ul li .actions .editing-button {
32
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li .actions .editing-button {
34
33
  border-radius: 0;
35
34
  margin: 0;
35
+ height: 30px;
36
36
  }
37
37
 
38
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="link"] ul li {
38
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li {
39
39
  padding: 0;
40
40
  }
41
41
 
42
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="link"] ul li input {
42
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li input {
43
43
  background: #fff;
44
44
  border: 0px solid #ddd;
45
45
  border-top-width: 1px;
@@ -47,7 +47,6 @@
47
47
  border-radius: 0 0 5px 5px;
48
48
  color: #555555;
49
49
  display: block;
50
- float: left;
51
50
  font-size: 14px;
52
51
  height: 31px;
53
52
  margin: 0;
@@ -55,19 +54,29 @@
55
54
  width: 100%;
56
55
  }
57
56
 
58
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="link"] ul li input:first-child {
57
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li input:first-child {
59
58
  border-radius: 5px 5px 0 0;
60
59
  border-top-width: 0px;
61
60
  }
62
61
 
62
+ /* micro clearfix */
63
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li:before,
64
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li:after {
65
+ content: " ";
66
+ display: table;
67
+ }
68
+
69
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li:after {
70
+ clear: both;
71
+ }
72
+
63
73
  @media (max-width: 550px) {
64
- [data-scrivito-field-type="link"] ul li .actions {
65
- float: left;
74
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li .actions {
66
75
  position: static;
76
+ float: right;
67
77
  }
68
78
 
69
- [data-scrivito-field-type="link"] ul li .actions .editing-button {
70
- border-radius: 5px;
79
+ .scrivito_editors_ui[data-scrivito-field-type="link"] ul li .actions .editing-button {
71
80
  margin: 4px 0 0 0;
72
81
  }
73
82
  }
@@ -2,57 +2,56 @@
2
2
  An editor to handle CMS linklist attributes.
3
3
  */
4
4
 
5
- [data-scrivito-field-type="linklist"] ul {
5
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul {
6
6
  list-style: none;
7
7
  margin: 0;
8
8
  padding: 0;
9
9
  }
10
10
 
11
- [data-scrivito-field-type="linklist"] ul li{
11
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li{
12
12
  background-color: #f3f3f3;
13
13
  border-radius: 5px;
14
14
  -webkit-border-radius: 5px;
15
15
  -moz-border-radius: 5px;
16
16
  margin: 4px 0;
17
- overflow: hidden;
18
17
  padding: 5px 10px;
19
18
  position: relative;
20
19
  border: 1px solid #ddd;
21
20
  }
22
21
 
23
- [data-scrivito-field-type="linklist"] ul li.scrivito-sortable-placeholder:before {
22
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li.scrivito-sortable-placeholder:before {
24
23
  display:none;
25
24
  }
26
25
 
27
- [data-scrivito-field-type="linklist"] ul li .list-content a {
26
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .list-content a {
28
27
  display:block;
29
28
  }
30
29
 
31
- [data-scrivito-field-type="linklist"] ul li .actions {
30
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .actions {
32
31
  position: absolute;
33
32
  bottom: 0;
34
33
  right: 0;
35
34
  }
36
35
 
37
- [data-scrivito-field-type="linklist"] ul li .actions .editing-button {
36
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .actions .editing-button {
38
37
  border-radius: 0;
39
38
  margin: 0;
39
+ height: 30px;
40
40
  }
41
41
 
42
- [data-scrivito-field-type="linklist"] ul li .actions .editing-button.delete {
42
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .actions .editing-button.delete {
43
43
  margin-left: 1px;
44
44
  float: right;
45
45
  }
46
46
 
47
- [data-scrivito-field-type="linklist"] ul li .actions .editing-button.content-browser-open {
47
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .actions .editing-button.content-browser-open {
48
48
  }
49
49
 
50
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="linklist"] ul li {
50
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li {
51
51
  padding: 0 0 0 30px;
52
52
  }
53
53
 
54
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="linklist"] ul li:before {
55
- content: "↕";
54
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .scrivito-editors-handle {
56
55
  color: #999;
57
56
  font-size: 19px;
58
57
  line-height: 0;
@@ -61,12 +60,16 @@
61
60
  top: 50%;
62
61
  }
63
62
 
64
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="linklist"] ul li:hover {
63
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .scrivito-editors-handle:before {
64
+ content: "↕";
65
+ }
66
+
67
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li:hover {
65
68
  background-color: #e6f3f7;
66
69
  cursor: move;
67
70
  }
68
71
 
69
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="linklist"] ul li.scrivito-sortable-placeholder {
72
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li.scrivito-sortable-placeholder {
70
73
  background: #f3f3f3;
71
74
  border: 2px dashed #9bc2cf;
72
75
  opacity: .5;
@@ -74,7 +77,7 @@
74
77
  visibility: visible!important;
75
78
  }
76
79
 
77
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="linklist"] ul li input {
80
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li input {
78
81
  background: #fff;
79
82
  border: 0px solid #ddd;
80
83
  border-top-width: 1px;
@@ -82,7 +85,6 @@
82
85
  border-radius: 0 0 5px 0;
83
86
  color: #555555;
84
87
  display: block;
85
- float: left;
86
88
  font-size: 14px;
87
89
  height: 31px;
88
90
  margin: 0;
@@ -90,7 +92,30 @@
90
92
  width: 100%;
91
93
  }
92
94
 
93
- [data-scrivito-display-mode="editing"] [data-scrivito-field-type="linklist"] ul li input:first-child {
95
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li input:first-child {
94
96
  border-radius: 0 5px 0 0;
95
97
  border-top-width: 0px;
96
98
  }
99
+
100
+ /* micro clearfix */
101
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li:before,
102
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li:after {
103
+ content: " ";
104
+ display: table;
105
+ }
106
+
107
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li:after {
108
+ clear: both;
109
+ }
110
+
111
+
112
+ @media (max-width: 550px) {
113
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .actions {
114
+ position: static;
115
+ float: right;
116
+ }
117
+
118
+ .scrivito_editors_ui[data-scrivito-field-type="linklist"] ul li .actions .editing-button {
119
+ margin: 4px 0 0 0;
120
+ }
121
+ }
@@ -385,7 +385,8 @@ if (!("classList" in document.createElement("_"))) {
385
385
 
386
386
  (function (root, factory) {
387
387
  'use strict';
388
- if (typeof module === 'object') {
388
+ var isElectron = typeof module === 'object' && process && process.versions && process.versions.electron;
389
+ if (!isElectron && typeof module === 'object') {
389
390
  module.exports = factory;
390
391
  } else if (typeof define === 'function' && define.amd) {
391
392
  define(function () {
@@ -1653,6 +1654,19 @@ MediumEditor.extensions = {};
1653
1654
  */
1654
1655
  setInactive: undefined,
1655
1656
 
1657
+ /* getInteractionElements: [function ()]
1658
+ *
1659
+ * If the extension renders any elements that the user can interact with,
1660
+ * this method should be implemented and return the root element or an array
1661
+ * containing all of the root elements. MediumEditor will call this function
1662
+ * during interaction to see if the user clicked on something outside of the editor.
1663
+ * The elements are used to check if the target element of a click or
1664
+ * other user event is a descendant of any extension elements.
1665
+ * This way, the editor can also count user interaction within editor elements as
1666
+ * interactions with the editor, and thus not trigger 'blur'
1667
+ */
1668
+ getInteractionElements: undefined,
1669
+
1656
1670
  /************************ Helpers ************************
1657
1671
  * The following are helpers that are either set by MediumEditor
1658
1672
  * during initialization, or are helper methods which either
@@ -2416,6 +2430,26 @@ MediumEditor.extensions = {};
2416
2430
  (function () {
2417
2431
  'use strict';
2418
2432
 
2433
+ function isElementDescendantOfExtension(extensions, element) {
2434
+ return extensions.some(function (extension) {
2435
+ if (typeof extension.getInteractionElements !== 'function') {
2436
+ return false;
2437
+ }
2438
+
2439
+ var extensionElements = extension.getInteractionElements();
2440
+ if (!extensionElements) {
2441
+ return false;
2442
+ }
2443
+
2444
+ if (!Array.isArray(extensionElements)) {
2445
+ extensionElements = [extensionElements];
2446
+ }
2447
+ return extensionElements.some(function (el) {
2448
+ return MediumEditor.util.isDescendant(el, element, true);
2449
+ });
2450
+ });
2451
+ }
2452
+
2419
2453
  var Events = function (instance) {
2420
2454
  this.base = instance;
2421
2455
  this.options = this.base.options;
@@ -2755,6 +2789,8 @@ MediumEditor.extensions = {};
2755
2789
  // Detecting drop on the contenteditables
2756
2790
  this.attachToEachElement('drop', this.handleDrop);
2757
2791
  break;
2792
+ // TODO: We need to have a custom 'paste' event separate from 'editablePaste'
2793
+ // Need to think about the way to introduce this without breaking folks
2758
2794
  case 'editablePaste':
2759
2795
  // Detecting paste on the contenteditables
2760
2796
  this.attachToEachElement('paste', this.handlePaste);
@@ -2792,21 +2828,16 @@ MediumEditor.extensions = {};
2792
2828
  },
2793
2829
 
2794
2830
  updateFocus: function (target, eventObj) {
2795
- var toolbar = this.base.getExtensionByName('toolbar'),
2796
- toolbarEl = toolbar ? toolbar.getToolbarElement() : null,
2797
- anchorPreview = this.base.getExtensionByName('anchor-preview'),
2798
- previewEl = (anchorPreview && anchorPreview.getPreviewElement) ? anchorPreview.getPreviewElement() : null,
2799
- hadFocus = this.base.getFocusedElement(),
2831
+ var hadFocus = this.base.getFocusedElement(),
2800
2832
  toFocus;
2801
2833
 
2802
- // For clicks, we need to know if the mousedown that caused the click happened inside the existing focused element.
2803
- // If so, we don't want to focus another element
2834
+ // For clicks, we need to know if the mousedown that caused the click happened inside the existing focused element
2835
+ // or one of the extension elements. If so, we don't want to focus another element
2804
2836
  if (hadFocus &&
2805
2837
  eventObj.type === 'click' &&
2806
2838
  this.lastMousedownTarget &&
2807
2839
  (MediumEditor.util.isDescendant(hadFocus, this.lastMousedownTarget, true) ||
2808
- MediumEditor.util.isDescendant(toolbarEl, this.lastMousedownTarget, true) ||
2809
- MediumEditor.util.isDescendant(previewEl, this.lastMousedownTarget, true))) {
2840
+ isElementDescendantOfExtension(this.base.extensions, this.lastMousedownTarget))) {
2810
2841
  toFocus = hadFocus;
2811
2842
  }
2812
2843
 
@@ -2822,10 +2853,9 @@ MediumEditor.extensions = {};
2822
2853
  }, this);
2823
2854
  }
2824
2855
 
2825
- // Check if the target is external (not part of the editor, toolbar, or anchorpreview)
2856
+ // Check if the target is external (not part of the editor, toolbar, or any other extension)
2826
2857
  var externalEvent = !MediumEditor.util.isDescendant(hadFocus, target, true) &&
2827
- !MediumEditor.util.isDescendant(toolbarEl, target, true) &&
2828
- !MediumEditor.util.isDescendant(previewEl, target, true);
2858
+ !isElementDescendantOfExtension(this.base.extensions, target);
2829
2859
 
2830
2860
  if (toFocus !== hadFocus) {
2831
2861
  // If element has focus, and focus is going outside of editor
@@ -3948,6 +3978,11 @@ MediumEditor.extensions = {};
3948
3978
  */
3949
3979
  showWhenToolbarIsVisible: false,
3950
3980
 
3981
+ /* showOnEmptyLinks: [boolean]
3982
+ * determines whether the anchor tag preview shows up on links with href="" or href="#something"
3983
+ */
3984
+ showOnEmptyLinks: true,
3985
+
3951
3986
  init: function () {
3952
3987
  this.anchorPreview = this.createPreview();
3953
3988
 
@@ -3956,6 +3991,11 @@ MediumEditor.extensions = {};
3956
3991
  this.attachToEditables();
3957
3992
  },
3958
3993
 
3994
+ getInteractionElements: function () {
3995
+ return this.getPreviewElement();
3996
+ },
3997
+
3998
+ // TODO: Remove this function in 6.0.0
3959
3999
  getPreviewElement: function () {
3960
4000
  return this.anchorPreview;
3961
4001
  },
@@ -4077,7 +4117,7 @@ MediumEditor.extensions = {};
4077
4117
  this.base.delay(function () {
4078
4118
  if (activeAnchor) {
4079
4119
  var opts = {
4080
- url: activeAnchor.attributes.href.value,
4120
+ value: activeAnchor.attributes.href.value,
4081
4121
  target: activeAnchor.getAttribute('target'),
4082
4122
  buttonClass: activeAnchor.getAttribute('class')
4083
4123
  };
@@ -4106,7 +4146,8 @@ MediumEditor.extensions = {};
4106
4146
  // Detect empty href attributes
4107
4147
  // The browser will make href="" or href="#top"
4108
4148
  // into absolute urls when accessed as event.target.href, so check the html
4109
- if (!/href=["']\S+["']/.test(target.outerHTML) || /href=["']#\S+["']/.test(target.outerHTML)) {
4149
+ if (!this.showOnEmptyLinks &&
4150
+ (!/href=["']\S+["']/.test(target.outerHTML) || /href=["']#\S+["']/.test(target.outerHTML))) {
4110
4151
  return true;
4111
4152
  }
4112
4153
 
@@ -5133,11 +5174,20 @@ MediumEditor.extensions = {};
5133
5174
  MediumEditor.Extension.prototype.init.apply(this, arguments);
5134
5175
 
5135
5176
  if (this.forcePlainText || this.cleanPastedHTML) {
5136
- this.subscribe('editablePaste', this.handlePaste.bind(this));
5137
5177
  this.subscribe('editableKeydown', this.handleKeydown.bind(this));
5178
+ // We need access to the full event data in paste
5179
+ // so we can't use the editablePaste event here
5180
+ this.getEditorElements().forEach(function (element) {
5181
+ this.on(element, 'paste', this.handlePaste.bind(this));
5182
+ }, this);
5183
+ this.subscribe('addElement', this.handleAddElement.bind(this));
5138
5184
  }
5139
5185
  },
5140
5186
 
5187
+ handleAddElement: function (event, editable) {
5188
+ this.on(editable, 'paste', this.handlePaste.bind(this));
5189
+ },
5190
+
5141
5191
  destroy: function () {
5142
5192
  // Make sure pastebin is destroyed in case it's still around for some reason
5143
5193
  if (this.forcePlainText || this.cleanPastedHTML) {
@@ -5214,6 +5264,12 @@ MediumEditor.extensions = {};
5214
5264
  event.preventDefault();
5215
5265
  this.removePasteBin();
5216
5266
  this.doPaste(pastedHTML, pastedPlain, editable);
5267
+
5268
+ // The event handling code listens for paste on the editable element
5269
+ // in order to trigger the editablePaste event. Since this paste event
5270
+ // is happening on the pastebin, the event handling code never knows about it
5271
+ // So, we have to trigger editablePaste manually
5272
+ this.trigger('editablePaste', { currentTarget: editable, target: editable }, editable);
5217
5273
  return;
5218
5274
  }
5219
5275
 
@@ -5231,6 +5287,12 @@ MediumEditor.extensions = {};
5231
5287
 
5232
5288
  // Handle the paste with the html from the paste bin
5233
5289
  this.doPaste(pastedHTML, pastedPlain, editable);
5290
+
5291
+ // The event handling code listens for paste on the editable element
5292
+ // in order to trigger the editablePaste event. Since this paste event
5293
+ // is happening on the pastebin, the event handling code never knows about it
5294
+ // So, we have to trigger editablePaste manually
5295
+ this.trigger('editablePaste', { currentTarget: editable, target: editable }, editable);
5234
5296
  }.bind(this), 0);
5235
5297
  },
5236
5298
 
@@ -5523,37 +5585,61 @@ MediumEditor.extensions = {};
5523
5585
  },
5524
5586
 
5525
5587
  initPlaceholders: function () {
5526
- this.getEditorElements().forEach(function (el) {
5527
- if (!el.getAttribute('data-placeholder')) {
5528
- el.setAttribute('data-placeholder', this.text);
5529
- }
5530
- this.updatePlaceholder(el);
5531
- }, this);
5588
+ this.getEditorElements().forEach(this.initElement, this);
5589
+ },
5590
+
5591
+ handleAddElement: function (event, editable) {
5592
+ this.initElement(editable);
5593
+ },
5594
+
5595
+ initElement: function (el) {
5596
+ if (!el.getAttribute('data-placeholder')) {
5597
+ el.setAttribute('data-placeholder', this.text);
5598
+ }
5599
+ this.updatePlaceholder(el);
5532
5600
  },
5533
5601
 
5534
5602
  destroy: function () {
5535
- this.getEditorElements().forEach(function (el) {
5536
- if (el.getAttribute('data-placeholder') === this.text) {
5537
- el.removeAttribute('data-placeholder');
5538
- }
5539
- }, this);
5603
+ this.getEditorElements().forEach(this.cleanupElement, this);
5604
+ },
5605
+
5606
+ handleRemoveElement: function (event, editable) {
5607
+ this.cleanupElement(editable);
5608
+ },
5609
+
5610
+ cleanupElement: function (el) {
5611
+ if (el.getAttribute('data-placeholder') === this.text) {
5612
+ el.removeAttribute('data-placeholder');
5613
+ }
5540
5614
  },
5541
5615
 
5542
5616
  showPlaceholder: function (el) {
5543
5617
  if (el) {
5544
- el.classList.add('medium-editor-placeholder');
5618
+ // https://github.com/yabwe/medium-editor/issues/234
5619
+ // In firefox, styling the placeholder with an absolutely positioned
5620
+ // pseudo element causes the cursor to appear in a bad location
5621
+ // when the element is completely empty, so apply a different class to
5622
+ // style it with a relatively positioned pseudo element
5623
+ if (MediumEditor.util.isFF && el.childNodes.length === 0) {
5624
+ el.classList.add('medium-editor-placeholder-relative');
5625
+ el.classList.remove('medium-editor-placeholder');
5626
+ } else {
5627
+ el.classList.add('medium-editor-placeholder');
5628
+ el.classList.remove('medium-editor-placeholder-relative');
5629
+ }
5545
5630
  }
5546
5631
  },
5547
5632
 
5548
5633
  hidePlaceholder: function (el) {
5549
5634
  if (el) {
5550
5635
  el.classList.remove('medium-editor-placeholder');
5636
+ el.classList.remove('medium-editor-placeholder-relative');
5551
5637
  }
5552
5638
  },
5553
5639
 
5554
5640
  updatePlaceholder: function (el, dontShow) {
5555
5641
  // If the element has content, hide the placeholder
5556
- if (el.querySelector('img, blockquote, ul, ol') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) {
5642
+ if (el.querySelector('img, blockquote, ul, ol, table') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) {
5557
5643
  return this.hidePlaceholder(el);
5558
5644
  }
5559
5645
 
@@ -5573,6 +5659,10 @@ MediumEditor.extensions = {};
5573
5659
 
5574
5660
  // When the editor loses focus, check if the placeholder should be visible
5575
5661
  this.subscribe('blur', this.handleBlur.bind(this));
5662
+
5663
+ // Need to know when elements are added/removed from the editor
5664
+ this.subscribe('addElement', this.handleAddElement.bind(this));
5665
+ this.subscribe('removeElement', this.handleRemoveElement.bind(this));
5576
5666
  },
5577
5667
 
5578
5668
  handleInput: function (event, element) {
@@ -5789,6 +5879,10 @@ MediumEditor.extensions = {};
5789
5879
 
5790
5880
  // Toolbar accessors
5791
5881
 
5882
+ getInteractionElements: function () {
5883
+ return this.getToolbarElement();
5884
+ },
5885
+
5792
5886
  getToolbarElement: function () {
5793
5887
  if (!this.toolbar) {
5794
5888
  this.toolbar = this.createToolbar();
@@ -6642,17 +6736,17 @@ MediumEditor.extensions = {};
6642
6736
  return !this.options.extensions['imageDragging'];
6643
6737
  }
6644
6738
 
6645
- function createContentEditable(textarea, id, doc) {
6646
- var div = doc.createElement('div'),
6739
+ function createContentEditable(textarea) {
6740
+ var div = this.options.ownerDocument.createElement('div'),
6647
6741
  now = Date.now(),
6648
- uniqueId = 'medium-editor-' + now + '-' + id,
6742
+ uniqueId = 'medium-editor-' + now,
6649
6743
  atts = textarea.attributes;
6650
6744
 
6651
6745
  // Some browsers can move pretty fast, since we're using a timestamp
6652
6746
  // to make a unique-id, ensure that the id is actually unique on the page
6653
- while (doc.getElementById(uniqueId)) {
6747
+ while (this.options.ownerDocument.getElementById(uniqueId)) {
6654
6748
  now++;
6655
- uniqueId = 'medium-editor-' + now + '-' + id;
6749
+ uniqueId = 'medium-editor-' + now;
6656
6750
  }
6657
6751
 
6658
6752
  div.className = textarea.className;
@@ -6669,6 +6763,16 @@ MediumEditor.extensions = {};
6669
6763
  }
6670
6764
  }
6671
6765
 
6766
+ // If textarea has a form, listen for reset on the form to clear
6767
+ // the content of the created div
6768
+ if (textarea.form) {
6769
+ this.on(textarea.form, 'reset', function (event) {
6770
+ if (!event.defaultPrevented) {
6771
+ this.resetContent(this.options.ownerDocument.getElementById(uniqueId));
6772
+ }
6773
+ }.bind(this));
6774
+ }
6775
+
6672
6776
  textarea.classList.add('medium-editor-hidden');
6673
6777
  textarea.parentNode.insertBefore(
6674
6778
  div,
@@ -6678,10 +6782,10 @@ MediumEditor.extensions = {};
6678
6782
  return div;
6679
6783
  }
6680
6784
 
6681
- function initElement(element, id) {
6785
+ function initElement(element, editorId) {
6682
6786
  if (!element.getAttribute('data-medium-editor-element')) {
6683
6787
  if (element.nodeName.toLowerCase() === 'textarea') {
6684
- element = createContentEditable(element, id, this.options.ownerDocument);
6788
+ element = createContentEditable.call(this, element);
6685
6789
 
6686
6790
  // Make sure we only attach to editableInput once for <textarea> elements
6687
6791
  if (!this.instanceHandleEditableInput) {
@@ -6709,10 +6813,18 @@ MediumEditor.extensions = {};
6709
6813
  this.on(element, 'keyup', handleKeyup.bind(this));
6710
6814
  }
6711
6815
 
6816
+ var elementId = MediumEditor.util.guid();
6817
+
6712
6818
  element.setAttribute('data-medium-editor-element', true);
6819
+ element.classList.add('medium-editor-element');
6713
6820
  element.setAttribute('role', 'textbox');
6714
6821
  element.setAttribute('aria-multiline', true);
6715
- element.setAttribute('medium-editor-index', MediumEditor.util.guid());
6822
+ element.setAttribute('data-medium-editor-editor-index', editorId);
6823
+ // TODO: Merge data-medium-editor-element and medium-editor-index attributes for 6.0.0
6824
+ // medium-editor-index is not named correctly anymore and can be re-purposed to signify
6825
+ // whether the element has been initialized or not
6826
+ element.setAttribute('medium-editor-index', elementId);
6827
+ initialContent[elementId] = element.innerHTML;
6716
6828
 
6717
6829
  this.events.attachAllEventsToElement(element);
6718
6830
  }
@@ -6931,6 +7043,8 @@ MediumEditor.extensions = {};
6931
7043
  }
6932
7044
  }
6933
7045
 
7046
+ var initialContent = {};
7047
+
6934
7048
  MediumEditor.prototype = {
6935
7049
  // NOT DOCUMENTED - exposed for backwards compatability
6936
7050
  init: function (elements, options) {
@@ -6949,6 +7063,7 @@ MediumEditor.extensions = {};
6949
7063
  return;
6950
7064
  }
6951
7065
 
7066
+ addToEditors.call(this, this.options.contentWindow);
6952
7067
  this.events = new MediumEditor.Events(this);
6953
7068
  this.elements = [];
6954
7069
 
@@ -6959,7 +7074,6 @@ MediumEditor.extensions = {};
6959
7074
  }
6960
7075
 
6961
7076
  this.isActive = true;
6962
- addToEditors.call(this, this.options.contentWindow);
6963
7077
 
6964
7078
  // Call initialization helpers
6965
7079
  initExtensions.call(this);
@@ -6991,9 +7105,11 @@ MediumEditor.extensions = {};
6991
7105
  element.removeAttribute('contentEditable');
6992
7106
  element.removeAttribute('spellcheck');
6993
7107
  element.removeAttribute('data-medium-editor-element');
7108
+ element.classList.remove('medium-editor-element');
6994
7109
  element.removeAttribute('role');
6995
7110
  element.removeAttribute('aria-multiline');
6996
7111
  element.removeAttribute('medium-editor-index');
7112
+ element.removeAttribute('data-medium-editor-editor-index');
6997
7113
 
6998
7114
  // Remove any elements created for textareas
6999
7115
  if (element.getAttribute('medium-editor-textarea-id')) {
@@ -7452,11 +7568,38 @@ MediumEditor.extensions = {};
7452
7568
  }
7453
7569
  },
7454
7570
 
7571
+ getContent: function (index) {
7572
+ index = index || 0;
7573
+
7574
+ if (this.elements[index]) {
7575
+ return this.elements[index].innerHTML.trim();
7576
+ }
7577
+ return null;
7578
+ },
7579
+
7455
7580
  checkContentChanged: function (editable) {
7456
7581
  editable = editable || MediumEditor.selection.getSelectionElement(this.options.contentWindow);
7457
7582
  this.events.updateInput(editable, { target: editable, currentTarget: editable });
7458
7583
  },
7459
7584
 
7585
+ resetContent: function (element) {
7586
+ // For all elements that exist in the this.elements array, we can assume:
7587
+ // - Its initial content has been set in the initialContent object
7588
+ // - It has a medium-editor-index attribute which is the key value in the initialContent object
7589
+
7590
+ if (element) {
7591
+ var index = this.elements.indexOf(element);
7592
+ if (index !== -1) {
7593
+ this.setContent(initialContent[element.getAttribute('medium-editor-index')], index);
7594
+ }
7595
+ return;
7596
+ }
7597
+
7598
+ this.elements.forEach(function (el, idx) {
7599
+ this.setContent(initialContent[el.getAttribute('medium-editor-index')], idx);
7600
+ }, this);
7601
+ },
7602
+
7460
7603
  addElements: function (selector) {
7461
7604
  // Convert elements into an array
7462
7605
  var elements = createElementsArray(selector, this.options.ownerDocument, true);
@@ -7468,10 +7611,13 @@ MediumEditor.extensions = {};
7468
7611
 
7469
7612
  elements.forEach(function (element) {
7470
7613
  // Initialize all new elements (we check that in those functions don't worry)
7471
- element = initElement.call(this, element);
7614
+ element = initElement.call(this, element, this.id);
7472
7615
 
7473
7616
  // Add new elements to our internal elements array
7474
7617
  this.elements.push(element);
7618
+
7619
+ // Trigger event so extensions can know when an element has been added
7620
+ this.trigger('addElement', { target: element, currentTarget: element }, element);
7475
7621
  }, this);
7476
7622
  },
7477
7623
 
@@ -7494,12 +7640,23 @@ MediumEditor.extensions = {};
7494
7640
  if (element.getAttribute('medium-editor-textarea-id')) {
7495
7641
  cleanupTextareaElement(element);
7496
7642
  }
7643
+ // Trigger event so extensions can clean-up elements that are being removed
7644
+ this.trigger('removeElement', { target: element, currentTarget: element }, element);
7497
7645
  return false;
7498
7646
  }
7499
7647
  return true;
7500
7648
  }, this);
7501
7649
  }
7502
7650
  };
7651
+
7652
+ MediumEditor.getEditorFromElement = function (element) {
7653
+ var index = element.getAttribute('data-medium-editor-editor-index'),
7654
+ win = element && element.ownerDocument && (element.ownerDocument.defaultView || element.ownerDocument.parentWindow);
7655
+ if (win && win._mediumEditors && win._mediumEditors[index]) {
7656
+ return win._mediumEditors[index];
7657
+ }
7658
+ return null;
7659
+ };
7503
7660
  }());
7504
7661
 
7505
7662
  (function () {
@@ -7540,7 +7697,7 @@ MediumEditor.parseVersionString = function (release) {
7540
7697
 
7541
7698
  MediumEditor.version = MediumEditor.parseVersionString.call(this, ({
7542
7699
  // grunt-bump looks for this:
7543
- 'version': '5.18.0'
7700
+ 'version': '5.21.0'
7544
7701
  }).version);
7545
7702
 
7546
7703
  return MediumEditor;
@@ -86,13 +86,23 @@
86
86
  .medium-editor-placeholder:after {
87
87
  content: attr(data-placeholder) !important;
88
88
  font-style: italic;
89
- left: 0;
90
89
  position: absolute;
90
+ left: 0;
91
91
  top: 0;
92
92
  white-space: pre;
93
93
  padding: inherit;
94
94
  margin: inherit; }
95
95
 
96
+ .medium-editor-placeholder-relative {
97
+ position: relative; }
98
+ .medium-editor-placeholder-relative:after {
99
+ content: attr(data-placeholder) !important;
100
+ font-style: italic;
101
+ position: relative;
102
+ white-space: pre;
103
+ padding: inherit;
104
+ margin: inherit; }
105
+
96
106
  .medium-toolbar-arrow-under:after, .medium-toolbar-arrow-over:before {
97
107
  border-style: solid;
98
108
  content: '';
@@ -206,14 +216,14 @@
206
216
  content: "";
207
217
  display: table; }
208
218
 
209
- [data-medium-editor-element] {
219
+ .medium-editor-element {
210
220
  word-wrap: break-word;
211
221
  min-height: 30px; }
212
- [data-medium-editor-element] img {
222
+ .medium-editor-element img {
213
223
  max-width: 100%; }
214
- [data-medium-editor-element] sub {
224
+ .medium-editor-element sub {
215
225
  vertical-align: sub; }
216
- [data-medium-editor-element] sup {
226
+ .medium-editor-element sup {
217
227
  vertical-align: super; }
218
228
 
219
229
  .medium-editor-hidden {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrivito_editors
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.5.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scrivito
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-14 00:00:00.000000000 Z
11
+ date: 2016-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jquery-ui-rails
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 5.0.0
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: 7.0.0
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 5.0.0
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: 7.0.0
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: railties
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -50,28 +44,28 @@ dependencies:
50
44
  requirements:
51
45
  - - '='
52
46
  - !ruby/object:Gem::Version
53
- version: 1.4.3
47
+ version: 1.5.0.rc1
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
52
  - - '='
59
53
  - !ruby/object:Gem::Version
60
- version: 1.4.3
54
+ version: 1.5.0.rc1
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: scrivito_sdk
63
57
  requirement: !ruby/object:Gem::Requirement
64
58
  requirements:
65
59
  - - '='
66
60
  - !ruby/object:Gem::Version
67
- version: 1.4.3
61
+ version: 1.5.0.rc1
68
62
  type: :runtime
69
63
  prerelease: false
70
64
  version_requirements: !ruby/object:Gem::Requirement
71
65
  requirements:
72
66
  - - '='
73
67
  - !ruby/object:Gem::Version
74
- version: 1.4.3
68
+ version: 1.5.0.rc1
75
69
  - !ruby/object:Gem::Dependency
76
70
  name: coffee-rails
77
71
  requirement: !ruby/object:Gem::Requirement
@@ -172,7 +166,6 @@ files:
172
166
  - app/assets/javascripts/scrivito_editors/binary_editor.js
173
167
  - app/assets/javascripts/scrivito_editors/date_editor.js
174
168
  - app/assets/javascripts/scrivito_editors/default_editor.js
175
- - app/assets/javascripts/scrivito_editors/dependencies/jquery_ui.js.erb
176
169
  - app/assets/javascripts/scrivito_editors/deprecated_data_attrs.js
177
170
  - app/assets/javascripts/scrivito_editors/enum_editor.js
178
171
  - app/assets/javascripts/scrivito_editors/filter_context.js
@@ -183,6 +176,7 @@ files:
183
176
  - app/assets/javascripts/scrivito_editors/image_drop_editor.js
184
177
  - app/assets/javascripts/scrivito_editors/image_editor.js
185
178
  - app/assets/javascripts/scrivito_editors/link_editor.js
179
+ - app/assets/javascripts/scrivito_editors/link_target_editing.js
186
180
  - app/assets/javascripts/scrivito_editors/linklist_editor.js
187
181
  - app/assets/javascripts/scrivito_editors/medium_editor.js
188
182
  - app/assets/javascripts/scrivito_editors/multienum_editor.js
@@ -1,11 +0,0 @@
1
- <% if Jquery::Ui::Rails::VERSION < "6" %>
2
- <% require_asset "jquery-ui/autocomplete" %>
3
- <% require_asset "jquery-ui/datepicker" %>
4
- <% require_asset "jquery-ui/slider" %>
5
- <% require_asset "jquery-ui/sortable" %>
6
- <% else %>
7
- <% require_asset "jquery-ui/widgets/autocomplete" %>
8
- <% require_asset "jquery-ui/widgets/datepicker" %>
9
- <% require_asset "jquery-ui/widgets/slider" %>
10
- <% require_asset "jquery-ui/widgets/sortable" %>
11
- <% end %>