source: trip-planner-front/node_modules/@angular/cdk/fesm2015/text-field.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 18.5 KB
Line 
1import * as i1 from '@angular/cdk/platform';
2import { normalizePassiveListenerOptions, Platform, PlatformModule } from '@angular/cdk/platform';
3import * as i0 from '@angular/core';
4import { Injectable, NgZone, EventEmitter, Directive, ElementRef, Output, Optional, Inject, Input, HostListener, NgModule } from '@angular/core';
5import { coerceElement, coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
6import { EMPTY, Subject, fromEvent } from 'rxjs';
7import { auditTime, takeUntil } from 'rxjs/operators';
8import { DOCUMENT } from '@angular/common';
9
10/**
11 * @license
12 * Copyright Google LLC All Rights Reserved.
13 *
14 * Use of this source code is governed by an MIT-style license that can be
15 * found in the LICENSE file at https://angular.io/license
16 */
17/** Options to pass to the animationstart listener. */
18const listenerOptions = normalizePassiveListenerOptions({ passive: true });
19/**
20 * An injectable service that can be used to monitor the autofill state of an input.
21 * Based on the following blog post:
22 * https://medium.com/@brunn/detecting-autofilled-fields-in-javascript-aed598d25da7
23 */
24class AutofillMonitor {
25 constructor(_platform, _ngZone) {
26 this._platform = _platform;
27 this._ngZone = _ngZone;
28 this._monitoredElements = new Map();
29 }
30 monitor(elementOrRef) {
31 if (!this._platform.isBrowser) {
32 return EMPTY;
33 }
34 const element = coerceElement(elementOrRef);
35 const info = this._monitoredElements.get(element);
36 if (info) {
37 return info.subject;
38 }
39 const result = new Subject();
40 const cssClass = 'cdk-text-field-autofilled';
41 const listener = ((event) => {
42 // Animation events fire on initial element render, we check for the presence of the autofill
43 // CSS class to make sure this is a real change in state, not just the initial render before
44 // we fire off events.
45 if (event.animationName === 'cdk-text-field-autofill-start' &&
46 !element.classList.contains(cssClass)) {
47 element.classList.add(cssClass);
48 this._ngZone.run(() => result.next({ target: event.target, isAutofilled: true }));
49 }
50 else if (event.animationName === 'cdk-text-field-autofill-end' &&
51 element.classList.contains(cssClass)) {
52 element.classList.remove(cssClass);
53 this._ngZone.run(() => result.next({ target: event.target, isAutofilled: false }));
54 }
55 });
56 this._ngZone.runOutsideAngular(() => {
57 element.addEventListener('animationstart', listener, listenerOptions);
58 element.classList.add('cdk-text-field-autofill-monitored');
59 });
60 this._monitoredElements.set(element, {
61 subject: result,
62 unlisten: () => {
63 element.removeEventListener('animationstart', listener, listenerOptions);
64 }
65 });
66 return result;
67 }
68 stopMonitoring(elementOrRef) {
69 const element = coerceElement(elementOrRef);
70 const info = this._monitoredElements.get(element);
71 if (info) {
72 info.unlisten();
73 info.subject.complete();
74 element.classList.remove('cdk-text-field-autofill-monitored');
75 element.classList.remove('cdk-text-field-autofilled');
76 this._monitoredElements.delete(element);
77 }
78 }
79 ngOnDestroy() {
80 this._monitoredElements.forEach((_info, element) => this.stopMonitoring(element));
81 }
82}
83AutofillMonitor.ɵprov = i0.ɵɵdefineInjectable({ factory: function AutofillMonitor_Factory() { return new AutofillMonitor(i0.ɵɵinject(i1.Platform), i0.ɵɵinject(i0.NgZone)); }, token: AutofillMonitor, providedIn: "root" });
84AutofillMonitor.decorators = [
85 { type: Injectable, args: [{ providedIn: 'root' },] }
86];
87AutofillMonitor.ctorParameters = () => [
88 { type: Platform },
89 { type: NgZone }
90];
91/** A directive that can be used to monitor the autofill state of an input. */
92class CdkAutofill {
93 constructor(_elementRef, _autofillMonitor) {
94 this._elementRef = _elementRef;
95 this._autofillMonitor = _autofillMonitor;
96 /** Emits when the autofill state of the element changes. */
97 this.cdkAutofill = new EventEmitter();
98 }
99 ngOnInit() {
100 this._autofillMonitor
101 .monitor(this._elementRef)
102 .subscribe(event => this.cdkAutofill.emit(event));
103 }
104 ngOnDestroy() {
105 this._autofillMonitor.stopMonitoring(this._elementRef);
106 }
107}
108CdkAutofill.decorators = [
109 { type: Directive, args: [{
110 selector: '[cdkAutofill]',
111 },] }
112];
113CdkAutofill.ctorParameters = () => [
114 { type: ElementRef },
115 { type: AutofillMonitor }
116];
117CdkAutofill.propDecorators = {
118 cdkAutofill: [{ type: Output }]
119};
120
121/**
122 * @license
123 * Copyright Google LLC All Rights Reserved.
124 *
125 * Use of this source code is governed by an MIT-style license that can be
126 * found in the LICENSE file at https://angular.io/license
127 */
128/** Directive to automatically resize a textarea to fit its content. */
129class CdkTextareaAutosize {
130 constructor(_elementRef, _platform, _ngZone,
131 /** @breaking-change 11.0.0 make document required */
132 document) {
133 this._elementRef = _elementRef;
134 this._platform = _platform;
135 this._ngZone = _ngZone;
136 this._destroyed = new Subject();
137 this._enabled = true;
138 /**
139 * Value of minRows as of last resize. If the minRows has decreased, the
140 * height of the textarea needs to be recomputed to reflect the new minimum. The maxHeight
141 * does not have the same problem because it does not affect the textarea's scrollHeight.
142 */
143 this._previousMinRows = -1;
144 this._isViewInited = false;
145 /** Handles `focus` and `blur` events. */
146 this._handleFocusEvent = (event) => {
147 this._hasFocus = event.type === 'focus';
148 };
149 this._document = document;
150 this._textareaElement = this._elementRef.nativeElement;
151 }
152 /** Minimum amount of rows in the textarea. */
153 get minRows() { return this._minRows; }
154 set minRows(value) {
155 this._minRows = coerceNumberProperty(value);
156 this._setMinHeight();
157 }
158 /** Maximum amount of rows in the textarea. */
159 get maxRows() { return this._maxRows; }
160 set maxRows(value) {
161 this._maxRows = coerceNumberProperty(value);
162 this._setMaxHeight();
163 }
164 /** Whether autosizing is enabled or not */
165 get enabled() { return this._enabled; }
166 set enabled(value) {
167 value = coerceBooleanProperty(value);
168 // Only act if the actual value changed. This specifically helps to not run
169 // resizeToFitContent too early (i.e. before ngAfterViewInit)
170 if (this._enabled !== value) {
171 (this._enabled = value) ? this.resizeToFitContent(true) : this.reset();
172 }
173 }
174 get placeholder() { return this._textareaElement.placeholder; }
175 set placeholder(value) {
176 this._cachedPlaceholderHeight = undefined;
177 this._textareaElement.placeholder = value;
178 this._cacheTextareaPlaceholderHeight();
179 }
180 /** Sets the minimum height of the textarea as determined by minRows. */
181 _setMinHeight() {
182 const minHeight = this.minRows && this._cachedLineHeight ?
183 `${this.minRows * this._cachedLineHeight}px` : null;
184 if (minHeight) {
185 this._textareaElement.style.minHeight = minHeight;
186 }
187 }
188 /** Sets the maximum height of the textarea as determined by maxRows. */
189 _setMaxHeight() {
190 const maxHeight = this.maxRows && this._cachedLineHeight ?
191 `${this.maxRows * this._cachedLineHeight}px` : null;
192 if (maxHeight) {
193 this._textareaElement.style.maxHeight = maxHeight;
194 }
195 }
196 ngAfterViewInit() {
197 if (this._platform.isBrowser) {
198 // Remember the height which we started with in case autosizing is disabled
199 this._initialHeight = this._textareaElement.style.height;
200 this.resizeToFitContent();
201 this._ngZone.runOutsideAngular(() => {
202 const window = this._getWindow();
203 fromEvent(window, 'resize')
204 .pipe(auditTime(16), takeUntil(this._destroyed))
205 .subscribe(() => this.resizeToFitContent(true));
206 this._textareaElement.addEventListener('focus', this._handleFocusEvent);
207 this._textareaElement.addEventListener('blur', this._handleFocusEvent);
208 });
209 this._isViewInited = true;
210 this.resizeToFitContent(true);
211 }
212 }
213 ngOnDestroy() {
214 this._textareaElement.removeEventListener('focus', this._handleFocusEvent);
215 this._textareaElement.removeEventListener('blur', this._handleFocusEvent);
216 this._destroyed.next();
217 this._destroyed.complete();
218 }
219 /**
220 * Cache the height of a single-row textarea if it has not already been cached.
221 *
222 * We need to know how large a single "row" of a textarea is in order to apply minRows and
223 * maxRows. For the initial version, we will assume that the height of a single line in the
224 * textarea does not ever change.
225 */
226 _cacheTextareaLineHeight() {
227 if (this._cachedLineHeight) {
228 return;
229 }
230 // Use a clone element because we have to override some styles.
231 let textareaClone = this._textareaElement.cloneNode(false);
232 textareaClone.rows = 1;
233 // Use `position: absolute` so that this doesn't cause a browser layout and use
234 // `visibility: hidden` so that nothing is rendered. Clear any other styles that
235 // would affect the height.
236 textareaClone.style.position = 'absolute';
237 textareaClone.style.visibility = 'hidden';
238 textareaClone.style.border = 'none';
239 textareaClone.style.padding = '0';
240 textareaClone.style.height = '';
241 textareaClone.style.minHeight = '';
242 textareaClone.style.maxHeight = '';
243 // In Firefox it happens that textarea elements are always bigger than the specified amount
244 // of rows. This is because Firefox tries to add extra space for the horizontal scrollbar.
245 // As a workaround that removes the extra space for the scrollbar, we can just set overflow
246 // to hidden. This ensures that there is no invalid calculation of the line height.
247 // See Firefox bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=33654
248 textareaClone.style.overflow = 'hidden';
249 this._textareaElement.parentNode.appendChild(textareaClone);
250 this._cachedLineHeight = textareaClone.clientHeight;
251 this._textareaElement.parentNode.removeChild(textareaClone);
252 // Min and max heights have to be re-calculated if the cached line height changes
253 this._setMinHeight();
254 this._setMaxHeight();
255 }
256 _measureScrollHeight() {
257 const element = this._textareaElement;
258 const previousMargin = element.style.marginBottom || '';
259 const isFirefox = this._platform.FIREFOX;
260 const needsMarginFiller = isFirefox && this._hasFocus;
261 const measuringClass = isFirefox ?
262 'cdk-textarea-autosize-measuring-firefox' :
263 'cdk-textarea-autosize-measuring';
264 // In some cases the page might move around while we're measuring the `textarea` on Firefox. We
265 // work around it by assigning a temporary margin with the same height as the `textarea` so that
266 // it occupies the same amount of space. See #23233.
267 if (needsMarginFiller) {
268 element.style.marginBottom = `${element.clientHeight}px`;
269 }
270 // Reset the textarea height to auto in order to shrink back to its default size.
271 // Also temporarily force overflow:hidden, so scroll bars do not interfere with calculations.
272 element.classList.add(measuringClass);
273 // The measuring class includes a 2px padding to workaround an issue with Chrome,
274 // so we account for that extra space here by subtracting 4 (2px top + 2px bottom).
275 const scrollHeight = element.scrollHeight - 4;
276 element.classList.remove(measuringClass);
277 if (needsMarginFiller) {
278 element.style.marginBottom = previousMargin;
279 }
280 return scrollHeight;
281 }
282 _cacheTextareaPlaceholderHeight() {
283 if (!this._isViewInited || this._cachedPlaceholderHeight != undefined) {
284 return;
285 }
286 if (!this.placeholder) {
287 this._cachedPlaceholderHeight = 0;
288 return;
289 }
290 const value = this._textareaElement.value;
291 this._textareaElement.value = this._textareaElement.placeholder;
292 this._cachedPlaceholderHeight = this._measureScrollHeight();
293 this._textareaElement.value = value;
294 }
295 ngDoCheck() {
296 if (this._platform.isBrowser) {
297 this.resizeToFitContent();
298 }
299 }
300 /**
301 * Resize the textarea to fit its content.
302 * @param force Whether to force a height recalculation. By default the height will be
303 * recalculated only if the value changed since the last call.
304 */
305 resizeToFitContent(force = false) {
306 // If autosizing is disabled, just skip everything else
307 if (!this._enabled) {
308 return;
309 }
310 this._cacheTextareaLineHeight();
311 this._cacheTextareaPlaceholderHeight();
312 // If we haven't determined the line-height yet, we know we're still hidden and there's no point
313 // in checking the height of the textarea.
314 if (!this._cachedLineHeight) {
315 return;
316 }
317 const textarea = this._elementRef.nativeElement;
318 const value = textarea.value;
319 // Only resize if the value or minRows have changed since these calculations can be expensive.
320 if (!force && this._minRows === this._previousMinRows && value === this._previousValue) {
321 return;
322 }
323 const scrollHeight = this._measureScrollHeight();
324 const height = Math.max(scrollHeight, this._cachedPlaceholderHeight || 0);
325 // Use the scrollHeight to know how large the textarea *would* be if fit its entire value.
326 textarea.style.height = `${height}px`;
327 this._ngZone.runOutsideAngular(() => {
328 if (typeof requestAnimationFrame !== 'undefined') {
329 requestAnimationFrame(() => this._scrollToCaretPosition(textarea));
330 }
331 else {
332 setTimeout(() => this._scrollToCaretPosition(textarea));
333 }
334 });
335 this._previousValue = value;
336 this._previousMinRows = this._minRows;
337 }
338 /**
339 * Resets the textarea to its original size
340 */
341 reset() {
342 // Do not try to change the textarea, if the initialHeight has not been determined yet
343 // This might potentially remove styles when reset() is called before ngAfterViewInit
344 if (this._initialHeight !== undefined) {
345 this._textareaElement.style.height = this._initialHeight;
346 }
347 }
348 // In Ivy the `host` metadata will be merged, whereas in ViewEngine it is overridden. In order
349 // to avoid double event listeners, we need to use `HostListener`. Once Ivy is the default, we
350 // can move this back into `host`.
351 // tslint:disable:no-host-decorator-in-concrete
352 _noopInputHandler() {
353 // no-op handler that ensures we're running change detection on input events.
354 }
355 /** Access injected document if available or fallback to global document reference */
356 _getDocument() {
357 return this._document || document;
358 }
359 /** Use defaultView of injected document if available or fallback to global window reference */
360 _getWindow() {
361 const doc = this._getDocument();
362 return doc.defaultView || window;
363 }
364 /**
365 * Scrolls a textarea to the caret position. On Firefox resizing the textarea will
366 * prevent it from scrolling to the caret position. We need to re-set the selection
367 * in order for it to scroll to the proper position.
368 */
369 _scrollToCaretPosition(textarea) {
370 const { selectionStart, selectionEnd } = textarea;
371 // IE will throw an "Unspecified error" if we try to set the selection range after the
372 // element has been removed from the DOM. Assert that the directive hasn't been destroyed
373 // between the time we requested the animation frame and when it was executed.
374 // Also note that we have to assert that the textarea is focused before we set the
375 // selection range. Setting the selection range on a non-focused textarea will cause
376 // it to receive focus on IE and Edge.
377 if (!this._destroyed.isStopped && this._hasFocus) {
378 textarea.setSelectionRange(selectionStart, selectionEnd);
379 }
380 }
381}
382CdkTextareaAutosize.decorators = [
383 { type: Directive, args: [{
384 selector: 'textarea[cdkTextareaAutosize]',
385 exportAs: 'cdkTextareaAutosize',
386 host: {
387 'class': 'cdk-textarea-autosize',
388 // Textarea elements that have the directive applied should have a single row by default.
389 // Browsers normally show two rows by default and therefore this limits the minRows binding.
390 'rows': '1',
391 },
392 },] }
393];
394CdkTextareaAutosize.ctorParameters = () => [
395 { type: ElementRef },
396 { type: Platform },
397 { type: NgZone },
398 { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] }
399];
400CdkTextareaAutosize.propDecorators = {
401 minRows: [{ type: Input, args: ['cdkAutosizeMinRows',] }],
402 maxRows: [{ type: Input, args: ['cdkAutosizeMaxRows',] }],
403 enabled: [{ type: Input, args: ['cdkTextareaAutosize',] }],
404 placeholder: [{ type: Input }],
405 _noopInputHandler: [{ type: HostListener, args: ['input',] }]
406};
407
408/**
409 * @license
410 * Copyright Google LLC All Rights Reserved.
411 *
412 * Use of this source code is governed by an MIT-style license that can be
413 * found in the LICENSE file at https://angular.io/license
414 */
415class TextFieldModule {
416}
417TextFieldModule.decorators = [
418 { type: NgModule, args: [{
419 declarations: [CdkAutofill, CdkTextareaAutosize],
420 imports: [PlatformModule],
421 exports: [CdkAutofill, CdkTextareaAutosize],
422 },] }
423];
424
425/**
426 * @license
427 * Copyright Google LLC All Rights Reserved.
428 *
429 * Use of this source code is governed by an MIT-style license that can be
430 * found in the LICENSE file at https://angular.io/license
431 */
432
433/**
434 * Generated bundle index. Do not edit.
435 */
436
437export { AutofillMonitor, CdkAutofill, CdkTextareaAutosize, TextFieldModule };
438//# sourceMappingURL=text-field.js.map
Note: See TracBrowser for help on using the repository browser.