scrivito-medium-editor 0.0.3 → 0.0.5

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: ad64db0faae3ded0f08706ae44afb519450f1ab0
4
- data.tar.gz: 73e66a90390e82b6af2b0c915f75033f946e198c
3
+ metadata.gz: 28d9531d02acc90b80f75d0e403f64bdb57a7969
4
+ data.tar.gz: c112fe03485146f350b80a8d366ce9ffbe250418
5
5
  SHA512:
6
- metadata.gz: bd1908f024b7b18b899408375e3dc5f86c4f1ab3519b266eb854c24aec30c68652545ddc460fac50e649fce76edeb8f8293855802f49d4840f0af78da9e24819
7
- data.tar.gz: 9325535cce58110e731e7d9627c6573af1b5418ce58c5cdcdb6a7ef94522c44b89dd6914803ed225399114534296671d417afe8b283e4b78248ce77b50bd8725
6
+ metadata.gz: 5a3f54bab3ab21a8934414599afd0fb84244e5983ecaa34ebd4a9786f4becec1e670262e19158374668dffef4acd2b66a81635cb334e3f5b2861f0fc6faf5f6c
7
+ data.tar.gz: 2e6483f8c0b3055f35abe706c40d1dc67452252f48ecb54d6563ca8e3b7ce80171757243408a42a0f80cc537bbee64648d1ab7af9a4de492dce3736838697c67
@@ -3,31 +3,87 @@
3
3
 
