UNPKG

@uiloos/core

Version:

The core of the uiloos headless UI

2 lines (1 loc) 10.5 kB
var uiloosTypewriter=function(t){"use strict";class s{constructor(){this.t=[],this.i=0}o(t){this.i>0&&(this.t.push(t),this.t.length-1===this.i&&this.t.shift())}h(t=0){this.i=t}}class i{constructor(){this.l=[]}u(t){return this.l.push(t),()=>{this.p(t)}}p(t){this.l=this.l.filter((s=>t!==s))}v(){this.l.length=0}$(t,s){this.l.forEach((i=>i(t,s)))}}class e{constructor(t,s,i,e){this.isBlinking=!0,this.m=null,this.D=t,this.position=s,this.selection=e,this.data=i}_(){this.isBlinking||(this.A(),this.m=window.setTimeout((()=>{this.isBlinking=!0;const t={type:"BLINKING",time:new Date,cursor:this};this.D.$(t)}),this.D.blinkAfter))}A(){this.m&&(window.clearTimeout(this.m),this.m=null)}}const r="Typewriter",o=`uiloos > ${r} >`;class h extends Error{constructor(){super(`${o} blinkAfter cannot be negative or zero`),this.name=`${r}BlinkAfterError`}}class n extends Error{constructor(){super(`${o} delay cannot be negative or zero`),this.name=`${r}DelayError`}}class c extends Error{constructor(){super(`${o} repeat cannot be negative or zero`),this.name=`${r}RepeatError`}}class a extends Error{constructor(){super(`${o} repeatDelay cannot be a negative number`),this.name=`${r}RepeatDelayError`}}class l extends Error{constructor(){super(`${o} cursor is out of bounds`),this.name=`${r}CursorOutOfBoundsError`}}class u extends Error{constructor(){super(`${o} cursor is not placed on edges of selection`),this.name=`${r}CursorNotAtSelectionEdgeError`}}class d extends Error{constructor(){super(`${o} cursors selection has an invalid range: start is equal or larger than the end`),this.name=`${r}CursorSelectionInvalidRangeError`}}class f extends Error{constructor(t){super(`${o} cursor selection ${t} is out of bounds`),this.name=`${t}InvalidCursorSelectionOutOfBoundsError`}}class w extends Error{constructor(){super(`${o} action uses an unknown cursor`),this.name=`${r}ActionUnknownCursorError`}}class p{constructor(t={},e){this.cursors=[],this.I=[],this.actions=[],this.lastPerformedAction=null,this.text="",this.g="",this.blinkAfter=250,this.isPlaying=!1,this.k=!1,this.isFinished=!1,this.repeat=!1,this.repeatDelay=0,this.S=0,this.hasBeenStoppedBefore=!1,this.C=0,this.N=null,this.M=new Date,this.O=null,this.T=new s,this.history=this.T.t,this.B=new i,uiloosLicenseChecker.licenseChecker._checkLicense(),e&&this.subscribe(e),this.initialize(t)}initialize(t){this.L(),this.cursors.forEach((t=>{t.A()})),this.actions.length=0,this.cursors.length=0,this.T.t.length=0,this.T.h(t.keepHistoryFor),this.text=void 0!==t.text?t.text:"",this.g=this.text;const s=Array.from(this.text).length;if(this.I.length=0,t.cursors?t.cursors.forEach((t=>{const i=t.position;if(i<0||i>s)throw new l;const r=t.selection;if(r){const{start:t,end:e}=r;if(i!==t&&i!==e)throw new u;if(t<0||t>s)throw new f(v);if(e<0||e>s)throw new f(y);if(t>=e)throw new d}this.I.push({position:t.position,data:t.data,selection:r?{start:r.start,end:r.end}:void 0}),this.cursors.push(new e(this,t.position,t.data?t.data:void 0,r))})):(this.cursors.push(new e(this,s,void 0,void 0)),this.I.push({data:void 0,position:s})),t.actions)for(let s=0;s<t.actions.length;s++){const i=t.actions[s];if(i.delay<=0)throw new n;if(void 0===this.cursors[i.cursor])throw new w;this.actions.push(i)}if(this.C=0,this.isPlaying=(!0===t.autoPlay||void 0===t.autoPlay)&&this.actions.length>0,this.isFinished=!1,this.blinkAfter=void 0!==t.blinkAfter?t.blinkAfter:250,this.blinkAfter<=0)throw new h;if(this.S=0,this.repeat=void 0!==t.repeat&&t.repeat,"number"==typeof this.repeat&&this.repeat<=0)throw new c;if(this.repeatDelay=void 0!==t.repeatDelay?t.repeatDelay:0,this.repeatDelay<0)throw new a;this.hasBeenStoppedBefore=!1,this.O=null,this.isPlaying&&this.R();const i={type:"INITIALIZED",time:new Date};this.$(i)}subscribe(t){return this.B.u(t)}unsubscribe(t){this.B.p(t)}unsubscribeAll(){this.B.v()}play(){if(this.isFinished||this.k)this.P(),this.k=!1,this.hasBeenStoppedBefore=!1,this.G();else if(this.isPlaying||0===this.actions.length)return;this.isPlaying=!0,this.R();const t={type:"PLAYING",time:new Date};this.$(t)}pause(){if(!this.isPlaying)return;this.L(),this.isPlaying=!1,this.O=new Date,this.cursors.forEach((t=>t._()));const t={type:"PAUSED",time:new Date};this.$(t)}stop(){if(this.isFinished||!this.isPlaying&&!this.O)return;this.L(),this.isPlaying=!1,this.hasBeenStoppedBefore=!0,this.k=!0,this.P();const t={type:"STOPPED",time:new Date};this.$(t)}P(){this.isFinished=!1,this.C=0,this.O=null,this.S=0,this.cursors.forEach((t=>t.isBlinking=!0))}R(){const t=this.actions[this.C],s=this.cursors[t.cursor];let i=t.delay;this.O&&(i-=this.O.getTime()-this.M.getTime(),this.O=null),this.M=new Date,this.N=window.setTimeout((()=>{var i,e;const r=Array.from(this.text);s.isBlinking=!1,s._();let o=!1;if("mouse"!==t.type)if("⎚"===t.text)""===this.text?o=!0:(this.text="",this.cursors.forEach((t=>{t.position=0,t.selection=void 0})));else if("←"===t.text)o=this.H(s,-1,(null===(i=s.selection)||void 0===i?void 0:i.start)||0,0);else if("→"===t.text)o=this.H(s,1,(null===(e=s.selection)||void 0===e?void 0:e.end)||0,r.length);else if("⇧←"===t.text)o=this.j(s,-1,v,0);else if("⇧→"===t.text)o=this.j(s,1,y,r.length);else if("⌫"===t.text){const t={start:-1,end:-1,no:-1};if(s.selection){const i=s.selection.start,e=s.selection.end,o=e-i;r.splice(s.selection.start,o),this.text=r.join(""),t.start=i,t.end=e,t.no=o}else{const i=s.position;0!==i?(r.splice(i-1,1),this.text=r.join(""),t.start=i-1,t.end=i,t.no=1):o=!0}s.selection=void 0,o||this.cursors.forEach((s=>{const i=this.F(s.selection,t)>0;s.position>t.start&&(s.selection&&i&&t.start<s.selection.start&&s.position<t.end?s.position=t.start:s.position-=t.no);const e=s.selection;if(e)if(i){const i=this.F(e,t);e.start<=t.start?e.end-=i:(e.start-=i,e.end-=t.no),e.start===e.end&&(s.selection=void 0)}else t.start<=e.start&&t.end<=e.start&&(e.start-=t.no,e.end-=t.no)}))}else{const i=Array.from(t.text);if(s.selection){const t=s.selection.start,e=s.selection.end,o=e-t;r.splice(s.selection.start,o),s.position=t;const h={start:t,end:e,no:o};r.splice(s.position,0,...i),this.text=r.join(""),this.cursors.forEach((t=>{if(s===t)return;const e=h.no-i.length,r=t.selection;if(r)if(r.start>=h.start&&r.end<=h.end)t.selection=void 0,t.position=h.start;else{if(this.F(r,h)>0){const s=r.start===t.position,e=this.F(r,h);r.start>h.start&&(r.start-=h.no-e,r.start=Math.max(0,r.start)),r.end===h.end?r.end-=h.no:r.end===h.end-1?r.end-=h.no-1:r.end!==h.start&&(r.end-=h.no-i.length),t.position=s?r.start:r.end}else if(h.start<=r.start&&h.end<=r.start){const s=r.start===t.position,i=Math.min(r.start,r.end);h.end===i?r.start=h.start:r.start-=e,r.end-=e,r.start=Math.max(0,r.start),t.position=s?r.start:r.end}}else t.position>=h.start&&t.position<=h.end?t.position=h.start:t.position>h.end&&(t.position-=e)})),s.position+=i.length}else r.splice(s.position,0,...i),this.text=r.join(""),this.cursors.forEach((t=>{if(s===t)return;const e=t.selection;e&&(s.position<e.start?(e.start+=i.length,e.end+=i.length):s.position<e.end&&(e.end+=i.length)),s.position<t.position&&(t.position+=i.length)})),s.position+=i.length;s.selection=void 0}else{const i=Math.min(r.length,Math.max(0,t.position));s.position===i&&this.K(s.selection,t.selection)?o=!0:(s.position=i,t.selection?s.selection={start:t.selection.start,end:t.selection.end}:s.selection=void 0)}if(this.C+=1,this.C>=this.actions.length)if(!1===this.repeat||this.repeat===this.S+1){this.isFinished=!0,this.isPlaying=!1;const i={type:"FINISHED",action:t,time:new Date,cursor:s};this.lastPerformedAction=t,this.$(i)}else this.S+=1,this.U(o,t,s),this.N=window.setTimeout((()=>{this.C=0,this.G(),this.cursors.forEach((t=>{t.A(),t.isBlinking=!0}));const t={type:"REPEATING",time:new Date,cursor:s};this.$(t),this.R()}),this.repeatDelay);else this.U(o,t,s),this.R()}),i)}L(){if(this.N)return window.clearTimeout(this.N),void(this.N=null)}G(){this.text=this.g,this.I.forEach(((t,s)=>{const i=this.cursors[s];i.data=t.data?t.data:void 0,i.position=t.position;const e=t.selection;i.selection=e?{start:e.start,end:e.end}:void 0}))}F(t,s){return t?Math.min(t.end,s.end)-Math.max(t.start,s.start):0}K(t,s){return t===s||!(!t||!s)&&(t.start===s.start&&t.end===s.end)}H(t,s,i,e){if(t.position===e){if(void 0===t.selection)return!0}else t.selection?t.position=i:t.position+=s;return t.selection=void 0,!1}j(t,s,i,e){if(t.position===e)return!0;{t.position+=s;const e=t.selection;if(e)e[i]+=s;else{const e={start:-1,end:-1};e[i===v?y:v]=t.position-s,e[i]=t.position,t.selection=e}}return!1}U(t,s,i){if(t)return;const e={type:"CHANGED",action:s,time:new Date,cursor:i};this.lastPerformedAction=s,this.$(e)}$(t){this.T.o(t),this.B.$(this,t)}*[Symbol.iterator](){const t=Array.from(this.text),s={};this.cursors.forEach((t=>{const i=t.position;s[i]?s[i].push(t):s[i]=[t]}));for(let i=0;i<t.length;i++){const e=s[i];yield{position:i,cursors:e||[],character:t[i],selected:this.cursors.filter((t=>t.selection&&i>=t.selection.start&&i<t.selection.end))}}const i=s[t.length];i&&(yield{position:t.length,character:"",cursors:i,selected:[]})}}const v="start",y="end";const b="keyboard";return t.Typewriter=p,t.TypewriterActionUnknownCursorError=w,t.TypewriterBlinkAfterError=h,t.TypewriterCursor=e,t.TypewriterCursorNotAtSelectionEdgeError=u,t.TypewriterCursorOutOfBoundsError=l,t.TypewriterCursorSelectionInvalidRangeError=d,t.TypewriterCursorSelectionOutOfBoundsError=f,t.TypewriterDelayError=n,t.TypewriterRepeatDelayError=a,t.TypewriterRepeatError=c,t.createTypewriterSubscriber=function(t){return(s,i)=>{!function(t,s,i,e){const r="on"+s.type.toLowerCase().split("_").reduce(((t,s)=>{const i=s.split("");return i[0]=i[0].toUpperCase(),t+i.join("")}),""),o=e[r];o?o(s,i):e.debug&&console.warn(`uiloos > ${t} event '${s.type}' was fired but '${r}' method is not implemented, this might not be correct.`)}("createTypewriterSubscriber",i,s,t)}},t.typewriterFromSentences=function(t,s){const i=void 0===t.delay?50:t.delay,e=void 0===t.sentenceDelay?2e3:t.sentenceDelay,r=[];let o=t.text?Array.from(t.text):[],h=!0;for(let s of t.sentences){const t=Array.from(s);let n=0;for(let s=0;s<o.length;s++){const i=o[s];if(t[s]!==i)break;n+=1}const c=o.length-n;o=o.slice(0,o.length-c);for(let t=0;t<c;t++){const s=h||0!==t?i:e;r.push({type:b,text:"⌫",delay:s,cursor:0})}const a=o.length>0?t.slice(n):t;for(const t of a)r.push({type:b,text:t,delay:i,cursor:0});o=o.concat(a),h=!1}return new p(Object.assign(Object.assign({repeatDelay:e},t),{actions:r}),s)},t}({});