PluginProbe
Booking Calendar / 11.8
Booking Calendar v11.8
11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 All 204 releases
booking / vendors / imask / esm / masked / dynamic.js

dynamic.js in Booking Calendar 11.8, at vendors/imask/esm/masked/dynamic.js

342 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { DIRECTION, objectIncludes } from '../core/utils.js';
2 import ChangeDetails from '../core/change-details.js';
3 import createMask, { normalizeOpts } from './factory.js';
4 import Masked from './base.js';
5 import IMask from '../core/holder.js';
6 import '../core/continuous-tail-details.js';
7
8 /** Dynamic mask for choosing appropriate mask in run-time */
9 class MaskedDynamic extends Masked {
10 constructor(opts) {
11 super({
12 ...MaskedDynamic.DEFAULTS,
13 ...opts
14 });
15 this.currentMask = undefined;
16 }
17 updateOptions(opts) {
18 super.updateOptions(opts);
19 }
20 _update(opts) {
21 super._update(opts);
22 if ('mask' in opts) {
23 this.exposeMask = undefined;
24 // mask could be totally dynamic with only `dispatch` option
25 this.compiledMasks = Array.isArray(opts.mask) ? opts.mask.map(m => {
26 const {
27 expose,
28 ...maskOpts
29 } = normalizeOpts(m);
30 const masked = createMask({
31 overwrite: this._overwrite,
32 eager: this._eager,
33 skipInvalid: this._skipInvalid,
34 ...maskOpts
35 });
36 if (expose) this.exposeMask = masked;
37 return masked;
38 }) : [];
39
40 // this.currentMask = this.doDispatch(''); // probably not needed but lets see
41 }
42 }
43 _appendCharRaw(ch, flags) {
44 if (flags === void 0) {
45 flags = {};
46 }
47 const details = this._applyDispatch(ch, flags);
48 if (this.currentMask) {
49 details.aggregate(this.currentMask._appendChar(ch, this.currentMaskFlags(flags)));
50 }
51 return details;
52 }
53 _applyDispatch(appended, flags, tail) {
54 if (appended === void 0) {
55 appended = '';
56 }
57 if (flags === void 0) {
58 flags = {};
59 }
60 if (tail === void 0) {
61 tail = '';
62 }
63 const prevValueBeforeTail = flags.tail && flags._beforeTailState != null ? flags._beforeTailState._value : this.value;
64 const inputValue = this.rawInputValue;
65 const insertValue = flags.tail && flags._beforeTailState != null ? flags._beforeTailState._rawInputValue : inputValue;
66 const tailValue = inputValue.slice(insertValue.length);
67 const prevMask = this.currentMask;
68 const details = new ChangeDetails();
69 const prevMaskState = prevMask == null ? void 0 : prevMask.state;
70
71 // clone flags to prevent overwriting `_beforeTailState`
72 this.currentMask = this.doDispatch(appended, {
73 ...flags
74 }, tail);
75
76 // restore state after dispatch
77 if (this.currentMask) {
78 if (this.currentMask !== prevMask) {
79 // if mask changed reapply input
80 this.currentMask.reset();
81 if (insertValue) {
82 this.currentMask.append(insertValue, {
83 raw: true
84 });
85 details.tailShift = this.currentMask.value.length - prevValueBeforeTail.length;
86 }
87 if (tailValue) {
88 details.tailShift += this.currentMask.append(tailValue, {
89 raw: true,
90 tail: true
91 }).tailShift;
92 }
93 } else if (prevMaskState) {
94 // Dispatch can do something bad with state, so
95 // restore prev mask state
96 this.currentMask.state = prevMaskState;
97 }
98 }
99 return details;
100 }
101 _appendPlaceholder() {
102 const details = this._applyDispatch();
103 if (this.currentMask) {
104 details.aggregate(this.currentMask._appendPlaceholder());
105 }
106 return details;
107 }
108 _appendEager() {
109 const details = this._applyDispatch();
110 if (this.currentMask) {
111 details.aggregate(this.currentMask._appendEager());
112 }
113 return details;
114 }
115 appendTail(tail) {
116 const details = new ChangeDetails();
117 if (tail) details.aggregate(this._applyDispatch('', {}, tail));
118 return details.aggregate(this.currentMask ? this.currentMask.appendTail(tail) : super.appendTail(tail));
119 }
120 currentMaskFlags(flags) {
121 var _flags$_beforeTailSta, _flags$_beforeTailSta2;
122 return {
123 ...flags,
124 _beforeTailState: ((_flags$_beforeTailSta = flags._beforeTailState) == null ? void 0 : _flags$_beforeTailSta.currentMaskRef) === this.currentMask && ((_flags$_beforeTailSta2 = flags._beforeTailState) == null ? void 0 : _flags$_beforeTailSta2.currentMask) || flags._beforeTailState
125 };
126 }
127 doDispatch(appended, flags, tail) {
128 if (flags === void 0) {
129 flags = {};
130 }
131 if (tail === void 0) {
132 tail = '';
133 }
134 return this.dispatch(appended, this, flags, tail);
135 }
136 doValidate(flags) {
137 return super.doValidate(flags) && (!this.currentMask || this.currentMask.doValidate(this.currentMaskFlags(flags)));
138 }
139 doPrepare(str, flags) {
140 if (flags === void 0) {
141 flags = {};
142 }
143 let [s, details] = super.doPrepare(str, flags);
144 if (this.currentMask) {
145 let currentDetails;
146 [s, currentDetails] = super.doPrepare(s, this.currentMaskFlags(flags));
147 details = details.aggregate(currentDetails);
148 }
149 return [s, details];
150 }
151 doPrepareChar(str, flags) {
152 if (flags === void 0) {
153 flags = {};
154 }
155 let [s, details] = super.doPrepareChar(str, flags);
156 if (this.currentMask) {
157 let currentDetails;
158 [s, currentDetails] = super.doPrepareChar(s, this.currentMaskFlags(flags));
159 details = details.aggregate(currentDetails);
160 }
161 return [s, details];
162 }
163 reset() {
164 var _this$currentMask;
165 (_this$currentMask = this.currentMask) == null || _this$currentMask.reset();
166 this.compiledMasks.forEach(m => m.reset());
167 }
168 get value() {
169 return this.exposeMask ? this.exposeMask.value : this.currentMask ? this.currentMask.value : '';
170 }
171 set value(value) {
172 if (this.exposeMask) {
173 this.exposeMask.value = value;
174 this.currentMask = this.exposeMask;
175 this._applyDispatch();
176 } else super.value = value;
177 }
178 get unmaskedValue() {
179 return this.exposeMask ? this.exposeMask.unmaskedValue : this.currentMask ? this.currentMask.unmaskedValue : '';
180 }
181 set unmaskedValue(unmaskedValue) {
182 if (this.exposeMask) {
183 this.exposeMask.unmaskedValue = unmaskedValue;
184 this.currentMask = this.exposeMask;
185 this._applyDispatch();
186 } else super.unmaskedValue = unmaskedValue;
187 }
188 get typedValue() {
189 return this.exposeMask ? this.exposeMask.typedValue : this.currentMask ? this.currentMask.typedValue : '';
190 }
191 set typedValue(typedValue) {
192 if (this.exposeMask) {
193 this.exposeMask.typedValue = typedValue;
194 this.currentMask = this.exposeMask;
195 this._applyDispatch();
196 return;
197 }
198 let unmaskedValue = String(typedValue);
199
200 // double check it
201 if (this.currentMask) {
202 this.currentMask.typedValue = typedValue;
203 unmaskedValue = this.currentMask.unmaskedValue;
204 }
205 this.unmaskedValue = unmaskedValue;
206 }
207 get displayValue() {
208 return this.currentMask ? this.currentMask.displayValue : '';
209 }
210 get isComplete() {
211 var _this$currentMask2;
212 return Boolean((_this$currentMask2 = this.currentMask) == null ? void 0 : _this$currentMask2.isComplete);
213 }
214 get isFilled() {
215 var _this$currentMask3;
216 return Boolean((_this$currentMask3 = this.currentMask) == null ? void 0 : _this$currentMask3.isFilled);
217 }
218 remove(fromPos, toPos) {
219 const details = new ChangeDetails();
220 if (this.currentMask) {
221 details.aggregate(this.currentMask.remove(fromPos, toPos))
222 // update with dispatch
223 .aggregate(this._applyDispatch());
224 }
225 return details;
226 }
227 get state() {
228 var _this$currentMask4;
229 return {
230 ...super.state,
231 _rawInputValue: this.rawInputValue,
232 compiledMasks: this.compiledMasks.map(m => m.state),
233 currentMaskRef: this.currentMask,
234 currentMask: (_this$currentMask4 = this.currentMask) == null ? void 0 : _this$currentMask4.state
235 };
236 }
237 set state(state) {
238 const {
239 compiledMasks,
240 currentMaskRef,
241 currentMask,
242 ...maskedState
243 } = state;
244 if (compiledMasks) this.compiledMasks.forEach((m, mi) => m.state = compiledMasks[mi]);
245 if (currentMaskRef != null) {
246 this.currentMask = currentMaskRef;
247 this.currentMask.state = currentMask;
248 }
249 super.state = maskedState;
250 }
251 extractInput(fromPos, toPos, flags) {
252 return this.currentMask ? this.currentMask.extractInput(fromPos, toPos, flags) : '';
253 }
254 extractTail(fromPos, toPos) {
255 return this.currentMask ? this.currentMask.extractTail(fromPos, toPos) : super.extractTail(fromPos, toPos);
256 }
257 doCommit() {
258 if (this.currentMask) this.currentMask.doCommit();
259 super.doCommit();
260 }
261 nearestInputPos(cursorPos, direction) {
262 return this.currentMask ? this.currentMask.nearestInputPos(cursorPos, direction) : super.nearestInputPos(cursorPos, direction);
263 }
264 get overwrite() {
265 return this.currentMask ? this.currentMask.overwrite : this._overwrite;
266 }
267 set overwrite(overwrite) {
268 this._overwrite = overwrite;
269 }
270 get eager() {
271 return this.currentMask ? this.currentMask.eager : this._eager;
272 }
273 set eager(eager) {
274 this._eager = eager;
275 }
276 get skipInvalid() {
277 return this.currentMask ? this.currentMask.skipInvalid : this._skipInvalid;
278 }
279 set skipInvalid(skipInvalid) {
280 this._skipInvalid = skipInvalid;
281 }
282 get autofix() {
283 return this.currentMask ? this.currentMask.autofix : this._autofix;
284 }
285 set autofix(autofix) {
286 this._autofix = autofix;
287 }
288 maskEquals(mask) {
289 return Array.isArray(mask) ? this.compiledMasks.every((m, mi) => {
290 if (!mask[mi]) return;
291 const {
292 mask: oldMask,
293 ...restOpts
294 } = mask[mi];
295 return objectIncludes(m, restOpts) && m.maskEquals(oldMask);
296 }) : super.maskEquals(mask);
297 }
298 typedValueEquals(value) {
299 var _this$currentMask5;
300 return Boolean((_this$currentMask5 = this.currentMask) == null ? void 0 : _this$currentMask5.typedValueEquals(value));
301 }
302 }
303 /** Currently chosen mask */
304 /** Currently chosen mask */
305 /** Compliled {@link Masked} options */
306 /** Chooses {@link Masked} depending on input value */
307 MaskedDynamic.DEFAULTS = {
308 ...Masked.DEFAULTS,
309 dispatch: (appended, masked, flags, tail) => {
310 if (!masked.compiledMasks.length) return;
311 const inputValue = masked.rawInputValue;
312
313 // simulate input
314 const inputs = masked.compiledMasks.map((m, index) => {
315 const isCurrent = masked.currentMask === m;
316 const startInputPos = isCurrent ? m.displayValue.length : m.nearestInputPos(m.displayValue.length, DIRECTION.FORCE_LEFT);
317 if (m.rawInputValue !== inputValue) {
318 m.reset();
319 m.append(inputValue, {
320 raw: true
321 });
322 } else if (!isCurrent) {
323 m.remove(startInputPos);
324 }
325 m.append(appended, masked.currentMaskFlags(flags));
326 m.appendTail(tail);
327 return {
328 index,
329 weight: m.rawInputValue.length,
330 totalInputPositions: m.totalInputPositions(0, Math.max(startInputPos, m.nearestInputPos(m.displayValue.length, DIRECTION.FORCE_LEFT)))
331 };
332 });
333
334 // pop masks with longer values first
335 inputs.sort((i1, i2) => i2.weight - i1.weight || i2.totalInputPositions - i1.totalInputPositions);
336 return masked.compiledMasks[inputs[0].index];
337 }
338 };
339 IMask.MaskedDynamic = MaskedDynamic;
340
341 export { MaskedDynamic as default };
342