scrivito_editors 1.4.3 → 1.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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 %>