ui_alchemy-rails 1.0.10 → 1.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/stylesheets/alchemy/components/fonts/_liberation.scss +14 -13
- data/app/assets/stylesheets/alchemy/components/fonts/_overpass.scss +10 -8
- data/lib/ui_alchemy/rails/version.rb +1 -1
- data/vendor/assets/javascripts/alchemy/jquery/plugins/jquery.jeditable.js +8 -0
- data/vendor/assets/ui_alchemy/alchemy-header/alchemy-header.js +114 -107
- data/vendor/assets/ui_alchemy/alchemy-header/alchemy-header.min.js +1 -1
- data/vendor/assets/ui_alchemy/alchemy-header/bower.json +28 -0
- data/vendor/assets/ui_alchemy/alchemy-header/component.json +2 -14
- data/vendor/assets/ui_alchemy/alchemy-header/header.scss +114 -160
- data/vendor/assets/ui_alchemy/angular/angular.js +276 -189
- data/vendor/assets/ui_alchemy/angular/angular.min.js +159 -158
- data/vendor/assets/ui_alchemy/angular/{component.json → bower.json} +3 -3
- data/vendor/assets/ui_alchemy/jquery/component.json +1 -1
- data/vendor/assets/ui_alchemy/jquery/composer.json +5 -0
- metadata +4 -3
@@ -1,8 +1,10 @@
|
|
1
|
+
@import "compass";
|
2
|
+
|
1
3
|
$nav-header_background: #FFA500 !default;
|
2
4
|
$logo-header_background: darken($nav-header_background, 10%) !default;
|
3
5
|
$menu-item_hover: darken($nav-header_background, 10%) !default;
|
4
6
|
$link_color: #000 !default;
|
5
|
-
$link-hover_color: lighten($link_color,
|
7
|
+
$link-hover_color: lighten($link_color, 100%) !default;
|
6
8
|
$link-border_color: lighten($nav-header_background, 30%) !default;
|
7
9
|
$dropdown-link-hover_background: #000 !default;
|
8
10
|
$nav-header_top_border: lighten($nav-header_background, 10%) !default;
|
@@ -10,190 +12,108 @@ $menu-item_hover_background: darken($logo-header_background, 10%) !default;
|
|
10
12
|
$menu-item_active_background: darken($logo-header_background, 10%) !default;
|
11
13
|
|
12
14
|
.left { float: left; }
|
13
|
-
.right {
|
14
|
-
|
15
|
-
.logo-header {
|
16
|
-
$logo-header_line_height: 25px;
|
17
|
-
|
18
|
-
height: $logo-header_line_height;
|
19
|
-
background-color: $logo-header_background;
|
20
|
-
z-index: 100;
|
21
|
-
line-height: $logo-header_line_height;
|
22
|
-
|
23
|
-
.logo {
|
24
|
-
margin-left: 30px;
|
25
|
-
}
|
26
|
-
|
27
|
-
.menu-container {
|
28
|
-
line-height: $logo-header_line_height;
|
29
|
-
|
30
|
-
.menu-item {
|
31
|
-
line-height: $logo-header_line_height;
|
32
|
-
|
33
|
-
.menu-item-link {
|
34
|
-
white-space: nowrap;
|
35
|
-
text-overflow: ellipsis;
|
36
|
-
@include transition( all .15s ease-in);
|
37
|
-
text-align: center;
|
38
|
-
font-family: overpass, sans-serif, sans;
|
39
|
-
text-decoration: none;
|
40
|
-
margin: 0 auto;
|
41
|
-
|
42
|
-
&:hover {
|
43
|
-
@include transition( all 0.3s ease-in-out);
|
44
|
-
|
45
|
-
color: $link-hover_color;
|
46
|
-
background: $menu-item_hover_background;
|
47
|
-
}
|
48
|
-
|
49
|
-
&.active-item {
|
50
|
-
color: $link-hover_color;
|
51
|
-
background: $menu-item_active_background;
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
.dropdown-active {
|
58
|
-
box-shadow: none;
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
.nav-header {
|
63
|
-
min-height: 40px;
|
64
|
-
background: $nav-header_background;
|
65
|
-
border-top: 1px solid $nav-header_top_border;
|
66
|
-
|
67
|
-
.menu-item {
|
68
|
-
font-family: Overpass;
|
69
|
-
line-height: 37px;
|
70
|
-
vertical-align: baseline;
|
71
|
-
font-size: 14px;
|
72
|
-
position: relative;
|
15
|
+
.right {
|
16
|
+
float: right;
|
73
17
|
|
74
|
-
|
75
|
-
|
76
|
-
white-space: nowrap;
|
77
|
-
text-overflow: ellipsis;
|
78
|
-
text-align: center;
|
79
|
-
font-family: overpass, sans-serif, sans;
|
80
|
-
text-decoration: none;
|
81
|
-
margin: 0 auto;
|
82
|
-
color: $link_color;
|
83
|
-
|
84
|
-
&:hover {
|
85
|
-
@include transition( all 0.15s ease-in-out);
|
86
|
-
border-bottom: 3px solid $link-border_color;
|
87
|
-
color: $link-hover_color;
|
88
|
-
background: $menu-item_hover_background;
|
89
|
-
box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
|
90
|
-
}
|
91
|
-
|
92
|
-
&.active-item {
|
93
|
-
box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
|
94
|
-
color: $link-hover_color;
|
95
|
-
border-bottom: 3px solid $link-border_color;
|
96
|
-
background: $menu-item_hover_background;
|
97
|
-
}
|
98
|
-
}
|
18
|
+
.menu-item .dropdown {
|
19
|
+
right: -1px;
|
99
20
|
}
|
100
21
|
}
|
101
22
|
|
102
23
|
.menu-container {
|
103
24
|
position: relative;
|
104
|
-
left: 0;
|
105
25
|
display: block;
|
106
26
|
float: left;
|
107
27
|
margin: 0;
|
108
28
|
list-style: none;
|
109
|
-
line-height: 40px;
|
110
29
|
|
111
30
|
.menu-item {
|
112
|
-
line-height:
|
31
|
+
line-height: 40px;
|
113
32
|
position: relative;
|
114
33
|
margin: 0;
|
115
34
|
float: left;
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
padding: 0 15px;
|
120
|
-
text-decoration: none;
|
121
|
-
display: block;
|
122
|
-
cursor: default;
|
123
|
-
@include box-sizing(border-box);
|
124
|
-
}
|
35
|
+
font-family: Overpass;
|
36
|
+
vertical-align: baseline;
|
37
|
+
font-size: 14px;
|
125
38
|
}
|
126
|
-
}
|
127
39
|
|
128
|
-
.menu-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
40
|
+
.menu-item-link {
|
41
|
+
@include transition( all .15s ease-in);
|
42
|
+
float: none;
|
43
|
+
padding: 0 15px;
|
44
|
+
margin: 0 auto;
|
45
|
+
display: block;
|
46
|
+
cursor: pointer;
|
47
|
+
white-space: nowrap;
|
48
|
+
text-overflow: ellipsis;
|
49
|
+
text-align: center;
|
50
|
+
font-family: overpass, sans-serif, sans;
|
51
|
+
text-decoration: none;
|
52
|
+
color: $link_color;
|
133
53
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
width: 100%;
|
141
|
-
z-index: 100;
|
142
|
-
}
|
54
|
+
&:hover {
|
55
|
+
@include transition( all 0.15s ease-in-out);
|
56
|
+
color: $link-hover_color;
|
57
|
+
background: $menu-item_hover_background;
|
58
|
+
box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
|
59
|
+
}
|
143
60
|
|
144
|
-
|
145
|
-
|
61
|
+
&.active-item {
|
62
|
+
box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
|
63
|
+
color: $link-hover_color;
|
64
|
+
background: $menu-item_hover_background;
|
65
|
+
}
|
66
|
+
}
|
146
67
|
|
68
|
+
.menu-anchor {
|
69
|
+
cursor: default;
|
70
|
+
}
|
147
71
|
}
|
148
72
|
|
149
73
|
.dropdown {
|
150
|
-
position:
|
151
|
-
top: 100%;
|
152
|
-
left: -1px;
|
153
|
-
float: left;
|
154
|
-
min-width: 200px;
|
74
|
+
position: fixed;
|
155
75
|
display: none;
|
156
76
|
list-style: none;
|
157
77
|
border-radius: 0 0 5px 5px;
|
158
78
|
padding: 0;
|
159
79
|
z-index: 3;
|
160
|
-
@include box-sizing(border-box);
|
161
|
-
|
162
80
|
border: 1px solid #C8C8C8;
|
163
81
|
border-top: none;
|
164
82
|
box-shadow: 0px 1px 5px #C8C8C8;
|
165
83
|
background: white;
|
166
84
|
opacity: 1;
|
167
|
-
|
85
|
+
min-width: 160px;
|
168
86
|
|
169
|
-
.dropdown-
|
170
|
-
}
|
171
|
-
|
172
|
-
li {
|
87
|
+
.dropdown-item {
|
173
88
|
text-align: left;
|
174
89
|
line-height: 35px;
|
175
90
|
position: relative;
|
176
91
|
display: block;
|
177
|
-
|
92
|
+
float: none;
|
93
|
+
}
|
178
94
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
95
|
+
.dropdown-item-link {
|
96
|
+
text-decoration: none;
|
97
|
+
color: #000;
|
98
|
+
text-decoration: none;
|
99
|
+
display: block;
|
100
|
+
padding: 5px 5px 5px 20px;
|
101
|
+
overflow: auto;
|
185
102
|
|
186
|
-
|
187
|
-
|
103
|
+
span { float: left; }
|
104
|
+
}
|
188
105
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
}
|
193
|
-
}
|
106
|
+
.dropdown-item-link-active {
|
107
|
+
background: $dropdown-link-hover_background;
|
108
|
+
color: $link-hover_color;
|
194
109
|
}
|
195
110
|
}
|
196
111
|
|
112
|
+
.dropdown-active {
|
113
|
+
@include transition(all 0.4s ease-in);
|
114
|
+
display: block;
|
115
|
+
}
|
116
|
+
|
197
117
|
.dropdown-left {
|
198
118
|
left: 0;
|
199
119
|
}
|
@@ -203,15 +123,12 @@ $menu-item_active_background: darken($logo-header_background, 10%) !default;
|
|
203
123
|
left: auto;
|
204
124
|
}
|
205
125
|
|
206
|
-
.dropdown-active {
|
207
|
-
@include transition(all 0.4s ease-in);
|
208
|
-
display: block;
|
209
|
-
}
|
210
|
-
|
211
126
|
.flyout-indicator {
|
212
|
-
margin-top:
|
213
|
-
float: right;
|
127
|
+
margin-top: 8px;
|
214
128
|
margin-right: 5px;
|
129
|
+
margin-left: 10px;
|
130
|
+
font-size: 18px;
|
131
|
+
float: right;
|
215
132
|
}
|
216
133
|
|
217
134
|
.flyout {
|
@@ -220,34 +137,71 @@ $menu-item_active_background: darken($logo-header_background, 10%) !default;
|
|
220
137
|
position: absolute;
|
221
138
|
top: -1px;
|
222
139
|
left: 100%;
|
223
|
-
min-width:
|
140
|
+
min-width: 160px;
|
224
141
|
border: 1px solid #C8C8C8;
|
225
142
|
border-radius: 0 3px 3px 3px;
|
226
143
|
box-shadow: 1px 0px 5px #C8C8C8;
|
227
144
|
z-index: 2;
|
228
145
|
background: white;
|
229
146
|
|
230
|
-
|
147
|
+
.flyout-item {
|
231
148
|
text-align: left;
|
232
149
|
line-height: 35px;
|
233
150
|
position: relative;
|
234
151
|
display: block;
|
235
152
|
clear: both;
|
153
|
+
}
|
236
154
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
}
|
155
|
+
.flyout-item-link {
|
156
|
+
color: #000;
|
157
|
+
text-decoration: none;
|
158
|
+
display: block;
|
159
|
+
padding: 5px 20px 5px 20px;
|
243
160
|
|
244
161
|
&:hover {
|
245
162
|
background: $dropdown-link-hover_background;
|
163
|
+
color: $link-hover_color;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
246
167
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
168
|
+
.logo-header {
|
169
|
+
$logo-header_line_height: 25px;
|
170
|
+
|
171
|
+
height: $logo-header_line_height;
|
172
|
+
background-color: $logo-header_background;
|
173
|
+
z-index: 3;
|
174
|
+
|
175
|
+
.logo {
|
176
|
+
margin-left: 30px;
|
177
|
+
}
|
178
|
+
|
179
|
+
.menu-container {
|
180
|
+
line-height: $logo-header_line_height;
|
181
|
+
|
182
|
+
.menu-item {
|
183
|
+
line-height: $logo-header_line_height;
|
251
184
|
}
|
252
185
|
}
|
186
|
+
|
187
|
+
.dropdown-active {
|
188
|
+
box-shadow: none;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
.nav-header {
|
193
|
+
background: $nav-header_background;
|
194
|
+
border-top: 1px solid $nav-header_top_border;
|
195
|
+
width: 100%;
|
196
|
+
overflow: auto;
|
197
|
+
}
|
198
|
+
|
199
|
+
.compact {
|
200
|
+
position:fixed;
|
201
|
+
vertical-align:middle;
|
202
|
+
top: 0;
|
203
|
+
padding:0;
|
204
|
+
margin: 0;
|
205
|
+
width: 100%;
|
206
|
+
z-index: 2;
|
253
207
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license AngularJS v1.0.
|
2
|
+
* @license AngularJS v1.0.7
|
3
3
|
* (c) 2010-2012 Google, Inc. http://angularjs.org
|
4
4
|
* License: MIT
|
5
5
|
*/
|
@@ -67,6 +67,29 @@ var /** holds major version number for IE or NaN for real browsers */
|
|
67
67
|
nodeName_,
|
68
68
|
uid = ['0', '0', '0'];
|
69
69
|
|
70
|
+
|
71
|
+
/**
|
72
|
+
* @private
|
73
|
+
* @param {*} obj
|
74
|
+
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
|
75
|
+
*/
|
76
|
+
function isArrayLike(obj) {
|
77
|
+
if (!obj || (typeof obj.length !== 'number')) return false;
|
78
|
+
|
79
|
+
// We have on object which has length property. Should we treat it as array?
|
80
|
+
if (typeof obj.hasOwnProperty != 'function' &&
|
81
|
+
typeof obj.constructor != 'function') {
|
82
|
+
// This is here for IE8: it is a bogus object treat it as array;
|
83
|
+
return true;
|
84
|
+
} else {
|
85
|
+
return obj instanceof JQLite || // JQLite
|
86
|
+
(jQuery && obj instanceof jQuery) || // jQuery
|
87
|
+
toString.call(obj) !== '[object Object]' || // some browser native object
|
88
|
+
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
|
70
93
|
/**
|
71
94
|
* @ngdoc function
|
72
95
|
* @name angular.forEach
|
@@ -94,30 +117,6 @@ var /** holds major version number for IE or NaN for real browsers */
|
|
94
117
|
* @param {Object=} context Object to become context (`this`) for the iterator function.
|
95
118
|
* @returns {Object|Array} Reference to `obj`.
|
96
119
|
*/
|
97
|
-
|
98
|
-
|
99
|
-
/**
|
100
|
-
* @private
|
101
|
-
* @param {*} obj
|
102
|
-
* @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
|
103
|
-
*/
|
104
|
-
function isArrayLike(obj) {
|
105
|
-
if (!obj || (typeof obj.length !== 'number')) return false;
|
106
|
-
|
107
|
-
// We have on object which has length property. Should we treat it as array?
|
108
|
-
if (typeof obj.hasOwnProperty != 'function' &&
|
109
|
-
typeof obj.constructor != 'function') {
|
110
|
-
// This is here for IE8: it is a bogus object treat it as array;
|
111
|
-
return true;
|
112
|
-
} else {
|
113
|
-
return obj instanceof JQLite || // JQLite
|
114
|
-
(jQuery && obj instanceof jQuery) || // jQuery
|
115
|
-
toString.call(obj) !== '[object Object]' || // some browser native object
|
116
|
-
typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
|
117
|
-
}
|
118
|
-
}
|
119
|
-
|
120
|
-
|
121
120
|
function forEach(obj, iterator, context) {
|
122
121
|
var key;
|
123
122
|
if (obj) {
|
@@ -201,6 +200,21 @@ function nextUid() {
|
|
201
200
|
return uid.join('');
|
202
201
|
}
|
203
202
|
|
203
|
+
|
204
|
+
/**
|
205
|
+
* Set or clear the hashkey for an object.
|
206
|
+
* @param obj object
|
207
|
+
* @param h the hashkey (!truthy to delete the hashkey)
|
208
|
+
*/
|
209
|
+
function setHashKey(obj, h) {
|
210
|
+
if (h) {
|
211
|
+
obj.$$hashKey = h;
|
212
|
+
}
|
213
|
+
else {
|
214
|
+
delete obj.$$hashKey;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
204
218
|
/**
|
205
219
|
* @ngdoc function
|
206
220
|
* @name angular.extend
|
@@ -212,8 +226,10 @@ function nextUid() {
|
|
212
226
|
*
|
213
227
|
* @param {Object} dst Destination object.
|
214
228
|
* @param {...Object} src Source object(s).
|
229
|
+
* @returns {Object} Reference to `dst`.
|
215
230
|
*/
|
216
231
|
function extend(dst) {
|
232
|
+
var h = dst.$$hashKey;
|
217
233
|
forEach(arguments, function(obj){
|
218
234
|
if (obj !== dst) {
|
219
235
|
forEach(obj, function(value, key){
|
@@ -221,6 +237,8 @@ function extend(dst) {
|
|
221
237
|
});
|
222
238
|
}
|
223
239
|
});
|
240
|
+
|
241
|
+
setHashKey(dst,h);
|
224
242
|
return dst;
|
225
243
|
}
|
226
244
|
|
@@ -575,12 +593,14 @@ function copy(source, destination){
|
|
575
593
|
destination.push(copy(source[i]));
|
576
594
|
}
|
577
595
|
} else {
|
596
|
+
var h = destination.$$hashKey;
|
578
597
|
forEach(destination, function(value, key){
|
579
598
|
delete destination[key];
|
580
599
|
});
|
581
600
|
for ( var key in source) {
|
582
601
|
destination[key] = copy(source[key]);
|
583
602
|
}
|
603
|
+
setHashKey(destination,h);
|
584
604
|
}
|
585
605
|
}
|
586
606
|
return destination;
|
@@ -620,7 +640,7 @@ function shallowCopy(src, dst) {
|
|
620
640
|
* During a property comparision, properties of `function` type and properties with names
|
621
641
|
* that begin with `$` are ignored.
|
622
642
|
*
|
623
|
-
* Scope and DOMWindow objects are being compared only
|
643
|
+
* Scope and DOMWindow objects are being compared only by identify (`===`).
|
624
644
|
*
|
625
645
|
* @param {*} o1 Object or value to compare.
|
626
646
|
* @param {*} o2 Object or value to compare.
|
@@ -680,7 +700,7 @@ function sliceArgs(args, startIndex) {
|
|
680
700
|
*
|
681
701
|
* @description
|
682
702
|
* Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
|
683
|
-
* `fn`). You can supply optional `args` that are
|
703
|
+
* `fn`). You can supply optional `args` that are prebound to the function. This feature is also
|
684
704
|
* known as [function currying](http://en.wikipedia.org/wiki/Currying).
|
685
705
|
*
|
686
706
|
* @param {Object} self Context which `fn` should be evaluated in.
|
@@ -873,7 +893,7 @@ function encodeUriQuery(val, pctEncodeSpaces) {
|
|
873
893
|
*
|
874
894
|
* @description
|
875
895
|
*
|
876
|
-
* Use this directive to auto-bootstrap
|
896
|
+
* Use this directive to auto-bootstrap an application. Only
|
877
897
|
* one directive can be used per HTML document. The directive
|
878
898
|
* designates the root of the application and is typically placed
|
879
899
|
* at the root of the page.
|
@@ -1012,7 +1032,7 @@ function bindJQuery() {
|
|
1012
1032
|
}
|
1013
1033
|
|
1014
1034
|
/**
|
1015
|
-
* throw error
|
1035
|
+
* throw error if the argument is falsy.
|
1016
1036
|
*/
|
1017
1037
|
function assertArg(arg, name, reason) {
|
1018
1038
|
if (!arg) {
|
@@ -1293,11 +1313,11 @@ function setupModuleLoader(window) {
|
|
1293
1313
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
1294
1314
|
*/
|
1295
1315
|
var version = {
|
1296
|
-
full: '1.0.
|
1316
|
+
full: '1.0.7', // all of these placeholder strings will be replaced by grunt's
|
1297
1317
|
major: 1, // package task
|
1298
1318
|
minor: 0,
|
1299
|
-
dot:
|
1300
|
-
codeName: '
|
1319
|
+
dot: 7,
|
1320
|
+
codeName: 'monochromatic-rainbow'
|
1301
1321
|
};
|
1302
1322
|
|
1303
1323
|
|
@@ -1442,18 +1462,18 @@ function publishExternalAPI(angular){
|
|
1442
1462
|
* - [after()](http://api.jquery.com/after/)
|
1443
1463
|
* - [append()](http://api.jquery.com/append/)
|
1444
1464
|
* - [attr()](http://api.jquery.com/attr/)
|
1445
|
-
* - [bind()](http://api.jquery.com/bind/)
|
1446
|
-
* - [children()](http://api.jquery.com/children/)
|
1465
|
+
* - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
|
1466
|
+
* - [children()](http://api.jquery.com/children/) - Does not support selectors
|
1447
1467
|
* - [clone()](http://api.jquery.com/clone/)
|
1448
1468
|
* - [contents()](http://api.jquery.com/contents/)
|
1449
1469
|
* - [css()](http://api.jquery.com/css/)
|
1450
1470
|
* - [data()](http://api.jquery.com/data/)
|
1451
1471
|
* - [eq()](http://api.jquery.com/eq/)
|
1452
|
-
* - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
|
1472
|
+
* - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name
|
1453
1473
|
* - [hasClass()](http://api.jquery.com/hasClass/)
|
1454
1474
|
* - [html()](http://api.jquery.com/html/)
|
1455
|
-
* - [next()](http://api.jquery.com/next/)
|
1456
|
-
* - [parent()](http://api.jquery.com/parent/)
|
1475
|
+
* - [next()](http://api.jquery.com/next/) - Does not support selectors
|
1476
|
+
* - [parent()](http://api.jquery.com/parent/) - Does not support selectors
|
1457
1477
|
* - [prepend()](http://api.jquery.com/prepend/)
|
1458
1478
|
* - [prop()](http://api.jquery.com/prop/)
|
1459
1479
|
* - [ready()](http://api.jquery.com/ready/)
|
@@ -1465,7 +1485,7 @@ function publishExternalAPI(angular){
|
|
1465
1485
|
* - [text()](http://api.jquery.com/text/)
|
1466
1486
|
* - [toggleClass()](http://api.jquery.com/toggleClass/)
|
1467
1487
|
* - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Doesn't pass native event objects to handlers.
|
1468
|
-
* - [unbind()](http://api.jquery.com/unbind/)
|
1488
|
+
* - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
|
1469
1489
|
* - [val()](http://api.jquery.com/val/)
|
1470
1490
|
* - [wrap()](http://api.jquery.com/wrap/)
|
1471
1491
|
*
|
@@ -2012,23 +2032,43 @@ forEach({
|
|
2012
2032
|
|
2013
2033
|
if (!eventFns) {
|
2014
2034
|
if (type == 'mouseenter' || type == 'mouseleave') {
|
2015
|
-
var
|
2035
|
+
var contains = document.body.contains || document.body.compareDocumentPosition ?
|
2036
|
+
function( a, b ) {
|
2037
|
+
var adown = a.nodeType === 9 ? a.documentElement : a,
|
2038
|
+
bup = b && b.parentNode;
|
2039
|
+
return a === bup || !!( bup && bup.nodeType === 1 && (
|
2040
|
+
adown.contains ?
|
2041
|
+
adown.contains( bup ) :
|
2042
|
+
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
2043
|
+
));
|
2044
|
+
} :
|
2045
|
+
function( a, b ) {
|
2046
|
+
if ( b ) {
|
2047
|
+
while ( (b = b.parentNode) ) {
|
2048
|
+
if ( b === a ) {
|
2049
|
+
return true;
|
2050
|
+
}
|
2051
|
+
}
|
2052
|
+
}
|
2053
|
+
return false;
|
2054
|
+
};
|
2016
2055
|
|
2017
|
-
events
|
2018
|
-
|
2056
|
+
events[type] = [];
|
2057
|
+
|
2058
|
+
// Refer to jQuery's implementation of mouseenter & mouseleave
|
2059
|
+
// Read about mouseenter and mouseleave:
|
2060
|
+
// http://www.quirksmode.org/js/events_mouse.html#link8
|
2061
|
+
var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}
|
2062
|
+
bindFn(element, eventmap[type], function(event) {
|
2063
|
+
var ret, target = this, related = event.relatedTarget;
|
2064
|
+
// For mousenter/leave call the handler if related is outside the target.
|
2065
|
+
// NB: No relatedTarget if the mouse left/entered the browser window
|
2066
|
+
if ( !related || (related !== target && !contains(target, related)) ){
|
2067
|
+
handle(event, type);
|
2068
|
+
}
|
2019
2069
|
|
2020
|
-
bindFn(element, 'mouseover', function(event) {
|
2021
|
-
counter++;
|
2022
|
-
if (counter == 1) {
|
2023
|
-
handle(event, 'mouseenter');
|
2024
|
-
}
|
2025
|
-
});
|
2026
|
-
bindFn(element, 'mouseout', function(event) {
|
2027
|
-
counter --;
|
2028
|
-
if (counter == 0) {
|
2029
|
-
handle(event, 'mouseleave');
|
2030
|
-
}
|
2031
2070
|
});
|
2071
|
+
|
2032
2072
|
} else {
|
2033
2073
|
addEventListenerFn(element, type, handle);
|
2034
2074
|
events[type] = [];
|
@@ -2344,7 +2384,7 @@ function annotate(fn) {
|
|
2344
2384
|
}
|
2345
2385
|
} else if (isArray(fn)) {
|
2346
2386
|
last = fn.length - 1;
|
2347
|
-
assertArgFn(fn[last], 'fn')
|
2387
|
+
assertArgFn(fn[last], 'fn');
|
2348
2388
|
$inject = fn.slice(0, last);
|
2349
2389
|
} else {
|
2350
2390
|
assertArgFn(fn, 'fn', true);
|
@@ -2378,7 +2418,7 @@ function annotate(fn) {
|
|
2378
2418
|
* # Injection Function Annotation
|
2379
2419
|
*
|
2380
2420
|
* JavaScript does not have annotations, and annotations are needed for dependency injection. The
|
2381
|
-
* following
|
2421
|
+
* following are all valid ways of annotating function with injection arguments and are equivalent.
|
2382
2422
|
*
|
2383
2423
|
* <pre>
|
2384
2424
|
* // inferred (only works if code not minified/obfuscated)
|
@@ -2507,7 +2547,7 @@ function annotate(fn) {
|
|
2507
2547
|
* // ...
|
2508
2548
|
* };
|
2509
2549
|
* tmpFn.$inject = ['$compile', '$rootScope'];
|
2510
|
-
* injector.invoke(
|
2550
|
+
* injector.invoke(tmpFn);
|
2511
2551
|
*
|
2512
2552
|
* // To better support inline function the inline annotation is supported
|
2513
2553
|
* injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
|
@@ -2560,7 +2600,7 @@ function annotate(fn) {
|
|
2560
2600
|
*
|
2561
2601
|
* beforeEach(module(function($provide) {
|
2562
2602
|
* $provide.provider('greet', GreetProvider);
|
2563
|
-
* });
|
2603
|
+
* }));
|
2564
2604
|
*
|
2565
2605
|
* it('should greet', inject(function(greet) {
|
2566
2606
|
* expect(greet('angular')).toEqual('Hello angular!');
|
@@ -2573,9 +2613,7 @@ function annotate(fn) {
|
|
2573
2613
|
* inject(function(greet) {
|
2574
2614
|
* expect(greet('angular')).toEqual('Ahoj angular!');
|
2575
2615
|
* });
|
2576
|
-
* )
|
2577
|
-
*
|
2578
|
-
* });
|
2616
|
+
* });
|
2579
2617
|
* </pre>
|
2580
2618
|
*/
|
2581
2619
|
|
@@ -2669,7 +2707,7 @@ function annotate(fn) {
|
|
2669
2707
|
*
|
2670
2708
|
* @param {string} name The name of the service to decorate.
|
2671
2709
|
* @param {function()} decorator This function will be invoked when the service needs to be
|
2672
|
-
*
|
2710
|
+
* instantiated. The function is called using the {@link AUTO.$injector#invoke
|
2673
2711
|
* injector.invoke} method and is therefore fully injectable. Local injection arguments:
|
2674
2712
|
*
|
2675
2713
|
* * `$delegate` - The original service instance, which can be monkey patched, configured,
|
@@ -2869,6 +2907,8 @@ function createInjector(modulesToLoad) {
|
|
2869
2907
|
var Constructor = function() {},
|
2870
2908
|
instance, returnedValue;
|
2871
2909
|
|
2910
|
+
// Check if Type is annotated and use just the given function at n-1 as parameter
|
2911
|
+
// e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
|
2872
2912
|
Constructor.prototype = (isArray(Type) ? Type[Type.length - 1] : Type).prototype;
|
2873
2913
|
instance = new Constructor();
|
2874
2914
|
returnedValue = invoke(Type, instance, locals);
|
@@ -3249,7 +3289,13 @@ function Browser(window, document, $log, $sniffer) {
|
|
3249
3289
|
cookie = cookieArray[i];
|
3250
3290
|
index = cookie.indexOf('=');
|
3251
3291
|
if (index > 0) { //ignore nameless cookies
|
3252
|
-
|
3292
|
+
var name = unescape(cookie.substring(0, index));
|
3293
|
+
// the first value that is seen for a cookie is the most
|
3294
|
+
// specific one. values for the same cookie name that
|
3295
|
+
// follow are for less specific paths.
|
3296
|
+
if (lastCookies[name] === undefined) {
|
3297
|
+
lastCookies[name] = unescape(cookie.substring(index + 1));
|
3298
|
+
}
|
3253
3299
|
}
|
3254
3300
|
}
|
3255
3301
|
}
|
@@ -4054,9 +4100,9 @@ function $CompileProvider($provide) {
|
|
4054
4100
|
|
4055
4101
|
|
4056
4102
|
/**
|
4057
|
-
* Once the directives have been collected their compile functions
|
4103
|
+
* Once the directives have been collected, their compile functions are executed. This method
|
4058
4104
|
* is responsible for inlining directive templates as well as terminating the application
|
4059
|
-
* of the directives if the terminal directive has been reached
|
4105
|
+
* of the directives if the terminal directive has been reached.
|
4060
4106
|
*
|
4061
4107
|
* @param {Array} directives Array of collected directives to execute their compile function.
|
4062
4108
|
* this needs to be pre-sorted by priority order.
|
@@ -4064,11 +4110,11 @@ function $CompileProvider($provide) {
|
|
4064
4110
|
* @param {Object} templateAttrs The shared attribute function
|
4065
4111
|
* @param {function(angular.Scope[, cloneAttachFn]} transcludeFn A linking function, where the
|
4066
4112
|
* scope argument is auto-generated to the new child of the transcluded parent scope.
|
4067
|
-
* @param {
|
4068
|
-
* argument has the root jqLite array so that we can replace
|
4113
|
+
* @param {JQLite} jqCollection If we are working on the root of the compile tree then this
|
4114
|
+
* argument has the root jqLite array so that we can replace nodes on it.
|
4069
4115
|
* @returns linkFn
|
4070
4116
|
*/
|
4071
|
-
function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,
|
4117
|
+
function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection) {
|
4072
4118
|
var terminalPriority = -Number.MAX_VALUE,
|
4073
4119
|
preLinkFns = [],
|
4074
4120
|
postLinkFns = [],
|
@@ -4122,7 +4168,7 @@ function $CompileProvider($provide) {
|
|
4122
4168
|
$compileNode = templateAttrs.$$element =
|
4123
4169
|
jqLite(document.createComment(' ' + directiveName + ': ' + templateAttrs[directiveName] + ' '));
|
4124
4170
|
compileNode = $compileNode[0];
|
4125
|
-
replaceWith(
|
4171
|
+
replaceWith(jqCollection, jqLite($template[0]), compileNode);
|
4126
4172
|
childTranscludeFn = compile($template, transcludeFn, terminalPriority);
|
4127
4173
|
} else {
|
4128
4174
|
$template = jqLite(JQLiteClone(compileNode)).contents();
|
@@ -4146,7 +4192,7 @@ function $CompileProvider($provide) {
|
|
4146
4192
|
throw new Error(MULTI_ROOT_TEMPLATE_ERROR + directiveValue);
|
4147
4193
|
}
|
4148
4194
|
|
4149
|
-
replaceWith(
|
4195
|
+
replaceWith(jqCollection, $compileNode, compileNode);
|
4150
4196
|
|
4151
4197
|
var newTemplateAttrs = {$attr: {}};
|
4152
4198
|
|
@@ -4174,7 +4220,7 @@ function $CompileProvider($provide) {
|
|
4174
4220
|
assertNoDuplicate('template', templateDirective, directive, $compileNode);
|
4175
4221
|
templateDirective = directive;
|
4176
4222
|
nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i),
|
4177
|
-
nodeLinkFn, $compileNode, templateAttrs,
|
4223
|
+
nodeLinkFn, $compileNode, templateAttrs, jqCollection, directive.replace,
|
4178
4224
|
childTranscludeFn);
|
4179
4225
|
ii = directives.length;
|
4180
4226
|
} else if (directive.compile) {
|
@@ -4307,7 +4353,7 @@ function $CompileProvider($provide) {
|
|
4307
4353
|
parentGet = $parse(attrs[attrName]);
|
4308
4354
|
scope[scopeName] = function(locals) {
|
4309
4355
|
return parentGet(parentScope, locals);
|
4310
|
-
}
|
4356
|
+
};
|
4311
4357
|
break;
|
4312
4358
|
}
|
4313
4359
|
|
@@ -4795,7 +4841,7 @@ function $DocumentProvider(){
|
|
4795
4841
|
*
|
4796
4842
|
*/
|
4797
4843
|
function $ExceptionHandlerProvider() {
|
4798
|
-
this.$get = ['$log', function($log){
|
4844
|
+
this.$get = ['$log', function($log) {
|
4799
4845
|
return function(exception, cause) {
|
4800
4846
|
$log.error.apply($log, arguments);
|
4801
4847
|
};
|
@@ -5560,6 +5606,10 @@ function $LocationProvider(){
|
|
5560
5606
|
// update $location when $browser url changes
|
5561
5607
|
$browser.onUrlChange(function(newUrl) {
|
5562
5608
|
if ($location.absUrl() != newUrl) {
|
5609
|
+
if ($rootScope.$broadcast('$locationChangeStart', newUrl, $location.absUrl()).defaultPrevented) {
|
5610
|
+
$browser.url($location.absUrl());
|
5611
|
+
return;
|
5612
|
+
}
|
5563
5613
|
$rootScope.$evalAsync(function() {
|
5564
5614
|
var oldUrl = $location.absUrl();
|
5565
5615
|
|
@@ -5868,10 +5918,10 @@ function lex(text, csp){
|
|
5868
5918
|
function readIdent() {
|
5869
5919
|
var ident = "",
|
5870
5920
|
start = index,
|
5871
|
-
lastDot, peekIndex, methodName;
|
5921
|
+
lastDot, peekIndex, methodName, ch;
|
5872
5922
|
|
5873
5923
|
while (index < text.length) {
|
5874
|
-
|
5924
|
+
ch = text.charAt(index);
|
5875
5925
|
if (ch == '.' || isIdent(ch) || isNumber(ch)) {
|
5876
5926
|
if (ch == '.') lastDot = index;
|
5877
5927
|
ident += ch;
|
@@ -5885,7 +5935,7 @@ function lex(text, csp){
|
|
5885
5935
|
if (lastDot) {
|
5886
5936
|
peekIndex = index;
|
5887
5937
|
while(peekIndex < text.length) {
|
5888
|
-
|
5938
|
+
ch = text.charAt(peekIndex);
|
5889
5939
|
if (ch == '(') {
|
5890
5940
|
methodName = ident.substr(lastDot - start + 1);
|
5891
5941
|
ident = ident.substr(0, lastDot - start);
|
@@ -6138,8 +6188,8 @@ function parser(text, json, $filter, csp){
|
|
6138
6188
|
text.substring(0, token.index) + "] can not be assigned to", token);
|
6139
6189
|
}
|
6140
6190
|
right = logicalOR();
|
6141
|
-
return function(
|
6142
|
-
return left.assign(
|
6191
|
+
return function(scope, locals){
|
6192
|
+
return left.assign(scope, right(scope, locals), locals);
|
6143
6193
|
};
|
6144
6194
|
} else {
|
6145
6195
|
return left;
|
@@ -6256,12 +6306,12 @@ function parser(text, json, $filter, csp){
|
|
6256
6306
|
var field = expect().text;
|
6257
6307
|
var getter = getterFn(field, csp);
|
6258
6308
|
return extend(
|
6259
|
-
function(
|
6260
|
-
return getter(object(
|
6309
|
+
function(scope, locals, self) {
|
6310
|
+
return getter(self || object(scope, locals), locals);
|
6261
6311
|
},
|
6262
6312
|
{
|
6263
|
-
assign:function(
|
6264
|
-
return setter(object(
|
6313
|
+
assign:function(scope, value, locals) {
|
6314
|
+
return setter(object(scope, locals), field, value);
|
6265
6315
|
}
|
6266
6316
|
}
|
6267
6317
|
);
|
@@ -6302,14 +6352,14 @@ function parser(text, json, $filter, csp){
|
|
6302
6352
|
} while (expect(','));
|
6303
6353
|
}
|
6304
6354
|
consume(')');
|
6305
|
-
return function(
|
6355
|
+
return function(scope, locals){
|
6306
6356
|
var args = [],
|
6307
|
-
context = contextGetter ? contextGetter(
|
6357
|
+
context = contextGetter ? contextGetter(scope, locals) : scope;
|
6308
6358
|
|
6309
6359
|
for ( var i = 0; i < argsFn.length; i++) {
|
6310
|
-
args.push(argsFn[i](
|
6360
|
+
args.push(argsFn[i](scope, locals));
|
6311
6361
|
}
|
6312
|
-
var fnPtr = fn(
|
6362
|
+
var fnPtr = fn(scope, locals, context) || noop;
|
6313
6363
|
// IE stupidity!
|
6314
6364
|
return fnPtr.apply
|
6315
6365
|
? fnPtr.apply(context, args)
|
@@ -6351,8 +6401,7 @@ function parser(text, json, $filter, csp){
|
|
6351
6401
|
var object = {};
|
6352
6402
|
for ( var i = 0; i < keyValues.length; i++) {
|
6353
6403
|
var keyValue = keyValues[i];
|
6354
|
-
|
6355
|
-
object[keyValue.key] = value;
|
6404
|
+
object[keyValue.key] = keyValue.value(self, locals);
|
6356
6405
|
}
|
6357
6406
|
return object;
|
6358
6407
|
};
|
@@ -6474,7 +6523,7 @@ function cspSafeGetterFn(key0, key1, key2, key3, key4) {
|
|
6474
6523
|
}
|
6475
6524
|
return pathVal;
|
6476
6525
|
};
|
6477
|
-
}
|
6526
|
+
}
|
6478
6527
|
|
6479
6528
|
function getterFn(path, csp) {
|
6480
6529
|
if (getterFnCache.hasOwnProperty(path)) {
|
@@ -6489,7 +6538,7 @@ function getterFn(path, csp) {
|
|
6489
6538
|
fn = (pathKeysLength < 6)
|
6490
6539
|
? cspSafeGetterFn(pathKeys[0], pathKeys[1], pathKeys[2], pathKeys[3], pathKeys[4])
|
6491
6540
|
: function(scope, locals) {
|
6492
|
-
var i = 0, val
|
6541
|
+
var i = 0, val;
|
6493
6542
|
do {
|
6494
6543
|
val = cspSafeGetterFn(
|
6495
6544
|
pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++], pathKeys[i++]
|
@@ -6702,7 +6751,7 @@ function $ParseProvider() {
|
|
6702
6751
|
* models and avoiding unnecessary browser repaints, which would result in flickering UI.
|
6703
6752
|
* - $q promises are recognized by the templating engine in angular, which means that in templates
|
6704
6753
|
* you can treat promises attached to a scope as if they were the resulting values.
|
6705
|
-
* - Q has many more features
|
6754
|
+
* - Q has many more features than $q, but that comes at a cost of bytes. $q is tiny, but contains
|
6706
6755
|
* all the important functionality needed for common async tasks.
|
6707
6756
|
*
|
6708
6757
|
* # Testing
|
@@ -6897,10 +6946,7 @@ function qFactory(nextTick, exceptionHandler) {
|
|
6897
6946
|
* the promise comes from a source that can't be trusted.
|
6898
6947
|
*
|
6899
6948
|
* @param {*} value Value or a promise
|
6900
|
-
* @returns {Promise} Returns a
|
6901
|
-
* each value corresponding to the promise at the same index in the `promises` array. If any of
|
6902
|
-
* the promises is resolved with a rejection, this resulting promise will be resolved with the
|
6903
|
-
* same rejection.
|
6949
|
+
* @returns {Promise} Returns a promise of the passed value or promise
|
6904
6950
|
*/
|
6905
6951
|
var when = function(value, callback, errback) {
|
6906
6952
|
var result = defer(),
|
@@ -7496,22 +7542,22 @@ function $RouteParamsProvider() {
|
|
7496
7542
|
/**
|
7497
7543
|
* DESIGN NOTES
|
7498
7544
|
*
|
7499
|
-
* The design decisions behind the scope
|
7545
|
+
* The design decisions behind the scope are heavily favored for speed and memory consumption.
|
7500
7546
|
*
|
7501
7547
|
* The typical use of scope is to watch the expressions, which most of the time return the same
|
7502
7548
|
* value as last time so we optimize the operation.
|
7503
7549
|
*
|
7504
|
-
* Closures construction is expensive
|
7505
|
-
* -
|
7550
|
+
* Closures construction is expensive in terms of speed as well as memory:
|
7551
|
+
* - No closures, instead use prototypical inheritance for API
|
7506
7552
|
* - Internal state needs to be stored on scope directly, which means that private state is
|
7507
7553
|
* exposed as $$____ properties
|
7508
7554
|
*
|
7509
7555
|
* Loop operations are optimized by using while(count--) { ... }
|
7510
7556
|
* - this means that in order to keep the same order of execution as addition we have to add
|
7511
|
-
* items to the array at the
|
7557
|
+
* items to the array at the beginning (shift) instead of at the end (push)
|
7512
7558
|
*
|
7513
7559
|
* Child scopes are created and removed often
|
7514
|
-
* - Using array would be slow since inserts in
|
7560
|
+
* - Using an array would be slow since inserts in middle are expensive so we use linked list
|
7515
7561
|
*
|
7516
7562
|
* There are few watches then a lot of observers. This is why you don't want the observer to be
|
7517
7563
|
* implemented in the same way as watch. Watch requires return of initialization function which
|
@@ -7533,7 +7579,7 @@ function $RouteParamsProvider() {
|
|
7533
7579
|
* @methodOf ng.$rootScopeProvider
|
7534
7580
|
* @description
|
7535
7581
|
*
|
7536
|
-
* Sets the number of digest
|
7582
|
+
* Sets the number of digest iterations the scope should attempt to execute before giving up and
|
7537
7583
|
* assuming that the model is unstable.
|
7538
7584
|
*
|
7539
7585
|
* The current default is 10 iterations.
|
@@ -7813,7 +7859,7 @@ function $RootScopeProvider(){
|
|
7813
7859
|
* @function
|
7814
7860
|
*
|
7815
7861
|
* @description
|
7816
|
-
*
|
7862
|
+
* Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and its children.
|
7817
7863
|
* Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change the model, the
|
7818
7864
|
* `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} until no more listeners are
|
7819
7865
|
* firing. This means that it is possible to get into an infinite loop. This function will throw
|
@@ -8155,7 +8201,7 @@ function $RootScopeProvider(){
|
|
8155
8201
|
* Afterwards, the event traverses upwards toward the root scope and calls all registered
|
8156
8202
|
* listeners along the way. The event will stop propagating if one of the listeners cancels it.
|
8157
8203
|
*
|
8158
|
-
* Any exception
|
8204
|
+
* Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed
|
8159
8205
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
8160
8206
|
*
|
8161
8207
|
* @param {string} name Event name to emit.
|
@@ -8224,7 +8270,7 @@ function $RootScopeProvider(){
|
|
8224
8270
|
* Any exception emmited from the {@link ng.$rootScope.Scope#$on listeners} will be passed
|
8225
8271
|
* onto the {@link ng.$exceptionHandler $exceptionHandler} service.
|
8226
8272
|
*
|
8227
|
-
* @param {string} name Event name to
|
8273
|
+
* @param {string} name Event name to broadcast.
|
8228
8274
|
* @param {...*} args Optional set of arguments which will be passed onto the event listeners.
|
8229
8275
|
* @return {Object} Event object, see {@link ng.$rootScope.Scope#$on}
|
8230
8276
|
*/
|
@@ -8370,10 +8416,23 @@ function $SnifferProvider() {
|
|
8370
8416
|
* @example
|
8371
8417
|
<doc:example>
|
8372
8418
|
<doc:source>
|
8373
|
-
<
|
8374
|
-
|
8419
|
+
<script>
|
8420
|
+
function Ctrl($scope, $window) {
|
8421
|
+
$scope.$window = $window;
|
8422
|
+
$scope.greeting = 'Hello, World!';
|
8423
|
+
}
|
8424
|
+
</script>
|
8425
|
+
<div ng-controller="Ctrl">
|
8426
|
+
<input type="text" ng-model="greeting" />
|
8427
|
+
<button ng-click="$window.alert(greeting)">ALERT</button>
|
8428
|
+
</div>
|
8375
8429
|
</doc:source>
|
8376
8430
|
<doc:scenario>
|
8431
|
+
it('should display the greeting in the input box', function() {
|
8432
|
+
input('greeting').enter('Hello, E2E Tests');
|
8433
|
+
// If we click the button it will block the test runner
|
8434
|
+
// element(':button').click();
|
8435
|
+
});
|
8377
8436
|
</doc:scenario>
|
8378
8437
|
</doc:example>
|
8379
8438
|
*/
|
@@ -8526,7 +8585,7 @@ function $HttpProvider() {
|
|
8526
8585
|
*
|
8527
8586
|
* @description
|
8528
8587
|
* The `$http` service is a core Angular service that facilitates communication with the remote
|
8529
|
-
* HTTP servers via browser's {@link https://developer.mozilla.org/en/xmlhttprequest
|
8588
|
+
* HTTP servers via the browser's {@link https://developer.mozilla.org/en/xmlhttprequest
|
8530
8589
|
* XMLHttpRequest} object or via {@link http://en.wikipedia.org/wiki/JSONP JSONP}.
|
8531
8590
|
*
|
8532
8591
|
* For unit testing applications that use `$http` service, see
|
@@ -8536,13 +8595,13 @@ function $HttpProvider() {
|
|
8536
8595
|
* $resource} service.
|
8537
8596
|
*
|
8538
8597
|
* The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by
|
8539
|
-
* the $q service. While for simple usage
|
8540
|
-
* it is important to familiarize yourself with these
|
8598
|
+
* the $q service. While for simple usage patterns this doesn't matter much, for advanced usage
|
8599
|
+
* it is important to familiarize yourself with these APIs and the guarantees they provide.
|
8541
8600
|
*
|
8542
8601
|
*
|
8543
8602
|
* # General usage
|
8544
8603
|
* The `$http` service is a function which takes a single argument — a configuration object —
|
8545
|
-
* that is used to generate an
|
8604
|
+
* that is used to generate an HTTP request and returns a {@link ng.$q promise}
|
8546
8605
|
* with two $http specific methods: `success` and `error`.
|
8547
8606
|
*
|
8548
8607
|
* <pre>
|
@@ -8557,21 +8616,21 @@ function $HttpProvider() {
|
|
8557
8616
|
* });
|
8558
8617
|
* </pre>
|
8559
8618
|
*
|
8560
|
-
* Since the returned value of calling the $http function is a
|
8619
|
+
* Since the returned value of calling the $http function is a `promise`, you can also use
|
8561
8620
|
* the `then` method to register callbacks, and these callbacks will receive a single argument –
|
8562
|
-
* an object representing the response. See the
|
8621
|
+
* an object representing the response. See the API signature and type info below for more
|
8563
8622
|
* details.
|
8564
8623
|
*
|
8565
|
-
* A response status code
|
8624
|
+
* A response status code between 200 and 299 is considered a success status and
|
8566
8625
|
* will result in the success callback being called. Note that if the response is a redirect,
|
8567
8626
|
* XMLHttpRequest will transparently follow it, meaning that the error callback will not be
|
8568
8627
|
* called for such responses.
|
8569
8628
|
*
|
8570
8629
|
* # Shortcut methods
|
8571
8630
|
*
|
8572
|
-
* Since all
|
8573
|
-
* POST
|
8574
|
-
* were created
|
8631
|
+
* Since all invocations of the $http service require passing in an HTTP method and URL, and
|
8632
|
+
* POST/PUT requests require request data to be provided as well, shortcut methods
|
8633
|
+
* were created:
|
8575
8634
|
*
|
8576
8635
|
* <pre>
|
8577
8636
|
* $http.get('/someUrl').success(successCallback);
|
@@ -8590,25 +8649,25 @@ function $HttpProvider() {
|
|
8590
8649
|
*
|
8591
8650
|
* # Setting HTTP Headers
|
8592
8651
|
*
|
8593
|
-
* The $http service will automatically add certain
|
8652
|
+
* The $http service will automatically add certain HTTP headers to all requests. These defaults
|
8594
8653
|
* can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
|
8595
8654
|
* object, which currently contains this default configuration:
|
8596
8655
|
*
|
8597
8656
|
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
|
8598
8657
|
* - `Accept: application/json, text/plain, * / *`
|
8599
8658
|
* - `X-Requested-With: XMLHttpRequest`
|
8600
|
-
* - `$httpProvider.defaults.headers.post`: (header defaults for
|
8659
|
+
* - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
|
8601
8660
|
* - `Content-Type: application/json`
|
8602
|
-
* - `$httpProvider.defaults.headers.put` (header defaults for
|
8661
|
+
* - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
|
8603
8662
|
* - `Content-Type: application/json`
|
8604
8663
|
*
|
8605
|
-
* To add or overwrite these defaults, simply add or remove a property from
|
8664
|
+
* To add or overwrite these defaults, simply add or remove a property from these configuration
|
8606
8665
|
* objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
|
8607
|
-
* with
|
8666
|
+
* with the lowercased HTTP method name as the key, e.g.
|
8608
8667
|
* `$httpProvider.defaults.headers.get['My-Header']='value'`.
|
8609
8668
|
*
|
8610
|
-
* Additionally, the defaults can be set at runtime via the `$http.defaults` object in
|
8611
|
-
*
|
8669
|
+
* Additionally, the defaults can be set at runtime via the `$http.defaults` object in the same
|
8670
|
+
* fashion.
|
8612
8671
|
*
|
8613
8672
|
*
|
8614
8673
|
* # Transforming Requests and Responses
|
@@ -8618,36 +8677,36 @@ function $HttpProvider() {
|
|
8618
8677
|
*
|
8619
8678
|
* Request transformations:
|
8620
8679
|
*
|
8621
|
-
* -
|
8680
|
+
* - If the `data` property of the request configuration object contains an object, serialize it into
|
8622
8681
|
* JSON format.
|
8623
8682
|
*
|
8624
8683
|
* Response transformations:
|
8625
8684
|
*
|
8626
|
-
* -
|
8627
|
-
* -
|
8685
|
+
* - If XSRF prefix is detected, strip it (see Security Considerations section below).
|
8686
|
+
* - If JSON response is detected, deserialize it using a JSON parser.
|
8628
8687
|
*
|
8629
8688
|
* To globally augment or override the default transforms, modify the `$httpProvider.defaults.transformRequest` and
|
8630
|
-
* `$httpProvider.defaults.transformResponse` properties
|
8689
|
+
* `$httpProvider.defaults.transformResponse` properties. These properties are by default an
|
8631
8690
|
* array of transform functions, which allows you to `push` or `unshift` a new transformation function into the
|
8632
8691
|
* transformation chain. You can also decide to completely override any default transformations by assigning your
|
8633
8692
|
* transformation functions to these properties directly without the array wrapper.
|
8634
8693
|
*
|
8635
8694
|
* Similarly, to locally override the request/response transforms, augment the `transformRequest` and/or
|
8636
|
-
* `transformResponse` properties of the
|
8695
|
+
* `transformResponse` properties of the configuration object passed into `$http`.
|
8637
8696
|
*
|
8638
8697
|
*
|
8639
8698
|
* # Caching
|
8640
8699
|
*
|
8641
|
-
* To enable caching set the configuration property `cache` to `true`. When the cache is
|
8700
|
+
* To enable caching, set the configuration property `cache` to `true`. When the cache is
|
8642
8701
|
* enabled, `$http` stores the response from the server in local cache. Next time the
|
8643
8702
|
* response is served from the cache without sending a request to the server.
|
8644
8703
|
*
|
8645
8704
|
* Note that even if the response is served from cache, delivery of the data is asynchronous in
|
8646
8705
|
* the same way that real requests are.
|
8647
8706
|
*
|
8648
|
-
* If there are multiple GET requests for the same
|
8707
|
+
* If there are multiple GET requests for the same URL that should be cached using the same
|
8649
8708
|
* cache, but the cache is not populated yet, only one request to the server will be made and
|
8650
|
-
* the remaining requests will be fulfilled using the response
|
8709
|
+
* the remaining requests will be fulfilled using the response from the first request.
|
8651
8710
|
*
|
8652
8711
|
*
|
8653
8712
|
* # Response interceptors
|
@@ -8699,7 +8758,7 @@ function $HttpProvider() {
|
|
8699
8758
|
* When designing web applications, consider security threats from:
|
8700
8759
|
*
|
8701
8760
|
* - {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
|
8702
|
-
* JSON
|
8761
|
+
* JSON vulnerability}
|
8703
8762
|
* - {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF}
|
8704
8763
|
*
|
8705
8764
|
* Both server and the client must cooperate in order to eliminate these threats. Angular comes
|
@@ -8709,8 +8768,8 @@ function $HttpProvider() {
|
|
8709
8768
|
* ## JSON Vulnerability Protection
|
8710
8769
|
*
|
8711
8770
|
* A {@link http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
|
8712
|
-
* JSON
|
8713
|
-
* {@link http://en.wikipedia.org/wiki/
|
8771
|
+
* JSON vulnerability} allows third party website to turn your JSON resource URL into
|
8772
|
+
* {@link http://en.wikipedia.org/wiki/JSONP JSONP} request under some conditions. To
|
8714
8773
|
* counter this your server can prefix all JSON requests with following string `")]}',\n"`.
|
8715
8774
|
* Angular will automatically strip the prefix before processing it as JSON.
|
8716
8775
|
*
|
@@ -8731,19 +8790,19 @@ function $HttpProvider() {
|
|
8731
8790
|
* ## Cross Site Request Forgery (XSRF) Protection
|
8732
8791
|
*
|
8733
8792
|
* {@link http://en.wikipedia.org/wiki/Cross-site_request_forgery XSRF} is a technique by which
|
8734
|
-
* an unauthorized site can gain your user's private data. Angular provides
|
8793
|
+
* an unauthorized site can gain your user's private data. Angular provides a mechanism
|
8735
8794
|
* to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie
|
8736
8795
|
* called `XSRF-TOKEN` and sets it as the HTTP header `X-XSRF-TOKEN`. Since only JavaScript that
|
8737
8796
|
* runs on your domain could read the cookie, your server can be assured that the XHR came from
|
8738
8797
|
* JavaScript running on your domain.
|
8739
8798
|
*
|
8740
8799
|
* To take advantage of this, your server needs to set a token in a JavaScript readable session
|
8741
|
-
* cookie called `XSRF-TOKEN` on first HTTP GET request. On subsequent
|
8800
|
+
* cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the
|
8742
8801
|
* server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure
|
8743
|
-
* that only JavaScript running on your domain could have
|
8744
|
-
* unique for each user and must be verifiable by the server (to prevent the JavaScript making
|
8802
|
+
* that only JavaScript running on your domain could have sent the request. The token must be
|
8803
|
+
* unique for each user and must be verifiable by the server (to prevent the JavaScript from making
|
8745
8804
|
* up its own tokens). We recommend that the token is a digest of your site's authentication
|
8746
|
-
* cookie with {@link
|
8805
|
+
* cookie with a {@link https://en.wikipedia.org/wiki/Salt_(cryptography) salt} for added security.
|
8747
8806
|
*
|
8748
8807
|
*
|
8749
8808
|
* @param {object} config Object describing the request to be made and how it should be
|
@@ -8921,7 +8980,7 @@ function $HttpProvider() {
|
|
8921
8980
|
* @methodOf ng.$http
|
8922
8981
|
*
|
8923
8982
|
* @description
|
8924
|
-
* Shortcut method to perform `GET` request
|
8983
|
+
* Shortcut method to perform `GET` request.
|
8925
8984
|
*
|
8926
8985
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
8927
8986
|
* @param {Object=} config Optional configuration object
|
@@ -8934,7 +8993,7 @@ function $HttpProvider() {
|
|
8934
8993
|
* @methodOf ng.$http
|
8935
8994
|
*
|
8936
8995
|
* @description
|
8937
|
-
* Shortcut method to perform `DELETE` request
|
8996
|
+
* Shortcut method to perform `DELETE` request.
|
8938
8997
|
*
|
8939
8998
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
8940
8999
|
* @param {Object=} config Optional configuration object
|
@@ -8947,7 +9006,7 @@ function $HttpProvider() {
|
|
8947
9006
|
* @methodOf ng.$http
|
8948
9007
|
*
|
8949
9008
|
* @description
|
8950
|
-
* Shortcut method to perform `HEAD` request
|
9009
|
+
* Shortcut method to perform `HEAD` request.
|
8951
9010
|
*
|
8952
9011
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
8953
9012
|
* @param {Object=} config Optional configuration object
|
@@ -8960,7 +9019,7 @@ function $HttpProvider() {
|
|
8960
9019
|
* @methodOf ng.$http
|
8961
9020
|
*
|
8962
9021
|
* @description
|
8963
|
-
* Shortcut method to perform `JSONP` request
|
9022
|
+
* Shortcut method to perform `JSONP` request.
|
8964
9023
|
*
|
8965
9024
|
* @param {string} url Relative or absolute URL specifying the destination of the request.
|
8966
9025
|
* Should contain `JSON_CALLBACK` string.
|
@@ -8975,7 +9034,7 @@ function $HttpProvider() {
|
|
8975
9034
|
* @methodOf ng.$http
|
8976
9035
|
*
|
8977
9036
|
* @description
|
8978
|
-
* Shortcut method to perform `POST` request
|
9037
|
+
* Shortcut method to perform `POST` request.
|
8979
9038
|
*
|
8980
9039
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
8981
9040
|
* @param {*} data Request content
|
@@ -8989,7 +9048,7 @@ function $HttpProvider() {
|
|
8989
9048
|
* @methodOf ng.$http
|
8990
9049
|
*
|
8991
9050
|
* @description
|
8992
|
-
* Shortcut method to perform `PUT` request
|
9051
|
+
* Shortcut method to perform `PUT` request.
|
8993
9052
|
*
|
8994
9053
|
* @param {string} url Relative or absolute URL specifying the destination of the request
|
8995
9054
|
* @param {*} data Request content
|
@@ -9041,7 +9100,7 @@ function $HttpProvider() {
|
|
9041
9100
|
|
9042
9101
|
|
9043
9102
|
/**
|
9044
|
-
* Makes the request
|
9103
|
+
* Makes the request.
|
9045
9104
|
*
|
9046
9105
|
* !!! ACCESSES CLOSURE VARS:
|
9047
9106
|
* $httpBackend, $config, $log, $rootScope, defaultCache, $http.pendingRequests
|
@@ -9388,17 +9447,17 @@ function $TimeoutProvider() {
|
|
9388
9447
|
* block and delegates any exceptions to
|
9389
9448
|
* {@link ng.$exceptionHandler $exceptionHandler} service.
|
9390
9449
|
*
|
9391
|
-
* The return value of registering a timeout function is a promise which will be resolved when
|
9450
|
+
* The return value of registering a timeout function is a promise, which will be resolved when
|
9392
9451
|
* the timeout is reached and the timeout function is executed.
|
9393
9452
|
*
|
9394
|
-
* To cancel a
|
9453
|
+
* To cancel a timeout request, call `$timeout.cancel(promise)`.
|
9395
9454
|
*
|
9396
9455
|
* In tests you can use {@link ngMock.$timeout `$timeout.flush()`} to
|
9397
9456
|
* synchronously flush the queue of deferred functions.
|
9398
9457
|
*
|
9399
|
-
* @param {function()} fn A function,
|
9458
|
+
* @param {function()} fn A function, whose execution should be delayed.
|
9400
9459
|
* @param {number=} [delay=0] Delay in milliseconds.
|
9401
|
-
* @param {boolean=} [invokeApply=true] If set to false skips model dirty checking, otherwise
|
9460
|
+
* @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise
|
9402
9461
|
* will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block.
|
9403
9462
|
* @returns {Promise} Promise that will be resolved when the timeout is reached. The value this
|
9404
9463
|
* promise will be resolved with is the return value of the `fn` function.
|
@@ -9438,7 +9497,7 @@ function $TimeoutProvider() {
|
|
9438
9497
|
* @methodOf ng.$timeout
|
9439
9498
|
*
|
9440
9499
|
* @description
|
9441
|
-
* Cancels a task associated with the `promise`. As a result of this the promise will be
|
9500
|
+
* Cancels a task associated with the `promise`. As a result of this, the promise will be
|
9442
9501
|
* resolved with a rejection.
|
9443
9502
|
*
|
9444
9503
|
* @param {Promise=} promise Promise returned by the `$timeout` function.
|
@@ -9526,7 +9585,7 @@ function $TimeoutProvider() {
|
|
9526
9585
|
*
|
9527
9586
|
* The general syntax in templates is as follows:
|
9528
9587
|
*
|
9529
|
-
* {{ expression | [
|
9588
|
+
* {{ expression [| filter_name[:parameter_value] ... ] }}
|
9530
9589
|
*
|
9531
9590
|
* @param {String} name Name of the filter function to retrieve
|
9532
9591
|
* @return {Function} the filter function
|
@@ -9611,7 +9670,7 @@ function $FilterProvider($provide) {
|
|
9611
9670
|
<hr>
|
9612
9671
|
Any: <input ng-model="search.$"> <br>
|
9613
9672
|
Name only <input ng-model="search.name"><br>
|
9614
|
-
Phone only <input ng-model="search.phone"
|
9673
|
+
Phone only <input ng-model="search.phone"><br>
|
9615
9674
|
<table id="searchObjResults">
|
9616
9675
|
<tr><th>Name</th><th>Phone</th></tr>
|
9617
9676
|
<tr ng-repeat="friend in friends | filter:search">
|
@@ -9914,6 +9973,7 @@ function padNumber(num, digits, trim) {
|
|
9914
9973
|
|
9915
9974
|
|
9916
9975
|
function dateGetter(name, size, offset, trim) {
|
9976
|
+
offset = offset || 0;
|
9917
9977
|
return function(date) {
|
9918
9978
|
var value = date['get' + name]();
|
9919
9979
|
if (offset > 0 || value > -offset)
|
@@ -10024,7 +10084,7 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
|
|
10024
10084
|
* (e.g. `"h o''clock"`).
|
10025
10085
|
*
|
10026
10086
|
* @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
|
10027
|
-
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and
|
10087
|
+
* number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.SSSZ and its
|
10028
10088
|
* shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
|
10029
10089
|
* specified in the string input, the time is considered to be in the local timezone.
|
10030
10090
|
* @param {string=} format Formatting rules (see Description). If not specified,
|
@@ -11142,8 +11202,8 @@ var inputType = {
|
|
11142
11202
|
*
|
11143
11203
|
* @param {string} ngModel Assignable angular expression to data-bind to.
|
11144
11204
|
* @param {string=} name Property name of the form under which the control is published.
|
11145
|
-
* @param {string=} min Sets the `min` validation error key if the value entered is less
|
11146
|
-
* @param {string=} max Sets the `max` validation error key if the value entered is greater
|
11205
|
+
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`.
|
11206
|
+
* @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`.
|
11147
11207
|
* @param {string=} required Sets `required` validation error key if the value is not entered.
|
11148
11208
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
11149
11209
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -11455,6 +11515,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
11455
11515
|
} else {
|
11456
11516
|
var timeout;
|
11457
11517
|
|
11518
|
+
var deferListener = function() {
|
11519
|
+
if (!timeout) {
|
11520
|
+
timeout = $browser.defer(function() {
|
11521
|
+
listener();
|
11522
|
+
timeout = null;
|
11523
|
+
});
|
11524
|
+
}
|
11525
|
+
};
|
11526
|
+
|
11458
11527
|
element.bind('keydown', function(event) {
|
11459
11528
|
var key = event.keyCode;
|
11460
11529
|
|
@@ -11462,16 +11531,16 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
|
|
11462
11531
|
// command modifiers arrows
|
11463
11532
|
if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;
|
11464
11533
|
|
11465
|
-
|
11466
|
-
timeout = $browser.defer(function() {
|
11467
|
-
listener();
|
11468
|
-
timeout = null;
|
11469
|
-
});
|
11470
|
-
}
|
11534
|
+
deferListener();
|
11471
11535
|
});
|
11472
11536
|
|
11473
11537
|
// if user paste into input using mouse, we need "change" event to catch it
|
11474
11538
|
element.bind('change', listener);
|
11539
|
+
|
11540
|
+
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
|
11541
|
+
if ($sniffer.hasEvent('paste')) {
|
11542
|
+
element.bind('paste cut', deferListener);
|
11543
|
+
}
|
11475
11544
|
}
|
11476
11545
|
|
11477
11546
|
|
@@ -11770,7 +11839,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
|
|
11770
11839
|
<tt>myForm.userName.$valid = {{myForm.userName.$valid}}</tt><br>
|
11771
11840
|
<tt>myForm.userName.$error = {{myForm.userName.$error}}</tt><br>
|
11772
11841
|
<tt>myForm.lastName.$valid = {{myForm.lastName.$valid}}</tt><br>
|
11773
|
-
<tt>myForm.
|
11842
|
+
<tt>myForm.lastName.$error = {{myForm.lastName.$error}}</tt><br>
|
11774
11843
|
<tt>myForm.$valid = {{myForm.$valid}}</tt><br>
|
11775
11844
|
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
|
11776
11845
|
<tt>myForm.$error.minlength = {{!!myForm.$error.minlength}}</tt><br>
|
@@ -12033,7 +12102,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
|
|
12033
12102
|
* For example {@link ng.directive:input input} or
|
12034
12103
|
* {@link ng.directive:select select} directives call it.
|
12035
12104
|
*
|
12036
|
-
* It internally calls all `
|
12105
|
+
* It internally calls all `parsers` and if resulted value is valid, updates the model and
|
12037
12106
|
* calls all registered change listeners.
|
12038
12107
|
*
|
12039
12108
|
* @param {string} value Value from the view.
|
@@ -12339,7 +12408,7 @@ var ngValueDirective = function() {
|
|
12339
12408
|
* Typically, you don't use `ngBind` directly, but instead you use the double curly markup like
|
12340
12409
|
* `{{ expression }}` which is similar but less verbose.
|
12341
12410
|
*
|
12342
|
-
*
|
12411
|
+
* One scenario in which the use of `ngBind` is preferred over `{{ expression }}` binding is when
|
12343
12412
|
* it's desirable to put bindings into template that is momentarily displayed by the browser in its
|
12344
12413
|
* raw state before Angular compiles it. Since `ngBind` is an element attribute, it makes the
|
12345
12414
|
* bindings invisible to the user while the page is loading.
|
@@ -12480,9 +12549,9 @@ function classDirective(name, selector) {
|
|
12480
12549
|
|
12481
12550
|
if (name !== 'ngClass') {
|
12482
12551
|
scope.$watch('$index', function($index, old$index) {
|
12483
|
-
var mod = $index
|
12484
|
-
if (mod !== old$index
|
12485
|
-
if (mod
|
12552
|
+
var mod = $index & 1;
|
12553
|
+
if (mod !== old$index & 1) {
|
12554
|
+
if (mod === selector) {
|
12486
12555
|
addClass(scope.$eval(attr[name]));
|
12487
12556
|
} else {
|
12488
12557
|
removeClass(scope.$eval(attr[name]));
|
@@ -12494,12 +12563,12 @@ function classDirective(name, selector) {
|
|
12494
12563
|
|
12495
12564
|
function ngClassWatchAction(newVal) {
|
12496
12565
|
if (selector === true || scope.$index % 2 === selector) {
|
12497
|
-
if (oldVal && (newVal
|
12566
|
+
if (oldVal && !equals(newVal,oldVal)) {
|
12498
12567
|
removeClass(oldVal);
|
12499
12568
|
}
|
12500
12569
|
addClass(newVal);
|
12501
12570
|
}
|
12502
|
-
oldVal = newVal;
|
12571
|
+
oldVal = copy(newVal);
|
12503
12572
|
}
|
12504
12573
|
|
12505
12574
|
|
@@ -12625,7 +12694,7 @@ var ngClassOddDirective = classDirective('Odd', 0);
|
|
12625
12694
|
* @name ng.directive:ngClassEven
|
12626
12695
|
*
|
12627
12696
|
* @description
|
12628
|
-
* The `ngClassOdd` and `ngClassEven`
|
12697
|
+
* The `ngClassOdd` and `ngClassEven` directives work exactly as
|
12629
12698
|
* {@link ng.directive:ngClass ngClass}, except it works in
|
12630
12699
|
* conjunction with `ngRepeat` and takes affect only on odd (even) rows.
|
12631
12700
|
*
|
@@ -12742,8 +12811,7 @@ var ngCloakDirective = ngDirective({
|
|
12742
12811
|
* * Controller — The `ngController` directive specifies a Controller class; the class has
|
12743
12812
|
* methods that typically express the business logic behind the application.
|
12744
12813
|
*
|
12745
|
-
* Note that an alternative way to define controllers is via the
|
12746
|
-
* service.
|
12814
|
+
* Note that an alternative way to define controllers is via the {@link ng.$route $route} service.
|
12747
12815
|
*
|
12748
12816
|
* @element ANY
|
12749
12817
|
* @scope
|
@@ -12834,16 +12902,32 @@ var ngControllerDirective = [function() {
|
|
12834
12902
|
* @name ng.directive:ngCsp
|
12835
12903
|
* @priority 1000
|
12836
12904
|
*
|
12905
|
+
* @element html
|
12837
12906
|
* @description
|
12838
12907
|
* Enables [CSP (Content Security Policy)](https://developer.mozilla.org/en/Security/CSP) support.
|
12839
|
-
*
|
12840
|
-
*
|
12841
|
-
*
|
12842
|
-
*
|
12843
|
-
*
|
12844
|
-
*
|
12845
|
-
*
|
12846
|
-
*
|
12908
|
+
*
|
12909
|
+
* This is necessary when developing things like Google Chrome Extensions.
|
12910
|
+
*
|
12911
|
+
* CSP forbids apps to use `eval` or `Function(string)` generated functions (among other things).
|
12912
|
+
* For us to be compatible, we just need to implement the "getterFn" in $parse without violating
|
12913
|
+
* any of these restrictions.
|
12914
|
+
*
|
12915
|
+
* AngularJS uses `Function(string)` generated functions as a speed optimization. By applying `ngCsp`
|
12916
|
+
* it is be possible to opt into the CSP compatible mode. When this mode is on AngularJS will
|
12917
|
+
* evaluate all expressions up to 30% slower than in non-CSP mode, but no security violations will
|
12918
|
+
* be raised.
|
12919
|
+
*
|
12920
|
+
* In order to use this feature put `ngCsp` directive on the root element of the application.
|
12921
|
+
*
|
12922
|
+
* @example
|
12923
|
+
* This example shows how to apply the `ngCsp` directive to the `html` tag.
|
12924
|
+
<pre>
|
12925
|
+
<!doctype html>
|
12926
|
+
<html ng-app ng-csp>
|
12927
|
+
...
|
12928
|
+
...
|
12929
|
+
</html>
|
12930
|
+
</pre>
|
12847
12931
|
*/
|
12848
12932
|
|
12849
12933
|
var ngCspDirective = ['$sniffer', function($sniffer) {
|
@@ -13468,7 +13552,7 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
|
|
13468
13552
|
if (!isNaN(value)) {
|
13469
13553
|
//if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
|
13470
13554
|
//check it against pluralization rules in $locale service
|
13471
|
-
if (!whens
|
13555
|
+
if (!(value in whens)) value = $locale.pluralCat(value - offset);
|
13472
13556
|
return whensExpFns[value](scope, element, true);
|
13473
13557
|
} else {
|
13474
13558
|
return '';
|
@@ -14201,7 +14285,8 @@ var scriptDirective = ['$templateCache', function($templateCache) {
|
|
14201
14285
|
* `select` model to be bound to a non-string value. This is because an option element can currently
|
14202
14286
|
* be bound to string values only.
|
14203
14287
|
*
|
14204
|
-
* @param {string}
|
14288
|
+
* @param {string} ngModel Assignable angular expression to data-bind to.
|
14289
|
+
* @param {string=} name Property name of the form under which the control is published.
|
14205
14290
|
* @param {string=} required The control is considered valid only if value is entered.
|
14206
14291
|
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
|
14207
14292
|
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
|
@@ -14568,10 +14653,6 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
14568
14653
|
|
14569
14654
|
if (multiple) {
|
14570
14655
|
selectedSet = new HashMap(modelValue);
|
14571
|
-
} else if (modelValue === null || nullOption) {
|
14572
|
-
// if we are not multiselect, and we are null then we have to add the nullOption
|
14573
|
-
optionGroups[''].push({selected:modelValue === null, id:'', label:''});
|
14574
|
-
selectedSet = true;
|
14575
14656
|
}
|
14576
14657
|
|
14577
14658
|
// We now build up the list of options we need (we merge later)
|
@@ -14596,9 +14677,14 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
14596
14677
|
selected: selected // determine if we should be selected
|
14597
14678
|
});
|
14598
14679
|
}
|
14599
|
-
if (!multiple
|
14600
|
-
|
14601
|
-
|
14680
|
+
if (!multiple) {
|
14681
|
+
if (nullOption || modelValue === null) {
|
14682
|
+
// insert null option if we have a placeholder, or the model is null
|
14683
|
+
optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
|
14684
|
+
} else if (!selectedSet) {
|
14685
|
+
// option could not be found, we have to insert the undefined item
|
14686
|
+
optionGroups[''].unshift({id:'?', label:'', selected:true});
|
14687
|
+
}
|
14602
14688
|
}
|
14603
14689
|
|
14604
14690
|
// Now we need to update the list of DOM nodes to match the optionGroups we computed above
|
@@ -14642,7 +14728,8 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
|
|
14642
14728
|
if (existingOption.id !== option.id) {
|
14643
14729
|
lastElement.val(existingOption.id = option.id);
|
14644
14730
|
}
|
14645
|
-
|
14731
|
+
// lastElement.prop('selected') provided by jQuery has side-effects
|
14732
|
+
if (lastElement[0].selected !== option.selected) {
|
14646
14733
|
lastElement.prop('selected', (existingOption.selected = option.selected));
|
14647
14734
|
}
|
14648
14735
|
} else {
|