Eugenio Romano 3a76027fe3 Services list in readme and in the doc generator (#2091)
* add services list in readme and in the autogenerator

* update tslint 5.5.0
2017-08-01 11:25:32 +01:00

228 lines
7.3 KiB
TypeScript

/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* tslint:disable:component-selector */
import {
Directive,
ElementRef,
forwardRef,
HostListener,
Input,
OnChanges,
Renderer,
SimpleChanges
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputMaskDirective),
multi: true
};
@Directive({
selector: '[textMask]',
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class InputMaskDirective implements OnChanges, ControlValueAccessor {
@Input('textMask') inputMask: {
mask: '',
isReversed: false
};
private translationMask = {
'0': { pattern: /\d/ },
'9': { pattern: /\d/, optional: true },
'#': { pattern: /\d/, recursive: true },
'A': { pattern: /[a-zA-Z0-9]/ },
'S': { pattern: /[a-zA-Z]/ }
};
private byPassKeys = [9, 16, 17, 18, 36, 37, 38, 39, 40, 91];
private value;
private invalidCharacters = [];
constructor(private el: ElementRef, private render: Renderer) {
}
_onChange = (_: any) => {
}
_onTouched = () => {
}
@HostListener('input', ['$event'])
@HostListener('keyup', ['$event']) onTextInput(event: KeyboardEvent) {
if (this.inputMask && this.inputMask.mask) {
this.maskValue(this.el.nativeElement.value, this.el.nativeElement.selectionStart,
this.inputMask.mask, this.inputMask.isReversed, event.keyCode);
} else {
this._onChange(this.el.nativeElement.value);
}
}
ngOnChanges(changes: SimpleChanges) {
if (changes['inputMask'] && changes['inputMask'].currentValue['mask']) {
this.inputMask = changes['inputMask'].currentValue;
}
}
writeValue(value: any) {
this.el.nativeElement.value = value;
}
registerOnChange(fn: any) {
this._onChange = fn;
}
registerOnTouched(fn: () => any): void {
this._onTouched = fn;
}
private maskValue(actualValue, startCaret, maskToApply, isMaskReversed, keyCode) {
if (this.byPassKeys.indexOf(keyCode) === -1) {
let value = this.getMasked(false, actualValue, maskToApply, isMaskReversed);
let calculatedCaret = this.calculateCaretPosition(startCaret, actualValue, keyCode);
this.render.setElementAttribute(this.el.nativeElement, 'value', value);
this.el.nativeElement.value = value;
this.setValue(value);
this._onChange(value);
this.setCaretPosition(calculatedCaret);
}
}
private setCaretPosition(caretPosition) {
this.el.nativeElement.moveStart = caretPosition;
this.el.nativeElement.moveEnd = caretPosition;
}
calculateCaretPosition(caretPosition, newValue, keyCode) {
let newValueLength = newValue.length;
let oldValue = this.getValue() || '';
let oldValueLength = oldValue.length;
if (keyCode === 8 && oldValue !== newValue) {
caretPosition = caretPosition - (newValue.slice(0, caretPosition).length - oldValue.slice(0, caretPosition).length);
} else if (oldValue !== newValue) {
if (caretPosition >= oldValueLength) {
caretPosition = newValueLength;
} else {
caretPosition = caretPosition + (newValue.slice(0, caretPosition).length - oldValue.slice(0, caretPosition).length);
}
}
return caretPosition;
}
getMasked(skipMaskChars, val, mask, isReversed = false) {
let buf = [],
value = val,
maskIndex = 0,
maskLen = mask.length,
valueIndex = 0,
valueLength = value.length,
offset = 1,
addMethod = 'push',
resetPos = -1,
lastMaskChar,
lastUntranslatedMaskChar,
check;
if (isReversed) {
addMethod = 'unshift';
offset = -1;
lastMaskChar = 0;
maskIndex = maskLen - 1;
valueIndex = valueLength - 1;
} else {
lastMaskChar = maskLen - 1;
}
check = this.isToCheck(isReversed, maskIndex, maskLen, valueIndex, valueLength);
while (check) {
let maskDigit = mask.charAt(maskIndex),
valDigit = value.charAt(valueIndex),
translation = this.translationMask[maskDigit];
if (translation) {
if (valDigit.match(translation.pattern)) {
buf[addMethod](valDigit);
if (translation.recursive) {
if (resetPos === -1) {
resetPos = maskIndex;
} else if (maskIndex === lastMaskChar) {
maskIndex = resetPos - offset;
}
if (lastMaskChar === resetPos) {
maskIndex -= offset;
}
}
maskIndex += offset;
} else if (valDigit === lastUntranslatedMaskChar) {
lastUntranslatedMaskChar = undefined;
} else if (translation.optional) {
maskIndex += offset;
valueIndex -= offset;
} else {
this.invalidCharacters.push({
index: valueIndex,
digit: valDigit,
translated: translation.pattern
});
}
valueIndex += offset;
} else {
if (!skipMaskChars) {
buf[addMethod](maskDigit);
}
if (valDigit === maskDigit) {
valueIndex += offset;
} else {
lastUntranslatedMaskChar = maskDigit;
}
maskIndex += offset;
}
check = this.isToCheck(isReversed, maskIndex, maskLen, valueIndex, valueLength);
}
let lastMaskCharDigit = mask.charAt(lastMaskChar);
if (maskLen === valueLength + 1 && !this.translationMask[lastMaskCharDigit]) {
buf.push(lastMaskCharDigit);
}
return buf.join('');
}
private isToCheck(isReversed, maskIndex, maskLen, valueIndex, valueLength) {
let check = false;
if (isReversed) {
check = (maskIndex > -1) && (valueIndex > -1);
} else {
check = (maskIndex < maskLen) && (valueIndex < valueLength);
}
return check;
}
private setValue(value) {
this.value = value;
}
private getValue() {
return this.value;
}
}