medium-editor-rails 2.3.2 → 2.3.3
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 +4 -4
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/lib/medium-editor-rails/version.rb +2 -2
- data/vendor/assets/javascripts/medium-editor.js +85 -33
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fbc5be5c8889b94516fe3d384de117a143a8f64
|
4
|
+
data.tar.gz: baa9b17e491b54932b130529bdc9c93a15bbd211
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5731769e8b3c8bcf932c2bf7f5a06c9a1e9c6e1fec3ae28e301e19c701623f7661ea3353cf6212c49cc3270a5ffa0dbc17ec7303af013ea0b32cf62a0f1e67ac
|
7
|
+
data.tar.gz: 4c75128963d9cb4cbcfadf3de3023576e5759f8b03e14e979fd58c5b01aecb3069722f75316125206e5ae4fdcf2945d4aacf185d4d2a38f0507a1fb1cbf9528a
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ This gem integrates [Medium Editor](https://github.com/yabwe/medium-editor) with
|
|
8
8
|
|
9
9
|
## Version
|
10
10
|
|
11
|
-
The latest version of Medium Editor bundled by this gem is [5.
|
11
|
+
The latest version of Medium Editor bundled by this gem is [5.23.2](https://github.com/yabwe/medium-editor/releases)
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
data/Rakefile
CHANGED
@@ -544,6 +544,9 @@ MediumEditor.extensions = {};
|
|
544
544
|
Util.moveTextRangeIntoElement(textNodes[0], textNodes[textNodes.length - 1], anchor);
|
545
545
|
anchor.setAttribute('href', href);
|
546
546
|
if (target) {
|
547
|
+
if (target === '_blank') {
|
548
|
+
anchor.setAttribute('rel', 'noopener noreferrer');
|
549
|
+
}
|
547
550
|
anchor.setAttribute('target', target);
|
548
551
|
}
|
549
552
|
return anchor;
|
@@ -629,11 +632,10 @@ MediumEditor.extensions = {};
|
|
629
632
|
splitEndNodeIfNeeded: function (currentNode, newNode, matchEndIndex, currentTextIndex) {
|
630
633
|
var textIndexOfEndOfFarthestNode,
|
631
634
|
endSplitPoint;
|
632
|
-
textIndexOfEndOfFarthestNode = currentTextIndex +
|
633
|
-
(newNode ?
|
634
|
-
|
635
|
-
|
636
|
-
(textIndexOfEndOfFarthestNode + 1 - matchEndIndex);
|
635
|
+
textIndexOfEndOfFarthestNode = currentTextIndex + currentNode.nodeValue.length +
|
636
|
+
(newNode ? newNode.nodeValue.length : 0) - 1;
|
637
|
+
endSplitPoint = matchEndIndex - currentTextIndex -
|
638
|
+
(newNode ? currentNode.nodeValue.length : 0);
|
637
639
|
if (textIndexOfEndOfFarthestNode >= matchEndIndex &&
|
638
640
|
currentTextIndex !== textIndexOfEndOfFarthestNode &&
|
639
641
|
endSplitPoint !== 0) {
|
@@ -990,12 +992,14 @@ MediumEditor.extensions = {};
|
|
990
992
|
var i, url = anchorUrl || false;
|
991
993
|
if (el.nodeName.toLowerCase() === 'a') {
|
992
994
|
el.target = '_blank';
|
995
|
+
el.rel = 'noopener noreferrer';
|
993
996
|
} else {
|
994
997
|
el = el.getElementsByTagName('a');
|
995
998
|
|
996
999
|
for (i = 0; i < el.length; i += 1) {
|
997
1000
|
if (false === url || url === el[i].attributes.href.value) {
|
998
1001
|
el[i].target = '_blank';
|
1002
|
+
el[i].rel = 'noopener noreferrer';
|
999
1003
|
}
|
1000
1004
|
}
|
1001
1005
|
}
|
@@ -1009,17 +1013,24 @@ MediumEditor.extensions = {};
|
|
1009
1013
|
var i;
|
1010
1014
|
if (el.nodeName.toLowerCase() === 'a') {
|
1011
1015
|
el.removeAttribute('target');
|
1016
|
+
el.removeAttribute('rel');
|
1012
1017
|
} else {
|
1013
1018
|
el = el.getElementsByTagName('a');
|
1014
1019
|
|
1015
1020
|
for (i = 0; i < el.length; i += 1) {
|
1016
1021
|
if (anchorUrl === el[i].attributes.href.value) {
|
1017
1022
|
el[i].removeAttribute('target');
|
1023
|
+
el[i].removeAttribute('rel');
|
1018
1024
|
}
|
1019
1025
|
}
|
1020
1026
|
}
|
1021
1027
|
},
|
1022
1028
|
|
1029
|
+
/*
|
1030
|
+
* this function adds one or several classes on an a element.
|
1031
|
+
* if el parameter is not an a, it will look for a children of el.
|
1032
|
+
* if no a children are found, it will look for the a parent.
|
1033
|
+
*/
|
1023
1034
|
addClassToAnchors: function (el, buttonClass) {
|
1024
1035
|
var classes = buttonClass.split(' '),
|
1025
1036
|
i,
|
@@ -1029,7 +1040,13 @@ MediumEditor.extensions = {};
|
|
1029
1040
|
el.classList.add(classes[j]);
|
1030
1041
|
}
|
1031
1042
|
} else {
|
1032
|
-
|
1043
|
+
var aChildren = el.getElementsByTagName('a');
|
1044
|
+
if (aChildren.length === 0) {
|
1045
|
+
var parentAnchor = Util.getClosestTag(el, 'a');
|
1046
|
+
el = parentAnchor ? [parentAnchor] : [];
|
1047
|
+
} else {
|
1048
|
+
el = aChildren;
|
1049
|
+
}
|
1033
1050
|
for (i = 0; i < el.length; i += 1) {
|
1034
1051
|
for (j = 0; j < classes.length; j += 1) {
|
1035
1052
|
el[i].classList.add(classes[j]);
|
@@ -2485,15 +2502,17 @@ MediumEditor.extensions = {};
|
|
2485
2502
|
win = this.base.options.contentWindow,
|
2486
2503
|
doc = this.base.options.ownerDocument;
|
2487
2504
|
|
2488
|
-
|
2505
|
+
if (targets !== null) {
|
2506
|
+
targets = MediumEditor.util.isElement(targets) || [win, doc].indexOf(targets) > -1 ? [targets] : targets;
|
2489
2507
|
|
2490
|
-
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2508
|
+
Array.prototype.forEach.call(targets, function (target) {
|
2509
|
+
index = this.indexOfListener(target, event, listener, useCapture);
|
2510
|
+
if (index !== -1) {
|
2511
|
+
e = this.events.splice(index, 1)[0];
|
2512
|
+
e[0].removeEventListener(e[1], e[2], e[3]);
|
2513
|
+
}
|
2514
|
+
}.bind(this));
|
2515
|
+
}
|
2497
2516
|
},
|
2498
2517
|
|
2499
2518
|
indexOfListener: function (target, event, listener, useCapture) {
|
@@ -3350,6 +3369,14 @@ MediumEditor.extensions = {};
|
|
3350
3369
|
contentDefault: '<b>image</b>',
|
3351
3370
|
contentFA: '<i class="fa fa-picture-o"></i>'
|
3352
3371
|
},
|
3372
|
+
'html': {
|
3373
|
+
name: 'html',
|
3374
|
+
action: 'html',
|
3375
|
+
aria: 'evaluate html',
|
3376
|
+
tagNames: ['iframe', 'object'],
|
3377
|
+
contentDefault: '<b>html</b>',
|
3378
|
+
contentFA: '<i class="fa fa-code"></i>'
|
3379
|
+
},
|
3353
3380
|
'orderedlist': {
|
3354
3381
|
name: 'orderedlist',
|
3355
3382
|
action: 'insertorderedlist',
|
@@ -3511,6 +3538,7 @@ MediumEditor.extensions = {};
|
|
3511
3538
|
};
|
3512
3539
|
|
3513
3540
|
})();
|
3541
|
+
|
3514
3542
|
(function () {
|
3515
3543
|
'use strict';
|
3516
3544
|
|
@@ -3743,8 +3771,8 @@ MediumEditor.extensions = {};
|
|
3743
3771
|
// figure out how to deprecate? also consider `fa-` icon default implcations.
|
3744
3772
|
template.push(
|
3745
3773
|
'<div class="medium-editor-toolbar-form-row">',
|
3746
|
-
'<input type="checkbox" class="medium-editor-toolbar-anchor-target">',
|
3747
|
-
'<label>',
|
3774
|
+
'<input type="checkbox" class="medium-editor-toolbar-anchor-target" id="medium-editor-toolbar-anchor-target-field-' + this.getEditorId() + '">',
|
3775
|
+
'<label for="medium-editor-toolbar-anchor-target-field-' + this.getEditorId() + '">',
|
3748
3776
|
this.targetCheckboxText,
|
3749
3777
|
'</label>',
|
3750
3778
|
'</div>'
|
@@ -3890,22 +3918,35 @@ MediumEditor.extensions = {};
|
|
3890
3918
|
// Matches common external protocols "mailto:" "tel:" "maps:"
|
3891
3919
|
// Matches relative hash link, begins with "#"
|
3892
3920
|
var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^\#/i,
|
3921
|
+
hasScheme = urlSchemeRegex.test(value),
|
3922
|
+
scheme = '',
|
3893
3923
|
// telRegex is a regex for checking if the string is a telephone number
|
3894
3924
|
telRegex = /^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/,
|
3895
|
-
|
3896
|
-
path =
|
3897
|
-
query =
|
3925
|
+
urlParts = value.match(/^(.*?)(?:\?(.*?))?(?:#(.*))?$/),
|
3926
|
+
path = urlParts[1],
|
3927
|
+
query = urlParts[2],
|
3928
|
+
fragment = urlParts[3];
|
3898
3929
|
|
3899
3930
|
if (telRegex.test(value)) {
|
3900
3931
|
return 'tel:' + value;
|
3901
|
-
} else {
|
3902
|
-
// Check for URL scheme and default to http:// if none found
|
3903
|
-
return (urlSchemeRegex.test(value) ? '' : 'http://') +
|
3904
|
-
// Ensure path is encoded
|
3905
|
-
this.ensureEncodedUri(path) +
|
3906
|
-
// Ensure query is encoded
|
3907
|
-
(query === undefined ? '' : '?' + this.ensureEncodedQuery(query));
|
3908
3932
|
}
|
3933
|
+
|
3934
|
+
if (!hasScheme) {
|
3935
|
+
var host = path.split('/')[0];
|
3936
|
+
// if the host part of the path looks like a hostname
|
3937
|
+
if (host.match(/.+(\.|:).+/) || host === 'localhost') {
|
3938
|
+
scheme = 'http://';
|
3939
|
+
}
|
3940
|
+
}
|
3941
|
+
|
3942
|
+
return scheme +
|
3943
|
+
// Ensure path is encoded
|
3944
|
+
this.ensureEncodedUri(path) +
|
3945
|
+
// Ensure query is encoded
|
3946
|
+
(query === undefined ? '' : '?' + this.ensureEncodedQuery(query)) +
|
3947
|
+
// Include fragment unencoded as encodeUriComponent is too
|
3948
|
+
// heavy handed for the many characters allowed in a fragment
|
3949
|
+
(fragment === undefined ? '' : '#' + fragment);
|
3909
3950
|
},
|
3910
3951
|
|
3911
3952
|
doFormCancel: function () {
|
@@ -4067,7 +4108,9 @@ MediumEditor.extensions = {};
|
|
4067
4108
|
},
|
4068
4109
|
|
4069
4110
|
hidePreview: function () {
|
4070
|
-
this.anchorPreview
|
4111
|
+
if (this.anchorPreview) {
|
4112
|
+
this.anchorPreview.classList.remove('medium-editor-anchor-preview-active');
|
4113
|
+
}
|
4071
4114
|
this.activeAnchor = null;
|
4072
4115
|
},
|
4073
4116
|
|
@@ -4305,7 +4348,8 @@ MediumEditor.extensions = {};
|
|
4305
4348
|
var WHITESPACE_CHARS,
|
4306
4349
|
KNOWN_TLDS_FRAGMENT,
|
4307
4350
|
LINK_REGEXP_TEXT,
|
4308
|
-
KNOWN_TLDS_REGEXP
|
4351
|
+
KNOWN_TLDS_REGEXP,
|
4352
|
+
LINK_REGEXP;
|
4309
4353
|
|
4310
4354
|
WHITESPACE_CHARS = [' ', '\t', '\n', '\r', '\u00A0', '\u2000', '\u2001', '\u2002', '\u2003',
|
4311
4355
|
'\u2028', '\u2029'];
|
@@ -4327,6 +4371,8 @@ MediumEditor.extensions = {};
|
|
4327
4371
|
|
4328
4372
|
KNOWN_TLDS_REGEXP = new RegExp('^(' + KNOWN_TLDS_FRAGMENT + ')$', 'i');
|
4329
4373
|
|
4374
|
+
LINK_REGEXP = new RegExp(LINK_REGEXP_TEXT, 'gi');
|
4375
|
+
|
4330
4376
|
function nodeIsNotInsideAnchorTag(node) {
|
4331
4377
|
return !MediumEditor.util.getClosestTag(node, 'a');
|
4332
4378
|
}
|
@@ -4508,12 +4554,11 @@ MediumEditor.extensions = {};
|
|
4508
4554
|
},
|
4509
4555
|
|
4510
4556
|
findLinkableText: function (contenteditable) {
|
4511
|
-
var
|
4512
|
-
textContent = contenteditable.textContent,
|
4557
|
+
var textContent = contenteditable.textContent,
|
4513
4558
|
match = null,
|
4514
4559
|
matches = [];
|
4515
4560
|
|
4516
|
-
while ((match =
|
4561
|
+
while ((match = LINK_REGEXP.exec(textContent)) !== null) {
|
4517
4562
|
var matchOk = true,
|
4518
4563
|
matchEnd = match.index + match[0].length;
|
4519
4564
|
// If the regexp detected something as a link that has text immediately preceding/following it, bail out.
|
@@ -5392,8 +5437,10 @@ MediumEditor.extensions = {};
|
|
5392
5437
|
// on empty line, rects is empty so we grab information from the first container of the range
|
5393
5438
|
if (rects.length) {
|
5394
5439
|
top += rects[0].top;
|
5395
|
-
} else {
|
5440
|
+
} else if (range.startContainer.getBoundingClientRect !== undefined) {
|
5396
5441
|
top += range.startContainer.getBoundingClientRect().top;
|
5442
|
+
} else {
|
5443
|
+
top += range.getBoundingClientRect().top;
|
5397
5444
|
}
|
5398
5445
|
}
|
5399
5446
|
|
@@ -7111,6 +7158,11 @@ MediumEditor.extensions = {};
|
|
7111
7158
|
return this.options.ownerDocument.execCommand('insertImage', false, src);
|
7112
7159
|
}
|
7113
7160
|
|
7161
|
+
if (action === 'html') {
|
7162
|
+
var html = this.options.contentWindow.getSelection().toString().trim();
|
7163
|
+
return MediumEditor.util.insertHTMLCommand(this.options.ownerDocument, html);
|
7164
|
+
}
|
7165
|
+
|
7114
7166
|
/* Issue: https://github.com/yabwe/medium-editor/issues/595
|
7115
7167
|
* If the action is to justify the text */
|
7116
7168
|
if (justifyAction.exec(action)) {
|
@@ -7826,7 +7878,7 @@ MediumEditor.parseVersionString = function (release) {
|
|
7826
7878
|
|
7827
7879
|
MediumEditor.version = MediumEditor.parseVersionString.call(this, ({
|
7828
7880
|
// grunt-bump looks for this:
|
7829
|
-
'version': '5.
|
7881
|
+
'version': '5.23.2'
|
7830
7882
|
}).version);
|
7831
7883
|
|
7832
7884
|
return MediumEditor;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: medium-editor-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ahmet Sezgin Duran
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-10-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|
96
96
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
97
|
+
rubygems_version: 2.6.13
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
100
|
summary: Metdium Editor integrated in Rails asset pipeline
|