Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat(docs): linkify error messages on minErr docs pages
Browse files Browse the repository at this point in the history
  • Loading branch information
ksheedlo authored and btford committed Sep 27, 2013
1 parent 6a8edc1 commit 6aaae06
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
49 changes: 49 additions & 0 deletions docs/component-spec/errorLinkFilterSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
describe("errorLinkFilter", function () {

var errorLinkFilter;

beforeEach(module('docsApp'));

beforeEach(inject(function ($filter) {
errorLinkFilter = $filter('errorLink');
}));

it('should not change text that does not contain links', function () {
expect(errorLinkFilter('This is a test')).toBe('This is a test');
});

it('should find links in text and linkify them', function () {
expect(errorLinkFilter("http://ab/ (http://a/) http://1.2/v:~-123. c")).
toBe('<a href="http://ab/">http://ab/</a> ' +
'(<a href="http://a/">http://a/</a>) ' +
'<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c');
expect(errorLinkFilter(undefined)).not.toBeDefined();
});

it('should handle mailto', function () {
expect(errorLinkFilter("mailto:[email protected]")).
toBe('<a href="mailto:[email protected]">[email protected]</a>');
expect(errorLinkFilter("[email protected]")).
toBe('<a href="mailto:[email protected]">[email protected]</a>');
expect(errorLinkFilter("send email to [email protected], but")).
toBe('send email to <a href="mailto:[email protected]">[email protected]</a>, but');
});

it('should handle target', function () {
expect(errorLinkFilter("http://example.com", "_blank")).
toBe('<a target="_blank" href="http://example.com">http://example.com</a>')
expect(errorLinkFilter("http://example.com", "someNamedIFrame")).
toBe('<a target="someNamedIFrame" href="http://example.com">http://example.com</a>')
});

it('should not linkify stack trace URLs', function () {
expect(errorLinkFilter("http://example.com/angular.min.js:42:1337")).
toBe("http://example.com/angular.min.js:42:1337");
});

it('should truncate linked URLs at 60 characters', function () {
expect(errorLinkFilter("http://errors.angularjs.org/very-long-version-string/$injector/nomod?p0=myApp")).
toBe('<a href="http://errors.angularjs.org/very-long-version-string/$injector/nomod?p0=myApp">' +
'http://errors.angularjs.org/very-long-version-string/$inj...</a>');
});
});
44 changes: 41 additions & 3 deletions docs/src/templates/js/docs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
var docsApp = {
controller: {},
directive: {},
serviceFactory: {}
serviceFactory: {},
filter: {}
};

docsApp.controller.DocsVersionsCtrl = ['$scope', '$window', 'NG_VERSIONS', 'NG_VERSION', function($scope, $window, NG_VERSIONS, NG_VERSION) {
Expand Down Expand Up @@ -255,7 +256,40 @@ docsApp.directive.docTutorialReset = function() {
};


docsApp.directive.errorDisplay = ['$location', function ($location) {
docsApp.filter.errorLink = ['$sanitize', function ($sanitize) {
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/g,
MAILTO_REGEXP = /^mailto:/,
STACK_TRACE_REGEXP = /:\d+:\d+$/;

var truncate = function (text, nchars) {
if (text.length > nchars) {
return text.substr(0, nchars - 3) + '...';
}
return text;
};

return function (text, target) {
var targetHtml = target ? ' target="' + target + '"' : '';

if (!text) return text;

return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) {
if (STACK_TRACE_REGEXP.test(url)) {
return url;
}

// if we did not match ftp/http/mailto then assume mailto
if (!/^((ftp|https?):\/\/|mailto:)/.test(url)) url = 'mailto:' + url;

return '<a' + targetHtml + ' href="' + url +'">' +
truncate(url.replace(MAILTO_REGEXP, ''), 60) +
'</a>';
}));
};
}];


docsApp.directive.errorDisplay = ['$location', 'errorLinkFilter', function ($location, errorLinkFilter) {
var interpolate = function (formatString) {
var formatArgs = arguments;
return formatString.replace(/\{\d+\}/g, function (match) {
Expand All @@ -278,7 +312,7 @@ docsApp.directive.errorDisplay = ['$location', function ($location) {
for (i = 0; angular.isDefined(search['p'+i]); i++) {
formatArgs.push(search['p'+i]);
}
element.text(interpolate.apply(null, formatArgs));
element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank'));
}
};
}];
Expand Down Expand Up @@ -873,3 +907,7 @@ angular.module('docsApp', ['ngResource', 'ngRoute', 'ngCookies', 'ngSanitize', '
factory(docsApp.serviceFactory).
directive(docsApp.directive).
controller(docsApp.controller);

angular.forEach(docsApp.filter, function (docsAppFilter, filterName) {
angular.module('docsApp').filter(filterName, docsAppFilter);
});

0 comments on commit 6aaae06

Please sign in to comment.