blob: fe5e3f57b58be4bfb5588f5de7fc167f5491e1b5 [file] [log] [blame]
{"version":3,"file":"cdk-text-field.umd.min.js","sources":["../../src/cdk/text-field/autofill.ts","../../src/cdk/text-field/autosize.ts","../../src/cdk/text-field/text-field-module.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Platform, normalizePassiveListenerOptions} from '@angular/cdk/platform';\nimport {\n Directive,\n ElementRef,\n EventEmitter,\n Injectable,\n NgZone,\n OnDestroy,\n OnInit,\n Output,\n} from '@angular/core';\nimport {coerceElement} from '@angular/cdk/coercion';\nimport {EMPTY, Observable, Subject} from 'rxjs';\n\n\n/** An event that is emitted when the autofill state of an input changes. */\nexport type AutofillEvent = {\n /** The element whose autofill state changes. */\n target: Element;\n /** Whether the element is currently autofilled. */\n isAutofilled: boolean;\n};\n\n\n/** Used to track info about currently monitored elements. */\ntype MonitoredElementInfo = {\n subject: Subject<AutofillEvent>;\n unlisten: () => void;\n};\n\n\n/** Options to pass to the animationstart listener. */\nconst listenerOptions = normalizePassiveListenerOptions({passive: true});\n\n\n/**\n * An injectable service that can be used to monitor the autofill state of an input.\n * Based on the following blog post:\n * https://medium.com/@brunn/detecting-autofilled-fields-in-javascript-aed598d25da7\n */\n@Injectable({providedIn: 'root'})\nexport class AutofillMonitor implements OnDestroy {\n private _monitoredElements = new Map<Element, MonitoredElementInfo>();\n\n constructor(private _platform: Platform, private _ngZone: NgZone) {}\n\n /**\n * Monitor for changes in the autofill state of the given input element.\n * @param element The element to monitor.\n * @return A stream of autofill state changes.\n */\n monitor(element: Element): Observable<AutofillEvent>;\n\n /**\n * Monitor for changes in the autofill state of the given input element.\n * @param element The element to monitor.\n * @return A stream of autofill state changes.\n */\n monitor(element: ElementRef<Element>): Observable<AutofillEvent>;\n\n monitor(elementOrRef: Element | ElementRef<Element>): Observable<AutofillEvent> {\n if (!this._platform.isBrowser) {\n return EMPTY;\n }\n\n const element = coerceElement(elementOrRef);\n const info = this._monitoredElements.get(element);\n\n if (info) {\n return info.subject.asObservable();\n }\n\n const result = new Subject<AutofillEvent>();\n const cssClass = 'cdk-text-field-autofilled';\n const listener = ((event: AnimationEvent) => {\n // Animation events fire on initial element render, we check for the presence of the autofill\n // CSS class to make sure this is a real change in state, not just the initial render before\n // we fire off events.\n if (event.animationName === 'cdk-text-field-autofill-start' &&\n !element.classList.contains(cssClass)) {\n element.classList.add(cssClass);\n this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: true}));\n } else if (event.animationName === 'cdk-text-field-autofill-end' &&\n element.classList.contains(cssClass)) {\n element.classList.remove(cssClass);\n this._ngZone.run(() => result.next({target: event.target as Element, isAutofilled: false}));\n }\n }) as EventListenerOrEventListenerObject;\n\n this._ngZone.runOutsideAngular(() => {\n element.addEventListener('animationstart', listener, listenerOptions);\n element.classList.add('cdk-text-field-autofill-monitored');\n });\n\n this._monitoredElements.set(element, {\n subject: result,\n unlisten: () => {\n element.removeEventListener('animationstart', listener, listenerOptions);\n }\n });\n\n return result.asObservable();\n }\n\n /**\n * Stop monitoring the autofill state of the given input element.\n * @param element The element to stop monitoring.\n */\n stopMonitoring(element: Element): void;\n\n /**\n * Stop monitoring the autofill state of the given input element.\n * @param element The element to stop monitoring.\n */\n stopMonitoring(element: ElementRef<Element>): void;\n\n stopMonitoring(elementOrRef: Element | ElementRef<Element>): void {\n const element = coerceElement(elementOrRef);\n const info = this._monitoredElements.get(element);\n\n if (info) {\n info.unlisten();\n info.subject.complete();\n element.classList.remove('cdk-text-field-autofill-monitored');\n element.classList.remove('cdk-text-field-autofilled');\n this._monitoredElements.delete(element);\n }\n }\n\n ngOnDestroy() {\n this._monitoredElements.forEach((_info, element) => this.stopMonitoring(element));\n }\n}\n\n\n/** A directive that can be used to monitor the autofill state of an input. */\n@Directive({\n selector: '[cdkAutofill]',\n})\nexport class CdkAutofill implements OnDestroy, OnInit {\n /** Emits when the autofill state of the element changes. */\n @Output() cdkAutofill: EventEmitter<AutofillEvent> = new EventEmitter<AutofillEvent>();\n\n constructor(private _elementRef: ElementRef<HTMLElement>,\n private _autofillMonitor: AutofillMonitor) {}\n\n ngOnInit() {\n this._autofillMonitor\n .monitor(this._elementRef)\n .subscribe(event => this.cdkAutofill.emit(event));\n }\n\n ngOnDestroy() {\n this._autofillMonitor.stopMonitoring(this._elementRef);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {coerceBooleanProperty} from '@angular/cdk/coercion';\nimport {\n Directive,\n ElementRef,\n Input,\n AfterViewInit,\n DoCheck,\n OnDestroy,\n NgZone,\n} from '@angular/core';\nimport {Platform} from '@angular/cdk/platform';\nimport {auditTime, takeUntil} from 'rxjs/operators';\nimport {fromEvent, Subject} from 'rxjs';\n\n\n/** Directive to automatically resize a textarea to fit its content. */\n@Directive({\n selector: 'textarea[cdkTextareaAutosize]',\n exportAs: 'cdkTextareaAutosize',\n host: {\n 'class': 'cdk-textarea-autosize',\n // Textarea elements that have the directive applied should have a single row by default.\n // Browsers normally show two rows by default and therefore this limits the minRows binding.\n 'rows': '1',\n '(input)': '_noopInputHandler()',\n },\n})\nexport class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy {\n /** Keep track of the previous textarea value to avoid resizing when the value hasn't changed. */\n private _previousValue?: string;\n private _initialHeight: string | null;\n private readonly _destroyed = new Subject<void>();\n\n private _minRows: number;\n private _maxRows: number;\n private _enabled: boolean = true;\n\n /**\n * Value of minRows as of last resize. If the minRows has decreased, the\n * height of the textarea needs to be recomputed to reflect the new minimum. The maxHeight\n * does not have the same problem because it does not affect the textarea's scrollHeight.\n */\n private _previousMinRows: number = -1;\n\n private _textareaElement: HTMLTextAreaElement;\n\n /** Minimum amount of rows in the textarea. */\n @Input('cdkAutosizeMinRows')\n get minRows(): number { return this._minRows; }\n set minRows(value: number) {\n this._minRows = value;\n this._setMinHeight();\n }\n\n /** Maximum amount of rows in the textarea. */\n @Input('cdkAutosizeMaxRows')\n get maxRows(): number { return this._maxRows; }\n set maxRows(value: number) {\n this._maxRows = value;\n this._setMaxHeight();\n }\n\n /** Whether autosizing is enabled or not */\n @Input('cdkTextareaAutosize')\n get enabled(): boolean { return this._enabled; }\n set enabled(value: boolean) {\n value = coerceBooleanProperty(value);\n\n // Only act if the actual value changed. This specifically helps to not run\n // resizeToFitContent too early (i.e. before ngAfterViewInit)\n if (this._enabled !== value) {\n (this._enabled = value) ? this.resizeToFitContent(true) : this.reset();\n }\n }\n\n /** Cached height of a textarea with a single row. */\n private _cachedLineHeight: number;\n\n constructor(\n private _elementRef: ElementRef<HTMLElement>,\n private _platform: Platform,\n private _ngZone: NgZone) {\n this._textareaElement = this._elementRef.nativeElement as HTMLTextAreaElement;\n }\n\n /** Sets the minimum height of the textarea as determined by minRows. */\n _setMinHeight(): void {\n const minHeight = this.minRows && this._cachedLineHeight ?\n `${this.minRows * this._cachedLineHeight}px` : null;\n\n if (minHeight) {\n this._textareaElement.style.minHeight = minHeight;\n }\n }\n\n /** Sets the maximum height of the textarea as determined by maxRows. */\n _setMaxHeight(): void {\n const maxHeight = this.maxRows && this._cachedLineHeight ?\n `${this.maxRows * this._cachedLineHeight}px` : null;\n\n if (maxHeight) {\n this._textareaElement.style.maxHeight = maxHeight;\n }\n }\n\n ngAfterViewInit() {\n if (this._platform.isBrowser) {\n // Remember the height which we started with in case autosizing is disabled\n this._initialHeight = this._textareaElement.style.height;\n\n this.resizeToFitContent();\n\n this._ngZone.runOutsideAngular(() => {\n fromEvent(window, 'resize')\n .pipe(auditTime(16), takeUntil(this._destroyed))\n .subscribe(() => this.resizeToFitContent(true));\n });\n }\n }\n\n ngOnDestroy() {\n this._destroyed.next();\n this._destroyed.complete();\n }\n\n /**\n * Cache the height of a single-row textarea if it has not already been cached.\n *\n * We need to know how large a single \"row\" of a textarea is in order to apply minRows and\n * maxRows. For the initial version, we will assume that the height of a single line in the\n * textarea does not ever change.\n */\n private _cacheTextareaLineHeight(): void {\n if (this._cachedLineHeight) {\n return;\n }\n\n // Use a clone element because we have to override some styles.\n let textareaClone = this._textareaElement.cloneNode(false) as HTMLTextAreaElement;\n textareaClone.rows = 1;\n\n // Use `position: absolute` so that this doesn't cause a browser layout and use\n // `visibility: hidden` so that nothing is rendered. Clear any other styles that\n // would affect the height.\n textareaClone.style.position = 'absolute';\n textareaClone.style.visibility = 'hidden';\n textareaClone.style.border = 'none';\n textareaClone.style.padding = '0';\n textareaClone.style.height = '';\n textareaClone.style.minHeight = '';\n textareaClone.style.maxHeight = '';\n\n // In Firefox it happens that textarea elements are always bigger than the specified amount\n // of rows. This is because Firefox tries to add extra space for the horizontal scrollbar.\n // As a workaround that removes the extra space for the scrollbar, we can just set overflow\n // to hidden. This ensures that there is no invalid calculation of the line height.\n // See Firefox bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=33654\n textareaClone.style.overflow = 'hidden';\n\n this._textareaElement.parentNode!.appendChild(textareaClone);\n this._cachedLineHeight = textareaClone.clientHeight;\n this._textareaElement.parentNode!.removeChild(textareaClone);\n\n // Min and max heights have to be re-calculated if the cached line height changes\n this._setMinHeight();\n this._setMaxHeight();\n }\n\n ngDoCheck() {\n if (this._platform.isBrowser) {\n this.resizeToFitContent();\n }\n }\n\n /**\n * Resize the textarea to fit its content.\n * @param force Whether to force a height recalculation. By default the height will be\n * recalculated only if the value changed since the last call.\n */\n resizeToFitContent(force: boolean = false) {\n // If autosizing is disabled, just skip everything else\n if (!this._enabled) {\n return;\n }\n\n this._cacheTextareaLineHeight();\n\n // If we haven't determined the line-height yet, we know we're still hidden and there's no point\n // in checking the height of the textarea.\n if (!this._cachedLineHeight) {\n return;\n }\n\n const textarea = this._elementRef.nativeElement as HTMLTextAreaElement;\n const value = textarea.value;\n\n // Only resize if the value or minRows have changed since these calculations can be expensive.\n if (!force && this._minRows === this._previousMinRows && value === this._previousValue) {\n return;\n }\n\n const placeholderText = textarea.placeholder;\n\n // Reset the textarea height to auto in order to shrink back to its default size.\n // Also temporarily force overflow:hidden, so scroll bars do not interfere with calculations.\n // Long placeholders that are wider than the textarea width may lead to a bigger scrollHeight\n // value. To ensure that the scrollHeight is not bigger than the content, the placeholders\n // need to be removed temporarily.\n textarea.classList.add('cdk-textarea-autosize-measuring');\n textarea.placeholder = '';\n\n // The cdk-textarea-autosize-measuring class includes a 2px padding to workaround an issue with\n // Chrome, so we account for that extra space here by subtracting 4 (2px top + 2px bottom).\n const height = textarea.scrollHeight - 4;\n\n // Use the scrollHeight to know how large the textarea *would* be if fit its entire value.\n textarea.style.height = `${height}px`;\n textarea.classList.remove('cdk-textarea-autosize-measuring');\n textarea.placeholder = placeholderText;\n\n this._ngZone.runOutsideAngular(() => {\n if (typeof requestAnimationFrame !== 'undefined') {\n requestAnimationFrame(() => this._scrollToCaretPosition(textarea));\n } else {\n setTimeout(() => this._scrollToCaretPosition(textarea));\n }\n });\n\n this._previousValue = value;\n this._previousMinRows = this._minRows;\n }\n\n /**\n * Resets the textarea to it's original size\n */\n reset() {\n // Do not try to change the textarea, if the initialHeight has not been determined yet\n // This might potentially remove styles when reset() is called before ngAfterViewInit\n if (this._initialHeight === undefined) {\n return;\n }\n this._textareaElement.style.height = this._initialHeight;\n }\n\n _noopInputHandler() {\n // no-op handler that ensures we're running change detection on input events.\n }\n\n /**\n * Scrolls a textarea to the caret position. On Firefox resizing the textarea will\n * prevent it from scrolling to the caret position. We need to re-set the selection\n * in order for it to scroll to the proper position.\n */\n private _scrollToCaretPosition(textarea: HTMLTextAreaElement) {\n const {selectionStart, selectionEnd} = textarea;\n\n // IE will throw an \"Unspecified error\" if we try to set the selection range after the\n // element has been removed from the DOM. Assert that the directive hasn't been destroyed\n // between the time we requested the animation frame and when it was executed.\n // Also note that we have to assert that the textarea is focused before we set the\n // selection range. Setting the selection range on a non-focused textarea will cause\n // it to receive focus on IE and Edge.\n if (!this._destroyed.isStopped && document.activeElement === textarea) {\n textarea.setSelectionRange(selectionStart, selectionEnd);\n }\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {PlatformModule} from '@angular/cdk/platform';\nimport {NgModule} from '@angular/core';\nimport {CdkAutofill} from './autofill';\nimport {CdkTextareaAutosize} from './autosize';\n\n\n@NgModule({\n declarations: [CdkAutofill, CdkTextareaAutosize],\n imports: [PlatformModule],\n exports: [CdkAutofill, CdkTextareaAutosize],\n})\nexport class TextFieldModule {}\n"],"names":["listenerOptions","normalizePassiveListenerOptions","passive","AutofillMonitor","_platform","_ngZone","this","_monitoredElements","Map","prototype","monitor","elementOrRef","_this","isBrowser","EMPTY","element","coerceElement","info","get","subject","asObservable","result","Subject","cssClass","listener","event","animationName","classList","contains","remove","run","next","target","isAutofilled","add","runOutsideAngular","addEventListener","set","unlisten","removeEventListener","stopMonitoring","complete","delete","ngOnDestroy","forEach","_info","type","Injectable","args","providedIn","Platform","NgZone","CdkAutofill","_elementRef","_autofillMonitor","cdkAutofill","EventEmitter","ngOnInit","subscribe","emit","Directive","selector","ElementRef","Output","CdkTextareaAutosize","_destroyed","_enabled","_previousMinRows","_textareaElement","Object","defineProperty","_minRows","value","_setMinHeight","_maxRows","_setMaxHeight","coerceBooleanProperty","resizeToFitContent","reset","minHeight","minRows","_cachedLineHeight","style","maxHeight","maxRows","ngAfterViewInit","_initialHeight","height","fromEvent","window","pipe","auditTime","takeUntil","_cacheTextareaLineHeight","textareaClone","cloneNode","rows","position","visibility","border","padding","overflow","appendChild","clientHeight","removeChild","ngDoCheck","force","textarea","_previousValue","placeholderText","placeholder","scrollHeight","requestAnimationFrame","_scrollToCaretPosition","setTimeout","undefined","_noopInputHandler","selectionStart","selectionEnd","isStopped","document","activeElement","setSelectionRange","exportAs","host","class","(input)","Input","enabled","TextFieldModule","NgModule","declarations","imports","PlatformModule","exports"],"mappings":"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"}