ui_alchemy-rails 1.0.10 → 1.0.11
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.
- 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 {
|