From da8357a741a2a5dfb39cef0bb26a2b7062c7acb2 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Thu, 8 Mar 2012 09:56:52 -0800 Subject: [PATCH] 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. --- assets.yml | 1 + media/js/jquery.linkify.js | 192 ++++++++++++++++++++++++++++++++++++ media/js/jquery.newsblur.js | 17 ---- media/js/newsblur/reader.js | 3 +- 4 files changed, 195 insertions(+), 18 deletions(-) create mode 100644 media/js/jquery.linkify.js diff --git a/assets.yml b/assets.yml index 18657808e..79077c4e4 100644 --- a/assets.yml +++ b/assets.yml @@ -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 diff --git a/media/js/jquery.linkify.js b/media/js/jquery.linkify.js new file mode 100644 index 000000000..b99ae4dd4 --- /dev/null +++ b/media/js/jquery.linkify.js @@ -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: + * + * + +----------------------------------------------------------------------------- + + 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]|<)(www\..+?\..+?)((?:[:?]|\.+)?(?:\s|$)|>|[)"',])/g, + httpOrMailtoUrl = /(^|["'(\s]|<)((?:(?:https?|ftp):\/\/|mailto:).+?)((?:[:?]|\.+)?(?:\s|$)|>|[)"',])/g, + linkifier = function ( html ) { + return html + .replace( noProtocolUrl, '$1$2$3' ) // NOTE: we escape `"http` as `"<``>` to make sure `httpOrMailtoUrl` below doesn't find it as a false-positive + .replace( httpOrMailtoUrl, '$1$2$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; i1 && /\S/.test(html) ) + { + var htmlChanged, + preHtml; + tmpCont = tmpCont || $('
')[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, '&' ) + .replace( //g, '>' ); + 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 = $('
').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]|<)([^"'(\s&]+?@.+\.[a-z]{2,7})(([:?]|\.+)?(\s|$)|>|[)"',])/gi, + tmpl: '$1$2$3' + } + }; + +})(jQuery); \ No newline at end of file diff --git a/media/js/jquery.newsblur.js b/media/js/jquery.newsblur.js index fcc15d11b..42f176281 100644 --- a/media/js/jquery.newsblur.js +++ b/media/js/jquery.newsblur.js @@ -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 '' + $0 + ''; - })); - } - } - }); - }); - }, - textNodes: function() { var ret = []; diff --git a/media/js/newsblur/reader.js b/media/js/newsblur/reader.js index 4504587c7..0a1770220 100644 --- a/media/js/newsblur/reader.js +++ b/media/js/newsblur/reader.js @@ -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 = $('
').html(story_content).autolink(); + var $story_content = $('
').html(story_content); return $story_content; },