angular-rails-engine 1.0.7.0 → 1.1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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);
|