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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 517e7d49f074c079067439b81a4a18c6f823fd0e
4
- data.tar.gz: 267ee3cda3176cb44557ec1ba3b925b26eaf86ec
3
+ metadata.gz: 9fbc5be5c8889b94516fe3d384de117a143a8f64
4
+ data.tar.gz: baa9b17e491b54932b130529bdc9c93a15bbd211
5
5
  SHA512:
6
- metadata.gz: f3b2005cc03fba7ddf20dbc2ddf726bfaa6e87f1609d5a286bd8d035cf170d24ac28882eca9557c3d70a6538018ea1a2b18eb15d50f597bda2f3cefd841c19de
7
- data.tar.gz: d0bbbd59734f772531e0464a810b9633bb621ade8dd0d973bbaf50e1a31a0a7e0305f6923141f7363a2e4f41165db64a84052ffc54eba90d9c382d36dc9ead99
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.22.1](https://github.com/yabwe/medium-editor/releases)
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
@@ -5,6 +5,7 @@ README_VERSION_REGEXP = /bundled by this gem is \[([^\]]*)\]/
5
5
  VERSION_FILE_REGEXP = /MEDIUM_EDITOR_VERSION\s.*/
6
6
 
7
7
  namespace :bower do
8
+ desc "updates JS version references in README and VERSION files"
8
9
  task :bump do
9
10
  bump_readme_file
10
11
  bump_version_file
@@ -1,6 +1,6 @@
1
1
  module MediumEditorRails
2
2
  module Rails
3
- VERSION = '2.3.2'
4
- MEDIUM_EDITOR_VERSION = '5.22.1'
3
+ VERSION = '2.3.3'
4
+ MEDIUM_EDITOR_VERSION = '5.23.2'
5
5
  end
6
6
  end
@@ -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 + (newNode || currentNode).nodeValue.length +
633
- (newNode ? currentNode.nodeValue.length : 0) -
634
- 1;
635
- endSplitPoint = (newNode || currentNode).nodeValue.length -
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
- el = el.getElementsByTagName('a');
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
- targets = MediumEditor.util.isElement(targets) || [win, doc].indexOf(targets) > -1 ? [targets] : targets;
2505
+ if (targets !== null) {
2506
+ targets = MediumEditor.util.isElement(targets) || [win, doc].indexOf(targets) > -1 ? [targets] : targets;
2489
2507
 
2490
- Array.prototype.forEach.call(targets, function (target) {
2491
- index = this.indexOfListener(target, event, listener, useCapture);
2492
- if (index !== -1) {
2493
- e = this.events.splice(index, 1)[0];
2494
- e[0].removeEventListener(e[1], e[2], e[3]);
2495
- }
2496
- }.bind(this));
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
- split = value.split('?'),
3896
- path = split[0],
3897
- query = split[1];
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.classList.remove('medium-editor-anchor-preview-active');
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 linkRegExp = new RegExp(LINK_REGEXP_TEXT, 'gi'),
4512
- textContent = contenteditable.textContent,
4557
+ var textContent = contenteditable.textContent,
4513
4558
  match = null,
4514
4559
  matches = [];
4515
4560
 
4516
- while ((match = linkRegExp.exec(textContent)) !== null) {
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.22.1'
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.2
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-01-18 00:00:00.000000000 Z
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.5.1
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