scrivito-medium-editor 0.0.3 → 0.0.5
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:
|
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
|