@angular-wave/angular.ts 0.0.51 → 0.0.53

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.
Files changed (42) hide show
  1. package/dist/angular-ts.esm.js +2 -2
  2. package/dist/angular-ts.umd.js +2 -2
  3. package/package.json +1 -1
  4. package/src/animations/animate-children-directive.js +19 -99
  5. package/src/animations/animate-children-directive.md +80 -0
  6. package/src/animations/animate-css-driver.js +250 -256
  7. package/src/animations/animate-css.js +646 -875
  8. package/src/animations/animate-css.md +263 -0
  9. package/src/animations/animate-js-driver.js +54 -56
  10. package/src/animations/animate-js.js +303 -306
  11. package/src/animations/animate-queue.js +707 -716
  12. package/src/animations/animate-swap.js +30 -119
  13. package/src/animations/animate-swap.md +88 -0
  14. package/src/animations/animation.js +3 -3
  15. package/src/core/animate/animate-css.js +21 -6
  16. package/src/core/animate/animate-runner.js +147 -145
  17. package/src/core/animate/animate.js +572 -585
  18. package/src/core/animate/animate.spec.js +194 -286
  19. package/src/core/animate/anomate.md +13 -0
  20. package/src/core/animate/helpers.js +10 -0
  21. package/src/core/compile/compile.spec.js +5 -6
  22. package/src/core/core.html +0 -1
  23. package/src/directive/select/select.js +301 -305
  24. package/src/public.js +0 -1
  25. package/src/router/directives/state-directives.js +256 -574
  26. package/src/router/directives/state-directives.md +435 -0
  27. package/src/router/directives/view-directive.js +3 -3
  28. package/src/router/index.js +7 -7
  29. package/types/animations/animate-children-directive.d.ts +5 -80
  30. package/types/animations/animate-css-driver.d.ts +11 -0
  31. package/types/animations/animate-css.d.ts +8 -0
  32. package/types/animations/animate-js-driver.d.ts +8 -0
  33. package/types/animations/animate-js.d.ts +12 -0
  34. package/types/animations/animate-queue.d.ts +19 -0
  35. package/types/animations/animate-swap.d.ts +5 -89
  36. package/types/core/animate/animate-css.d.ts +1 -1
  37. package/types/core/animate/animate-runner.d.ts +32 -0
  38. package/types/core/animate/animate.d.ts +509 -0
  39. package/types/core/animate/helpers.d.ts +8 -0
  40. package/types/directive/select/select.d.ts +79 -0
  41. package/types/router/directives/state-directives.d.ts +31 -0
  42. package/src/core/document.spec.js +0 -52
