Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

medium-editor

Package Overview
Dependencies
Maintainers
4
Versions
125
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

medium-editor - npm Package Compare versions

Comparing version 4.11.0 to 4.11.1

2

bower.json
{
"name": "medium-editor",
"version": "4.11.0",
"version": "4.11.1",
"homepage": "http://daviferreira.github.io/medium-editor/",

@@ -5,0 +5,0 @@ "authors": [

@@ -0,1 +1,7 @@

4.11.1 / 2015-05-26
==================
* Fix issue with auto-linked text after manually unlinking
* Fix some incorrect TLDs for auto-link
4.11.0 / 2015-05-26

@@ -2,0 +8,0 @@ ==================

{
"name": "medium-editor",
"version": "4.11.0",
"version": "4.11.1",
"author": "Davi Ferreira <hi@daviferreira.com>",

@@ -5,0 +5,0 @@ "contributors": [

@@ -39,3 +39,6 @@ /*global describe, it, expect, beforeEach, afterEach,

'http://www.example.com/baz?foo=bar#buzz',
'http://www.example.com/#buzz'
'http://www.example.com/#buzz',
'http://about.museum',
'http://getty.art.museum/visit/center/art.html',
'http://en.wikipedia.org/wiki/List_of_diplomatic_missions_of_China'
],

@@ -46,3 +49,6 @@ notLinks = [

'app.can',
'sadasda.sdfasf.sdfas'
'sadasda.sdfasf.sdfas',
'www.example.combasic',
// Our algorithm assumes that '.' is punctuation, not part of the URL.
'en.wikipedia.org/wiki/Embassy_of_China_in_Washington,_D.C.'
];

@@ -101,3 +107,3 @@

var anchors = this.el.getElementsByTagName('a');
expect(anchors.length).toBe(0);
expect(anchors.length).toBe(0, '# of anchors');
};

@@ -165,6 +171,6 @@ }

expect(links.length).toBe(1);
expect(links[0].innerHTML).toBe('<span data-auto-link="true">' +
'<span class="a"><b>http://www.</b>exa</span>mple.com</span>');
expect(links[0].getAttribute('href')).toBe('http://www.example.com');
expect(links[0].firstChild.getAttribute('data-auto-link')).toBe('true');
expect(links[0].firstChild.nodeName.toLowerCase()).toBe('span');
expect(links[0].firstChild.innerHTML).toBe('<span class="a"><b>http://www.</b>exa</span>mple.com');
expect(this.el.firstChild.lastChild.nodeValue).toBe(' ');

@@ -187,4 +193,5 @@ });

expect(links.length).toBe(1);
expect(links[0].innerHTML).toBe('<span data-auto-link="true">' +
'<b>http://www.</b>exampl<b>e</b>.com</span>');
expect(links[0].firstChild.getAttribute('data-auto-link')).toBe('true');
expect(links[0].firstChild.nodeName.toLowerCase()).toBe('span');
expect(links[0].firstChild.innerHTML).toBe('<b>http://www.</b>exampl<b>e</b>.com');
expect(links[0].getAttribute('href')).toBe('http://www.example.com');

@@ -217,2 +224,4 @@ expect(links[0].firstChild.getAttribute('data-auto-link')).toBe('true');

expect(links[0].firstChild.getAttribute('data-auto-link')).toBe('true');
expect(links[0].firstChild.getAttribute('data-href')).toBe('http://www.google.com/wow');
links[0].firstChild.removeAttribute('data-href'); // to make the next innerHTML check work consistently

@@ -265,3 +274,4 @@ var expectedOutput = '' +

it('should not auto-link text inside a span with data-auto-link=true', function () {
this.el.innerHTML = 'Click this <span data-auto-link="true">http://www.example.com</span> link';
this.el.innerHTML = 'Click this <span data-href="http://www.example.com" data-auto-link="true">' +
'http://www.example.com</span> link';

@@ -272,6 +282,8 @@ selectElementContentsAndFire(this.el.firstChild);

expect(this.el.getElementsByTagName('a').length).toBe(0, 'should not create a link');
expect(this.el.getElementsByTagName('span').length).toBe(1, 'span should remain in place');
});
it('should not auto-link text containing a span with data-auto-link=true', function () {
this.el.innerHTML = 'Click this <span data-auto-link="true">http://www.example.com</span>foo/bar/baz link';
this.el.innerHTML = 'Click this <span data-href="http://www.example.com" data-auto-link="true">' +
'www.example.com</span>foo/bar/baz link';

@@ -282,4 +294,24 @@ selectElementContentsAndFire(this.el.firstChild);

expect(this.el.getElementsByTagName('a').length).toBe(0, 'should not create a link');
expect(this.el.getElementsByTagName('span').length).toBe(1, 'span should remain in place');
});
it('should remove a span with data-auto-link=true when the text no longer matches the original link', function () {
this.el.innerHTML = 'Click this <span data-auto-link="true" data-href="http://www.example.com">' +
'foo</span> link';
triggerAutolinking(this.el);
expect(this.el.getElementsByTagName('span').length).toBe(0, 'span should have been removed');
});
it('should create a link with data-auto-link=true when the text no longer matches the original link' +
' and it has been unlinked', function () {
this.el.innerHTML = 'Click this <span data-auto-link="true" data-href="http://www.example.com">' +
'www.example.co.uk</span> link';
triggerAutolinking(this.el);
expect(this.el.getElementsByTagName('a').length).toBe(1, 'link should have been added');
expect(this.el.getElementsByTagName('a')[0].getAttribute('href')).toBe('http://www.example.co.uk',
'link should have been added');
});
it('should stop attempting to auto-link on keypress if an error is encountered', function () {

@@ -286,0 +318,0 @@ var spy = spyOn(MediumEditor.extensions.autoLink.prototype, 'performLinking').and.throwError('DOM ERROR');

/*global Extension, Util */
var AutoLink,
KNOWN_TLDS_FRAGMENT,
LINK_REGEXP_TEXT;
KNOWN_TLDS_FRAGMENT = 'com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|' +
'xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|' +
'bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|' +
'fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|' +
'is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|' +
'mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|' +
'pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|' +
'tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw';
LINK_REGEXP_TEXT =
'(' +
// Version of Gruber URL Regexp optimized for JS: http://stackoverflow.com/a/17733640
'((?:(https?://|ftps?://|nntp://)|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}\\\/)\\S+(?:[^\\s`!\\[\\]{};:\'\".,?\u00AB\u00BB\u201C\u201D\u2018\u2019]))' +
'((?:(https?://|ftps?://|nntp://)|www\\d{0,3}[.]|[a-z0-9.\\-]+[.](' + KNOWN_TLDS_FRAGMENT + ')\\\/)\\S+(?:[^\\s`!\\[\\]{};:\'\".,?\u00AB\u00BB\u201C\u201D\u2018\u2019]))' +
// Addition to above Regexp to support bare domains/one level subdomains with common non-i18n TLDs and without www prefix:
')|(([a-z0-9\\-]+\\.)?[a-z0-9\\-]+\\.(com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj| Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw))';
')|(([a-z0-9\\-]+\\.)?[a-z0-9\\-]+\\.(' + KNOWN_TLDS_FRAGMENT + '))';

@@ -16,2 +25,8 @@ (function () {

var KNOWN_TLDS_REGEXP = new RegExp('^(' + KNOWN_TLDS_FRAGMENT + ')$', 'i');
function nodeIsNotInsideAnchorTag(node) {
return !Util.getClosestTag(node, 'a');
}
AutoLink = Extension.extend({

@@ -66,3 +81,3 @@

var paragraphs = contenteditable.querySelectorAll('p'),
linkCreated = false;
documentModified = false;
if (paragraphs.length === 0) {

@@ -72,5 +87,6 @@ paragraphs = [contenteditable];

for (var i = 0; i < paragraphs.length; i++) {
linkCreated = this.performLinkingWithinElement(paragraphs[i]) || linkCreated;
documentModified = this.removeObsoleteAutoLinkSpans(paragraphs[i]) || documentModified;
documentModified = this.performLinkingWithinElement(paragraphs[i]) || documentModified;
}
return linkCreated;
return documentModified;
},

@@ -100,2 +116,24 @@

removeObsoleteAutoLinkSpans: function (element) {
var spans = element.querySelectorAll('span[data-auto-link="true"]'),
documentModified = false;
for (var i = 0; i < spans.length; i++) {
var textContent = spans[i].textContent;
if (textContent.indexOf('://') === -1) {
textContent = Util.ensureUrlHasProtocol(textContent);
}
if (spans[i].getAttribute('data-href') !== textContent && nodeIsNotInsideAnchorTag(spans[i])) {
documentModified = true;
// Some editing has happened to the span, so just remove it entirely. The user can put it back
// around just the href content if they need to prevent it from linking
while (spans[i].childNodes.length > 0) {
spans[i].parentNode.insertBefore(spans[i].firstChild, spans[i]);
}
spans[i].parentNode.removeChild(spans[i]);
}
}
return documentModified;
},
performLinkingWithinElement: function (element) {

@@ -121,6 +159,11 @@ var matches = this.findLinkableText(element),

while ((match = linkRegExp.exec(textContent)) !== null) {
var matchEnd = match.index + match[0].length;
var matchOk = true,
matchEnd = match.index + match[0].length;
// If the regexp detected something as a link that has text immediately preceding/following it, bail out.
if ((match.index === 0 || whitespaceChars.indexOf(textContent[match.index - 1]) !== -1) &&
(matchEnd === textContent.length || whitespaceChars.indexOf(textContent[matchEnd]) !== -1)) {
matchOk = (match.index === 0 || whitespaceChars.indexOf(textContent[match.index - 1]) !== -1) &&
(matchEnd === textContent.length || whitespaceChars.indexOf(textContent[matchEnd]) !== -1);
// If the regexp detected a bare domain that doesn't use one of our expected TLDs, bail out.
matchOk = matchOk && (match[0].indexOf('/') !== -1 ||
KNOWN_TLDS_REGEXP.test(match[0].split('.').pop().split('?').shift()));
if (matchOk) {
matches.push({

@@ -188,6 +231,8 @@ href: match[0],

var anchor = this.document.createElement('a'),
span = this.document.createElement('span');
span = this.document.createElement('span'),
hrefWithProtocol = Util.ensureUrlHasProtocol(href);
Util.moveTextRangeIntoElement(textNodes[0], textNodes[textNodes.length - 1], span);
span.setAttribute('data-auto-link', 'true');
anchor.setAttribute('href', Util.ensureUrlHasProtocol(href));
span.setAttribute('data-href', hrefWithProtocol);
anchor.setAttribute('href', hrefWithProtocol);
span.parentNode.insertBefore(anchor, span);

@@ -194,0 +239,0 @@ anchor.appendChild(span);

@@ -14,3 +14,3 @@ /*global MediumEditor */

// grunt-bump looks for this:
'version': '4.11.0'
'version': '4.11.1'
}).version.split('.'));

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc