UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

1 lines 6.07 kB
(()=>{"use strict";var e={d:(t,r)=>{for(var s in r)e.o(r,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:r[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{TinyTextRangeEditor:()=>r});const r=class{#e;#t;#r;constructor(e,{openTag:t="[",closeTag:r="]"}={}){if(!(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement))throw new TypeError("Element must be an input or textarea.");if("string"!=typeof t)throw new TypeError("openTag must be a string.");if("string"!=typeof r)throw new TypeError("closeTag must be a string.");this.#e=e,this.#t=t,this.#r=r}getOpenTag(){return this.#t}getCloseTag(){return this.#r}setOpenTag(e){if("string"!=typeof e)throw new TypeError("Open tag must be a string.");this.#t=e}setCloseTag(e){if("string"!=typeof e)throw new TypeError("Close tag must be a string.");this.#r=e}ensureFocus(){return document.activeElement!==this.#e&&this.#e.focus(),this}focus(){return this.#e.focus(),this}getSelectionRange(){return{start:this.#e.selectionStart??NaN,end:this.#e.selectionEnd??NaN}}setSelectionRange(e,t,r=!0){if("number"!=typeof e||"number"!=typeof t)throw new TypeError("start and end must be numbers.");if("boolean"!=typeof r)throw new TypeError("preserveScroll must be a boolean.");const s=this.#e.scrollTop,n=this.#e.scrollLeft;return this.#e.setSelectionRange(e,t),r&&(this.#e.scrollTop=s,this.#e.scrollLeft=n),this}getValue(){return this.#e.value}setValue(e){if("string"!=typeof e)throw new TypeError("Value must be a string.");return this.#e.value=e,this}getSelectedText(){const{start:e,end:t}=this.getSelectionRange();return this.#e.value.slice(e,t)}insertText(e,{newCursor:t="end",autoSpacing:r=!1,autoSpaceLeft:s=r,autoSpaceRight:n=r}={}){if("string"!=typeof e)throw new TypeError("Text must be a string.");if(!["start","end","preserve"].includes(t))throw new TypeError("newCursor must be one of 'start', 'end', or 'preserve'.");if("boolean"!=typeof r)throw new TypeError("autoSpacing must be a boolean.");if("boolean"!=typeof s)throw new TypeError("autoSpaceLeft must be a boolean.");if("boolean"!=typeof n)throw new TypeError("autoSpaceRight must be a boolean.");const{start:i,end:o}=this.getSelectionRange(),a=this.#e.value,l=a[i-1]||"",h=a[o]||"",g=`${s&&l&&!/\s/.test(l)?" ":""}${e}${n&&h&&!/\s/.test(h)?" ":""}`,c=a.slice(0,i)+g+a.slice(o);this.setValue(c);let p=i;return"end"===t?p=i+g.length:"preserve"===t&&(p=i),this.setSelectionRange(p,p),this}deleteSelection(){return this.insertText(""),this}transformSelection(e){if("function"!=typeof e)throw new TypeError("transformer must be a function.");const{start:t}=this.getSelectionRange(),r=e(this.getSelectedText());return this.insertText(r),this.setSelectionRange(t,t+r.length),this}surroundSelection(e,t){if("string"!=typeof e||"string"!=typeof t)throw new TypeError("prefix and suffix must be strings.");const r=this.getSelectedText();return this.insertText(`${e}${r}${t}`),this}moveCaret(e){if("number"!=typeof e)throw new TypeError("offset must be a number.");const{start:t}=this.getSelectionRange(),r=Math.max(0,t+e);return this.setSelectionRange(r,r),this}selectAll(){return this.setSelectionRange(0,this.#e.value.length),this}expandSelection(e,t){if("number"!=typeof e||"number"!=typeof t)throw new TypeError("before and after must be numbers.");const{start:r,end:s}=this.getSelectionRange(),n=Math.max(0,r-e),i=Math.min(this.#e.value.length,s+t);return this.setSelectionRange(n,i),this}replaceAll(e,t){if(!(e instanceof RegExp))throw new TypeError("regex must be a RegExp.");if("function"!=typeof t)throw new TypeError("replacer must be a function.");const r=this.#e.value.replace(e,t);return this.setValue(r),this}replaceInSelection(e,t){if(!(e instanceof RegExp))throw new TypeError("regex must be a RegExp.");if("function"!=typeof t)throw new TypeError("replacer must be a function.");const{start:r,end:s}=this.getSelectionRange(),n=this.#e.value,i=n.slice(r,s).replace(e,t),o=n.slice(0,r)+i+n.slice(s);return this.setValue(o),this.setSelectionRange(r,r+i.length),this}toggleCode(e){if("string"!=typeof e)throw new TypeError("codeName must be a string.");const t=this.getSelectedText();if(t.startsWith(e)&&t.endsWith(e)){const r=t.slice(e.length,t.length-e.length);this.insertText(r)}else this.insertText(`${e}${t}${e}`);return this}_insertAttr(e){let t="";if(Array.isArray(e)){if(!e.every(e=>"string"==typeof e))throw new TypeError("All entries in attributes array must be strings.");t=e.map(e=>`${e}`).join(" ")}else{if("object"!=typeof e||null===e)throw new TypeError("attributes must be an object or an array of strings.");t=Object.entries(e).map(([e,t])=>{if("string"!=typeof t)throw new TypeError("All entries in attributes object must be strings.");return`${e}${t.length>0?`="${t}"`:""}`}).join(" ")}return t}wrapWithTag(e,t={}){if("string"!=typeof e)throw new TypeError("tagName must be a string.");const r=this._insertAttr(t),s=r?`${this.#t}${e} ${r}${this.#r}`:`${this.#t}${e}${this.#r}`,n=`${this.#t}/${e}${this.#r}`;return this.surroundSelection(s,n),this}insertTag(e,t="",r={}){if("string"!=typeof e)throw new TypeError("tagName must be a string.");if("string"!=typeof t)throw new TypeError("content must be a string.");const s=this._insertAttr(r),n=s?`${this.#t}${e} ${s}${this.#r}`:`${this.#t}${e}${this.#r}`,i=`${this.#t}/${e}${this.#r}`;return this.insertText(`${n}${t}${i}`),this}insertSelfClosingTag(e,t={}){if("string"!=typeof e)throw new TypeError("tagName must be a string.");const r=this._insertAttr(t),s=r?`${this.#t}${e} ${r}${this.#r}`:`${this.#t}${e}${this.#r}`;return this.insertText(s),this}toggleTag(e,t={}){if("string"!=typeof e)throw new TypeError("tagName must be a string.");const r=this.getSelectedText(),s=new RegExp(`^\\[${e}(\\s+[^\\]]*)?\\]`),n=new RegExp(`\\[/${e}\\]$`),i=s.test(r),o=n.test(r);if(i&&o){const e=r.replace(s,"").replace(n,"");this.insertText(e)}else{const s=this._insertAttr(t),n=s?`${this.#t}${e} ${s}${this.#r}`:`${this.#t}${e}${this.#r}`,i=`${this.#t}/${e}${this.#r}`;this.insertText(`${n}${r}${i}`)}return this}};window.TinyTextRangeEditor=t.TinyTextRangeEditor})();