@@ -32,347 +32,343 @@ function setOptionSelectedStatus(optionEl, value) {
32
32
  * {@link ng.ngOptions ngOptions} select element.
33
33
  *
34
34
  */
35
- var SelectController = [
36
- "$element",
37
- "$scope",
38
- function ($element, $scope) {
39
- const self = this;
40
- const optionsMap = new Map();
41
-
42
- self.selectValueMap = {}; // Keys are the hashed values, values the original values
43
-
44
- // If the ngModel doesn't get provided then provide a dummy noop version to prevent errors
45
- self.ngModelCtrl = noopNgModelController;
46
- self.multiple = false;
47
-
48
- // The "unknown" option is one that is prepended to the list if the viewValue
49
- // does not match any of the options. When it is rendered the value of the unknown
50
- // option is '? XXX ?' where XXX is the hashKey of the value that is not known.
51
- //
52
- // Support: IE 9 only
53
- // We can't just JQLite('<option>') since JQLite is not smart enough
54
- // to create it in <select> and IE barfs otherwise.
55
- self.unknownOption = JQLite(window.document.createElement("option"));
56
-
57
- // The empty option is an option with the value '' that the application developer can
58
- // provide inside the select. It is always selectable and indicates that a "null" selection has
59
- // been made by the user.
60
- // If the select has an empty option, and the model of the select is set to "undefined" or "null",
61
- // the empty option is selected.
62
- // If the model is set to a different unmatched value, the unknown option is rendered and
63
- // selected, i.e both are present, because a "null" selection and an unknown value are different.
64
- self.hasEmptyOption = false;
65
- self.emptyOption = undefined;
66
-
67
- self.renderUnknownOption = function (val) {
68
- const unknownVal = self.generateUnknownOptionValue(val);
69
- self.unknownOption.val(unknownVal);
70
- $element.prepend(self.unknownOption);
71
- setOptionSelectedStatus(self.unknownOption, true);
72
- $element.val(unknownVal);
73
- };
35
+ SelectController.$inject = ["$element", "$scope"];
36
+ function SelectController($element, $scope) {
37
+ const self = this;
38
+ const optionsMap = new Map();
39
+
40
+ self.selectValueMap = {}; // Keys are the hashed values, values the original values
41
+
42
+ // If the ngModel doesn't get provided then provide a dummy noop version to prevent errors
43
+ self.ngModelCtrl = noopNgModelController;
44
+ self.multiple = false;
45
+
46
+ // The "unknown" option is one that is prepended to the list if the viewValue
47
+ // does not match any of the options. When it is rendered the value of the unknown
48
+ // option is '? XXX ?' where XXX is the hashKey of the value that is not known.
49
+ //
50
+ // Support: IE 9 only
51
+ // We can't just JQLite('<option>') since JQLite is not smart enough
52
+ // to create it in <select> and IE barfs otherwise.
53
+ self.unknownOption = JQLite(window.document.createElement("option"));
54
+
55
+ // The empty option is an option with the value '' that the application developer can
56
+ // provide inside the select. It is always selectable and indicates that a "null" selection has
57
+ // been made by the user.
58
+ // If the select has an empty option, and the model of the select is set to "undefined" or "null",
59
+ // the empty option is selected.
60
+ // If the model is set to a different unmatched value, the unknown option is rendered and
61
+ // selected, i.e both are present, because a "null" selection and an unknown value are different.
62
+ self.hasEmptyOption = false;
63
+ self.emptyOption = undefined;
64
+
65
+ self.renderUnknownOption = function (val) {
66
+ const unknownVal = self.generateUnknownOptionValue(val);
67
+ self.unknownOption.val(unknownVal);
68
+ $element.prepend(self.unknownOption);
69
+ setOptionSelectedStatus(self.unknownOption, true);
70
+ $element.val(unknownVal);
71
+ };
74
72
 
75
- self.updateUnknownOption = function (val) {
76
- const unknownVal = self.generateUnknownOptionValue(val);
77
- self.unknownOption.val(unknownVal);
78
- setOptionSelectedStatus(self.unknownOption, true);
79
- $element.val(unknownVal);
80
- };
73
+ self.updateUnknownOption = function (val) {
74
+ const unknownVal = self.generateUnknownOptionValue(val);
75
+ self.unknownOption.val(unknownVal);
76
+ setOptionSelectedStatus(self.unknownOption, true);
77
+ $element.val(unknownVal);
78
+ };
81
79
 
82
- self.generateUnknownOptionValue = function (val) {
83
- return `? ${hashKey(val)} ?`;
84
- };
80
+ self.generateUnknownOptionValue = function (val) {
81
+ return `? ${hashKey(val)} ?`;
82
+ };
85
83
 
86
- self.removeUnknownOption = function () {
87
- if (self.unknownOption.parent()) self.unknownOption.remove();
88
- };
84
+ self.removeUnknownOption = function () {
85
+ if (self.unknownOption.parent()) self.unknownOption.remove();
86
+ };
89
87
 
90
- self.selectEmptyOption = function () {
91
- if (self.emptyOption) {
92
- $element.val("");
93
- setOptionSelectedStatus(self.emptyOption, true);
94
- }
95
- };
88
+ self.selectEmptyOption = function () {
89
+ if (self.emptyOption) {
90
+ $element.val("");
91
+ setOptionSelectedStatus(self.emptyOption, true);
92
+ }
93
+ };
96
94
 
97
- self.unselectEmptyOption = function () {
98
- if (self.hasEmptyOption) {
99
- setOptionSelectedStatus(self.emptyOption, false);
100
- }
101
- };
95
+ self.unselectEmptyOption = function () {
96
+ if (self.hasEmptyOption) {
97
+ setOptionSelectedStatus(self.emptyOption, false);
98
+ }
99
+ };
102
100
 
103
- $scope.$on("$destroy", () => {
104
- // disable unknown option so that we don't do work when the whole select is being destroyed
105
- self.renderUnknownOption = () => {};
106
- });
101
+ $scope.$on("$destroy", () => {
102
+ // disable unknown option so that we don't do work when the whole select is being destroyed
103
+ self.renderUnknownOption = () => {};
104
+ });
107
105
 
108
- // Read the value of the select control, the implementation of this changes depending
109
- // upon whether the select can have multiple values and whether ngOptions is at work.
110
- self.readValue = function readSingleValue() {
111
- const val = $element.val();
112
- // ngValue added option values are stored in the selectValueMap, normal interpolations are not
113
- const realVal =
114
- val in self.selectValueMap ? self.selectValueMap[val] : val;
106
+ // Read the value of the select control, the implementation of this changes depending
107
+ // upon whether the select can have multiple values and whether ngOptions is at work.
108
+ self.readValue = function readSingleValue() {
109
+ const val = $element.val();
110
+ // ngValue added option values are stored in the selectValueMap, normal interpolations are not
111
+ const realVal = val in self.selectValueMap ? self.selectValueMap[val] : val;
115
112
 
116
- if (self.hasOption(realVal)) {
117
- return realVal;
118
- }
113
+ if (self.hasOption(realVal)) {
114
+ return realVal;
115
+ }
119
116
 
120
- return null;
121
- };
117
+ return null;
118
+ };
122
119
 
123
- // Write the value to the select control, the implementation of this changes depending
124
- // upon whether the select can have multiple values and whether ngOptions is at work.
125
- self.writeValue = function writeSingleValue(value) {
126
- // Make sure to remove the selected attribute from the previously selected option
127
- // Otherwise, screen readers might get confused
128
- const currentlySelectedOption =
129
- $element[0].options[$element[0].selectedIndex];
130
- if (currentlySelectedOption)
131
- setOptionSelectedStatus(JQLite(currentlySelectedOption), false);
132
-
133
- if (self.hasOption(value)) {
134
- self.removeUnknownOption();
135
-
136
- const hashedVal = hashKey(value);
137
- $element.val(hashedVal in self.selectValueMap ? hashedVal : value);
138
-
139
- // Set selected attribute and property on selected option for screen readers
140
- const selectedOption = $element[0].options[$element[0].selectedIndex];
141
- setOptionSelectedStatus(JQLite(selectedOption), true);
142
- } else {
143
- self.selectUnknownOrEmptyOption(value);
144
- }
145
- };
120
+ // Write the value to the select control, the implementation of this changes depending
121
+ // upon whether the select can have multiple values and whether ngOptions is at work.
122
+ self.writeValue = function writeSingleValue(value) {
123
+ // Make sure to remove the selected attribute from the previously selected option
124
+ // Otherwise, screen readers might get confused
125
+ const currentlySelectedOption =
126
+ $element[0].options[$element[0].selectedIndex];
127
+ if (currentlySelectedOption)
128
+ setOptionSelectedStatus(JQLite(currentlySelectedOption), false);
129
+
130
+ if (self.hasOption(value)) {
131
+ self.removeUnknownOption();
132
+
133
+ const hashedVal = hashKey(value);
134
+ $element.val(hashedVal in self.selectValueMap ? hashedVal : value);
135
+
136
+ // Set selected attribute and property on selected option for screen readers
137
+ const selectedOption = $element[0].options[$element[0].selectedIndex];
138
+ setOptionSelectedStatus(JQLite(selectedOption), true);
139
+ } else {
140
+ self.selectUnknownOrEmptyOption(value);
141
+ }
142
+ };
146
143
 
147
- // Tell the select control that an option, with the given value, has been added
148
- self.addOption = function (value, element) {
149
- // Skip comment nodes, as they only pollute the `optionsMap`
150
- if (element[0].nodeType === Node.COMMENT_NODE) return;
144
+ // Tell the select control that an option, with the given value, has been added
145
+ self.addOption = function (value, element) {
146
+ // Skip comment nodes, as they only pollute the `optionsMap`
147
+ if (element[0].nodeType === Node.COMMENT_NODE) return;
151
148
 
152
- assertNotHasOwnProperty(value, '"option value"');
153
- if (value === "") {
154
- self.hasEmptyOption = true;
155
- self.emptyOption = element;
156
- }
157
- const count = optionsMap.get(value) || 0;
158
- optionsMap.set(value, count + 1);
159
- // Only render at the end of a digest. This improves render performance when many options
160
- // are added during a digest and ensures all relevant options are correctly marked as selected
161
- scheduleRender();
162
- };
149
+ assertNotHasOwnProperty(value, '"option value"');
150
+ if (value === "") {
151
+ self.hasEmptyOption = true;
152
+ self.emptyOption = element;
153
+ }
154
+ const count = optionsMap.get(value) || 0;
155
+ optionsMap.set(value, count + 1);
156
+ // Only render at the end of a digest. This improves render performance when many options
157
+ // are added during a digest and ensures all relevant options are correctly marked as selected
158
+ scheduleRender();
159
+ };
163
160
 
164
- // Tell the select control that an option, with the given value, has been removed
165
- self.removeOption = function (value) {
166
- const count = optionsMap.get(value);
167
- if (count) {
168
- if (count === 1) {
169
- optionsMap.delete(value);
170
- if (value === "") {
171
- self.hasEmptyOption = false;
172
- self.emptyOption = undefined;
173
- }
174
- } else {
175
- optionsMap.set(value, count - 1);
161
+ // Tell the select control that an option, with the given value, has been removed
162
+ self.removeOption = function (value) {
163
+ const count = optionsMap.get(value);
164
+ if (count) {
165
+ if (count === 1) {
166
+ optionsMap.delete(value);
167
+ if (value === "") {
168
+ self.hasEmptyOption = false;
169
+ self.emptyOption = undefined;
176
170
  }
171
+ } else {
172
+ optionsMap.set(value, count - 1);
177
173
  }
178
- };
179
-
180
- // Check whether the select control has an option matching the given value
181
- self.hasOption = function (value) {
182
- return !!optionsMap.get(value);
183
- };
174
+ }
175
+ };
184
176
 
185
- /**
186
- * @ngdoc method
187
- * @name select.SelectController#$hasEmptyOption
188
- *
189
- * @description
190
- *
191
- * Returns `true` if the select element currently has an empty option
192
- * element, i.e. an option that signifies that the select is empty / the selection is null.
193
- *
194
- */
195
- self.$hasEmptyOption = function () {
196
- return self.hasEmptyOption;
197
- };
177
+ // Check whether the select control has an option matching the given value
178
+ self.hasOption = function (value) {
179
+ return !!optionsMap.get(value);
180
+ };
198
181
 
199
- /**
200
- * @ngdoc method
201
- * @name select.SelectController#$isUnknownOptionSelected
202
- *
203
- * @description
204
- *
205
- * Returns `true` if the select element's unknown option is selected. The unknown option is added
206
- * and automatically selected whenever the select model doesn't match any option.
207
- *
208
- */
209
- self.$isUnknownOptionSelected = function () {
210
- // Presence of the unknown option means it is selected
211
- return $element[0].options[0] === self.unknownOption[0];
212
- };
182
+ /**
183
+ * @ngdoc method
184
+ * @name select.SelectController#$hasEmptyOption
185
+ *
186
+ * @description
187
+ *
188
+ * Returns `true` if the select element currently has an empty option
189
+ * element, i.e. an option that signifies that the select is empty / the selection is null.
190
+ *
191
+ */
192
+ self.$hasEmptyOption = function () {
193
+ return self.hasEmptyOption;
194
+ };
213
195
 
214
- /**
215
- * @ngdoc method
216
- * @name select.SelectController#$isEmptyOptionSelected
217
- *
218
- * @description
219
- *
220
- * Returns `true` if the select element has an empty option and this empty option is currently
221
- * selected. Returns `false` if the select element has no empty option or it is not selected.
222
- *
223
- */
224
- self.$isEmptyOptionSelected = function () {
225
- return (
226
- self.hasEmptyOption &&
227
- $element[0].options[$element[0].selectedIndex] === self.emptyOption[0]
228
- );
229
- };
196
+ /**
197
+ * @ngdoc method
198
+ * @name select.SelectController#$isUnknownOptionSelected
199
+ *
200
+ * @description
201
+ *
202
+ * Returns `true` if the select element's unknown option is selected. The unknown option is added
203
+ * and automatically selected whenever the select model doesn't match any option.
204
+ *
205
+ */
206
+ self.$isUnknownOptionSelected = function () {
207
+ // Presence of the unknown option means it is selected
208
+ return $element[0].options[0] === self.unknownOption[0];
209
+ };
230
210
 
231
- self.selectUnknownOrEmptyOption = function (value) {
232
- if (value == null && self.emptyOption) {
233
- self.removeUnknownOption();
234
- self.selectEmptyOption();
235
- } else if (self.unknownOption.parent().length) {
236
- self.updateUnknownOption(value);
237
- } else {
238
- self.renderUnknownOption(value);
239
- }
240
- };
211
+ /**
212
+ * @ngdoc method
213
+ * @name select.SelectController#$isEmptyOptionSelected
214
+ *
215
+ * @description
216
+ *
217
+ * Returns `true` if the select element has an empty option and this empty option is currently
218
+ * selected. Returns `false` if the select element has no empty option or it is not selected.
219
+ *
220
+ */
221
+ self.$isEmptyOptionSelected = function () {
222
+ return (
223
+ self.hasEmptyOption &&
224
+ $element[0].options[$element[0].selectedIndex] === self.emptyOption[0]
225
+ );
226
+ };
241
227
 
242
- let renderScheduled = false;
243
- function scheduleRender() {
244
- if (renderScheduled) return;
245
- renderScheduled = true;
246
- $scope.$$postDigest(() => {
247
- renderScheduled = false;
248
- self.ngModelCtrl.$render();
249
- });
228
+ self.selectUnknownOrEmptyOption = function (value) {
229
+ if (value == null && self.emptyOption) {
230
+ self.removeUnknownOption();
231
+ self.selectEmptyOption();
232
+ } else if (self.unknownOption.parent().length) {
233
+ self.updateUnknownOption(value);
234
+ } else {
235
+ self.renderUnknownOption(value);
250
236
  }
237
+ };
251
238
 
252
- let updateScheduled = false;
253
- function scheduleViewValueUpdate(renderAfter) {
254
- if (updateScheduled) return;
255
-
256
- updateScheduled = true;
239
+ let renderScheduled = false;
240
+ function scheduleRender() {
241
+ if (renderScheduled) return;
242
+ renderScheduled = true;
243
+ $scope.$$postDigest(() => {
244
+ renderScheduled = false;
245
+ self.ngModelCtrl.$render();
246
+ });
247
+ }
257
248
 
258
- $scope.$$postDigest(() => {
259
- if ($scope.$$destroyed) return;
249
+ let updateScheduled = false;
250
+ function scheduleViewValueUpdate(renderAfter) {
251
+ if (updateScheduled) return;
260
252
 
261
- updateScheduled = false;
262
- self.ngModelCtrl.$setViewValue(self.readValue());
263
- if (renderAfter) self.ngModelCtrl.$render();
264
- });
265
- }
253
+ updateScheduled = true;
266
254
 
267
- self.registerOption = function (
268
- optionScope,
269
- optionElement,
270
- optionAttrs,
271
- interpolateValueFn,
272
- interpolateTextFn,
273
- ) {
274
- let oldVal;
275
- let hashedVal;
276
- if (optionAttrs.$attr.ngValue) {
277
- // The value attribute is set by ngValue
278
-
279
- optionAttrs.$observe("value", (newVal) => {
280
- let removal;
281
- const previouslySelected = optionElement[0].selected;
282
-
283
- if (isDefined(hashedVal)) {
284
- self.removeOption(oldVal);
285
- delete self.selectValueMap[hashedVal];
286
- removal = true;
287
- }
255
+ $scope.$$postDigest(() => {
256
+ if ($scope.$$destroyed) return;
288
257
 
289
- hashedVal = hashKey(newVal);
290
- oldVal = newVal;
291
- self.selectValueMap[hashedVal] = newVal;
292
- self.addOption(newVal, optionElement);
293
- // Set the attribute directly instead of using optionAttrs.$set - this stops the observer
294
- // from firing a second time. Other $observers on value will also get the result of the
295
- // ngValue expression, not the hashed value
296
- optionElement.attr("value", hashedVal);
297
-
298
- if (removal && previouslySelected) {
299
- scheduleViewValueUpdate();
300
- }
301
- });
302
- } else if (interpolateValueFn) {
303
- // The value attribute is interpolated
304
- optionAttrs.$observe("value", (newVal) => {
305
- // This method is overwritten in ngOptions and has side-effects!
306
- self.readValue();
307
-
308
- let removal;
309
- const previouslySelected = optionElement[0].selected;
310
-
311
- if (isDefined(oldVal)) {
312
- self.removeOption(oldVal);
313
- removal = true;
314
- }
315
- oldVal = newVal;
316
- self.addOption(newVal, optionElement);
317
-
318
- if (removal && previouslySelected) {
319
- scheduleViewValueUpdate();
320
- }
321
- });
322
- } else if (interpolateTextFn) {
323
- // The text content is interpolated
324
- optionScope.$watch(interpolateTextFn, (newVal, oldVal) => {
325
- optionAttrs.$set("value", newVal);
326
- const previouslySelected = optionElement[0].selected;
327
- if (oldVal !== newVal) {
328
- self.removeOption(oldVal);
329
- }
330
- self.addOption(newVal, optionElement);
258
+ updateScheduled = false;
259
+ self.ngModelCtrl.$setViewValue(self.readValue());
260
+ if (renderAfter) self.ngModelCtrl.$render();
261
+ });
262
+ }
331
263
 
332
- if (oldVal && previouslySelected) {
333
- scheduleViewValueUpdate();
334
- }
335
- });
336
- } else {
337
- // The value attribute is static
338
- self.addOption(optionAttrs.value, optionElement);
339
- }
264
+ self.registerOption = function (
265
+ optionScope,
266
+ optionElement,
267
+ optionAttrs,
268
+ interpolateValueFn,
269
+ interpolateTextFn,
270
+ ) {
271
+ let oldVal;
272
+ let hashedVal;
273
+ if (optionAttrs.$attr.ngValue) {
274
+ // The value attribute is set by ngValue
275
+
276
+ optionAttrs.$observe("value", (newVal) => {
277
+ let removal;
278
+ const previouslySelected = optionElement[0].selected;
279
+
280
+ if (isDefined(hashedVal)) {
281
+ self.removeOption(oldVal);
282
+ delete self.selectValueMap[hashedVal];
283
+ removal = true;
284
+ }
340
285
 
341
- optionAttrs.$observe("disabled", (newVal) => {
342
- // Since model updates will also select disabled options (like ngOptions),
343
- // we only have to handle options becoming disabled, not enabled
286
+ hashedVal = hashKey(newVal);
287
+ oldVal = newVal;
288
+ self.selectValueMap[hashedVal] = newVal;
289
+ self.addOption(newVal, optionElement);
290
+ // Set the attribute directly instead of using optionAttrs.$set - this stops the observer
291
+ // from firing a second time. Other $observers on value will also get the result of the
292
+ // ngValue expression, not the hashed value
293
+ optionElement.attr("value", hashedVal);
294
+
295
+ if (removal && previouslySelected) {
296
+ scheduleViewValueUpdate();
297
+ }
298
+ });
299
+ } else if (interpolateValueFn) {
300
+ // The value attribute is interpolated
301
+ optionAttrs.$observe("value", (newVal) => {
302
+ // This method is overwritten in ngOptions and has side-effects!
303
+ self.readValue();
304
+
305
+ let removal;
306
+ const previouslySelected = optionElement[0].selected;
307
+
308
+ if (isDefined(oldVal)) {
309
+ self.removeOption(oldVal);
310
+ removal = true;
311
+ }
312
+ oldVal = newVal;
313
+ self.addOption(newVal, optionElement);
344
314
 
345
- if (newVal === "true" || (newVal && optionElement[0].selected)) {
346
- if (self.multiple) {
347
- scheduleViewValueUpdate(true);
348
- } else {
349
- self.ngModelCtrl.$setViewValue(null);
350
- self.ngModelCtrl.$render();
351
- }
315
+ if (removal && previouslySelected) {
316
+ scheduleViewValueUpdate();
352
317
  }
353
318
  });
319
+ } else if (interpolateTextFn) {
320
+ // The text content is interpolated
321
+ optionScope.$watch(interpolateTextFn, (newVal, oldVal) => {
322
+ optionAttrs.$set("value", newVal);
323
+ const previouslySelected = optionElement[0].selected;
324
+ if (oldVal !== newVal) {
325
+ self.removeOption(oldVal);
326
+ }
327
+ self.addOption(newVal, optionElement);
354
328
 
355
- optionElement.on("$destroy", () => {
356
- const currentValue = self.readValue();
357
- const removeValue = optionAttrs.value;
329
+ if (oldVal && previouslySelected) {
330
+ scheduleViewValueUpdate();
331
+ }
332
+ });
333
+ } else {
334
+ // The value attribute is static
335
+ self.addOption(optionAttrs.value, optionElement);
336
+ }
358
337
 
359
- self.removeOption(removeValue);
360
- scheduleRender();
338
+ optionAttrs.$observe("disabled", (newVal) => {
339
+ // Since model updates will also select disabled options (like ngOptions),
340
+ // we only have to handle options becoming disabled, not enabled
361
341
 
362
- if (
363
- (self.multiple &&
364
- currentValue &&
365
- currentValue.indexOf(removeValue) !== -1) ||
366
- currentValue === removeValue
367
- ) {
368
- // When multiple (selected) options are destroyed at the same time, we don't want
369
- // to run a model update for each of them. Instead, run a single update in the $$postDigest
342
+ if (newVal === "true" || (newVal && optionElement[0].selected)) {
343
+ if (self.multiple) {
370
344
  scheduleViewValueUpdate(true);
345
+ } else {
346
+ self.ngModelCtrl.$setViewValue(null);
347
+ self.ngModelCtrl.$render();
371
348
  }
372
- });
373
- };
374
- },
375
- ];
349
+ }
350
+ });
351
+
352
+ optionElement.on("$destroy", () => {
353
+ const currentValue = self.readValue();
354
+ const removeValue = optionAttrs.value;
355
+
356
+ self.removeOption(removeValue);
357
+ scheduleRender();
358
+
359
+ if (
360
+ (self.multiple &&
361
+ currentValue &&
362
+ currentValue.indexOf(removeValue) !== -1) ||
363
+ currentValue === removeValue
364
+ ) {
365
+ // When multiple (selected) options are destroyed at the same time, we don't want
366
+ // to run a model update for each of them. Instead, run a single update in the $$postDigest
367
+ scheduleViewValueUpdate(true);
368
+ }
369
+ });
370
+ };
371
+ }
376
372
 
377
373
  /**
378
374
  * @ngdoc directive
package/src/public.js CHANGED
@@ -185,7 +185,6 @@ export function publishExternalAPI() {
185
185
  $cacheFactory: CacheFactoryProvider,
186
186
  $controller: $ControllerProvider,
187
187
  $document: $DocumentProvider,
188
- $$isDocumentHidden: $$IsDocumentHiddenProvider,
189
188
  $exceptionHandler: $ExceptionHandlerProvider,
190
189
  $filter: $FilterProvider,
191
190
  $interpolate: $InterpolateProvider,