angular-rails-engine 1.0.7.0 → 1.1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +5 -1
- data/app/assets/javascripts/angular/angular-cookies.js +1 -1
- data/app/assets/javascripts/angular/angular-cookies.min.js +1 -1
- data/app/assets/javascripts/angular/angular-resource.js +133 -53
- data/app/assets/javascripts/angular/angular-resource.min.js +7 -6
- data/app/assets/javascripts/angular/angular-sanitize.js +25 -4
- data/app/assets/javascripts/angular/angular-sanitize.min.js +9 -9
- data/app/assets/javascripts/angular/angular.js +2879 -850
- data/app/assets/javascripts/angular/angular.min.js +174 -159
- data/lib/angular-rails-engine.rb +2 -1
- data/lib/angular-rails-engine/version.rb +1 -1
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26672e71f0500d424e50d99f4064f26d1ef11db9
|
4
|
+
data.tar.gz: 82e9f502e9224e38c81c1b6bb3009410f3974aa9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a71aaecf256d7e5e463f93b8809d8361a557eef011d0d9b412ad46c7584a2e101ca40da57bdbfade750506efe75bee23a8b179f7aae991a3d4d3ef2ccc8c815f
|
7
|
+
data.tar.gz: 9013d9a11734b93f100ac67f495ecd9fe7a5c42b2dbceda660b2480e93daf2228bb0a9d2bbf63a644f88c927bce1b439a2743eb9398250b7a59849731c6bc39d
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -2,7 +2,11 @@
|
|
2
2
|
Make [Angular.js](http://angularjs.org) into Rails Engine.
|
3
3
|
|
4
4
|
## Version
|
5
|
-
Angular.js 1.
|
5
|
+
Angular.js 1.1.5
|
6
|
+
|
7
|
+
### Older Versions
|
8
|
+
|
9
|
+
For Angular.js 1.0.x, try [1.0 branch](https://github.com/yjchen/angular-rails-engine/tree/1.0) or gem version around 1.0.x.x.
|
6
10
|
|
7
11
|
## Rails 3.2 or later
|
8
12
|
Include Gemfile,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
2
|
+
* @license AngularJS v1.1.5
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -25,7 +25,7 @@
|
|
25
25
|
* the need to interact with the low level {@link ng.$http $http} service.
|
26
26
|
*
|
27
27
|
* # Installation
|
28
|
-
* To use $resource make sure you have included the `angular-resource.js` that comes in Angular
|
28
|
+
* To use $resource make sure you have included the `angular-resource.js` that comes in Angular
|
29
29
|
* package. You can also find this file on Google CDN, bower as well as at
|
30
30
|
* {@link http://code.angularjs.org/ code.angularjs.org}.
|
31
31
|
*
|
@@ -35,13 +35,21 @@
|
|
35
35
|
*
|
36
36
|
* and you are ready to get started!
|
37
37
|
*
|
38
|
-
* @param {string} url A
|
39
|
-
* `/user/:username`. If you are using a URL with a port number (e.g.
|
38
|
+
* @param {string} url A parametrized URL template with parameters prefixed by `:` as in
|
39
|
+
* `/user/:username`. If you are using a URL with a port number (e.g.
|
40
40
|
* `http://example.com:8080/api`), you'll need to escape the colon character before the port
|
41
41
|
* number, like this: `$resource('http://example.com\\:8080/api')`.
|
42
42
|
*
|
43
|
+
* If you are using a url with a suffix, just add the suffix, like this:
|
44
|
+
* `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')
|
45
|
+
* or even `$resource('http://example.com/resource/:resource_id.:format')`
|
46
|
+
* If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
|
47
|
+
* collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
|
48
|
+
* can escape it with `/\.`.
|
49
|
+
*
|
43
50
|
* @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
|
44
|
-
* `actions` methods.
|
51
|
+
* `actions` methods. If any of the parameter value is a function, it will be executed every time
|
52
|
+
* when a param value needs to be obtained for a request (unless the param was overridden).
|
45
53
|
*
|
46
54
|
* Each key value in the parameter object is first bound to url template if present and then any
|
47
55
|
* excess keys are appended to the url search query after the `?`.
|
@@ -53,21 +61,43 @@
|
|
53
61
|
* the data object (useful for non-GET operations).
|
54
62
|
*
|
55
63
|
* @param {Object.<Object>=} actions Hash with declaration of custom action that should extend the
|
56
|
-
* default set of resource actions. The declaration should be created in the
|
64
|
+
* default set of resource actions. The declaration should be created in the format of {@link
|
65
|
+
* ng.$http#Parameters $http.config}:
|
57
66
|
*
|
58
|
-
* {action1: {method:?, params:?, isArray
|
59
|
-
* action2: {method:?, params:?, isArray
|
67
|
+
* {action1: {method:?, params:?, isArray:?, headers:?, ...},
|
68
|
+
* action2: {method:?, params:?, isArray:?, headers:?, ...},
|
60
69
|
* ...}
|
61
70
|
*
|
62
71
|
* Where:
|
63
72
|
*
|
64
|
-
* -
|
73
|
+
* - **`action`** – {string} – The name of action. This name becomes the name of the method on your
|
65
74
|
* resource object.
|
66
|
-
* -
|
67
|
-
* and `JSONP
|
68
|
-
* -
|
69
|
-
*
|
75
|
+
* - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, `DELETE`,
|
76
|
+
* and `JSONP`.
|
77
|
+
* - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of the
|
78
|
+
* parameter value is a function, it will be executed every time when a param value needs to be
|
79
|
+
* obtained for a request (unless the param was overridden).
|
80
|
+
* - **`url`** – {string} – action specific `url` override. The url templating is supported just like
|
81
|
+
* for the resource-level urls.
|
82
|
+
* - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, see
|
70
83
|
* `returns` section.
|
84
|
+
* - **`transformRequest`** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
85
|
+
* transform function or an array of such functions. The transform function takes the http
|
86
|
+
* request body and headers and returns its transformed (typically serialized) version.
|
87
|
+
* - **`transformResponse`** – `{function(data, headersGetter)|Array.<function(data, headersGetter)>}` –
|
88
|
+
* transform function or an array of such functions. The transform function takes the http
|
89
|
+
* response body and headers and returns its transformed (typically deserialized) version.
|
90
|
+
* - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the
|
91
|
+
* GET request, otherwise if a cache instance built with
|
92
|
+
* {@link ng.$cacheFactory $cacheFactory}, this cache will be used for
|
93
|
+
* caching.
|
94
|
+
* - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that
|
95
|
+
* should abort the request when resolved.
|
96
|
+
* - **`withCredentials`** - `{boolean}` - whether to to set the `withCredentials` flag on the
|
97
|
+
* XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5
|
98
|
+
* requests with credentials} for more information.
|
99
|
+
* - **`responseType`** - `{string}` - see {@link
|
100
|
+
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
|
71
101
|
*
|
72
102
|
* @returns {Object} A resource "class" object with methods for the default set of resource actions
|
73
103
|
* optionally extended with custom `actions`. The default set contains these actions:
|
@@ -107,6 +137,24 @@
|
|
107
137
|
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
|
108
138
|
*
|
109
139
|
*
|
140
|
+
* The Resource instances and collection have these additional properties:
|
141
|
+
*
|
142
|
+
* - `$then`: the `then` method of a {@link ng.$q promise} derived from the underlying
|
143
|
+
* {@link ng.$http $http} call.
|
144
|
+
*
|
145
|
+
* The success callback for the `$then` method will be resolved if the underlying `$http` requests
|
146
|
+
* succeeds.
|
147
|
+
*
|
148
|
+
* The success callback is called with a single object which is the {@link ng.$http http response}
|
149
|
+
* object extended with a new property `resource`. This `resource` property is a reference to the
|
150
|
+
* result of the resource action — resource object or array of resources.
|
151
|
+
*
|
152
|
+
* The error callback is called with the {@link ng.$http http response} object when an http
|
153
|
+
* error occurs.
|
154
|
+
*
|
155
|
+
* - `$resolved`: true if the promise has been resolved (either with success or rejection);
|
156
|
+
* Knowing if the Resource has been resolved is useful in data-binding.
|
157
|
+
*
|
110
158
|
* @example
|
111
159
|
*
|
112
160
|
* # Credit card resource
|
@@ -149,7 +197,7 @@
|
|
149
197
|
* The object returned from this function execution is a resource "class" which has "static" method
|
150
198
|
* for each action in the definition.
|
151
199
|
*
|
152
|
-
* Calling these methods invoke `$http` on the `url` template with the given `method` and `
|
200
|
+
* Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and `headers`.
|
153
201
|
* When the data is returned from the server then the object is an instance of the resource type and
|
154
202
|
* all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD
|
155
203
|
* operations (create, read, update, delete) on server-side data.
|
@@ -264,7 +312,7 @@ angular.module('ngResource', ['ng']).
|
|
264
312
|
|
265
313
|
/**
|
266
314
|
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
|
267
|
-
* method
|
315
|
+
* method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
|
268
316
|
* encoded per http://tools.ietf.org/html/rfc3986:
|
269
317
|
* query = *( pchar / "/" / "?" )
|
270
318
|
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
@@ -283,32 +331,34 @@ angular.module('ngResource', ['ng']).
|
|
283
331
|
}
|
284
332
|
|
285
333
|
function Route(template, defaults) {
|
286
|
-
this.template = template
|
334
|
+
this.template = template;
|
287
335
|
this.defaults = defaults || {};
|
288
|
-
|
289
|
-
forEach(template.split(/\W/), function(param){
|
290
|
-
if (param && (new RegExp("(^|[^\\\\]):" + param + "\\W").test(template))) {
|
291
|
-
urlParams[param] = true;
|
292
|
-
}
|
293
|
-
});
|
294
|
-
this.template = template.replace(/\\:/g, ':');
|
336
|
+
this.urlParams = {};
|
295
337
|
}
|
296
338
|
|
297
339
|
Route.prototype = {
|
298
|
-
|
340
|
+
setUrlParams: function(config, params, actionUrl) {
|
299
341
|
var self = this,
|
300
|
-
url =
|
342
|
+
url = actionUrl || self.template,
|
301
343
|
val,
|
302
344
|
encodedVal;
|
303
345
|
|
346
|
+
var urlParams = self.urlParams = {};
|
347
|
+
forEach(url.split(/\W/), function(param){
|
348
|
+
if (param && (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
|
349
|
+
urlParams[param] = true;
|
350
|
+
}
|
351
|
+
});
|
352
|
+
url = url.replace(/\\:/g, ':');
|
353
|
+
|
304
354
|
params = params || {};
|
305
|
-
forEach(
|
355
|
+
forEach(self.urlParams, function(_, urlParam){
|
306
356
|
val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
|
307
357
|
if (angular.isDefined(val) && val !== null) {
|
308
358
|
encodedVal = encodeUriSegment(val);
|
309
|
-
url = url.replace(new RegExp(":" + urlParam + "(\\W)", "g"), encodedVal + "$1");
|
359
|
+
url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), encodedVal + "$1");
|
310
360
|
} else {
|
311
|
-
url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W)", "g"), function(match,
|
361
|
+
url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
|
312
362
|
leadingSlashes, tail) {
|
313
363
|
if (tail.charAt(0) == '/') {
|
314
364
|
return tail;
|
@@ -318,16 +368,23 @@ angular.module('ngResource', ['ng']).
|
|
318
368
|
});
|
319
369
|
}
|
320
370
|
});
|
321
|
-
|
322
|
-
|
371
|
+
|
372
|
+
// strip trailing slashes and set the url
|
373
|
+
url = url.replace(/\/+$/, '');
|
374
|
+
// then replace collapse `/.` if found in the last URL path segment before the query
|
375
|
+
// E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x`
|
376
|
+
url = url.replace(/\/\.(?=\w+($|\?))/, '.');
|
377
|
+
// replace escaped `/\.` with `/.`
|
378
|
+
config.url = url.replace(/\/\\\./, '/.');
|
379
|
+
|
380
|
+
|
381
|
+
// set params - delegate param encoding to $http
|
323
382
|
forEach(params, function(value, key){
|
324
383
|
if (!self.urlParams[key]) {
|
325
|
-
|
384
|
+
config.params = config.params || {};
|
385
|
+
config.params[key] = value;
|
326
386
|
}
|
327
387
|
});
|
328
|
-
query.sort();
|
329
|
-
url = url.replace(/\/*$/, '');
|
330
|
-
return url + (query.length ? '?' + query.join('&') : '');
|
331
388
|
}
|
332
389
|
};
|
333
390
|
|
@@ -341,7 +398,8 @@ angular.module('ngResource', ['ng']).
|
|
341
398
|
var ids = {};
|
342
399
|
actionParams = extend({}, paramDefaults, actionParams);
|
343
400
|
forEach(actionParams, function(value, key){
|
344
|
-
|
401
|
+
if (isFunction(value)) { value = value(); }
|
402
|
+
ids[key] = value && value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
|
345
403
|
});
|
346
404
|
return ids;
|
347
405
|
}
|
@@ -358,6 +416,8 @@ angular.module('ngResource', ['ng']).
|
|
358
416
|
var data;
|
359
417
|
var success = noop;
|
360
418
|
var error = null;
|
419
|
+
var promise;
|
420
|
+
|
361
421
|
switch(arguments.length) {
|
362
422
|
case 4:
|
363
423
|
error = a4;
|
@@ -393,25 +453,45 @@ angular.module('ngResource', ['ng']).
|
|
393
453
|
}
|
394
454
|
|
395
455
|
var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
456
|
+
var httpConfig = {},
|
457
|
+
promise;
|
458
|
+
|
459
|
+
forEach(action, function(value, key) {
|
460
|
+
if (key != 'params' && key != 'isArray' ) {
|
461
|
+
httpConfig[key] = copy(value);
|
462
|
+
}
|
463
|
+
});
|
464
|
+
httpConfig.data = data;
|
465
|
+
route.setUrlParams(httpConfig, extend({}, extractParams(data, action.params || {}), params), action.url);
|
466
|
+
|
467
|
+
function markResolved() { value.$resolved = true; }
|
468
|
+
|
469
|
+
promise = $http(httpConfig);
|
470
|
+
value.$resolved = false;
|
471
|
+
|
472
|
+
promise.then(markResolved, markResolved);
|
473
|
+
value.$then = promise.then(function(response) {
|
474
|
+
var data = response.data;
|
475
|
+
var then = value.$then, resolved = value.$resolved;
|
476
|
+
|
477
|
+
if (data) {
|
478
|
+
if (action.isArray) {
|
479
|
+
value.length = 0;
|
480
|
+
forEach(data, function(item) {
|
481
|
+
value.push(new Resource(item));
|
482
|
+
});
|
483
|
+
} else {
|
484
|
+
copy(data, value);
|
485
|
+
value.$then = then;
|
486
|
+
value.$resolved = resolved;
|
412
487
|
}
|
413
|
-
|
414
|
-
|
488
|
+
}
|
489
|
+
|
490
|
+
(success||noop)(value, response.headers);
|
491
|
+
|
492
|
+
response.resource = value;
|
493
|
+
return response;
|
494
|
+
}, error).then;
|
415
495
|
|
416
496
|
return value;
|
417
497
|
};
|
@@ -1,10 +1,11 @@
|
|
1
1
|
/*
|
2
|
-
AngularJS v1.
|
2
|
+
AngularJS v1.1.5
|
3
3
|
(c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
License: MIT
|
5
5
|
*/
|
6
|
-
(function(
|
7
|
-
|
8
|
-
|
9
|
-
arguments.length+" arguments.";}
|
10
|
-
"=").replace(/%2B/gi,"+"),
|
6
|
+
(function(B,f,w){'use strict';f.module("ngResource",["ng"]).factory("$resource",["$http","$parse",function(x,y){function u(b,d){this.template=b;this.defaults=d||{};this.urlParams={}}function v(b,d,e){function j(c,b){var p={},b=m({},d,b);l(b,function(a,b){k(a)&&(a=a());var g;a&&a.charAt&&a.charAt(0)=="@"?(g=a.substr(1),g=y(g)(c)):g=a;p[b]=g});return p}function c(c){t(c||{},this)}var n=new u(b),e=m({},z,e);l(e,function(b,d){b.method=f.uppercase(b.method);var p=b.method=="POST"||b.method=="PUT"||b.method==
|
7
|
+
"PATCH";c[d]=function(a,d,g,A){function f(){h.$resolved=!0}var i={},e,o=q,r=null;switch(arguments.length){case 4:r=A,o=g;case 3:case 2:if(k(d)){if(k(a)){o=a;r=d;break}o=d;r=g}else{i=a;e=d;o=g;break}case 1:k(a)?o=a:p?e=a:i=a;break;case 0:break;default:throw"Expected between 0-4 arguments [params, data, success, error], got "+arguments.length+" arguments.";}var h=this instanceof c?this:b.isArray?[]:new c(e),s={};l(b,function(a,b){b!="params"&&b!="isArray"&&(s[b]=t(a))});s.data=e;n.setUrlParams(s,m({},
|
8
|
+
j(e,b.params||{}),i),b.url);i=x(s);h.$resolved=!1;i.then(f,f);h.$then=i.then(function(a){var d=a.data,g=h.$then,e=h.$resolved;if(d)b.isArray?(h.length=0,l(d,function(a){h.push(new c(a))})):(t(d,h),h.$then=g,h.$resolved=e);(o||q)(h,a.headers);a.resource=h;return a},r).then;return h};c.prototype["$"+d]=function(a,b,g){var e=j(this),f=q,i;switch(arguments.length){case 3:e=a;f=b;i=g;break;case 2:case 1:k(a)?(f=a,i=b):(e=a,f=b||q);case 0:break;default:throw"Expected between 1-3 arguments [params, success, error], got "+
|
9
|
+
arguments.length+" arguments.";}c[d].call(this,e,p?this:w,f,i)}});c.bind=function(c){return v(b,m({},d,c),e)};return c}var z={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},q=f.noop,l=f.forEach,m=f.extend,t=f.copy,k=f.isFunction;u.prototype={setUrlParams:function(b,d,e){var j=this,c=e||j.template,n,k,m=j.urlParams={};l(c.split(/\W/),function(b){b&&RegExp("(^|[^\\\\]):"+b+"(\\W|$)").test(c)&&(m[b]=!0)});c=c.replace(/\\:/g,
|
10
|
+
":");d=d||{};l(j.urlParams,function(b,a){n=d.hasOwnProperty(a)?d[a]:j.defaults[a];f.isDefined(n)&&n!==null?(k=encodeURIComponent(n).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),c=c.replace(RegExp(":"+a+"(\\W|$)","g"),k+"$1")):c=c.replace(RegExp("(/?):"+a+"(\\W|$)","g"),function(b,a,c){return c.charAt(0)=="/"?c:a+c})});c=c.replace(/\/+$/,"");c=c.replace(/\/\.(?=\w+($|\?))/,".");
|
11
|
+
b.url=c.replace(/\/\\\./,"/.");l(d,function(c,a){if(!j.urlParams[a])b.params=b.params||{},b.params[a]=c})}};return v}])})(window,window.angular);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.
|
2
|
+
* @license AngularJS v1.1.5
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -129,7 +129,7 @@ var START_TAG_REGEXP = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:
|
|
129
129
|
BEGING_END_TAGE_REGEXP = /^<\s*\//,
|
130
130
|
COMMENT_REGEXP = /<!--(.*?)-->/g,
|
131
131
|
CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
|
132
|
-
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|#)/,
|
132
|
+
URI_REGEXP = /^((ftp|https?):\/\/|mailto:|tel:|#)/,
|
133
133
|
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // Match everything outside of normal chars and " (quote character)
|
134
134
|
|
135
135
|
|
@@ -433,6 +433,7 @@ angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($san
|
|
433
433
|
* plain email address links.
|
434
434
|
*
|
435
435
|
* @param {string} text Input text.
|
436
|
+
* @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
|
436
437
|
* @returns {string} Html-linkified text.
|
437
438
|
*
|
438
439
|
* @usage
|
@@ -449,6 +450,7 @@ angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($san
|
|
449
450
|
'mailto:us@somewhere.org,\n'+
|
450
451
|
'another@somewhere.org,\n'+
|
451
452
|
'and one more: ftp://127.0.0.1/.';
|
453
|
+
$scope.snippetWithTarget = 'http://angularjs.org/';
|
452
454
|
}
|
453
455
|
</script>
|
454
456
|
<div ng-controller="Ctrl">
|
@@ -468,6 +470,15 @@ angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($san
|
|
468
470
|
<div ng-bind-html="snippet | linky"></div>
|
469
471
|
</td>
|
470
472
|
</tr>
|
473
|
+
<tr id="linky-target">
|
474
|
+
<td>linky target</td>
|
475
|
+
<td>
|
476
|
+
<pre><div ng-bind-html="snippetWithTarget | linky:'_blank'"><br></div></pre>
|
477
|
+
</td>
|
478
|
+
<td>
|
479
|
+
<div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
|
480
|
+
</td>
|
481
|
+
</tr>
|
471
482
|
<tr id="escaped-html">
|
472
483
|
<td>no filter</td>
|
473
484
|
<td><pre><div ng-bind="snippet"><br></div></pre></td>
|
@@ -500,6 +511,11 @@ angular.module('ngSanitize').directive('ngBindHtml', ['$sanitize', function($san
|
|
500
511
|
toBe('new <a href="http://link">http://link</a>.');
|
501
512
|
expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
|
502
513
|
});
|
514
|
+
|
515
|
+
it('should work with the target property', function() {
|
516
|
+
expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")).
|
517
|
+
toBe('<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>');
|
518
|
+
});
|
503
519
|
</doc:scenario>
|
504
520
|
</doc:example>
|
505
521
|
*/
|
@@ -507,7 +523,7 @@ angular.module('ngSanitize').filter('linky', function() {
|
|
507
523
|
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,
|
508
524
|
MAILTO_REGEXP = /^mailto:/;
|
509
525
|
|
510
|
-
return function(text) {
|
526
|
+
return function(text, target) {
|
511
527
|
if (!text) return text;
|
512
528
|
var match;
|
513
529
|
var raw = text;
|
@@ -516,6 +532,10 @@ angular.module('ngSanitize').filter('linky', function() {
|
|
516
532
|
var writer = htmlSanitizeWriter(html);
|
517
533
|
var url;
|
518
534
|
var i;
|
535
|
+
var properties = {};
|
536
|
+
if (angular.isDefined(target)) {
|
537
|
+
properties.target = target;
|
538
|
+
}
|
519
539
|
while ((match = raw.match(LINKY_URL_REGEXP))) {
|
520
540
|
// We can not end in these as they are sometimes found at the end of the sentence
|
521
541
|
url = match[0];
|
@@ -523,7 +543,8 @@ angular.module('ngSanitize').filter('linky', function() {
|
|
523
543
|
if (match[2] == match[3]) url = 'mailto:' + url;
|
524
544
|
i = match.index;
|
525
545
|
writer.chars(raw.substr(0, i));
|
526
|
-
|
546
|
+
properties.href = url;
|
547
|
+
writer.start('a', properties);
|
527
548
|
writer.chars(match[0].replace(MAILTO_REGEXP, ''));
|
528
549
|
writer.end('a');
|
529
550
|
raw = raw.substring(i + match[0].length);
|
@@ -1,13 +1,13 @@
|
|
1
1
|
/*
|
2
|
-
AngularJS v1.
|
2
|
+
AngularJS v1.1.5
|
3
3
|
(c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
License: MIT
|
5
5
|
*/
|
6
|
-
(function(I,
|
7
|
-
|
8
|
-
|
9
|
-
!0&&(
|
10
|
-
E=/<!\[CDATA\[(.*?)]]\>/g,H=/^((ftp|https?):\/\/|mailto:|#)/,F=/([^\#-~| |!])/g,p=i("area,br,col,hr,img,wbr"),x=i("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),y=i("rp,rt"),o=
|
11
|
-
q=i("script,style"),v=
|
12
|
-
z(a,u(d));return d.join("")});
|
13
|
-
|
6
|
+
(function(I,h){'use strict';function i(a){var d={},a=a.split(","),c;for(c=0;c<a.length;c++)d[a[c]]=!0;return d}function z(a,d){function c(a,b,c,f){b=h.lowercase(b);if(m[b])for(;e.last()&&n[e.last()];)g("",e.last());o[b]&&e.last()==b&&g("",b);(f=p[b]||!!f)||e.push(b);var j={};c.replace(A,function(a,b,d,c,g){j[b]=k(d||c||g||"")});d.start&&d.start(b,j,f)}function g(a,b){var c=0,g;if(b=h.lowercase(b))for(c=e.length-1;c>=0;c--)if(e[c]==b)break;if(c>=0){for(g=e.length-1;g>=c;g--)d.end&&d.end(e[g]);e.length=
|
7
|
+
c}}var b,f,e=[],j=a;for(e.last=function(){return e[e.length-1]};a;){f=!0;if(!e.last()||!q[e.last()]){if(a.indexOf("<\!--")===0)b=a.indexOf("--\>"),b>=0&&(d.comment&&d.comment(a.substring(4,b)),a=a.substring(b+3),f=!1);else if(B.test(a)){if(b=a.match(r))a=a.substring(b[0].length),b[0].replace(r,g),f=!1}else if(C.test(a)&&(b=a.match(s)))a=a.substring(b[0].length),b[0].replace(s,c),f=!1;f&&(b=a.indexOf("<"),f=b<0?a:a.substring(0,b),a=b<0?"":a.substring(b),d.chars&&d.chars(k(f)))}else a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+
|
8
|
+
e.last()+"[^>]*>","i"),function(a,b){b=b.replace(D,"$1").replace(E,"$1");d.chars&&d.chars(k(b));return""}),g("",e.last());if(a==j)throw"Parse Error: "+a;j=a}g()}function k(a){l.innerHTML=a.replace(/</g,"<");return l.innerText||l.textContent||""}function t(a){return a.replace(/&/g,"&").replace(F,function(a){return"&#"+a.charCodeAt(0)+";"}).replace(/</g,"<").replace(/>/g,">")}function u(a){var d=!1,c=h.bind(a,a.push);return{start:function(a,b,f){a=h.lowercase(a);!d&&q[a]&&(d=a);!d&&v[a]==
|
9
|
+
!0&&(c("<"),c(a),h.forEach(b,function(a,b){var d=h.lowercase(b);if(G[d]==!0&&(w[d]!==!0||a.match(H)))c(" "),c(b),c('="'),c(t(a)),c('"')}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);!d&&v[a]==!0&&(c("</"),c(a),c(">"));a==d&&(d=!1)},chars:function(a){d||c(t(a))}}}var s=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,r=/^<\s*\/\s*([\w:-]+)[^>]*>/,A=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,C=/^</,B=/^<\s*\//,D=/<\!--(.*?)--\>/g,
|
10
|
+
E=/<!\[CDATA\[(.*?)]]\>/g,H=/^((ftp|https?):\/\/|mailto:|tel:|#)/,F=/([^\#-~| |!])/g,p=i("area,br,col,hr,img,wbr"),x=i("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),y=i("rp,rt"),o=h.extend({},y,x),m=h.extend({},x,i("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),n=h.extend({},y,i("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),
|
11
|
+
q=i("script,style"),v=h.extend({},p,m,n,o),w=i("background,cite,href,longdesc,src,usemap"),G=h.extend({},w,i("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,span,start,summary,target,title,type,valign,value,vspace,width")),l=document.createElement("pre");h.module("ngSanitize",[]).value("$sanitize",function(a){var d=[];
|
12
|
+
z(a,u(d));return d.join("")});h.module("ngSanitize").directive("ngBindHtml",["$sanitize",function(a){return function(d,c,g){c.addClass("ng-binding").data("$binding",g.ngBindHtml);d.$watch(g.ngBindHtml,function(b){b=a(b);c.html(b||"")})}}]);h.module("ngSanitize").filter("linky",function(){var a=/((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}\<\>]/,d=/^mailto:/;return function(c,g){if(!c)return c;var b,f=c,e=[],j=u(e),i,k,l={};if(h.isDefined(g))l.target=g;for(;b=f.match(a);)i=
|
13
|
+
b[0],b[2]==b[3]&&(i="mailto:"+i),k=b.index,j.chars(f.substr(0,k)),l.href=i,j.start("a",l),j.chars(b[0].replace(d,"")),j.end("a"),f=f.substring(k+b[0].length);j.chars(f);return e.join("")}})})(window,window.angular);
|