avances en plantillas
This commit is contained in:
parent
0f84beacf1
commit
da0530d79b
2062 changed files with 598814 additions and 22 deletions
422
storage/public/dist/libs/imask/esm/masked/base.js
vendored
Normal file
422
storage/public/dist/libs/imask/esm/masked/base.js
vendored
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
import ChangeDetails from '../core/change-details.js';
|
||||
import ContinuousTailDetails from '../core/continuous-tail-details.js';
|
||||
import { isString, DIRECTION, objectIncludes, forceDirection } from '../core/utils.js';
|
||||
import IMask from '../core/holder.js';
|
||||
|
||||
/** Append flags */
|
||||
|
||||
/** Extract flags */
|
||||
|
||||
// see https://github.com/microsoft/TypeScript/issues/6223
|
||||
|
||||
/** Provides common masking stuff */
|
||||
class Masked {
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** Transforms value before mask processing */
|
||||
|
||||
/** Transforms each char before mask processing */
|
||||
|
||||
/** Validates if value is acceptable */
|
||||
|
||||
/** Does additional processing at the end of editing */
|
||||
|
||||
/** Format typed value to string */
|
||||
|
||||
/** Parse string to get typed value */
|
||||
|
||||
/** Enable characters overwriting */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
constructor(opts) {
|
||||
this._value = '';
|
||||
this._update({
|
||||
...Masked.DEFAULTS,
|
||||
...opts
|
||||
});
|
||||
this._initialized = true;
|
||||
}
|
||||
|
||||
/** Sets and applies new options */
|
||||
updateOptions(opts) {
|
||||
if (!this.optionsIsChanged(opts)) return;
|
||||
this.withValueRefresh(this._update.bind(this, opts));
|
||||
}
|
||||
|
||||
/** Sets new options */
|
||||
_update(opts) {
|
||||
Object.assign(this, opts);
|
||||
}
|
||||
|
||||
/** Mask state */
|
||||
get state() {
|
||||
return {
|
||||
_value: this.value,
|
||||
_rawInputValue: this.rawInputValue
|
||||
};
|
||||
}
|
||||
set state(state) {
|
||||
this._value = state._value;
|
||||
}
|
||||
|
||||
/** Resets value */
|
||||
reset() {
|
||||
this._value = '';
|
||||
}
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
set value(value) {
|
||||
this.resolve(value, {
|
||||
input: true
|
||||
});
|
||||
}
|
||||
|
||||
/** Resolve new value */
|
||||
resolve(value, flags) {
|
||||
if (flags === void 0) {
|
||||
flags = {
|
||||
input: true
|
||||
};
|
||||
}
|
||||
this.reset();
|
||||
this.append(value, flags, '');
|
||||
this.doCommit();
|
||||
}
|
||||
get unmaskedValue() {
|
||||
return this.value;
|
||||
}
|
||||
set unmaskedValue(value) {
|
||||
this.resolve(value, {});
|
||||
}
|
||||
get typedValue() {
|
||||
return this.parse ? this.parse(this.value, this) : this.unmaskedValue;
|
||||
}
|
||||
set typedValue(value) {
|
||||
if (this.format) {
|
||||
this.value = this.format(value, this);
|
||||
} else {
|
||||
this.unmaskedValue = String(value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Value that includes raw user input */
|
||||
get rawInputValue() {
|
||||
return this.extractInput(0, this.displayValue.length, {
|
||||
raw: true
|
||||
});
|
||||
}
|
||||
set rawInputValue(value) {
|
||||
this.resolve(value, {
|
||||
raw: true
|
||||
});
|
||||
}
|
||||
get displayValue() {
|
||||
return this.value;
|
||||
}
|
||||
get isComplete() {
|
||||
return true;
|
||||
}
|
||||
get isFilled() {
|
||||
return this.isComplete;
|
||||
}
|
||||
|
||||
/** Finds nearest input position in direction */
|
||||
nearestInputPos(cursorPos, direction) {
|
||||
return cursorPos;
|
||||
}
|
||||
totalInputPositions(fromPos, toPos) {
|
||||
if (fromPos === void 0) {
|
||||
fromPos = 0;
|
||||
}
|
||||
if (toPos === void 0) {
|
||||
toPos = this.displayValue.length;
|
||||
}
|
||||
return Math.min(this.displayValue.length, toPos - fromPos);
|
||||
}
|
||||
|
||||
/** Extracts value in range considering flags */
|
||||
extractInput(fromPos, toPos, flags) {
|
||||
if (fromPos === void 0) {
|
||||
fromPos = 0;
|
||||
}
|
||||
if (toPos === void 0) {
|
||||
toPos = this.displayValue.length;
|
||||
}
|
||||
return this.displayValue.slice(fromPos, toPos);
|
||||
}
|
||||
|
||||
/** Extracts tail in range */
|
||||
extractTail(fromPos, toPos) {
|
||||
if (fromPos === void 0) {
|
||||
fromPos = 0;
|
||||
}
|
||||
if (toPos === void 0) {
|
||||
toPos = this.displayValue.length;
|
||||
}
|
||||
return new ContinuousTailDetails(this.extractInput(fromPos, toPos), fromPos);
|
||||
}
|
||||
|
||||
/** Appends tail */
|
||||
appendTail(tail) {
|
||||
if (isString(tail)) tail = new ContinuousTailDetails(String(tail));
|
||||
return tail.appendTo(this);
|
||||
}
|
||||
|
||||
/** Appends char */
|
||||
_appendCharRaw(ch, flags) {
|
||||
if (!ch) return new ChangeDetails();
|
||||
this._value += ch;
|
||||
return new ChangeDetails({
|
||||
inserted: ch,
|
||||
rawInserted: ch
|
||||
});
|
||||
}
|
||||
|
||||
/** Appends char */
|
||||
_appendChar(ch, flags, checkTail) {
|
||||
if (flags === void 0) {
|
||||
flags = {};
|
||||
}
|
||||
const consistentState = this.state;
|
||||
let details;
|
||||
[ch, details] = this.doPrepareChar(ch, flags);
|
||||
if (ch) {
|
||||
details = details.aggregate(this._appendCharRaw(ch, flags));
|
||||
|
||||
// TODO handle `skip`?
|
||||
|
||||
// try `autofix` lookahead
|
||||
if (!details.rawInserted && this.autofix === 'pad') {
|
||||
const noFixState = this.state;
|
||||
this.state = consistentState;
|
||||
let fixDetails = this.pad(flags);
|
||||
const chDetails = this._appendCharRaw(ch, flags);
|
||||
fixDetails = fixDetails.aggregate(chDetails);
|
||||
|
||||
// if fix was applied or
|
||||
// if details are equal use skip restoring state optimization
|
||||
if (chDetails.rawInserted || fixDetails.equals(details)) {
|
||||
details = fixDetails;
|
||||
} else {
|
||||
this.state = noFixState;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (details.inserted) {
|
||||
let consistentTail;
|
||||
let appended = this.doValidate(flags) !== false;
|
||||
if (appended && checkTail != null) {
|
||||
// validation ok, check tail
|
||||
const beforeTailState = this.state;
|
||||
if (this.overwrite === true) {
|
||||
consistentTail = checkTail.state;
|
||||
for (let i = 0; i < details.rawInserted.length; ++i) {
|
||||
checkTail.unshift(this.displayValue.length - details.tailShift);
|
||||
}
|
||||
}
|
||||
let tailDetails = this.appendTail(checkTail);
|
||||
appended = tailDetails.rawInserted.length === checkTail.toString().length;
|
||||
|
||||
// not ok, try shift
|
||||
if (!(appended && tailDetails.inserted) && this.overwrite === 'shift') {
|
||||
this.state = beforeTailState;
|
||||
consistentTail = checkTail.state;
|
||||
for (let i = 0; i < details.rawInserted.length; ++i) {
|
||||
checkTail.shift();
|
||||
}
|
||||
tailDetails = this.appendTail(checkTail);
|
||||
appended = tailDetails.rawInserted.length === checkTail.toString().length;
|
||||
}
|
||||
|
||||
// if ok, rollback state after tail
|
||||
if (appended && tailDetails.inserted) this.state = beforeTailState;
|
||||
}
|
||||
|
||||
// revert all if something went wrong
|
||||
if (!appended) {
|
||||
details = new ChangeDetails();
|
||||
this.state = consistentState;
|
||||
if (checkTail && consistentTail) checkTail.state = consistentTail;
|
||||
}
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
/** Appends optional placeholder at the end */
|
||||
_appendPlaceholder() {
|
||||
return new ChangeDetails();
|
||||
}
|
||||
|
||||
/** Appends optional eager placeholder at the end */
|
||||
_appendEager() {
|
||||
return new ChangeDetails();
|
||||
}
|
||||
|
||||
/** Appends symbols considering flags */
|
||||
append(str, flags, tail) {
|
||||
if (!isString(str)) throw new Error('value should be string');
|
||||
const checkTail = isString(tail) ? new ContinuousTailDetails(String(tail)) : tail;
|
||||
if (flags != null && flags.tail) flags._beforeTailState = this.state;
|
||||
let details;
|
||||
[str, details] = this.doPrepare(str, flags);
|
||||
for (let ci = 0; ci < str.length; ++ci) {
|
||||
const d = this._appendChar(str[ci], flags, checkTail);
|
||||
if (!d.rawInserted && !this.doSkipInvalid(str[ci], flags, checkTail)) break;
|
||||
details.aggregate(d);
|
||||
}
|
||||
if ((this.eager === true || this.eager === 'append') && flags != null && flags.input && str) {
|
||||
details.aggregate(this._appendEager());
|
||||
}
|
||||
|
||||
// append tail but aggregate only tailShift
|
||||
if (checkTail != null) {
|
||||
details.tailShift += this.appendTail(checkTail).tailShift;
|
||||
// TODO it's a good idea to clear state after appending ends
|
||||
// but it causes bugs when one append calls another (when dynamic dispatch set rawInputValue)
|
||||
// this._resetBeforeTailState();
|
||||
}
|
||||
return details;
|
||||
}
|
||||
remove(fromPos, toPos) {
|
||||
if (fromPos === void 0) {
|
||||
fromPos = 0;
|
||||
}
|
||||
if (toPos === void 0) {
|
||||
toPos = this.displayValue.length;
|
||||
}
|
||||
this._value = this.displayValue.slice(0, fromPos) + this.displayValue.slice(toPos);
|
||||
return new ChangeDetails();
|
||||
}
|
||||
|
||||
/** Calls function and reapplies current value */
|
||||
withValueRefresh(fn) {
|
||||
if (this._refreshing || !this._initialized) return fn();
|
||||
this._refreshing = true;
|
||||
const rawInput = this.rawInputValue;
|
||||
const value = this.value;
|
||||
const ret = fn();
|
||||
this.rawInputValue = rawInput;
|
||||
// append lost trailing chars at the end
|
||||
if (this.value && this.value !== value && value.indexOf(this.value) === 0) {
|
||||
this.append(value.slice(this.displayValue.length), {}, '');
|
||||
this.doCommit();
|
||||
}
|
||||
delete this._refreshing;
|
||||
return ret;
|
||||
}
|
||||
runIsolated(fn) {
|
||||
if (this._isolated || !this._initialized) return fn(this);
|
||||
this._isolated = true;
|
||||
const state = this.state;
|
||||
const ret = fn(this);
|
||||
this.state = state;
|
||||
delete this._isolated;
|
||||
return ret;
|
||||
}
|
||||
doSkipInvalid(ch, flags, checkTail) {
|
||||
return Boolean(this.skipInvalid);
|
||||
}
|
||||
|
||||
/** Prepares string before mask processing */
|
||||
doPrepare(str, flags) {
|
||||
if (flags === void 0) {
|
||||
flags = {};
|
||||
}
|
||||
return ChangeDetails.normalize(this.prepare ? this.prepare(str, this, flags) : str);
|
||||
}
|
||||
|
||||
/** Prepares each char before mask processing */
|
||||
doPrepareChar(str, flags) {
|
||||
if (flags === void 0) {
|
||||
flags = {};
|
||||
}
|
||||
return ChangeDetails.normalize(this.prepareChar ? this.prepareChar(str, this, flags) : str);
|
||||
}
|
||||
|
||||
/** Validates if value is acceptable */
|
||||
doValidate(flags) {
|
||||
return (!this.validate || this.validate(this.value, this, flags)) && (!this.parent || this.parent.doValidate(flags));
|
||||
}
|
||||
|
||||
/** Does additional processing at the end of editing */
|
||||
doCommit() {
|
||||
if (this.commit) this.commit(this.value, this);
|
||||
}
|
||||
splice(start, deleteCount, inserted, removeDirection, flags) {
|
||||
if (inserted === void 0) {
|
||||
inserted = '';
|
||||
}
|
||||
if (removeDirection === void 0) {
|
||||
removeDirection = DIRECTION.NONE;
|
||||
}
|
||||
if (flags === void 0) {
|
||||
flags = {
|
||||
input: true
|
||||
};
|
||||
}
|
||||
const tailPos = start + deleteCount;
|
||||
const tail = this.extractTail(tailPos);
|
||||
const eagerRemove = this.eager === true || this.eager === 'remove';
|
||||
let oldRawValue;
|
||||
if (eagerRemove) {
|
||||
removeDirection = forceDirection(removeDirection);
|
||||
oldRawValue = this.extractInput(0, tailPos, {
|
||||
raw: true
|
||||
});
|
||||
}
|
||||
let startChangePos = start;
|
||||
const details = new ChangeDetails();
|
||||
|
||||
// if it is just deletion without insertion
|
||||
if (removeDirection !== DIRECTION.NONE) {
|
||||
startChangePos = this.nearestInputPos(start, deleteCount > 1 && start !== 0 && !eagerRemove ? DIRECTION.NONE : removeDirection);
|
||||
|
||||
// adjust tailShift if start was aligned
|
||||
details.tailShift = startChangePos - start;
|
||||
}
|
||||
details.aggregate(this.remove(startChangePos));
|
||||
if (eagerRemove && removeDirection !== DIRECTION.NONE && oldRawValue === this.rawInputValue) {
|
||||
if (removeDirection === DIRECTION.FORCE_LEFT) {
|
||||
let valLength;
|
||||
while (oldRawValue === this.rawInputValue && (valLength = this.displayValue.length)) {
|
||||
details.aggregate(new ChangeDetails({
|
||||
tailShift: -1
|
||||
})).aggregate(this.remove(valLength - 1));
|
||||
}
|
||||
} else if (removeDirection === DIRECTION.FORCE_RIGHT) {
|
||||
tail.unshift();
|
||||
}
|
||||
}
|
||||
return details.aggregate(this.append(inserted, flags, tail));
|
||||
}
|
||||
maskEquals(mask) {
|
||||
return this.mask === mask;
|
||||
}
|
||||
optionsIsChanged(opts) {
|
||||
return !objectIncludes(this, opts);
|
||||
}
|
||||
typedValueEquals(value) {
|
||||
const tval = this.typedValue;
|
||||
return value === tval || Masked.EMPTY_VALUES.includes(value) && Masked.EMPTY_VALUES.includes(tval) || (this.format ? this.format(value, this) === this.format(this.typedValue, this) : false);
|
||||
}
|
||||
pad(flags) {
|
||||
return new ChangeDetails();
|
||||
}
|
||||
}
|
||||
Masked.DEFAULTS = {
|
||||
skipInvalid: true
|
||||
};
|
||||
Masked.EMPTY_VALUES = [undefined, null, ''];
|
||||
IMask.Masked = Masked;
|
||||
|
||||
export { Masked as default };
|
||||
Loading…
Add table
Add a link
Reference in a new issue