observers.es5.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /**
  2. * @license
  3. * Copyright Google LLC All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. import { coerceBooleanProperty, coerceNumberProperty, coerceElement } from '@angular/cdk/coercion';
  9. import { Directive, ElementRef, EventEmitter, Injectable, Input, NgModule, NgZone, Output, ɵɵdefineInjectable, ɵɵinject } from '@angular/core';
  10. import { Observable, Subject } from 'rxjs';
  11. import { debounceTime } from 'rxjs/operators';
  12. /**
  13. * @fileoverview added by tsickle
  14. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  15. */
  16. /**
  17. * Factory that creates a new MutationObserver and allows us to stub it out in unit tests.
  18. * \@docs-private
  19. */
  20. var MutationObserverFactory = /** @class */ (function () {
  21. function MutationObserverFactory() {
  22. }
  23. /**
  24. * @param {?} callback
  25. * @return {?}
  26. */
  27. MutationObserverFactory.prototype.create = /**
  28. * @param {?} callback
  29. * @return {?}
  30. */
  31. function (callback) {
  32. return typeof MutationObserver === 'undefined' ? null : new MutationObserver(callback);
  33. };
  34. MutationObserverFactory.decorators = [
  35. { type: Injectable, args: [{ providedIn: 'root' },] },
  36. ];
  37. /** @nocollapse */ MutationObserverFactory.ngInjectableDef = ɵɵdefineInjectable({ factory: function MutationObserverFactory_Factory() { return new MutationObserverFactory(); }, token: MutationObserverFactory, providedIn: "root" });
  38. return MutationObserverFactory;
  39. }());
  40. /**
  41. * An injectable service that allows watching elements for changes to their content.
  42. */
  43. var ContentObserver = /** @class */ (function () {
  44. function ContentObserver(_mutationObserverFactory) {
  45. this._mutationObserverFactory = _mutationObserverFactory;
  46. /**
  47. * Keeps track of the existing MutationObservers so they can be reused.
  48. */
  49. this._observedElements = new Map();
  50. }
  51. /**
  52. * @return {?}
  53. */
  54. ContentObserver.prototype.ngOnDestroy = /**
  55. * @return {?}
  56. */
  57. function () {
  58. var _this = this;
  59. this._observedElements.forEach((/**
  60. * @param {?} _
  61. * @param {?} element
  62. * @return {?}
  63. */
  64. function (_, element) { return _this._cleanupObserver(element); }));
  65. };
  66. /**
  67. * @param {?} elementOrRef
  68. * @return {?}
  69. */
  70. ContentObserver.prototype.observe = /**
  71. * @param {?} elementOrRef
  72. * @return {?}
  73. */
  74. function (elementOrRef) {
  75. var _this = this;
  76. /** @type {?} */
  77. var element = coerceElement(elementOrRef);
  78. return new Observable((/**
  79. * @param {?} observer
  80. * @return {?}
  81. */
  82. function (observer) {
  83. /** @type {?} */
  84. var stream = _this._observeElement(element);
  85. /** @type {?} */
  86. var subscription = stream.subscribe(observer);
  87. return (/**
  88. * @return {?}
  89. */
  90. function () {
  91. subscription.unsubscribe();
  92. _this._unobserveElement(element);
  93. });
  94. }));
  95. };
  96. /**
  97. * Observes the given element by using the existing MutationObserver if available, or creating a
  98. * new one if not.
  99. */
  100. /**
  101. * Observes the given element by using the existing MutationObserver if available, or creating a
  102. * new one if not.
  103. * @private
  104. * @param {?} element
  105. * @return {?}
  106. */
  107. ContentObserver.prototype._observeElement = /**
  108. * Observes the given element by using the existing MutationObserver if available, or creating a
  109. * new one if not.
  110. * @private
  111. * @param {?} element
  112. * @return {?}
  113. */
  114. function (element) {
  115. if (!this._observedElements.has(element)) {
  116. /** @type {?} */
  117. var stream_1 = new Subject();
  118. /** @type {?} */
  119. var observer = this._mutationObserverFactory.create((/**
  120. * @param {?} mutations
  121. * @return {?}
  122. */
  123. function (mutations) { return stream_1.next(mutations); }));
  124. if (observer) {
  125. observer.observe(element, {
  126. characterData: true,
  127. childList: true,
  128. subtree: true
  129. });
  130. }
  131. this._observedElements.set(element, { observer: observer, stream: stream_1, count: 1 });
  132. }
  133. else {
  134. (/** @type {?} */ (this._observedElements.get(element))).count++;
  135. }
  136. return (/** @type {?} */ (this._observedElements.get(element))).stream;
  137. };
  138. /**
  139. * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is
  140. * observing this element.
  141. */
  142. /**
  143. * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is
  144. * observing this element.
  145. * @private
  146. * @param {?} element
  147. * @return {?}
  148. */
  149. ContentObserver.prototype._unobserveElement = /**
  150. * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is
  151. * observing this element.
  152. * @private
  153. * @param {?} element
  154. * @return {?}
  155. */
  156. function (element) {
  157. if (this._observedElements.has(element)) {
  158. (/** @type {?} */ (this._observedElements.get(element))).count--;
  159. if (!(/** @type {?} */ (this._observedElements.get(element))).count) {
  160. this._cleanupObserver(element);
  161. }
  162. }
  163. };
  164. /** Clean up the underlying MutationObserver for the specified element. */
  165. /**
  166. * Clean up the underlying MutationObserver for the specified element.
  167. * @private
  168. * @param {?} element
  169. * @return {?}
  170. */
  171. ContentObserver.prototype._cleanupObserver = /**
  172. * Clean up the underlying MutationObserver for the specified element.
  173. * @private
  174. * @param {?} element
  175. * @return {?}
  176. */
  177. function (element) {
  178. if (this._observedElements.has(element)) {
  179. var _a = (/** @type {?} */ (this._observedElements.get(element))), observer = _a.observer, stream = _a.stream;
  180. if (observer) {
  181. observer.disconnect();
  182. }
  183. stream.complete();
  184. this._observedElements.delete(element);
  185. }
  186. };
  187. ContentObserver.decorators = [
  188. { type: Injectable, args: [{ providedIn: 'root' },] },
  189. ];
  190. /** @nocollapse */
  191. ContentObserver.ctorParameters = function () { return [
  192. { type: MutationObserverFactory }
  193. ]; };
  194. /** @nocollapse */ ContentObserver.ngInjectableDef = ɵɵdefineInjectable({ factory: function ContentObserver_Factory() { return new ContentObserver(ɵɵinject(MutationObserverFactory)); }, token: ContentObserver, providedIn: "root" });
  195. return ContentObserver;
  196. }());
  197. /**
  198. * Directive that triggers a callback whenever the content of
  199. * its associated element has changed.
  200. */
  201. var CdkObserveContent = /** @class */ (function () {
  202. function CdkObserveContent(_contentObserver, _elementRef, _ngZone) {
  203. this._contentObserver = _contentObserver;
  204. this._elementRef = _elementRef;
  205. this._ngZone = _ngZone;
  206. /**
  207. * Event emitted for each change in the element's content.
  208. */
  209. this.event = new EventEmitter();
  210. this._disabled = false;
  211. this._currentSubscription = null;
  212. }
  213. Object.defineProperty(CdkObserveContent.prototype, "disabled", {
  214. /**
  215. * Whether observing content is disabled. This option can be used
  216. * to disconnect the underlying MutationObserver until it is needed.
  217. */
  218. get: /**
  219. * Whether observing content is disabled. This option can be used
  220. * to disconnect the underlying MutationObserver until it is needed.
  221. * @return {?}
  222. */
  223. function () { return this._disabled; },
  224. set: /**
  225. * @param {?} value
  226. * @return {?}
  227. */
  228. function (value) {
  229. this._disabled = coerceBooleanProperty(value);
  230. this._disabled ? this._unsubscribe() : this._subscribe();
  231. },
  232. enumerable: true,
  233. configurable: true
  234. });
  235. Object.defineProperty(CdkObserveContent.prototype, "debounce", {
  236. /** Debounce interval for emitting the changes. */
  237. get: /**
  238. * Debounce interval for emitting the changes.
  239. * @return {?}
  240. */
  241. function () { return this._debounce; },
  242. set: /**
  243. * @param {?} value
  244. * @return {?}
  245. */
  246. function (value) {
  247. this._debounce = coerceNumberProperty(value);
  248. this._subscribe();
  249. },
  250. enumerable: true,
  251. configurable: true
  252. });
  253. /**
  254. * @return {?}
  255. */
  256. CdkObserveContent.prototype.ngAfterContentInit = /**
  257. * @return {?}
  258. */
  259. function () {
  260. if (!this._currentSubscription && !this.disabled) {
  261. this._subscribe();
  262. }
  263. };
  264. /**
  265. * @return {?}
  266. */
  267. CdkObserveContent.prototype.ngOnDestroy = /**
  268. * @return {?}
  269. */
  270. function () {
  271. this._unsubscribe();
  272. };
  273. /**
  274. * @private
  275. * @return {?}
  276. */
  277. CdkObserveContent.prototype._subscribe = /**
  278. * @private
  279. * @return {?}
  280. */
  281. function () {
  282. var _this = this;
  283. this._unsubscribe();
  284. /** @type {?} */
  285. var stream = this._contentObserver.observe(this._elementRef);
  286. // TODO(mmalerba): We shouldn't be emitting on this @Output() outside the zone.
  287. // Consider brining it back inside the zone next time we're making breaking changes.
  288. // Bringing it back inside can cause things like infinite change detection loops and changed
  289. // after checked errors if people's code isn't handling it properly.
  290. this._ngZone.runOutsideAngular((/**
  291. * @return {?}
  292. */
  293. function () {
  294. _this._currentSubscription =
  295. (_this.debounce ? stream.pipe(debounceTime(_this.debounce)) : stream).subscribe(_this.event);
  296. }));
  297. };
  298. /**
  299. * @private
  300. * @return {?}
  301. */
  302. CdkObserveContent.prototype._unsubscribe = /**
  303. * @private
  304. * @return {?}
  305. */
  306. function () {
  307. if (this._currentSubscription) {
  308. this._currentSubscription.unsubscribe();
  309. }
  310. };
  311. CdkObserveContent.decorators = [
  312. { type: Directive, args: [{
  313. selector: '[cdkObserveContent]',
  314. exportAs: 'cdkObserveContent',
  315. },] },
  316. ];
  317. /** @nocollapse */
  318. CdkObserveContent.ctorParameters = function () { return [
  319. { type: ContentObserver },
  320. { type: ElementRef },
  321. { type: NgZone }
  322. ]; };
  323. CdkObserveContent.propDecorators = {
  324. event: [{ type: Output, args: ['cdkObserveContent',] }],
  325. disabled: [{ type: Input, args: ['cdkObserveContentDisabled',] }],
  326. debounce: [{ type: Input }]
  327. };
  328. return CdkObserveContent;
  329. }());
  330. var ObserversModule = /** @class */ (function () {
  331. function ObserversModule() {
  332. }
  333. ObserversModule.decorators = [
  334. { type: NgModule, args: [{
  335. exports: [CdkObserveContent],
  336. declarations: [CdkObserveContent],
  337. providers: [MutationObserverFactory]
  338. },] },
  339. ];
  340. return ObserversModule;
  341. }());
  342. /**
  343. * @fileoverview added by tsickle
  344. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  345. */
  346. /**
  347. * @fileoverview added by tsickle
  348. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  349. */
  350. export { MutationObserverFactory, ContentObserver, CdkObserveContent, ObserversModule };
  351. //# sourceMappingURL=observers.es5.js.map