4
4
  ;(function() {
5
5
 
6
- scrivito.on('content', function(content) {
7
- if (!scrivito.in_editable_view()) { return; }
6
+ var ScrivitoAnchor = MediumEditor.extensions.anchor.extend({
7
+ name: 'scrivito_anchor',
8
+ contentDefault: '<i class="scrivito_customer_icon sci_link"></i>',
8
9
 
9
- $(content).find('[data-editor=medium]').each(function() {
10
- var contenteditable = $(this);
10
+ handleClick: function (event) {
11
+ if (!this.isDisplayed()) {
12
+ var selection_range = MediumEditor.selection.getSelectionRange(this.document);
13
+ var selected_parent = MediumEditor.selection.getSelectedParentElement(selection_range);
14
+ var first_text_element = MediumEditor.util.getFirstTextNode(selected_parent);
15
+ var link_element = MediumEditor.util.getClosestTag(first_text_element, 'a');
16
+ var link_value = $(link_element).attr('href');
17
+ this.showForm(link_value);
18
+ }
19
+ return false;
20
+ },
21
+
22
+ getTemplate: function() {
23
+ return '<i class="medium-editor-toolbar-browse scrivito_customer_icon sci_collection"></i>' +
24
+ '<input type="text" class="medium-editor-toolbar-input" placeholder="'+this.placeholderText+'">' +
25
+ '<i class="medium-editor-toolbar-save scrivito_customer_icon sci_check"></i>' +
26
+ '<i class="medium-editor-toolbar-close scrivito_customer_icon sci_cross"></i>';
27
+ },
28
+
29
+ attachFormEvents: function(form) {
30
+ MediumEditor.extensions.anchor.prototype.attachFormEvents.call(this, form);
31
+
32
+ form = $(form);
33
+ var input = form.find('.medium-editor-toolbar-input');
34
+ form.find('.medium-editor-toolbar-browse').on('click', function() {
35
+ scrivito.content_browser.open({selection: input.val(), selection_mode: 'single'})
36
+ .done(function(selection) { if (selection) { input.val(selection); } });
37
+ return false;
38
+ });
39
+ },
11
40
 
12
- var config;
13
- if (contenteditable.attr('data-medium-editor')) {
14
- config = JSON.parse(contenteditable.attr('data-medium-editor'));
41
+ completeFormSave: function (opts) {
42
+ this.base.restoreSelection();
43
+ if (opts.url) {
44
+ this.execAction(this.action, opts);
15
45
  } else {
16
- config = {buttons: [
46
+ this.execAction('unlink');
47
+ }
48
+ this.base.checkSelection();
49
+ },
50
+ });
51
+
52
+ var editor_options = function(toolbar_options) {
53
+ var options = {
54
+ anchorPreview: false,
55
+ extensions: {scrivito_anchor: new ScrivitoAnchor()},
56
+ toolbar: {
57
+ buttons: [
58
+ 'h1',
59
+ 'h2',
60
+ 'h3',
17
61
  'bold',
18
62
  'italic',
63
+ 'scrivito_anchor',
19
64
  'underline',
20
- 'header1',
21
- 'header2',
65
+ 'orderedlist',
22
66
  'unorderedlist',
23
- 'orderedlist'
24
- ]};
67
+ 'indent',
68
+ 'outdent',
69
+ 'justifyLeft',
70
+ 'justifyCenter',
71
+ 'justifyFull'
72
+ ]
25
73
  }
74
+ };
75
+ if (toolbar_options) { options.toolbar = toolbar_options; }
76
+ return options;
77
+ };
26
78
 
27
- new MediumEditor(contenteditable, config);
79
+ scrivito.on('content', function(content) {
80
+ if (!scrivito.in_editable_view()) { return; }
28
81
 
29
- contenteditable.on('input', function() {
30
- contenteditable.scrivito('save', $(this).html());
82
+ $(content).find('[data-editor=medium]').each(function() {
83
+ var dom_element = $(this);
84
+ new MediumEditor(dom_element, editor_options(dom_element.data('medium-editor-toolbar')));
85
+ dom_element.on('input', function() {
86
+ dom_element.scrivito('save', dom_element.html());
31
87
  });
32
88
  });
33
89
  });
@@ -3,5 +3,18 @@
3
3
  *= require medium-editor-theme-flat
4
4
  *= require_self
5
5
  */
6
-
6
+ .medium-toolbar-arrow-under::after { top: auto;}
7
+ .medium-editor-toolbar { z-index: 11112; margin:0 10px; background:rgba(67, 148, 57, 0.9);
8
+ border-radius:4px;}
9
+ .medium-editor-toolbar li button { height:40px; min-width:40px; padding:10px;
10
+ border:none; margin:1px; background:rgba(0,0,0,.1);
11
+ }
7
12
  .medium-editor-toolbar li button * { color: inherit; }
13
+ .medium-editor-toolbar li button .scrivito_customer_icon { font-size:18px;}
14
+ .medium-editor-toolbar-form .scrivito_customer_icon { font-size:18px;
15
+ min-width:40px; height:40px; line-height: 40px!important;
16
+ display:inline-block; text-align:center;
17
+ color: #fff; margin: 1px; background:rgba(0,0,0,.1);
18
+ }
19
+ .medium-editor-toolbar-form .scrivito_customer_icon:hover {background:rgba(0,0,0,.3);}
20
+ .medium-editor-toolbar-form .medium-editor-toolbar-input {margin: 1px;height:40px; background:rgba(0,0,0,.3);}
@@ -1,3 +1,3 @@
1
1
  module ScrivitoMediumEditor
2
- VERSION = '0.0.3'.freeze
2
+ VERSION = '0.0.5'.freeze
3
3
  end
@@ -1905,7 +1905,7 @@ var Selection;
1905
1905
  }
1906
1906
  }
1907
1907
 
1908
- if (selectionState.emptyBlocksIndex && selectionState.end === nextCharIndex) {
1908
+ if (selectionState.emptyBlocksIndex) {
1909
1909
  var targetNode = Util.getTopBlockContainer(range.startContainer),
1910
1910
  index = 0;
1911
1911
  // Skip over empty blocks until we hit the block we want the selection to be in
@@ -1921,7 +1921,6 @@ var Selection;
1921
1921
  // We're selecting a high-level block node, so make sure the cursor gets moved into the deepest
1922
1922
  // element at the beginning of the block
1923
1923
  range.setStart(Util.getFirstSelectableLeafNode(targetNode), 0);
1924
- range.collapse(true);
1925
1924
  }
1926
1925
 
1927
1926
  // If the selection is right at the ending edge of a link, put it outside the anchor tag instead of inside.
@@ -2541,6 +2540,9 @@ var Events;
2541
2540
  },
2542
2541
 
2543
2542
  updateInput: function (target, eventObj) {
2543
+ if (!this.contentCache) {
2544
+ return;
2545
+ }
2544
2546
  // An event triggered which signifies that the user may have changed someting
2545
2547
  // Look in our cache of input for the contenteditables to see if something changed
2546
2548
  var index = target.getAttribute('medium-editor-index');
@@ -3066,10 +3068,11 @@ var AnchorForm;
3066
3068
  event.preventDefault();
3067
3069
  event.stopPropagation();
3068
3070
 
3069
- var selectedParentElement = Selection.getSelectedParentElement(Selection.getSelectionRange(this.document)),
3070
- firstTextNode = Util.getFirstTextNode(selectedParentElement);
3071
+ var range = Selection.getSelectionRange(this.document);
3071
3072
 
3072
- if (Util.getClosestTag(firstTextNode, 'a')) {
3073
+ if (range.startContainer.nodeName.toLowerCase() === 'a' ||
3074
+ range.endContainer.nodeName.toLowerCase() === 'a' ||
3075
+ Util.getClosestTag(Selection.getSelectedParentElement(range), 'a')) {
3073
3076
  return this.execAction('unlink');
3074
3077
  }
3075
3078
 
@@ -3117,10 +3120,12 @@ var AnchorForm;
3117
3120
  // fixme: ideally, this targetCheckboxText would be a formLabel too,
3118
3121
  // figure out how to deprecate? also consider `fa-` icon default implcations.
3119
3122
  template.push(
3123
+ '<div class="medium-editor-toolbar-form-row">',
3120
3124
  '<input type="checkbox" class="medium-editor-toolbar-anchor-target">',
3121
3125
  '<label>',
3122
3126
  this.targetCheckboxText,
3123
- '</label>'
3127
+ '</label>',
3128
+ '</div>'
3124
3129
  );
3125
3130
  }
3126
3131
 
@@ -3128,10 +3133,12 @@ var AnchorForm;
3128
3133
  // fixme: expose this `Button` text as a formLabel property, too
3129
3134
  // and provide similar access to a `fa-` icon default.
3130
3135
  template.push(
3136
+ '<div class="medium-editor-toolbar-form-row">',
3131
3137
  '<input type="checkbox" class="medium-editor-toolbar-anchor-button">',
3132
3138
  '<label>',
3133
3139
  this.customClassOptionText,
3134
- '</label>'
3140
+ '</label>',
3141
+ '</div>'
3135
3142
  );
3136
3143
  }
3137
3144
 
@@ -3149,16 +3156,40 @@ var AnchorForm;
3149
3156
  this.getInput().value = '';
3150
3157
  },
3151
3158
 
3152
- showForm: function (linkValue) {
3153
- var input = this.getInput();
3159
+ showForm: function (opts) {
3160
+ var input = this.getInput(),
3161
+ targetCheckbox = this.getAnchorTargetCheckbox(),
3162
+ buttonCheckbox = this.getAnchorButtonCheckbox();
3163
+
3164
+ opts = opts || { url: '' };
3165
+ // TODO: This is for backwards compatability
3166
+ // We don't need to support the 'string' argument in 6.0.0
3167
+ if (typeof opts === 'string') {
3168
+ opts = {
3169
+ url: opts
3170
+ };
3171
+ }
3154
3172
 
3155
3173
  this.base.saveSelection();
3156
3174
  this.hideToolbarDefaultActions();
3157
3175
  this.getForm().style.display = 'block';
3158
3176
  this.setToolbarPosition();
3159
3177
 
3160
- input.value = linkValue || '';
3178
+ input.value = opts.url;
3161
3179
  input.focus();
3180
+
3181
+ // If we have a target checkbox, we want it to be checked/unchecked
3182
+ // based on whether the existing link has target=_blank
3183
+ if (targetCheckbox) {
3184
+ targetCheckbox.checked = opts.target === '_blank';
3185
+ }
3186
+
3187
+ // If we have a custom class checkbox, we want it to be checked/unchecked
3188
+ // based on whether an existing link already has the class
3189
+ if (buttonCheckbox) {
3190
+ var classList = opts.buttonClass ? opts.buttonClass.split(' ') : [];
3191
+ buttonCheckbox.checked = (classList.indexOf(this.customClassOption) !== -1);
3192
+ }
3162
3193
  },
3163
3194
 
3164
3195
  // Called by core when tearing down medium-editor (destroy)
@@ -3178,8 +3209,8 @@ var AnchorForm;
3178
3209
 
3179
3210
  getFormOpts: function () {
3180
3211
  // no notion of private functions? wanted `_getFormOpts`
3181
- var targetCheckbox = this.getForm().querySelector('.medium-editor-toolbar-anchor-target'),
3182
- buttonCheckbox = this.getForm().querySelector('.medium-editor-toolbar-anchor-button'),
3212
+ var targetCheckbox = this.getAnchorTargetCheckbox(),
3213
+ buttonCheckbox = this.getAnchorButtonCheckbox(),
3183
3214
  opts = {
3184
3215
  url: this.getInput().value
3185
3216
  };
@@ -3258,6 +3289,14 @@ var AnchorForm;
3258
3289
  return this.getForm().querySelector('input.medium-editor-toolbar-input');
3259
3290
  },
3260
3291
 
3292
+ getAnchorTargetCheckbox: function () {
3293
+ return this.getForm().querySelector('.medium-editor-toolbar-anchor-target');
3294
+ },
3295
+
3296
+ getAnchorButtonCheckbox: function () {
3297
+ return this.getForm().querySelector('.medium-editor-toolbar-anchor-button');
3298
+ },
3299
+
3261
3300
  handleTextboxKeyup: function (event) {
3262
3301
  // For ENTER -> create the anchor
3263
3302
  if (event.keyCode === Util.keyCode.ENTER) {
@@ -3427,7 +3466,12 @@ var AnchorPreview;
3427
3466
  // We may actually be displaying the anchor form, which should be controlled by delay
3428
3467
  this.base.delay(function () {
3429
3468
  if (activeAnchor) {
3430
- anchorExtension.showForm(activeAnchor.attributes.href.value);
3469
+ var opts = {
3470
+ url: activeAnchor.attributes.href.value,
3471
+ target: activeAnchor.getAttribute('target'),
3472
+ buttonClass: activeAnchor.getAttribute('class')
3473
+ };
3474
+ anchorExtension.showForm(opts);
3431
3475
  activeAnchor = null;
3432
3476
  }
3433
3477
  }.bind(this));
@@ -3451,7 +3495,7 @@ var AnchorPreview;
3451
3495
 
3452
3496
  // Detect empty href attributes
3453
3497
  // The browser will make href="" or href="#top"
3454
- // into absolute urls when accessed as event.targed.href, so check the html
3498
+ // into absolute urls when accessed as event.target.href, so check the html
3455
3499
  if (!/href=["']\S+["']/.test(target.outerHTML) || /href=["']#\S+["']/.test(target.outerHTML)) {
3456
3500
  return true;
3457
3501
  }
@@ -3918,7 +3962,7 @@ var KeyboardCommands;
3918
3962
  event.preventDefault();
3919
3963
  event.stopPropagation();
3920
3964
 
3921
- // command can be false so the shortcurt is just disabled
3965
+ // command can be false so the shortcut is just disabled
3922
3966
  if (false !== data.command) {
3923
3967
  this.execAction(data.command);
3924
3968
  }
@@ -4245,8 +4289,7 @@ var PasteHandler;
4245
4289
  },
4246
4290
 
4247
4291
  cleanPaste: function (text) {
4248
- var i, elList, workEl,
4249
- el = Selection.getSelectionElement(this.window),
4292
+ var i, elList,
4250
4293
  multiline = /<p|<br|<div/.test(text),
4251
4294
  replacements = createReplacements().concat(this.cleanReplacements || []);
4252
4295
 
@@ -4262,31 +4305,6 @@ var PasteHandler;
4262
4305
  elList = text.split('<br><br>');
4263
4306
 
4264
4307
  this.pasteHTML('<p>' + elList.join('</p><p>') + '</p>');
4265
-
4266
- try {
4267
- this.document.execCommand('insertText', false, '\n');
4268
- } catch (ignore) { }
4269
-
4270
- // block element cleanup
4271
- elList = el.querySelectorAll('a,p,div,br');
4272
- for (i = 0; i < elList.length; i += 1) {
4273
- workEl = elList[i];
4274
-
4275
- // Microsoft Word replaces some spaces with newlines.
4276
- // While newlines between block elements are meaningless, newlines within
4277
- // elements are sometimes actually spaces.
4278
- workEl.innerHTML = workEl.innerHTML.replace(/\n/gi, ' ');
4279
-
4280
- switch (workEl.nodeName.toLowerCase()) {
4281
- case 'p':
4282
- case 'div':
4283
- this.filterCommonBlocks(workEl);
4284
- break;
4285
- case 'br':
4286
- this.filterLineBreak(workEl);
4287
- break;
4288
- }
4289
- }
4290
4308
  },
4291
4309
 
4292
4310
  pasteHTML: function (html, options) {
@@ -4305,7 +4323,6 @@ var PasteHandler;
4305
4323
  this.cleanupSpans(fragmentBody);
4306
4324
 
4307
4325
  elList = fragmentBody.querySelectorAll('*');
4308
-
4309
4326
  for (i = 0; i < elList.length; i += 1) {
4310
4327
  workEl = elList[i];
4311
4328
 
@@ -4317,6 +4334,27 @@ var PasteHandler;
4317
4334
  Util.cleanupTags(workEl, options.cleanTags);
4318
4335
  }
4319
4336
 
4337
+ // block element cleanup
4338
+ elList = fragmentBody.querySelectorAll('a,p,div,br');
4339
+ for (i = 0; i < elList.length; i += 1) {
4340
+ workEl = elList[i];
4341
+
4342
+ // Microsoft Word replaces some spaces with newlines.
4343
+ // While newlines between block elements are meaningless, newlines within
4344
+ // elements are sometimes actually spaces.
4345
+ workEl.innerHTML = workEl.innerHTML.replace(/\n/gi, ' ');
4346
+
4347
+ switch (workEl.nodeName.toLowerCase()) {
4348
+ case 'p':
4349
+ case 'div':
4350
+ this.filterCommonBlocks(workEl);
4351
+ break;
4352
+ case 'br':
4353
+ this.filterLineBreak(workEl);
4354
+ break;
4355
+ }
4356
+ }
4357
+
4320
4358
  Util.insertHTMLCommand(this.document, fragmentBody.innerHTML.replace(/&nbsp;/g, ' '));
4321
4359
  },
4322
4360
 
@@ -4863,7 +4901,7 @@ var Toolbar;
4863
4901
  offset = offset + 1;
4864
4902
  }
4865
4903
  selectionRange = Selection.select(this.document, adjacentNode, offset,
4866
- selectionRange.endContainer, selectionRange.offset);
4904
+ selectionRange.endContainer, selectionRange.endOffset);
4867
4905
  }
4868
4906
  }
4869
4907
  },
@@ -5177,8 +5215,7 @@ var ImageDragging;
5177
5215
 
5178
5216
  var extensionDefaults;
5179
5217
  (function () {
5180
- // for now this is empty because nothing interally uses an Extension default.
5181
- // as they are converted, provide them here.
5218
+
5182
5219
  extensionDefaults = {
5183
5220
  button: Button,
5184
5221
  form: FormExtension,
@@ -5488,28 +5525,23 @@ function MediumEditor(elements, options) {
5488
5525
  function createContentEditable(textarea, id) {
5489
5526
  var div = this.options.ownerDocument.createElement('div'),
5490
5527
  uniqueId = 'medium-editor-' + Date.now() + '-' + id,
5491
- attributesToClone = [
5492
- 'data-disable-editing',
5493
- 'data-disable-toolbar',
5494
- 'data-placeholder',
5495
- 'data-disable-return',
5496
- 'data-disable-double-return',
5497
- 'data-disable-preview',
5498
- 'spellcheck'
5499
- ];
5528
+ atts = textarea.attributes;
5500
5529
 
5501
5530
  div.className = textarea.className;
5502
5531
  div.id = uniqueId;
5503
5532
  div.innerHTML = textarea.value;
5504
- div.setAttribute('medium-editor-textarea-id', id);
5505
- attributesToClone.forEach(function (attr) {
5506
- if (textarea.hasAttribute(attr)) {
5507
- div.setAttribute(attr, textarea.getAttribute(attr));
5533
+
5534
+ textarea.setAttribute('medium-editor-textarea-id', id);
5535
+
5536
+ // re-create all attributes from the textearea to the new created div
5537
+ for (var i = 0, n = atts.length; i < n; i++) {
5538
+ // do not re-create existing attributes
5539
+ if (!div.hasAttribute(atts[i].nodeName)) {
5540
+ div.setAttribute(atts[i].nodeName, atts[i].nodeValue);
5508
5541
  }
5509
- });
5542
+ }
5510
5543
 
5511
5544
  textarea.classList.add('medium-editor-hidden');
5512
- textarea.setAttribute('medium-editor-textarea-id', id);
5513
5545
  textarea.parentNode.insertBefore(
5514
5546
  div,
5515
5547
  textarea
@@ -5613,7 +5645,7 @@ function MediumEditor(elements, options) {
5613
5645
  // Built-in extensions
5614
5646
  var builtIns = {
5615
5647
  paste: true,
5616
- anchorPreview: isAnchorPreviewEnabled.call(this),
5648
+ 'anchor-preview': isAnchorPreviewEnabled.call(this),
5617
5649
  autoLink: isAutoLinkEnabled.call(this),
5618
5650
  keyboardCommands: isKeyboardCommandsEnabled.call(this),
5619
5651
  placeholder: isPlaceholderEnabled.call(this)
@@ -5905,7 +5937,7 @@ function MediumEditor(elements, options) {
5905
5937
  merged = Util.extend({}, this.options.anchor, opts);
5906
5938
  extension = new MediumEditor.extensions.anchor(merged);
5907
5939
  break;
5908
- case 'anchorPreview':
5940
+ case 'anchor-preview':
5909
5941
  extension = new MediumEditor.extensions.anchorPreview(this.options.anchorPreview);
5910
5942
  break;
5911
5943
  case 'autoLink':
@@ -6097,8 +6129,7 @@ function MediumEditor(elements, options) {
6097
6129
  },
6098
6130
 
6099
6131
  createLink: function (opts) {
6100
- var customEvent,
6101
- i;
6132
+ var customEvent, i;
6102
6133
 
6103
6134
  if (opts.url && opts.url.trim().length > 0) {
6104
6135
  var currentSelection = this.options.contentWindow.getSelection();
@@ -6108,17 +6139,22 @@ function MediumEditor(elements, options) {
6108
6139
  endContainerParentElement,
6109
6140
  textNodes;
6110
6141
 
6111
- startContainerParentElement = Util.getClosestBlockContainer(
6112
- currentSelection.getRangeAt(0).startContainer);
6113
- endContainerParentElement = Util.getClosestBlockContainer(
6114
- currentSelection.getRangeAt(0).endContainer);
6142
+ startContainerParentElement = Util.getClosestBlockContainer(currentSelection.getRangeAt(0).startContainer);
6143
+ endContainerParentElement = Util.getClosestBlockContainer(currentSelection.getRangeAt(0).endContainer);
6115
6144
 
6116
6145
  if (startContainerParentElement === endContainerParentElement) {
6117
6146
  var currentEditor = Selection.getSelectionElement(this.options.contentWindow),
6118
6147
  parentElement = (startContainerParentElement || currentEditor),
6119
6148
  fragment = this.options.ownerDocument.createDocumentFragment();
6149
+
6150
+ // since we are going to create a link from an extracted text,
6151
+ // be sure that if we are updating a link, we won't let an empty link behind (see #754)
6152
+ // (Workaroung for Chrome)
6153
+ this.execAction('unlink');
6154
+
6120
6155
  exportedSelection = this.exportSelection();
6121
6156
  fragment.appendChild(parentElement.cloneNode(true));
6157
+
6122
6158
  if (currentEditor === parentElement) {
6123
6159
  // We have to avoid the editor itself being wiped out when it's the only block element,
6124
6160
  // as our reference inside this.elements gets detached from the page when insertHTML runs.
@@ -6131,37 +6167,50 @@ function MediumEditor(elements, options) {
6131
6167
  // In WebKit:
6132
6168
  // an invented <br /> tag at the end in the same situation
6133
6169
 
6134
- Selection.select(this.options.ownerDocument,
6135
- parentElement.firstChild, 0,
6136
- parentElement.lastChild, parentElement.lastChild.nodeType === 3 ?
6137
- parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length);
6170
+ Selection.select(
6171
+ this.options.ownerDocument,
6172
+ parentElement.firstChild,
6173
+ 0,
6174
+ parentElement.lastChild,
6175
+ parentElement.lastChild.nodeType === 3 ?
6176
+ parentElement.lastChild.nodeValue.length : parentElement.lastChild.childNodes.length
6177
+ );
6138
6178
  } else {
6139
- Selection.select(this.options.ownerDocument,
6140
- parentElement, 0,
6141
- parentElement, parentElement.childNodes.length);
6179
+ Selection.select(
6180
+ this.options.ownerDocument,
6181
+ parentElement,
6182
+ 0,
6183
+ parentElement,
6184
+ parentElement.childNodes.length
6185
+ );
6142
6186
  }
6187
+
6143
6188
  var modifiedExportedSelection = this.exportSelection();
6144
6189
 
6145
- textNodes = Util.findOrCreateMatchingTextNodes(this.options.ownerDocument,
6146
- fragment,
6147
- {
6148
- start: exportedSelection.start - modifiedExportedSelection.start,
6149
- end: exportedSelection.end - modifiedExportedSelection.start,
6150
- editableElementIndex: exportedSelection.editableElementIndex
6151
- });
6190
+ textNodes = Util.findOrCreateMatchingTextNodes(
6191
+ this.options.ownerDocument,
6192
+ fragment,
6193
+ {
6194
+ start: exportedSelection.start - modifiedExportedSelection.start,
6195
+ end: exportedSelection.end - modifiedExportedSelection.start,
6196
+ editableElementIndex: exportedSelection.editableElementIndex
6197
+ }
6198
+ );
6199
+
6152
6200
  // Creates the link in the document fragment
6153
6201
  Util.createLink(this.options.ownerDocument, textNodes, opts.url.trim());
6154
6202
  // Chrome trims the leading whitespaces when inserting HTML, which messes up restoring the selection.
6155
6203
  var leadingWhitespacesCount = (fragment.firstChild.innerHTML.match(/^\s+/) || [''])[0].length;
6156
6204
  // Now move the created link back into the original document in a way to preserve undo/redo history
6157
- Util.insertHTMLCommand(this.options.ownerDocument,
6158
- fragment.firstChild.innerHTML.replace(/^\s+/, ''));
6205
+ Util.insertHTMLCommand(this.options.ownerDocument, fragment.firstChild.innerHTML.replace(/^\s+/, ''));
6159
6206
  exportedSelection.start -= leadingWhitespacesCount;
6160
6207
  exportedSelection.end -= leadingWhitespacesCount;
6208
+
6161
6209
  this.importSelection(exportedSelection);
6162
6210
  } else {
6163
6211
  this.options.ownerDocument.execCommand('createLink', false, opts.url);
6164
6212
  }
6213
+
6165
6214
  if (this.options.targetBlank || opts.target === '_blank') {
6166
6215
  Util.setTargetBlank(Selection.getSelectionStart(this.options.ownerDocument), opts.url);
6167
6216
  }
@@ -6187,6 +6236,16 @@ function MediumEditor(elements, options) {
6187
6236
 
6188
6237
  pasteHTML: function (html, options) {
6189
6238
  this.getExtensionByName('paste').pasteHTML(html, options);
6239
+ },
6240
+
6241
+ setContent: function (html, index) {
6242
+ index = index || 0;
6243
+
6244
+ if (this.elements[index]) {
6245
+ var target = this.elements[index];
6246
+ target.innerHTML = html;
6247
+ this.events.updateInput(target, { target: target, currentTarget: target });
6248
+ }
6190
6249
  }
6191
6250
  };
6192
6251
  }());
@@ -6208,7 +6267,7 @@ MediumEditor.parseVersionString = function (release) {
6208
6267
 
6209
6268
  MediumEditor.version = MediumEditor.parseVersionString.call(this, ({
6210
6269
  // grunt-bump looks for this:
6211
- 'version': '5.4.0'
6270
+ 'version': '5.5.3'
6212
6271
  }).version);
6213
6272
 
6214
6273
  return MediumEditor;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scrivito-medium-editor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scrivito
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-27 00:00:00.000000000 Z
11
+ date: 2015-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler