diff --git a/app/assets/javascripts/discourse/lib/click_track.js b/app/assets/javascripts/discourse/lib/click_track.js index 84b3e0983d8..fb2cdb80f55 100644 --- a/app/assets/javascripts/discourse/lib/click_track.js +++ b/app/assets/javascripts/discourse/lib/click_track.js @@ -85,7 +85,7 @@ Discourse.ClickTrack = { } // If we're on the same site, use the router and track via AJAX - if ((href.indexOf(Discourse.URL.origin()) === 0) && !href.match(/\/uploads\//i)) { + if (Discourse.URL.isInternal(href) && !href.match(/\/uploads\//i)) { Discourse.ajax("/clicks/track", { data: { url: href, diff --git a/app/assets/javascripts/discourse/lib/url.js b/app/assets/javascripts/discourse/lib/url.js index ca78faba912..681085fbb7d 100644 --- a/app/assets/javascripts/discourse/lib/url.js +++ b/app/assets/javascripts/discourse/lib/url.js @@ -89,6 +89,23 @@ Discourse.URL = Em.Object.createWithMixins({ window.location = Discourse.getURL(url); }, + /** + * Determines whether a URL is internal or not + * + * @method isInternal + * @param {String} url + **/ + isInternal: function(url) { + if (url && url.length) { + if (url.indexOf('/') === 0) { return true; } + if (url.indexOf(this.origin()) === 0) { return true; } + if (url.replace(/^http[^s]/, 'https').indexOf(this.origin()) === 0) { return true; } + if (url.replace(/^https/, 'http').indexOf(this.origin()) === 0) { return true; } + } + return false; + }, + + /** @private diff --git a/test/javascripts/lib/url_test.js b/test/javascripts/lib/url_test.js index ee8afbae2eb..5006277098d 100644 --- a/test/javascripts/lib/url_test.js +++ b/test/javascripts/lib/url_test.js @@ -1,5 +1,20 @@ module("Discourse.URL"); +test("isInternal with a HTTP url", function() { + this.stub(Discourse.URL, "origin").returns("http://eviltrout.com"); + + ok(!Discourse.URL.isInternal(null), "a blank URL is not internal"); + ok(Discourse.URL.isInternal("/test"), "relative URLs are internal"); + ok(Discourse.URL.isInternal("http://eviltrout.com/tophat"), "a url on the same host is internal"); + ok(Discourse.URL.isInternal("https://eviltrout.com/moustache"), "a url on a HTTPS of the same host is internal"); + ok(!Discourse.URL.isInternal("http://twitter.com"), "a different host is not internal"); +}); + +test("isInternal with a HTTPS url", function() { + this.stub(Discourse.URL, "origin").returns("https://eviltrout.com"); + ok(Discourse.URL.isInternal("http://eviltrout.com/monocle"), "HTTPS urls match HTTP urls"); +}); + test("navigatedToHome", function() { var fakeListController = { refresh: function() { return true; } }; var mock = sinon.mock(fakeListController);