1 | class _LicenseChecker {
|
2 | constructor() {
|
3 | this._licenseKey = '';
|
4 | this._logOnSuccess = false;
|
5 | this._success = false;
|
6 | }
|
7 | activateLicense(licenseKey, options = { logLicenseActivated: true }) {
|
8 | this._licenseKey = licenseKey;
|
9 | this._logOnSuccess = options.logLicenseActivated;
|
10 | }
|
11 | _checkLicense() {
|
12 | if (this._success) {
|
13 | return;
|
14 | }
|
15 | if (this._licenseKey) {
|
16 | const parts = this._licenseKey.split('-');
|
17 | if (parts.length !== 2) {
|
18 | console.warn(`uiloos > license > invalid license key detected: ${this._licenseKey}, ${buy}`);
|
19 | }
|
20 | else {
|
21 | const [_, type] = parts;
|
22 | if (this._logOnSuccess) {
|
23 | console.log(`uiloos > license > license activated, this license is for use with ${type} developers. We thank you for your support, you can disable this message if you want to. ${owner}`);
|
24 | }
|
25 | this._success = true;
|
26 | }
|
27 | }
|
28 | else {
|
29 | console.warn(`uiloos > license > you are using commercial software, ${buy}`);
|
30 | }
|
31 | }
|
32 | }
|
33 | let licenseChecker = new _LicenseChecker();
|
34 | const owner = 'If you are not the owner of this website please ignore this message.';
|
35 | const buy = `please purchase a license at https://www.uiloos.dev. ${owner}`;
|
36 |
|
37 | const common$3 = `uiloos > ActiveList >`;
|
38 |
|
39 | class ActiveListAutoPlayDurationError extends Error {
|
40 | constructor() {
|
41 | super(`${common$3} autoPlay > duration cannot be negative or zero`);
|
42 | this.name = 'ActiveListAutoPlayDurationError';
|
43 | }
|
44 | }
|
45 |
|
46 | class _AutoPlay {
|
47 | constructor(activeList, config) {
|
48 | this._autoPlayTimeoutId = null;
|
49 | this._autoPlayStarted = new Date();
|
50 | this._pauseStarted = null;
|
51 | this._autoPlayCurrentDuration = 0;
|
52 | this._config = null;
|
53 | this._activeList = activeList;
|
54 | this._config = config;
|
55 | }
|
56 | _setConfig(config) {
|
57 | this._config = config;
|
58 | }
|
59 | _play(inform) {
|
60 | this._cancelTimer();
|
61 | if (!this._config || this._activeList.lastActivatedContent === null) {
|
62 | return;
|
63 | }
|
64 | const duration = this._getDuration(this._config, this._activeList.lastActivatedContent);
|
65 | if (duration <= 0) {
|
66 | throw new ActiveListAutoPlayDurationError();
|
67 | }
|
68 | this._autoPlayCurrentDuration = duration;
|
69 | if (this._pauseStarted === null) {
|
70 | this._activeList.autoPlay.duration = duration;
|
71 | }
|
72 | else {
|
73 | this._pauseStarted = null;
|
74 | }
|
75 | this._autoPlayStarted = new Date();
|
76 | this._autoPlayTimeoutId = window.setTimeout(() => {
|
77 | this._autoPlayTimeoutId = null;
|
78 | this._activeList.activateNext({ isUserInteraction: false });
|
79 | }, duration);
|
80 | this._activeList.autoPlay.isPlaying = true;
|
81 | if (inform) {
|
82 | const event = {
|
83 | type: 'AUTO_PLAY_PLAYING',
|
84 | time: new Date(),
|
85 | };
|
86 | this._activeList._inform(event);
|
87 | }
|
88 | }
|
89 | _pause() {
|
90 | if (!this._activeList.autoPlay.isPlaying) {
|
91 | return;
|
92 | }
|
93 | this._pauseStarted = new Date();
|
94 | this._cancelTimer();
|
95 | this._activeList.autoPlay.isPlaying = false;
|
96 | const event = {
|
97 | type: 'AUTO_PLAY_PAUSED',
|
98 | time: new Date(),
|
99 | };
|
100 | this._activeList._inform(event);
|
101 | }
|
102 | _stop() {
|
103 | if (!this._activeList.autoPlay.isPlaying && !this._pauseStarted) {
|
104 | return;
|
105 | }
|
106 | this._cancelTimer();
|
107 | this._pauseStarted = null;
|
108 | this._activeList.autoPlay.isPlaying = false;
|
109 | this._activeList.autoPlay.duration = 0;
|
110 | this._activeList.autoPlay.hasBeenStoppedBefore = true;
|
111 | const event = {
|
112 | type: 'AUTO_PLAY_STOPPED',
|
113 | time: new Date(),
|
114 | };
|
115 | this._activeList._inform(event);
|
116 | }
|
117 | _cancelTimer() {
|
118 | if (this._autoPlayTimeoutId !== null) {
|
119 | window.clearTimeout(this._autoPlayTimeoutId);
|
120 | this._autoPlayTimeoutId = null;
|
121 | }
|
122 | }
|
123 | _onDeactivation(activationOptions) {
|
124 | if (this._activeList.lastActivatedContent === null) {
|
125 | this._stop();
|
126 | return;
|
127 | }
|
128 | if (!this._config) {
|
129 | return;
|
130 | }
|
131 | if (this._shouldStopOnUserInteraction(activationOptions, this._config)) {
|
132 | this._stop();
|
133 | return;
|
134 | }
|
135 | }
|
136 | onActiveIndexChanged(index, activationOptions) {
|
137 | if (!this._config) {
|
138 | return;
|
139 | }
|
140 | if (this._shouldStopOnUserInteraction(activationOptions, this._config)) {
|
141 | this._stop();
|
142 | }
|
143 | else if (this._activeList.isCircular === false &&
|
144 | index === this._activeList.getLastIndex()) {
|
145 | this._stop();
|
146 | }
|
147 | else {
|
148 | this._play(false);
|
149 | }
|
150 | }
|
151 | _shouldStopOnUserInteraction(activationOptions, config) {
|
152 | return !!(activationOptions &&
|
153 | activationOptions.isUserInteraction !== false &&
|
154 | config.stopsOnUserInteraction);
|
155 | }
|
156 | _getDuration(config, lastActivatedContent) {
|
157 | if (this._pauseStarted) {
|
158 | return (this._autoPlayCurrentDuration -
|
159 | (this._pauseStarted.getTime() - this._autoPlayStarted.getTime()));
|
160 | }
|
161 | if (typeof config.duration === 'number') {
|
162 | return config.duration;
|
163 | }
|
164 | else {
|
165 | return config.duration({
|
166 | index: lastActivatedContent.index,
|
167 | content: lastActivatedContent,
|
168 | value: lastActivatedContent.value,
|
169 | activeList: this._activeList,
|
170 | });
|
171 | }
|
172 | }
|
173 | }
|
174 |
|
175 | class ActiveListContent {
|
176 | constructor(activeList, index, value) {
|
177 | this.isActive = false;
|
178 | this.hasBeenActiveBefore = false;
|
179 | this.isFirst = false;
|
180 | this.isLast = false;
|
181 | this.hasNext = false;
|
182 | this.hasPrevious = false;
|
183 | this.isNext = false;
|
184 | this.isPrevious = false;
|
185 | this.activeList = activeList;
|
186 | this.index = index;
|
187 | this.value = value;
|
188 | }
|
189 | activate(activationOptions) {
|
190 | this.activeList.activateByIndex(this.index, activationOptions);
|
191 | }
|
192 | deactivate(activationOptions) {
|
193 | this.activeList.deactivateByIndex(this.index, activationOptions);
|
194 | }
|
195 | toggle(activationOptions) {
|
196 | this.activeList.toggleByIndex(this.index, activationOptions);
|
197 | }
|
198 | remove() {
|
199 | return this.activeList.removeByIndex(this.index);
|
200 | }
|
201 | swapWith(item) {
|
202 | const itemIndex = this.activeList.getIndex(item);
|
203 | this.swapWithByIndex(itemIndex);
|
204 | }
|
205 | swapWithByIndex(index) {
|
206 | this.activeList.swapByIndex(this.index, index);
|
207 | }
|
208 | swapWithNext() {
|
209 | const nextIndex = this.activeList._getBoundedNextIndex(this.index);
|
210 | this.swapWithByIndex(nextIndex);
|
211 | }
|
212 | swapWithPrevious() {
|
213 | const previousIndex = this.activeList._getBoundedPreviousIndex(this.index);
|
214 | this.swapWithByIndex(previousIndex);
|
215 | }
|
216 | moveToIndex(to) {
|
217 | this.activeList.moveByIndex(this.index, to);
|
218 | }
|
219 | moveToPredicate(predicate, options) {
|
220 | this.activeList.moveByIndexByPredicate(this.index, predicate, options);
|
221 | }
|
222 | moveToFirst() {
|
223 | this.activeList.moveByIndex(this.index, 0);
|
224 | }
|
225 | moveToLast() {
|
226 | this.activeList.moveByIndex(this.index, this.activeList.getLastIndex());
|
227 | }
|
228 | }
|
229 |
|
230 | class ActiveListCooldownDurationError extends Error {
|
231 | constructor() {
|
232 | super(`${common$3} cooldown > duration cannot be negative or zero`);
|
233 | this.name = "ActiveListCooldownDurationError";
|
234 | }
|
235 | }
|
236 |
|
237 | class _CooldownTimer {
|
238 | constructor(activeList, cooldown) {
|
239 | this._cooldownTimeoutId = null;
|
240 | this._cooldown = undefined;
|
241 | if (typeof cooldown === 'number') {
|
242 | this._assertDuration(cooldown);
|
243 | }
|
244 | this._activeList = activeList;
|
245 | this._cooldown = cooldown;
|
246 | }
|
247 | _isActive(activationOptions) {
|
248 | if (activationOptions.isUserInteraction === false) {
|
249 | return false;
|
250 | }
|
251 | return this._activeList.cooldown.isActive;
|
252 | }
|
253 | _setCooldown(activationOptions, content) {
|
254 | if (activationOptions.isUserInteraction === false) {
|
255 | return;
|
256 | }
|
257 | const duration = this._getDuration(activationOptions, content);
|
258 | if (duration === -1) {
|
259 | this._stopCooldown();
|
260 | return;
|
261 | }
|
262 | this._activeList.cooldown.isActive = true;
|
263 | this._activeList.cooldown.duration = duration;
|
264 | this._cooldownTimeoutId = window.setTimeout(() => {
|
265 | this._stopCooldown();
|
266 | }, duration);
|
267 | const event = {
|
268 | type: 'COOLDOWN_STARTED',
|
269 | time: new Date(),
|
270 | };
|
271 | this._activeList._inform(event);
|
272 | }
|
273 | _getDuration(activationOptions, content) {
|
274 | let duration = -1;
|
275 | if (activationOptions.cooldown !== undefined) {
|
276 | duration = this._getDurationFromConfig(activationOptions.cooldown, content);
|
277 | }
|
278 | else if (this._cooldown !== undefined) {
|
279 | duration = this._getDurationFromConfig(this._cooldown, content);
|
280 | }
|
281 | else {
|
282 | return -1;
|
283 | }
|
284 | this._assertDuration(duration);
|
285 | return duration;
|
286 | }
|
287 | _getDurationFromConfig(cooldownConfig, content) {
|
288 | if (typeof cooldownConfig === 'number') {
|
289 | return cooldownConfig;
|
290 | }
|
291 | else {
|
292 | return cooldownConfig({
|
293 | index: content.index,
|
294 | content: content,
|
295 | value: content.value,
|
296 | activeList: this._activeList,
|
297 | });
|
298 | }
|
299 | }
|
300 | _assertDuration(cooldownValue) {
|
301 | if (cooldownValue <= 0) {
|
302 | throw new ActiveListCooldownDurationError();
|
303 | }
|
304 | }
|
305 | _stopCooldown() {
|
306 | if (this._cooldownTimeoutId) {
|
307 | window.clearTimeout(this._cooldownTimeoutId);
|
308 | }
|
309 | if (!this._activeList.cooldown.isActive) {
|
310 | return;
|
311 | }
|
312 | this._activeList.cooldown.isActive = false;
|
313 | this._activeList.cooldown.duration = 0;
|
314 | const event = {
|
315 | type: 'COOLDOWN_ENDED',
|
316 | time: new Date(),
|
317 | };
|
318 | this._activeList._inform(event);
|
319 | }
|
320 | }
|
321 |
|
322 | class ActiveListActivationLimitReachedError extends Error {
|
323 | constructor() {
|
324 | super(`${common$3} activateByIndex > activation limit reached`);
|
325 | this.name = 'ActiveListActivationLimitReachedError';
|
326 | }
|
327 | }
|
328 |
|
329 | class ActiveListIndexOutOfBoundsError extends Error {
|
330 | constructor(message) {
|
331 | super(message);
|
332 | this.name = "ActiveListIndexOutOfBoundsError";
|
333 | }
|
334 | }
|
335 | function throwIndexOutOfBoundsError(method, indexName) {
|
336 | throw new ActiveListIndexOutOfBoundsError(`${common$3} ${method} > "${indexName}" is out of bounds`);
|
337 | }
|
338 |
|
339 | class ActiveListItemNotFoundError extends Error {
|
340 | constructor() {
|
341 | super(`${common$3} getIndex > index cannot be found, item is not in contents array`);
|
342 | this.name = 'ActiveListItemNotFoundError';
|
343 | }
|
344 | }
|
345 |
|
346 | class _History {
|
347 | constructor() {
|
348 | this._events = [];
|
349 | this._keepHistoryFor = 0;
|
350 | }
|
351 | _push(event) {
|
352 | if (this._keepHistoryFor > 0) {
|
353 | this._events.push(event);
|
354 | if (this._events.length - 1 === this._keepHistoryFor) {
|
355 | this._events.shift();
|
356 | }
|
357 | }
|
358 | }
|
359 | _setKeepHistoryFor(_keepHistoryFor = 0) {
|
360 | this._keepHistoryFor = _keepHistoryFor;
|
361 | }
|
362 | }
|
363 |
|
364 | class _Observer {
|
365 | constructor() {
|
366 | this._subscribers = [];
|
367 | }
|
368 | _subscribe(subscriber) {
|
369 | this._subscribers.push(subscriber);
|
370 | return () => {
|
371 | this._unsubscribe(subscriber);
|
372 | };
|
373 | }
|
374 | _unsubscribe(subscriber) {
|
375 | this._subscribers = this._subscribers.filter((s) => subscriber !== s);
|
376 | }
|
377 | _clear() {
|
378 | this._subscribers.length = 0;
|
379 | }
|
380 | _inform(observable, event) {
|
381 | this._subscribers.forEach((subscriber) => subscriber(observable, event));
|
382 | }
|
383 | }
|
384 |
|
385 | class ActiveList {
|
386 | constructor(config = {}, subscriber) {
|
387 | this._isInitializing = false;
|
388 | this.contents = [];
|
389 | this.maxActivationLimit = 1;
|
390 | this.maxActivationLimitBehavior = 'circular';
|
391 | this.active = [];
|
392 | this.activeContents = [];
|
393 | this.activeIndexes = [];
|
394 | this.lastActivated = null;
|
395 | this.lastActivatedContent = null;
|
396 | this.lastActivatedIndex = -1;
|
397 | this.lastDeactivated = null;
|
398 | this.lastDeactivatedContent = null;
|
399 | this.lastDeactivatedIndex = -1;
|
400 | this.isCircular = false;
|
401 | this.direction = 'right';
|
402 | this.oppositeDirection = 'left';
|
403 | this._history = new _History();
|
404 | this.history = this._history._events;
|
405 | this._observer = new _Observer();
|
406 | this.hasActiveChangedAtLeastOnce = false;
|
407 | this.cooldown = {
|
408 | isActive: false,
|
409 | duration: 0,
|
410 | };
|
411 | this.autoPlay = {
|
412 | isPlaying: false,
|
413 | duration: 0,
|
414 | hasBeenStoppedBefore: false,
|
415 | };
|
416 | licenseChecker._checkLicense();
|
417 | if (subscriber) {
|
418 | this.subscribe(subscriber);
|
419 | }
|
420 | this.initialize(config);
|
421 | }
|
422 | subscribe(subscriber) {
|
423 | return this._observer._subscribe(subscriber);
|
424 | }
|
425 | unsubscribe(subscriber) {
|
426 | this._observer._unsubscribe(subscriber);
|
427 | }
|
428 | unsubscribeAll() {
|
429 | this._observer._clear();
|
430 | }
|
431 | initialize(config) {
|
432 | this._isInitializing = true;
|
433 | this.maxActivationLimit =
|
434 | config.maxActivationLimit !== undefined ? config.maxActivationLimit : 1;
|
435 | this.maxActivationLimitBehavior = config.maxActivationLimitBehavior
|
436 | ? config.maxActivationLimitBehavior
|
437 | : 'circular';
|
438 | this.isCircular = !!config.isCircular;
|
439 | const contents = config.contents ? config.contents : [];
|
440 | this.contents.length = 0;
|
441 | contents.forEach((c, index) => {
|
442 | this.contents[index] = this._initializeABrokenContent(c, index, contents);
|
443 | });
|
444 | this._directions = config.directions
|
445 | ? config.directions
|
446 | : { next: 'right', previous: 'left' };
|
447 | this._history._events.length = 0;
|
448 | this._history._setKeepHistoryFor(config.keepHistoryFor);
|
449 | this._becameEmpty();
|
450 | this._activationCooldownTimer = new _CooldownTimer(this, config.cooldown);
|
451 | this.cooldown.isActive = false;
|
452 | this.cooldown.duration = 0;
|
453 | if (config.active !== undefined) {
|
454 | if (Array.isArray(config.active)) {
|
455 | config.active.forEach((active) => this.activate(active, { isUserInteraction: false }));
|
456 | }
|
457 | else {
|
458 | this.activate(config.active, { isUserInteraction: false });
|
459 | }
|
460 | }
|
461 | else if (config.activeIndexes !== undefined) {
|
462 | if (Array.isArray(config.activeIndexes)) {
|
463 | config.activeIndexes.forEach((index) => this.activateByIndex(index, {
|
464 | isUserInteraction: false,
|
465 | }));
|
466 | }
|
467 | else {
|
468 | this.activateByIndex(config.activeIndexes, {
|
469 | isUserInteraction: false,
|
470 | });
|
471 | }
|
472 | }
|
473 | this._emptyLastDeactivated();
|
474 | this.hasActiveChangedAtLeastOnce = false;
|
475 | this.direction = this._directions.next;
|
476 | this.oppositeDirection = this._directions.previous;
|
477 | this.autoPlay.isPlaying = false;
|
478 | this.autoPlay.duration = 0;
|
479 | this.autoPlay.hasBeenStoppedBefore = false;
|
480 | this._autoPlay = new _AutoPlay(this, config.autoPlay ? config.autoPlay : null);
|
481 | this._autoPlay._play(false);
|
482 | this._isInitializing = false;
|
483 | const event = {
|
484 | type: 'INITIALIZED',
|
485 | values: [...this.active],
|
486 | indexes: [...this.activeIndexes],
|
487 | time: new Date(),
|
488 | };
|
489 | this._inform(event);
|
490 | }
|
491 | _initializeABrokenContent(value, index, contents) {
|
492 | const content = new ActiveListContent(this, index, value);
|
493 | this._repairContent(content, index, contents);
|
494 | return content;
|
495 | }
|
496 | activateByIndex(index, activationOptions = {
|
497 | isUserInteraction: true,
|
498 | cooldown: undefined,
|
499 | }) {
|
500 | const previousDeactivatedIndex = this.lastDeactivatedIndex;
|
501 | const activatedContent = this._doActivateByIndex(index, activationOptions);
|
502 | if (!activatedContent) {
|
503 | return;
|
504 | }
|
505 | let deactivatedIndex = -1;
|
506 | let deactivatedValue = null;
|
507 | if (previousDeactivatedIndex !== this.lastDeactivatedIndex) {
|
508 | deactivatedIndex = this.lastDeactivatedIndex;
|
509 | deactivatedValue = this.lastDeactivated;
|
510 | }
|
511 | const event = {
|
512 | type: 'ACTIVATED',
|
513 | value: activatedContent.value,
|
514 | index,
|
515 | deactivatedIndex,
|
516 | deactivatedValue,
|
517 | time: new Date(),
|
518 | };
|
519 | this._inform(event);
|
520 | this._activationCooldownTimer._setCooldown(activationOptions, this.lastActivatedContent);
|
521 | }
|
522 | _doActivateByIndex(index, activationOptions) {
|
523 | if (this._checkIndex(index)) {
|
524 | throwIndexOutOfBoundsError('activateByIndex', 'index');
|
525 | }
|
526 | if (this.activeIndexes.includes(index)) {
|
527 | return null;
|
528 | }
|
529 | if (this._activationCooldownTimer._isActive(activationOptions)) {
|
530 | return null;
|
531 | }
|
532 | const limitReached = this.maxActivationLimit === false
|
533 | ? false
|
534 | : this.maxActivationLimit === this.activeIndexes.length;
|
535 | if (limitReached) {
|
536 | if (this.maxActivationLimitBehavior === 'error') {
|
537 | throw new ActiveListActivationLimitReachedError();
|
538 | }
|
539 | else if (this.maxActivationLimitBehavior === 'ignore') {
|
540 | return null;
|
541 | }
|
542 | }
|
543 | const nextIndex = this._getUnboundedNextIndex(index);
|
544 | const previousIndex = this._getUnboundedPreviousIndex(index);
|
545 | this.contents.forEach((content, i) => {
|
546 | content.isActive = content.isActive ? content.isActive : index === i;
|
547 | content.isNext = nextIndex === i;
|
548 | content.isPrevious = previousIndex === i;
|
549 | if (index === i) {
|
550 | this.activeIndexes.push(i);
|
551 | this.activeContents.push(content);
|
552 | this.active.push(content.value);
|
553 | if (limitReached) {
|
554 | this.activeIndexes.shift();
|
555 | this.active.shift();
|
556 | const content = this.activeContents.shift();
|
557 | if (content) {
|
558 | this._deactivateContent(content);
|
559 | }
|
560 | }
|
561 | this.direction = this._getDirectionWhenMovingToIndex(i);
|
562 | this.oppositeDirection =
|
563 | this.direction === this._directions.next
|
564 | ? this._directions.previous
|
565 | : this._directions.next;
|
566 | this.lastActivated = content.value;
|
567 | this.lastActivatedContent = content;
|
568 | this.lastActivatedIndex = i;
|
569 | content.hasBeenActiveBefore = true;
|
570 | }
|
571 | });
|
572 | if (this._autoPlay) {
|
573 | this._autoPlay.onActiveIndexChanged(index, activationOptions);
|
574 | }
|
575 | this.hasActiveChangedAtLeastOnce = true;
|
576 | return this.lastActivatedContent;
|
577 | }
|
578 | activate(item, activationOptions) {
|
579 | const index = this.getIndex(item);
|
580 | this.activateByIndex(index, activationOptions);
|
581 | }
|
582 | activateByPredicate(predicate, activationOptions = {
|
583 | isUserInteraction: true,
|
584 | cooldown: undefined,
|
585 | }) {
|
586 | if (this._activationCooldownTimer._isActive(activationOptions)) {
|
587 | return undefined;
|
588 | }
|
589 | const previousActiveIndexes = [...this.activeIndexes];
|
590 | let lastActivated = null;
|
591 | let error = null;
|
592 | this._execPred(predicate, (index) => {
|
593 | try {
|
594 | const content = this._doActivateByIndex(index, activationOptions);
|
595 | if (content) {
|
596 | lastActivated = content;
|
597 | }
|
598 | }
|
599 | catch (e) {
|
600 | if (e instanceof ActiveListActivationLimitReachedError) {
|
601 | error = e;
|
602 | return true;
|
603 | }
|
604 | }
|
605 | });
|
606 | if (lastActivated) {
|
607 | const values = [];
|
608 | const indexes = [];
|
609 | this.activeIndexes.forEach((current) => {
|
610 | const isNewlyActivated = previousActiveIndexes.every((prev) => prev !== current);
|
611 | if (isNewlyActivated) {
|
612 | indexes.push(current);
|
613 | values.push(this.contents[current].value);
|
614 | }
|
615 | });
|
616 | const deactivatedValues = [];
|
617 | const deactivatedIndexes = [];
|
618 | if (this.maxActivationLimit !== false &&
|
619 | this.maxActivationLimitBehavior === 'circular') {
|
620 | previousActiveIndexes.forEach((prev) => {
|
621 | const isNewlyDeactivated = this.activeIndexes.every((current) => prev !== current);
|
622 | if (isNewlyDeactivated) {
|
623 | deactivatedIndexes.push(prev);
|
624 | deactivatedValues.push(this.contents[prev].value);
|
625 | }
|
626 | });
|
627 | }
|
628 | const event = {
|
629 | type: 'ACTIVATED_MULTIPLE',
|
630 | values,
|
631 | indexes,
|
632 | deactivatedIndexes,
|
633 | deactivatedValues,
|
634 | time: new Date(),
|
635 | };
|
636 | this._inform(event);
|
637 | if (lastActivated) {
|
638 | this._activationCooldownTimer._setCooldown(activationOptions, lastActivated);
|
639 | }
|
640 | }
|
641 | if (error) {
|
642 | throw error;
|
643 | }
|
644 | }
|
645 | activateNext(activationOptions) {
|
646 | if (this.isEmpty()) {
|
647 | return;
|
648 | }
|
649 | const index = this._getBoundedNextIndex(this.lastActivatedIndex);
|
650 | this.activateByIndex(index, activationOptions);
|
651 | }
|
652 | activatePrevious(activationOptions) {
|
653 | if (this.isEmpty()) {
|
654 | return;
|
655 | }
|
656 | const index = this._getBoundedPreviousIndex(this.lastActivatedIndex);
|
657 | this.activateByIndex(index, activationOptions);
|
658 | }
|
659 | activateFirst(activationOptions) {
|
660 | if (this.isEmpty()) {
|
661 | return;
|
662 | }
|
663 | this.activateByIndex(0, activationOptions);
|
664 | }
|
665 | activateLast(activationOptions) {
|
666 | if (this.isEmpty()) {
|
667 | return;
|
668 | }
|
669 | this.activateByIndex(this.getLastIndex(), activationOptions);
|
670 | }
|
671 | deactivateByIndex(index, activationOptions = {
|
672 | isUserInteraction: true,
|
673 | cooldown: undefined,
|
674 | }) {
|
675 | const deactivatedContent = this._doDeactivateByIndex(index, activationOptions);
|
676 | if (!deactivatedContent) {
|
677 | return;
|
678 | }
|
679 | const event = {
|
680 | type: 'DEACTIVATED',
|
681 | value: this.contents[index].value,
|
682 | index,
|
683 | time: new Date(),
|
684 | };
|
685 | this._inform(event);
|
686 | this._activationCooldownTimer._setCooldown(activationOptions, deactivatedContent);
|
687 | }
|
688 | _doDeactivateByIndex(index, activationOptions) {
|
689 | if (this._checkIndex(index)) {
|
690 | throwIndexOutOfBoundsError('deactivateByIndex', 'index');
|
691 | }
|
692 | const indexOfIndex = this.activeIndexes.indexOf(index);
|
693 | if (indexOfIndex === -1) {
|
694 | return null;
|
695 | }
|
696 | if (this._activationCooldownTimer._isActive(activationOptions)) {
|
697 | return null;
|
698 | }
|
699 | const deactivatedContent = this.activeContents[indexOfIndex];
|
700 | this._deactivateContent(deactivatedContent);
|
701 | this.activeIndexes.splice(indexOfIndex, 1);
|
702 | this.active.splice(indexOfIndex, 1);
|
703 | this.activeContents.splice(indexOfIndex, 1);
|
704 | if (this.activeIndexes.length === 0) {
|
705 | this._emptyLastActives();
|
706 | this.direction = this._directions.next;
|
707 | }
|
708 | else {
|
709 | this._setLastActives();
|
710 | this.direction = this._getDirectionWhenMovingToIndex(deactivatedContent.index);
|
711 | this.oppositeDirection = this.direction;
|
712 | this.direction =
|
713 | this.direction === this._directions.next
|
714 | ? this._directions.previous
|
715 | : this._directions.next;
|
716 | }
|
717 | this._repairContents();
|
718 | this.hasActiveChangedAtLeastOnce = true;
|
719 | if (this._autoPlay) {
|
720 | this._autoPlay._onDeactivation(activationOptions);
|
721 | }
|
722 | return deactivatedContent;
|
723 | }
|
724 | deactivate(item, activationOptions) {
|
725 | const index = this.getIndex(item);
|
726 | this.deactivateByIndex(index, activationOptions);
|
727 | }
|
728 | deactivateByPredicate(predicate, activationOptions = {
|
729 | isUserInteraction: true,
|
730 | cooldown: undefined,
|
731 | }) {
|
732 | if (this._activationCooldownTimer._isActive(activationOptions)) {
|
733 | return undefined;
|
734 | }
|
735 | const deactivatedIndexes = [];
|
736 | const deactivatedValues = [];
|
737 | let lastRemoved = null;
|
738 | this._execPred(predicate, (index) => {
|
739 | const content = this._doDeactivateByIndex(index, activationOptions);
|
740 | if (content) {
|
741 | deactivatedIndexes.push(content.index);
|
742 | deactivatedValues.push(content.value);
|
743 | lastRemoved = content;
|
744 | }
|
745 | });
|
746 | if (deactivatedIndexes.length === 0) {
|
747 | return;
|
748 | }
|
749 | const event = {
|
750 | type: 'DEACTIVATED_MULTIPLE',
|
751 | values: deactivatedValues,
|
752 | indexes: deactivatedIndexes,
|
753 | time: new Date(),
|
754 | };
|
755 | this._inform(event);
|
756 | if (lastRemoved) {
|
757 | this._activationCooldownTimer._setCooldown(activationOptions, lastRemoved);
|
758 | }
|
759 | }
|
760 | toggleByIndex(index, activationOptions) {
|
761 | if (this._checkIndex(index)) {
|
762 | throwIndexOutOfBoundsError('toggleByIndex', 'index');
|
763 | }
|
764 | if (this.contents[index].isActive) {
|
765 | this.deactivateByIndex(index, activationOptions);
|
766 | }
|
767 | else {
|
768 | this.activateByIndex(index, activationOptions);
|
769 | }
|
770 | }
|
771 | toggle(item, activationOptions) {
|
772 | const index = this.getIndex(item);
|
773 | this.toggleByIndex(index, activationOptions);
|
774 | }
|
775 | play() {
|
776 | this._autoPlay._play(true);
|
777 | }
|
778 | pause() {
|
779 | this._autoPlay._pause();
|
780 | }
|
781 | stop() {
|
782 | this._autoPlay._stop();
|
783 | }
|
784 | configureAutoPlay(autoPlayConfig) {
|
785 | this._autoPlay._setConfig(autoPlayConfig);
|
786 | if (autoPlayConfig) {
|
787 | this._autoPlay._play(true);
|
788 | }
|
789 | else {
|
790 | this._autoPlay._stop();
|
791 | }
|
792 | }
|
793 | insertAtIndex(item, index) {
|
794 | if (index < 0 || index > this.contents.length) {
|
795 | throwIndexOutOfBoundsError('insertAtIndex', 'index');
|
796 | }
|
797 | const content = this._initializeABrokenContent(item, index, this.contents);
|
798 | this.activeIndexes.forEach((i, aiIndex) => {
|
799 | this.activeIndexes[aiIndex] = i >= index ? i + 1 : i;
|
800 | });
|
801 | this.contents.splice(index, 0, content);
|
802 | if (index <= this.lastActivatedIndex) {
|
803 | this.lastActivatedIndex += 1;
|
804 | }
|
805 | this._repairContents();
|
806 | const event = {
|
807 | type: 'INSERTED',
|
808 | value: item,
|
809 | index,
|
810 | time: new Date(),
|
811 | };
|
812 | this._inform(event);
|
813 | return content;
|
814 | }
|
815 | push(item) {
|
816 | return this.insertAtIndex(item, this.contents.length);
|
817 | }
|
818 | unshift(item) {
|
819 | return this.insertAtIndex(item, 0);
|
820 | }
|
821 | insertByPredicate(item, predicate, options = { mode: 'at' }) {
|
822 | const mod = this._modeToMod(options.mode);
|
823 | return this._execPred(predicate, (index) => {
|
824 | const atIndex = Math.max(0, index + mod);
|
825 | return this.insertAtIndex(item, atIndex);
|
826 | });
|
827 | }
|
828 | removeByIndex(index) {
|
829 | const value = this._doRemoveAtIndex(index);
|
830 | const indexOfIndex = this.activeIndexes.indexOf(index);
|
831 | if (indexOfIndex !== -1) {
|
832 | this.activeIndexes.splice(indexOfIndex, 1);
|
833 | this.active.splice(indexOfIndex, 1);
|
834 | this.activeContents.splice(indexOfIndex, 1);
|
835 | this.hasActiveChangedAtLeastOnce = true;
|
836 | }
|
837 | this.activeIndexes.map((i, aiIndex) => {
|
838 | this.activeIndexes[aiIndex] = i >= index ? i - 1 : i;
|
839 | });
|
840 | if (this.isEmpty()) {
|
841 | this._becameEmpty();
|
842 | this._autoPlay._stop();
|
843 | }
|
844 | else {
|
845 | this._setLastActives();
|
846 | }
|
847 | this._repairContents();
|
848 | const event = {
|
849 | type: 'REMOVED',
|
850 | value,
|
851 | index,
|
852 | time: new Date(),
|
853 | };
|
854 | this._inform(event);
|
855 | return value;
|
856 | }
|
857 | _doRemoveAtIndex(index) {
|
858 | if (this._checkIndex(index)) {
|
859 | throwIndexOutOfBoundsError('removeByIndex', 'index');
|
860 | }
|
861 | if (this.lastDeactivated && this.lastDeactivatedIndex === index) {
|
862 | this._emptyLastDeactivated();
|
863 | }
|
864 | const value = this.contents[index].value;
|
865 | this.contents.splice(index, 1);
|
866 | return value;
|
867 | }
|
868 | remove(item) {
|
869 | const index = this.getIndex(item);
|
870 | return this.removeByIndex(index);
|
871 | }
|
872 | pop() {
|
873 | if (this.isEmpty()) {
|
874 | return undefined;
|
875 | }
|
876 | return this.removeByIndex(this.getLastIndex());
|
877 | }
|
878 | shift() {
|
879 | if (this.isEmpty()) {
|
880 | return undefined;
|
881 | }
|
882 | return this.removeByIndex(0);
|
883 | }
|
884 | removeByPredicate(predicate) {
|
885 | if (this.isEmpty()) {
|
886 | return [];
|
887 | }
|
888 | const removed = [];
|
889 | this._execPred(predicate, (index) => {
|
890 | const content = this.contents[index];
|
891 | removed.push(content);
|
892 | });
|
893 | const removedIndexes = [];
|
894 | removed.forEach((content, index) => {
|
895 | const actualIndex = content.index - index;
|
896 | this._doRemoveAtIndex(actualIndex);
|
897 | removedIndexes.push(content.index);
|
898 | });
|
899 | if (this.isEmpty()) {
|
900 | this._becameEmpty();
|
901 | this._autoPlay._stop();
|
902 | }
|
903 | else {
|
904 | removedIndexes.forEach((index) => {
|
905 | const indexOfIndex = this.activeIndexes.indexOf(index);
|
906 | if (indexOfIndex !== -1) {
|
907 | this.activeIndexes.splice(indexOfIndex, 1);
|
908 | this.active.splice(indexOfIndex, 1);
|
909 | this.activeContents.splice(indexOfIndex, 1);
|
910 | this.hasActiveChangedAtLeastOnce = true;
|
911 | }
|
912 | });
|
913 | removedIndexes.forEach((removed) => {
|
914 | this.activeIndexes.forEach((index, aiIndex) => {
|
915 | this.activeIndexes[aiIndex] = index >= removed ? index - 1 : index;
|
916 | });
|
917 | });
|
918 | this._setLastActives();
|
919 | }
|
920 | const removedValues = removed.map((r) => r.value);
|
921 | if (removedIndexes.length > 0) {
|
922 | this._repairContents();
|
923 | const event = {
|
924 | type: 'REMOVED_MULTIPLE',
|
925 | indexes: [...removedIndexes],
|
926 | values: [...removedValues],
|
927 | time: new Date(),
|
928 | };
|
929 | this._inform(event);
|
930 | }
|
931 | return removedValues;
|
932 | }
|
933 | swapByIndex(a, b) {
|
934 | if (this._checkIndex(a)) {
|
935 | throwIndexOutOfBoundsError('swapByIndex', 'a');
|
936 | }
|
937 | if (this._checkIndex(b)) {
|
938 | throwIndexOutOfBoundsError('swapByIndex', 'b');
|
939 | }
|
940 | if (a === b) {
|
941 | return;
|
942 | }
|
943 | const itemA = this.contents[a];
|
944 | const itemB = this.contents[b];
|
945 | if (this.lastActivatedIndex === itemA.index) {
|
946 | this.lastActivatedIndex = itemB.index;
|
947 | }
|
948 | else if (this.lastActivatedIndex === itemB.index) {
|
949 | this.lastActivatedIndex = itemA.index;
|
950 | }
|
951 | const indexOfA = this.activeIndexes.indexOf(itemA.index);
|
952 | const indexOfB = this.activeIndexes.indexOf(itemB.index);
|
953 | if (indexOfA !== -1) {
|
954 | this.activeIndexes[indexOfA] = itemB.index;
|
955 | }
|
956 | if (indexOfB !== -1) {
|
957 | this.activeIndexes[indexOfB] = itemA.index;
|
958 | }
|
959 | itemA.index = b;
|
960 | itemB.index = a;
|
961 | this.contents[a] = itemB;
|
962 | this.contents[b] = itemA;
|
963 | this._repairContents();
|
964 | const event = {
|
965 | type: 'SWAPPED',
|
966 | value: {
|
967 | a: itemA.value,
|
968 | b: itemB.value,
|
969 | },
|
970 | index: {
|
971 | a,
|
972 | b,
|
973 | },
|
974 | time: new Date(),
|
975 | };
|
976 | this._inform(event);
|
977 | }
|
978 | swap(a, b) {
|
979 | const indexA = this.getIndex(a);
|
980 | const indexB = this.getIndex(b);
|
981 | this.swapByIndex(indexA, indexB);
|
982 | }
|
983 | moveByIndex(from, to) {
|
984 | if (this._checkIndex(from)) {
|
985 | throwIndexOutOfBoundsError('moveByIndex', 'from');
|
986 | }
|
987 | if (this._checkIndex(to)) {
|
988 | throwIndexOutOfBoundsError('moveByIndex', 'to');
|
989 | }
|
990 | if (from === to) {
|
991 | return;
|
992 | }
|
993 | const lastActivatedIndex = this.lastActivatedIndex;
|
994 | if (lastActivatedIndex === from) {
|
995 | this.lastActivatedIndex = to;
|
996 | }
|
997 | else if (to === lastActivatedIndex && from > lastActivatedIndex) {
|
998 | this.lastActivatedIndex += 1;
|
999 | }
|
1000 | else if (to === lastActivatedIndex && from < lastActivatedIndex) {
|
1001 | this.lastActivatedIndex -= 1;
|
1002 | }
|
1003 | else if (to > lastActivatedIndex && from < lastActivatedIndex) {
|
1004 | this.lastActivatedIndex -= 1;
|
1005 | }
|
1006 | else if (to < lastActivatedIndex && from > lastActivatedIndex) {
|
1007 | this.lastActivatedIndex += 1;
|
1008 | }
|
1009 | this.activeIndexes.forEach((index, aiIndex) => {
|
1010 | if (index === from) {
|
1011 | this.activeIndexes[aiIndex] = to;
|
1012 | return;
|
1013 | }
|
1014 | if (index > from && index > to) {
|
1015 | this.activeIndexes[aiIndex] = index;
|
1016 | return;
|
1017 | }
|
1018 | if (index < from && index < to) {
|
1019 | this.activeIndexes[aiIndex] = index;
|
1020 | return;
|
1021 | }
|
1022 | this.activeIndexes[aiIndex] = from > to ? index + 1 : index - 1;
|
1023 | });
|
1024 | const fromItem = this.contents[from];
|
1025 | this.contents.splice(from, 1);
|
1026 | this.contents.splice(to, 0, fromItem);
|
1027 | this._repairContents();
|
1028 | const event = {
|
1029 | type: 'MOVED',
|
1030 | value: fromItem.value,
|
1031 | index: {
|
1032 | from,
|
1033 | to,
|
1034 | },
|
1035 | time: new Date(),
|
1036 | };
|
1037 | this._inform(event);
|
1038 | }
|
1039 | move(item, to) {
|
1040 | const from = this.getIndex(item);
|
1041 | this.moveByIndex(from, to);
|
1042 | }
|
1043 | moveByIndexByPredicate(index, predicate, options = { mode: 'at' }) {
|
1044 | const mod = this._modeToMod(options.mode);
|
1045 | this._execPred(predicate, (i, length) => {
|
1046 | const atIndex = Math.min(Math.max(0, i + mod), length - 1);
|
1047 | this.moveByIndex(index, atIndex);
|
1048 | return true;
|
1049 | });
|
1050 | }
|
1051 | moveByPredicate(item, predicate, options) {
|
1052 | const index = this.getIndex(item);
|
1053 | this.moveByIndexByPredicate(index, predicate, options);
|
1054 | }
|
1055 | getIndex(item) {
|
1056 | const contents = this.contents;
|
1057 | const length = contents.length;
|
1058 | for (let i = 0; i < length; i++) {
|
1059 | if (contents[i].value === item) {
|
1060 | return i;
|
1061 | }
|
1062 | }
|
1063 | throw new ActiveListItemNotFoundError();
|
1064 | }
|
1065 | getLastIndex() {
|
1066 | return this.contents.length - 1;
|
1067 | }
|
1068 | _getBoundedNextIndex(index) {
|
1069 | let nextIndex = index + 1;
|
1070 | if (nextIndex >= this.contents.length) {
|
1071 | nextIndex = this.isCircular ? 0 : this.getLastIndex();
|
1072 | }
|
1073 | return nextIndex;
|
1074 | }
|
1075 | _getBoundedPreviousIndex(index) {
|
1076 | let previousIndex = index - 1;
|
1077 | if (previousIndex < 0) {
|
1078 | previousIndex = this.isCircular ? this.getLastIndex() : 0;
|
1079 | }
|
1080 | return previousIndex;
|
1081 | }
|
1082 | _getUnboundedNextIndex(index) {
|
1083 | const nextIndex = index + 1;
|
1084 | if (this.isCircular && nextIndex === this.contents.length) {
|
1085 | return 0;
|
1086 | }
|
1087 | return nextIndex;
|
1088 | }
|
1089 | _getUnboundedPreviousIndex(index) {
|
1090 | const previousIndex = index - 1;
|
1091 | if (this.isCircular && previousIndex < 0) {
|
1092 | return this.getLastIndex();
|
1093 | }
|
1094 | return previousIndex;
|
1095 | }
|
1096 | isEmpty() {
|
1097 | return this.contents.length === 0;
|
1098 | }
|
1099 | _getDirectionWhenMovingToIndex(next) {
|
1100 | const lastActivatedIndex = this.lastActivatedIndex;
|
1101 | if (this.isCircular) {
|
1102 | if (this.lastActivatedIndex === -1) {
|
1103 | return this._directions.next;
|
1104 | }
|
1105 | const lastActivatedLargerThanNext = this.lastActivatedIndex > next;
|
1106 | const lastIndex = this.getLastIndex();
|
1107 | const leftDistance = lastActivatedLargerThanNext
|
1108 | ? this.lastActivatedIndex - next
|
1109 | : lastIndex - next + this.lastActivatedIndex + 1;
|
1110 | const rightDistance = lastActivatedLargerThanNext
|
1111 | ? 1 + next + (lastIndex - this.lastActivatedIndex)
|
1112 | : next - this.lastActivatedIndex;
|
1113 | return leftDistance >= rightDistance
|
1114 | ? this._directions.next
|
1115 | : this._directions.previous;
|
1116 | }
|
1117 | else {
|
1118 | return next >= lastActivatedIndex
|
1119 | ? this._directions.next
|
1120 | : this._directions.previous;
|
1121 | }
|
1122 | }
|
1123 | _repairContents() {
|
1124 | let nextIndex = null;
|
1125 | let previousIndex = null;
|
1126 | if (this.lastActivatedIndex !== -1) {
|
1127 | nextIndex = this._getUnboundedNextIndex(this.lastActivatedIndex);
|
1128 | previousIndex = this._getUnboundedPreviousIndex(this.lastActivatedIndex);
|
1129 | }
|
1130 | this.contents.forEach((content, index) => {
|
1131 | content.index = index;
|
1132 | content.isNext = nextIndex === index;
|
1133 | content.isPrevious = previousIndex === index;
|
1134 | this._repairContent(content, index, this.contents);
|
1135 | });
|
1136 | }
|
1137 | _repairContent(content, index, contents) {
|
1138 | content.isFirst = index === 0;
|
1139 | content.isLast = index === contents.length - 1;
|
1140 | if (this.isCircular) {
|
1141 | content.hasNext = true;
|
1142 | content.hasPrevious = true;
|
1143 | }
|
1144 | else {
|
1145 | content.hasNext = index + 1 < contents.length;
|
1146 | content.hasPrevious = index - 1 >= 0;
|
1147 | }
|
1148 | }
|
1149 | _emptyLastActives() {
|
1150 | this.lastActivatedIndex = -1;
|
1151 | this.lastActivated = null;
|
1152 | this.lastActivatedContent = null;
|
1153 | }
|
1154 | _emptyLastDeactivated() {
|
1155 | this.lastDeactivatedIndex = -1;
|
1156 | this.lastDeactivated = null;
|
1157 | this.lastDeactivatedContent = null;
|
1158 | }
|
1159 | _becameEmpty() {
|
1160 | this._emptyLastDeactivated();
|
1161 | this._emptyLastActives();
|
1162 | this.activeContents.length = 0;
|
1163 | this.activeIndexes.length = 0;
|
1164 | this.active.length = 0;
|
1165 | this.hasActiveChangedAtLeastOnce = true;
|
1166 | }
|
1167 | _setLastActives() {
|
1168 | if (this.activeIndexes.length === 0) {
|
1169 | this._emptyLastActives();
|
1170 | return;
|
1171 | }
|
1172 | const newLastActiveIndex = this.activeIndexes[this.activeIndexes.length - 1];
|
1173 | const newLastActiveList = this.contents[newLastActiveIndex];
|
1174 | this.lastActivated = newLastActiveList.value;
|
1175 | this.lastActivatedContent = newLastActiveList;
|
1176 | this.lastActivatedIndex = newLastActiveIndex;
|
1177 | }
|
1178 | _deactivateContent(content) {
|
1179 | content.isActive = false;
|
1180 | this.lastDeactivated = content.value;
|
1181 | this.lastDeactivatedContent = content;
|
1182 | this.lastDeactivatedIndex = content.index;
|
1183 | }
|
1184 | _execPred(predicate, action) {
|
1185 | const contents = this.contents;
|
1186 | const length = contents.length;
|
1187 | for (let index = 0; index < length; index++) {
|
1188 | const content = this.contents[index];
|
1189 | const data = {
|
1190 | index,
|
1191 | content,
|
1192 | value: content.value,
|
1193 | activeList: this,
|
1194 | };
|
1195 | if (predicate(data)) {
|
1196 | const result = action(index, length);
|
1197 | if (result !== undefined) {
|
1198 | return result;
|
1199 | }
|
1200 | }
|
1201 | }
|
1202 | return null;
|
1203 | }
|
1204 | _inform(event) {
|
1205 | if (this._isInitializing) {
|
1206 | return;
|
1207 | }
|
1208 | this._history._push(event);
|
1209 | this._observer._inform(this, event);
|
1210 | }
|
1211 | _checkIndex(index) {
|
1212 | return index < 0 || index >= this.contents.length;
|
1213 | }
|
1214 | _modeToMod(mode) {
|
1215 | return mode === 'at' ? 0 : mode === 'after' ? 1 : -1;
|
1216 | }
|
1217 | }
|
1218 |
|
1219 | function _callSubscriber(subscriberName, event, component, config) {
|
1220 | const methodName = 'on' +
|
1221 | event.type
|
1222 | .toLowerCase()
|
1223 | .split('_')
|
1224 | .reduce((acc, word) => {
|
1225 | const letters = word.split('');
|
1226 | letters[0] = letters[0].toUpperCase();
|
1227 | return acc + letters.join('');
|
1228 | }, '');
|
1229 | const method = config[methodName];
|
1230 | if (!method) {
|
1231 | if (config.debug) {
|
1232 | console.warn(`uiloos > ${subscriberName} event '${event.type}' was fired but '${methodName}' method is not implemented, this might not be correct.`);
|
1233 | }
|
1234 | return;
|
1235 | }
|
1236 | method(event, component);
|
1237 | }
|
1238 |
|
1239 | function createActiveListSubscriber(config) {
|
1240 | return (activeList, event) => {
|
1241 | _callSubscriber('createActiveListSubscriber', event, activeList, config);
|
1242 | };
|
1243 | }
|
1244 |
|
1245 | const common$2 = `uiloos > ViewChannel >`;
|
1246 |
|
1247 | class ViewChannelAutoDismissDurationError extends Error {
|
1248 | constructor() {
|
1249 | super(`${common$2} autoDismiss > duration cannot be negative or zero`);
|
1250 | this.name = 'ViewChannelAutoDismissDurationError';
|
1251 | }
|
1252 | }
|
1253 |
|
1254 | class _AutoDismiss {
|
1255 | constructor(view, config) {
|
1256 | this._autoDismissTimeoutId = null;
|
1257 | this._autoDismissStarted = new Date();
|
1258 | this._pauseStarted = null;
|
1259 | this._autoDismissCurrentDuration = 0;
|
1260 | this._config = null;
|
1261 | this._view = view;
|
1262 | this._config = config;
|
1263 | }
|
1264 | _play(inform) {
|
1265 | if (this._view.autoDismiss.isPlaying) {
|
1266 | return;
|
1267 | }
|
1268 | this._cancelTimer();
|
1269 | if (!this._config) {
|
1270 | return;
|
1271 | }
|
1272 | const duration = this._getDuration(this._config);
|
1273 | if (duration <= 0) {
|
1274 | throw new ViewChannelAutoDismissDurationError();
|
1275 | }
|
1276 | this._autoDismissCurrentDuration = duration;
|
1277 | this._autoDismissStarted = new Date();
|
1278 | if (this._pauseStarted === null) {
|
1279 | this._view.autoDismiss.duration = duration;
|
1280 | }
|
1281 | const result = this._config.result;
|
1282 | this._autoDismissTimeoutId = window.setTimeout(() => {
|
1283 | if (this._view.isPresented) {
|
1284 | this._view.autoDismiss.isPlaying = false;
|
1285 | this._view.autoDismiss.duration = 0;
|
1286 | this._view.viewChannel._doRemoveByIndex(this._view.index, result, 'AUTO_DISMISS');
|
1287 | }
|
1288 | this._autoDismissTimeoutId = null;
|
1289 | }, duration);
|
1290 | this._view.result.then(() => {
|
1291 | this._cancelTimer();
|
1292 | });
|
1293 | this._view.autoDismiss.isPlaying = true;
|
1294 | if (inform) {
|
1295 | const event = {
|
1296 | type: 'AUTO_DISMISS_PLAYING',
|
1297 | view: this._view,
|
1298 | index: this._view.index,
|
1299 | time: new Date(),
|
1300 | };
|
1301 | this._view.viewChannel._inform(event);
|
1302 | }
|
1303 | }
|
1304 | _pause() {
|
1305 | if (!this._view.autoDismiss.isPlaying) {
|
1306 | return;
|
1307 | }
|
1308 | this._pauseStarted = new Date();
|
1309 | this._cancelTimer();
|
1310 | this._view.autoDismiss.isPlaying = false;
|
1311 | const event = {
|
1312 | type: 'AUTO_DISMISS_PAUSED',
|
1313 | view: this._view,
|
1314 | index: this._view.index,
|
1315 | time: new Date(),
|
1316 | };
|
1317 | this._view.viewChannel._inform(event);
|
1318 | }
|
1319 | _stop() {
|
1320 | if (!this._view.autoDismiss.isPlaying && !this._pauseStarted) {
|
1321 | return;
|
1322 | }
|
1323 | this._cancelTimer();
|
1324 | this._pauseStarted = null;
|
1325 | this._view.autoDismiss.isPlaying = false;
|
1326 | this._view.autoDismiss.duration = 0;
|
1327 | const event = {
|
1328 | type: 'AUTO_DISMISS_STOPPED',
|
1329 | view: this._view,
|
1330 | index: this._view.index,
|
1331 | time: new Date(),
|
1332 | };
|
1333 | this._view.viewChannel._inform(event);
|
1334 | }
|
1335 | _cancelTimer() {
|
1336 | if (this._autoDismissTimeoutId !== null) {
|
1337 | window.clearTimeout(this._autoDismissTimeoutId);
|
1338 | this._autoDismissTimeoutId = null;
|
1339 | }
|
1340 | }
|
1341 | _getDuration(config) {
|
1342 | if (this._pauseStarted) {
|
1343 | return (this._autoDismissCurrentDuration -
|
1344 | (this._pauseStarted.getTime() - this._autoDismissStarted.getTime()));
|
1345 | }
|
1346 | return config.duration;
|
1347 | }
|
1348 | }
|
1349 |
|
1350 | class ViewChannelView {
|
1351 | constructor(viewChannel, index, data, priority, autoDismissConfig) {
|
1352 | var _a;
|
1353 | this.autoDismiss = {
|
1354 | isPlaying: false,
|
1355 | duration: 0,
|
1356 | };
|
1357 | this._resolve = null;
|
1358 | this.isPresented = true;
|
1359 | this.viewChannel = viewChannel;
|
1360 | this.index = index;
|
1361 | this.data = data;
|
1362 | this.priority = priority;
|
1363 | this.result = new Promise((resolve) => {
|
1364 | this._resolve = resolve;
|
1365 | });
|
1366 | this._autoDismiss = new _AutoDismiss(this, autoDismissConfig);
|
1367 | this._autoDismiss._play(false);
|
1368 | this.autoDismiss.duration = (_a = autoDismissConfig === null || autoDismissConfig === void 0 ? void 0 : autoDismissConfig.duration) !== null && _a !== void 0 ? _a : 0;
|
1369 | }
|
1370 | dismiss(result) {
|
1371 | this.viewChannel.dismiss(this, result);
|
1372 | }
|
1373 | play() {
|
1374 | this._autoDismiss._play(true);
|
1375 | }
|
1376 | pause() {
|
1377 | this._autoDismiss._pause();
|
1378 | }
|
1379 | stop() {
|
1380 | this._autoDismiss._stop();
|
1381 | }
|
1382 | changeData(data) {
|
1383 | this.viewChannel.changeData(this, data);
|
1384 | }
|
1385 | }
|
1386 |
|
1387 | class ViewChannelIndexOutOfBoundsError extends Error {
|
1388 | constructor(method) {
|
1389 | super(`${common$2} ${method} > "index" is out of bounds`);
|
1390 | this.name = 'ViewChannelIndexOutOfBoundsError';
|
1391 | }
|
1392 | }
|
1393 |
|
1394 | class ViewChannelViewNotFoundError extends Error {
|
1395 | constructor(method) {
|
1396 | super(`${common$2} ${method} > "ViewChannelView" not found in views array`);
|
1397 | this.name = 'ViewChannelViewNotFoundError';
|
1398 | }
|
1399 | }
|
1400 |
|
1401 | class ViewChannel {
|
1402 | constructor(config = {}, subscriber) {
|
1403 | this.views = [];
|
1404 | this._history = new _History();
|
1405 | this.history = this._history._events;
|
1406 | this._observer = new _Observer();
|
1407 | licenseChecker._checkLicense();
|
1408 | if (subscriber) {
|
1409 | this.subscribe(subscriber);
|
1410 | }
|
1411 | this.initialize(config);
|
1412 | }
|
1413 | initialize(config) {
|
1414 | this._history._events.length = 0;
|
1415 | this._history._setKeepHistoryFor(config.keepHistoryFor);
|
1416 | this._clearViews();
|
1417 | const event = {
|
1418 | type: 'INITIALIZED',
|
1419 | time: new Date(),
|
1420 | };
|
1421 | this._inform(event);
|
1422 | }
|
1423 | subscribe(subscriber) {
|
1424 | return this._observer._subscribe(subscriber);
|
1425 | }
|
1426 | unsubscribe(subscriber) {
|
1427 | this._observer._unsubscribe(subscriber);
|
1428 | }
|
1429 | unsubscribeAll() {
|
1430 | this._observer._clear();
|
1431 | }
|
1432 | present(viewConfig) {
|
1433 | const priority = viewConfig.priority ? viewConfig.priority : 0;
|
1434 | const priorityArray = Array.isArray(priority) ? priority : [priority];
|
1435 | const index = this._getIndexForPriority(priorityArray);
|
1436 | const view = new ViewChannelView(this, index, viewConfig.data, priorityArray, viewConfig.autoDismiss);
|
1437 | this.views.splice(index, 0, view);
|
1438 | this._repairIndexes();
|
1439 | const event = {
|
1440 | type: 'PRESENTED',
|
1441 | view,
|
1442 | index,
|
1443 | time: new Date(),
|
1444 | };
|
1445 | this._inform(event);
|
1446 | return view;
|
1447 | }
|
1448 | _doRemoveByIndex(index, result, reason) {
|
1449 | if (index < 0 || index >= this.views.length) {
|
1450 | throw new ViewChannelIndexOutOfBoundsError('dismissByIndex');
|
1451 | }
|
1452 | const view = this.views[index];
|
1453 | this.views.splice(index, 1);
|
1454 | this._repairIndexes();
|
1455 | view.isPresented = false;
|
1456 | view.autoDismiss.duration = 0;
|
1457 | view.autoDismiss.isPlaying = false;
|
1458 | view._resolve(result);
|
1459 | const event = {
|
1460 | type: 'DISMISSED',
|
1461 | view,
|
1462 | index,
|
1463 | reason,
|
1464 | time: new Date(),
|
1465 | };
|
1466 | this._inform(event);
|
1467 | }
|
1468 | dismissByIndex(index, result) {
|
1469 | this._doRemoveByIndex(index, result, 'USER_INTERACTION');
|
1470 | }
|
1471 | dismiss(view, result) {
|
1472 | if (!view.isPresented) {
|
1473 | return;
|
1474 | }
|
1475 | const index = this.views.indexOf(view);
|
1476 | if (index === -1) {
|
1477 | throw new ViewChannelViewNotFoundError('dismiss');
|
1478 | }
|
1479 | this.dismissByIndex(index, result);
|
1480 | }
|
1481 | dismissAll(result) {
|
1482 | if (this.views.length === 0) {
|
1483 | return;
|
1484 | }
|
1485 | const indexes = [];
|
1486 | const dismissedViews = [...this.views];
|
1487 | this._clearViews();
|
1488 | dismissedViews.forEach((view) => {
|
1489 | view.isPresented = false;
|
1490 | view._resolve(result);
|
1491 | indexes.push(view.index);
|
1492 | });
|
1493 | const event = {
|
1494 | type: 'DISMISSED_ALL',
|
1495 | views: dismissedViews,
|
1496 | indexes,
|
1497 | time: new Date(),
|
1498 | };
|
1499 | this._inform(event);
|
1500 | }
|
1501 | changeDataByIndex(index, data) {
|
1502 | if (index < 0 || index >= this.views.length) {
|
1503 | throw new ViewChannelIndexOutOfBoundsError('changeDataByIndex');
|
1504 | }
|
1505 | const view = this.views[index];
|
1506 | view.data = data;
|
1507 | const event = {
|
1508 | type: 'DATA_CHANGED',
|
1509 | view: view,
|
1510 | data,
|
1511 | index: view.index,
|
1512 | time: new Date(),
|
1513 | };
|
1514 | this._inform(event);
|
1515 | }
|
1516 | changeData(view, data) {
|
1517 | const index = this.views.indexOf(view);
|
1518 | if (index === -1) {
|
1519 | throw new ViewChannelViewNotFoundError('changeData');
|
1520 | }
|
1521 | this.changeDataByIndex(index, data);
|
1522 | }
|
1523 | _getIndexForPriority(priority) {
|
1524 | for (let view of this.views) {
|
1525 | const largestArray = priority.length > view.priority.length ? priority : view.priority;
|
1526 | for (let level = 0; level < largestArray.length; level++) {
|
1527 | const inserted = this._getPriorityAtLevel(priority, level);
|
1528 | const existing = this._getPriorityAtLevel(view.priority, level);
|
1529 | if (inserted < existing) {
|
1530 | return view.index;
|
1531 | }
|
1532 | }
|
1533 | }
|
1534 | return this.views.length;
|
1535 | }
|
1536 | _getPriorityAtLevel(priorityArray, level) {
|
1537 | const priority = priorityArray[level];
|
1538 | if (priority !== undefined) {
|
1539 | return priority;
|
1540 | }
|
1541 | else {
|
1542 | return 0;
|
1543 | }
|
1544 | }
|
1545 | _repairIndexes() {
|
1546 | this.views.forEach((view, index) => {
|
1547 | view.index = index;
|
1548 | });
|
1549 | }
|
1550 | _clearViews() {
|
1551 | this.views.length = 0;
|
1552 | }
|
1553 | _inform(event) {
|
1554 | this._history._push(event);
|
1555 | this._observer._inform(this, event);
|
1556 | }
|
1557 | }
|
1558 |
|
1559 | function createViewChannelSubscriber(config) {
|
1560 | return (viewChannel, event) => {
|
1561 | _callSubscriber('createViewChannelSubscriber', event, viewChannel, config);
|
1562 | };
|
1563 | }
|
1564 |
|
1565 | class TypewriterCursor {
|
1566 | constructor(typewriter, position, data, selection) {
|
1567 | this.isBlinking = true;
|
1568 | this._blinkTimeoutId = null;
|
1569 | this._typewriter = typewriter;
|
1570 | this.position = position;
|
1571 | this.selection = selection;
|
1572 | this.data = data;
|
1573 | }
|
1574 | _startBlink() {
|
1575 | if (this.isBlinking) {
|
1576 | return;
|
1577 | }
|
1578 | this._clearBlink();
|
1579 | this._blinkTimeoutId = window.setTimeout(() => {
|
1580 | this.isBlinking = true;
|
1581 | const event = {
|
1582 | type: 'BLINKING',
|
1583 | time: new Date(),
|
1584 | cursor: this,
|
1585 | };
|
1586 | this._typewriter._inform(event);
|
1587 | }, this._typewriter.blinkAfter);
|
1588 | }
|
1589 | _clearBlink() {
|
1590 | if (this._blinkTimeoutId) {
|
1591 | window.clearTimeout(this._blinkTimeoutId);
|
1592 | this._blinkTimeoutId = null;
|
1593 | }
|
1594 | }
|
1595 | }
|
1596 |
|
1597 | const name = 'Typewriter';
|
1598 | const common$1 = `uiloos > ${name} >`;
|
1599 |
|
1600 | class TypewriterBlinkAfterError extends Error {
|
1601 | constructor() {
|
1602 | super(`${common$1} blinkAfter cannot be negative or zero`);
|
1603 | this.name = `${name}BlinkAfterError`;
|
1604 | }
|
1605 | }
|
1606 |
|
1607 | class TypewriterDelayError extends Error {
|
1608 | constructor() {
|
1609 | super(`${common$1} delay cannot be negative or zero`);
|
1610 | this.name = `${name}DelayError`;
|
1611 | }
|
1612 | }
|
1613 |
|
1614 | class TypewriterRepeatError extends Error {
|
1615 | constructor() {
|
1616 | super(`${common$1} repeat cannot be negative or zero`);
|
1617 | this.name = `${name}RepeatError`;
|
1618 | }
|
1619 | }
|
1620 |
|
1621 | class TypewriterRepeatDelayError extends Error {
|
1622 | constructor() {
|
1623 | super(`${common$1} repeatDelay cannot be a negative number`);
|
1624 | this.name = `${name}RepeatDelayError`;
|
1625 | }
|
1626 | }
|
1627 |
|
1628 | class TypewriterCursorOutOfBoundsError extends Error {
|
1629 | constructor() {
|
1630 | super(`${common$1} cursor is out of bounds`);
|
1631 | this.name = `${name}CursorOutOfBoundsError`;
|
1632 | }
|
1633 | }
|
1634 |
|
1635 | class TypewriterCursorNotAtSelectionEdgeError extends Error {
|
1636 | constructor() {
|
1637 | super(`${common$1} cursor is not placed on edges of selection`);
|
1638 | this.name = `${name}CursorNotAtSelectionEdgeError`;
|
1639 | }
|
1640 | }
|
1641 |
|
1642 | class TypewriterCursorSelectionInvalidRangeError extends Error {
|
1643 | constructor() {
|
1644 | super(`${common$1} cursors selection has an invalid range: start is equal or larger than the end`);
|
1645 | this.name = `${name}CursorSelectionInvalidRangeError`;
|
1646 | }
|
1647 | }
|
1648 |
|
1649 | class TypewriterCursorSelectionOutOfBoundsError extends Error {
|
1650 | constructor(name) {
|
1651 | super(`${common$1} cursor selection ${name} is out of bounds`);
|
1652 | this.name = `${name}InvalidCursorSelectionOutOfBoundsError`;
|
1653 | }
|
1654 | }
|
1655 |
|
1656 | class TypewriterActionUnknownCursorError extends Error {
|
1657 | constructor() {
|
1658 | super(`${common$1} action uses an unknown cursor`);
|
1659 | this.name = `${name}ActionUnknownCursorError`;
|
1660 | }
|
1661 | }
|
1662 |
|
1663 | class Typewriter {
|
1664 | constructor(config = {}, subscriber) {
|
1665 | this.cursors = [];
|
1666 | this._originalCursors = [];
|
1667 | this.actions = [];
|
1668 | this.lastPerformedAction = null;
|
1669 | this.text = '';
|
1670 | this._originalText = '';
|
1671 | this.blinkAfter = 250;
|
1672 | this.isPlaying = false;
|
1673 | this._stopped = false;
|
1674 | this.isFinished = false;
|
1675 | this.repeat = false;
|
1676 | this.repeatDelay = 0;
|
1677 | this._repeated = 0;
|
1678 | this.hasBeenStoppedBefore = false;
|
1679 | this._index = 0;
|
1680 | this._animationTimeoutId = null;
|
1681 | this._tickStarted = new Date();
|
1682 | this._pauseStarted = null;
|
1683 | this._history = new _History();
|
1684 | this.history = this._history._events;
|
1685 | this._observer = new _Observer();
|
1686 | licenseChecker._checkLicense();
|
1687 | if (subscriber) {
|
1688 | this.subscribe(subscriber);
|
1689 | }
|
1690 | this.initialize(config);
|
1691 | }
|
1692 | initialize(config) {
|
1693 | this._clearAnimation();
|
1694 | this.cursors.forEach((c) => {
|
1695 | c._clearBlink();
|
1696 | });
|
1697 | this.actions.length = 0;
|
1698 | this.cursors.length = 0;
|
1699 | this._history._events.length = 0;
|
1700 | this._history._setKeepHistoryFor(config.keepHistoryFor);
|
1701 | this.text = config.text !== undefined ? config.text : '';
|
1702 | this._originalText = this.text;
|
1703 | const textLength = Array.from(this.text).length;
|
1704 | this._originalCursors.length = 0;
|
1705 | if (config.cursors) {
|
1706 | config.cursors.forEach((cursor) => {
|
1707 | const position = cursor.position;
|
1708 | if (position < 0 || position > textLength) {
|
1709 | throw new TypewriterCursorOutOfBoundsError();
|
1710 | }
|
1711 | const selection = cursor.selection;
|
1712 | if (selection) {
|
1713 | const { start, end } = selection;
|
1714 | if (position !== start && position !== end) {
|
1715 | throw new TypewriterCursorNotAtSelectionEdgeError();
|
1716 | }
|
1717 | if (start < 0 || start > textLength) {
|
1718 | throw new TypewriterCursorSelectionOutOfBoundsError(_START);
|
1719 | }
|
1720 | if (end < 0 || end > textLength) {
|
1721 | throw new TypewriterCursorSelectionOutOfBoundsError(_END);
|
1722 | }
|
1723 | if (start >= end) {
|
1724 | throw new TypewriterCursorSelectionInvalidRangeError();
|
1725 | }
|
1726 | }
|
1727 | this._originalCursors.push({
|
1728 | position: cursor.position,
|
1729 | data: cursor.data,
|
1730 | selection: selection
|
1731 | ? {
|
1732 | start: selection.start,
|
1733 | end: selection.end,
|
1734 | }
|
1735 | : undefined,
|
1736 | });
|
1737 | this.cursors.push(new TypewriterCursor(this, cursor.position, cursor.data ? cursor.data : undefined, selection));
|
1738 | });
|
1739 | }
|
1740 | else {
|
1741 | this.cursors.push(new TypewriterCursor(this, textLength, undefined, undefined));
|
1742 | this._originalCursors.push({ data: undefined, position: textLength });
|
1743 | }
|
1744 | if (config.actions) {
|
1745 | for (let i = 0; i < config.actions.length; i++) {
|
1746 | const action = config.actions[i];
|
1747 | if (action.delay <= 0) {
|
1748 | throw new TypewriterDelayError();
|
1749 | }
|
1750 | if (this.cursors[action.cursor] === undefined) {
|
1751 | throw new TypewriterActionUnknownCursorError();
|
1752 | }
|
1753 | this.actions.push(action);
|
1754 | }
|
1755 | }
|
1756 | this._index = 0;
|
1757 | this.isPlaying =
|
1758 | (config.autoPlay === true || config.autoPlay === undefined) &&
|
1759 | this.actions.length > 0;
|
1760 | this.isFinished = false;
|
1761 | this.blinkAfter = config.blinkAfter !== undefined ? config.blinkAfter : 250;
|
1762 | if (this.blinkAfter <= 0) {
|
1763 | throw new TypewriterBlinkAfterError();
|
1764 | }
|
1765 | this._repeated = 0;
|
1766 | this.repeat = config.repeat !== undefined ? config.repeat : false;
|
1767 | if (typeof this.repeat === 'number' && this.repeat <= 0) {
|
1768 | throw new TypewriterRepeatError();
|
1769 | }
|
1770 | this.repeatDelay =
|
1771 | config.repeatDelay !== undefined ? config.repeatDelay : 0;
|
1772 | if (this.repeatDelay < 0) {
|
1773 | throw new TypewriterRepeatDelayError();
|
1774 | }
|
1775 | this.hasBeenStoppedBefore = false;
|
1776 | this._pauseStarted = null;
|
1777 | if (this.isPlaying) {
|
1778 | this._tick();
|
1779 | }
|
1780 | const event = {
|
1781 | type: 'INITIALIZED',
|
1782 | time: new Date(),
|
1783 | };
|
1784 | this._inform(event);
|
1785 | }
|
1786 | subscribe(subscriber) {
|
1787 | return this._observer._subscribe(subscriber);
|
1788 | }
|
1789 | unsubscribe(subscriber) {
|
1790 | this._observer._unsubscribe(subscriber);
|
1791 | }
|
1792 | unsubscribeAll() {
|
1793 | this._observer._clear();
|
1794 | }
|
1795 | play() {
|
1796 | if (this.isFinished || this._stopped) {
|
1797 | this._init();
|
1798 | this._stopped = false;
|
1799 | this.hasBeenStoppedBefore = false;
|
1800 | this._resetTandC();
|
1801 | }
|
1802 | else if (this.isPlaying || this.actions.length === 0) {
|
1803 | return;
|
1804 | }
|
1805 | this.isPlaying = true;
|
1806 | this._tick();
|
1807 | const event = {
|
1808 | type: 'PLAYING',
|
1809 | time: new Date(),
|
1810 | };
|
1811 | this._inform(event);
|
1812 | }
|
1813 | pause() {
|
1814 | if (!this.isPlaying) {
|
1815 | return;
|
1816 | }
|
1817 | this._clearAnimation();
|
1818 | this.isPlaying = false;
|
1819 | this._pauseStarted = new Date();
|
1820 | this.cursors.forEach((c) => c._startBlink());
|
1821 | const event = {
|
1822 | type: 'PAUSED',
|
1823 | time: new Date(),
|
1824 | };
|
1825 | this._inform(event);
|
1826 | }
|
1827 | stop() {
|
1828 | if (this.isFinished || (!this.isPlaying && !this._pauseStarted)) {
|
1829 | return;
|
1830 | }
|
1831 | this._clearAnimation();
|
1832 | this.isPlaying = false;
|
1833 | this.hasBeenStoppedBefore = true;
|
1834 | this._stopped = true;
|
1835 | this._init();
|
1836 | const event = {
|
1837 | type: 'STOPPED',
|
1838 | time: new Date(),
|
1839 | };
|
1840 | this._inform(event);
|
1841 | }
|
1842 | _init() {
|
1843 | this.isFinished = false;
|
1844 | this._index = 0;
|
1845 | this._pauseStarted = null;
|
1846 | this._repeated = 0;
|
1847 | this.cursors.forEach((c) => (c.isBlinking = true));
|
1848 | }
|
1849 | _tick() {
|
1850 | const action = this.actions[this._index];
|
1851 | const cursor = this.cursors[action.cursor];
|
1852 | let delay = action.delay;
|
1853 | if (this._pauseStarted) {
|
1854 | delay -= this._pauseStarted.getTime() - this._tickStarted.getTime();
|
1855 | this._pauseStarted = null;
|
1856 | }
|
1857 | this._tickStarted = new Date();
|
1858 | this._animationTimeoutId = window.setTimeout(() => {
|
1859 | var _a, _b;
|
1860 | const textArray = Array.from(this.text);
|
1861 | cursor.isBlinking = false;
|
1862 | cursor._startBlink();
|
1863 | let noOp = false;
|
1864 | if (action.type !== 'mouse') {
|
1865 | if (action.text === '⎚') {
|
1866 | if (this.text === '') {
|
1867 | noOp = true;
|
1868 | }
|
1869 | else {
|
1870 | this.text = '';
|
1871 | this.cursors.forEach((c) => {
|
1872 | c.position = 0;
|
1873 | c.selection = undefined;
|
1874 | });
|
1875 | }
|
1876 | }
|
1877 | else if (action.text === '←') {
|
1878 | noOp = this._actionLorR(cursor, -1, ((_a = cursor.selection) === null || _a === void 0 ? void 0 : _a.start) || 0, 0);
|
1879 | }
|
1880 | else if (action.text === '→') {
|
1881 | noOp = this._actionLorR(cursor, 1, ((_b = cursor.selection) === null || _b === void 0 ? void 0 : _b.end) || 0, textArray.length);
|
1882 | }
|
1883 | else if (action.text === '⇧←') {
|
1884 | noOp = this._actionSLorR(cursor, -1, _START, 0);
|
1885 | }
|
1886 | else if (action.text === '⇧→') {
|
1887 | noOp = this._actionSLorR(cursor, 1, _END, textArray.length);
|
1888 | }
|
1889 | else if (action.text === '⌫') {
|
1890 | const removed = {
|
1891 | start: -1,
|
1892 | end: -1,
|
1893 | no: -1,
|
1894 | };
|
1895 | if (cursor.selection) {
|
1896 | const start = cursor.selection.start;
|
1897 | const end = cursor.selection.end;
|
1898 | const no = end - start;
|
1899 | textArray.splice(cursor.selection.start, no);
|
1900 | this.text = textArray.join('');
|
1901 | removed.start = start;
|
1902 | removed.end = end;
|
1903 | removed.no = no;
|
1904 | }
|
1905 | else {
|
1906 | const position = cursor.position;
|
1907 | if (position !== 0) {
|
1908 | textArray.splice(position - 1, 1);
|
1909 | this.text = textArray.join('');
|
1910 | removed.start = position - 1;
|
1911 | removed.end = position;
|
1912 | removed.no = 1;
|
1913 | }
|
1914 | else {
|
1915 | noOp = true;
|
1916 | }
|
1917 | }
|
1918 | cursor.selection = undefined;
|
1919 | if (!noOp) {
|
1920 | this.cursors.forEach((c) => {
|
1921 | const hasOverlap = this._overlap(c.selection, removed) > 0;
|
1922 | if (c.position > removed.start) {
|
1923 | if (c.selection &&
|
1924 | hasOverlap &&
|
1925 | removed.start < c.selection.start &&
|
1926 | c.position < removed.end) {
|
1927 | c.position = removed.start;
|
1928 | }
|
1929 | else {
|
1930 | c.position -= removed.no;
|
1931 | }
|
1932 | }
|
1933 | const selection = c.selection;
|
1934 | if (selection) {
|
1935 | if (hasOverlap) {
|
1936 | const overlap = this._overlap(selection, removed);
|
1937 | if (selection.start <= removed.start) {
|
1938 | selection.end -= overlap;
|
1939 | }
|
1940 | else {
|
1941 | selection.start -= overlap;
|
1942 | selection.end -= removed.no;
|
1943 | }
|
1944 | if (selection.start === selection.end) {
|
1945 | c.selection = undefined;
|
1946 | }
|
1947 | }
|
1948 | else if (removed.start <= selection.start &&
|
1949 | removed.end <= selection.start) {
|
1950 | selection.start -= removed.no;
|
1951 | selection.end -= removed.no;
|
1952 | }
|
1953 | }
|
1954 | });
|
1955 | }
|
1956 | }
|
1957 | else {
|
1958 | const text = Array.from(action.text);
|
1959 | if (cursor.selection) {
|
1960 | const start = cursor.selection.start;
|
1961 | const end = cursor.selection.end;
|
1962 | const no = end - start;
|
1963 | textArray.splice(cursor.selection.start, no);
|
1964 | cursor.position = start;
|
1965 | const removed = {
|
1966 | start,
|
1967 | end,
|
1968 | no,
|
1969 | };
|
1970 | textArray.splice(cursor.position, 0, ...text);
|
1971 | this.text = textArray.join('');
|
1972 | this.cursors.forEach((c) => {
|
1973 | if (cursor === c) {
|
1974 | return;
|
1975 | }
|
1976 | const removedNo = removed.no - text.length;
|
1977 | const selection = c.selection;
|
1978 | if (selection) {
|
1979 | if (selection.start >= removed.start &&
|
1980 | selection.end <= removed.end) {
|
1981 | c.selection = undefined;
|
1982 | c.position = removed.start;
|
1983 | }
|
1984 | else {
|
1985 | const hasOverlap = this._overlap(selection, removed) > 0;
|
1986 | if (hasOverlap) {
|
1987 | const isPosStart = selection.start === c.position;
|
1988 | const overlap = this._overlap(selection, removed);
|
1989 | if (selection.start > removed.start) {
|
1990 | selection.start -= removed.no - overlap;
|
1991 | selection.start = Math.max(0, selection.start);
|
1992 | }
|
1993 | if (selection.end === removed.end) {
|
1994 | selection.end -= removed.no;
|
1995 | }
|
1996 | else if (selection.end === removed.end - 1) {
|
1997 | selection.end -= removed.no - 1;
|
1998 | }
|
1999 | else if (selection.end !== removed.start) {
|
2000 | selection.end -= removed.no - text.length;
|
2001 | }
|
2002 | c.position = isPosStart ? selection.start : selection.end;
|
2003 | }
|
2004 | else if (removed.start <= selection.start &&
|
2005 | removed.end <= selection.start) {
|
2006 | const isPosStart = selection.start === c.position;
|
2007 | const leftMost = Math.min(selection.start, selection.end);
|
2008 | if (removed.end === leftMost) {
|
2009 | selection.start = removed.start;
|
2010 | }
|
2011 | else {
|
2012 | selection.start -= removedNo;
|
2013 | }
|
2014 | selection.end -= removedNo;
|
2015 | selection.start = Math.max(0, selection.start);
|
2016 | c.position = isPosStart ? selection.start : selection.end;
|
2017 | }
|
2018 | }
|
2019 | }
|
2020 | else {
|
2021 | if (c.position >= removed.start && c.position <= removed.end) {
|
2022 | c.position = removed.start;
|
2023 | }
|
2024 | else if (c.position > removed.end) {
|
2025 | c.position -= removedNo;
|
2026 | }
|
2027 | }
|
2028 | });
|
2029 | cursor.position += text.length;
|
2030 | }
|
2031 | else {
|
2032 | textArray.splice(cursor.position, 0, ...text);
|
2033 | this.text = textArray.join('');
|
2034 | this.cursors.forEach((c) => {
|
2035 | if (cursor === c) {
|
2036 | return;
|
2037 | }
|
2038 | const selection = c.selection;
|
2039 | if (selection) {
|
2040 | if (cursor.position < selection.start) {
|
2041 | selection.start += text.length;
|
2042 | selection.end += text.length;
|
2043 | }
|
2044 | else if (cursor.position < selection.end) {
|
2045 | selection.end += text.length;
|
2046 | }
|
2047 | }
|
2048 | if (cursor.position < c.position) {
|
2049 | c.position += text.length;
|
2050 | }
|
2051 | });
|
2052 | cursor.position += text.length;
|
2053 | }
|
2054 | cursor.selection = undefined;
|
2055 | }
|
2056 | }
|
2057 | else {
|
2058 | const position = Math.min(textArray.length, Math.max(0, action.position));
|
2059 | if (cursor.position === position &&
|
2060 | this._same(cursor.selection, action.selection)) {
|
2061 | noOp = true;
|
2062 | }
|
2063 | else {
|
2064 | cursor.position = position;
|
2065 | if (action.selection) {
|
2066 | cursor.selection = {
|
2067 | start: action.selection.start,
|
2068 | end: action.selection.end,
|
2069 | };
|
2070 | }
|
2071 | else {
|
2072 | cursor.selection = undefined;
|
2073 | }
|
2074 | }
|
2075 | }
|
2076 | this._index += 1;
|
2077 | if (this._index >= this.actions.length) {
|
2078 | if (this.repeat === false || this.repeat === this._repeated + 1) {
|
2079 | this.isFinished = true;
|
2080 | this.isPlaying = false;
|
2081 | const event = {
|
2082 | type: 'FINISHED',
|
2083 | action,
|
2084 | time: new Date(),
|
2085 | cursor,
|
2086 | };
|
2087 | this.lastPerformedAction = action;
|
2088 | this._inform(event);
|
2089 | }
|
2090 | else {
|
2091 | this._repeated += 1;
|
2092 | this._change(noOp, action, cursor);
|
2093 | this._animationTimeoutId = window.setTimeout(() => {
|
2094 | this._index = 0;
|
2095 | this._resetTandC();
|
2096 | this.cursors.forEach((c) => {
|
2097 | c._clearBlink();
|
2098 | c.isBlinking = true;
|
2099 | });
|
2100 | const event = {
|
2101 | type: 'REPEATING',
|
2102 | time: new Date(),
|
2103 | cursor,
|
2104 | };
|
2105 | this._inform(event);
|
2106 | this._tick();
|
2107 | }, this.repeatDelay);
|
2108 | }
|
2109 | }
|
2110 | else {
|
2111 | this._change(noOp, action, cursor);
|
2112 | this._tick();
|
2113 | }
|
2114 | }, delay);
|
2115 | }
|
2116 | _clearAnimation() {
|
2117 | if (this._animationTimeoutId) {
|
2118 | window.clearTimeout(this._animationTimeoutId);
|
2119 | this._animationTimeoutId = null;
|
2120 | return;
|
2121 | }
|
2122 | }
|
2123 | _resetTandC() {
|
2124 | this.text = this._originalText;
|
2125 | this._originalCursors.forEach((copy, index) => {
|
2126 | const cursor = this.cursors[index];
|
2127 | cursor.data = copy.data ? copy.data : undefined;
|
2128 | cursor.position = copy.position;
|
2129 | const selection = copy.selection;
|
2130 | if (selection) {
|
2131 | cursor.selection = {
|
2132 | start: selection.start,
|
2133 | end: selection.end,
|
2134 | };
|
2135 | }
|
2136 | else {
|
2137 | cursor.selection = undefined;
|
2138 | }
|
2139 | });
|
2140 | }
|
2141 | _overlap(s, r) {
|
2142 | if (!s) {
|
2143 | return 0;
|
2144 | }
|
2145 | return Math.min(s.end, r.end) - Math.max(s.start, r.start);
|
2146 | }
|
2147 | _same(a, b) {
|
2148 | if (a === b) {
|
2149 | return true;
|
2150 | }
|
2151 | if (a && b) {
|
2152 | return a.start === b.start && a.end === b.end;
|
2153 | }
|
2154 | else {
|
2155 | return false;
|
2156 | }
|
2157 | }
|
2158 | _actionLorR(cursor, mod, select, stop) {
|
2159 | if (cursor.position === stop) {
|
2160 | if (cursor.selection === undefined) {
|
2161 | return true;
|
2162 | }
|
2163 | }
|
2164 | else {
|
2165 | if (cursor.selection) {
|
2166 | cursor.position = select;
|
2167 | }
|
2168 | else {
|
2169 | cursor.position += mod;
|
2170 | }
|
2171 | }
|
2172 | cursor.selection = undefined;
|
2173 | return false;
|
2174 | }
|
2175 | _actionSLorR(cursor, mod, which, stop) {
|
2176 | if (cursor.position === stop) {
|
2177 | return true;
|
2178 | }
|
2179 | else {
|
2180 | cursor.position += mod;
|
2181 | const selection = cursor.selection;
|
2182 | if (selection) {
|
2183 | selection[which] += mod;
|
2184 | }
|
2185 | else {
|
2186 | const selection = { start: -1, end: -1 };
|
2187 | selection[which === _START ? _END : _START] = cursor.position - mod;
|
2188 | selection[which] = cursor.position;
|
2189 | cursor.selection = selection;
|
2190 | }
|
2191 | }
|
2192 | return false;
|
2193 | }
|
2194 | _change(noOp, action, cursor) {
|
2195 | if (noOp) {
|
2196 | return;
|
2197 | }
|
2198 | const event = {
|
2199 | type: 'CHANGED',
|
2200 | action,
|
2201 | time: new Date(),
|
2202 | cursor,
|
2203 | };
|
2204 | this.lastPerformedAction = action;
|
2205 | this._inform(event);
|
2206 | }
|
2207 | _inform(event) {
|
2208 | this._history._push(event);
|
2209 | this._observer._inform(this, event);
|
2210 | }
|
2211 | *[Symbol.iterator]() {
|
2212 | const text = Array.from(this.text);
|
2213 | const cursorMap = {};
|
2214 | this.cursors.forEach((c) => {
|
2215 | const pos = c.position;
|
2216 | if (cursorMap[pos]) {
|
2217 | cursorMap[pos].push(c);
|
2218 | }
|
2219 | else {
|
2220 | cursorMap[pos] = [c];
|
2221 | }
|
2222 | });
|
2223 | for (let i = 0; i < text.length; i++) {
|
2224 | const cursors = cursorMap[i];
|
2225 | yield {
|
2226 | position: i,
|
2227 | cursors: cursors ? cursors : [],
|
2228 | character: text[i],
|
2229 | selected: this.cursors.filter((c) => c.selection && i >= c.selection.start && i < c.selection.end),
|
2230 | };
|
2231 | }
|
2232 | const finalCursors = cursorMap[text.length];
|
2233 | if (finalCursors) {
|
2234 | yield {
|
2235 | position: text.length,
|
2236 | character: '',
|
2237 | cursors: finalCursors,
|
2238 | selected: [],
|
2239 | };
|
2240 | }
|
2241 | }
|
2242 | }
|
2243 | const _START = 'start';
|
2244 | const _END = 'end';
|
2245 |
|
2246 | function createTypewriterSubscriber(config) {
|
2247 | return (typewriter, event) => {
|
2248 | _callSubscriber('createTypewriterSubscriber', event, typewriter, config);
|
2249 | };
|
2250 | }
|
2251 |
|
2252 | const typewriterActionTypeBackspace = '⌫';
|
2253 |
|
2254 | function typewriterFromSentences(config, subscriber) {
|
2255 | const delay = config.delay === undefined ? 50 : config.delay;
|
2256 | const sentenceDelay = config.sentenceDelay === undefined ? 2000 : config.sentenceDelay;
|
2257 | const actions = [];
|
2258 | let text = config.text ? Array.from(config.text) : [];
|
2259 | let firstSentence = true;
|
2260 | for (let sentence of config.sentences) {
|
2261 | const sentenceArray = Array.from(sentence);
|
2262 | let charsInCommonFromStart = 0;
|
2263 | for (let i = 0; i < text.length; i++) {
|
2264 | const fromChar = text[i];
|
2265 | const toChar = sentenceArray[i];
|
2266 | if (toChar === fromChar) {
|
2267 | charsInCommonFromStart += 1;
|
2268 | }
|
2269 | else {
|
2270 | break;
|
2271 | }
|
2272 | }
|
2273 | const backspaces = text.length - charsInCommonFromStart;
|
2274 | text = text.slice(0, text.length - backspaces);
|
2275 | for (let i = 0; i < backspaces; i++) {
|
2276 | const actualDelay = !firstSentence && i === 0 ? sentenceDelay : delay;
|
2277 | actions.push({
|
2278 | type: _KEYBOARD,
|
2279 | text: typewriterActionTypeBackspace,
|
2280 | delay: actualDelay,
|
2281 | cursor: 0,
|
2282 | });
|
2283 | }
|
2284 | const missingChars = text.length > 0
|
2285 | ? sentenceArray.slice(charsInCommonFromStart)
|
2286 | : sentenceArray;
|
2287 | for (const missingChar of missingChars) {
|
2288 | actions.push({
|
2289 | type: _KEYBOARD,
|
2290 | text: missingChar,
|
2291 | delay,
|
2292 | cursor: 0,
|
2293 | });
|
2294 | }
|
2295 | text = text.concat(missingChars);
|
2296 | firstSentence = false;
|
2297 | }
|
2298 | return new Typewriter(Object.assign(Object.assign({ repeatDelay: sentenceDelay }, config), { actions }), subscriber);
|
2299 | }
|
2300 | const _KEYBOARD = 'keyboard';
|
2301 |
|
2302 | const DATE_GALLERY_MODES = [
|
2303 | 'day',
|
2304 | 'week',
|
2305 | 'month',
|
2306 | 'month-six-weeks',
|
2307 | 'month-pad-to-week',
|
2308 | 'year',
|
2309 | ];
|
2310 |
|
2311 | class DateGalleryDate {
|
2312 | constructor(dateGallery, date, events, isPadding, isSelected) {
|
2313 | this.canBeSelected = true;
|
2314 | this.dateGallery = dateGallery;
|
2315 | this.date = date;
|
2316 | this.events = events;
|
2317 | this.isPadding = isPadding;
|
2318 | this.isSelected = isSelected;
|
2319 | this.isToday = dateGallery._sameDay(new Date(), date);
|
2320 | this.hasEvents = events.length > 0;
|
2321 | this.hasEventsWithOverlap = this.events.some(e => e.isOverlapping);
|
2322 | if (dateGallery._canSelect) {
|
2323 | this.canBeSelected = dateGallery._canSelect(this);
|
2324 | }
|
2325 | }
|
2326 | select() {
|
2327 | this.dateGallery.selectDate(this.date);
|
2328 | }
|
2329 | deselect() {
|
2330 | this.dateGallery.deselectDate(this.date);
|
2331 | }
|
2332 | toggle() {
|
2333 | this.dateGallery.toggleDateSelection(this.date);
|
2334 | }
|
2335 | }
|
2336 |
|
2337 | function _hasOverlap(a, b) {
|
2338 | const earlier = a.startDate < b.startDate ? a : b;
|
2339 | const later = earlier === a ? b : a;
|
2340 | const laterStart = later.startDate.getTime();
|
2341 | const earlierStart = earlier.startDate.getTime();
|
2342 | const earlierEnd = earlier.endDate.getTime();
|
2343 | return laterStart >= earlierStart && laterStart < earlierEnd;
|
2344 | }
|
2345 |
|
2346 | class DateGalleryEvent {
|
2347 | constructor(dateGallery, data, startDate, endDate) {
|
2348 | this.overlappingEvents = [];
|
2349 | this.isOverlapping = false;
|
2350 | this.spansMultipleDays = false;
|
2351 | this.dateGallery = dateGallery;
|
2352 | this.data = data;
|
2353 | this.startDate = startDate;
|
2354 | this.endDate = endDate;
|
2355 | }
|
2356 | _recalculate() {
|
2357 | this.overlappingEvents.length = 0;
|
2358 | this.dateGallery.events.forEach((other) => {
|
2359 | if (other === this) {
|
2360 | return;
|
2361 | }
|
2362 | if (_hasOverlap(this, other)) {
|
2363 | this.overlappingEvents.push(other);
|
2364 | }
|
2365 | });
|
2366 | this.overlappingEvents.sort((a, b) => {
|
2367 | return a.startDate.getTime() - b.startDate.getTime();
|
2368 | });
|
2369 | this.spansMultipleDays = !this.dateGallery._sameDay(this.startDate, this.endDate);
|
2370 | this.isOverlapping = this.overlappingEvents.length > 0;
|
2371 | }
|
2372 | remove() {
|
2373 | this.dateGallery.removeEvent(this);
|
2374 | }
|
2375 | move(range) {
|
2376 | this.dateGallery.moveEvent(this, range);
|
2377 | }
|
2378 | changeData(data) {
|
2379 | this.dateGallery.changeEventData(this, data);
|
2380 | }
|
2381 | }
|
2382 |
|
2383 | const common = `uiloos > DateGallery >`;
|
2384 |
|
2385 | class DateGalleryEventInvalidRangeError extends Error {
|
2386 | constructor() {
|
2387 | super(`${common} invalid range, an events startDate lies after its endDate`);
|
2388 | this.name = 'DateGalleryEventInvalidRangeError';
|
2389 | }
|
2390 | }
|
2391 |
|
2392 | class DateGalleryEventNotFoundError extends Error {
|
2393 | constructor(method) {
|
2394 | super(`${common} ${method} > "DateGalleryEvent" not found in events array`);
|
2395 | this.name = 'DateGalleryEventNotFoundError';
|
2396 | }
|
2397 | }
|
2398 |
|
2399 | class DateGalleryFirstDayOfWeekError extends Error {
|
2400 | constructor() {
|
2401 | super(`${common} invalid firstDayOfWeek`);
|
2402 | this.name = 'DateGalleryFirstDayOfWeekError';
|
2403 | }
|
2404 | }
|
2405 |
|
2406 | class DateGalleryInvalidDateError extends Error {
|
2407 | constructor(method, dateName) {
|
2408 | super(`${common} ${method} > "${dateName}" is an or contains an invalid date`);
|
2409 | this.name = 'DateGalleryInvalidDateError';
|
2410 | }
|
2411 | }
|
2412 |
|
2413 | class DateGalleryModeError extends Error {
|
2414 | constructor(mode) {
|
2415 | super(`${common} unknown mode: "${mode}" provided`);
|
2416 | this.name = 'DateGalleryModeError';
|
2417 | }
|
2418 | }
|
2419 |
|
2420 | class DateGalleryNumberOfFramesError extends Error {
|
2421 | constructor() {
|
2422 | super(`${common} numberOfFrames cannot be negative or zero`);
|
2423 | this.name = 'DateGalleryNumberOfFramesError';
|
2424 | }
|
2425 | }
|
2426 |
|
2427 | class DateGallerySelectionLimitReachedError extends Error {
|
2428 | constructor(method) {
|
2429 | super(`${common} ${method} > selection limit reached`);
|
2430 | this.name = 'DateGallerySelectionLimitReachedError';
|
2431 | }
|
2432 | }
|
2433 |
|
2434 | class DateGallery {
|
2435 | constructor(config = {}, subscriber) {
|
2436 | this._isInitializing = false;
|
2437 | this.isUTC = false;
|
2438 | this.frames = [];
|
2439 | this.firstFrame = {
|
2440 | dates: [],
|
2441 | events: [],
|
2442 | anchorDate: new Date(),
|
2443 | };
|
2444 | this.numberOfFrames = 1;
|
2445 | this.maxSelectionLimit = false;
|
2446 | this.maxSelectionLimitBehavior = 'circular';
|
2447 | this.selectedDates = [];
|
2448 | this._canSelect = undefined;
|
2449 | this.events = [];
|
2450 | this.mode = 'month-six-weeks';
|
2451 | this.firstDayOfWeek = 0;
|
2452 | this._anchorDate = new Date();
|
2453 | this._history = new _History();
|
2454 | this.history = this._history._events;
|
2455 | this._observer = new _Observer();
|
2456 | licenseChecker._checkLicense();
|
2457 | if (subscriber) {
|
2458 | this.subscribe(subscriber);
|
2459 | }
|
2460 | this._doInitialize(config, 'constructor');
|
2461 | }
|
2462 | subscribe(subscriber) {
|
2463 | return this._observer._subscribe(subscriber);
|
2464 | }
|
2465 | unsubscribe(subscriber) {
|
2466 | this._observer._unsubscribe(subscriber);
|
2467 | }
|
2468 | unsubscribeAll() {
|
2469 | this._observer._clear();
|
2470 | }
|
2471 | initialize(config) {
|
2472 | this._doInitialize(config, 'initialize');
|
2473 | }
|
2474 | _doInitialize(config, method) {
|
2475 | this._isInitializing = true;
|
2476 | this.isUTC = config.isUTC !== undefined ? config.isUTC : false;
|
2477 | this.mode = config.mode ? config.mode : 'month-six-weeks';
|
2478 | this._checkMode(this.mode);
|
2479 | this.firstDayOfWeek = config.firstDayOfWeek ? config.firstDayOfWeek : 0;
|
2480 | if (this.firstDayOfWeek < 0 || this.firstDayOfWeek > 6) {
|
2481 | throw new DateGalleryFirstDayOfWeekError();
|
2482 | }
|
2483 | this.numberOfFrames =
|
2484 | config.numberOfFrames !== undefined ? config.numberOfFrames : 1;
|
2485 | if (this.numberOfFrames <= 0) {
|
2486 | throw new DateGalleryNumberOfFramesError();
|
2487 | }
|
2488 | this.maxSelectionLimit =
|
2489 | config.maxSelectionLimit !== undefined ? config.maxSelectionLimit : false;
|
2490 | this.maxSelectionLimitBehavior =
|
2491 | config.maxSelectionLimitBehavior !== undefined
|
2492 | ? config.maxSelectionLimitBehavior
|
2493 | : 'circular';
|
2494 | this._anchorDate = config.initialDate
|
2495 | ? this._toDate(config.initialDate, method, 'initialDate')
|
2496 | : new Date();
|
2497 | this._toMidnight(this._anchorDate);
|
2498 | this._dragAnchor();
|
2499 | this.events.length = 0;
|
2500 | this.selectedDates.length = 0;
|
2501 | this._canSelect = config.canSelect;
|
2502 | if (config.selectedDates) {
|
2503 | config.selectedDates.forEach((s) => {
|
2504 | this.selectDate(this._toDate(s, method, 'selectedDates'));
|
2505 | });
|
2506 | }
|
2507 | if (config.events) {
|
2508 | config.events.forEach((config) => {
|
2509 | this._doAddEvent(config, method);
|
2510 | });
|
2511 | this.events.forEach((e) => {
|
2512 | e._recalculate();
|
2513 | });
|
2514 | }
|
2515 | this._buildFrames();
|
2516 | this._history._events.length = 0;
|
2517 | this._history._setKeepHistoryFor(config.keepHistoryFor);
|
2518 | this._isInitializing = false;
|
2519 | const event = {
|
2520 | type: 'INITIALIZED',
|
2521 | time: new Date(),
|
2522 | };
|
2523 | this._inform(event);
|
2524 | }
|
2525 | changeConfig(config) {
|
2526 | if (config.initialDate === undefined &&
|
2527 | config.mode === undefined &&
|
2528 | config.numberOfFrames === undefined) {
|
2529 | return;
|
2530 | }
|
2531 | let changed = false;
|
2532 | let drag = false;
|
2533 | const method = 'changeConfig';
|
2534 | if (config.mode !== undefined) {
|
2535 | this._checkMode(config.mode);
|
2536 | if (this.mode !== config.mode) {
|
2537 | this.mode = config.mode;
|
2538 | changed = true;
|
2539 | drag = true;
|
2540 | }
|
2541 | }
|
2542 | if (config.initialDate !== undefined) {
|
2543 | const date = this._toDate(config.initialDate, method, 'initialDate');
|
2544 | this._toMidnight(date);
|
2545 | if (!this._sameDay(date, this._anchorDate)) {
|
2546 | this._anchorDate = date;
|
2547 | changed = true;
|
2548 | drag = true;
|
2549 | }
|
2550 | }
|
2551 | if (config.numberOfFrames !== undefined) {
|
2552 | if (config.numberOfFrames <= 0) {
|
2553 | throw new DateGalleryNumberOfFramesError();
|
2554 | }
|
2555 | if (this.numberOfFrames !== config.numberOfFrames) {
|
2556 | this.numberOfFrames = config.numberOfFrames;
|
2557 | changed = true;
|
2558 | }
|
2559 | }
|
2560 | if (changed) {
|
2561 | if (drag) {
|
2562 | this._dragAnchor();
|
2563 | }
|
2564 | this._buildFrames();
|
2565 | const event = {
|
2566 | type: 'CONFIG_CHANGED',
|
2567 | mode: this.mode,
|
2568 | anchorDate: new Date(this._anchorDate),
|
2569 | numberOfFrames: this.numberOfFrames,
|
2570 | frames: this.frames,
|
2571 | time: new Date(),
|
2572 | };
|
2573 | this._inform(event);
|
2574 | }
|
2575 | }
|
2576 | today() {
|
2577 | this.changeConfig({
|
2578 | initialDate: new Date(),
|
2579 | });
|
2580 | }
|
2581 | _buildFrames(inform = false) {
|
2582 | this.frames.length = 0;
|
2583 | const anchorAtStart = this._anchorDate;
|
2584 | for (let i = 0; i < this.numberOfFrames; i++) {
|
2585 | if (i !== 0) {
|
2586 | this._moveFrame(1);
|
2587 | }
|
2588 | const frame = {
|
2589 | dates: [],
|
2590 | events: [],
|
2591 | anchorDate: new Date(this._anchorDate),
|
2592 | };
|
2593 | const anchor = new Date(this._anchorDate);
|
2594 | if (this.mode === 'day') {
|
2595 | frame.dates.push(this._makeDate(anchor));
|
2596 | }
|
2597 | else if (this.mode === 'week') {
|
2598 | this._addNoDates(anchor, 7, frame);
|
2599 | }
|
2600 | else if (this.mode === 'year') {
|
2601 | const year = this._getFullYear(anchor);
|
2602 | const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
2603 | this._addNoDates(anchor, isLeapYear ? 366 : 365, frame);
|
2604 | }
|
2605 | else if (this.mode === 'month') {
|
2606 | const anchorMonth = this._getMonth(anchor);
|
2607 | this._addMonth(anchor, anchorMonth, frame);
|
2608 | }
|
2609 | else if (this.mode === 'month-pad-to-week') {
|
2610 | const date = this._firstDayOfWeek(anchor);
|
2611 | const anchorMonth = this._getMonth(anchor);
|
2612 | while (this._getMonth(date) !== anchorMonth) {
|
2613 | this._pushDay(date, frame);
|
2614 | }
|
2615 | this._addMonth(date, anchorMonth, frame);
|
2616 | while (this._getDay(date) !== this.firstDayOfWeek) {
|
2617 | this._pushDay(date, frame);
|
2618 | }
|
2619 | }
|
2620 | else if (this.mode === 'month-six-weeks') {
|
2621 | const date = this._firstDayOfWeek(anchor);
|
2622 | this._addNoDates(date, 42, frame);
|
2623 | }
|
2624 | this.frames.push(frame);
|
2625 | const startDate = new Date(frame.dates[0].date);
|
2626 | const endDate = new Date(frame.dates[frame.dates.length - 1].date);
|
2627 | this._toMidnight(startDate);
|
2628 | this._moveDateBy(endDate, 1);
|
2629 | this._toMidnight(endDate);
|
2630 | this.events.forEach((event) => {
|
2631 | if (_hasOverlap({ startDate, endDate }, event)) {
|
2632 | frame.events.push(event);
|
2633 | }
|
2634 | });
|
2635 | }
|
2636 | this._anchorDate = anchorAtStart;
|
2637 | this.firstFrame = this.frames[0];
|
2638 | if (inform) {
|
2639 | const event = {
|
2640 | type: 'FRAME_CHANGED',
|
2641 | frames: this.frames,
|
2642 | time: new Date(),
|
2643 | };
|
2644 | this._inform(event);
|
2645 | }
|
2646 | }
|
2647 | next() {
|
2648 | this._moveFrame(this.numberOfFrames);
|
2649 | this._buildFrames(true);
|
2650 | }
|
2651 | previous() {
|
2652 | this._moveFrame(-this.numberOfFrames);
|
2653 | this._buildFrames(true);
|
2654 | }
|
2655 | _moveFrame(mod) {
|
2656 | const date = new Date(this._anchorDate);
|
2657 | if (this.mode === 'day') {
|
2658 | this._moveDateBy(date, 1 * mod);
|
2659 | }
|
2660 | else if (this.mode === 'week') {
|
2661 | this._moveDateBy(date, 7 * mod);
|
2662 | }
|
2663 | else if (this.mode === 'year') {
|
2664 | if (this.isUTC) {
|
2665 | date.setUTCFullYear(date.getUTCFullYear() + 1 * mod);
|
2666 | }
|
2667 | else {
|
2668 | date.setFullYear(date.getFullYear() + 1 * mod);
|
2669 | }
|
2670 | }
|
2671 | else {
|
2672 | if (this.isUTC) {
|
2673 | date.setUTCMonth(date.getUTCMonth() + 1 * mod);
|
2674 | }
|
2675 | else {
|
2676 | date.setMonth(date.getMonth() + 1 * mod);
|
2677 | }
|
2678 | }
|
2679 | this._anchorDate = date;
|
2680 | }
|
2681 | selectDate(date) {
|
2682 | const method = 'selectDate';
|
2683 | const _date = this._toDate(date, method, 'date');
|
2684 | const [index] = this._indexOfDate(_date, method);
|
2685 | if (index === -1) {
|
2686 | this._doSelectDate(_date, method);
|
2687 | }
|
2688 | }
|
2689 | _doSelectDate(date, method) {
|
2690 | const deselectedDates = [];
|
2691 | const midnight = this._pushSelectDate(date, method, deselectedDates);
|
2692 | if (!midnight) {
|
2693 | return;
|
2694 | }
|
2695 | this._buildFrames();
|
2696 | let deselectedDate = deselectedDates[0];
|
2697 | if (!deselectedDate) {
|
2698 | deselectedDate = null;
|
2699 | }
|
2700 | const event = {
|
2701 | type: 'DATE_SELECTED',
|
2702 | date: new Date(midnight),
|
2703 | deselectedDate,
|
2704 | time: new Date(),
|
2705 | };
|
2706 | this._inform(event);
|
2707 | }
|
2708 | _pushSelectDate(date, method, deselectedDates) {
|
2709 | const midnight = this._toDate(date, method, 'date');
|
2710 | this._toMidnight(midnight);
|
2711 | if (this._canSelect && !this._canSelect(this._makeDate(midnight))) {
|
2712 | return null;
|
2713 | }
|
2714 | const limitReached = this.maxSelectionLimit === false
|
2715 | ? false
|
2716 | : this.maxSelectionLimit === this.selectedDates.length;
|
2717 | if (limitReached) {
|
2718 | if (this.maxSelectionLimitBehavior === 'error') {
|
2719 | throw new DateGallerySelectionLimitReachedError(method);
|
2720 | }
|
2721 | else if (this.maxSelectionLimitBehavior === 'ignore') {
|
2722 | return null;
|
2723 | }
|
2724 | else {
|
2725 | const deselected = this.selectedDates.shift();
|
2726 | if (deselected) {
|
2727 | deselectedDates.push(deselected);
|
2728 | }
|
2729 | }
|
2730 | }
|
2731 | this.selectedDates.push(midnight);
|
2732 | return midnight;
|
2733 | }
|
2734 | deselectDate(date) {
|
2735 | const [index, _date] = this._indexOfDate(date, 'deselectDate');
|
2736 | if (index === -1) {
|
2737 | return;
|
2738 | }
|
2739 | this._doDeselectDate(index, _date);
|
2740 | }
|
2741 | _doDeselectDate(index, date) {
|
2742 | this.selectedDates.splice(index, 1);
|
2743 | this._buildFrames();
|
2744 | const event = {
|
2745 | type: 'DATE_DESELECTED',
|
2746 | date,
|
2747 | time: new Date(),
|
2748 | };
|
2749 | this._inform(event);
|
2750 | }
|
2751 | toggleDateSelection(date) {
|
2752 | const [index, _date] = this._indexOfDate(date, 'toggleDateSelection');
|
2753 | if (index === -1) {
|
2754 | this._doSelectDate(_date, 'toggleDateSelection');
|
2755 | }
|
2756 | else {
|
2757 | this._doDeselectDate(index, _date);
|
2758 | }
|
2759 | }
|
2760 | _indexOfDate(date, method) {
|
2761 | const _date = this._toDate(date, method, 'date');
|
2762 | const index = this.selectedDates.findIndex((s) => {
|
2763 | return this._sameDay(s, _date);
|
2764 | });
|
2765 | return [index, _date];
|
2766 | }
|
2767 | deselectAll() {
|
2768 | if (this.selectedDates.length === 0) {
|
2769 | return;
|
2770 | }
|
2771 | const dates = [...this.selectedDates];
|
2772 | this.selectedDates.length = 0;
|
2773 | this._buildFrames();
|
2774 | const e = {
|
2775 | type: 'DATE_DESELECTED_MULTIPLE',
|
2776 | dates,
|
2777 | time: new Date(),
|
2778 | };
|
2779 | this._inform(e);
|
2780 | }
|
2781 | selectRange(a, b) {
|
2782 | const method = 'selectRange';
|
2783 | const aDate = this._toDate(a, method, 'a');
|
2784 | const bDate = this._toDate(b, method, 'b');
|
2785 | const startDate = bDate.getTime() > aDate.getTime() ? aDate : bDate;
|
2786 | const endDate = aDate === startDate ? bDate : aDate;
|
2787 | this._toMidnight(startDate);
|
2788 | this._moveDateBy(endDate, 1);
|
2789 | this._toMidnight(endDate);
|
2790 | const date = new Date(startDate);
|
2791 | const oldSelected = [...this.selectedDates];
|
2792 | const selectedCollector = [];
|
2793 | const deselectedCollector = [];
|
2794 | let error = null;
|
2795 | try {
|
2796 | while (!this._sameDay(date, endDate)) {
|
2797 | const index = this.selectedDates.findIndex((s) => {
|
2798 | return this._sameDay(s, date);
|
2799 | });
|
2800 | if (index === -1) {
|
2801 | const midnight = this._pushSelectDate(date, method, deselectedCollector);
|
2802 | if (midnight) {
|
2803 | selectedCollector.push(midnight);
|
2804 | }
|
2805 | }
|
2806 | this._moveDateBy(date, 1);
|
2807 | }
|
2808 | }
|
2809 | catch (e) {
|
2810 | if (e instanceof DateGallerySelectionLimitReachedError) {
|
2811 | error = e;
|
2812 | }
|
2813 | }
|
2814 | const reportedSelectedDates = selectedCollector.filter((selectedDate) => !deselectedCollector.includes(selectedDate));
|
2815 | if (reportedSelectedDates.length === 0) {
|
2816 | if (error) {
|
2817 | throw error;
|
2818 | }
|
2819 | return;
|
2820 | }
|
2821 | const deselectedDates = oldSelected.filter((oldSelect) => !this.selectedDates.some((selectedDate) => this._sameDay(oldSelect, selectedDate)));
|
2822 | this._buildFrames();
|
2823 | const event = {
|
2824 | type: 'DATE_SELECTED_MULTIPLE',
|
2825 | dates: reportedSelectedDates.map((d) => new Date(d)),
|
2826 | deselectedDates: deselectedDates.map((d) => new Date(d)),
|
2827 | time: new Date(),
|
2828 | };
|
2829 | this._inform(event);
|
2830 | if (error) {
|
2831 | throw error;
|
2832 | }
|
2833 | }
|
2834 | addEvent(event) {
|
2835 | const addedEvent = this._doAddEvent(event, 'addEvent');
|
2836 | this.events.forEach((e) => {
|
2837 | e._recalculate();
|
2838 | });
|
2839 | this._buildFrames();
|
2840 | const e = {
|
2841 | type: 'EVENT_ADDED',
|
2842 | event: addedEvent,
|
2843 | time: new Date(),
|
2844 | };
|
2845 | this._inform(e);
|
2846 | return addedEvent;
|
2847 | }
|
2848 | _doAddEvent(config, method) {
|
2849 | const startDate = this._toDate(config.startDate, method, 'event.startDate');
|
2850 | const endDate = this._toDate(config.endDate, method, 'event.endDate');
|
2851 | if (startDate.getTime() > endDate.getTime()) {
|
2852 | throw new DateGalleryEventInvalidRangeError();
|
2853 | }
|
2854 | const event = new DateGalleryEvent(this, config.data, startDate, endDate);
|
2855 | this.events.push(event);
|
2856 | this.events.sort((a, b) => {
|
2857 | return a.startDate.getTime() - b.startDate.getTime();
|
2858 | });
|
2859 | return event;
|
2860 | }
|
2861 | removeEvent(event) {
|
2862 | const index = this.events.indexOf(event);
|
2863 | if (index === -1) {
|
2864 | return event;
|
2865 | }
|
2866 | this.events.splice(index, 1);
|
2867 | this.events.forEach((e) => {
|
2868 | e._recalculate();
|
2869 | });
|
2870 | this._buildFrames();
|
2871 | const e = {
|
2872 | type: 'EVENT_REMOVED',
|
2873 | event,
|
2874 | time: new Date(),
|
2875 | };
|
2876 | this._inform(e);
|
2877 | return event;
|
2878 | }
|
2879 | moveEvent(event, range) {
|
2880 | const startDate = this._toDate(range.startDate, 'moveEvent', 'range.startDate');
|
2881 | const endDate = this._toDate(range.endDate, 'moveEvent', 'range.endDate');
|
2882 | if (startDate.getTime() > endDate.getTime()) {
|
2883 | throw new DateGalleryEventInvalidRangeError();
|
2884 | }
|
2885 | if (startDate.getTime() === event.startDate.getTime() &&
|
2886 | endDate.getTime() === event.endDate.getTime()) {
|
2887 | return;
|
2888 | }
|
2889 | const index = this.events.indexOf(event);
|
2890 | if (index === -1) {
|
2891 | throw new DateGalleryEventNotFoundError('moveEvent');
|
2892 | }
|
2893 | event.startDate = startDate;
|
2894 | event.endDate = endDate;
|
2895 | this.events.sort((a, b) => {
|
2896 | return a.startDate.getTime() - b.startDate.getTime();
|
2897 | });
|
2898 | this.events.forEach((e) => {
|
2899 | e._recalculate();
|
2900 | });
|
2901 | this._buildFrames();
|
2902 | const e = {
|
2903 | type: 'EVENT_MOVED',
|
2904 | event,
|
2905 | time: new Date(),
|
2906 | };
|
2907 | this._inform(e);
|
2908 | }
|
2909 | changeEventData(event, data) {
|
2910 | const index = this.events.indexOf(event);
|
2911 | if (index === -1) {
|
2912 | throw new DateGalleryEventNotFoundError('changeEventData');
|
2913 | }
|
2914 | event.data = data;
|
2915 | const e = {
|
2916 | type: 'EVENT_DATA_CHANGED',
|
2917 | event,
|
2918 | data,
|
2919 | time: new Date(),
|
2920 | };
|
2921 | this._inform(e);
|
2922 | }
|
2923 | _dragAnchor() {
|
2924 | if (this.mode === 'year') {
|
2925 | if (this.isUTC) {
|
2926 | this._anchorDate.setUTCDate(1);
|
2927 | this._anchorDate.setUTCMonth(0);
|
2928 | }
|
2929 | else {
|
2930 | this._anchorDate.setDate(1);
|
2931 | this._anchorDate.setMonth(0);
|
2932 | }
|
2933 | }
|
2934 | else if (this.mode === 'week') {
|
2935 | this._anchorDate = this._firstDayOfWeek(this._anchorDate);
|
2936 | }
|
2937 | else if (this.mode.startsWith('month')) {
|
2938 | if (this.isUTC) {
|
2939 | this._anchorDate.setUTCDate(1);
|
2940 | }
|
2941 | else {
|
2942 | this._anchorDate.setDate(1);
|
2943 | }
|
2944 | }
|
2945 | }
|
2946 | _inform(event) {
|
2947 | if (this._isInitializing) {
|
2948 | return;
|
2949 | }
|
2950 | this._history._push(event);
|
2951 | this._observer._inform(this, event);
|
2952 | }
|
2953 | _toDate(date, method, dateName) {
|
2954 | if (date instanceof Date) {
|
2955 | this._checkDate(date, method, dateName);
|
2956 | }
|
2957 | const result = new Date(date);
|
2958 | this._checkDate(result, method, dateName);
|
2959 | return result;
|
2960 | }
|
2961 | _checkDate(date, method, dateName) {
|
2962 | const isValid = Object.prototype.toString.call(date) === '[object Date]' &&
|
2963 | !isNaN(date.valueOf());
|
2964 | if (!isValid) {
|
2965 | throw new DateGalleryInvalidDateError(method, dateName);
|
2966 | }
|
2967 | }
|
2968 | _firstDayOfWeek(date) {
|
2969 | const copy = new Date(date);
|
2970 | while (this._getDay(copy) !== this.firstDayOfWeek) {
|
2971 | this._moveDateBy(copy, -1);
|
2972 | }
|
2973 | return copy;
|
2974 | }
|
2975 | _addNoDates(date, amount, frame) {
|
2976 | for (let i = 0; i < amount; i++) {
|
2977 | this._pushDay(date, frame);
|
2978 | }
|
2979 | }
|
2980 | _addMonth(date, month, frame) {
|
2981 | while (this._getMonth(date) === month) {
|
2982 | this._pushDay(date, frame);
|
2983 | }
|
2984 | }
|
2985 | _pushDay(date, frame) {
|
2986 | frame.dates.push(this._makeDate(date));
|
2987 | this._moveDateBy(date, 1);
|
2988 | }
|
2989 | _makeDate(date) {
|
2990 | const _date = new Date(date);
|
2991 | this._toMidnight(_date);
|
2992 | let isPadding = false;
|
2993 | if (this.mode === 'month-pad-to-week' || this.mode === 'month-six-weeks') {
|
2994 | const anchorMonth = this._getMonth(this._anchorDate);
|
2995 | isPadding = this._getMonth(_date) !== anchorMonth;
|
2996 | }
|
2997 | return new DateGalleryDate(this, _date, this.events.filter((event) => {
|
2998 | const time = _date.getTime();
|
2999 | const startDate = new Date(event.startDate);
|
3000 | const start = this._toMidnight(startDate);
|
3001 | const endDate = new Date(event.endDate);
|
3002 | this._moveDateBy(endDate, 1);
|
3003 | const end = this._toMidnight(endDate);
|
3004 | return time >= start && time < end;
|
3005 | }), isPadding, this.selectedDates.some((selected) => {
|
3006 | return this._sameDay(selected, _date);
|
3007 | }));
|
3008 | }
|
3009 | isSameDay(a, b) {
|
3010 | const method = 'isSameDay';
|
3011 | return this._sameDay(this._toDate(a, method, 'a'), this._toDate(b, method, 'b'));
|
3012 | }
|
3013 | _sameDay(a, b) {
|
3014 | return (this._getFullYear(a) === this._getFullYear(b) &&
|
3015 | this._getMonth(a) === this._getMonth(b) &&
|
3016 | this._getDate(a) === this._getDate(b));
|
3017 | }
|
3018 | _getFullYear(date) {
|
3019 | return this.isUTC ? date.getUTCFullYear() : date.getFullYear();
|
3020 | }
|
3021 | _getMonth(date) {
|
3022 | return this.isUTC ? date.getUTCMonth() : date.getMonth();
|
3023 | }
|
3024 | _getDate(date) {
|
3025 | return this.isUTC ? date.getUTCDate() : date.getDate();
|
3026 | }
|
3027 | _getDay(date) {
|
3028 | return this.isUTC ? date.getUTCDay() : date.getDay();
|
3029 | }
|
3030 | _checkMode(mode) {
|
3031 | if (!DATE_GALLERY_MODES.includes(mode)) {
|
3032 | throw new DateGalleryModeError(mode);
|
3033 | }
|
3034 | }
|
3035 | _toMidnight(date) {
|
3036 | if (this.isUTC) {
|
3037 | return date.setUTCHours(0, 0, 0, 0);
|
3038 | }
|
3039 | else {
|
3040 | return date.setHours(0, 0, 0, 0);
|
3041 | }
|
3042 | }
|
3043 | _moveDateBy(date, mod) {
|
3044 | if (this.isUTC) {
|
3045 | date.setUTCDate(date.getUTCDate() + mod);
|
3046 | }
|
3047 | else {
|
3048 | date.setDate(date.getDate() + mod);
|
3049 | }
|
3050 | }
|
3051 | }
|
3052 |
|
3053 | function createDateGallerySubscriber(config) {
|
3054 | return (activeList, event) => {
|
3055 | _callSubscriber('createDateGallerySubscriber', event, activeList, config);
|
3056 | };
|
3057 | }
|
3058 |
|
3059 | export { ActiveList, ActiveListActivationLimitReachedError, ActiveListAutoPlayDurationError, ActiveListContent, ActiveListCooldownDurationError, ActiveListIndexOutOfBoundsError, ActiveListItemNotFoundError, DATE_GALLERY_MODES, DateGallery, DateGalleryDate, DateGalleryEvent, DateGalleryEventInvalidRangeError, DateGalleryEventNotFoundError, DateGalleryFirstDayOfWeekError, DateGalleryInvalidDateError, DateGalleryModeError, DateGalleryNumberOfFramesError, DateGallerySelectionLimitReachedError, Typewriter, TypewriterActionUnknownCursorError, TypewriterBlinkAfterError, TypewriterCursor, TypewriterCursorNotAtSelectionEdgeError, TypewriterCursorOutOfBoundsError, TypewriterCursorSelectionInvalidRangeError, TypewriterCursorSelectionOutOfBoundsError, TypewriterDelayError, TypewriterRepeatDelayError, TypewriterRepeatError, ViewChannel, ViewChannelAutoDismissDurationError, ViewChannelIndexOutOfBoundsError, ViewChannelView, ViewChannelViewNotFoundError, _LicenseChecker, createActiveListSubscriber, createDateGallerySubscriber, createTypewriterSubscriber, createViewChannelSubscriber, licenseChecker, typewriterFromSentences };
|
3060 |
|