mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-08 14:54:44 +00:00
feat(docs): linkify error messages on minErr docs pages
This commit is contained in:
parent
6a8edc1d43
commit
6aaae06217
2 changed files with 90 additions and 3 deletions
49
docs/component-spec/errorLinkFilterSpec.js
Normal file
49
docs/component-spec/errorLinkFilterSpec.js
Normal file
|
|
@ -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:me@example.com")).
|
||||||
|
toBe('<a href="mailto:me@example.com">me@example.com</a>');
|
||||||
|
expect(errorLinkFilter("me@example.com")).
|
||||||
|
toBe('<a href="mailto:me@example.com">me@example.com</a>');
|
||||||
|
expect(errorLinkFilter("send email to me@example.com, but")).
|
||||||
|
toBe('send email to <a href="mailto:me@example.com">me@example.com</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>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
var docsApp = {
|
var docsApp = {
|
||||||
controller: {},
|
controller: {},
|
||||||
directive: {},
|
directive: {},
|
||||||
serviceFactory: {}
|
serviceFactory: {},
|
||||||
|
filter: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
docsApp.controller.DocsVersionsCtrl = ['$scope', '$window', 'NG_VERSIONS', 'NG_VERSION', function($scope, $window, NG_VERSIONS, NG_VERSION) {
|
docsApp.controller.DocsVersionsCtrl = ['$scope', '$window', 'NG_VERSIONS', 'NG_VERSION', function($scope, $window, NG_VERSIONS, NG_VERSION) {
|
||||||
|
|
@ -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 interpolate = function (formatString) {
|
||||||
var formatArgs = arguments;
|
var formatArgs = arguments;
|
||||||
return formatString.replace(/\{\d+\}/g, function (match) {
|
return formatString.replace(/\{\d+\}/g, function (match) {
|
||||||
|
|
@ -278,7 +312,7 @@ docsApp.directive.errorDisplay = ['$location', function ($location) {
|
||||||
for (i = 0; angular.isDefined(search['p'+i]); i++) {
|
for (i = 0; angular.isDefined(search['p'+i]); i++) {
|
||||||
formatArgs.push(search['p'+i]);
|
formatArgs.push(search['p'+i]);
|
||||||
}
|
}
|
||||||
element.text(interpolate.apply(null, formatArgs));
|
element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
|
|
@ -873,3 +907,7 @@ angular.module('docsApp', ['ngResource', 'ngRoute', 'ngCookies', 'ngSanitize', '
|
||||||
factory(docsApp.serviceFactory).
|
factory(docsApp.serviceFactory).
|
||||||
directive(docsApp.directive).
|
directive(docsApp.directive).
|
||||||
controller(docsApp.controller);
|
controller(docsApp.controller);
|
||||||
|
|
||||||
|
angular.forEach(docsApp.filter, function (docsAppFilter, filterName) {
|
||||||
|
angular.module('docsApp').filter(filterName, docsAppFilter);
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue