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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28d9531d02acc90b80f75d0e403f64bdb57a7969
|
4
|
+
data.tar.gz: c112fe03485146f350b80a8d366ce9ffbe250418
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a3f54bab3ab21a8934414599afd0fb84244e5983ecaa34ebd4a9786f4becec1e670262e19158374668dffef4acd2b66a81635cb334e3f5b2861f0fc6faf5f6c
|
7
|
+
data.tar.gz: 2e6483f8c0b3055f35abe706c40d1dc67452252f48ecb54d6563ca8e3b7ce80171757243408a42a0f80cc537bbee64648d1ab7af9a4de492dce3736838697c67
|
@@ -3,31 +3,87 @@
|
|
3
3
|
|
4
4
|
;(function() {
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
var ScrivitoAnchor = MediumEditor.extensions.anchor.extend({
|
7
|
+
name: 'scrivito_anchor',
|
8
|
+
contentDefault: '<i class="scrivito_customer_icon sci_link"></i>',
|
8
9
|
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
41
|
+
completeFormSave: function (opts) {
|
42
|
+
this.base.restoreSelection();
|
43
|
+
if (opts.url) {
|
44
|
+
this.execAction(this.action, opts);
|
15
45
|
} else {
|
16
|
-
|
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
|
-
'
|
21
|
-
'header2',
|
65
|
+
'orderedlist',
|
22
66
|
'unorderedlist',
|
23
|
-
'
|
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
|
-
|
79
|
+
scrivito.on('content', function(content) {
|
80
|
+
if (!scrivito.in_editable_view()) { return; }
|
28
81
|
|
29
|
-
|
30
|
-
|
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);}
|
@@ -1905,7 +1905,7 @@ var Selection;
|
|
1905
1905
|
}
|
1906
1906
|
}
|
1907
1907
|
|
1908
|
-
if (selectionState.emptyBlocksIndex
|
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
|
3070
|
-
firstTextNode = Util.getFirstTextNode(selectedParentElement);
|
3071
|
+
var range = Selection.getSelectionRange(this.document);
|
3071
3072
|
|
3072
|
-
if (
|
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 (
|
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 =
|
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.
|
3182
|
-
buttonCheckbox = this.
|
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
|
-
|
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.
|
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
|
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,
|
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(/ /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.
|
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
|
-
|
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
|
-
|
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
|
-
|
5505
|
-
|
5506
|
-
|
5507
|
-
|
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
|
-
|
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 '
|
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
|
-
|
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(
|
6135
|
-
|
6136
|
-
parentElement.
|
6137
|
-
|
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(
|
6140
|
-
|
6141
|
-
parentElement,
|
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(
|
6146
|
-
|
6147
|
-
|
6148
|
-
|
6149
|
-
|
6150
|
-
|
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.
|
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.
|
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-
|
11
|
+
date: 2015-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|