Fixing errant linkify text bug that resulted in some javascript being executed and overwriting the page. Thanks to @aaronlidman for the help in identifying the bug.

This commit is contained in:
Samuel Clay 2012-03-08 09:56:52 -08:00
parent 16ddf028d2
commit da8357a741
4 changed files with 195 additions and 18 deletions

View file

@ -50,6 +50,7 @@ javascripts:
- media/js/jquery.flot.js
- media/js/jquery.tipsy.js
- media/js/jquery.chosen.js
- media/js/jquery.linkify.js
- media/js/audio.js
- media/js/socket.io-client.0.8.7.js
- media/js/inflector.js

192
media/js/jquery.linkify.js Normal file
View file

@ -0,0 +1,192 @@
/* encoding: utf-8
**** linkify plugin for jQuery - automatically finds and changes URLs in text content into proper hyperlinks ****
Version: 1.0
Copyright (c) 2009
Már Örlygsson (http://mar.anomy.net/) &
Hugsmiðjan ehf. (http://www.hugsmidjan.is)
Dual licensed under a MIT licence (http://en.wikipedia.org/wiki/MIT_License)
and GPL 2.0 or above (http://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
-----------------------------------------------------------------------------
Demo and Qunit-tests:
* <./jquery.linkify-1.0-demo.html>
* <./jquery.linkify-1.0-test.html>
Documentation:
* ...
Get updates from:
* <http://github.com/maranomynet/linkify/>
* <git://github.com/maranomynet/linkify.git>
-----------------------------------------------------------------------------
Requires:
* jQuery (1.2.6 or later)
Usage:
jQuery('.articlebody').linkify();
// adding plugins:
jQuery.extend( jQuery.fn.linkify.plugins, {
name1: {
re: RegExp
tmpl: String/Function
},
name2: function(html){ return html; }
});
// Uses all plugins by default:
jQuery('.articlebody').linkify();
// Use only certain plugins:
jQuery('.articlebody').linkify( 'name1,name2' );
jQuery('.articlebody').linkify({ use: 'name1,name2' });
jQuery('.articlebody').linkify({ use: ['name1','name2'] });
// Explicitly use all plugins:
jQuery('.articlebody').linkify('*');
jQuery('.articlebody').linkify({ use: '*' });
jQuery('.articlebody').linkify({ use: ['*'] });
// Use no plugins:
jQuery('.articlebody').linkify('');
jQuery('.articlebody').linkify({ use: '' });
jQuery('.articlebody').linkify({ use: [] });
jQuery('.articlebody').linkify({ use: [''] });
// Perfmorm actions on all newly created links:
jQuery('.articlebody').linkify( function (links){ links.addClass('linkified'); } );
jQuery('.articlebody').linkify({ handleLinks: function (links){ links.addClass('linkified'); } });
*/
(function($){
var noProtocolUrl = /(^|["'(\s]|&lt;)(www\..+?\..+?)((?:[:?]|\.+)?(?:\s|$)|&gt;|[)"',])/g,
httpOrMailtoUrl = /(^|["'(\s]|&lt;)((?:(?:https?|ftp):\/\/|mailto:).+?)((?:[:?]|\.+)?(?:\s|$)|&gt;|[)"',])/g,
linkifier = function ( html ) {
return html
.replace( noProtocolUrl, '$1<a href="<``>://$2">$2</a>$3' ) // NOTE: we escape `"http` as `"<``>` to make sure `httpOrMailtoUrl` below doesn't find it as a false-positive
.replace( httpOrMailtoUrl, '$1<a href="$2">$2</a>$3' )
.replace( /"<``>/g, '"http' ); // reinsert `"http`
},
linkify = $.fn.linkify = function ( cfg ) {
if ( !$.isPlainObject( cfg ) )
{
cfg = {
use: (typeof cfg == 'string') ? cfg : undefined,
handleLinks: $.isFunction(cfg) ? cfg : arguments[1]
};
}
var use = cfg.use,
allPlugins = linkify.plugins || {},
plugins = [linkifier],
tmpCont,
newLinks = [],
callback = cfg.handleLinks;
if ( use == undefined || use == '*' ) // use === undefined || use === null
{
for ( var name in allPlugins )
{
plugins.push( allPlugins[name] );
}
}
else
{
use = $.isArray( use ) ? use : $.trim(use).split( / *, */ );
var plugin,
name;
for ( var i=0, l=use.length; i<l; i++ )
{
name = use[i];
plugin = allPlugins[name];
if ( plugin )
{
plugins.push( plugin );
}
}
}
this.each(function () {
var childNodes = this.childNodes,
i = childNodes.length;
while ( i-- )
{
var n = childNodes[i];
if ( n.nodeType == 3 )
{
var html = n.nodeValue;
if ( html.length>1 && /\S/.test(html) )
{
var htmlChanged,
preHtml;
tmpCont = tmpCont || $('<div/>')[0];
tmpCont.innerHTML = '';
tmpCont.appendChild( n.cloneNode(false) );
var tmpContNodes = tmpCont.childNodes;
for (var j=0, plugin; (plugin = plugins[j]); j++)
{
var k = tmpContNodes.length,
tmpNode;
while ( k-- )
{
tmpNode = tmpContNodes[k];
if ( tmpNode.nodeType == 3 )
{
html = tmpNode.nodeValue;
if ( html.length>1 && /\S/.test(html) )
{
preHtml = html;
html = html
.replace( /&/g, '&amp;' )
.replace( /</g, '&lt;' )
.replace( />/g, '&gt;' );
html = $.isFunction( plugin ) ?
plugin( html ):
html.replace( plugin.re, plugin.tmpl );
htmlChanged = htmlChanged || preHtml!=html;
preHtml!=html && $(tmpNode).after(html).remove();
}
}
}
}
html = tmpCont.innerHTML;
if ( callback )
{
html = $('<div/>').html(html);
//newLinks.push.apply( newLinks, html.find('a').toArray() );
newLinks = newLinks.concat( html.find('a').toArray().reverse() );
html = html.contents();
}
htmlChanged && $(n).after(html).remove();
}
}
else if ( n.nodeType == 1 && !/^(a|button|textarea|code|pre)$/i.test(n.tagName) )
{
arguments.callee.call( n );
}
};
});
callback && callback( $(newLinks.reverse()) );
return this;
};
linkify.plugins = {
// default mailto: plugin
mailto: {
re: /(^|["'(\s]|&lt;)([^"'(\s&]+?@.+\.[a-z]{2,7})(([:?]|\.+)?(\s|$)|&gt;|[)"',])/gi,
tmpl: '$1<a href="mailto:$2">$2</a>$3'
}
};
})(jQuery);

View file

@ -33,23 +33,6 @@ NEWSBLUR.log = function(msg) {
$.fn.extend({
autolink: function() {
return this.each(function(){
var $desc = $(this);
$desc.textNodes().each(function(){
var text = $(this);
if(text && text.parent() && text.parent()[0] && text.parent()[0].nodeName != 'A') {
if (this.data.indexOf('http') != -1) {
text.replaceWith(this.data.replace(URL_REGEX, function($0, $1) {
console.log(["Replacing text link", $0]);
return '<a href="' + $0 +'">' + $0 + '</a>';
}));
}
}
});
});
},
textNodes: function() {
var ret = [];

View file

@ -3672,6 +3672,7 @@
}
return true;
});
$('.NB-feed-story-content', $story).linkify();
})($story, story, image_count);
}
}
@ -3687,7 +3688,7 @@
},
make_story_content: function(story_content) {
var $story_content = $('<div>').html(story_content).autolink();
var $story_content = $('<div>').html(story_content);
return $story_content;
},